@nexub/react 7.4.0 → 7.5.0

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.
@@ -2,37 +2,94 @@
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import * as RadixSelect from "@radix-ui/react-select";
5
- import { Check, ChevronDown, ChevronUp } from "@nexub/icons";
5
+ import { Check, ChevronDown, ChevronUp, X } from "@nexub/icons";
6
6
  import { cn } from "../../utils/cn.js";
7
7
  import { field, fieldFocusVisible, fieldInvalid } from "../../utils/control.js";
8
8
  import { floatingSurface, menuLabel, menuSeparator } from "../../utils/surface.js";
9
- const Root = RadixSelect.Root;
10
- const Group = RadixSelect.Group;
11
- const Value = RadixSelect.Value;
12
- const Trigger = React.forwardRef(
13
- ({ className, children, invalid, ...props }, ref) => /* @__PURE__ */ jsxs(
14
- RadixSelect.Trigger,
9
+ import { useControllableState } from "../../hooks/useControllableState.js";
10
+ import { useMergedRefs } from "../../hooks/useMergedRefs.js";
11
+ import { useNexubMessages } from "../NexubProvider/NexubProvider.js";
12
+ import { IconButton } from "../IconButton/IconButton.js";
13
+ const SelectContext = React.createContext({
14
+ clearable: false,
15
+ hasValue: false,
16
+ clear: () => {
17
+ },
18
+ query: "",
19
+ setQuery: () => {
20
+ }
21
+ });
22
+ const Root = ({ clearable = false, value, defaultValue, onValueChange, onOpenChange, ...props }) => {
23
+ const [current, setCurrent] = useControllableState({ value, defaultValue, onChange: onValueChange });
24
+ const [query, setQuery] = React.useState("");
25
+ const ctx = React.useMemo(
26
+ () => ({ clearable, hasValue: Boolean(current), clear: () => setCurrent(""), query, setQuery }),
27
+ [clearable, current, setCurrent, query]
28
+ );
29
+ return /* @__PURE__ */ jsx(SelectContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(
30
+ RadixSelect.Root,
15
31
  {
16
- ref,
17
- className: cn(
18
- "flex h-control-md w-full items-center justify-between gap-2 px-3.5 text-body-md",
19
- field,
20
- fieldFocusVisible,
21
- // Open reads like focus: the 2px primary border.
22
- "data-[state=open]:border-[var(--color-primary)] data-[state=open]:shadow-[inset_0_0_0_1px_var(--color-primary)]",
23
- "data-[placeholder]:text-[var(--color-on-surface-muted)]",
24
- "disabled:cursor-not-allowed disabled:border-[var(--color-outline-variant)] disabled:bg-[var(--color-surface-container-low)] disabled:text-[var(--color-text-disabled)]",
25
- invalid && fieldInvalid,
26
- "[&>span]:line-clamp-1",
27
- className
28
- ),
29
32
  ...props,
30
- children: [
31
- children,
32
- /* @__PURE__ */ jsx(RadixSelect.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { size: "sm", className: "shrink-0 text-[var(--color-on-surface-variant)]", "aria-hidden": "true" }) })
33
- ]
33
+ ...clearable ? { value: current ?? "", onValueChange: setCurrent } : { value, defaultValue, onValueChange },
34
+ onOpenChange: (open) => {
35
+ if (!open) setQuery("");
36
+ onOpenChange?.(open);
37
+ }
34
38
  }
35
- )
39
+ ) });
40
+ };
41
+ Root.displayName = "Select.Root";
42
+ const Group = RadixSelect.Group;
43
+ const Value = RadixSelect.Value;
44
+ const Trigger = React.forwardRef(
45
+ ({ className, children, invalid, ...props }, ref) => {
46
+ const ctx = React.useContext(SelectContext);
47
+ const messages = useNexubMessages();
48
+ const innerRef = React.useRef(null);
49
+ const mergedRef = useMergedRefs(ref, innerRef);
50
+ const showClear = ctx.clearable && ctx.hasValue && !props.disabled;
51
+ const trigger = /* @__PURE__ */ jsxs(
52
+ RadixSelect.Trigger,
53
+ {
54
+ ref: mergedRef,
55
+ className: cn(
56
+ "flex h-control-md w-full items-center justify-between gap-2 px-3.5 text-body-md",
57
+ field,
58
+ fieldFocusVisible,
59
+ // Open reads like focus: the 2px primary border.
60
+ "data-[state=open]:border-[var(--color-primary)] data-[state=open]:shadow-[inset_0_0_0_1px_var(--color-primary)]",
61
+ "data-[placeholder]:text-[var(--color-on-surface-muted)]",
62
+ "disabled:cursor-not-allowed disabled:border-[var(--color-outline-variant)] disabled:bg-[var(--color-surface-container-low)] disabled:text-[var(--color-text-disabled)]",
63
+ invalid && fieldInvalid,
64
+ "[&>span]:line-clamp-1",
65
+ className
66
+ ),
67
+ ...props,
68
+ children: [
69
+ children,
70
+ showClear && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "ms-auto w-control-xs shrink-0" }),
71
+ /* @__PURE__ */ jsx(RadixSelect.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { size: "sm", className: "shrink-0 text-[var(--color-on-surface-variant)]", "aria-hidden": "true" }) })
72
+ ]
73
+ }
74
+ );
75
+ if (!ctx.clearable) return trigger;
76
+ return /* @__PURE__ */ jsxs("div", { className: "relative w-full", children: [
77
+ trigger,
78
+ showClear && /* @__PURE__ */ jsx(
79
+ IconButton,
80
+ {
81
+ size: "xs",
82
+ label: messages.clearSelection,
83
+ className: "absolute end-9.5 top-1/2 -translate-y-1/2",
84
+ onClick: () => {
85
+ ctx.clear();
86
+ innerRef.current?.focus();
87
+ },
88
+ children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4", "aria-hidden": "true" })
89
+ }
90
+ )
91
+ ] });
92
+ }
36
93
  );
