@xingxingmofashu/ui 0.1.2 → 0.1.4

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 (54) hide show
  1. package/README.md +12 -60
  2. package/dist/components/accordion.d.ts +14 -10
  3. package/dist/components/accordion.mjs +78 -20
  4. package/dist/components/alert-dialog.d.ts +7 -2
  5. package/dist/components/alert-dialog.mjs +74 -33
  6. package/dist/components/button.d.ts +6 -2
  7. package/dist/components/button.mjs +20 -11
  8. package/dist/components/card.d.ts +6 -1
  9. package/dist/components/card.mjs +27 -4
  10. package/dist/components/checkbox.d.ts +5 -1
  11. package/dist/components/checkbox.mjs +53 -14
  12. package/dist/components/dialog.d.ts +7 -2
  13. package/dist/components/dialog.mjs +66 -20
  14. package/dist/components/drawer.d.ts +7 -2
  15. package/dist/components/drawer.mjs +66 -20
  16. package/dist/components/input.d.ts +5 -1
  17. package/dist/components/input.mjs +60 -33
  18. package/dist/components/popover.d.ts +7 -2
  19. package/dist/components/popover.mjs +53 -14
  20. package/dist/components/progress.d.ts +21 -0
  21. package/dist/components/progress.mjs +71 -0
  22. package/dist/components/scroll-area.d.ts +7 -2
  23. package/dist/components/scroll-area.mjs +48 -14
  24. package/dist/components/slider.d.ts +7 -2
  25. package/dist/components/slider.mjs +38 -22
  26. package/dist/components/switch.d.ts +5 -1
  27. package/dist/components/switch.mjs +47 -23
  28. package/dist/components/toast.d.ts +6 -1
  29. package/dist/components/toast.mjs +68 -15
  30. package/dist/components/toggle-group.d.ts +11 -5
  31. package/dist/components/toggle-group.mjs +54 -6
  32. package/dist/components/toggle.d.ts +5 -1
  33. package/dist/components/toggle.mjs +36 -5
  34. package/dist/composables/use-toast.d.ts +5 -1
  35. package/dist/composables/use-toast.mjs +2 -1
  36. package/dist/index.css +1 -1
  37. package/dist/index.d.ts +2 -2
  38. package/dist/index.mjs +2 -1
  39. package/dist/internal/tv.d.ts +13 -0
  40. package/dist/internal/tv.mjs +0 -0
  41. package/dist/keyframes.css +1 -1
  42. package/dist/theme/alert-dialog.mjs +1 -1
  43. package/dist/theme/checkbox.mjs +4 -4
  44. package/dist/theme/dialog.mjs +1 -1
  45. package/dist/theme/drawer.mjs +1 -1
  46. package/dist/theme/popover.mjs +2 -2
  47. package/dist/theme/progress.d.ts +80 -0
  48. package/dist/theme/progress.mjs +64 -0
  49. package/dist/theme/slider.mjs +8 -0
  50. package/dist/theme/switch.mjs +2 -0
  51. package/dist/theme/toast.mjs +1 -1
  52. package/package.json +7 -2
  53. package/dist/composables/create-toast-manager.d.ts +0 -6
  54. package/dist/composables/create-toast-manager.mjs +0 -3
