solid-element-ui 0.2.4 → 0.2.6

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 (96) hide show
  1. package/dist/{src/alert-dialog → alert-dialog}/alert-dialog.d.ts +1 -1
  2. package/dist/{src/badge → badge}/badge.d.ts +2 -2
  3. package/dist/index.css +3 -1
  4. package/dist/index.js +16097 -17258
  5. package/dist/{src/separator → separator}/separator.d.ts +11 -5
  6. package/dist/{src/skeleton → skeleton}/skeleton.d.ts +2 -2
  7. package/dist/{src/slider → slider}/slider.d.ts +12 -0
  8. package/dist/{src/toast → toast}/toast.d.ts +3 -1
  9. package/dist/{src/toggle-button → toggle-button}/toggle-button.d.ts +0 -3
  10. package/package.json +11 -7
  11. package/src/accordion/accordion.tsx +80 -0
  12. package/src/alert/alert.tsx +86 -0
  13. package/src/alert-dialog/alert-dialog.tsx +129 -0
  14. package/src/badge/badge.tsx +49 -0
  15. package/src/breadcrumbs/breadcrumbs.tsx +69 -0
  16. package/src/button/button.tsx +216 -0
  17. package/src/checkbox/checkbox.tsx +63 -0
  18. package/src/collapsible/collapsible.tsx +46 -0
  19. package/src/color-area/color-area.tsx +46 -0
  20. package/src/color-channel-field/color-channel-field.tsx +46 -0
  21. package/src/color-field/color-field.tsx +64 -0
  22. package/src/color-slider/color-slider.tsx +60 -0
  23. package/src/color-swatch/color-swatch.tsx +33 -0
  24. package/src/color-wheel/color-wheel.tsx +50 -0
  25. package/src/combobox/combobox.tsx +97 -0
  26. package/src/context-menu/context-menu.tsx +102 -0
  27. package/src/dialog/dialog.tsx +101 -0
  28. package/src/dropdown-menu/dropdown-menu.tsx +111 -0
  29. package/src/file-field/file-field.tsx +114 -0
  30. package/src/hover-card/hover-card.tsx +61 -0
  31. package/src/image/image.tsx +59 -0
  32. package/src/index.tsx +94 -0
  33. package/src/link/link.tsx +64 -0
  34. package/src/menubar/menubar.tsx +85 -0
  35. package/src/meter/meter.tsx +89 -0
  36. package/src/navigation-menu/navigation-menu.tsx +90 -0
  37. package/src/number-field/number-field.tsx +79 -0
  38. package/src/pagination/pagination.tsx +67 -0
  39. package/src/popover/popover.tsx +58 -0
  40. package/src/progress/progress.tsx +83 -0
  41. package/src/radio-group/radio-group.tsx +94 -0
  42. package/src/rating-group/rating-group.tsx +101 -0
  43. package/src/search/search.tsx +99 -0
  44. package/src/segmented-control/segmented-control.tsx +92 -0
  45. package/src/select/select.tsx +163 -0
  46. package/src/separator/separator.tsx +64 -0
  47. package/src/skeleton/skeleton.tsx +73 -0
  48. package/src/slider/slider.tsx +94 -0
  49. package/src/style/global.css +156 -0
  50. package/src/switch/switch.tsx +104 -0
  51. package/src/tabs/tabs.tsx +73 -0
  52. package/src/text-field/text-field.tsx +97 -0
  53. package/src/time-field/time-field.tsx +103 -0
  54. package/src/toast/toast.tsx +132 -0
  55. package/src/toggle-button/toggle-button.tsx +69 -0
  56. package/src/toggle-group/toggle-group.tsx +85 -0
  57. package/src/tooltip/tooltip.tsx +73 -0
  58. /package/dist/{src/accordion → accordion}/accordion.d.ts +0 -0
  59. /package/dist/{src/alert → alert}/alert.d.ts +0 -0
  60. /package/dist/{src/breadcrumbs → breadcrumbs}/breadcrumbs.d.ts +0 -0
  61. /package/dist/{src/button → button}/button.d.ts +0 -0
  62. /package/dist/{src/checkbox → checkbox}/checkbox.d.ts +0 -0
  63. /package/dist/{src/collapsible → collapsible}/collapsible.d.ts +0 -0
  64. /package/dist/{src/color-area → color-area}/color-area.d.ts +0 -0
  65. /package/dist/{src/color-channel-field → color-channel-field}/color-channel-field.d.ts +0 -0
  66. /package/dist/{src/color-field → color-field}/color-field.d.ts +0 -0
  67. /package/dist/{src/color-slider → color-slider}/color-slider.d.ts +0 -0
  68. /package/dist/{src/color-swatch → color-swatch}/color-swatch.d.ts +0 -0
  69. /package/dist/{src/color-wheel → color-wheel}/color-wheel.d.ts +0 -0
  70. /package/dist/{src/combobox → combobox}/combobox.d.ts +0 -0
  71. /package/dist/{src/context-menu → context-menu}/context-menu.d.ts +0 -0
  72. /package/dist/{src/dialog → dialog}/dialog.d.ts +0 -0
  73. /package/dist/{src/dropdown-menu → dropdown-menu}/dropdown-menu.d.ts +0 -0
  74. /package/dist/{src/file-field → file-field}/file-field.d.ts +0 -0
  75. /package/dist/{src/hover-card → hover-card}/hover-card.d.ts +0 -0
  76. /package/dist/{src/image → image}/image.d.ts +0 -0
  77. /package/dist/{src/index.d.ts → index.d.ts} +0 -0
  78. /package/dist/{src/link → link}/link.d.ts +0 -0
  79. /package/dist/{src/menubar → menubar}/menubar.d.ts +0 -0
  80. /package/dist/{src/meter → meter}/meter.d.ts +0 -0
  81. /package/dist/{src/navigation-menu → navigation-menu}/navigation-menu.d.ts +0 -0
  82. /package/dist/{src/number-field → number-field}/number-field.d.ts +0 -0
  83. /package/dist/{src/pagination → pagination}/pagination.d.ts +0 -0
  84. /package/dist/{src/popover → popover}/popover.d.ts +0 -0
  85. /package/dist/{src/progress → progress}/progress.d.ts +0 -0
  86. /package/dist/{src/radio-group → radio-group}/radio-group.d.ts +0 -0
  87. /package/dist/{src/rating-group → rating-group}/rating-group.d.ts +0 -0
  88. /package/dist/{src/search → search}/search.d.ts +0 -0
  89. /package/dist/{src/segmented-control → segmented-control}/segmented-control.d.ts +0 -0
  90. /package/dist/{src/select → select}/select.d.ts +0 -0
  91. /package/dist/{src/switch → switch}/switch.d.ts +0 -0
  92. /package/dist/{src/tabs → tabs}/tabs.d.ts +0 -0
  93. /package/dist/{src/text-field → text-field}/text-field.d.ts +0 -0
  94. /package/dist/{src/time-field → time-field}/time-field.d.ts +0 -0
  95. /package/dist/{src/toggle-group → toggle-group}/toggle-group.d.ts +0 -0
  96. /package/dist/{src/tooltip → tooltip}/tooltip.d.ts +0 -0
