create-strayl-web-app 1.0.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 (78) hide show
  1. package/dist/index.js +59 -0
  2. package/dist/index.js.map +1 -0
  3. package/package.json +39 -0
  4. package/template/README.md +290 -0
  5. package/template/components.json +24 -0
  6. package/template/package.json +56 -0
  7. package/template/public/favicon.ico +0 -0
  8. package/template/public/google-logo.svg +6 -0
  9. package/template/public/logo-dark.ico +0 -0
  10. package/template/public/logo-dark.webp +0 -0
  11. package/template/public/logo-light.ico +0 -0
  12. package/template/public/logo-light.webp +0 -0
  13. package/template/public/manifest.json +16 -0
  14. package/template/public/robots.txt +3 -0
  15. package/template/src/components/Header.tsx +76 -0
  16. package/template/src/components/language-switcher.tsx +38 -0
  17. package/template/src/components/theme-provider.tsx +14 -0
  18. package/template/src/components/themed-logo.tsx +44 -0
  19. package/template/src/components/ui/accordion.tsx +69 -0
  20. package/template/src/components/ui/alert-dialog.tsx +169 -0
  21. package/template/src/components/ui/alert.tsx +80 -0
  22. package/template/src/components/ui/autocomplete.tsx +301 -0
  23. package/template/src/components/ui/avatar.tsx +46 -0
  24. package/template/src/components/ui/badge.tsx +60 -0
  25. package/template/src/components/ui/breadcrumb.tsx +112 -0
  26. package/template/src/components/ui/button.tsx +73 -0
  27. package/template/src/components/ui/card.tsx +244 -0
  28. package/template/src/components/ui/checkbox-group.tsx +16 -0
  29. package/template/src/components/ui/checkbox.tsx +60 -0
  30. package/template/src/components/ui/collapsible.tsx +45 -0
  31. package/template/src/components/ui/combobox.tsx +415 -0
  32. package/template/src/components/ui/command.tsx +264 -0
  33. package/template/src/components/ui/dialog.tsx +196 -0
  34. package/template/src/components/ui/empty.tsx +127 -0
  35. package/template/src/components/ui/field.tsx +74 -0
  36. package/template/src/components/ui/fieldset.tsx +29 -0
  37. package/template/src/components/ui/form.tsx +17 -0
  38. package/template/src/components/ui/frame.tsx +82 -0
  39. package/template/src/components/ui/group.tsx +97 -0
  40. package/template/src/components/ui/input-group.tsx +101 -0
  41. package/template/src/components/ui/input.tsx +66 -0
  42. package/template/src/components/ui/kbd.tsx +28 -0
  43. package/template/src/components/ui/label.tsx +28 -0
  44. package/template/src/components/ui/menu.tsx +310 -0
  45. package/template/src/components/ui/meter.tsx +67 -0
  46. package/template/src/components/ui/number-field.tsx +160 -0
  47. package/template/src/components/ui/pagination.tsx +136 -0
  48. package/template/src/components/ui/popover.tsx +104 -0
  49. package/template/src/components/ui/preview-card.tsx +55 -0
  50. package/template/src/components/ui/progress.tsx +81 -0
  51. package/template/src/components/ui/radio-group.tsx +36 -0
  52. package/template/src/components/ui/scroll-area.tsx +64 -0
  53. package/template/src/components/ui/select.tsx +180 -0
  54. package/template/src/components/ui/separator.tsx +23 -0
  55. package/template/src/components/ui/sheet.tsx +203 -0
  56. package/template/src/components/ui/sidebar.tsx +743 -0
  57. package/template/src/components/ui/skeleton.tsx +16 -0
  58. package/template/src/components/ui/slider.tsx +74 -0
  59. package/template/src/components/ui/spinner.tsx +18 -0
  60. package/template/src/components/ui/switch.tsx +27 -0
  61. package/template/src/components/ui/table.tsx +126 -0
  62. package/template/src/components/ui/tabs.tsx +87 -0
  63. package/template/src/components/ui/textarea.tsx +51 -0
  64. package/template/src/components/ui/toast.tsx +269 -0
  65. package/template/src/components/ui/toggle-group.tsx +102 -0
  66. package/template/src/components/ui/toggle.tsx +45 -0
  67. package/template/src/components/ui/toolbar.tsx +83 -0
  68. package/template/src/components/ui/tooltip.tsx +65 -0
  69. package/template/src/hooks/use-mobile.ts +21 -0
  70. package/template/src/lib/i18n.ts +70 -0
  71. package/template/src/lib/utils.ts +6 -0
  72. package/template/src/routeTree.gen.ts +68 -0
  73. package/template/src/router.tsx +17 -0
  74. package/template/src/routes/__root.tsx +62 -0
  75. package/template/src/routes/index.tsx +71 -0
  76. package/template/src/styles.css +121 -0
  77. package/template/tsconfig.json +28 -0
  78. package/template/vite.config.ts +30 -0
