@salesforce/ui-bundle-template-feature-react-search 11.3.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 (169) hide show
  1. package/LICENSE.txt +82 -0
  2. package/README.md +692 -0
  3. package/dist/.forceignore +15 -0
  4. package/dist/.husky/pre-commit +4 -0
  5. package/dist/.prettierignore +11 -0
  6. package/dist/.prettierrc +17 -0
  7. package/dist/CHANGELOG.md +3499 -0
  8. package/dist/README.md +28 -0
  9. package/dist/config/project-scratch-def.json +13 -0
  10. package/dist/eslint.config.js +7 -0
  11. package/dist/force-app/main/default/uiBundles/feature-react-search/.forceignore +15 -0
  12. package/dist/force-app/main/default/uiBundles/feature-react-search/.graphqlrc.yml +2 -0
  13. package/dist/force-app/main/default/uiBundles/feature-react-search/.prettierignore +9 -0
  14. package/dist/force-app/main/default/uiBundles/feature-react-search/.prettierrc +11 -0
  15. package/dist/force-app/main/default/uiBundles/feature-react-search/CHANGELOG.md +10 -0
  16. package/dist/force-app/main/default/uiBundles/feature-react-search/README.md +75 -0
  17. package/dist/force-app/main/default/uiBundles/feature-react-search/codegen.yml +95 -0
  18. package/dist/force-app/main/default/uiBundles/feature-react-search/components.json +18 -0
  19. package/dist/force-app/main/default/uiBundles/feature-react-search/e2e/app.spec.ts +17 -0
  20. package/dist/force-app/main/default/uiBundles/feature-react-search/eslint.config.js +169 -0
  21. package/dist/force-app/main/default/uiBundles/feature-react-search/feature-react-search.uibundle-meta.xml +7 -0
  22. package/dist/force-app/main/default/uiBundles/feature-react-search/index.html +12 -0
  23. package/dist/force-app/main/default/uiBundles/feature-react-search/package.json +76 -0
  24. package/dist/force-app/main/default/uiBundles/feature-react-search/playwright.config.ts +24 -0
  25. package/dist/force-app/main/default/uiBundles/feature-react-search/scripts/get-graphql-schema.mjs +71 -0
  26. package/dist/force-app/main/default/uiBundles/feature-react-search/scripts/rewrite-e2e-assets.mjs +23 -0
  27. package/dist/force-app/main/default/uiBundles/feature-react-search/src/api/graphqlClient.ts +44 -0
  28. package/dist/force-app/main/default/uiBundles/feature-react-search/src/app.tsx +17 -0
  29. package/dist/force-app/main/default/uiBundles/feature-react-search/src/appLayout.tsx +83 -0
  30. package/dist/force-app/main/default/uiBundles/feature-react-search/src/assets/icons/book.svg +3 -0
  31. package/dist/force-app/main/default/uiBundles/feature-react-search/src/assets/icons/copy.svg +4 -0
  32. package/dist/force-app/main/default/uiBundles/feature-react-search/src/assets/icons/rocket.svg +3 -0
  33. package/dist/force-app/main/default/uiBundles/feature-react-search/src/assets/icons/star.svg +3 -0
  34. package/dist/force-app/main/default/uiBundles/feature-react-search/src/assets/images/codey-1.png +0 -0
  35. package/dist/force-app/main/default/uiBundles/feature-react-search/src/assets/images/codey-2.png +0 -0
  36. package/dist/force-app/main/default/uiBundles/feature-react-search/src/assets/images/codey-3.png +0 -0
  37. package/dist/force-app/main/default/uiBundles/feature-react-search/src/assets/images/vibe-codey.svg +194 -0
  38. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/alerts/status-alert.tsx +52 -0
  39. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/layouts/card-layout.tsx +29 -0
  40. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/alert.tsx +76 -0
  41. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/avatar.tsx +109 -0
  42. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/badge.tsx +48 -0
  43. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/breadcrumb.tsx +109 -0
  44. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/button.tsx +67 -0
  45. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/calendar.tsx +232 -0
  46. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/card.tsx +103 -0
  47. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/checkbox.tsx +32 -0
  48. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/collapsible.tsx +33 -0
  49. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/datePicker.tsx +127 -0
  50. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/dialog.tsx +162 -0
  51. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/dropdown-menu.tsx +257 -0
  52. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/field.tsx +237 -0
  53. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/index.ts +109 -0
  54. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/input.tsx +19 -0
  55. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/label.tsx +22 -0
  56. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/pagination.tsx +132 -0
  57. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/popover.tsx +89 -0
  58. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/select.tsx +193 -0
  59. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/separator.tsx +26 -0
  60. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/skeleton.tsx +14 -0
  61. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/sonner.tsx +20 -0
  62. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/spinner.tsx +16 -0
  63. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/table.tsx +114 -0
  64. package/dist/force-app/main/default/uiBundles/feature-react-search/src/components/ui/tabs.tsx +88 -0
  65. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/api/distinctValuesService.ts +84 -0
  66. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/api/searchService.ts +71 -0
  67. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/Search.tsx +160 -0
  68. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/SearchResults.tsx +77 -0
  69. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/SourceSection.tsx +167 -0
  70. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/controls/PaginationControls.tsx +115 -0
  71. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/controls/ScopeSelector.tsx +55 -0
  72. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/controls/SearchBar.tsx +55 -0
  73. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/controls/SortControl.tsx +62 -0
  74. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/ActiveFilters.tsx +61 -0
  75. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/DefaultFilterPanel.tsx +122 -0
  76. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/FilterContext.tsx +70 -0
  77. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/inputs/BooleanFilter.tsx +50 -0
  78. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/inputs/DateRangeFilter.tsx +50 -0
  79. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/inputs/FilterFieldWrapper.tsx +26 -0
  80. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/inputs/MultiSelectFilter.tsx +47 -0
  81. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/inputs/NumericRangeFilter.tsx +78 -0
  82. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/inputs/SelectFilter.tsx +46 -0
  83. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/inputs/TextFilter.tsx +52 -0
  84. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/results/DefaultResultRow.tsx +109 -0
  85. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/config.json +82 -0
  86. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/hooks/useAsyncData.ts +56 -0
  87. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/hooks/useDistinctValues.ts +59 -0
  88. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/hooks/useSearch.ts +442 -0
  89. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/index.ts +80 -0
  90. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/loadConfig.ts +14 -0
  91. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/queryBuilder.ts +156 -0
  92. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/types.ts +169 -0
  93. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/utils/debounce.ts +17 -0
  94. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/utils/fieldUtils.ts +14 -0
  95. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/utils/filterUtils.ts +272 -0
  96. package/dist/force-app/main/default/uiBundles/feature-react-search/src/features/search/utils/sortUtils.ts +34 -0
  97. package/dist/force-app/main/default/uiBundles/feature-react-search/src/hooks/useAsyncData.ts +67 -0
  98. package/dist/force-app/main/default/uiBundles/feature-react-search/src/lib/utils.ts +6 -0
  99. package/dist/force-app/main/default/uiBundles/feature-react-search/src/navigationMenu.tsx +80 -0
  100. package/dist/force-app/main/default/uiBundles/feature-react-search/src/pages/Home.tsx +11 -0
  101. package/dist/force-app/main/default/uiBundles/feature-react-search/src/pages/NotFound.tsx +18 -0
  102. package/dist/force-app/main/default/uiBundles/feature-react-search/src/router-utils.tsx +35 -0
  103. package/dist/force-app/main/default/uiBundles/feature-react-search/src/routes.tsx +22 -0
  104. package/dist/force-app/main/default/uiBundles/feature-react-search/src/styles/global.css +135 -0
  105. package/dist/force-app/main/default/uiBundles/feature-react-search/tsconfig.json +45 -0
  106. package/dist/force-app/main/default/uiBundles/feature-react-search/tsconfig.node.json +13 -0
  107. package/dist/force-app/main/default/uiBundles/feature-react-search/ui-bundle.json +7 -0
  108. package/dist/force-app/main/default/uiBundles/feature-react-search/vite-env.d.ts +4 -0
  109. package/dist/force-app/main/default/uiBundles/feature-react-search/vite.config.ts +106 -0
  110. package/dist/force-app/main/default/uiBundles/feature-react-search/vitest-env.d.ts +2 -0
  111. package/dist/force-app/main/default/uiBundles/feature-react-search/vitest.config.ts +11 -0
  112. package/dist/force-app/main/default/uiBundles/feature-react-search/vitest.setup.ts +1 -0
  113. package/dist/jest.config.js +6 -0
  114. package/dist/package-lock.json +9995 -0
  115. package/dist/package.json +44 -0
  116. package/dist/scripts/apex/hello.apex +10 -0
  117. package/dist/scripts/gitignore-templates.json +4 -0
  118. package/dist/scripts/graphql-search.sh +191 -0
  119. package/dist/scripts/org-setup-config-schema.mjs +96 -0
  120. package/dist/scripts/org-setup.config.json +5 -0
  121. package/dist/scripts/org-setup.mjs +1392 -0
  122. package/dist/scripts/sf-project-setup.mjs +103 -0
  123. package/dist/scripts/soql/account.soql +6 -0
  124. package/dist/scripts/validate-org-setup-config.mjs +38 -0
  125. package/dist/sfdx-project.json +12 -0
  126. package/package.json +51 -0
  127. package/src/force-app/main/default/uiBundles/feature-react-search/src/__inherit__appLayout.tsx +9 -0
  128. package/src/force-app/main/default/uiBundles/feature-react-search/src/components/ui/__inherit__alert.tsx +39 -0
  129. package/src/force-app/main/default/uiBundles/feature-react-search/src/components/ui/__inherit__button.tsx +45 -0
  130. package/src/force-app/main/default/uiBundles/feature-react-search/src/components/ui/__inherit__checkbox.tsx +8 -0
  131. package/src/force-app/main/default/uiBundles/feature-react-search/src/components/ui/__inherit__input.tsx +5 -0
  132. package/src/force-app/main/default/uiBundles/feature-react-search/src/components/ui/__inherit__label.tsx +8 -0
  133. package/src/force-app/main/default/uiBundles/feature-react-search/src/components/ui/__inherit__pagination.tsx +47 -0
  134. package/src/force-app/main/default/uiBundles/feature-react-search/src/components/ui/__inherit__select.tsx +57 -0
  135. package/src/force-app/main/default/uiBundles/feature-react-search/src/components/ui/__inherit__skeleton.tsx +5 -0
  136. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/api/distinctValuesService.ts +84 -0
  137. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/api/searchService.ts +71 -0
  138. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/Search.tsx +160 -0
  139. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/SearchResults.tsx +77 -0
  140. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/SourceSection.tsx +167 -0
  141. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/controls/PaginationControls.tsx +115 -0
  142. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/controls/ScopeSelector.tsx +55 -0
  143. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/controls/SearchBar.tsx +55 -0
  144. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/controls/SortControl.tsx +62 -0
  145. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/ActiveFilters.tsx +61 -0
  146. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/DefaultFilterPanel.tsx +122 -0
  147. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/FilterContext.tsx +70 -0
  148. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/inputs/BooleanFilter.tsx +50 -0
  149. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/inputs/DateRangeFilter.tsx +50 -0
  150. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/inputs/FilterFieldWrapper.tsx +26 -0
  151. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/inputs/MultiSelectFilter.tsx +47 -0
  152. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/inputs/NumericRangeFilter.tsx +78 -0
  153. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/inputs/SelectFilter.tsx +46 -0
  154. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/filters/inputs/TextFilter.tsx +52 -0
  155. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/components/results/DefaultResultRow.tsx +109 -0
  156. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/config.json +82 -0
  157. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/hooks/useAsyncData.ts +56 -0
  158. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/hooks/useDistinctValues.ts +59 -0
  159. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/hooks/useSearch.ts +442 -0
  160. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/index.ts +80 -0
  161. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/loadConfig.ts +14 -0
  162. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/queryBuilder.ts +156 -0
  163. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/types.ts +169 -0
  164. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/utils/debounce.ts +17 -0
  165. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/utils/fieldUtils.ts +14 -0
  166. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/utils/filterUtils.ts +272 -0
  167. package/src/force-app/main/default/uiBundles/feature-react-search/src/features/search/utils/sortUtils.ts +34 -0
  168. package/src/force-app/main/default/uiBundles/feature-react-search/src/pages/Home.tsx +11 -0
  169. package/src/force-app/main/default/uiBundles/feature-react-search/src/routes.tsx +10 -0