@@ -0,0 +1,216 @@
1
+ import { Button as KButton } from "@kobalte/core/button";
2
+ import { splitProps, type JSX, type ComponentProps, Show } from "solid-js";
3
+ import { tv, type VariantProps } from "tailwind-variants";
4
+ import { LoaderCircle } from "lucide-solid";
5
+
6
+ // --- 样式定义保持不变 ---
7
+ const buttonStyles = tv(
8
+ {
9
+ slots: {
10
+ base: "inline-flex items-center cursor-pointer justify-center rounded-sm text-sm font-medium transition-all duration-200 active:scale-[0.98] focus:outline-none disabled:opacity-50 disabled:pointer-events-none",
11
+ icon: "animate-spin -ml-1 mr-2 h-4 w-4 text-current",
12
+ },
13
+ variants: {
14
+ size: {
15
+ sm: { base: "h-6 px-2 text-xs" },
16
+ md: { base: "h-8 px-4 text-sm" },
17
+ lg: { base: "h-10 px-6 text-base" },
18
+ },
19
+ loading: {
20
+ true: {
21
+ base: "pointer-events-none opacity-70",
22
+ },
23
+ },
24
+ variant: {
25
+ default: { base: "bg-main text-reversal" },
26
+ outline: {
27
+ base: "border border-base hover:border-primary hover:text-primary",
28
+ },
29
+ dashed: {
30
+ base: "border border-dashed border-base hover:border-primary hover:text-primary",
31
+ },
32
+ filled: { base: "bg-main/5 hover:bg-main/10" },
33
+ text: { base: "hover:bg-main/10" },
34
+ },
35
+ color: {
36
+ primary: { base: "" },
37
+ success: { base: "" },
38
+ warning: { base: "" },
39
+ danger: { base: "" },
40
+ },
41
+ },
42
+ compoundVariants: [
43
+ {
44
+ variant: "default",
45
+ color: "primary",
46
+ class: {
47
+ base: "bg-primary text-white border-primary hover:bg-primary/70 hover:border-primary/70",
48
+ },
49
+ },
50
+ {
51
+ variant: "default",
52
+ color: "success",
53
+ class: {
54
+ base: "bg-success text-white border-success hover:bg-success/70 hover:border-success/70",
55
+ },
56
+ },
57
+ {
58
+ variant: "default",
59
+ color: "warning",
60
+ class: {
61
+ base: "bg-warning text-white border-warning hover:bg-warning/70 hover:border-warning/70",
62
+ },
63
+ },
64
+ {
65
+ variant: "default",
66
+ color: "danger",
67
+ class: {
68
+ base: "bg-danger text-white border-danger hover:bg-danger/70 hover:border-danger/70",
69
+ },
70
+ },
71
+ // --- outline 和 dashed 类型 ---
72
+ {
73
+ variant: ["outline", "dashed"],
74
+ color: "primary",
75
+ class: {
76
+ base: "text-primary border-primary hover:border-primary/70 hover:text-primary/70",
77
+ },
78
+ },
79
+ {
80
+ variant: ["outline", "dashed"],
81
+ color: "success",
82
+ class: {
83
+ base: "text-success border-success hover:border-success/70 hover:text-success/70",
84
+ },
85
+ },
86
+ {
87
+ variant: ["outline", "dashed"],
88
+ color: "warning",
89
+ class: {
90
+ base: "text-warning border-warning hover:border-warning/70 hover:text-warning/70",
91
+ },
92
+ },
93
+ {
94
+ variant: ["outline", "dashed"],
95
+ color: "danger",
96
+ class: {
97
+ base: "text-danger border-danger hover:border-danger/70 hover:text-danger/70",
98
+ },
99
+ },
100
+
101
+ // --- filled 类型 ---
102
+ {
103
+ variant: "filled",
104
+ color: "primary",
105
+ class: {
106
+ base: "text-primary bg-primary/5 hover:bg-primary/10",
107
+ },
108
+ },
109
+ {
110
+ variant: "filled",
111
+ color: "success",
112
+ class: {
113
+ base: "text-success bg-success/5 hover:bg-success/10",
114
+ },
115
+ },
116
+ {
117
+ variant: "filled",
118
+ color: "warning",
119
+ class: {
120
+ base: "text-warning bg-warning/5 hover:bg-warning/10",
121
+ },
122
+ },
123
+ {
124
+ variant: "filled",
125
+ color: "danger",
126
+ class: {
127
+ base: "text-danger bg-danger/5 hover:bg-danger/10",
128
+ },
129
+ },
130
+ // --- text 类型 ---
131
+ {
132
+ variant: "text",
133
+ color: "primary",
134
+ class: {
135
+ base: "text-primary hover:bg-primary/10",
136
+ },
137
+ },
138
+ {
139
+ variant: "text",
140
+ color: "success",
141
+ class: {
142
+ base: "text-success hover:bg-success/10",
143
+ },
144
+ },
145
+ {
146
+ variant: "text",
147
+ color: "warning",
148
+ class: {
149
+ base: "text-warning hover:bg-warning/10",
150
+ },
151
+ },
152
+ {
153
+ variant: "text",
154
+ color: "danger",
155
+ class: {
156
+ base: "text-danger hover:bg-danger/10",
157
+ },
158
+ },
159
+ ],
160
+ defaultVariants: {
161
+ size: "md",
162
+ variant: "default",
163
+ },
164
+ },
165
+ { twMerge: true },
166
+ );
167
+
168
+ type ButtonVariants = VariantProps<typeof buttonStyles>;
169
+
170
+ export interface ButtonProps
171
+ extends ComponentProps<typeof KButton>, ButtonVariants {
172
+ loading?: boolean;
173
+ leftIcon?: JSX.Element;
174
+ rightIcon?: JSX.Element;
175
+ }
176
+
177
+ export const Button = (props: ButtonProps) => {
178
+ const [local, variantKeys, others] = splitProps(
179
+ props,
180
+ ["class", "children", "loading", "leftIcon", "rightIcon", "disabled"],
181
+ ["variant", "size", "color", "loading"],
182
+ );
183
+
184
+ // 2. 调用 styles 获取 slots
185
+ // 注意:将 local.class 传入 base 槽位
186
+ const styles = () =>
187
+ buttonStyles({
188
+ ...variantKeys,
189
+ class: local.class,
190
+ });
191
+
192
+ return (
193
+ <KButton
194
+ class={styles().base()}
195
+ disabled={local.disabled || local.loading}
196
+ {...others}
197
+ >
198
+ {/* Loading 状态显示 */}
199
+ <Show when={local.loading}>
200
+ <LoaderCircle class={styles().icon()} />
201
+ </Show>
202
+
203
+ {/* 非 Loading 状态下的 Left Icon */}
204
+ <Show when={!local.loading && local.leftIcon}>
205
+ <span class="mr-2 inline-flex">{local.leftIcon}</span>
206
+ </Show>
207
+
208
+ {local.children}
209
+
210
+ {/* Right Icon */}
211
+ <Show when={local.rightIcon}>
212
+ <span class="ml-2 inline-flex">{local.rightIcon}</span>
213
+ </Show>
214
+ </KButton>
215
+ );
216
+ };
@@ -0,0 +1,63 @@
1
+ import { Checkbox as KCheckbox } from "@kobalte/core/checkbox";
2
+ import { splitProps, type ComponentProps, type JSX } from "solid-js";
3
+ import { tv } from "tailwind-variants";
4
+ import { Check } from "lucide-solid";
5
+
6
+ // TODO 添加checkbox 的几种形状尺寸,看情况吧
7
+
8
+
9
+ const checkboxStyles = tv(
10
+ {
11
+ slots: {
12
+ root: "group flex items-center gap-2 cursor-pointer disabled:cursor-not-allowed disabled:opacity-50",
13
+ control: [
14
+ "flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border border-base transition-all",
15
+ "group-focus-visible:outline-none group-focus-visible:ring-2 group-focus-visible:ring-zinc-950",
16
+ "data-[checked]:bg-zinc-900 data-[checked]:border-zinc-900 data-[checked]:text-zinc-50",
17
+ "data-[disabled]:bg-zinc-400 data-[disabled]:border-zinc-400",
18
+ "dark:data-[checked]:bg-zinc-50 dark:data-[checked]:text-zinc-900 dark:group-focus-visible:ring-zinc-300",
19
+ ],
20
+ label: "text-sm font-medium leading-none select-none data-[disabled]:text-zinc-400",
21
+ indicator: "h-3.5 w-3.5",
22
+ description: "text-sm text-zinc-500",
23
+ errorMessage: "text-sm text-red-500",
24
+ },
25
+ },
26
+ {
27
+ twMerge: true,
28
+ },
29
+ );
30
+
31
+ const { root, control, label, indicator, description, errorMessage } = checkboxStyles();
32
+ export interface CheckboxProps extends ComponentProps<typeof KCheckbox> {
33
+ label?: JSX.Element;
34
+ }
35
+
36
+ export const Checkbox = (props: CheckboxProps) => {
37
+ const [local, others] = splitProps(props, [
38
+ "label",
39
+ "class",
40
+ "description",
41
+ "errorMessage",
42
+ ]);
43
+
44
+ return (
45
+ <KCheckbox class={root({ class: local.class })} {...others}>
46
+ <KCheckbox.Input />
47
+ <KCheckbox.Control class={control()}>
48
+ <KCheckbox.Indicator class={indicator()}>
49
+ <Check class={indicator()} stroke-width={3} />
50
+ </KCheckbox.Indicator>
51
+ </KCheckbox.Control>
52
+ {local.label && (
53
+ <KCheckbox.Label class={label()}>{local.label}</KCheckbox.Label>
54
+ )}
55
+ <KCheckbox.Description class={description()}>
56
+ {local.description}
57
+ </KCheckbox.Description>
58
+ <KCheckbox.ErrorMessage class={errorMessage()}>
59
+ {local.errorMessage}
60
+ </KCheckbox.ErrorMessage>
61
+ </KCheckbox>
62
+ );
63
+ };
@@ -0,0 +1,46 @@
1
+ import { Collapsible as KCollapsible } from "@kobalte/core/collapsible";
2
+ import { splitProps, type JSX, type ComponentProps } from "solid-js";
3
+ import { tv } from "tailwind-variants";
4
+ import { ChevronDown } from "lucide-solid";
5
+
6
+ const collapsibleStyles = tv(
7
+ {
8
+ slots: {
9
+ root: "w-full space-y-2",
10
+ trigger:
11
+ "flex w-full items-center justify-between border border-light bg-foreground px-4 py-2 text-sm font-medium hover:bg-foreground/80 transition-all group mb-0",
12
+ content:
13
+ "overflow-hidden text-sm transition-all data-[expanded]:animate-collapsible-down data-[closed]:animate-collapsible-up",
14
+ contentInner:
15
+ "px-4 py-3 text-main border border-light !border-t-0",
16
+ icon: "h-4 w-4 text-zinc-500 transition-transform duration-200 group-data-[expanded]:rotate-180",
17
+ },
18
+ },
19
+ {
20
+ twMerge: true,
21
+ },
22
+ );
23
+
24
+ const { root, trigger, content, contentInner, icon } = collapsibleStyles();
25
+
26
+ interface CollapsibleProps extends ComponentProps<typeof KCollapsible> {
27
+ title: JSX.Element;
28
+ children: JSX.Element;
29
+ }
30
+
31
+ export const Collapsible = (props: CollapsibleProps) => {
32
+ const [local, others] = splitProps(props, ["title", "children", "class"]);
33
+
34
+ return (
35
+ <KCollapsible class={root({ class: local.class })} {...others}>
36
+ <KCollapsible.Trigger class={trigger()}>
37
+ <span>{local.title}</span>
38
+ <ChevronDown class={icon()} />
39
+ </KCollapsible.Trigger>
40
+
41
+ <KCollapsible.Content class={content()}>
42
+ <div class={contentInner()}>{local.children}</div>
43
+ </KCollapsible.Content>
44
+ </KCollapsible>
45
+ );
46
+ };
@@ -0,0 +1,46 @@
1
+ import { ColorArea as KColorArea } from "@kobalte/core/color-area";
2
+ import { splitProps, type ComponentProps } from "solid-js";
3
+ import { tv } from "tailwind-variants";
4
+
5
+ const colorAreaStyles = tv(
6
+ {
7
+ slots: {
8
+ root: "relative h-48 w-full shrink-0 rounded-lg border border-base touch-none",
9
+ background: "h-full w-full rounded-[inherit]",
10
+ thumb: [
11
+ "z-10 h-5 w-5 rounded-full border-2 border-white bg-transparent shadow-md transition-[transform]",
12
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-zinc-950 focus-visible:ring-offset-2",
13
+ "hover:scale-110 active:scale-90 cursor-grab active:cursor-grabbing",
14
+ ],
15
+ },
16
+ },
17
+ {
18
+ twMerge: true,
19
+ },
20
+ );
21
+
22
+ const { root, background, thumb } = colorAreaStyles();
23
+
24
+ export interface ColorAreaProps extends ComponentProps<typeof KColorArea> {}
25
+
26
+ export const ColorArea = (props: ColorAreaProps) => {
27
+ const [local, others] = splitProps(props, ["class"]);
28
+
29
+ return (
30
+ <KColorArea class={root({ class: local.class })} {...others}>
31
+ <KColorArea.Background
32
+ class={background()}
33
+ // 默认背景,通常实际使用时会根据 Hue 滑块动态改变这里的红色部分
34
+ style={{
35
+ background:
36
+ "linear-gradient(to top, #000, transparent), linear-gradient(to right, #fff, transparent), red",
37
+ }}
38
+ />
39
+ <KColorArea.Thumb class={thumb()}>
40
+ {/* 修复点:ColorArea 需要分别定义 X 和 Y 的隐藏输入框 */}
41
+ <KColorArea.HiddenInputX />
42
+ <KColorArea.HiddenInputY />
43
+ </KColorArea.Thumb>
44
+ </KColorArea>
45
+ );
46
+ };
@@ -0,0 +1,46 @@
1
+ import { ColorChannelField as KColorChannelField } from "@kobalte/core/color-channel-field";
2
+ import { splitProps, type ComponentProps } from "solid-js";
3
+ import { tv } from "tailwind-variants";
4
+
5
+ const fieldStyles = tv(
6
+ {
7
+ slots: {
8
+ root: "flex flex-col gap-1.5 w-full",
9
+ label: "text-sm font-medium text-zinc-900 dark:text-zinc-100 select-none",
10
+ input: [
11
+ "h-9 w-full rounded-md border border-zinc-200 bg-white px-3 py-1 text-sm shadow-sm transition-colors",
12
+ "placeholder:text-zinc-500 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-zinc-950",
13
+ "disabled:cursor-not-allowed disabled:opacity-50",
14
+ "dark:border-zinc-800 dark:bg-zinc-950 dark:focus-visible:ring-zinc-300",
15
+ ],
16
+ },
17
+ },
18
+ {
19
+ twMerge: true,
20
+ },
21
+ );
22
+
23
+ const { root, label, input } = fieldStyles();
24
+
25
+ export interface ColorChannelFieldProps
26
+ extends ComponentProps<typeof KColorChannelField> {
27
+ label?: string;
28
+ }
29
+
30
+
31
+ // TODO channel 问题
32
+
33
+ export const ColorChannelField = (props: ColorChannelFieldProps) => {
34
+ const [local, others] = splitProps(props, ["label", "class"]);
35
+
36
+ return (
37
+ <KColorChannelField class={root({ class: local.class })} {...others}>
38
+ {local.label && (
39
+ <KColorChannelField.Label class={label()}>
40
+ {local.label}
41
+ </KColorChannelField.Label>
42
+ )}
43
+ <KColorChannelField.Input class={input()} />
44
+ </KColorChannelField>
45
+ );
46
+ };
@@ -0,0 +1,64 @@
1
+ import { ColorField as KColorField } from "@kobalte/core/color-field";
2
+ import { splitProps, type ComponentProps } from "solid-js";
3
+ import { tv } from "tailwind-variants";
4
+
5
+ const colorFieldStyles = tv(
6
+ {
7
+ slots: {
8
+ root: "flex flex-col gap-1.5 w-full",
9
+ label: "text-sm font-medium text-zinc-900 dark:text-zinc-100 select-none disabled:opacity-50",
10
+ input: [
11
+ "h-9 w-full rounded-md border border-zinc-200 bg-white px-3 py-1 text-sm shadow-sm transition-all",
12
+ "placeholder:text-zinc-500 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-zinc-950",
13
+ "data-[invalid]:border-red-500 data-[invalid]:focus-visible:ring-red-500",
14
+ "disabled:cursor-not-allowed disabled:opacity-50",
15
+ "dark:border-zinc-800 dark:bg-zinc-950 dark:focus-visible:ring-zinc-300",
16
+ ],
17
+ description: "text-[0.8rem] text-zinc-500 dark:text-zinc-400",
18
+ errorMessage: "text-[0.8rem] font-medium text-red-500",
19
+ },
20
+ },
21
+ {
22
+ twMerge: true,
23
+ },
24
+ );
25
+
26
+ const { root, label, input, description, errorMessage } = colorFieldStyles();
27
+
28
+ export interface ColorFieldProps extends ComponentProps<typeof KColorField> {
29
+ label?: string;
30
+ desc?: string;
31
+ error?: string;
32
+ }
33
+
34
+ export const ColorField = (props: ColorFieldProps) => {
35
+ const [local, others] = splitProps(props, [
36
+ "label",
37
+ "desc",
38
+ "error",
39
+ "class",
40
+ ]);
41
+
42
+ return (
43
+ <KColorField
44
+ class={root({ class: local.class })}
45
+ validationState={local.error ? "invalid" : "valid"}
46
+ {...others}
47
+ >
48
+ {local.label && (
49
+ <KColorField.Label class={label()}>
50
+ {local.label}
51
+ </KColorField.Label>
52
+ )}
53
+ <KColorField.Input class={input()} placeholder="#FFFFFF" />
54
+ {local.desc && !local.error && (
55
+ <KColorField.Description class={description()}>
56
+ {local.desc}
57
+ </KColorField.Description>
58
+ )}
59
+ <KColorField.ErrorMessage class={errorMessage()}>
60
+ {local.error}
61
+ </KColorField.ErrorMessage>
62
+ </KColorField>
63
+ );
64
+ };
@@ -0,0 +1,60 @@
1
+ import { ColorSlider as KColorSlider } from "@kobalte/core/color-slider";
2
+ import { splitProps, type ComponentProps } from "solid-js";
3
+ import { tv } from "tailwind-variants";
4
+
5
+ // TODO defaultValue,还有channel 的问题
6
+
7
+ const sliderStyles = tv(
8
+ {
9
+ slots: {
10
+ root: "relative flex flex-col items-center select-none touch-none w-full gap-2",
11
+ label: "text-sm font-medium text-zinc-900 dark:text-zinc-100 self-start",
12
+ track: "relative h-3 w-full rounded-full border border-black/5 dark:border-white/10",
13
+ thumb: [
14
+ "z-10 h-5 w-5 rounded-full border-2 border-white bg-transparent shadow-md transition-[transform]",
15
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-zinc-950 focus-visible:ring-offset-2",
16
+ "hover:scale-110 active:scale-90 cursor-grab active:cursor-grabbing",
17
+ ],
18
+ valueLabel: "text-xs text-zinc-500 dark:text-zinc-400 tabular-nums",
19
+ },
20
+ },
21
+ {
22
+ twMerge: true,
23
+ },
24
+ );
25
+
26
+ const { root, label, track, thumb, valueLabel } = sliderStyles();
27
+
28
+ export interface ColorSliderProps extends ComponentProps<typeof KColorSlider> {
29
+ label?: string;
30
+ showValue?: boolean;
31
+ }
32
+
33
+ export const ColorSlider = (props: ColorSliderProps) => {
34
+ const [local, others] = splitProps(props, ["label", "showValue", "class"]);
35
+
36
+ return (
37
+ <KColorSlider class={root({ class: local.class })} {...others}>
38
+ <div class="flex w-full justify-between items-center">
39
+ {local.label && (
40
+ <KColorSlider.Label class={label()}>
41
+ {local.label}
42
+ </KColorSlider.Label>
43
+ )}
44
+ {local.showValue && (
45
+ <KColorSlider.ValueLabel class={valueLabel()} />
46
+ )}
47
+ </div>
48
+ <KColorSlider.Track
49
+ class={track()}
50
+ style={{
51
+ background: "var(--kb-color-slider-track-background)",
52
+ }}
53
+ >
54
+ <KColorSlider.Thumb class={thumb()}>
55
+ <KColorSlider.Input />
56
+ </KColorSlider.Thumb>
57
+ </KColorSlider.Track>
58
+ </KColorSlider>
59
+ );
60
+ };
@@ -0,0 +1,33 @@
1
+ import { ColorSwatch as KColorSwatch } from "@kobalte/core/color-swatch";
2
+ import { splitProps, type ComponentProps } from "solid-js";
3
+ import { tv } from "tailwind-variants";
4
+
5
+ const colorSwatchStyles = tv(
6
+ {
7
+ base: [
8
+ "h-8 w-8 rounded-md border border-black/10 shadow-sm transition-transform",
9
+ "hover:scale-105 select-none dark:border-white/20",
10
+ ],
11
+ },
12
+ {
13
+ twMerge: true,
14
+ },
15
+ );
16
+
17
+
18
+ // TODO 源代码问题
19
+
20
+ // FIXME 源代码问题
21
+
22
+ export interface ColorSwatchProps extends ComponentProps<typeof KColorSwatch> {}
23
+
24
+ export const ColorSwatch = (props: ColorSwatchProps) => {
25
+ const [local, others] = splitProps(props, ["class", "style"]);
26
+
27
+ return (
28
+ <KColorSwatch
29
+ class={colorSwatchStyles({ class: local.class })}
30
+ {...others}
31
+ />
32
+ );
33
+ };
@@ -0,0 +1,50 @@
1
+ import { ColorWheel as KColorWheel } from "@kobalte/core/color-wheel";
2
+ import { splitProps, type ComponentProps } from "solid-js";
3
+ import { tv } from "tailwind-variants";
4
+
5
+ // FIXME 颜色选项都有源代码问题,注意查看原始kobalte的问题。
6
+
7
+ const colorWheelStyles = tv(
8
+ {
9
+ slots: {
10
+ root: "relative flex flex-col items-center justify-center select-none touch-none",
11
+ track: "relative rounded-full border border-black/5 dark:border-white/10",
12
+ thumb: [
13
+ "z-10 h-5 w-5 rounded-full border-2 border-white bg-transparent shadow-md transition-[transform]",
14
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-zinc-950 focus-visible:ring-offset-2",
15
+ "hover:scale-110 active:scale-90 cursor-grab active:cursor-grabbing",
16
+ ],
17
+ },
18
+ },
19
+ {
20
+ twMerge: true,
21
+ },
22
+ );
23
+
24
+ const { root, track, thumb } = colorWheelStyles();
25
+
26
+ export interface ColorWheelProps extends ComponentProps<typeof KColorWheel> {
27
+ size?: number;
28
+ }
29
+
30
+ export const ColorWheel = (props: ColorWheelProps) => {
31
+ const [local, others] = splitProps(props, ["size", "class"]);
32
+
33
+ return (
34
+ <KColorWheel class={root({ class: local.class })} {...others}>
35
+
36
+ <KColorWheel.Track
37
+ class={track()}
38
+ style={{
39
+ width: `${local.size || 160}px`,
40
+ height: `${local.size || 160}px`,
41
+ background: "var(--kb-color-wheel-track-background)",
42
+ }}
43
+ >
44
+ <KColorWheel.Thumb class={thumb()}>
45
+ <KColorWheel.Input />
46
+ </KColorWheel.Thumb>
47
+ </KColorWheel.Track>
48
+ </KColorWheel>
49
+ );
50
+ };