@@ -0,0 +1,71 @@
1
+ "use client";
2
+ import { Progress as UIProgress } from "@base-ui/react/progress";
3
+ import { cn } from "cn";
4
+ import * as React from "react";
5
+ import { mergeIds } from "../internal/aria.mjs";
6
+ import theme from "../theme/progress.mjs";
7
+ function Progress({
8
+ className,
9
+ ui,
10
+ label,
11
+ description,
12
+ size,
13
+ value = null,
14
+ "aria-describedby": ariaDescribedBy,
15
+ ...props
16
+ }) {
17
+ const styles = theme({ size });
18
+ const descriptionId = React.useId();
19
+ const describedBy = mergeIds(
20
+ ariaDescribedBy,
21
+ description ? descriptionId : void 0
22
+ );
23
+ return /* @__PURE__ */ React.createElement(
24
+ UIProgress.Root,
25
+ {
26
+ ...props,
27
+ value,
28
+ "aria-describedby": describedBy,
29
+ "data-slot": "root",
30
+ className: cn(styles.root(), ui?.root, className)
31
+ },
32
+ /* @__PURE__ */ React.createElement("div", { "data-slot": "header", className: cn(styles.header(), ui?.header) }, label ? /* @__PURE__ */ React.createElement(
33
+ UIProgress.Label,
34
+ {
35
+ "data-slot": "label",
36
+ className: cn(styles.label(), ui?.label)
37
+ },
38
+ label
39
+ ) : null, /* @__PURE__ */ React.createElement(
40
+ UIProgress.Value,
41
+ {
42
+ "data-slot": "value",
43
+ className: cn(styles.value(), ui?.value)
44
+ }
45
+ )),
46
+ /* @__PURE__ */ React.createElement(
47
+ UIProgress.Track,
48
+ {
49
+ "data-slot": "track",
50
+ className: cn(styles.track(), ui?.track)
51
+ },
52
+ /* @__PURE__ */ React.createElement(
53
+ UIProgress.Indicator,
54
+ {
55
+ "data-slot": "indicator",
56
+ className: cn(styles.indicator(), ui?.indicator)
57
+ }
58
+ )
59
+ ),
60
+ description ? /* @__PURE__ */ React.createElement(
61
+ "span",
62
+ {
63
+ id: descriptionId,
64
+ "data-slot": "description",
65
+ className: cn(styles.description(), ui?.description)
66
+ },
67
+ description
68
+ ) : null
69
+ );
70
+ }
71
+ export { Progress };
@@ -1,14 +1,19 @@
1
1
  import { ScrollArea as UIScrollArea } from "@base-ui/react/scroll-area";
2
2
  import * as React from "react";
3
+ import { type ComponentConfig } from "../internal/tv";
4
+ import theme from "../theme/scroll-area";
3
5
  /** Scrollbar axes rendered by the scroll area. */
4
6
  type ScrollAreaOrientation = "vertical" | "horizontal" | "both";
7
+ type ScrollArea = ComponentConfig<typeof theme>;
5
8
  type ScrollAreaProps = Omit<UIScrollArea.Root.Props, "children" | "className" | "style"> & {
6
9
  /** Scrollable content. */
7
10
  children?: React.ReactNode;
8
11
  /** Scrollbar axes to render. Defaults to `"vertical"`. */
9
12
  orientation?: ScrollAreaOrientation;
10
13
  /** Tailwind classes merged into the root. */
11
- className?: any;
14
+ className?: string;
15
+ /** Tailwind classes for internal slots, keyed by `data-slot`. */
16
+ ui?: ScrollArea["slots"];
12
17
  };
13
18
  /**
14
19
  * A native scroll container with custom liquid glass scrollbars.
@@ -16,6 +21,6 @@ type ScrollAreaProps = Omit<UIScrollArea.Root.Props, "children" | "className" |
16
21
  * The root owns the visible glass surface. Give it a height (for example
17
22
  * `className="h-64"`) to create a scrollable viewport.
18
23
  */
19
- declare function ScrollArea({ "aria-describedby": ariaDescribedBy, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, children, className, orientation, ...props }: ScrollAreaProps): React.JSX.Element;
24
+ declare function ScrollArea({ "aria-describedby": ariaDescribedBy, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, children, className, ui, orientation, ...props }: ScrollAreaProps): React.JSX.Element;
20
25
  export { ScrollArea };
21
26
  export type { ScrollAreaOrientation, ScrollAreaProps };
