Sofondo
SofondoFrameworkDocs

Sofondo Framework - API Reference

Complete API reference for all Sofondo Framework components, hooks, providers, and utilities.

Table of Contents


Installation

npm install @sofondo/core @sofondo/react @sofondo/styles

Core Utilities

Storage Utilities

getStorageStatus(value, max, inverted?)

Calculate storage usage status based on percentage thresholds.

Parameters:

  • value: number - Current usage value
  • max: number - Maximum capacity
  • inverted?: boolean - If true, higher percentages are better (default: false)

Returns: 'healthy' | 'warning' | 'critical'

Example:

import { getStorageStatus } from '@sofondo/core';

const status = getStorageStatus(75, 100); // 'warning'
const completionStatus = getStorageStatus(90, 100, true); // 'healthy'

getStorageColor(status)

Get hex color code for a storage status.

Parameters:

  • status: 'healthy' | 'warning' | 'critical' - Storage status

Returns: string - Hex color code

Colors:

  • healthy: #0f9d58 (green)
  • warning: #f9ab00 (orange)
  • critical: #ea4335 (red)

Example:

import { getStorageStatus, getStorageColor } from '@sofondo/core';

const status = getStorageStatus(usage, max);
const color = getStorageColor(status);

getStorageClassName(status)

Get CSS class name suffix for a storage status.

Parameters:

  • status: 'healthy' | 'warning' | 'critical' - Storage status

Returns: 'positive' | 'warning' | 'negative'

Example:

const className = getStorageClassName('healthy'); // 'positive'

Configuration

defineConfig(config)

Define a type-safe Sofondo configuration.

Parameters:

  • config: UserConfig - Partial configuration object

Returns: UserConfig - The same configuration (for type safety)

Example:

import { defineConfig } from '@sofondo/core';

export default defineConfig({
  theme: { defaultMode: 'dark' },
  sidebar: { defaultCollapsed: true },
});

mergeConfig(userConfig?)

Merge user configuration with defaults.

Parameters:

  • userConfig?: UserConfig - User configuration to merge

Returns: ResolvedConfig - Complete configuration with defaults

validateConfig(config)

Validate configuration and return errors.

Parameters:

  • config: UserConfig - Configuration to validate

Returns: string[] - Array of error messages (empty if valid)


React Components

Layout Components

Page header with breadcrumbs, title, subtitle, and actions.

Props:

interface PageHeaderProps {
  breadcrumbs?: BreadcrumbItem[];
  title: string;
  subtitle?: ReactNode;
  actions?: ReactNode;
}

Example:

<PageHeader
  title="Dashboard"
  subtitle="Welcome back!"
  actions={<button>New Item</button>}
/>

<BaseSidebar />

Framework-agnostic sidebar component.

Props:

interface BaseSidebarProps {
  isCollapsed: boolean;
  toggleSidebar: () => void;
  menuItems: MenuItem[];
  navigationAdapter: NavigationAdapter;
  tooltipOffsetX?: number;
  tooltipOffsetY?: number;
}

<BaseHeader />

Framework-agnostic header component.

Props:

interface BaseHeaderProps {
  user?: {
    name: string;
    email?: string;
    avatar?: string;
  };
  navigationAdapter: NavigationAdapter;
}

<BaseAdminLayout />

Complete admin layout with sidebar and header.

Props:

interface BaseAdminLayoutProps {
  children: ReactNode;
  menuItems: MenuItem[];
  user?: UserInfo;
  navigationAdapter: NavigationAdapter;
}

UI Components

<ProgressBar />

Horizontal progress indicator.

Props:

interface ProgressBarProps {
  value: number;          // Current value
  max: number;            // Maximum value
  height?: number;        // Height in pixels (default: 6)
  color?: string;         // Fill color
}

Example:

<ProgressBar value={45} max={100} height={8} color="#0066cc" />

<Skeleton />

Loading skeleton placeholder.

Props:

interface SkeletonProps {
  width?: number | string;
  height?: number | string;
  variant?: 'text' | 'circular' | 'rounded' | 'rectangular';
  style?: React.CSSProperties;
}

Example:

<Skeleton width={200} height={20} />
<Skeleton variant="circular" width={40} height={40} />

<DataGrid />

Flexible data table component.

Props:

interface DataGridProps<T> {
  data: T[];
  columns: Column<T>[];
  keyField: keyof T;
}

interface Column<T> {
  key: keyof T;
  header: string;
  width?: string;
  align?: 'left' | 'center' | 'right';
  render?: (item: T) => ReactNode;
}

Example:

<DataGrid
  data={users}
  keyField="id"
  columns={[
    { key: 'name', header: 'Name', width: '2fr' },
    { key: 'email', header: 'Email', width: '2fr' },
    { key: 'role', header: 'Role', width: '1fr' },
  ]}
/>

<Toast />

Toast notification component.

Props:

interface ToastProps {
  id: string;
  message: string;
  type?: 'info' | 'success' | 'warning' | 'error';
  duration?: number;
  onClose: (id: string) => void;
}