@@ -0,0 +1,196 @@
1
+ "use client";
2
+
3
+ import { Dialog as DialogPrimitive } from "@base-ui/react/dialog";
4
+ import { XIcon } from "lucide-react";
5
+ import { cn } from "@/lib/utils";
6
+ import { Button } from "@/components/ui/button";
7
+ import { ScrollArea } from "@/components/ui/scroll-area";
8
+
9
+ const DialogCreateHandle = DialogPrimitive.createHandle;
10
+
11
+ const Dialog = DialogPrimitive.Root;
12
+
13
+ const DialogPortal = DialogPrimitive.Portal;
14
+
15
+ function DialogTrigger(props: DialogPrimitive.Trigger.Props) {
16
+ return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
17
+ }
18
+
19
+ function DialogClose(props: DialogPrimitive.Close.Props) {
20
+ return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
21
+ }
22
+
23
+ function DialogBackdrop({
24
+ className,
25
+ ...props
26
+ }: DialogPrimitive.Backdrop.Props) {
27
+ return (
28
+ <DialogPrimitive.Backdrop
29
+ className={cn(
30
+ "fixed inset-0 z-50 bg-black/32 backdrop-blur-sm transition-all duration-200 data-ending-style:opacity-0 data-starting-style:opacity-0",
31
+ className,
32
+ )}
33
+ data-slot="dialog-backdrop"
34
+ {...props}
35
+ />
36
+ );
37
+ }
38
+
39
+ function DialogViewport({
40
+ className,
41
+ ...props
42
+ }: DialogPrimitive.Viewport.Props) {
43
+ return (
44
+ <DialogPrimitive.Viewport
45
+ className={cn(
46
+ "fixed inset-0 z-50 grid grid-rows-[1fr_auto_3fr] justify-items-center p-4",
47
+ className,
48
+ )}
49
+ data-slot="dialog-viewport"
50
+ {...props}
51
+ />
52
+ );
53
+ }
54
+
55
+ function DialogPopup({
56
+ className,
57
+ children,
58
+ showCloseButton = true,
59
+ bottomStickOnMobile = true,
60
+ ...props
61
+ }: DialogPrimitive.Popup.Props & {
62
+ showCloseButton?: boolean;
63
+ bottomStickOnMobile?: boolean;
64
+ }) {
65
+ return (
66
+ <DialogPortal>
67
+ <DialogBackdrop />
68
+ <DialogViewport
69
+ className={cn(
70
+ bottomStickOnMobile &&
71
+ "max-sm:grid-rows-[1fr_auto] max-sm:p-0 max-sm:pt-12",
72
+ )}
73
+ >
74
+ <DialogPrimitive.Popup
75
+ className={cn(
76
+ "-translate-y-[calc(1.25rem*var(--nested-dialogs))] relative row-start-2 flex max-h-full min-h-0 w-full min-w-0 max-w-lg scale-[calc(1-0.1*var(--nested-dialogs))] flex-col rounded-2xl border bg-popover not-dark:bg-clip-padding text-popover-foreground opacity-[calc(1-0.1*var(--nested-dialogs))] shadow-lg/5 transition-[scale,opacity,translate] duration-200 ease-in-out will-change-transform before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-2xl)-1px)] before:shadow-[0_1px_--theme(--color-black/6%)] data-nested:data-ending-style:translate-y-8 data-nested:data-starting-style:translate-y-8 data-nested-dialog-open:origin-top data-ending-style:scale-98 data-starting-style:scale-98 data-ending-style:opacity-0 data-starting-style:opacity-0 dark:before:shadow-[0_-1px_--theme(--color-white/6%)]",
77
+ bottomStickOnMobile &&
78
+ "max-sm:max-w-none max-sm:rounded-none max-sm:border-x-0 max-sm:border-t max-sm:border-b-0 max-sm:opacity-[calc(1-min(var(--nested-dialogs),1))] max-sm:data-ending-style:translate-y-4 max-sm:data-starting-style:translate-y-4 max-sm:before:hidden max-sm:before:rounded-none",
79
+ className,
80
+ )}
81
+ data-slot="dialog-popup"
82
+ {...props}
83
+ >
84
+ {children}
85
+ {showCloseButton && (
86
+ <DialogPrimitive.Close
87
+ aria-label="Close"
88
+ className="absolute end-2 top-2"
89
+ render={<Button size="icon" variant="ghost" />}
90
+ >
91
+ <XIcon />
92
+ </DialogPrimitive.Close>
93
+ )}
94
+ </DialogPrimitive.Popup>
95
+ </DialogViewport>
96
+ </DialogPortal>
97
+ );
98
+ }
99
+
100
+ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
101
+ return (
102
+ <div
103
+ className={cn(
104
+ "flex flex-col gap-2 p-6 in-[[data-slot=dialog-popup]:has([data-slot=dialog-panel])]:pb-3 max-sm:pb-4",
105
+ className,
106
+ )}
107
+ data-slot="dialog-header"
108
+ {...props}
109
+ />
110
+ );
111
+ }
112
+
113
+ function DialogFooter({
114
+ className,
115
+ variant = "default",
116
+ ...props
117
+ }: React.ComponentProps<"div"> & {
118
+ variant?: "default" | "bare";
119
+ }) {
120
+ return (
121
+ <div
122
+ className={cn(
123
+ "flex flex-col-reverse gap-2 px-6 sm:flex-row sm:justify-end sm:rounded-b-[calc(var(--radius-2xl)-1px)]",
124
+ variant === "default" && "border-t bg-muted/72 py-4",
125
+ variant === "bare" &&
126
+ "in-[[data-slot=dialog-popup]:has([data-slot=dialog-panel])]:pt-3 pt-4 pb-6",
127
+ className,
128
+ )}
129
+ data-slot="dialog-footer"
130
+ {...props}
131
+ />
132
+ );
133
+ }
134
+
135
+ function DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {
136
+ return (
137
+ <DialogPrimitive.Title
138
+ className={cn(
139
+ "font-heading font-semibold text-xl leading-none",
140
+ className,
141
+ )}
142
+ data-slot="dialog-title"
143
+ {...props}
144
+ />
145
+ );
146
+ }
147
+
148
+ function DialogDescription({
149
+ className,
150
+ ...props
151
+ }: DialogPrimitive.Description.Props) {
152
+ return (
153
+ <DialogPrimitive.Description
154
+ className={cn("text-muted-foreground text-sm", className)}
155
+ data-slot="dialog-description"
156
+ {...props}
157
+ />
158
+ );
159
+ }
160
+
161
+ function DialogPanel({
162
+ className,
163
+ scrollFade = true,
164
+ ...props
165
+ }: React.ComponentProps<"div"> & { scrollFade?: boolean }) {
166
+ return (
167
+ <ScrollArea scrollFade={scrollFade}>
168
+ <div
169
+ className={cn(
170
+ "p-6 in-[[data-slot=dialog-popup]:has([data-slot=dialog-header])]:pt-1 in-[[data-slot=dialog-popup]:has([data-slot=dialog-footer]:not(.border-t))]:pb-1",
171
+ className,
172
+ )}
173
+ data-slot="dialog-panel"
174
+ {...props}
175
+ />
176
+ </ScrollArea>
177
+ );
178
+ }
179
+
180
+ export {
181
+ DialogCreateHandle,
182
+ Dialog,
183
+ DialogTrigger,
184
+ DialogPortal,
185
+ DialogClose,
186
+ DialogBackdrop,
187
+ DialogBackdrop as DialogOverlay,
188
+ DialogPopup,
189
+ DialogPopup as DialogContent,
190
+ DialogHeader,
191
+ DialogFooter,
192
+ DialogTitle,
193
+ DialogDescription,
194
+ DialogPanel,
195
+ DialogViewport,
196
+ };
@@ -0,0 +1,127 @@
1
+ import { cva, type VariantProps } from "class-variance-authority";
2
+
3
+ import { cn } from "@/lib/utils";
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,74 @@
1
+ "use client";
2
+
3
+ import { Field as FieldPrimitive } from "@base-ui/react/field";
4
+
5
+ import { cn } from "@/lib/utils";
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
+ const FieldControl = FieldPrimitive.Control;
64
+ const FieldValidity = FieldPrimitive.Validity;
65
+
66
+ export {
67
+ Field,
68
+ FieldLabel,
69
+ FieldDescription,
70
+ FieldError,
71
+ FieldControl,
72
+ FieldItem,
73
+ FieldValidity,
74
+ };
@@ -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";
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";
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";
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
+ };
@@ -0,0 +1,97 @@
1
+ "use client";
2
+
3
+ import { mergeProps } from "@base-ui/react/merge-props";
4
+ import { useRender } from "@base-ui/react/use-render";
5
+ import { cva, type VariantProps } from "class-variance-authority";
6
+ import type * as React from "react";
7
+
8
+ import { cn } from "@/lib/utils";
9
+ import { Separator } from "@/components/ui/separator";
10
+
11
+ const groupVariants = cva(
12
+ "flex w-fit *:focus-visible:z-1 has-[>[data-slot=group]]:gap-2 *:has-focus-visible:z-1 dark:*:[[data-slot=button]:hover~[data-slot=separator]:not([data-slot]:hover~[data-slot=separator]~[data-slot=separator]),[data-slot][data-pressed]~[data-slot=separator]:not([data-slot][data-pressed]~[data-slot=separator]~[data-slot=separator])]:before:bg-input/64 dark:*:[[data-slot=separator]:has(~[data-slot=button]:hover):not(:has(~[data-slot=separator]~[data-slot]:hover)),[data-slot=separator]:has(~[data-slot][data-pressed]):not(:has(~[data-slot=separator]~[data-slot][data-pressed]))]:before:bg-input/64",
13
+ {
14
+ defaultVariants: {
15
+ orientation: "horizontal",
16
+ },
17
+ variants: {
18
+ orientation: {
19
+ horizontal:
20
+ "*:[[data-slot]~[data-slot]:not([data-slot=separator])]:before:-start-[0.5px] *:data-slot:not-data-[slot=separator]:has-[~[data-slot]]:before:-end-[0.5px] *:pointer-coarse:after:min-w-auto *:data-slot:has-[~[data-slot]]:rounded-e-none *:data-slot:has-[~[data-slot]]:border-e-0 *:data-slot:has-[~[data-slot]]:before:rounded-e-none *:[[data-slot]~[data-slot]]:rounded-s-none *:[[data-slot]~[data-slot]]:border-s-0 *:[[data-slot]~[data-slot]]:before:rounded-s-none",
21
+ vertical:
22
+ "*:[[data-slot]~[data-slot]:not([data-slot=separator])]:before:-top-[0.5px] *:data-slot:not-data-[slot=separator]:has-[~[data-slot]]:before:-bottom-[0.5px] flex-col *:pointer-coarse:after:min-h-auto *:data-slot:has-[~[data-slot]]:rounded-b-none *:data-slot:has-[~[data-slot]]:border-b-0 *:data-slot:not-data-[slot=separator]:has-[~[data-slot]]:before:hidden *:data-slot:has-[~[data-slot]]:before:rounded-b-none dark:*:last:before:hidden dark:*:first:before:block *:[[data-slot]~[data-slot]]:rounded-t-none *:[[data-slot]~[data-slot]]:border-t-0 *:[[data-slot]~[data-slot]]:before:rounded-t-none",
23
+ },
24
+ },
25
+ },
26
+ );
27
+
28
+ function Group({
29
+ className,
30
+ orientation,
31
+ children,
32
+ ...props
33
+ }: {
34
+ className?: string;
35
+ orientation?: VariantProps<typeof groupVariants>["orientation"];
36
+ children: React.ReactNode;
37
+ } & React.ComponentProps<"div">) {
38
+ return (
39
+ <div
40
+ className={cn(groupVariants({ orientation }), className)}
41
+ data-orientation={orientation}
42
+ data-slot="group"
43
+ role="group"
44
+ {...props}
45
+ >
46
+ {children}
47
+ </div>
48
+ );
49
+ }
50
+
51
+ function GroupText({
52
+ className,
53
+ render,
54
+ ...props
55
+ }: useRender.ComponentProps<"div">) {
56
+ const defaultProps = {
57
+ className: cn(
58
+ "relative inline-flex items-center whitespace-nowrap rounded-lg border border-input bg-muted not-dark:bg-clip-padding px-[calc(--spacing(3)-1px)] text-muted-foreground text-base sm:text-sm shadow-xs/5 outline-none transition-shadow before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-lg)-1px)] before:shadow-[0_1px_--theme(--color-black/6%)] dark:bg-input/64 dark:before:shadow-[0_-1px_--theme(--color-white/6%)] [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 [&_svg]:-mx-0.5",
59
+ className,
60
+ ),
61
+ "data-slot": "group-text",
62
+ };
63
+ return useRender({
64
+ defaultTagName: "div",
65
+ props: mergeProps(defaultProps, props),
66
+ render,
67
+ });
68
+ }
69
+
70
+ function GroupSeparator({
71
+ className,
72
+ orientation = "vertical",
73
+ ...props
74
+ }: {
75
+ className?: string;
76
+ } & React.ComponentProps<typeof Separator>) {
77
+ return (
78
+ <Separator
79
+ className={cn(
80
+ "[[data-slot=input-control]:focus-within+&,[data-slot=input-group]:focus-within+&,[data-slot=select-trigger]:focus-visible+*+&,[data-slot=number-field]:focus-within+input+&]:-translate-x-px pointer-events-none relative z-2 bg-input before:absolute before:inset-0 has-[+[data-slot=input-control]:focus-within,+[data-slot=input-group]:focus-within,+[data-slot=select-trigger]:focus-visible+*,+[data-slot=number-field]:focus-within]:translate-x-px has-[+[data-slot=input-control]:focus-within,+[data-slot=input-group]:focus-within,+[data-slot=select-trigger]:focus-visible+*,+[data-slot=number-field]:focus-within]:bg-ring dark:before:bg-input/32 [[data-slot=input-control]:focus-within+&,[data-slot=input-group]:focus-within+&,[data-slot=select-trigger]:focus-visible+*+&,[data-slot=number-field]:focus-within+&,[data-slot=number-field]:focus-within+input+&]:bg-ring",
81
+ className,
82
+ )}
83
+ orientation={orientation}
84
+ {...props}
85
+ />
86
+ );
87
+ }
88
+
89
+ export {
90
+ Group,
91
+ Group as ButtonGroup,
92
+ GroupText,
93
+ GroupText as ButtonGroupText,
94
+ GroupSeparator,
95
+ GroupSeparator as ButtonGroupSeparator,
96
+ groupVariants,
97
+ };