@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,28 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useState } from 'react';
4
+
5
+ export function useMediaQuery(query: string, defaultValue = false): boolean {
6
+ const [matches, setMatches] = useState(defaultValue);
7
+
8
+ useEffect(() => {
9
+ const mediaQuery = window.matchMedia(query);
10
+
11
+ const handleChange = (): void => {
12
+ setMatches(mediaQuery.matches);
13
+ };
14
+
15
+ handleChange();
16
+ mediaQuery.addEventListener('change', handleChange);
17
+
18
+ return () => {
19
+ mediaQuery.removeEventListener('change', handleChange);
20
+ };
21
+ }, [query]);
22
+
23
+ return matches;
24
+ }
25
+
26
+ export function useIsMobile(maxWidth = 767): boolean {
27
+ return useMediaQuery(`(max-width: ${String(maxWidth)}px)`);
28
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "input",
3
+ "description": "Editable source registry entry for input.",
4
+ "importPath": "@carefully-built/ui",
5
+ "exports": [
6
+ "Input"
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/input.tsx",
24
+ "target": "components/ui/input.tsx"
25
+ },
26
+ {
27
+ "source": "utils/cn.ts",
28
+ "target": "lib/utils.ts"
29
+ }
30
+ ]
31
+ }
@@ -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 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,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,32 @@
1
+ {
2
+ "name": "keyboard-shortcut-hint",
3
+ "description": "Editable source registry entry for keyboard-shortcut-hint.",
4
+ "importPath": "@carefully-built/ui",
5
+ "exports": [
6
+ "KeyboardKeycap",
7
+ "ShortcutModifierKeycap"
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/keyboard-shortcut-hint.tsx",
25
+ "target": "components/ui/keyboard-shortcut-hint.tsx"
26
+ },
27
+ {
28
+ "source": "utils/cn.ts",
29
+ "target": "lib/utils.ts"
30
+ }
31
+ ]
32
+ }
@@ -0,0 +1,40 @@
1
+ 'use client';
2
+
3
+ import { Command } from 'lucide-react';
4
+
5
+ import type { ReactNode } from 'react';
6
+
7
+ import { cn } from '@/lib/utils';
8
+
9
+ export function KeyboardKeycap({
10
+ children,
11
+ className,
12
+ }: {
13
+ readonly children: ReactNode;
14
+ readonly className?: string;
15
+ }): React.ReactElement {
16
+ return (
17
+ <span
18
+ className={cn(
19
+ 'inline-flex h-4 min-w-4 items-center justify-center rounded-[4px] border px-1 text-[9px] font-semibold leading-none',
20
+ className,
21
+ )}
22
+ >
23
+ {children}
24
+ </span>
25
+ );
26
+ }
27
+
28
+ export function ShortcutModifierKeycap({
29
+ modifierLabel,
30
+ className,
31
+ }: {
32
+ readonly modifierLabel: string;
33
+ readonly className?: string;
34
+ }): React.ReactElement {
35
+ return (
36
+ <KeyboardKeycap className={className}>
37
+ {modifierLabel === 'Cmd' ? <Command className="size-[10px]" /> : 'Ctrl'}
38
+ </KeyboardKeycap>
39
+ );
40
+ }
@@ -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": "label",
3
+ "description": "Editable source registry entry for label.",
4
+ "importPath": "@carefully-built/ui",
5
+ "exports": [
6
+ "Label"
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/label.tsx",
24
+ "target": "components/ui/label.tsx"
25
+ },
26
+ {
27
+ "source": "utils/cn.ts",
28
+ "target": "lib/utils.ts"
29
+ }
30
+ ]
31
+ }
@@ -0,0 +1,21 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { Label as LabelPrimitive } from 'radix-ui';
5
+
6
+ import { cn } from '@/lib/utils';
7
+
8
+ function Label({ className, ...props }: React.ComponentProps<typeof LabelPrimitive.Root>) {
9
+ return (
10
+ <LabelPrimitive.Root
11
+ data-slot="label"
12
+ className={cn(
13
+ 'flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50',
14
+ className,
15
+ )}
16
+ {...props}
17
+ />
18
+ );
19
+ }
20
+
21
+ export { Label };
@@ -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": "pagination",
3
+ "description": "Editable source registry entry for pagination.",
4
+ "importPath": "@carefully-built/ui",
5
+ "exports": [
6
+ "Pagination",
7
+ "PaginationProps"
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/button.tsx",
25
+ "target": "components/ui/button.tsx"
26
+ },
27
+ {
28
+ "source": "primitives/pagination.tsx",
29
+ "target": "components/ui/pagination.tsx"
30
+ },
31
+ {
32
+ "source": "utils/cn.ts",
33
+ "target": "lib/utils.ts"
34
+ }
35
+ ]
36
+ }
@@ -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,143 @@
1
+ 'use client';
2
+
3
+ import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from 'lucide-react';
4
+
5
+ import { Button } from '@/components/ui/button';
6
+ import { cn } from '@/lib/utils';
7
+
8
+ export interface PaginationProps {
9
+ /** Current page (1-indexed) */
10
+ currentPage: number;
11
+ /** Total number of pages */
12
+ totalPages: number;
13
+ /** Total number of items */
14
+ totalItems: number;
15
+ /** Items per page */
16
+ pageSize: number;
17
+ /** Start index of current page items (1-indexed for display) */
18
+ startIndex: number;
19
+ /** End index of current page items */
20
+ endIndex: number;
21
+ /** Go to specific page */
22
+ onPageChange: (page: number) => void;
23
+ /** Optional: page size options */
24
+ pageSizeOptions?: number[];
25
+ /** Optional: callback when page size changes */
26
+ onPageSizeChange?: (size: number) => void;
27
+ /** Optional: custom className */
28
+ className?: string;
29
+ }
30
+
31
+ export function Pagination({
32
+ currentPage,
33
+ totalPages,
34
+ totalItems,
35
+ pageSize,
36
+ startIndex,
37
+ endIndex,
38
+ onPageChange,
39
+ pageSizeOptions,
40
+ onPageSizeChange,
41
+ className,
42
+ }: PaginationProps): React.ReactElement | null {
43
+ if (totalPages <= 1) {
44
+ return null;
45
+ }
46
+
47
+ const hasPrevPage = currentPage > 1;
48
+ const hasNextPage = currentPage < totalPages;
49
+
50
+ return (
51
+ <div className={cn('flex items-center justify-between gap-3 py-3', className)}>
52
+ {/* Items info */}
53
+ <div className="text-xs text-muted-foreground">
54
+ {totalItems === 0 ? (
55
+ 'No items'
56
+ ) : (
57
+ <>
58
+ Showing <span className="font-medium">{startIndex + 1}</span> -{' '}
59
+ <span className="font-medium">{endIndex}</span> of{' '}
60
+ <span className="font-medium">{totalItems}</span>
61
+ </>
62
+ )}
63
+ </div>
64
+
65
+ <div className="flex items-center gap-1.5">
66
+ {/* Page size selector */}
67
+ {pageSizeOptions && onPageSizeChange && (
68
+ <div className="hidden items-center gap-1.5 sm:flex">
69
+ <span className="text-xs text-muted-foreground">Rows:</span>
70
+ <select
71
+ value={String(pageSize)}
72
+ onChange={(event) => {
73
+ onPageSizeChange(Number(event.target.value));
74
+ }}
75
+ className="border-input bg-background h-7 w-[64px] rounded-md border px-2 text-xs"
76
+ >
77
+ {pageSizeOptions.map((size) => (
78
+ <option key={size} value={String(size)}>
79
+ {size}
80
+ </option>
81
+ ))}
82
+ </select>
83
+ </div>
84
+ )}
85
+
86
+ {/* Page info */}
87
+ <div className="hidden text-xs text-muted-foreground sm:block">
88
+ Page {currentPage} of {totalPages}
89
+ </div>
90
+
91
+ {/* Navigation buttons */}
92
+ <div className="flex items-center gap-0.5">
93
+ <Button
94
+ variant="outline"
95
+ size="icon"
96
+ className="size-7"
97
+ onClick={() => { onPageChange(1); }}
98
+ disabled={!hasPrevPage}
99
+ >
100
+ <ChevronsLeft className="size-3.5" />
101
+ <span className="sr-only">First page</span>
102
+ </Button>
103
+ <Button
104
+ variant="outline"
105
+ size="icon"
106
+ className="size-7"
107
+ onClick={() => { onPageChange(currentPage - 1); }}
108
+ disabled={!hasPrevPage}
109
+ >
110
+ <ChevronLeft className="size-3.5" />
111
+ <span className="sr-only">Previous page</span>
112
+ </Button>
113
+
114
+ {/* Mobile page indicator */}
115
+ <span className="px-1.5 text-xs sm:hidden">
116
+ {currentPage}/{totalPages}
117
+ </span>
118
+
119
+ <Button
120
+ variant="outline"
121
+ size="icon"
122
+ className="size-7"
123
+ onClick={() => { onPageChange(currentPage + 1); }}
124
+ disabled={!hasNextPage}
125
+ >
126
+ <ChevronRight className="size-3.5" />
127
+ <span className="sr-only">Next page</span>
128
+ </Button>
129
+ <Button
130
+ variant="outline"
131
+ size="icon"
132
+ className="size-7"
133
+ onClick={() => { onPageChange(totalPages); }}
134
+ disabled={!hasNextPage}
135
+ >
136
+ <ChevronsRight className="size-3.5" />
137
+ <span className="sr-only">Last page</span>
138
+ </Button>
139
+ </div>
140
+ </div>
141
+ </div>
142
+ );
143
+ }
@@ -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": "popover",
3
+ "description": "Editable source registry entry for popover.",
4
+ "importPath": "@carefully-built/ui",
5
+ "exports": [
6
+ "Popover",
7
+ "PopoverContent",
8
+ "PopoverTrigger"
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/popover.tsx",
26
+ "target": "components/ui/popover.tsx"
27
+ },
28
+ {
29
+ "source": "utils/cn.ts",
30
+ "target": "lib/utils.ts"
31
+ }
32
+ ]
33
+ }
@@ -0,0 +1,46 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Popover as PopoverPrimitive } from "radix-ui"
5
+
6
+ import { cn } from "@/lib/utils"
7
+
8
+ function Popover({
9
+ ...props
10
+ }: React.ComponentProps<typeof PopoverPrimitive.Root>) {
11
+ return <PopoverPrimitive.Root data-slot="popover" {...props} />
12
+ }
13
+
14
+ function PopoverTrigger({
15
+ ...props
16
+ }: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {
17
+ return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />
18
+ }
19
+
20
+ function PopoverContent({
21
+ className,
22
+ align = "center",
23
+ sideOffset = 4,
24
+ ...props
25
+ }: React.ComponentProps<typeof PopoverPrimitive.Content>) {
26
+ return (
27
+ <PopoverPrimitive.Portal>
28
+ <PopoverPrimitive.Content
29
+ data-slot="popover-content"
30
+ align={align}
31
+ sideOffset={sideOffset}
32
+ className={cn(
33
+ "z-50 flex w-72 origin-(--radix-popover-content-transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 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-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
34
+ className
35
+ )}
36
+ {...props}
37
+ />
38
+ </PopoverPrimitive.Portal>
39
+ )
40
+ }
41
+
42
+ export {
43
+ Popover,
44
+ PopoverContent,
45
+ PopoverTrigger,
46
+ }
@@ -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,66 @@
1
+ {
2
+ "name": "responsive-sheet",
3
+ "description": "Editable source registry entry for responsive-sheet.",
4
+ "importPath": "@carefully-built/ui",
5
+ "exports": [
6
+ "ResponsiveSheet",
7
+ "ResponsiveSheetClassNames",
8
+ "ResponsiveSheetProps",
9
+ "SheetOutsideInteractionGuard"
10
+ ],
11
+ "dependencies": [
12
+ "class-variance-authority",
13
+ "clsx",
14
+ "tailwind-merge"
15
+ ],
16
+ "peerDependencies": [
17
+ "react",
18
+ "react-dom",
19
+ "radix-ui",
20
+ "lucide-react",
21
+ "react-day-picker",
22
+ "vaul"
23
+ ],
24
+ "files": [
25
+ {
26
+ "source": "overlays/responsive-sheet.footer.tsx",
27
+ "target": "components/ui/responsive-sheet.footer.tsx"
28
+ },
29
+ {
30
+ "source": "overlays/responsive-sheet.layouts.tsx",
31
+ "target": "components/ui/responsive-sheet.layouts.tsx"
32
+ },
33
+ {
34
+ "source": "overlays/responsive-sheet.shortcuts.ts",
35
+ "target": "components/ui/responsive-sheet.shortcuts.ts"
36
+ },
37
+ {
38
+ "source": "overlays/responsive-sheet.tsx",
39
+ "target": "components/ui/responsive-sheet.tsx"
40
+ },
41
+ {
42
+ "source": "primitives/button.tsx",
43
+ "target": "components/ui/button.tsx"
44
+ },
45
+ {
46
+ "source": "primitives/drawer.tsx",
47
+ "target": "components/ui/drawer.tsx"
48
+ },
49
+ {
50
+ "source": "primitives/keyboard-shortcut-hint.tsx",
51
+ "target": "components/ui/keyboard-shortcut-hint.tsx"
52
+ },
53
+ {
54
+ "source": "primitives/sheet.tsx",
55
+ "target": "components/ui/sheet.tsx"
56
+ },
57
+ {
58
+ "source": "utils/cn.ts",
59
+ "target": "lib/utils.ts"
60
+ },
61
+ {
62
+ "source": "utils/use-media-query.ts",
63
+ "target": "components/ui/use-media-query.ts"
64
+ }
65
+ ]
66
+ }