@carefully-built/cli 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/README.md +148 -7
  2. package/dist/index.mjs +71 -11
  3. package/dist/index.mjs.map +1 -1
  4. package/package.json +4 -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/registry/ui/button/cn.ts +0 -6
  212. /package/registry/ui/button/{button.tsx → primitives/button.tsx} +0 -0
@@ -0,0 +1,68 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { ChevronLeft, ChevronRight } from "lucide-react"
5
+ import { DayPicker, getDefaultClassNames } from "react-day-picker"
6
+
7
+ import { buttonVariants } from "@/components/ui/button"
8
+ import { cn } from "@/lib/utils"
9
+
10
+ function Calendar({
11
+ className,
12
+ classNames,
13
+ showOutsideDays = true,
14
+ ...props
15
+ }: React.ComponentProps<typeof DayPicker>) {
16
+ const defaultClassNames = getDefaultClassNames()
17
+
18
+ return (
19
+ <DayPicker
20
+ showOutsideDays={showOutsideDays}
21
+ className={cn("p-3", className)}
22
+ classNames={{
23
+ root: cn("w-fit", defaultClassNames.root),
24
+ months: "flex flex-col gap-4",
25
+ month: "flex flex-col gap-4",
26
+ month_caption: "relative flex items-center justify-center pt-1",
27
+ caption_label: "text-sm font-medium",
28
+ nav: "flex items-center gap-1",
29
+ button_previous: cn(
30
+ buttonVariants({ variant: "ghost", size: "icon-sm" }),
31
+ "absolute left-1 size-7 bg-transparent p-0 opacity-70 hover:opacity-100"
32
+ ),
33
+ button_next: cn(
34
+ buttonVariants({ variant: "ghost", size: "icon-sm" }),
35
+ "absolute right-1 size-7 bg-transparent p-0 opacity-70 hover:opacity-100"
36
+ ),
37
+ month_grid: "w-full border-collapse space-y-1",
38
+ weekdays: "flex",
39
+ weekday:
40
+ "w-9 text-[0.78rem] font-medium text-muted-foreground",
41
+ week: "mt-2 flex w-full",
42
+ day: "size-9 p-0 text-sm",
43
+ day_button: cn(
44
+ buttonVariants({ variant: "ghost", size: "icon-sm" }),
45
+ "size-9 p-0 font-normal aria-selected:opacity-100"
46
+ ),
47
+ selected:
48
+ "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
49
+ today: "bg-muted text-foreground",
50
+ outside: "text-muted-foreground opacity-50 aria-selected:bg-primary/10 aria-selected:text-muted-foreground",
51
+ disabled: "text-muted-foreground opacity-50",
52
+ hidden: "invisible",
53
+ ...classNames,
54
+ }}
55
+ components={{
56
+ Chevron: ({ orientation, className: iconClassName, ...iconProps }) =>
57
+ orientation === "left" ? (
58
+ <ChevronLeft className={cn("size-4", iconClassName)} {...iconProps} />
59
+ ) : (
60
+ <ChevronRight className={cn("size-4", iconClassName)} {...iconProps} />
61
+ ),
62
+ }}
63
+ {...props}
64
+ />
65
+ )
66
+ }
67
+
68
+ export { Calendar }
@@ -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,36 @@
1
+ {
2
+ "name": "card",
3
+ "description": "Editable source registry entry for card.",
4
+ "importPath": "@carefully-built/ui",
5
+ "exports": [
6
+ "Card",
7
+ "CardContent",
8
+ "CardDescription",
9
+ "CardFooter",
10
+ "CardHeader",
11
+ "CardTitle"
12
+ ],
13
+ "dependencies": [
14
+ "class-variance-authority",
15
+ "clsx",
16
+ "tailwind-merge"
17
+ ],
18
+ "peerDependencies": [
19
+ "react",
20
+ "react-dom",
21
+ "radix-ui",
22
+ "lucide-react",
23
+ "react-day-picker",
24
+ "vaul"
25
+ ],
26
+ "files": [
27
+ {
28
+ "source": "primitives/card.tsx",
29
+ "target": "components/ui/card.tsx"
30
+ },
31
+ {
32
+ "source": "utils/cn.ts",
33
+ "target": "lib/utils.ts"
34
+ }
35
+ ]
36
+ }
@@ -0,0 +1,80 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "@/lib/utils"
4
+
5
+ function Card({
6
+ className,
7
+ size = "default",
8
+ ...props
9
+ }: React.ComponentProps<"div"> & { size?: "default" | "sm" }) {
10
+ return (
11
+ <div
12
+ data-slot="card"
13
+ data-size={size}
14
+ className={cn("ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-xl py-4 text-sm ring-1 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col", className)}
15
+ {...props}
16
+ />
17
+ )
18
+ }
19
+
20
+ function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
21
+ return (
22
+ <div
23
+ data-slot="card-header"
24
+ className={cn(
25
+ "gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3 group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]",
26
+ className
27
+ )}
28
+ {...props}
29
+ />
30
+ )
31
+ }
32
+
33
+ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
34
+ return (
35
+ <div
36
+ data-slot="card-title"
37
+ className={cn("text-base leading-snug font-medium group-data-[size=sm]/card:text-sm", className)}
38
+ {...props}
39
+ />
40
+ )
41
+ }
42
+
43
+ function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
44
+ return (
45
+ <div
46
+ data-slot="card-description"
47
+ className={cn("text-muted-foreground text-sm", className)}
48
+ {...props}
49
+ />
50
+ )
51
+ }
52
+
53
+ function CardContent({ className, ...props }: React.ComponentProps<"div">) {
54
+ return (
55
+ <div
56
+ data-slot="card-content"
57
+ className={cn("px-4 group-data-[size=sm]/card:px-3", className)}
58
+ {...props}
59
+ />
60
+ )
61
+ }
62
+
63
+ function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
64
+ return (
65
+ <div
66
+ data-slot="card-footer"
67
+ className={cn("bg-muted/50 rounded-b-xl border-t p-4 group-data-[size=sm]/card:p-3 flex items-center", className)}
68
+ {...props}
69
+ />
70
+ )
71
+ }
72
+
73
+ export {
74
+ Card,
75
+ CardHeader,
76
+ CardFooter,
77
+ CardTitle,
78
+ CardDescription,
79
+ CardContent,
80
+ }
@@ -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,36 @@
1
+ {
2
+ "name": "chip",
3
+ "description": "Editable source registry entry for chip.",
4
+ "importPath": "@carefully-built/ui",
5
+ "exports": [
6
+ "Chip",
7
+ "ChipButton"
8
+ ],
9
+ "dependencies": [
10
+ "class-variance-authority",
11
+ "clsx",
12
+ "tailwind-merge"
13
+ ],
14
+ "peerDependencies": [
15
+ "react",
16
+ "react-dom",
17
+ "radix-ui",
18
+ "lucide-react",
19
+ "react-day-picker",
20
+ "vaul"
21
+ ],
22
+ "files": [
23
+ {
24
+ "source": "primitives/chip-utils.ts",
25
+ "target": "components/ui/chip-utils.ts"
26
+ },
27
+ {
28
+ "source": "primitives/chip.tsx",
29
+ "target": "components/ui/chip.tsx"
30
+ },
31
+ {
32
+ "source": "utils/cn.ts",
33
+ "target": "lib/utils.ts"
34
+ }
35
+ ]
36
+ }
@@ -0,0 +1,10 @@
1
+ export const CHIP_CLASS_NAMES = {
2
+ default: 'inline-flex w-fit max-w-full flex-none items-center gap-1 rounded-md px-1.5 py-[2px] text-xs font-medium leading-4',
3
+ compact: 'inline-flex w-fit max-w-full flex-none items-center gap-1 rounded-[4px] px-1.5 py-px text-[10px] font-medium leading-3',
4
+ } as const;
5
+
6
+ export type ChipSize = keyof typeof CHIP_CLASS_NAMES;
7
+
8
+ export function getChipClassName(size: ChipSize = 'default'): string {
9
+ return CHIP_CLASS_NAMES[size];
10
+ }
@@ -0,0 +1,74 @@
1
+ 'use client';
2
+
3
+ import type { ButtonHTMLAttributes, HTMLAttributes, ReactNode } from 'react';
4
+
5
+ import { getChipClassName, type ChipSize } from '@/components/ui/chip-utils';
6
+ import { cn } from '@/lib/utils';
7
+
8
+ interface ChipProps extends HTMLAttributes<HTMLSpanElement> {
9
+ readonly children: ReactNode;
10
+ readonly leading?: ReactNode;
11
+ readonly trailing?: ReactNode;
12
+ readonly size?: ChipSize;
13
+ }
14
+
15
+ export function Chip({
16
+ children,
17
+ className,
18
+ leading,
19
+ size = 'default',
20
+ trailing,
21
+ ...props
22
+ }: ChipProps): React.ReactElement {
23
+ return (
24
+ <span
25
+ {...props}
26
+ className={cn(
27
+ getChipClassName(size),
28
+ className
29
+ )}
30
+ >
31
+ {leading ? <span className="shrink-0">{leading}</span> : null}
32
+ <span className="truncate">{children}</span>
33
+ {trailing ? <span className="shrink-0">{trailing}</span> : null}
34
+ </span>
35
+ );
36
+ }
37
+
38
+ interface ChipButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
39
+ readonly children: ReactNode;
40
+ readonly leading?: ReactNode;
41
+ readonly trailing?: ReactNode;
42
+ readonly selected?: boolean;
43
+ readonly size?: ChipSize;
44
+ }
45
+
46
+ export function ChipButton({
47
+ children,
48
+ className,
49
+ leading,
50
+ selected = false,
51
+ size = 'default',
52
+ trailing,
53
+ ...props
54
+ }: ChipButtonProps): React.ReactElement {
55
+ return (
56
+ <button
57
+ type="button"
58
+ aria-pressed={selected}
59
+ {...props}
60
+ className={cn(
61
+ getChipClassName(size),
62
+ 'border text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
63
+ selected
64
+ ? 'border-[#713dff] bg-[#f6f1ff] text-[#1f1f23] shadow-[0_0_0_1px_rgba(113,61,255,0.08)] hover:bg-[#f6f1ff]'
65
+ : 'border-[#e7e8eb] bg-white text-[#5f6368] hover:bg-[#f7f7f9]',
66
+ className
67
+ )}
68
+ >
69
+ {leading ? <span className="shrink-0">{leading}</span> : null}
70
+ <span className="truncate">{children}</span>
71
+ {trailing ? <span className="shrink-0">{trailing}</span> : null}
72
+ </button>
73
+ );
74
+ }
@@ -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,33 @@
1
+ {
2
+ "name": "chip-utils",
3
+ "description": "Editable source registry entry for chip-utils.",
4
+ "importPath": "@carefully-built/ui",
5
+ "exports": [
6
+ "CHIP_CLASS_NAMES",
7
+ "ChipSize",
8
+ "getChipClassName"
9
+ ],
10
+ "dependencies": [
11
+ "class-variance-authority",
12
+ "clsx",
13
+ "tailwind-merge"
14
+ ],
15
+ "peerDependencies": [
16
+ "react",
17
+ "react-dom",
18
+ "radix-ui",
19
+ "lucide-react",
20
+ "react-day-picker",
21
+ "vaul"
22
+ ],
23
+ "files": [
24
+ {
25
+ "source": "primitives/chip-utils.ts",
26
+ "target": "components/ui/chip-utils.ts"
27
+ },
28
+ {
29
+ "source": "utils/cn.ts",
30
+ "target": "lib/utils.ts"
31
+ }
32
+ ]
33
+ }
@@ -0,0 +1,10 @@
1
+ export const CHIP_CLASS_NAMES = {
2
+ default: 'inline-flex w-fit max-w-full flex-none items-center gap-1 rounded-md px-1.5 py-[2px] text-xs font-medium leading-4',
3
+ compact: 'inline-flex w-fit max-w-full flex-none items-center gap-1 rounded-[4px] px-1.5 py-px text-[10px] font-medium leading-3',
4
+ } as const;
5
+
6
+ export type ChipSize = keyof typeof CHIP_CLASS_NAMES;
7
+
8
+ export function getChipClassName(size: ChipSize = 'default'): string {
9
+ return CHIP_CLASS_NAMES[size];
10
+ }
@@ -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,33 @@
1
+ {
2
+ "name": "date-display",
3
+ "description": "Editable source registry entry for date-display.",
4
+ "importPath": "@carefully-built/ui",
5
+ "exports": [
6
+ "DateDisplayValue",
7
+ "formatAbsoluteDate",
8
+ "formatDisplayDate"
9
+ ],
10
+ "dependencies": [
11
+ "class-variance-authority",
12
+ "clsx",
13
+ "tailwind-merge"
14
+ ],
15
+ "peerDependencies": [
16
+ "react",
17
+ "react-dom",
18
+ "radix-ui",
19
+ "lucide-react",
20
+ "react-day-picker",
21
+ "vaul"
22
+ ],
23
+ "files": [
24
+ {
25
+ "source": "utils/cn.ts",
26
+ "target": "lib/utils.ts"
27
+ },
28
+ {
29
+ "source": "utils/date-display.ts",
30
+ "target": "components/ui/date-display.ts"
31
+ }
32
+ ]
33
+ }
@@ -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,61 @@
1
+ export type DateDisplayValue = Date | number | string;
2
+
3
+ function getDate(value: DateDisplayValue): Date {
4
+ return value instanceof Date ? value : new Date(value);
5
+ }
6
+
7
+ function startOfDay(date: Date): Date {
8
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
9
+ }
10
+
11
+ function getDayDifference(from: Date, to: Date): number {
12
+ const millisecondsPerDay = 24 * 60 * 60 * 1000;
13
+ return Math.round((startOfDay(to).getTime() - startOfDay(from).getTime()) / millisecondsPerDay);
14
+ }
15
+
16
+ function capitalizeMonthLabel(value: string): string {
17
+ return value
18
+ .split(' ')
19
+ .map((part, index) => {
20
+ if (index !== 1 || part.length === 0) {
21
+ return part;
22
+ }
23
+
24
+ const [firstCharacter = '', ...restCharacters] = part;
25
+ return `${firstCharacter.toUpperCase()}${restCharacters.join('')}`;
26
+ })
27
+ .join(' ');
28
+ }
29
+
30
+ export function formatAbsoluteDate(value: DateDisplayValue): string {
31
+ const date = getDate(value);
32
+ const currentYear = new Date().getFullYear();
33
+ const includesYear = date.getFullYear() !== currentYear;
34
+
35
+ return capitalizeMonthLabel(
36
+ new Intl.DateTimeFormat('it-IT', {
37
+ day: 'numeric',
38
+ month: 'short',
39
+ ...(includesYear ? { year: 'numeric' } : {}),
40
+ }).format(date)
41
+ );
42
+ }
43
+
44
+ export function formatDisplayDate(value: DateDisplayValue): string {
45
+ const date = getDate(value);
46
+ const dayDifference = getDayDifference(date, new Date());
47
+
48
+ if (dayDifference === 0) {
49
+ return 'Oggi';
50
+ }
51
+
52
+ if (dayDifference === 1) {
53
+ return 'Ieri';
54
+ }
55
+
56
+ if (dayDifference >= 2 && dayDifference <= 10) {
57
+ return `${String(dayDifference)} giorni fa`;
58
+ }
59
+
60
+ return formatAbsoluteDate(date);
61
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "dialog",
3
+ "description": "Editable source registry entry for dialog.",
4
+ "importPath": "@carefully-built/ui",
5
+ "exports": [
6
+ "Dialog",
7
+ "DialogContent",
8
+ "DialogDescription",
9
+ "DialogFooter",
10
+ "DialogHeader",
11
+ "DialogOverlay",
12
+ "DialogPortal",
13
+ "DialogTitle",
14
+ "DialogTrigger"
15
+ ],
16
+ "dependencies": [
17
+ "class-variance-authority",
18
+ "clsx",
19
+ "tailwind-merge"
20
+ ],
21
+ "peerDependencies": [
22
+ "react",
23
+ "react-dom",
24
+ "radix-ui",
25
+ "lucide-react",
26
+ "react-day-picker",
27
+ "vaul"
28
+ ],
29
+ "files": [
30
+ {
31
+ "source": "primitives/button.tsx",
32
+ "target": "components/ui/button.tsx"
33
+ },
34
+ {
35
+ "source": "primitives/dialog.tsx",
36
+ "target": "components/ui/dialog.tsx"
37
+ },
38
+ {
39
+ "source": "utils/cn.ts",
40
+ "target": "lib/utils.ts"
41
+ }
42
+ ]
43
+ }
@@ -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 };