@@ -0,0 +1,257 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react';
5
+ import { DropdownMenu as DropdownMenuPrimitive } from 'radix-ui';
6
+
7
+ import { cn } from '@/lib/utils';
8
+
9
+ function DropdownMenu({
10
+ ...props
11
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
12
+ return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
13
+ }
14
+
15
+ function DropdownMenuPortal({
16
+ ...props
17
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
18
+ return (
19
+ <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
20
+ );
21
+ }
22
+
23
+ function DropdownMenuTrigger({
24
+ ...props
25
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
26
+ return (
27
+ <DropdownMenuPrimitive.Trigger
28
+ data-slot="dropdown-menu-trigger"
29
+ {...props}
30
+ />
31
+ );
32
+ }
33
+
34
+ function DropdownMenuContent({
35
+ className,
36
+ sideOffset = 4,
37
+ ...props
38
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
39
+ return (
40
+ <DropdownMenuPrimitive.Portal>
41
+ <DropdownMenuPrimitive.Content
42
+ data-slot="dropdown-menu-content"
43
+ sideOffset={sideOffset}
44
+ className={cn(
45
+ 'z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border bg-popover p-1 text-popover-foreground shadow-md 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 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95',
46
+ className
47
+ )}
48
+ {...props}
49
+ />
50
+ </DropdownMenuPrimitive.Portal>
51
+ );
52
+ }
53
+
54
+ function DropdownMenuGroup({
55
+ ...props
56
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
57
+ return (
58
+ <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
59
+ );
60
+ }
61
+
62
+ function DropdownMenuItem({
63
+ className,
64
+ inset,
65
+ variant = 'default',
66
+ ...props
67
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
68
+ inset?: boolean;
69
+ variant?: 'default' | 'destructive';
70
+ }) {
71
+ return (
72
+ <DropdownMenuPrimitive.Item
73
+ data-slot="dropdown-menu-item"
74
+ data-inset={inset}
75
+ data-variant={variant}
76
+ className={cn(
77
+ "relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground data-[variant=destructive]:*:[svg]:text-destructive!",
78
+ className
79
+ )}
80
+ {...props}
81
+ />
82
+ );
83
+ }
84
+
85
+ function DropdownMenuCheckboxItem({
86
+ className,
87
+ children,
88
+ checked,
89
+ ...props
90
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
91
+ return (
92
+ <DropdownMenuPrimitive.CheckboxItem
93
+ data-slot="dropdown-menu-checkbox-item"
94
+ className={cn(
95
+ "relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
96
+ className
97
+ )}
98
+ checked={checked}
99
+ {...props}
100
+ >
101
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
102
+ <DropdownMenuPrimitive.ItemIndicator>
103
+ <CheckIcon className="size-4" />
104
+ </DropdownMenuPrimitive.ItemIndicator>
105
+ </span>
106
+ {children}
107
+ </DropdownMenuPrimitive.CheckboxItem>
108
+ );
109
+ }
110
+
111
+ function DropdownMenuRadioGroup({
112
+ ...props
113
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
114
+ return (
115
+ <DropdownMenuPrimitive.RadioGroup
116
+ data-slot="dropdown-menu-radio-group"
117
+ {...props}
118
+ />
119
+ );
120
+ }
121
+
122
+ function DropdownMenuRadioItem({
123
+ className,
124
+ children,
125
+ ...props
126
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
127
+ return (
128
+ <DropdownMenuPrimitive.RadioItem
129
+ data-slot="dropdown-menu-radio-item"
130
+ className={cn(
131
+ "relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
132
+ className
133
+ )}
134
+ {...props}
135
+ >
136
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
137
+ <DropdownMenuPrimitive.ItemIndicator>
138
+ <CircleIcon className="size-2 fill-current" />
139
+ </DropdownMenuPrimitive.ItemIndicator>
140
+ </span>
141
+ {children}
142
+ </DropdownMenuPrimitive.RadioItem>
143
+ );
144
+ }
145
+
146
+ function DropdownMenuLabel({
147
+ className,
148
+ inset,
149
+ ...props
150
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
151
+ inset?: boolean;
152
+ }) {
153
+ return (
154
+ <DropdownMenuPrimitive.Label
155
+ data-slot="dropdown-menu-label"
156
+ data-inset={inset}
157
+ className={cn(
158
+ 'px-2 py-1.5 text-sm font-medium data-[inset]:pl-8',
159
+ className
160
+ )}
161
+ {...props}
162
+ />
163
+ );
164
+ }
165
+
166
+ function DropdownMenuSeparator({
167
+ className,
168
+ ...props
169
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
170
+ return (
171
+ <DropdownMenuPrimitive.Separator
172
+ data-slot="dropdown-menu-separator"
173
+ className={cn('-mx-1 my-1 h-px bg-border', className)}
174
+ {...props}
175
+ />
176
+ );
177
+ }
178
+
179
+ function DropdownMenuShortcut({
180
+ className,
181
+ ...props
182
+ }: React.ComponentProps<'span'>) {
183
+ return (
184
+ <span
185
+ data-slot="dropdown-menu-shortcut"
186
+ className={cn(
187
+ 'ml-auto text-xs tracking-widest text-muted-foreground',
188
+ className
189
+ )}
190
+ {...props}
191
+ />
192
+ );
193
+ }
194
+
195
+ function DropdownMenuSub({
196
+ ...props
197
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
198
+ return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />;
199
+ }
200
+
201
+ function DropdownMenuSubTrigger({
202
+ className,
203
+ inset,
204
+ children,
205
+ ...props
206
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
207
+ inset?: boolean;
208
+ }) {
209
+ return (
210
+ <DropdownMenuPrimitive.SubTrigger
211
+ data-slot="dropdown-menu-sub-trigger"
212
+ data-inset={inset}
213
+ className={cn(
214
+ "flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[inset]:pl-8 data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground",
215
+ className
216
+ )}
217
+ {...props}
218
+ >
219
+ {children}
220
+ <ChevronRightIcon className="ml-auto size-4" />
221
+ </DropdownMenuPrimitive.SubTrigger>
222
+ );
223
+ }
224
+
225
+ function DropdownMenuSubContent({
226
+ className,
227
+ ...props
228
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
229
+ return (
230
+ <DropdownMenuPrimitive.SubContent
231
+ data-slot="dropdown-menu-sub-content"
232
+ className={cn(
233
+ 'z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg 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 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95',
234
+ className
235
+ )}
236
+ {...props}
237
+ />
238
+ );
239
+ }
240
+
241
+ export {
242
+ DropdownMenu,
243
+ DropdownMenuPortal,
244
+ DropdownMenuTrigger,
245
+ DropdownMenuContent,
246
+ DropdownMenuGroup,
247
+ DropdownMenuLabel,
248
+ DropdownMenuItem,
249
+ DropdownMenuCheckboxItem,
250
+ DropdownMenuRadioGroup,
251
+ DropdownMenuRadioItem,
252
+ DropdownMenuSeparator,
253
+ DropdownMenuShortcut,
254
+ DropdownMenuSub,
255
+ DropdownMenuSubTrigger,
256
+ DropdownMenuSubContent,
257
+ };
@@ -0,0 +1,237 @@
1
+ import * as React from 'react';
2
+ import { useMemo } from 'react';
3
+ import { cva, type VariantProps } from 'class-variance-authority';
4
+
5
+ import { cn } from '../../lib/utils';
6
+ import { Label } from './label';
7
+ import { Separator } from './separator';
8
+
9
+ function FieldSet({ className, ...props }: React.ComponentProps<'fieldset'>) {
10
+ return (
11
+ <fieldset
12
+ data-slot="field-set"
13
+ className={cn(
14
+ 'gap-4 has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3 flex flex-col',
15
+ className
16
+ )}
17
+ {...props}
18
+ />
19
+ );
20
+ }
21
+
22
+ function FieldLegend({
23
+ className,
24
+ variant = 'legend',
25
+ ...props
26
+ }: React.ComponentProps<'legend'> & { variant?: 'legend' | 'label' }) {
27
+ return (
28
+ <legend
29
+ data-slot="field-legend"
30
+ data-variant={variant}
31
+ className={cn(
32
+ 'mb-1.5 font-medium data-[variant=label]:text-sm data-[variant=legend]:text-base',
33
+ className
34
+ )}
35
+ {...props}
36
+ />
37
+ );
38
+ }
39
+
40
+ function FieldGroup({ className, ...props }: React.ComponentProps<'div'>) {
41
+ return (
42
+ <div
43
+ data-slot="field-group"
44
+ className={cn(
45
+ 'gap-5 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4 group/field-group @container/field-group flex w-full flex-col',
46
+ className
47
+ )}
48
+ {...props}
49
+ />
50
+ );
51
+ }
52
+
53
+ const fieldVariants = cva(
54
+ 'data-[invalid=true]:text-destructive gap-2 group/field flex w-full',
55
+ {
56
+ variants: {
57
+ orientation: {
58
+ vertical: 'flex-col *:w-full [&>.sr-only]:w-auto',
59
+ horizontal:
60
+ 'flex-row items-center *:data-[slot=field-label]:flex-auto has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',
61
+ responsive:
62
+ 'flex-col *:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:*:w-auto @md/field-group:*:data-[slot=field-label]:flex-auto @md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',
63
+ },
64
+ },
65
+ defaultVariants: {
66
+ orientation: 'vertical',
67
+ },
68
+ }
69
+ );
70
+
71
+ function Field({
72
+ className,
73
+ orientation = 'vertical',
74
+ ...props
75
+ }: React.ComponentProps<'div'> & VariantProps<typeof fieldVariants>) {
76
+ return (
77
+ <div
78
+ role="group"
79
+ data-slot="field"
80
+ data-orientation={orientation}
81
+ className={cn(fieldVariants({ orientation }), className)}
82
+ {...props}
83
+ />
84
+ );
85
+ }
86
+
87
+ function FieldContent({ className, ...props }: React.ComponentProps<'div'>) {
88
+ return (
89
+ <div
90
+ data-slot="field-content"
91
+ className={cn(
92
+ 'gap-0.5 group/field-content flex flex-1 flex-col leading-snug',
93
+ className
94
+ )}
95
+ {...props}
96
+ />
97
+ );
98
+ }
99
+
100
+ function FieldLabel({
101
+ className,
102
+ ...props
103
+ }: React.ComponentProps<typeof Label>) {
104
+ return (
105
+ <Label
106
+ data-slot="field-label"
107
+ className={cn(
108
+ 'has-data-checked:bg-primary/5 has-data-checked:border-primary/30 dark:has-data-checked:border-primary/20 dark:has-data-checked:bg-primary/10 gap-2 group-data-[disabled=true]/field:opacity-50 has-[>[data-slot=field]]:rounded-lg has-[>[data-slot=field]]:border *:data-[slot=field]:p-2.5 group/field-label peer/field-label flex w-fit leading-snug',
109
+ 'has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col',
110
+ className
111
+ )}
112
+ {...props}
113
+ />
114
+ );
115
+ }
116
+
117
+ function FieldTitle({ className, ...props }: React.ComponentProps<'div'>) {
118
+ return (
119
+ <div
120
+ data-slot="field-label"
121
+ className={cn(
122
+ 'gap-2 text-sm font-medium group-data-[disabled=true]/field:opacity-50 flex w-fit items-center leading-snug',
123
+ className
124
+ )}
125
+ {...props}
126
+ />
127
+ );
128
+ }
129
+
130
+ function FieldDescription({ className, ...props }: React.ComponentProps<'p'>) {
131
+ return (
132
+ <p
133
+ data-slot="field-description"
134
+ className={cn(
135
+ 'text-muted-foreground text-left text-sm [[data-variant=legend]+&]:-mt-1.5 leading-normal font-normal group-has-data-horizontal/field:text-balance',
136
+ 'last:mt-0 nth-last-2:-mt-1',
137
+ '[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4',
138
+ className
139
+ )}
140
+ {...props}
141
+ />
142
+ );
143
+ }
144
+
145
+ function FieldSeparator({
146
+ children,
147
+ className,
148
+ ...props
149
+ }: React.ComponentProps<'div'> & {
150
+ children?: React.ReactNode;
151
+ }) {
152
+ return (
153
+ <div
154
+ data-slot="field-separator"
155
+ data-content={!!children}
156
+ className={cn(
157
+ '-my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2 relative',
158
+ className
159
+ )}
160
+ {...props}
161
+ >
162
+ <Separator className="absolute inset-0 top-1/2" />
163
+ {children && (
164
+ <span
165
+ className="text-muted-foreground px-2 bg-background relative mx-auto block w-fit"
166
+ data-slot="field-separator-content"
167
+ >
168
+ {children}
169
+ </span>
170
+ )}
171
+ </div>
172
+ );
173
+ }
174
+
175
+ function FieldError({
176
+ className,
177
+ children,
178
+ errors,
179
+ ...props
180
+ }: React.ComponentProps<'div'> & {
181
+ errors?: Array<{ message?: string } | undefined>;
182
+ }) {
183
+ const content = useMemo(() => {
184
+ if (children) {
185
+ return children;
186
+ }
187
+
188
+ if (!errors?.length) {
189
+ return null;
190
+ }
191
+
192
+ const uniqueErrors = [
193
+ ...new Map(errors.map(error => [error?.message, error])).values(),
194
+ ];
195
+
196
+ if (uniqueErrors?.length == 1) {
197
+ return uniqueErrors[0]?.message;
198
+ }
199
+
200
+ return (
201
+ <ul className="ml-4 flex list-disc flex-col gap-1">
202
+ {uniqueErrors.map(
203
+ (error, index) =>
204
+ error?.message && <li key={index}>{error.message}</li>
205
+ )}
206
+ </ul>
207
+ );
208
+ }, [children, errors]);
209
+
210
+ if (!content) {
211
+ return null;
212
+ }
213
+
214
+ return (
215
+ <div
216
+ role="alert"
217
+ data-slot="field-error"
218
+ className={cn('text-destructive text-sm font-normal', className)}
219
+ {...props}
220
+ >
221
+ {content}
222
+ </div>
223
+ );
224
+ }
225
+
226
+ export {
227
+ Field,
228
+ FieldLabel,
229
+ FieldDescription,
230
+ FieldError,
231
+ FieldGroup,
232
+ FieldLegend,
233
+ FieldSeparator,
234
+ FieldSet,
235
+ FieldContent,
236
+ FieldTitle,
237
+ };
@@ -0,0 +1,109 @@
1
+ /**
2
+ * UI Components Index
3
+ *
4
+ * Re-exports all UI components for easier imports.
5
+ *
6
+ * Usage:
7
+ * import { Button, Input, Tabs } from "@/components/ui"
8
+ *
9
+ * Instead of:
10
+ * import { Button } from "@/components/ui/button"
11
+ * import { Input } from "@/components/ui/input"
12
+ * import { Tabs } from "@/components/ui/tabs"
13
+ */
14
+
15
+ export { Alert, AlertTitle, AlertDescription, AlertAction } from './alert';
16
+ export {
17
+ Avatar,
18
+ AvatarImage,
19
+ AvatarFallback,
20
+ AvatarBadge,
21
+ AvatarGroup,
22
+ AvatarGroupCount,
23
+ } from './avatar';
24
+ export { Button, buttonVariants } from './button';
25
+ export {
26
+ Card,
27
+ CardHeader,
28
+ CardFooter,
29
+ CardTitle,
30
+ CardAction,
31
+ CardDescription,
32
+ CardContent,
33
+ } from './card';
34
+ export {
35
+ Dialog,
36
+ DialogClose,
37
+ DialogContent,
38
+ DialogDescription,
39
+ DialogFooter,
40
+ DialogHeader,
41
+ DialogOverlay,
42
+ DialogPortal,
43
+ DialogTitle,
44
+ DialogTrigger,
45
+ } from './dialog';
46
+ export {
47
+ DropdownMenu,
48
+ DropdownMenuPortal,
49
+ DropdownMenuTrigger,
50
+ DropdownMenuContent,
51
+ DropdownMenuGroup,
52
+ DropdownMenuLabel,
53
+ DropdownMenuItem,
54
+ DropdownMenuCheckboxItem,
55
+ DropdownMenuRadioGroup,
56
+ DropdownMenuRadioItem,
57
+ DropdownMenuSeparator,
58
+ DropdownMenuShortcut,
59
+ DropdownMenuSub,
60
+ DropdownMenuSubTrigger,
61
+ DropdownMenuSubContent,
62
+ } from './dropdown-menu';
63
+ export {
64
+ Field,
65
+ FieldDescription,
66
+ FieldError,
67
+ FieldGroup,
68
+ FieldLabel,
69
+ FieldLegend,
70
+ FieldSeparator,
71
+ FieldSet,
72
+ } from './field';
73
+ export { Input } from './input';
74
+ export { Label } from './label';
75
+ export {
76
+ Select,
77
+ SelectGroup,
78
+ SelectValue,
79
+ SelectTrigger,
80
+ SelectContent,
81
+ SelectLabel,
82
+ SelectItem,
83
+ SelectSeparator,
84
+ SelectScrollUpButton,
85
+ SelectScrollDownButton,
86
+ } from './select';
87
+ export { Spinner } from './spinner';
88
+ export { Skeleton } from './skeleton';
89
+ export {
90
+ Table,
91
+ TableHeader,
92
+ TableBody,
93
+ TableFooter,
94
+ TableHead,
95
+ TableRow,
96
+ TableCell,
97
+ TableCaption,
98
+ } from './table';
99
+ export { Tabs, TabsList, TabsTrigger, TabsContent } from './tabs';
100
+ export {
101
+ Pagination,
102
+ PaginationContent,
103
+ PaginationEllipsis,
104
+ PaginationItem,
105
+ PaginationLink,
106
+ PaginationNext,
107
+ PaginationPrevious,
108
+ } from './pagination';
109
+ export { Separator } from './separator';
@@ -0,0 +1,19 @@
1
+ import * as React from 'react';
2
+
3
+ import { cn } from '../../lib/utils';
4
+
5
+ function Input({ className, type, ...props }: React.ComponentProps<'input'>) {
6
+ return (
7
+ <input
8
+ type={type}
9
+ data-slot="input"
10
+ className={cn(
11
+ 'dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 h-8 rounded-lg border bg-transparent px-2.5 py-1 text-base transition-colors file:h-6 file:text-sm file:font-medium focus-visible:ring-3 aria-invalid:ring-3 md:text-sm file:text-foreground placeholder:text-muted-foreground/70 placeholder:italic w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',
12
+ className
13
+ )}
14
+ {...props}
15
+ />
16
+ );
17
+ }
18
+
19
+ export { Input };
@@ -0,0 +1,22 @@
1
+ import * as React from 'react';
2
+ import { Label as LabelPrimitive } from 'radix-ui';
3
+
4
+ import { cn } from '../../lib/utils';
5
+
6
+ function Label({
7
+ className,
8
+ ...props
9
+ }: React.ComponentProps<typeof LabelPrimitive.Root>) {
10
+ return (
11
+ <LabelPrimitive.Root
12
+ data-slot="label"
13
+ className={cn(
14
+ 'gap-2 text-sm leading-none font-medium group-data-[disabled=true]:opacity-50 peer-disabled:opacity-50 flex items-center select-none group-data-[disabled=true]:pointer-events-none peer-disabled:cursor-not-allowed',
15
+ className
16
+ )}
17
+ {...props}
18
+ />
19
+ );
20
+ }
21
+
22
+ export { Label };