@cntyclub/ui-react 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/dist/chunk-HDGMSYQS.js +26461 -0
  2. package/dist/chunk-HDGMSYQS.js.map +1 -0
  3. package/dist/chunk-PR4QN5HX.js +39 -0
  4. package/dist/chunk-PR4QN5HX.js.map +1 -0
  5. package/dist/form.d.ts +175 -0
  6. package/dist/form.js +5207 -0
  7. package/dist/form.js.map +1 -0
  8. package/dist/index.d.ts +1462 -0
  9. package/dist/index.js +81862 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/input-CZvh825j.d.ts +24 -0
  12. package/dist/qr-code-styling-3Y6LZH6V.js +1123 -0
  13. package/dist/qr-code-styling-3Y6LZH6V.js.map +1 -0
  14. package/package.json +79 -0
  15. package/src/components/form/checkbox-group-field.tsx +101 -0
  16. package/src/components/form/date-field.tsx +79 -0
  17. package/src/components/form/date-range-field.tsx +106 -0
  18. package/src/components/form/form-context.ts +10 -0
  19. package/src/components/form/form.tsx +54 -0
  20. package/src/components/form/number-field.tsx +69 -0
  21. package/src/components/form/select-field.tsx +76 -0
  22. package/src/components/form/submit-button.tsx +28 -0
  23. package/src/components/form/text-field.tsx +107 -0
  24. package/src/components/layout/dashboard-header.tsx +54 -0
  25. package/src/components/layout/dashboard-panel.tsx +34 -0
  26. package/src/components/theme-provider.tsx +403 -0
  27. package/src/components/ui/accordion.tsx +69 -0
  28. package/src/components/ui/alert-dialog.tsx +169 -0
  29. package/src/components/ui/alert.tsx +80 -0
  30. package/src/components/ui/animated-theme-toggler.tsx +265 -0
  31. package/src/components/ui/app-store-buttons.tsx +182 -0
  32. package/src/components/ui/aspect-ratio.tsx +23 -0
  33. package/src/components/ui/autocomplete.tsx +296 -0
  34. package/src/components/ui/avatar-group.tsx +95 -0
  35. package/src/components/ui/avatar.tsx +285 -0
  36. package/src/components/ui/badge-group.tsx +160 -0
  37. package/src/components/ui/badge.tsx +172 -0
  38. package/src/components/ui/breadcrumb.tsx +112 -0
  39. package/src/components/ui/button.tsx +77 -0
  40. package/src/components/ui/calendar.tsx +137 -0
  41. package/src/components/ui/card.tsx +244 -0
  42. package/src/components/ui/carousel.tsx +258 -0
  43. package/src/components/ui/chart.tsx +379 -0
  44. package/src/components/ui/checkbox-group.tsx +16 -0
  45. package/src/components/ui/checkbox.tsx +82 -0
  46. package/src/components/ui/collapsible.tsx +45 -0
  47. package/src/components/ui/combobox.tsx +411 -0
  48. package/src/components/ui/command.tsx +264 -0
  49. package/src/components/ui/context-menu.tsx +271 -0
  50. package/src/components/ui/credit-card.tsx +214 -0
  51. package/src/components/ui/dialog.tsx +196 -0
  52. package/src/components/ui/drawer.tsx +135 -0
  53. package/src/components/ui/empty.tsx +127 -0
  54. package/src/components/ui/featured-icon.tsx +149 -0
  55. package/src/components/ui/field.tsx +88 -0
  56. package/src/components/ui/fieldset.tsx +29 -0
  57. package/src/components/ui/form.tsx +17 -0
  58. package/src/components/ui/frame.tsx +82 -0
  59. package/src/components/ui/generic-empty.tsx +142 -0
  60. package/src/components/ui/group.tsx +97 -0
  61. package/src/components/ui/horizontal-scroll-fader.tsx +228 -0
  62. package/src/components/ui/input-group.tsx +102 -0
  63. package/src/components/ui/input-otp.tsx +96 -0
  64. package/src/components/ui/input.tsx +66 -0
  65. package/src/components/ui/item.tsx +198 -0
  66. package/src/components/ui/kbd.tsx +30 -0
  67. package/src/components/ui/label.tsx +28 -0
  68. package/src/components/ui/menu.tsx +312 -0
  69. package/src/components/ui/menubar.tsx +93 -0
  70. package/src/components/ui/meter.tsx +67 -0
  71. package/src/components/ui/multi-select.tsx +308 -0
  72. package/src/components/ui/navigation-menu.tsx +143 -0
  73. package/src/components/ui/number-field.tsx +160 -0
  74. package/src/components/ui/pagination-controls.tsx +74 -0
  75. package/src/components/ui/pagination.tsx +149 -0
  76. package/src/components/ui/popover.tsx +119 -0
  77. package/src/components/ui/preview-card.tsx +55 -0
  78. package/src/components/ui/progress.tsx +289 -0
  79. package/src/components/ui/qr-code.tsx +150 -0
  80. package/src/components/ui/radio-group.tsx +103 -0
  81. package/src/components/ui/resizable.tsx +56 -0
  82. package/src/components/ui/scroll-area.tsx +90 -0
  83. package/src/components/ui/scroller.tsx +38 -0
  84. package/src/components/ui/section-header.tsx +118 -0
  85. package/src/components/ui/select.tsx +181 -0
  86. package/src/components/ui/separator.tsx +23 -0
  87. package/src/components/ui/sheet.tsx +224 -0
  88. package/src/components/ui/sidebar.tsx +744 -0
  89. package/src/components/ui/skeleton.tsx +16 -0
  90. package/src/components/ui/slider.tsx +108 -0
  91. package/src/components/ui/smooth-scroll.tsx +143 -0
  92. package/src/components/ui/social-button.tsx +247 -0
  93. package/src/components/ui/spinner-on-demand.tsx +32 -0
  94. package/src/components/ui/spinner.tsx +18 -0
  95. package/src/components/ui/stat.tsx +187 -0
  96. package/src/components/ui/stepper.tsx +167 -0
  97. package/src/components/ui/switch.tsx +56 -0
  98. package/src/components/ui/table.tsx +126 -0
  99. package/src/components/ui/tabs.tsx +90 -0
  100. package/src/components/ui/tag.tsx +229 -0
  101. package/src/components/ui/target-countdown.tsx +46 -0
  102. package/src/components/ui/text-editor.tsx +313 -0
  103. package/src/components/ui/textarea.tsx +51 -0
  104. package/src/components/ui/timeline.tsx +116 -0
  105. package/src/components/ui/toast.tsx +268 -0
  106. package/src/components/ui/toggle-group.tsx +101 -0
  107. package/src/components/ui/toggle.tsx +45 -0
  108. package/src/components/ui/toolbar.tsx +89 -0
  109. package/src/components/ui/tooltip.tsx +102 -0
  110. package/src/components/ui/vertical-scroll-fader.tsx +250 -0
  111. package/src/components/ui/video-player.tsx +275 -0
  112. package/src/components/upload/avatar-upload-base.tsx +131 -0
  113. package/src/components/upload/image-upload-base.tsx +112 -0
  114. package/src/form.ts +17 -0
  115. package/src/index.ts +125 -0
  116. package/src/lib/hooks/use-callback-ref.ts +15 -0
  117. package/src/lib/hooks/use-first-render.ts +11 -0
  118. package/src/lib/hooks/use-hover.ts +53 -0
  119. package/src/lib/hooks/use-is-tab-active.ts +17 -0
  120. package/src/lib/hooks/use-media-query.ts +164 -0
  121. package/src/lib/utils/css.ts +6 -0
  122. package/src/styles.css +300 -0
  123. package/src/types/helpers.ts +24 -0
  124. package/src/types/react.d.ts +7 -0
