@iris-ui-kit/react 0.2.3 → 0.3.1

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 (48) hide show
  1. package/dist/admin.cjs +6 -3
  2. package/dist/admin.cjs.map +1 -1
  3. package/dist/admin.js +1 -1
  4. package/dist/async.cjs +16 -7
  5. package/dist/async.cjs.map +1 -1
  6. package/dist/async.d.cts +7 -6
  7. package/dist/async.d.ts +7 -6
  8. package/dist/async.js +1 -1
  9. package/dist/chunk-3772LKJP.js +942 -0
  10. package/dist/chunk-3772LKJP.js.map +1 -0
  11. package/dist/{chunk-TO7YVSAI.js → chunk-3KYNBLRY.js} +18 -9
  12. package/dist/chunk-3KYNBLRY.js.map +1 -0
  13. package/dist/{chunk-AUA5GBT6.js → chunk-4VPCQ3U4.js} +28 -27
  14. package/dist/chunk-4VPCQ3U4.js.map +1 -0
  15. package/dist/{chunk-V3KHE2WB.js → chunk-QKDOW7FG.js} +15 -9
  16. package/dist/chunk-QKDOW7FG.js.map +1 -0
  17. package/dist/{chunk-KRFZ5KL4.js → chunk-TDVRIHE6.js} +8 -5
  18. package/dist/chunk-TDVRIHE6.js.map +1 -0
  19. package/dist/{chunk-QZJXMCRR.js → chunk-VLWZSOTH.js} +2 -2
  20. package/dist/chunk-VLWZSOTH.js.map +1 -0
  21. package/dist/data.cjs.map +1 -1
  22. package/dist/data.d.cts +2 -2
  23. package/dist/data.d.ts +2 -2
  24. package/dist/data.js +1 -1
  25. package/dist/grid.cjs +1007 -0
  26. package/dist/grid.cjs.map +1 -0
  27. package/dist/grid.d.cts +324 -0
  28. package/dist/grid.d.ts +324 -0
  29. package/dist/grid.js +5 -0
  30. package/dist/grid.js.map +1 -0
  31. package/dist/index.cjs +14296 -2652
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +1993 -251
  34. package/dist/index.d.ts +1993 -251
  35. package/dist/index.js +13031 -2362
  36. package/dist/index.js.map +1 -1
  37. package/dist/modal-utils.cjs +26 -25
  38. package/dist/modal-utils.cjs.map +1 -1
  39. package/dist/modal-utils.js +1 -1
  40. package/dist/skeletons.cjs +13 -7
  41. package/dist/skeletons.cjs.map +1 -1
  42. package/dist/skeletons.js +1 -1
  43. package/package.json +20 -15
  44. package/dist/chunk-AUA5GBT6.js.map +0 -1
  45. package/dist/chunk-KRFZ5KL4.js.map +0 -1
  46. package/dist/chunk-QZJXMCRR.js.map +0 -1
  47. package/dist/chunk-TO7YVSAI.js.map +0 -1
  48. package/dist/chunk-V3KHE2WB.js.map +0 -1
@@ -106,6 +106,31 @@ function getFocusable(root) {
106
106
  (el) => !el.hasAttribute("disabled") && el.tabIndex !== -1
107
107
  );
108
108
  }
