@suphark/ui 0.19.0 → 0.20.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 (72) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/package.json +14 -13
  3. package/scripts/audit.mjs +0 -0
  4. package/src/components/app-shell/app-shell.tsx +12 -0
  5. package/src/components/app-shell/index.ts +1 -0
  6. package/src/components/app-shell/mobile-tab-bar.tsx +104 -0
  7. package/src/components/shared/action-menu.tsx +155 -0
  8. package/src/components/shared/filter-bar.tsx +108 -0
  9. package/src/components/shared/month-stepper.tsx +124 -0
  10. package/src/components/shared/segmented-control.tsx +73 -0
  11. package/src/components/shared/settings-layout.tsx +170 -0
  12. package/src/components/shared/setup-checklist.tsx +104 -0
  13. package/src/components/shared/simple-dialog.tsx +172 -0
  14. package/src/components/shared/simple-pagination.tsx +109 -0
  15. package/src/components/shared/simple-table.tsx +93 -0
  16. package/src/components/shared/simple-tabs.tsx +118 -0
  17. package/src/components/shared/simple-tooltip.tsx +87 -0
  18. package/src/components/shared/ui-text.tsx +28 -0
  19. package/src/components/ui/accordion.tsx +2 -2
  20. package/src/components/ui/alert-dialog.tsx +4 -4
  21. package/src/components/ui/alert.tsx +2 -2
  22. package/src/components/ui/attachment.tsx +9 -9
  23. package/src/components/ui/avatar.tsx +4 -4
  24. package/src/components/ui/badge.tsx +1 -1
  25. package/src/components/ui/breadcrumb.tsx +1 -1
  26. package/src/components/ui/bubble.tsx +123 -0
  27. package/src/components/ui/button-group.tsx +2 -2
  28. package/src/components/ui/button.tsx +6 -6
  29. package/src/components/ui/calendar.tsx +9 -9
  30. package/src/components/ui/card.tsx +3 -3
  31. package/src/components/ui/chart.tsx +2 -2
  32. package/src/components/ui/checkbox.tsx +1 -1
  33. package/src/components/ui/combobox.tsx +6 -6
  34. package/src/components/ui/command.tsx +4 -4
  35. package/src/components/ui/context-menu.tsx +7 -7
  36. package/src/components/ui/dialog.tsx +4 -4
  37. package/src/components/ui/direction.tsx +6 -0
  38. package/src/components/ui/drawer.tsx +10 -10
  39. package/src/components/ui/dropdown-menu.tsx +8 -8
  40. package/src/components/ui/empty.tsx +4 -4
  41. package/src/components/ui/field.tsx +8 -8
  42. package/src/components/ui/hover-card.tsx +1 -2
  43. package/src/components/ui/input-group.tsx +3 -3
  44. package/src/components/ui/input-otp.tsx +1 -1
  45. package/src/components/ui/input.tsx +1 -1
  46. package/src/components/ui/item.tsx +4 -4
  47. package/src/components/ui/kbd.tsx +1 -1
  48. package/src/components/ui/label.tsx +1 -1
  49. package/src/components/ui/marker.tsx +67 -0
  50. package/src/components/ui/menubar.tsx +9 -9
  51. package/src/components/ui/message-scroller.tsx +129 -0
  52. package/src/components/ui/message.tsx +84 -0
  53. package/src/components/ui/native-select.tsx +1 -1
  54. package/src/components/ui/navigation-menu.tsx +6 -6
  55. package/src/components/ui/popover.tsx +1 -1
  56. package/src/components/ui/progress.tsx +2 -3
  57. package/src/components/ui/questionnaire.tsx +314 -0
  58. package/src/components/ui/radio-group.tsx +1 -2
  59. package/src/components/ui/resizable.tsx +1 -1
  60. package/src/components/ui/select.tsx +4 -4
  61. package/src/components/ui/separator.tsx +0 -1
  62. package/src/components/ui/sheet.tsx +3 -3
  63. package/src/components/ui/sidebar.tsx +14 -14
  64. package/src/components/ui/switch.tsx +2 -3
  65. package/src/components/ui/textarea.tsx +1 -1
  66. package/src/components/ui/toast.tsx +221 -0
  67. package/src/components/ui/toggle-group.tsx +2 -2
  68. package/src/components/ui/toggle.tsx +1 -1
  69. package/src/components/ui/tooltip.tsx +0 -1
  70. package/src/index.ts +41 -0
  71. package/src/lib/month.ts +60 -0
  72. package/src/styles.css +10 -0