@@ -0,0 +1,135 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { Drawer as DrawerPrimitive } from "vaul";
5
+
6
+ import { cn } from "../../lib/utils/css";
7
+
8
+ function Drawer(props: React.ComponentProps<typeof DrawerPrimitive.Root>) {
9
+ return <DrawerPrimitive.Root data-slot="drawer" {...props} />;
10
+ }
11
+
12
+ function DrawerTrigger(
13
+ props: React.ComponentProps<typeof DrawerPrimitive.Trigger>,
14
+ ) {
15
+ return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />;
16
+ }
17
+
18
+ function DrawerPortal(
19
+ props: React.ComponentProps<typeof DrawerPrimitive.Portal>,
20
+ ) {
21
+ return <DrawerPrimitive.Portal data-slot="drawer-portal" {...props} />;
22
+ }
23
+
24
+ function DrawerClose(props: React.ComponentProps<typeof DrawerPrimitive.Close>) {
25
+ return <DrawerPrimitive.Close data-slot="drawer-close" {...props} />;
26
+ }
27
+
28
+ function DrawerOverlay({
29
+ className,
30
+ ...props
31
+ }: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {
32
+ return (
33
+ <DrawerPrimitive.Overlay
34
+ className={cn(
35
+ "fixed inset-0 z-50 bg-black/32 backdrop-blur-sm data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
36
+ className,
37
+ )}
38
+ data-slot="drawer-overlay"
39
+ {...props}
40
+ />
41
+ );
42
+ }
43
+
44
+ function DrawerContent({
45
+ className,
46
+ children,
47
+ ...props
48
+ }: React.ComponentProps<typeof DrawerPrimitive.Content>) {
49
+ return (
50
+ <DrawerPortal>
51
+ <DrawerOverlay />
52
+ <DrawerPrimitive.Content
53
+ className={cn(
54
+ "group/drawer-content fixed z-50 flex h-auto flex-col bg-popover not-dark:bg-clip-padding text-popover-foreground shadow-lg/5 outline-none",
55
+ "data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[82vh] data-[vaul-drawer-direction=bottom]:rounded-t-2xl data-[vaul-drawer-direction=bottom]:border-t",
56
+ "data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[82vh] data-[vaul-drawer-direction=top]:rounded-b-2xl data-[vaul-drawer-direction=top]:border-b",
57
+ "data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-[calc(100%-(--spacing(12)))] data-[vaul-drawer-direction=right]:max-w-md data-[vaul-drawer-direction=right]:border-s",
58
+ "data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-[calc(100%-(--spacing(12)))] data-[vaul-drawer-direction=left]:max-w-md data-[vaul-drawer-direction=left]:border-e",
59
+ className,
60
+ )}
61
+ data-slot="drawer-content"
62
+ {...props}
63
+ >
64
+ {/* Grab handle — shown for bottom/top drawers. */}
65
+ <div className="mx-auto mt-3 hidden h-1.5 w-12 shrink-0 rounded-full bg-border group-data-[vaul-drawer-direction=bottom]/drawer-content:block group-data-[vaul-drawer-direction=top]/drawer-content:block" />
66
+ {children}
67
+ </DrawerPrimitive.Content>
68
+ </DrawerPortal>
69
+ );
70
+ }
71
+
72
+ function DrawerHeader({ className, ...props }: React.ComponentProps<"div">) {
73
+ return (
74
+ <div
75
+ className={cn(
76
+ "flex flex-col gap-1.5 p-6 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center md:group-data-[vaul-drawer-direction=bottom]/drawer-content:text-left",
77
+ className,
78
+ )}
79
+ data-slot="drawer-header"
80
+ {...props}
81
+ />
82
+ );
83
+ }
84
+
85
+ function DrawerFooter({ className, ...props }: React.ComponentProps<"div">) {
86
+ return (
87
+ <div
88
+ className={cn(
89
+ "mt-auto flex flex-col gap-2 border-t bg-muted/72 px-6 py-4",
90
+ className,
91
+ )}
92
+ data-slot="drawer-footer"
93
+ {...props}
94
+ />
95
+ );
96
+ }
97
+
98
+ function DrawerTitle({
99
+ className,
100
+ ...props
101
+ }: React.ComponentProps<typeof DrawerPrimitive.Title>) {
102
+ return (
103
+ <DrawerPrimitive.Title
104
+ className={cn("font-semibold text-xl leading-none", className)}
105
+ data-slot="drawer-title"
106
+ {...props}
107
+ />
108
+ );
109
+ }
110
+
111
+ function DrawerDescription({
112
+ className,
113
+ ...props
114
+ }: React.ComponentProps<typeof DrawerPrimitive.Description>) {
115
+ return (
116
+ <DrawerPrimitive.Description
117
+ className={cn("text-muted-foreground text-sm", className)}
118
+ data-slot="drawer-description"
119
+ {...props}
120
+ />
121
+ );
122
+ }
123
+
124
+ export {
125
+ Drawer,
126
+ DrawerPortal,
127
+ DrawerOverlay,
128
+ DrawerTrigger,
129
+ DrawerClose,
130
+ DrawerContent,
131
+ DrawerHeader,
132
+ DrawerFooter,
133
+ DrawerTitle,
134
+ DrawerDescription,
135
+ };
@@ -0,0 +1,127 @@
1
+ import { cva, type VariantProps } from "class-variance-authority";
2
+
3
+ import { cn } from "../../lib/utils/css";
4
+
5
+ function Empty({ className, ...props }: React.ComponentProps<"div">) {
6
+ return (
7
+ <div
8
+ className={cn(
9
+ "flex min-w-0 flex-1 flex-col items-center justify-center gap-6 text-balance p-6 text-center md:p-12",
10
+ className,
11
+ )}
12
+ data-slot="empty"
13
+ {...props}
14
+ />
15
+ );
16
+ }
17
+
18
+ function EmptyHeader({ className, ...props }: React.ComponentProps<"div">) {
19
+ return (
20
+ <div
21
+ className={cn(
22
+ "flex max-w-sm flex-col items-center text-center",
23
+ className,
24
+ )}
25
+ data-slot="empty-header"
26
+ {...props}
27
+ />
28
+ );
29
+ }
30
+
31
+ const emptyMediaVariants = cva(
32
+ "flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
33
+ {
34
+ defaultVariants: {
35
+ variant: "default",
36
+ },
37
+ variants: {
38
+ variant: {
39
+ default: "bg-transparent",
40
+ icon: "relative flex size-9 shrink-0 items-center justify-center rounded-md border bg-card text-foreground shadow-sm/5 before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-md)-1px)] before:shadow-[0_1px_--theme(--color-black/6%)] dark:before:shadow-[0_-1px_--theme(--color-white/6%)] [&_svg:not([class*='size-'])]:size-4.5",
41
+ },
42
+ },
43
+ },
44
+ );
45
+
46
+ function EmptyMedia({
47
+ className,
48
+ variant = "default",
49
+ ...props
50
+ }: React.ComponentProps<"div"> & VariantProps<typeof emptyMediaVariants>) {
51
+ return (
52
+ <div
53
+ className={cn("relative mb-6", className)}
54
+ data-slot="empty-media"
55
+ data-variant={variant}
56
+ {...props}
57
+ >
58
+ {variant === "icon" && (
59
+ <>
60
+ <div
61
+ aria-hidden="true"
62
+ className={cn(
63
+ emptyMediaVariants({ className, variant }),
64
+ "-translate-x-0.5 -rotate-10 pointer-events-none absolute bottom-px origin-bottom-left scale-84 shadow-none",
65
+ )}
66
+ />
67
+ <div
68
+ aria-hidden="true"
69
+ className={cn(
70
+ emptyMediaVariants({ className, variant }),
71
+ "pointer-events-none absolute bottom-px origin-bottom-right translate-x-0.5 rotate-10 scale-84 shadow-none",
72
+ )}
73
+ />
74
+ </>
75
+ )}
76
+ <div
77
+ className={cn(emptyMediaVariants({ className, variant }))}
78
+ {...props}
79
+ />
80
+ </div>
81
+ );
82
+ }
83
+
84
+ function EmptyTitle({ className, ...props }: React.ComponentProps<"div">) {
85
+ return (
86
+ <div
87
+ className={cn("font-heading font-semibold text-xl", className)}
88
+ data-slot="empty-title"
89
+ {...props}
90
+ />
91
+ );
92
+ }
93
+
94
+ function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) {
95
+ return (
96
+ <div
97
+ className={cn(
98
+ "text-muted-foreground text-sm [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4 [[data-slot=empty-title]+&]:mt-1",
99
+ className,
100
+ )}
101
+ data-slot="empty-description"
102
+ {...props}
103
+ />
104
+ );
105
+ }
106
+
107
+ function EmptyContent({ className, ...props }: React.ComponentProps<"div">) {
108
+ return (
109
+ <div
110
+ className={cn(
111
+ "flex w-full min-w-0 max-w-sm flex-col items-center gap-4 text-balance text-sm",
112
+ className,
113
+ )}
114
+ data-slot="empty-content"
115
+ {...props}
116
+ />
117
+ );
118
+ }
119
+
120
+ export {
121
+ Empty,
122
+ EmptyHeader,
123
+ EmptyTitle,
124
+ EmptyDescription,
125
+ EmptyContent,
126
+ EmptyMedia,
127
+ };
@@ -0,0 +1,149 @@
1
+ "use client";
2
+
3
+ import { cva, type VariantProps } from "class-variance-authority";
4
+ import type * as React from "react";
5
+
6
+ import { cn } from "../../lib/utils/css";
7
+
8
+ const featuredIconVariants = cva(
9
+ "relative inline-flex shrink-0 select-none items-center justify-center align-middle [&_svg]:pointer-events-none [&_svg]:shrink-0",
10
+ {
11
+ compoundVariants: [
12
+ // The bordered themes are squared, with corners that scale with the size.
13
+ {
14
+ className: "rounded-md before:rounded-[calc(var(--radius-md)-3px)]",
15
+ size: "sm",
16
+ theme: ["modern", "modern-neue"],
17
+ },
18
+ {
19
+ className: "rounded-lg before:rounded-[calc(var(--radius-lg)-3px)]",
20
+ size: "md",
21
+ theme: ["modern", "modern-neue"],
22
+ },
23
+ {
24
+ className: "rounded-[10px] before:rounded-[7px]",
25
+ size: "lg",
26
+ theme: ["modern", "modern-neue"],
27
+ },
28
+ {
29
+ className: "rounded-xl before:rounded-[calc(var(--radius-xl)-3px)]",
30
+ size: "xl",
31
+ theme: ["modern", "modern-neue"],
32
+ },
33
+ ],
34
+ defaultVariants: { color: "brand", size: "md", theme: "light" },
35
+ variants: {
36
+ // Colors are applied through the theme/color maps below — the variant
37
+ // exists so cva carries the prop type.
38
+ color: { brand: "", error: "", gray: "", success: "", warning: "" },
39
+ size: {
40
+ sm: "size-8 [&_svg:not([class*='size-'])]:size-4",
41
+ md: "size-10 [&_svg:not([class*='size-'])]:size-5",
42
+ lg: "size-12 [&_svg:not([class*='size-'])]:size-6",
43
+ xl: "size-14 [&_svg:not([class*='size-'])]:size-7",
44
+ },
45
+ theme: {
46
+ dark: "rounded-full text-white shadow-xs not-dark:inset-shadow-[0_1px_--theme(--color-white/16%)]",
47
+ gradient:
48
+ "rounded-full bg-linear-to-b from-white/24 to-white/0 text-white shadow-xs inset-shadow-[0_1px_--theme(--color-white/24%)]",
49
+ light: "rounded-full",
50
+ modern:
51
+ "border border-input bg-background shadow-xs not-dark:bg-clip-padding dark:bg-input/32",
52
+ "modern-neue":
53
+ "border border-input bg-background shadow-xs not-dark:bg-clip-padding dark:bg-input/32 before:pointer-events-none before:absolute before:inset-[3px] before:border before:border-border/72 before:shadow-xs",
54
+ outline:
55
+ "rounded-full before:pointer-events-none before:absolute before:inset-0 before:rounded-full before:border-2 before:border-current before:opacity-12 after:pointer-events-none after:absolute after:inset-[15%] after:rounded-full after:border-2 after:border-current after:opacity-32",
56
+ },
57
+ },
58
+ },
59
+ );
60
+
61
+ type FeaturedIconTheme = NonNullable<
62
+ VariantProps<typeof featuredIconVariants>["theme"]
63
+ >;
64
+ type FeaturedIconColor = NonNullable<
65
+ VariantProps<typeof featuredIconVariants>["color"]
66
+ >;
67
+
68
+ /** Per-theme color treatments, using the design-system tonal/solid tokens. */
69
+ const featuredIconColors: Record<
70
+ FeaturedIconTheme,
71
+ Record<FeaturedIconColor, string>
72
+ > = {
73
+ dark: {
74
+ brand: "bg-brand",
75
+ error: "bg-destructive",
76
+ gray: "bg-secondary-foreground text-background",
77
+ success: "bg-success",
78
+ warning: "bg-warning",
79
+ },
80
+ gradient: {
81
+ brand: "bg-brand",
82
+ error: "bg-destructive",
83
+ gray: "bg-secondary-foreground text-background",
84
+ success: "bg-success",
85
+ warning: "bg-warning",
86
+ },
87
+ light: {
88
+ brand: "bg-brand/12 text-sidebar-primary dark:bg-brand/20",
89
+ error: "bg-destructive/8 text-destructive-foreground dark:bg-destructive/16",
90
+ gray: "bg-secondary text-secondary-foreground",
91
+ success: "bg-success/8 text-success-foreground dark:bg-success/16",
92
+ warning: "bg-warning/8 text-warning-foreground dark:bg-warning/16",
93
+ },
94
+ modern: {
95
+ brand: "text-sidebar-primary",
96
+ error: "text-destructive-foreground",
97
+ gray: "text-foreground",
98
+ success: "text-success-foreground",
99
+ warning: "text-warning-foreground",
100
+ },
101
+ "modern-neue": {
102
+ brand: "text-sidebar-primary",
103
+ error: "text-destructive-foreground",
104
+ gray: "text-foreground",
105
+ success: "text-success-foreground",
106
+ warning: "text-warning-foreground",
107
+ },
108
+ outline: {
109
+ brand: "text-sidebar-primary",
110
+ error: "text-destructive-foreground",
111
+ gray: "text-muted-foreground",
112
+ success: "text-success-foreground",
113
+ warning: "text-warning-foreground",
114
+ },
115
+ };
116
+
117
+ interface FeaturedIconProps extends Omit<React.ComponentProps<"span">, "color"> {
118
+ theme?: FeaturedIconTheme;
119
+ color?: FeaturedIconColor;
120
+ size?: VariantProps<typeof featuredIconVariants>["size"];
121
+ /** Icon component rendered inside (e.g. a lucide icon). Or pass children. */
122
+ icon?: React.ElementType;
123
+ }
124
+
125
+ function FeaturedIcon({
126
+ className,
127
+ theme = "light",
128
+ color = "brand",
129
+ size,
130
+ icon: Icon,
131
+ children,
132
+ ...props
133
+ }: FeaturedIconProps) {
134
+ return (
135
+ <span
136
+ className={cn(
137
+ featuredIconVariants({ color, size, theme }),
138
+ featuredIconColors[theme][color],
139
+ className,
140
+ )}
141
+ data-slot="featured-icon"
142
+ {...props}
143
+ >
144
+ {children ?? (Icon ? <Icon /> : null)}
145
+ </span>
146
+ );
147
+ }
148
+
149
+ export { FeaturedIcon, featuredIconVariants };
@@ -0,0 +1,88 @@
1
+ "use client";
2
+
3
+ import { Field as FieldPrimitive } from "@base-ui/react/field";
4
+
5
+ import { cn } from "../../lib/utils/css";
6
+
7
+ function Field({ className, ...props }: FieldPrimitive.Root.Props) {
8
+ return (
9
+ <FieldPrimitive.Root
10
+ className={cn("flex flex-col items-start gap-2", className)}
11
+ data-slot="field"
12
+ {...props}
13
+ />
14
+ );
15
+ }
16
+
17
+ function FieldLabel({ className, ...props }: FieldPrimitive.Label.Props) {
18
+ return (
19
+ <FieldPrimitive.Label
20
+ className={cn(
21
+ "inline-flex items-center gap-2 font-medium text-base/4.5 text-foreground sm:text-sm/4",
22
+ className,
23
+ )}
24
+ data-slot="field-label"
25
+ {...props}
26
+ />
27
+ );
28
+ }
29
+
30
+ function FieldItem({ className, ...props }: FieldPrimitive.Item.Props) {
31
+ return (
32
+ <FieldPrimitive.Item
33
+ className={cn("flex", className)}
34
+ data-slot="field-item"
35
+ {...props}
36
+ />
37
+ );
38
+ }
39
+
40
+ function FieldDescription({
41
+ className,
42
+ ...props
43
+ }: FieldPrimitive.Description.Props) {
44
+ return (
45
+ <FieldPrimitive.Description
46
+ className={cn("text-muted-foreground text-xs", className)}
47
+ data-slot="field-description"
48
+ {...props}
49
+ />
50
+ );
51
+ }
52
+
53
+ function FieldError({ className, ...props }: FieldPrimitive.Error.Props) {
54
+ return (
55
+ <FieldPrimitive.Error
56
+ className={cn("text-destructive-foreground text-xs", className)}
57
+ data-slot="field-error"
58
+ {...props}
59
+ />
60
+ );
61
+ }
62
+
63
+ function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
64
+ return (
65
+ <div
66
+ data-slot="field-group"
67
+ className={cn(
68
+ "gap-5 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4 group/field-group @container/field-group flex w-full flex-col",
69
+ className,
70
+ )}
71
+ {...props}
72
+ />
73
+ );
74
+ }
75
+
76
+ const FieldControl = FieldPrimitive.Control;
77
+ const FieldValidity = FieldPrimitive.Validity;
78
+
79
+ export {
80
+ Field,
81
+ FieldLabel,
82
+ FieldDescription,
83
+ FieldError,
84
+ FieldControl,
85
+ FieldItem,
86
+ FieldValidity,
87
+ FieldGroup,
88
+ };
@@ -0,0 +1,29 @@
1
+ "use client";
2
+
3
+ import { Fieldset as FieldsetPrimitive } from "@base-ui/react/fieldset";
4
+
5
+ import { cn } from "../../lib/utils/css";
6
+
7
+ function Fieldset({ className, ...props }: FieldsetPrimitive.Root.Props) {
8
+ return (
9
+ <FieldsetPrimitive.Root
10
+ className={cn("flex w-full max-w-64 flex-col gap-6", className)}
11
+ data-slot="fieldset"
12
+ {...props}
13
+ />
14
+ );
15
+ }
16
+ function FieldsetLegend({
17
+ className,
18
+ ...props
19
+ }: FieldsetPrimitive.Legend.Props) {
20
+ return (
21
+ <FieldsetPrimitive.Legend
22
+ className={cn("font-semibold text-foreground", className)}
23
+ data-slot="fieldset-legend"
24
+ {...props}
25
+ />
26
+ );
27
+ }
28
+
29
+ export { Fieldset, FieldsetLegend };
@@ -0,0 +1,17 @@
1
+ "use client";
2
+
3
+ import { Form as FormPrimitive } from "@base-ui/react/form";
4
+
5
+ import { cn } from "../../lib/utils/css";
6
+
7
+ function Form({ className, ...props }: FormPrimitive.Props) {
8
+ return (
9
+ <FormPrimitive
10
+ className={cn("flex w-full flex-col gap-4", className)}
11
+ data-slot="form"
12
+ {...props}
13
+ />
14
+ );
15
+ }
16
+
17
+ export { Form };
@@ -0,0 +1,82 @@
1
+ import type * as React from "react";
2
+
3
+ import { cn } from "../../lib/utils/css";
4
+
5
+ function Frame({ className, ...props }: React.ComponentProps<"div">) {
6
+ return (
7
+ <div
8
+ className={cn(
9
+ "relative flex flex-col rounded-2xl bg-muted/72 p-1",
10
+ "*:[[data-slot=frame-panel]+[data-slot=frame-panel]]:mt-1",
11
+ className,
12
+ )}
13
+ data-slot="frame"
14
+ {...props}
15
+ />
16
+ );
17
+ }
18
+
19
+ function FramePanel({ className, ...props }: React.ComponentProps<"div">) {
20
+ return (
21
+ <div
22
+ className={cn(
23
+ "relative rounded-xl border bg-background bg-clip-padding p-5 shadow-xs/5 before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-xl)-1px)] before:shadow-[0_1px_--theme(--color-black/6%)] dark:before:shadow-[0_-1px_--theme(--color-white/6%)]",
24
+ className,
25
+ )}
26
+ data-slot="frame-panel"
27
+ {...props}
28
+ />
29
+ );
30
+ }
31
+
32
+ function FrameHeader({ className, ...props }: React.ComponentProps<"header">) {
33
+ return (
34
+ <header
35
+ className={cn("flex flex-col px-5 py-4", className)}
36
+ data-slot="frame-panel-header"
37
+ {...props}
38
+ />
39
+ );
40
+ }
41
+
42
+ function FrameTitle({ className, ...props }: React.ComponentProps<"div">) {
43
+ return (
44
+ <div
45
+ className={cn("font-semibold text-sm", className)}
46
+ data-slot="frame-panel-title"
47
+ {...props}
48
+ />
49
+ );
50
+ }
51
+
52
+ function FrameDescription({
53
+ className,
54
+ ...props
55
+ }: React.ComponentProps<"div">) {
56
+ return (
57
+ <div
58
+ className={cn("text-muted-foreground text-sm", className)}
59
+ data-slot="frame-panel-description"
60
+ {...props}
61
+ />
62
+ );
63
+ }
64
+
65
+ function FrameFooter({ className, ...props }: React.ComponentProps<"footer">) {
66
+ return (
67
+ <footer
68
+ className={cn("px-5 py-4", className)}
69
+ data-slot="frame-panel-footer"
70
+ {...props}
71
+ />
72
+ );
73
+ }
74
+
75
+ export {
76
+ Frame,
77
+ FramePanel,
78
+ FrameHeader,
79
+ FrameTitle,
80
+ FrameDescription,
81
+ FrameFooter,
82
+ };