109
+ function createFocusTrapKeyHandler(container) {
110
+ return (event) => {
111
+ if (event.key !== "Tab") return;
112
+ const root = container.current;
113
+ if (!root) return;
114
+ const focusables = getFocusable(root);
115
+ if (focusables.length === 0) {
116
+ event.preventDefault();
117
+ root.focus();
118
+ return;
119
+ }
120
+ const first = focusables[0];
121
+ const last = focusables[focusables.length - 1];
122
+ const active = document.activeElement;
123
+ if (event.shiftKey) {
124
+ if (active === first || !root.contains(active)) {
125
+ event.preventDefault();
126
+ last.focus();
127
+ }
128
+ } else if (active === last || !root.contains(active)) {
129
+ event.preventDefault();
130
+ first.focus();
131
+ }
132
+ };
133
+ }
109
134
  function useFocusTrap(options) {
110
135
  const { container, active, returnFocusTo, initialFocus = true } = options;
111
136
  const previouslyFocusedRef = React2__namespace.useRef(null);
@@ -113,31 +138,7 @@ function useFocusTrap(options) {
113
138
  if (!active) return;
114
139
  if (typeof document === "undefined") return;
115
140
  previouslyFocusedRef.current = document.activeElement ?? null;
116
- const onKeyDown = (event) => {
117
- if (event.key !== "Tab") return;
118
- const root = container.current;
119
- if (!root) return;
120
- const focusables = getFocusable(root);
121
- if (focusables.length === 0) {
122
- event.preventDefault();
123
- root.focus();
124
- return;
125
- }
126
- const first = focusables[0];
127
- const last = focusables[focusables.length - 1];
128
- const active2 = document.activeElement;
129
- if (event.shiftKey) {
130
- if (active2 === first || !root.contains(active2)) {
131
- event.preventDefault();
132
- last.focus();
133
- }
134
- } else {
135
- if (active2 === last || !root.contains(active2)) {
136
- event.preventDefault();
137
- first.focus();
138
- }
139
- }
140
- };
141
+ const onKeyDown = createFocusTrapKeyHandler(container);
141
142
  document.addEventListener("keydown", onKeyDown);
142
143
  let raf;
143
144
  if (initialFocus) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/modal-utils/useBodyScrollLock.ts","../src/modal-utils/useFocusTrap.ts"],"names":["React","React2","active"],"mappings":"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","file":"modal-utils.cjs","sourcesContent":["import * as React from 'react'\n\nlet lockCount = 0\nlet savedOverflow: string | null = null\nlet savedPaddingRight: string | null = null\n// What we actually wrote, so unlock can detect a host mutation made while\n// locked and avoid clobbering it.\nlet appliedOverflow: string | null = null\nlet appliedPaddingRight: string | null = null\n\nfunction lock(): void {\n if (typeof document === 'undefined') return\n lockCount += 1\n if (lockCount > 1) return\n const body = document.body\n const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth\n savedOverflow = body.style.overflow\n savedPaddingRight = body.style.paddingRight\n body.style.overflow = 'hidden'\n appliedOverflow = 'hidden'\n if (scrollbarWidth > 0) {\n const currentPadding = parseFloat(getComputedStyle(body).paddingRight || '0')\n appliedPaddingRight = `${currentPadding + scrollbarWidth}px`\n body.style.paddingRight = appliedPaddingRight\n } else {\n appliedPaddingRight = null\n }\n}\n\nfunction unlock(): void {\n if (typeof document === 'undefined') return\n lockCount = Math.max(0, lockCount - 1)\n if (lockCount > 0) return\n const body = document.body\n // Only restore if our locked value is still in place; if a host changed body\n // overflow / padding-right while locked, respect that rather than clobber it.\n if (body.style.overflow === appliedOverflow) {\n body.style.overflow = savedOverflow ?? ''\n }\n if (appliedPaddingRight !== null && body.style.paddingRight === appliedPaddingRight) {\n body.style.paddingRight = savedPaddingRight ?? ''\n }\n savedOverflow = null\n savedPaddingRight = null\n appliedOverflow = null\n appliedPaddingRight = null\n}\n\n/**\n * Lock the document body's scroll while `active` is true. Reference-counted\n * so multiple stacked overlays cooperate. Restores prior `overflow` and\n * `padding-right` (to compensate for the scrollbar gap) when the last lock\n * releases. SSR-safe.\n */\nexport function useBodyScrollLock(active: boolean): void {\n React.useEffect(() => {\n if (!active) return\n lock()\n return () => {\n unlock()\n }\n }, [active])\n}\n\n/** Test-only: read the current lock count. */\nexport function __getBodyScrollLockCount(): number {\n return lockCount\n}\n\n/** Test-only: hard-reset the module-level lock state. */\nexport function __resetBodyScrollLock(): void {\n lockCount = 0\n savedOverflow = null\n savedPaddingRight = null\n appliedOverflow = null\n appliedPaddingRight = null\n if (typeof document !== 'undefined') {\n document.body.style.overflow = ''\n document.body.style.paddingRight = ''\n }\n}\n","import * as React from 'react'\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'area[href]',\n 'button:not([disabled])',\n 'input:not([disabled]):not([type=\"hidden\"])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]',\n 'audio[controls]',\n 'video[controls]',\n 'iframe',\n 'object',\n 'embed',\n].join(',')\n\nfunction getFocusable(root: HTMLElement): HTMLElement[] {\n return Array.from(root.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter(\n (el) => !el.hasAttribute('disabled') && el.tabIndex !== -1,\n )\n}\n\nexport interface UseFocusTrapOptions {\n /** Element whose Tab key cycle is being trapped. */\n container: React.RefObject<HTMLElement | null>\n /** Whether the trap is currently active. */\n active: boolean\n /** Element to restore focus to when the trap deactivates. */\n returnFocusTo?: React.RefObject<HTMLElement | null | undefined>\n /** Whether to focus the first focusable element on activation. Default `true`. */\n initialFocus?: boolean\n}\n\n/**\n * Constrain Tab / Shift+Tab focus traversal to descendants of `container`.\n *\n * Behavior on activation:\n * - Records the currently focused element.\n * - If `initialFocus !== false`, focuses the first focusable descendant\n * (or the container itself if there are none).\n *\n * Behavior while active:\n * - Tab on the last focusable element wraps to the first; Shift+Tab on\n * the first wraps to the last.\n *\n * Behavior on deactivation:\n * - Restores focus to `returnFocusTo?.current` if provided, else to the\n * element that was focused when the trap activated.\n */\nexport function useFocusTrap(options: UseFocusTrapOptions): void {\n const { container, active, returnFocusTo, initialFocus = true } = options\n const previouslyFocusedRef = React.useRef<HTMLElement | null>(null)\n\n React.useEffect(() => {\n if (!active) return\n if (typeof document === 'undefined') return\n\n previouslyFocusedRef.current = (document.activeElement as HTMLElement | null) ?? null\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key !== 'Tab') return\n const root = container.current\n if (!root) return\n const focusables = getFocusable(root)\n if (focusables.length === 0) {\n event.preventDefault()\n root.focus()\n return\n }\n const first = focusables[0]!\n const last = focusables[focusables.length - 1]!\n const active = document.activeElement as HTMLElement | null\n\n if (event.shiftKey) {\n if (active === first || !root.contains(active)) {\n event.preventDefault()\n last.focus()\n }\n } else {\n if (active === last || !root.contains(active)) {\n event.preventDefault()\n first.focus()\n }\n }\n }\n document.addEventListener('keydown', onKeyDown)\n\n let raf: number | undefined\n if (initialFocus) {\n raf = requestAnimationFrame(() => {\n const root = container.current\n if (!root) return\n const focusables = getFocusable(root)\n ;(focusables[0] ?? root).focus()\n })\n }\n\n return () => {\n document.removeEventListener('keydown', onKeyDown)\n if (raf !== undefined) cancelAnimationFrame(raf)\n const target = returnFocusTo?.current ?? previouslyFocusedRef.current\n requestAnimationFrame(() => {\n // The element that had focus when the trap opened may have been\n // unmounted while it was open; focusing a detached node silently drops\n // focus to <body>. Only restore if it is still in the document.\n if (target && target.isConnected) target.focus?.()\n })\n previouslyFocusedRef.current = null\n }\n }, [active, container, returnFocusTo, initialFocus])\n}\n"]}
1
+ {"version":3,"sources":["../src/modal-utils/useBodyScrollLock.ts","../src/modal-utils/useFocusTrap.ts"],"names":["React","React2"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,IAAI,SAAA,GAAY,CAAA;AAChB,IAAI,aAAA,GAA+B,IAAA;AACnC,IAAI,iBAAA,GAAmC,IAAA;AAGvC,IAAI,eAAA,GAAiC,IAAA;AACrC,IAAI,mBAAA,GAAqC,IAAA;AAEzC,SAAS,IAAA,GAAa;AACpB,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACrC,EAAA,SAAA,IAAa,CAAA;AACb,EAAA,IAAI,YAAY,CAAA,EAAG;AACnB,EAAA,MAAM,OAAO,QAAA,CAAS,IAAA;AACtB,EAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,UAAA,GAAa,QAAA,CAAS,eAAA,CAAgB,WAAA;AACpE,EAAA,aAAA,GAAgB,KAAK,KAAA,CAAM,QAAA;AAC3B,EAAA,iBAAA,GAAoB,KAAK,KAAA,CAAM,YAAA;AAC/B,EAAA,IAAA,CAAK,MAAM,QAAA,GAAW,QAAA;AACtB,EAAA,eAAA,GAAkB,QAAA;AAClB,EAAA,IAAI,iBAAiB,CAAA,EAAG;AACtB,IAAA,MAAM,iBAAiB,UAAA,CAAW,gBAAA,CAAiB,IAAI,CAAA,CAAE,gBAAgB,GAAG,CAAA;AAC5E,IAAA,mBAAA,GAAsB,CAAA,EAAG,iBAAiB,cAAc,CAAA,EAAA,CAAA;AACxD,IAAA,IAAA,CAAK,MAAM,YAAA,GAAe,mBAAA;AAAA,EAC5B,CAAA,MAAO;AACL,IAAA,mBAAA,GAAsB,IAAA;AAAA,EACxB;AACF;AAEA,SAAS,MAAA,GAAe;AACtB,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACrC,EAAA,SAAA,GAAY,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,SAAA,GAAY,CAAC,CAAA;AACrC,EAAA,IAAI,YAAY,CAAA,EAAG;AACnB,EAAA,MAAM,OAAO,QAAA,CAAS,IAAA;AAGtB,EAAA,IAAI,IAAA,CAAK,KAAA,CAAM,QAAA,KAAa,eAAA,EAAiB;AAC3C,IAAA,IAAA,CAAK,KAAA,CAAM,WAAW,aAAA,IAAiB,EAAA;AAAA,EACzC;AACA,EAAA,IAAI,mBAAA,KAAwB,IAAA,IAAQ,IAAA,CAAK,KAAA,CAAM,iBAAiB,mBAAA,EAAqB;AACnF,IAAA,IAAA,CAAK,KAAA,CAAM,eAAe,iBAAA,IAAqB,EAAA;AAAA,EACjD;AACA,EAAA,aAAA,GAAgB,IAAA;AAChB,EAAA,iBAAA,GAAoB,IAAA;AACpB,EAAA,eAAA,GAAkB,IAAA;AAClB,EAAA,mBAAA,GAAsB,IAAA;AACxB;AAQO,SAAS,kBAAkB,MAAA,EAAuB;AACvD,EAAMA,4BAAU,MAAM;AACpB,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,IAAA,EAAK;AACL,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,EAAO;AAAA,IACT,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AACb;AAGO,SAAS,wBAAA,GAAmC;AACjD,EAAA,OAAO,SAAA;AACT;AAGO,SAAS,qBAAA,GAA8B;AAC5C,EAAA,SAAA,GAAY,CAAA;AACZ,EAAA,aAAA,GAAgB,IAAA;AAChB,EAAA,iBAAA,GAAoB,IAAA;AACpB,EAAA,eAAA,GAAkB,IAAA;AAClB,EAAA,mBAAA,GAAsB,IAAA;AACtB,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACnC,IAAA,QAAA,CAAS,IAAA,CAAK,MAAM,QAAA,GAAW,EAAA;AAC/B,IAAA,QAAA,CAAS,IAAA,CAAK,MAAM,YAAA,GAAe,EAAA;AAAA,EACrC;AACF;AC9EA,IAAM,kBAAA,GAAqB;AAAA,EACzB,SAAA;AAAA,EACA,YAAA;AAAA,EACA,wBAAA;AAAA,EACA,4CAAA;AAAA,EACA,wBAAA;AAAA,EACA,0BAAA;AAAA,EACA,iCAAA;AAAA,EACA,0BAAA;AAAA,EACA,iBAAA;AAAA,EACA,iBAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,CAAE,KAAK,GAAG,CAAA;AAEV,SAAS,aAAa,IAAA,EAAkC;AACtD,EAAA,OAAO,MAAM,IAAA,CAAK,IAAA,CAAK,gBAAA,CAA8B,kBAAkB,CAAC,CAAA,CAAE,MAAA;AAAA,IACxE,CAAC,OAAO,CAAC,EAAA,CAAG,aAAa,UAAU,CAAA,IAAK,GAAG,QAAA,KAAa;AAAA,GAC1D;AACF;AAaA,SAAS,0BACP,SAAA,EACgC;AAChC,EAAA,OAAO,CAAC,KAAA,KAA+B;AACrC,IAAA,IAAI,KAAA,CAAM,QAAQ,KAAA,EAAO;AACzB,IAAA,MAAM,OAAO,SAAA,CAAU,OAAA;AACvB,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,MAAM,UAAA,GAAa,aAAa,IAAI,CAAA;AACpC,IAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,MAAA,KAAA,CAAM,cAAA,EAAe;AACrB,MAAA,IAAA,CAAK,KAAA,EAAM;AACX,MAAA;AAAA,IACF;AACA,IAAA,MAAM,KAAA,GAAQ,WAAW,CAAC,CAAA;AAC1B,IAAA,MAAM,IAAA,GAAO,UAAA,CAAW,UAAA,CAAW,MAAA,GAAS,CAAC,CAAA;AAC7C,IAAA,MAAM,SAAS,QAAA,CAAS,aAAA;AAExB,IAAA,IAAI,MAAM,QAAA,EAAU;AAClB,MAAA,IAAI,WAAW,KAAA,IAAS,CAAC,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,EAAG;AAC9C,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb;AAAA,IACF,WAAW,MAAA,KAAW,IAAA,IAAQ,CAAC,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,EAAG;AACpD,MAAA,KAAA,CAAM,cAAA,EAAe;AACrB,MAAA,KAAA,CAAM,KAAA,EAAM;AAAA,IACd;AAAA,EACF,CAAA;AACF;AAkBO,SAAS,aAAa,OAAA,EAAoC;AAC/D,EAAA,MAAM,EAAE,SAAA,EAAW,MAAA,EAAQ,aAAA,EAAe,YAAA,GAAe,MAAK,GAAI,OAAA;AAClE,EAAA,MAAM,oBAAA,GAA6BC,yBAA2B,IAAI,CAAA;AAElE,EAAMA,4BAAU,MAAM;AACpB,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AAErC,IAAA,oBAAA,CAAqB,OAAA,GAAW,SAAS,aAAA,IAAwC,IAAA;AAEjF,IAAA,MAAM,SAAA,GAAY,0BAA0B,SAAS,CAAA;AACrD,IAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,SAAS,CAAA;AAE9C,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,GAAA,GAAM,sBAAsB,MAAM;AAChC,QAAA,MAAM,OAAO,SAAA,CAAU,OAAA;AACvB,QAAA,IAAI,CAAC,IAAA,EAAM;AACX,QAAA,MAAM,UAAA,GAAa,aAAa,IAAI,CAAA;AACnC,QAAA,CAAC,UAAA,CAAW,CAAC,CAAA,IAAK,IAAA,EAAM,KAAA,EAAM;AAAA,MACjC,CAAC,CAAA;AAAA,IACH;AAEA,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,mBAAA,CAAoB,WAAW,SAAS,CAAA;AACjD,MAAA,IAAI,GAAA,KAAQ,MAAA,EAAW,oBAAA,CAAqB,GAAG,CAAA;AAC/C,MAAA,MAAM,MAAA,GAAS,aAAA,EAAe,OAAA,IAAW,oBAAA,CAAqB,OAAA;AAC9D,MAAA,qBAAA,CAAsB,MAAM;AAI1B,QAAA,IAAI,MAAA,IAAU,MAAA,CAAO,WAAA,EAAa,MAAA,CAAO,KAAA,IAAQ;AAAA,MACnD,CAAC,CAAA;AACD,MAAA,oBAAA,CAAqB,OAAA,GAAU,IAAA;AAAA,IACjC,CAAA;AAAA,EACF,GAAG,CAAC,MAAA,EAAQ,SAAA,EAAW,aAAA,EAAe,YAAY,CAAC,CAAA;AACrD","file":"modal-utils.cjs","sourcesContent":["import * as React from 'react'\n\nlet lockCount = 0\nlet savedOverflow: string | null = null\nlet savedPaddingRight: string | null = null\n// What we actually wrote, so unlock can detect a host mutation made while\n// locked and avoid clobbering it.\nlet appliedOverflow: string | null = null\nlet appliedPaddingRight: string | null = null\n\nfunction lock(): void {\n if (typeof document === 'undefined') return\n lockCount += 1\n if (lockCount > 1) return\n const body = document.body\n const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth\n savedOverflow = body.style.overflow\n savedPaddingRight = body.style.paddingRight\n body.style.overflow = 'hidden'\n appliedOverflow = 'hidden'\n if (scrollbarWidth > 0) {\n const currentPadding = parseFloat(getComputedStyle(body).paddingRight || '0')\n appliedPaddingRight = `${currentPadding + scrollbarWidth}px`\n body.style.paddingRight = appliedPaddingRight\n } else {\n appliedPaddingRight = null\n }\n}\n\nfunction unlock(): void {\n if (typeof document === 'undefined') return\n lockCount = Math.max(0, lockCount - 1)\n if (lockCount > 0) return\n const body = document.body\n // Only restore if our locked value is still in place; if a host changed body\n // overflow / padding-right while locked, respect that rather than clobber it.\n if (body.style.overflow === appliedOverflow) {\n body.style.overflow = savedOverflow ?? ''\n }\n if (appliedPaddingRight !== null && body.style.paddingRight === appliedPaddingRight) {\n body.style.paddingRight = savedPaddingRight ?? ''\n }\n savedOverflow = null\n savedPaddingRight = null\n appliedOverflow = null\n appliedPaddingRight = null\n}\n\n/**\n * Lock the document body's scroll while `active` is true. Reference-counted\n * so multiple stacked overlays cooperate. Restores prior `overflow` and\n * `padding-right` (to compensate for the scrollbar gap) when the last lock\n * releases. SSR-safe.\n */\nexport function useBodyScrollLock(active: boolean): void {\n React.useEffect(() => {\n if (!active) return\n lock()\n return () => {\n unlock()\n }\n }, [active])\n}\n\n/** Test-only: read the current lock count. */\nexport function __getBodyScrollLockCount(): number {\n return lockCount\n}\n\n/** Test-only: hard-reset the module-level lock state. */\nexport function __resetBodyScrollLock(): void {\n lockCount = 0\n savedOverflow = null\n savedPaddingRight = null\n appliedOverflow = null\n appliedPaddingRight = null\n if (typeof document !== 'undefined') {\n document.body.style.overflow = ''\n document.body.style.paddingRight = ''\n }\n}\n","import * as React from 'react'\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'area[href]',\n 'button:not([disabled])',\n 'input:not([disabled]):not([type=\"hidden\"])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]',\n 'audio[controls]',\n 'video[controls]',\n 'iframe',\n 'object',\n 'embed',\n].join(',')\n\nfunction getFocusable(root: HTMLElement): HTMLElement[] {\n return Array.from(root.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter(\n (el) => !el.hasAttribute('disabled') && el.tabIndex !== -1,\n )\n}\n\nexport interface UseFocusTrapOptions {\n /** Element whose Tab key cycle is being trapped. */\n container: React.RefObject<HTMLElement | null>\n /** Whether the trap is currently active. */\n active: boolean\n /** Element to restore focus to when the trap deactivates. */\n returnFocusTo?: React.RefObject<HTMLElement | null | undefined>\n /** Whether to focus the first focusable element on activation. Default `true`. */\n initialFocus?: boolean\n}\n\nfunction createFocusTrapKeyHandler(\n container: React.RefObject<HTMLElement | null>,\n): (event: KeyboardEvent) => void {\n return (event: KeyboardEvent): void => {\n if (event.key !== 'Tab') return\n const root = container.current\n if (!root) return\n const focusables = getFocusable(root)\n if (focusables.length === 0) {\n event.preventDefault()\n root.focus()\n return\n }\n const first = focusables[0]!\n const last = focusables[focusables.length - 1]!\n const active = document.activeElement as HTMLElement | null\n\n if (event.shiftKey) {\n if (active === first || !root.contains(active)) {\n event.preventDefault()\n last.focus()\n }\n } else if (active === last || !root.contains(active)) {\n event.preventDefault()\n first.focus()\n }\n }\n}\n\n/**\n * Constrain Tab / Shift+Tab focus traversal to descendants of `container`.\n *\n * Behavior on activation:\n * - Records the currently focused element.\n * - If `initialFocus !== false`, focuses the first focusable descendant\n * (or the container itself if there are none).\n *\n * Behavior while active:\n * - Tab on the last focusable element wraps to the first; Shift+Tab on\n * the first wraps to the last.\n *\n * Behavior on deactivation:\n * - Restores focus to `returnFocusTo?.current` if provided, else to the\n * element that was focused when the trap activated.\n */\nexport function useFocusTrap(options: UseFocusTrapOptions): void {\n const { container, active, returnFocusTo, initialFocus = true } = options\n const previouslyFocusedRef = React.useRef<HTMLElement | null>(null)\n\n React.useEffect(() => {\n if (!active) return\n if (typeof document === 'undefined') return\n\n previouslyFocusedRef.current = (document.activeElement as HTMLElement | null) ?? null\n\n const onKeyDown = createFocusTrapKeyHandler(container)\n document.addEventListener('keydown', onKeyDown)\n\n let raf: number | undefined\n if (initialFocus) {\n raf = requestAnimationFrame(() => {\n const root = container.current\n if (!root) return\n const focusables = getFocusable(root)\n ;(focusables[0] ?? root).focus()\n })\n }\n\n return () => {\n document.removeEventListener('keydown', onKeyDown)\n if (raf !== undefined) cancelAnimationFrame(raf)\n const target = returnFocusTo?.current ?? previouslyFocusedRef.current\n requestAnimationFrame(() => {\n // The element that had focus when the trap opened may have been\n // unmounted while it was open; focusing a detached node silently drops\n // focus to <body>. Only restore if it is still in the document.\n if (target && target.isConnected) target.focus?.()\n })\n previouslyFocusedRef.current = null\n }\n }, [active, container, returnFocusTo, initialFocus])\n}\n"]}
@@ -1,4 +1,4 @@
1
1
  'use client'
2
- export { __getBodyScrollLockCount, __resetBodyScrollLock, useBodyScrollLock, useFocusTrap } from './chunk-AUA5GBT6.js';
2
+ export { __getBodyScrollLockCount, __resetBodyScrollLock, useBodyScrollLock, useFocusTrap } from './chunk-4VPCQ3U4.js';
3
3
  //# sourceMappingURL=modal-utils.js.map
4
4
  //# sourceMappingURL=modal-utils.js.map
@@ -147,11 +147,11 @@ var IrisInput = React9__namespace.forwardRef(function IrisInput2({
147
147
  display: "inline-flex",
148
148
  alignItems: "center",
149
149
  gap: "var(--iris-space-xs, 8px)",
150
- background: "var(--iris-background)",
150
+ background: rest.readOnly ? "var(--iris-surface)" : "var(--iris-background)",
151
151
  color: "var(--iris-foreground)",
152
152
  border: `1px solid ${borderColor}`,
153
153
  borderRadius: "var(--iris-radius-md, 6px)",
154
- cursor: rest.disabled ? "not-allowed" : "text",
154
+ cursor: rest.disabled ? "not-allowed" : rest.readOnly ? "default" : "text",
155
155
  opacity: rest.disabled ? 0.6 : 1,
156
156
  transition: "border-color 120ms ease, box-shadow 120ms ease",
157
157
  boxShadow,
@@ -176,7 +176,7 @@ var IrisInput = React9__namespace.forwardRef(function IrisInput2({
176
176
  {
177
177
  "data-iris-input": "",
178
178
  "data-iris-input-size": size,
179
- "data-state": invalid ? "invalid" : focused ? "focused" : "idle",
179
+ "data-state": invalid ? "invalid" : focused ? "focused" : rest.readOnly ? "readonly" : "idle",
180
180
  style: wrapperStyle,
181
181
  children: [
182
182
  prefix ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -465,15 +465,18 @@ function installButtonStyles() {
465
465
  var SIZE_STYLES = {
466
466
  sm: {
467
467
  padding: "var(--iris-padding-sm) var(--iris-padding-md)",
468
- fontSize: "var(--iris-font-size-xs, 12px)"
468
+ fontSize: "var(--iris-font-size-xs, 12px)",
469
+ minHeight: "var(--iris-control-height-sm, 28px)"
469
470
  },
470
471
  md: {
471
472
  padding: "var(--iris-padding-sm) var(--iris-padding-lg)",
472
- fontSize: "var(--iris-font-size-md, 14px)"
473
+ fontSize: "var(--iris-font-size-md, 14px)",
474
+ minHeight: "var(--iris-control-height-md, 34px)"
473
475
  },
474
476
  lg: {
475
477
  padding: "var(--iris-padding-md) var(--iris-padding-lg)",
476
- fontSize: "var(--iris-font-size-lg, 16px)"
478
+ fontSize: "var(--iris-font-size-lg, 16px)",
479
+ minHeight: "var(--iris-control-height-lg, 40px)"
477
480
  }
478
481
  };
479
482
  var VARIANT_STYLES = {
@@ -506,7 +509,10 @@ var VARIANT_STYLES = {
506
509
  };
507
510
  function buildInlineStyle(variant, size) {
508
511
  const base = { ...SIZE_STYLES[size], ...VARIANT_STYLES[variant] };
509
- if (variant === "link") base.padding = "0";
512
+ if (variant === "link") {
513
+ base.padding = "0";
514
+ delete base.minHeight;
515
+ }
510
516
  return base;
511
517
  }
512
518
  function Spinner() {