@@ -9,26 +9,35 @@ function ScrollArea({
9
9
  "aria-labelledby": ariaLabelledBy,
10
10
  children,
11
11
  className,
12
+ ui,
12
13
  orientation = "vertical",
13
14
  ...props
14
15
  }) {
15
- const ui = theme();
16
+ const styles = theme();
16
17
  return /* @__PURE__ */ React.createElement(
17
18
  UIScrollArea.Root,
18
19
  {
19
20
  ...props,
20
21
  "data-slot": "root",
21
22
  "data-orientation": orientation,
22
- className: cn(ui.root(), className)
23
+ className: cn(styles.root(), ui?.root, className)
23
24
  },
24
- /* @__PURE__ */ React.createElement("span", { "aria-hidden": "true", "data-slot": "glass", className: ui.glass() }, /* @__PURE__ */ React.createElement(
25
+ /* @__PURE__ */ React.createElement(
25
26
  "span",
26
27
  {
27
28
  "aria-hidden": "true",
28
- "data-slot": "overlay",
29
- className: ui.overlay()
30
- }
31
- )),
29
+ "data-slot": "glass",
30
+ className: cn(styles.glass(), ui?.glass)
31
+ },
32
+ /* @__PURE__ */ React.createElement(
33
+ "span",
34
+ {
35
+ "aria-hidden": "true",
36
+ "data-slot": "overlay",
37
+ className: cn(styles.overlay(), ui?.overlay)
38
+ }
39
+ )
40
+ ),
32
41
  /* @__PURE__ */ React.createElement(
33
42
  UIScrollArea.Viewport,
34
43
  {
@@ -36,29 +45,54 @@ function ScrollArea({
36
45
  "aria-label": ariaLabel,
37
46
  "aria-labelledby": ariaLabelledBy,
38
47
  "data-slot": "viewport",
39
- className: ui.viewport()
48
+ className: cn(styles.viewport(), ui?.viewport)
40
49
  },
41
- /* @__PURE__ */ React.createElement(UIScrollArea.Content, { "data-slot": "content", className: ui.content() }, children)
50
+ /* @__PURE__ */ React.createElement(
51
+ UIScrollArea.Content,
52
+ {
53
+ "data-slot": "content",
54
+ className: cn(styles.content(), ui?.content)
55
+ },
56
+ children
57
+ )
42
58
  ),
43
59
  orientation !== "horizontal" ? /* @__PURE__ */ React.createElement(
44
60
  UIScrollArea.Scrollbar,
45
61
  {
46
62
  "data-slot": "scrollbar",
47
63
  orientation: "vertical",
48
- className: ui.scrollbar()
64
+ className: cn(styles.scrollbar(), ui?.scrollbar)
49
65
  },
50
- /* @__PURE__ */ React.createElement(UIScrollArea.Thumb, { "data-slot": "thumb", className: ui.thumb() })
66
+ /* @__PURE__ */ React.createElement(
67
+ UIScrollArea.Thumb,
68
+ {
69
+ "data-slot": "thumb",
70
+ className: cn(styles.thumb(), ui?.thumb)
71
+ }
72
+ )
51
73
  ) : null,
52
74
  orientation !== "vertical" ? /* @__PURE__ */ React.createElement(
53
75
  UIScrollArea.Scrollbar,
54
76
  {
55
77
  "data-slot": "scrollbar",
56
78
  orientation: "horizontal",
57
- className: ui.scrollbar()
79
+ className: cn(styles.scrollbar(), ui?.scrollbar)
58
80
  },
59
- /* @__PURE__ */ React.createElement(UIScrollArea.Thumb, { "data-slot": "thumb", className: ui.thumb() })
81
+ /* @__PURE__ */ React.createElement(
82
+ UIScrollArea.Thumb,
83
+ {
84
+ "data-slot": "thumb",
85
+ className: cn(styles.thumb(), ui?.thumb)
86
+ }
87
+ )
60
88
  ) : null,
61
- orientation === "both" ? /* @__PURE__ */ React.createElement(UIScrollArea.Corner, { "data-slot": "corner", className: ui.corner() }) : null
89
+ orientation === "both" ? /* @__PURE__ */ React.createElement(
90
+ UIScrollArea.Corner,
91
+ {
92
+ "data-slot": "corner",
93
+ className: cn(styles.corner(), ui?.corner)
94
+ }
95
+ ) : null
62
96
  );
63
97
  }
64
98
  export { ScrollArea };
@@ -1,8 +1,13 @@
1
1
  import { Slider as UISlider } from "@base-ui/react/slider";
2
2
  import * as React from "react";
3
+ import { type ComponentConfig } from "../internal/tv";
4
+ import theme from "../theme/slider";
5
+ type Slider = ComponentConfig<typeof theme>;
3
6
  type SliderProps<Value extends number | readonly number[] = number> = Omit<UISlider.Root.Props<Value>, "children" | "style" | "className"> & {
4
7
  /** Tailwind classes merged into the root. */
5
- className?: any;
8
+ className?: string;
9
+ /** Tailwind classes for internal slots, keyed by `data-slot`. */
10
+ ui?: Slider["slots"];
6
11
  /** Accessible name for the thumb at `index`. Useful for range sliders. */
7
12
  getAriaLabel?: UISlider.Thumb.Props["getAriaLabel"];
8
13
  /** Accessible value text for the thumb at `index`. */
@@ -13,6 +18,6 @@ type SliderProps<Value extends number | readonly number[] = number> = Omit<UISli
13
18
  * both are forwarded from the root to every thumb. `aria-describedby` is also
14
19
  * forwarded so supporting copy is announced with each thumb.
15
20
  */
16
- declare function Slider<Value extends number | readonly number[] = number>({ className, value, defaultValue, "aria-describedby": ariaDescribedBy, "aria-errormessage": ariaErrorMessage, "aria-invalid": ariaInvalid, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, getAriaLabel, getAriaValueText, ...props }: SliderProps<Value>): React.JSX.Element;
21
+ declare function Slider<Value extends number | readonly number[] = number>({ className, ui, value, defaultValue, "aria-describedby": ariaDescribedBy, "aria-errormessage": ariaErrorMessage, "aria-invalid": ariaInvalid, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, getAriaLabel, getAriaValueText, ...props }: SliderProps<Value>): React.JSX.Element;
17
22
  export { Slider };
18
23
  export type { SliderProps };
@@ -12,6 +12,7 @@ function setAriaAttribute(input, name, value) {
12
12
  }
13
13
  function Slider({
14
14
  className,
15
+ ui,
15
16
  value,
16
17
  defaultValue,
17
18
  "aria-describedby": ariaDescribedBy,
@@ -23,7 +24,7 @@ function Slider({
23
24
  getAriaValueText,
24
25
  ...props
25
26
  }) {
26
- const ui = theme();
27
+ const styles = theme();
27
28
  const syncThumbAria = React.useCallback(
28
29
  (input) => {
29
30
  if (!input) {
@@ -45,30 +46,45 @@ function Slider({
45
46
  value,
46
47
  defaultValue,
47
48
  "data-slot": "root",
48
- className: cn(ui.root(), className)
49
+ className: cn(styles.root(), ui?.root, className)
49
50
  },
50
- /* @__PURE__ */ React.createElement(UISlider.Control, { "data-slot": "control", className: ui.control() }, /* @__PURE__ */ React.createElement(UISlider.Track, { "data-slot": "track", className: ui.track() }, /* @__PURE__ */ React.createElement(
51
- UISlider.Indicator,
51
+ /* @__PURE__ */ React.createElement(
52
+ UISlider.Control,
52
53
  {
53
- "data-slot": "indicator",
54
- className: ui.indicator()
55
- }
56
- )), Array.from({ length: thumbCount }, (_, index) => /* @__PURE__ */ React.createElement(
57
- UISlider.Thumb,
58
- {
59
- key: index,
60
- index,
61
- "aria-describedby": ariaDescribedBy,
62
- "aria-label": ariaLabel,
63
- "aria-labelledby": ariaLabelledBy,
64
- getAriaLabel,
65
- getAriaValueText,
66
- inputRef: syncThumbAria,
67
- "data-slot": "thumb",
68
- className: ui.thumb()
54
+ "data-slot": "control",
55
+ className: cn(styles.control(), ui?.control)
69
56
  },
70
- /* @__PURE__ */ React.createElement("span", { "aria-hidden": "true", "data-layer": "thumb-glass" }, /* @__PURE__ */ React.createElement("span", { "data-layer": "thumb-lens" }), /* @__PURE__ */ React.createElement("span", { "data-layer": "thumb-specular" }), /* @__PURE__ */ React.createElement("span", { "data-layer": "thumb-glare" }))
71
- )))
57
+ /* @__PURE__ */ React.createElement(
58
+ UISlider.Track,
59
+ {
60
+ "data-slot": "track",
61
+ className: cn(styles.track(), ui?.track)
62
+ },
63
+ /* @__PURE__ */ React.createElement(
64
+ UISlider.Indicator,
65
+ {
66
+ "data-slot": "indicator",
67
+ className: cn(styles.indicator(), ui?.indicator)
68
+ }
69
+ )
70
+ ),
71
+ Array.from({ length: thumbCount }, (_, index) => /* @__PURE__ */ React.createElement(
72
+ UISlider.Thumb,
73
+ {
74
+ key: index,
75
+ index,
76
+ "aria-describedby": ariaDescribedBy,
77
+ "aria-label": ariaLabel,
78
+ "aria-labelledby": ariaLabelledBy,
79
+ getAriaLabel,
80
+ getAriaValueText,
81
+ inputRef: syncThumbAria,
82
+ "data-slot": "thumb",
83
+ className: cn(styles.thumb(), ui?.thumb)
84
+ },
85
+ /* @__PURE__ */ React.createElement("span", { "aria-hidden": "true", "data-layer": "thumb-glass" }, /* @__PURE__ */ React.createElement("span", { "data-layer": "thumb-lens" }), /* @__PURE__ */ React.createElement("span", { "data-layer": "thumb-specular" }), /* @__PURE__ */ React.createElement("span", { "data-layer": "thumb-glare" }))
86
+ ))
87
+ )
72
88
  );
73
89
  }
74
90
  export { Slider };
@@ -1,17 +1,21 @@
1
1
  import { Switch as UISwitch } from "@base-ui/react/switch";
2
2
  import * as React from "react";
3
3
  import { type VariantProps } from "tailwind-variants";
4
+ import { type ComponentConfig } from "../internal/tv";
4
5
  import theme from "../theme/switch";
6
+ type Switch = ComponentConfig<typeof theme>;
5
7
  interface SwitchProps extends Omit<UISwitch.Root.Props, "className" | "children" | "style" | "ref">, VariantProps<typeof theme> {
6
8
  /** Ref to the rendered root element. */
7
9
  ref?: React.Ref<HTMLElement>;
8
10
  /** Tailwind classes merged into the Base UI switch root. */
9
11
  className?: string;
12
+ /** Tailwind classes for internal slots, keyed by `data-slot`. */
13
+ ui?: Switch["slots"];
10
14
  /** Visible label. */
11
15
  label?: React.ReactNode;
12
16
  /** Optional supporting text. */
13
17
  description?: React.ReactNode;
14
18
  }
15
- declare function Switch({ className, label, description, size, disabled, readOnly, onCheckedChange, "aria-describedby": ariaDescribedBy, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...props }: SwitchProps): React.JSX.Element;
19
+ declare function Switch({ className, ui, label, description, size, disabled, readOnly, onCheckedChange, "aria-describedby": ariaDescribedBy, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...props }: SwitchProps): React.JSX.Element;
16
20
  export { Switch };
17
21
  export type { SwitchProps };
@@ -48,6 +48,7 @@ function LiquidGlassFilter({ id }) {
48
48
  }
49
49
  function Switch({
50
50
  className,
51
+ ui,
51
52
  label,
52
53
  description,
53
54
  size,
@@ -59,7 +60,7 @@ function Switch({
59
60
  "aria-labelledby": ariaLabelledBy,
60
61
  ...props
61
62
  }) {
62
- const ui = theme({ size });
63
+ const styles = theme({ size });
63
64
  const filterId = React.useId();
64
65
  const labelId = React.useId();
65
66
  const descriptionId = React.useId();
@@ -100,39 +101,62 @@ function Switch({
100
101
  "data-slot": "root",
101
102
  "data-animating": animating || void 0,
102
103
  onCheckedChange: handleCheckedChange,
103
- className: cn(ui.root(), className)
104
+ className: cn(styles.root(), ui?.root, className)
104
105
  },
105
- /* @__PURE__ */ React.createElement("span", { "data-slot": "container", className: ui.container() }, /* @__PURE__ */ React.createElement(
106
+ /* @__PURE__ */ React.createElement(
106
107
  "span",
107
108
  {
108
- "data-slot": "base",
109
- className: ui.base(),
110
- style: filterStyles
109
+ "data-slot": "container",
110
+ className: cn(styles.container(), ui?.container)
111
111
  },
112
- /* @__PURE__ */ React.createElement(LiquidGlassFilter, { id: filterId }),
113
- /* @__PURE__ */ React.createElement("span", { "aria-hidden": "true", "data-layer": "mask" }, /* @__PURE__ */ React.createElement("span", { "data-layer": "track" }, /* @__PURE__ */ React.createElement("span", { "data-layer": "track-mask" }))),
114
112
  /* @__PURE__ */ React.createElement(
115
- UISwitch.Thumb,
113
+ "span",
116
114
  {
117
- "data-slot": "thumb",
118
- "aria-hidden": "true",
119
- onTransitionEnd: handleThumbTransitionEnd,
120
- className: ui.thumb()
115
+ "data-slot": "base",
116
+ className: cn(styles.base(), ui?.base),
117
+ style: filterStyles
121
118
  },
122
- /* @__PURE__ */ React.createElement("span", { "aria-hidden": "true", "data-layer": "glass-rim" }),
123
- /* @__PURE__ */ React.createElement("span", { "data-layer": "glass-lens" }, /* @__PURE__ */ React.createElement("span", { "data-layer": "goo" }, /* @__PURE__ */ React.createElement("span", { "data-layer": "inner-glow" }), /* @__PURE__ */ React.createElement("span", { "data-layer": "fill" }))),
124
- /* @__PURE__ */ React.createElement("span", { "data-layer": "cover" })
119
+ /* @__PURE__ */ React.createElement(LiquidGlassFilter, { id: filterId }),
120
+ /* @__PURE__ */ React.createElement("span", { "aria-hidden": "true", "data-layer": "mask" }, /* @__PURE__ */ React.createElement("span", { "data-layer": "track" }, /* @__PURE__ */ React.createElement("span", { "data-layer": "track-mask" }))),
121
+ /* @__PURE__ */ React.createElement(
122
+ UISwitch.Thumb,
123
+ {
124
+ "data-slot": "thumb",
125
+ "aria-hidden": "true",
126
+ onTransitionEnd: handleThumbTransitionEnd,
127
+ className: cn(styles.thumb(), ui?.thumb)
128
+ },
129
+ /* @__PURE__ */ React.createElement("span", { "aria-hidden": "true", "data-layer": "glass-rim" }),
130
+ /* @__PURE__ */ React.createElement("span", { "data-layer": "glass-lens" }, /* @__PURE__ */ React.createElement("span", { "data-layer": "goo" }, /* @__PURE__ */ React.createElement("span", { "data-layer": "inner-glow" }), /* @__PURE__ */ React.createElement("span", { "data-layer": "fill" }))),
131
+ /* @__PURE__ */ React.createElement("span", { "data-layer": "cover" })
132
+ )
125
133
  )
126
- )),
127
- label || description ? /* @__PURE__ */ React.createElement("span", { "data-slot": "wrapper", className: ui.wrapper() }, label ? /* @__PURE__ */ React.createElement("span", { id: labelId, "data-slot": "label", className: ui.label() }, label) : null, description ? /* @__PURE__ */ React.createElement(
134
+ ),
135
+ label || description ? /* @__PURE__ */ React.createElement(
128
136
  "span",
129
137
  {
130
- id: descriptionId,
131
- "data-slot": "description",
132
- className: ui.description()
138
+ "data-slot": "wrapper",
139
+ className: cn(styles.wrapper(), ui?.wrapper)
133
140
  },
134
- description
135
- ) : null) : null
141
+ label ? /* @__PURE__ */ React.createElement(
142
+ "span",
143
+ {
144
+ id: labelId,
145
+ "data-slot": "label",
146
+ className: cn(styles.label(), ui?.label)
147
+ },
148
+ label
149
+ ) : null,
150
+ description ? /* @__PURE__ */ React.createElement(
151
+ "span",
152
+ {
153
+ id: descriptionId,
154
+ "data-slot": "description",
155
+ className: cn(styles.description(), ui?.description)
156
+ },
157
+ description
158
+ ) : null
159
+ ) : null
136
160
  );
137
161
  }
138
162
  export { Switch };
@@ -1,11 +1,14 @@
1
1
  import { Toast as UIToast } from "@base-ui/react/toast";
2
2
  import * as React from "react";
3
+ import { type ComponentConfig } from "../internal/tv";
4
+ import theme from "../theme/toast";
3
5
  /** Corner where the toast stack is anchored. */
4
6
  type ToastPosition = "top-left" | "top-right" | "bottom-left" | "bottom-right";
5
7
  interface ToastProviderProps extends Omit<UIToast.Provider.Props, "children"> {
6
8
  /** App content that can call `useToast`. */
7
9
  children?: React.ReactNode;
8
10
  }
11
+ type Toast = ComponentConfig<typeof theme>;
9
12
  interface ToastProps extends Omit<UIToast.Root.Props, "children" | "className" | "swipeDirection" | "toast"> {
10
13
  /** Corner where the toast stack is anchored. */
11
14
  position?: ToastPosition;
@@ -13,8 +16,10 @@ interface ToastProps extends Omit<UIToast.Root.Props, "children" | "className" |
13
16
  close?: React.ReactNode;
14
17
  /** Tailwind classes merged into each toast. */
15
18
  className?: string;
19
+ /** Tailwind classes for internal slots, keyed by `data-slot`. */
20
+ ui?: Toast["slots"];
16
21
  }
17
22
  declare function ToastProvider({ children, ...props }: ToastProviderProps): React.JSX.Element;
18
- declare function Toast({ position, close, className, ...props }: ToastProps): React.JSX.Element;
23
+ declare function Toast({ position, close, className, ui, ...props }: ToastProps): React.JSX.Element;
19
24
  export { Toast, ToastProvider };
20
25
  export type { ToastPosition, ToastProps, ToastProviderProps };
@@ -49,16 +49,17 @@ function Toast({
49
49
  position = "bottom-right",
50
50
  close,
51
51
  className,
52
+ ui,
52
53
  ...props
53
54
  }) {
54
55
  const { toasts } = useToast();
55
- const ui = theme({ position });
56
+ const styles = theme({ position });
56
57
  return /* @__PURE__ */ React.createElement(UIToast.Portal, null, /* @__PURE__ */ React.createElement(
57
58
  UIToast.Viewport,
58
59
  {
59
60
  "data-slot": "viewport",
60
61
  "data-position": position,
61
- className: ui.viewport()
62
+ className: cn(styles.viewport(), ui?.viewport)
62
63
  },
63
64
  toasts.map((toast) => /* @__PURE__ */ React.createElement(
64
65
  UIToast.Root,
@@ -66,25 +67,77 @@ function Toast({
66
67
  ...props,
67
68
  key: toast.id,
68
69
  toast,
69
- "data-slot": "toast",
70
- className: cn(ui.root(), className),
70
+ "data-slot": "root",
71
+ className: cn(styles.root(), ui?.root, className),
71
72
  swipeDirection: SWIPE_DIRECTIONS[position]
72
73
  },
73
- /* @__PURE__ */ React.createElement("span", { "aria-hidden": "true", "data-slot": "glass", className: ui.glass() }, /* @__PURE__ */ React.createElement(
74
+ /* @__PURE__ */ React.createElement(
74
75
  "span",
75
76
  {
77
+ key: "glass",
76
78
  "aria-hidden": "true",
77
- "data-slot": "overlay",
78
- className: ui.overlay()
79
- }
80
- )),
81
- /* @__PURE__ */ React.createElement(UIToast.Content, { "data-slot": "content", className: ui.content() }, /* @__PURE__ */ React.createElement(ToastStatusIcon, { type: toast.type, className: ui.icon() }), /* @__PURE__ */ React.createElement("div", { "data-slot": "text", className: ui.text() }, /* @__PURE__ */ React.createElement(UIToast.Title, { "data-slot": "title", className: ui.title() }), /* @__PURE__ */ React.createElement(
82
- UIToast.Description,
79
+ "data-slot": "glass",
80
+ className: cn(styles.glass(), ui?.glass)
81
+ },
82
+ /* @__PURE__ */ React.createElement(
83
+ "span",
84
+ {
85
+ "aria-hidden": "true",
86
+ "data-slot": "overlay",
87
+ className: cn(styles.overlay(), ui?.overlay)
88
+ }
89
+ )
90
+ ),
91
+ /* @__PURE__ */ React.createElement(
92
+ UIToast.Content,
83
93
  {
84
- "data-slot": "description",
85
- className: ui.description()
86
- }
87
- )), /* @__PURE__ */ React.createElement("div", { "data-slot": "actions", className: ui.actions() }, /* @__PURE__ */ React.createElement(UIToast.Action, { "data-slot": "action", className: ui.action() }), close ? close : /* @__PURE__ */ React.createElement(UIToast.Close, { "data-slot": "close", className: ui.close() }, /* @__PURE__ */ React.createElement(CloseIcon, { className: "size-4" }))))
94
+ key: "content",
95
+ "data-slot": "content",
96
+ className: cn(styles.content(), ui?.content)
97
+ },
98
+ /* @__PURE__ */ React.createElement(
99
+ ToastStatusIcon,
100
+ {
101
+ type: toast.type,
102
+ className: cn(styles.icon(), ui?.icon)
103
+ }
104
+ ),
105
+ /* @__PURE__ */ React.createElement("div", { "data-slot": "text", className: cn(styles.text(), ui?.text) }, /* @__PURE__ */ React.createElement(
106
+ UIToast.Title,
107
+ {
108
+ "data-slot": "title",
109
+ className: cn(styles.title(), ui?.title)
110
+ }
111
+ ), /* @__PURE__ */ React.createElement(
112
+ UIToast.Description,
113
+ {
114
+ "data-slot": "description",
115
+ className: cn(styles.description(), ui?.description)
116
+ }
117
+ )),
118
+ /* @__PURE__ */ React.createElement(
119
+ "div",
120
+ {
121
+ "data-slot": "actions",
122
+ className: cn(styles.actions(), ui?.actions)
123
+ },
124
+ /* @__PURE__ */ React.createElement(
125
+ UIToast.Action,
126
+ {
127
+ "data-slot": "action",
128
+ className: cn(styles.action(), ui?.action)
129
+ }
130
+ ),
131
+ close ? close : /* @__PURE__ */ React.createElement(
132
+ UIToast.Close,
133
+ {
134
+ "data-slot": "close",
135
+ className: cn(styles.close(), ui?.close)
136
+ },
137
+ /* @__PURE__ */ React.createElement(CloseIcon, { className: "size-4" })
138
+ )
139
+ )
140
+ )
88
141
  ))
89
142
  ));
90
143
  }
@@ -2,24 +2,30 @@ import { Toggle as UIToggle } from "@base-ui/react/toggle";
2
2
  import { ToggleGroup as UIToggleGroup } from "@base-ui/react/toggle-group";
3
3
  import * as React from "react";
4
4
  import { type VariantProps } from "tailwind-variants";
5
+ import { type ComponentConfig } from "../internal/tv";
5
6
  import theme from "../theme/toggle-group";
7
+ type ToggleGroup = ComponentConfig<typeof theme>;
6
8
  /** One option managed by the toggle group. */
7
- type ToggleGroupItemProps = Omit<UIToggle.Props, "className" | "children" | "style" | "value" | "pressed" | "defaultPressed"> & {
9
+ type ToggleGroupItemProps<Value extends string = string> = Omit<UIToggle.Props<Value>, "className" | "children" | "style" | "value" | "pressed" | "defaultPressed"> & {
8
10
  /** Value that identifies the option in the group value. */
9
- value: string;
11
+ value: Value;
10
12
  /** Visible content inside the item. */
11
13
  label?: React.ReactNode;
12
14
  /** Icon rendered before the label. */
13
15
  icon?: React.ReactNode;
14
16
  /** Tailwind classes merged into the item root. */
15
17
  className?: string;
18
+ /** Tailwind classes for this item's internal slots, keyed by `data-slot`. */
19
+ ui?: Partial<Pick<ToggleGroup["slots"], "item" | "content" | "icon" | "label">>;
16
20
  };
17
21
  type ToggleGroupProps<Value extends string = string> = Omit<UIToggleGroup.Props<Value>, "className" | "style" | "children"> & VariantProps<typeof theme> & {
18
22
  /** Options rendered by the toggle group. */
19
- items: readonly ToggleGroupItemProps[];
23
+ items: readonly ToggleGroupItemProps<Value>[];
20
24
  /** Tailwind classes merged into the group root. */
21
- className?: any;
25
+ className?: string;
26
+ /** Tailwind classes for internal slots, keyed by `data-slot`. */
27
+ ui?: ToggleGroup["slots"];
22
28
  };
23
- declare function ToggleGroup<Value extends string = string>({ className, size, items, ...props }: ToggleGroupProps<Value>): React.JSX.Element;
29
+ declare function ToggleGroup<Value extends string = string>({ className, ui, size, items, ...props }: ToggleGroupProps<Value>): React.JSX.Element;
24
30
  export { ToggleGroup };
25
31
  export type { ToggleGroupItemProps, ToggleGroupProps };