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
package/src/index.tsx ADDED
@@ -0,0 +1,94 @@
1
+ import "./style/global.css";
2
+
3
+ // TODO 组件 form , data等
4
+ // TODO background-color 等颜色相关的属性,添加 dark 模式的支持
5
+
6
+ export { Accordion } from "./accordion/accordion";
7
+
8
+ export { Alert } from "./alert/alert";
9
+
10
+ export { AlertDialog } from "./alert-dialog/alert-dialog";
11
+
12
+ export { Badge } from "./badge/badge";
13
+
14
+ export { Breadcrumbs } from "./breadcrumbs/breadcrumbs";
15
+
16
+ export { Button } from "./button/button";
17
+
18
+ export { Checkbox } from "./checkbox/checkbox";
19
+
20
+ export { Collapsible } from "./collapsible/collapsible";
21
+
22
+ export { ColorArea } from "./color-area/color-area";
23
+
24
+ export { ColorChannelField } from "./color-channel-field/color-channel-field";
25
+
26
+ export { ColorField } from "./color-field/color-field";
27
+
28
+ export { ColorSlider } from "./color-slider/color-slider";
29
+
30
+ export { ColorSwatch } from "./color-swatch/color-swatch";
31
+
32
+ export { ColorWheel } from "./color-wheel/color-wheel";
33
+
34
+ export { Combobox, ComboboxItem } from "./combobox/combobox";
35
+
36
+ export { ContextMenu } from "./context-menu/context-menu";
37
+
38
+ export { Dialog } from "./dialog/dialog";
39
+
40
+ export { DropdownMenu } from "./dropdown-menu/dropdown-menu";
41
+
42
+ export { FileField } from "./file-field/file-field";
43
+
44
+ export { HoverCard } from "./hover-card/hover-card";
45
+
46
+ export { Image } from "./image/image";
47
+
48
+ export { Link } from "./link/link";
49
+
50
+ export { Menubar } from "./menubar/menubar";
51
+
52
+ export { Meter } from "./meter/meter";
53
+
54
+ export { NavigationMenu } from "./navigation-menu/navigation-menu";
55
+
56
+ export { NumberField } from "./number-field/number-field";
57
+
58
+ export { Pagination } from "./pagination/pagination";
59
+
60
+ export { Popover } from "./popover/popover";
61
+
62
+ export { Progress } from "./progress/progress";
63
+
64
+ export { RadioGroup } from "./radio-group/radio-group";
65
+
66
+ // rating-group 组件
67
+
68
+ export { Search } from "./search/search";
69
+
70
+ export { SegmentedControl } from "./segmented-control/segmented-control";
71
+
72
+ export { Select } from "./select/select";
73
+
74
+ export { Separator } from "./separator/separator";
75
+
76
+ export { Skeleton } from "./skeleton/skeleton";
77
+
78
+ export { Slider } from "./slider/slider";
79
+
80
+ export { Switch } from "./switch/switch";
81
+
82
+ export { Tabs } from "./tabs/tabs";
83
+
84
+ export { TextField } from "./text-field/text-field";
85
+
86
+ // time-field
87
+
88
+ export { ToastProvider, showToast } from "./toast/toast";
89
+
90
+ export { ToggleButton } from "./toggle-button/toggle-button";
91
+
92
+ export { ToggleGroup } from "./toggle-group/toggle-group";
93
+
94
+ export { Tooltip } from "./tooltip/tooltip";
@@ -0,0 +1,64 @@
1
+ import { Link as KLink } from "@kobalte/core/link";
2
+ import { splitProps, type ComponentProps } from "solid-js";
3
+ import { tv, type VariantProps } from "tailwind-variants";
4
+
5
+ const linkStyles = tv(
6
+ {
7
+ base: "inline-flex items-center justify-center transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 rounded-sm disabled:pointer-events-none disabled:opacity-50",
8
+ variants: {
9
+ variant: {
10
+ default:
11
+ "text-main hover:text-main/80 underline-offset-4",
12
+ primary:
13
+ "text-primary hover:text-primary/80 font-medium",
14
+ muted: "text-muted hover:text-muted/80",
15
+ button: "bg-reversal-bg text-reversal hover:reversal-bg/90 px-4 py-2 text-sm ",
16
+ },
17
+ underline: {
18
+ always: "underline",
19
+ hover: "no-underline hover:underline",
20
+ none: "no-underline",
21
+ },
22
+ },
23
+ defaultVariants: {
24
+ variant: "default",
25
+ underline: "hover",
26
+ },
27
+ },
28
+ {
29
+ twMerge: true,
30
+ },
31
+ );
32
+
33
+ type LinkVariants = VariantProps<typeof linkStyles>;
34
+
35
+ export interface LinkProps extends ComponentProps<typeof KLink>, LinkVariants {
36
+ external?: boolean;
37
+ }
38
+
39
+ export const Link = (props: LinkProps) => {
40
+ const [local, variantProps, others] = splitProps(
41
+ props,
42
+ ["class", "external", "children", "href"],
43
+ ["variant", "underline"]
44
+ );
45
+
46
+ const styles = () =>
47
+ linkStyles({
48
+ variant: variantProps.variant,
49
+ underline: variantProps.underline,
50
+ class: local.class,
51
+ });
52
+
53
+ return (
54
+ <KLink
55
+ href={local.href}
56
+ target={local.external ? "_blank" : undefined}
57
+ rel={local.external ? "noopener noreferrer" : undefined}
58
+ class={styles()}
59
+ {...others}
60
+ >
61
+ {local.children}
62
+ </KLink>
63
+ );
64
+ };
@@ -0,0 +1,85 @@
1
+ import { Menubar as KMenubar } from "@kobalte/core/menubar";
2
+ import { splitProps, type ComponentProps } from "solid-js";
3
+ import { tv } from "tailwind-variants";
4
+
5
+ // TODO 1. 格式
6
+
7
+ const menubarStyles = tv(
8
+ {
9
+ slots: {
10
+ root: "flex h-10 items-center space-x-1 rounded-md border bg-app p-1 shadow-sm ",
11
+ trigger:
12
+ "flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none focus:foreground data-[state=open]:foreground",
13
+ content: [
14
+ "z-50 min-w-[12rem] overflow-hidden rounded-md border bg-app p-1 shadow-md border-light animate-in fade-in zoom-in-95",
15
+ "data-[expanded]:animate-in data-[closed]:animate-out",
16
+ ],
17
+ item: [
18
+ "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none ",
19
+
20
+ "focus:bg-foreground data-[disabled]:opacity-50",
21
+ ],
22
+ separator: "-mx-1 my-1 h-px border-light",
23
+ shortcut: "ml-auto text-xs tracking-widest text-slate-500",
24
+ },
25
+ },
26
+ {
27
+ twMerge: true,
28
+ },
29
+ );
30
+
31
+ const s = menubarStyles();
32
+
33
+ export const Menubar = Object.assign(
34
+ (props: ComponentProps<typeof KMenubar>) => {
35
+ const [local, others] = splitProps(props, ["class"]);
36
+ return <KMenubar class={s.root({ class: local.class })} {...others} />;
37
+ },
38
+ {
39
+ Menu: KMenubar.Menu,
40
+ Trigger: (props: ComponentProps<typeof KMenubar.Trigger>) => {
41
+ const [local, others] = splitProps(props, ["class"]);
42
+ return (
43
+ <KMenubar.Trigger
44
+ class={s.trigger({ class: local.class })}
45
+ {...others}
46
+ />
47
+ );
48
+ },
49
+ Content: (props: ComponentProps<typeof KMenubar.Content>) => {
50
+ const [local, others] = splitProps(props, ["class"]);
51
+ return (
52
+ <KMenubar.Portal>
53
+ <KMenubar.Content
54
+ class={s.content({ class: local.class })}
55
+ {...others}
56
+ />
57
+ </KMenubar.Portal>
58
+ );
59
+ },
60
+ Item: (props: ComponentProps<typeof KMenubar.Item>) => {
61
+ const [local, others] = splitProps(props, ["class"]);
62
+ return (
63
+ <KMenubar.Item
64
+ class={s.item({ class: local.class })}
65
+ {...others}
66
+ />
67
+ );
68
+ },
69
+ Separator: (props: ComponentProps<typeof KMenubar.Separator>) => {
70
+ const [local, others] = splitProps(props, ["class"]);
71
+ return (
72
+ <KMenubar.Separator
73
+ class={s.separator({ class: local.class })}
74
+ {...others}
75
+ />
76
+ );
77
+ },
78
+ Shortcut: (props: ComponentProps<"span">) => {
79
+ const [local, others] = splitProps(props, ["class"]);
80
+ return (
81
+ <span class={s.shortcut({ class: local.class })} {...others} />
82
+ );
83
+ },
84
+ },
85
+ );
@@ -0,0 +1,89 @@
1
+ import { Meter as KMeter } from "@kobalte/core/meter";
2
+ import { splitProps, type ComponentProps } from "solid-js";
3
+ import { tv, type VariantProps } from "tailwind-variants";
4
+
5
+ // TODO 1. 格式
6
+
7
+ const meterStyles = tv(
8
+ {
9
+ slots: {
10
+ root: "flex flex-col gap-2 w-full antialiased",
11
+ labelContainer:
12
+ "flex justify-between items-center text-sm font-medium text-main",
13
+ track: "h-2.5 w-full rounded-full bg-foreground overflow-hidden",
14
+ fill: "h-full transition-all duration-500 ease-out rounded-full",
15
+ },
16
+ variants: {
17
+ color: {
18
+ primary: { fill: "bg-primary" },
19
+ success: { fill: "bg-success" },
20
+ warning: { fill: "bg-warning" },
21
+ danger: { fill: "bg-danger" },
22
+ },
23
+ },
24
+ defaultVariants: {
25
+ color: "primary",
26
+ },
27
+ },
28
+ {
29
+ twMerge: true,
30
+ },
31
+ );
32
+
33
+ type MeterVariants = VariantProps<typeof meterStyles>;
34
+
35
+ export const Meter = Object.assign(
36
+ (props: ComponentProps<typeof KMeter> & MeterVariants) => {
37
+ const [local, variantProps, others] = splitProps(
38
+ props,
39
+ ["class"],
40
+ ["color"]
41
+ );
42
+ const s = () => meterStyles({ color: variantProps.color });
43
+
44
+ return (
45
+ <KMeter class={s().root({ class: local.class })} {...others}>
46
+ {others.children}
47
+ </KMeter>
48
+ );
49
+ },
50
+ {
51
+ Label: (props: ComponentProps<typeof KMeter.Label>) => {
52
+ const [local, others] = splitProps(props, ["class"]);
53
+ return (
54
+ <KMeter.Label
55
+ class={meterStyles().labelContainer({ class: local.class })}
56
+ {...others}
57
+ />
58
+ );
59
+ },
60
+ ValueLabel: (props: ComponentProps<typeof KMeter.ValueLabel>) => {
61
+ const [local, others] = splitProps(props, ["class"]);
62
+ return (
63
+ <KMeter.ValueLabel
64
+ class={`text-xs text-slate-500 ${local.class}`}
65
+ {...others}
66
+ />
67
+ );
68
+ },
69
+ Track: (props: ComponentProps<typeof KMeter.Track>) => {
70
+ const [local, others] = splitProps(props, ["class"]);
71
+ return (
72
+ <KMeter.Track
73
+ class={meterStyles().track({ class: local.class })}
74
+ {...others}
75
+ />
76
+ );
77
+ },
78
+ Fill: (props: ComponentProps<typeof KMeter.Fill>) => {
79
+ const [local, others] = splitProps(props, ["class"]);
80
+ // 注意:Fill 不需要手动设置宽度,Kobalte 会通过 style 注入百分比
81
+ return (
82
+ <KMeter.Fill
83
+ class={meterStyles().fill({ class: local.class })}
84
+ {...others}
85
+ />
86
+ );
87
+ },
88
+ }
89
+ );
@@ -0,0 +1,90 @@
1
+ import { NavigationMenu as KNavigationMenu } from "@kobalte/core/navigation-menu";
2
+ import { splitProps, type ComponentProps, type JSX, For, Show } from "solid-js";
3
+ import { tv } from "tailwind-variants";
4
+
5
+ // TODO 不显示问题
6
+
7
+ const navStyles = tv(
8
+ {
9
+ slots: {
10
+ root: "relative z-10 flex w-full justify-center antialiased",
11
+ trigger: [
12
+ "group inline-flex h-9 w-max items-center justify-center rounded-md px-4 py-2 text-sm font-medium transition-all",
13
+ "hover:bg-slate-100 hover:text-slate-900 data-[state=open]:bg-slate-100/50",
14
+ "dark:hover:bg-slate-800 dark:hover:text-slate-50",
15
+ ],
16
+ content:
17
+ "absolute left-0 top-0 w-full p-2 animate-in fade-in zoom-in-95 duration-200",
18
+ viewport:
19
+ "relative mt-1.5 h-(--kb-navigation-menu-viewport-height) w-(--kb-navigation-menu-viewport-width) origin-[top_center] overflow-hidden rounded-md border bg-white shadow-xl dark:bg-slate-950 dark:border-slate-800 transition-[width,height] duration-300",
20
+ },
21
+ },
22
+ {
23
+ twMerge: true,
24
+ },
25
+ );
26
+
27
+ const { root, trigger, content, viewport } = navStyles();
28
+
29
+ interface NavItem {
30
+ title: string;
31
+ href?: string;
32
+ content?: JSX.Element;
33
+ }
34
+
35
+ export interface NavigationMenuProps
36
+ extends ComponentProps<typeof KNavigationMenu> {
37
+ items: NavItem[];
38
+ }
39
+
40
+ export const NavigationMenu = (props: NavigationMenuProps) => {
41
+ const [local, others] = splitProps(props, ["items", "class"]);
42
+
43
+ return (
44
+ <KNavigationMenu class={root({ class: local.class })} {...others}>
45
+ <For each={local.items}>
46
+ {(item) => (
47
+ <KNavigationMenu.Menu>
48
+ <Show
49
+ when={item.content}
50
+ fallback={
51
+ <KNavigationMenu.Trigger
52
+ as="a"
53
+ href={item.href}
54
+ class={trigger()}
55
+ >
56
+ {item.title}
57
+ </KNavigationMenu.Trigger>
58
+ }
59
+ >
60
+ <KNavigationMenu.Trigger class={trigger()}>
61
+ {item.title}
62
+ <svg
63
+ class="ml-1 h-3 w-3 transition-transform duration-200 group-data-[state=open]:rotate-180"
64
+ fill="none"
65
+ viewBox="0 0 24 24"
66
+ stroke="currentColor"
67
+ >
68
+ <path
69
+ stroke-linecap="round"
70
+ stroke-linejoin="round"
71
+ stroke-width="2"
72
+ d="M19 9l-7 7-7-7"
73
+ />
74
+ </svg>
75
+ </KNavigationMenu.Trigger>
76
+ <KNavigationMenu.Portal>
77
+ <KNavigationMenu.Content class={content()}>
78
+ {item.content}
79
+ </KNavigationMenu.Content>
80
+ </KNavigationMenu.Portal>
81
+ </Show>
82
+ </KNavigationMenu.Menu>
83
+ )}
84
+ </For>
85
+ <KNavigationMenu.Viewport class={viewport()}>
86
+ <KNavigationMenu.Arrow />
87
+ </KNavigationMenu.Viewport>
88
+ </KNavigationMenu>
89
+ );
90
+ };
@@ -0,0 +1,79 @@
1
+ import { NumberField as KNumberField } from "@kobalte/core/number-field";
2
+ import { splitProps, type ComponentProps, Show } from "solid-js";
3
+ import { tv, type VariantProps } from "tailwind-variants";
4
+ import { ChevronUp, ChevronDown } from "lucide-solid";
5
+
6
+ const numberFieldStyles = tv(
7
+ {
8
+ slots: {
9
+ root: "flex flex-col gap-1.5 w-full antialiased",
10
+ label: "text-sm font-medium text-main ml-1",
11
+ container: [
12
+ "relative flex items-center rounded-md border border-slate-200 bg-app transition-shadow shadow-sm",
13
+ "focus-within:ring-2 focus-within:ring-blue-500/20 focus-within:border-blue-500",
14
+ ],
15
+ input: "flex-1 bg-transparent px-3 py-2 text-sm outline-none placeholder:text-muted disabled:cursor-not-allowed",
16
+ controls:
17
+ "flex flex-col border-l border-slate-200 dark:border-slate-800",
18
+ stepper: [
19
+ "flex h-1/2 w-8 items-center justify-center transition-colors hover:bg-foreground active:bg-foreground",
20
+ "disabled:opacity-30 disabled:pointer-events-none",
21
+ ],
22
+ errorMessage: "text-xs text-danger font-medium ml-1 mt-1",
23
+ },
24
+ },
25
+ {
26
+ twMerge: true,
27
+ },
28
+ );
29
+
30
+ type NumberFieldVariants = VariantProps<typeof numberFieldStyles>;
31
+
32
+ export interface NumberFieldProps
33
+ extends Omit<ComponentProps<typeof KNumberField>, "class">,
34
+ NumberFieldVariants {
35
+ label?: string;
36
+ description?: string;
37
+ class?: string;
38
+ }
39
+
40
+ export const NumberField = (props: NumberFieldProps) => {
41
+ // 严格处理属性,防止 TS 报错“已声明但未使用”
42
+ const [local, others] = splitProps(props, [
43
+ "label",
44
+ "description",
45
+ "class",
46
+ ]);
47
+ const s = numberFieldStyles();
48
+
49
+ return (
50
+ <KNumberField class={s.root({ class: local.class })} {...others}>
51
+ <Show when={local.label}>
52
+ <KNumberField.Label class={s.label()}>
53
+ {local.label}
54
+ </KNumberField.Label>
55
+ </Show>
56
+
57
+ <div class={s.container()}>
58
+ <KNumberField.Input class={s.input()} />
59
+ <div class={s.controls()}>
60
+ <KNumberField.IncrementTrigger class={s.stepper()}>
61
+ <ChevronUp size={14} />
62
+ </KNumberField.IncrementTrigger>
63
+ <KNumberField.DecrementTrigger
64
+ class={s.stepper({
65
+ class: "border-t border-slate-200 dark:border-slate-800",
66
+ })}
67
+ >
68
+ <ChevronDown size={14} />
69
+ </KNumberField.DecrementTrigger>
70
+ </div>
71
+ </div>
72
+
73
+ <Show when={local.description}>
74
+ <KNumberField.Description class="text-xs text-slate-500 ml-1 mt-1" />
75
+ </Show>
76
+ <KNumberField.ErrorMessage class={s.errorMessage()} />
77
+ </KNumberField>
78
+ );
79
+ };
@@ -0,0 +1,67 @@
1
+ import { Pagination as KPagination } from "@kobalte/core/pagination";
2
+ import { splitProps, type ComponentProps } from "solid-js";
3
+ import { tv } from "tailwind-variants";
4
+ import { ChevronLeft, ChevronRight, Ellipsis } from "lucide-solid";
5
+
6
+
7
+ // FIXME 样式修改,
8
+
9
+ const paginationStyles = tv(
10
+ {
11
+ slots: {
12
+ root: "flex w-full justify-center antialiased",
13
+ itemsContainer: "flex items-center gap-1",
14
+ item: [
15
+ "inline-flex h-9 w-9 items-center justify-center rounded-md text-sm font-medium transition-colors text-main",
16
+ "hover:bg-foreground hover:text-muted",
17
+ "data-[current]:bg-foreground data-[current]:text-muted",
18
+ "disabled:pointer-events-none disabled:opacity-50",
19
+ ],
20
+ ellipsis: "flex h-9 w-9 items-center justify-center text-slate-400",
21
+ trigger:
22
+ "inline-flex h-9 w-9 items-center justify-center rounded-md border border-light bg-transparent hover:bg-foreground ",
23
+ },
24
+ },
25
+ {
26
+ twMerge: true,
27
+ },
28
+ );
29
+
30
+ const s = paginationStyles();
31
+
32
+ export interface PaginationProps extends ComponentProps<typeof KPagination> {}
33
+
34
+ export const Pagination = (props: PaginationProps) => {
35
+ // 显式提取 count 以满足类型约束,同时清理 others
36
+ const [local, others] = splitProps(props, ["class", "count"]);
37
+
38
+ return (
39
+ <KPagination
40
+ class={s.root({ class: local.class })}
41
+ count={local.count}
42
+ {...others}
43
+ itemComponent={(p) => (
44
+ <KPagination.Item page={p.page} class={s.item()}>
45
+ {p.page}
46
+ </KPagination.Item>
47
+ )}
48
+ ellipsisComponent={() => (
49
+ <KPagination.Ellipsis class={s.ellipsis()}>
50
+ <Ellipsis size={16} />
51
+ </KPagination.Ellipsis>
52
+ )}
53
+ >
54
+ <div class={s.itemsContainer()}>
55
+ <KPagination.Previous class={s.trigger()}>
56
+ <ChevronLeft size={16} />
57
+ </KPagination.Previous>
58
+
59
+ <KPagination.Items />
60
+
61
+ <KPagination.Next class={s.trigger()}>
62
+ <ChevronRight size={16} />
63
+ </KPagination.Next>
64
+ </div>
65
+ </KPagination>
66
+ );
67
+ };
@@ -0,0 +1,58 @@
1
+ import { Popover as KPopover } from "@kobalte/core/popover";
2
+ import { CrossIcon } from "lucide-solid";
3
+ import { splitProps, type ComponentProps, type JSX } from "solid-js";
4
+ import { tv } from "tailwind-variants";
5
+
6
+ // FIXME 与其他的气泡样式不统一的问题
7
+ // Description,而不是内敛。
8
+ // trigger用内部,而其他放在标签属性
9
+
10
+ const popoverStyles = tv(
11
+ {
12
+ slots: {
13
+ content: [
14
+ "z-50 w-72 rounded-md border border-light bg-app p-4 shadow-md outline-none antialiased text-main",
15
+ "data-[expanded]:animate-in data-[closed]:animate-out",
16
+ ],
17
+ arrow: "fill-app stroke-slate-200 dark:stroke-slate-800",
18
+ },
19
+ },
20
+ {
21
+ twMerge: true,
22
+ },
23
+ );
24
+
25
+ const {content, arrow} = popoverStyles();
26
+
27
+ export interface PopoverProps extends ComponentProps<typeof KPopover> {
28
+ trigger: JSX.Element;
29
+ title: string;
30
+ }
31
+
32
+ export const Popover = (props: PopoverProps) => {
33
+ const [local, others] = splitProps(props, ["trigger", "children", "title"]);
34
+
35
+ return (
36
+ <KPopover {...others}>
37
+ <KPopover.Trigger class="inline-flex">
38
+ {local.trigger}
39
+ </KPopover.Trigger>
40
+
41
+ <KPopover.Portal>
42
+ <KPopover.Content class={content()}>
43
+ <KPopover.Arrow class={arrow()} />
44
+
45
+ <div class="flex">
46
+ <KPopover.Title>{local.title}</KPopover.Title>
47
+ <KPopover.CloseButton>
48
+ <CrossIcon />
49
+ </KPopover.CloseButton>
50
+ </div>
51
+ <KPopover.Description>
52
+ {local.children}
53
+ </KPopover.Description>
54
+ </KPopover.Content>
55
+ </KPopover.Portal>
56
+ </KPopover>
57
+ );
58
+ };