37
94
  Trigger.displayName = "Select.Trigger";
38
95
  const ScrollUpButton = React.forwardRef(
@@ -60,35 +117,66 @@ const ScrollDownButton = React.forwardRef(
60
117
  );
61
118
  ScrollDownButton.displayName = "Select.ScrollDownButton";
62
119
  const Content = React.forwardRef(
63
- ({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(RadixSelect.Portal, { children: /* @__PURE__ */ jsxs(
64
- RadixSelect.Content,
65
- {
66
- ref,
67
- className: cn(
68
- "relative z-[var(--z-popover)] max-h-96 min-w-32 overflow-hidden",
69
- floatingSurface,
70
- "nx-motion nx-pop origin-[var(--radix-select-content-transform-origin)]",
71
- position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1 w-[var(--radix-select-trigger-width)]",
72
- className
73
- ),
74
- position,
75
- ...props,
76
- children: [
77
- /* @__PURE__ */ jsx(ScrollUpButton, {}),
78
- /* @__PURE__ */ jsx(
79
- RadixSelect.Viewport,
80
- {
81
- className: cn(
82
- "p-1.5",
83
- position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
84
- ),
85
- children
86
- }
120
+ ({ className, children, position = "popper", searchable, onKeyDown, ...props }, ref) => {
121
+ const ctx = React.useContext(SelectContext);
122
+ const messages = useNexubMessages();
123
+ const searchRef = React.useRef(null);
124
+ return /* @__PURE__ */ jsx(RadixSelect.Portal, { children: /* @__PURE__ */ jsxs(
125
+ RadixSelect.Content,
126
+ {
127
+ ref,
128
+ className: cn(
129
+ "relative z-[var(--z-popover)] max-h-96 min-w-32 overflow-hidden",
130
+ floatingSurface,
131
+ "nx-motion nx-pop origin-[var(--radix-select-content-transform-origin)]",
132
+ position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1 w-[var(--radix-select-trigger-width)]",
133
+ className
87
134
  ),
88
- /* @__PURE__ */ jsx(ScrollDownButton, {})
89
- ]
90
- }
91
- ) })
135
+ position,
136
+ onKeyDown: (e) => {
137
+ onKeyDown?.(e);
138
+ if (searchable && !e.defaultPrevented && e.target !== searchRef.current && e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {
139
+ const input = searchRef.current;
140
+ if (!input) return;
141
+ e.preventDefault();
142
+ input.focus();
143
+ input.setRangeText(e.key, input.value.length, input.value.length, "end");
144
+ input.dispatchEvent(new Event("input", { bubbles: true }));
145
+ }
146
+ },
147
+ ...props,
148
+ children: [
149
+ searchable && /* @__PURE__ */ jsx("div", { className: "p-1.5 pb-0", children: /* @__PURE__ */ jsx(
150
+ "input",
151
+ {
152
+ ref: searchRef,
153
+ type: "text",
154
+ value: ctx.query,
155
+ onChange: (e) => ctx.setQuery(e.target.value),
156
+ onKeyDown: (e) => {
157
+ if (e.key.length === 1 || e.key === "Home" || e.key === "End") e.stopPropagation();
158
+ },
159
+ placeholder: messages.searchPlaceholder,
160
+ "aria-label": messages.search,
161
+ className: cn("h-control-sm w-full px-3 text-body-sm", field, fieldFocusVisible)
162
+ }
163
+ ) }),
164
+ /* @__PURE__ */ jsx(ScrollUpButton, {}),
165
+ /* @__PURE__ */ jsx(
166
+ RadixSelect.Viewport,
167
+ {
168
+ className: cn(
169
+ "p-1.5",
170
+ position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
171
+ ),
172
+ children
173
+ }
174
+ ),
175
+ /* @__PURE__ */ jsx(ScrollDownButton, {})
176
+ ]
177
+ }
178
+ ) });
179
+ }
92
180
  );
93
181
  Content.displayName = "Select.Content";
94
182
  const Label = React.forwardRef(
@@ -103,24 +191,35 @@ const Label = React.forwardRef(
103
191
  );
104
192
  Label.displayName = "Select.Label";
105
193
  const Item = React.forwardRef(
106
- ({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
107
- RadixSelect.Item,
108
- {
109
- ref,
110
- className: cn(
111
- "relative flex w-full cursor-default select-none items-center rounded-[10px] py-2 ps-8 pe-2 text-body-sm text-[var(--color-on-surface)] outline-none",
112
- // Highlight = the on-surface state layer at hover opacity.
113
- "focus:bg-[color-mix(in_srgb,var(--color-on-surface)_8%,transparent)]",
114
- "data-[disabled]:pointer-events-none data-[disabled]:text-[var(--color-text-disabled)]",
115
- className
116
- ),
117
- ...props,
118
- children: [
119
- /* @__PURE__ */ jsx("span", { className: "absolute start-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(RadixSelect.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { size: "xs", "aria-hidden": "true" }) }) }),
120
- /* @__PURE__ */ jsx(RadixSelect.ItemText, { children })
121
- ]
122
- }
123
- )
194
+ ({ className, children, description, ...props }, ref) => {
195
+ const { query } = React.useContext(SelectContext);
196
+ const descriptionId = React.useId();
197
+ const text = props.textValue ?? (typeof children === "string" ? children : void 0);
198
+ const filtered = Boolean(query.trim()) && text !== void 0 && !text.toLowerCase().includes(query.trim().toLowerCase());
199
+ return /* @__PURE__ */ jsxs(
200
+ RadixSelect.Item,
201
+ {
202
+ ref,
203
+ "aria-describedby": description ? descriptionId : void 0,
204
+ className: cn(
205
+ "relative flex w-full cursor-default select-none items-center rounded-[10px] py-2 ps-8 pe-2 text-body-sm text-[var(--color-on-surface)] outline-none",
206
+ // Highlight = the on-surface state layer at hover opacity.
207
+ "focus:bg-[color-mix(in_srgb,var(--color-on-surface)_8%,transparent)]",
208
+ "data-[disabled]:pointer-events-none data-[disabled]:text-[var(--color-text-disabled)]",
209
+ className,
210
+ filtered && "hidden"
211
+ ),
212
+ ...props,
213
+ children: [
214
+ /* @__PURE__ */ jsx("span", { className: "absolute start-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(RadixSelect.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { size: "xs", "aria-hidden": "true" }) }) }),
215
+ description ? /* @__PURE__ */ jsxs("span", { className: "flex flex-col", children: [
216
+ /* @__PURE__ */ jsx(RadixSelect.ItemText, { children }),
217
+ /* @__PURE__ */ jsx("span", { id: descriptionId, className: "text-label-sm text-[var(--color-on-surface-muted)]", children: description })
218
+ ] }) : /* @__PURE__ */ jsx(RadixSelect.ItemText, { children })
219
+ ]
220
+ }
221
+ );
222
+ }
124
223
  );
125
224
  Item.displayName = "Select.Item";
126
225
  const Separator = React.forwardRef(
@@ -1,7 +1,17 @@
1
1
  import * as React from 'react';
2
2
  import * as RadixSlider from '@radix-ui/react-slider';
3
+ export type SliderMark = number | {
4
+ value: number;
5
+ label?: string;
6
+ };
3
7
  export interface SliderProps extends RadixSlider.SliderProps {
4
8
  /** Accessible name per thumb (e.g. ['Minimum', 'Maximum']). Falls back to `aria-label`. */
5
9
  thumbLabels?: string[];
10
+ /** Ticks along the track, optionally labelled (`[0, { value: 50, label: '50%' }, 100]`). */
11
+ marks?: SliderMark[];
12
+ /** Value bubble above each thumb: `true` always, `'hover'` on hover, focus and drag. */
13
+ showValue?: boolean | 'hover';
14
+ /** Formats the bubble and each thumb's `aria-valuetext`. */
15
+ formatValue?: (value: number) => string;
6
16
  }
7
17
  export declare const Slider: React.ForwardRefExoticComponent<SliderProps & React.RefAttributes<HTMLSpanElement>>;
@@ -4,25 +4,70 @@ import * as React from "react";
4
4
  import * as RadixSlider from "@radix-ui/react-slider";
5
5
  import { cn } from "../../utils/cn.js";
6
6
  const Slider = React.forwardRef(
7
- ({ className, thumbLabels, "aria-label": ariaLabel, ...props }, ref) => {
7
+ ({ className, thumbLabels, marks, showValue, formatValue, "aria-label": ariaLabel, onValueChange, ...props }, ref) => {
8
+ const { min = 0, max = 100, inverted } = props;
9
+ const [own, setOwn] = React.useState(props.defaultValue ?? [min]);
10
+ const values = props.value ?? own;
8
11
  const count = (props.value ?? props.defaultValue ?? [0]).length;
12
+ const format = formatValue ?? String;
13
+ const at = (v) => {
14
+ const p = (v - min) / (max - min) * 100;
15
+ const pct = inverted ? 100 - p : p;
16
+ return { insetInlineStart: `calc(${pct}% + ${(0.5 - pct / 100) * 1.25}rem)` };
17
+ };
18
+ const list = marks?.map((m) => typeof m === "number" ? { value: m } : m);
19
+ const labelled = list?.some((m) => m.label);
9
20
  return /* @__PURE__ */ jsxs(
10
21
  RadixSlider.Root,
11
22
  {
12
23
  ref,
13
- className: cn("group relative flex h-control-sm w-full touch-none select-none items-center", className),
24
+ className: cn(
25
+ "group relative flex h-control-sm w-full touch-none select-none items-center",
26
+ labelled && "mb-5",
27
+ className
28
+ ),
29
+ onValueChange: (v) => {
30
+ setOwn(v);
31
+ onValueChange?.(v);
32
+ },
14
33
  ...props,
15
34
  children: [
16
35
  /* @__PURE__ */ jsx(RadixSlider.Track, { className: "relative h-1.5 w-full grow overflow-hidden rounded-full bg-[var(--color-surface-container-highest)]", children: /* @__PURE__ */ jsx(RadixSlider.Range, { className: "absolute h-full bg-[var(--color-primary)] group-data-[disabled]:bg-[var(--color-text-disabled)]" }) }),
36
+ list?.map((m) => /* @__PURE__ */ jsxs(
37
+ "span",
38
+ {
39
+ "aria-hidden": "true",
40
+ "data-mark": m.value,
41
+ className: "pointer-events-none absolute inset-y-0 flex w-0 flex-col items-center justify-center",
42
+ style: at(m.value),
43
+ children: [
44
+ /* @__PURE__ */ jsx("span", { className: "h-1 w-1 shrink-0 rounded-full bg-[var(--color-on-surface-muted)]" }),
45
+ m.label && /* @__PURE__ */ jsx("span", { className: "absolute top-full whitespace-nowrap text-label-sm text-[var(--color-on-surface-muted)]", children: m.label })
46
+ ]
47
+ },
48
+ m.value
49
+ )),
17
50
  Array.from({ length: count }, (_, i) => /* @__PURE__ */ jsx(
18
51
  RadixSlider.Thumb,
19
52
  {
20
53
  "aria-label": thumbLabels?.[i] ?? ariaLabel,
54
+ "aria-valuetext": formatValue && values[i] !== void 0 ? formatValue(values[i]) : void 0,
21
55
  className: cn(
22
- "nx-state-layer block h-5 w-5 rounded-full border-2 border-[var(--color-surface-container-lowest)] bg-[var(--color-primary)] text-[var(--color-primary)] shadow-elevation-1",
56
+ "nx-state-layer group/thumb relative block h-5 w-5 rounded-full border-2 border-[var(--color-surface-container-lowest)] bg-[var(--color-primary)] text-[var(--color-primary)] shadow-elevation-1",
23
57
  "before:-inset-2.5 cursor-grab active:cursor-grabbing",
24
58
  // Opaque disabled knob (text-disabled is translucent and would show the range through it).
25
59
  "group-data-[disabled]:pointer-events-none group-data-[disabled]:bg-[color-mix(in_srgb,var(--color-on-surface)_38%,var(--color-surface))]"
60
+ ),
61
+ children: showValue && values[i] !== void 0 && /* @__PURE__ */ jsx(
62
+ "span",
63
+ {
64
+ "aria-hidden": "true",
65
+ className: cn(
66
+ "pointer-events-none absolute bottom-full left-1/2 mb-2 -translate-x-1/2 whitespace-nowrap rounded-shape-tooltip bg-[var(--color-inverse-surface)] px-2 py-1 text-label-md text-[var(--color-inverse-on-surface)] shadow-elevation-1 transition-opacity",
67
+ showValue === "hover" && "opacity-0 group-hover/thumb:opacity-100 group-focus/thumb:opacity-100"
68
+ ),
69
+ children: format(values[i])
70
+ }
26
71
  )
27
72
  },
28
73
  i
@@ -1,2 +1,2 @@
1
1
  export { Slider } from './Slider.js';
2
- export type { SliderProps } from './Slider.js';
2
+ export type { SliderProps, SliderMark } from './Slider.js';
@@ -8,5 +8,11 @@ export declare const thumbVariants: (props?: ({
8
8
  size?: "sm" | "md" | "lg" | null | undefined;
9
9
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
10
10
  export interface SwitchProps extends RadixSwitch.SwitchProps, VariantProps<typeof switchVariants> {
11
+ /** Spinner in the thumb and `aria-busy`; clicks don't toggle while loading. Stays focusable. */
12
+ loading?: boolean;
13
+ /** Small icon inside the thumb while on. */
14
+ checkedIcon?: React.ReactNode;
15
+ /** Small icon inside the thumb while off. */
16
+ uncheckedIcon?: React.ReactNode;
11
17
  }
12
18
  export declare const Switch: React.ForwardRefExoticComponent<SwitchProps & React.RefAttributes<HTMLButtonElement>>;
@@ -1,9 +1,10 @@
1
1
  "use client";
2
- import { jsx } from "react/jsx-runtime";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import * as RadixSwitch from "@radix-ui/react-switch";
5
5
  import { cn } from "../../utils/cn.js";
6
6
  import { cva } from "class-variance-authority";
7
+ import { spinnerVariants } from "../Spinner/Spinner.js";
7
8
  const switchVariants = cva(
8
9
  // Off: tonal track with a 2px outline (>= 3:1, WCAG 1.4.11). On: primary.
9
10
  // Focus = the global ring (it follows the capsule).
@@ -43,8 +44,34 @@ const thumbVariants = cva(
43
44
  defaultVariants: { size: "md" }
44
45
  }
45
46
  );
47
+ const thumbSlot = "hidden h-full w-full items-center justify-center [&>svg]:h-2/3 [&>svg]:w-2/3";
46
48
  const Switch = React.forwardRef(
47
- ({ className, size, ...props }, ref) => /* @__PURE__ */ jsx(RadixSwitch.Root, { ref, className: cn(switchVariants({ size }), "nx-hit", className), ...props, children: /* @__PURE__ */ jsx(RadixSwitch.Thumb, { className: cn(thumbVariants({ size })) }) })
49
+ ({ className, size, loading, checkedIcon, uncheckedIcon, onClick, ...props }, ref) => /* @__PURE__ */ jsx(
50
+ RadixSwitch.Root,
51
+ {
52
+ ref,
53
+ className: cn(switchVariants({ size }), "nx-hit", loading && "cursor-progress", className),
54
+ "aria-busy": loading || void 0,
55
+ onClick: (e) => {
56
+ onClick?.(e);
57
+ if (loading) e.preventDefault();
58
+ },
59
+ ...props,
60
+ children: /* @__PURE__ */ jsx(
61
+ RadixSwitch.Thumb,
62
+ {
63
+ className: cn(
64
+ thumbVariants({ size }),
65
+ (loading || checkedIcon || uncheckedIcon) && "group/thumb flex items-center justify-center data-[state=checked]:text-[var(--color-primary)] data-[state=unchecked]:text-[var(--color-surface-container-highest)]"
66
+ ),
67
+ children: loading ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn(spinnerVariants({ size: "xs" }), "h-2/3 w-2/3 border-current border-t-transparent") }) : /* @__PURE__ */ jsxs(Fragment, { children: [
68
+ checkedIcon && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn(thumbSlot, "group-data-[state=checked]/thumb:flex"), children: checkedIcon }),
69
+ uncheckedIcon && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn(thumbSlot, "group-data-[state=unchecked]/thumb:flex"), children: uncheckedIcon })
70
+ ] })
71
+ }
72
+ )
73
+ }
74
+ )
48
75
  );
49
76
  Switch.displayName = "Switch";
50
77
  export {
package/dist/index.d.ts CHANGED
@@ -180,7 +180,7 @@ export { Checkbox } from './components/Checkbox/index.js';
180
180
  export type { CheckboxProps } from './components/Checkbox/index.js';
181
181
  export { RadioGroup } from './components/RadioGroup/index.js';
182
182
  export { Slider } from './components/Slider/index.js';
183
- export type { SliderProps } from './components/Slider/index.js';
183
+ export type { SliderProps, SliderMark } from './components/Slider/index.js';
184
184
  export { Toggle, toggleVariants } from './components/Toggle/index.js';
185
185
  export type { ToggleProps } from './components/Toggle/index.js';
186
186
  export { ToggleGroup } from './components/ToggleGroup/index.js';