@carefully-built/cli 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) hide show
  1. package/README.md +101 -80
  2. package/dist/index.mjs +8 -5
  3. package/dist/index.mjs.map +1 -1
  4. package/package.json +3 -3
  5. package/registry/ui/avatar/manifest.json +33 -0
  6. package/registry/ui/avatar/primitives/avatar.tsx +64 -0
  7. package/registry/ui/avatar/utils/cn.ts +6 -0
  8. package/registry/ui/button/manifest.json +24 -5
  9. package/registry/ui/button/utils/cn.ts +6 -0
  10. package/registry/ui/calendar/manifest.json +35 -0
  11. package/registry/ui/calendar/primitives/button.tsx +89 -0
  12. package/registry/ui/calendar/primitives/calendar.tsx +68 -0
  13. package/registry/ui/calendar/utils/cn.ts +6 -0
  14. package/registry/ui/card/manifest.json +36 -0
  15. package/registry/ui/card/primitives/card.tsx +80 -0
  16. package/registry/ui/card/utils/cn.ts +6 -0
  17. package/registry/ui/chip/manifest.json +36 -0
  18. package/registry/ui/chip/primitives/chip-utils.ts +10 -0
  19. package/registry/ui/chip/primitives/chip.tsx +74 -0
  20. package/registry/ui/chip/utils/cn.ts +6 -0
  21. package/registry/ui/chip-utils/manifest.json +33 -0
  22. package/registry/ui/chip-utils/primitives/chip-utils.ts +10 -0
  23. package/registry/ui/chip-utils/utils/cn.ts +6 -0
  24. package/registry/ui/date-display/manifest.json +33 -0
  25. package/registry/ui/date-display/utils/cn.ts +6 -0
  26. package/registry/ui/date-display/utils/date-display.ts +61 -0
  27. package/registry/ui/dialog/manifest.json +43 -0
  28. package/registry/ui/dialog/primitives/button.tsx +89 -0
  29. package/registry/ui/dialog/primitives/dialog.tsx +147 -0
  30. package/registry/ui/dialog/utils/cn.ts +6 -0
  31. package/registry/ui/display-date/manifest.json +36 -0
  32. package/registry/ui/display-date/primitives/display-date.tsx +20 -0
  33. package/registry/ui/display-date/utils/cn.ts +6 -0
  34. package/registry/ui/display-date/utils/date-display.ts +61 -0
  35. package/registry/ui/drawer/manifest.json +37 -0
  36. package/registry/ui/drawer/primitives/drawer.tsx +99 -0
  37. package/registry/ui/drawer/utils/cn.ts +6 -0
  38. package/registry/ui/dropdown-menu/manifest.json +37 -0
  39. package/registry/ui/dropdown-menu/primitives/dropdown-menu.tsx +140 -0
  40. package/registry/ui/dropdown-menu/utils/cn.ts +6 -0
  41. package/registry/ui/empty-state/empty-state/collection-empty-state.ts +29 -0
  42. package/registry/ui/empty-state/empty-state/empty-state-card.tsx +72 -0
  43. package/registry/ui/empty-state/empty-state/index.ts +8 -0
  44. package/registry/ui/empty-state/empty-state/initial-empty-state.tsx +36 -0
  45. package/registry/ui/empty-state/empty-state/no-results-state.tsx +20 -0
  46. package/registry/ui/empty-state/manifest.json +63 -0
  47. package/registry/ui/empty-state/primitives/button.tsx +89 -0
  48. package/registry/ui/empty-state/primitives/card.tsx +80 -0
  49. package/registry/ui/empty-state/utils/cn.ts +6 -0
  50. package/registry/ui/error-page/error-page/error-code.tsx +16 -0
  51. package/registry/ui/error-page/error-page/error-page-content.ts +75 -0
  52. package/registry/ui/error-page/error-page/index.ts +19 -0
  53. package/registry/ui/error-page/error-page/posthog-error-capture.ts +83 -0
  54. package/registry/ui/error-page/error-page/saas-error-page.tsx +146 -0
  55. package/registry/ui/error-page/manifest.json +64 -0
  56. package/registry/ui/error-page/primitives/button.tsx +89 -0
  57. package/registry/ui/error-page/utils/cn.ts +6 -0
  58. package/registry/ui/field-detail-row/manifest.json +32 -0
  59. package/registry/ui/field-detail-row/primitives/field-detail-row.tsx +28 -0
  60. package/registry/ui/field-detail-row/utils/cn.ts +6 -0
  61. package/registry/ui/file-dropzone/manifest.json +35 -0
  62. package/registry/ui/file-dropzone/primitives/button.tsx +89 -0
  63. package/registry/ui/file-dropzone/primitives/file-dropzone.tsx +236 -0
  64. package/registry/ui/file-dropzone/utils/cn.ts +6 -0
  65. package/registry/ui/help-info-button/manifest.json +72 -0
  66. package/registry/ui/help-info-button/overlays/responsive-sheet.footer.tsx +88 -0
  67. package/registry/ui/help-info-button/overlays/responsive-sheet.layouts.tsx +207 -0
  68. package/registry/ui/help-info-button/overlays/responsive-sheet.shortcuts.ts +103 -0
  69. package/registry/ui/help-info-button/overlays/responsive-sheet.tsx +132 -0
  70. package/registry/ui/help-info-button/primitives/button.tsx +89 -0
  71. package/registry/ui/help-info-button/primitives/drawer.tsx +99 -0
  72. package/registry/ui/help-info-button/primitives/help-info-button.tsx +63 -0
  73. package/registry/ui/help-info-button/primitives/keyboard-shortcut-hint.tsx +40 -0
  74. package/registry/ui/help-info-button/primitives/sheet.tsx +103 -0
  75. package/registry/ui/help-info-button/primitives/tooltip.tsx +57 -0
  76. package/registry/ui/help-info-button/utils/cn.ts +6 -0
  77. package/registry/ui/help-info-button/utils/use-media-query.ts +28 -0
  78. package/registry/ui/input/manifest.json +31 -0
  79. package/registry/ui/input/primitives/input.tsx +19 -0
  80. package/registry/ui/input/utils/cn.ts +6 -0
  81. package/registry/ui/keyboard-shortcut-hint/manifest.json +32 -0
  82. package/registry/ui/keyboard-shortcut-hint/primitives/keyboard-shortcut-hint.tsx +40 -0
  83. package/registry/ui/keyboard-shortcut-hint/utils/cn.ts +6 -0
  84. package/registry/ui/label/manifest.json +31 -0
  85. package/registry/ui/label/primitives/label.tsx +21 -0
  86. package/registry/ui/label/utils/cn.ts +6 -0
  87. package/registry/ui/pagination/manifest.json +36 -0
  88. package/registry/ui/pagination/primitives/button.tsx +89 -0
  89. package/registry/ui/pagination/primitives/pagination.tsx +143 -0
  90. package/registry/ui/pagination/utils/cn.ts +6 -0
  91. package/registry/ui/popover/manifest.json +33 -0
  92. package/registry/ui/popover/primitives/popover.tsx +46 -0
  93. package/registry/ui/popover/utils/cn.ts +6 -0
  94. package/registry/ui/responsive-sheet/manifest.json +66 -0
  95. package/registry/ui/responsive-sheet/overlays/responsive-sheet.footer.tsx +88 -0
  96. package/registry/ui/responsive-sheet/overlays/responsive-sheet.layouts.tsx +207 -0
  97. package/registry/ui/responsive-sheet/overlays/responsive-sheet.shortcuts.ts +103 -0
  98. package/registry/ui/responsive-sheet/overlays/responsive-sheet.tsx +132 -0
  99. package/registry/ui/responsive-sheet/primitives/button.tsx +89 -0
  100. package/registry/ui/responsive-sheet/primitives/drawer.tsx +99 -0
  101. package/registry/ui/responsive-sheet/primitives/keyboard-shortcut-hint.tsx +40 -0
  102. package/registry/ui/responsive-sheet/primitives/sheet.tsx +103 -0
  103. package/registry/ui/responsive-sheet/utils/cn.ts +6 -0
  104. package/registry/ui/responsive-sheet/utils/use-media-query.ts +28 -0
  105. package/registry/ui/responsive-sheet.footer/manifest.json +40 -0
  106. package/registry/ui/responsive-sheet.footer/overlays/responsive-sheet.footer.tsx +88 -0
  107. package/registry/ui/responsive-sheet.footer/primitives/button.tsx +89 -0
  108. package/registry/ui/responsive-sheet.footer/primitives/keyboard-shortcut-hint.tsx +40 -0
  109. package/registry/ui/responsive-sheet.footer/utils/cn.ts +6 -0
  110. package/registry/ui/responsive-sheet.shortcuts/manifest.json +34 -0
  111. package/registry/ui/responsive-sheet.shortcuts/overlays/responsive-sheet.shortcuts.ts +103 -0
  112. package/registry/ui/responsive-sheet.shortcuts/utils/cn.ts +6 -0
  113. package/registry/ui/scroll-fade-area/manifest.json +31 -0
  114. package/registry/ui/scroll-fade-area/primitives/scroll-fade-area.tsx +295 -0
  115. package/registry/ui/scroll-fade-area/utils/cn.ts +6 -0
  116. package/registry/ui/search/manifest.json +35 -0
  117. package/registry/ui/search/utils/cn.ts +6 -0
  118. package/registry/ui/search/utils/search.ts +227 -0
  119. package/registry/ui/searchable-select/manifest.json +48 -0
  120. package/registry/ui/searchable-select/primitives/input.tsx +19 -0
  121. package/registry/ui/searchable-select/search/searchable-select-position.ts +95 -0
  122. package/registry/ui/searchable-select/search/searchable-select.tsx +431 -0
  123. package/registry/ui/searchable-select/utils/cn.ts +6 -0
  124. package/registry/ui/searchable-select/utils/search.ts +227 -0
  125. package/registry/ui/searchable-select-position/manifest.json +32 -0
  126. package/registry/ui/searchable-select-position/search/searchable-select-position.ts +95 -0
  127. package/registry/ui/searchable-select-position/utils/cn.ts +6 -0
  128. package/registry/ui/segmented-toggle/manifest.json +41 -0
  129. package/registry/ui/segmented-toggle/primitives/scroll-fade-area.tsx +295 -0
  130. package/registry/ui/segmented-toggle/primitives/segmented-toggle.tsx +106 -0
  131. package/registry/ui/segmented-toggle/primitives/tabs.tsx +97 -0
  132. package/registry/ui/segmented-toggle/utils/cn.ts +6 -0
  133. package/registry/ui/select/manifest.json +37 -0
  134. package/registry/ui/select/primitives/select.tsx +142 -0
  135. package/registry/ui/select/utils/cn.ts +6 -0
  136. package/registry/ui/sheet/manifest.json +39 -0
  137. package/registry/ui/sheet/primitives/button.tsx +89 -0
  138. package/registry/ui/sheet/primitives/sheet.tsx +103 -0
  139. package/registry/ui/sheet/utils/cn.ts +6 -0
  140. package/registry/ui/skeleton/manifest.json +31 -0
  141. package/registry/ui/skeleton/primitives/skeleton.tsx +13 -0
  142. package/registry/ui/skeleton/utils/cn.ts +6 -0
  143. package/registry/ui/smart-table/manifest.json +115 -0
  144. package/registry/ui/smart-table/primitives/button.tsx +89 -0
  145. package/registry/ui/smart-table/primitives/card.tsx +80 -0
  146. package/registry/ui/smart-table/primitives/display-date.tsx +20 -0
  147. package/registry/ui/smart-table/primitives/pagination.tsx +143 -0
  148. package/registry/ui/smart-table/primitives/skeleton.tsx +13 -0
  149. package/registry/ui/smart-table/primitives/table.tsx +92 -0
  150. package/registry/ui/smart-table/primitives/tooltip.tsx +57 -0
  151. package/registry/ui/smart-table/smart-table/DesktopView.tsx +343 -0
  152. package/registry/ui/smart-table/smart-table/MobileView.tsx +170 -0
  153. package/registry/ui/smart-table/smart-table/SmartTable.tsx +85 -0
  154. package/registry/ui/smart-table/smart-table/SmartTableActions.tsx +71 -0
  155. package/registry/ui/smart-table/smart-table/TruncatedContent.tsx +147 -0
  156. package/registry/ui/smart-table/smart-table/index.ts +15 -0
  157. package/registry/ui/smart-table/smart-table/sorting.ts +148 -0
  158. package/registry/ui/smart-table/smart-table/truncated-content.utils.ts +22 -0
  159. package/registry/ui/smart-table/smart-table/types.ts +95 -0
  160. package/registry/ui/smart-table/smart-table/utils.ts +150 -0
  161. package/registry/ui/smart-table/utils/cn.ts +6 -0
  162. package/registry/ui/smart-table/utils/date-display.ts +61 -0
  163. package/registry/ui/smart-table/utils/use-media-query.ts +28 -0
  164. package/registry/ui/switch/manifest.json +31 -0
  165. package/registry/ui/switch/primitives/switch.tsx +31 -0
  166. package/registry/ui/switch/utils/cn.ts +6 -0
  167. package/registry/ui/table/manifest.json +38 -0
  168. package/registry/ui/table/primitives/table.tsx +92 -0
  169. package/registry/ui/table/utils/cn.ts +6 -0
  170. package/registry/ui/table-toolbar/manifest.json +93 -0
  171. package/registry/ui/table-toolbar/overlays/responsive-sheet.footer.tsx +88 -0
  172. package/registry/ui/table-toolbar/overlays/responsive-sheet.layouts.tsx +207 -0
  173. package/registry/ui/table-toolbar/overlays/responsive-sheet.shortcuts.ts +103 -0
  174. package/registry/ui/table-toolbar/overlays/responsive-sheet.tsx +132 -0
  175. package/registry/ui/table-toolbar/primitives/button.tsx +89 -0
  176. package/registry/ui/table-toolbar/primitives/drawer.tsx +99 -0
  177. package/registry/ui/table-toolbar/primitives/input.tsx +19 -0
  178. package/registry/ui/table-toolbar/primitives/keyboard-shortcut-hint.tsx +40 -0
  179. package/registry/ui/table-toolbar/primitives/sheet.tsx +103 -0
  180. package/registry/ui/table-toolbar/search/searchable-select-position.ts +95 -0
  181. package/registry/ui/table-toolbar/search/searchable-select.tsx +431 -0
  182. package/registry/ui/table-toolbar/table-toolbar/index.ts +9 -0
  183. package/registry/ui/table-toolbar/table-toolbar/table-toolbar.tsx +552 -0
  184. package/registry/ui/table-toolbar/utils/cn.ts +6 -0
  185. package/registry/ui/table-toolbar/utils/search.ts +227 -0
  186. package/registry/ui/table-toolbar/utils/use-media-query.ts +28 -0
  187. package/registry/ui/tabs/manifest.json +40 -0
  188. package/registry/ui/tabs/primitives/scroll-fade-area.tsx +295 -0
  189. package/registry/ui/tabs/primitives/tabs.tsx +97 -0
  190. package/registry/ui/tabs/utils/cn.ts +6 -0
  191. package/registry/ui/textarea/manifest.json +31 -0
  192. package/registry/ui/textarea/primitives/textarea.tsx +18 -0
  193. package/registry/ui/textarea/utils/cn.ts +6 -0
  194. package/registry/ui/tooltip/manifest.json +34 -0
  195. package/registry/ui/tooltip/primitives/tooltip.tsx +57 -0
  196. package/registry/ui/tooltip/utils/cn.ts +6 -0
  197. package/registry/ui/use-media-query/manifest.json +32 -0
  198. package/registry/ui/use-media-query/utils/cn.ts +6 -0
  199. package/registry/ui/use-media-query/utils/use-media-query.ts +28 -0
  200. package/registry/ui/user-picker/manifest.json +52 -0
  201. package/registry/ui/user-picker/primitives/avatar.tsx +64 -0
  202. package/registry/ui/user-picker/primitives/button.tsx +89 -0
  203. package/registry/ui/user-picker/primitives/input.tsx +19 -0
  204. package/registry/ui/user-picker/primitives/popover.tsx +46 -0
  205. package/registry/ui/user-picker/primitives/user-picker-utils.ts +113 -0
  206. package/registry/ui/user-picker/primitives/user-picker.tsx +226 -0
  207. package/registry/ui/user-picker/utils/cn.ts +6 -0
  208. package/registry/ui/user-picker-utils/manifest.json +38 -0
  209. package/registry/ui/user-picker-utils/primitives/user-picker-utils.ts +113 -0
  210. package/registry/ui/user-picker-utils/utils/cn.ts +6 -0
  211. package/assets/hero.png +0 -0
  212. package/registry/ui/button/cn.ts +0 -6
  213. /package/registry/ui/button/{button.tsx → primitives/button.tsx} +0 -0
