azamat-ui-kit-cli 0.2.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 (213) hide show
  1. package/README.md +8 -0
  2. package/dist/index.js +432 -0
  3. package/package.json +34 -0
  4. package/vendor/package.json +4 -0
  5. package/vendor/src/components/actions/action-bar.tsx +35 -0
  6. package/vendor/src/components/actions/action-menu.tsx +120 -0
  7. package/vendor/src/components/actions/button-group.tsx +47 -0
  8. package/vendor/src/components/actions/copy-button.tsx +91 -0
  9. package/vendor/src/components/actions/copy-field.tsx +31 -0
  10. package/vendor/src/components/actions/floating-action-button.tsx +33 -0
  11. package/vendor/src/components/actions/index.ts +7 -0
  12. package/vendor/src/components/actions/public.ts +5 -0
  13. package/vendor/src/components/actions/quick-action-grid.tsx +162 -0
  14. package/vendor/src/components/calendar/calendar.tsx +328 -0
  15. package/vendor/src/components/calendar/date-picker.tsx +78 -0
  16. package/vendor/src/components/calendar/date-range-picker.tsx +96 -0
  17. package/vendor/src/components/calendar/date-utils.ts +89 -0
  18. package/vendor/src/components/calendar/index.ts +4 -0
  19. package/vendor/src/components/charts/charts.tsx +275 -0
  20. package/vendor/src/components/charts/horizontal-bar-chart.tsx +46 -0
  21. package/vendor/src/components/charts/index.ts +4 -0
  22. package/vendor/src/components/charts/kpi.tsx +68 -0
  23. package/vendor/src/components/charts/progress-ring.tsx +45 -0
  24. package/vendor/src/components/charts/public.ts +1 -0
  25. package/vendor/src/components/command/command-palette.tsx +375 -0
  26. package/vendor/src/components/command/index.ts +1 -0
  27. package/vendor/src/components/data-table/data-table-actions-column.tsx +58 -0
  28. package/vendor/src/components/data-table/data-table-bulk-actions.tsx +84 -0
  29. package/vendor/src/components/data-table/data-table-column-visibility-menu.tsx +79 -0
  30. package/vendor/src/components/data-table/data-table-pagination.tsx +91 -0
  31. package/vendor/src/components/data-table/data-table-row-actions.tsx +48 -0
  32. package/vendor/src/components/data-table/data-table-select-column.tsx +59 -0
  33. package/vendor/src/components/data-table/data-table-sortable-header.tsx +45 -0
  34. package/vendor/src/components/data-table/data-table-toolbar.tsx +76 -0
  35. package/vendor/src/components/data-table/data-table-view-presets.tsx +128 -0
  36. package/vendor/src/components/data-table/data-table.tsx +507 -0
  37. package/vendor/src/components/data-table/index.ts +12 -0
  38. package/vendor/src/components/data-table/public.ts +10 -0
  39. package/vendor/src/components/data-table/table-export-menu.tsx +56 -0
  40. package/vendor/src/components/data-table/table-import-button.tsx +43 -0
  41. package/vendor/src/components/display/activity-feed.tsx +97 -0
  42. package/vendor/src/components/display/avatar.tsx +131 -0
  43. package/vendor/src/components/display/code-block.tsx +33 -0
  44. package/vendor/src/components/display/data-state.tsx +63 -0
  45. package/vendor/src/components/display/description-list.tsx +119 -0
  46. package/vendor/src/components/display/descriptions.tsx +83 -0
  47. package/vendor/src/components/display/entity-card.tsx +53 -0
  48. package/vendor/src/components/display/file-card.tsx +54 -0
  49. package/vendor/src/components/display/index.ts +30 -0
  50. package/vendor/src/components/display/kanban.tsx +104 -0
  51. package/vendor/src/components/display/keyboard-shortcut.tsx +31 -0
  52. package/vendor/src/components/display/list.tsx +100 -0
  53. package/vendor/src/components/display/metric-grid.tsx +86 -0
  54. package/vendor/src/components/display/progress.tsx +162 -0
  55. package/vendor/src/components/display/property-grid.tsx +54 -0
  56. package/vendor/src/components/display/result.tsx +90 -0
  57. package/vendor/src/components/display/smart-card.tsx +168 -0
  58. package/vendor/src/components/display/statistic.tsx +107 -0
  59. package/vendor/src/components/display/status-legend.tsx +108 -0
  60. package/vendor/src/components/display/tag-list.tsx +52 -0
  61. package/vendor/src/components/display/timeline.tsx +132 -0
  62. package/vendor/src/components/display/tree-view.tsx +116 -0
  63. package/vendor/src/components/feedback/alert.tsx +69 -0
  64. package/vendor/src/components/feedback/empty-state.tsx +56 -0
  65. package/vendor/src/components/feedback/index.ts +5 -0
  66. package/vendor/src/components/feedback/loading-state.tsx +39 -0
  67. package/vendor/src/components/feedback/page-state.tsx +69 -0
  68. package/vendor/src/components/feedback/status-badge.tsx +62 -0
  69. package/vendor/src/components/filters/filter-bar.tsx +89 -0
  70. package/vendor/src/components/filters/filter-chips.tsx +69 -0
  71. package/vendor/src/components/filters/index.ts +2 -0
  72. package/vendor/src/components/form/form-actions.tsx +53 -0
  73. package/vendor/src/components/form/form-async-select.tsx +26 -0
  74. package/vendor/src/components/form/form-date-input.tsx +19 -0
  75. package/vendor/src/components/form/form-date-picker.tsx +54 -0
  76. package/vendor/src/components/form/form-date-range-input.tsx +79 -0
  77. package/vendor/src/components/form/form-date-range-picker.tsx +57 -0
  78. package/vendor/src/components/form/form-field-shell.tsx +191 -0
  79. package/vendor/src/components/form/form-input.tsx +480 -0
  80. package/vendor/src/components/form/form-number-input.tsx +19 -0
  81. package/vendor/src/components/form/form-password-input.tsx +19 -0
  82. package/vendor/src/components/form/form-phone-input.tsx +22 -0
  83. package/vendor/src/components/form/form-search-input.tsx +19 -0
  84. package/vendor/src/components/form/form-section.tsx +29 -0
  85. package/vendor/src/components/form/form-select.tsx +194 -0
  86. package/vendor/src/components/form/form-switch.tsx +145 -0
  87. package/vendor/src/components/form/form-textarea.tsx +103 -0
  88. package/vendor/src/components/form/index.ts +17 -0
  89. package/vendor/src/components/form/public.ts +14 -0
  90. package/vendor/src/components/form/smart-form-shell.tsx +59 -0
  91. package/vendor/src/components/inputs/async-select.tsx +1143 -0
  92. package/vendor/src/components/inputs/clearable-input.tsx +78 -0
  93. package/vendor/src/components/inputs/color-input.tsx +47 -0
  94. package/vendor/src/components/inputs/combobox.tsx +89 -0
  95. package/vendor/src/components/inputs/date-input.tsx +32 -0
  96. package/vendor/src/components/inputs/date-range-input.tsx +67 -0
  97. package/vendor/src/components/inputs/index.ts +19 -0
  98. package/vendor/src/components/inputs/input-chrome.tsx +37 -0
  99. package/vendor/src/components/inputs/input-decorator.tsx +64 -0
  100. package/vendor/src/components/inputs/input-value.ts +42 -0
  101. package/vendor/src/components/inputs/masked-input.tsx +51 -0
  102. package/vendor/src/components/inputs/money-input.tsx +73 -0
  103. package/vendor/src/components/inputs/number-input.tsx +87 -0
  104. package/vendor/src/components/inputs/numeric-value.ts +39 -0
  105. package/vendor/src/components/inputs/otp-input.tsx +102 -0
  106. package/vendor/src/components/inputs/password-input.tsx +85 -0
  107. package/vendor/src/components/inputs/phone-input.tsx +46 -0
  108. package/vendor/src/components/inputs/quantity-input.tsx +116 -0
  109. package/vendor/src/components/inputs/quantity-stepper.tsx +49 -0
  110. package/vendor/src/components/inputs/rating.tsx +98 -0
  111. package/vendor/src/components/inputs/search-input.tsx +26 -0
  112. package/vendor/src/components/inputs/simple-select.tsx +72 -0
  113. package/vendor/src/components/inputs/slider.tsx +149 -0
  114. package/vendor/src/components/inputs/tag-input.tsx +104 -0
  115. package/vendor/src/components/layout/app-header.tsx +46 -0
  116. package/vendor/src/components/layout/app-shell.tsx +243 -0
  117. package/vendor/src/components/layout/app-sidebar.tsx +179 -0
  118. package/vendor/src/components/layout/breadcrumbs.tsx +72 -0
  119. package/vendor/src/components/layout/index.ts +11 -0
  120. package/vendor/src/components/layout/page-container.tsx +30 -0
  121. package/vendor/src/components/layout/page-header.tsx +60 -0
  122. package/vendor/src/components/layout/public.ts +10 -0
  123. package/vendor/src/components/layout/section.tsx +76 -0
  124. package/vendor/src/components/layout/sidebar-nav.tsx +147 -0
  125. package/vendor/src/components/layout/stat-card.tsx +88 -0
  126. package/vendor/src/components/layout/sticky-footer-bar.tsx +23 -0
  127. package/vendor/src/components/layout/workspace-shell.tsx +50 -0
  128. package/vendor/src/components/navigation/anchor-nav.tsx +44 -0
  129. package/vendor/src/components/navigation/index.ts +4 -0
  130. package/vendor/src/components/navigation/page-tabs.tsx +67 -0
  131. package/vendor/src/components/navigation/pagination.tsx +179 -0
  132. package/vendor/src/components/navigation/stepper-tabs.tsx +67 -0
  133. package/vendor/src/components/notifications/index.ts +1 -0
  134. package/vendor/src/components/notifications/toast.tsx +259 -0
  135. package/vendor/src/components/overlay/confirm-dialog.tsx +66 -0
  136. package/vendor/src/components/overlay/dialog-actions.tsx +68 -0
  137. package/vendor/src/components/overlay/index.ts +4 -0
  138. package/vendor/src/components/overlay/modal-shell.tsx +93 -0
  139. package/vendor/src/components/overlay/sheet-shell.tsx +212 -0
  140. package/vendor/src/components/patterns/action-system.tsx +116 -0
  141. package/vendor/src/components/patterns/crud-system.tsx +53 -0
  142. package/vendor/src/components/patterns/data-view.tsx +84 -0
  143. package/vendor/src/components/patterns/entity-details.tsx +66 -0
  144. package/vendor/src/components/patterns/filter-builder.tsx +113 -0
  145. package/vendor/src/components/patterns/form-builder-presets.ts +131 -0
  146. package/vendor/src/components/patterns/form-builder.tsx +334 -0
  147. package/vendor/src/components/patterns/index.ts +12 -0
  148. package/vendor/src/components/patterns/public.ts +4 -0
  149. package/vendor/src/components/patterns/resource-detail-page.tsx +160 -0
  150. package/vendor/src/components/patterns/resource-page.tsx +159 -0
  151. package/vendor/src/components/patterns/resource-system.tsx +61 -0
  152. package/vendor/src/components/patterns/settings-section.tsx +46 -0
  153. package/vendor/src/components/patterns/status-system.tsx +89 -0
  154. package/vendor/src/components/theme-provider.tsx +51 -0
  155. package/vendor/src/components/ui/badge.tsx +52 -0
  156. package/vendor/src/components/ui/button.tsx +61 -0
  157. package/vendor/src/components/ui/card.tsx +103 -0
  158. package/vendor/src/components/ui/checkbox.tsx +82 -0
  159. package/vendor/src/components/ui/collapse.tsx +126 -0
  160. package/vendor/src/components/ui/command.tsx +194 -0
  161. package/vendor/src/components/ui/dialog.tsx +160 -0
  162. package/vendor/src/components/ui/divider.tsx +46 -0
  163. package/vendor/src/components/ui/dropdown-menu.tsx +266 -0
  164. package/vendor/src/components/ui/input-group.tsx +158 -0
  165. package/vendor/src/components/ui/input.tsx +20 -0
  166. package/vendor/src/components/ui/popover.tsx +90 -0
  167. package/vendor/src/components/ui/segmented-control.tsx +78 -0
  168. package/vendor/src/components/ui/select.tsx +201 -0
  169. package/vendor/src/components/ui/skeleton.tsx +75 -0
  170. package/vendor/src/components/ui/spinner.tsx +50 -0
  171. package/vendor/src/components/ui/switch.tsx +71 -0
  172. package/vendor/src/components/ui/table.tsx +114 -0
  173. package/vendor/src/components/ui/tabs.tsx +55 -0
  174. package/vendor/src/components/ui/textarea.tsx +18 -0
  175. package/vendor/src/components/ui/tooltip.tsx +38 -0
  176. package/vendor/src/components/upload/file-upload.tsx +483 -0
  177. package/vendor/src/components/upload/image-upload.tsx +118 -0
  178. package/vendor/src/components/upload/index.ts +2 -0
  179. package/vendor/src/components/wizard/index.ts +2 -0
  180. package/vendor/src/components/wizard/stepper.tsx +53 -0
  181. package/vendor/src/components/wizard/wizard.tsx +60 -0
  182. package/vendor/src/families/card-family.ts +28 -0
  183. package/vendor/src/families/catalog.ts +96 -0
  184. package/vendor/src/families/data-table-family.ts +31 -0
  185. package/vendor/src/families/docs-adoption.ts +103 -0
  186. package/vendor/src/families/docs-groups.ts +209 -0
  187. package/vendor/src/families/docs-queries.ts +84 -0
  188. package/vendor/src/families/docs-routing.ts +89 -0
  189. package/vendor/src/families/form-family.ts +45 -0
  190. package/vendor/src/families/index.ts +17 -0
  191. package/vendor/src/families/input-family.ts +61 -0
  192. package/vendor/src/families/member-metadata.ts +466 -0
  193. package/vendor/src/families/member-queries.ts +28 -0
  194. package/vendor/src/families/member-snippet-queries.ts +54 -0
  195. package/vendor/src/families/member-snippets.ts +673 -0
  196. package/vendor/src/families/migration-map.ts +79 -0
  197. package/vendor/src/families/queries.ts +63 -0
  198. package/vendor/src/families/select-family.ts +33 -0
  199. package/vendor/src/families/views.ts +81 -0
  200. package/vendor/src/hooks/index.ts +6 -0
  201. package/vendor/src/hooks/use-before-unload-when-dirty.ts +21 -0
  202. package/vendor/src/hooks/use-data-table-view-state.ts +122 -0
  203. package/vendor/src/hooks/use-debounce.ts +52 -0
  204. package/vendor/src/hooks/use-disclosure.ts +38 -0
  205. package/vendor/src/hooks/use-is-mobile.ts +28 -0
  206. package/vendor/src/hooks/use-session-storage-state.ts +85 -0
  207. package/vendor/src/index.ts +38 -0
  208. package/vendor/src/lib/utils.ts +6 -0
  209. package/vendor/templates/components/button.tsx +0 -0
  210. package/vendor/templates/components/data-table.tsx +0 -0
  211. package/vendor/templates/components/input.tsx +0 -0
  212. package/vendor/templates/lib/utils.ts +0 -0
  213. package/vendor/templates/styles/globals.css +0 -0
