@multicomma/arkcn 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/README.md +7 -0
  2. package/cli/commands.mjs +12 -5
  3. package/cli/project.mjs +62 -16
  4. package/cli/registry.mjs +1 -0
  5. package/package.json +42 -32
  6. package/registry/index.json +1578 -156
  7. package/registry/items/accordion.json +11 -1
  8. package/registry/items/activity-feed.json +18 -2
  9. package/registry/items/alert-dialog.json +18 -1
  10. package/registry/items/alert.json +7 -1
  11. package/registry/items/angle-slider.json +13 -1
  12. package/registry/items/app-shell.json +58 -2
  13. package/registry/items/aspect-ratio.json +3 -0
  14. package/registry/items/attachment.json +12 -1
  15. package/registry/items/avatar.json +11 -1
  16. package/registry/items/badge.json +5 -1
  17. package/registry/items/breadcrumb.json +10 -1
  18. package/registry/items/bubble.json +7 -1
  19. package/registry/items/button-group.json +8 -2
  20. package/registry/items/button.json +5 -1
  21. package/registry/items/calendar.json +5 -1
  22. package/registry/items/canvas.json +20 -3
  23. package/registry/items/card.json +10 -1
  24. package/registry/items/carousel.json +9 -1
  25. package/registry/items/cascader.json +24 -3
  26. package/registry/items/chart.json +9 -1
  27. package/registry/items/chat.json +44 -3
  28. package/registry/items/checkbox.json +13 -1
  29. package/registry/items/clipboard.json +12 -1
  30. package/registry/items/collapsible.json +8 -0
  31. package/registry/items/color-picker.json +34 -1
  32. package/registry/items/combobox.json +31 -1
  33. package/registry/items/command.json +20 -1
  34. package/registry/items/comment-thread.json +36 -4
  35. package/registry/items/context-menu.json +28 -1
  36. package/registry/items/data-grid.json +21 -4
  37. package/registry/items/data-table.json +35 -3
  38. package/registry/items/date-input.json +12 -1
  39. package/registry/items/dialog.json +16 -1
  40. package/registry/items/direction.json +4 -0
  41. package/registry/items/drawer.json +21 -1
  42. package/registry/items/dropdown-menu.json +27 -1
  43. package/registry/items/editable.json +14 -1
  44. package/registry/items/empty.json +9 -1
  45. package/registry/items/field.json +14 -2
  46. package/registry/items/file-upload.json +18 -1
  47. package/registry/items/floating-panel.json +18 -1
  48. package/registry/items/floating-toolbar.json +4 -1
  49. package/registry/items/format.json +7 -0
  50. package/registry/items/gantt.json +28 -3
  51. package/registry/items/{use-mobile.json → hooks/use-mobile.json} +4 -1
  52. package/registry/items/hotkeys.json +11 -1
  53. package/registry/items/hover-card.json +11 -1
  54. package/registry/items/image-cropper.json +11 -1
  55. package/registry/items/input-group.json +10 -2
  56. package/registry/items/input-otp.json +7 -1
  57. package/registry/items/input.json +4 -1
  58. package/registry/items/item.json +14 -2
  59. package/registry/items/json-tree-view.json +6 -1
  60. package/registry/items/kanban.json +29 -3
  61. package/registry/items/kbd.json +5 -1
  62. package/registry/items/label.json +4 -1
  63. package/registry/items/{controllable.json → lib/controllable.json} +4 -1
  64. package/registry/items/{data-table-adapter.json → lib/data-table-adapter.json} +2 -1
  65. package/registry/items/{drag-preview.json → lib/drag-preview.json} +4 -1
  66. package/registry/items/{form.json → lib/form.json} +4 -1
  67. package/registry/items/{history.json → lib/history.json} +4 -1
  68. package/registry/items/{row-layout.json → lib/row-layout.json} +6 -1
  69. package/registry/items/lib/table.json +19 -0
  70. package/registry/items/{time.json → lib/time.json} +5 -1
  71. package/registry/items/{utils.json → lib/utils.json} +4 -1
  72. package/registry/items/live-region.json +5 -1
  73. package/registry/items/marker.json +7 -1
  74. package/registry/items/marquee.json +10 -1
  75. package/registry/items/menubar.json +26 -2
  76. package/registry/items/message.json +9 -1
  77. package/registry/items/navigation-menu.json +17 -1
  78. package/registry/items/node-graph.json +33 -2
  79. package/registry/items/number-input.json +14 -1
  80. package/registry/items/pagination.json +10 -1
  81. package/registry/items/password-input.json +11 -1
  82. package/registry/items/popconfirm.json +14 -2
  83. package/registry/items/popover.json +17 -1
  84. package/registry/items/progress.json +15 -1
  85. package/registry/items/qr-code.json +10 -1
  86. package/registry/items/query-builder.json +32 -3
  87. package/registry/items/radio-group.json +13 -1
  88. package/registry/items/rating-group.json +11 -1
  89. package/registry/items/resizable.json +6 -1
  90. package/registry/items/rich-text-editor.json +19 -2
  91. package/registry/items/scheduler.json +35 -3
  92. package/registry/items/scroll-area.json +11 -1
  93. package/registry/items/segment-group.json +13 -1
  94. package/registry/items/select.json +26 -1
  95. package/registry/items/separator.json +4 -1
  96. package/registry/items/sheet.json +16 -1
  97. package/registry/items/sidebar.json +29 -3
  98. package/registry/items/signature-pad.json +12 -1
  99. package/registry/items/skeleton.json +4 -1
  100. package/registry/items/slider.json +17 -1
  101. package/registry/items/sonner.json +3 -0
  102. package/registry/items/spinner.json +4 -1
  103. package/registry/items/steps.json +17 -1
  104. package/registry/items/swap.json +6 -1
  105. package/registry/items/switch.json +11 -1
  106. package/registry/items/table.json +15 -5
  107. package/registry/items/tabs.json +11 -1
  108. package/registry/items/tags-input.json +17 -1
  109. package/registry/items/textarea.json +4 -1
  110. package/registry/items/timer.json +11 -1
  111. package/registry/items/toc.json +13 -1
  112. package/registry/items/toggle-group.json +8 -2
  113. package/registry/items/toggle.json +8 -1
  114. package/registry/items/tooltip.json +12 -1
  115. package/registry/items/tour.json +20 -1
  116. package/registry/items/transfer-list.json +21 -3
  117. package/registry/items/tree-select.json +22 -3
  118. package/registry/items/tree-view.json +24 -1
  119. package/registry/items/virtual-list.json +10 -1
