@miethe/ui 0.2.0

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 (251) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/README.md +1536 -0
  3. package/dist/bulk-actions/Button.d.ts +28 -0
  4. package/dist/bulk-actions/Button.d.ts.map +1 -0
  5. package/dist/bulk-actions/Button.js +45 -0
  6. package/dist/bulk-actions/Button.js.map +1 -0
  7. package/dist/bulk-actions/bulk-action-bar.d.ts +91 -0
  8. package/dist/bulk-actions/bulk-action-bar.d.ts.map +1 -0
  9. package/dist/bulk-actions/bulk-action-bar.js +94 -0
  10. package/dist/bulk-actions/bulk-action-bar.js.map +1 -0
  11. package/dist/bulk-actions/index.d.ts +5 -0
  12. package/dist/bulk-actions/index.d.ts.map +1 -0
  13. package/dist/bulk-actions/index.js +7 -0
  14. package/dist/bulk-actions/index.js.map +1 -0
  15. package/dist/bulk-actions/utils.d.ts +6 -0
  16. package/dist/bulk-actions/utils.d.ts.map +1 -0
  17. package/dist/bulk-actions/utils.js +9 -0
  18. package/dist/bulk-actions/utils.js.map +1 -0
  19. package/dist/components/ui/alert.d.ts +9 -0
  20. package/dist/components/ui/alert.d.ts.map +1 -0
  21. package/dist/components/ui/alert.js +23 -0
  22. package/dist/components/ui/alert.js.map +1 -0
  23. package/dist/components/ui/button.d.ts +12 -0
  24. package/dist/components/ui/button.d.ts.map +1 -0
  25. package/dist/components/ui/button.js +34 -0
  26. package/dist/components/ui/button.js.map +1 -0
  27. package/dist/components/ui/collapsible.d.ts +6 -0
  28. package/dist/components/ui/collapsible.d.ts.map +1 -0
  29. package/dist/components/ui/collapsible.js +7 -0
  30. package/dist/components/ui/collapsible.js.map +1 -0
  31. package/dist/components/ui/skeleton.d.ts +4 -0
  32. package/dist/components/ui/skeleton.d.ts.map +1 -0
  33. package/dist/components/ui/skeleton.js +7 -0
  34. package/dist/components/ui/skeleton.js.map +1 -0
  35. package/dist/content-viewer/ContentPane.d.ts +107 -0
  36. package/dist/content-viewer/ContentPane.d.ts.map +1 -0
  37. package/dist/content-viewer/ContentPane.js +247 -0
  38. package/dist/content-viewer/ContentPane.js.map +1 -0
  39. package/dist/content-viewer/ContentViewerProvider.d.ts +83 -0
  40. package/dist/content-viewer/ContentViewerProvider.d.ts.map +1 -0
  41. package/dist/content-viewer/ContentViewerProvider.js +92 -0
  42. package/dist/content-viewer/ContentViewerProvider.js.map +1 -0
  43. package/dist/content-viewer/FileTree.d.ts +71 -0
  44. package/dist/content-viewer/FileTree.d.ts.map +1 -0
  45. package/dist/content-viewer/FileTree.js +294 -0
  46. package/dist/content-viewer/FileTree.js.map +1 -0
  47. package/dist/content-viewer/adapters.d.ts +101 -0
  48. package/dist/content-viewer/adapters.d.ts.map +1 -0
  49. package/dist/content-viewer/adapters.js +32 -0
  50. package/dist/content-viewer/adapters.js.map +1 -0
  51. package/dist/content-viewer/index.d.ts +8 -0
  52. package/dist/content-viewer/index.d.ts.map +1 -0
  53. package/dist/content-viewer/index.js +5 -0
  54. package/dist/content-viewer/index.js.map +1 -0
  55. package/dist/diff/DiffViewer.d.ts +112 -0
  56. package/dist/diff/DiffViewer.d.ts.map +1 -0
  57. package/dist/diff/DiffViewer.js +414 -0
  58. package/dist/diff/DiffViewer.js.map +1 -0
  59. package/dist/diff/diff.d.ts +32 -0
  60. package/dist/diff/diff.d.ts.map +1 -0
  61. package/dist/diff/diff.js +8 -0
  62. package/dist/diff/diff.js.map +1 -0
  63. package/dist/diff/index.d.ts +4 -0
  64. package/dist/diff/index.d.ts.map +1 -0
  65. package/dist/diff/index.js +3 -0
  66. package/dist/diff/index.js.map +1 -0
  67. package/dist/display/FilePreviewPane.d.ts +31 -0
  68. package/dist/display/FilePreviewPane.d.ts.map +1 -0
  69. package/dist/display/FilePreviewPane.js +144 -0
  70. package/dist/display/FilePreviewPane.js.map +1 -0
  71. package/dist/display/FrontmatterDisplay.d.ts +33 -0
  72. package/dist/display/FrontmatterDisplay.d.ts.map +1 -0
  73. package/dist/display/FrontmatterDisplay.js +79 -0
  74. package/dist/display/FrontmatterDisplay.js.map +1 -0
  75. package/dist/display/index.d.ts +5 -0
  76. package/dist/display/index.d.ts.map +1 -0
  77. package/dist/display/index.js +4 -0
  78. package/dist/display/index.js.map +1 -0
  79. package/dist/editor/MarkdownEditor.d.ts +28 -0
  80. package/dist/editor/MarkdownEditor.d.ts.map +1 -0
  81. package/dist/editor/MarkdownEditor.js +160 -0
  82. package/dist/editor/MarkdownEditor.js.map +1 -0
  83. package/dist/editor/SplitPreview.d.ts +28 -0
  84. package/dist/editor/SplitPreview.d.ts.map +1 -0
  85. package/dist/editor/SplitPreview.js +34 -0
  86. package/dist/editor/SplitPreview.js.map +1 -0
  87. package/dist/editor/index.d.ts +5 -0
  88. package/dist/editor/index.d.ts.map +1 -0
  89. package/dist/editor/index.js +4 -0
  90. package/dist/editor/index.js.map +1 -0
  91. package/dist/filters/filters-dropdown.d.ts +24 -0
  92. package/dist/filters/filters-dropdown.d.ts.map +1 -0
  93. package/dist/filters/filters-dropdown.js +36 -0
  94. package/dist/filters/filters-dropdown.js.map +1 -0
  95. package/dist/filters/index.d.ts +9 -0
  96. package/dist/filters/index.d.ts.map +1 -0
  97. package/dist/filters/index.js +5 -0
  98. package/dist/filters/index.js.map +1 -0
  99. package/dist/filters/sort-dropdown.d.ts +13 -0
  100. package/dist/filters/sort-dropdown.d.ts.map +1 -0
  101. package/dist/filters/sort-dropdown.js +20 -0
  102. package/dist/filters/sort-dropdown.js.map +1 -0
  103. package/dist/filters/tag-filter-popover.d.ts +39 -0
  104. package/dist/filters/tag-filter-popover.d.ts.map +1 -0
  105. package/dist/filters/tag-filter-popover.js +72 -0
  106. package/dist/filters/tag-filter-popover.js.map +1 -0
  107. package/dist/filters/tool-filter-popover.d.ts +42 -0
  108. package/dist/filters/tool-filter-popover.d.ts.map +1 -0
  109. package/dist/filters/tool-filter-popover.js +67 -0
  110. package/dist/filters/tool-filter-popover.js.map +1 -0
  111. package/dist/hooks/use-debounce.d.ts +9 -0
  112. package/dist/hooks/use-debounce.d.ts.map +1 -0
  113. package/dist/hooks/use-debounce.js +21 -0
  114. package/dist/hooks/use-debounce.js.map +1 -0
  115. package/dist/hooks/use-intersection-observer.d.ts +11 -0
  116. package/dist/hooks/use-intersection-observer.d.ts.map +1 -0
  117. package/dist/hooks/use-intersection-observer.js +25 -0
  118. package/dist/hooks/use-intersection-observer.js.map +1 -0
  119. package/dist/index.d.ts +10 -0
  120. package/dist/index.d.ts.map +1 -0
  121. package/dist/index.js +10 -0
  122. package/dist/index.js.map +1 -0
  123. package/dist/pickers/EntityPickerDialog.d.ts +233 -0
  124. package/dist/pickers/EntityPickerDialog.d.ts.map +1 -0
  125. package/dist/pickers/EntityPickerDialog.js +355 -0
  126. package/dist/pickers/EntityPickerDialog.js.map +1 -0
  127. package/dist/pickers/EntityPickerViewToggle.d.ts +8 -0
  128. package/dist/pickers/EntityPickerViewToggle.d.ts.map +1 -0
  129. package/dist/pickers/EntityPickerViewToggle.js +17 -0
  130. package/dist/pickers/EntityPickerViewToggle.js.map +1 -0
  131. package/dist/pickers/index.d.ts +5 -0
  132. package/dist/pickers/index.d.ts.map +1 -0
  133. package/dist/pickers/index.js +3 -0
  134. package/dist/pickers/index.js.map +1 -0
  135. package/dist/primitives/Badge.d.ts +16 -0
  136. package/dist/primitives/Badge.d.ts.map +1 -0
  137. package/dist/primitives/Badge.js +43 -0
  138. package/dist/primitives/Badge.js.map +1 -0
  139. package/dist/primitives/BaseArtifactModal.d.ts +114 -0
  140. package/dist/primitives/BaseArtifactModal.d.ts.map +1 -0
  141. package/dist/primitives/BaseArtifactModal.js +76 -0
  142. package/dist/primitives/BaseArtifactModal.js.map +1 -0
  143. package/dist/primitives/Dialog.d.ts +20 -0
  144. package/dist/primitives/Dialog.d.ts.map +1 -0
  145. package/dist/primitives/Dialog.js +24 -0
  146. package/dist/primitives/Dialog.js.map +1 -0
  147. package/dist/primitives/DropdownMenu.d.ts +28 -0
  148. package/dist/primitives/DropdownMenu.d.ts.map +1 -0
  149. package/dist/primitives/DropdownMenu.js +34 -0
  150. package/dist/primitives/DropdownMenu.js.map +1 -0
  151. package/dist/primitives/EnterpriseOwnerBadge.d.ts +9 -0
  152. package/dist/primitives/EnterpriseOwnerBadge.d.ts.map +1 -0
  153. package/dist/primitives/EnterpriseOwnerBadge.js +12 -0
  154. package/dist/primitives/EnterpriseOwnerBadge.js.map +1 -0
  155. package/dist/primitives/GroupedSelect.d.ts +30 -0
  156. package/dist/primitives/GroupedSelect.d.ts.map +1 -0
  157. package/dist/primitives/GroupedSelect.js +47 -0
  158. package/dist/primitives/GroupedSelect.js.map +1 -0
  159. package/dist/primitives/Input.d.ts +6 -0
  160. package/dist/primitives/Input.d.ts.map +1 -0
  161. package/dist/primitives/Input.js +9 -0
  162. package/dist/primitives/Input.js.map +1 -0
  163. package/dist/primitives/LockIcon.d.ts +11 -0
  164. package/dist/primitives/LockIcon.d.ts.map +1 -0
  165. package/dist/primitives/LockIcon.js +15 -0
  166. package/dist/primitives/LockIcon.js.map +1 -0
  167. package/dist/primitives/MaskedSecretInput.d.ts +16 -0
  168. package/dist/primitives/MaskedSecretInput.d.ts.map +1 -0
  169. package/dist/primitives/MaskedSecretInput.js +42 -0
  170. package/dist/primitives/MaskedSecretInput.js.map +1 -0
  171. package/dist/primitives/ModalHeader.d.ts +66 -0
  172. package/dist/primitives/ModalHeader.d.ts.map +1 -0
  173. package/dist/primitives/ModalHeader.js +58 -0
  174. package/dist/primitives/ModalHeader.js.map +1 -0
  175. package/dist/primitives/Popover.d.ts +9 -0
  176. package/dist/primitives/Popover.d.ts.map +1 -0
  177. package/dist/primitives/Popover.js +13 -0
  178. package/dist/primitives/Popover.js.map +1 -0
  179. package/dist/primitives/ScrollArea.d.ts +6 -0
  180. package/dist/primitives/ScrollArea.d.ts.map +1 -0
  181. package/dist/primitives/ScrollArea.js +11 -0
  182. package/dist/primitives/ScrollArea.js.map +1 -0
  183. package/dist/primitives/SearchableCombobox.d.ts +30 -0
  184. package/dist/primitives/SearchableCombobox.d.ts.map +1 -0
  185. package/dist/primitives/SearchableCombobox.js +124 -0
  186. package/dist/primitives/SearchableCombobox.js.map +1 -0
  187. package/dist/primitives/SearchablePickerDialog.d.ts +20 -0
  188. package/dist/primitives/SearchablePickerDialog.d.ts.map +1 -0
  189. package/dist/primitives/SearchablePickerDialog.js +78 -0
  190. package/dist/primitives/SearchablePickerDialog.js.map +1 -0
  191. package/dist/primitives/StatusBadge.d.ts +21 -0
  192. package/dist/primitives/StatusBadge.d.ts.map +1 -0
  193. package/dist/primitives/StatusBadge.js +25 -0
  194. package/dist/primitives/StatusBadge.js.map +1 -0
  195. package/dist/primitives/TabNavigation.d.ts +68 -0
  196. package/dist/primitives/TabNavigation.d.ts.map +1 -0
  197. package/dist/primitives/TabNavigation.js +74 -0
  198. package/dist/primitives/TabNavigation.js.map +1 -0
  199. package/dist/primitives/Tabs.d.ts +8 -0
  200. package/dist/primitives/Tabs.d.ts.map +1 -0
  201. package/dist/primitives/Tabs.js +14 -0
  202. package/dist/primitives/Tabs.js.map +1 -0
  203. package/dist/primitives/Tooltip.d.ts +8 -0
  204. package/dist/primitives/Tooltip.d.ts.map +1 -0
  205. package/dist/primitives/Tooltip.js +12 -0
  206. package/dist/primitives/Tooltip.js.map +1 -0
  207. package/dist/primitives/VerticalTabNavigation.d.ts +75 -0
  208. package/dist/primitives/VerticalTabNavigation.d.ts.map +1 -0
  209. package/dist/primitives/VerticalTabNavigation.js +166 -0
  210. package/dist/primitives/VerticalTabNavigation.js.map +1 -0
  211. package/dist/primitives/ViewModeToggle.d.ts +12 -0
  212. package/dist/primitives/ViewModeToggle.d.ts.map +1 -0
  213. package/dist/primitives/ViewModeToggle.js +56 -0
  214. package/dist/primitives/ViewModeToggle.js.map +1 -0
  215. package/dist/primitives/WizardShell.d.ts +81 -0
  216. package/dist/primitives/WizardShell.d.ts.map +1 -0
  217. package/dist/primitives/WizardShell.js +73 -0
  218. package/dist/primitives/WizardShell.js.map +1 -0
  219. package/dist/primitives/index.d.ts +38 -0
  220. package/dist/primitives/index.d.ts.map +1 -0
  221. package/dist/primitives/index.js +24 -0
  222. package/dist/primitives/index.js.map +1 -0
  223. package/dist/primitives/utils.d.ts +6 -0
  224. package/dist/primitives/utils.d.ts.map +1 -0
  225. package/dist/primitives/utils.js +9 -0
  226. package/dist/primitives/utils.js.map +1 -0
  227. package/dist/types/index.d.ts +63 -0
  228. package/dist/types/index.d.ts.map +1 -0
  229. package/dist/types/index.js +9 -0
  230. package/dist/types/index.js.map +1 -0
  231. package/dist/utils/frontmatter.d.ts +63 -0
  232. package/dist/utils/frontmatter.d.ts.map +1 -0
  233. package/dist/utils/frontmatter.js +345 -0
  234. package/dist/utils/frontmatter.js.map +1 -0
  235. package/dist/utils/index.d.ts +6 -0
  236. package/dist/utils/index.d.ts.map +1 -0
  237. package/dist/utils/index.js +6 -0
  238. package/dist/utils/index.js.map +1 -0
  239. package/dist/utils/perf-marks.d.ts +28 -0
  240. package/dist/utils/perf-marks.d.ts.map +1 -0
  241. package/dist/utils/perf-marks.js +45 -0
  242. package/dist/utils/perf-marks.js.map +1 -0
  243. package/dist/utils/readme-utils.d.ts +67 -0
  244. package/dist/utils/readme-utils.d.ts.map +1 -0
  245. package/dist/utils/readme-utils.js +164 -0
  246. package/dist/utils/readme-utils.js.map +1 -0
  247. package/dist/utils/type-colors.d.ts +70 -0
  248. package/dist/utils/type-colors.d.ts.map +1 -0
  249. package/dist/utils/type-colors.js +118 -0
  250. package/dist/utils/type-colors.js.map +1 -0
  251. package/package.json +131 -0
