raft-ui 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.
Files changed (134) hide show
  1. package/README.md +24 -0
  2. package/dist/cn.d.mts +2 -0
  3. package/dist/cn.mjs +2 -0
  4. package/dist/index.d.mts +2710 -0
  5. package/dist/index.mjs +4821 -0
  6. package/dist/label-DWq4ia5I.mjs +115 -0
  7. package/dist/styled-props-B3SNekJg.d.mts +16 -0
  8. package/dist/wip.d.mts +1238 -0
  9. package/dist/wip.mjs +1416 -0
  10. package/package.json +70 -0
  11. package/src/components/avatar/avatar.tsx +375 -0
  12. package/src/components/avatar/index.ts +17 -0
  13. package/src/components/badge/badge.tsx +393 -0
  14. package/src/components/badge/index.ts +2 -0
  15. package/src/components/banner/banner.tsx +269 -0
  16. package/src/components/banner/index.ts +8 -0
  17. package/src/components/bottom-sheet/bottom-sheet.tsx +152 -0
  18. package/src/components/bottom-sheet/index.ts +22 -0
  19. package/src/components/button/button.tsx +497 -0
  20. package/src/components/button/index.ts +2 -0
  21. package/src/components/checkbox/checkbox-indicator.tsx +128 -0
  22. package/src/components/checkbox/checkbox.tsx +350 -0
  23. package/src/components/checkbox/index.ts +2 -0
  24. package/src/components/combobox/combobox.tsx +603 -0
  25. package/src/components/combobox/index.ts +52 -0
  26. package/src/components/context-menu/context-menu.tsx +380 -0
  27. package/src/components/context-menu/index.ts +34 -0
  28. package/src/components/conversation-preview-card/conversation-preview-card.tsx +336 -0
  29. package/src/components/conversation-preview-card/index.ts +32 -0
  30. package/src/components/description-list/description-list.tsx +116 -0
  31. package/src/components/description-list/index.ts +14 -0
  32. package/src/components/dropdown-menu/dropdown-menu.tsx +405 -0
  33. package/src/components/dropdown-menu/index.ts +38 -0
  34. package/src/components/empty-state/empty-state.tsx +177 -0
  35. package/src/components/empty-state/index.ts +16 -0
  36. package/src/components/field/field.tsx +125 -0
  37. package/src/components/field/index.ts +18 -0
  38. package/src/components/inline-code/index.ts +2 -0
  39. package/src/components/inline-code/inline-code.tsx +33 -0
  40. package/src/components/input/index.ts +2 -0
  41. package/src/components/input/input.tsx +76 -0
  42. package/src/components/input-group/index.ts +7 -0
  43. package/src/components/input-group/input-group.tsx +215 -0
  44. package/src/components/kbd/index.ts +2 -0
  45. package/src/components/kbd/kbd.tsx +43 -0
  46. package/src/components/label/index.ts +7 -0
  47. package/src/components/label/label.tsx +99 -0
  48. package/src/components/lightbox/index.ts +24 -0
  49. package/src/components/lightbox/lightbox.tsx +245 -0
  50. package/src/components/list-item/index.ts +20 -0
  51. package/src/components/list-item/list-item.tsx +263 -0
  52. package/src/components/media-list-item/index.ts +20 -0
  53. package/src/components/media-list-item/media-list-item.tsx +169 -0
  54. package/src/components/notification-center/index.ts +39 -0
  55. package/src/components/notification-center/notification-center.tsx +558 -0
  56. package/src/components/panel-header/index.ts +22 -0
  57. package/src/components/panel-header/panel-header.tsx +199 -0
  58. package/src/components/popover/index.ts +30 -0
  59. package/src/components/popover/popover.tsx +248 -0
  60. package/src/components/preview-shell/index.ts +2 -0
  61. package/src/components/preview-shell/preview-shell.tsx +51 -0
  62. package/src/components/quoted-message-card/index.ts +36 -0
  63. package/src/components/quoted-message-card/quoted-message-card.tsx +391 -0
  64. package/src/components/radio-group/index.ts +6 -0
  65. package/src/components/radio-group/radio-group.tsx +119 -0
  66. package/src/components/section-header/index.ts +16 -0
  67. package/src/components/section-header/section-header.tsx +117 -0
  68. package/src/components/section-label/index.ts +2 -0
  69. package/src/components/section-label/section-label.tsx +38 -0
  70. package/src/components/segmented-control/index.ts +12 -0
  71. package/src/components/segmented-control/segmented-control.tsx +129 -0
  72. package/src/components/select/index.ts +40 -0
  73. package/src/components/select/select.tsx +382 -0
  74. package/src/components/spinner/index.ts +2 -0
  75. package/src/components/spinner/spinner.tsx +228 -0
  76. package/src/components/status/index.ts +2 -0
  77. package/src/components/status/status.tsx +152 -0
  78. package/src/components/tabs/index.ts +24 -0
  79. package/src/components/tabs/tabs.tsx +417 -0
  80. package/src/components/text/index.ts +2 -0
  81. package/src/components/text/text.tsx +130 -0
  82. package/src/components/textarea/index.ts +2 -0
  83. package/src/components/textarea/textarea.tsx +136 -0
  84. package/src/components/toggle-group/index.ts +12 -0
  85. package/src/components/toggle-group/toggle-group.tsx +111 -0
  86. package/src/components/tooltip/index.ts +14 -0
  87. package/src/components/tooltip/tooltip.tsx +186 -0
  88. package/src/fonts/brutal.css +2 -0
  89. package/src/index.ts +404 -0
  90. package/src/legacy/AttentionDot.tsx +28 -0
  91. package/src/legacy/AvatarListRow.tsx +87 -0
  92. package/src/legacy/AvatarSlot.tsx +157 -0
  93. package/src/legacy/Badge.tsx +95 -0
  94. package/src/legacy/Banner.tsx +74 -0
  95. package/src/legacy/BottomSheet.tsx +76 -0
  96. package/src/legacy/CheckMarker.tsx +72 -0
  97. package/src/legacy/Checkbox.tsx +81 -0
  98. package/src/legacy/ConversationPreviewCard.tsx +169 -0
  99. package/src/legacy/DismissBackdrop.tsx +68 -0
  100. package/src/legacy/EmptyState.tsx +63 -0
  101. package/src/legacy/ExperimentalBadge.tsx +19 -0
  102. package/src/legacy/FormField.tsx +106 -0
  103. package/src/legacy/KeyValueRow.tsx +67 -0
  104. package/src/legacy/Lightbox.tsx +119 -0
  105. package/src/legacy/NotificationCenter.tsx +217 -0
  106. package/src/legacy/PanelHeader.tsx +94 -0
  107. package/src/legacy/PreviewShell.tsx +40 -0
  108. package/src/legacy/QuotedMessageCard.tsx +181 -0
  109. package/src/legacy/ReorderablePanelTabs.tsx +151 -0
  110. package/src/legacy/SandboxedPreviewFrame.tsx +59 -0
  111. package/src/legacy/SearchInput.tsx +23 -0
  112. package/src/legacy/SectionEyebrow.tsx +60 -0
  113. package/src/legacy/SectionHeader.tsx +68 -0
  114. package/src/legacy/SegmentedControl.tsx +74 -0
  115. package/src/legacy/SlugInput.tsx +29 -0
  116. package/src/legacy/Spinner.tsx +89 -0
  117. package/src/legacy/StatusDot.tsx +51 -0
  118. package/src/legacy/SurfaceListItem.tsx +32 -0
  119. package/src/legacy/Textarea.tsx +137 -0
  120. package/src/legacy/button.tsx +100 -0
  121. package/src/legacy/context-menu-divider.tsx +12 -0
  122. package/src/legacy/menu-item.tsx +66 -0
  123. package/src/legacy/selection-popover.tsx +212 -0
  124. package/src/legacy/server-switcher-menu.tsx +203 -0
  125. package/src/legacy/source.css +240 -0
  126. package/src/lib/cn.ts +1 -0
  127. package/src/lib/styled-props.ts +11 -0
  128. package/src/lib/theme/theme-context.ts +28 -0
  129. package/src/lib/theme/theme-provider.tsx +181 -0
  130. package/src/lib/theme/use-theme.ts +12 -0
  131. package/src/lib/tv.ts +29 -0
  132. package/src/lib/without-children.ts +6 -0
  133. package/src/styles.css +467 -0
  134. package/src/wip.ts +255 -0
