@theruntime/components 0.0.0 → 0.0.1
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.
- package/LICENSE +21 -0
- package/package.json +113 -4
- package/src/accordion.tsx +62 -0
- package/src/alert-dialog.tsx +177 -0
- package/src/alert.tsx +60 -0
- package/src/aspect-ratio.tsx +7 -0
- package/src/attachment.tsx +192 -0
- package/src/avatar.tsx +94 -0
- package/src/badge.tsx +46 -0
- package/src/breadcrumb.tsx +102 -0
- package/src/bubble.tsx +125 -0
- package/src/button-group.tsx +82 -0
- package/src/button.tsx +62 -0
- package/src/calendar.tsx +178 -0
- package/src/card.tsx +75 -0
- package/src/carousel.tsx +228 -0
- package/src/chart/container.tsx +72 -0
- package/src/chart/context.tsx +39 -0
- package/src/chart/index.ts +4 -0
- package/src/chart/legend.tsx +63 -0
- package/src/chart/payload.ts +31 -0
- package/src/chart/tooltip.tsx +149 -0
- package/src/checkbox.tsx +27 -0
- package/src/cn.ts +36 -0
- package/src/collapsible.tsx +19 -0
- package/src/combobox/chips.tsx +71 -0
- package/src/combobox/content.tsx +123 -0
- package/src/combobox/index.ts +13 -0
- package/src/combobox/input.tsx +39 -0
- package/src/combobox/trigger.tsx +44 -0
- package/src/command.tsx +153 -0
- package/src/context-menu.tsx +222 -0
- package/src/dialog.tsx +142 -0
- package/src/direction.tsx +18 -0
- package/src/drawer.tsx +122 -0
- package/src/dropdown-menu.tsx +226 -0
- package/src/empty.tsx +94 -0
- package/src/field.tsx +232 -0
- package/src/form.tsx +153 -0
- package/src/hover-card.tsx +36 -0
- package/src/index.ts +90 -0
- package/src/input-group.tsx +156 -0
- package/src/input-otp.tsx +68 -0
- package/src/input.tsx +21 -0
- package/src/item.tsx +172 -0
- package/src/kbd.tsx +28 -0
- package/src/label.tsx +19 -0
- package/src/marker.tsx +66 -0
- package/src/menubar.tsx +250 -0
- package/src/message-scroller.tsx +128 -0
- package/src/message.tsx +85 -0
- package/src/native-select.tsx +56 -0
- package/src/navigation-menu.tsx +161 -0
- package/src/pagination.tsx +106 -0
- package/src/popover.tsx +72 -0
- package/src/progress.tsx +26 -0
- package/src/questionnaire/actions.tsx +118 -0
- package/src/questionnaire/choices.tsx +113 -0
- package/src/questionnaire/index.ts +21 -0
- package/src/questionnaire/root.tsx +75 -0
- package/src/radio-group.tsx +43 -0
- package/src/resizable.tsx +45 -0
- package/src/scroll-area.tsx +54 -0
- package/src/select.tsx +173 -0
- package/src/separator.tsx +26 -0
- package/src/sheet.tsx +132 -0
- package/src/shell/app-tab.tsx +67 -0
- package/src/shell/entry-row.tsx +137 -0
- package/src/shell/field.tsx +83 -0
- package/src/shell/group-head.tsx +19 -0
- package/src/shell/scope-chip.tsx +32 -0
- package/src/shell/suggest-panel.tsx +92 -0
- package/src/sidebar/context.tsx +128 -0
- package/src/sidebar/index.ts +23 -0
- package/src/sidebar/menu.tsx +239 -0
- package/src/sidebar/sections.tsx +118 -0
- package/src/sidebar/sidebar.tsx +183 -0
- package/src/skeleton.tsx +13 -0
- package/src/slider.tsx +56 -0
- package/src/sonner.tsx +41 -0
- package/src/spinner.tsx +16 -0
- package/src/styles.css +149 -0
- package/src/switch.tsx +33 -0
- package/src/table.tsx +90 -0
- package/src/tabs.tsx +79 -0
- package/src/textarea.tsx +18 -0
- package/src/toggle-group.tsx +81 -0
- package/src/toggle.tsx +44 -0
- package/src/tooltip.tsx +51 -0
- package/src/use-mobile.ts +21 -0
- package/README.md +0 -3
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { CaretLeftIcon, CaretRightIcon, DotsThreeIcon } from "@phosphor-icons/react";
|
|
3
|
+
|
|
4
|
+
import { cn } from "./cn";
|
|
5
|
+
import { buttonVariants, type Button } from "./button";
|
|
6
|
+
|
|
7
|
+
function Pagination({ className, ...props }: React.ComponentProps<"nav">) {
|
|
8
|
+
return (
|
|
9
|
+
<nav
|
|
10
|
+
role="navigation"
|
|
11
|
+
aria-label="pagination"
|
|
12
|
+
data-slot="pagination"
|
|
13
|
+
className={cn("mx-auto flex w-full justify-center", className)}
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function PaginationContent({ className, ...props }: React.ComponentProps<"ul">) {
|
|
20
|
+
return (
|
|
21
|
+
<ul
|
|
22
|
+
data-slot="pagination-content"
|
|
23
|
+
className={cn("flex flex-row items-center gap-1", className)}
|
|
24
|
+
{...props}
|
|
25
|
+
/>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function PaginationItem({ ...props }: React.ComponentProps<"li">) {
|
|
30
|
+
return <li data-slot="pagination-item" {...props} />;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
type PaginationLinkProps = {
|
|
34
|
+
isActive?: boolean;
|
|
35
|
+
} & Pick<React.ComponentProps<typeof Button>, "size"> &
|
|
36
|
+
React.ComponentProps<"a">;
|
|
37
|
+
|
|
38
|
+
function PaginationLink({ className, isActive, size = "icon", ...props }: PaginationLinkProps) {
|
|
39
|
+
return (
|
|
40
|
+
<a
|
|
41
|
+
aria-current={isActive ? "page" : undefined}
|
|
42
|
+
data-slot="pagination-link"
|
|
43
|
+
data-active={isActive}
|
|
44
|
+
className={cn(
|
|
45
|
+
buttonVariants({
|
|
46
|
+
variant: isActive ? "outline" : "ghost",
|
|
47
|
+
size,
|
|
48
|
+
}),
|
|
49
|
+
className,
|
|
50
|
+
)}
|
|
51
|
+
{...props}
|
|
52
|
+
/>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function PaginationPrevious({ className, ...props }: React.ComponentProps<typeof PaginationLink>) {
|
|
57
|
+
return (
|
|
58
|
+
<PaginationLink
|
|
59
|
+
aria-label="Go to previous page"
|
|
60
|
+
size="default"
|
|
61
|
+
className={cn("gap-1 px-2.5 sm:pl-2.5", className)}
|
|
62
|
+
{...props}
|
|
63
|
+
>
|
|
64
|
+
<CaretLeftIcon />
|
|
65
|
+
<span className="hidden sm:block">Previous</span>
|
|
66
|
+
</PaginationLink>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function PaginationNext({ className, ...props }: React.ComponentProps<typeof PaginationLink>) {
|
|
71
|
+
return (
|
|
72
|
+
<PaginationLink
|
|
73
|
+
aria-label="Go to next page"
|
|
74
|
+
size="default"
|
|
75
|
+
className={cn("gap-1 px-2.5 sm:pr-2.5", className)}
|
|
76
|
+
{...props}
|
|
77
|
+
>
|
|
78
|
+
<span className="hidden sm:block">Next</span>
|
|
79
|
+
<CaretRightIcon />
|
|
80
|
+
</PaginationLink>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function PaginationEllipsis({ className, ...props }: React.ComponentProps<"span">) {
|
|
85
|
+
return (
|
|
86
|
+
<span
|
|
87
|
+
aria-hidden
|
|
88
|
+
data-slot="pagination-ellipsis"
|
|
89
|
+
className={cn("flex size-9 items-center justify-center", className)}
|
|
90
|
+
{...props}
|
|
91
|
+
>
|
|
92
|
+
<DotsThreeIcon className="size-4" />
|
|
93
|
+
<span className="sr-only">More pages</span>
|
|
94
|
+
</span>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export {
|
|
99
|
+
Pagination,
|
|
100
|
+
PaginationContent,
|
|
101
|
+
PaginationLink,
|
|
102
|
+
PaginationItem,
|
|
103
|
+
PaginationPrevious,
|
|
104
|
+
PaginationNext,
|
|
105
|
+
PaginationEllipsis,
|
|
106
|
+
};
|
package/src/popover.tsx
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Popover as PopoverPrimitive } from "radix-ui";
|
|
3
|
+
|
|
4
|
+
import { cn } from "./cn";
|
|
5
|
+
|
|
6
|
+
function Popover({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Root>) {
|
|
7
|
+
return <PopoverPrimitive.Root data-slot="popover" {...props} />;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function PopoverTrigger({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {
|
|
11
|
+
return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function PopoverContent({
|
|
15
|
+
className,
|
|
16
|
+
align = "center",
|
|
17
|
+
sideOffset = 4,
|
|
18
|
+
...props
|
|
19
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Content>) {
|
|
20
|
+
return (
|
|
21
|
+
<PopoverPrimitive.Portal>
|
|
22
|
+
<PopoverPrimitive.Content
|
|
23
|
+
data-slot="popover-content"
|
|
24
|
+
align={align}
|
|
25
|
+
sideOffset={sideOffset}
|
|
26
|
+
className={cn(
|
|
27
|
+
"z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-hidden 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-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
28
|
+
className,
|
|
29
|
+
)}
|
|
30
|
+
{...props}
|
|
31
|
+
/>
|
|
32
|
+
</PopoverPrimitive.Portal>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function PopoverAnchor({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {
|
|
37
|
+
return <PopoverPrimitive.Anchor data-slot="popover-anchor" {...props} />;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function PopoverHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
41
|
+
return (
|
|
42
|
+
<div
|
|
43
|
+
data-slot="popover-header"
|
|
44
|
+
className={cn("flex flex-col gap-1 text-sm", className)}
|
|
45
|
+
{...props}
|
|
46
|
+
/>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function PopoverTitle({ className, ...props }: React.ComponentProps<"h2">) {
|
|
51
|
+
return <div data-slot="popover-title" className={cn("font-medium", className)} {...props} />;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function PopoverDescription({ className, ...props }: React.ComponentProps<"p">) {
|
|
55
|
+
return (
|
|
56
|
+
<p
|
|
57
|
+
data-slot="popover-description"
|
|
58
|
+
className={cn("text-muted-foreground", className)}
|
|
59
|
+
{...props}
|
|
60
|
+
/>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export {
|
|
65
|
+
Popover,
|
|
66
|
+
PopoverTrigger,
|
|
67
|
+
PopoverContent,
|
|
68
|
+
PopoverAnchor,
|
|
69
|
+
PopoverHeader,
|
|
70
|
+
PopoverTitle,
|
|
71
|
+
PopoverDescription,
|
|
72
|
+
};
|
package/src/progress.tsx
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Progress as ProgressPrimitive } from "radix-ui";
|
|
3
|
+
|
|
4
|
+
import { cn } from "./cn";
|
|
5
|
+
|
|
6
|
+
function Progress({
|
|
7
|
+
className,
|
|
8
|
+
value,
|
|
9
|
+
...props
|
|
10
|
+
}: React.ComponentProps<typeof ProgressPrimitive.Root>) {
|
|
11
|
+
return (
|
|
12
|
+
<ProgressPrimitive.Root
|
|
13
|
+
data-slot="progress"
|
|
14
|
+
className={cn("relative h-2 w-full overflow-hidden rounded-full bg-primary/20", className)}
|
|
15
|
+
{...props}
|
|
16
|
+
>
|
|
17
|
+
<ProgressPrimitive.Indicator
|
|
18
|
+
data-slot="progress-indicator"
|
|
19
|
+
className="h-full w-full flex-1 bg-primary transition-all"
|
|
20
|
+
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
|
|
21
|
+
/>
|
|
22
|
+
</ProgressPrimitive.Root>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { Progress };
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Questionnaire as QuestionnairePrimitive } from "@shadcn/react/questionnaire";
|
|
3
|
+
|
|
4
|
+
import { cn } from "../cn";
|
|
5
|
+
import { buttonVariants, type Button } from "../button";
|
|
6
|
+
|
|
7
|
+
export function QuestionnaireActions({ className, ...props }: React.ComponentProps<"div">) {
|
|
8
|
+
return (
|
|
9
|
+
<div
|
|
10
|
+
data-slot="questionnaire-actions"
|
|
11
|
+
className={cn(
|
|
12
|
+
"grid min-h-11 w-full grid-cols-[minmax(0,1fr)_auto_auto] items-center gap-2 sm:min-h-8",
|
|
13
|
+
className,
|
|
14
|
+
)}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function QuestionnairePrevious({
|
|
21
|
+
children,
|
|
22
|
+
className,
|
|
23
|
+
size = "default",
|
|
24
|
+
variant = "outline",
|
|
25
|
+
...props
|
|
26
|
+
}: React.ComponentProps<typeof QuestionnairePrimitive.Previous> &
|
|
27
|
+
Pick<React.ComponentProps<typeof Button>, "size" | "variant">) {
|
|
28
|
+
return (
|
|
29
|
+
<QuestionnairePrimitive.Previous
|
|
30
|
+
data-slot="questionnaire-previous"
|
|
31
|
+
data-size={size}
|
|
32
|
+
data-variant={variant}
|
|
33
|
+
className={cn(
|
|
34
|
+
buttonVariants({ size, variant }),
|
|
35
|
+
"col-start-1 row-start-1 min-h-11 justify-self-start sm:min-h-0",
|
|
36
|
+
className,
|
|
37
|
+
)}
|
|
38
|
+
{...props}
|
|
39
|
+
>
|
|
40
|
+
{children ?? "Previous"}
|
|
41
|
+
</QuestionnairePrimitive.Previous>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function QuestionnaireSkip({
|
|
46
|
+
children,
|
|
47
|
+
className,
|
|
48
|
+
size = "default",
|
|
49
|
+
variant = "outline",
|
|
50
|
+
...props
|
|
51
|
+
}: React.ComponentProps<typeof QuestionnairePrimitive.Skip> &
|
|
52
|
+
Pick<React.ComponentProps<typeof Button>, "size" | "variant">) {
|
|
53
|
+
return (
|
|
54
|
+
<QuestionnairePrimitive.Skip
|
|
55
|
+
data-slot="questionnaire-skip"
|
|
56
|
+
data-size={size}
|
|
57
|
+
data-variant={variant}
|
|
58
|
+
className={cn(
|
|
59
|
+
buttonVariants({ size, variant }),
|
|
60
|
+
"col-start-2 row-start-1 min-h-11 justify-self-end sm:min-h-0",
|
|
61
|
+
className,
|
|
62
|
+
)}
|
|
63
|
+
{...props}
|
|
64
|
+
>
|
|
65
|
+
{children ?? "Skip"}
|
|
66
|
+
</QuestionnairePrimitive.Skip>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function QuestionnaireNext({
|
|
71
|
+
children,
|
|
72
|
+
className,
|
|
73
|
+
size = "default",
|
|
74
|
+
variant = "default",
|
|
75
|
+
...props
|
|
76
|
+
}: React.ComponentProps<typeof QuestionnairePrimitive.Next> &
|
|
77
|
+
Pick<React.ComponentProps<typeof Button>, "size" | "variant">) {
|
|
78
|
+
return (
|
|
79
|
+
<QuestionnairePrimitive.Next
|
|
80
|
+
data-slot="questionnaire-next"
|
|
81
|
+
data-size={size}
|
|
82
|
+
data-variant={variant}
|
|
83
|
+
className={cn(
|
|
84
|
+
buttonVariants({ size, variant }),
|
|
85
|
+
"col-start-3 row-start-1 min-h-11 justify-self-end sm:min-h-0",
|
|
86
|
+
className,
|
|
87
|
+
)}
|
|
88
|
+
{...props}
|
|
89
|
+
>
|
|
90
|
+
{children ?? "Next"}
|
|
91
|
+
</QuestionnairePrimitive.Next>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function QuestionnaireSubmit({
|
|
96
|
+
children,
|
|
97
|
+
className,
|
|
98
|
+
size = "default",
|
|
99
|
+
variant = "default",
|
|
100
|
+
...props
|
|
101
|
+
}: React.ComponentProps<typeof QuestionnairePrimitive.Submit> &
|
|
102
|
+
Pick<React.ComponentProps<typeof Button>, "size" | "variant">) {
|
|
103
|
+
return (
|
|
104
|
+
<QuestionnairePrimitive.Submit
|
|
105
|
+
data-slot="questionnaire-submit"
|
|
106
|
+
data-size={size}
|
|
107
|
+
data-variant={variant}
|
|
108
|
+
className={cn(
|
|
109
|
+
buttonVariants({ size, variant }),
|
|
110
|
+
"col-start-3 row-start-1 min-h-11 justify-self-end sm:min-h-0",
|
|
111
|
+
className,
|
|
112
|
+
)}
|
|
113
|
+
{...props}
|
|
114
|
+
>
|
|
115
|
+
{children ?? "Submit"}
|
|
116
|
+
</QuestionnairePrimitive.Submit>
|
|
117
|
+
);
|
|
118
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Questionnaire as QuestionnairePrimitive } from "@shadcn/react/questionnaire";
|
|
3
|
+
import { CheckIcon } from "@phosphor-icons/react";
|
|
4
|
+
|
|
5
|
+
import { cn } from "../cn";
|
|
6
|
+
|
|
7
|
+
export function QuestionnaireChoices({
|
|
8
|
+
className,
|
|
9
|
+
...props
|
|
10
|
+
}: React.ComponentProps<typeof QuestionnairePrimitive.Choices>) {
|
|
11
|
+
return (
|
|
12
|
+
<QuestionnairePrimitive.Choices
|
|
13
|
+
data-slot="questionnaire-choices"
|
|
14
|
+
className={cn("group/questionnaire-choices grid min-w-0 gap-2", className)}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function QuestionnaireChoice({
|
|
21
|
+
children,
|
|
22
|
+
className,
|
|
23
|
+
...props
|
|
24
|
+
}: React.ComponentProps<typeof QuestionnairePrimitive.Choice>) {
|
|
25
|
+
return (
|
|
26
|
+
<QuestionnairePrimitive.Choice
|
|
27
|
+
data-slot="questionnaire-choice"
|
|
28
|
+
className={cn(
|
|
29
|
+
"group/questionnaire-choice relative flex min-h-11 cursor-pointer items-start gap-2.5 rounded-lg border border-input bg-transparent px-3 py-2.5 text-start text-sm transition-colors outline-none select-none hover:bg-muted/50 has-[>input:focus-visible]:border-ring has-[>input:focus-visible]:ring-3 has-[>input:focus-visible]:ring-ring/50 data-invalid:border-destructive dark:bg-input/20 data-checked:border-primary/40 data-checked:bg-muted dark:data-checked:bg-muted",
|
|
30
|
+
"data-disabled:pointer-events-none data-disabled:cursor-not-allowed data-disabled:opacity-50",
|
|
31
|
+
className,
|
|
32
|
+
)}
|
|
33
|
+
{...props}
|
|
34
|
+
>
|
|
35
|
+
<QuestionnairePrimitive.ChoiceInput
|
|
36
|
+
data-slot="questionnaire-choice-input"
|
|
37
|
+
className="absolute inset-0 z-10 size-full cursor-pointer opacity-0"
|
|
38
|
+
/>
|
|
39
|
+
<span
|
|
40
|
+
aria-hidden="true"
|
|
41
|
+
data-slot="questionnaire-choice-indicator"
|
|
42
|
+
className="pointer-events-none relative flex size-4 shrink-0 translate-y-[--spacing(0.45)] items-center justify-center rounded-[4px] border border-input group-has-data-[slot=questionnaire-choice-description]/questionnaire-choice:translate-y-0.5 group-data-[type=radio]/questionnaire-choice:rounded-full group-data-checked/questionnaire-choice:border-primary group-data-checked/questionnaire-choice:bg-primary group-data-checked/questionnaire-choice:text-primary-foreground dark:bg-input/30 dark:group-data-checked/questionnaire-choice:bg-primary"
|
|
43
|
+
>
|
|
44
|
+
<span
|
|
45
|
+
data-slot="questionnaire-choice-indicator-dot"
|
|
46
|
+
className="hidden size-2 rounded-full bg-primary-foreground group-data-[type=checkbox]/questionnaire-choice:hidden group-data-checked/questionnaire-choice:block"
|
|
47
|
+
/>
|
|
48
|
+
<CheckIcon
|
|
49
|
+
data-slot="questionnaire-choice-indicator-check"
|
|
50
|
+
className="hidden size-3.5 group-data-[type=radio]/questionnaire-choice:hidden group-data-checked/questionnaire-choice:block"
|
|
51
|
+
/>
|
|
52
|
+
</span>
|
|
53
|
+
<QuestionnairePrimitive.ChoiceLabel
|
|
54
|
+
data-slot="questionnaire-choice-label"
|
|
55
|
+
className="flex min-w-0 flex-1 flex-col gap-0.5 leading-snug"
|
|
56
|
+
>
|
|
57
|
+
{children}
|
|
58
|
+
</QuestionnairePrimitive.ChoiceLabel>
|
|
59
|
+
<QuestionnairePrimitive.ChoiceShortcut
|
|
60
|
+
data-slot="questionnaire-choice-shortcut"
|
|
61
|
+
className="pointer-events-none ms-auto hidden size-5 shrink-0 translate-y-[--spacing(0.45)] items-center justify-center rounded-md border border-input bg-background font-mono text-[0.625rem] leading-none font-medium text-muted-foreground group-has-data-[slot=questionnaire-choice-description]/questionnaire-choice:translate-y-0.5 group-data-[shortcut]/questionnaire-choice:inline-flex"
|
|
62
|
+
/>
|
|
63
|
+
</QuestionnairePrimitive.Choice>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function QuestionnaireChoiceDescription({
|
|
68
|
+
className,
|
|
69
|
+
...props
|
|
70
|
+
}: React.ComponentProps<"span">) {
|
|
71
|
+
return (
|
|
72
|
+
<span
|
|
73
|
+
data-slot="questionnaire-choice-description"
|
|
74
|
+
className={cn("text-muted-foreground", className)}
|
|
75
|
+
{...props}
|
|
76
|
+
/>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function QuestionnaireInput({
|
|
81
|
+
className,
|
|
82
|
+
...props
|
|
83
|
+
}: React.ComponentProps<typeof QuestionnairePrimitive.Input>) {
|
|
84
|
+
return (
|
|
85
|
+
<div
|
|
86
|
+
data-slot="questionnaire-input-wrapper"
|
|
87
|
+
className="group/questionnaire-input relative w-full min-w-0"
|
|
88
|
+
>
|
|
89
|
+
<QuestionnairePrimitive.Input
|
|
90
|
+
data-slot="questionnaire-input"
|
|
91
|
+
className={cn(
|
|
92
|
+
"h-8 min-h-11 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-[color,box-shadow,background-color] outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 sm:min-h-0 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
|
|
93
|
+
"selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground",
|
|
94
|
+
className,
|
|
95
|
+
)}
|
|
96
|
+
{...props}
|
|
97
|
+
/>
|
|
98
|
+
</div>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function QuestionnaireError({
|
|
103
|
+
className,
|
|
104
|
+
...props
|
|
105
|
+
}: React.ComponentProps<typeof QuestionnairePrimitive.Error>) {
|
|
106
|
+
return (
|
|
107
|
+
<QuestionnairePrimitive.Error
|
|
108
|
+
data-slot="questionnaire-error"
|
|
109
|
+
className={cn("mt-2 text-sm text-destructive", className)}
|
|
110
|
+
{...props}
|
|
111
|
+
/>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export {
|
|
2
|
+
Questionnaire,
|
|
3
|
+
QuestionnaireDescription,
|
|
4
|
+
QuestionnaireItem,
|
|
5
|
+
QuestionnaireProgress,
|
|
6
|
+
QuestionnaireTitle,
|
|
7
|
+
} from "./root";
|
|
8
|
+
export {
|
|
9
|
+
QuestionnaireChoice,
|
|
10
|
+
QuestionnaireChoiceDescription,
|
|
11
|
+
QuestionnaireChoices,
|
|
12
|
+
QuestionnaireError,
|
|
13
|
+
QuestionnaireInput,
|
|
14
|
+
} from "./choices";
|
|
15
|
+
export {
|
|
16
|
+
QuestionnaireActions,
|
|
17
|
+
QuestionnaireNext,
|
|
18
|
+
QuestionnairePrevious,
|
|
19
|
+
QuestionnaireSkip,
|
|
20
|
+
QuestionnaireSubmit,
|
|
21
|
+
} from "./actions";
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Questionnaire as QuestionnairePrimitive } from "@shadcn/react/questionnaire";
|
|
3
|
+
|
|
4
|
+
import { cn } from "../cn";
|
|
5
|
+
|
|
6
|
+
export function Questionnaire({
|
|
7
|
+
className,
|
|
8
|
+
...props
|
|
9
|
+
}: React.ComponentProps<typeof QuestionnairePrimitive.Root>) {
|
|
10
|
+
return (
|
|
11
|
+
<QuestionnairePrimitive.Root
|
|
12
|
+
data-slot="questionnaire"
|
|
13
|
+
className={cn("flex w-full min-w-0 flex-col gap-4", className)}
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function QuestionnaireProgress({
|
|
20
|
+
className,
|
|
21
|
+
...props
|
|
22
|
+
}: React.ComponentProps<typeof QuestionnairePrimitive.Progress>) {
|
|
23
|
+
return (
|
|
24
|
+
<QuestionnairePrimitive.Progress
|
|
25
|
+
data-slot="questionnaire-progress"
|
|
26
|
+
className={cn(
|
|
27
|
+
"min-h-[1lh] w-fit min-w-[14ch] text-xs font-medium text-muted-foreground tabular-nums",
|
|
28
|
+
className,
|
|
29
|
+
)}
|
|
30
|
+
{...props}
|
|
31
|
+
/>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function QuestionnaireItem({
|
|
36
|
+
className,
|
|
37
|
+
...props
|
|
38
|
+
}: React.ComponentProps<typeof QuestionnairePrimitive.Item>) {
|
|
39
|
+
return (
|
|
40
|
+
<QuestionnairePrimitive.Item
|
|
41
|
+
data-slot="questionnaire-item"
|
|
42
|
+
className={cn("flex min-w-0 flex-col gap-4 border-0 p-0 outline-none", className)}
|
|
43
|
+
{...props}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function QuestionnaireTitle({
|
|
49
|
+
className,
|
|
50
|
+
...props
|
|
51
|
+
}: React.ComponentProps<typeof QuestionnairePrimitive.Title>) {
|
|
52
|
+
return (
|
|
53
|
+
<QuestionnairePrimitive.Title
|
|
54
|
+
data-slot="questionnaire-title"
|
|
55
|
+
className={cn(
|
|
56
|
+
"cn-font-heading text-base leading-snug font-medium text-pretty [&:not(:has(~[data-slot=questionnaire-description]))]:mb-4",
|
|
57
|
+
className,
|
|
58
|
+
)}
|
|
59
|
+
{...props}
|
|
60
|
+
/>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function QuestionnaireDescription({
|
|
65
|
+
className,
|
|
66
|
+
...props
|
|
67
|
+
}: React.ComponentProps<typeof QuestionnairePrimitive.Description>) {
|
|
68
|
+
return (
|
|
69
|
+
<QuestionnairePrimitive.Description
|
|
70
|
+
data-slot="questionnaire-description"
|
|
71
|
+
className={cn("text-sm text-pretty text-muted-foreground", className)}
|
|
72
|
+
{...props}
|
|
73
|
+
/>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { CircleIcon } from "@phosphor-icons/react";
|
|
3
|
+
import { RadioGroup as RadioGroupPrimitive } from "radix-ui";
|
|
4
|
+
|
|
5
|
+
import { cn } from "./cn";
|
|
6
|
+
|
|
7
|
+
function RadioGroup({
|
|
8
|
+
className,
|
|
9
|
+
...props
|
|
10
|
+
}: React.ComponentProps<typeof RadioGroupPrimitive.Root>) {
|
|
11
|
+
return (
|
|
12
|
+
<RadioGroupPrimitive.Root
|
|
13
|
+
data-slot="radio-group"
|
|
14
|
+
className={cn("grid gap-3", className)}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function RadioGroupItem({
|
|
21
|
+
className,
|
|
22
|
+
...props
|
|
23
|
+
}: React.ComponentProps<typeof RadioGroupPrimitive.Item>) {
|
|
24
|
+
return (
|
|
25
|
+
<RadioGroupPrimitive.Item
|
|
26
|
+
data-slot="radio-group-item"
|
|
27
|
+
className={cn(
|
|
28
|
+
"aspect-square size-4 shrink-0 rounded-full border border-input text-primary shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:bg-input/30 dark:aria-invalid:ring-destructive/40",
|
|
29
|
+
className,
|
|
30
|
+
)}
|
|
31
|
+
{...props}
|
|
32
|
+
>
|
|
33
|
+
<RadioGroupPrimitive.Indicator
|
|
34
|
+
data-slot="radio-group-indicator"
|
|
35
|
+
className="relative flex items-center justify-center"
|
|
36
|
+
>
|
|
37
|
+
<CircleIcon className="absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 fill-primary" />
|
|
38
|
+
</RadioGroupPrimitive.Indicator>
|
|
39
|
+
</RadioGroupPrimitive.Item>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { RadioGroup, RadioGroupItem };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { DotsSixVerticalIcon } from "@phosphor-icons/react";
|
|
2
|
+
import * as ResizablePrimitive from "react-resizable-panels";
|
|
3
|
+
|
|
4
|
+
import { cn } from "./cn";
|
|
5
|
+
|
|
6
|
+
function ResizablePanelGroup({ className, ...props }: ResizablePrimitive.GroupProps) {
|
|
7
|
+
return (
|
|
8
|
+
<ResizablePrimitive.Group
|
|
9
|
+
data-slot="resizable-panel-group"
|
|
10
|
+
className={cn("flex h-full w-full aria-[orientation=vertical]:flex-col", className)}
|
|
11
|
+
{...props}
|
|
12
|
+
/>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function ResizablePanel({ ...props }: ResizablePrimitive.PanelProps) {
|
|
17
|
+
return <ResizablePrimitive.Panel data-slot="resizable-panel" {...props} />;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function ResizableHandle({
|
|
21
|
+
withHandle,
|
|
22
|
+
className,
|
|
23
|
+
...props
|
|
24
|
+
}: ResizablePrimitive.SeparatorProps & {
|
|
25
|
+
withHandle?: boolean;
|
|
26
|
+
}) {
|
|
27
|
+
return (
|
|
28
|
+
<ResizablePrimitive.Separator
|
|
29
|
+
data-slot="resizable-handle"
|
|
30
|
+
className={cn(
|
|
31
|
+
"relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-hidden aria-[orientation=horizontal]:h-px aria-[orientation=horizontal]:w-full aria-[orientation=horizontal]:after:left-0 aria-[orientation=horizontal]:after:h-1 aria-[orientation=horizontal]:after:w-full aria-[orientation=horizontal]:after:translate-x-0 aria-[orientation=horizontal]:after:-translate-y-1/2 [&[aria-orientation=horizontal]>div]:rotate-90",
|
|
32
|
+
className,
|
|
33
|
+
)}
|
|
34
|
+
{...props}
|
|
35
|
+
>
|
|
36
|
+
{withHandle && (
|
|
37
|
+
<div className="z-10 flex h-4 w-3 items-center justify-center rounded-xs border bg-border">
|
|
38
|
+
<DotsSixVerticalIcon className="size-2.5" />
|
|
39
|
+
</div>
|
|
40
|
+
)}
|
|
41
|
+
</ResizablePrimitive.Separator>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { ResizableHandle, ResizablePanel, ResizablePanelGroup };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { ScrollArea as ScrollAreaPrimitive } from "radix-ui";
|
|
3
|
+
|
|
4
|
+
import { cn } from "./cn";
|
|
5
|
+
|
|
6
|
+
function ScrollArea({
|
|
7
|
+
className,
|
|
8
|
+
children,
|
|
9
|
+
...props
|
|
10
|
+
}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
|
|
11
|
+
return (
|
|
12
|
+
<ScrollAreaPrimitive.Root
|
|
13
|
+
data-slot="scroll-area"
|
|
14
|
+
className={cn("relative", className)}
|
|
15
|
+
{...props}
|
|
16
|
+
>
|
|
17
|
+
<ScrollAreaPrimitive.Viewport
|
|
18
|
+
data-slot="scroll-area-viewport"
|
|
19
|
+
className="size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1"
|
|
20
|
+
>
|
|
21
|
+
{children}
|
|
22
|
+
</ScrollAreaPrimitive.Viewport>
|
|
23
|
+
<ScrollBar />
|
|
24
|
+
<ScrollAreaPrimitive.Corner />
|
|
25
|
+
</ScrollAreaPrimitive.Root>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function ScrollBar({
|
|
30
|
+
className,
|
|
31
|
+
orientation = "vertical",
|
|
32
|
+
...props
|
|
33
|
+
}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
|
|
34
|
+
return (
|
|
35
|
+
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
|
36
|
+
data-slot="scroll-area-scrollbar"
|
|
37
|
+
orientation={orientation}
|
|
38
|
+
className={cn(
|
|
39
|
+
"flex touch-none p-px transition-colors select-none",
|
|
40
|
+
orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent",
|
|
41
|
+
orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent",
|
|
42
|
+
className,
|
|
43
|
+
)}
|
|
44
|
+
{...props}
|
|
45
|
+
>
|
|
46
|
+
<ScrollAreaPrimitive.ScrollAreaThumb
|
|
47
|
+
data-slot="scroll-area-thumb"
|
|
48
|
+
className="relative flex-1 rounded-full bg-border"
|
|
49
|
+
/>
|
|
50
|
+
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { ScrollArea, ScrollBar };
|