@nexub/react 7.8.0 → 8.0.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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "7.8.0",
2
+ "version": "8.0.0",
3
3
  "standard": "WCAG 2.2 Level AA",
4
4
  "method": {
5
5
  "automated": "axe-core rules tagged wcag2a, wcag2aa, wcag21a, wcag21aa and wcag22aa, run on every Storybook story in light and dark, and on open popups (menus, listboxes, dialogs), on every pull request; a new violation fails the build.",
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import * as RadixAlertDialog from '@radix-ui/react-alert-dialog';
3
3
  import { type ScrollLock } from '../../hooks/useClassScrollLock.js';
4
4
  export interface AlertDialogRootProps extends RadixAlertDialog.AlertDialogProps {
5
- /** See Dialog.Root `scrollLock`. @default 'style' (becomes 'class' in 8.0) */
5
+ /** See Dialog.Root `scrollLock`. @default 'class' (since 8.0) */
6
6
  scrollLock?: ScrollLock;
7
7
  }
8
8
  declare function Root({ scrollLock, ...props }: AlertDialogRootProps): React.JSX.Element;
@@ -10,7 +10,7 @@ import { useNexubMessages } from "../NexubProvider/NexubProvider.js";
10
10
  import { ClassLockOverlay, ScrollLockContext } from "../../hooks/useClassScrollLock.js";
11
11
  const ConfirmContext = React.createContext(null);
12
12
  const ALERT_LOCK = { style: { scrollLock: "style", modal: true }, class: { scrollLock: "class", modal: true } };
13
- function Root({ scrollLock = "style", ...props }) {
13
+ function Root({ scrollLock = "class", ...props }) {
14
14
  return /* @__PURE__ */ jsx(ScrollLockContext.Provider, { value: ALERT_LOCK[scrollLock], children: /* @__PURE__ */ jsx(RadixAlertDialog.Root, { ...props }) });
15
15
  }
16
16
  const Trigger = RadixAlertDialog.Trigger;
@@ -5,7 +5,7 @@ import { cva } from "class-variance-authority";
5
5
  import { cn } from "../../utils/cn.js";
6
6
  import { useNexubMessages } from "../NexubProvider/NexubProvider.js";
7
7
  const chipVariants = cva(
8
- "inline-flex items-center gap-1 rounded-shape-control select-none",
8
+ "inline-flex items-center gap-1 rounded-[var(--shape-pill,var(--shape-control))] select-none",
9
9
  {
10
10
  variants: {
11
11
  size: {
@@ -7,8 +7,8 @@ export interface CommandPaletteRootProps extends RadixDialog.DialogProps {
7
7
  label?: string;
8
8
  /**
9
9
  * How page scroll is locked while open.
10
- * - `'style'` (default): Radix's lock, which injects a `<style>` tag (blocked by `style-src 'self'`).
11
- * - `'class'`: the `nexub-scroll-lock` class from `@nexub/themes/base`. Strict-CSP safe.
10
+ * - `'class'` (default since 8.0): the `nexub-scroll-lock` class from `@nexub/themes/base`. Strict-CSP safe.
11
+ * - `'style'`: Radix's lock, which injects a `<style>` tag (blocked by `style-src 'self'`).
12
12
  */
13
13
  scrollLock?: 'style' | 'class';
14
14
  /** `false` when the items are already filtered (e.g. async search results). @default true */
@@ -32,7 +32,7 @@ const Root = React.forwardRef(
32
32
  ({
33
33
  children,
34
34
  label: labelProp,
35
- scrollLock = "style",
35
+ scrollLock = "class",
36
36
  shouldFilter,
37
37
  shortcut,
38
38
  open: openProp,
@@ -7,7 +7,7 @@ export interface DialogRootProps extends RadixDialog.DialogProps {
7
7
  /**
8
8
  * `'class'` locks page scroll with a class on <html> instead of the <style>
9
9
  * Radix injects, so the dialog works under a strict `style-src` with no nonce.
10
- * @default 'style' (becomes 'class' in 8.0)
10
+ * @default 'class' (since 8.0)
11
11
  */
12
12
  scrollLock?: ScrollLock;
13
13
  }
@@ -10,7 +10,7 @@ import { useMediaQuery } from "../../hooks/useMediaQuery.js";
10
10
  import { X } from "@nexub/icons";
11
11
  import { IconButton } from "../IconButton/IconButton.js";
12
12
  import { useNexubMessages } from "../NexubProvider/NexubProvider.js";
13
- function Root({ scrollLock = "style", modal = true, ...props }) {
13
+ function Root({ scrollLock = "class", modal = true, ...props }) {
14
14
  const lock = React.useMemo(() => ({ scrollLock, modal }), [scrollLock, modal]);
15
15
  return /* @__PURE__ */ jsx(ScrollLockContext.Provider, { value: lock, children: /* @__PURE__ */ jsx(RadixDialog.Root, { modal, ...props }) });
16
16
  }
@@ -21,7 +21,7 @@ export interface DrawerRootProps {
21
21
  * - `'class'`: adds the `nexub-scroll-lock` class from `@nexub/themes/base` to `<html>`.
22
22
  * Injects nothing, so it works under `style-src 'self'`. Focus trap, Escape and
23
23
  * outside-click dismissal are unchanged.
24
- * @default 'style'
24
+ * @default 'class' (since 8.0)
25
25
  */
26
26
  scrollLock?: 'style' | 'class';
27
27
  /** When `false`, dragging, outside clicks and Escape don't close the drawer. @default true */
@@ -8,7 +8,7 @@ import { scrim } from "../../utils/surface.js";
8
8
  import { useClassScrollLock } from "../../hooks/useClassScrollLock.js";
9
9
  import { glassSurfaceClass } from "../../utils/glass.js";
10
10
  const DrawerContext = React.createContext({ scrollLock: "style", open: false, modal: true });
11
- function Root({ scrollLock = "style", onOpenChange, ...props }) {
11
+ function Root({ scrollLock = "class", onOpenChange, ...props }) {
12
12
  const [uncontrolledOpen, setUncontrolledOpen] = React.useState(props.defaultOpen ?? false);
13
13
  const open = props.open ?? uncontrolledOpen;
14
14
  return /* @__PURE__ */ jsx(DrawerContext.Provider, { value: { scrollLock, open, modal: props.modal ?? true }, children: /* @__PURE__ */ jsx(
@@ -12,7 +12,7 @@ const FilterChip = React.forwardRef(
12
12
  {
13
13
  className: cn(
14
14
  // Matches Chip; hover/press come from the state layer.
15
- "nx-state-layer inline-flex items-center gap-1 rounded-shape-control border h-8 px-3 text-label-lg select-none",
15
+ "nx-state-layer inline-flex items-center gap-1 rounded-[var(--shape-pill,var(--shape-control))] border h-8 px-3 text-label-lg select-none",
16
16
  selected ? "bg-[var(--color-secondary-container)] text-[var(--color-on-secondary-container)] border-transparent" : "bg-[var(--color-surface-container-low)] text-[var(--color-on-surface-variant)] border-[var(--color-outline-variant)]"
17
17
  ),
18
18
  children: [
@@ -22,7 +22,7 @@ const FilterChip = React.forwardRef(
22
22
  ref,
23
23
  type: "button",
24
24
  className: cn(
25
- "inline-flex items-center gap-1 bg-transparent border-0 p-0 m-0 cursor-pointer rounded-shape-control text-current",
25
+ "inline-flex items-center gap-1 bg-transparent border-0 p-0 m-0 cursor-pointer rounded-[var(--shape-pill,var(--shape-control))] text-current",
26
26
  disabledText,
27
27
  className
28
28
  ),
@@ -1,12 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import type { MotionBaseProps } from './motion.types.js';
3
- export interface CollapseProps extends Omit<MotionBaseProps, 'easing'>, React.HTMLAttributes<HTMLDivElement> {
4
- /**
5
- * Legacy: set it to use `--duration-*` + `--ease-{value}` instead of the
6
- * spatial spring for the height transition.
7
- * @deprecated since 7.3, removed in 8.0 (see MotionBaseProps.easing).
8
- */
9
- easing?: MotionBaseProps['easing'];
3
+ export interface CollapseProps extends MotionBaseProps, React.HTMLAttributes<HTMLDivElement> {
10
4
  /**
11
5
  * Starting height when collapsed. Useful for "peek" effects.
12
6
  * @default 0
@@ -1,11 +1,10 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
- import { DURATION_MS, SPRING_MS, SPRING_SPEED, spring, usePrefersReducedMotion } from "./useMotion.js";
4
+ import { SPRING_MS, SPRING_SPEED, spring, usePrefersReducedMotion } from "./useMotion.js";
5
5
  const Collapse = React.forwardRef(function Collapse2({
6
6
  in: visible,
7
7
  duration = "normal",
8
- easing,
9
8
  unmountOnExit = false,
10
9
  collapsedHeight = 0,
11
10
  children,
@@ -14,9 +13,8 @@ const Collapse = React.forwardRef(function Collapse2({
14
13
  ...rest
15
14
  }, ref) {
16
15
  const reduced = usePrefersReducedMotion();
17
- const legacy = easing !== void 0;
18
16
  const instant = duration === "instant" || reduced;
19
- const settleMs = instant ? 0 : legacy ? DURATION_MS[duration] : SPRING_MS.spatial[SPRING_SPEED[duration]];
17
+ const settleMs = instant ? 0 : SPRING_MS.spatial[SPRING_SPEED[duration]];
20
18
  const [mounted, setMounted] = React.useState(unmountOnExit ? visible : true);
21
19
  const [expanded, setExpanded] = React.useState(visible);
22
20
  const [settled, setSettled] = React.useState(true);
@@ -56,7 +54,7 @@ const Collapse = React.forwardRef(function Collapse2({
56
54
  display: "grid",
57
55
  gridTemplateRows: expanded ? "1fr" : "0fr",
58
56
  overflow,
59
- transition: instant ? "none" : legacy ? `grid-template-rows var(--duration-${duration}) var(--ease-${easing})` : spring("grid-template-rows", "spatial", SPRING_SPEED[duration]),
57
+ transition: instant ? "none" : spring("grid-template-rows", "spatial", SPRING_SPEED[duration]),
60
58
  ...style
61
59
  },
62
60
  onTransitionEnd: (e) => {
@@ -5,7 +5,6 @@ import { useMotion } from "./useMotion.js";
5
5
  const Fade = React.forwardRef(function Fade2({
6
6
  in: visible,
7
7
  duration = "normal",
8
- easing,
9
8
  unmountOnExit = false,
10
9
  children,
11
10
  style,
@@ -15,7 +14,6 @@ const Fade = React.forwardRef(function Fade2({
15
14
  const { phase, mounted, transitionStyle, handleTransitionEnd } = useMotion({
16
15
  visible,
17
16
  duration,
18
- easing,
19
17
  unmountOnExit
20
18
  });
21
19
  if (!mounted) return null;
@@ -5,7 +5,6 @@ import { useMotion } from "./useMotion.js";
5
5
  const Scale = React.forwardRef(function Scale2({
6
6
  in: visible,
7
7
  duration = "fast",
8
- easing,
9
8
  unmountOnExit = false,
10
9
  initialScale = 0.95,
11
10
  children,
@@ -16,7 +15,6 @@ const Scale = React.forwardRef(function Scale2({
16
15
  const { phase, mounted, reduced, transitionStyle, handleTransitionEnd } = useMotion({
17
16
  visible,
18
17
  duration,
19
- easing,
20
18
  unmountOnExit
21
19
  });
22
20
  if (!mounted) return null;
@@ -11,7 +11,6 @@ const directionTransform = {
11
11
  const Slide = React.forwardRef(function Slide2({
12
12
  in: visible,
13
13
  duration = "normal",
14
- easing,
15
14
  unmountOnExit = false,
16
15
  direction = "up",
17
16
  distance,
@@ -23,7 +22,6 @@ const Slide = React.forwardRef(function Slide2({
23
22
  const { phase, mounted, reduced, transitionStyle, handleTransitionEnd } = useMotion({
24
23
  visible,
25
24
  duration,
26
- easing,
27
25
  unmountOnExit
28
26
  });
29
27
  if (!mounted) return null;
@@ -9,7 +9,7 @@ export type { CollapseProps } from './Collapse.js';
9
9
  export { ListTransition, SkeletonSwap } from './ListTransition.js';
10
10
  export type { ListTransitionProps, SkeletonSwapProps } from './ListTransition.js';
11
11
  export { usePrefersReducedMotion } from './useMotion.js';
12
- export type { MotionDuration, MotionEasing, MotionBaseProps } from './motion.types.js';
12
+ export type { MotionDuration, MotionBaseProps } from './motion.types.js';
13
13
  export { Reveal } from './Reveal.js';
14
14
  export type { RevealProps } from './Reveal.js';
15
15
  export { Float } from './Float.js';
@@ -1,5 +1,4 @@
1
1
  export type MotionDuration = 'instant' | 'fast' | 'normal' | 'slow' | 'slower';
2
- export type MotionEasing = 'linear' | 'in' | 'out' | 'in-out' | 'out-expo' | 'spring';
3
2
  export interface MotionBaseProps {
4
3
  /** Whether the component is visible / mounted. */
5
4
  in: boolean;
@@ -9,13 +8,6 @@ export interface MotionBaseProps {
9
8
  * @default 'normal'
10
9
  */
11
10
  duration?: MotionDuration;
12
- /**
13
- * Legacy: set it to use the old `--duration-*` + `--ease-{value}` tokens
14
- * instead of springs. Omit it to ride the spring tokens.
15
- * @deprecated since 7.3: the `--duration-*` / `--ease-*` tokens (tokens/motion.json) are
16
- * retired in favour of the spring tokens. Removed in 8.0.
17
- */
18
- easing?: MotionEasing;
19
11
  /**
20
12
  * Remove the element from the DOM when `in` becomes false
21
13
  * (after the exit transition completes).
@@ -1,6 +1,5 @@
1
1
  import * as React from 'react';
2
- import type { MotionDuration, MotionEasing } from './motion.types.js';
3
- export declare const DURATION_MS: Record<MotionDuration, number>;
2
+ import type { MotionDuration } from './motion.types.js';
4
3
  export type SpringSpeed = 'fast' | 'default' | 'slow';
5
4
  export type SpringFamily = 'spatial' | 'effects' | 'expressive';
6
5
  /** `duration` → spring speed. `instant` is handled separately (no motion). */
@@ -31,11 +30,9 @@ export interface UseMotionReturn {
31
30
  *
32
31
  * Enter rides the springs (opacity on `effects`, transform on `spatial`).
33
32
  * Exit is quicker and never overshoots (`effects` fast for both).
34
- * Passing `easing` opts back into the legacy duration + easing tokens.
35
33
  */
36
- export declare function useMotion({ visible, duration, easing, unmountOnExit, }: {
34
+ export declare function useMotion({ visible, duration, unmountOnExit, }: {
37
35
  visible: boolean;
38
36
  duration?: MotionDuration;
39
- easing?: MotionEasing;
40
37
  unmountOnExit?: boolean;
41
38
  }): UseMotionReturn;
@@ -1,13 +1,6 @@
1
1
  "use client";
2
2
  import * as React from "react";
3
3
  import { useMediaQuery } from "../../hooks/useMediaQuery.js";
4
- const DURATION_MS = {
5
- instant: 0,
6
- fast: 150,
7
- normal: 200,
8
- slow: 300,
9
- slower: 500
10
- };
11
4
  const SPRING_SPEED = {
12
5
  fast: "fast",
13
6
  normal: "default",
@@ -27,7 +20,6 @@ function usePrefersReducedMotion() {
27
20
  function useMotion({
28
21
  visible,
29
22
  duration = "normal",
30
- easing,
31
23
  unmountOnExit = false
32
24
  }) {
33
25
  const [phase, setPhase] = React.useState(
@@ -58,8 +50,7 @@ function useMotion({
58
50
  setPhase("exiting");
59
51
  }
60
52
  }, [visible]);
61
- const legacy = easing !== void 0;
62
- const exitMs = duration === "instant" ? 0 : legacy ? DURATION_MS[duration] : SPRING_MS.effects.fast;
53
+ const exitMs = duration === "instant" ? 0 : SPRING_MS.effects.fast;
63
54
  React.useEffect(() => {
64
55
  if (phase !== "exiting") return;
65
56
  const t = setTimeout(() => setPhase("exited"), exitMs + FALLBACK_MARGIN_MS);
@@ -74,12 +65,6 @@ function useMotion({
74
65
  let transitionStyle;
75
66
  if (duration === "instant") {
76
67
  transitionStyle = { transition: "none" };
77
- } else if (legacy) {
78
- transitionStyle = {
79
- transitionDuration: `var(--duration-${duration})`,
80
- transitionTimingFunction: `var(--ease-${easing})`,
81
- transitionProperty: "opacity, transform"
82
- };
83
68
  } else if (phase === "exiting" || phase === "exited") {
84
69
  transitionStyle = {
85
70
  transition: [spring("opacity", "effects", "fast"), spring("transform", "effects", "fast")].join(", ")
@@ -93,7 +78,6 @@ function useMotion({
93
78
  return { phase, mounted, reduced, transitionStyle, handleTransitionEnd };
94
79
  }
95
80
  export {
96
- DURATION_MS,
97
81
  SPRING_MS,
98
82
  SPRING_SPEED,
99
83
  spring,
@@ -21,7 +21,7 @@ const Item = React.forwardRef(
21
21
  className
22
22
  ),
23
23
  ...props,
24
- children: /* @__PURE__ */ jsx(RadixRadioGroup.Indicator, { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: "block h-2 w-2 rounded-full bg-[var(--color-primary)] [[data-disabled]_&]:bg-[var(--color-text-disabled)]" }) })
24
+ children: /* @__PURE__ */ jsx(RadixRadioGroup.Indicator, { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: "nx-dot-in block h-2 w-2 rounded-full bg-[var(--color-primary)] [[data-disabled]_&]:bg-[var(--color-text-disabled)]" }) })
25
25
  }
26
26
  )
27
27
  );
@@ -21,7 +21,7 @@ const Root = React.forwardRef(
21
21
  ref: useMergedRefs(ref, forwardedRef),
22
22
  type: "single",
23
23
  className: cn(
24
- "relative inline-flex items-stretch rounded-shape-control bg-[var(--color-surface-container-high)] p-0.5",
24
+ "relative inline-flex items-stretch rounded-[var(--shape-pill,var(--shape-control))] bg-[var(--color-surface-container-high)] p-0.5",
25
25
  sizeMap[size],
26
26
  className
27
27
  ),
@@ -32,7 +32,7 @@ const Root = React.forwardRef(
32
32
  {
33
33
  "aria-hidden": "true",
34
34
  className: cn(
35
- "pointer-events-none absolute inset-y-0.5 left-0 rounded-shape-control",
35
+ "pointer-events-none absolute inset-y-0.5 left-0 rounded-[var(--shape-pill,var(--shape-control))]",
36
36
  "bg-[var(--color-surface-container-lowest)] shadow-elevation-1",
37
37
  "w-[var(--nx-ind-w,0px)] translate-x-[var(--nx-ind-x,0px)] opacity-[var(--nx-ind-o,0)]",
38
38
  "[[data-nx-indicator=ready]>&]:transition-[transform,width] [[data-nx-indicator=ready]>&]:duration-spatial-default [[data-nx-indicator=ready]>&]:ease-spatial-default"
@@ -54,7 +54,7 @@ const Item = React.forwardRef(
54
54
  {
55
55
  ref,
56
56
  className: cn(
57
- "relative z-10 inline-flex items-center justify-center rounded-shape-control select-none",
57
+ "relative z-10 inline-flex items-center justify-center rounded-[var(--shape-pill,var(--shape-control))] select-none",
58
58
  size === "sm" ? "px-3" : size === "lg" ? "px-5" : "px-4",
59
59
  "text-[var(--color-on-surface-variant)] transition-colors duration-effects-fast ease-effects-fast",
60
60
  "hover:text-[var(--color-on-surface)] data-[state=on]:text-[var(--color-on-surface)]",
@@ -17,10 +17,11 @@ const switchVariants = cva(
17
17
  ],
18
18
  {
19
19
  variants: {
20
+ // --nx-switch-travel: the Signature full thumb's slide (track width - height).
20
21
  size: {
21
- sm: "h-5 w-9",
22
- md: "h-7 w-12",
23
- lg: "h-8 w-14"
22
+ sm: "h-5 w-9 [--nx-switch-travel:16px]",
23
+ md: "h-7 w-12 [--nx-switch-travel:20px]",
24
+ lg: "h-8 w-14 [--nx-switch-travel:24px]"
24
25
  }
25
26
  },
26
27
  defaultVariants: { size: "md" }
@@ -50,7 +51,7 @@ const Switch = React.forwardRef(
50
51
  RadixSwitch.Root,
51
52
  {
52
53
  ref,
53
- className: cn(switchVariants({ size }), "nx-hit", loading && "cursor-progress", className),
54
+ className: cn(switchVariants({ size }), "nx-switch nx-hit", loading && "cursor-progress", className),
54
55
  "aria-busy": loading || void 0,
55
56
  onClick: (e) => {
56
57
  onClick?.(e);
@@ -62,6 +63,7 @@ const Switch = React.forwardRef(
62
63
  {
63
64
  className: cn(
64
65
  thumbVariants({ size }),
66
+ "nx-switch-thumb",
65
67
  (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
68
  ),
67
69
  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: [
@@ -27,7 +27,7 @@ const List = React.forwardRef(
27
27
  // Vertical: a column with the rule on the inline-end side.
28
28
  "data-[orientation=vertical]:w-auto data-[orientation=vertical]:shrink-0 data-[orientation=vertical]:flex-col",
29
29
  "data-[orientation=vertical]:overflow-x-visible data-[orientation=vertical]:overflow-y-auto",
30
- pill ? "w-fit max-w-full rounded-shape-control bg-[var(--color-surface-container-high)] p-0.5" : "border-b border-[var(--color-outline-variant)] data-[orientation=vertical]:border-b-0 data-[orientation=vertical]:border-e",
30
+ pill ? "w-fit max-w-full rounded-[var(--shape-pill,var(--shape-control))] bg-[var(--color-surface-container-high)] p-0.5" : "border-b border-[var(--color-outline-variant)] data-[orientation=vertical]:border-b-0 data-[orientation=vertical]:border-e",
31
31
  className
32
32
  ),
33
33
  ...props,
@@ -40,7 +40,7 @@ const List = React.forwardRef(
40
40
  {
41
41
  "aria-hidden": "true",
42
42
  className: cn(
43
- "pointer-events-none absolute left-0 top-0 rounded-shape-control",
43
+ "pointer-events-none absolute left-0 top-0 rounded-[var(--shape-pill,var(--shape-control))]",
44
44
  "bg-[var(--color-surface-container-lowest)] shadow-elevation-1",
45
45
  "h-[var(--nx-ind-h,0px)] w-[var(--nx-ind-w,0px)] translate-x-[var(--nx-ind-x,0px)] translate-y-[var(--nx-ind-y,0px)] opacity-[var(--nx-ind-o,0)]",
46
46
  "[[data-nx-indicator=ready]>&]:transition-[transform,width,height] [[data-nx-indicator=ready]>&]:duration-spatial-default [[data-nx-indicator=ready]>&]:ease-spatial-default"
@@ -118,7 +118,7 @@ const Trigger = React.forwardRef(
118
118
  "nx-state-layer relative inline-flex h-control-md items-center justify-center whitespace-nowrap px-4 text-label-lg select-none",
119
119
  "group-data-[orientation=vertical]/tabs:justify-start",
120
120
  "text-[var(--color-on-surface-variant)] transition-colors duration-effects-fast ease-effects-fast",
121
- pill ? "z-10 rounded-shape-control hover:text-[var(--color-on-surface)] data-[state=active]:text-[var(--color-on-surface)]" : cn(
121
+ pill ? "z-10 rounded-[var(--shape-pill,var(--shape-control))] hover:text-[var(--color-on-surface)] data-[state=active]:text-[var(--color-on-surface)]" : cn(
122
122
  "rounded-t-[var(--shape-field)] data-[state=active]:text-[var(--color-primary)]",
123
123
  "group-data-[orientation=vertical]/tabs:rounded-none group-data-[orientation=vertical]/tabs:rounded-s-[var(--shape-field)]"
124
124
  ),
@@ -7,7 +7,7 @@ import { cn } from "../../utils/cn.js";
7
7
  const toggleVariants = cva(
8
8
  [
9
9
  // Pressable capsule; on = the secondary container (tonal selection).
10
- "nx-state-layer nx-press relative inline-flex items-center justify-center gap-2 rounded-shape-control select-none",
10
+ "nx-state-layer nx-press relative inline-flex items-center justify-center gap-2 rounded-[var(--shape-pill,var(--shape-control))] select-none",
11
11
  "text-[var(--color-on-surface-variant)] transition-[background-color,color] duration-effects-fast ease-effects-fast",
12
12
  "data-[state=on]:bg-[var(--color-secondary-container)] data-[state=on]:text-[var(--color-on-secondary-container)]",
13
13
  "disabled:pointer-events-none disabled:text-[var(--color-text-disabled)]"
package/dist/index.d.ts CHANGED
@@ -255,7 +255,7 @@ export type { DateRangePickerProps, DateRange, DateRangePreset } from './compone
255
255
  export { ThemeProvider, ThemeScript, useTheme } from './components/ThemeProvider/index.js';
256
256
  export type { ThemeMode, GlassMode, ThemeContextValue, ThemeProviderProps, ThemeScriptProps } from './components/ThemeProvider/index.js';
257
257
  export { Fade, Slide, Scale, Collapse, ListTransition, SkeletonSwap, usePrefersReducedMotion, Reveal, Float, Marquee } from './components/Motion/index.js';
258
- export type { FadeProps, SlideProps, SlideDirection, ScaleProps, CollapseProps, ListTransitionProps, SkeletonSwapProps, MotionDuration, MotionEasing, MotionBaseProps, RevealProps, FloatProps, MarqueeProps } from './components/Motion/index.js';
258
+ export type { FadeProps, SlideProps, SlideDirection, ScaleProps, CollapseProps, ListTransitionProps, SkeletonSwapProps, MotionDuration, MotionBaseProps, RevealProps, FloatProps, MarqueeProps } from './components/Motion/index.js';
259
259
  export type { DataTableColumn } from './components/DataTable/index.js';
260
260
  export type { TableRootProps } from './components/Table/index.js';
261
261
  export type { PromiseToastOptions } from './components/Toast/index.js';