@@ -1,7 +1,10 @@
1
1
  {
2
- "name": "use-mobile",
2
+ "name": "hooks/use-mobile",
3
3
  "type": "hook",
4
4
  "description": "",
5
+ "exports": [
6
+ "useIsMobile"
7
+ ],
5
8
  "dependencies": {},
6
9
  "registryDependencies": [],
7
10
  "files": [
@@ -2,11 +2,21 @@
2
2
  "name": "hotkeys",
3
3
  "type": "ui",
4
4
  "description": "-------------------------------- parsing --------------------------------",
5
+ "exports": [
6
+ "HotkeyKbd",
7
+ "HotkeysDialog",
8
+ "HotkeysProvider",
9
+ "formatHotkey",
10
+ "parseHotkey",
11
+ "useHotkey",
12
+ "useHotkeys",
13
+ "useHotkeysDialog"
14
+ ],
5
15
  "dependencies": {},
6
16
  "registryDependencies": [
7
17
  "dialog",
8
18
  "kbd",
9
- "utils"
19
+ "lib/utils"
10
20
  ],
11
21
  "files": [
12
22
  {
@@ -2,11 +2,21 @@
2
2
  "name": "hover-card",
3
3
  "type": "ui",
4
4
  "description": "",
5
+ "ark": "HoverCard",
6
+ "exports": [
7
+ "HoverCard",
8
+ "HoverCardArrow",
9
+ "HoverCardContent",
10
+ "HoverCardContext",
11
+ "HoverCardPortal",
12
+ "HoverCardPositioner",
13
+ "HoverCardTrigger"
14
+ ],
5
15
  "dependencies": {
6
16
  "@ark-ui/react": "^5.39.1"
7
17
  },
8
18
  "registryDependencies": [
9
- "utils"
19
+ "lib/utils"
10
20
  ],
11
21
  "files": [
12
22
  {
@@ -2,11 +2,21 @@
2
2
  "name": "image-cropper",
3
3
  "type": "ui",
4
4
  "description": "",
5
+ "ark": "ImageCropper",
6
+ "exports": [
7
+ "ImageCropper",
8
+ "ImageCropperContext",
9
+ "ImageCropperGrid",
10
+ "ImageCropperHandle",
11
+ "ImageCropperImage",
12
+ "ImageCropperSelection",
13
+ "ImageCropperViewport"
14
+ ],
5
15
  "dependencies": {
6
16
  "@ark-ui/react": "^5.39.1"
7
17
  },
8
18
  "registryDependencies": [
9
- "utils"
19
+ "lib/utils"
10
20
  ],
11
21
  "files": [
12
22
  {
@@ -2,14 +2,22 @@
2
2
  "name": "input-group",
3
3
  "type": "ui",
4
4
  "description": "",
5
+ "exports": [
6
+ "InputGroup",
7
+ "InputGroupAddon",
8
+ "InputGroupTrigger",
9
+ "InputGroupText",
10
+ "InputGroupInput",
11
+ "InputGroupTextarea"
12
+ ],
5
13
  "dependencies": {
6
14
  "class-variance-authority": "^0.7.1"
7
15
  },
8
16
  "registryDependencies": [
9
17
  "button",
10
18
  "input",
11
- "textarea",
12
- "utils"
19
+ "lib/utils",
20
+ "textarea"
13
21
  ],
14
22
  "files": [
15
23
  {
@@ -2,12 +2,18 @@
2
2
  "name": "input-otp",
3
3
  "type": "ui",
4
4
  "description": "",
5
+ "exports": [
6
+ "InputOTP",
7
+ "InputOTPGroup",
8
+ "InputOTPSlot",
9
+ "InputOTPSeparator"
10
+ ],
5
11
  "dependencies": {
6
12
  "input-otp": "^1.5.0",
7
13
  "lucide-react": "^1.41.0"
8
14
  },
9
15
  "registryDependencies": [
10
- "utils"
16
+ "lib/utils"
11
17
  ],
12
18
  "files": [
13
19
  {
@@ -2,9 +2,12 @@
2
2
  "name": "input",
3
3
  "type": "ui",
4
4
  "description": "",
5
+ "exports": [
6
+ "Input"
7
+ ],
5
8
  "dependencies": {},
6
9
  "registryDependencies": [
7
- "utils"
10
+ "lib/utils"
8
11
  ],
9
12
  "files": [
10
13
  {
@@ -2,13 +2,25 @@
2
2
  "name": "item",
3
3
  "type": "ui",
4
4
  "description": "",
5
+ "exports": [
6
+ "Item",
7
+ "ItemMedia",
8
+ "ItemContent",
9
+ "ItemActions",
10
+ "ItemGroup",
11
+ "ItemSeparator",
12
+ "ItemTitle",
13
+ "ItemDescription",
14
+ "ItemHeader",
15
+ "ItemFooter"
16
+ ],
5
17
  "dependencies": {
6
18
  "@ark-ui/react": "^5.39.1",
7
19
  "class-variance-authority": "^0.7.1"
8
20
  },
9
21
  "registryDependencies": [
10
- "separator",
11
- "utils"
22
+ "lib/utils",
23
+ "separator"
12
24
  ],
13
25
  "files": [
14
26
  {
@@ -2,11 +2,16 @@
2
2
  "name": "json-tree-view",
3
3
  "type": "ui",
4
4
  "description": "",
5
+ "ark": "JsonTreeView",
6
+ "exports": [
7
+ "JsonTreeView",
8
+ "JsonTreeViewTree"
9
+ ],
5
10
  "dependencies": {
6
11
  "@ark-ui/react": "^5.39.1"
7
12
  },
8
13
  "registryDependencies": [
9
- "utils"
14
+ "lib/utils"
10
15
  ],
11
16
  "files": [
12
17
  {
@@ -2,6 +2,32 @@
2
2
  "name": "kanban",
3
3
  "type": "ui",
4
4
  "description": "Kanban — a compositional, data-agnostic board on Pragmatic drag and drop. The consumer owns columns and cards and re-renders them from its own state; the primitive wires dragging and reports intents through `onCardMove` and `onColumnMove`. ",
5
+ "exports": [
6
+ "Kanban",
7
+ "KanbanAddTrigger",
8
+ "KanbanBoard",
9
+ "KanbanCard",
10
+ "KanbanCardDescription",
11
+ "KanbanCardFooter",
12
+ "KanbanCardHandle",
13
+ "KanbanCardHeader",
14
+ "KanbanCardTitle",
15
+ "KanbanColumn",
16
+ "KanbanColumnActions",
17
+ "KanbanColumnContent",
18
+ "KanbanColumnCount",
19
+ "KanbanColumnFooter",
20
+ "KanbanColumnHandle",
21
+ "KanbanColumnHeader",
22
+ "KanbanColumnTitle",
23
+ "KanbanDropIndicator",
24
+ "KanbanDropSlot",
25
+ "KanbanEmpty",
26
+ "moveCard",
27
+ "moveColumn",
28
+ "useKanban",
29
+ "useKanbanColumn"
30
+ ],
5
31
  "dependencies": {
6
32
  "@ark-ui/react": "^5.39.1",
7
33
  "@atlaskit/pragmatic-drag-and-drop": "^3.1.0",
@@ -12,9 +38,9 @@
12
38
  "registryDependencies": [
13
39
  "badge",
14
40
  "button",
15
- "drag-preview",
16
- "live-region",
17
- "utils"
41
+ "lib/drag-preview",
42
+ "lib/utils",
43
+ "live-region"
18
44
  ],
19
45
  "files": [
20
46
  {
@@ -2,9 +2,13 @@
2
2
  "name": "kbd",
3
3
  "type": "ui",
4
4
  "description": "",
5
+ "exports": [
6
+ "Kbd",
7
+ "KbdGroup"
8
+ ],
5
9
  "dependencies": {},
6
10
  "registryDependencies": [
7
- "utils"
11
+ "lib/utils"
8
12
  ],
9
13
  "files": [
10
14
  {
@@ -2,9 +2,12 @@
2
2
  "name": "label",
3
3
  "type": "ui",
4
4
  "description": "Ark UI has no standalone Label primitive (its labels live inside each component's anatomy). This mirrors Radix's: a native `label` that ignores double-click text selection.",
5
+ "exports": [
6
+ "Label"
7
+ ],
5
8
  "dependencies": {},
6
9
  "registryDependencies": [
7
- "utils"
10
+ "lib/utils"
8
11
  ],
9
12
  "files": [
10
13
  {
@@ -1,7 +1,10 @@
1
1
  {
2
- "name": "controllable",
2
+ "name": "lib/controllable",
3
3
  "type": "lib",
4
4
  "description": "Both live on Ark's `TreeCollection` (`createTreeCollection`, re-exported) and a Popover, and own only the open state, the search query, and the value (`value`/`defaultValue`/`onValueChange`, always a `string[]`); the trigger is a focusable ",
5
+ "exports": [
6
+ "useControllable"
7
+ ],
5
8
  "dependencies": {},
6
9
  "registryDependencies": [],
7
10
  "files": [
@@ -1,7 +1,8 @@
1
1
  {
2
- "name": "data-table-adapter",
2
+ "name": "lib/data-table-adapter",
3
3
  "type": "lib",
4
4
  "description": "The contract the data table parts render against. `<DataTable>` accepts any object that satisfies it, so the parts are independent of where the rows, sorting, filtering, and paging come from. The built-in engine in `@/lib/table` satisfies i",
5
+ "exports": [],
5
6
  "dependencies": {},
6
7
  "registryDependencies": [],
7
8
  "files": [
@@ -1,7 +1,10 @@
1
1
  {
2
- "name": "drag-preview",
2
+ "name": "lib/drag-preview",
3
3
  "type": "lib",
4
4
  "description": "`src/components/ui/kanban.tsx` is a compositional, data-agnostic board on `@atlaskit/pragmatic-drag-and-drop` (+ `-hitbox` closest-edge/reorder index, `-auto-scroll`).",
5
+ "exports": [
6
+ "cloneDragPreview"
7
+ ],
5
8
  "dependencies": {
6
9
  "@atlaskit/pragmatic-drag-and-drop": "^3.1.0"
7
10
  },
@@ -1,7 +1,10 @@
1
1
  {
2
- "name": "form",
2
+ "name": "lib/form",
3
3
  "type": "lib",
4
4
  "description": "`src/lib/form.ts` exports `useForm(defaultValues, validate, onSubmit, { mode })`: a small, dependency-free hook (values, per-field errors, validating submit) that pairs with the `Field*` parts.",
5
+ "exports": [
6
+ "useForm"
7
+ ],
5
8
  "dependencies": {},
6
9
  "registryDependencies": [],
7
10
  "files": [
@@ -1,7 +1,10 @@
1
1
  {
2
- "name": "history",
2
+ "name": "lib/history",
3
3
  "type": "lib",
4
4
  "description": "Undo/redo state for any immutable value. `set` records a history entry unless `{ commit: false }` is passed (live drags, typing); `checkpoint` snapshots the present before such a sequence so one undo restores it.",
5
+ "exports": [
6
+ "useHistory"
7
+ ],
5
8
  "dependencies": {},
6
9
  "registryDependencies": [],
7
10
  "files": [
@@ -1,7 +1,12 @@
1
1
  {
2
- "name": "row-layout",
2
+ "name": "lib/row-layout",
3
3
  "type": "lib",
4
4
  "description": "Rows-and-columns layout helpers for the Canvas primitive. A layout is `Row[]`, each row a list of items with a `width` (flex-grow weight). Drops above/below an item create a row, beside it a column; the resize handle shifts width between ne",
5
+ "exports": [
6
+ "applyRowDrop",
7
+ "resizeRowItems",
8
+ "removeRowItem"
9
+ ],
5
10
  "dependencies": {},
6
11
  "registryDependencies": [
7
12
  "canvas"
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "lib/table",
3
+ "type": "lib",
4
+ "description": "A small headless table engine: column definitions, sorting, global and per-column filtering with faceted counts, pagination, row selection, and column visibility. No external dependencies.",
5
+ "exports": [
6
+ "useTable"
7
+ ],
8
+ "dependencies": {},
9
+ "registryDependencies": [
10
+ "lib/controllable"
11
+ ],
12
+ "files": [
13
+ {
14
+ "path": "lib/table.ts",
15
+ "content": "import * as React from \"react\"\nimport { useControllable } from \"@/lib/controllable\"\n\n/**\n * A small headless table engine: column definitions, sorting, global and\n * per-column filtering with faceted counts, pagination, row selection, and\n * column visibility. No external dependencies.\n */\n\n/* ------------------------------- Definitions ------------------------------- */\n\nexport type SortingState = { id: string; desc: boolean }[]\nexport type ColumnFiltersState = { id: string; value: unknown }[]\nexport type PaginationState = { pageIndex: number; pageSize: number }\nexport type RowSelectionState = Record<string, boolean>\nexport type VisibilityState = Record<string, boolean>\n\nexport type TableState = {\n sorting: SortingState\n columnFilters: ColumnFiltersState\n globalFilter: string\n pagination: PaginationState\n rowSelection: RowSelectionState\n columnVisibility: VisibilityState\n}\n\nexport type Updater<T> = T | ((previous: T) => T)\nexport type OnChange<T> = (updater: Updater<T>) => void\n\nexport type FilterFn<TData> = (row: Row<TData>, columnId: string, filterValue: unknown) => boolean\n\nexport type SortingFn<TData> = (a: Row<TData>, b: Row<TData>, columnId: string) => number\n\nexport type ColumnDef<TData, TValue = unknown> = {\n /** Required when no `accessorKey` is given. */\n id?: string\n /** Read the value from this property of the row. */\n accessorKey?: keyof TData & string\n /** Compute the value from the row. */\n accessorFn?: (row: TData, index: number) => TValue\n /** Human label (view options, headers); falls back to the column id. */\n label?: string\n enableSorting?: boolean\n enableHiding?: boolean\n enableGlobalFilter?: boolean\n filterFn?: FilterFn<TData>\n sortingFn?: SortingFn<TData>\n}\n\n/* ---------------------------------- Runtime -------------------------------- */\n\nexport interface Column<TData, TValue = unknown> {\n id: string\n label?: string\n columnDef: ColumnDef<TData, TValue>\n accessorFn?: (row: TData, index: number) => TValue\n getCanSort: () => boolean\n getIsSorted: () => false | \"asc\" | \"desc\"\n toggleSorting: (desc?: boolean) => void\n clearSorting: () => void\n getCanHide: () => boolean\n getIsVisible: () => boolean\n toggleVisibility: (visible?: boolean) => void\n getCanFilter: () => boolean\n getFilterValue: () => unknown\n setFilterValue: (value: unknown) => void\n getFacetedUniqueValues: () => Map<unknown, number>\n}\n\nexport interface Row<TData> {\n id: string\n index: number\n original: TData\n getValue: <TValue = unknown>(columnId: string) => TValue\n getIsSelected: () => boolean\n getCanSelect: () => boolean\n toggleSelected: (selected?: boolean) => void\n}\n\nexport interface RowModel<TData> {\n rows: Row<TData>[]\n}\n\nexport interface Table<TData> {\n options: TableOptions<TData>\n getState: () => TableState\n getAllColumns: () => Column<TData>[]\n getVisibleColumns: () => Column<TData>[]\n getColumn: (id: string) => Column<TData> | undefined\n /** All rows before filtering. */\n getCoreRowModel: () => RowModel<TData>\n /** Rows after global and column filters. */\n getFilteredRowModel: () => RowModel<TData>\n /** Filtered and sorted rows. */\n getSortedRowModel: () => RowModel<TData>\n /** The current page of sorted, filtered rows. */\n getRowModel: () => RowModel<TData>\n getFilteredSelectedRowModel: () => RowModel<TData>\n getSelectedRowModel: () => RowModel<TData>\n // sorting\n setSorting: OnChange<SortingState>\n resetSorting: () => void\n // filtering\n setGlobalFilter: (value: string) => void\n setColumnFilters: OnChange<ColumnFiltersState>\n resetColumnFilters: () => void\n // pagination\n setPagination: OnChange<PaginationState>\n setPageIndex: (index: number) => void\n setPageSize: (size: number) => void\n getPageCount: () => number\n getCanPreviousPage: () => boolean\n getCanNextPage: () => boolean\n previousPage: () => void\n nextPage: () => void\n // selection\n setRowSelection: OnChange<RowSelectionState>\n resetRowSelection: () => void\n getIsAllPageRowsSelected: () => boolean\n getIsSomePageRowsSelected: () => boolean\n toggleAllPageRowsSelected: (selected?: boolean) => void\n getIsAllRowsSelected: () => boolean\n toggleAllRowsSelected: (selected?: boolean) => void\n // visibility\n setColumnVisibility: OnChange<VisibilityState>\n resetColumnVisibility: () => void\n}\n\nexport type TableOptions<TData> = {\n data: TData[]\n columns: ColumnDef<TData, any>[] // eslint-disable-line @typescript-eslint/no-explicit-any\n getRowId?: (row: TData, index: number) => string\n enableRowSelection?: boolean | ((row: Row<TData>) => boolean)\n /** Runs against every row when `globalFilter` is set. Defaults to a case-insensitive `includes` over globally filterable columns. */\n globalFilterFn?: FilterFn<TData>\n /** Uncontrolled initial values. */\n initialState?: Partial<TableState>\n /** Controlled values; pair each with its `on*Change` handler. */\n state?: Partial<TableState>\n onSortingChange?: OnChange<SortingState>\n onColumnFiltersChange?: OnChange<ColumnFiltersState>\n onGlobalFilterChange?: OnChange<string>\n onPaginationChange?: OnChange<PaginationState>\n onRowSelectionChange?: OnChange<RowSelectionState>\n onColumnVisibilityChange?: OnChange<VisibilityState>\n /** Keep the page index inside the page count as filters change. Defaults to true. */\n autoResetPageIndex?: boolean\n}\n\n/* ----------------------------------- Helpers -------------------------------- */\n\nfunction defaultCompare(a: unknown, b: unknown) {\n if (a == null && b == null) return 0\n if (a == null) return 1\n if (b == null) return -1\n if (typeof a === \"number\" && typeof b === \"number\") return a - b\n if (a instanceof Date && b instanceof Date) return a.getTime() - b.getTime()\n return String(a).localeCompare(String(b), undefined, { numeric: true, sensitivity: \"base\" })\n}\n\nfunction defaultColumnFilter<TData>(row: Row<TData>, columnId: string, filterValue: unknown) {\n const value = row.getValue(columnId)\n if (Array.isArray(filterValue)) return filterValue.includes(value)\n if (filterValue == null || filterValue === \"\") return true\n return String(value ?? \"\")\n .toLowerCase()\n .includes(String(filterValue).toLowerCase())\n}\n\n/* ------------------------------------ Hook ---------------------------------- */\n\nexport function useTable<TData>(options: TableOptions<TData>): Table<TData> {\n const {\n data,\n columns: columnDefs,\n getRowId,\n enableRowSelection = true,\n globalFilterFn,\n initialState,\n state: controlled,\n autoResetPageIndex = true,\n } = options\n\n const [sorting, setSorting] = useControllable(\n controlled?.sorting,\n initialState?.sorting ?? [],\n options.onSortingChange\n )\n const [columnFilters, setColumnFilters] = useControllable(\n controlled?.columnFilters,\n initialState?.columnFilters ?? [],\n options.onColumnFiltersChange\n )\n const [globalFilter, setGlobalFilterState] = useControllable(\n controlled?.globalFilter,\n initialState?.globalFilter ?? \"\",\n options.onGlobalFilterChange\n )\n const [pagination, setPagination] = useControllable(\n controlled?.pagination,\n initialState?.pagination ?? { pageIndex: 0, pageSize: 10 },\n options.onPaginationChange\n )\n const [rowSelection, setRowSelection] = useControllable(\n controlled?.rowSelection,\n initialState?.rowSelection ?? {},\n options.onRowSelectionChange\n )\n const [columnVisibility, setColumnVisibility] = useControllable(\n controlled?.columnVisibility,\n initialState?.columnVisibility ?? {},\n options.onColumnVisibilityChange\n )\n\n const state: TableState = React.useMemo(\n () => ({ sorting, columnFilters, globalFilter, pagination, rowSelection, columnVisibility }),\n [sorting, columnFilters, globalFilter, pagination, rowSelection, columnVisibility]\n )\n\n // Keep a mutable reference so column and row methods always see fresh state\n // without rebuilding every object on each render.\n const tableRef = React.useRef<Table<TData>>(null!)\n\n /* Columns */\n const columns = React.useMemo<Column<TData>[]>(() => {\n return columnDefs.map((def) => {\n const id = def.id ?? def.accessorKey\n if (!id) throw new Error(\"Every column needs an `id` or an `accessorKey`.\")\n const accessorFn =\n def.accessorFn ??\n (def.accessorKey ? (row: TData) => (row as Record<string, unknown>)[def.accessorKey as string] : undefined)\n const column: Column<TData> = {\n id,\n columnDef: def,\n\n label: def.label,\n accessorFn: accessorFn as Column<TData>[\"accessorFn\"],\n getCanSort: () => (def.enableSorting ?? true) && !!accessorFn,\n getIsSorted: () => {\n const entry = tableRef.current.getState().sorting.find((s) => s.id === id)\n return entry ? (entry.desc ? \"desc\" : \"asc\") : false\n },\n toggleSorting: (desc) => {\n tableRef.current.setSorting((prev) => {\n const current = prev.find((s) => s.id === id)\n const nextDesc = desc ?? (current ? !current.desc : false)\n return [{ id, desc: nextDesc }]\n })\n },\n clearSorting: () => tableRef.current.setSorting((prev) => prev.filter((s) => s.id !== id)),\n getCanHide: () => def.enableHiding ?? true,\n getIsVisible: () => tableRef.current.getState().columnVisibility[id] !== false,\n toggleVisibility: (visible) => {\n tableRef.current.setColumnVisibility((prev) => ({\n ...prev,\n [id]: visible ?? prev[id] === false,\n }))\n },\n getCanFilter: () => !!accessorFn,\n getFilterValue: () => tableRef.current.getState().columnFilters.find((f) => f.id === id)?.value,\n setFilterValue: (value) => {\n tableRef.current.setColumnFilters((prev) => {\n const rest = prev.filter((f) => f.id !== id)\n const isEmpty =\n value === undefined || value === null || value === \"\" || (Array.isArray(value) && value.length === 0)\n return isEmpty ? rest : [...rest, { id, value }]\n })\n },\n getFacetedUniqueValues: () => facetsRef.current.get(id) ?? new Map(),\n }\n return column\n })\n }, [columnDefs])\n\n const columnById = React.useMemo(() => new Map(columns.map((c) => [c.id, c])), [columns])\n\n /* Rows */\n const coreRows = React.useMemo<Row<TData>[]>(() => {\n return data.map((original, index) => {\n const id = getRowId ? getRowId(original, index) : String(index)\n const valueCache = new Map<string, unknown>()\n const row: Row<TData> = {\n id,\n index,\n original,\n getValue: <TValue>(columnId: string) => {\n if (valueCache.has(columnId)) return valueCache.get(columnId) as TValue\n const column = columnById.get(columnId)\n const value = column?.accessorFn ? column.accessorFn(original, index) : undefined\n valueCache.set(columnId, value)\n return value as TValue\n },\n getIsSelected: () => !!tableRef.current.getState().rowSelection[id],\n getCanSelect: () => (typeof enableRowSelection === \"function\" ? enableRowSelection(row) : enableRowSelection),\n toggleSelected: (selected) => {\n if (!row.getCanSelect()) return\n tableRef.current.setRowSelection((prev) => {\n const next = { ...prev }\n const value = selected ?? !prev[id]\n if (value) next[id] = true\n else delete next[id]\n return next\n })\n },\n }\n return row\n })\n }, [data, getRowId, columnById, enableRowSelection])\n\n /* Filtering */\n const globallyFilteredRows = React.useMemo(() => {\n if (!globalFilter) return coreRows\n const fn: FilterFn<TData> =\n globalFilterFn ??\n ((row, _id, value) => {\n const search = String(value).toLowerCase()\n return columns.some((column) => {\n if (!column.accessorFn || column.columnDef.enableGlobalFilter === false) return false\n return String(row.getValue(column.id) ?? \"\")\n .toLowerCase()\n .includes(search)\n })\n })\n return coreRows.filter((row) => fn(row, \"__global__\", globalFilter))\n }, [coreRows, globalFilter, globalFilterFn, columns])\n\n const filteredRows = React.useMemo(() => {\n let rows = globallyFilteredRows\n for (const filter of columnFilters) {\n const column = columnById.get(filter.id)\n if (!column) continue\n const fn = column.columnDef.filterFn ?? defaultColumnFilter\n rows = rows.filter((row) => fn(row, filter.id, filter.value))\n }\n return rows\n }, [globallyFilteredRows, columnFilters, columnById])\n\n /* Facets: unique value counts per column, over rows filtered by everything except that column. */\n const facetsRef = React.useRef(new Map<string, Map<unknown, number>>())\n facetsRef.current = React.useMemo(() => {\n const result = new Map<string, Map<unknown, number>>()\n for (const column of columns) {\n if (!column.accessorFn) continue\n let rows = globallyFilteredRows\n for (const filter of columnFilters) {\n if (filter.id === column.id) continue\n const other = columnById.get(filter.id)\n if (!other) continue\n const fn = other.columnDef.filterFn ?? defaultColumnFilter\n rows = rows.filter((row) => fn(row, filter.id, filter.value))\n }\n const counts = new Map<unknown, number>()\n for (const row of rows) {\n const value = row.getValue(column.id)\n counts.set(value, (counts.get(value) ?? 0) + 1)\n }\n result.set(column.id, counts)\n }\n return result\n }, [columns, globallyFilteredRows, columnFilters, columnById])\n\n /* Sorting */\n const sortedRows = React.useMemo(() => {\n if (sorting.length === 0) return filteredRows\n const rows = [...filteredRows]\n rows.sort((a, b) => {\n for (const { id, desc } of sorting) {\n const column = columnById.get(id)\n if (!column) continue\n const compare = column.columnDef.sortingFn\n ? column.columnDef.sortingFn(a, b, id)\n : defaultCompare(a.getValue(id), b.getValue(id))\n if (compare !== 0) return desc ? -compare : compare\n }\n return a.index - b.index\n })\n return rows\n }, [filteredRows, sorting, columnById])\n\n /* Pagination */\n const pageCount = Math.max(1, Math.ceil(sortedRows.length / pagination.pageSize))\n const pageRows = React.useMemo(() => {\n const start = pagination.pageIndex * pagination.pageSize\n return sortedRows.slice(start, start + pagination.pageSize)\n }, [sortedRows, pagination])\n\n React.useEffect(() => {\n if (!autoResetPageIndex) return\n if (pagination.pageIndex > pageCount - 1) {\n setPagination((prev) => ({ ...prev, pageIndex: Math.max(0, pageCount - 1) }))\n }\n }, [autoResetPageIndex, pageCount, pagination.pageIndex, setPagination])\n\n /* Table */\n const table = React.useMemo<Table<TData>>(() => {\n const t: Table<TData> = {\n options,\n getState: () => state,\n getAllColumns: () => columns,\n getVisibleColumns: () => columns.filter((c) => c.getIsVisible()),\n getColumn: (id) => columnById.get(id),\n getCoreRowModel: () => ({ rows: coreRows }),\n getFilteredRowModel: () => ({ rows: filteredRows }),\n getSortedRowModel: () => ({ rows: sortedRows }),\n getRowModel: () => ({ rows: pageRows }),\n getFilteredSelectedRowModel: () => ({\n rows: filteredRows.filter((r) => r.getIsSelected()),\n }),\n getSelectedRowModel: () => ({ rows: coreRows.filter((r) => r.getIsSelected()) }),\n setSorting,\n resetSorting: () => setSorting([]),\n setGlobalFilter: (value) => {\n setGlobalFilterState(value)\n if (autoResetPageIndex) setPagination((p) => ({ ...p, pageIndex: 0 }))\n },\n setColumnFilters: (updater) => {\n setColumnFilters(updater)\n if (autoResetPageIndex) setPagination((p) => ({ ...p, pageIndex: 0 }))\n },\n resetColumnFilters: () => setColumnFilters([]),\n setPagination,\n setPageIndex: (index) => setPagination((p) => ({ ...p, pageIndex: Math.min(Math.max(0, index), pageCount - 1) })),\n setPageSize: (size) =>\n setPagination((p) => ({ pageSize: size, pageIndex: Math.floor((p.pageIndex * p.pageSize) / size) })),\n getPageCount: () => pageCount,\n getCanPreviousPage: () => pagination.pageIndex > 0,\n getCanNextPage: () => pagination.pageIndex < pageCount - 1,\n previousPage: () => t.setPageIndex(pagination.pageIndex - 1),\n nextPage: () => t.setPageIndex(pagination.pageIndex + 1),\n setRowSelection,\n resetRowSelection: () => setRowSelection({}),\n getIsAllPageRowsSelected: () =>\n pageRows.length > 0 && pageRows.every((r) => !r.getCanSelect() || r.getIsSelected()),\n getIsSomePageRowsSelected: () => pageRows.some((r) => r.getIsSelected()) && !t.getIsAllPageRowsSelected(),\n toggleAllPageRowsSelected: (selected) => {\n const value = selected ?? !t.getIsAllPageRowsSelected()\n setRowSelection((prev) => {\n const next = { ...prev }\n for (const row of pageRows) {\n if (!row.getCanSelect()) continue\n if (value) next[row.id] = true\n else delete next[row.id]\n }\n return next\n })\n },\n getIsAllRowsSelected: () =>\n filteredRows.length > 0 && filteredRows.every((r) => !r.getCanSelect() || r.getIsSelected()),\n toggleAllRowsSelected: (selected) => {\n const value = selected ?? !t.getIsAllRowsSelected()\n setRowSelection(() => {\n const next: RowSelectionState = {}\n if (value) for (const row of filteredRows) if (row.getCanSelect()) next[row.id] = true\n return next\n })\n },\n setColumnVisibility,\n resetColumnVisibility: () => setColumnVisibility({}),\n }\n return t\n }, [\n options,\n state,\n columns,\n columnById,\n coreRows,\n filteredRows,\n sortedRows,\n pageRows,\n pageCount,\n pagination,\n autoResetPageIndex,\n setSorting,\n setGlobalFilterState,\n setColumnFilters,\n setPagination,\n setRowSelection,\n setColumnVisibility,\n ])\n\n tableRef.current = table\n return table\n}\n"
16
+ }
17
+ ],
18
+ "docs": "## Data table\n`src/lib/table.ts` is a dependency-free headless table engine (columns, sorting, global +\ncolumn filters with faceted counts, pagination, row selection, visibility). Column config is\ndata only: `{ id | accessorKey | accessorFn, label, enableSorting, enableHiding, filterFn,\nsortingFn }`. No render functions and no markup in column definitions.\n`src/components/ui/data-table.tsx` builds compositional parts on the source-agnostic\n`DataTableInstance` contract in `src/lib/data-table-adapter.ts`: toolbar, search, faceted\nfilter, reset, view options, `DataTableTable` > `DataTableHeader` (one `DataTableHead\ncolumn=\"id\"` per column; sortable columns get the sort/hide menu with `children` as the title)\n+ `DataTableBody` (`children` is `(row) => cells`; wrap in `DataTableRow` or return a fragment\nof `DataTableCell column=\"id\"` cells), `DataTableEmpty`, select-all/select-row cells, row\nactions, pagination pieces, bulk actions. Heads and cells keyed by a hidden column render\nnothing, so visibility toggles need no extra wiring. The toolkit must not know about specific\ntable libraries (no TanStack). `src/demo/tasks/` and `src/demo/users/` are the reference\nconsumers: `columns.tsx` is pure config, `*-table.tsx` composes the markup."
19
+ }
@@ -1,7 +1,11 @@
1
1
  {
2
- "name": "time",
2
+ "name": "lib/time",
3
3
  "type": "lib",
4
4
  "description": "`src/components/ui/activity-feed.tsx` is a compositional timeline of events on the WAI-ARIA feed pattern (`role=\"feed\"`, focusable articles, PageUp/PageDown move, Ctrl+Home/End jump): `ActivityFeed` > `ActivityFeedGroup` > `ActivityFeedGrou",
5
+ "exports": [
6
+ "formatRelativeTime",
7
+ "formatCompactAge"
8
+ ],
5
9
  "dependencies": {},
6
10
  "registryDependencies": [],
7
11
  "files": [
@@ -1,7 +1,10 @@
1
1
  {
2
- "name": "utils",
2
+ "name": "lib/utils",
3
3
  "type": "lib",
4
4
  "description": "- **Feature parity** with the shadcn original: same exported names, same props surface where Ark supports it, same visual result, same variants. - **Ark's tree wins** where the structure differs (e.g.",
5
+ "exports": [
6
+ "cn"
7
+ ],
5
8
  "dependencies": {
6
9
  "clsx": "^2.1.1",
7
10
  "tailwind-merge": "^3.6.0"
@@ -2,9 +2,13 @@
2
2
  "name": "live-region",
3
3
  "type": "ui",
4
4
  "description": "Shared screen-reader announcer. `announce` re-fires even when the same text is announced twice, and `clearAfter` (ms) empties the region so stale text is not re-read when a user lands on it.",
5
+ "exports": [
6
+ "LiveRegion",
7
+ "useLiveRegion"
8
+ ],
5
9
  "dependencies": {},
6
10
  "registryDependencies": [
7
- "utils"
11
+ "lib/utils"
8
12
  ],
9
13
  "files": [
10
14
  {
@@ -2,12 +2,18 @@
2
2
  "name": "marker",
3
3
  "type": "ui",
4
4
  "description": "",
5
+ "exports": [
6
+ "Marker",
7
+ "MarkerIcon",
8
+ "MarkerContent",
9
+ "markerVariants"
10
+ ],
5
11
  "dependencies": {
6
12
  "@ark-ui/react": "^5.39.1",
7
13
  "class-variance-authority": "^0.7.1"
8
14
  },
9
15
  "registryDependencies": [
10
- "utils"
16
+ "lib/utils"
11
17
  ],
12
18
  "files": [
13
19
  {
@@ -2,11 +2,20 @@
2
2
  "name": "marquee",
3
3
  "type": "ui",
4
4
  "description": "",
5
+ "ark": "Marquee",
6
+ "exports": [
7
+ "Marquee",
8
+ "MarqueeContent",
9
+ "MarqueeContext",
10
+ "MarqueeEdge",
11
+ "MarqueeItem",
12
+ "MarqueeViewport"
13
+ ],
5
14
  "dependencies": {
6
15
  "@ark-ui/react": "^5.39.1"
7
16
  },
8
17
  "registryDependencies": [
9
- "utils"
18
+ "lib/utils"
10
19
  ],
11
20
  "files": [
12
21
  {
@@ -2,13 +2,37 @@
2
2
  "name": "menubar",
3
3
  "type": "ui",
4
4
  "description": "Ark UI has no Menubar primitive. `Menubar` composes Ark `Menu` roots and adds the menubar behaviours Radix provides: one open menu at a time, hover switching between triggers once a menu is open, roving tabindex across triggers, and ArrowLe",
5
+ "ark": "Menu",
6
+ "exports": [
7
+ "Menubar",
8
+ "MenubarArrow",
9
+ "MenubarCheckboxItem",
10
+ "MenubarContent",
11
+ "MenubarContext",
12
+ "MenubarGroup",
13
+ "MenubarItem",
14
+ "MenubarItemIndicator",
15
+ "MenubarItemText",
16
+ "MenubarLabel",
17
+ "MenubarMenu",
18
+ "MenubarPortal",
19
+ "MenubarPositioner",
20
+ "MenubarRadioGroup",
21
+ "MenubarRadioItem",
22
+ "MenubarSeparator",
23
+ "MenubarShortcut",
24
+ "MenubarSub",
25
+ "MenubarSubContent",
26
+ "MenubarSubTrigger",
27
+ "MenubarTrigger"
28
+ ],
5
29
  "dependencies": {
6
30
  "@ark-ui/react": "^5.39.1",
7
31
  "lucide-react": "^1.41.0"
8
32
  },
9
33
  "registryDependencies": [
10
- "controllable",
11
- "utils"
34
+ "lib/controllable",
35
+ "lib/utils"
12
36
  ],
13
37
  "files": [
14
38
  {
@@ -2,9 +2,17 @@
2
2
  "name": "message",
3
3
  "type": "ui",
4
4
  "description": "",
5
+ "exports": [
6
+ "MessageGroup",
7
+ "Message",
8
+ "MessageAvatar",
9
+ "MessageContent",
10
+ "MessageFooter",
11
+ "MessageHeader"
12
+ ],
5
13
  "dependencies": {},
6
14
  "registryDependencies": [
7
- "utils"
15
+ "lib/utils"
8
16
  ],
9
17
  "files": [
10
18
  {
@@ -2,13 +2,29 @@
2
2
  "name": "navigation-menu",
3
3
  "type": "ui",
4
4
  "description": "",
5
+ "ark": "NavigationMenu",
6
+ "exports": [
7
+ "NavigationMenu",
8
+ "NavigationMenuArrow",
9
+ "NavigationMenuContent",
10
+ "NavigationMenuContext",
11
+ "NavigationMenuIndicator",
12
+ "NavigationMenuItem",
13
+ "NavigationMenuLink",
14
+ "NavigationMenuList",
15
+ "NavigationMenuTrigger",
16
+ "NavigationMenuViewport",
17
+ "NavigationMenuViewportPositioner",
18
+ "navigationMenuTriggerStyle",
19
+ "NavigationMenuItemIndicator"
20
+ ],
5
21
  "dependencies": {
6
22
  "@ark-ui/react": "^5.39.1",
7
23
  "class-variance-authority": "^0.7.1",
8
24
  "lucide-react": "^1.41.0"
9
25
  },
10
26
  "registryDependencies": [
11
- "utils"
27
+ "lib/utils"
12
28
  ],
13
29
  "files": [
14
30
  {
@@ -2,6 +2,37 @@
2
2
  "name": "node-graph",
3
3
  "type": "ui",
4
4
  "description": "NodeGraph — a compositional, data-agnostic node editor in the spirit of visual scripting graphs. The consumer owns nodes and edges; the graph owns only the viewport (pan/zoom), the selection, and in-flight interactions (dragging nodes, draw",
5
+ "exports": [
6
+ "NodeGraph",
7
+ "NodeGraphViewport",
8
+ "NodeGraphBackground",
9
+ "NodeGraphSurface",
10
+ "NodeGraphEdges",
11
+ "NodeGraphEdge",
12
+ "NodeGraphConnectionLine",
13
+ "NodeGraphSelectionBox",
14
+ "NodeGraphNode",
15
+ "NodeGraphNodeHeader",
16
+ "NodeGraphNodeActions",
17
+ "NodeGraphNodeTitle",
18
+ "NodeGraphNodeSubtitle",
19
+ "NodeGraphNodeBody",
20
+ "NodeGraphNodeInputs",
21
+ "NodeGraphNodeOutputs",
22
+ "NodeGraphNodeFooter",
23
+ "NodeGraphPort",
24
+ "NodeGraphPortPin",
25
+ "NodeGraphPortLabel",
26
+ "NodeGraphControls",
27
+ "NodeGraphZoomInTrigger",
28
+ "NodeGraphZoomOutTrigger",
29
+ "NodeGraphFitViewTrigger",
30
+ "NodeGraphZoomValue",
31
+ "NodeGraphMinimap",
32
+ "NodeGraphEmpty",
33
+ "useNodeGraph",
34
+ "getBezierPath"
35
+ ],
5
36
  "dependencies": {
6
37
  "@ark-ui/react": "^5.39.1",
7
38
  "class-variance-authority": "^0.7.1",
@@ -9,8 +40,8 @@
9
40
  },
10
41
  "registryDependencies": [
11
42
  "button",
12
- "live-region",
13
- "utils"
43
+ "lib/utils",
44
+ "live-region"
14
45
  ],
15
46
  "files": [
16
47
  {