@@ -0,0 +1,106 @@
1
+ 'use client';
2
+
3
+ import type { ReactNode } from 'react';
4
+
5
+ import { Tabs, TabsList, TabsScrollArea, TabsTrigger } from '@/components/ui/tabs';
6
+ import { cn } from '@/lib/utils';
7
+
8
+ export interface SegmentedToggleOption<TValue extends string> {
9
+ readonly value: TValue;
10
+ readonly label: string;
11
+ readonly icon?: ReactNode;
12
+ }
13
+
14
+ export interface SegmentedToggleProps<TValue extends string> {
15
+ readonly value: TValue;
16
+ readonly onChange: (value: TValue) => void;
17
+ readonly options: readonly SegmentedToggleOption<TValue>[];
18
+ readonly disabled?: boolean;
19
+ readonly className?: string;
20
+ readonly variant?: 'default' | 'primary';
21
+ readonly scrollable?: boolean;
22
+ }
23
+
24
+ export function SegmentedToggle<TValue extends string>({
25
+ value,
26
+ onChange,
27
+ options,
28
+ disabled = false,
29
+ className,
30
+ variant = 'default',
31
+ scrollable = false,
32
+ }: SegmentedToggleProps<TValue>): React.ReactElement {
33
+ const isPrimaryVariant = variant === 'primary';
34
+
35
+ return (
36
+ <Tabs
37
+ value={value}
38
+ onValueChange={(nextValue) => {
39
+ if (nextValue) {
40
+ onChange(nextValue as TValue);
41
+ }
42
+ }}
43
+ className={cn('w-full', disabled && 'opacity-50', className)}
44
+ >
45
+ {scrollable ? (
46
+ <TabsScrollArea>
47
+ <TabsList
48
+ className={cn(
49
+ 'w-full min-w-max',
50
+ isPrimaryVariant &&
51
+ 'border-border bg-background h-8 gap-0.5 rounded-lg border p-0.5 shadow-none',
52
+ )}
53
+ >
54
+ {options.map((option) => (
55
+ <TabsTrigger
56
+ key={option.value}
57
+ value={option.value}
58
+ disabled={disabled}
59
+ className={cn(
60
+ 'shrink-0',
61
+ isPrimaryVariant && [
62
+ 'text-foreground h-full gap-1.5 rounded-md px-2 py-0 text-[13px] leading-5 font-medium tracking-[-0.28px] shadow-none',
63
+ 'hover:text-foreground',
64
+ 'data-active:border-border data-active:bg-accent data-active:text-accent-foreground data-active:shadow-none',
65
+ '[&_svg:not([class*=size-])]:size-4',
66
+ ],
67
+ )}
68
+ >
69
+ {option.icon}
70
+ {option.label}
71
+ </TabsTrigger>
72
+ ))}
73
+ </TabsList>
74
+ </TabsScrollArea>
75
+ ) : (
76
+ <TabsList
77
+ className={cn(
78
+ 'w-full',
79
+ isPrimaryVariant &&
80
+ 'border-border bg-background h-8 gap-0.5 rounded-lg border p-0.5 shadow-none',
81
+ )}
82
+ >
83
+ {options.map((option) => (
84
+ <TabsTrigger
85
+ key={option.value}
86
+ value={option.value}
87
+ disabled={disabled}
88
+ className={cn(
89
+ 'flex-1',
90
+ isPrimaryVariant && [
91
+ 'text-foreground h-full gap-1.5 rounded-md px-2 py-0 text-[13px] leading-5 font-medium tracking-[-0.28px] shadow-none',
92
+ 'hover:text-foreground',
93
+ 'data-active:border-border data-active:bg-accent data-active:text-accent-foreground data-active:shadow-none',
94
+ '[&_svg:not([class*=size-])]:size-4',
95
+ ],
96
+ )}
97
+ >
98
+ {option.icon}
99
+ {option.label}
100
+ </TabsTrigger>
101
+ ))}
102
+ </TabsList>
103
+ )}
104
+ </Tabs>
105
+ );
106
+ }
@@ -0,0 +1,97 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { cva, type VariantProps } from 'class-variance-authority';
5
+ import { Tabs as TabsPrimitive } from 'radix-ui';
6
+
7
+ import { ScrollFadeArea } from '@/components/ui/scroll-fade-area';
8
+ import { cn } from '@/lib/utils';
9
+
10
+ function Tabs({
11
+ className,
12
+ orientation = 'horizontal',
13
+ ...props
14
+ }: React.ComponentProps<typeof TabsPrimitive.Root>) {
15
+ return (
16
+ <TabsPrimitive.Root
17
+ data-slot="tabs"
18
+ data-orientation={orientation}
19
+ className={cn('group/tabs flex gap-2 data-horizontal:flex-col', className)}
20
+ {...props}
21
+ />
22
+ );
23
+ }
24
+
25
+ const tabsListVariants = cva(
26
+ 'gap-2 rounded-lg p-[3px] group-data-horizontal/tabs:h-8 data-[variant=line]:rounded-none group/tabs-list text-muted-foreground inline-flex w-fit items-center justify-center group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col',
27
+ {
28
+ variants: {
29
+ variant: {
30
+ default: 'bg-muted',
31
+ line: 'gap-2 bg-transparent',
32
+ },
33
+ },
34
+ defaultVariants: {
35
+ variant: 'default',
36
+ },
37
+ },
38
+ );
39
+
40
+ function TabsList({
41
+ className,
42
+ variant = 'default',
43
+ ...props
44
+ }: React.ComponentProps<typeof TabsPrimitive.List> & VariantProps<typeof tabsListVariants>) {
45
+ return (
46
+ <TabsPrimitive.List
47
+ data-slot="tabs-list"
48
+ data-variant={variant}
49
+ className={cn(tabsListVariants({ variant }), className)}
50
+ {...props}
51
+ />
52
+ );
53
+ }
54
+
55
+ function TabsScrollArea({
56
+ className,
57
+ viewportClassName,
58
+ ...props
59
+ }: React.ComponentProps<typeof ScrollFadeArea>) {
60
+ return (
61
+ <ScrollFadeArea
62
+ {...props}
63
+ data-slot="tabs-scroll-area"
64
+ orientation="horizontal"
65
+ className={cn('w-full min-w-0', className)}
66
+ viewportClassName={cn('min-w-0', viewportClassName)}
67
+ />
68
+ );
69
+ }
70
+
71
+ function TabsTrigger({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
72
+ return (
73
+ <TabsPrimitive.Trigger
74
+ data-slot="tabs-trigger"
75
+ className={cn(
76
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-foreground/60 hover:text-foreground dark:text-muted-foreground dark:hover:text-foreground relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium whitespace-nowrap transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
77
+ 'group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent',
78
+ 'data-active:bg-background dark:data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 data-active:text-foreground',
79
+ 'after:bg-foreground after:absolute after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100',
80
+ className,
81
+ )}
82
+ {...props}
83
+ />
84
+ );
85
+ }
86
+
87
+ function TabsContent({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Content>) {
88
+ return (
89
+ <TabsPrimitive.Content
90
+ data-slot="tabs-content"
91
+ className={cn('flex-1 text-sm outline-none', className)}
92
+ {...props}
93
+ />
94
+ );
95
+ }
96
+
97
+ export { Tabs, TabsList, TabsScrollArea, TabsTrigger, TabsContent, tabsListVariants };
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]): string {
5
+ return twMerge(clsx(inputs))
6
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "select",
3
+ "description": "Editable source registry entry for select.",
4
+ "importPath": "@carefully-built/ui",
5
+ "exports": [
6
+ "Select",
7
+ "SelectContent",
8
+ "SelectItem",
9
+ "SelectScrollDownButton",
10
+ "SelectScrollUpButton",
11
+ "SelectTrigger",
12
+ "SelectValue"
13
+ ],
14
+ "dependencies": [
15
+ "class-variance-authority",
16
+ "clsx",
17
+ "tailwind-merge"
18
+ ],
19
+ "peerDependencies": [
20
+ "react",
21
+ "react-dom",
22
+ "radix-ui",
23
+ "lucide-react",
24
+ "react-day-picker",
25
+ "vaul"
26
+ ],
27
+ "files": [
28
+ {
29
+ "source": "primitives/select.tsx",
30
+ "target": "components/ui/select.tsx"
31
+ },
32
+ {
33
+ "source": "utils/cn.ts",
34
+ "target": "lib/utils.ts"
35
+ }
36
+ ]
37
+ }
@@ -0,0 +1,142 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Check, ChevronDown, ChevronUp, ChevronsUpDown } from "lucide-react"
5
+ import { Select as SelectPrimitive } from "radix-ui"
6
+
7
+ import { cn } from "@/lib/utils"
8
+
9
+ function Select({
10
+ ...props
11
+ }: React.ComponentProps<typeof SelectPrimitive.Root>) {
12
+ return <SelectPrimitive.Root data-slot="select" {...props} />
13
+ }
14
+
15
+ function SelectValue({
16
+ ...props
17
+ }: React.ComponentProps<typeof SelectPrimitive.Value>) {
18
+ return <SelectPrimitive.Value data-slot="select-value" {...props} />
19
+ }
20
+
21
+ function SelectTrigger({
22
+ className,
23
+ size = "default",
24
+ children,
25
+ ...props
26
+ }: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
27
+ size?: "sm" | "default"
28
+ }) {
29
+ return (
30
+ <SelectPrimitive.Trigger
31
+ data-slot="select-trigger"
32
+ data-size={size}
33
+ className={cn(
34
+ "border-input data-placeholder:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 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 gap-1.5 rounded-lg border bg-transparent py-1 pr-2 pl-2 text-sm transition-colors select-none focus-visible:ring-3 aria-invalid:ring-3 data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:gap-1.5 [&_svg:not([class*='size-'])]:size-4 flex w-fit items-center justify-between whitespace-nowrap outline-none disabled:cursor-not-allowed disabled:opacity-50 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
35
+ className
36
+ )}
37
+ {...props}
38
+ >
39
+ {children}
40
+ <SelectPrimitive.Icon asChild>
41
+ <ChevronsUpDown className="text-muted-foreground size-4 pointer-events-none" />
42
+ </SelectPrimitive.Icon>
43
+ </SelectPrimitive.Trigger>
44
+ )
45
+ }
46
+
47
+ function SelectContent({
48
+ className,
49
+ children,
50
+ position = "item-aligned",
51
+ align = "center",
52
+ ...props
53
+ }: React.ComponentProps<typeof SelectPrimitive.Content>) {
54
+ return (
55
+ <SelectPrimitive.Portal>
56
+ <SelectPrimitive.Content
57
+ data-slot="select-content"
58
+ data-align-trigger={position === "item-aligned"}
59
+ className={cn("bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-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 ring-foreground/10 min-w-[250px] rounded-lg shadow-md ring-1 duration-100 relative z-50 max-h-(--radix-select-content-available-height) origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto data-[align-trigger=true]:animate-none", position ==="popper"&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className )}
60
+ position={position}
61
+ align={align}
62
+ {...props}
63
+ >
64
+ <SelectScrollUpButton />
65
+ <SelectPrimitive.Viewport
66
+ data-position={position}
67
+ className={cn(
68
+ "data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)",
69
+ position === "popper" && ""
70
+ )}
71
+ >
72
+ {children}
73
+ </SelectPrimitive.Viewport>
74
+ <SelectScrollDownButton />
75
+ </SelectPrimitive.Content>
76
+ </SelectPrimitive.Portal>
77
+ )
78
+ }
79
+
80
+ function SelectItem({
81
+ className,
82
+ children,
83
+ ...props
84
+ }: React.ComponentProps<typeof SelectPrimitive.Item>) {
85
+ return (
86
+ <SelectPrimitive.Item
87
+ data-slot="select-item"
88
+ className={cn(
89
+ "focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2 relative flex w-full cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
90
+ className
91
+ )}
92
+ {...props}
93
+ >
94
+ <span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center">
95
+ <SelectPrimitive.ItemIndicator>
96
+ <Check className="pointer-events-none size-4" />
97
+ </SelectPrimitive.ItemIndicator>
98
+ </span>
99
+ <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
100
+ </SelectPrimitive.Item>
101
+ )
102
+ }
103
+
104
+ function SelectScrollUpButton({
105
+ className,
106
+ ...props
107
+ }: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {
108
+ return (
109
+ <SelectPrimitive.ScrollUpButton
110
+ data-slot="select-scroll-up-button"
111
+ className={cn("bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-4", className)}
112
+ {...props}
113
+ >
114
+ <ChevronUp />
115
+ </SelectPrimitive.ScrollUpButton>
116
+ )
117
+ }
118
+
119
+ function SelectScrollDownButton({
120
+ className,
121
+ ...props
122
+ }: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {
123
+ return (
124
+ <SelectPrimitive.ScrollDownButton
125
+ data-slot="select-scroll-down-button"
126
+ className={cn("bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-4", className)}
127
+ {...props}
128
+ >
129
+ <ChevronDown />
130
+ </SelectPrimitive.ScrollDownButton>
131
+ )
132
+ }
133
+
134
+ export {
135
+ Select,
136
+ SelectContent,
137
+ SelectItem,
138
+ SelectScrollDownButton,
139
+ SelectScrollUpButton,
140
+ SelectTrigger,
141
+ SelectValue,
142
+ }
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]): string {
5
+ return twMerge(clsx(inputs))
6
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "sheet",
3
+ "description": "Editable source registry entry for sheet.",
4
+ "importPath": "@carefully-built/ui",
5
+ "exports": [
6
+ "Sheet",
7
+ "SheetContent",
8
+ "SheetDescription",
9
+ "SheetHeader",
10
+ "SheetTitle"
11
+ ],
12
+ "dependencies": [
13
+ "class-variance-authority",
14
+ "clsx",
15
+ "tailwind-merge"
16
+ ],
17
+ "peerDependencies": [
18
+ "react",
19
+ "react-dom",
20
+ "radix-ui",
21
+ "lucide-react",
22
+ "react-day-picker",
23
+ "vaul"
24
+ ],
25
+ "files": [
26
+ {
27
+ "source": "primitives/button.tsx",
28
+ "target": "components/ui/button.tsx"
29
+ },
30
+ {
31
+ "source": "primitives/sheet.tsx",
32
+ "target": "components/ui/sheet.tsx"
33
+ },
34
+ {
35
+ "source": "utils/cn.ts",
36
+ "target": "lib/utils.ts"
37
+ }
38
+ ]
39
+ }
@@ -0,0 +1,89 @@
1
+ import * as React from "react";
2
+ import { cva } from "class-variance-authority";
3
+ import { Slot } from "radix-ui";
4
+
5
+ import { cn } from "@/lib/utils";
6
+
7
+ const buttonVariants = cva(
8
+ "group/button inline-flex shrink-0 cursor-pointer items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default:
13
+ "bg-primary text-primary-foreground hover:brightness-90 [a]:hover:bg-primary/80",
14
+ outline:
15
+ "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
16
+ secondary:
17
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
18
+ ghost:
19
+ "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
20
+ destructive:
21
+ "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
22
+ link: "text-primary underline-offset-4 hover:underline",
23
+ },
24
+ size: {
25
+ default:
26
+ "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
27
+ xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
28
+ sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
29
+ lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
30
+ icon: "size-8",
31
+ "icon-xs":
32
+ "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
33
+ "icon-sm":
34
+ "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
35
+ "icon-lg": "size-9",
36
+ },
37
+ },
38
+ defaultVariants: {
39
+ variant: "default",
40
+ size: "default",
41
+ },
42
+ },
43
+ );
44
+
45
+ type ButtonVariant =
46
+ | "default"
47
+ | "outline"
48
+ | "secondary"
49
+ | "ghost"
50
+ | "destructive"
51
+ | "link";
52
+ type ButtonSize =
53
+ | "default"
54
+ | "xs"
55
+ | "sm"
56
+ | "lg"
57
+ | "icon"
58
+ | "icon-xs"
59
+ | "icon-sm"
60
+ | "icon-lg";
61
+
62
+ interface ButtonProps extends React.ComponentProps<"button"> {
63
+ readonly asChild?: boolean;
64
+ readonly size?: ButtonSize;
65
+ readonly variant?: ButtonVariant;
66
+ }
67
+
68
+ function Button({
69
+ className,
70
+ variant = "default",
71
+ size = "default",
72
+ asChild = false,
73
+ ...props
74
+ }: ButtonProps) {
75
+ const Comp = asChild ? Slot.Root : "button";
76
+
77
+ return (
78
+ <Comp
79
+ data-slot="button"
80
+ data-variant={variant}
81
+ data-size={size}
82
+ className={cn(buttonVariants({ variant, size, className }))}
83
+ {...props}
84
+ />
85
+ );
86
+ }
87
+
88
+ export { Button, buttonVariants };
89
+ export type { ButtonProps, ButtonSize, ButtonVariant };
@@ -0,0 +1,103 @@
1
+ 'use client';
2
+
3
+ import { X } from 'lucide-react';
4
+ import * as React from 'react';
5
+ import { Dialog as SheetPrimitive } from 'radix-ui';
6
+
7
+ import { Button } from '@/components/ui/button';
8
+ import { cn } from '@/lib/utils';
9
+
10
+ function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
11
+ return <SheetPrimitive.Root data-slot="sheet" {...props} />;
12
+ }
13
+
14
+ function SheetPortal({ ...props }: React.ComponentProps<typeof SheetPrimitive.Portal>) {
15
+ return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />;
16
+ }
17
+
18
+ function SheetOverlay({
19
+ className,
20
+ ...props
21
+ }: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
22
+ return (
23
+ <SheetPrimitive.Overlay
24
+ data-slot="sheet-overlay"
25
+ className={cn(
26
+ 'data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 fixed inset-0 z-50 bg-black/10 backdrop-blur-xs duration-100 data-ending-style:opacity-0 data-starting-style:opacity-0',
27
+ className,
28
+ )}
29
+ {...props}
30
+ />
31
+ );
32
+ }
33
+
34
+ function SheetContent({
35
+ className,
36
+ children,
37
+ side = 'right',
38
+ showCloseButton = true,
39
+ ...props
40
+ }: React.ComponentProps<typeof SheetPrimitive.Content> & {
41
+ side?: 'top' | 'right' | 'bottom' | 'left';
42
+ showCloseButton?: boolean;
43
+ }) {
44
+ return (
45
+ <SheetPortal>
46
+ <SheetOverlay />
47
+ <SheetPrimitive.Content
48
+ data-slot="sheet-content"
49
+ data-side={side}
50
+ className={cn(
51
+ 'bg-background data-open:animate-in data-closed:animate-out data-[side=right]:data-closed:slide-out-to-right-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=top]:data-closed:slide-out-to-top-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:fade-out-0 data-open:fade-in-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=bottom]:data-open:slide-in-from-bottom-10 fixed z-50 flex flex-col gap-4 overflow-visible bg-clip-padding text-sm shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:rounded-r-xl data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:rounded-l-xl data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm',
52
+ className,
53
+ )}
54
+ {...props}
55
+ >
56
+ {children}
57
+ {showCloseButton ? (
58
+ <SheetPrimitive.Close data-slot="sheet-close" asChild>
59
+ <Button variant="ghost" className="absolute top-3 right-3" size="icon-sm">
60
+ <X className="size-4" />
61
+ <span className="sr-only">Close</span>
62
+ </Button>
63
+ </SheetPrimitive.Close>
64
+ ) : null}
65
+ </SheetPrimitive.Content>
66
+ </SheetPortal>
67
+ );
68
+ }
69
+
70
+ function SheetHeader({ className, ...props }: React.ComponentProps<'div'>) {
71
+ return (
72
+ <div
73
+ data-slot="sheet-header"
74
+ className={cn('flex flex-col gap-0.5 p-4', className)}
75
+ {...props}
76
+ />
77
+ );
78
+ }
79
+
80
+ function SheetTitle({ className, ...props }: React.ComponentProps<typeof SheetPrimitive.Title>) {
81
+ return (
82
+ <SheetPrimitive.Title
83
+ data-slot="sheet-title"
84
+ className={cn('text-foreground text-base font-medium', className)}
85
+ {...props}
86
+ />
87
+ );
88
+ }
89
+
90
+ function SheetDescription({
91
+ className,
92
+ ...props
93
+ }: React.ComponentProps<typeof SheetPrimitive.Description>) {
94
+ return (
95
+ <SheetPrimitive.Description
96
+ data-slot="sheet-description"
97
+ className={cn('text-muted-foreground text-sm', className)}
98
+ {...props}
99
+ />
100
+ );
101
+ }
102
+
103
+ export { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle };
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]): string {
5
+ return twMerge(clsx(inputs))
6
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "skeleton",
3
+ "description": "Editable source registry entry for skeleton.",
4
+ "importPath": "@carefully-built/ui",
5
+ "exports": [
6
+ "Skeleton"
7
+ ],
8
+ "dependencies": [
9
+ "class-variance-authority",
10
+ "clsx",
11
+ "tailwind-merge"
12
+ ],
13
+ "peerDependencies": [
14
+ "react",
15
+ "react-dom",
16
+ "radix-ui",
17
+ "lucide-react",
18
+ "react-day-picker",
19
+ "vaul"
20
+ ],
21
+ "files": [
22
+ {
23
+ "source": "primitives/skeleton.tsx",
24
+ "target": "components/ui/skeleton.tsx"
25
+ },
26
+ {
27
+ "source": "utils/cn.ts",
28
+ "target": "lib/utils.ts"
29
+ }
30
+ ]
31
+ }
@@ -0,0 +1,13 @@
1
+ import { cn } from "@/lib/utils"
2
+
3
+ function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
4
+ return (
5
+ <div
6
+ data-slot="skeleton"
7
+ className={cn("bg-muted rounded-md animate-pulse", className)}
8
+ {...props}
9
+ />
10
+ )
11
+ }
12
+
13
+ export { Skeleton }