<StatCard />

Statistics card for dashboard metrics.

Props:

interface StatCardProps {
  icon: LucideIcon;
  label: string;
  value: string | number;
  change?: string;
  changeClassName?: 'positive' | 'warning' | 'negative';
  children?: ReactNode;
  animate?: boolean;
}

Example:

<StatCard
  icon={Users}
  label="Total Users"
  value="1,234"
  change="+12% this month"
  changeClassName="positive"
/>

<StatGrid />

Grid container for stat cards.

Props:

interface StatGridProps {
  children: ReactNode;
  animate?: boolean;
}

<Card />

Generic card container.

Props:

interface CardProps {
  children: ReactNode;
  className?: string;
  style?: React.CSSProperties;
}

Breadcrumb navigation.

Props:

interface BreadcrumbProps {
  items: BreadcrumbItem[];
}

interface BreadcrumbItem {
  icon?: LucideIcon;
  label: string;
  href?: string;
}

<CustomScrollbar />

Custom styled scrollbar.

Props:

interface CustomScrollbarProps {
  container: HTMLElement | null;
  className?: string;
}

<ContextPanel />

Contextual information panel.

Props:

interface ContextPanelProps {
  title: string;
  children: ReactNode;
  isOpen: boolean;
  onClose: () => void;
}

<TableOfContents />

Automatically tracks and displays page headings with smooth scrolling navigation. Features include:

  • Highlights the currently visible section as user scrolls
  • Auto-scrolls the TOC to keep active items visible
  • Smooth scrolling to sections when clicked
  • Accounts for sticky headers during scroll
  • Supports nested heading levels (h2, h3, etc.)

Props:

interface TableOfContentsProps {
  headings: TocHeading[];
  title?: string;  // Default: "On This Page"
  className?: string;
}

interface TocHeading {
  id: string;    // The heading's DOM id
  text: string;  // Display text
  level: number; // Heading level (2 for h2, 3 for h3, etc.)
}

Example:

import TableOfContents from '@sofondo/react';

const headings = [
  { id: 'introduction', text: 'Introduction', level: 2 },
  { id: 'getting-started', text: 'Getting Started', level: 2 },
  { id: 'installation', text: 'Installation', level: 3 },
  { id: 'configuration', text: 'Configuration', level: 3 },
  { id: 'usage', text: 'Usage', level: 2 }
];

<TableOfContents
  headings={headings}
  title="On This Page"
/>

Framework Integration:

For Astro:

// Extract headings from Astro content collections
const { Content, headings } = await doc.render();

const tocHeadings = headings
  .filter(h => h.depth === 2 || h.depth === 3)
  .map(h => ({
    id: h.slug,
    text: h.text,
    level: h.depth
  }));

<TableOfContents headings={tocHeadings} />

React Hooks

useConfig()

Access the complete Sofondo configuration.

Returns: ResolvedConfig

Example:

const config = useConfig();
const isDarkMode = config.theme.defaultMode === 'dark';

Throws: Error if used outside ConfigProvider

useConfigSection(section)

Access a specific configuration section.

Parameters:

  • section: keyof ResolvedConfig - Configuration section name

Returns: Configuration section

Example:

const themeConfig = useConfigSection('theme');
const sidebarConfig = useConfigSection('sidebar');

useTheme()

Access and control the theme.

Returns:

{
  theme: 'light' | 'dark';
  mode: 'light' | 'dark' | 'system';
  setMode: (mode: ThemeMode) => void;
  toggleTheme: () => void;
}

Example:

const { theme, mode, setMode, toggleTheme } = useTheme();

// Set specific mode
setMode('dark');

// Toggle through modes: light → dark → system → light
toggleTheme();

useToast()

Add toast notifications.

Returns:

{
  addToast: (
    message: string,
    type?: 'info' | 'success' | 'warning' | 'error',
    duration?: number
  ) => void;
}

Example:

const { addToast } = useToast();

addToast('Settings saved!', 'success');
addToast('Error occurred', 'error', 10000);

useMediaQuery(query)

Subscribe to media query changes.

Parameters:

  • query: string - Media query string

Returns: boolean - Whether query matches

Example:

const isMobile = useMediaQuery('(max-width: 768px)');
const isDark = useMediaQuery('(prefers-color-scheme: dark)');

useLocalStorage(key, initialValue)

Persist state in localStorage.

Parameters:

  • key: string - Storage key
  • initialValue: T - Initial value

Returns: [T, (value: T) => void] - Value and setter

Example:

const [name, setName] = useLocalStorage('username', '');

useDebounce(value, delay)

Debounce a value.

Parameters:

  • value: T - Value to debounce
  • delay: number - Delay in milliseconds

Returns: T - Debounced value

Example:

const [searchTerm, setSearchTerm] = useState('');
const debouncedSearch = useDebounce(searchTerm, 500);

useEffect(() => {
  // API call with debounced value
}, [debouncedSearch]);

useClickOutside(ref, handler)

Detect clicks outside an element.