@@ -0,0 +1,128 @@
1
+ import { Check, Minus } from "lucide-react";
2
+ import type { ComponentPropsWithRef } from "react";
3
+ import { tv, type VariantProps } from "../../lib/tv.ts";
4
+ import { useThemeFamily } from "../../lib/theme/use-theme.ts";
5
+
6
+ const checkboxIndicator = tv({
7
+ slots: {
8
+ root: [
9
+ "inline-flex shrink-0 items-center justify-center",
10
+ "transition-colors",
11
+ "[&_svg]:shrink-0",
12
+ ],
13
+ },
14
+ variants: {
15
+ theme: {
16
+ brutal: {
17
+ root: ["border-2 border-line-strong"],
18
+ },
19
+ elegant: {},
20
+ },
21
+ shape: {
22
+ square: {
23
+ root: "",
24
+ },
25
+ circle: {
26
+ root: "rounded-full",
27
+ },
28
+ },
29
+ size: {
30
+ sm: {
31
+ root: ["size-3.5", "[&_svg:not([class*='size-'])]:size-2.5 [&_svg]:[stroke-width:4]"],
32
+ },
33
+ md: {
34
+ root: ["size-4", "[&_svg:not([class*='size-'])]:size-3 [&_svg]:[stroke-width:4]"],
35
+ },
36
+ lg: {
37
+ root: ["size-5", "[&_svg:not([class*='size-'])]:size-[13px] [&_svg]:[stroke-width:3]"],
38
+ },
39
+ },
40
+ fill: {
41
+ black: {
42
+ root: "",
43
+ },
44
+ yellow: {
45
+ root: "",
46
+ },
47
+ },
48
+ checked: {
49
+ true: {
50
+ root: "",
51
+ },
52
+ false: {
53
+ root: "bg-layer-panel text-transparent",
54
+ },
55
+ },
56
+ disabled: {
57
+ true: {
58
+ root: "opacity-50",
59
+ },
60
+ false: {
61
+ root: "",
62
+ },
63
+ },
64
+ previewOnHover: {
65
+ true: {
66
+ root: "",
67
+ },
68
+ false: {
69
+ root: "",
70
+ },
71
+ },
72
+ },
73
+ compoundVariants: [
74
+ { checked: true, fill: "black", class: { root: "bg-line-strong text-foreground-inverse" } },
75
+ { checked: true, fill: "yellow", class: { root: "bg-primary-400 text-foreground-strong" } },
76
+ { checked: false, previewOnHover: true, class: { root: "group-hover:text-foreground/20" } },
77
+ ],
78
+ defaultVariants: {
79
+ shape: "square",
80
+ size: "sm",
81
+ fill: "black",
82
+ disabled: false,
83
+ previewOnHover: false,
84
+ },
85
+ });
86
+
87
+ type CheckboxIndicatorMark = "check" | "minus";
88
+
89
+ export type CheckboxIndicatorProps = ComponentPropsWithRef<"span"> &
90
+ Omit<VariantProps<typeof checkboxIndicator>, "theme" | "checked"> & {
91
+ checked: boolean;
92
+ mark?: CheckboxIndicatorMark;
93
+ };
94
+
95
+ export function CheckboxIndicator({
96
+ checked,
97
+ mark = "check",
98
+ shape,
99
+ size,
100
+ fill,
101
+ disabled,
102
+ previewOnHover,
103
+ className,
104
+ ...props
105
+ }: CheckboxIndicatorProps) {
106
+ const theme = useThemeFamily();
107
+ const { root } = checkboxIndicator({
108
+ theme,
109
+ shape,
110
+ size,
111
+ fill,
112
+ checked,
113
+ disabled,
114
+ previewOnHover,
115
+ });
116
+ const Icon = mark === "minus" ? Minus : Check;
117
+
118
+ return (
119
+ <span
120
+ {...props}
121
+ data-slot="checkbox-indicator-graphic"
122
+ aria-hidden
123
+ className={root({ className })}
124
+ >
125
+ {(checked || previewOnHover) && <Icon />}
126
+ </span>
127
+ );
128
+ }
@@ -0,0 +1,350 @@
1
+ import { useId } from "react";
2
+ import { Checkbox as BaseCheckbox } from "@base-ui/react/checkbox";
3
+ import { tv, type VariantProps } from "../../lib/tv.ts";
4
+ import { CheckboxIndicator } from "./checkbox-indicator.tsx";
5
+ import type { StyledProps } from "../../lib/styled-props.ts";
6
+ import { useThemeFamily } from "../../lib/theme/use-theme.ts";
7
+
8
+ const checkbox = tv({
9
+ slots: {
10
+ root: [
11
+ "relative inline-flex shrink-0 touch-manipulation items-center justify-center outline-none",
12
+ "focus-visible:ring-2 focus-visible:ring-line-focus",
13
+ "data-disabled:cursor-not-allowed",
14
+ "after:absolute after:-inset-x-3 after:-inset-y-2 after:content-['']",
15
+ ],
16
+ indicator: ["pointer-events-none"],
17
+ graphic: ["pointer-events-none"],
18
+ outerRect: ["transition-[fill,stroke] duration-[160ms] ease-out motion-reduce:transition-none"],
19
+ overlayRect: [
20
+ "pointer-events-none opacity-0 transition-opacity duration-[160ms] ease-out motion-reduce:transition-none",
21
+ "group-data-[disabled]/checkbox:opacity-0",
22
+ "group-hover/checkbox:group-data-[disabled]/checkbox:opacity-0 group-focus-visible/checkbox:group-data-[disabled]/checkbox:opacity-0",
23
+ ],
24
+ mark: ["absolute left-1/2 top-1/2 shrink-0 origin-center -translate-x-1/2 -translate-y-1/2"],
25
+ checkMark: [
26
+ "-rotate-6 scale-[0.82] opacity-0",
27
+ "transition-[opacity,transform] duration-[180ms] ease-out motion-reduce:transition-none",
28
+ "motion-reduce:rotate-0 motion-reduce:scale-100",
29
+ ],
30
+ indeterminateMark: [
31
+ "invisible scale-x-50 opacity-0",
32
+ "transition-[opacity,transform] duration-[160ms] ease-out motion-reduce:transition-none",
33
+ "motion-reduce:scale-x-100",
34
+ ],
35
+ },
36
+ variants: {
37
+ theme: {
38
+ brutal: {},
39
+ elegant: {
40
+ root: [
41
+ "group/checkbox rounded-[3px] focus:outline-none",
42
+ "shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.05),0_2px_2px_-1px_oklch(0_0_0_/_0.04),0_4px_4px_-2px_oklch(0_0_0_/_0.02),0_0_0_1px_var(--line-subtle)]",
43
+ "transition-[box-shadow,transform] duration-100 ease-out motion-reduce:transition-none",
44
+ "active:scale-[0.96] data-[disabled]:active:scale-100 motion-reduce:active:scale-100",
45
+ ],
46
+ graphic: ["absolute inset-0 size-full"],
47
+ },
48
+ },
49
+ variant: {
50
+ default: {},
51
+ primary: {},
52
+ },
53
+ color: {
54
+ default: {},
55
+ primary: {},
56
+ },
57
+ size: {
58
+ sm: {
59
+ root: "size-3.5",
60
+ },
61
+ md: {
62
+ root: "size-4",
63
+ },
64
+ },
65
+ },
66
+ compoundVariants: [
67
+ {
68
+ theme: "elegant",
69
+ size: "sm",
70
+ class: { root: "size-4" },
71
+ },
72
+ {
73
+ theme: "elegant",
74
+ size: "md",
75
+ class: { root: "size-[18px]" },
76
+ },
77
+ {
78
+ theme: "elegant",
79
+ variant: "default",
80
+ color: "default",
81
+ class: {
82
+ root: [
83
+ "data-[checked]:shadow-[0_2px_2px_-1px_oklch(0_0_0_/_0.04),0_4px_4px_-2px_oklch(0_0_0_/_0.02)]",
84
+ "data-[indeterminate]:shadow-[0_2px_2px_-1px_oklch(0_0_0_/_0.04),0_4px_4px_-2px_oklch(0_0_0_/_0.02)]",
85
+ "data-[disabled]:shadow-[0_1px_1px_-1px_oklch(0_0_0_/_0.02),0_0_0_1px_var(--line-subtle)]",
86
+ "data-[checked]:data-[disabled]:shadow-[0_1px_1px_-1px_oklch(0_0_0_/_0.02),0_0_0_1px_var(--line-subtle)]",
87
+ "data-[indeterminate]:data-[disabled]:shadow-[0_1px_1px_-1px_oklch(0_0_0_/_0.02),0_0_0_1px_var(--line-subtle)]",
88
+ ],
89
+ outerRect: [
90
+ "fill-layer-panel",
91
+ "stroke-transparent",
92
+ "group-hover/checkbox:fill-[oklch(0.976_0.001_286)]",
93
+ "group-focus-visible/checkbox:fill-foreground-strong",
94
+ "group-hover/checkbox:group-data-[checked]/checkbox:fill-[oklch(0.38_0.006_285)]",
95
+ "group-hover/checkbox:group-data-[indeterminate]/checkbox:fill-[oklch(0.38_0.006_285)]",
96
+ "group-focus-visible/checkbox:group-data-[checked]/checkbox:fill-foreground-strong",
97
+ "group-focus-visible/checkbox:group-data-[indeterminate]/checkbox:fill-foreground-strong",
98
+ "group-data-[checked]/checkbox:fill-foreground-strong",
99
+ "group-data-[indeterminate]/checkbox:fill-foreground-strong",
100
+ "group-data-[disabled]/checkbox:fill-layer-muted",
101
+ "group-data-[checked]/checkbox:group-data-[disabled]/checkbox:fill-layer-muted",
102
+ "group-data-[indeterminate]/checkbox:group-data-[disabled]/checkbox:fill-layer-muted",
103
+ "group-hover/checkbox:group-data-[checked]/checkbox:group-data-[disabled]/checkbox:fill-layer-muted",
104
+ "group-hover/checkbox:group-data-[indeterminate]/checkbox:group-data-[disabled]/checkbox:fill-layer-muted",
105
+ "group-focus-visible/checkbox:group-data-[checked]/checkbox:group-data-[disabled]/checkbox:fill-layer-muted",
106
+ "group-focus-visible/checkbox:group-data-[indeterminate]/checkbox:group-data-[disabled]/checkbox:fill-layer-muted",
107
+ ],
108
+ mark: ["text-foreground-inverse group-data-[disabled]/checkbox:text-line"],
109
+ },
110
+ },
111
+ {
112
+ theme: "elegant",
113
+ variant: "primary",
114
+ class: {
115
+ root: [
116
+ "data-[checked]:shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.2),0_1px_1px_-0.5px_oklch(0.85_0.162_91.89_/_0.1),0_2px_2px_-1px_oklch(0.85_0.162_91.89_/_0.06),0_0_0_1px_oklch(0.83_0.14_91.89_/_0.7)]",
117
+ "data-[indeterminate]:shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.2),0_1px_1px_-0.5px_oklch(0.85_0.162_91.89_/_0.1),0_2px_2px_-1px_oklch(0.85_0.162_91.89_/_0.06),0_0_0_1px_oklch(0.83_0.14_91.89_/_0.7)]",
118
+ "data-[disabled]:shadow-[0_1px_1px_-1px_oklch(0_0_0_/_0.02),0_0_0_1px_var(--line-subtle)]",
119
+ "data-[checked]:data-[disabled]:shadow-[0_1px_1px_-1px_oklch(0_0_0_/_0.02),0_0_0_1px_var(--line-subtle)]",
120
+ "data-[indeterminate]:data-[disabled]:shadow-[0_1px_1px_-1px_oklch(0_0_0_/_0.02),0_0_0_1px_var(--line-subtle)]",
121
+ ],
122
+ outerRect: [
123
+ "fill-layer-panel",
124
+ "stroke-transparent",
125
+ "group-hover/checkbox:fill-[oklch(0.976_0.001_286)]",
126
+ "group-focus-visible/checkbox:fill-primary-400",
127
+ "group-hover/checkbox:group-data-[checked]/checkbox:fill-[oklch(0.86_0.15_91.89)]",
128
+ "group-hover/checkbox:group-data-[indeterminate]/checkbox:fill-[oklch(0.86_0.15_91.89)]",
129
+ "group-focus-visible/checkbox:group-data-[checked]/checkbox:fill-primary-400",
130
+ "group-focus-visible/checkbox:group-data-[indeterminate]/checkbox:fill-primary-400",
131
+ "group-data-[checked]/checkbox:fill-primary-400",
132
+ "group-data-[indeterminate]/checkbox:fill-primary-400",
133
+ "group-data-[disabled]/checkbox:fill-layer-muted",
134
+ "group-data-[checked]/checkbox:group-data-[disabled]/checkbox:fill-layer-muted",
135
+ "group-data-[indeterminate]/checkbox:group-data-[disabled]/checkbox:fill-layer-muted",
136
+ "group-hover/checkbox:group-data-[checked]/checkbox:group-data-[disabled]/checkbox:fill-layer-muted",
137
+ "group-hover/checkbox:group-data-[indeterminate]/checkbox:group-data-[disabled]/checkbox:fill-layer-muted",
138
+ "group-focus-visible/checkbox:group-data-[checked]/checkbox:group-data-[disabled]/checkbox:fill-layer-muted",
139
+ "group-focus-visible/checkbox:group-data-[indeterminate]/checkbox:group-data-[disabled]/checkbox:fill-layer-muted",
140
+ ],
141
+ overlayRect: [
142
+ "group-hover/checkbox:group-data-[checked]/checkbox:opacity-100 group-focus-visible/checkbox:group-data-[checked]/checkbox:opacity-100",
143
+ "group-hover/checkbox:group-data-[indeterminate]/checkbox:opacity-100 group-focus-visible/checkbox:group-data-[indeterminate]/checkbox:opacity-100",
144
+ ],
145
+ mark: ["text-primary-950 group-data-[disabled]/checkbox:text-line"],
146
+ },
147
+ },
148
+ {
149
+ theme: "elegant",
150
+ variant: "default",
151
+ color: "primary",
152
+ class: {
153
+ root: [
154
+ "data-[checked]:shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.2),0_1px_1px_-0.5px_oklch(0.85_0.162_91.89_/_0.1),0_2px_2px_-1px_oklch(0.85_0.162_91.89_/_0.06),0_0_0_1px_oklch(0.83_0.14_91.89_/_0.7)]",
155
+ "data-[indeterminate]:shadow-[inset_0_1px_0.5px_oklch(1_0_0_/_0.2),0_1px_1px_-0.5px_oklch(0.85_0.162_91.89_/_0.1),0_2px_2px_-1px_oklch(0.85_0.162_91.89_/_0.06),0_0_0_1px_oklch(0.83_0.14_91.89_/_0.7)]",
156
+ "data-[disabled]:shadow-[0_1px_1px_-1px_oklch(0_0_0_/_0.02),0_0_0_1px_var(--line-subtle)]",
157
+ "data-[checked]:data-[disabled]:shadow-[0_1px_1px_-1px_oklch(0_0_0_/_0.02),0_0_0_1px_var(--line-subtle)]",
158
+ "data-[indeterminate]:data-[disabled]:shadow-[0_1px_1px_-1px_oklch(0_0_0_/_0.02),0_0_0_1px_var(--line-subtle)]",
159
+ ],
160
+ outerRect: [
161
+ "fill-layer-panel",
162
+ "stroke-transparent",
163
+ "group-hover/checkbox:fill-[oklch(0.976_0.001_286)]",
164
+ "group-focus-visible/checkbox:fill-primary-400",
165
+ "group-hover/checkbox:group-data-[checked]/checkbox:fill-[oklch(0.86_0.15_91.89)]",
166
+ "group-hover/checkbox:group-data-[indeterminate]/checkbox:fill-[oklch(0.86_0.15_91.89)]",
167
+ "group-focus-visible/checkbox:group-data-[checked]/checkbox:fill-primary-400",
168
+ "group-focus-visible/checkbox:group-data-[indeterminate]/checkbox:fill-primary-400",
169
+ "group-data-[checked]/checkbox:fill-primary-400",
170
+ "group-data-[indeterminate]/checkbox:fill-primary-400",
171
+ "group-data-[disabled]/checkbox:fill-layer-muted",
172
+ "group-data-[checked]/checkbox:group-data-[disabled]/checkbox:fill-layer-muted",
173
+ "group-data-[indeterminate]/checkbox:group-data-[disabled]/checkbox:fill-layer-muted",
174
+ "group-hover/checkbox:group-data-[checked]/checkbox:group-data-[disabled]/checkbox:fill-layer-muted",
175
+ "group-hover/checkbox:group-data-[indeterminate]/checkbox:group-data-[disabled]/checkbox:fill-layer-muted",
176
+ "group-focus-visible/checkbox:group-data-[checked]/checkbox:group-data-[disabled]/checkbox:fill-layer-muted",
177
+ "group-focus-visible/checkbox:group-data-[indeterminate]/checkbox:group-data-[disabled]/checkbox:fill-layer-muted",
178
+ ],
179
+ overlayRect: [
180
+ "group-hover/checkbox:group-data-[checked]/checkbox:opacity-100 group-focus-visible/checkbox:group-data-[checked]/checkbox:opacity-100",
181
+ "group-hover/checkbox:group-data-[indeterminate]/checkbox:opacity-100 group-focus-visible/checkbox:group-data-[indeterminate]/checkbox:opacity-100",
182
+ ],
183
+ mark: ["text-primary-950 group-data-[disabled]/checkbox:text-line"],
184
+ },
185
+ },
186
+ ],
187
+ defaultVariants: {
188
+ color: "default",
189
+ size: "sm",
190
+ variant: "default",
191
+ },
192
+ });
193
+
194
+ function CheckboxCheckIcon({ className }: { className?: string }) {
195
+ return (
196
+ <svg
197
+ width="10"
198
+ height="8"
199
+ viewBox="0 0 10 8"
200
+ fill="none"
201
+ xmlns="http://www.w3.org/2000/svg"
202
+ aria-hidden
203
+ className={className}
204
+ >
205
+ <path
206
+ d="M1 3.5L4 6.5L9 1.5"
207
+ stroke="currentColor"
208
+ strokeWidth="1"
209
+ strokeLinecap="round"
210
+ strokeLinejoin="round"
211
+ />
212
+ </svg>
213
+ );
214
+ }
215
+
216
+ function CheckboxIndeterminateIcon({ className }: { className?: string }) {
217
+ return (
218
+ <svg
219
+ width="8"
220
+ height="2"
221
+ viewBox="0 0 8 2"
222
+ fill="none"
223
+ xmlns="http://www.w3.org/2000/svg"
224
+ aria-hidden
225
+ className={className}
226
+ >
227
+ <path d="M0 1H8" stroke="currentColor" strokeWidth="1" strokeLinecap="round" />
228
+ </svg>
229
+ );
230
+ }
231
+
232
+ type ElegantCheckboxGraphicProps = {
233
+ classNames: {
234
+ graphic: string;
235
+ outerRect: string;
236
+ overlayRect: string;
237
+ };
238
+ };
239
+
240
+ function ElegantCheckboxGraphic({ classNames }: ElegantCheckboxGraphicProps) {
241
+ const gradientId = `checkbox-hover-${useId().replace(/:/g, "")}`;
242
+
243
+ return (
244
+ <svg
245
+ width="16"
246
+ height="16"
247
+ viewBox="0 0 16 16"
248
+ fill="none"
249
+ xmlns="http://www.w3.org/2000/svg"
250
+ aria-hidden
251
+ className={classNames.graphic}
252
+ >
253
+ <defs>
254
+ <linearGradient id={gradientId} x1="0" y1="0" x2="0" y2="1">
255
+ <stop offset="0%" stopColor="oklab(100% 0 0 / 14%)" />
256
+ <stop offset="100%" stopColor="oklab(0% 0 0 / 3%)" />
257
+ </linearGradient>
258
+ </defs>
259
+ <rect width="16" height="16" rx="3" className={classNames.outerRect} />
260
+ <rect
261
+ width="16"
262
+ height="16"
263
+ rx="3"
264
+ fill={`url(#${gradientId})`}
265
+ className={classNames.overlayRect}
266
+ />
267
+ </svg>
268
+ );
269
+ }
270
+
271
+ export type CheckboxProps = StyledProps<BaseCheckbox.Root.Props> &
272
+ Omit<VariantProps<typeof checkbox>, "theme">;
273
+
274
+ export function Checkbox({
275
+ size,
276
+ color = "default",
277
+ variant = "default",
278
+ className,
279
+ ...props
280
+ }: CheckboxProps) {
281
+ const theme = useThemeFamily();
282
+ const { root, indicator, graphic, outerRect, overlayRect, mark, checkMark, indeterminateMark } =
283
+ checkbox({
284
+ theme,
285
+ size,
286
+ color,
287
+ variant,
288
+ });
289
+
290
+ if (theme === "elegant") {
291
+ return (
292
+ <BaseCheckbox.Root data-slot="checkbox" className={root({ className })} {...props}>
293
+ <ElegantCheckboxGraphic
294
+ classNames={{
295
+ graphic: graphic(),
296
+ outerRect: outerRect(),
297
+ overlayRect: overlayRect(),
298
+ }}
299
+ />
300
+ <BaseCheckbox.Indicator
301
+ keepMounted
302
+ data-slot="checkbox-indicator"
303
+ className={indicator()}
304
+ render={(indicatorProps, state) => (
305
+ <span
306
+ {...indicatorProps}
307
+ className={indicator({ className: indicatorProps.className })}
308
+ >
309
+ <CheckboxCheckIcon
310
+ className={mark({
311
+ className: checkMark({
312
+ className:
313
+ state.checked && !state.indeterminate ? "rotate-0 scale-100 opacity-100" : "",
314
+ }),
315
+ })}
316
+ />
317
+ <CheckboxIndeterminateIcon
318
+ className={mark({
319
+ className: indeterminateMark({
320
+ className: state.indeterminate ? "visible scale-x-100 opacity-100" : "",
321
+ }),
322
+ })}
323
+ />
324
+ </span>
325
+ )}
326
+ />
327
+ </BaseCheckbox.Root>
328
+ );
329
+ }
330
+
331
+ return (
332
+ <BaseCheckbox.Root data-slot="checkbox" className={root({ className })} {...props}>
333
+ <BaseCheckbox.Indicator
334
+ keepMounted
335
+ data-slot="checkbox-indicator"
336
+ className={indicator()}
337
+ render={(indicatorProps, state) => (
338
+ <CheckboxIndicator
339
+ {...indicatorProps}
340
+ checked={state.checked || state.indeterminate}
341
+ disabled={state.disabled}
342
+ mark={state.indeterminate ? "minus" : "check"}
343
+ size={size}
344
+ fill={variant === "primary" || color === "primary" ? "yellow" : "black"}
345
+ />
346
+ )}
347
+ />
348
+ </BaseCheckbox.Root>
349
+ );
350
+ }
@@ -0,0 +1,2 @@
1
+ export { Checkbox } from "./checkbox.tsx";
2
+ export type { CheckboxProps } from "./checkbox.tsx";