@trackunit/react-modal 1.13.7 → 1.13.9

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.
package/index.cjs.js CHANGED
@@ -145,7 +145,7 @@ const cvaModalBackdrop = cssClassVarianceUtilities.cvaMerge([
145
145
  variants: {
146
146
  isFrontmost: {
147
147
  // Frontmost modal shows backdrop
148
- true: "bg-black/50",
148
+ true: ["bg-black/50", "backdrop-saturate-150"],
149
149
  // Non-frontmost modals have transparent backdrop with no transition (avoids flash)
150
150
  false: ["bg-transparent", "transition-none"],
151
151
  },
@@ -531,7 +531,7 @@ const SCALE_FACTOR_PER_LEVEL = 0.05;
531
531
  * };
532
532
  * ```
533
533
  */
534
- const Modal = ({ children, isOpen, role = "dialog", "data-testid": dataTestId, className, size, floatingUi, ref, }) => {
534
+ const Modal = ({ children, isOpen, role = "dialog", "data-testid": dataTestId, className, size, floatingUi, ref, restoreFocus = true, }) => {
535
535
  // For dialogs/modals, Floating UI recommends not using floatingStyles since the modal
536
536
  // is viewport-centered via CSS, not positioned relative to a reference element.
537
537
  // See: https://floating-ui.com/docs/dialog
@@ -543,7 +543,7 @@ const Modal = ({ children, isOpen, role = "dialog", "data-testid": dataTestId, c
543
543
  // Track modal stack position for stacked modal styling
544
544
  const { depthFromFront, stackSizeAtOpen } = useModalStack(isOpen);
545
545
  const isFrontmost = depthFromFront === 0;
546
- return (jsxRuntime.jsx(reactComponents.Portal, { root: rootElement, children: isOpen ? (jsxRuntime.jsx(react$1.FloatingOverlay, { className: cvaModalBackdrop({ isFrontmost, shouldAnimate: stackSizeAtOpen === 0 }), lockScroll: true, children: jsxRuntime.jsx(react$1.FloatingFocusManager, { context: context, children: jsxRuntime.jsx("div", { "aria-modal": true, className: cvaModalContainer(), ref: mergedRef, role: role,
546
+ return (jsxRuntime.jsx(reactComponents.Portal, { root: rootElement, children: isOpen ? (jsxRuntime.jsx(react$1.FloatingOverlay, { className: cvaModalBackdrop({ isFrontmost, shouldAnimate: stackSizeAtOpen === 0 }), lockScroll: true, children: jsxRuntime.jsx(react$1.FloatingFocusManager, { context: context, restoreFocus: restoreFocus, children: jsxRuntime.jsx("div", { "aria-modal": true, className: cvaModalContainer(), ref: mergedRef, role: role,
547
547
  // Scale down modals that are behind the frontmost
548
548
  style: isFrontmost ? undefined : { transform: `scale(${1 - depthFromFront * SCALE_FACTOR_PER_LEVEL})` }, ...getFloatingProps(), children: jsxRuntime.jsx(reactComponents.Card, { className: cvaModalCard({ className, animation: stackSizeAtOpen === 0 ? "fade" : "rise" }), "data-testid": dataTestId, ref: cardRef, style: getModalCardCSSVariables(size), children: children }) }) }) })) : null }));
549
549
  };
package/index.esm.js CHANGED
@@ -143,7 +143,7 @@ const cvaModalBackdrop = cvaMerge([
143
143
  variants: {
144
144
  isFrontmost: {
145
145
  // Frontmost modal shows backdrop
146
- true: "bg-black/50",
146
+ true: ["bg-black/50", "backdrop-saturate-150"],
147
147
  // Non-frontmost modals have transparent backdrop with no transition (avoids flash)
148
148
  false: ["bg-transparent", "transition-none"],
149
149
  },
@@ -529,7 +529,7 @@ const SCALE_FACTOR_PER_LEVEL = 0.05;
529
529
  * };
530
530
  * ```
531
531
  */
532
- const Modal = ({ children, isOpen, role = "dialog", "data-testid": dataTestId, className, size, floatingUi, ref, }) => {
532
+ const Modal = ({ children, isOpen, role = "dialog", "data-testid": dataTestId, className, size, floatingUi, ref, restoreFocus = true, }) => {
533
533
  // For dialogs/modals, Floating UI recommends not using floatingStyles since the modal
534
534
  // is viewport-centered via CSS, not positioned relative to a reference element.
535
535
  // See: https://floating-ui.com/docs/dialog
@@ -541,7 +541,7 @@ const Modal = ({ children, isOpen, role = "dialog", "data-testid": dataTestId, c
541
541
  // Track modal stack position for stacked modal styling
542
542
  const { depthFromFront, stackSizeAtOpen } = useModalStack(isOpen);
543
543
  const isFrontmost = depthFromFront === 0;
544
- return (jsx(Portal, { root: rootElement, children: isOpen ? (jsx(FloatingOverlay, { className: cvaModalBackdrop({ isFrontmost, shouldAnimate: stackSizeAtOpen === 0 }), lockScroll: true, children: jsx(FloatingFocusManager, { context: context, children: jsx("div", { "aria-modal": true, className: cvaModalContainer(), ref: mergedRef, role: role,
544
+ return (jsx(Portal, { root: rootElement, children: isOpen ? (jsx(FloatingOverlay, { className: cvaModalBackdrop({ isFrontmost, shouldAnimate: stackSizeAtOpen === 0 }), lockScroll: true, children: jsx(FloatingFocusManager, { context: context, restoreFocus: restoreFocus, children: jsx("div", { "aria-modal": true, className: cvaModalContainer(), ref: mergedRef, role: role,
545
545
  // Scale down modals that are behind the frontmost
546
546
  style: isFrontmost ? undefined : { transform: `scale(${1 - depthFromFront * SCALE_FACTOR_PER_LEVEL})` }, ...getFloatingProps(), children: jsx(Card, { className: cvaModalCard({ className, animation: stackSizeAtOpen === 0 ? "fade" : "rise" }), "data-testid": dataTestId, ref: cardRef, style: getModalCardCSSVariables(size), children: children }) }) }) })) : null }));
547
547
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-modal",
3
- "version": "1.13.7",
3
+ "version": "1.13.9",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -8,13 +8,13 @@
8
8
  },
9
9
  "dependencies": {
10
10
  "@floating-ui/react": "^0.26.25",
11
- "@trackunit/react-components": "1.16.7",
11
+ "@trackunit/react-components": "1.16.9",
12
12
  "react": "19.0.0",
13
- "@trackunit/css-class-variance-utilities": "1.11.26",
14
- "@trackunit/shared-utils": "1.13.26",
13
+ "@trackunit/css-class-variance-utilities": "1.11.27",
14
+ "@trackunit/shared-utils": "1.13.27",
15
15
  "@floating-ui/react-dom": "2.1.2",
16
- "@trackunit/react-core-contexts-api": "1.13.7",
17
- "@trackunit/i18n-library-translation": "1.12.7"
16
+ "@trackunit/react-core-contexts-api": "1.13.8",
17
+ "@trackunit/i18n-library-translation": "1.12.8"
18
18
  },
19
19
  "module": "./index.esm.js",
20
20
  "main": "./index.cjs.js",
@@ -17,6 +17,13 @@ export type ModalProps = PropsWithChildren<UseModalReturnValue & {
17
17
  * The test ID applied to the modal.
18
18
  */
19
19
  "data-testid"?: string;
20
+ /**
21
+ * Determines if focus should be restored to the nearest tabbable element
22
+ * if the currently focused element inside the modal is removed from the DOM.
23
+ *
24
+ * @default true
25
+ */
26
+ restoreFocus?: boolean;
20
27
  }>;
21
28
  /**
22
29
  * - Modals are used to present critical information or request user input needed to complete a user's workflow.
@@ -46,6 +53,6 @@ export type ModalProps = PropsWithChildren<UseModalReturnValue & {
46
53
  * ```
47
54
  */
48
55
  export declare const Modal: {
49
- ({ children, isOpen, role, "data-testid": dataTestId, className, size, floatingUi, ref, }: ModalProps): ReactElement;
56
+ ({ children, isOpen, role, "data-testid": dataTestId, className, size, floatingUi, ref, restoreFocus, }: ModalProps): ReactElement;
50
57
  displayName: string;
51
58
  };
@@ -4,7 +4,7 @@ type Story = StoryObjWithOptionalArgs<typeof meta, "ref" | "isOpen" | "close" |
4
4
  declare const meta: {
5
5
  title: string;
6
6
  component: {
7
- ({ children, isOpen, role, "data-testid": dataTestId, className, size, floatingUi, ref, }: import("./Modal").ModalProps): ReactElement;
7
+ ({ children, isOpen, role, "data-testid": dataTestId, className, size, floatingUi, ref, restoreFocus, }: import("./Modal").ModalProps): ReactElement;
8
8
  displayName: string;
9
9
  };
10
10
  tags: string[];