Parameters:

  • ref: RefObject<HTMLElement> - Element ref
  • handler: () => void - Callback function

Example:

const menuRef = useRef<HTMLDivElement>(null);
useClickOutside(menuRef, () => setIsOpen(false));

useCopyToClipboard()

Copy text to clipboard.

Returns:

{
  copy: (text: string) => Promise<boolean>;
  copied: boolean;
}

Example:

const { copy, copied } = useCopyToClipboard();

<button onClick={() => copy('Hello!')}>
  {copied ? 'Copied!' : 'Copy'}
</button>

Providers

<ConfigProvider />

Provide configuration to components.

Props:

interface ConfigProviderProps {
  config?: UserConfig;
  children: ReactNode;
  throwOnValidationError?: boolean;
}

Example:

import config from './sofondo.config';

<ConfigProvider config={config}>
  <App />
</ConfigProvider>

<ThemeProvider />

Provide theme state and controls.

Props:

interface ThemeProviderProps {
  children: ReactNode;
  config?: ThemeConfig;
}

Example:

<ThemeProvider config={{ defaultMode: 'dark' }}>
  <App />
</ThemeProvider>

<ToastProvider />

Provide toast notification system.

Props:

interface ToastProviderProps {
  children: ReactNode;
  position?: 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
  defaultDuration?: number;
  maxToasts?: number;
}

Example:

<ToastProvider position="top-right" defaultDuration={5000}>
  <App />
</ToastProvider>

Animation Utilities

Framer Motion animation variants for consistent animations.

staggerContainer

Container that staggers children animations.

Example:

<motion.div variants={staggerContainer} initial="hidden" animate="show">
  <motion.div variants={fadeInUp}>Item 1</motion.div>
  <motion.div variants={fadeInUp}>Item 2</motion.div>
</motion.div>

fadeInUp

Fade in from bottom with spring animation.

fadeInDown

Fade in from top.

fadeInLeft

Fade in from left.

fadeInRight

Fade in from right.

fadeIn

Simple fade in/out.

scaleUp

Scale up animation.

Example:

import { fadeInUp, staggerContainer } from '@sofondo/react';

<motion.div variants={fadeInUp} initial="hidden" animate="show">
  Content
</motion.div>

TypeScript Types

Configuration Types

// User configuration (all optional)
type UserConfig = Partial<SofondoConfig>;

// Resolved configuration (all required)
type ResolvedConfig = Required<{
  [K in keyof SofondoConfig]: Required<NonNullable<SofondoConfig[K]>>;
}>;

// Individual section types
type ThemeConfig = { /* ... */ };
type SidebarConfig = { /* ... */ };
type AnimationsConfig = { /* ... */ };
type ComponentsConfig = { /* ... */ };
type AccessibilityConfig = { /* ... */ };
type DevConfig = { /* ... */ };

Component Types

// Menu item for navigation
interface MenuItem {
  icon: LucideIcon;
  label: string;
  href?: string;
  exact?: boolean;
  children?: MenuItem[];
}

// Column definition for DataGrid
interface Column<T> {
  key: keyof T;
  header: string;
  width?: string;
  align?: 'left' | 'center' | 'right';
  render?: (item: T) => ReactNode;
}

// Breadcrumb item
interface BreadcrumbItem {
  icon?: LucideIcon;
  label: string;
  href?: string;
}

For framework-agnostic components:

interface NavigationAdapter {
  Link: ComponentType<{ href: string; children: ReactNode; className?: string }>;
  usePathname: () => string;
}

// Next.js adapter
import { nextjsNavigationAdapter } from '@sofondo/next';

// Custom adapter
const customAdapter: NavigationAdapter = {
  Link: ({ href, children, className }) => (
    <a href={href} className={className}>{children}</a>
  ),
  usePathname: () => window.location.pathname,
};

Best Practices

Importing

// Core utilities and types
import { getStorageStatus, defineConfig } from '@sofondo/core';
import type { UserConfig, MenuItem } from '@sofondo/core';

// React components
import { PageHeader, ProgressBar, DataGrid } from '@sofondo/react';

// React hooks
import { useConfig, useTheme, useToast } from '@sofondo/react';

// Providers
import { ConfigProvider, ThemeProvider, ToastProvider } from '@sofondo/react';

// Animation variants
import { fadeInUp, staggerContainer } from '@sofondo/react';

// Styles
import styles from '@sofondo/styles/dashboard.module.css';

Provider Setup

Wrap your app with providers in this order:

<ConfigProvider config={config}>
  <ThemeProvider>
    <ToastProvider>
      <YourApp />
    </ToastProvider>
  </ThemeProvider>
</ConfigProvider>

TypeScript

Always import and use types:

import type { MenuItem, Column } from '@sofondo/core';
import type { PageHeaderProps } from '@sofondo/react';

const menuItems: MenuItem[] = [/* ... */];
const columns: Column<User>[] = [/* ... */];

Examples

See the Configuration Guide for detailed configuration examples.

See API Design Standards for component development guidelines.

Support

For issues and questions, please refer to: