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.
- package/dist/{src/alert-dialog → alert-dialog}/alert-dialog.d.ts +1 -1
- package/dist/{src/badge → badge}/badge.d.ts +2 -2
- package/dist/index.css +3 -1
- package/dist/index.js +16097 -17258
- package/dist/{src/separator → separator}/separator.d.ts +11 -5
- package/dist/{src/skeleton → skeleton}/skeleton.d.ts +2 -2
- package/dist/{src/slider → slider}/slider.d.ts +12 -0
- package/dist/{src/toast → toast}/toast.d.ts +3 -1
- package/dist/{src/toggle-button → toggle-button}/toggle-button.d.ts +0 -3
- package/package.json +11 -7
- package/src/accordion/accordion.tsx +80 -0
- package/src/alert/alert.tsx +86 -0
- package/src/alert-dialog/alert-dialog.tsx +129 -0
- package/src/badge/badge.tsx +49 -0
- package/src/breadcrumbs/breadcrumbs.tsx +69 -0
- package/src/button/button.tsx +216 -0
- package/src/checkbox/checkbox.tsx +63 -0
- package/src/collapsible/collapsible.tsx +46 -0
- package/src/color-area/color-area.tsx +46 -0
- package/src/color-channel-field/color-channel-field.tsx +46 -0
- package/src/color-field/color-field.tsx +64 -0
- package/src/color-slider/color-slider.tsx +60 -0
- package/src/color-swatch/color-swatch.tsx +33 -0
- package/src/color-wheel/color-wheel.tsx +50 -0
- package/src/combobox/combobox.tsx +97 -0
- package/src/context-menu/context-menu.tsx +102 -0
- package/src/dialog/dialog.tsx +101 -0
- package/src/dropdown-menu/dropdown-menu.tsx +111 -0
- package/src/file-field/file-field.tsx +114 -0
- package/src/hover-card/hover-card.tsx +61 -0
- package/src/image/image.tsx +59 -0
- package/src/index.tsx +94 -0
- package/src/link/link.tsx +64 -0
- package/src/menubar/menubar.tsx +85 -0
- package/src/meter/meter.tsx +89 -0
- package/src/navigation-menu/navigation-menu.tsx +90 -0
- package/src/number-field/number-field.tsx +79 -0
- package/src/pagination/pagination.tsx +67 -0
- package/src/popover/popover.tsx +58 -0
- package/src/progress/progress.tsx +83 -0
- package/src/radio-group/radio-group.tsx +94 -0
- package/src/rating-group/rating-group.tsx +101 -0
- package/src/search/search.tsx +99 -0
- package/src/segmented-control/segmented-control.tsx +92 -0
- package/src/select/select.tsx +163 -0
- package/src/separator/separator.tsx +64 -0
- package/src/skeleton/skeleton.tsx +73 -0
- package/src/slider/slider.tsx +94 -0
- package/src/style/global.css +156 -0
- package/src/switch/switch.tsx +104 -0
- package/src/tabs/tabs.tsx +73 -0
- package/src/text-field/text-field.tsx +97 -0
- package/src/time-field/time-field.tsx +103 -0
- package/src/toast/toast.tsx +132 -0
- package/src/toggle-button/toggle-button.tsx +69 -0
- package/src/toggle-group/toggle-group.tsx +85 -0
- package/src/tooltip/tooltip.tsx +73 -0
- /package/dist/{src/accordion → accordion}/accordion.d.ts +0 -0
- /package/dist/{src/alert → alert}/alert.d.ts +0 -0
- /package/dist/{src/breadcrumbs → breadcrumbs}/breadcrumbs.d.ts +0 -0
- /package/dist/{src/button → button}/button.d.ts +0 -0
- /package/dist/{src/checkbox → checkbox}/checkbox.d.ts +0 -0
- /package/dist/{src/collapsible → collapsible}/collapsible.d.ts +0 -0
- /package/dist/{src/color-area → color-area}/color-area.d.ts +0 -0
- /package/dist/{src/color-channel-field → color-channel-field}/color-channel-field.d.ts +0 -0
- /package/dist/{src/color-field → color-field}/color-field.d.ts +0 -0
- /package/dist/{src/color-slider → color-slider}/color-slider.d.ts +0 -0
- /package/dist/{src/color-swatch → color-swatch}/color-swatch.d.ts +0 -0
- /package/dist/{src/color-wheel → color-wheel}/color-wheel.d.ts +0 -0
- /package/dist/{src/combobox → combobox}/combobox.d.ts +0 -0
- /package/dist/{src/context-menu → context-menu}/context-menu.d.ts +0 -0
- /package/dist/{src/dialog → dialog}/dialog.d.ts +0 -0
- /package/dist/{src/dropdown-menu → dropdown-menu}/dropdown-menu.d.ts +0 -0
- /package/dist/{src/file-field → file-field}/file-field.d.ts +0 -0
- /package/dist/{src/hover-card → hover-card}/hover-card.d.ts +0 -0
- /package/dist/{src/image → image}/image.d.ts +0 -0
- /package/dist/{src/index.d.ts → index.d.ts} +0 -0
- /package/dist/{src/link → link}/link.d.ts +0 -0
- /package/dist/{src/menubar → menubar}/menubar.d.ts +0 -0
- /package/dist/{src/meter → meter}/meter.d.ts +0 -0
- /package/dist/{src/navigation-menu → navigation-menu}/navigation-menu.d.ts +0 -0
- /package/dist/{src/number-field → number-field}/number-field.d.ts +0 -0
- /package/dist/{src/pagination → pagination}/pagination.d.ts +0 -0
- /package/dist/{src/popover → popover}/popover.d.ts +0 -0
- /package/dist/{src/progress → progress}/progress.d.ts +0 -0
- /package/dist/{src/radio-group → radio-group}/radio-group.d.ts +0 -0
- /package/dist/{src/rating-group → rating-group}/rating-group.d.ts +0 -0
- /package/dist/{src/search → search}/search.d.ts +0 -0
- /package/dist/{src/segmented-control → segmented-control}/segmented-control.d.ts +0 -0
- /package/dist/{src/select → select}/select.d.ts +0 -0
- /package/dist/{src/switch → switch}/switch.d.ts +0 -0
- /package/dist/{src/tabs → tabs}/tabs.d.ts +0 -0
- /package/dist/{src/text-field → text-field}/text-field.d.ts +0 -0
- /package/dist/{src/time-field → time-field}/time-field.d.ts +0 -0
- /package/dist/{src/toggle-group → toggle-group}/toggle-group.d.ts +0 -0
- /package/dist/{src/tooltip → tooltip}/tooltip.d.ts +0 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// import { TimeField as KTimeField } from "@kobalte/core/time-field";
|
|
2
|
+
// import { splitProps, For, type ComponentProps, Show } from "solid-js";
|
|
3
|
+
// import { tv, type VariantProps } from "tailwind-variants";
|
|
4
|
+
|
|
5
|
+
// const timeFieldStyles = tv({
|
|
6
|
+
// slots: {
|
|
7
|
+
// root: "flex flex-col gap-1.5 w-full",
|
|
8
|
+
// label: "text-sm font-medium text-slate-700 dark:text-slate-300 peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
|
9
|
+
// control: [
|
|
10
|
+
// "flex h-10 w-full rounded-md border border-slate-200 bg-white px-3 py-2 text-sm transition-shadow",
|
|
11
|
+
// "focus-within:ring-2 focus-within:ring-blue-500 focus-within:ring-offset-2",
|
|
12
|
+
// "disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-800 dark:bg-slate-950",
|
|
13
|
+
// "data-[invalid]:border-red-500 data-[invalid]:focus-within:ring-red-500",
|
|
14
|
+
// ],
|
|
15
|
+
// segment: [
|
|
16
|
+
// "inline rounded-sm px-0.5 tabular-nums outline-none transition-colors",
|
|
17
|
+
// "focus:bg-blue-600 focus:text-white dark:focus:bg-blue-500",
|
|
18
|
+
// "data-[placeholder]:text-slate-400 data-[type=literal]:px-0",
|
|
19
|
+
// ],
|
|
20
|
+
// description: "text-xs text-slate-500 dark:text-slate-400",
|
|
21
|
+
// errorMessage: "text-xs text-red-500",
|
|
22
|
+
// },
|
|
23
|
+
// variants: {
|
|
24
|
+
// size: {
|
|
25
|
+
// sm: { control: "h-8 px-2 text-xs" },
|
|
26
|
+
// md: { control: "h-10 px-3 text-sm" },
|
|
27
|
+
// lg: { control: "h-12 px-4 text-base" },
|
|
28
|
+
// },
|
|
29
|
+
// },
|
|
30
|
+
// defaultVariants: {
|
|
31
|
+
// size: "md",
|
|
32
|
+
// },
|
|
33
|
+
// });
|
|
34
|
+
|
|
35
|
+
// type TimeFieldVariants = VariantProps<typeof timeFieldStyles>;
|
|
36
|
+
|
|
37
|
+
// export interface TimeFieldProps
|
|
38
|
+
// extends Omit<ComponentProps<typeof KTimeField>, "class">,
|
|
39
|
+
// TimeFieldVariants {
|
|
40
|
+
// label?: string;
|
|
41
|
+
// description?: string;
|
|
42
|
+
// errorMessage?: string;
|
|
43
|
+
// class?: string;
|
|
44
|
+
// }
|
|
45
|
+
|
|
46
|
+
// export const TimeField = (props: TimeFieldProps) => {
|
|
47
|
+
// const [local, variantProps, others] = splitProps(
|
|
48
|
+
// props,
|
|
49
|
+
// ["label", "description", "errorMessage", "class"],
|
|
50
|
+
// ["size"]
|
|
51
|
+
// );
|
|
52
|
+
|
|
53
|
+
// const styles = timeFieldStyles(variantProps);
|
|
54
|
+
|
|
55
|
+
// return (
|
|
56
|
+
// <KTimeField
|
|
57
|
+
// class={styles.root({ class: local.class })}
|
|
58
|
+
// validationState={local.errorMessage ? "invalid" : "valid"}
|
|
59
|
+
// {...others}
|
|
60
|
+
// >
|
|
61
|
+
// <Show when={local.label}>
|
|
62
|
+
// <KTimeField.Label class={styles.label()}>
|
|
63
|
+
// {local.label}
|
|
64
|
+
// </KTimeField.Label>
|
|
65
|
+
// </Show>
|
|
66
|
+
|
|
67
|
+
// <KTimeField.Input class={styles.control()}>
|
|
68
|
+
// <For
|
|
69
|
+
// each={
|
|
70
|
+
// others.value
|
|
71
|
+
// ? []
|
|
72
|
+
// : [1] /* 仅作为占位,Kobalte 内部会自动处理内容 */
|
|
73
|
+
// }
|
|
74
|
+
// >
|
|
75
|
+
// {() => <KTimeField.Segment class={styles.segment()} />}
|
|
76
|
+
// </For>
|
|
77
|
+
// {/* 注意:通常情况下,直接在 Input 内部放置 Segment 映射即可 */}
|
|
78
|
+
// {(state) => (
|
|
79
|
+
// <For each={state.segments()}>
|
|
80
|
+
// {(segment) => (
|
|
81
|
+
// <KTimeField.Segment
|
|
82
|
+
// segment={segment}
|
|
83
|
+
// class={styles.segment()}
|
|
84
|
+
// />
|
|
85
|
+
// )}
|
|
86
|
+
// </For>
|
|
87
|
+
// )}
|
|
88
|
+
// </KTimeField.Input>
|
|
89
|
+
|
|
90
|
+
// <Show when={local.description}>
|
|
91
|
+
// <KTimeField.Description class={styles.description()}>
|
|
92
|
+
// {local.description}
|
|
93
|
+
// </KTimeField.Description>
|
|
94
|
+
// </Show>
|
|
95
|
+
|
|
96
|
+
// <Show when={local.errorMessage}>
|
|
97
|
+
// <KTimeField.ErrorMessage class={styles.errorMessage()}>
|
|
98
|
+
// {local.errorMessage}
|
|
99
|
+
// </KTimeField.ErrorMessage>
|
|
100
|
+
// </Show>
|
|
101
|
+
// </KTimeField>
|
|
102
|
+
// );
|
|
103
|
+
// };
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { Toast as KToast, toaster } from "@kobalte/core/toast";
|
|
2
|
+
|
|
3
|
+
import { isServer } from "solid-js/web";
|
|
4
|
+
import {
|
|
5
|
+
splitProps,
|
|
6
|
+
type ComponentProps,
|
|
7
|
+
Show,
|
|
8
|
+
type ParentProps,
|
|
9
|
+
} from "solid-js";
|
|
10
|
+
import { tv, type VariantProps } from "tailwind-variants";
|
|
11
|
+
import { X, CircleCheck, CircleAlert, Info, TriangleAlert } from "lucide-solid";
|
|
12
|
+
|
|
13
|
+
const toastStyles = tv(
|
|
14
|
+
{
|
|
15
|
+
slots: {
|
|
16
|
+
root: [
|
|
17
|
+
"group relative flex w-[400px] items-start justify-between space-x-4 overflow-hidden rounded-md border p-4 pr-8 shadow-lg transition-all",
|
|
18
|
+
"data-[opened]:animate-slide-in",
|
|
19
|
+
"data-[closed]:animate-hide",
|
|
20
|
+
|
|
21
|
+
// 滑动手势处理
|
|
22
|
+
"data-[swipe=move]:translate-x-[--kb-toast-swipe-move-x]",
|
|
23
|
+
"data-[swipe=cancel]:translate-x-0 data-[swipe=cancel]:transition-transform data-[swipe=cancel]:duration-200 data-[swipe=cancel]:ease-out",
|
|
24
|
+
"data-[swipe=end]:animate-swipe-out",
|
|
25
|
+
],
|
|
26
|
+
title: "text-sm font-semibold",
|
|
27
|
+
description: "text-xs opacity-90 leading-relaxed",
|
|
28
|
+
closeButton: [
|
|
29
|
+
"absolute right-2 top-2 rounded-md p-1 opacity-0 transition-opacity hover:text-main",
|
|
30
|
+
"focus:opacity-100 focus:outline-none focus:ring-2 group-hover:opacity-100",
|
|
31
|
+
],
|
|
32
|
+
content: "flex flex-col gap-1 flex-1",
|
|
33
|
+
icon: "h-5 w-5 shrink-0 mt-0.5", // 稍微下移一点对齐文字
|
|
34
|
+
},
|
|
35
|
+
variants: {
|
|
36
|
+
variant: {
|
|
37
|
+
info: {
|
|
38
|
+
root: "bg-app border-light text-main",
|
|
39
|
+
icon: "text-primary",
|
|
40
|
+
},
|
|
41
|
+
success: {
|
|
42
|
+
root: "bg-success/50 border-success text-success",
|
|
43
|
+
icon: "text-success",
|
|
44
|
+
},
|
|
45
|
+
warning: {
|
|
46
|
+
root: "bg-warning/50 border-warning text-warning",
|
|
47
|
+
icon: "text-warning",
|
|
48
|
+
},
|
|
49
|
+
error: {
|
|
50
|
+
root: "bg-danger/50 border-danger text-danger",
|
|
51
|
+
icon: "text-danger",
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
defaultVariants: { variant: "info" },
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
twMerge: true,
|
|
59
|
+
},
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
type ToastVariants = VariantProps<typeof toastStyles>;
|
|
63
|
+
|
|
64
|
+
export interface ToastProps
|
|
65
|
+
extends Omit<ComponentProps<typeof KToast>, "class">, ToastVariants {
|
|
66
|
+
title?: string;
|
|
67
|
+
description?: string;
|
|
68
|
+
class?: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const iconMap = {
|
|
72
|
+
info: Info,
|
|
73
|
+
success: CircleCheck,
|
|
74
|
+
warning: TriangleAlert,
|
|
75
|
+
error: CircleAlert,
|
|
76
|
+
} as const; // 使用 const 断言增强类型推导
|
|
77
|
+
|
|
78
|
+
export const ToastProvider = (props: ParentProps) => {
|
|
79
|
+
return (
|
|
80
|
+
<>
|
|
81
|
+
{props.children}
|
|
82
|
+
<KToast.Region>
|
|
83
|
+
<KToast.List class="fixed bottom-4 right-4 z-100 flex flex-col gap-3 w-full max-w-100 outline-none" />
|
|
84
|
+
</KToast.Region>
|
|
85
|
+
</>
|
|
86
|
+
);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const Toast = (props: ToastProps) => {
|
|
90
|
+
const [local, variantProps, others] = splitProps(
|
|
91
|
+
props,
|
|
92
|
+
["title", "description", "class", "toastId"],
|
|
93
|
+
["variant"]
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
const { root, icon, content, title, description, closeButton } =
|
|
97
|
+
toastStyles(variantProps);
|
|
98
|
+
// 显式回退到 info,确保 Icon 组件始终存在
|
|
99
|
+
const Icon = iconMap[variantProps.variant ?? "info"];
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<KToast
|
|
103
|
+
toastId={local.toastId}
|
|
104
|
+
class={root({ class: local.class })}
|
|
105
|
+
{...others}
|
|
106
|
+
>
|
|
107
|
+
<Icon class={icon()} />
|
|
108
|
+
<div class={content()}>
|
|
109
|
+
<Show when={local.title}>
|
|
110
|
+
<KToast.Title class={title()}>
|
|
111
|
+
{local.title}
|
|
112
|
+
</KToast.Title>
|
|
113
|
+
</Show>
|
|
114
|
+
<Show when={local.description}>
|
|
115
|
+
<KToast.Description class={description()}>
|
|
116
|
+
{local.description}
|
|
117
|
+
</KToast.Description>
|
|
118
|
+
</Show>
|
|
119
|
+
</div>
|
|
120
|
+
<KToast.CloseButton class={closeButton()}>
|
|
121
|
+
<X size={16} />
|
|
122
|
+
</KToast.CloseButton>
|
|
123
|
+
</KToast>
|
|
124
|
+
);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export const showToast = (props: Omit<ToastProps, "toastId">) => {
|
|
128
|
+
if (isServer) {
|
|
129
|
+
return { toastId: () => "server-id" }; // 给个假实现,不报错就行
|
|
130
|
+
}
|
|
131
|
+
return toaster.show((data) => <Toast toastId={data.toastId} {...props} />);
|
|
132
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { ToggleButton as KToggle } from "@kobalte/core/toggle-button";
|
|
2
|
+
import { splitProps, type JSX, type ComponentProps } from "solid-js";
|
|
3
|
+
import { tv, type VariantProps } from "tailwind-variants";
|
|
4
|
+
|
|
5
|
+
// TODO 切换样式问题
|
|
6
|
+
|
|
7
|
+
const toggleStyles = tv(
|
|
8
|
+
{
|
|
9
|
+
base: [
|
|
10
|
+
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors",
|
|
11
|
+
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-slate-400 focus-visible:ring-offset-1",
|
|
12
|
+
"disabled:pointer-events-none disabled:opacity-50 select-none cursor-pointer",
|
|
13
|
+
],
|
|
14
|
+
variants: {
|
|
15
|
+
variant: {
|
|
16
|
+
solid: "bg-foreground text-main hover:bg-foreground/80 data-[pressed]:bg-reversal-bg data-[pressed]:text-reversal",
|
|
17
|
+
outline:
|
|
18
|
+
"border border-light bg-transparent hover:bg-slate-100 data-[pressed]:bg-slate-900 data-[pressed]:text-white dark:hover:bg-slate-800 dark:data-[pressed]:bg-slate-50 dark:data-[pressed]:text-slate-900",
|
|
19
|
+
},
|
|
20
|
+
size: {
|
|
21
|
+
sm: "h-8 px-3 text-xs",
|
|
22
|
+
md: "h-10 px-4 text-sm",
|
|
23
|
+
lg: "h-12 px-6 text-base",
|
|
24
|
+
icon: "h-10 w-10",
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
defaultVariants: {
|
|
28
|
+
variant: "solid",
|
|
29
|
+
size: "md",
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
twMerge: true,
|
|
34
|
+
},
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
type ToggleVariants = VariantProps<typeof toggleStyles>;
|
|
38
|
+
|
|
39
|
+
export interface ToggleButtonProps
|
|
40
|
+
extends Omit<ComponentProps<typeof KToggle>, "class">,
|
|
41
|
+
ToggleVariants {
|
|
42
|
+
class?: string;
|
|
43
|
+
children?: JSX.Element;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const ToggleButton = (props: ToggleButtonProps) => {
|
|
47
|
+
const [local, variantProps, others] = splitProps(
|
|
48
|
+
props,
|
|
49
|
+
["class", "children"],
|
|
50
|
+
["variant", "size"]
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<KToggle
|
|
55
|
+
class={toggleStyles({
|
|
56
|
+
variant: variantProps.variant,
|
|
57
|
+
size: variantProps.size,
|
|
58
|
+
class: local.class,
|
|
59
|
+
})}
|
|
60
|
+
{...others}
|
|
61
|
+
>
|
|
62
|
+
{(state) =>
|
|
63
|
+
typeof local.children === "function"
|
|
64
|
+
? (local.children as any)(state)
|
|
65
|
+
: local.children
|
|
66
|
+
}
|
|
67
|
+
</KToggle>
|
|
68
|
+
);
|
|
69
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { ToggleGroup as KToggleGroup } from "@kobalte/core/toggle-group";
|
|
2
|
+
import { splitProps, For, type ComponentProps, type JSX } from "solid-js";
|
|
3
|
+
import { tv, type VariantProps } from "tailwind-variants";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
// TODO 单选,多选出现问题
|
|
7
|
+
|
|
8
|
+
const toggleGroupStyles = tv(
|
|
9
|
+
{
|
|
10
|
+
slots: {
|
|
11
|
+
root: "inline-flex items-center justify-center rounded-md border border-light bg-transparent p-1",
|
|
12
|
+
item: [
|
|
13
|
+
"inline-flex items-center justify-center rounded-sm px-3 py-1.5 text-sm font-medium transition-all cursor-pointer",
|
|
14
|
+
"outline-none focus-visible:ring-2 focus-visible:ring-slate-400 focus-visible:ring-offset-2",
|
|
15
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
16
|
+
"hover:bg-foreground/80 hover:text-muted/80",
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
variants: {
|
|
20
|
+
variant: {
|
|
21
|
+
default: {
|
|
22
|
+
root: "bg-transparent",
|
|
23
|
+
item: "data-[pressed]:bg-foreground data-[pressed]:text-main",
|
|
24
|
+
},
|
|
25
|
+
outline: {
|
|
26
|
+
root: "border border-light",
|
|
27
|
+
item: "border-r last:border-r-0 border-light rounded-none first:rounded-l-md last:rounded-r-md",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
size: {
|
|
31
|
+
sm: { item: "h-8 px-2.5 text-xs" },
|
|
32
|
+
md: { item: "h-10 px-3 text-sm" },
|
|
33
|
+
lg: { item: "h-12 px-5 text-base" },
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
defaultVariants: {
|
|
37
|
+
variant: "default",
|
|
38
|
+
size: "md",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
twMerge: true,
|
|
43
|
+
},
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
type ToggleGroupVariants = VariantProps<typeof toggleGroupStyles>;
|
|
47
|
+
|
|
48
|
+
interface Option {
|
|
49
|
+
label: string | JSX.Element;
|
|
50
|
+
value: string;
|
|
51
|
+
disabled?: boolean;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface ToggleGroupProps
|
|
55
|
+
extends Omit<ComponentProps<typeof KToggleGroup>, "class">,
|
|
56
|
+
ToggleGroupVariants {
|
|
57
|
+
options: Option[];
|
|
58
|
+
class?: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const ToggleGroup = (props: ToggleGroupProps) => {
|
|
62
|
+
const [local, variantProps, others] = splitProps(
|
|
63
|
+
props,
|
|
64
|
+
["options", "class"],
|
|
65
|
+
["size", "variant"]
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const styles = toggleGroupStyles(variantProps);
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<KToggleGroup class={styles.root({ class: local.class })} {...others}>
|
|
72
|
+
<For each={local.options}>
|
|
73
|
+
{(option) => (
|
|
74
|
+
<KToggleGroup.Item
|
|
75
|
+
value={option.value}
|
|
76
|
+
disabled={option.disabled}
|
|
77
|
+
class={styles.item()}
|
|
78
|
+
>
|
|
79
|
+
{option.label}
|
|
80
|
+
</KToggleGroup.Item>
|
|
81
|
+
)}
|
|
82
|
+
</For>
|
|
83
|
+
</KToggleGroup>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Tooltip as KTooltip } from "@kobalte/core/tooltip";
|
|
2
|
+
import { splitProps, type JSX, type ComponentProps } from "solid-js";
|
|
3
|
+
import { tv, type VariantProps } from "tailwind-variants";
|
|
4
|
+
|
|
5
|
+
const tooltipStyles = tv(
|
|
6
|
+
{
|
|
7
|
+
slots: {
|
|
8
|
+
content: [
|
|
9
|
+
"z-50 rounded-md px-4 py-1.5 text-xs shadow-md",
|
|
10
|
+
"animate-in zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
11
|
+
],
|
|
12
|
+
arrow: "",
|
|
13
|
+
},
|
|
14
|
+
variants: {
|
|
15
|
+
variant: {
|
|
16
|
+
default: {
|
|
17
|
+
content:
|
|
18
|
+
"bg-reversal-bg text-reversal ",
|
|
19
|
+
arrow: "fill-muted",
|
|
20
|
+
},
|
|
21
|
+
danger: {
|
|
22
|
+
content: "bg-danger text-white",
|
|
23
|
+
arrow: "fill-danger",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
defaultVariants: {
|
|
28
|
+
variant: "default",
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
twMerge: true,
|
|
33
|
+
},
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
type TooltipVariants = VariantProps<typeof tooltipStyles>;
|
|
37
|
+
|
|
38
|
+
export interface TooltipProps
|
|
39
|
+
extends Omit<ComponentProps<typeof KTooltip>, "class">, TooltipVariants {
|
|
40
|
+
content: JSX.Element;
|
|
41
|
+
children: JSX.Element;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const Tooltip = (props: TooltipProps) => {
|
|
45
|
+
// 1. 分离属性
|
|
46
|
+
const [local, variantProps, others] = splitProps(
|
|
47
|
+
props,
|
|
48
|
+
["children", "content"],
|
|
49
|
+
["variant"]
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
// 2. 生成样式
|
|
53
|
+
const styles = tooltipStyles(variantProps);
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<KTooltip
|
|
57
|
+
gutter={4}
|
|
58
|
+
openDelay={200}
|
|
59
|
+
{...others}
|
|
60
|
+
>
|
|
61
|
+
<KTooltip.Trigger class="block">
|
|
62
|
+
{local.children}
|
|
63
|
+
</KTooltip.Trigger>
|
|
64
|
+
|
|
65
|
+
<KTooltip.Portal>
|
|
66
|
+
<KTooltip.Content class={styles.content()}>
|
|
67
|
+
<KTooltip.Arrow class={styles.arrow()} />
|
|
68
|
+
{local.content}
|
|
69
|
+
</KTooltip.Content>
|
|
70
|
+
</KTooltip.Portal>
|
|
71
|
+
</KTooltip>
|
|
72
|
+
);
|
|
73
|
+
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|