@@ -0,0 +1,84 @@
1
+ import { cn } from "@suphark/ui/lib/utils";
2
+ import type * as React from "react";
3
+
4
+ function MessageGroup({ className, ...props }: React.ComponentProps<"div">) {
5
+ return (
6
+ <div
7
+ data-slot="message-group"
8
+ className={cn("flex min-w-0 flex-col gap-2", className)}
9
+ {...props}
10
+ />
11
+ );
12
+ }
13
+
14
+ function Message({
15
+ className,
16
+ align = "start",
17
+ ...props
18
+ }: React.ComponentProps<"div"> & { align?: "start" | "end" }) {
19
+ return (
20
+ <div
21
+ data-slot="message"
22
+ data-align={align}
23
+ className={cn(
24
+ "group/message relative flex w-full min-w-0 gap-2 text-sm data-[align=end]:flex-row-reverse",
25
+ className,
26
+ )}
27
+ {...props}
28
+ />
29
+ );
30
+ }
31
+
32
+ function MessageAvatar({ className, ...props }: React.ComponentProps<"div">) {
33
+ return (
34
+ <div
35
+ data-slot="message-avatar"
36
+ className={cn(
37
+ "flex w-fit min-w-8 shrink-0 items-center justify-center self-end overflow-hidden rounded-full bg-muted group-has-data-[slot=message-footer]/message:-translate-y-8",
38
+ className,
39
+ )}
40
+ {...props}
41
+ />
42
+ );
43
+ }
44
+
45
+ function MessageContent({ className, ...props }: React.ComponentProps<"div">) {
46
+ return (
47
+ <div
48
+ data-slot="message-content"
49
+ className={cn(
50
+ "flex w-full min-w-0 flex-col gap-2.5 wrap-break-word group-data-[align=end]/message:*:data-slot:self-end",
51
+ className,
52
+ )}
53
+ {...props}
54
+ />
55
+ );
56
+ }
57
+
58
+ function MessageHeader({ className, ...props }: React.ComponentProps<"div">) {
59
+ return (
60
+ <div
61
+ data-slot="message-header"
62
+ className={cn(
63
+ "flex max-w-full min-w-0 items-center px-3 text-xs font-medium text-muted-foreground group-has-data-[variant=ghost]/message:px-0",
64
+ className,
65
+ )}
66
+ {...props}
67
+ />
68
+ );
69
+ }
70
+
71
+ function MessageFooter({ className, ...props }: React.ComponentProps<"div">) {
72
+ return (
73
+ <div
74
+ data-slot="message-footer"
75
+ className={cn(
76
+ "flex max-w-full min-w-0 items-center px-3 text-xs font-medium text-muted-foreground group-has-data-[variant=ghost]/message:px-0 group-data-[align=end]/message:justify-end",
77
+ className,
78
+ )}
79
+ {...props}
80
+ />
81
+ );
82
+ }
83
+
84
+ export { Message, MessageAvatar, MessageContent, MessageFooter, MessageGroup, MessageHeader };
@@ -1,4 +1,4 @@
1
- import { cn } from "cn";
1
+ import { cn } from "@suphark/ui/lib/utils";
2
2
  import { ChevronDownIcon } from "lucide-react";
3
3
  import type * as React from "react";
4
4
 
@@ -51,7 +51,7 @@ function NavigationMenuItem({
51
51
  }
52
52
 
53
53
  const navigationMenuTriggerStyle = cva(
54
- "group/navigation-menu-trigger inline-flex h-9 w-max items-center justify-center rounded-lg px-2.5 py-1.5 font-medium text-sm outline-none transition-all hover:bg-muted focus:bg-muted focus-visible:outline-1 focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 data-open:bg-muted/50 data-popup-open:bg-muted/50 data-open:focus:bg-muted data-open:hover:bg-muted data-popup-open:hover:bg-muted",
54
+ "group/navigation-menu-trigger inline-flex h-9 w-max items-center justify-center rounded-lg px-2.5 py-1.5 text-sm font-medium transition-all outline-none hover:bg-muted focus:bg-muted focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-popup-open:bg-muted/50 data-popup-open:hover:bg-muted data-open:bg-muted/50 data-open:hover:bg-muted data-open:focus:bg-muted",
55
55
  );
56
56
 
57
57
  function NavigationMenuTrigger({
@@ -67,7 +67,7 @@ function NavigationMenuTrigger({
67
67
  >
68
68
  {children}{" "}
69
69
  <ChevronDownIcon
70
- className="relative top-px ml-1 size-3 transition duration-300 group-data-open/navigation-menu-trigger:rotate-180 group-data-popup-open/navigation-menu-trigger:rotate-180"
70
+ className="relative top-px ml-1 size-3 transition duration-300 group-data-popup-open/navigation-menu-trigger:rotate-180 group-data-open/navigation-menu-trigger:rotate-180"
71
71
  aria-hidden="true"
72
72
  />
73
73
  </NavigationMenuPrimitive.Trigger>
@@ -79,7 +79,7 @@ function NavigationMenuContent({ className, ...props }: NavigationMenuPrimitive.
79
79
  <NavigationMenuPrimitive.Content
80
80
  data-slot="navigation-menu-content"
81
81
  className={cn(
82
- "data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out group-data-[viewport=false]/navigation-menu:data-open:fade-in-0 group-data-[viewport=false]/navigation-menu:data-open:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-closed:fade-out-0 group-data-[viewport=false]/navigation-menu:data-closed:zoom-out-95 h-full w-auto p-1 transition-[opacity,transform,translate] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)] data-ending-style:data-activation-direction=left:translate-x-[50%] data-ending-style:data-activation-direction=right:translate-x-[-50%] data-starting-style:data-activation-direction=left:translate-x-[-50%] data-starting-style:data-activation-direction=right:translate-x-[50%] data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-ending-style:opacity-0 data-starting-style:opacity-0 **:data-[slot=navigation-menu-link]:focus:outline-none **:data-[slot=navigation-menu-link]:focus:ring-0 group-data-[viewport=false]/navigation-menu:rounded-lg group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:ring-1 group-data-[viewport=false]/navigation-menu:ring-foreground/10 group-data-[viewport=false]/navigation-menu:duration-300 group-data-[viewport=false]/navigation-menu:data-closed:animate-out group-data-[viewport=false]/navigation-menu:data-open:animate-in",
82
+ "data-ending-style:data-activation-direction=left:translate-x-[50%] data-ending-style:data-activation-direction=right:translate-x-[-50%] data-starting-style:data-activation-direction=left:translate-x-[-50%] data-starting-style:data-activation-direction=right:translate-x-[50%] h-full w-auto p-1 transition-[opacity,transform,translate] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)] group-data-[viewport=false]/navigation-menu:rounded-lg group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:ring-1 group-data-[viewport=false]/navigation-menu:ring-foreground/10 group-data-[viewport=false]/navigation-menu:duration-300 data-ending-style:opacity-0 data-starting-style:opacity-0 data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 data-[motion^=from-]:animate-in data-[motion^=from-]:fade-in data-[motion^=to-]:animate-out data-[motion^=to-]:fade-out **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none group-data-[viewport=false]/navigation-menu:data-open:animate-in group-data-[viewport=false]/navigation-menu:data-open:fade-in-0 group-data-[viewport=false]/navigation-menu:data-open:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-closed:animate-out group-data-[viewport=false]/navigation-menu:data-closed:fade-out-0 group-data-[viewport=false]/navigation-menu:data-closed:zoom-out-95",
83
83
  className,
84
84
  )}
85
85
  {...props}
@@ -108,7 +108,7 @@ function NavigationMenuPositioner({
108
108
  )}
109
109
  {...props}
110
110
  >
111
- <NavigationMenuPrimitive.Popup className="data-[ending-style]:easing-[ease] relative h-(--popup-height) w-(--popup-width) xs:w-(--popup-width) origin-(--transform-origin) rounded-lg bg-popover text-popover-foreground shadow outline-none ring-1 ring-foreground/10 transition-[opacity,transform,width,height,scale,translate] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)] data-ending-style:scale-90 data-starting-style:scale-90 data-ending-style:opacity-0 data-starting-style:opacity-0 data-ending-style:duration-150">
111
+ <NavigationMenuPrimitive.Popup className="data-[ending-style]:easing-[ease] xs:w-(--popup-width) relative h-(--popup-height) w-(--popup-width) origin-(--transform-origin) rounded-lg bg-popover text-popover-foreground shadow ring-1 ring-foreground/10 transition-[opacity,transform,width,height,scale,translate] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)] outline-none data-ending-style:scale-90 data-ending-style:opacity-0 data-ending-style:duration-150 data-starting-style:scale-90 data-starting-style:opacity-0">
112
112
  <NavigationMenuPrimitive.Viewport className="relative size-full overflow-hidden" />
113
113
  </NavigationMenuPrimitive.Popup>
114
114
  </NavigationMenuPrimitive.Positioner>
@@ -121,7 +121,7 @@ function NavigationMenuLink({ className, ...props }: NavigationMenuPrimitive.Lin
121
121
  <NavigationMenuPrimitive.Link
122
122
  data-slot="navigation-menu-link"
123
123
  className={cn(
124
- "flex items-center gap-2 in-data-[slot=navigation-menu-content]:rounded-md rounded-lg p-2 text-sm outline-none transition-all hover:bg-muted focus:bg-muted focus-visible:outline-1 focus-visible:ring-3 focus-visible:ring-ring/50 data-active:bg-muted/50 data-active:focus:bg-muted data-active:hover:bg-muted [&_svg:not([class*='size-'])]:size-4",
124
+ "flex items-center gap-2 rounded-lg p-2 text-sm transition-all outline-none hover:bg-muted focus:bg-muted focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:outline-1 in-data-[slot=navigation-menu-content]:rounded-md data-active:bg-muted/50 data-active:hover:bg-muted data-active:focus:bg-muted [&_svg:not([class*='size-'])]:size-4",
125
125
  className,
126
126
  )}
127
127
  {...props}
@@ -137,7 +137,7 @@ function NavigationMenuIndicator({
137
137
  <NavigationMenuPrimitive.Icon
138
138
  data-slot="navigation-menu-indicator"
139
139
  className={cn(
140
- "data-[state=hidden]:fade-out data-[state=visible]:fade-in top-full z-1 flex h-1.5 items-end justify-center overflow-hidden data-[state=hidden]:animate-out data-[state=visible]:animate-in",
140
+ "top-full z-1 flex h-1.5 items-end justify-center overflow-hidden data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:animate-in data-[state=visible]:fade-in",
141
141
  className,
142
142
  )}
143
143
  {...props}
@@ -33,7 +33,7 @@ function PopoverContent({
33
33
  <PopoverPrimitive.Popup
34
34
  data-slot="popover-content"
35
35
  className={cn(
36
- "data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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:fade-in-0 data-open:zoom-in-95 data-closed:fade-out-0 data-closed:zoom-out-95 z-50 flex w-72 origin-(--transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-popover-foreground text-sm shadow-md outline-hidden ring-1 ring-foreground/10 duration-100 data-closed:animate-out data-open:animate-in",
36
+ "z-50 flex w-72 origin-(--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=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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",
37
37
  className,
38
38
  )}
39
39
  {...props}
@@ -1,7 +1,6 @@
1
1
  "use client";
2
2
 
3
3
  import { Progress as ProgressPrimitive } from "@base-ui/react/progress";
4
-
5
4
  import { cn } from "@suphark/ui/lib/utils";
6
5
 
7
6
  function Progress({ className, children, value, ...props }: ProgressPrimitive.Root.Props) {
@@ -46,7 +45,7 @@ function ProgressIndicator({ className, ...props }: ProgressPrimitive.Indicator.
46
45
  function ProgressLabel({ className, ...props }: ProgressPrimitive.Label.Props) {
47
46
  return (
48
47
  <ProgressPrimitive.Label
49
- className={cn("font-medium text-sm", className)}
48
+ className={cn("text-sm font-medium", className)}
50
49
  data-slot="progress-label"
51
50
  {...props}
52
51
  />
@@ -56,7 +55,7 @@ function ProgressLabel({ className, ...props }: ProgressPrimitive.Label.Props) {
56
55
  function ProgressValue({ className, ...props }: ProgressPrimitive.Value.Props) {
57
56
  return (
58
57
  <ProgressPrimitive.Value
59
- className={cn("ml-auto text-muted-foreground text-sm tabular-nums", className)}
58
+ className={cn("ml-auto text-sm text-muted-foreground tabular-nums", className)}
60
59
  data-slot="progress-value"
61
60
  {...props}
62
61
  />
@@ -0,0 +1,314 @@
1
+ "use client";
2
+
3
+ import { Questionnaire as QuestionnairePrimitive } from "@shadcn/react/questionnaire";
4
+ import { type Button, buttonVariants } from "@suphark/ui/components/ui/button";
5
+ import { cn } from "@suphark/ui/lib/utils";
6
+ import { CheckIcon } from "lucide-react";
7
+ import type * as React from "react";
8
+
9
+ function Questionnaire({
10
+ className,
11
+ ...props
12
+ }: React.ComponentProps<typeof QuestionnairePrimitive.Root>) {
13
+ return (
14
+ <QuestionnairePrimitive.Root
15
+ data-slot="questionnaire"
16
+ className={cn("flex w-full min-w-0 flex-col gap-4", className)}
17
+ {...props}
18
+ />
19
+ );
20
+ }
21
+
22
+ function QuestionnaireProgress({
23
+ className,
24
+ ...props
25
+ }: React.ComponentProps<typeof QuestionnairePrimitive.Progress>) {
26
+ return (
27
+ <QuestionnairePrimitive.Progress
28
+ data-slot="questionnaire-progress"
29
+ className={cn(
30
+ "min-h-[1lh] w-fit min-w-[14ch] text-xs font-medium text-muted-foreground tabular-nums",
31
+ className,
32
+ )}
33
+ {...props}
34
+ />
35
+ );
36
+ }
37
+
38
+ function QuestionnaireItem({
39
+ className,
40
+ ...props
41
+ }: React.ComponentProps<typeof QuestionnairePrimitive.Item>) {
42
+ return (
43
+ <QuestionnairePrimitive.Item
44
+ data-slot="questionnaire-item"
45
+ className={cn("flex min-w-0 flex-col gap-4 border-0 p-0 outline-none", className)}
46
+ {...props}
47
+ />
48
+ );
49
+ }
50
+
51
+ function QuestionnaireTitle({
52
+ className,
53
+ ...props
54
+ }: React.ComponentProps<typeof QuestionnairePrimitive.Title>) {
55
+ return (
56
+ <QuestionnairePrimitive.Title
57
+ data-slot="questionnaire-title"
58
+ className={cn(
59
+ "text-base leading-snug font-medium text-pretty [&:not(:has(~[data-slot=questionnaire-description]))]:mb-4",
60
+ className,
61
+ )}
62
+ {...props}
63
+ />
64
+ );
65
+ }
66
+
67
+ function QuestionnaireDescription({
68
+ className,
69
+ ...props
70
+ }: React.ComponentProps<typeof QuestionnairePrimitive.Description>) {
71
+ return (
72
+ <QuestionnairePrimitive.Description
73
+ data-slot="questionnaire-description"
74
+ className={cn("text-sm text-pretty text-muted-foreground", className)}
75
+ {...props}
76
+ />
77
+ );
78
+ }
79
+
80
+ function QuestionnaireChoices({
81
+ className,
82
+ ...props
83
+ }: React.ComponentProps<typeof QuestionnairePrimitive.Choices>) {
84
+ return (
85
+ <QuestionnairePrimitive.Choices
86
+ data-slot="questionnaire-choices"
87
+ className={cn("group/questionnaire-choices grid min-w-0 gap-2", className)}
88
+ {...props}
89
+ />
90
+ );
91
+ }
92
+
93
+ function QuestionnaireChoice({
94
+ children,
95
+ className,
96
+ ...props
97
+ }: React.ComponentProps<typeof QuestionnairePrimitive.Choice>) {
98
+ return (
99
+ <QuestionnairePrimitive.Choice
100
+ data-slot="questionnaire-choice"
101
+ className={cn(
102
+ "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",
103
+ "data-disabled:pointer-events-none data-disabled:cursor-not-allowed data-disabled:opacity-50",
104
+ className,
105
+ )}
106
+ {...props}
107
+ >
108
+ <QuestionnairePrimitive.ChoiceInput
109
+ data-slot="questionnaire-choice-input"
110
+ className="absolute inset-0 z-10 size-full cursor-pointer opacity-0"
111
+ />
112
+ <span
113
+ aria-hidden="true"
114
+ data-slot="questionnaire-choice-indicator"
115
+ 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"
116
+ >
117
+ <span
118
+ data-slot="questionnaire-choice-indicator-dot"
119
+ className="hidden size-2 rounded-full bg-primary-foreground group-data-[type=checkbox]/questionnaire-choice:hidden group-data-checked/questionnaire-choice:block"
120
+ />
121
+ <CheckIcon
122
+ data-slot="questionnaire-choice-indicator-check"
123
+ className="hidden size-3.5 group-data-[type=radio]/questionnaire-choice:hidden group-data-checked/questionnaire-choice:block"
124
+ />
125
+ </span>
126
+ <QuestionnairePrimitive.ChoiceLabel
127
+ data-slot="questionnaire-choice-label"
128
+ className="flex min-w-0 flex-1 flex-col gap-0.5 leading-snug"
129
+ >
130
+ {children}
131
+ </QuestionnairePrimitive.ChoiceLabel>
132
+ <QuestionnairePrimitive.ChoiceShortcut
133
+ data-slot="questionnaire-choice-shortcut"
134
+ 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"
135
+ />
136
+ </QuestionnairePrimitive.Choice>
137
+ );
138
+ }
139
+
140
+ function QuestionnaireChoiceDescription({ className, ...props }: React.ComponentProps<"span">) {
141
+ return (
142
+ <span
143
+ data-slot="questionnaire-choice-description"
144
+ className={cn("text-muted-foreground", className)}
145
+ {...props}
146
+ />
147
+ );
148
+ }
149
+
150
+ function QuestionnaireInput({
151
+ className,
152
+ ...props
153
+ }: React.ComponentProps<typeof QuestionnairePrimitive.Input>) {
154
+ return (
155
+ <div
156
+ data-slot="questionnaire-input-wrapper"
157
+ className="group/questionnaire-input relative w-full min-w-0"
158
+ >
159
+ <QuestionnairePrimitive.Input
160
+ data-slot="questionnaire-input"
161
+ className={cn(
162
+ "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",
163
+ "selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground",
164
+ className,
165
+ )}
166
+ {...props}
167
+ />
168
+ </div>
169
+ );
170
+ }
171
+
172
+ function QuestionnaireError({
173
+ className,
174
+ ...props
175
+ }: React.ComponentProps<typeof QuestionnairePrimitive.Error>) {
176
+ return (
177
+ <QuestionnairePrimitive.Error
178
+ data-slot="questionnaire-error"
179
+ className={cn("mt-2 text-sm text-destructive", className)}
180
+ {...props}
181
+ />
182
+ );
183
+ }
184
+
185
+ function QuestionnaireActions({ className, ...props }: React.ComponentProps<"div">) {
186
+ return (
187
+ <div
188
+ data-slot="questionnaire-actions"
189
+ className={cn(
190
+ "grid min-h-11 w-full grid-cols-[minmax(0,1fr)_auto_auto] items-center gap-2 sm:min-h-8",
191
+ className,
192
+ )}
193
+ {...props}
194
+ />
195
+ );
196
+ }
197
+
198
+ function QuestionnairePrevious({
199
+ children,
200
+ className,
201
+ size = "default",
202
+ variant = "outline",
203
+ ...props
204
+ }: React.ComponentProps<typeof QuestionnairePrimitive.Previous> &
205
+ Pick<React.ComponentProps<typeof Button>, "size" | "variant">) {
206
+ return (
207
+ <QuestionnairePrimitive.Previous
208
+ data-slot="questionnaire-previous"
209
+ data-size={size}
210
+ data-variant={variant}
211
+ className={cn(
212
+ buttonVariants({ size, variant }),
213
+ "col-start-1 row-start-1 min-h-11 justify-self-start sm:min-h-0",
214
+ className,
215
+ )}
216
+ {...props}
217
+ >
218
+ {children ?? "Previous"}
219
+ </QuestionnairePrimitive.Previous>
220
+ );
221
+ }
222
+
223
+ function QuestionnaireSkip({
224
+ children,
225
+ className,
226
+ size = "default",
227
+ variant = "outline",
228
+ ...props
229
+ }: React.ComponentProps<typeof QuestionnairePrimitive.Skip> &
230
+ Pick<React.ComponentProps<typeof Button>, "size" | "variant">) {
231
+ return (
232
+ <QuestionnairePrimitive.Skip
233
+ data-slot="questionnaire-skip"
234
+ data-size={size}
235
+ data-variant={variant}
236
+ className={cn(
237
+ buttonVariants({ size, variant }),
238
+ "col-start-2 row-start-1 min-h-11 justify-self-end sm:min-h-0",
239
+ className,
240
+ )}
241
+ {...props}
242
+ >
243
+ {children ?? "Skip"}
244
+ </QuestionnairePrimitive.Skip>
245
+ );
246
+ }
247
+
248
+ function QuestionnaireNext({
249
+ children,
250
+ className,
251
+ size = "default",
252
+ variant = "default",
253
+ ...props
254
+ }: React.ComponentProps<typeof QuestionnairePrimitive.Next> &
255
+ Pick<React.ComponentProps<typeof Button>, "size" | "variant">) {
256
+ return (
257
+ <QuestionnairePrimitive.Next
258
+ data-slot="questionnaire-next"
259
+ data-size={size}
260
+ data-variant={variant}
261
+ className={cn(
262
+ buttonVariants({ size, variant }),
263
+ "col-start-3 row-start-1 min-h-11 justify-self-end sm:min-h-0",
264
+ className,
265
+ )}
266
+ {...props}
267
+ >
268
+ {children ?? "Next"}
269
+ </QuestionnairePrimitive.Next>
270
+ );
271
+ }
272
+
273
+ function QuestionnaireSubmit({
274
+ children,
275
+ className,
276
+ size = "default",
277
+ variant = "default",
278
+ ...props
279
+ }: React.ComponentProps<typeof QuestionnairePrimitive.Submit> &
280
+ Pick<React.ComponentProps<typeof Button>, "size" | "variant">) {
281
+ return (
282
+ <QuestionnairePrimitive.Submit
283
+ data-slot="questionnaire-submit"
284
+ data-size={size}
285
+ data-variant={variant}
286
+ className={cn(
287
+ buttonVariants({ size, variant }),
288
+ "col-start-3 row-start-1 min-h-11 justify-self-end sm:min-h-0",
289
+ className,
290
+ )}
291
+ {...props}
292
+ >
293
+ {children ?? "Submit"}
294
+ </QuestionnairePrimitive.Submit>
295
+ );
296
+ }
297
+
298
+ export {
299
+ Questionnaire,
300
+ QuestionnaireActions,
301
+ QuestionnaireChoice,
302
+ QuestionnaireChoiceDescription,
303
+ QuestionnaireChoices,
304
+ QuestionnaireDescription,
305
+ QuestionnaireError,
306
+ QuestionnaireInput,
307
+ QuestionnaireItem,
308
+ QuestionnaireNext,
309
+ QuestionnairePrevious,
310
+ QuestionnaireProgress,
311
+ QuestionnaireSkip,
312
+ QuestionnaireSubmit,
313
+ QuestionnaireTitle,
314
+ };
@@ -2,7 +2,6 @@
2
2
 
3
3
  import { Radio as RadioPrimitive } from "@base-ui/react/radio";
4
4
  import { RadioGroup as RadioGroupPrimitive } from "@base-ui/react/radio-group";
5
-
6
5
  import { cn } from "@suphark/ui/lib/utils";
7
6
 
8
7
  function RadioGroup({ className, ...props }: RadioGroupPrimitive.Props) {
@@ -20,7 +19,7 @@ function RadioGroupItem({ className, ...props }: RadioPrimitive.Root.Props) {
20
19
  <RadioPrimitive.Root
21
20
  data-slot="radio-group-item"
22
21
  className={cn(
23
- "group/radio-group-item peer relative flex aspect-square size-4 shrink-0 rounded-full border border-input outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 group-has-[:focus-visible]/field-label:not-data-checked:border-input group-has-[:focus-visible]/field-label:ring-0 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground group-has-[:focus-visible]/field-label:data-checked:border-primary dark:bg-input/30 dark:data-checked:bg-primary dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
22
+ "group/radio-group-item peer relative flex aspect-square size-4 shrink-0 rounded-full border border-input outline-none group-has-[:focus-visible]/field-label:ring-0 group-has-[:focus-visible]/field-label:not-data-checked:border-input after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground group-has-[:focus-visible]/field-label:data-checked:border-primary dark:data-checked:bg-primary",
24
23
  className,
25
24
  )}
26
25
  {...props}
@@ -28,7 +28,7 @@ function ResizableHandle({
28
28
  <ResizablePrimitive.Separator
29
29
  data-slot="resizable-handle"
30
30
  className={cn(
31
- "relative flex w-px items-center justify-center bg-border ring-offset-background after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring 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",
31
+ "relative flex w-px items-center justify-center bg-border ring-offset-background 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: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
32
  className,
33
33
  )}
34
34
  {...props}
@@ -40,7 +40,7 @@ function SelectTrigger({
40
40
  data-slot="select-trigger"
41
41
  data-size={size}
42
42
  className={cn(
43
- "flex w-fit select-none items-center justify-between gap-1.5 whitespace-nowrap rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm outline-none transition-colors focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-placeholder:text-muted-foreground *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 dark:hover:bg-input/50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
43
+ "flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 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",
44
44
  className,
45
45
  )}
46
46
  {...props}
@@ -81,7 +81,7 @@ function SelectContent({
81
81
  data-slot="select-content"
82
82
  data-align-trigger={alignItemWithTrigger}
83
83
  className={cn(
84
- "data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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:fade-in-0 data-open:zoom-in-95 data-closed:fade-out-0 data-closed:zoom-out-95 relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-y-auto overflow-x-hidden rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-closed:animate-out data-open:animate-in",
84
+ "relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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",
85
85
  className,
86
86
  )}
87
87
  {...props}
@@ -99,7 +99,7 @@ function SelectLabel({ className, ...props }: SelectPrimitive.GroupLabel.Props)
99
99
  return (
100
100
  <SelectPrimitive.GroupLabel
101
101
  data-slot="select-label"
102
- className={cn("px-1.5 py-1 text-muted-foreground text-xs", className)}
102
+ className={cn("px-1.5 py-1 text-xs text-muted-foreground", className)}
103
103
  {...props}
104
104
  />
105
105
  );
@@ -110,7 +110,7 @@ function SelectItem({ className, children, ...props }: SelectPrimitive.Item.Prop
110
110
  <SelectPrimitive.Item
111
111
  data-slot="select-item"
112
112
  className={cn(
113
- "relative flex w-full cursor-default select-none items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
113
+ "relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
114
114
  className,
115
115
  )}
116
116
  {...props}
@@ -1,7 +1,6 @@
1
1
  "use client";
2
2
 
3
3
  import { Separator as SeparatorPrimitive } from "@base-ui/react/separator";
4
-
5
4
  import { cn } from "@suphark/ui/lib/utils";
6
5
 
7
6
  function Separator({ className, orientation = "horizontal", ...props }: SeparatorPrimitive.Props) {
@@ -52,7 +52,7 @@ function SheetContent({
52
52
  data-slot="sheet-content"
53
53
  data-side={side}
54
54
  className={cn(
55
- "fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-popover-foreground text-sm shadow-lg transition duration-200 ease-in-out data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] data-[side=bottom]:inset-x-0 data-[side=top]:inset-x-0 data-[side=left]:inset-y-0 data-[side=right]:inset-y-0 data-[side=top]:top-0 data-[side=right]:right-0 data-[side=bottom]:bottom-0 data-[side=left]:left-0 data-[side=bottom]:h-auto data-[side=left]:h-full data-[side=right]:h-full data-[side=top]:h-auto data-[side=left]:w-3/4 data-[side=right]:w-3/4 data-[side=bottom]:border-t data-[side=left]:border-r data-[side=top]:border-b data-[side=right]:border-l data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm",
55
+ "fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm",
56
56
  className,
57
57
  )}
58
58
  {...props}
@@ -96,7 +96,7 @@ function SheetTitle({ className, ...props }: SheetPrimitive.Title.Props) {
96
96
  return (
97
97
  <SheetPrimitive.Title
98
98
  data-slot="sheet-title"
99
- className={cn("font-medium text-base text-foreground", className)}
99
+ className={cn("text-base font-medium text-foreground", className)}
100
100
  {...props}
101
101
  />
102
102
  );
@@ -106,7 +106,7 @@ function SheetDescription({ className, ...props }: SheetPrimitive.Description.Pr
106
106
  return (
107
107
  <SheetPrimitive.Description
108
108
  data-slot="sheet-description"
109
- className={cn("text-muted-foreground text-sm", className)}
109
+ className={cn("text-sm text-muted-foreground", className)}
110
110
  {...props}
111
111
  />
112
112
  );