@@ -0,0 +1,78 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from 'react';
4
+ import { Search, CheckSquare, Square } from 'lucide-react';
5
+ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, } from './Dialog';
6
+ import { Input } from './Input';
7
+ import { cn } from './utils';
8
+ function SearchablePickerDialogInner(props, _ref) {
9
+ const { open, onOpenChange, title, searchPlaceholder = 'Search…', emptyMessage = 'No items found', items, renderItem, getItemId, getItemLabel, onConfirm, onCancel, isLoading = false, } = props;
10
+ const [searchQuery, setSearchQuery] = React.useState('');
11
+ const [selectedIds, setSelectedIds] = React.useState(new Set());
12
+ // Reset state when dialog opens
13
+ React.useEffect(() => {
14
+ if (open) {
15
+ setSearchQuery('');
16
+ setSelectedIds(new Set());
17
+ }
18
+ }, [open]);
19
+ const filteredItems = React.useMemo(() => {
20
+ if (!searchQuery.trim())
21
+ return items;
22
+ const lower = searchQuery.toLowerCase();
23
+ return items.filter((item) => getItemLabel(item).toLowerCase().includes(lower));
24
+ }, [items, searchQuery, getItemLabel]);
25
+ const allFilteredIds = React.useMemo(() => filteredItems.map(getItemId), [filteredItems, getItemId]);
26
+ const allSelected = allFilteredIds.length > 0 && allFilteredIds.every((id) => selectedIds.has(id));
27
+ const toggleItem = React.useCallback((id) => {
28
+ setSelectedIds((prev) => {
29
+ const next = new Set(prev);
30
+ if (next.has(id)) {
31
+ next.delete(id);
32
+ }
33
+ else {
34
+ next.add(id);
35
+ }
36
+ return next;
37
+ });
38
+ }, []);
39
+ const selectAll = React.useCallback(() => {
40
+ setSelectedIds((prev) => {
41
+ const next = new Set(prev);
42
+ allFilteredIds.forEach((id) => next.add(id));
43
+ return next;
44
+ });
45
+ }, [allFilteredIds]);
46
+ const clearAll = React.useCallback(() => {
47
+ setSelectedIds((prev) => {
48
+ const next = new Set(prev);
49
+ allFilteredIds.forEach((id) => next.delete(id));
50
+ return next;
51
+ });
52
+ }, [allFilteredIds]);
53
+ const handleConfirm = React.useCallback(() => {
54
+ onConfirm(Array.from(selectedIds));
55
+ }, [selectedIds, onConfirm]);
56
+ const handleCancel = React.useCallback(() => {
57
+ onCancel();
58
+ }, [onCancel]);
59
+ const handleKeyDown = React.useCallback((event) => {
60
+ if (event.key === 'Escape') {
61
+ handleCancel();
62
+ }
63
+ }, [handleCancel]);
64
+ return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "flex max-h-[80vh] w-full max-w-md flex-col gap-0 p-0", onKeyDown: handleKeyDown, children: [_jsx(DialogHeader, { className: "border-b px-6 py-4", children: _jsx(DialogTitle, { children: title }) }), _jsx("div", { className: "border-b px-4 py-3", children: _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }), _jsx(Input, { type: "text", placeholder: searchPlaceholder, value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: "pl-9", "aria-label": searchPlaceholder, autoFocus: true })] }) }), !isLoading && filteredItems.length > 0 && (_jsxs("div", { className: "flex items-center gap-2 border-b px-4 py-2", children: [_jsx("button", { type: "button", onClick: allSelected ? clearAll : selectAll, className: "text-xs font-medium text-muted-foreground underline-offset-2 hover:text-foreground hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: allSelected ? 'Clear all' : 'Select all' }), selectedIds.size > 0 && (_jsxs("span", { className: "ml-auto text-xs text-muted-foreground", children: [selectedIds.size, " selected"] }))] })), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-2", role: "list", "aria-label": title, children: isLoading ? (_jsxs("div", { className: "flex items-center justify-center py-8 text-sm text-muted-foreground", children: [_jsx("span", { "aria-hidden": "true", className: "mr-2 h-4 w-4 animate-spin rounded-full border-2 border-muted-foreground/30 border-t-muted-foreground" }), "Loading\u2026"] })) : filteredItems.length === 0 ? (_jsx("p", { className: "py-8 text-center text-sm text-muted-foreground", children: emptyMessage })) : (filteredItems.map((item) => {
65
+ const id = getItemId(item);
66
+ const isSelected = selectedIds.has(id);
67
+ return (_jsxs("div", { role: "listitem", className: cn('flex cursor-pointer items-center gap-3 rounded-md px-2 py-2 text-sm transition-colors', 'hover:bg-accent hover:text-accent-foreground', isSelected && 'bg-accent/50'), onClick: () => toggleItem(id), onKeyDown: (e) => {
68
+ if (e.key === ' ' || e.key === 'Enter') {
69
+ e.preventDefault();
70
+ toggleItem(id);
71
+ }
72
+ }, tabIndex: 0, "aria-selected": isSelected, children: [isSelected ? (_jsx(CheckSquare, { className: "h-4 w-4 shrink-0 text-primary", "aria-hidden": "true" })) : (_jsx(Square, { className: "h-4 w-4 shrink-0 text-muted-foreground", "aria-hidden": "true" })), _jsx("span", { className: "min-w-0 flex-1", children: renderItem(item) })] }, id));
73
+ })) }), _jsxs(DialogFooter, { className: "border-t px-6 py-4", children: [_jsx("button", { type: "button", onClick: handleCancel, className: cn('inline-flex h-9 items-center justify-center rounded-md border border-input px-4 text-sm font-medium', 'bg-background hover:bg-accent hover:text-accent-foreground', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2', 'transition-colors'), children: "Cancel" }), _jsxs("button", { type: "button", onClick: handleConfirm, disabled: selectedIds.size === 0, className: cn('inline-flex h-9 items-center justify-center rounded-md px-4 text-sm font-medium', 'bg-primary text-primary-foreground hover:bg-primary/90', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2', 'disabled:cursor-not-allowed disabled:opacity-50', 'transition-colors'), children: ["Confirm", selectedIds.size > 0 && (_jsxs("span", { className: "ml-1.5 tabular-nums", children: ["(", selectedIds.size, ")"] }))] })] })] }) }));
74
+ }
75
+ // Generic forwardRef workaround — same pattern as SearchableCombobox
76
+ const SearchablePickerDialog = React.forwardRef(SearchablePickerDialogInner);
77
+ export { SearchablePickerDialog };
78
+ //# sourceMappingURL=SearchablePickerDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchablePickerDialog.js","sourceRoot":"","sources":["../../src/primitives/SearchablePickerDialog.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EACL,MAAM,EACN,aAAa,EACb,YAAY,EACZ,WAAW,EACX,YAAY,GACb,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAiB7B,SAAS,2BAA2B,CAClC,KAAqC,EACrC,IAAwC;IAExC,MAAM,EACJ,IAAI,EACJ,YAAY,EACZ,KAAK,EACL,iBAAiB,GAAG,SAAS,EAC7B,YAAY,GAAG,gBAAgB,EAC/B,KAAK,EACL,UAAU,EACV,SAAS,EACT,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,SAAS,GAAG,KAAK,GAClB,GAAG,KAAK,CAAC;IAEV,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACzD,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAc,IAAI,GAAG,EAAE,CAAC,CAAC;IAE7E,gCAAgC;IAChC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,IAAI,EAAE,CAAC;YACT,cAAc,CAAC,EAAE,CAAC,CAAC;YACnB,cAAc,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACvC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE;YAAE,OAAO,KAAK,CAAC;QACtC,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAClF,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;IAEvC,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAClC,GAAG,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,EAClC,CAAC,aAAa,EAAE,SAAS,CAAC,CAC3B,CAAC;IAEF,MAAM,WAAW,GACf,cAAc,CAAC,MAAM,GAAG,CAAC,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAEjF,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,EAAU,EAAE,EAAE;QAClD,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE;YACtB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACjB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACf,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QACvC,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE;YACtB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;YAC3B,cAAc,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YAC7C,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IAErB,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QACtC,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE;YACtB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;YAC3B,cAAc,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;YAChD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IAErB,MAAM,aAAa,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QAC3C,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IACrC,CAAC,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;IAE7B,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QAC1C,QAAQ,EAAE,CAAC;IACb,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,MAAM,aAAa,GAAG,KAAK,CAAC,WAAW,CACrC,CAAC,KAA0B,EAAE,EAAE;QAC7B,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC3B,YAAY,EAAE,CAAC;QACjB,CAAC;IACH,CAAC,EACD,CAAC,YAAY,CAAC,CACf,CAAC;IAEF,OAAO,CACL,KAAC,MAAM,IAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,YAC5C,MAAC,aAAa,IACZ,SAAS,EAAC,sDAAsD,EAChE,SAAS,EAAE,aAAa,aAExB,KAAC,YAAY,IAAC,SAAS,EAAC,oBAAoB,YAC1C,KAAC,WAAW,cAAE,KAAK,GAAe,GACrB,EAGf,cAAK,SAAS,EAAC,oBAAoB,YACjC,eAAK,SAAS,EAAC,UAAU,aACvB,KAAC,MAAM,IAAC,SAAS,EAAC,wEAAwE,GAAG,EAC7F,KAAC,KAAK,IACJ,IAAI,EAAC,MAAM,EACX,WAAW,EAAE,iBAAiB,EAC9B,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAC/C,SAAS,EAAC,MAAM,gBACJ,iBAAiB,EAC7B,SAAS,SACT,IACE,GACF,EAGL,CAAC,SAAS,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,CACzC,eAAK,SAAS,EAAC,4CAA4C,aACzD,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAC3C,SAAS,EAAC,4KAA4K,YAErL,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,GAClC,EACR,WAAW,CAAC,IAAI,GAAG,CAAC,IAAI,CACvB,gBAAM,SAAS,EAAC,uCAAuC,aACpD,WAAW,CAAC,IAAI,iBACZ,CACR,IACG,CACP,EAGD,cACE,SAAS,EAAC,kCAAkC,EAC5C,IAAI,EAAC,MAAM,gBACC,KAAK,YAEhB,SAAS,CAAC,CAAC,CAAC,CACX,eAAK,SAAS,EAAC,qEAAqE,aAClF,8BACc,MAAM,EAClB,SAAS,EAAC,sGAAsG,GAChH,qBAEE,CACP,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAC/B,YAAG,SAAS,EAAC,gDAAgD,YAAE,YAAY,GAAK,CACjF,CAAC,CAAC,CAAC,CACF,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;wBACzB,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;wBAC3B,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;wBACvC,OAAO,CACL,eAEE,IAAI,EAAC,UAAU,EACf,SAAS,EAAE,EAAE,CACX,uFAAuF,EACvF,8CAA8C,EAC9C,UAAU,IAAI,cAAc,CAC7B,EACD,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,EAC7B,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;gCACf,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;oCACvC,CAAC,CAAC,cAAc,EAAE,CAAC;oCACnB,UAAU,CAAC,EAAE,CAAC,CAAC;gCACjB,CAAC;4BACH,CAAC,EACD,QAAQ,EAAE,CAAC,mBACI,UAAU,aAExB,UAAU,CAAC,CAAC,CAAC,CACZ,KAAC,WAAW,IACV,SAAS,EAAC,+BAA+B,iBAC7B,MAAM,GAClB,CACH,CAAC,CAAC,CAAC,CACF,KAAC,MAAM,IACL,SAAS,EAAC,wCAAwC,iBACtC,MAAM,GAClB,CACH,EACD,eAAM,SAAS,EAAC,gBAAgB,YAAE,UAAU,CAAC,IAAI,CAAC,GAAQ,KA5BrD,EAAE,CA6BH,CACP,CAAC;oBACJ,CAAC,CAAC,CACH,GACG,EAEN,MAAC,YAAY,IAAC,SAAS,EAAC,oBAAoB,aAC1C,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,YAAY,EACrB,SAAS,EAAE,EAAE,CACX,qGAAqG,EACrG,4DAA4D,EAC5D,qGAAqG,EACrG,mBAAmB,CACpB,uBAGM,EACT,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,WAAW,CAAC,IAAI,KAAK,CAAC,EAChC,SAAS,EAAE,EAAE,CACX,iFAAiF,EACjF,wDAAwD,EACxD,qGAAqG,EACrG,iDAAiD,EACjD,mBAAmB,CACpB,wBAGA,WAAW,CAAC,IAAI,GAAG,CAAC,IAAI,CACvB,gBAAM,SAAS,EAAC,qBAAqB,kBAAG,WAAW,CAAC,IAAI,SAAS,CAClE,IACM,IACI,IACD,GACT,CACV,CAAC;AACJ,CAAC;AAED,qEAAqE;AACrE,MAAM,sBAAsB,GAAG,KAAK,CAAC,UAAU,CAAC,2BAA2B,CAE7C,CAAC;AAE/B,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { BadgeProps } from './Badge';
2
+ export interface StatusBadgeProps extends Omit<BadgeProps, 'variant' | 'children'> {
3
+ /** The lifecycle status to display (e.g. "draft", "published", "deprecated"). */
4
+ status: string;
5
+ /**
6
+ * Optional map from status string to Badge variant.
7
+ * Merged on top of the default map; unknown statuses fall back to "outline".
8
+ */
9
+ statusColorMap?: Record<string, string>;
10
+ }
11
+ /**
12
+ * StatusBadge — a thin wrapper around Badge that maps a lifecycle status string
13
+ * to a variant using a configurable color map.
14
+ *
15
+ * @example
16
+ * <StatusBadge status="draft" />
17
+ * <StatusBadge status="active" statusColorMap={{ active: 'default' }} />
18
+ */
19
+ declare function StatusBadge({ status, statusColorMap, className, ...rest }: StatusBadgeProps): import("react/jsx-runtime").JSX.Element;
20
+ export { StatusBadge };
21
+ //# sourceMappingURL=StatusBadge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusBadge.d.ts","sourceRoot":"","sources":["../../src/primitives/StatusBadge.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAW1C,MAAM,WAAW,gBACf,SAAQ,IAAI,CAAC,UAAU,EAAE,SAAS,GAAG,UAAU,CAAC;IAChD,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED;;;;;;;GAOG;AACH,iBAAS,WAAW,CAAC,EACnB,MAAM,EACN,cAAc,EACd,SAAS,EACT,GAAG,IAAI,EACR,EAAE,gBAAgB,2CAalB;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Badge } from './Badge';
3
+ const DEFAULT_STATUS_COLOR_MAP = {
4
+ draft: 'secondary',
5
+ published: 'default',
6
+ deprecated: 'destructive',
7
+ };
8
+ /**
9
+ * StatusBadge — a thin wrapper around Badge that maps a lifecycle status string
10
+ * to a variant using a configurable color map.
11
+ *
12
+ * @example
13
+ * <StatusBadge status="draft" />
14
+ * <StatusBadge status="active" statusColorMap={{ active: 'default' }} />
15
+ */
16
+ function StatusBadge({ status, statusColorMap, className, ...rest }) {
17
+ const map = statusColorMap
18
+ ? { ...DEFAULT_STATUS_COLOR_MAP, ...statusColorMap }
19
+ : DEFAULT_STATUS_COLOR_MAP;
20
+ const variant = map[status] ?? 'outline';
21
+ const displayText = status.charAt(0).toUpperCase() + status.slice(1);
22
+ return (_jsx(Badge, { variant: variant, className: className, ...rest, children: displayText }));
23
+ }
24
+ export { StatusBadge };
25
+ //# sourceMappingURL=StatusBadge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusBadge.js","sourceRoot":"","sources":["../../src/primitives/StatusBadge.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAMhC,MAAM,wBAAwB,GAAiC;IAC7D,KAAK,EAAE,WAAW;IAClB,SAAS,EAAE,SAAS;IACpB,UAAU,EAAE,aAAa;CAC1B,CAAC;AAaF;;;;;;;GAOG;AACH,SAAS,WAAW,CAAC,EACnB,MAAM,EACN,cAAc,EACd,SAAS,EACT,GAAG,IAAI,EACU;IACjB,MAAM,GAAG,GAAG,cAAc;QACxB,CAAC,CAAC,EAAE,GAAG,wBAAwB,EAAE,GAAG,cAAc,EAAE;QACpD,CAAC,CAAC,wBAAwB,CAAC;IAE7B,MAAM,OAAO,GAAI,GAAG,CAAC,MAAM,CAA8B,IAAI,SAAS,CAAC;IACvE,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAErE,OAAO,CACL,KAAC,KAAK,IAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,KAAM,IAAI,YACpD,WAAW,GACN,CACT,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Tab Navigation Component
3
+ *
4
+ * A styled tab list for modal tabs with underline style (not rounded).
5
+ * Uses Radix UI Tabs primitives with custom styling for consistent modal navigation.
6
+ *
7
+ * @example Basic usage
8
+ * ```tsx
9
+ * <Tabs value={activeTab} onValueChange={setActiveTab}>
10
+ * <TabNavigation
11
+ * tabs={[
12
+ * { value: 'overview', label: 'Overview' },
13
+ * { value: 'settings', label: 'Settings' },
14
+ * ]}
15
+ * />
16
+ * <TabsContent value="overview">...</TabsContent>
17
+ * <TabsContent value="settings">...</TabsContent>
18
+ * </Tabs>
19
+ * ```
20
+ *
21
+ * @example With icons and badges
22
+ * ```tsx
23
+ * <TabNavigation
24
+ * tabs={[
25
+ * { value: 'overview', label: 'Overview', icon: Info },
26
+ * { value: 'files', label: 'Files', icon: FileText, badge: 12 },
27
+ * { value: 'disabled', label: 'Coming Soon', disabled: true },
28
+ * ]}
29
+ * />
30
+ * ```
31
+ */
32
+ import * as React from 'react';
33
+ export interface Tab {
34
+ /** Unique identifier for the tab */
35
+ value: string;
36
+ /** Display label for the tab */
37
+ label: string;
38
+ /** Optional icon component */
39
+ icon?: React.ComponentType<{
40
+ className?: string;
41
+ }>;
42
+ /** Optional badge count to display */
43
+ badge?: number;
44
+ /** Whether the tab is disabled */
45
+ disabled?: boolean;
46
+ }
47
+ export interface TabNavigationProps {
48
+ /** Array of tab configurations */
49
+ tabs: Tab[];
50
+ /** Additional CSS classes for the TabsList container */
51
+ className?: string;
52
+ /** Accessible label for the tab list */
53
+ ariaLabel?: string;
54
+ }
55
+ /**
56
+ * TabNavigation - Underline-styled tab list for modals
57
+ *
58
+ * Renders a horizontal tab list with underline styling instead of
59
+ * the default rounded pill style. Supports icons, badges, and disabled states.
60
+ *
61
+ * Must be used within a Tabs component from @radix-ui/react-tabs.
62
+ *
63
+ * @param tabs - Array of tab configurations
64
+ * @param className - Additional CSS classes for the container
65
+ * @param ariaLabel - Accessible label for the tab list
66
+ */
67
+ export declare function TabNavigation({ tabs, className, ariaLabel, }: TabNavigationProps): import("react/jsx-runtime").JSX.Element;
68
+ //# sourceMappingURL=TabNavigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TabNavigation.d.ts","sourceRoot":"","sources":["../../src/primitives/TabNavigation.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAIH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,MAAM,WAAW,GAAG;IAClB,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,kCAAkC;IAClC,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,SAAS,EACT,SAA6B,GAC9B,EAAE,kBAAkB,2CAsDpB"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Tab Navigation Component
3
+ *
4
+ * A styled tab list for modal tabs with underline style (not rounded).
5
+ * Uses Radix UI Tabs primitives with custom styling for consistent modal navigation.
6
+ *
7
+ * @example Basic usage
8
+ * ```tsx
9
+ * <Tabs value={activeTab} onValueChange={setActiveTab}>
10
+ * <TabNavigation
11
+ * tabs={[
12
+ * { value: 'overview', label: 'Overview' },
13
+ * { value: 'settings', label: 'Settings' },
14
+ * ]}
15
+ * />
16
+ * <TabsContent value="overview">...</TabsContent>
17
+ * <TabsContent value="settings">...</TabsContent>
18
+ * </Tabs>
19
+ * ```
20
+ *
21
+ * @example With icons and badges
22
+ * ```tsx
23
+ * <TabNavigation
24
+ * tabs={[
25
+ * { value: 'overview', label: 'Overview', icon: Info },
26
+ * { value: 'files', label: 'Files', icon: FileText, badge: 12 },
27
+ * { value: 'disabled', label: 'Coming Soon', disabled: true },
28
+ * ]}
29
+ * />
30
+ * ```
31
+ */
32
+ 'use client';
33
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
34
+ import { cn } from './utils';
35
+ import { TabsList, TabsTrigger } from './Tabs';
36
+ import { Badge } from './Badge';
37
+ // ============================================================================
38
+ // Component
39
+ // ============================================================================
40
+ /**
41
+ * TabNavigation - Underline-styled tab list for modals
42
+ *
43
+ * Renders a horizontal tab list with underline styling instead of
44
+ * the default rounded pill style. Supports icons, badges, and disabled states.
45
+ *
46
+ * Must be used within a Tabs component from @radix-ui/react-tabs.
47
+ *
48
+ * @param tabs - Array of tab configurations
49
+ * @param className - Additional CSS classes for the container
50
+ * @param ariaLabel - Accessible label for the tab list
51
+ */
52
+ export function TabNavigation({ tabs, className, ariaLabel = 'Navigation tabs', }) {
53
+ return (_jsx(TabsList, { className: cn(
54
+ // Override default rounded/background styling for underline style
55
+ 'h-auto w-full justify-start gap-0 rounded-none border-b bg-transparent p-0', className), "aria-label": ariaLabel, children: tabs.map((tab) => {
56
+ const Icon = tab.icon;
57
+ return (_jsxs(TabsTrigger, { value: tab.value, disabled: tab.disabled, className: cn(
58
+ // Base styles
59
+ 'relative inline-flex items-center gap-2 px-4 py-2.5 text-sm font-medium',
60
+ // Remove default rounded styling
61
+ 'rounded-none border-b-2 border-transparent bg-transparent shadow-none',
62
+ // Active state - underline instead of background
63
+ 'data-[state=active]:border-primary data-[state=active]:bg-transparent data-[state=active]:text-foreground data-[state=active]:shadow-none',
64
+ // Inactive/hover states
65
+ 'text-muted-foreground hover:text-foreground',
66
+ // Disabled state
67
+ 'disabled:cursor-not-allowed disabled:opacity-50',
68
+ // Focus ring
69
+ 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2'), "aria-label": tab.badge !== undefined && tab.badge > 0
70
+ ? `${tab.label}, ${tab.badge} items`
71
+ : undefined, children: [Icon && _jsx(Icon, { className: "h-4 w-4 flex-shrink-0", "aria-hidden": "true" }), _jsx("span", { children: tab.label }), typeof tab.badge === 'number' && tab.badge > 0 && (_jsx(Badge, { variant: "secondary", className: "ml-1 h-5 min-w-[1.25rem] px-1.5 text-xs", "aria-hidden": "true", children: tab.badge > 99 ? '99+' : tab.badge }))] }, tab.value));
72
+ }) }));
73
+ }
74
+ //# sourceMappingURL=TabNavigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TabNavigation.js","sourceRoot":"","sources":["../../src/primitives/TabNavigation.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,YAAY,CAAC;;AAGb,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AA4BhC,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,IAAI,EACJ,SAAS,EACT,SAAS,GAAG,iBAAiB,GACV;IACnB,OAAO,CACL,KAAC,QAAQ,IACP,SAAS,EAAE,EAAE;QACX,kEAAkE;QAClE,4EAA4E,EAC5E,SAAS,CACV,gBACW,SAAS,YAEpB,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YAChB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;YAEtB,OAAO,CACL,MAAC,WAAW,IAEV,KAAK,EAAE,GAAG,CAAC,KAAK,EAChB,QAAQ,EAAE,GAAG,CAAC,QAAQ,EACtB,SAAS,EAAE,EAAE;gBACX,cAAc;gBACd,yEAAyE;gBACzE,iCAAiC;gBACjC,uEAAuE;gBACvE,iDAAiD;gBACjD,2IAA2I;gBAC3I,wBAAwB;gBACxB,6CAA6C;gBAC7C,iBAAiB;gBACjB,iDAAiD;gBACjD,aAAa;gBACb,qGAAqG,CACtG,gBAEC,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,GAAG,CAAC,KAAK,GAAG,CAAC;oBACtC,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,KAAK,GAAG,CAAC,KAAK,QAAQ;oBACpC,CAAC,CAAC,SAAS,aAGd,IAAI,IAAI,KAAC,IAAI,IAAC,SAAS,EAAC,uBAAuB,iBAAa,MAAM,GAAG,EACtE,yBAAO,GAAG,CAAC,KAAK,GAAQ,EACvB,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,CACjD,KAAC,KAAK,IACJ,OAAO,EAAC,WAAW,EACnB,SAAS,EAAC,yCAAyC,iBACvC,MAAM,YAEjB,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,GAC7B,CACT,KAjCI,GAAG,CAAC,KAAK,CAkCF,CACf,CAAC;QACJ,CAAC,CAAC,GACO,CACZ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ import * as React from 'react';
2
+ import * as TabsPrimitive from '@radix-ui/react-tabs';
3
+ declare const Tabs: React.ForwardRefExoticComponent<TabsPrimitive.TabsProps & React.RefAttributes<HTMLDivElement>>;
4
+ declare const TabsList: React.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsListProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
5
+ declare const TabsTrigger: React.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
6
+ declare const TabsContent: React.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
7
+ export { Tabs, TabsList, TabsTrigger, TabsContent };
8
+ //# sourceMappingURL=Tabs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../src/primitives/Tabs.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAC;AAItD,QAAA,MAAM,IAAI,gGAAqB,CAAC;AAEhC,QAAA,MAAM,QAAQ,uJAYZ,CAAC;AAGH,QAAA,MAAM,WAAW,gKAYf,CAAC;AAGH,QAAA,MAAM,WAAW,0JAYf,CAAC;AAGH,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,14 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import * as React from 'react';
4
+ import * as TabsPrimitive from '@radix-ui/react-tabs';
5
+ import { cn } from './utils';
6
+ const Tabs = TabsPrimitive.Root;
7
+ const TabsList = React.forwardRef(({ className, ...props }, ref) => (_jsx(TabsPrimitive.List, { ref: ref, className: cn('inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground', className), ...props })));
8
+ TabsList.displayName = TabsPrimitive.List.displayName;
9
+ const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => (_jsx(TabsPrimitive.Trigger, { ref: ref, className: cn('inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow', className), ...props })));
10
+ TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
11
+ const TabsContent = React.forwardRef(({ className, ...props }, ref) => (_jsx(TabsPrimitive.Content, { ref: ref, className: cn('mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2', className), ...props })));
12
+ TabsContent.displayName = TabsPrimitive.Content.displayName;
13
+ export { Tabs, TabsList, TabsTrigger, TabsContent };
14
+ //# sourceMappingURL=Tabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tabs.js","sourceRoot":"","sources":["../../src/primitives/Tabs.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAE7B,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC;AAEhC,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAG/B,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClC,KAAC,aAAa,CAAC,IAAI,IACjB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CACX,2FAA2F,EAC3F,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAC,CAAC;AACH,QAAQ,CAAC,WAAW,GAAG,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC;AAEtD,MAAM,WAAW,GAAG,KAAK,CAAC,UAAU,CAGlC,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClC,KAAC,aAAa,CAAC,OAAO,IACpB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CACX,gYAAgY,EAChY,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAC,CAAC;AACH,WAAW,CAAC,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC;AAE5D,MAAM,WAAW,GAAG,KAAK,CAAC,UAAU,CAGlC,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClC,KAAC,aAAa,CAAC,OAAO,IACpB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CACX,iIAAiI,EACjI,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAC,CAAC;AACH,WAAW,CAAC,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC;AAE5D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ import * as React from 'react';
2
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
3
+ declare const TooltipProvider: React.FC<TooltipPrimitive.TooltipProviderProps>;
4
+ declare const Tooltip: React.FC<TooltipPrimitive.TooltipProps>;
5
+ declare const TooltipTrigger: React.ForwardRefExoticComponent<TooltipPrimitive.TooltipTriggerProps & React.RefAttributes<HTMLButtonElement>>;
6
+ declare const TooltipContent: React.ForwardRefExoticComponent<Omit<TooltipPrimitive.TooltipContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
7
+ export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
8
+ //# sourceMappingURL=Tooltip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../src/primitives/Tooltip.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAC;AAI5D,QAAA,MAAM,eAAe,iDAA4B,CAAC;AAElD,QAAA,MAAM,OAAO,yCAAwB,CAAC;AAEtC,QAAA,MAAM,cAAc,gHAA2B,CAAC;AAEhD,QAAA,MAAM,cAAc,gKAalB,CAAC;AAGH,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,12 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import * as React from 'react';
4
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
5
+ import { cn } from './utils';
6
+ const TooltipProvider = TooltipPrimitive.Provider;
7
+ const Tooltip = TooltipPrimitive.Root;
8
+ const TooltipTrigger = TooltipPrimitive.Trigger;
9
+ const TooltipContent = React.forwardRef(({ className, sideOffset = 4, ...props }, ref) => (_jsx(TooltipPrimitive.Content, { ref: ref, sideOffset: sideOffset, className: cn('z-50 origin-[--radix-tooltip-content-transform-origin] overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', className), ...props })));
10
+ TooltipContent.displayName = TooltipPrimitive.Content.displayName;
11
+ export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
12
+ //# sourceMappingURL=Tooltip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tooltip.js","sourceRoot":"","sources":["../../src/primitives/Tooltip.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAE7B,MAAM,eAAe,GAAG,gBAAgB,CAAC,QAAQ,CAAC;AAElD,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC;AAEtC,MAAM,cAAc,GAAG,gBAAgB,CAAC,OAAO,CAAC;AAEhD,MAAM,cAAc,GAAG,KAAK,CAAC,UAAU,CAGrC,CAAC,EAAE,SAAS,EAAE,UAAU,GAAG,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClD,KAAC,gBAAgB,CAAC,OAAO,IACvB,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,EAAE,CACX,sbAAsb,EACtb,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAC,CAAC;AACH,cAAc,CAAC,WAAW,GAAG,gBAAgB,CAAC,OAAO,CAAC,WAAW,CAAC;AAElE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Vertical Tab Navigation Component
3
+ *
4
+ * A standalone vertical tab list with keyboard navigation and ARIA attributes.
5
+ * Unlike TabNavigation (which wraps Radix TabsList), this component manages its
6
+ * own focus and activation logic so it can be used outside a Radix Tabs context —
7
+ * useful for sidebar navigation panels where the tab panel is rendered elsewhere.
8
+ *
9
+ * @example Basic usage
10
+ * ```tsx
11
+ * const [activeTab, setActiveTab] = React.useState('overview');
12
+ *
13
+ * <VerticalTabNavigation
14
+ * tabs={[
15
+ * { value: 'overview', label: 'Overview', icon: Info },
16
+ * { value: 'settings', label: 'Settings', icon: Settings },
17
+ * ]}
18
+ * activeTab={activeTab}
19
+ * onTabChange={setActiveTab}
20
+ * ariaLabel="Artifact detail navigation"
21
+ * />
22
+ * ```
23
+ *
24
+ * @example With badges and disabled tabs
25
+ * ```tsx
26
+ * <VerticalTabNavigation
27
+ * tabs={[
28
+ * { value: 'files', label: 'Files', icon: FileText, badge: 12 },
29
+ * { value: 'preview', label: 'Coming Soon', disabled: true },
30
+ * ]}
31
+ * activeTab={activeTab}
32
+ * onTabChange={setActiveTab}
33
+ * />
34
+ * ```
35
+ */
36
+ import * as React from 'react';
37
+ export type { Tab } from './TabNavigation';
38
+ import type { Tab } from './TabNavigation';
39
+ export interface VerticalTabNavigationProps {
40
+ /** Array of tab configurations */
41
+ tabs: Tab[];
42
+ /** Currently active tab value */
43
+ activeTab: string;
44
+ /** Callback invoked when the user selects a tab */
45
+ onTabChange: (tabId: string) => void;
46
+ /** Additional CSS classes for the container */
47
+ className?: string;
48
+ /** Accessible label for the tab list */
49
+ ariaLabel?: string;
50
+ }
51
+ /** Imperative handle exposed via forwardRef for programmatic focus control. */
52
+ export interface VerticalTabNavigationHandle {
53
+ /** Focus the first enabled tab button without changing the active tab. */
54
+ focusFirstTab: () => void;
55
+ }
56
+ /**
57
+ * VerticalTabNavigation — forward-ref enabled version of the component.
58
+ *
59
+ * Allows consumers to access the imperative handle for programmatic focus control
60
+ * via the `ref` prop.
61
+ *
62
+ * @example
63
+ * ```tsx
64
+ * const navRef = React.useRef<VerticalTabNavigationHandle>(null);
65
+ *
66
+ * // Focus the first tab when lens changes, without changing activeTab
67
+ * React.useEffect(() => {
68
+ * navRef.current?.focusFirstTab();
69
+ * }, [activeLens]);
70
+ *
71
+ * return <VerticalTabNavigation ref={navRef} tabs={tabs} activeTab={activeTab} ... />
72
+ * ```
73
+ */
74
+ export declare const VerticalTabNavigation: React.ForwardRefExoticComponent<VerticalTabNavigationProps & React.RefAttributes<VerticalTabNavigationHandle>>;
75
+ //# sourceMappingURL=VerticalTabNavigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VerticalTabNavigation.d.ts","sourceRoot":"","sources":["../../src/primitives/VerticalTabNavigation.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAIH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,YAAY,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAE3C,MAAM,WAAW,0BAA0B;IACzC,kCAAkC;IAClC,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,+EAA+E;AAC/E,MAAM,WAAW,2BAA2B;IAC1C,0EAA0E;IAC1E,aAAa,EAAE,MAAM,IAAI,CAAC;CAC3B;AA8KD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,qBAAqB,gHAA6B,CAAC"}
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Vertical Tab Navigation Component
3
+ *
4
+ * A standalone vertical tab list with keyboard navigation and ARIA attributes.
5
+ * Unlike TabNavigation (which wraps Radix TabsList), this component manages its
6
+ * own focus and activation logic so it can be used outside a Radix Tabs context —
7
+ * useful for sidebar navigation panels where the tab panel is rendered elsewhere.
8
+ *
9
+ * @example Basic usage
10
+ * ```tsx
11
+ * const [activeTab, setActiveTab] = React.useState('overview');
12
+ *
13
+ * <VerticalTabNavigation
14
+ * tabs={[
15
+ * { value: 'overview', label: 'Overview', icon: Info },
16
+ * { value: 'settings', label: 'Settings', icon: Settings },
17
+ * ]}
18
+ * activeTab={activeTab}
19
+ * onTabChange={setActiveTab}
20
+ * ariaLabel="Artifact detail navigation"
21
+ * />
22
+ * ```
23
+ *
24
+ * @example With badges and disabled tabs
25
+ * ```tsx
26
+ * <VerticalTabNavigation
27
+ * tabs={[
28
+ * { value: 'files', label: 'Files', icon: FileText, badge: 12 },
29
+ * { value: 'preview', label: 'Coming Soon', disabled: true },
30
+ * ]}
31
+ * activeTab={activeTab}
32
+ * onTabChange={setActiveTab}
33
+ * />
34
+ * ```
35
+ */
36
+ 'use client';
37
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
38
+ import * as React from 'react';
39
+ import { cn } from './utils';
40
+ import { Badge } from './Badge';
41
+ // ============================================================================
42
+ // Component
43
+ // ============================================================================
44
+ /**
45
+ * VerticalTabNavigation — standalone vertical tab list with full keyboard support.
46
+ *
47
+ * Implements the WAI-ARIA Tabs pattern with vertical orientation:
48
+ * - ArrowDown / ArrowUp navigate between enabled tabs (wraps around).
49
+ * - Home / End jump to first / last enabled tab.
50
+ * - Focus automatically activates the tab (roving tabindex pattern).
51
+ * - Tab key exits the tab list entirely (standard browser behavior).
52
+ *
53
+ * @param tabs - Array of tab configurations (value, label, icon, badge, disabled)
54
+ * @param activeTab - Controlled active tab value
55
+ * @param onTabChange - Callback fired when a tab becomes active
56
+ * @param className - Additional CSS classes for the container div
57
+ * @param ariaLabel - Accessible label for the tab list element
58
+ *
59
+ * Exposes a `VerticalTabNavigationHandle` via `forwardRef` with:
60
+ * - `focusFirstTab()` — moves focus to the first enabled tab without changing
61
+ * the active tab value. Useful when the tab list is swapped (e.g. lens change)
62
+ * and focus needs to follow the new content.
63
+ */
64
+ const VerticalTabNavigationInner = React.forwardRef(function VerticalTabNavigation({ tabs, activeTab, onTabChange, className, ariaLabel = 'Navigation tabs', }, ref) {
65
+ // Refs for each button so we can programmatically move focus.
66
+ const buttonRefs = React.useRef(new Map());
67
+ const enabledTabs = React.useMemo(() => tabs.filter((t) => !t.disabled), [tabs]);
68
+ // Expose imperative handle so parents can focus the first tab on demand
69
+ // (e.g. when a lens change swaps the visible tab list).
70
+ React.useImperativeHandle(ref, () => ({
71
+ focusFirstTab: () => {
72
+ const first = enabledTabs[0];
73
+ if (first) {
74
+ buttonRefs.current.get(first.value)?.focus();
75
+ }
76
+ },
77
+ }), [enabledTabs]);
78
+ const focusAndActivate = React.useCallback((tabValue) => {
79
+ onTabChange(tabValue);
80
+ buttonRefs.current.get(tabValue)?.focus();
81
+ }, [onTabChange]);
82
+ // WAI-ARIA Tabs pattern keyboard handler.
83
+ // Implements arrow key navigation (wraps around), Home/End jumping, and focus-activates
84
+ // the roving tabindex pattern (only one tab is ever in the tab order at a time).
85
+ const handleKeyDown = React.useCallback((event, currentValue) => {
86
+ const currentIndex = enabledTabs.findIndex((t) => t.value === currentValue);
87
+ switch (event.key) {
88
+ case 'ArrowDown': {
89
+ event.preventDefault();
90
+ const next = enabledTabs[(currentIndex + 1) % enabledTabs.length];
91
+ if (next)
92
+ focusAndActivate(next.value);
93
+ break;
94
+ }
95
+ case 'ArrowUp': {
96
+ event.preventDefault();
97
+ const prev = enabledTabs[(currentIndex - 1 + enabledTabs.length) % enabledTabs.length];
98
+ if (prev)
99
+ focusAndActivate(prev.value);
100
+ break;
101
+ }
102
+ case 'Home': {
103
+ event.preventDefault();
104
+ const first = enabledTabs[0];
105
+ if (first)
106
+ focusAndActivate(first.value);
107
+ break;
108
+ }
109
+ case 'End': {
110
+ event.preventDefault();
111
+ const last = enabledTabs[enabledTabs.length - 1];
112
+ if (last)
113
+ focusAndActivate(last.value);
114
+ break;
115
+ }
116
+ default:
117
+ break;
118
+ }
119
+ }, [enabledTabs, focusAndActivate]);
120
+ return (_jsx("div", { role: "tablist", "aria-orientation": "vertical", "aria-label": ariaLabel, className: cn('flex flex-col', className), children: tabs.map((tab) => {
121
+ const Icon = tab.icon;
122
+ const isActive = tab.value === activeTab;
123
+ return (_jsxs("button", { ref: (el) => {
124
+ if (el) {
125
+ buttonRefs.current.set(tab.value, el);
126
+ }
127
+ else {
128
+ buttonRefs.current.delete(tab.value);
129
+ }
130
+ }, role: "tab", "aria-selected": isActive, "aria-controls": `panel-${tab.value}`, "aria-disabled": tab.disabled, tabIndex: isActive ? 0 : -1, disabled: tab.disabled, onClick: () => !tab.disabled && onTabChange(tab.value), onKeyDown: (e) => !tab.disabled && handleKeyDown(e, tab.value), "aria-label": tab.badge !== undefined && tab.badge > 0
131
+ ? `${tab.label}, ${tab.badge} items`
132
+ : undefined, className: cn(
133
+ // Base
134
+ 'flex items-center gap-2 px-3 py-2 text-sm rounded-r-md w-full text-left',
135
+ // Transition
136
+ 'transition-colors',
137
+ // Active state
138
+ isActive
139
+ ? 'border-l-2 border-primary bg-accent text-foreground font-medium'
140
+ : 'border-l-2 border-transparent text-muted-foreground hover:bg-accent/50',
141
+ // Disabled state
142
+ tab.disabled && 'cursor-not-allowed opacity-50',
143
+ // Focus ring
144
+ 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2'), children: [Icon && _jsx(Icon, { className: "h-4 w-4 flex-shrink-0", "aria-hidden": "true" }), _jsx("span", { className: "flex-1 text-sm", children: tab.label }), typeof tab.badge === 'number' && tab.badge > 0 && (_jsx(Badge, { variant: "secondary", className: "ml-1 h-5 min-w-[1.25rem] px-1.5 text-xs", "aria-hidden": "true", children: tab.badge > 99 ? '99+' : tab.badge }))] }, tab.value));
145
+ }) }));
146
+ });
147
+ /**
148
+ * VerticalTabNavigation — forward-ref enabled version of the component.
149
+ *
150
+ * Allows consumers to access the imperative handle for programmatic focus control
151
+ * via the `ref` prop.
152
+ *
153
+ * @example
154
+ * ```tsx
155
+ * const navRef = React.useRef<VerticalTabNavigationHandle>(null);
156
+ *
157
+ * // Focus the first tab when lens changes, without changing activeTab
158
+ * React.useEffect(() => {
159
+ * navRef.current?.focusFirstTab();
160
+ * }, [activeLens]);
161
+ *
162
+ * return <VerticalTabNavigation ref={navRef} tabs={tabs} activeTab={activeTab} ... />
163
+ * ```
164
+ */
165
+ export const VerticalTabNavigation = VerticalTabNavigationInner;
166
+ //# sourceMappingURL=VerticalTabNavigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VerticalTabNavigation.js","sourceRoot":"","sources":["../../src/primitives/VerticalTabNavigation.tsx"],"names":[],"mappings":"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"}