{
  "package": "@dreamtree-org/twreact-ui",
  "catalog": {
    "package": "@dreamtree-org/twreact-ui",
    "components": [
      {
        "name": "Input",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Text input with optional label, error/success states, clear button, character count, and password visibility toggle.",
        "props": [
          {
            "prop": "id",
            "type": "`string`",
            "default": "",
            "description": "Input id (auto-generated if not set)"
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Extra CSS classes"
          },
          {
            "prop": "type",
            "type": "`string`",
            "default": "\"text\"",
            "description": "`text`, `search`, `password`, etc."
          },
          {
            "prop": "label",
            "type": "`string`",
            "default": "",
            "description": "Label text"
          },
          {
            "prop": "placeholder",
            "type": "`string`",
            "default": "",
            "description": "Placeholder"
          },
          {
            "prop": "error",
            "type": "`string`",
            "default": "",
            "description": "Error message (shows error state)"
          },
          {
            "prop": "success",
            "type": "`boolean`",
            "default": "",
            "description": "Success state"
          },
          {
            "prop": "disabled",
            "type": "`boolean`",
            "default": "false",
            "description": "Disable input"
          },
          {
            "prop": "required",
            "type": "`boolean`",
            "default": "false",
            "description": "Required field"
          },
          {
            "prop": "clearable",
            "type": "`boolean`",
            "default": "false",
            "description": "Show clear button when has value"
          },
          {
            "prop": "icon",
            "type": "`ReactNode`",
            "default": "",
            "description": "Left or right icon"
          },
          {
            "prop": "iconPosition",
            "type": "`\"left\"` ",
            "default": "\"right\"",
            "description": "`\"left\"`"
          },
          {
            "prop": "onClear",
            "type": "`function`",
            "default": "",
            "description": "Called when clear is clicked"
          },
          {
            "prop": "showCount",
            "type": "`boolean`",
            "default": "false",
            "description": "Show character count"
          },
          {
            "prop": "maxLength",
            "type": "`number`",
            "default": "",
            "description": "Max length (used with showCount)"
          },
          {
            "prop": "readOnly",
            "type": "`boolean`",
            "default": "false",
            "description": "Read-only"
          },
          {
            "prop": "value",
            "type": "`string`",
            "default": "",
            "description": "Controlled value"
          },
          {
            "prop": "defaultValue",
            "type": "`string`",
            "default": "",
            "description": "Uncontrolled default"
          },
          {
            "prop": "onChange",
            "type": "`function`",
            "default": "",
            "description": "Change handler"
          },
          {
            "prop": "...rest",
            "type": "—",
            "default": "",
            "description": "Passed to native `<input>`"
          }
        ],
        "examples": "### Basic\n\n```jsx\n<Input label=\"Email\" placeholder=\"you@example.com\" />\n```\n\n### With error\n\n```jsx\n<Input label=\"Email\" error=\"Invalid email address\" />\n```\n\n### Password with toggle\n\n```jsx\n<Input type=\"password\" label=\"Password\" placeholder=\"Enter password\" />\n```\n\n### Clearable and character count\n\n```jsx\n<Input\n  label=\"Bio\"\n  clearable\n  showCount\n  maxLength={200}\n  placeholder=\"Tell us about yourself\"\n/>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Button",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Button with variants, sizes, loading state, and optional left/right icons.",
        "props": [
          {
            "prop": "variant",
            "type": "`string`",
            "default": "\"primary\"",
            "description": "`primary`, `secondary`, `outline`, `ghost`, `destructive`, `success`, `warning`"
          },
          {
            "prop": "size",
            "type": "`string`",
            "default": "\"md\"",
            "description": "`sm`, `md`, `lg`"
          },
          {
            "prop": "disabled",
            "type": "`boolean`",
            "default": "",
            "description": "Disable button"
          },
          {
            "prop": "loading",
            "type": "`boolean`",
            "default": "",
            "description": "Show spinner and disable"
          },
          {
            "prop": "leftIcon",
            "type": "`ReactNode`",
            "default": "",
            "description": "Icon before children"
          },
          {
            "prop": "rightIcon",
            "type": "`ReactNode`",
            "default": "",
            "description": "Icon after children"
          },
          {
            "prop": "fullWidth",
            "type": "`boolean`",
            "default": "",
            "description": "Full width"
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Extra CSS classes"
          },
          {
            "prop": "...rest",
            "type": "—",
            "default": "",
            "description": "Passed to native `<button>`"
          }
        ],
        "examples": "### Basic\n\n```jsx\n<Button variant=\"primary\">Save</Button>\n<Button variant=\"outline\">Cancel</Button>\n```\n\n### Sizes and loading\n\n```jsx\n<Button size=\"sm\">Small</Button>\n<Button size=\"lg\">Large</Button>\n<Button loading>Saving...</Button>\n```\n\n### With icons\n\n```jsx\nimport { Download } from 'lucide-react';\n\n<Button leftIcon={<Download className=\"h-4 w-4\" />}>Download</Button>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Select",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Single or multi-select dropdown with search, grouped options, creatable options, and optional select-all.",
        "props": [
          {
            "prop": "options",
            "type": "`Array`",
            "default": "[]",
            "description": "`[{ value, label, disabled }]` or grouped `[{ label, options: [...] }]`"
          },
          {
            "prop": "value",
            "type": "`any` ",
            "default": "any[]",
            "description": "—"
          },
          {
            "prop": "onChange",
            "type": "`function`",
            "default": "",
            "description": "`(value)` or `(values[])`"
          },
          {
            "prop": "placeholder",
            "type": "`string`",
            "default": "\"Select an option...\"",
            "description": "Placeholder text"
          },
          {
            "prop": "label",
            "type": "`string`",
            "default": "",
            "description": "Label"
          },
          {
            "prop": "error",
            "type": "`string`",
            "default": "",
            "description": "Error message"
          },
          {
            "prop": "disabled",
            "type": "`boolean`",
            "default": "",
            "description": "Disable select"
          },
          {
            "prop": "required",
            "type": "`boolean`",
            "default": "",
            "description": "Required"
          },
          {
            "prop": "multiSelect",
            "type": "`boolean`",
            "default": "false",
            "description": "Allow multiple selection"
          },
          {
            "prop": "searchable",
            "type": "`boolean`",
            "default": "false",
            "description": "Show search input"
          },
          {
            "prop": "grouped",
            "type": "`boolean`",
            "default": "false",
            "description": "Options are grouped"
          },
          {
            "prop": "allowClear",
            "type": "`boolean`",
            "default": "true",
            "description": "Show clear button"
          },
          {
            "prop": "creatable",
            "type": "`boolean`",
            "default": "false",
            "description": "Allow creating new option when no match"
          },
          {
            "prop": "onCreateOption",
            "type": "`function`",
            "default": "",
            "description": "Called when creating option"
          },
          {
            "prop": "onSearch",
            "type": "`function`",
            "default": "",
            "description": "Search term callback"
          },
          {
            "prop": "loading",
            "type": "`boolean`",
            "default": "false",
            "description": "Loading state"
          },
          {
            "prop": "selectAllOption",
            "type": "`boolean`",
            "default": "true",
            "description": "Show select all (multi)"
          },
          {
            "prop": "closeOnSelect",
            "type": "`boolean`",
            "default": "false",
            "description": "Close dropdown on select (single)"
          },
          {
            "prop": "maxTagCount",
            "type": "`number`",
            "default": "3",
            "description": "Max tags shown in multi (rest as \"+N\")"
          },
          {
            "prop": "onMenuItemRender",
            "type": "`function`",
            "default": "",
            "description": "Custom option render"
          },
          {
            "prop": "renderGroupLabel",
            "type": "`function`",
            "default": "",
            "description": "Custom group label"
          },
          {
            "prop": "name",
            "type": "`string`",
            "default": "",
            "description": "Form field name"
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Extra CSS classes"
          }
        ],
        "examples": "### Basic single select\n\n```jsx\nconst options = [\n  { value: 'a', label: 'Option A' },\n  { value: 'b', label: 'Option B' },\n];\n<Select\n  options={options}\n  value={value}\n  onChange={setValue}\n  placeholder=\"Choose one\"\n/>\n```\n\n### Multi select with search\n\n```jsx\n<Select\n  options={options}\n  value={selected}\n  onChange={setSelected}\n  multiSelect\n  searchable\n  placeholder=\"Choose multiple\"\n/>\n```\n\n### Grouped options\n\n```jsx\nconst grouped = [\n  { label: 'Fruits', options: [{ value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }] },\n  { label: 'Veggies', options: [{ value: 'carrot', label: 'Carrot' }] },\n];\n<Select options={grouped} grouped value={value} onChange={setValue} />\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Table",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Data table with sorting, filtering, pagination, row selection, expandable details, and responsive mobile card view.",
        "props": [
          {
            "prop": "data",
            "type": "`Array`",
            "default": "[]",
            "description": "Row data (array of objects)"
          },
          {
            "prop": "columns",
            "type": "`Array`",
            "default": "[]",
            "description": "`[{ key, label, sortable?, isVisible?, render? }]`"
          },
          {
            "prop": "sortable",
            "type": "`boolean`",
            "default": "true",
            "description": "Enable column sort"
          },
          {
            "prop": "filterable",
            "type": "`boolean`",
            "default": "false",
            "description": "Enable column filters"
          },
          {
            "prop": "selectable",
            "type": "`boolean`",
            "default": "false",
            "description": "Row selection checkboxes"
          },
          {
            "prop": "pagination",
            "type": "`boolean`",
            "default": "false",
            "description": "Enable pagination"
          },
          {
            "prop": "pageSize",
            "type": "`number`",
            "default": "25",
            "description": "Rows per page"
          },
          {
            "prop": "onSort",
            "type": "`function`",
            "default": "",
            "description": "Sort callback"
          },
          {
            "prop": "onFilter",
            "type": "`function`",
            "default": "",
            "description": "Filter callback"
          },
          {
            "prop": "onFetch",
            "type": "`function`",
            "default": "",
            "description": "Server-side fetch (setData, setLoading, filters, page, limit, sort)"
          },
          {
            "prop": "onFilterChange",
            "type": "`function`",
            "default": "",
            "description": "Filter change callback"
          },
          {
            "prop": "onSelectionChange",
            "type": "`function`",
            "default": "",
            "description": "Selected rows callback"
          },
          {
            "prop": "onRowClick",
            "type": "`function`",
            "default": "",
            "description": "Row click callback"
          },
          {
            "prop": "hasDetails",
            "type": "`boolean`",
            "default": "false",
            "description": "Expandable row details"
          },
          {
            "prop": "DetailsComponent",
            "type": "`Component`",
            "default": "",
            "description": "Component for expanded content"
          },
          {
            "prop": "withAction",
            "type": "`boolean`",
            "default": "true",
            "description": "Show actions column"
          },
          {
            "prop": "onAction",
            "type": "`function`",
            "default": "",
            "description": "Action menu callback"
          },
          {
            "prop": "actions",
            "type": "`Array`",
            "default": "",
            "description": "Custom actions (edit, delete, etc.)"
          },
          {
            "prop": "showSerial",
            "type": "`boolean`",
            "default": "true",
            "description": "Show row number column"
          },
          {
            "prop": "cellClass",
            "type": "`string` ",
            "default": "function",
            "description": "—"
          },
          {
            "prop": "rowClass",
            "type": "`string` ",
            "default": "function",
            "description": "—"
          },
          {
            "prop": "globalSearch",
            "type": "`boolean`",
            "default": "false",
            "description": "Global search box"
          },
          {
            "prop": "limitOptions",
            "type": "`number[]`",
            "default": "[10,25,50,100]",
            "description": "Page size options"
          },
          {
            "prop": "showLimitSelector",
            "type": "`boolean`",
            "default": "true",
            "description": "Show page size selector"
          },
          {
            "prop": "showReloadButton",
            "type": "`boolean`",
            "default": "true",
            "description": "Show reload button"
          },
          {
            "prop": "onReload",
            "type": "`function`",
            "default": "",
            "description": "Reload click handler"
          },
          {
            "prop": "stripedRows",
            "type": "`boolean`",
            "default": "true",
            "description": "Striped row background"
          },
          {
            "prop": "theme",
            "type": "`object`",
            "default": "",
            "description": "`stripedColors`, `rowHover`, `accentColor`"
          },
          {
            "prop": "serverSide",
            "type": "`boolean`",
            "default": "false",
            "description": "Server-side pagination/sort/filter"
          },
          {
            "prop": "totalRecords",
            "type": "`number`",
            "default": "0",
            "description": "Total count (serverSide)"
          },
          {
            "prop": "pageNumber",
            "type": "`number`",
            "default": "",
            "description": "Controlled page"
          },
          {
            "prop": "onPageChange",
            "type": "`(page: number) => void`",
            "default": "",
            "description": "Called with the new page number when the page changes. Consumed by the table — it is **not** forwarded onto the `<table>`."
          },
          {
            "prop": "responsiveBreakpoint",
            "type": "`number`",
            "default": "768",
            "description": "px breakpoint for mobile cards"
          }
        ],
        "examples": "### Basic table\n\n```jsx\nconst columns = [\n  { key: 'name', label: 'Name' },\n  { key: 'email', label: 'Email' },\n];\nconst data = [\n  { id: 1, name: 'Alice', email: 'alice@example.com' },\n  { id: 2, name: 'Bob', email: 'bob@example.com' },\n];\n<Table data={data} columns={columns} />\n```\n\n### With pagination and selection\n\n```jsx\n<Table\n  data={data}\n  columns={columns}\n  pagination\n  pageSize={10}\n  selectable\n  onSelectionChange={(selected) => console.log(selected)}\n/>\n```\n\n### Server-side data\n\n```jsx\n<Table\n  data={data}\n  columns={columns}\n  serverSide\n  pagination\n  totalRecords={total}\n  onFetch={async ({ setData, setLoading, page, limit, sort }) => {\n    setLoading(true);\n    const res = await fetch(`/api/users?page=${page}&limit=${limit}`);\n    const json = await res.json();\n    setData(json.rows);\n    setLoading(false);\n  }}\n/>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Form",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Form built on **react-hook-form** with a `fields` config array. Renders Input, Select, DatePicker, Checkbox, Switch, textarea, etc., and handles submit/reset. Use `validationSchema` (e.g. from `@hookform/resolvers` with yup) for validation.",
        "props": [
          {
            "prop": "fields",
            "type": "`Array`",
            "default": "[]",
            "description": "Field configs (see Field shape below)."
          },
          {
            "prop": "onSubmit",
            "type": "`(data: object) => void`",
            "default": "",
            "description": "Submit handler; receives form data."
          },
          {
            "prop": "defaultValues",
            "type": "`object`",
            "default": "{}",
            "description": "Default values for each field name."
          },
          {
            "prop": "validationSchema",
            "type": "`object`",
            "default": "",
            "description": "Resolver from e.g. `yupResolver(schema)`."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Form wrapper CSS classes."
          },
          {
            "prop": "submitText",
            "type": "`string`",
            "default": "\"Submit\"",
            "description": "Submit button text."
          },
          {
            "prop": "resetText",
            "type": "`string`",
            "default": "\"Reset\"",
            "description": "Reset button text."
          },
          {
            "prop": "submitButtonClass",
            "type": "`string`",
            "default": "",
            "description": "Submit button CSS classes."
          },
          {
            "prop": "resetButtonClass",
            "type": "`string`",
            "default": "",
            "description": "Reset button CSS classes."
          },
          {
            "prop": "showReset",
            "type": "`boolean`",
            "default": "true",
            "description": "Show reset button."
          },
          {
            "prop": "submitDisabled",
            "type": "`boolean`",
            "default": "false",
            "description": "Disable submit button."
          },
          {
            "prop": "...rest",
            "type": "—",
            "default": "",
            "description": "Passed to react-hook-form `useForm` (e.g. `mode`)."
          }
        ],
        "examples": "```jsx\nimport { Form } from '@dreamtree-org/twreact-ui';\nimport { yupResolver } from '@hookform/resolvers/yup';\nimport * as yup from 'yup';\n\nconst schema = yup.object({\n  email: yup.string().email().required(),\n  password: yup.string().min(6).required(),\n});\n\n<Form\n  fields={[\n    { type: 'email', name: 'email', label: 'Email', required: true, placeholder: 'you@example.com' },\n    { type: 'password', name: 'password', label: 'Password', required: true },\n    { type: 'select', name: 'role', label: 'Role', options: [{ value: 'user', label: 'User' }, { value: 'admin', label: 'Admin' }] },\n  ]}\n  defaultValues={{ email: '', password: '', role: 'user' }}\n  validationSchema={yupResolver(schema)}\n  onSubmit={(data) => console.log(data)}\n  submitText=\"Sign in\"\n  showReset\n/>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Accordion",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Expandable/collapsible content panels. Only one panel open at a time by default, or multiple when `allowMultiple` is true. Supports keyboard navigation (Arrow keys, Home, End, Enter, Space).",
        "props": [
          {
            "prop": "items",
            "type": "`Array`",
            "default": "[]",
            "description": "Array of `{ id?, title, subtitle?, content, disabled?, leftIcon? }`. `leftIcon` can be ReactNode or `(index, item) => ReactNode`."
          },
          {
            "prop": "allowMultiple",
            "type": "`boolean`",
            "default": "false",
            "description": "If true, multiple panels can be open at once."
          },
          {
            "prop": "defaultOpenIndexes",
            "type": "`number[]`",
            "default": "[]",
            "description": "Initial open panel index(es)."
          },
          {
            "prop": "onChange",
            "type": "`(openIndexes: number[]) => void`",
            "default": "",
            "description": "Called when open panels change."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "\"\"",
            "description": "Wrapper CSS classes."
          },
          {
            "prop": "headerClassName",
            "type": "`string`",
            "default": "\"\"",
            "description": "Header button CSS classes."
          },
          {
            "prop": "contentClassName",
            "type": "`string`",
            "default": "\"\"",
            "description": "Panel content CSS classes."
          },
          {
            "prop": "chevronPosition",
            "type": "`\"left\"` ",
            "default": "\"right\"",
            "description": "`\"right\"`"
          },
          {
            "prop": "chevronIcon",
            "type": "`ReactNode`",
            "default": "default SVG",
            "description": "Custom chevron icon."
          },
          {
            "prop": "bordered",
            "type": "`boolean`",
            "default": "true",
            "description": "Whether to show border/background."
          },
          {
            "prop": "rounded",
            "type": "`\"none\"` ",
            "default": "\"sm\" \\",
            "description": "`\"md\"` \\"
          },
          {
            "prop": "size",
            "type": "`\"sm\"` ",
            "default": "\"md\" \\",
            "description": "`\"lg\"`"
          },
          {
            "prop": "transitionDuration",
            "type": "`number`",
            "default": "220",
            "description": "Max-height transition duration in ms."
          }
        ],
        "examples": "```jsx\n<Accordion\n  items={[\n    { id: '1', title: 'Section 1', content: <p>Content for section 1</p> },\n    { id: '2', title: 'Section 2', subtitle: 'Optional', content: <p>Content 2</p> },\n    { title: 'Disabled', content: <p>Content</p>, disabled: true },\n  ]}\n  allowMultiple={false}\n  defaultOpenIndexes={[0]}\n  onChange={(indexes) => console.log('Open:', indexes)}\n  size=\"md\"\n  chevronPosition=\"right\"\n/>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Checkbox",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Checkbox with label, sizes, and optional indeterminate state.",
        "props": [
          {
            "prop": "id",
            "type": "`string`",
            "default": "",
            "description": "Input id"
          },
          {
            "prop": "name",
            "type": "`string`",
            "default": "",
            "description": "Form name"
          },
          {
            "prop": "label",
            "type": "`string`",
            "default": "",
            "description": "Label text"
          },
          {
            "prop": "checked",
            "type": "`boolean`",
            "default": "",
            "description": "Controlled checked"
          },
          {
            "prop": "defaultChecked",
            "type": "`boolean`",
            "default": "false",
            "description": "Uncontrolled default"
          },
          {
            "prop": "onChange",
            "type": "`function`",
            "default": "",
            "description": "Change handler"
          },
          {
            "prop": "disabled",
            "type": "`boolean`",
            "default": "false",
            "description": "Disable"
          },
          {
            "prop": "required",
            "type": "`boolean`",
            "default": "false",
            "description": "Required"
          },
          {
            "prop": "size",
            "type": "`string`",
            "default": "\"md\"",
            "description": "`sm`, `md`, `lg`"
          },
          {
            "prop": "labelPosition",
            "type": "`string`",
            "default": "\"right\"",
            "description": "`left`, `right`"
          },
          {
            "prop": "value",
            "type": "`any`",
            "default": "",
            "description": "Value when checked"
          },
          {
            "prop": "indeterminate",
            "type": "`boolean`",
            "default": "false",
            "description": "Indeterminate state"
          },
          {
            "prop": "borderColor",
            "type": "`string`",
            "default": "\"#ccc\"",
            "description": "Box border color"
          },
          {
            "prop": "iconClass",
            "type": "`string`",
            "default": "",
            "description": "Extra classes for the check icon"
          },
          {
            "prop": "checkedClass",
            "type": "`string`",
            "default": "",
            "description": "Extra classes applied when checked"
          }
        ],
        "examples": "```jsx\n<Checkbox label=\"Accept terms\" checked={checked} onChange={e => setChecked(e.target.checked)} />\n<Checkbox label=\"Remember me\" defaultChecked />\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "ColorPicker",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Color picker with optional swatches, hex input, HSL sliders, and alpha. Value can be hex or rgba string; `onChange` receives normalized `rgba(r,g,b,a)` string.",
        "props": [
          {
            "prop": "value",
            "type": "`string`",
            "default": "",
            "description": "Controlled value (hex or rgba string)."
          },
          {
            "prop": "defaultValue",
            "type": "`string`",
            "default": "",
            "description": "Uncontrolled initial value."
          },
          {
            "prop": "onChange",
            "type": "`(rgbaString: string) => void`",
            "default": "",
            "description": "Called with normalized `rgba(r,g,b,a)` string."
          },
          {
            "prop": "swatches",
            "type": "`string[]`",
            "default": "",
            "description": "Array of hex/rgba strings for preset swatches."
          },
          {
            "prop": "showAlpha",
            "type": "`boolean`",
            "default": "false",
            "description": "Show alpha slider. When off (or when the alpha channel is fully opaque), the displayed hex is the 6-char `#rrggbb` form; the 8-char `#rrggbbff` form is shown only when `showAlpha` is on **and** alpha < 1."
          },
          {
            "prop": "size",
            "type": "`\"sm\"` ",
            "default": "\"md\" \\",
            "description": "`\"lg\"`"
          },
          {
            "prop": "disabled",
            "type": "`boolean`",
            "default": "",
            "description": "Disable the picker."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Wrapper CSS classes."
          },
          {
            "prop": "label",
            "type": "`string`",
            "default": "",
            "description": "Label text."
          },
          {
            "prop": "id",
            "type": "`string`",
            "default": "",
            "description": "Input id."
          }
        ],
        "examples": "```jsx\nconst [color, setColor] = useState('#3b82f6');\n<ColorPicker\n  value={color}\n  onChange={setColor}\n  swatches={['#ef4444', '#22c55e', '#3b82f6']}\n  showAlpha\n  label=\"Background\"\n/>\n```"
      },
      {
        "name": "DateRangePicker",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Date range picker: user selects start then end. Value is `{ start: Date, end: Date }`. Popup stays open until both are selected (or user clears). Supports min/max, clear, and optional portal.",
        "props": [
          {
            "prop": "value",
            "type": "`{ start: Date",
            "default": "string, end: Date\\",
            "description": "string }`"
          },
          {
            "prop": "onChange",
            "type": "`(range: { start, end } ",
            "default": "null) => void",
            "description": "—"
          },
          {
            "prop": "placeholder",
            "type": "`string`",
            "default": "\"Select date range...\"",
            "description": "Input placeholder."
          },
          {
            "prop": "label",
            "type": "`string`",
            "default": "",
            "description": "Label text."
          },
          {
            "prop": "error",
            "type": "`string`",
            "default": "",
            "description": "Error message."
          },
          {
            "prop": "disabled",
            "type": "`boolean`",
            "default": "",
            "description": "Disable."
          },
          {
            "prop": "required",
            "type": "`boolean`",
            "default": "",
            "description": "Required."
          },
          {
            "prop": "minDate",
            "type": "`Date`",
            "default": "",
            "description": "Minimum selectable date."
          },
          {
            "prop": "maxDate",
            "type": "`Date`",
            "default": "",
            "description": "Maximum selectable date."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Wrapper CSS classes."
          },
          {
            "prop": "weekStartsOn",
            "type": "`0` ",
            "default": "1",
            "description": "`0`"
          },
          {
            "prop": "portal",
            "type": "`boolean`",
            "default": "false",
            "description": "Render popup in document.body."
          },
          {
            "prop": "displayFormat",
            "type": "`string`",
            "default": "\"MMM dd, yyyy\"",
            "description": "date-fns format for display."
          },
          {
            "prop": "locale",
            "type": "`Locale`",
            "default": "",
            "description": "date-fns locale."
          },
          {
            "prop": "showClear",
            "type": "`boolean`",
            "default": "true",
            "description": "Show clear button."
          },
          {
            "prop": "closeOnSelect",
            "type": "`boolean`",
            "default": "true",
            "description": "Close when both dates selected."
          }
        ],
        "examples": "```jsx\nconst [range, setRange] = useState({ start: null, end: null });\n<DateRangePicker value={range} onChange={setRange} label=\"Period\" />\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Loader",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Loading indicator in three variants: spinner (default), dots, or bar. Configurable size, speed, colors, and optional label text.",
        "props": [
          {
            "prop": "size",
            "type": "`\"sm\"` ",
            "default": "\"md\" \\",
            "description": "`\"lg\"` \\"
          },
          {
            "prop": "speed",
            "type": "`number`",
            "default": "0.9",
            "description": "Animation duration in seconds."
          },
          {
            "prop": "thickness",
            "type": "`number`",
            "default": "2.5",
            "description": "Stroke thickness (spinner)."
          },
          {
            "prop": "color",
            "type": "`string`",
            "default": "\"currentColor\"",
            "description": "Main color (spinner/dots/bar)."
          },
          {
            "prop": "secondaryColor",
            "type": "`string`",
            "default": "\"rgba(0,0,0,0.08)\"",
            "description": "Track/background color."
          },
          {
            "prop": "variant",
            "type": "`\"spinner\"` ",
            "default": "\"dots\" \\",
            "description": "`\"bar\"`"
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "\"\"",
            "description": "Wrapper CSS classes."
          },
          {
            "prop": "inline",
            "type": "`boolean`",
            "default": "false",
            "description": "If true, wrapper is inline-flex."
          },
          {
            "prop": "ariaLabel",
            "type": "`string`",
            "default": "\"Loading\"",
            "description": "Accessibility label."
          },
          {
            "prop": "text",
            "type": "`string`",
            "default": "",
            "description": "Optional label shown next to loader."
          },
          {
            "prop": "reverse",
            "type": "`boolean`",
            "default": "false",
            "description": "Reverse spinner rotation direction."
          },
          {
            "prop": "style",
            "type": "`object`",
            "default": "",
            "description": "Inline style for wrapper."
          }
        ],
        "examples": "```jsx\n<Loader />\n<Loader variant=\"dots\" size=\"sm\" />\n<Loader variant=\"bar\" text=\"Loading...\" />\n<Loader size={32} color=\"#2563eb\" />\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "PriceRangePicker",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Dual-thumb range slider for min/max values (e.g. price or any number). Optional number inputs and preset buttons. Controlled via `value` or uncontrolled via `defaultValue`.",
        "props": [
          {
            "prop": "min",
            "type": "`number`",
            "default": "0",
            "description": "Minimum value."
          },
          {
            "prop": "max",
            "type": "`number`",
            "default": "1000",
            "description": "Maximum value."
          },
          {
            "prop": "step",
            "type": "`number`",
            "default": "1",
            "description": "Step for thumbs and inputs."
          },
          {
            "prop": "minGap",
            "type": "`number`",
            "default": "5",
            "description": "Minimum gap between min and max."
          },
          {
            "prop": "value",
            "type": "`{ min, max }` ",
            "default": "null",
            "description": "`null`"
          },
          {
            "prop": "defaultValue",
            "type": "`{ min, max }`",
            "default": "{ min: 0, max: 1000 }",
            "description": "Uncontrolled initial value."
          },
          {
            "prop": "onChange",
            "type": "`(value: { min, max }) => void`",
            "default": "() => {}",
            "description": "Called on thumb/input change."
          },
          {
            "prop": "onFinalChange",
            "type": "`(value: { min, max }) => void`",
            "default": "() => {}",
            "description": "Called on mouseup/touchend or Enter in inputs."
          },
          {
            "prop": "showInputs",
            "type": "`boolean`",
            "default": "true",
            "description": "Show min/max number inputs."
          },
          {
            "prop": "showTooltips",
            "type": "`boolean`",
            "default": "true",
            "description": "Show tooltips on thumbs."
          },
          {
            "prop": "disabled",
            "type": "`boolean`",
            "default": "false",
            "description": "Disable the control."
          },
          {
            "prop": "presets",
            "type": "`Array<{ id, label, value: { min, max } }>`",
            "default": "[]",
            "description": "Preset buttons."
          },
          {
            "prop": "formatValue",
            "type": "`(n: number) => string`",
            "default": "(n) => String(n)",
            "description": "Format display (e.g. currency)."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "\"\"",
            "description": "Container CSS classes."
          },
          {
            "prop": "size",
            "type": "`\"sm\"` ",
            "default": "\"md\" \\",
            "description": "`\"lg\"`"
          },
          {
            "prop": "colorClass",
            "type": "`string`",
            "default": "\"bgpink500\"",
            "description": "Tailwind class for active track/thumb."
          },
          {
            "prop": "ariaLabel",
            "type": "`string`",
            "default": "\"Price range\"",
            "description": "Accessibility label."
          }
        ],
        "examples": "```jsx\nconst [range, setRange] = useState({ min: 100, max: 500 });\n<PriceRangePicker\n  min={0}\n  max={1000}\n  value={range}\n  onChange={setRange}\n  formatValue={(n) => `$${n}`}\n  presets={[\n    { id: '1', label: 'Under $200', value: { min: 0, max: 200 } },\n  ]}\n/>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "ProgressBar",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Progress bar showing a value between 0 and max. Supports custom HEX colors, optional label, value text inside the bar, striped and animated styles.",
        "props": [
          {
            "prop": "value",
            "type": "`number`",
            "default": "0",
            "description": "Current value."
          },
          {
            "prop": "max",
            "type": "`number`",
            "default": "100",
            "description": "Maximum value."
          },
          {
            "prop": "size",
            "type": "`\"xs\"` ",
            "default": "\"sm\" \\",
            "description": "`\"md\"` \\"
          },
          {
            "prop": "showValue",
            "type": "`boolean`",
            "default": "false",
            "description": "Show percentage text inside the fill."
          },
          {
            "prop": "rounded",
            "type": "`boolean`",
            "default": "true",
            "description": "Rounded corners."
          },
          {
            "prop": "color",
            "type": "`string` (HEX)",
            "default": "\"#2563eb\"",
            "description": "Fill color (HEX only)."
          },
          {
            "prop": "bgColor",
            "type": "`string` (HEX)",
            "default": "\"#e6eefc\"",
            "description": "Track background (HEX only)."
          },
          {
            "prop": "valueColor",
            "type": "`string` (HEX)",
            "default": "auto",
            "description": "Text color inside fill; auto from luminance if omitted."
          },
          {
            "prop": "striped",
            "type": "`boolean`",
            "default": "false",
            "description": "Striped fill pattern."
          },
          {
            "prop": "animated",
            "type": "`boolean`",
            "default": "false",
            "description": "Animate stripe movement."
          },
          {
            "prop": "label",
            "type": "`string`",
            "default": "\"\"",
            "description": "Label above the bar."
          },
          {
            "prop": "ariaLabel",
            "type": "`string`",
            "default": "\"Progress\"",
            "description": "Accessibility label."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "\"\"",
            "description": "Wrapper CSS classes."
          },
          {
            "prop": "style",
            "type": "`object`",
            "default": "{}",
            "description": "Wrapper inline style."
          }
        ],
        "examples": "```jsx\n<ProgressBar value={60} max={100} />\n<ProgressBar value={75} showValue label=\"Upload\" color=\"#16a34a\" />\n<ProgressBar value={40} striped animated size=\"lg\" />\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Radio",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Single radio button; use multiple with the same `name` for a group. Controlled via `checked` or uncontrolled via `defaultChecked`.",
        "props": [
          {
            "prop": "id",
            "type": "`string`",
            "default": "auto",
            "description": "Input id."
          },
          {
            "prop": "name",
            "type": "`string`",
            "default": "",
            "description": "Group name (required for grouping)."
          },
          {
            "prop": "value",
            "type": "`any`",
            "default": "",
            "description": "Value when selected."
          },
          {
            "prop": "checked",
            "type": "`boolean`",
            "default": "",
            "description": "Controlled checked."
          },
          {
            "prop": "defaultChecked",
            "type": "`boolean`",
            "default": "",
            "description": "Uncontrolled initial."
          },
          {
            "prop": "onChange",
            "type": "`(e: Event) => void`",
            "default": "",
            "description": "Change handler."
          },
          {
            "prop": "disabled",
            "type": "`boolean`",
            "default": "false",
            "description": "Disable."
          },
          {
            "prop": "required",
            "type": "`boolean`",
            "default": "false",
            "description": "Required."
          },
          {
            "prop": "label",
            "type": "`string`",
            "default": "",
            "description": "Label text."
          },
          {
            "prop": "size",
            "type": "`\"sm\"` ",
            "default": "\"md\" \\",
            "description": "`\"lg\"`"
          },
          {
            "prop": "labelPosition",
            "type": "`\"left\"` ",
            "default": "\"right\"",
            "description": "`\"right\"`"
          },
          {
            "prop": "radioColor",
            "type": "`string`",
            "default": "\"blue\"",
            "description": "Accent color (Tailwind name)."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "\"\"",
            "description": "Label wrapper classes."
          },
          {
            "prop": "ariaLabel",
            "type": "`string`",
            "default": "",
            "description": "Accessibility label."
          }
        ],
        "examples": "```jsx\nconst [choice, setChoice] = useState('a');\n<>\n  <Radio name=\"choice\" value=\"a\" checked={choice === 'a'} onChange={() => setChoice('a')} label=\"Option A\" />\n  <Radio name=\"choice\" value=\"b\" checked={choice === 'b'} onChange={() => setChoice('b')} label=\"Option B\" />\n</>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Rate",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Star (or custom icon) rating input/display. Controlled via `value` or uncontrolled via `defaultValue`. Supports hover preview and optional read-only.",
        "props": [
          {
            "prop": "count",
            "type": "`number`",
            "default": "5",
            "description": "Number of stars."
          },
          {
            "prop": "value",
            "type": "`number`",
            "default": "",
            "description": "Controlled value (0 to count)."
          },
          {
            "prop": "defaultValue",
            "type": "`number`",
            "default": "0",
            "description": "Uncontrolled initial value."
          },
          {
            "prop": "readOnly",
            "type": "`boolean`",
            "default": "false",
            "description": "Read-only (no onChange)."
          },
          {
            "prop": "icon",
            "type": "`ReactNode`",
            "default": "<StarOutline />",
            "description": "Icon for inactive star."
          },
          {
            "prop": "toggledIcon",
            "type": "`ReactNode`",
            "default": "<StarFilled />",
            "description": "Icon for active star."
          },
          {
            "prop": "activeColor",
            "type": "`string`",
            "default": "\"#f6b026\"",
            "description": "Color for active stars."
          },
          {
            "prop": "inactiveColor",
            "type": "`string`",
            "default": "\"#e5e7eb\"",
            "description": "Color for inactive stars."
          },
          {
            "prop": "size",
            "type": "`number`",
            "default": "20",
            "description": "Icon size in px."
          },
          {
            "prop": "onChange",
            "type": "`(value: number) => void`",
            "default": "",
            "description": "Called when value changes."
          },
          {
            "prop": "onClick",
            "type": "`(value: number) => void`",
            "default": "",
            "description": "Called on star click."
          },
          {
            "prop": "text",
            "type": "`ReactNode`",
            "default": "",
            "description": "Optional text (e.g. label) next to stars."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "\"\"",
            "description": "Wrapper CSS classes."
          },
          {
            "prop": "id",
            "type": "`string`",
            "default": "",
            "description": "Wrapper id."
          },
          {
            "prop": "name",
            "type": "`string`",
            "default": "",
            "description": "Form field name."
          }
        ],
        "examples": "```jsx\nconst [rating, setRating] = useState(0);\n<Rate value={rating} onChange={setRating} count={5} />\n<Rate defaultValue={3} readOnly />\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "RoundedTag",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Tag/chip with optional avatar (image or initials) and optional remove button. Used for labels, selected items, or filters.",
        "props": [
          {
            "prop": "label",
            "type": "`string`",
            "default": "",
            "description": "Main label text."
          },
          {
            "prop": "avatarSrc",
            "type": "`string`",
            "default": "null",
            "description": "Image URL for avatar."
          },
          {
            "prop": "avatarAlt",
            "type": "`string`",
            "default": "\"avatar\"",
            "description": "Alt for avatar image."
          },
          {
            "prop": "initials",
            "type": "`string`",
            "default": "\"\"",
            "description": "Initials when no image (e.g. \"AB\")."
          },
          {
            "prop": "size",
            "type": "`\"sm\"` ",
            "default": "\"md\" \\",
            "description": "`\"lg\"`"
          },
          {
            "prop": "onRemove",
            "type": "`(e?) => void`",
            "default": "null",
            "description": "If provided, shows remove button and calls on click."
          },
          {
            "prop": "onClick",
            "type": "`(e?) => void`",
            "default": "null",
            "description": "Click handler for the tag."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "\"\"",
            "description": "Wrapper CSS classes."
          },
          {
            "prop": "closeClass",
            "type": "`string`",
            "default": "\"\"",
            "description": "Remove button CSS classes."
          },
          {
            "prop": "ariaLabel",
            "type": "`string`",
            "default": "\"tag\"",
            "description": "Accessibility label."
          },
          {
            "prop": "avatarPosition",
            "type": "`\"left\"` ",
            "default": "\"right\"",
            "description": "`\"left\"`"
          },
          {
            "prop": "avatarClassname",
            "type": "`string`",
            "default": "\"\"",
            "description": "Avatar wrapper classes."
          },
          {
            "prop": "initialClassname",
            "type": "`string`",
            "default": "\"\"",
            "description": "Initials span classes."
          }
        ],
        "examples": "```jsx\n<RoundedTag label=\"React\" />\n<RoundedTag label=\"John\" initials=\"JD\" onRemove={() => {}} />\n<RoundedTag label=\"With image\" avatarSrc=\"/user.jpg\" size=\"lg\" />\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Skeleton",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Placeholder blocks for loading states. Renders shimmer bars (or circles) when `active` is true; otherwise renders `children`.",
        "props": [
          {
            "prop": "count",
            "type": "`number`",
            "default": "1",
            "description": "Number of skeleton items."
          },
          {
            "prop": "circle",
            "type": "`boolean`",
            "default": "false",
            "description": "Render items as circles."
          },
          {
            "prop": "height",
            "type": "`number` ",
            "default": "string",
            "description": "`16`"
          },
          {
            "prop": "width",
            "type": "`number` ",
            "default": "string",
            "description": "—"
          },
          {
            "prop": "rounded",
            "type": "`boolean`",
            "default": "true",
            "description": "Rounded corners (when not circle)."
          },
          {
            "prop": "animated",
            "type": "`boolean`",
            "default": "true",
            "description": "Shimmer animation."
          },
          {
            "prop": "active",
            "type": "`boolean`",
            "default": "true",
            "description": "If true show skeletons; if false render children."
          },
          {
            "prop": "gap",
            "type": "`string`",
            "default": "\"8px\"",
            "description": "Spacing between items."
          },
          {
            "prop": "inline",
            "type": "`boolean`",
            "default": "false",
            "description": "Layout items in a row."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "\"\"",
            "description": "Wrapper CSS classes."
          },
          {
            "prop": "style",
            "type": "`object`",
            "default": "{}",
            "description": "Wrapper inline style."
          },
          {
            "prop": "children",
            "type": "`ReactNode`",
            "default": "null",
            "description": "Rendered when `active` is false."
          }
        ],
        "examples": "```jsx\n<Skeleton />\n<Skeleton count={3} height={20} gap=\"12px\" />\n<Skeleton circle height={40} />\n<Skeleton active={loading} count={2}>\n  <RealContent />\n</Skeleton>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Switch",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Toggle switch (on/off). Controlled or uncontrolled.",
        "props": [
          {
            "prop": "checked",
            "type": "`boolean`",
            "default": "",
            "description": "Controlled checked"
          },
          {
            "prop": "defaultChecked",
            "type": "`boolean`",
            "default": "false",
            "description": "Uncontrolled default"
          },
          {
            "prop": "onChange",
            "type": "`(checked: boolean) => void`",
            "default": "",
            "description": "Receives the new boolean state (not a DOM event)"
          },
          {
            "prop": "disabled",
            "type": "`boolean`",
            "default": "false",
            "description": "Disable"
          },
          {
            "prop": "size",
            "type": "`string`",
            "default": "\"md\"",
            "description": "`sm`, `md`, `lg`"
          },
          {
            "prop": "name",
            "type": "`string`",
            "default": "",
            "description": "Form name"
          },
          {
            "prop": "topLabel",
            "type": "`string`",
            "default": "",
            "description": "Label above"
          },
          {
            "prop": "bottomLabel",
            "type": "`string`",
            "default": "",
            "description": "Label below"
          },
          {
            "prop": "leftLabel",
            "type": "`string`",
            "default": "",
            "description": "Label left"
          },
          {
            "prop": "rightLabel",
            "type": "`string`",
            "default": "",
            "description": "Label right"
          }
        ],
        "examples": "```jsx\n<Switch checked={enabled} onChange={checked => setEnabled(checked)} />\n<Switch defaultChecked rightLabel=\"Enable notifications\" />\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Tabs",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Tabbed content with list and panels. Use subcomponents: `Tabs.List`, `Tabs.Tab`, `Tabs.Panels`, `Tabs.Panel`. Supports controlled (`index` + `onChange`) or uncontrolled (`defaultIndex`), keyboard navigation, and variants.",
        "props": [
          {
            "prop": "children",
            "type": "`ReactNode`",
            "default": "",
            "description": "Must include `Tabs.List` and `Tabs.Panels`."
          },
          {
            "prop": "defaultIndex",
            "type": "`number`",
            "default": "0",
            "description": "Uncontrolled initial active tab index."
          },
          {
            "prop": "index",
            "type": "`number`",
            "default": "",
            "description": "Controlled active index."
          },
          {
            "prop": "onChange",
            "type": "`(index: number) => void`",
            "default": "",
            "description": "Called when tab changes."
          },
          {
            "prop": "orientation",
            "type": "`\"horizontal\"` ",
            "default": "\"vertical\"",
            "description": "`\"horizontal\"`"
          },
          {
            "prop": "size",
            "type": "`\"sm\"` ",
            "default": "\"md\" \\",
            "description": "`\"lg\"`"
          },
          {
            "prop": "variant",
            "type": "`\"line\"` ",
            "default": "\"pills\" \\",
            "description": "`\"unstyled\"`"
          },
          {
            "prop": "animated",
            "type": "`boolean`",
            "default": "true",
            "description": "Fade animation on panel change."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "\"\"",
            "description": "Wrapper CSS classes."
          }
        ],
        "examples": ""
      },
      {
        "name": "ThreeDotPopover",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Dropdown menu triggered by a three-dot (kebab) button. Use for row actions (Edit, Delete, etc.). Closes on outside click and Escape; optional close on item select.",
        "props": [
          {
            "prop": "items",
            "type": "`Array`",
            "default": "[]",
            "description": "Menu items: `{ key, label, icon?, onClick?, disabled?, destructive? }`. `icon` can be component (e.g. `Edit2`)."
          },
          {
            "prop": "trigger",
            "type": "`ReactNode`",
            "default": "",
            "description": "Custom trigger; default is three-dot button."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "\"\"",
            "description": "CSS classes for the **default** trigger button (merged via `cn()`)."
          },
          {
            "prop": "wrapperClassName",
            "type": "`string`",
            "default": "\"\"",
            "description": "CSS classes merged (via `cn()`) onto the root container element."
          },
          {
            "prop": "menuClass",
            "type": "`string`",
            "default": "\"\"",
            "description": "Menu container CSS classes."
          },
          {
            "prop": "menuItemClass",
            "type": "`string`",
            "default": "\"\"",
            "description": "Each menu item CSS classes."
          },
          {
            "prop": "closeOnSelect",
            "type": "`boolean`",
            "default": "true",
            "description": "Close menu when an item is selected."
          },
          {
            "prop": "ariaLabel",
            "type": "`string`",
            "default": "\"More options\"",
            "description": "Trigger button aria-label."
          }
        ],
        "examples": "```jsx\nimport { Edit2, Eye, Trash } from 'lucide-react';\n\n<ThreeDotPopover\n  items={[\n    { key: 'edit', label: 'Edit', icon: Edit2, onClick: () => edit(row) },\n    { key: 'view', label: 'View', icon: Eye, onClick: () => view(row) },\n    { key: 'delete', label: 'Delete', destructive: true, onClick: () => remove(row) },\n  ]}\n  closeOnSelect\n/>\n```"
      },
      {
        "name": "Tooltip",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Tooltip shown on hover, focus, or click. Supports placement (auto/top/bottom/left/right), delay, offset, and optional portal. Content can be string or render prop `({ close }) => ReactNode`.",
        "props": [
          {
            "prop": "position",
            "type": "`\"auto\"` ",
            "default": "\"top\" \\",
            "description": "`\"bottom\"` \\"
          },
          {
            "prop": "trigger",
            "type": "`\"hover\"` ",
            "default": "\"click\" \\",
            "description": "`\"focus\"` \\"
          },
          {
            "prop": "content",
            "type": "`ReactNode` ",
            "default": "({ close }) => ReactNode",
            "description": "—"
          },
          {
            "prop": "customTrigger",
            "type": "`ReactElement`",
            "default": "",
            "description": "Use instead of children as trigger."
          },
          {
            "prop": "children",
            "type": "`ReactNode`",
            "default": "",
            "description": "Trigger element when customTrigger not used."
          },
          {
            "prop": "open",
            "type": "`boolean`",
            "default": "",
            "description": "Controlled open state."
          },
          {
            "prop": "defaultOpen",
            "type": "`boolean`",
            "default": "false",
            "description": "Uncontrolled initial open."
          },
          {
            "prop": "onChange",
            "type": "`(open: boolean) => void`",
            "default": "",
            "description": "Called when open state changes."
          },
          {
            "prop": "delay",
            "type": "`number`",
            "default": "80",
            "description": "Delay in ms before opening (hover)."
          },
          {
            "prop": "offset",
            "type": "`number`",
            "default": "8",
            "description": "Spacing in px between trigger and tooltip."
          },
          {
            "prop": "textColor",
            "type": "`string` (hex)",
            "default": "",
            "description": "Tooltip text color."
          },
          {
            "prop": "bgColor",
            "type": "`string` (hex)",
            "default": "\"#ffffff\"",
            "description": "Tooltip background color."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "\"\"",
            "description": "Tooltip box CSS classes."
          },
          {
            "prop": "portal",
            "type": "`boolean`",
            "default": "true",
            "description": "Render tooltip in document.body."
          },
          {
            "prop": "id",
            "type": "`string`",
            "default": "",
            "description": "Tooltip id (auto-generated if omitted)."
          }
        ],
        "examples": "```jsx\n<Tooltip content=\"Save your changes\">\n  <Button>Save</Button>\n</Tooltip>\n\n<Tooltip trigger=\"click\" content={({ close }) => <span>Click to close <button onClick={close}>OK</button></span>}>\n  <span>Click me</span>\n</Tooltip>\n\n<Tooltip position=\"bottom\" delay={200} content=\"Delayed tip\">\n  <Input placeholder=\"Focus me\" />\n</Tooltip>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "DatePicker",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Single date picker with calendar popup. Accepts `Date` or ISO date string; supports min/max, clear button, and optional portal rendering.",
        "props": [
          {
            "prop": "value",
            "type": "`Date` ",
            "default": "string",
            "description": "—"
          },
          {
            "prop": "onChange",
            "type": "`(date: Date ",
            "default": "null) => void",
            "description": "—"
          },
          {
            "prop": "placeholder",
            "type": "`string`",
            "default": "\"Select date...\"",
            "description": "Input placeholder."
          },
          {
            "prop": "label",
            "type": "`string`",
            "default": "",
            "description": "Label text."
          },
          {
            "prop": "error",
            "type": "`string`",
            "default": "",
            "description": "Error message."
          },
          {
            "prop": "disabled",
            "type": "`boolean`",
            "default": "",
            "description": "Disable the picker."
          },
          {
            "prop": "required",
            "type": "`boolean`",
            "default": "",
            "description": "Required field."
          },
          {
            "prop": "minDate",
            "type": "`Date`",
            "default": "",
            "description": "Minimum selectable date."
          },
          {
            "prop": "maxDate",
            "type": "`Date`",
            "default": "",
            "description": "Maximum selectable date."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Wrapper CSS classes."
          },
          {
            "prop": "weekStartsOn",
            "type": "`0` ",
            "default": "1",
            "description": "`0`"
          },
          {
            "prop": "portal",
            "type": "`boolean`",
            "default": "false",
            "description": "Render calendar in `document.body`."
          },
          {
            "prop": "displayFormat",
            "type": "`string`",
            "default": "\"MMM dd, yyyy\"",
            "description": "date-fns format for display."
          },
          {
            "prop": "locale",
            "type": "`Locale`",
            "default": "",
            "description": "date-fns locale."
          },
          {
            "prop": "showClear",
            "type": "`boolean`",
            "default": "true",
            "description": "Show clear button."
          },
          {
            "prop": "closeOnSelect",
            "type": "`boolean`",
            "default": "true",
            "description": "Close popup on date select."
          }
        ],
        "examples": "```jsx\nconst [date, setDate] = useState(null);\n<DatePicker\n  value={date}\n  onChange={setDate}\n  placeholder=\"Select date\"\n  minDate={new Date()}\n  label=\"Start date\"\n/>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "LocationPicker",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Input for latitude/longitude. User can type `lat, lng` (e.g. `12.34, 56.78`) or click the icon to use browser geolocation. Value is `{ lat, lng }` or `null`.",
        "props": [
          {
            "prop": "value",
            "type": "`{ lat: number, lng: number }` ",
            "default": "null",
            "description": "`null`"
          },
          {
            "prop": "onChange",
            "type": "`(coords: { lat, lng } ",
            "default": "null) => void",
            "description": "—"
          },
          {
            "prop": "inputProps",
            "type": "`object`",
            "default": "{}",
            "description": "Props spread to the underlying input (e.g. `placeholder`). A supplied `inputProps.onChange` is forwarded **in addition to** (not instead of) the component's coord-parsing handler — both fire. `inputProps.className` is merged via `cn()`."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Classes merged (via `cn()`) onto the root wrapper."
          },
          {
            "prop": "icon",
            "type": "`ReactNode`",
            "default": "default pin SVG",
            "description": "Icon for \"use my location\" button."
          },
          {
            "prop": "iconProps",
            "type": "`object`",
            "default": "{}",
            "description": "Props for the icon button (e.g. `className`, `onClick`)."
          },
          {
            "prop": "iconPosition",
            "type": "`\"left\"` ",
            "default": "\"right\"",
            "description": "`\"right\"`"
          },
          {
            "prop": "placeholder",
            "type": "`string`",
            "default": "\"lat, lng\"",
            "description": "Input placeholder."
          }
        ],
        "examples": "```jsx\nconst [location, setLocation] = useState(null);\n<LocationPicker\n  value={location}\n  onChange={setLocation}\n  placeholder=\"Enter lat, lng or use location\"\n/>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "SpeechToText",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Voice-to-text using the Web Speech API. Headless by default — render a custom control via `renderButton`, or drive it imperatively through the ref. The built-in fallback button is `className`-extensible and forwards arbitrary props.",
        "props": [
          {
            "prop": "lang",
            "type": "`string`",
            "default": "\"enUS\"",
            "description": "Recognition language"
          },
          {
            "prop": "continuous",
            "type": "`boolean`",
            "default": "true",
            "description": "Keep listening until stopped (forced `false` on mobile)"
          },
          {
            "prop": "interimResults",
            "type": "`boolean`",
            "default": "true",
            "description": "Return interim results"
          },
          {
            "prop": "onSpeechComplete",
            "type": "`function`",
            "default": "",
            "description": "Final transcript chunk callback `(text) => void`"
          },
          {
            "prop": "onSpeaking",
            "type": "`function`",
            "default": "",
            "description": "Interim transcript callback `(text) => void`"
          },
          {
            "prop": "onError",
            "type": "`function`",
            "default": "",
            "description": "Fatal error callback `(Error) => void`. Routine events (`no-speech`, `aborted`) are **not** surfaced"
          },
          {
            "prop": "onStart",
            "type": "`function`",
            "default": "",
            "description": "Start callback"
          },
          {
            "prop": "onStop",
            "type": "`function`",
            "default": "",
            "description": "Stop callback"
          },
          {
            "prop": "renderButton",
            "type": "`function`",
            "default": "",
            "description": "Custom control render-prop (see signature below)"
          },
          {
            "prop": "autoStart",
            "type": "`boolean`",
            "default": "false",
            "description": "Start on mount (once, after support is detected)"
          },
          {
            "prop": "disabled",
            "type": "`boolean`",
            "default": "false",
            "description": "Disable"
          },
          {
            "prop": "resetOnStart",
            "type": "`boolean`",
            "default": "false",
            "description": "Clear the accumulated transcript when a new session starts"
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Merged (via `cn`) onto the default button"
          },
          {
            "prop": "...rest",
            "type": "—",
            "default": "",
            "description": "Forwarded to the default `<button>`"
          }
        ],
        "examples": "```jsx\nconst [transcript, setTranscript] = useState('');\n<SpeechToText\n  onSpeechComplete={(chunk) => setTranscript((t) => `${t} ${chunk}`.trim())}\n  onError={(e) => console.error(e)}\n/>\n<div>Transcript: {transcript}</div>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "TextToSpeech",
        "group": "core",
        "familyExports": [],
        "hasDoc": true,
        "description": "Text-to-speech using the browser’s Speech Synthesis API. Renders a default \"Speak\" / \"Stop\" button or a custom button via `renderButton`. Toggling speak while playing stops playback.",
        "props": [
          {
            "prop": "text",
            "type": "`string`",
            "default": "\"\"",
            "description": "Text to speak (used as initial input if component manages input)."
          },
          {
            "prop": "rate",
            "type": "`number`",
            "default": "1",
            "description": "Speech rate (0.1–10)."
          },
          {
            "prop": "pitch",
            "type": "`number`",
            "default": "0.5",
            "description": "Pitch (0–2)."
          },
          {
            "prop": "onSpeak",
            "type": "`(text: string) => void`",
            "default": "() => {}",
            "description": "Called when speech starts (with the text spoken)."
          },
          {
            "prop": "renderButton",
            "type": "`(props: { onClick, isSpeaking }) => ReactNode`",
            "default": "",
            "description": "Custom button; receives `onClick` and `isSpeaking`."
          }
        ],
        "examples": "```jsx\n<TextToSpeech text=\"Hello, world!\" rate={1} onSpeak={(t) => console.log('Speaking:', t)} />\n\n<TextToSpeech\n  text={content}\n  renderButton={({ onClick, isSpeaking }) => (\n    <Button onClick={onClick}>{isSpeaking ? 'Stop' : 'Play'} audio</Button>\n  )}\n/>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Sidebar",
        "group": "navigation",
        "familyExports": [],
        "hasDoc": true,
        "description": "Collapsible side navigation with optional nested items, logo, and user block. Supports desktop collapsed state and mobile drawer. Tooltips show when collapsed; optional `drawerPosition` for mobile.",
        "props": [
          {
            "prop": "items",
            "type": "`Array`",
            "default": "[]",
            "description": "Nav items: `{ id, label, icon, children?, onClick?, active? }`. `children` = nested items."
          },
          {
            "prop": "collapsed",
            "type": "`boolean`",
            "default": "false",
            "description": "Desktop collapsed state (icon-only)."
          },
          {
            "prop": "onToggle",
            "type": "`() => void`",
            "default": "",
            "description": "Toggle collapse (e.g. chevron click)."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Wrapper CSS classes."
          },
          {
            "prop": "logo",
            "type": "`ReactNode`",
            "default": "",
            "description": "Logo at top."
          },
          {
            "prop": "user",
            "type": "`object` ",
            "default": "ReactNode",
            "description": "—"
          },
          {
            "prop": "onUserClick",
            "type": "`function`",
            "default": "",
            "description": "User block click."
          },
          {
            "prop": "drawerPosition",
            "type": "`\"left\"` ",
            "default": "\"right\"",
            "description": "`\"left\"`"
          },
          {
            "prop": "isMobileOpen",
            "type": "`boolean`",
            "default": "",
            "description": "Controlled mobile open."
          },
          {
            "prop": "setIsMobileOpen",
            "type": "`(open: boolean) => void`",
            "default": "",
            "description": "Set mobile open (when controlled)."
          },
          {
            "prop": "showCollapsedTooltips",
            "type": "`boolean`",
            "default": "true",
            "description": "Show tooltips when collapsed."
          },
          {
            "prop": "tooltipOptions",
            "type": "`object`",
            "default": "",
            "description": "Options for internal Tooltip."
          }
        ],
        "examples": "```jsx\nconst [collapsed, setCollapsed] = useState(false);\n<Sidebar\n  items={[\n    { id: 'dash', label: 'Dashboard', icon: <Home /> },\n    { id: 'settings', label: 'Settings', icon: <Settings />, children: [\n      { id: 'profile', label: 'Profile' },\n      { id: 'security', label: 'Security' },\n    ]},\n  ]}\n  collapsed={collapsed}\n  onToggle={() => setCollapsed(!collapsed)}\n  logo={<Logo />}\n  user={{ name: 'Jane', avatar: '/jane.jpg' }}\n/>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Navbar",
        "group": "navigation",
        "familyExports": [],
        "hasDoc": true,
        "description": "Top navigation bar with logo, nav items (links or buttons), optional search, notifications dropdown, and login/logout. Uses an **emitter** for notification actions (view, markAsRead, markAsUnread, clearAll, delete). Responsive: left icon and hamburger on mobile; desktop nav and search. You can replace the right area with a custom component via `rightMenuContent`.",
        "props": [
          {
            "prop": "emitter",
            "type": "`object`",
            "default": "**required**",
            "description": "Event emitter for notifications (e.g. `notification:view`, `notification:markAsRead`, etc.)."
          },
          {
            "prop": "logo",
            "type": "`ReactNode`",
            "default": "",
            "description": "Logo (e.g. image or link)."
          },
          {
            "prop": "items",
            "type": "`Array`",
            "default": "[]",
            "description": "Nav items: `{ id, label, href?, active?, onClick?(item) }`. If `href` is set, renders `<a>`; else `<button>` with `onClick`."
          },
          {
            "prop": "user",
            "type": "`object` ",
            "default": "null",
            "description": "—"
          },
          {
            "prop": "notifications",
            "type": "`Array`",
            "default": "[]",
            "description": "List of notifications for the dropdown. Each: `{ id, title, message?, read? }`."
          },
          {
            "prop": "searchable",
            "type": "`boolean`",
            "default": "false",
            "description": "Show search input (desktop)."
          },
          {
            "prop": "onSearch",
            "type": "`(term: string) => void`",
            "default": "",
            "description": "Called on search form submit with current search term."
          },
          {
            "prop": "leftIcon",
            "type": "`ReactNode` ",
            "default": "false",
            "description": "`<ChevronLeft />`"
          },
          {
            "prop": "onLeftIconClick",
            "type": "`() => void`",
            "default": "",
            "description": "Called when left icon (mobile) is clicked."
          },
          {
            "prop": "rightMenuContent",
            "type": "`(props) => ReactNode`",
            "default": "",
            "description": "Custom right menu. Receives `{ notifications }` and any Navbar `...props` (e.g. `emitter`, `onFetch`). If not provided, default renders notifications dropdown."
          },
          {
            "prop": "onLoginClick",
            "type": "`() => void`",
            "default": "",
            "description": "Called when login button is clicked."
          },
          {
            "prop": "onLogoutClick",
            "type": "`() => void`",
            "default": "",
            "description": "Called when logout button is clicked."
          },
          {
            "prop": "onFetch",
            "type": "`({ setNotifications }) => void`",
            "default": "",
            "description": "Refresh handler for the default notifications dropdown. Called on mount and when `notifications` changes. Consumed by the right menu — it is **not** forwarded onto `<nav>`."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Wrapper CSS classes."
          },
          {
            "prop": "...rest",
            "type": "—",
            "default": "",
            "description": "Only DOM-valid attributes (e.g. `id`, `aria-*`, `data-*`, event handlers) are forwarded to the root `<nav>`. The component's own control props (`isMobileOpen`, `setIsMobileOpen`, `onFetch`, …) are consumed and never leak to the DOM."
          }
        ],
        "examples": "```jsx\nimport { Navbar } from '@dreamtree-org/twreact-ui';\nimport MyEmitter from './emitter';\n\n<Navbar\n  emitter={MyEmitter}\n  logo={<a href=\"/\"><img src=\"/logo.svg\" alt=\"Home\" /></a>}\n  items={[\n    { id: '1', label: 'Home', href: '/', active: pathname === '/' },\n    { id: '2', label: 'About', href: '/about' },\n    { id: '3', label: 'Settings', onClick: () => openSettings() },\n  ]}\n  user={user}\n  notifications={notifications}\n  searchable\n  onSearch={(term) => doSearch(term)}\n  onLoginClick={() => navigate('/login')}\n  onLogoutClick={logout}\n  onFetch={async ({ setNotifications }) => {\n    const res = await fetch('/api/notifications');\n    const data = await res.json();\n    setNotifications(data.items);\n  }}\n/>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "FootNav",
        "group": "navigation",
        "familyExports": [],
        "hasDoc": true,
        "description": "Fixed bottom navigation for mobile (hidden on `md` and up via `md:hidden`). Renders a row of items with icon and label; optional badge per item. Items support `onClick`.",
        "props": [
          {
            "prop": "items",
            "type": "`Array`",
            "default": "[]",
            "description": "Each item: `{ id, label, icon, onClick?, active?, badge? }`."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Nav wrapper CSS classes."
          },
          {
            "prop": "...rest",
            "type": "—",
            "default": "",
            "description": "Passed to `<nav>`."
          }
        ],
        "examples": "```jsx\n<FootNav\n  items={[\n    { id: 'home', label: 'Home', icon: <Home />, onClick: () => navigate('/'), active: path === '/' },\n    { id: 'search', label: 'Search', icon: <Search />, onClick: () => openSearch() },\n    { id: 'notifications', label: 'Alerts', icon: <Bell />, badge: 3, onClick: () => openNotifications() },\n    { id: 'profile', label: 'Profile', icon: <User />, onClick: () => navigate('/profile') },\n  ]}\n/>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Breadcrumbs",
        "group": "navigation",
        "familyExports": [],
        "hasDoc": true,
        "description": "Breadcrumb navigation trail. Optional home link and custom separator.",
        "props": [
          {
            "prop": "items",
            "type": "`Array`",
            "default": "[]",
            "description": "`[{ id, label, href?, onClick? }]`"
          },
          {
            "prop": "separator",
            "type": "`ReactNode`",
            "default": "<ChevronRight />",
            "description": "Separator between items"
          },
          {
            "prop": "showHome",
            "type": "`boolean`",
            "default": "true",
            "description": "Prepend Home link"
          },
          {
            "prop": "homeIcon",
            "type": "`ReactNode`",
            "default": "",
            "description": "Icon for Home"
          },
          {
            "prop": "onHomeClick",
            "type": "`function`",
            "default": "",
            "description": "Home click handler"
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Extra CSS classes"
          }
        ],
        "examples": "```jsx\n<Breadcrumbs\n  items={[\n    { id: '1', label: 'Products', href: '/products' },\n    { id: '2', label: 'Category', href: '/products/cat' },\n    { id: '3', label: 'Current Page' },\n  ]}\n  showHome\n/>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Dialog",
        "group": "feedback",
        "familyExports": [],
        "hasDoc": true,
        "description": "Modal dialog with title, body, optional footer, and configurable size. Supports escape key and backdrop click to close when dismissible.",
        "props": [
          {
            "prop": "isOpen",
            "type": "`boolean`",
            "default": "",
            "description": "Controls visibility"
          },
          {
            "prop": "onClose",
            "type": "`function`",
            "default": "",
            "description": "Called when dialog should close"
          },
          {
            "prop": "title",
            "type": "`string`",
            "default": "",
            "description": "Dialog title"
          },
          {
            "prop": "children",
            "type": "`ReactNode`",
            "default": "",
            "description": "Body content"
          },
          {
            "prop": "size",
            "type": "`string`",
            "default": "\"md\"",
            "description": "`sm`, `md`, `lg`, `xl`, `full`"
          },
          {
            "prop": "dismissible",
            "type": "`boolean`",
            "default": "true",
            "description": "Allow close via backdrop or Escape"
          },
          {
            "prop": "showCloseButton",
            "type": "`boolean`",
            "default": "true",
            "description": "Show X button"
          },
          {
            "prop": "footer",
            "type": "`ReactNode`",
            "default": "",
            "description": "Footer content (e.g. buttons)"
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Extra CSS classes"
          },
          {
            "prop": "onOpen",
            "type": "`function`",
            "default": "",
            "description": "Called when dialog opens (e.g. with dialogRef)"
          }
        ],
        "examples": "### Basic\n\n```jsx\nconst [open, setOpen] = useState(false);\n\n<Button onClick={() => setOpen(true)}>Open</Button>\n<Dialog\n  isOpen={open}\n  onClose={() => setOpen(false)}\n  title=\"Confirm\"\n>\n  Are you sure you want to continue?\n</Dialog>\n```\n\n### With footer\n\n```jsx\n<Dialog\n  isOpen={open}\n  onClose={() => setOpen(false)}\n  title=\"Edit\"\n  footer={\n    <>\n      <Button variant=\"ghost\" onClick={() => setOpen(false)}>Cancel</Button>\n      <Button onClick={handleSave}>Save</Button>\n    </>\n  }\n>\n  <Input label=\"Name\" value={name} onChange={e => setName(e.target.value)} />\n</Dialog>\n```"
      },
      {
        "name": "Toast",
        "group": "feedback",
        "familyExports": [
          "ToastContainer",
          "useToast"
        ],
        "hasDoc": true,
        "description": "Toast notification component and container. Use with `ToastContainer` and optional `useToast` (or your own state) to show temporary messages.",
        "props": [
          {
            "prop": "id",
            "type": "`string`",
            "default": "",
            "description": "Unique id (for key/onClose)"
          },
          {
            "prop": "title",
            "type": "`string`",
            "default": "",
            "description": "Toast title"
          },
          {
            "prop": "message",
            "type": "`string`",
            "default": "",
            "description": "Toast message"
          },
          {
            "prop": "type",
            "type": "`string`",
            "default": "\"info\"",
            "description": "`success`, `error`, `warning`, `info`"
          },
          {
            "prop": "duration",
            "type": "`number`",
            "default": "5000",
            "description": "Auto-close ms (0 = no auto-close)"
          },
          {
            "prop": "onClose",
            "type": "`function`",
            "default": "",
            "description": "Called when toast closes"
          },
          {
            "prop": "position",
            "type": "`string`",
            "default": "\"topright\"",
            "description": "Position key for styling"
          }
        ],
        "examples": "```jsx\nfunction App() {\n  const [toasts, setToasts] = useState([]);\n  const addToast = (toast) => setToasts((prev) => [...prev, { ...toast, id: Date.now() }]);\n  const removeToast = (id) => setToasts((prev) => prev.filter((t) => t.id !== id));\n\n  return (\n    <>\n      <Button onClick={() => addToast({ title: 'Done', message: 'Saved.', type: 'success' })}>\n        Show toast\n      </Button>\n      <ToastContainer toasts={toasts} onRemove={removeToast} position=\"top-right\" />\n    </>\n  );\n}\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Alert",
        "group": "feedback",
        "familyExports": [],
        "hasDoc": true,
        "description": "Inline alert box for success, error, warning, or info messages. Optional title and dismiss button.",
        "props": [
          {
            "prop": "variant",
            "type": "`string`",
            "default": "\"info\"",
            "description": "`success`, `error`, `warning`, `info`"
          },
          {
            "prop": "title",
            "type": "`string`",
            "default": "",
            "description": "Optional title"
          },
          {
            "prop": "children",
            "type": "`ReactNode`",
            "default": "",
            "description": "Alert body content"
          },
          {
            "prop": "dismissible",
            "type": "`boolean`",
            "default": "false",
            "description": "Show close button"
          },
          {
            "prop": "onDismiss",
            "type": "`function`",
            "default": "",
            "description": "Called when dismissed"
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Extra CSS classes"
          }
        ],
        "examples": "```jsx\n<Alert variant=\"info\" title=\"Note\">Your session will expire in 5 minutes.</Alert>\n<Alert variant=\"success\">Saved successfully.</Alert>\n<Alert variant=\"error\" title=\"Error\">Something went wrong.</Alert>\n<Alert variant=\"warning\" dismissible onDismiss={() => {}}>\n  Please review your input.\n</Alert>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Badge",
        "group": "utility",
        "familyExports": [],
        "hasDoc": true,
        "description": "Badge or pill for counts, labels, and status.",
        "props": [
          {
            "prop": "variant",
            "type": "`string`",
            "default": "\"default\"",
            "description": "`default`, `primary`, `secondary`, `success`, `warning`, `error`, `outline`"
          },
          {
            "prop": "size",
            "type": "`string`",
            "default": "\"md\"",
            "description": "`sm`, `md`, `lg`"
          },
          {
            "prop": "rounded",
            "type": "`boolean`",
            "default": "true",
            "description": "Rounded pill when true"
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Extra CSS classes"
          },
          {
            "prop": "children",
            "type": "`ReactNode`",
            "default": "",
            "description": "Badge content"
          }
        ],
        "examples": "```jsx\n<Badge>New</Badge>\n<Badge variant=\"success\">Active</Badge>\n<Badge variant=\"error\" size=\"sm\">3</Badge>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Avatar",
        "group": "utility",
        "familyExports": [],
        "hasDoc": true,
        "description": "User avatar: image or initials fallback. Optional status indicator.",
        "props": [
          {
            "prop": "src",
            "type": "`string`",
            "default": "",
            "description": "Image URL"
          },
          {
            "prop": "alt",
            "type": "`string`",
            "default": "",
            "description": "Image alt"
          },
          {
            "prop": "name",
            "type": "`string`",
            "default": "",
            "description": "Used for initials when no src"
          },
          {
            "prop": "size",
            "type": "`string`",
            "default": "\"md\"",
            "description": "`xs`, `sm`, `md`, `lg`, `xl`, `2xl`"
          },
          {
            "prop": "shape",
            "type": "`string`",
            "default": "\"circle\"",
            "description": "`circle`, `rounded`, `square`"
          },
          {
            "prop": "status",
            "type": "`string`",
            "default": "",
            "description": "`online`, `offline`, `away`, `busy`"
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Extra CSS classes"
          }
        ],
        "examples": "```jsx\n<Avatar name=\"Alice Smith\" />\n<Avatar src=\"/photo.jpg\" alt=\"User\" />\n<Avatar name=\"Bob\" status=\"online\" size=\"lg\" />\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Card",
        "group": "utility",
        "familyExports": [],
        "hasDoc": true,
        "description": "Card container with optional hover shadow. Subcomponents: `Card.Header`, `Card.Title`, `Card.Description`, `Card.Content`, `Card.Footer` for structure.",
        "props": [
          {
            "prop": "children",
            "type": "`ReactNode`",
            "default": "",
            "description": "Card content."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Wrapper CSS classes."
          },
          {
            "prop": "hover",
            "type": "`boolean`",
            "default": "false",
            "description": "If true, add hover:shadow-md transition."
          },
          {
            "prop": "...rest",
            "type": "—",
            "default": "",
            "description": "Passed to root `<div>`."
          }
        ],
        "examples": "```jsx\n<Card hover>\n  <Card.Header>\n    <Card.Title>Card title</Card.Title>\n    <Card.Description>Optional description text.</Card.Description>\n  </Card.Header>\n  <Card.Content>\n    Main content here.\n  </Card.Content>\n  <Card.Footer>\n    <Button>Action</Button>\n  </Card.Footer>\n</Card>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Pagination",
        "group": "utility",
        "familyExports": [],
        "hasDoc": true,
        "description": "Page navigation: first, previous, page numbers, next, last. Renders only when `totalPages > 1`. Optional `theme` for styling (e.g. from Table).",
        "props": [
          {
            "prop": "currentPage",
            "type": "`number`",
            "default": "1",
            "description": "Current page (1-based)."
          },
          {
            "prop": "totalPages",
            "type": "`number`",
            "default": "1",
            "description": "Total pages. If ≤ 1, component returns null."
          },
          {
            "prop": "onPageChange",
            "type": "`(page: number) => void`",
            "default": "",
            "description": "Called when user selects a page."
          },
          {
            "prop": "showFirstLast",
            "type": "`boolean`",
            "default": "true",
            "description": "Show first/last page buttons."
          },
          {
            "prop": "showPrevNext",
            "type": "`boolean`",
            "default": "true",
            "description": "Show previous/next buttons."
          },
          {
            "prop": "maxVisiblePages",
            "type": "`number`",
            "default": "5",
            "description": "Max page number buttons to show."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Nav wrapper CSS classes."
          },
          {
            "prop": "...rest",
            "type": "—",
            "default": "",
            "description": "Passed to `<nav>`."
          }
        ],
        "examples": "```jsx\n<Pagination\n  currentPage={page}\n  totalPages={Math.ceil(total / pageSize)}\n  onPageChange={setPage}\n  maxVisiblePages={5}\n/>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Stepper",
        "group": "utility",
        "familyExports": [],
        "hasDoc": true,
        "description": "Horizontal or vertical step indicator. Each step has circle (with check for completed), optional line, and label. Optional `onStepClick` for clickable steps.",
        "props": [
          {
            "prop": "steps",
            "type": "`Array`",
            "default": "[]",
            "description": "Each step: `{ id?, label?, description? }`."
          },
          {
            "prop": "currentStep",
            "type": "`number`",
            "default": "0",
            "description": "Zero-based index of current step."
          },
          {
            "prop": "orientation",
            "type": "`\"horizontal\"` ",
            "default": "\"vertical\"",
            "description": "`\"horizontal\"`"
          },
          {
            "prop": "variant",
            "type": "`string`",
            "default": "\"default\"",
            "description": "Visual variant."
          },
          {
            "prop": "onStepClick",
            "type": "`(step, stepIndex) => void`",
            "default": "",
            "description": "Called when a step is clicked (e.g. for completed/current)."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Nav wrapper CSS classes."
          },
          {
            "prop": "...rest",
            "type": "—",
            "default": "",
            "description": "Passed to `<nav>`."
          }
        ],
        "examples": "```jsx\n<Stepper\n  steps={[\n    { id: '1', label: 'Details' },\n    { id: '2', label: 'Payment' },\n    { id: '3', label: 'Confirm' },\n  ]}\n  currentStep={1}\n  orientation=\"horizontal\"\n  onStepClick={(step, idx) => setStep(idx)}\n/>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "FileUpload",
        "group": "utility",
        "familyExports": [],
        "hasDoc": true,
        "description": "File upload zone: drag-and-drop or click to open file dialog. Supports single/multiple, `accept`, `maxSize` validation, and list of selected files with remove. Calls `onFileSelect` with valid files and `onFileRemove` with index.",
        "props": [
          {
            "prop": "accept",
            "type": "`string`",
            "default": "",
            "description": "Input accept (e.g. `\"image/*\"`, `\".pdf\"`)."
          },
          {
            "prop": "multiple",
            "type": "`boolean`",
            "default": "false",
            "description": "Allow multiple files."
          },
          {
            "prop": "maxSize",
            "type": "`number`",
            "default": "",
            "description": "Max file size in bytes; larger files trigger error and are not added."
          },
          {
            "prop": "onFileSelect",
            "type": "`(files: File[]) => void`",
            "default": "",
            "description": "Called with valid selected/dropped files."
          },
          {
            "prop": "onFileRemove",
            "type": "`(fileIndex: number) => void`",
            "default": "",
            "description": "Called when user removes a file from the list."
          },
          {
            "prop": "files",
            "type": "`File[]`",
            "default": "[]",
            "description": "List of files to display (e.g. controlled from parent)."
          },
          {
            "prop": "disabled",
            "type": "`boolean`",
            "default": "false",
            "description": "Disable the zone and remove buttons."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Wrapper CSS classes."
          },
          {
            "prop": "...rest",
            "type": "—",
            "default": "",
            "description": "Passed to wrapper div."
          }
        ],
        "examples": "```jsx\nconst [files, setFiles] = useState([]);\n<FileUpload\n  accept=\"image/*\"\n  multiple\n  maxSize={5 * 1024 * 1024}\n  files={files}\n  onFileSelect={(newFiles) => setFiles(prev => [...prev, ...newFiles])}\n  onFileRemove={(index) => setFiles(prev => prev.filter((_, i) => i !== index))}\n/>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Condition",
        "group": "utility",
        "familyExports": [],
        "hasDoc": true,
        "description": "Renders `children` when a condition is true, otherwise renders `fallback`. Simple conditional wrapper with no extra DOM when not needed.",
        "props": [
          {
            "prop": "condition",
            "type": "`boolean`",
            "default": "",
            "description": "When true, render `children`; when false, render `fallback`."
          },
          {
            "prop": "children",
            "type": "`ReactNode`",
            "default": "",
            "description": "Content when condition is true."
          },
          {
            "prop": "fallback",
            "type": "`ReactNode`",
            "default": "null",
            "description": "Content when condition is false."
          }
        ],
        "examples": "```jsx\n<Condition condition={isLoggedIn}>\n  <Dashboard />\n</Condition>\n\n<Condition condition={loading} fallback={<Loader />}>\n  <Content />\n</Condition>\n\n<Condition condition={hasError} fallback={<Alert variant=\"error\">Error</Alert>}>\n  <Data />\n</Condition>\n```\n\n[← Component overview](README.md)"
      },
      {
        "name": "Carousel",
        "group": "utility",
        "familyExports": [],
        "hasDoc": true,
        "description": "Horizontal carousel of slides. Renders `children` as slides (one per child). Optional auto-play, previous/next buttons (shown on hover), and dot indicators. Pauses auto-play on hover.",
        "props": [
          {
            "prop": "children",
            "type": "`ReactNode`",
            "default": "",
            "description": "Each child is one slide."
          },
          {
            "prop": "autoPlay",
            "type": "`boolean`",
            "default": "false",
            "description": "Auto-advance slides."
          },
          {
            "prop": "interval",
            "type": "`number`",
            "default": "5000",
            "description": "Auto-play interval in ms."
          },
          {
            "prop": "showDots",
            "type": "`boolean`",
            "default": "true",
            "description": "Show dot indicators at bottom."
          },
          {
            "prop": "className",
            "type": "`string`",
            "default": "",
            "description": "Wrapper CSS classes."
          },
          {
            "prop": "itemClassName",
            "type": "`string`",
            "default": "",
            "description": "Each slide wrapper CSS classes."
          }
        ],
        "examples": "```jsx\n<Carousel autoPlay interval={5000} showDots>\n  <div className=\"h-64 bg-gray-100 flex items-center justify-center\">Slide 1</div>\n  <div className=\"h-64 bg-gray-200 flex items-center justify-center\">Slide 2</div>\n  <div className=\"h-64 bg-gray-300 flex items-center justify-center\">Slide 3</div>\n</Carousel>\n```\n\n[← Component overview](README.md)"
      }
    ],
    "hooks": [
      {
        "name": "useTheme",
        "group": "hook",
        "familyExports": [
          "ThemeProvider"
        ],
        "hasDoc": false,
        "description": "",
        "props": [],
        "examples": ""
      },
      {
        "name": "useMixins",
        "group": "hook",
        "familyExports": [],
        "hasDoc": false,
        "description": "",
        "props": [],
        "examples": ""
      },
      {
        "name": "useApi",
        "group": "hook",
        "familyExports": [],
        "hasDoc": false,
        "description": "",
        "props": [],
        "examples": ""
      }
    ],
    "store": [
      {
        "name": "StoreProvider",
        "group": "store",
        "familyExports": [],
        "hasDoc": false,
        "description": "",
        "props": [],
        "examples": ""
      }
    ],
    "utils": [
      {
        "name": "cn",
        "group": "util",
        "familyExports": [],
        "hasDoc": false,
        "description": "",
        "props": [],
        "examples": ""
      },
      {
        "name": "Helpers",
        "group": "util",
        "familyExports": [],
        "hasDoc": false,
        "description": "",
        "props": [],
        "examples": ""
      },
      {
        "name": "Emitter",
        "group": "util",
        "familyExports": [],
        "hasDoc": false,
        "description": "",
        "props": [],
        "examples": ""
      }
    ],
    "groups": [
      "core",
      "feedback",
      "navigation",
      "utility"
    ],
    "counts": {
      "components": 39,
      "hooks": 3,
      "utils": 3,
      "store": 1
    }
  },
  "docs": {
    "Accordion": "# Accordion\n\nExpandable/collapsible content panels. Only one panel open at a time by default, or multiple when `allowMultiple` is true. Supports keyboard navigation (Arrow keys, Home, End, Enter, Space).\n\n## Import\n\n```jsx\nimport { Accordion } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `items` | `Array` | `[]` | Array of `{ id?, title, subtitle?, content, disabled?, leftIcon? }`. `leftIcon` can be ReactNode or `(index, item) => ReactNode`. |\n| `allowMultiple` | `boolean` | `false` | If true, multiple panels can be open at once. |\n| `defaultOpenIndexes` | `number[]` | `[]` | Initial open panel index(es). |\n| `onChange` | `(openIndexes: number[]) => void` | — | Called when open panels change. |\n| `className` | `string` | `\"\"` | Wrapper CSS classes. |\n| `headerClassName` | `string` | `\"\"` | Header button CSS classes. |\n| `contentClassName` | `string` | `\"\"` | Panel content CSS classes. |\n| `chevronPosition` | `\"left\"` \\| `\"right\"` | `\"right\"` | Position of chevron icon. |\n| `chevronIcon` | `ReactNode` | default SVG | Custom chevron icon. |\n| `bordered` | `boolean` | `true` | Whether to show border/background. |\n| `rounded` | `\"none\"` \\| `\"sm\"` \\| `\"md\"` \\| `\"lg\"` \\| `\"xl\"` | `\"md\"` | Border radius of wrapper. |\n| `size` | `\"sm\"` \\| `\"md\"` \\| `\"lg\"` | `\"md\"` | Header and content padding/text size. |\n| `transitionDuration` | `number` | `220` | Max-height transition duration in ms. |\n\n## Example\n\n```jsx\n<Accordion\n  items={[\n    { id: '1', title: 'Section 1', content: <p>Content for section 1</p> },\n    { id: '2', title: 'Section 2', subtitle: 'Optional', content: <p>Content 2</p> },\n    { title: 'Disabled', content: <p>Content</p>, disabled: true },\n  ]}\n  allowMultiple={false}\n  defaultOpenIndexes={[0]}\n  onChange={(indexes) => console.log('Open:', indexes)}\n  size=\"md\"\n  chevronPosition=\"right\"\n/>\n```\n\n[← Component overview](README.md)\n",
    "Alert": "# Alert\n\nInline alert box for success, error, warning, or info messages. Optional title and dismiss button.\n\n## Import\n\n```jsx\nimport { Alert } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `variant` | `string` | `\"info\"` | `success`, `error`, `warning`, `info` |\n| `title` | `string` | — | Optional title |\n| `children` | `ReactNode` | — | Alert body content |\n| `dismissible` | `boolean` | `false` | Show close button |\n| `onDismiss` | `function` | — | Called when dismissed |\n| `className` | `string` | — | Extra CSS classes |\n\n## Examples\n\n```jsx\n<Alert variant=\"info\" title=\"Note\">Your session will expire in 5 minutes.</Alert>\n<Alert variant=\"success\">Saved successfully.</Alert>\n<Alert variant=\"error\" title=\"Error\">Something went wrong.</Alert>\n<Alert variant=\"warning\" dismissible onDismiss={() => {}}>\n  Please review your input.\n</Alert>\n```\n\n[← Component overview](README.md)\n",
    "Avatar": "# Avatar\n\nUser avatar: image or initials fallback. Optional status indicator.\n\n## Import\n\n```jsx\nimport { Avatar } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `src` | `string` | — | Image URL |\n| `alt` | `string` | — | Image alt |\n| `name` | `string` | — | Used for initials when no src |\n| `size` | `string` | `\"md\"` | `xs`, `sm`, `md`, `lg`, `xl`, `2xl` |\n| `shape` | `string` | `\"circle\"` | `circle`, `rounded`, `square` |\n| `status` | `string` | — | `online`, `offline`, `away`, `busy` |\n| `className` | `string` | — | Extra CSS classes |\n\n## Example\n\n```jsx\n<Avatar name=\"Alice Smith\" />\n<Avatar src=\"/photo.jpg\" alt=\"User\" />\n<Avatar name=\"Bob\" status=\"online\" size=\"lg\" />\n```\n\n[← Component overview](README.md)\n",
    "Badge": "# Badge\n\nBadge or pill for counts, labels, and status.\n\n## Import\n\n```jsx\nimport { Badge } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `variant` | `string` | `\"default\"` | `default`, `primary`, `secondary`, `success`, `warning`, `error`, `outline` |\n| `size` | `string` | `\"md\"` | `sm`, `md`, `lg` |\n| `rounded` | `boolean` | `true` | Rounded pill when true |\n| `className` | `string` | — | Extra CSS classes |\n| `children` | `ReactNode` | — | Badge content |\n\n## Example\n\n```jsx\n<Badge>New</Badge>\n<Badge variant=\"success\">Active</Badge>\n<Badge variant=\"error\" size=\"sm\">3</Badge>\n```\n\n[← Component overview](README.md)\n",
    "Breadcrumbs": "# Breadcrumbs\n\nBreadcrumb navigation trail. Optional home link and custom separator.\n\n## Import\n\n```jsx\nimport { Breadcrumbs } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `items` | `Array` | `[]` | `[{ id, label, href?, onClick? }]` |\n| `separator` | `ReactNode` | `<ChevronRight />` | Separator between items |\n| `showHome` | `boolean` | `true` | Prepend Home link |\n| `homeIcon` | `ReactNode` | — | Icon for Home |\n| `onHomeClick` | `function` | — | Home click handler |\n| `className` | `string` | — | Extra CSS classes |\n\n## Example\n\n```jsx\n<Breadcrumbs\n  items={[\n    { id: '1', label: 'Products', href: '/products' },\n    { id: '2', label: 'Category', href: '/products/cat' },\n    { id: '3', label: 'Current Page' },\n  ]}\n  showHome\n/>\n```\n\n[← Component overview](README.md)\n",
    "Button": "# Button\n\nButton with variants, sizes, loading state, and optional left/right icons.\n\n## Import\n\n```jsx\nimport { Button } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `variant` | `string` | `\"primary\"` | `primary`, `secondary`, `outline`, `ghost`, `destructive`, `success`, `warning` |\n| `size` | `string` | `\"md\"` | `sm`, `md`, `lg` |\n| `disabled` | `boolean` | — | Disable button |\n| `loading` | `boolean` | — | Show spinner and disable |\n| `leftIcon` | `ReactNode` | — | Icon before children |\n| `rightIcon` | `ReactNode` | — | Icon after children |\n| `fullWidth` | `boolean` | — | Full width |\n| `className` | `string` | — | Extra CSS classes |\n| ...rest | — | — | Passed to native `<button>` |\n\n## Examples\n\n### Basic\n\n```jsx\n<Button variant=\"primary\">Save</Button>\n<Button variant=\"outline\">Cancel</Button>\n```\n\n### Sizes and loading\n\n```jsx\n<Button size=\"sm\">Small</Button>\n<Button size=\"lg\">Large</Button>\n<Button loading>Saving...</Button>\n```\n\n### With icons\n\n```jsx\nimport { Download } from 'lucide-react';\n\n<Button leftIcon={<Download className=\"h-4 w-4\" />}>Download</Button>\n```\n\n[← Component overview](README.md)\n",
    "Card": "# Card\n\nCard container with optional hover shadow. Subcomponents: `Card.Header`, `Card.Title`, `Card.Description`, `Card.Content`, `Card.Footer` for structure.\n\n## Import\n\n```jsx\nimport { Card } from '@dreamtree-org/twreact-ui';\n```\n\n## Props (Card root)\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `children` | `ReactNode` | — | Card content. |\n| `className` | `string` | — | Wrapper CSS classes. |\n| `hover` | `boolean` | `false` | If true, add hover:shadow-md transition. |\n| ...rest | — | — | Passed to root `<div>`. |\n\n## Subcomponents\n\n- **Card.Header**: Wrapper for header (border-bottom, padding). Accepts `children`, `className`.\n- **Card.Title**: `<h3>` for title. Accepts `children`, `className`.\n- **Card.Description**: `<p>` for description. Accepts `children`, `className`.\n- **Card.Content**: Main body (padding). Accepts `children`, `className`.\n- **Card.Footer**: Footer (border-top, padding). Accepts `children`, `className`.\n\n## Example\n\n```jsx\n<Card hover>\n  <Card.Header>\n    <Card.Title>Card title</Card.Title>\n    <Card.Description>Optional description text.</Card.Description>\n  </Card.Header>\n  <Card.Content>\n    Main content here.\n  </Card.Content>\n  <Card.Footer>\n    <Button>Action</Button>\n  </Card.Footer>\n</Card>\n```\n\n[← Component overview](README.md)\n",
    "Carousel": "# Carousel\n\nHorizontal carousel of slides. Renders `children` as slides (one per child). Optional auto-play, previous/next buttons (shown on hover), and dot indicators. Pauses auto-play on hover.\n\n## Import\n\n```jsx\nimport { Carousel } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `children` | `ReactNode` | — | Each child is one slide. |\n| `autoPlay` | `boolean` | `false` | Auto-advance slides. |\n| `interval` | `number` | `5000` | Auto-play interval in ms. |\n| `showDots` | `boolean` | `true` | Show dot indicators at bottom. |\n| `className` | `string` | — | Wrapper CSS classes. |\n| `itemClassName` | `string` | — | Each slide wrapper CSS classes. |\n\n## Behavior\n\n- Slides are laid out in a row; current slide is translated into view.\n- Previous/Next buttons appear on hover (positioned left/right center).\n- Dots are clickable to jump to a slide.\n- On mouse enter, auto-play pauses; on mouse leave, it resumes (if `autoPlay` is true).\n\n## Example\n\n```jsx\n<Carousel autoPlay interval={5000} showDots>\n  <div className=\"h-64 bg-gray-100 flex items-center justify-center\">Slide 1</div>\n  <div className=\"h-64 bg-gray-200 flex items-center justify-center\">Slide 2</div>\n  <div className=\"h-64 bg-gray-300 flex items-center justify-center\">Slide 3</div>\n</Carousel>\n```\n\n[← Component overview](README.md)\n",
    "Checkbox": "# Checkbox\n\nCheckbox with label, sizes, and optional indeterminate state.\n\n## Import\n\n```jsx\nimport { Checkbox } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `id` | `string` | — | Input id |\n| `name` | `string` | — | Form name |\n| `label` | `string` | — | Label text |\n| `checked` | `boolean` | — | Controlled checked |\n| `defaultChecked` | `boolean` | `false` | Uncontrolled default |\n| `onChange` | `function` | — | Change handler |\n| `disabled` | `boolean` | `false` | Disable |\n| `required` | `boolean` | `false` | Required |\n| `size` | `string` | `\"md\"` | `sm`, `md`, `lg` |\n| `labelPosition` | `string` | `\"right\"` | `left`, `right` |\n| `value` | `any` | — | Value when checked |\n| `indeterminate` | `boolean` | `false` | Indeterminate state |\n| `borderColor` | `string` | `\"#ccc\"` | Box border color |\n| `iconClass` | `string` | — | Extra classes for the check icon |\n| `checkedClass` | `string` | — | Extra classes applied when checked |\n\n## Example\n\n```jsx\n<Checkbox label=\"Accept terms\" checked={checked} onChange={e => setChecked(e.target.checked)} />\n<Checkbox label=\"Remember me\" defaultChecked />\n```\n\n[← Component overview](README.md)\n",
    "ColorPicker": "# ColorPicker\n\nColor picker with optional swatches, hex input, HSL sliders, and alpha. Value can be hex or rgba string; `onChange` receives normalized `rgba(r,g,b,a)` string.\n\n## Import\n\n```jsx\nimport { ColorPicker } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `value` | `string` | — | Controlled value (hex or rgba string). |\n| `defaultValue` | `string` | — | Uncontrolled initial value. |\n| `onChange` | `(rgbaString: string) => void` | — | Called with normalized `rgba(r,g,b,a)` string. |\n| `swatches` | `string[]` | — | Array of hex/rgba strings for preset swatches. |\n| `showAlpha` | `boolean` | `false` | Show alpha slider. When off (or when the alpha channel is fully opaque), the displayed hex is the 6-char `#rrggbb` form; the 8-char `#rrggbbff` form is shown only when `showAlpha` is on **and** alpha < 1. |\n| `size` | `\"sm\"` \\| `\"md\"` \\| `\"lg\"` | — | Picker size. |\n| `disabled` | `boolean` | — | Disable the picker. |\n| `className` | `string` | — | Wrapper CSS classes. |\n| `label` | `string` | — | Label text. |\n| `id` | `string` | — | Input id. |\n\n## Example\n\n```jsx\nconst [color, setColor] = useState('#3b82f6');\n<ColorPicker\n  value={color}\n  onChange={setColor}\n  swatches={['#ef4444', '#22c55e', '#3b82f6']}\n  showAlpha\n  label=\"Background\"\n/>\n```\n\n## Notes\n\n- Forwards `ref` to the root wrapper element and spreads unknown props (`...rest`,\n  e.g. `data-*`) onto it. `className` is merged via `cn()` so caller classes win\n  on Tailwind conflicts.\n- The default render (no `showAlpha`) displays the 6-char `#rrggbb` value.\n\n[← Component overview](README.md)\n",
    "Condition": "# Condition\n\nRenders `children` when a condition is true, otherwise renders `fallback`. Simple conditional wrapper with no extra DOM when not needed.\n\n## Import\n\n```jsx\nimport { Condition } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `condition` | `boolean` | — | When true, render `children`; when false, render `fallback`. |\n| `children` | `ReactNode` | — | Content when condition is true. |\n| `fallback` | `ReactNode` | `null` | Content when condition is false. |\n\n## Example\n\n```jsx\n<Condition condition={isLoggedIn}>\n  <Dashboard />\n</Condition>\n\n<Condition condition={loading} fallback={<Loader />}>\n  <Content />\n</Condition>\n\n<Condition condition={hasError} fallback={<Alert variant=\"error\">Error</Alert>}>\n  <Data />\n</Condition>\n```\n\n[← Component overview](README.md)\n",
    "DatePicker": "# DatePicker\n\nSingle date picker with calendar popup. Accepts `Date` or ISO date string; supports min/max, clear button, and optional portal rendering.\n\n## Import\n\n```jsx\nimport { DatePicker } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `value` | `Date` \\| `string` | — | Selected date (Date or ISO string). |\n| `onChange` | `(date: Date \\| null) => void` | — | Called when date changes. |\n| `placeholder` | `string` | `\"Select date...\"` | Input placeholder. |\n| `label` | `string` | — | Label text. |\n| `error` | `string` | — | Error message. |\n| `disabled` | `boolean` | — | Disable the picker. |\n| `required` | `boolean` | — | Required field. |\n| `minDate` | `Date` | — | Minimum selectable date. |\n| `maxDate` | `Date` | — | Maximum selectable date. |\n| `className` | `string` | — | Wrapper CSS classes. |\n| `weekStartsOn` | `0` \\| `1` | `0` | 0 = Sunday, 1 = Monday. |\n| `portal` | `boolean` | `false` | Render calendar in `document.body`. |\n| `displayFormat` | `string` | `\"MMM dd, yyyy\"` | date-fns format for display. |\n| `locale` | `Locale` | — | date-fns locale. |\n| `showClear` | `boolean` | `true` | Show clear button. |\n| `closeOnSelect` | `boolean` | `true` | Close popup on date select. |\n\n## Example\n\n```jsx\nconst [date, setDate] = useState(null);\n<DatePicker\n  value={date}\n  onChange={setDate}\n  placeholder=\"Select date\"\n  minDate={new Date()}\n  label=\"Start date\"\n/>\n```\n\n[← Component overview](README.md)\n",
    "DateRangePicker": "# DateRangePicker\n\nDate range picker: user selects start then end. Value is `{ start: Date, end: Date }`. Popup stays open until both are selected (or user clears). Supports min/max, clear, and optional portal.\n\n## Import\n\n```jsx\nimport { DateRangePicker } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `value` | `{ start: Date\\|string, end: Date\\|string }` | — | Selected range. |\n| `onChange` | `(range: { start, end } \\| null) => void` | — | Called when range changes. |\n| `placeholder` | `string` | `\"Select date range...\"` | Input placeholder. |\n| `label` | `string` | — | Label text. |\n| `error` | `string` | — | Error message. |\n| `disabled` | `boolean` | — | Disable. |\n| `required` | `boolean` | — | Required. |\n| `minDate` | `Date` | — | Minimum selectable date. |\n| `maxDate` | `Date` | — | Maximum selectable date. |\n| `className` | `string` | — | Wrapper CSS classes. |\n| `weekStartsOn` | `0` \\| `1` | `0` | 0 = Sunday, 1 = Monday. |\n| `portal` | `boolean` | `false` | Render popup in document.body. |\n| `displayFormat` | `string` | `\"MMM dd, yyyy\"` | date-fns format for display. |\n| `locale` | `Locale` | — | date-fns locale. |\n| `showClear` | `boolean` | `true` | Show clear button. |\n| `closeOnSelect` | `boolean` | `true` | Close when both dates selected. |\n\n## Example\n\n```jsx\nconst [range, setRange] = useState({ start: null, end: null });\n<DateRangePicker value={range} onChange={setRange} label=\"Period\" />\n```\n\n[← Component overview](README.md)\n",
    "Dialog": "# Dialog\n\nModal dialog with title, body, optional footer, and configurable size. Supports escape key and backdrop click to close when dismissible.\n\n## Import\n\n```jsx\nimport { Dialog } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `isOpen` | `boolean` | — | Controls visibility |\n| `onClose` | `function` | — | Called when dialog should close |\n| `title` | `string` | — | Dialog title |\n| `children` | `ReactNode` | — | Body content |\n| `size` | `string` | `\"md\"` | `sm`, `md`, `lg`, `xl`, `full` |\n| `dismissible` | `boolean` | `true` | Allow close via backdrop or Escape |\n| `showCloseButton` | `boolean` | `true` | Show X button |\n| `footer` | `ReactNode` | — | Footer content (e.g. buttons) |\n| `className` | `string` | — | Extra CSS classes |\n| `onOpen` | `function` | — | Called when dialog opens (e.g. with dialogRef) |\n\n## Examples\n\n### Basic\n\n```jsx\nconst [open, setOpen] = useState(false);\n\n<Button onClick={() => setOpen(true)}>Open</Button>\n<Dialog\n  isOpen={open}\n  onClose={() => setOpen(false)}\n  title=\"Confirm\"\n>\n  Are you sure you want to continue?\n</Dialog>\n```\n\n### With footer\n\n```jsx\n<Dialog\n  isOpen={open}\n  onClose={() => setOpen(false)}\n  title=\"Edit\"\n  footer={\n    <>\n      <Button variant=\"ghost\" onClick={() => setOpen(false)}>Cancel</Button>\n      <Button onClick={handleSave}>Save</Button>\n    </>\n  }\n>\n  <Input label=\"Name\" value={name} onChange={e => setName(e.target.value)} />\n</Dialog>\n```\n\n## Accessibility & keyboard\n\n`Dialog` renders `role=\"dialog\"` + `aria-modal=\"true\"` and backs that promise\nwith real focus management (no extra dependency — a built-in focus trap):\n\n| Behavior | Detail |\n|----------|--------|\n| Focus on open | Focus moves to the first focusable element inside the panel (or the panel itself when there is none). |\n| Focus trap | `Tab` / `Shift`+`Tab` cycle only through focusable elements inside the panel; focus cannot reach the page behind the modal. |\n| Focus restore | On close, focus returns to the element that had it when the dialog opened (typically the trigger). |\n| `Escape` | Closes the dialog when `dismissible` (default); ignored when `dismissible={false}`. |\n| Backdrop click | Closes the dialog when `dismissible`. |\n| Reduced motion | The scale-in entrance is suppressed under `prefers-reduced-motion` (`motion-reduce:animate-none`). |\n| Labelling | When `title` is set, the panel is `aria-labelledby` the title heading. |\n\n[← Component overview](README.md)\n",
    "FileUpload": "# FileUpload\n\nFile upload zone: drag-and-drop or click to open file dialog. Supports single/multiple, `accept`, `maxSize` validation, and list of selected files with remove. Calls `onFileSelect` with valid files and `onFileRemove` with index.\n\n## Import\n\n```jsx\nimport { FileUpload } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `accept` | `string` | — | Input accept (e.g. `\"image/*\"`, `\".pdf\"`). |\n| `multiple` | `boolean` | `false` | Allow multiple files. |\n| `maxSize` | `number` | — | Max file size in bytes; larger files trigger error and are not added. |\n| `onFileSelect` | `(files: File[]) => void` | — | Called with valid selected/dropped files. |\n| `onFileRemove` | `(fileIndex: number) => void` | — | Called when user removes a file from the list. |\n| `files` | `File[]` | `[]` | List of files to display (e.g. controlled from parent). |\n| `disabled` | `boolean` | `false` | Disable the zone and remove buttons. |\n| `className` | `string` | — | Wrapper CSS classes. |\n| ...rest | — | — | Passed to wrapper div. |\n\n## Behavior\n\n- Validates each file: if `maxSize` is set and file.size > maxSize, shows error and does not add that file.\n- File type icons: image, text/document, or generic file.\n- Displays file size in human-readable form (Bytes, KB, MB, GB).\n\n## Example\n\n```jsx\nconst [files, setFiles] = useState([]);\n<FileUpload\n  accept=\"image/*\"\n  multiple\n  maxSize={5 * 1024 * 1024}\n  files={files}\n  onFileSelect={(newFiles) => setFiles(prev => [...prev, ...newFiles])}\n  onFileRemove={(index) => setFiles(prev => prev.filter((_, i) => i !== index))}\n/>\n```\n\n[← Component overview](README.md)\n",
    "FootNav": "# FootNav\n\nFixed bottom navigation for mobile (hidden on `md` and up via `md:hidden`). Renders a row of items with icon and label; optional badge per item. Items support `onClick`.\n\n## Import\n\n```jsx\nimport { FootNav } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `items` | `Array` | `[]` | Each item: `{ id, label, icon, onClick?, active?, badge? }`. |\n| `className` | `string` | — | Nav wrapper CSS classes. |\n| ...rest | — | — | Passed to `<nav>`. |\n\n## Item shape\n\n- `id`: string or number (key).\n- `label`: string.\n- `icon`: ReactNode (e.g. Lucide icon).\n- `onClick(item)`: optional; called when item is clicked.\n- `active`: boolean; highlights as primary.\n- `badge`: optional number or node; shown as small badge on the icon.\n\n## Example\n\n```jsx\n<FootNav\n  items={[\n    { id: 'home', label: 'Home', icon: <Home />, onClick: () => navigate('/'), active: path === '/' },\n    { id: 'search', label: 'Search', icon: <Search />, onClick: () => openSearch() },\n    { id: 'notifications', label: 'Alerts', icon: <Bell />, badge: 3, onClick: () => openNotifications() },\n    { id: 'profile', label: 'Profile', icon: <User />, onClick: () => navigate('/profile') },\n  ]}\n/>\n```\n\n[← Component overview](README.md)\n",
    "Form": "# Form\n\nForm built on **react-hook-form** with a `fields` config array. Renders Input, Select, DatePicker, Checkbox, Switch, textarea, etc., and handles submit/reset. Use `validationSchema` (e.g. from `@hookform/resolvers` with yup) for validation.\n\n## Import\n\n```jsx\nimport { Form } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `fields` | `Array` | `[]` | Field configs (see Field shape below). |\n| `onSubmit` | `(data: object) => void` | — | Submit handler; receives form data. |\n| `defaultValues` | `object` | `{}` | Default values for each field name. |\n| `validationSchema` | `object` | — | Resolver from e.g. `yupResolver(schema)`. |\n| `className` | `string` | — | Form wrapper CSS classes. |\n| `submitText` | `string` | `\"Submit\"` | Submit button text. |\n| `resetText` | `string` | `\"Reset\"` | Reset button text. |\n| `submitButtonClass` | `string` | — | Submit button CSS classes. |\n| `resetButtonClass` | `string` | — | Reset button CSS classes. |\n| `showReset` | `boolean` | `true` | Show reset button. |\n| `submitDisabled` | `boolean` | `false` | Disable submit button. |\n| ...rest | — | — | Passed to react-hook-form `useForm` (e.g. `mode`). |\n\n## Field shape\n\nEach item in `fields` can have:\n\n- `type`: `\"text\"` \\| `\"email\"` \\| `\"password\"` \\| `\"number\"` \\| `\"tel\"` \\| `\"url\"` \\| `\"select\"` \\| `\"date\"` \\| `\"textarea\"` \\| `\"checkbox\"` \\| `\"switch\"` (and possibly others; check component for full list).\n- `name`: string (required).\n- `label`: string.\n- `required`: boolean.\n- `placeholder`: string.\n- `options`: for select, array of `{ value, label }`; other options passed to the underlying component.\n- `rows`: for textarea.\n- Any other prop passed through to the rendered component (e.g. `disabled`).\n\n## Example\n\n```jsx\nimport { Form } from '@dreamtree-org/twreact-ui';\nimport { yupResolver } from '@hookform/resolvers/yup';\nimport * as yup from 'yup';\n\nconst schema = yup.object({\n  email: yup.string().email().required(),\n  password: yup.string().min(6).required(),\n});\n\n<Form\n  fields={[\n    { type: 'email', name: 'email', label: 'Email', required: true, placeholder: 'you@example.com' },\n    { type: 'password', name: 'password', label: 'Password', required: true },\n    { type: 'select', name: 'role', label: 'Role', options: [{ value: 'user', label: 'User' }, { value: 'admin', label: 'Admin' }] },\n  ]}\n  defaultValues={{ email: '', password: '', role: 'user' }}\n  validationSchema={yupResolver(schema)}\n  onSubmit={(data) => console.log(data)}\n  submitText=\"Sign in\"\n  showReset\n/>\n```\n\n[← Component overview](README.md)\n",
    "Input": "# Input\n\nText input with optional label, error/success states, clear button, character count, and password visibility toggle.\n\n## Import\n\n```jsx\nimport { Input } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `id` | `string` | — | Input id (auto-generated if not set) |\n| `className` | `string` | — | Extra CSS classes |\n| `type` | `string` | `\"text\"` | `text`, `search`, `password`, etc. |\n| `label` | `string` | — | Label text |\n| `placeholder` | `string` | — | Placeholder |\n| `error` | `string` | — | Error message (shows error state) |\n| `success` | `boolean` | — | Success state |\n| `disabled` | `boolean` | `false` | Disable input |\n| `required` | `boolean` | `false` | Required field |\n| `clearable` | `boolean` | `false` | Show clear button when has value |\n| `icon` | `ReactNode` | — | Left or right icon |\n| `iconPosition` | `\"left\"` \\| `\"right\"` | `\"left\"` | Icon position |\n| `onClear` | `function` | — | Called when clear is clicked |\n| `showCount` | `boolean` | `false` | Show character count |\n| `maxLength` | `number` | — | Max length (used with showCount) |\n| `readOnly` | `boolean` | `false` | Read-only |\n| `value` | `string` | — | Controlled value |\n| `defaultValue` | `string` | — | Uncontrolled default |\n| `onChange` | `function` | — | Change handler |\n| ...rest | — | — | Passed to native `<input>` |\n\n## Examples\n\n### Basic\n\n```jsx\n<Input label=\"Email\" placeholder=\"you@example.com\" />\n```\n\n### With error\n\n```jsx\n<Input label=\"Email\" error=\"Invalid email address\" />\n```\n\n### Password with toggle\n\n```jsx\n<Input type=\"password\" label=\"Password\" placeholder=\"Enter password\" />\n```\n\n### Clearable and character count\n\n```jsx\n<Input\n  label=\"Bio\"\n  clearable\n  showCount\n  maxLength={200}\n  placeholder=\"Tell us about yourself\"\n/>\n```\n\n[← Component overview](README.md)\n",
    "Loader": "# Loader\n\nLoading indicator in three variants: spinner (default), dots, or bar. Configurable size, speed, colors, and optional label text.\n\n## Import\n\n```jsx\nimport { Loader } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `size` | `\"sm\"` \\| `\"md\"` \\| `\"lg\"` \\| `number` | `\"md\"` | Size: sm=14px, md=20px, lg=36px, or numeric px. |\n| `speed` | `number` | `0.9` | Animation duration in seconds. |\n| `thickness` | `number` | `2.5` | Stroke thickness (spinner). |\n| `color` | `string` | `\"currentColor\"` | Main color (spinner/dots/bar). |\n| `secondaryColor` | `string` | `\"rgba(0,0,0,0.08)\"` | Track/background color. |\n| `variant` | `\"spinner\"` \\| `\"dots\"` \\| `\"bar\"` | `\"spinner\"` | Visual style. |\n| `className` | `string` | `\"\"` | Wrapper CSS classes. |\n| `inline` | `boolean` | `false` | If true, wrapper is inline-flex. |\n| `ariaLabel` | `string` | `\"Loading\"` | Accessibility label. |\n| `text` | `string` | — | Optional label shown next to loader. |\n| `reverse` | `boolean` | `false` | Reverse spinner rotation direction. |\n| `style` | `object` | — | Inline style for wrapper. |\n\n## Examples\n\n```jsx\n<Loader />\n<Loader variant=\"dots\" size=\"sm\" />\n<Loader variant=\"bar\" text=\"Loading...\" />\n<Loader size={32} color=\"#2563eb\" />\n```\n\n[← Component overview](README.md)\n",
    "LocationPicker": "# LocationPicker\n\nInput for latitude/longitude. User can type `lat, lng` (e.g. `12.34, 56.78`) or click the icon to use browser geolocation. Value is `{ lat, lng }` or `null`.\n\n## Import\n\n```jsx\nimport { LocationPicker } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `value` | `{ lat: number, lng: number }` \\| `null` | `null` | Current coordinates. |\n| `onChange` | `(coords: { lat, lng } \\| null) => void` | — | Called when value changes (typed or from geolocation). |\n| `inputProps` | `object` | `{}` | Props spread to the underlying input (e.g. `placeholder`). A supplied `inputProps.onChange` is forwarded **in addition to** (not instead of) the component's coord-parsing handler — both fire. `inputProps.className` is merged via `cn()`. |\n| `className` | `string` | — | Classes merged (via `cn()`) onto the root wrapper. |\n| `icon` | `ReactNode` | default pin SVG | Icon for \"use my location\" button. |\n| `iconProps` | `object` | `{}` | Props for the icon button (e.g. `className`, `onClick`). |\n| `iconPosition` | `\"left\"` \\| `\"right\"` | `\"right\"` | Position of the icon button. |\n| `placeholder` | `string` | `\"lat, lng\"` | Input placeholder. |\n\n## Behavior\n\n- Display format is `lat.toFixed(6), lng.toFixed(6)`.\n- Typing a valid \"lat, lng\" string calls `onChange` with `{ lat, lng }` (e.g.\n  typing `\"1.5, 2.5\"` calls `onChange({ lat: 1.5, lng: 2.5 })`). A\n  consumer-supplied `inputProps.onChange` still fires alongside it.\n- Clearing the input calls `onChange(null)`.\n- Clicking the icon calls `navigator.geolocation.getCurrentPosition` and passes the result to `onChange`. Requires HTTPS in production.\n- Forwards `ref` to the underlying `<input>` and spreads unknown props (`...rest`) onto the root wrapper.\n\n## Example\n\n```jsx\nconst [location, setLocation] = useState(null);\n<LocationPicker\n  value={location}\n  onChange={setLocation}\n  placeholder=\"Enter lat, lng or use location\"\n/>\n```\n\n[← Component overview](README.md)\n",
    "Navbar": "# Navbar\n\nTop navigation bar with logo, nav items (links or buttons), optional search, notifications dropdown, and login/logout. Uses an **emitter** for notification actions (view, markAsRead, markAsUnread, clearAll, delete). Responsive: left icon and hamburger on mobile; desktop nav and search. You can replace the right area with a custom component via `rightMenuContent`.\n\n## Import\n\n```jsx\nimport { Navbar } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `emitter` | `object` | **required** | Event emitter for notifications (e.g. `notification:view`, `notification:markAsRead`, etc.). |\n| `logo` | `ReactNode` | — | Logo (e.g. image or link). |\n| `items` | `Array` | `[]` | Nav items: `{ id, label, href?, active?, onClick?(item) }`. If `href` is set, renders `<a>`; else `<button>` with `onClick`. |\n| `user` | `object` \\| `null` | — | If set, shows logout button; if null/undefined, shows login button. |\n| `notifications` | `Array` | `[]` | List of notifications for the dropdown. Each: `{ id, title, message?, read? }`. |\n| `searchable` | `boolean` | `false` | Show search input (desktop). |\n| `onSearch` | `(term: string) => void` | — | Called on search form submit with current search term. |\n| `leftIcon` | `ReactNode` \\| `false` | `<ChevronLeft />` | Icon shown on mobile (e.g. back). Set `false` to hide. |\n| `onLeftIconClick` | `() => void` | — | Called when left icon (mobile) is clicked. |\n| `rightMenuContent` | `(props) => ReactNode` | — | Custom right menu. Receives `{ notifications }` and any Navbar `...props` (e.g. `emitter`, `onFetch`). If not provided, default renders notifications dropdown. |\n| `onLoginClick` | `() => void` | — | Called when login button is clicked. |\n| `onLogoutClick` | `() => void` | — | Called when logout button is clicked. |\n| `onFetch` | `({ setNotifications }) => void` | — | Refresh handler for the default notifications dropdown. Called on mount and when `notifications` changes. Consumed by the right menu — it is **not** forwarded onto `<nav>`. |\n| `className` | `string` | — | Wrapper CSS classes. |\n| ...rest | — | — | Only DOM-valid attributes (e.g. `id`, `aria-*`, `data-*`, event handlers) are forwarded to the root `<nav>`. The component's own control props (`isMobileOpen`, `setIsMobileOpen`, `onFetch`, …) are consumed and never leak to the DOM. |\n\n`Navbar` forwards `ref` to its root `<nav>` element.\n\n## Item shape (items)\n\n- `id`: string or number (key).\n- `label`: string.\n- `href`: optional; if set, item is an `<a href={href}>`.\n- `active`: optional boolean; applies primary styling.\n- `onClick(item)`: optional; used when no `href` (button click).\n\n## Notification shape (notifications)\n\n- `id`: string or number.\n- `title`: string.\n- `message`: optional string.\n- `read`: optional boolean; unread count uses `!n.read`.\n\n## Default notifications dropdown\n\nIf `rightMenuContent` is not provided, the right menu shows a bell icon and dropdown with:\n\n- Unread count badge.\n- \"Clear all\" that clears the list and calls emitter `notification:clearAll`.\n- Per notification: title, message, \"Mark as Read\" / \"Mark as Unread\", \"Delete\" (emitter events).\n- Clicking a notification calls `emitter.emit('notification:view', [n])`.\n\nTo refresh the list from the server, pass `onFetch({ setNotifications })`; the default dropdown uses it on mount and when `notifications` prop changes.\n\n## Example\n\n```jsx\nimport { Navbar } from '@dreamtree-org/twreact-ui';\nimport MyEmitter from './emitter';\n\n<Navbar\n  emitter={MyEmitter}\n  logo={<a href=\"/\"><img src=\"/logo.svg\" alt=\"Home\" /></a>}\n  items={[\n    { id: '1', label: 'Home', href: '/', active: pathname === '/' },\n    { id: '2', label: 'About', href: '/about' },\n    { id: '3', label: 'Settings', onClick: () => openSettings() },\n  ]}\n  user={user}\n  notifications={notifications}\n  searchable\n  onSearch={(term) => doSearch(term)}\n  onLoginClick={() => navigate('/login')}\n  onLogoutClick={logout}\n  onFetch={async ({ setNotifications }) => {\n    const res = await fetch('/api/notifications');\n    const data = await res.json();\n    setNotifications(data.items);\n  }}\n/>\n```\n\n[← Component overview](README.md)\n",
    "Pagination": "# Pagination\n\nPage navigation: first, previous, page numbers, next, last. Renders only when `totalPages > 1`. Optional `theme` for styling (e.g. from Table).\n\n## Import\n\n```jsx\nimport { Pagination } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `currentPage` | `number` | `1` | Current page (1-based). |\n| `totalPages` | `number` | `1` | Total pages. If ≤ 1, component returns null. |\n| `onPageChange` | `(page: number) => void` | — | Called when user selects a page. |\n| `showFirstLast` | `boolean` | `true` | Show first/last page buttons. |\n| `showPrevNext` | `boolean` | `true` | Show previous/next buttons. |\n| `maxVisiblePages` | `number` | `5` | Max page number buttons to show. |\n| `className` | `string` | — | Nav wrapper CSS classes. |\n| ...rest | — | — | Passed to `<nav>`. |\n\n## Example\n\n```jsx\n<Pagination\n  currentPage={page}\n  totalPages={Math.ceil(total / pageSize)}\n  onPageChange={setPage}\n  maxVisiblePages={5}\n/>\n```\n\n[← Component overview](README.md)\n",
    "PriceRangePicker": "# PriceRangePicker\n\nDual-thumb range slider for min/max values (e.g. price or any number). Optional number inputs and preset buttons. Controlled via `value` or uncontrolled via `defaultValue`.\n\n## Import\n\n```jsx\nimport { PriceRangePicker } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `min` | `number` | `0` | Minimum value. |\n| `max` | `number` | `1000` | Maximum value. |\n| `step` | `number` | `1` | Step for thumbs and inputs. |\n| `minGap` | `number` | `5` | Minimum gap between min and max. |\n| `value` | `{ min, max }` \\| `null` | `null` | Controlled value. |\n| `defaultValue` | `{ min, max }` | `{ min: 0, max: 1000 }` | Uncontrolled initial value. |\n| `onChange` | `(value: { min, max }) => void` | `() => {}` | Called on thumb/input change. |\n| `onFinalChange` | `(value: { min, max }) => void` | `() => {}` | Called on mouseup/touchend or Enter in inputs. |\n| `showInputs` | `boolean` | `true` | Show min/max number inputs. |\n| `showTooltips` | `boolean` | `true` | Show tooltips on thumbs. |\n| `disabled` | `boolean` | `false` | Disable the control. |\n| `presets` | `Array<{ id, label, value: { min, max } }>` | `[]` | Preset buttons. |\n| `formatValue` | `(n: number) => string` | `(n) => String(n)` | Format display (e.g. currency). |\n| `className` | `string` | `\"\"` | Container CSS classes. |\n| `size` | `\"sm\"` \\| `\"md\"` \\| `\"lg\"` | `\"md\"` | Thumb and spacing size. |\n| `colorClass` | `string` | `\"bg-pink-500\"` | Tailwind class for active track/thumb. |\n| `ariaLabel` | `string` | `\"Price range\"` | Accessibility label. |\n\n## Example\n\n```jsx\nconst [range, setRange] = useState({ min: 100, max: 500 });\n<PriceRangePicker\n  min={0}\n  max={1000}\n  value={range}\n  onChange={setRange}\n  formatValue={(n) => `$${n}`}\n  presets={[\n    { id: '1', label: 'Under $200', value: { min: 0, max: 200 } },\n  ]}\n/>\n```\n\n[← Component overview](README.md)\n",
    "ProgressBar": "# ProgressBar\n\nProgress bar showing a value between 0 and max. Supports custom HEX colors, optional label, value text inside the bar, striped and animated styles.\n\n## Import\n\n```jsx\nimport { ProgressBar } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `value` | `number` | `0` | Current value. |\n| `max` | `number` | `100` | Maximum value. |\n| `size` | `\"xs\"` \\| `\"sm\"` \\| `\"md\"` \\| `\"lg\"` \\| `number` | `\"md\"` | Height: xs/sm/md/lg or px. |\n| `showValue` | `boolean` | `false` | Show percentage text inside the fill. |\n| `rounded` | `boolean` | `true` | Rounded corners. |\n| `color` | `string` (HEX) | `\"#2563eb\"` | Fill color (HEX only). |\n| `bgColor` | `string` (HEX) | `\"#e6eefc\"` | Track background (HEX only). |\n| `valueColor` | `string` (HEX) | auto | Text color inside fill; auto from luminance if omitted. |\n| `striped` | `boolean` | `false` | Striped fill pattern. |\n| `animated` | `boolean` | `false` | Animate stripe movement. |\n| `label` | `string` | `\"\"` | Label above the bar. |\n| `ariaLabel` | `string` | `\"Progress\"` | Accessibility label. |\n| `className` | `string` | `\"\"` | Wrapper CSS classes. |\n| `style` | `object` | `{}` | Wrapper inline style. |\n\n## Example\n\n```jsx\n<ProgressBar value={60} max={100} />\n<ProgressBar value={75} showValue label=\"Upload\" color=\"#16a34a\" />\n<ProgressBar value={40} striped animated size=\"lg\" />\n```\n\n[← Component overview](README.md)\n",
    "Radio": "# Radio\n\nSingle radio button; use multiple with the same `name` for a group. Controlled via `checked` or uncontrolled via `defaultChecked`.\n\n## Import\n\n```jsx\nimport { Radio } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `id` | `string` | auto | Input id. |\n| `name` | `string` | — | Group name (required for grouping). |\n| `value` | `any` | — | Value when selected. |\n| `checked` | `boolean` | — | Controlled checked. |\n| `defaultChecked` | `boolean` | — | Uncontrolled initial. |\n| `onChange` | `(e: Event) => void` | — | Change handler. |\n| `disabled` | `boolean` | `false` | Disable. |\n| `required` | `boolean` | `false` | Required. |\n| `label` | `string` | — | Label text. |\n| `size` | `\"sm\"` \\| `\"md\"` \\| `\"lg\"` | `\"md\"` | Size. |\n| `labelPosition` | `\"left\"` \\| `\"right\"` | `\"right\"` | Label side. |\n| `radioColor` | `string` | `\"blue\"` | Accent color (Tailwind name). |\n| `className` | `string` | `\"\"` | Label wrapper classes. |\n| `ariaLabel` | `string` | — | Accessibility label. |\n\n## Example\n\n```jsx\nconst [choice, setChoice] = useState('a');\n<>\n  <Radio name=\"choice\" value=\"a\" checked={choice === 'a'} onChange={() => setChoice('a')} label=\"Option A\" />\n  <Radio name=\"choice\" value=\"b\" checked={choice === 'b'} onChange={() => setChoice('b')} label=\"Option B\" />\n</>\n```\n\n[← Component overview](README.md)\n",
    "Rate": "# Rate\n\nStar (or custom icon) rating input/display. Controlled via `value` or uncontrolled via `defaultValue`. Supports hover preview and optional read-only.\n\n## Import\n\n```jsx\nimport { Rate } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `count` | `number` | `5` | Number of stars. |\n| `value` | `number` | — | Controlled value (0 to count). |\n| `defaultValue` | `number` | `0` | Uncontrolled initial value. |\n| `readOnly` | `boolean` | `false` | Read-only (no onChange). |\n| `icon` | `ReactNode` | `<StarOutline />` | Icon for inactive star. |\n| `toggledIcon` | `ReactNode` | `<StarFilled />` | Icon for active star. |\n| `activeColor` | `string` | `\"#f6b026\"` | Color for active stars. |\n| `inactiveColor` | `string` | `\"#e5e7eb\"` | Color for inactive stars. |\n| `size` | `number` | `20` | Icon size in px. |\n| `onChange` | `(value: number) => void` | — | Called when value changes. |\n| `onClick` | `(value: number) => void` | — | Called on star click. |\n| `text` | `ReactNode` | — | Optional text (e.g. label) next to stars. |\n| `className` | `string` | `\"\"` | Wrapper CSS classes. |\n| `id` | `string` | — | Wrapper id. |\n| `name` | `string` | — | Form field name. |\n\n## Example\n\n```jsx\nconst [rating, setRating] = useState(0);\n<Rate value={rating} onChange={setRating} count={5} />\n<Rate defaultValue={3} readOnly />\n```\n\n[← Component overview](README.md)\n",
    "RoundedTag": "# RoundedTag\n\nTag/chip with optional avatar (image or initials) and optional remove button. Used for labels, selected items, or filters.\n\n## Import\n\n```jsx\nimport { RoundedTag } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `label` | `string` | — | Main label text. |\n| `avatarSrc` | `string` | `null` | Image URL for avatar. |\n| `avatarAlt` | `string` | `\"avatar\"` | Alt for avatar image. |\n| `initials` | `string` | `\"\"` | Initials when no image (e.g. \"AB\"). |\n| `size` | `\"sm\"` \\| `\"md\"` \\| `\"lg\"` | `\"md\"` | Size. |\n| `onRemove` | `(e?) => void` | `null` | If provided, shows remove button and calls on click. |\n| `onClick` | `(e?) => void` | `null` | Click handler for the tag. |\n| `className` | `string` | `\"\"` | Wrapper CSS classes. |\n| `closeClass` | `string` | `\"\"` | Remove button CSS classes. |\n| `ariaLabel` | `string` | `\"tag\"` | Accessibility label. |\n| `avatarPosition` | `\"left\"` \\| `\"right\"` | `\"left\"` | Avatar position. |\n| `avatarClassname` | `string` | `\"\"` | Avatar wrapper classes. |\n| `initialClassname` | `string` | `\"\"` | Initials span classes. |\n\n## Example\n\n```jsx\n<RoundedTag label=\"React\" />\n<RoundedTag label=\"John\" initials=\"JD\" onRemove={() => {}} />\n<RoundedTag label=\"With image\" avatarSrc=\"/user.jpg\" size=\"lg\" />\n```\n\n[← Component overview](README.md)\n",
    "Select": "# Select\n\nSingle or multi-select dropdown with search, grouped options, creatable options, and optional select-all.\n\n> **The open menu portals to `document.body`.** The dropdown is rendered through\n> a React portal with `position: fixed`, anchored to the trigger via its viewport\n> rect. This means the menu **escapes any ancestor with `overflow: hidden | auto |\n> scroll`** instead of being clipped by it, and it repositions on scroll/resize\n> while open. There is no new prop and no opt-out — portaling is the default\n> behavior. Behaviorally everything else is unchanged (keyboard nav,\n> click-outside-to-close, placement flip, trigger-width matching, ARIA wiring).\n\n## Import\n\n```jsx\nimport { Select } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `options` | `Array` | `[]` | `[{ value, label, disabled }]` or grouped `[{ label, options: [...] }]` |\n| `value` | `any` \\| `any[]` | — | Selected value(s); array when `multiSelect` |\n| `onChange` | `function` | — | `(value)` or `(values[])` |\n| `placeholder` | `string` | `\"Select an option...\"` | Placeholder text |\n| `label` | `string` | — | Label |\n| `error` | `string` | — | Error message |\n| `disabled` | `boolean` | — | Disable select |\n| `required` | `boolean` | — | Required |\n| `multiSelect` | `boolean` | `false` | Allow multiple selection |\n| `searchable` | `boolean` | `false` | Show search input |\n| `grouped` | `boolean` | `false` | Options are grouped |\n| `allowClear` | `boolean` | `true` | Show clear button |\n| `creatable` | `boolean` | `false` | Allow creating new option when no match |\n| `onCreateOption` | `function` | — | Called when creating option |\n| `onSearch` | `function` | — | Search term callback |\n| `loading` | `boolean` | `false` | Loading state |\n| `selectAllOption` | `boolean` | `true` | Show select all (multi) |\n| `closeOnSelect` | `boolean` | `false` | Close dropdown on select (single) |\n| `maxTagCount` | `number` | `3` | Max tags shown in multi (rest as \"+N\") |\n| `onMenuItemRender` | `function` | — | Custom option render |\n| `renderGroupLabel` | `function` | — | Custom group label |\n| `name` | `string` | — | Form field name |\n| `className` | `string` | — | Extra CSS classes |\n\n## Examples\n\n### Basic single select\n\n```jsx\nconst options = [\n  { value: 'a', label: 'Option A' },\n  { value: 'b', label: 'Option B' },\n];\n<Select\n  options={options}\n  value={value}\n  onChange={setValue}\n  placeholder=\"Choose one\"\n/>\n```\n\n### Multi select with search\n\n```jsx\n<Select\n  options={options}\n  value={selected}\n  onChange={setSelected}\n  multiSelect\n  searchable\n  placeholder=\"Choose multiple\"\n/>\n```\n\n### Grouped options\n\n```jsx\nconst grouped = [\n  { label: 'Fruits', options: [{ value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }] },\n  { label: 'Veggies', options: [{ value: 'carrot', label: 'Carrot' }] },\n];\n<Select options={grouped} grouped value={value} onChange={setValue} />\n```\n\n[← Component overview](README.md)\n",
    "Sidebar": "# Sidebar\n\nCollapsible side navigation with optional nested items, logo, and user block. Supports desktop collapsed state and mobile drawer. Tooltips show when collapsed; optional `drawerPosition` for mobile.\n\n## Import\n\n```jsx\nimport { Sidebar } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `items` | `Array` | `[]` | Nav items: `{ id, label, icon, children?, onClick?, active? }`. `children` = nested items. |\n| `collapsed` | `boolean` | `false` | Desktop collapsed state (icon-only). |\n| `onToggle` | `() => void` | — | Toggle collapse (e.g. chevron click). |\n| `className` | `string` | — | Wrapper CSS classes. |\n| `logo` | `ReactNode` | — | Logo at top. |\n| `user` | `object` \\| `ReactNode` | — | User block at bottom. |\n| `onUserClick` | `function` | — | User block click. |\n| `drawerPosition` | `\"left\"` \\| `\"right\"` | `\"left\"` | Mobile drawer side. |\n| `isMobileOpen` | `boolean` | — | Controlled mobile open. |\n| `setIsMobileOpen` | `(open: boolean) => void` | — | Set mobile open (when controlled). |\n| `showCollapsedTooltips` | `boolean` | `true` | Show tooltips when collapsed. |\n| `tooltipOptions` | `object` | — | Options for internal Tooltip. |\n\n## Item shape\n\n- `id`: string (required for expand/active).\n- `label`: string.\n- `icon`: ReactNode.\n- `children`: optional array of same shape (nested items).\n- `onClick`: optional handler.\n- `active`: optional boolean for current page.\n\n## Example\n\n```jsx\nconst [collapsed, setCollapsed] = useState(false);\n<Sidebar\n  items={[\n    { id: 'dash', label: 'Dashboard', icon: <Home /> },\n    { id: 'settings', label: 'Settings', icon: <Settings />, children: [\n      { id: 'profile', label: 'Profile' },\n      { id: 'security', label: 'Security' },\n    ]},\n  ]}\n  collapsed={collapsed}\n  onToggle={() => setCollapsed(!collapsed)}\n  logo={<Logo />}\n  user={{ name: 'Jane', avatar: '/jane.jpg' }}\n/>\n```\n\n[← Component overview](README.md)\n",
    "Skeleton": "# Skeleton\n\nPlaceholder blocks for loading states. Renders shimmer bars (or circles) when `active` is true; otherwise renders `children`.\n\n## Import\n\n```jsx\nimport { Skeleton } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `count` | `number` | `1` | Number of skeleton items. |\n| `circle` | `boolean` | `false` | Render items as circles. |\n| `height` | `number` \\| `string` | `16` | Height in px or CSS unit (e.g. `\"2rem\"`). |\n| `width` | `number` \\| `string` | — | Width; default 100% (column) or height (inline/circle). |\n| `rounded` | `boolean` | `true` | Rounded corners (when not circle). |\n| `animated` | `boolean` | `true` | Shimmer animation. |\n| `active` | `boolean` | `true` | If true show skeletons; if false render children. |\n| `gap` | `string` | `\"8px\"` | Spacing between items. |\n| `inline` | `boolean` | `false` | Layout items in a row. |\n| `className` | `string` | `\"\"` | Wrapper CSS classes. |\n| `style` | `object` | `{}` | Wrapper inline style. |\n| `children` | `ReactNode` | `null` | Rendered when `active` is false. |\n\n## Examples\n\n```jsx\n<Skeleton />\n<Skeleton count={3} height={20} gap=\"12px\" />\n<Skeleton circle height={40} />\n<Skeleton active={loading} count={2}>\n  <RealContent />\n</Skeleton>\n```\n\n[← Component overview](README.md)\n",
    "SpeechToText": "# SpeechToText\n\nVoice-to-text using the Web Speech API. Headless by default — render a custom\ncontrol via `renderButton`, or drive it imperatively through the ref. The\nbuilt-in fallback button is `className`-extensible and forwards arbitrary props.\n\n## Import\n\n```jsx\nimport { SpeechToText } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `lang` | `string` | `\"en-US\"` | Recognition language |\n| `continuous` | `boolean` | `true` | Keep listening until stopped (forced `false` on mobile) |\n| `interimResults` | `boolean` | `true` | Return interim results |\n| `onSpeechComplete` | `function` | — | Final transcript chunk callback `(text) => void` |\n| `onSpeaking` | `function` | — | Interim transcript callback `(text) => void` |\n| `onError` | `function` | — | Fatal error callback `(Error) => void`. Routine events (`no-speech`, `aborted`) are **not** surfaced |\n| `onStart` | `function` | — | Start callback |\n| `onStop` | `function` | — | Stop callback |\n| `renderButton` | `function` | — | Custom control render-prop (see signature below) |\n| `autoStart` | `boolean` | `false` | Start on mount (once, after support is detected) |\n| `disabled` | `boolean` | `false` | Disable |\n| `resetOnStart` | `boolean` | `false` | Clear the accumulated transcript when a new session starts |\n| `className` | `string` | — | Merged (via `cn`) onto the default button |\n| `...rest` | — | — | Forwarded to the default `<button>` |\n\nThe default button is keyboard-accessible (`aria-pressed`, `aria-label`) and\ntoken-driven. When `renderButton` is supplied, `className`/`...rest` are not\napplied (you own the rendered control).\n\n## `renderButton` signature\n\n```js\nrenderButton({ isListening, isSupported, error, start, stop, toggle, disabled })\n```\n\n## Ref methods\n\n`start()`, `stop()`, `toggle()`, `isListening()`, `isSupported()`,\n`getTranscript()`, `clearTranscript()`, `getError()`.\n\n## Example\n\n```jsx\nconst [transcript, setTranscript] = useState('');\n<SpeechToText\n  onSpeechComplete={(chunk) => setTranscript((t) => `${t} ${chunk}`.trim())}\n  onError={(e) => console.error(e)}\n/>\n<div>Transcript: {transcript}</div>\n```\n\n[← Component overview](README.md)\n",
    "Stepper": "# Stepper\n\nHorizontal or vertical step indicator. Each step has circle (with check for completed), optional line, and label. Optional `onStepClick` for clickable steps.\n\n## Import\n\n```jsx\nimport { Stepper } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `steps` | `Array` | `[]` | Each step: `{ id?, label?, description? }`. |\n| `currentStep` | `number` | `0` | Zero-based index of current step. |\n| `orientation` | `\"horizontal\"` \\| `\"vertical\"` | `\"horizontal\"` | Layout. |\n| `variant` | `string` | `\"default\"` | Visual variant. |\n| `onStepClick` | `(step, stepIndex) => void` | — | Called when a step is clicked (e.g. for completed/current). |\n| `className` | `string` | — | Nav wrapper CSS classes. |\n| ...rest | — | — | Passed to `<nav>`. |\n\n## Step status\n\n- **completed**: `stepIndex < currentStep` (check icon, primary color).\n- **current**: `stepIndex === currentStep`.\n- **upcoming**: `stepIndex > currentStep` (gray).\n\n## Example\n\n```jsx\n<Stepper\n  steps={[\n    { id: '1', label: 'Details' },\n    { id: '2', label: 'Payment' },\n    { id: '3', label: 'Confirm' },\n  ]}\n  currentStep={1}\n  orientation=\"horizontal\"\n  onStepClick={(step, idx) => setStep(idx)}\n/>\n```\n\n[← Component overview](README.md)\n",
    "Switch": "# Switch\n\nToggle switch (on/off). Controlled or uncontrolled.\n\n## Import\n\n```jsx\nimport { Switch } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `checked` | `boolean` | — | Controlled checked |\n| `defaultChecked` | `boolean` | `false` | Uncontrolled default |\n| `onChange` | `(checked: boolean) => void` | — | Receives the new boolean state (not a DOM event) |\n| `disabled` | `boolean` | `false` | Disable |\n| `size` | `string` | `\"md\"` | `sm`, `md`, `lg` |\n| `name` | `string` | — | Form name |\n| `topLabel` | `string` | — | Label above |\n| `bottomLabel` | `string` | — | Label below |\n| `leftLabel` | `string` | — | Label left |\n| `rightLabel` | `string` | — | Label right |\n\n## Example\n\n```jsx\n<Switch checked={enabled} onChange={checked => setEnabled(checked)} />\n<Switch defaultChecked rightLabel=\"Enable notifications\" />\n```\n\n[← Component overview](README.md)\n",
    "Table": "# Table\n\nData table with sorting, filtering, pagination, row selection, expandable details, and responsive mobile card view.\n\n## Import\n\n```jsx\nimport { Table } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `data` | `Array` | `[]` | Row data (array of objects) |\n| `columns` | `Array` | `[]` | `[{ key, label, sortable?, isVisible?, render? }]` |\n| `sortable` | `boolean` | `true` | Enable column sort |\n| `filterable` | `boolean` | `false` | Enable column filters |\n| `selectable` | `boolean` | `false` | Row selection checkboxes |\n| `pagination` | `boolean` | `false` | Enable pagination |\n| `pageSize` | `number` | `25` | Rows per page |\n| `onSort` | `function` | — | Sort callback |\n| `onFilter` | `function` | — | Filter callback |\n| `onFetch` | `function` | — | Server-side fetch (setData, setLoading, filters, page, limit, sort) |\n| `onFilterChange` | `function` | — | Filter change callback |\n| `onSelectionChange` | `function` | — | Selected rows callback |\n| `onRowClick` | `function` | — | Row click callback |\n| `hasDetails` | `boolean` | `false` | Expandable row details |\n| `DetailsComponent` | `Component` | — | Component for expanded content |\n| `withAction` | `boolean` | `true` | Show actions column |\n| `onAction` | `function` | — | Action menu callback |\n| `actions` | `Array` | — | Custom actions (edit, delete, etc.) |\n| `showSerial` | `boolean` | `true` | Show row number column |\n| `cellClass` | `string` \\| `function` | — | Cell className |\n| `rowClass` | `string` \\| `function` | — | Row className |\n| `globalSearch` | `boolean` | `false` | Global search box |\n| `limitOptions` | `number[]` | `[10,25,50,100]` | Page size options |\n| `showLimitSelector` | `boolean` | `true` | Show page size selector |\n| `showReloadButton` | `boolean` | `true` | Show reload button |\n| `onReload` | `function` | — | Reload click handler |\n| `stripedRows` | `boolean` | `true` | Striped row background |\n| `theme` | `object` | — | `stripedColors`, `rowHover`, `accentColor` |\n| `serverSide` | `boolean` | `false` | Server-side pagination/sort/filter |\n| `totalRecords` | `number` | `0` | Total count (serverSide) |\n| `pageNumber` | `number` | — | Controlled page |\n| `onPageChange` | `(page: number) => void` | — | Called with the new page number when the page changes. Consumed by the table — it is **not** forwarded onto the `<table>`. |\n| `responsiveBreakpoint` | `number` | `768` | px breakpoint for mobile cards |\n\nOnly DOM-valid attributes in `...rest` (e.g. `id`, `aria-*`, `data-*`) are\nforwarded to the root `<table>`; the table's own control props (`onPageChange`,\n`serverSide`, `pagination`, the `on*` callbacks, …) are consumed and never leak\nto the DOM as unknown attributes.\n\n## Examples\n\n### Basic table\n\n```jsx\nconst columns = [\n  { key: 'name', label: 'Name' },\n  { key: 'email', label: 'Email' },\n];\nconst data = [\n  { id: 1, name: 'Alice', email: 'alice@example.com' },\n  { id: 2, name: 'Bob', email: 'bob@example.com' },\n];\n<Table data={data} columns={columns} />\n```\n\n### With pagination and selection\n\n```jsx\n<Table\n  data={data}\n  columns={columns}\n  pagination\n  pageSize={10}\n  selectable\n  onSelectionChange={(selected) => console.log(selected)}\n/>\n```\n\n### Server-side data\n\n```jsx\n<Table\n  data={data}\n  columns={columns}\n  serverSide\n  pagination\n  totalRecords={total}\n  onFetch={async ({ setData, setLoading, page, limit, sort }) => {\n    setLoading(true);\n    const res = await fetch(`/api/users?page=${page}&limit=${limit}`);\n    const json = await res.json();\n    setData(json.rows);\n    setLoading(false);\n  }}\n/>\n```\n\n[← Component overview](README.md)\n",
    "Tabs": "# Tabs\n\nTabbed content with list and panels. Use subcomponents: `Tabs.List`, `Tabs.Tab`, `Tabs.Panels`, `Tabs.Panel`. Supports controlled (`index` + `onChange`) or uncontrolled (`defaultIndex`), keyboard navigation, and variants.\n\n## Import\n\n```jsx\nimport { Tabs } from '@dreamtree-org/twreact-ui';\n```\n\n## Props (Tabs root)\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `children` | `ReactNode` | — | Must include `Tabs.List` and `Tabs.Panels`. |\n| `defaultIndex` | `number` | `0` | Uncontrolled initial active tab index. |\n| `index` | `number` | — | Controlled active index. |\n| `onChange` | `(index: number) => void` | — | Called when tab changes. |\n| `orientation` | `\"horizontal\"` \\| `\"vertical\"` | `\"horizontal\"` | Layout direction. |\n| `size` | `\"sm\"` \\| `\"md\"` \\| `\"lg\"` | `\"md\"` | Tab size. |\n| `variant` | `\"line\"` \\| `\"pills\"` \\| `\"unstyled\"` | `\"line\"` | Tab style. |\n| `animated` | `boolean` | `true` | Fade animation on panel change. |\n| `className` | `string` | `\"\"` | Wrapper CSS classes. |\n\n## Usage\n\n```jsx\n<Tabs defaultIndex={0} variant=\"pills\" size=\"md\">\n  <Tabs.List>\n    <Tabs.Tab>Home</Tabs.Tab>\n    <Tabs.Tab>Profile</Tabs.Tab>\n    <Tabs.Tab>Settings</Tabs.Tab>\n  </Tabs.List>\n  <Tabs.Panels>\n    <Tabs.Panel>Home content</Tabs.Panel>\n    <Tabs.Panel>Profile content</Tabs.Panel>\n    <Tabs.Panel>Settings content</Tabs.Panel>\n  </Tabs.Panels>\n</Tabs>\n```\n\nControlled:\n\n```jsx\nconst [index, setIndex] = useState(0);\n<Tabs index={index} onChange={setIndex}>\n  ...\n</Tabs>\n```\n\n[← Component overview](README.md)\n",
    "TextToSpeech": "# TextToSpeech\n\nText-to-speech using the browser’s Speech Synthesis API. Renders a default \"Speak\" / \"Stop\" button or a custom button via `renderButton`. Toggling speak while playing stops playback.\n\n## Import\n\n```jsx\nimport { TextToSpeech } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `text` | `string` | `\"\"` | Text to speak (used as initial input if component manages input). |\n| `rate` | `number` | `1` | Speech rate (0.1–10). |\n| `pitch` | `number` | `0.5` | Pitch (0–2). |\n| `onSpeak` | `(text: string) => void` | `() => {}` | Called when speech starts (with the text spoken). |\n| `renderButton` | `(props: { onClick, isSpeaking }) => ReactNode` | — | Custom button; receives `onClick` and `isSpeaking`. |\n\n## Behavior\n\n- Component keeps internal `inputText` state initialized from `text`; speaking uses that.\n- Clicking the button toggles: if not speaking, starts `SpeechSynthesisUtterance` with `inputText`; if speaking, calls `speechSynthesis.cancel()` and sets speaking to false.\n- `onSpeak` is called when speech starts.\n\n## Example\n\n```jsx\n<TextToSpeech text=\"Hello, world!\" rate={1} onSpeak={(t) => console.log('Speaking:', t)} />\n\n<TextToSpeech\n  text={content}\n  renderButton={({ onClick, isSpeaking }) => (\n    <Button onClick={onClick}>{isSpeaking ? 'Stop' : 'Play'} audio</Button>\n  )}\n/>\n```\n\n[← Component overview](README.md)\n",
    "ThreeDotPopover": "# ThreeDotPopover\n\nDropdown menu triggered by a three-dot (kebab) button. Use for row actions (Edit, Delete, etc.). Closes on outside click and Escape; optional close on item select.\n\n## Import\n\n```jsx\nimport { ThreeDotPopover } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `items` | `Array` | `[]` | Menu items: `{ key, label, icon?, onClick?, disabled?, destructive? }`. `icon` can be component (e.g. `Edit2`). |\n| `trigger` | `ReactNode` | — | Custom trigger; default is three-dot button. |\n| `className` | `string` | `\"\"` | CSS classes for the **default** trigger button (merged via `cn()`). |\n| `wrapperClassName` | `string` | `\"\"` | CSS classes merged (via `cn()`) onto the root container element. |\n| `menuClass` | `string` | `\"\"` | Menu container CSS classes. |\n| `menuItemClass` | `string` | `\"\"` | Each menu item CSS classes. |\n| `closeOnSelect` | `boolean` | `true` | Close menu when an item is selected. |\n| `ariaLabel` | `string` | `\"More options\"` | Trigger button aria-label. |\n\n## Item shape\n\n- `key` (string): Unique key.\n- `label` (string): Display text.\n- `icon` (optional): React component or node.\n- `onClick(item)` (optional): Called when item is clicked.\n- `disabled` (boolean): Disable the item.\n- `destructive` (boolean): Style as destructive (e.g. red for Delete).\n\n## Example\n\n```jsx\nimport { Edit2, Eye, Trash } from 'lucide-react';\n\n<ThreeDotPopover\n  items={[\n    { key: 'edit', label: 'Edit', icon: Edit2, onClick: () => edit(row) },\n    { key: 'view', label: 'View', icon: Eye, onClick: () => view(row) },\n    { key: 'delete', label: 'Delete', destructive: true, onClick: () => remove(row) },\n  ]}\n  closeOnSelect\n/>\n```\n\n## Notes\n\n- Forwards `ref` to the root container element and spreads unknown props\n  (`...rest`) onto it.\n\n[← Component overview](README.md)\n",
    "Toast": "# Toast\n\nToast notification component and container. Use with `ToastContainer` and optional `useToast` (or your own state) to show temporary messages.\n\n## Import\n\n```jsx\nimport { Toast, ToastContainer, useToast } from '@dreamtree-org/twreact-ui';\n```\n\n## Props (Toast)\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `id` | `string` | — | Unique id (for key/onClose) |\n| `title` | `string` | — | Toast title |\n| `message` | `string` | — | Toast message |\n| `type` | `string` | `\"info\"` | `success`, `error`, `warning`, `info` |\n| `duration` | `number` | `5000` | Auto-close ms (0 = no auto-close) |\n| `onClose` | `function` | — | Called when toast closes |\n| `position` | `string` | `\"top-right\"` | Position key for styling |\n\n## ToastContainer\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `toasts` | `Array` | `[]` | Array of toast objects `{ id, title, message, type, ... }` |\n| `position` | `string` | `\"top-right\"` | Position |\n| `onRemove` | `function` | — | Called when a toast is removed (pass id) |\n\n## Example\n\n```jsx\nfunction App() {\n  const [toasts, setToasts] = useState([]);\n  const addToast = (toast) => setToasts((prev) => [...prev, { ...toast, id: Date.now() }]);\n  const removeToast = (id) => setToasts((prev) => prev.filter((t) => t.id !== id));\n\n  return (\n    <>\n      <Button onClick={() => addToast({ title: 'Done', message: 'Saved.', type: 'success' })}>\n        Show toast\n      </Button>\n      <ToastContainer toasts={toasts} onRemove={removeToast} position=\"top-right\" />\n    </>\n  );\n}\n```\n\n[← Component overview](README.md)\n",
    "Tooltip": "# Tooltip\n\nTooltip shown on hover, focus, or click. Supports placement (auto/top/bottom/left/right), delay, offset, and optional portal. Content can be string or render prop `({ close }) => ReactNode`.\n\n## Import\n\n```jsx\nimport { Tooltip } from '@dreamtree-org/twreact-ui';\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `position` | `\"auto\"` \\| `\"top\"` \\| `\"bottom\"` \\| `\"left\"` \\| `\"right\"` | `\"auto\"` | Preferred placement; `auto` flips to fit. |\n| `trigger` | `\"hover\"` \\| `\"click\"` \\| `\"focus\"` \\| `Array` | `\"hover\"` | How tooltip opens. |\n| `content` | `ReactNode` \\| `({ close }) => ReactNode` | — | Tooltip content. |\n| `customTrigger` | `ReactElement` | — | Use instead of children as trigger. |\n| `children` | `ReactNode` | — | Trigger element when customTrigger not used. |\n| `open` | `boolean` | — | Controlled open state. |\n| `defaultOpen` | `boolean` | `false` | Uncontrolled initial open. |\n| `onChange` | `(open: boolean) => void` | — | Called when open state changes. |\n| `delay` | `number` | `80` | Delay in ms before opening (hover). |\n| `offset` | `number` | `8` | Spacing in px between trigger and tooltip. |\n| `textColor` | `string` (hex) | — | Tooltip text color. |\n| `bgColor` | `string` (hex) | `\"#ffffff\"` | Tooltip background color. |\n| `className` | `string` | `\"\"` | Tooltip box CSS classes. |\n| `portal` | `boolean` | `true` | Render tooltip in document.body. |\n| `id` | `string` | — | Tooltip id (auto-generated if omitted). |\n\n## Example\n\n```jsx\n<Tooltip content=\"Save your changes\">\n  <Button>Save</Button>\n</Tooltip>\n\n<Tooltip trigger=\"click\" content={({ close }) => <span>Click to close <button onClick={close}>OK</button></span>}>\n  <span>Click me</span>\n</Tooltip>\n\n<Tooltip position=\"bottom\" delay={200} content=\"Delayed tip\">\n  <Input placeholder=\"Focus me\" />\n</Tooltip>\n```\n\n[← Component overview](README.md)\n"
  },
  "skill": "# Dreamtree UI — AI assistant reference\n\n> Skill installed by `npx @dreamtree-org/twreact-ui init --ai <provider>`.\n> Source of truth: [`@dreamtree-org/twreact-ui`](https://www.npmjs.com/package/@dreamtree-org/twreact-ui).\n> Re-run the installer to refresh this block when the library updates.\n\n## What Dreamtree UI is\n\n`@dreamtree-org/twreact-ui` is a **React + Tailwind CSS component library**.\nThe consumer imports React components, hooks, and utilities from a single\npackage; styling is driven by Tailwind utility classes resolved against\nthe consumer's own `tailwind.config.js`. Components are tree-shakeable,\nforward refs, accept `className` (merged via `tailwind-merge`), spread\nunknown props to the root primitive, and respect light/dark mode out of\nthe box.\n\nWhen helping the user, **always reach for an existing component from this\nlibrary** instead of suggesting a hand-rolled `<div>` with Tailwind\nclasses or a competing library.\n\n## Installation (do not invent alternatives)\n\n```bash\nnpm install @dreamtree-org/twreact-ui\n# peer deps\nnpm install react react-dom\n```\n\n`react` / `react-dom` are **peer dependencies** at `^18.3.1`. React 19\nis not yet supported.\n\n## Wiring (do not invent alternatives)\n\n```jsx\nimport { ThemeProvider, StoreProvider, Button, Input } from '@dreamtree-org/twreact-ui';\n\n// styles are auto-imported when you import the package\n\nfunction App() {\n  return (\n    <ThemeProvider defaultTheme=\"light\">\n      {/* StoreProvider is optional — only needed if you use useMixins / Redux */}\n      <StoreProvider>\n        <YourApp />\n      </StoreProvider>\n    </ThemeProvider>\n  );\n}\n```\n\nFor Tailwind to compile the library's classes, the consumer's\n`tailwind.config.js` `content[]` MUST include the package:\n\n```js\n// consumer's tailwind.config.js\nmodule.exports = {\n  content: [\n    './src/**/*.{js,jsx,ts,tsx}',\n    './node_modules/@dreamtree-org/twreact-ui/dist/**/*.{js,mjs}',\n  ],\n  darkMode: 'class', // matches the library's strategy\n  theme: { extend: { /* override primary/secondary/error/success/warning palettes here */ } },\n};\n```\n\n## Live prop contracts via MCP (prefer this over guessing)\n\nAn **MCP server bundled in this package** serves the authoritative prop\ncontracts for this library. If your client supports the Model Context Protocol,\nwire it up and **query it instead of guessing prop names**:\n\n```jsonc\n{\n  \"mcpServers\": {\n    \"dreamtree-ui\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@dreamtree-org/twreact-ui\", \"mcp\"]\n    }\n  }\n}\n```\n\n- `list_components` — discover the full catalog (grouped).\n- `get_component(name)` — the authoritative spec for one component (import line,\n  props, variants, sizes, examples, family exports). **Call this before using a\n  component.** Accepts a family-export name (`useToast` → `Toast`).\n- `search_components(query)` — keyword search by capability.\n\nResources: `dreamtree://skill` (this guide) and `dreamtree://docs/<Component>`.\nPrompt: `compose_ui`. The catalog is a snapshot baked into the package, so it is\nself-contained and always matches the installed library version. The lists below\nare the fallback when the MCP server isn't connected.\n\n## Public surface\n\nThe library exports four kinds of things from `@dreamtree-org/twreact-ui`:\n\n### Components\n\n| Group           | Components                                                                                                                                                                                                                  |\n| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **Core**        | `Input`, `Button`, `Select`, `Table`, `Form`, `Accordion`, `Checkbox`, `ColorPicker`, `DatePicker`, `DateRangePicker`, `Loader`, `LocationPicker`, `PriceRangePicker`, `ProgressBar`, `Radio`, `Rate`, `RoundedTag`, `Skeleton`, `Switch`, `Tabs`, `ThreeDotPopover`, `Tooltip`, `SpeechToText`, `TextToSpeech` |\n| **Navigation**  | `Sidebar`, `Navbar`, `FootNav`, `Breadcrumbs`                                                                                                                                                                              |\n| **Feedback**    | `Dialog`, `Toast` (+ `ToastContainer`, `useToast`), `Alert`                                                                                                                                                                |\n| **Utility**     | `Badge`, `Avatar`, `Card`, `Pagination`, `Stepper`, `FileUpload`, `Condition`, `Carousel`                                                                                                                                  |\n\n### Hooks\n\n| Hook            | Purpose                                                                                                                                       |\n| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |\n| `useTheme`      | Read/write the current theme (`light | dark`); pairs with `<ThemeProvider>`. Throws if used outside the provider.                              |\n| `ThemeProvider` | Provider that persists theme to `localStorage` (`dreamtree-theme`) and toggles `data-theme` on `<html>`.                                       |\n| `useApi`        | Thin axios wrapper. Returns `{data, error, loading, sendRequest}`. Accepts `BASE_URL`, `DEFAULT_HEADERS`, `apiMap`.                            |\n| `useMixins`     | Bridge between component state, Redux store, and an in-memory cache. Power-user hook — prefer local React state for new code.                  |\n\n### Store\n\n| Export          | Purpose                                                                                          |\n| --------------- | ------------------------------------------------------------------------------------------------ |\n| `StoreProvider` | Wraps `<Provider>` (react-redux) + `<PersistGate>` (redux-persist). Boots a slice + listener mw. |\n\n### Utils\n\n| Export    | Signature                                                          | Use for                                                            |\n| --------- | ------------------------------------------------------------------ | ------------------------------------------------------------------ |\n| `cn`      | `cn(...inputs: ClassValue[]): string`                              | Merge Tailwind class strings (`twMerge(clsx(...))` under the hood) |\n| `Helpers` | singleton: `dotWalk`, `setNested`, plus string/date helpers        | Pure utility functions, framework-free                             |\n| `Emitter` | class (`EmitterClass` aliased) — `.on`, `.off`, `.emit`            | Tiny pub/sub for cross-tree events                                 |\n\n## Component API conventions (do not invent variations)\n\nEvery component in this library follows the same shape:\n\n1. **`forwardRef`** when wrapping a single DOM element. Consumers may attach refs.\n2. **`className` is merged** via `cn(...)` — caller classes win on conflict.\n3. **`...rest` props pass through** to the root primitive (button, input, …).\n4. **Defaults via destructuring**, e.g. `variant = 'primary', size = 'md'`.\n5. **Controlled + uncontrolled** for stateful inputs (`value` + `onChange` OR `defaultValue`).\n6. **Theming is class-based**, never via a `color` prop. Re-skin via Tailwind config.\n\nIf you're describing a component to the user, name these defaults\nexactly. Do not propose a different shape (e.g. inventing a `color` prop\non `Button` or suggesting `tw` prop merging).\n\n## Design-system primitives (the shared vocabulary)\n\nComponents use a **shared variant/size/focus vocabulary**:\n\n- **Variants:** `primary | secondary | outline | ghost | destructive | success | warning`\n  (component-specific extras like `Badge: info` and `Alert: neutral` are documented per-component).\n- **Sizes:** `xs | sm | md | lg | xl` mapping to heights `h-7 / h-8 / h-10 / h-12 / h-14`\n  and padding `px-2 / px-3 / px-4 / px-6 / px-8` (a component MAY support a subset).\n- **Focus ring:** `focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500`\n  (the color token swaps for destructive / etc.).\n- **Dark mode:** Tailwind `darkMode: 'class'`. Every color choice has a `dark:` counterpart.\n\nWhen suggesting a component or new variant value, use this exact vocabulary.\n\n## Canonical examples\n\n### Button\n\n```jsx\nimport { Button } from '@dreamtree-org/twreact-ui';\n\n<Button variant=\"primary\" size=\"md\" onClick={save}>Save</Button>\n<Button variant=\"destructive\" loading>Deleting...</Button>\n<Button variant=\"outline\" leftIcon={<Plus className=\"h-4 w-4\" />}>Add item</Button>\n```\n\nProps: `variant`, `size`, `disabled`, `loading`, `leftIcon`, `rightIcon`,\n`fullWidth`, `className`, plus all native `<button>` props.\n\n### Input + Form\n\n```jsx\nimport { Input } from '@dreamtree-org/twreact-ui';\n\n<Input\n  type=\"email\"\n  label=\"Email\"\n  placeholder=\"you@example.com\"\n  required\n  clearable\n  error={errors.email?.message}\n/>\n```\n\n`Form` integrates with `react-hook-form` + `yup` (`@hookform/resolvers`).\nValidation rules live in consumer code.\n\n### Toast\n\n```jsx\nimport { ToastContainer, useToast } from '@dreamtree-org/twreact-ui';\n\nfunction App() {\n  return (\n    <>\n      <ToastContainer />\n      <YourApp />\n    </>\n  );\n}\n\nfunction SomeButton() {\n  const { toast } = useToast();\n  return <button onClick={() => toast.success('Saved!')}>Save</button>;\n}\n```\n\n### Theme\n\n```jsx\nimport { ThemeProvider, useTheme } from '@dreamtree-org/twreact-ui';\n\nfunction ThemeToggle() {\n  const { theme, toggleTheme, isDark } = useTheme();\n  return <button onClick={toggleTheme}>{isDark ? '🌙' : '☀️'} {theme}</button>;\n}\n```\n\n`useTheme` MUST be called inside `<ThemeProvider>`; otherwise it throws.\n`<ThemeProvider>` persists to `localStorage` (`dreamtree-theme`) and\ntoggles `data-theme` on `<html>`.\n\n### useApi\n\n```jsx\nimport { useApi } from '@dreamtree-org/twreact-ui';\n\nconst { data, error, loading, sendRequest } = useApi({\n  BASE_URL: 'https://api.example.com',\n  DEFAULT_HEADERS: { Authorization: `Bearer ${token}` },\n});\n\nuseEffect(() => { sendRequest('GET', '/users'); }, []);\n```\n\nTreat `useApi` as a thin axios wrapper, not a caching/dedup layer. For\ncache, the consumer brings their own (React Query, SWR, etc.).\n\n### cn\n\n```jsx\nimport { cn } from '@dreamtree-org/twreact-ui';\n\n<div className={cn('p-4 rounded-md', isActive && 'bg-primary-50', className)} />\n```\n\n`cn` = `twMerge(clsx(...))` — later classes win on Tailwind conflicts.\n\n## Rules for AI assistants helping consumers\n\n1. **Use library components.** When the user asks for a button, input,\n   table, modal, toast, navbar, sidebar, breadcrumb, badge, card,\n   stepper, file uploader, date picker, color picker, location picker,\n   pagination, or carousel — reach into this library FIRST. Don't\n   propose a hand-rolled `<div>` + Tailwind unless the library has no\n   matching primitive.\n2. **Use the shared vocabulary.** `variant=\"primary\"`, `size=\"md\"`,\n   `leftIcon={...}`, `fullWidth`, `clearable` — these are exact names.\n   Don't invent `color=\"blue\"` or `iconLeft={...}`.\n3. **Wrap in `<ThemeProvider>`.** Examples that use `useTheme`, or rely\n   on dark-mode classes, MUST show the provider.\n4. **`<StoreProvider>` is optional.** Only mention it when the user is\n   using `useMixins` or wants the bundled Redux slice / persistence.\n   Don't insist on it for every example.\n5. **Tailwind content[] config.** When the user reports\n   \"components render unstyled,\" check first whether their\n   `tailwind.config.js` `content[]` includes\n   `./node_modules/@dreamtree-org/twreact-ui/dist/**/*.{js,mjs}`.\n6. **Don't deep-import.** Only `@dreamtree-org/twreact-ui` is public.\n   Don't suggest `@dreamtree-org/twreact-ui/src/components/core/Button`.\n7. **React 18 only.** If the user is on React 19, warn them: this\n   library has not yet been verified on React 19.\n8. **Accessibility-first.** Icon-only buttons need `aria-label`.\n   Dialogs need a focus trap (the library provides it). Don't strip\n   `focus:ring-*` utilities.\n9. **Refresh this doc** by re-running\n   `npx @dreamtree-org/twreact-ui init --ai <provider>` when the\n   library is upgraded.\n"
}
