@nexub/react 7.9.0 → 8.1.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.9.0",
2
+ "version": "8.1.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;
@@ -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(
@@ -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,
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';