@@ -0,0 +1,79 @@
1
+ export type FamilyMigrationStatus =
2
+ | "canonical"
3
+ | "family-member"
4
+ | "family-member helper"
5
+ | "canonical composed member"
6
+ | "transitional"
7
+ | "advanced"
8
+
9
+ export type FamilyMigrationEntry = {
10
+ component: string
11
+ family: "InputFamily" | "SelectFamily" | "CardFamily" | "FormFamily" | "DataTableFamily"
12
+ member?: string
13
+ status: FamilyMigrationStatus
14
+ notes?: string
15
+ }
16
+
17
+ export const componentFamilyMigrationMap: FamilyMigrationEntry[] = [
18
+ { component: "Input", family: "InputFamily", member: "Root", status: "canonical" },
19
+ { component: "ClearableInput", family: "InputFamily", member: "Clearable", status: "family-member" },
20
+ { component: "SearchInput", family: "InputFamily", member: "Search", status: "family-member" },
21
+ { component: "PasswordInput", family: "InputFamily", member: "Password", status: "family-member" },
22
+ { component: "NumberInput", family: "InputFamily", member: "Number", status: "family-member" },
23
+ { component: "DateInput", family: "InputFamily", member: "Date", status: "family-member" },
24
+ { component: "DateRangeInput", family: "InputFamily", member: "DateRange", status: "family-member" },
25
+ { component: "MoneyInput", family: "InputFamily", member: "Money", status: "family-member" },
26
+ { component: "QuantityInput", family: "InputFamily", member: "Quantity", status: "family-member" },
27
+ { component: "MaskedInput", family: "InputFamily", member: "Masked", status: "family-member" },
28
+ { component: "PhoneInput", family: "InputFamily", member: "Phone", status: "family-member" },
29
+ { component: "OtpInput", family: "InputFamily", member: "Otp", status: "family-member" },
30
+ { component: "ColorInput", family: "InputFamily", member: "Color", status: "family-member" },
31
+ { component: "TagInput", family: "InputFamily", member: "Tag", status: "advanced" },
32
+ { component: "QuantityStepper", family: "InputFamily", member: "QuantityStepper", status: "advanced" },
33
+
34
+ { component: "Select", family: "SelectFamily", member: "Root", status: "canonical" },
35
+ { component: "SimpleSelect", family: "SelectFamily", member: "Simple", status: "family-member" },
36
+ { component: "AsyncSelect", family: "SelectFamily", member: "Async", status: "family-member" },
37
+ { component: "AsyncMultiSelect", family: "SelectFamily", member: "AsyncMulti", status: "family-member" },
38
+ { component: "Combobox", family: "SelectFamily", member: "Combobox", status: "family-member" },
39
+ { component: "FormSelect", family: "SelectFamily", member: "Form.Select", status: "family-member" },
40
+ { component: "FormAsyncSelect", family: "SelectFamily", member: "Form.Async", status: "family-member" },
41
+
42
+ { component: "Card", family: "CardFamily", member: "Root", status: "canonical" },
43
+ { component: "InfoCard", family: "CardFamily", member: "Info", status: "canonical composed member" },
44
+ { component: "SmartCard", family: "CardFamily", member: "Info", status: "transitional", notes: "Prefer InfoCard or CardFamily.Info in docs and new usage." },
45
+ { component: "StatCard", family: "CardFamily", member: "Stat", status: "family-member" },
46
+ { component: "StatisticCard", family: "CardFamily", member: "Statistic", status: "family-member" },
47
+ { component: "EntityCard", family: "CardFamily", member: "Entity", status: "family-member" },
48
+ { component: "FileCard", family: "CardFamily", member: "File", status: "family-member" },
49
+
50
+ { component: "FormFieldShell", family: "FormFamily", member: "Field", status: "canonical" },
51
+ { component: "FormInput", family: "FormFamily", member: "Input", status: "family-member" },
52
+ { component: "FormTextarea", family: "FormFamily", member: "Textarea", status: "family-member" },
53
+ { component: "FormSelect", family: "FormFamily", member: "Select", status: "family-member" },
54
+ { component: "FormAsyncSelect", family: "FormFamily", member: "AsyncSelect", status: "family-member" },
55
+ { component: "FormSwitch", family: "FormFamily", member: "Switch", status: "family-member" },
56
+ { component: "FormSearchInput", family: "FormFamily", member: "Search", status: "family-member" },
57
+ { component: "FormPasswordInput", family: "FormFamily", member: "Password", status: "family-member" },
58
+ { component: "FormNumberInput", family: "FormFamily", member: "Number", status: "family-member" },
59
+ { component: "FormPhoneInput", family: "FormFamily", member: "Phone", status: "family-member" },
60
+ { component: "FormDateInput", family: "FormFamily", member: "Date", status: "family-member" },
61
+ { component: "FormDateRangeInput", family: "FormFamily", member: "DateRange", status: "family-member" },
62
+ { component: "FormDatePicker", family: "FormFamily", member: "DatePicker", status: "family-member" },
63
+ { component: "FormDateRangePicker", family: "FormFamily", member: "DateRangePicker", status: "family-member" },
64
+ { component: "SmartFormShell", family: "FormFamily", member: "Shell", status: "transitional" },
65
+ { component: "FormBuilder", family: "FormFamily", member: "Builder", status: "advanced" },
66
+
67
+ { component: "DataTable", family: "DataTableFamily", member: "Root", status: "canonical" },
68
+ { component: "DataTableToolbar", family: "DataTableFamily", member: "Toolbar", status: "family-member" },
69
+ { component: "DataTablePagination", family: "DataTableFamily", member: "Pagination", status: "family-member" },
70
+ { component: "DataTableColumnVisibilityMenu", family: "DataTableFamily", member: "ColumnVisibilityMenu", status: "family-member" },
71
+ { component: "DataTableSortableHeader", family: "DataTableFamily", member: "SortableHeader", status: "family-member" },
72
+ { component: "DataTableRowActions", family: "DataTableFamily", member: "RowActions", status: "family-member" },
73
+ { component: "DataTableBulkActions", family: "DataTableFamily", member: "BulkActions", status: "family-member" },
74
+ { component: "DataTableViewPresets", family: "DataTableFamily", member: "ViewPresets", status: "family-member" },
75
+ { component: "createDataTableSelectColumn", family: "DataTableFamily", member: "createSelectColumn", status: "family-member helper" },
76
+ { component: "createDataTableActionsColumn", family: "DataTableFamily", member: "createActionsColumn", status: "family-member helper" },
77
+ { component: "TableExportMenu", family: "DataTableFamily", member: "ExportMenu", status: "advanced" },
78
+ { component: "TableImportButton", family: "DataTableFamily", member: "ImportButton", status: "advanced" },
79
+ ] as const
@@ -0,0 +1,63 @@
1
+ import { componentFamilyCatalog, type ComponentFamilyCatalogEntry, type ComponentFamilyName } from "@/families/catalog"
2
+ import {
3
+ componentFamilyMigrationMap,
4
+ type FamilyMigrationEntry,
5
+ type FamilyMigrationStatus,
6
+ } from "@/families/migration-map"
7
+
8
+ const familyCatalogMap = new Map<ComponentFamilyName, ComponentFamilyCatalogEntry>(
9
+ componentFamilyCatalog.map((entry) => [entry.family, entry])
10
+ )
11
+
12
+ const componentMigrationMap = new Map<string, FamilyMigrationEntry[]>()
13
+
14
+ for (const entry of componentFamilyMigrationMap) {
15
+ const existingEntries = componentMigrationMap.get(entry.component) ?? []
16
+ existingEntries.push(entry)
17
+ componentMigrationMap.set(entry.component, existingEntries)
18
+ }
19
+
20
+ function getFamilyCatalogEntry(family: ComponentFamilyName) {
21
+ return familyCatalogMap.get(family)
22
+ }
23
+
24
+ function getFamilyMembers(family: ComponentFamilyName) {
25
+ return componentFamilyMigrationMap.filter((entry) => entry.family === family)
26
+ }
27
+
28
+ function getComponentFamilyEntry(component: string) {
29
+ return componentMigrationMap.get(component)?.[0]
30
+ }
31
+
32
+ function getComponentFamilyEntries(component: string) {
33
+ return componentMigrationMap.get(component) ?? []
34
+ }
35
+
36
+ function listComponentsByStatus(status: FamilyMigrationStatus) {
37
+ return componentFamilyMigrationMap.filter((entry) => entry.status === status)
38
+ }
39
+
40
+ function listTransitionalComponents() {
41
+ return listComponentsByStatus("transitional")
42
+ }
43
+
44
+ function listAdvancedComponents() {
45
+ return listComponentsByStatus("advanced")
46
+ }
47
+
48
+ function listCanonicalComponents() {
49
+ return componentFamilyMigrationMap.filter(
50
+ (entry) => entry.status === "canonical" || entry.status === "canonical composed member"
51
+ )
52
+ }
53
+
54
+ export {
55
+ getComponentFamilyEntry,
56
+ getComponentFamilyEntries,
57
+ getFamilyCatalogEntry,
58
+ getFamilyMembers,
59
+ listAdvancedComponents,
60
+ listCanonicalComponents,
61
+ listComponentsByStatus,
62
+ listTransitionalComponents,
63
+ }
@@ -0,0 +1,33 @@
1
+ import { FormAsyncSelect, FormSelect } from "@/components/form"
2
+ import { AsyncMultiSelect, AsyncSelect, Combobox, SimpleSelect } from "@/components/inputs"
3
+ import {
4
+ Select,
5
+ SelectContent,
6
+ SelectGroup,
7
+ SelectItem,
8
+ SelectLabel,
9
+ SelectSeparator,
10
+ SelectTrigger,
11
+ SelectValue,
12
+ } from "@/components/ui/select"
13
+
14
+ const SelectFamily = {
15
+ Root: Select,
16
+ Trigger: SelectTrigger,
17
+ Value: SelectValue,
18
+ Content: SelectContent,
19
+ Group: SelectGroup,
20
+ Label: SelectLabel,
21
+ Item: SelectItem,
22
+ Separator: SelectSeparator,
23
+ Simple: SimpleSelect,
24
+ Async: AsyncSelect,
25
+ AsyncMulti: AsyncMultiSelect,
26
+ Combobox,
27
+ Form: {
28
+ Select: FormSelect,
29
+ Async: FormAsyncSelect,
30
+ },
31
+ } as const
32
+
33
+ export { SelectFamily }
@@ -0,0 +1,81 @@
1
+ import { componentFamilyCatalog, type ComponentFamilyCatalogEntry, type ComponentFamilyName } from "@/families/catalog"
2
+ import type { FamilyMigrationEntry } from "@/families/migration-map"
3
+ import {
4
+ getFamilyCatalogEntry,
5
+ getFamilyMembers,
6
+ listAdvancedComponents,
7
+ listCanonicalComponents,
8
+ listTransitionalComponents,
9
+ } from "@/families/queries"
10
+
11
+ export type ComponentFamilyView = ComponentFamilyCatalogEntry & {
12
+ canonicalEntries: FamilyMigrationEntry[]
13
+ memberEntries: FamilyMigrationEntry[]
14
+ transitionalEntries: FamilyMigrationEntry[]
15
+ advancedEntries: FamilyMigrationEntry[]
16
+ }
17
+
18
+ function toSortedEntries(entries: FamilyMigrationEntry[]) {
19
+ return [...entries].sort((left, right) => left.component.localeCompare(right.component))
20
+ }
21
+
22
+ function getFamilyView(family: ComponentFamilyName): ComponentFamilyView | undefined {
23
+ const catalogEntry = getFamilyCatalogEntry(family)
24
+
25
+ if (!catalogEntry) return undefined
26
+
27
+ const familyMembers = getFamilyMembers(family)
28
+ const canonicalEntries = toSortedEntries(
29
+ familyMembers.filter(
30
+ (entry) => entry.status === "canonical" || entry.status === "canonical composed member"
31
+ )
32
+ )
33
+ const transitionalEntries = toSortedEntries(
34
+ familyMembers.filter((entry) => entry.status === "transitional")
35
+ )
36
+ const advancedEntries = toSortedEntries(
37
+ familyMembers.filter((entry) => entry.status === "advanced")
38
+ )
39
+ const memberEntries = toSortedEntries(
40
+ familyMembers.filter(
41
+ (entry) => entry.status === "family-member" || entry.status === "family-member helper"
42
+ )
43
+ )
44
+
45
+ return {
46
+ ...catalogEntry,
47
+ canonicalEntries,
48
+ memberEntries,
49
+ transitionalEntries,
50
+ advancedEntries,
51
+ }
52
+ }
53
+
54
+ function listFamilyViews() {
55
+ return componentFamilyCatalog
56
+ .map((entry) => getFamilyView(entry.family))
57
+ .filter((entry): entry is ComponentFamilyView => Boolean(entry))
58
+ }
59
+
60
+ function getFamilyNavigation() {
61
+ return componentFamilyCatalog.map((entry) => ({
62
+ family: entry.family,
63
+ label: entry.label,
64
+ description: entry.description,
65
+ canonicalCount: entry.canonical.length,
66
+ memberCount: entry.members.length,
67
+ transitionalCount: entry.transitional?.length ?? 0,
68
+ advancedCount: entry.advanced?.length ?? 0,
69
+ }))
70
+ }
71
+
72
+ function getMetadataSummary() {
73
+ return {
74
+ families: componentFamilyCatalog.length,
75
+ canonical: listCanonicalComponents().length,
76
+ transitional: listTransitionalComponents().length,
77
+ advanced: listAdvancedComponents().length,
78
+ }
79
+ }
80
+
81
+ export { getFamilyNavigation, getFamilyView, getMetadataSummary, listFamilyViews }
@@ -0,0 +1,6 @@
1
+ export * from "./use-session-storage-state"
2
+ export * from "./use-before-unload-when-dirty"
3
+ export * from "./use-is-mobile"
4
+ export * from "./use-disclosure"
5
+ export * from "./use-debounce"
6
+ export * from "./use-data-table-view-state"
@@ -0,0 +1,21 @@
1
+ import * as React from "react"
2
+
3
+ function useBeforeUnloadWhenDirty(isDirty: boolean, message = "Changes you made may not be saved.") {
4
+ React.useEffect(() => {
5
+ if (!isDirty) return
6
+
7
+ const handleBeforeUnload = (event: BeforeUnloadEvent) => {
8
+ event.preventDefault()
9
+ event.returnValue = message
10
+ return message
11
+ }
12
+
13
+ window.addEventListener("beforeunload", handleBeforeUnload)
14
+
15
+ return () => {
16
+ window.removeEventListener("beforeunload", handleBeforeUnload)
17
+ }
18
+ }, [isDirty, message])
19
+ }
20
+
21
+ export { useBeforeUnloadWhenDirty }
@@ -0,0 +1,122 @@
1
+ import * as React from "react"
2
+
3
+ export type DataTableViewStorage = "local" | "session" | "memory"
4
+
5
+ export type UseDataTableViewStateOptions<TValue extends string> = {
6
+ key: string
7
+ defaultValue?: TValue
8
+ allowedValues?: readonly TValue[]
9
+ storage?: DataTableViewStorage
10
+ syncAcrossTabs?: boolean
11
+ serialize?: (value: TValue) => string
12
+ deserialize?: (value: string) => TValue
13
+ onValueChange?: (value: TValue | undefined) => void
14
+ }
15
+
16
+ export type UseDataTableViewStateReturn<TValue extends string> = {
17
+ value: TValue | undefined
18
+ setValue: (value: TValue | undefined) => void
19
+ clearValue: () => void
20
+ resetValue: () => void
21
+ isDefaultValue: boolean
22
+ }
23
+
24
+ const defaultSerialize = <TValue extends string>(value: TValue) => value
25
+ const defaultDeserialize = <TValue extends string>(value: string) => value as TValue
26
+
27
+ function getStorage(storage: DataTableViewStorage) {
28
+ if (typeof window === "undefined" || storage === "memory") return undefined
29
+ return storage === "local" ? window.localStorage : window.sessionStorage
30
+ }
31
+
32
+ function isAllowedValue<TValue extends string>(
33
+ value: TValue | undefined,
34
+ allowedValues?: readonly TValue[]
35
+ ) {
36
+ if (value === undefined) return true
37
+ if (!allowedValues?.length) return true
38
+ return allowedValues.includes(value)
39
+ }
40
+
41
+ function useDataTableViewState<TValue extends string>({
42
+ key,
43
+ defaultValue,
44
+ allowedValues,
45
+ storage = "local",
46
+ syncAcrossTabs = true,
47
+ serialize = defaultSerialize,
48
+ deserialize = defaultDeserialize,
49
+ onValueChange,
50
+ }: UseDataTableViewStateOptions<TValue>): UseDataTableViewStateReturn<TValue> {
51
+ const readValue = React.useCallback(() => {
52
+ const fallbackValue = isAllowedValue(defaultValue, allowedValues) ? defaultValue : undefined
53
+ const targetStorage = getStorage(storage)
54
+
55
+ if (!targetStorage) return fallbackValue
56
+
57
+ try {
58
+ const storedValue = targetStorage.getItem(key)
59
+ if (!storedValue) return fallbackValue
60
+
61
+ const parsedValue = deserialize(storedValue)
62
+ return isAllowedValue(parsedValue, allowedValues) ? parsedValue : fallbackValue
63
+ } catch {
64
+ return fallbackValue
65
+ }
66
+ }, [allowedValues, defaultValue, deserialize, key, storage])
67
+
68
+ const [value, setInternalValue] = React.useState<TValue | undefined>(readValue)
69
+
70
+ const setValue = React.useCallback(
71
+ (nextValue: TValue | undefined) => {
72
+ const normalizedValue = isAllowedValue(nextValue, allowedValues) ? nextValue : undefined
73
+ const targetStorage = getStorage(storage)
74
+
75
+ setInternalValue(normalizedValue)
76
+
77
+ if (targetStorage) {
78
+ try {
79
+ if (normalizedValue === undefined) {
80
+ targetStorage.removeItem(key)
81
+ } else {
82
+ targetStorage.setItem(key, serialize(normalizedValue))
83
+ }
84
+ } catch {
85
+ // Ignore storage failures. State still updates in memory.
86
+ }
87
+ }
88
+
89
+ onValueChange?.(normalizedValue)
90
+ },
91
+ [allowedValues, key, onValueChange, serialize, storage]
92
+ )
93
+
94
+ const clearValue = React.useCallback(() => setValue(undefined), [setValue])
95
+ const resetValue = React.useCallback(() => setValue(defaultValue), [defaultValue, setValue])
96
+
97
+ React.useEffect(() => {
98
+ setInternalValue(readValue())
99
+ }, [readValue])
100
+
101
+ React.useEffect(() => {
102
+ if (!syncAcrossTabs || storage !== "local" || typeof window === "undefined") return undefined
103
+
104
+ const handleStorage = (event: StorageEvent) => {
105
+ if (event.storageArea !== window.localStorage || event.key !== key) return
106
+ setInternalValue(readValue())
107
+ }
108
+
109
+ window.addEventListener("storage", handleStorage)
110
+ return () => window.removeEventListener("storage", handleStorage)
111
+ }, [key, readValue, storage, syncAcrossTabs])
112
+
113
+ return {
114
+ value,
115
+ setValue,
116
+ clearValue,
117
+ resetValue,
118
+ isDefaultValue: value === defaultValue,
119
+ }
120
+ }
121
+
122
+ export { useDataTableViewState }
@@ -0,0 +1,52 @@
1
+ import * as React from "react"
2
+
3
+ function useDebouncedValue<TValue>(value: TValue, delay = 300) {
4
+ const [debouncedValue, setDebouncedValue] = React.useState(value)
5
+
6
+ React.useEffect(() => {
7
+ const timer = window.setTimeout(() => {
8
+ setDebouncedValue(value)
9
+ }, delay)
10
+
11
+ return () => {
12
+ window.clearTimeout(timer)
13
+ }
14
+ }, [delay, value])
15
+
16
+ return debouncedValue
17
+ }
18
+
19
+ function useDebouncedCallback<TArgs extends unknown[]>(
20
+ callback: (...args: TArgs) => void,
21
+ delay = 300
22
+ ) {
23
+ const callbackRef = React.useRef(callback)
24
+ const timerRef = React.useRef<number | null>(null)
25
+
26
+ React.useEffect(() => {
27
+ callbackRef.current = callback
28
+ }, [callback])
29
+
30
+ React.useEffect(() => {
31
+ return () => {
32
+ if (timerRef.current) {
33
+ window.clearTimeout(timerRef.current)
34
+ }
35
+ }
36
+ }, [])
37
+
38
+ return React.useCallback(
39
+ (...args: TArgs) => {
40
+ if (timerRef.current) {
41
+ window.clearTimeout(timerRef.current)
42
+ }
43
+
44
+ timerRef.current = window.setTimeout(() => {
45
+ callbackRef.current(...args)
46
+ }, delay)
47
+ },
48
+ [delay]
49
+ )
50
+ }
51
+
52
+ export { useDebouncedCallback, useDebouncedValue }
@@ -0,0 +1,38 @@
1
+ import * as React from "react"
2
+
3
+ export type UseDisclosureOptions = {
4
+ defaultOpen?: boolean
5
+ open?: boolean
6
+ onOpenChange?: (open: boolean) => void
7
+ }
8
+
9
+ function useDisclosure({ defaultOpen = false, open, onOpenChange }: UseDisclosureOptions = {}) {
10
+ const isControlled = open !== undefined
11
+ const [internalOpen, setInternalOpen] = React.useState(defaultOpen)
12
+ const currentOpen = isControlled ? open : internalOpen
13
+
14
+ const setOpen = React.useCallback(
15
+ (nextOpen: boolean) => {
16
+ if (!isControlled) {
17
+ setInternalOpen(nextOpen)
18
+ }
19
+
20
+ onOpenChange?.(nextOpen)
21
+ },
22
+ [isControlled, onOpenChange]
23
+ )
24
+
25
+ const openDisclosure = React.useCallback(() => setOpen(true), [setOpen])
26
+ const closeDisclosure = React.useCallback(() => setOpen(false), [setOpen])
27
+ const toggleDisclosure = React.useCallback(() => setOpen(!currentOpen), [currentOpen, setOpen])
28
+
29
+ return {
30
+ open: currentOpen,
31
+ setOpen,
32
+ openDisclosure,
33
+ closeDisclosure,
34
+ toggleDisclosure,
35
+ } as const
36
+ }
37
+
38
+ export { useDisclosure }
@@ -0,0 +1,28 @@
1
+ import * as React from "react"
2
+
3
+ const DEFAULT_MOBILE_BREAKPOINT = 768
4
+
5
+ function useIsMobile(breakpoint = DEFAULT_MOBILE_BREAKPOINT) {
6
+ const [isMobile, setIsMobile] = React.useState(false)
7
+
8
+ React.useEffect(() => {
9
+ if (typeof window === "undefined") return
10
+
11
+ const query = window.matchMedia(`(max-width: ${breakpoint - 1}px)`)
12
+
13
+ const update = () => {
14
+ setIsMobile(query.matches)
15
+ }
16
+
17
+ update()
18
+ query.addEventListener("change", update)
19
+
20
+ return () => {
21
+ query.removeEventListener("change", update)
22
+ }
23
+ }, [breakpoint])
24
+
25
+ return isMobile
26
+ }
27
+
28
+ export { useIsMobile, DEFAULT_MOBILE_BREAKPOINT }
@@ -0,0 +1,85 @@
1
+ import * as React from "react"
2
+
3
+ type SessionStorageOptions<T> = {
4
+ serialize?: (value: T) => string
5
+ deserialize?: (value: string) => T
6
+ }
7
+
8
+ type SetSessionStorageStateAction<T> = T | ((previousValue: T) => T)
9
+
10
+ const defaultSerialize = JSON.stringify
11
+ const defaultDeserialize = JSON.parse
12
+
13
+ function getInitialValue<T>(initialValue: T | (() => T)) {
14
+ return typeof initialValue === "function"
15
+ ? (initialValue as () => T)()
16
+ : initialValue
17
+ }
18
+
19
+ function useSessionStorageState<T>(
20
+ key: string,
21
+ initialValue: T | (() => T),
22
+ options: SessionStorageOptions<T> = {}
23
+ ) {
24
+ const { serialize = defaultSerialize, deserialize = defaultDeserialize } = options
25
+
26
+ const readValue = React.useCallback(() => {
27
+ const fallbackValue = getInitialValue(initialValue)
28
+
29
+ if (typeof window === "undefined") {
30
+ return fallbackValue
31
+ }
32
+
33
+ try {
34
+ const item = window.sessionStorage.getItem(key)
35
+ return item ? (deserialize(item) as T) : fallbackValue
36
+ } catch {
37
+ return fallbackValue
38
+ }
39
+ }, [deserialize, initialValue, key])
40
+
41
+ const [state, setState] = React.useState<T>(readValue)
42
+
43
+ const setValue = React.useCallback(
44
+ (value: SetSessionStorageStateAction<T>) => {
45
+ setState((previousValue) => {
46
+ const nextValue =
47
+ typeof value === "function"
48
+ ? (value as (previousValue: T) => T)(previousValue)
49
+ : value
50
+
51
+ if (typeof window !== "undefined") {
52
+ try {
53
+ window.sessionStorage.setItem(key, serialize(nextValue))
54
+ } catch {
55
+ // Ignore storage failures. State still updates in memory.
56
+ }
57
+ }
58
+
59
+ return nextValue
60
+ })
61
+ },
62
+ [key, serialize]
63
+ )
64
+
65
+ const removeValue = React.useCallback(() => {
66
+ if (typeof window !== "undefined") {
67
+ try {
68
+ window.sessionStorage.removeItem(key)
69
+ } catch {
70
+ // Ignore storage failures.
71
+ }
72
+ }
73
+
74
+ setState(getInitialValue(initialValue))
75
+ }, [initialValue, key])
76
+
77
+ React.useEffect(() => {
78
+ setState(readValue())
79
+ }, [readValue])
80
+
81
+ return [state, setValue, removeValue] as const
82
+ }
83
+
84
+ export { useSessionStorageState }
85
+ export type { SessionStorageOptions, SetSessionStorageStateAction }
@@ -0,0 +1,38 @@
1
+ export * from './components/ui/button'
2
+ export * from './components/ui/input'
3
+ export * from './components/ui/textarea'
4
+ export * from './components/ui/checkbox'
5
+ export * from './components/ui/switch'
6
+ export * from './components/ui/dialog'
7
+ export * from './components/ui/dropdown-menu'
8
+ export * from './components/ui/popover'
9
+ export * from './components/ui/select'
10
+ export * from './components/ui/table'
11
+ export * from './components/ui/badge'
12
+ export * from './components/ui/card'
13
+ export * from './components/ui/tabs'
14
+ export * from './components/ui/collapse'
15
+ export * from './components/ui/skeleton'
16
+ export * from './components/ui/divider'
17
+ export * from './components/ui/segmented-control'
18
+ export * from './components/ui/spinner'
19
+ export * from './components/ui/tooltip'
20
+
21
+ export * from './components/actions/public'
22
+ export * from './components/layout/public'
23
+ export * from './components/filters'
24
+ export * from './components/overlay'
25
+ export * from './components/navigation'
26
+ export * from './components/inputs'
27
+ export * from './components/form/public'
28
+ export * from './components/feedback'
29
+ export * from './components/display'
30
+ export * from './components/data-table/public'
31
+ export * from './components/notifications'
32
+ export * from './components/command'
33
+ export * from './components/calendar'
34
+ export * from './components/upload'
35
+ export * from './components/wizard'
36
+ export * from './components/charts/public'
37
+ export * from './hooks'
38
+ export * from './lib/utils'
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs))
6
+ }
File without changes
File without changes
File without changes
File without changes
File without changes