@lmb-it/kitsconcerto-native 0.1.264 → 0.1.266

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 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../src/animations/index.ts"],"sourcesContent":["/**\n * ════════════════════════════════════════════════════════════════════════\n * Overlay animation tuning — EDIT THIS FILE TO CONTROL ALL OVERLAY MOTION\n * ════════════════════════════════════════════════════════════════════════\n *\n * Every in/out animation value used by the animated overlay components on\n * React Native (reanimated) lives here. Change a number and it updates\n * everywhere that animation is used — no need to touch the component files.\n *\n * Consumed by (native):\n * • components/overlay/Dialog/index.native.tsx\n * • components/overlay/ConfirmDialog/index.native.tsx\n * • components/overlay/Toast/index.native.tsx\n *\n * Two kinds of value:\n * • spring → reanimated `.springify().damping(d).stiffness(s)` (+ optional `.delay`)\n * - damping ↓ lower = bouncier, longer settle\n * - stiffness ↑ higher = snappier, faster\n * • duration → milliseconds for `.duration(ms)` (timing-based fade/slide)\n */\n\nexport interface ISpringConfig {\n /** reanimated `.damping()` — lower = bouncier / slower to settle. */\n damping: number;\n /** reanimated `.stiffness()` — higher = snappier / faster. */\n stiffness: number;\n /** reanimated `.mass()` — heavier = slower / more inertia. Defaults to 1. */\n mass?: number;\n /** reanimated `.delay()` in ms — wait before the animation starts. */\n delay?: number;\n}\n\nexport interface IOverlayAnimations {\n /**\n * Dimmed backdrop behind every overlay (fade in/out).\n *\n * ⚠️ `exitDuration` is a FLOOR, not the value to pass. The scrim is the\n * panel's PARENT — read `scrimExitDuration()` below before using it.\n */\n scrim: { enterDuration: number; exitDuration: number };\n /** Centered Dialog panel (zoom-in spring in, timed zoom-out). */\n dialog: { enter: ISpringConfig; exitDuration: number };\n /** Confirm: centered panel, its floating icon bubble, and the content-only/prompt panel. */\n confirm: { enter: ISpringConfig; icon: ISpringConfig; content: ISpringConfig; exitDuration: number };\n /**\n * Bottom sheet shared by Dialog & Confirm (slide-up spring in, timed\n * slide-down out).\n *\n * `keepMotionWhenReduced` asks Reanimated to run this one even when the\n * reader has iOS \"Reduce Motion\" on — see the note beside the value.\n */\n sheet: { enter: ISpringConfig; exitDuration: number; keepMotionWhenReduced: boolean };\n /** Toast — single merged fade+slide entrance, timed exit, re-layout, keyboard gap. */\n toast: {\n enter: ISpringConfig;\n exitDuration: number;\n layoutDuration: number;\n keyboardGap: number;\n };\n}\n\nexport const overlayAnimations: IOverlayAnimations = {\n // ── Backdrop / scrim ─────────────────────────────────────\n scrim: {\n enterDuration: 120,\n exitDuration: 100,\n },\n\n // ── Centered Dialog panel ────────────────────────────────\n // Enter: critically-ish damped spring — snappy but settles cleanly (no\n // ringing). Exit: timing-based zoom-out (springs are enter-only).\n dialog: {\n enter: { damping: 26, stiffness: 420, mass: 1 },\n exitDuration: 120,\n },\n\n // ── Confirm dialog ───────────────────────────────────────\n confirm: {\n /** Centered confirm panel pop. */\n enter: { damping: 26, stiffness: 420, mass: 1 },\n /** Floating severity-icon bubble — pops in slightly after the panel. */\n icon: { damping: 26, stiffness: 420, mass: 1, delay: 60 },\n /** Content-only / prompt panel (no header/buttons chrome). */\n content: { damping: 26, stiffness: 420, mass: 1 },\n /** Timed zoom-out for the confirm center/content panels. */\n exitDuration: 120,\n },\n\n // ── Bottom sheet (Dialog + Confirm, position=\"bottom\") ───\n // Slightly heavier damping/lower stiffness so the sheet glides up without\n // overshoot. Exit: timed slide-down.\n sheet: {\n enter: { damping: 26, stiffness: 140, mass: 1 },\n exitDuration: 260,\n /*\n * ⛔ REDUCE MOTION TURNS THIS OFF, AND THAT READS AS A FADE. Reanimated\n * honours iOS \"Reduce Motion\" by default: the entering/exiting\n * animation is skipped and the panel simply appears, so the only thing\n * left moving is the scrim's opacity. Measured on an iPhone 16 Pro\n * simulator, sheet top edge per frame at 30fps:\n * Reduce Motion OFF — 1924 → 1302 → 898 → 683 → 655 px\n * Reduce Motion ON — 655 in a single frame\n * That second row is exactly the \"it still fades\" report.\n *\n * A bottom sheet is kept moving because the platform keeps it moving:\n * iOS's own sheets still slide up under Reduce Motion — what that\n * setting removes is parallax and zoom, not the presentation of a\n * sheet. The centred Dialog's ZoomIn and the scrim's fade are NOT\n * overridden; they stay on the system default.\n */\n keepMotionWhenReduced: true,\n },\n\n // ── Toast ────────────────────────────────────────────────\n // One element owns the entrance: FadeInUp/FadeInDown animate opacity AND\n // translateY together, so there is no second concurrent layer to desync.\n toast: {\n /** Merged fade+slide entrance (position-appropriate direction). */\n enter: { damping: 30, stiffness: 400, mass: 1 },\n /** Timed fade+slide out. */\n exitDuration: 120,\n /** Re-positioning when toasts stack/unstack. */\n layoutDuration: 150,\n /** Gap (pt) kept between a bottom toast and the keyboard when it opens. */\n keyboardGap: 8,\n },\n};\n\n/**\n * How long the SCRIM may take to leave, given the panel sitting inside it.\n *\n * ⛔ THE SCRIM CONTAINS THE PANEL, SO A SCRIM THAT FINISHES FIRST TAKES THE\n * PANEL WITH IT MID-ANIMATION. Every overlay here nests the panel inside the\n * scrim's Animated.View. React unmounts a subtree as one thing: when the\n * parent's exiting animation reports finished, the child is removed wherever\n * its own exiting animation happens to be. A 260ms slide-down under a 100ms\n * fade-out does not play for 260ms — it plays for 100 and then the sheet is\n * simply gone.\n *\n * Measured on an iPhone 16 Pro simulator, 30fps, closing the bottom sheet.\n * The flags inside the sheet are the only saturated pixels on the screen, so\n * their y is the sheet's own edge and not the screen's:\n *\n * frame flag y (of 348) sheet white scrim\n * 125 140 237 143 settled\n * 126 143 240 149 starts down\n * 127 197 253 192 54 units travelled\n * 128 gone — 234 removed\n *\n * Three frames. The sheet covered a sixth of its travel and vanished, while\n * the scrim faded normally — which is exactly the report that the overlay\n * fades and the sheet does not move.\n *\n * ⚠️ IT WAS INVISIBLE TO THE OBVIOUS MEASUREMENT. A scan for the topmost\n * bright row could not tell a sheet edge at y=655 from the page behind it at\n * y=655; both read white, so the close looked motionless in both the broken\n * and the fixed build. Only a feature that exists ONLY inside the sheet could\n * say which was on screen.\n *\n * The centred dialog has the same fault at a smaller size — 120ms of zoom-out\n * under a 100ms fade — which is why this is a rule about containment rather\n * than a number for the sheet.\n */\nexport function scrimExitDuration(panelExitDuration: number): number {\n return Math.max(overlayAnimations.scrim.exitDuration, panelExitDuration);\n}\n\nexport default overlayAnimations;\n"],"names":[],"mappings":";;AA6DO,MAAM,iBAAA,GAAwC;AAAA;AAAA,EAEjD,KAAA,EAAO;AAAA,IACH,aAAA,EAAe,GAAA;AAAA,IACf,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAA,EAAQ;AAAA,IACJ,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA,IAC9C,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA,EAGA,OAAA,EAAS;AAAA;AAAA,IAEL,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA;AAAA,IAE9C,IAAA,EAAM,EAAE,OAAA,EAAS,EAAA,EAAI,WAAW,GAAA,EAAK,IAAA,EAAM,CAAA,EAAG,KAAA,EAAO,EAAA,EAAG;AAAA;AAAA,IAExD,SAAS,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA;AAAA,IAEhD,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,EAAO;AAAA,IACH,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA,IAC9C,YAAA,EAAc,GAkBlB,CAAA;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,EAAO;AAAA;AAAA,IAEH,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA;AAAA,IAE9C,YAAA,EAAc,GAAA;AAAA;AAAA,IAEd,cAAA,EAAgB,GAAA;AAAA;AAAA,IAEhB,WAAA,EAAa;AAAA;AAErB;AAqCO,SAAS,kBAAkB,iBAAA,EAAmC;AACjE,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,iBAAA,CAAkB,KAAA,CAAM,cAAc,iBAAiB,CAAA;AAC3E;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../src/animations/index.ts"],"sourcesContent":["/**\n * ════════════════════════════════════════════════════════════════════════\n * Overlay animation tuning — EDIT THIS FILE TO CONTROL ALL OVERLAY MOTION\n * ════════════════════════════════════════════════════════════════════════\n *\n * Every in/out animation value used by the animated overlay components on\n * React Native (reanimated) lives here. Change a number and it updates\n * everywhere that animation is used — no need to touch the component files.\n *\n * Consumed by (native):\n * • components/overlay/Dialog/index.native.tsx\n * • components/overlay/ConfirmDialog/index.native.tsx\n * • components/overlay/Toast/index.native.tsx\n *\n * Two kinds of value:\n * • spring → reanimated `.springify().damping(d).stiffness(s)` (+ optional `.delay`)\n * - damping ↓ lower = bouncier, longer settle\n * - stiffness ↑ higher = snappier, faster\n * • duration → milliseconds for `.duration(ms)` (timing-based fade/slide)\n */\n\nexport interface ISpringConfig {\n /** reanimated `.damping()` — lower = bouncier / slower to settle. */\n damping: number;\n /** reanimated `.stiffness()` — higher = snappier / faster. */\n stiffness: number;\n /** reanimated `.mass()` — heavier = slower / more inertia. Defaults to 1. */\n mass?: number;\n /** reanimated `.delay()` in ms — wait before the animation starts. */\n delay?: number;\n}\n\nexport interface IOverlayAnimations {\n /**\n * Dimmed backdrop behind every overlay (fade in/out).\n *\n * ⚠️ `exitDuration` is a FLOOR, not the value to pass — read\n * `scrimExitDuration()` below before using it. The dim has to outlast the\n * panel's own exit or the page behind reappears while the panel is still\n * leaving. ⛔ The old wording here said \"the scrim is the panel's PARENT\";\n * that stopped being true of the Dialog on 29 September 2026, and the\n * function's own comment records both the old reason and the new one.\n */\n scrim: { enterDuration: number; exitDuration: number };\n /** Centered Dialog panel (zoom-in spring in, timed zoom-out). */\n dialog: { enter: ISpringConfig; exitDuration: number };\n /** Confirm: centered panel, its floating icon bubble, and the content-only/prompt panel. */\n confirm: { enter: ISpringConfig; icon: ISpringConfig; content: ISpringConfig; exitDuration: number };\n /**\n * Bottom sheet shared by Dialog & Confirm (slide-up spring in, timed\n * slide-down out).\n *\n * `keepMotionWhenReduced` asks Reanimated to run this one even when the\n * reader has iOS \"Reduce Motion\" on — see the note beside the value.\n */\n sheet: { enter: ISpringConfig; exitDuration: number; keepMotionWhenReduced: boolean };\n /** Toast — single merged fade+slide entrance, timed exit, re-layout, keyboard gap. */\n toast: {\n enter: ISpringConfig;\n exitDuration: number;\n layoutDuration: number;\n keyboardGap: number;\n };\n}\n\nexport const overlayAnimations: IOverlayAnimations = {\n // ── Backdrop / scrim ─────────────────────────────────────\n scrim: {\n enterDuration: 120,\n exitDuration: 100,\n },\n\n // ── Centered Dialog panel ────────────────────────────────\n // Enter: critically-ish damped spring — snappy but settles cleanly (no\n // ringing). Exit: timing-based zoom-out (springs are enter-only).\n dialog: {\n enter: { damping: 26, stiffness: 420, mass: 1 },\n exitDuration: 120,\n },\n\n // ── Confirm dialog ───────────────────────────────────────\n confirm: {\n /** Centered confirm panel pop. */\n enter: { damping: 26, stiffness: 420, mass: 1 },\n /** Floating severity-icon bubble — pops in slightly after the panel. */\n icon: { damping: 26, stiffness: 420, mass: 1, delay: 60 },\n /** Content-only / prompt panel (no header/buttons chrome). */\n content: { damping: 26, stiffness: 420, mass: 1 },\n /** Timed zoom-out for the confirm center/content panels. */\n exitDuration: 120,\n },\n\n // ── Bottom sheet (Dialog + Confirm, position=\"bottom\") ───\n // Slightly heavier damping/lower stiffness so the sheet glides up without\n // overshoot. Exit: timed slide-down.\n sheet: {\n enter: { damping: 26, stiffness: 140, mass: 1 },\n exitDuration: 260,\n /*\n * ⛔ REDUCE MOTION TURNS THIS OFF, AND THAT READS AS A FADE. Reanimated\n * honours iOS \"Reduce Motion\" by default: the entering/exiting\n * animation is skipped and the panel simply appears, so the only thing\n * left moving is the scrim's opacity. Measured on an iPhone 16 Pro\n * simulator, sheet top edge per frame at 30fps:\n * Reduce Motion OFF — 1924 → 1302 → 898 → 683 → 655 px\n * Reduce Motion ON — 655 in a single frame\n * That second row is exactly the \"it still fades\" report.\n *\n * A bottom sheet is kept moving because the platform keeps it moving:\n * iOS's own sheets still slide up under Reduce Motion — what that\n * setting removes is parallax and zoom, not the presentation of a\n * sheet. The centred Dialog's ZoomIn and the scrim's fade are NOT\n * overridden; they stay on the system default.\n */\n keepMotionWhenReduced: true,\n },\n\n // ── Toast ────────────────────────────────────────────────\n // One element owns the entrance: FadeInUp/FadeInDown animate opacity AND\n // translateY together, so there is no second concurrent layer to desync.\n toast: {\n /** Merged fade+slide entrance (position-appropriate direction). */\n enter: { damping: 30, stiffness: 400, mass: 1 },\n /** Timed fade+slide out. */\n exitDuration: 120,\n /** Re-positioning when toasts stack/unstack. */\n layoutDuration: 150,\n /** Gap (pt) kept between a bottom toast and the keyboard when it opens. */\n keyboardGap: 8,\n },\n};\n\n/**\n * How long the SCRIM may take to leave, so the dim outlasts the panel.\n *\n * ⛔ THE REASON IS NOW VISUAL, NOT STRUCTURAL — rewritten 29 September 2026 when\n * the Dialog's scrim and panel became siblings. The panel slides down over\n * `sheet.exitDuration` (260ms). If the dim were allowed to finish in\n * `scrim.exitDuration` (100ms), the last 160ms of that slide would play against\n * the undimmed screen behind it: the page reappears at full brightness while a\n * panel is still visibly on its way out. `max()` keeps the dim present until the\n * panel is off screen.\n *\n * THE TWO NUMBERS, so neither is a bare literal: `scrim.exitDuration` is 100ms —\n * the fade's own pace, and the floor. `sheet.exitDuration` is 260ms and\n * `dialog.exitDuration` is 120ms. So the sheet gets 260 and the centred dialog\n * gets 120; in both cases the panel's own duration wins, and the floor only\n * matters if a caller ever passes something shorter than 100.\n *\n * ── ✅ AND THE FAULT THIS FUNCTION WAS ORIGINALLY WRITTEN FOR IS FIXED ───────\n *\n * It used to exist because the scrim was the panel's PARENT: React unmounts a\n * subtree as one thing, so when the parent's exiting animation reported finished\n * the child was removed wherever its own animation happened to be. A 260ms slide\n * under a 100ms fade did not play for 260ms — it played for 100 and the sheet was\n * simply gone.\n *\n * ⚠️ THE MEASUREMENT IS KEPT, because it is the evidence and a fix that erases\n * its own evidence leaves nothing for the next reader (§12.5). iPhone 16 Pro\n * simulator, 30fps, closing the bottom sheet. The flags inside the sheet are the\n * only saturated pixels on screen, so their y is the sheet's own edge and not the\n * screen's:\n *\n * frame flag y (of 348) sheet white scrim\n * 125 140 237 143 settled\n * 126 143 240 149 starts down\n * 127 197 253 192 54 units travelled\n * 128 gone — 234 removed\n *\n * Three frames. The sheet covered a sixth of its travel and vanished while the\n * scrim faded normally — which is exactly the report that the overlay fades and\n * the sheet does not move.\n *\n * ⚠️ IT WAS INVISIBLE TO THE OBVIOUS MEASUREMENT. A scan for the topmost bright\n * row could not tell a sheet edge at y=655 from the page behind it at y=655; both\n * read white. Only a feature that exists ONLY inside the sheet could say which was\n * on screen.\n *\n * ⛔ THE DIALOG NO LONGER HAS THAT CONTAINMENT. Its panel is a sibling of the\n * scrim and owns the teardown — the Modal unmounts on the PANEL's exit callback,\n * so a scrim that finishes first can no longer take the panel with it.\n * ⚠️ `ConfirmDialog` still nests its panel inside its scrim and therefore still\n * depends on this function for the original reason as well as the visual one.\n * Converting it is a separate unit.\n */\nexport function scrimExitDuration(panelExitDuration: number): number {\n return Math.max(overlayAnimations.scrim.exitDuration, panelExitDuration);\n}\n\nexport default overlayAnimations;\n"],"names":[],"mappings":";;AAiEO,MAAM,iBAAA,GAAwC;AAAA;AAAA,EAEjD,KAAA,EAAO;AAAA,IACH,aAAA,EAAe,GAAA;AAAA,IACf,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAA,EAAQ;AAAA,IACJ,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA,IAC9C,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA,EAGA,OAAA,EAAS;AAAA;AAAA,IAEL,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA;AAAA,IAE9C,IAAA,EAAM,EAAE,OAAA,EAAS,EAAA,EAAI,WAAW,GAAA,EAAK,IAAA,EAAM,CAAA,EAAG,KAAA,EAAO,EAAA,EAAG;AAAA;AAAA,IAExD,SAAS,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA;AAAA,IAEhD,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,EAAO;AAAA,IACH,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA,IAC9C,YAAA,EAAc,GAkBlB,CAAA;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,EAAO;AAAA;AAAA,IAEH,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA;AAAA,IAE9C,YAAA,EAAc,GAAA;AAAA;AAAA,IAEd,cAAA,EAAgB,GAAA;AAAA;AAAA,IAEhB,WAAA,EAAa;AAAA;AAErB;AAuDO,SAAS,kBAAkB,iBAAA,EAAmC;AACjE,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,iBAAA,CAAkB,KAAA,CAAM,cAAc,iBAAiB,CAAA;AAC3E;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/animations/index.ts"],"sourcesContent":["/**\n * ════════════════════════════════════════════════════════════════════════\n * Overlay animation tuning — EDIT THIS FILE TO CONTROL ALL OVERLAY MOTION\n * ════════════════════════════════════════════════════════════════════════\n *\n * Every in/out animation value used by the animated overlay components on\n * React Native (reanimated) lives here. Change a number and it updates\n * everywhere that animation is used — no need to touch the component files.\n *\n * Consumed by (native):\n * • components/overlay/Dialog/index.native.tsx\n * • components/overlay/ConfirmDialog/index.native.tsx\n * • components/overlay/Toast/index.native.tsx\n *\n * Two kinds of value:\n * • spring → reanimated `.springify().damping(d).stiffness(s)` (+ optional `.delay`)\n * - damping ↓ lower = bouncier, longer settle\n * - stiffness ↑ higher = snappier, faster\n * • duration → milliseconds for `.duration(ms)` (timing-based fade/slide)\n */\n\nexport interface ISpringConfig {\n /** reanimated `.damping()` — lower = bouncier / slower to settle. */\n damping: number;\n /** reanimated `.stiffness()` — higher = snappier / faster. */\n stiffness: number;\n /** reanimated `.mass()` — heavier = slower / more inertia. Defaults to 1. */\n mass?: number;\n /** reanimated `.delay()` in ms — wait before the animation starts. */\n delay?: number;\n}\n\nexport interface IOverlayAnimations {\n /**\n * Dimmed backdrop behind every overlay (fade in/out).\n *\n * ⚠️ `exitDuration` is a FLOOR, not the value to pass. The scrim is the\n * panel's PARENT — read `scrimExitDuration()` below before using it.\n */\n scrim: { enterDuration: number; exitDuration: number };\n /** Centered Dialog panel (zoom-in spring in, timed zoom-out). */\n dialog: { enter: ISpringConfig; exitDuration: number };\n /** Confirm: centered panel, its floating icon bubble, and the content-only/prompt panel. */\n confirm: { enter: ISpringConfig; icon: ISpringConfig; content: ISpringConfig; exitDuration: number };\n /**\n * Bottom sheet shared by Dialog & Confirm (slide-up spring in, timed\n * slide-down out).\n *\n * `keepMotionWhenReduced` asks Reanimated to run this one even when the\n * reader has iOS \"Reduce Motion\" on — see the note beside the value.\n */\n sheet: { enter: ISpringConfig; exitDuration: number; keepMotionWhenReduced: boolean };\n /** Toast — single merged fade+slide entrance, timed exit, re-layout, keyboard gap. */\n toast: {\n enter: ISpringConfig;\n exitDuration: number;\n layoutDuration: number;\n keyboardGap: number;\n };\n}\n\nexport const overlayAnimations: IOverlayAnimations = {\n // ── Backdrop / scrim ─────────────────────────────────────\n scrim: {\n enterDuration: 120,\n exitDuration: 100,\n },\n\n // ── Centered Dialog panel ────────────────────────────────\n // Enter: critically-ish damped spring — snappy but settles cleanly (no\n // ringing). Exit: timing-based zoom-out (springs are enter-only).\n dialog: {\n enter: { damping: 26, stiffness: 420, mass: 1 },\n exitDuration: 120,\n },\n\n // ── Confirm dialog ───────────────────────────────────────\n confirm: {\n /** Centered confirm panel pop. */\n enter: { damping: 26, stiffness: 420, mass: 1 },\n /** Floating severity-icon bubble — pops in slightly after the panel. */\n icon: { damping: 26, stiffness: 420, mass: 1, delay: 60 },\n /** Content-only / prompt panel (no header/buttons chrome). */\n content: { damping: 26, stiffness: 420, mass: 1 },\n /** Timed zoom-out for the confirm center/content panels. */\n exitDuration: 120,\n },\n\n // ── Bottom sheet (Dialog + Confirm, position=\"bottom\") ───\n // Slightly heavier damping/lower stiffness so the sheet glides up without\n // overshoot. Exit: timed slide-down.\n sheet: {\n enter: { damping: 26, stiffness: 140, mass: 1 },\n exitDuration: 260,\n /*\n * ⛔ REDUCE MOTION TURNS THIS OFF, AND THAT READS AS A FADE. Reanimated\n * honours iOS \"Reduce Motion\" by default: the entering/exiting\n * animation is skipped and the panel simply appears, so the only thing\n * left moving is the scrim's opacity. Measured on an iPhone 16 Pro\n * simulator, sheet top edge per frame at 30fps:\n * Reduce Motion OFF — 1924 → 1302 → 898 → 683 → 655 px\n * Reduce Motion ON — 655 in a single frame\n * That second row is exactly the \"it still fades\" report.\n *\n * A bottom sheet is kept moving because the platform keeps it moving:\n * iOS's own sheets still slide up under Reduce Motion — what that\n * setting removes is parallax and zoom, not the presentation of a\n * sheet. The centred Dialog's ZoomIn and the scrim's fade are NOT\n * overridden; they stay on the system default.\n */\n keepMotionWhenReduced: true,\n },\n\n // ── Toast ────────────────────────────────────────────────\n // One element owns the entrance: FadeInUp/FadeInDown animate opacity AND\n // translateY together, so there is no second concurrent layer to desync.\n toast: {\n /** Merged fade+slide entrance (position-appropriate direction). */\n enter: { damping: 30, stiffness: 400, mass: 1 },\n /** Timed fade+slide out. */\n exitDuration: 120,\n /** Re-positioning when toasts stack/unstack. */\n layoutDuration: 150,\n /** Gap (pt) kept between a bottom toast and the keyboard when it opens. */\n keyboardGap: 8,\n },\n};\n\n/**\n * How long the SCRIM may take to leave, given the panel sitting inside it.\n *\n * ⛔ THE SCRIM CONTAINS THE PANEL, SO A SCRIM THAT FINISHES FIRST TAKES THE\n * PANEL WITH IT MID-ANIMATION. Every overlay here nests the panel inside the\n * scrim's Animated.View. React unmounts a subtree as one thing: when the\n * parent's exiting animation reports finished, the child is removed wherever\n * its own exiting animation happens to be. A 260ms slide-down under a 100ms\n * fade-out does not play for 260ms — it plays for 100 and then the sheet is\n * simply gone.\n *\n * Measured on an iPhone 16 Pro simulator, 30fps, closing the bottom sheet.\n * The flags inside the sheet are the only saturated pixels on the screen, so\n * their y is the sheet's own edge and not the screen's:\n *\n * frame flag y (of 348) sheet white scrim\n * 125 140 237 143 settled\n * 126 143 240 149 starts down\n * 127 197 253 192 54 units travelled\n * 128 gone — 234 removed\n *\n * Three frames. The sheet covered a sixth of its travel and vanished, while\n * the scrim faded normally — which is exactly the report that the overlay\n * fades and the sheet does not move.\n *\n * ⚠️ IT WAS INVISIBLE TO THE OBVIOUS MEASUREMENT. A scan for the topmost\n * bright row could not tell a sheet edge at y=655 from the page behind it at\n * y=655; both read white, so the close looked motionless in both the broken\n * and the fixed build. Only a feature that exists ONLY inside the sheet could\n * say which was on screen.\n *\n * The centred dialog has the same fault at a smaller size — 120ms of zoom-out\n * under a 100ms fade — which is why this is a rule about containment rather\n * than a number for the sheet.\n */\nexport function scrimExitDuration(panelExitDuration: number): number {\n return Math.max(overlayAnimations.scrim.exitDuration, panelExitDuration);\n}\n\nexport default overlayAnimations;\n"],"names":[],"mappings":"AA6DO,MAAM,iBAAA,GAAwC;AAAA;AAAA,EAEjD,KAAA,EAAO;AAAA,IACH,aAAA,EAAe,GAAA;AAAA,IACf,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAA,EAAQ;AAAA,IACJ,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA,IAC9C,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA,EAGA,OAAA,EAAS;AAAA;AAAA,IAEL,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA;AAAA,IAE9C,IAAA,EAAM,EAAE,OAAA,EAAS,EAAA,EAAI,WAAW,GAAA,EAAK,IAAA,EAAM,CAAA,EAAG,KAAA,EAAO,EAAA,EAAG;AAAA;AAAA,IAExD,SAAS,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA;AAAA,IAEhD,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,EAAO;AAAA,IACH,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA,IAC9C,YAAA,EAAc,GAkBlB,CAAA;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,EAAO;AAAA;AAAA,IAEH,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA;AAAA,IAE9C,YAAA,EAAc,GAAA;AAAA;AAAA,IAEd,cAAA,EAAgB,GAAA;AAAA;AAAA,IAEhB,WAAA,EAAa;AAAA;AAErB;AAqCO,SAAS,kBAAkB,iBAAA,EAAmC;AACjE,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,iBAAA,CAAkB,KAAA,CAAM,cAAc,iBAAiB,CAAA;AAC3E;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/animations/index.ts"],"sourcesContent":["/**\n * ════════════════════════════════════════════════════════════════════════\n * Overlay animation tuning — EDIT THIS FILE TO CONTROL ALL OVERLAY MOTION\n * ════════════════════════════════════════════════════════════════════════\n *\n * Every in/out animation value used by the animated overlay components on\n * React Native (reanimated) lives here. Change a number and it updates\n * everywhere that animation is used — no need to touch the component files.\n *\n * Consumed by (native):\n * • components/overlay/Dialog/index.native.tsx\n * • components/overlay/ConfirmDialog/index.native.tsx\n * • components/overlay/Toast/index.native.tsx\n *\n * Two kinds of value:\n * • spring → reanimated `.springify().damping(d).stiffness(s)` (+ optional `.delay`)\n * - damping ↓ lower = bouncier, longer settle\n * - stiffness ↑ higher = snappier, faster\n * • duration → milliseconds for `.duration(ms)` (timing-based fade/slide)\n */\n\nexport interface ISpringConfig {\n /** reanimated `.damping()` — lower = bouncier / slower to settle. */\n damping: number;\n /** reanimated `.stiffness()` — higher = snappier / faster. */\n stiffness: number;\n /** reanimated `.mass()` — heavier = slower / more inertia. Defaults to 1. */\n mass?: number;\n /** reanimated `.delay()` in ms — wait before the animation starts. */\n delay?: number;\n}\n\nexport interface IOverlayAnimations {\n /**\n * Dimmed backdrop behind every overlay (fade in/out).\n *\n * ⚠️ `exitDuration` is a FLOOR, not the value to pass — read\n * `scrimExitDuration()` below before using it. The dim has to outlast the\n * panel's own exit or the page behind reappears while the panel is still\n * leaving. ⛔ The old wording here said \"the scrim is the panel's PARENT\";\n * that stopped being true of the Dialog on 29 September 2026, and the\n * function's own comment records both the old reason and the new one.\n */\n scrim: { enterDuration: number; exitDuration: number };\n /** Centered Dialog panel (zoom-in spring in, timed zoom-out). */\n dialog: { enter: ISpringConfig; exitDuration: number };\n /** Confirm: centered panel, its floating icon bubble, and the content-only/prompt panel. */\n confirm: { enter: ISpringConfig; icon: ISpringConfig; content: ISpringConfig; exitDuration: number };\n /**\n * Bottom sheet shared by Dialog & Confirm (slide-up spring in, timed\n * slide-down out).\n *\n * `keepMotionWhenReduced` asks Reanimated to run this one even when the\n * reader has iOS \"Reduce Motion\" on — see the note beside the value.\n */\n sheet: { enter: ISpringConfig; exitDuration: number; keepMotionWhenReduced: boolean };\n /** Toast — single merged fade+slide entrance, timed exit, re-layout, keyboard gap. */\n toast: {\n enter: ISpringConfig;\n exitDuration: number;\n layoutDuration: number;\n keyboardGap: number;\n };\n}\n\nexport const overlayAnimations: IOverlayAnimations = {\n // ── Backdrop / scrim ─────────────────────────────────────\n scrim: {\n enterDuration: 120,\n exitDuration: 100,\n },\n\n // ── Centered Dialog panel ────────────────────────────────\n // Enter: critically-ish damped spring — snappy but settles cleanly (no\n // ringing). Exit: timing-based zoom-out (springs are enter-only).\n dialog: {\n enter: { damping: 26, stiffness: 420, mass: 1 },\n exitDuration: 120,\n },\n\n // ── Confirm dialog ───────────────────────────────────────\n confirm: {\n /** Centered confirm panel pop. */\n enter: { damping: 26, stiffness: 420, mass: 1 },\n /** Floating severity-icon bubble — pops in slightly after the panel. */\n icon: { damping: 26, stiffness: 420, mass: 1, delay: 60 },\n /** Content-only / prompt panel (no header/buttons chrome). */\n content: { damping: 26, stiffness: 420, mass: 1 },\n /** Timed zoom-out for the confirm center/content panels. */\n exitDuration: 120,\n },\n\n // ── Bottom sheet (Dialog + Confirm, position=\"bottom\") ───\n // Slightly heavier damping/lower stiffness so the sheet glides up without\n // overshoot. Exit: timed slide-down.\n sheet: {\n enter: { damping: 26, stiffness: 140, mass: 1 },\n exitDuration: 260,\n /*\n * ⛔ REDUCE MOTION TURNS THIS OFF, AND THAT READS AS A FADE. Reanimated\n * honours iOS \"Reduce Motion\" by default: the entering/exiting\n * animation is skipped and the panel simply appears, so the only thing\n * left moving is the scrim's opacity. Measured on an iPhone 16 Pro\n * simulator, sheet top edge per frame at 30fps:\n * Reduce Motion OFF — 1924 → 1302 → 898 → 683 → 655 px\n * Reduce Motion ON — 655 in a single frame\n * That second row is exactly the \"it still fades\" report.\n *\n * A bottom sheet is kept moving because the platform keeps it moving:\n * iOS's own sheets still slide up under Reduce Motion — what that\n * setting removes is parallax and zoom, not the presentation of a\n * sheet. The centred Dialog's ZoomIn and the scrim's fade are NOT\n * overridden; they stay on the system default.\n */\n keepMotionWhenReduced: true,\n },\n\n // ── Toast ────────────────────────────────────────────────\n // One element owns the entrance: FadeInUp/FadeInDown animate opacity AND\n // translateY together, so there is no second concurrent layer to desync.\n toast: {\n /** Merged fade+slide entrance (position-appropriate direction). */\n enter: { damping: 30, stiffness: 400, mass: 1 },\n /** Timed fade+slide out. */\n exitDuration: 120,\n /** Re-positioning when toasts stack/unstack. */\n layoutDuration: 150,\n /** Gap (pt) kept between a bottom toast and the keyboard when it opens. */\n keyboardGap: 8,\n },\n};\n\n/**\n * How long the SCRIM may take to leave, so the dim outlasts the panel.\n *\n * ⛔ THE REASON IS NOW VISUAL, NOT STRUCTURAL — rewritten 29 September 2026 when\n * the Dialog's scrim and panel became siblings. The panel slides down over\n * `sheet.exitDuration` (260ms). If the dim were allowed to finish in\n * `scrim.exitDuration` (100ms), the last 160ms of that slide would play against\n * the undimmed screen behind it: the page reappears at full brightness while a\n * panel is still visibly on its way out. `max()` keeps the dim present until the\n * panel is off screen.\n *\n * THE TWO NUMBERS, so neither is a bare literal: `scrim.exitDuration` is 100ms —\n * the fade's own pace, and the floor. `sheet.exitDuration` is 260ms and\n * `dialog.exitDuration` is 120ms. So the sheet gets 260 and the centred dialog\n * gets 120; in both cases the panel's own duration wins, and the floor only\n * matters if a caller ever passes something shorter than 100.\n *\n * ── ✅ AND THE FAULT THIS FUNCTION WAS ORIGINALLY WRITTEN FOR IS FIXED ───────\n *\n * It used to exist because the scrim was the panel's PARENT: React unmounts a\n * subtree as one thing, so when the parent's exiting animation reported finished\n * the child was removed wherever its own animation happened to be. A 260ms slide\n * under a 100ms fade did not play for 260ms — it played for 100 and the sheet was\n * simply gone.\n *\n * ⚠️ THE MEASUREMENT IS KEPT, because it is the evidence and a fix that erases\n * its own evidence leaves nothing for the next reader (§12.5). iPhone 16 Pro\n * simulator, 30fps, closing the bottom sheet. The flags inside the sheet are the\n * only saturated pixels on screen, so their y is the sheet's own edge and not the\n * screen's:\n *\n * frame flag y (of 348) sheet white scrim\n * 125 140 237 143 settled\n * 126 143 240 149 starts down\n * 127 197 253 192 54 units travelled\n * 128 gone — 234 removed\n *\n * Three frames. The sheet covered a sixth of its travel and vanished while the\n * scrim faded normally — which is exactly the report that the overlay fades and\n * the sheet does not move.\n *\n * ⚠️ IT WAS INVISIBLE TO THE OBVIOUS MEASUREMENT. A scan for the topmost bright\n * row could not tell a sheet edge at y=655 from the page behind it at y=655; both\n * read white. Only a feature that exists ONLY inside the sheet could say which was\n * on screen.\n *\n * ⛔ THE DIALOG NO LONGER HAS THAT CONTAINMENT. Its panel is a sibling of the\n * scrim and owns the teardown — the Modal unmounts on the PANEL's exit callback,\n * so a scrim that finishes first can no longer take the panel with it.\n * ⚠️ `ConfirmDialog` still nests its panel inside its scrim and therefore still\n * depends on this function for the original reason as well as the visual one.\n * Converting it is a separate unit.\n */\nexport function scrimExitDuration(panelExitDuration: number): number {\n return Math.max(overlayAnimations.scrim.exitDuration, panelExitDuration);\n}\n\nexport default overlayAnimations;\n"],"names":[],"mappings":"AAiEO,MAAM,iBAAA,GAAwC;AAAA;AAAA,EAEjD,KAAA,EAAO;AAAA,IACH,aAAA,EAAe,GAAA;AAAA,IACf,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAA,EAAQ;AAAA,IACJ,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA,IAC9C,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA,EAGA,OAAA,EAAS;AAAA;AAAA,IAEL,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA;AAAA,IAE9C,IAAA,EAAM,EAAE,OAAA,EAAS,EAAA,EAAI,WAAW,GAAA,EAAK,IAAA,EAAM,CAAA,EAAG,KAAA,EAAO,EAAA,EAAG;AAAA;AAAA,IAExD,SAAS,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA;AAAA,IAEhD,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,EAAO;AAAA,IACH,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA,IAC9C,YAAA,EAAc,GAkBlB,CAAA;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,EAAO;AAAA;AAAA,IAEH,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA;AAAA,IAE9C,YAAA,EAAc,GAAA;AAAA;AAAA,IAEd,cAAA,EAAgB,GAAA;AAAA;AAAA,IAEhB,WAAA,EAAa;AAAA;AAErB;AAuDO,SAAS,kBAAkB,iBAAA,EAAmC;AACjE,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,iBAAA,CAAkB,KAAA,CAAM,cAAc,iBAAiB,CAAA;AAC3E;;;;"}
@@ -66,6 +66,7 @@ require('../../../../../packages/types/src/Theme/defaultTheme.cjs');
66
66
  require('../../../../../packages/types/src/Theme/alphaColors.cjs');
67
67
  require('../../Factory/helpers/cssVarMap.cjs');
68
68
  var useKeyboardHeight = require('../../Factory/helpers/useKeyboardHeight.cjs');
69
+ var readerEdge = require('../../Factory/helpers/readerEdge.cjs');
69
70
  require('i18next');
70
71
  require('react-i18next');
71
72
  require('../AutoComplete/index.cjs');
@@ -85,7 +86,6 @@ require('../RadioButton/index.cjs');
85
86
  require('../Input/index.cjs');
86
87
  require('../Input/Field.cjs');
87
88
  require('../Input/Slot.cjs');
88
- var readerEdge = require('../../Factory/helpers/readerEdge.cjs');
89
89
  var panelGeometry = require('./panelGeometry.cjs');
90
90
 
91
91
  const getLabel = (item, optionLabel) => {
@@ -62,6 +62,7 @@ import '../../../../../packages/types/src/Theme/defaultTheme.js';
62
62
  import '../../../../../packages/types/src/Theme/alphaColors.js';
63
63
  import '../../Factory/helpers/cssVarMap.js';
64
64
  import { useKeyboardHeight } from '../../Factory/helpers/useKeyboardHeight.js';
65
+ import { readerEdge } from '../../Factory/helpers/readerEdge.js';
65
66
  import 'i18next';
66
67
  import 'react-i18next';
67
68
  import '../AutoComplete/index.js';
@@ -81,7 +82,6 @@ import '../RadioButton/index.js';
81
82
  import '../Input/index.js';
82
83
  import '../Input/Field.js';
83
84
  import '../Input/Slot.js';
84
- import { readerEdge } from '../../Factory/helpers/readerEdge.js';
85
85
  import { computePanelGeometry } from './panelGeometry.js';
86
86
 
87
87
  const getLabel = (item, optionLabel) => {
@@ -27,6 +27,7 @@ function useOverlayPresence(visible) {
27
27
  }, []);
28
28
  return { mounted, handleExitFinished };
29
29
  }
30
+ const AnimatedPressable = Animated.createAnimatedComponent(reactNative.Pressable);
30
31
  function KitsDialogControlled({ state, onHide }) {
31
32
  const {
32
33
  children,
@@ -98,15 +99,22 @@ function KitsDialogControlled({ state, onHide }) {
98
99
  if (!mounted) return null;
99
100
  const content = typeof children === "function" ? children(hide) : children;
100
101
  const contentMode = contentProp != null ? typeof contentProp === "function" ? contentProp({ hide }) : contentProp : null;
101
- return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Modal, { visible: true, transparent: true, animationType: "none", onRequestClose: hide, children: state.visible && /* @__PURE__ */ jsxRuntime.jsxs(
102
- Animated.View,
103
- {
104
- entering: Animated.FadeIn.duration(index.overlayAnimations.scrim.enterDuration),
105
- exiting: Animated.FadeOut.duration(index.scrimExitDuration(isSheet ? index.overlayAnimations.sheet.exitDuration : index.overlayAnimations.dialog.exitDuration)),
106
- style: [isSheet ? styles.sheetOverlay : styles.overlay, { backgroundColor: scrimColor }, resolvedMaskStyle],
107
- children: [
108
- /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style: reactNative.StyleSheet.absoluteFill, onPress: dismissableMask ? hide : void 0 }),
109
- /* @__PURE__ */ jsxRuntime.jsx(
102
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Modal, { visible: true, transparent: true, animationType: "none", onRequestClose: hide, children: state.visible && /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles.root, children: [
103
+ /* @__PURE__ */ jsxRuntime.jsx(
104
+ AnimatedPressable,
105
+ {
106
+ entering: Animated.FadeIn.duration(index.overlayAnimations.scrim.enterDuration),
107
+ exiting: Animated.FadeOut.duration(index.scrimExitDuration(isSheet ? index.overlayAnimations.sheet.exitDuration : index.overlayAnimations.dialog.exitDuration)),
108
+ style: [reactNative.StyleSheet.absoluteFill, { backgroundColor: scrimColor }, resolvedMaskStyle],
109
+ onPress: dismissableMask ? hide : void 0
110
+ }
111
+ ),
112
+ /* @__PURE__ */ jsxRuntime.jsx(
113
+ reactNative.View,
114
+ {
115
+ style: isSheet ? styles.sheetArrange : styles.centerArrange,
116
+ pointerEvents: "box-none",
117
+ children: /* @__PURE__ */ jsxRuntime.jsx(
110
118
  Animated.View,
111
119
  {
112
120
  entering: isSheet ? Animated.SlideInDown.springify().damping(index.overlayAnimations.sheet.enter.damping).stiffness(index.overlayAnimations.sheet.enter.stiffness).mass(index.overlayAnimations.sheet.enter.mass).reduceMotion(Animated.ReduceMotion.Never ) : Animated.ZoomIn.springify().damping(index.overlayAnimations.dialog.enter.damping).stiffness(index.overlayAnimations.dialog.enter.stiffness).mass(index.overlayAnimations.dialog.enter.mass),
@@ -162,19 +170,35 @@ function KitsDialogControlled({ state, onHide }) {
162
170
  ] })
163
171
  }
164
172
  )
165
- ]
166
- }
167
- ) });
173
+ }
174
+ )
175
+ ] }) });
168
176
  }
169
177
  const styles = reactNative.StyleSheet.create({
170
- overlay: {
171
- flex: 1,
178
+ /**
179
+ * The container. ⛔ IT IS NEVER ANIMATED AND CARRIES NO OPACITY — that is the
180
+ * whole point of the change. It only exists to give the scrim and the panel a
181
+ * shared parent so they can be siblings.
182
+ */
183
+ root: {
184
+ flex: 1
185
+ },
186
+ /**
187
+ * Places the panel. ⚠️ The 24 padding moved here from the old `overlay` style,
188
+ * and it had to: `position: absolute` resolves against a parent's PADDING box
189
+ * in React Native, so a scrim absolutely filling a padded parent would have
190
+ * stopped 24 short of every screen edge and left an undimmed frame. The scrim
191
+ * now fills `root`, which has no padding, and the inset belongs to the layer
192
+ * that positions the panel.
193
+ */
194
+ centerArrange: {
195
+ ...reactNative.StyleSheet.absoluteFillObject,
172
196
  justifyContent: "center",
173
197
  alignItems: "center",
174
198
  padding: 24
175
199
  },
176
- sheetOverlay: {
177
- flex: 1,
200
+ sheetArrange: {
201
+ ...reactNative.StyleSheet.absoluteFillObject,
178
202
  justifyContent: "flex-end"
179
203
  },
180
204
  sheetPanel: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../../../src/components/overlay/Dialog/index.native.tsx"],"sourcesContent":["import React from \"react\";\nimport {Modal, Pressable, ScrollView, StyleSheet, View, useWindowDimensions} from \"react-native\";\nimport Animated, {Easing, FadeIn, FadeOut, ReduceMotion, runOnJS, SlideInDown, SlideOutDown, ZoomIn, ZoomOut} from \"react-native-reanimated\";\nimport {useSafeAreaInsets} from \"react-native-safe-area-context\";\nimport {Icon, Text} from \"../../../_compat\";\nimport type {IKitsDialogControlled} from \"@lmb-it/kitsconcerto-types\";\nimport {useKitsTheme} from \"../../../contexts/Theme\";\nimport {useSeverityColors} from \"../../../hooks/useSeverityColors\";\nimport {useResolvedStyle} from \"../../../hooks\";\nimport {overlayAnimations as anim, scrimExitDuration} from \"../../../animations\";\n\n/**\n * Keeps the RN Modal mounted through the exit animation. `visible` drives the\n * inner scrim + panel entering/exiting; the Modal itself stays mounted until\n * the panel's exit animation reports finished, then unmounts.\n *\n * Re-entrancy: a new `visible=true` during an exit re-renders the inner (which\n * re-enters), and the still-pending exit callback is ignored because\n * `visibleRef` is already back to `true` — so the Modal is never torn down\n * mid-reopen.\n */\nfunction useOverlayPresence(visible: boolean) {\n const [mounted, setMounted] = React.useState(visible);\n const visibleRef = React.useRef(visible);\n React.useEffect(() => {\n visibleRef.current = visible;\n if (visible) setMounted(true);\n }, [visible]);\n // Runs on the JS thread (dispatched via runOnJS from the exit worklet).\n const handleExitFinished = React.useCallback(() => {\n if (!visibleRef.current) setMounted(false);\n }, []);\n return {mounted, handleExitFinished};\n}\n\nexport default function KitsDialogControlled({state, onHide}: IKitsDialogControlled) {\n const {\n children,\n content: contentProp,\n onClose,\n asyncClose,\n type,\n icon,\n style,\n contentStyle,\n headerStyle,\n maskStyle,\n position = 'center',\n responsive = true,\n hideHeader,\n headerRender,\n footerRender,\n footerStyle,\n canClose,\n bodyStyle,\n closeIcon,\n // Native default true preserves historical tap-to-dismiss; web's\n // PrimeReact default is false — pass explicitly in shared code.\n dismissableMask = true,\n breakpoints,\n ...rest\n } = state;\n const {resolveToken, theme} = useKitsTheme();\n const severityColors = useSeverityColors(type || 'secondary');\n const colors = type ? severityColors : null;\n const insets = useSafeAreaInsets();\n const isSheet = position === 'bottom';\n\n const surfaceColor = resolveToken('surface-card');\n const textColor = resolveToken('text');\n const borderColor = colors?.border ?? resolveToken('border');\n const subtextColor = resolveToken('gray.500');\n const grabberColor = resolveToken('gray.300');\n // Scrim via the literal alpha overlay token → rgba(0,0,0,0.4) in both modes.\n const scrimColor = resolveToken('black-alpha-40');\n const brandLogo = type === 'brand' ? theme.config.logo : null;\n\n const resolvedStyle = useResolvedStyle(style || {});\n const resolvedContentStyle = useResolvedStyle(contentStyle || {});\n const resolvedHeaderStyle = useResolvedStyle(headerStyle || {});\n const resolvedMaskStyle = useResolvedStyle(maskStyle || {});\n const resolvedFooterStyle = useResolvedStyle(footerStyle || {});\n const resolvedBodyStyle = useResolvedStyle(bodyStyle || {});\n\n const {width: screenWidth} = useWindowDimensions();\n // Consumer `breakpoints` ({'960px': '75vw'}) mirrors the web prop: the\n // smallest max-width threshold >= the screen width wins; vw/% both map\n // to a percentage of the window width. Falls back to the responsive\n // default (50% tablets/desktop, 95% phones <=641px).\n const breakpointWidth = (() => {\n if (!breakpoints) return null;\n const matches = Object.entries(breakpoints)\n .map(([k, v]) => [parseFloat(k), v] as const)\n .filter(([px]) => !Number.isNaN(px) && screenWidth <= px)\n .sort(([a], [b]) => a - b);\n const value = matches[0]?.[1];\n if (value == null) return null;\n const num = parseFloat(value);\n return Number.isNaN(num) ? null : `${num}%`;\n })();\n const responsiveWidth = breakpointWidth ?? (screenWidth > 641 ? '50%' : '95%');\n const hasExplicitWidth = (resolvedStyle as any).width != null;\n\n const hide = async () => {\n // canClose gate — intercepts every close path (backdrop Pressable,\n // built-in X Pressable, RN Modal onRequestClose). When blocked,\n // onClose is suppressed and the dialog stays open.\n if (canClose === false || (typeof canClose === 'function' && !canClose())) {\n return;\n }\n if (asyncClose && typeof onClose === \"function\") {\n await onClose();\n } else {\n onClose?.();\n }\n onHide();\n };\n\n const {mounted, handleExitFinished} = useOverlayPresence(!!state.visible);\n if (!mounted) return null;\n\n const content = typeof children === \"function\" ? children(hide) : children;\n // Content-mode override (mirrors web): consumer node replaces the whole\n // header / body / footer template inside the panel.\n const contentMode = contentProp != null\n ? (typeof contentProp === \"function\" ? contentProp({hide}) : contentProp)\n : null;\n\n return (\n <Modal visible transparent animationType=\"none\" onRequestClose={hide}>\n {state.visible && (\n <Animated.View\n entering={FadeIn.duration(anim.scrim.enterDuration)}\n /* The panel is a CHILD of this view, so this fade must not\n finish first — see `scrimExitDuration`. */\n exiting={FadeOut.duration(scrimExitDuration(isSheet ? anim.sheet.exitDuration : anim.dialog.exitDuration))}\n style={[isSheet ? styles.sheetOverlay : styles.overlay, {backgroundColor: scrimColor}, resolvedMaskStyle as any]}\n >\n <Pressable style={StyleSheet.absoluteFill} onPress={dismissableMask ? hide : undefined}/>\n <Animated.View\n /* The sheet asks Reanimated to keep moving under iOS\n \"Reduce Motion\" — see `overlayAnimations.sheet`. Without\n it the panel appears in one frame and the only motion\n left is the scrim, which reads as a fade. The centred\n dialog keeps the system default. */\n entering={isSheet\n ? SlideInDown.springify().damping(anim.sheet.enter.damping).stiffness(anim.sheet.enter.stiffness).mass(anim.sheet.enter.mass ?? 1)\n .reduceMotion(anim.sheet.keepMotionWhenReduced ? ReduceMotion.Never : ReduceMotion.System)\n : ZoomIn.springify().damping(anim.dialog.enter.damping).stiffness(anim.dialog.enter.stiffness).mass(anim.dialog.enter.mass ?? 1)}\n exiting={(isSheet\n ? SlideOutDown.duration(anim.sheet.exitDuration).easing(Easing.in(Easing.ease))\n .reduceMotion(anim.sheet.keepMotionWhenReduced ? ReduceMotion.Never : ReduceMotion.System)\n : ZoomOut.duration(anim.dialog.exitDuration).easing(Easing.in(Easing.ease))\n ).withCallback((finished) => {\n 'worklet';\n if (finished) runOnJS(handleExitFinished)();\n })}\n style={[\n styles.panel,\n isSheet && styles.sheetPanel,\n {backgroundColor: surfaceColor, borderColor},\n // Explicit `breakpoints` win even when responsive=false (web parity)\n !isSheet && !hasExplicitWidth && (breakpoints != null || responsive) ? {width: responsiveWidth} : null,\n resolvedStyle as any,\n resolvedContentStyle as any,\n ]}\n >\n {contentMode != null ? contentMode : <>\n {/* Grabber (bottom-sheet) */}\n {isSheet && <View style={[styles.grabber, {backgroundColor: grabberColor}]}/>}\n\n {/* Severity accent strip */}\n {colors && !isSheet && (\n <View style={{height: 4, backgroundColor: colors.solid, borderTopLeftRadius: 20, borderTopRightRadius: 20}}/>\n )}\n\n {/* Custom header (headerRender) — fully replaces the built-in header\n View when provided. Wins over the default header even if `header`\n is also set. */}\n {!hideHeader && headerRender != null && headerRender({close: () => { void hide(); }})}\n\n {/* Header (default) — rendered when no headerRender and `header` is set. */}\n {!hideHeader && headerRender == null && rest.header != null && (\n <View style={[styles.header, {borderBottomColor: borderColor}, resolvedHeaderStyle as any]}>\n {/* Inline severity icon */}\n {(icon || brandLogo) && colors && (\n <View style={{\n width: 36,\n height: 36,\n borderRadius: 18,\n backgroundColor: colors.iconBg,\n alignItems: 'center',\n justifyContent: 'center',\n marginRight: 12,\n }}>\n {brandLogo ? brandLogo : typeof icon === 'string' ? (\n <Icon name={icon as never} size={'lg'} color={colors.iconFg}/>\n ) : icon}\n </View>\n )}\n <Text style={{fontSize: 18, fontWeight: \"700\", color: textColor, flex: 1}}>\n {rest.header as React.ReactNode}\n </Text>\n <Pressable onPress={hide} hitSlop={8}>\n {closeIcon ?? <Text style={{fontSize: 18, color: subtextColor}}>✕</Text>}\n </Pressable>\n </View>\n )}\n\n {/* Body — bodyStyle is applied AFTER the built-in maxHeight: 400,\n so consumers can lift the cap (`maxHeight: 600`) or unlock flex\n sizing (`minHeight: 0`) without losing the default behavior when\n bodyStyle is unset. */}\n <ScrollView\n style={[styles.body, resolvedBodyStyle as any]}\n contentContainerStyle={styles.bodyContent}\n showsVerticalScrollIndicator={false}\n >\n {content}\n </ScrollView>\n\n {/* Footer — footerRender takes precedence over `footer`. footerStyle\n is merged AFTER the built-in flex defaults so consumers can override\n alignment (e.g. justifyContent: 'space-between' for left-delete /\n right-actions layouts) without losing the borderTop / padding. */}\n {(footerRender != null || rest.footer != null) && (\n <View style={[\n styles.footer,\n {borderTopColor: borderColor},\n isSheet && {paddingBottom: 12 + insets.bottom},\n resolvedFooterStyle as any,\n ]}>\n {footerRender\n ? footerRender({close: () => { void hide(); }})\n : (rest.footer as React.ReactNode)}\n </View>\n )}\n </>}\n </Animated.View>\n </Animated.View>\n )}\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n overlay: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"center\",\n padding: 24,\n },\n sheetOverlay: {\n flex: 1,\n justifyContent: \"flex-end\",\n },\n sheetPanel: {\n width: \"100%\",\n maxWidth: \"100%\",\n maxHeight: \"90%\",\n borderWidth: 0,\n borderTopLeftRadius: 24,\n borderTopRightRadius: 24,\n borderBottomLeftRadius: 0,\n borderBottomRightRadius: 0,\n paddingTop: 10,\n },\n grabber: {\n width: 40,\n height: 5,\n borderRadius: 999,\n alignSelf: \"center\",\n marginBottom: 6,\n },\n panel: {\n // 20 == radii.xl (no numeric radii resolver on native — see report).\n borderRadius: 20,\n borderWidth: 1,\n minWidth: 250,\n maxWidth: \"90%\",\n maxHeight: \"80%\",\n overflow: \"hidden\",\n // Subtle elevation: low opacity, wide blur, minimal offset.\n elevation: 6,\n shadowColor: \"#000\",\n shadowOffset: {width: 0, height: 2},\n shadowOpacity: 0.15,\n shadowRadius: 20,\n },\n header: {\n flexDirection: \"row\",\n alignItems: \"center\",\n paddingHorizontal: 20,\n paddingVertical: 16,\n borderBottomWidth: 1,\n },\n body: {\n maxHeight: 400,\n },\n bodyContent: {\n padding: 20,\n },\n footer: {\n flexDirection: \"row\",\n justifyContent: \"flex-end\",\n paddingHorizontal: 20,\n paddingVertical: 12,\n borderTopWidth: 1,\n gap: 8,\n },\n});\n"],"names":["useKitsTheme","useSeverityColors","useSafeAreaInsets","useResolvedStyle","useWindowDimensions","jsx","Modal","jsxs","FadeIn","anim","FadeOut","scrimExitDuration","Pressable","StyleSheet","SlideInDown","ReduceMotion","ZoomIn","SlideOutDown","Easing","ZoomOut","runOnJS","Fragment","View","Icon","Text","ScrollView"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../../../src/components/overlay/Dialog/index.native.tsx"],"sourcesContent":["import React from \"react\";\nimport {Modal, Pressable, ScrollView, StyleSheet, View, useWindowDimensions} from \"react-native\";\nimport Animated, {Easing, FadeIn, FadeOut, ReduceMotion, runOnJS, SlideInDown, SlideOutDown, ZoomIn, ZoomOut} from \"react-native-reanimated\";\nimport {useSafeAreaInsets} from \"react-native-safe-area-context\";\nimport {Icon, Text} from \"../../../_compat\";\nimport type {IKitsDialogControlled} from \"@lmb-it/kitsconcerto-types\";\nimport {useKitsTheme} from \"../../../contexts/Theme\";\nimport {useSeverityColors} from \"../../../hooks/useSeverityColors\";\nimport {useResolvedStyle} from \"../../../hooks\";\nimport {overlayAnimations as anim, scrimExitDuration} from \"../../../animations\";\n\n/**\n * Keeps the RN Modal mounted through the exit animation. `visible` drives the\n * inner scrim + panel entering/exiting; the Modal itself stays mounted until\n * the panel's exit animation reports finished, then unmounts.\n *\n * Re-entrancy: a new `visible=true` during an exit re-renders the inner (which\n * re-enters), and the still-pending exit callback is ignored because\n * `visibleRef` is already back to `true` — so the Modal is never torn down\n * mid-reopen.\n */\nfunction useOverlayPresence(visible: boolean) {\n const [mounted, setMounted] = React.useState(visible);\n const visibleRef = React.useRef(visible);\n React.useEffect(() => {\n visibleRef.current = visible;\n if (visible) setMounted(true);\n }, [visible]);\n // Runs on the JS thread (dispatched via runOnJS from the exit worklet).\n const handleExitFinished = React.useCallback(() => {\n if (!visibleRef.current) setMounted(false);\n }, []);\n return {mounted, handleExitFinished};\n}\n\n/**\n * The scrim: it fades AND it is the thing you tap to dismiss, in one element.\n *\n * ⛔ THIS IS THE ACTIONSHEET'S SHAPE, NOT A THIRD PATTERN (§5). Two components in\n * this library already keep the backdrop a sibling of the panel:\n * `apps/mobile/src/ui/actionsheet/index.tsx:53` declares `Backdrop:\n * AnimatedPressable` — an animated, tappable element in its own right — and\n * `apps/mobile/src/ui/bottomsheet/index.tsx:124` passes `backdropComponent` to\n * `@gorhom/bottom-sheet`. The gorhom one is a prop-injection API belonging to a\n * sheet container that owns its own presentation; this Dialog owns its own RN\n * `Modal`, so there is nothing to inject into. The actionsheet's shape is the one\n * that fits, and it also collapses the separate `absoluteFill` Pressable this\n * component used to need into the scrim itself.\n *\n * ⚠️ BUILT WITH REANIMATED, NOT WITH THE ACTIONSHEET'S `createMotionAnimatedComponent`.\n * That helper wraps a different animation engine; this file's entering/exiting are\n * reanimated layout animations throughout, and mixing two engines in one overlay\n * would be inventing the third pattern §5 forbids.\n */\nconst AnimatedPressable = Animated.createAnimatedComponent(Pressable);\n\nexport default function KitsDialogControlled({state, onHide}: IKitsDialogControlled) {\n const {\n children,\n content: contentProp,\n onClose,\n asyncClose,\n type,\n icon,\n style,\n contentStyle,\n headerStyle,\n maskStyle,\n position = 'center',\n responsive = true,\n hideHeader,\n headerRender,\n footerRender,\n footerStyle,\n canClose,\n bodyStyle,\n closeIcon,\n // Native default true preserves historical tap-to-dismiss; web's\n // PrimeReact default is false — pass explicitly in shared code.\n dismissableMask = true,\n breakpoints,\n ...rest\n } = state;\n const {resolveToken, theme} = useKitsTheme();\n const severityColors = useSeverityColors(type || 'secondary');\n const colors = type ? severityColors : null;\n const insets = useSafeAreaInsets();\n const isSheet = position === 'bottom';\n\n const surfaceColor = resolveToken('surface-card');\n const textColor = resolveToken('text');\n const borderColor = colors?.border ?? resolveToken('border');\n const subtextColor = resolveToken('gray.500');\n const grabberColor = resolveToken('gray.300');\n // Scrim via the literal alpha overlay token → rgba(0,0,0,0.4) in both modes.\n const scrimColor = resolveToken('black-alpha-40');\n const brandLogo = type === 'brand' ? theme.config.logo : null;\n\n const resolvedStyle = useResolvedStyle(style || {});\n const resolvedContentStyle = useResolvedStyle(contentStyle || {});\n const resolvedHeaderStyle = useResolvedStyle(headerStyle || {});\n const resolvedMaskStyle = useResolvedStyle(maskStyle || {});\n const resolvedFooterStyle = useResolvedStyle(footerStyle || {});\n const resolvedBodyStyle = useResolvedStyle(bodyStyle || {});\n\n const {width: screenWidth} = useWindowDimensions();\n // Consumer `breakpoints` ({'960px': '75vw'}) mirrors the web prop: the\n // smallest max-width threshold >= the screen width wins; vw/% both map\n // to a percentage of the window width. Falls back to the responsive\n // default (50% tablets/desktop, 95% phones <=641px).\n const breakpointWidth = (() => {\n if (!breakpoints) return null;\n const matches = Object.entries(breakpoints)\n .map(([k, v]) => [parseFloat(k), v] as const)\n .filter(([px]) => !Number.isNaN(px) && screenWidth <= px)\n .sort(([a], [b]) => a - b);\n const value = matches[0]?.[1];\n if (value == null) return null;\n const num = parseFloat(value);\n return Number.isNaN(num) ? null : `${num}%`;\n })();\n const responsiveWidth = breakpointWidth ?? (screenWidth > 641 ? '50%' : '95%');\n const hasExplicitWidth = (resolvedStyle as any).width != null;\n\n const hide = async () => {\n // canClose gate — intercepts every close path (backdrop Pressable,\n // built-in X Pressable, RN Modal onRequestClose). When blocked,\n // onClose is suppressed and the dialog stays open.\n if (canClose === false || (typeof canClose === 'function' && !canClose())) {\n return;\n }\n if (asyncClose && typeof onClose === \"function\") {\n await onClose();\n } else {\n onClose?.();\n }\n onHide();\n };\n\n const {mounted, handleExitFinished} = useOverlayPresence(!!state.visible);\n if (!mounted) return null;\n\n const content = typeof children === \"function\" ? children(hide) : children;\n // Content-mode override (mirrors web): consumer node replaces the whole\n // header / body / footer template inside the panel.\n const contentMode = contentProp != null\n ? (typeof contentProp === \"function\" ? contentProp({hide}) : contentProp)\n : null;\n\n return (\n <Modal visible transparent animationType=\"none\" onRequestClose={hide}>\n {state.visible && (\n <View style={styles.root}>\n {/*\n ⛔ THE SCRIM IS A SIBLING OF THE PANEL, NOT ITS PARENT.\n It used to be the panel's parent, and opacity composes down a\n view tree — so the scrim's FadeIn/FadeOut multiplied the panel's\n opacity for the whole of both animations and the panel faded as\n well as travelled. `SlideInDown` animates `originY` only and\n never touched opacity; the fade was entirely inherited. Fixed\n 29 September 2026 — the structure is the fix, and no duration\n was tuned to make it look better (§12.5).\n\n ⚠️ IT IS ALSO THE DISMISS TARGET. The component used to draw a\n separate `absoluteFill` Pressable inside the scrim; scrim and\n target are one element now, which is the actionsheet's shape.\n */}\n <AnimatedPressable\n entering={FadeIn.duration(anim.scrim.enterDuration)}\n exiting={FadeOut.duration(scrimExitDuration(isSheet ? anim.sheet.exitDuration : anim.dialog.exitDuration))}\n style={[StyleSheet.absoluteFill, {backgroundColor: scrimColor}, resolvedMaskStyle as any]}\n onPress={dismissableMask ? hide : undefined}\n />\n {/*\n ⚠️ `pointerEvents=\"box-none\"` IS LOAD-BEARING. This view spans the\n screen so it can place the panel — centred, or pinned to the\n bottom — and it sits ON TOP of the scrim. Without `box-none` it\n would swallow every tap meant for the scrim and tap-to-dismiss\n would stop working. With it, the empty area passes taps through\n to the scrim beneath while the panel still receives its own.\n */}\n <View\n style={isSheet ? styles.sheetArrange : styles.centerArrange}\n pointerEvents=\"box-none\"\n >\n <Animated.View\n /* The sheet asks Reanimated to keep moving under iOS\n \"Reduce Motion\" — see `overlayAnimations.sheet`. Without\n it the panel appears in one frame and the only motion\n left is the scrim, which reads as a fade. The centred\n dialog keeps the system default. */\n entering={isSheet\n ? SlideInDown.springify().damping(anim.sheet.enter.damping).stiffness(anim.sheet.enter.stiffness).mass(anim.sheet.enter.mass ?? 1)\n .reduceMotion(anim.sheet.keepMotionWhenReduced ? ReduceMotion.Never : ReduceMotion.System)\n : ZoomIn.springify().damping(anim.dialog.enter.damping).stiffness(anim.dialog.enter.stiffness).mass(anim.dialog.enter.mass ?? 1)}\n exiting={(isSheet\n ? SlideOutDown.duration(anim.sheet.exitDuration).easing(Easing.in(Easing.ease))\n .reduceMotion(anim.sheet.keepMotionWhenReduced ? ReduceMotion.Never : ReduceMotion.System)\n : ZoomOut.duration(anim.dialog.exitDuration).easing(Easing.in(Easing.ease))\n ).withCallback((finished) => {\n 'worklet';\n if (finished) runOnJS(handleExitFinished)();\n })}\n style={[\n styles.panel,\n isSheet && styles.sheetPanel,\n {backgroundColor: surfaceColor, borderColor},\n // Explicit `breakpoints` win even when responsive=false (web parity)\n !isSheet && !hasExplicitWidth && (breakpoints != null || responsive) ? {width: responsiveWidth} : null,\n resolvedStyle as any,\n resolvedContentStyle as any,\n ]}\n >\n {contentMode != null ? contentMode : <>\n {/* Grabber (bottom-sheet) */}\n {isSheet && <View style={[styles.grabber, {backgroundColor: grabberColor}]}/>}\n\n {/* Severity accent strip */}\n {colors && !isSheet && (\n <View style={{height: 4, backgroundColor: colors.solid, borderTopLeftRadius: 20, borderTopRightRadius: 20}}/>\n )}\n\n {/* Custom header (headerRender) — fully replaces the built-in header\n View when provided. Wins over the default header even if `header`\n is also set. */}\n {!hideHeader && headerRender != null && headerRender({close: () => { void hide(); }})}\n\n {/* Header (default) — rendered when no headerRender and `header` is set. */}\n {!hideHeader && headerRender == null && rest.header != null && (\n <View style={[styles.header, {borderBottomColor: borderColor}, resolvedHeaderStyle as any]}>\n {/* Inline severity icon */}\n {(icon || brandLogo) && colors && (\n <View style={{\n width: 36,\n height: 36,\n borderRadius: 18,\n backgroundColor: colors.iconBg,\n alignItems: 'center',\n justifyContent: 'center',\n marginRight: 12,\n }}>\n {brandLogo ? brandLogo : typeof icon === 'string' ? (\n <Icon name={icon as never} size={'lg'} color={colors.iconFg}/>\n ) : icon}\n </View>\n )}\n <Text style={{fontSize: 18, fontWeight: \"700\", color: textColor, flex: 1}}>\n {rest.header as React.ReactNode}\n </Text>\n <Pressable onPress={hide} hitSlop={8}>\n {closeIcon ?? <Text style={{fontSize: 18, color: subtextColor}}>✕</Text>}\n </Pressable>\n </View>\n )}\n\n {/* Body — bodyStyle is applied AFTER the built-in maxHeight: 400,\n so consumers can lift the cap (`maxHeight: 600`) or unlock flex\n sizing (`minHeight: 0`) without losing the default behavior when\n bodyStyle is unset. */}\n <ScrollView\n style={[styles.body, resolvedBodyStyle as any]}\n contentContainerStyle={styles.bodyContent}\n showsVerticalScrollIndicator={false}\n >\n {content}\n </ScrollView>\n\n {/* Footer — footerRender takes precedence over `footer`. footerStyle\n is merged AFTER the built-in flex defaults so consumers can override\n alignment (e.g. justifyContent: 'space-between' for left-delete /\n right-actions layouts) without losing the borderTop / padding. */}\n {(footerRender != null || rest.footer != null) && (\n <View style={[\n styles.footer,\n {borderTopColor: borderColor},\n isSheet && {paddingBottom: 12 + insets.bottom},\n resolvedFooterStyle as any,\n ]}>\n {footerRender\n ? footerRender({close: () => { void hide(); }})\n : (rest.footer as React.ReactNode)}\n </View>\n )}\n </>}\n </Animated.View>\n </View>\n </View>\n )}\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n /**\n * The container. ⛔ IT IS NEVER ANIMATED AND CARRIES NO OPACITY — that is the\n * whole point of the change. It only exists to give the scrim and the panel a\n * shared parent so they can be siblings.\n */\n root: {\n flex: 1,\n },\n /**\n * Places the panel. ⚠️ The 24 padding moved here from the old `overlay` style,\n * and it had to: `position: absolute` resolves against a parent's PADDING box\n * in React Native, so a scrim absolutely filling a padded parent would have\n * stopped 24 short of every screen edge and left an undimmed frame. The scrim\n * now fills `root`, which has no padding, and the inset belongs to the layer\n * that positions the panel.\n */\n centerArrange: {\n ...StyleSheet.absoluteFillObject,\n justifyContent: \"center\",\n alignItems: \"center\",\n padding: 24,\n },\n sheetArrange: {\n ...StyleSheet.absoluteFillObject,\n justifyContent: \"flex-end\",\n },\n sheetPanel: {\n width: \"100%\",\n maxWidth: \"100%\",\n maxHeight: \"90%\",\n borderWidth: 0,\n borderTopLeftRadius: 24,\n borderTopRightRadius: 24,\n borderBottomLeftRadius: 0,\n borderBottomRightRadius: 0,\n paddingTop: 10,\n },\n grabber: {\n width: 40,\n height: 5,\n borderRadius: 999,\n alignSelf: \"center\",\n marginBottom: 6,\n },\n panel: {\n // 20 == radii.xl (no numeric radii resolver on native — see report).\n borderRadius: 20,\n borderWidth: 1,\n minWidth: 250,\n maxWidth: \"90%\",\n maxHeight: \"80%\",\n overflow: \"hidden\",\n // Subtle elevation: low opacity, wide blur, minimal offset.\n elevation: 6,\n shadowColor: \"#000\",\n shadowOffset: {width: 0, height: 2},\n shadowOpacity: 0.15,\n shadowRadius: 20,\n },\n header: {\n flexDirection: \"row\",\n alignItems: \"center\",\n paddingHorizontal: 20,\n paddingVertical: 16,\n borderBottomWidth: 1,\n },\n body: {\n maxHeight: 400,\n },\n bodyContent: {\n padding: 20,\n },\n footer: {\n flexDirection: \"row\",\n justifyContent: \"flex-end\",\n paddingHorizontal: 20,\n paddingVertical: 12,\n borderTopWidth: 1,\n gap: 8,\n },\n});\n"],"names":["Pressable","useKitsTheme","useSeverityColors","useSafeAreaInsets","useResolvedStyle","useWindowDimensions","Modal","jsxs","View","jsx","FadeIn","anim","FadeOut","scrimExitDuration","StyleSheet","SlideInDown","ReduceMotion","ZoomIn","SlideOutDown","Easing","ZoomOut","runOnJS","Fragment","Icon","Text","ScrollView"],"mappings":"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"}
@@ -1,12 +1,12 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import React from 'react';
3
- import { useWindowDimensions, Modal, Pressable, StyleSheet, View, ScrollView } from 'react-native';
4
- import Animated, { SlideOutDown, Easing, ReduceMotion, ZoomOut, runOnJS, SlideInDown, ZoomIn, FadeOut, FadeIn } from 'react-native-reanimated';
3
+ import { useWindowDimensions, Modal, View, StyleSheet, Pressable, ScrollView } from 'react-native';
4
+ import Animated, { FadeOut, FadeIn, SlideOutDown, Easing, ReduceMotion, ZoomOut, runOnJS, SlideInDown, ZoomIn } from 'react-native-reanimated';
5
5
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
6
6
  import { useSeverityColors } from '../../../hooks/useSeverityColors.js';
7
7
  import '../../../contexts/DialogContext.js';
8
8
  import useResolvedStyle from '../../../hooks/useResolvedStyle.js';
9
- import { overlayAnimations, scrimExitDuration } from '../../../animations/index.js';
9
+ import { scrimExitDuration, overlayAnimations } from '../../../animations/index.js';
10
10
  import { useKitsTheme } from '../../../contexts/Theme/KitsThemeProvider.js';
11
11
  import { Icon } from '../../../primitives/Icon/index.js';
12
12
  import Text from '../../../primitives/Text/index.js';
@@ -23,6 +23,7 @@ function useOverlayPresence(visible) {
23
23
  }, []);
24
24
  return { mounted, handleExitFinished };
25
25
  }
26
+ const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
26
27
  function KitsDialogControlled({ state, onHide }) {
27
28
  const {
28
29
  children,
@@ -94,15 +95,22 @@ function KitsDialogControlled({ state, onHide }) {
94
95
  if (!mounted) return null;
95
96
  const content = typeof children === "function" ? children(hide) : children;
96
97
  const contentMode = contentProp != null ? typeof contentProp === "function" ? contentProp({ hide }) : contentProp : null;
97
- return /* @__PURE__ */ jsx(Modal, { visible: true, transparent: true, animationType: "none", onRequestClose: hide, children: state.visible && /* @__PURE__ */ jsxs(
98
- Animated.View,
99
- {
100
- entering: FadeIn.duration(overlayAnimations.scrim.enterDuration),
101
- exiting: FadeOut.duration(scrimExitDuration(isSheet ? overlayAnimations.sheet.exitDuration : overlayAnimations.dialog.exitDuration)),
102
- style: [isSheet ? styles.sheetOverlay : styles.overlay, { backgroundColor: scrimColor }, resolvedMaskStyle],
103
- children: [
104
- /* @__PURE__ */ jsx(Pressable, { style: StyleSheet.absoluteFill, onPress: dismissableMask ? hide : void 0 }),
105
- /* @__PURE__ */ jsx(
98
+ return /* @__PURE__ */ jsx(Modal, { visible: true, transparent: true, animationType: "none", onRequestClose: hide, children: state.visible && /* @__PURE__ */ jsxs(View, { style: styles.root, children: [
99
+ /* @__PURE__ */ jsx(
100
+ AnimatedPressable,
101
+ {
102
+ entering: FadeIn.duration(overlayAnimations.scrim.enterDuration),
103
+ exiting: FadeOut.duration(scrimExitDuration(isSheet ? overlayAnimations.sheet.exitDuration : overlayAnimations.dialog.exitDuration)),
104
+ style: [StyleSheet.absoluteFill, { backgroundColor: scrimColor }, resolvedMaskStyle],
105
+ onPress: dismissableMask ? hide : void 0
106
+ }
107
+ ),
108
+ /* @__PURE__ */ jsx(
109
+ View,
110
+ {
111
+ style: isSheet ? styles.sheetArrange : styles.centerArrange,
112
+ pointerEvents: "box-none",
113
+ children: /* @__PURE__ */ jsx(
106
114
  Animated.View,
107
115
  {
108
116
  entering: isSheet ? SlideInDown.springify().damping(overlayAnimations.sheet.enter.damping).stiffness(overlayAnimations.sheet.enter.stiffness).mass(overlayAnimations.sheet.enter.mass).reduceMotion(ReduceMotion.Never ) : ZoomIn.springify().damping(overlayAnimations.dialog.enter.damping).stiffness(overlayAnimations.dialog.enter.stiffness).mass(overlayAnimations.dialog.enter.mass),
@@ -158,19 +166,35 @@ function KitsDialogControlled({ state, onHide }) {
158
166
  ] })
159
167
  }
160
168
  )
161
- ]
162
- }
163
- ) });
169
+ }
170
+ )
171
+ ] }) });
164
172
  }
165
173
  const styles = StyleSheet.create({
166
- overlay: {
167
- flex: 1,
174
+ /**
175
+ * The container. ⛔ IT IS NEVER ANIMATED AND CARRIES NO OPACITY — that is the
176
+ * whole point of the change. It only exists to give the scrim and the panel a
177
+ * shared parent so they can be siblings.
178
+ */
179
+ root: {
180
+ flex: 1
181
+ },
182
+ /**
183
+ * Places the panel. ⚠️ The 24 padding moved here from the old `overlay` style,
184
+ * and it had to: `position: absolute` resolves against a parent's PADDING box
185
+ * in React Native, so a scrim absolutely filling a padded parent would have
186
+ * stopped 24 short of every screen edge and left an undimmed frame. The scrim
187
+ * now fills `root`, which has no padding, and the inset belongs to the layer
188
+ * that positions the panel.
189
+ */
190
+ centerArrange: {
191
+ ...StyleSheet.absoluteFillObject,
168
192
  justifyContent: "center",
169
193
  alignItems: "center",
170
194
  padding: 24
171
195
  },
172
- sheetOverlay: {
173
- flex: 1,
196
+ sheetArrange: {
197
+ ...StyleSheet.absoluteFillObject,
174
198
  justifyContent: "flex-end"
175
199
  },
176
200
  sheetPanel: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../../src/components/overlay/Dialog/index.native.tsx"],"sourcesContent":["import React from \"react\";\nimport {Modal, Pressable, ScrollView, StyleSheet, View, useWindowDimensions} from \"react-native\";\nimport Animated, {Easing, FadeIn, FadeOut, ReduceMotion, runOnJS, SlideInDown, SlideOutDown, ZoomIn, ZoomOut} from \"react-native-reanimated\";\nimport {useSafeAreaInsets} from \"react-native-safe-area-context\";\nimport {Icon, Text} from \"../../../_compat\";\nimport type {IKitsDialogControlled} from \"@lmb-it/kitsconcerto-types\";\nimport {useKitsTheme} from \"../../../contexts/Theme\";\nimport {useSeverityColors} from \"../../../hooks/useSeverityColors\";\nimport {useResolvedStyle} from \"../../../hooks\";\nimport {overlayAnimations as anim, scrimExitDuration} from \"../../../animations\";\n\n/**\n * Keeps the RN Modal mounted through the exit animation. `visible` drives the\n * inner scrim + panel entering/exiting; the Modal itself stays mounted until\n * the panel's exit animation reports finished, then unmounts.\n *\n * Re-entrancy: a new `visible=true` during an exit re-renders the inner (which\n * re-enters), and the still-pending exit callback is ignored because\n * `visibleRef` is already back to `true` — so the Modal is never torn down\n * mid-reopen.\n */\nfunction useOverlayPresence(visible: boolean) {\n const [mounted, setMounted] = React.useState(visible);\n const visibleRef = React.useRef(visible);\n React.useEffect(() => {\n visibleRef.current = visible;\n if (visible) setMounted(true);\n }, [visible]);\n // Runs on the JS thread (dispatched via runOnJS from the exit worklet).\n const handleExitFinished = React.useCallback(() => {\n if (!visibleRef.current) setMounted(false);\n }, []);\n return {mounted, handleExitFinished};\n}\n\nexport default function KitsDialogControlled({state, onHide}: IKitsDialogControlled) {\n const {\n children,\n content: contentProp,\n onClose,\n asyncClose,\n type,\n icon,\n style,\n contentStyle,\n headerStyle,\n maskStyle,\n position = 'center',\n responsive = true,\n hideHeader,\n headerRender,\n footerRender,\n footerStyle,\n canClose,\n bodyStyle,\n closeIcon,\n // Native default true preserves historical tap-to-dismiss; web's\n // PrimeReact default is false — pass explicitly in shared code.\n dismissableMask = true,\n breakpoints,\n ...rest\n } = state;\n const {resolveToken, theme} = useKitsTheme();\n const severityColors = useSeverityColors(type || 'secondary');\n const colors = type ? severityColors : null;\n const insets = useSafeAreaInsets();\n const isSheet = position === 'bottom';\n\n const surfaceColor = resolveToken('surface-card');\n const textColor = resolveToken('text');\n const borderColor = colors?.border ?? resolveToken('border');\n const subtextColor = resolveToken('gray.500');\n const grabberColor = resolveToken('gray.300');\n // Scrim via the literal alpha overlay token → rgba(0,0,0,0.4) in both modes.\n const scrimColor = resolveToken('black-alpha-40');\n const brandLogo = type === 'brand' ? theme.config.logo : null;\n\n const resolvedStyle = useResolvedStyle(style || {});\n const resolvedContentStyle = useResolvedStyle(contentStyle || {});\n const resolvedHeaderStyle = useResolvedStyle(headerStyle || {});\n const resolvedMaskStyle = useResolvedStyle(maskStyle || {});\n const resolvedFooterStyle = useResolvedStyle(footerStyle || {});\n const resolvedBodyStyle = useResolvedStyle(bodyStyle || {});\n\n const {width: screenWidth} = useWindowDimensions();\n // Consumer `breakpoints` ({'960px': '75vw'}) mirrors the web prop: the\n // smallest max-width threshold >= the screen width wins; vw/% both map\n // to a percentage of the window width. Falls back to the responsive\n // default (50% tablets/desktop, 95% phones <=641px).\n const breakpointWidth = (() => {\n if (!breakpoints) return null;\n const matches = Object.entries(breakpoints)\n .map(([k, v]) => [parseFloat(k), v] as const)\n .filter(([px]) => !Number.isNaN(px) && screenWidth <= px)\n .sort(([a], [b]) => a - b);\n const value = matches[0]?.[1];\n if (value == null) return null;\n const num = parseFloat(value);\n return Number.isNaN(num) ? null : `${num}%`;\n })();\n const responsiveWidth = breakpointWidth ?? (screenWidth > 641 ? '50%' : '95%');\n const hasExplicitWidth = (resolvedStyle as any).width != null;\n\n const hide = async () => {\n // canClose gate — intercepts every close path (backdrop Pressable,\n // built-in X Pressable, RN Modal onRequestClose). When blocked,\n // onClose is suppressed and the dialog stays open.\n if (canClose === false || (typeof canClose === 'function' && !canClose())) {\n return;\n }\n if (asyncClose && typeof onClose === \"function\") {\n await onClose();\n } else {\n onClose?.();\n }\n onHide();\n };\n\n const {mounted, handleExitFinished} = useOverlayPresence(!!state.visible);\n if (!mounted) return null;\n\n const content = typeof children === \"function\" ? children(hide) : children;\n // Content-mode override (mirrors web): consumer node replaces the whole\n // header / body / footer template inside the panel.\n const contentMode = contentProp != null\n ? (typeof contentProp === \"function\" ? contentProp({hide}) : contentProp)\n : null;\n\n return (\n <Modal visible transparent animationType=\"none\" onRequestClose={hide}>\n {state.visible && (\n <Animated.View\n entering={FadeIn.duration(anim.scrim.enterDuration)}\n /* The panel is a CHILD of this view, so this fade must not\n finish first — see `scrimExitDuration`. */\n exiting={FadeOut.duration(scrimExitDuration(isSheet ? anim.sheet.exitDuration : anim.dialog.exitDuration))}\n style={[isSheet ? styles.sheetOverlay : styles.overlay, {backgroundColor: scrimColor}, resolvedMaskStyle as any]}\n >\n <Pressable style={StyleSheet.absoluteFill} onPress={dismissableMask ? hide : undefined}/>\n <Animated.View\n /* The sheet asks Reanimated to keep moving under iOS\n \"Reduce Motion\" — see `overlayAnimations.sheet`. Without\n it the panel appears in one frame and the only motion\n left is the scrim, which reads as a fade. The centred\n dialog keeps the system default. */\n entering={isSheet\n ? SlideInDown.springify().damping(anim.sheet.enter.damping).stiffness(anim.sheet.enter.stiffness).mass(anim.sheet.enter.mass ?? 1)\n .reduceMotion(anim.sheet.keepMotionWhenReduced ? ReduceMotion.Never : ReduceMotion.System)\n : ZoomIn.springify().damping(anim.dialog.enter.damping).stiffness(anim.dialog.enter.stiffness).mass(anim.dialog.enter.mass ?? 1)}\n exiting={(isSheet\n ? SlideOutDown.duration(anim.sheet.exitDuration).easing(Easing.in(Easing.ease))\n .reduceMotion(anim.sheet.keepMotionWhenReduced ? ReduceMotion.Never : ReduceMotion.System)\n : ZoomOut.duration(anim.dialog.exitDuration).easing(Easing.in(Easing.ease))\n ).withCallback((finished) => {\n 'worklet';\n if (finished) runOnJS(handleExitFinished)();\n })}\n style={[\n styles.panel,\n isSheet && styles.sheetPanel,\n {backgroundColor: surfaceColor, borderColor},\n // Explicit `breakpoints` win even when responsive=false (web parity)\n !isSheet && !hasExplicitWidth && (breakpoints != null || responsive) ? {width: responsiveWidth} : null,\n resolvedStyle as any,\n resolvedContentStyle as any,\n ]}\n >\n {contentMode != null ? contentMode : <>\n {/* Grabber (bottom-sheet) */}\n {isSheet && <View style={[styles.grabber, {backgroundColor: grabberColor}]}/>}\n\n {/* Severity accent strip */}\n {colors && !isSheet && (\n <View style={{height: 4, backgroundColor: colors.solid, borderTopLeftRadius: 20, borderTopRightRadius: 20}}/>\n )}\n\n {/* Custom header (headerRender) — fully replaces the built-in header\n View when provided. Wins over the default header even if `header`\n is also set. */}\n {!hideHeader && headerRender != null && headerRender({close: () => { void hide(); }})}\n\n {/* Header (default) — rendered when no headerRender and `header` is set. */}\n {!hideHeader && headerRender == null && rest.header != null && (\n <View style={[styles.header, {borderBottomColor: borderColor}, resolvedHeaderStyle as any]}>\n {/* Inline severity icon */}\n {(icon || brandLogo) && colors && (\n <View style={{\n width: 36,\n height: 36,\n borderRadius: 18,\n backgroundColor: colors.iconBg,\n alignItems: 'center',\n justifyContent: 'center',\n marginRight: 12,\n }}>\n {brandLogo ? brandLogo : typeof icon === 'string' ? (\n <Icon name={icon as never} size={'lg'} color={colors.iconFg}/>\n ) : icon}\n </View>\n )}\n <Text style={{fontSize: 18, fontWeight: \"700\", color: textColor, flex: 1}}>\n {rest.header as React.ReactNode}\n </Text>\n <Pressable onPress={hide} hitSlop={8}>\n {closeIcon ?? <Text style={{fontSize: 18, color: subtextColor}}>✕</Text>}\n </Pressable>\n </View>\n )}\n\n {/* Body — bodyStyle is applied AFTER the built-in maxHeight: 400,\n so consumers can lift the cap (`maxHeight: 600`) or unlock flex\n sizing (`minHeight: 0`) without losing the default behavior when\n bodyStyle is unset. */}\n <ScrollView\n style={[styles.body, resolvedBodyStyle as any]}\n contentContainerStyle={styles.bodyContent}\n showsVerticalScrollIndicator={false}\n >\n {content}\n </ScrollView>\n\n {/* Footer — footerRender takes precedence over `footer`. footerStyle\n is merged AFTER the built-in flex defaults so consumers can override\n alignment (e.g. justifyContent: 'space-between' for left-delete /\n right-actions layouts) without losing the borderTop / padding. */}\n {(footerRender != null || rest.footer != null) && (\n <View style={[\n styles.footer,\n {borderTopColor: borderColor},\n isSheet && {paddingBottom: 12 + insets.bottom},\n resolvedFooterStyle as any,\n ]}>\n {footerRender\n ? footerRender({close: () => { void hide(); }})\n : (rest.footer as React.ReactNode)}\n </View>\n )}\n </>}\n </Animated.View>\n </Animated.View>\n )}\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n overlay: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"center\",\n padding: 24,\n },\n sheetOverlay: {\n flex: 1,\n justifyContent: \"flex-end\",\n },\n sheetPanel: {\n width: \"100%\",\n maxWidth: \"100%\",\n maxHeight: \"90%\",\n borderWidth: 0,\n borderTopLeftRadius: 24,\n borderTopRightRadius: 24,\n borderBottomLeftRadius: 0,\n borderBottomRightRadius: 0,\n paddingTop: 10,\n },\n grabber: {\n width: 40,\n height: 5,\n borderRadius: 999,\n alignSelf: \"center\",\n marginBottom: 6,\n },\n panel: {\n // 20 == radii.xl (no numeric radii resolver on native — see report).\n borderRadius: 20,\n borderWidth: 1,\n minWidth: 250,\n maxWidth: \"90%\",\n maxHeight: \"80%\",\n overflow: \"hidden\",\n // Subtle elevation: low opacity, wide blur, minimal offset.\n elevation: 6,\n shadowColor: \"#000\",\n shadowOffset: {width: 0, height: 2},\n shadowOpacity: 0.15,\n shadowRadius: 20,\n },\n header: {\n flexDirection: \"row\",\n alignItems: \"center\",\n paddingHorizontal: 20,\n paddingVertical: 16,\n borderBottomWidth: 1,\n },\n body: {\n maxHeight: 400,\n },\n bodyContent: {\n padding: 20,\n },\n footer: {\n flexDirection: \"row\",\n justifyContent: \"flex-end\",\n paddingHorizontal: 20,\n paddingVertical: 12,\n borderTopWidth: 1,\n gap: 8,\n },\n});\n"],"names":["anim"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../../../src/components/overlay/Dialog/index.native.tsx"],"sourcesContent":["import React from \"react\";\nimport {Modal, Pressable, ScrollView, StyleSheet, View, useWindowDimensions} from \"react-native\";\nimport Animated, {Easing, FadeIn, FadeOut, ReduceMotion, runOnJS, SlideInDown, SlideOutDown, ZoomIn, ZoomOut} from \"react-native-reanimated\";\nimport {useSafeAreaInsets} from \"react-native-safe-area-context\";\nimport {Icon, Text} from \"../../../_compat\";\nimport type {IKitsDialogControlled} from \"@lmb-it/kitsconcerto-types\";\nimport {useKitsTheme} from \"../../../contexts/Theme\";\nimport {useSeverityColors} from \"../../../hooks/useSeverityColors\";\nimport {useResolvedStyle} from \"../../../hooks\";\nimport {overlayAnimations as anim, scrimExitDuration} from \"../../../animations\";\n\n/**\n * Keeps the RN Modal mounted through the exit animation. `visible` drives the\n * inner scrim + panel entering/exiting; the Modal itself stays mounted until\n * the panel's exit animation reports finished, then unmounts.\n *\n * Re-entrancy: a new `visible=true` during an exit re-renders the inner (which\n * re-enters), and the still-pending exit callback is ignored because\n * `visibleRef` is already back to `true` — so the Modal is never torn down\n * mid-reopen.\n */\nfunction useOverlayPresence(visible: boolean) {\n const [mounted, setMounted] = React.useState(visible);\n const visibleRef = React.useRef(visible);\n React.useEffect(() => {\n visibleRef.current = visible;\n if (visible) setMounted(true);\n }, [visible]);\n // Runs on the JS thread (dispatched via runOnJS from the exit worklet).\n const handleExitFinished = React.useCallback(() => {\n if (!visibleRef.current) setMounted(false);\n }, []);\n return {mounted, handleExitFinished};\n}\n\n/**\n * The scrim: it fades AND it is the thing you tap to dismiss, in one element.\n *\n * ⛔ THIS IS THE ACTIONSHEET'S SHAPE, NOT A THIRD PATTERN (§5). Two components in\n * this library already keep the backdrop a sibling of the panel:\n * `apps/mobile/src/ui/actionsheet/index.tsx:53` declares `Backdrop:\n * AnimatedPressable` — an animated, tappable element in its own right — and\n * `apps/mobile/src/ui/bottomsheet/index.tsx:124` passes `backdropComponent` to\n * `@gorhom/bottom-sheet`. The gorhom one is a prop-injection API belonging to a\n * sheet container that owns its own presentation; this Dialog owns its own RN\n * `Modal`, so there is nothing to inject into. The actionsheet's shape is the one\n * that fits, and it also collapses the separate `absoluteFill` Pressable this\n * component used to need into the scrim itself.\n *\n * ⚠️ BUILT WITH REANIMATED, NOT WITH THE ACTIONSHEET'S `createMotionAnimatedComponent`.\n * That helper wraps a different animation engine; this file's entering/exiting are\n * reanimated layout animations throughout, and mixing two engines in one overlay\n * would be inventing the third pattern §5 forbids.\n */\nconst AnimatedPressable = Animated.createAnimatedComponent(Pressable);\n\nexport default function KitsDialogControlled({state, onHide}: IKitsDialogControlled) {\n const {\n children,\n content: contentProp,\n onClose,\n asyncClose,\n type,\n icon,\n style,\n contentStyle,\n headerStyle,\n maskStyle,\n position = 'center',\n responsive = true,\n hideHeader,\n headerRender,\n footerRender,\n footerStyle,\n canClose,\n bodyStyle,\n closeIcon,\n // Native default true preserves historical tap-to-dismiss; web's\n // PrimeReact default is false — pass explicitly in shared code.\n dismissableMask = true,\n breakpoints,\n ...rest\n } = state;\n const {resolveToken, theme} = useKitsTheme();\n const severityColors = useSeverityColors(type || 'secondary');\n const colors = type ? severityColors : null;\n const insets = useSafeAreaInsets();\n const isSheet = position === 'bottom';\n\n const surfaceColor = resolveToken('surface-card');\n const textColor = resolveToken('text');\n const borderColor = colors?.border ?? resolveToken('border');\n const subtextColor = resolveToken('gray.500');\n const grabberColor = resolveToken('gray.300');\n // Scrim via the literal alpha overlay token → rgba(0,0,0,0.4) in both modes.\n const scrimColor = resolveToken('black-alpha-40');\n const brandLogo = type === 'brand' ? theme.config.logo : null;\n\n const resolvedStyle = useResolvedStyle(style || {});\n const resolvedContentStyle = useResolvedStyle(contentStyle || {});\n const resolvedHeaderStyle = useResolvedStyle(headerStyle || {});\n const resolvedMaskStyle = useResolvedStyle(maskStyle || {});\n const resolvedFooterStyle = useResolvedStyle(footerStyle || {});\n const resolvedBodyStyle = useResolvedStyle(bodyStyle || {});\n\n const {width: screenWidth} = useWindowDimensions();\n // Consumer `breakpoints` ({'960px': '75vw'}) mirrors the web prop: the\n // smallest max-width threshold >= the screen width wins; vw/% both map\n // to a percentage of the window width. Falls back to the responsive\n // default (50% tablets/desktop, 95% phones <=641px).\n const breakpointWidth = (() => {\n if (!breakpoints) return null;\n const matches = Object.entries(breakpoints)\n .map(([k, v]) => [parseFloat(k), v] as const)\n .filter(([px]) => !Number.isNaN(px) && screenWidth <= px)\n .sort(([a], [b]) => a - b);\n const value = matches[0]?.[1];\n if (value == null) return null;\n const num = parseFloat(value);\n return Number.isNaN(num) ? null : `${num}%`;\n })();\n const responsiveWidth = breakpointWidth ?? (screenWidth > 641 ? '50%' : '95%');\n const hasExplicitWidth = (resolvedStyle as any).width != null;\n\n const hide = async () => {\n // canClose gate — intercepts every close path (backdrop Pressable,\n // built-in X Pressable, RN Modal onRequestClose). When blocked,\n // onClose is suppressed and the dialog stays open.\n if (canClose === false || (typeof canClose === 'function' && !canClose())) {\n return;\n }\n if (asyncClose && typeof onClose === \"function\") {\n await onClose();\n } else {\n onClose?.();\n }\n onHide();\n };\n\n const {mounted, handleExitFinished} = useOverlayPresence(!!state.visible);\n if (!mounted) return null;\n\n const content = typeof children === \"function\" ? children(hide) : children;\n // Content-mode override (mirrors web): consumer node replaces the whole\n // header / body / footer template inside the panel.\n const contentMode = contentProp != null\n ? (typeof contentProp === \"function\" ? contentProp({hide}) : contentProp)\n : null;\n\n return (\n <Modal visible transparent animationType=\"none\" onRequestClose={hide}>\n {state.visible && (\n <View style={styles.root}>\n {/*\n ⛔ THE SCRIM IS A SIBLING OF THE PANEL, NOT ITS PARENT.\n It used to be the panel's parent, and opacity composes down a\n view tree — so the scrim's FadeIn/FadeOut multiplied the panel's\n opacity for the whole of both animations and the panel faded as\n well as travelled. `SlideInDown` animates `originY` only and\n never touched opacity; the fade was entirely inherited. Fixed\n 29 September 2026 — the structure is the fix, and no duration\n was tuned to make it look better (§12.5).\n\n ⚠️ IT IS ALSO THE DISMISS TARGET. The component used to draw a\n separate `absoluteFill` Pressable inside the scrim; scrim and\n target are one element now, which is the actionsheet's shape.\n */}\n <AnimatedPressable\n entering={FadeIn.duration(anim.scrim.enterDuration)}\n exiting={FadeOut.duration(scrimExitDuration(isSheet ? anim.sheet.exitDuration : anim.dialog.exitDuration))}\n style={[StyleSheet.absoluteFill, {backgroundColor: scrimColor}, resolvedMaskStyle as any]}\n onPress={dismissableMask ? hide : undefined}\n />\n {/*\n ⚠️ `pointerEvents=\"box-none\"` IS LOAD-BEARING. This view spans the\n screen so it can place the panel — centred, or pinned to the\n bottom — and it sits ON TOP of the scrim. Without `box-none` it\n would swallow every tap meant for the scrim and tap-to-dismiss\n would stop working. With it, the empty area passes taps through\n to the scrim beneath while the panel still receives its own.\n */}\n <View\n style={isSheet ? styles.sheetArrange : styles.centerArrange}\n pointerEvents=\"box-none\"\n >\n <Animated.View\n /* The sheet asks Reanimated to keep moving under iOS\n \"Reduce Motion\" — see `overlayAnimations.sheet`. Without\n it the panel appears in one frame and the only motion\n left is the scrim, which reads as a fade. The centred\n dialog keeps the system default. */\n entering={isSheet\n ? SlideInDown.springify().damping(anim.sheet.enter.damping).stiffness(anim.sheet.enter.stiffness).mass(anim.sheet.enter.mass ?? 1)\n .reduceMotion(anim.sheet.keepMotionWhenReduced ? ReduceMotion.Never : ReduceMotion.System)\n : ZoomIn.springify().damping(anim.dialog.enter.damping).stiffness(anim.dialog.enter.stiffness).mass(anim.dialog.enter.mass ?? 1)}\n exiting={(isSheet\n ? SlideOutDown.duration(anim.sheet.exitDuration).easing(Easing.in(Easing.ease))\n .reduceMotion(anim.sheet.keepMotionWhenReduced ? ReduceMotion.Never : ReduceMotion.System)\n : ZoomOut.duration(anim.dialog.exitDuration).easing(Easing.in(Easing.ease))\n ).withCallback((finished) => {\n 'worklet';\n if (finished) runOnJS(handleExitFinished)();\n })}\n style={[\n styles.panel,\n isSheet && styles.sheetPanel,\n {backgroundColor: surfaceColor, borderColor},\n // Explicit `breakpoints` win even when responsive=false (web parity)\n !isSheet && !hasExplicitWidth && (breakpoints != null || responsive) ? {width: responsiveWidth} : null,\n resolvedStyle as any,\n resolvedContentStyle as any,\n ]}\n >\n {contentMode != null ? contentMode : <>\n {/* Grabber (bottom-sheet) */}\n {isSheet && <View style={[styles.grabber, {backgroundColor: grabberColor}]}/>}\n\n {/* Severity accent strip */}\n {colors && !isSheet && (\n <View style={{height: 4, backgroundColor: colors.solid, borderTopLeftRadius: 20, borderTopRightRadius: 20}}/>\n )}\n\n {/* Custom header (headerRender) — fully replaces the built-in header\n View when provided. Wins over the default header even if `header`\n is also set. */}\n {!hideHeader && headerRender != null && headerRender({close: () => { void hide(); }})}\n\n {/* Header (default) — rendered when no headerRender and `header` is set. */}\n {!hideHeader && headerRender == null && rest.header != null && (\n <View style={[styles.header, {borderBottomColor: borderColor}, resolvedHeaderStyle as any]}>\n {/* Inline severity icon */}\n {(icon || brandLogo) && colors && (\n <View style={{\n width: 36,\n height: 36,\n borderRadius: 18,\n backgroundColor: colors.iconBg,\n alignItems: 'center',\n justifyContent: 'center',\n marginRight: 12,\n }}>\n {brandLogo ? brandLogo : typeof icon === 'string' ? (\n <Icon name={icon as never} size={'lg'} color={colors.iconFg}/>\n ) : icon}\n </View>\n )}\n <Text style={{fontSize: 18, fontWeight: \"700\", color: textColor, flex: 1}}>\n {rest.header as React.ReactNode}\n </Text>\n <Pressable onPress={hide} hitSlop={8}>\n {closeIcon ?? <Text style={{fontSize: 18, color: subtextColor}}>✕</Text>}\n </Pressable>\n </View>\n )}\n\n {/* Body — bodyStyle is applied AFTER the built-in maxHeight: 400,\n so consumers can lift the cap (`maxHeight: 600`) or unlock flex\n sizing (`minHeight: 0`) without losing the default behavior when\n bodyStyle is unset. */}\n <ScrollView\n style={[styles.body, resolvedBodyStyle as any]}\n contentContainerStyle={styles.bodyContent}\n showsVerticalScrollIndicator={false}\n >\n {content}\n </ScrollView>\n\n {/* Footer — footerRender takes precedence over `footer`. footerStyle\n is merged AFTER the built-in flex defaults so consumers can override\n alignment (e.g. justifyContent: 'space-between' for left-delete /\n right-actions layouts) without losing the borderTop / padding. */}\n {(footerRender != null || rest.footer != null) && (\n <View style={[\n styles.footer,\n {borderTopColor: borderColor},\n isSheet && {paddingBottom: 12 + insets.bottom},\n resolvedFooterStyle as any,\n ]}>\n {footerRender\n ? footerRender({close: () => { void hide(); }})\n : (rest.footer as React.ReactNode)}\n </View>\n )}\n </>}\n </Animated.View>\n </View>\n </View>\n )}\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n /**\n * The container. ⛔ IT IS NEVER ANIMATED AND CARRIES NO OPACITY — that is the\n * whole point of the change. It only exists to give the scrim and the panel a\n * shared parent so they can be siblings.\n */\n root: {\n flex: 1,\n },\n /**\n * Places the panel. ⚠️ The 24 padding moved here from the old `overlay` style,\n * and it had to: `position: absolute` resolves against a parent's PADDING box\n * in React Native, so a scrim absolutely filling a padded parent would have\n * stopped 24 short of every screen edge and left an undimmed frame. The scrim\n * now fills `root`, which has no padding, and the inset belongs to the layer\n * that positions the panel.\n */\n centerArrange: {\n ...StyleSheet.absoluteFillObject,\n justifyContent: \"center\",\n alignItems: \"center\",\n padding: 24,\n },\n sheetArrange: {\n ...StyleSheet.absoluteFillObject,\n justifyContent: \"flex-end\",\n },\n sheetPanel: {\n width: \"100%\",\n maxWidth: \"100%\",\n maxHeight: \"90%\",\n borderWidth: 0,\n borderTopLeftRadius: 24,\n borderTopRightRadius: 24,\n borderBottomLeftRadius: 0,\n borderBottomRightRadius: 0,\n paddingTop: 10,\n },\n grabber: {\n width: 40,\n height: 5,\n borderRadius: 999,\n alignSelf: \"center\",\n marginBottom: 6,\n },\n panel: {\n // 20 == radii.xl (no numeric radii resolver on native — see report).\n borderRadius: 20,\n borderWidth: 1,\n minWidth: 250,\n maxWidth: \"90%\",\n maxHeight: \"80%\",\n overflow: \"hidden\",\n // Subtle elevation: low opacity, wide blur, minimal offset.\n elevation: 6,\n shadowColor: \"#000\",\n shadowOffset: {width: 0, height: 2},\n shadowOpacity: 0.15,\n shadowRadius: 20,\n },\n header: {\n flexDirection: \"row\",\n alignItems: \"center\",\n paddingHorizontal: 20,\n paddingVertical: 16,\n borderBottomWidth: 1,\n },\n body: {\n maxHeight: 400,\n },\n bodyContent: {\n padding: 20,\n },\n footer: {\n flexDirection: \"row\",\n justifyContent: \"flex-end\",\n paddingHorizontal: 20,\n paddingVertical: 12,\n borderTopWidth: 1,\n gap: 8,\n },\n});\n"],"names":["anim"],"mappings":"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"}
@@ -65,6 +65,7 @@ require('../../../packages/types/src/Theme/alphaColors.cjs');
65
65
  require('../../../apps/mobile/src/Factory/helpers/cssVarMap.cjs');
66
66
  require('../../../apps/mobile/src/Factory/DimensionsContext.cjs');
67
67
  var useKeyboardHeight = require('../../../apps/mobile/src/Factory/helpers/useKeyboardHeight.cjs');
68
+ var readerEdge = require('../../../apps/mobile/src/Factory/helpers/readerEdge.cjs');
68
69
  require('i18next');
69
70
  require('react-i18next');
70
71
  require('../../../apps/mobile/src/Core/AutoComplete/index.cjs');
@@ -96,6 +97,7 @@ const SHEET_MIN_HEIGHT = 240;
96
97
  const SelectPopupOverlay = ({ visible, onClose, title, children }) => {
97
98
  const { resolveToken } = KitsThemeProvider_native.useKitsTheme();
98
99
  const { isRTL } = locale.useLanguage();
100
+ const edge = readerEdge.readerEdge(isRTL);
99
101
  const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
100
102
  const { height: windowHeight } = reactNative.useWindowDimensions();
101
103
  const headingFont = useThemedFont.default("heading");
@@ -135,9 +137,17 @@ const SelectPopupOverlay = ({ visible, onClose, title, children }) => {
135
137
  style: [
136
138
  styles.header,
137
139
  { borderBottomColor: borderColor },
138
- // The header mirrors with the reader, like every
139
- // other row this library draws.
140
- isRTL ? styles.headerRtl : styles.headerLtr
140
+ /* ⛔ THE PHYSICAL EDGE IS COMPUTED, NEVER NAMED.
141
+ React Native mirrors `flexDirection: 'row'`
142
+ and `textAlign` when the process is RTL — the
143
+ App calls `I18nManager.forceRTL` — so naming
144
+ the RTL edge for an RTL reader asks for it
145
+ twice and lands on the LTR one. That is why
146
+ this header drew its title LEFT and its ✕
147
+ RIGHT in Arabic while the option rows below
148
+ it, which already went through `readerEdge`,
149
+ were correct. See `readerEdge`. */
150
+ { flexDirection: edge.flexDirection }
141
151
  ],
142
152
  children: [
143
153
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -147,7 +157,13 @@ const SelectPopupOverlay = ({ visible, onClose, title, children }) => {
147
157
  style: [
148
158
  styles.title,
149
159
  { color: textColor, fontFamily: headingFont },
150
- isRTL ? styles.titleRtl : styles.titleLtr
160
+ {
161
+ textAlign: edge.textAlign,
162
+ /* `writingDirection` is NOT mirrored — it
163
+ orders glyphs inside the line, so it
164
+ takes the reader's own direction. */
165
+ writingDirection: isRTL ? "rtl" : "ltr"
166
+ }
151
167
  ],
152
168
  children: title
153
169
  }
@@ -182,15 +198,11 @@ const styles = reactNative.StyleSheet.create({
182
198
  borderBottomWidth: 1,
183
199
  gap: 12
184
200
  },
185
- headerLtr: { flexDirection: "row" },
186
- headerRtl: { flexDirection: "row-reverse" },
187
201
  title: {
188
202
  flex: 1,
189
203
  fontSize: 17,
190
204
  fontWeight: "700"
191
205
  },
192
- titleLtr: { textAlign: "left", writingDirection: "ltr" },
193
- titleRtl: { textAlign: "right", writingDirection: "rtl" },
194
206
  close: {
195
207
  fontSize: 18
196
208
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SelectPopupOverlay.cjs","sources":["../../../../../src/form/selects/helpers/SelectPopupOverlay.native.tsx"],"sourcesContent":["import React from 'react';\nimport {Pressable, StyleSheet, Text, View, useWindowDimensions} from 'react-native';\nimport {useSafeAreaInsets} from 'react-native-safe-area-context';\nimport {useKeyboardHeight} from '@lmb-it/kitsconcertomobile';\nimport KitsDialogControlled from '../../../components/overlay/Dialog';\nimport {useKitsTheme} from '../../../contexts/Theme';\nimport {useLanguage} from '../../../hooks';\nimport useThemedFont from '../../../hooks/useThemedFont';\n\n/**\n * The container a select's options live in when `popup` is on.\n *\n * ⛔ THIS IS NOT A SECOND OVERLAY MECHANISM. It is the library's own\n * `KitsDialogControlled` in bottom-sheet position, so the scrim, the slide\n * animation, the safe-area insets, `dismissableMask` and Android's hardware\n * back all come from the one place that already owns them. The only thing\n * this file adds is the header row and the sizing a picker needs.\n *\n * ⛔ IT USES `content` MODE ON PURPOSE. The Dialog's default template puts its\n * children inside a ScrollView with `maxHeight: 400`. A FlatList inside a\n * ScrollView scrolls badly and warns, and a 400pt cap is the very thing the\n * popup exists to escape. `content` replaces the whole header/body/footer\n * template, so the caller's search field can be pinned and its list can own\n * the remaining height.\n *\n * WHY A FIXED FRACTION OF THE SCREEN. The popup's whole purpose is that its\n * height does not depend on where the trigger happens to sit or on whether the\n * keyboard is up. It takes a fixed share of the window, the search field sits\n * at the top of it, and the list takes the rest.\n */\n\nexport interface ISelectPopupOverlayProps {\n /** Open state. */\n visible: boolean;\n /** Called for every dismissal route — the ✕, the scrim, Android back. */\n onClose: () => void;\n /** Title shown beside the close control. Falls back to the field's label. */\n title?: React.ReactNode;\n /** The search field and the list. */\n children: React.ReactNode;\n}\n\n/** Share of the window height the sheet occupies when the keyboard is down. */\nconst SHEET_HEIGHT_RATIO = 0.75;\n/** Never shorter than this, even on a small screen with the keyboard up. */\nconst SHEET_MIN_HEIGHT = 240;\n\nconst SelectPopupOverlay = ({visible, onClose, title, children}: ISelectPopupOverlayProps) => {\n const {resolveToken} = useKitsTheme();\n const {isRTL} = useLanguage();\n const insets = useSafeAreaInsets();\n const {height: windowHeight} = useWindowDimensions();\n /* Raw RN <Text> does not inherit `fontFamily` through View parents, so a\n consumer that swaps the theme font would see it everywhere except here.\n See useThemedFont's own note. */\n const headingFont = useThemedFont('heading');\n const keyboardHeight = useKeyboardHeight();\n\n /*\n * ⛔ \"OWNS THE SCREEN\" MEANS ABOVE THE KEYBOARD, NOT BEHIND IT. A sheet\n * pinned to the bottom at a fixed 75% still has its lower half under the\n * keyboard the moment the search field takes focus, and the list is back to\n * competing for the gap — the exact fault the popup exists to escape, one\n * layer along. The sheet is capped to what is actually visible.\n *\n * The keyboard replaces the bottom inset rather than adding to it: it\n * covers the home indicator.\n */\n const visibleHeight = windowHeight - Math.max(insets.bottom, keyboardHeight) - insets.top;\n const sheetHeight = Math.max(\n Math.min(SHEET_MIN_HEIGHT, visibleHeight),\n Math.min(Math.round(windowHeight * SHEET_HEIGHT_RATIO), visibleHeight),\n );\n\n const textColor = resolveToken('text');\n const borderColor = resolveToken('border');\n const grabberColor = resolveToken('gray.300');\n const subtextColor = resolveToken('gray.500');\n\n return (\n <KitsDialogControlled\n onHide={onClose}\n state={{\n visible,\n position: 'bottom',\n // Tap-outside dismiss. `onRequestClose` inside the Dialog gives\n // Android's back button the same route.\n dismissableMask: true,\n onClose,\n style: {\n height: sheetHeight,\n // The keyboard already clears the home indicator, so the\n // inset is only owed when the keyboard is down.\n paddingBottom: keyboardHeight > 0 ? 0 : insets.bottom,\n marginBottom: keyboardHeight,\n },\n content: ({hide}: {hide: () => void}) => (\n <View style={styles.root}>\n <View style={[styles.grabber, {backgroundColor: grabberColor}]} />\n <View\n style={[\n styles.header,\n {borderBottomColor: borderColor},\n // The header mirrors with the reader, like every\n // other row this library draws.\n isRTL ? styles.headerRtl : styles.headerLtr,\n ]}>\n <Text\n numberOfLines={1}\n style={[\n styles.title,\n {color: textColor, fontFamily: headingFont},\n isRTL ? styles.titleRtl : styles.titleLtr,\n ]}>\n {title}\n </Text>\n <Pressable onPress={hide} hitSlop={12} accessibilityRole=\"button\">\n <Text style={[styles.close, {color: subtextColor}]}>✕</Text>\n </Pressable>\n </View>\n {children}\n </View>\n ),\n }}\n />\n );\n};\n\nconst styles = StyleSheet.create({\n root: {\n flex: 1,\n minHeight: 0,\n },\n grabber: {\n width: 40,\n height: 4,\n borderRadius: 2,\n alignSelf: 'center',\n marginTop: 8,\n marginBottom: 4,\n },\n header: {\n alignItems: 'center',\n paddingHorizontal: 16,\n paddingVertical: 12,\n borderBottomWidth: 1,\n gap: 12,\n },\n headerLtr: {flexDirection: 'row'},\n headerRtl: {flexDirection: 'row-reverse'},\n title: {\n flex: 1,\n fontSize: 17,\n fontWeight: '700',\n },\n titleLtr: {textAlign: 'left', writingDirection: 'ltr'},\n titleRtl: {textAlign: 'right', writingDirection: 'rtl'},\n close: {\n fontSize: 18,\n },\n});\n\nexport default SelectPopupOverlay;\n"],"names":["useKitsTheme","useLanguage","useSafeAreaInsets","useWindowDimensions","useThemedFont","useKeyboardHeight","jsx","KitsDialogControlled","jsxs","View","Text","Pressable","StyleSheet"],"mappings":"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"}
1
+ {"version":3,"file":"SelectPopupOverlay.cjs","sources":["../../../../../src/form/selects/helpers/SelectPopupOverlay.native.tsx"],"sourcesContent":["import React from 'react';\nimport {Pressable, StyleSheet, Text, View, useWindowDimensions} from 'react-native';\nimport {useSafeAreaInsets} from 'react-native-safe-area-context';\nimport {readerEdge, useKeyboardHeight} from '@lmb-it/kitsconcertomobile';\nimport KitsDialogControlled from '../../../components/overlay/Dialog';\nimport {useKitsTheme} from '../../../contexts/Theme';\nimport {useLanguage} from '../../../hooks';\nimport useThemedFont from '../../../hooks/useThemedFont';\n\n/**\n * The container a select's options live in when `popup` is on.\n *\n * ⛔ THIS IS NOT A SECOND OVERLAY MECHANISM. It is the library's own\n * `KitsDialogControlled` in bottom-sheet position, so the scrim, the slide\n * animation, the safe-area insets, `dismissableMask` and Android's hardware\n * back all come from the one place that already owns them. The only thing\n * this file adds is the header row and the sizing a picker needs.\n *\n * ⛔ IT USES `content` MODE ON PURPOSE. The Dialog's default template puts its\n * children inside a ScrollView with `maxHeight: 400`. A FlatList inside a\n * ScrollView scrolls badly and warns, and a 400pt cap is the very thing the\n * popup exists to escape. `content` replaces the whole header/body/footer\n * template, so the caller's search field can be pinned and its list can own\n * the remaining height.\n *\n * WHY A FIXED FRACTION OF THE SCREEN. The popup's whole purpose is that its\n * height does not depend on where the trigger happens to sit or on whether the\n * keyboard is up. It takes a fixed share of the window, the search field sits\n * at the top of it, and the list takes the rest.\n */\n\nexport interface ISelectPopupOverlayProps {\n /** Open state. */\n visible: boolean;\n /** Called for every dismissal route — the ✕, the scrim, Android back. */\n onClose: () => void;\n /** Title shown beside the close control. Falls back to the field's label. */\n title?: React.ReactNode;\n /** The search field and the list. */\n children: React.ReactNode;\n}\n\n/** Share of the window height the sheet occupies when the keyboard is down. */\nconst SHEET_HEIGHT_RATIO = 0.75;\n/** Never shorter than this, even on a small screen with the keyboard up. */\nconst SHEET_MIN_HEIGHT = 240;\n\nconst SelectPopupOverlay = ({visible, onClose, title, children}: ISelectPopupOverlayProps) => {\n const {resolveToken} = useKitsTheme();\n const {isRTL} = useLanguage();\n /* Physical edges to write so the header lands where the reader starts. */\n const edge = readerEdge(isRTL);\n const insets = useSafeAreaInsets();\n const {height: windowHeight} = useWindowDimensions();\n /* Raw RN <Text> does not inherit `fontFamily` through View parents, so a\n consumer that swaps the theme font would see it everywhere except here.\n See useThemedFont's own note. */\n const headingFont = useThemedFont('heading');\n const keyboardHeight = useKeyboardHeight();\n\n /*\n * ⛔ \"OWNS THE SCREEN\" MEANS ABOVE THE KEYBOARD, NOT BEHIND IT. A sheet\n * pinned to the bottom at a fixed 75% still has its lower half under the\n * keyboard the moment the search field takes focus, and the list is back to\n * competing for the gap — the exact fault the popup exists to escape, one\n * layer along. The sheet is capped to what is actually visible.\n *\n * The keyboard replaces the bottom inset rather than adding to it: it\n * covers the home indicator.\n */\n const visibleHeight = windowHeight - Math.max(insets.bottom, keyboardHeight) - insets.top;\n const sheetHeight = Math.max(\n Math.min(SHEET_MIN_HEIGHT, visibleHeight),\n Math.min(Math.round(windowHeight * SHEET_HEIGHT_RATIO), visibleHeight),\n );\n\n const textColor = resolveToken('text');\n const borderColor = resolveToken('border');\n const grabberColor = resolveToken('gray.300');\n const subtextColor = resolveToken('gray.500');\n\n return (\n <KitsDialogControlled\n onHide={onClose}\n state={{\n visible,\n position: 'bottom',\n // Tap-outside dismiss. `onRequestClose` inside the Dialog gives\n // Android's back button the same route.\n dismissableMask: true,\n onClose,\n style: {\n height: sheetHeight,\n // The keyboard already clears the home indicator, so the\n // inset is only owed when the keyboard is down.\n paddingBottom: keyboardHeight > 0 ? 0 : insets.bottom,\n marginBottom: keyboardHeight,\n },\n content: ({hide}: {hide: () => void}) => (\n <View style={styles.root}>\n <View style={[styles.grabber, {backgroundColor: grabberColor}]} />\n <View\n style={[\n styles.header,\n {borderBottomColor: borderColor},\n /* ⛔ THE PHYSICAL EDGE IS COMPUTED, NEVER NAMED.\n React Native mirrors `flexDirection: 'row'`\n and `textAlign` when the process is RTL — the\n App calls `I18nManager.forceRTL` — so naming\n the RTL edge for an RTL reader asks for it\n twice and lands on the LTR one. That is why\n this header drew its title LEFT and its ✕\n RIGHT in Arabic while the option rows below\n it, which already went through `readerEdge`,\n were correct. See `readerEdge`. */\n {flexDirection: edge.flexDirection},\n ]}>\n <Text\n numberOfLines={1}\n style={[\n styles.title,\n {color: textColor, fontFamily: headingFont},\n {\n textAlign: edge.textAlign,\n /* `writingDirection` is NOT mirrored — it\n orders glyphs inside the line, so it\n takes the reader's own direction. */\n writingDirection: isRTL ? ('rtl' as const) : ('ltr' as const),\n },\n ]}>\n {title}\n </Text>\n <Pressable onPress={hide} hitSlop={12} accessibilityRole=\"button\">\n <Text style={[styles.close, {color: subtextColor}]}>✕</Text>\n </Pressable>\n </View>\n {children}\n </View>\n ),\n }}\n />\n );\n};\n\nconst styles = StyleSheet.create({\n root: {\n flex: 1,\n minHeight: 0,\n },\n grabber: {\n width: 40,\n height: 4,\n borderRadius: 2,\n alignSelf: 'center',\n marginTop: 8,\n marginBottom: 4,\n },\n header: {\n alignItems: 'center',\n paddingHorizontal: 16,\n paddingVertical: 12,\n borderBottomWidth: 1,\n gap: 12,\n },\n title: {\n flex: 1,\n fontSize: 17,\n fontWeight: '700',\n },\n close: {\n fontSize: 18,\n },\n});\n\nexport default SelectPopupOverlay;\n"],"names":["useKitsTheme","useLanguage","readerEdge","useSafeAreaInsets","useWindowDimensions","useThemedFont","useKeyboardHeight","jsx","KitsDialogControlled","jsxs","View","Text","Pressable","StyleSheet"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,MAAM,kBAAA,GAAqB,IAAA;AAE3B,MAAM,gBAAA,GAAmB,GAAA;AAEzB,MAAM,qBAAqB,CAAC,EAAC,SAAS,OAAA,EAAS,KAAA,EAAO,UAAQ,KAAgC;AAC1F,EAAA,MAAM,EAAC,YAAA,EAAY,GAAIA,qCAAA,EAAa;AACpC,EAAA,MAAM,EAAC,KAAA,EAAK,GAAIC,kBAAA,EAAY;AAE5B,EAAA,MAAM,IAAA,GAAOC,sBAAW,KAAK,CAAA;AAC7B,EAAA,MAAM,SAASC,4CAAA,EAAkB;AACjC,EAAA,MAAM,EAAC,MAAA,EAAQ,YAAA,EAAY,GAAIC,+BAAA,EAAoB;AAInD,EAAA,MAAM,WAAA,GAAcC,sBAAc,SAAS,CAAA;AAC3C,EAAA,MAAM,iBAAiBC,mCAAA,EAAkB;AAYzC,EAAA,MAAM,aAAA,GAAgB,eAAe,IAAA,CAAK,GAAA,CAAI,OAAO,MAAA,EAAQ,cAAc,IAAI,MAAA,CAAO,GAAA;AACtF,EAAA,MAAM,cAAc,IAAA,CAAK,GAAA;AAAA,IACrB,IAAA,CAAK,GAAA,CAAI,gBAAA,EAAkB,aAAa,CAAA;AAAA,IACxC,KAAK,GAAA,CAAI,IAAA,CAAK,MAAM,YAAA,GAAe,kBAAkB,GAAG,aAAa;AAAA,GACzE;AAEA,EAAA,MAAM,SAAA,GAAY,aAAa,MAAM,CAAA;AACrC,EAAA,MAAM,WAAA,GAAc,aAAa,QAAQ,CAAA;AACzC,EAAA,MAAM,YAAA,GAAe,aAAa,UAAU,CAAA;AAC5C,EAAA,MAAM,YAAA,GAAe,aAAa,UAAU,CAAA;AAE5C,EAAA,uBACIC,cAAA;AAAA,IAACC,oBAAA;AAAA,IAAA;AAAA,MACG,MAAA,EAAQ,OAAA;AAAA,MACR,KAAA,EAAO;AAAA,QACH,OAAA;AAAA,QACA,QAAA,EAAU,QAAA;AAAA;AAAA;AAAA,QAGV,eAAA,EAAiB,IAAA;AAAA,QACjB,OAAA;AAAA,QACA,KAAA,EAAO;AAAA,UACH,MAAA,EAAQ,WAAA;AAAA;AAAA;AAAA,UAGR,aAAA,EAAe,cAAA,GAAiB,CAAA,GAAI,CAAA,GAAI,MAAA,CAAO,MAAA;AAAA,UAC/C,YAAA,EAAc;AAAA,SAClB;AAAA,QACA,OAAA,EAAS,CAAC,EAAC,IAAA,uBACPC,eAAA,CAACC,gBAAA,EAAA,EAAK,KAAA,EAAO,MAAA,CAAO,IAAA,EAChB,QAAA,EAAA;AAAA,0BAAAH,cAAA,CAACG,gBAAA,EAAA,EAAK,OAAO,CAAC,MAAA,CAAO,SAAS,EAAC,eAAA,EAAiB,YAAA,EAAa,CAAA,EAAG,CAAA;AAAA,0BAChED,eAAA;AAAA,YAACC,gBAAA;AAAA,YAAA;AAAA,cACG,KAAA,EAAO;AAAA,gBACH,MAAA,CAAO,MAAA;AAAA,gBACP,EAAC,mBAAmB,WAAA,EAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAW/B,EAAC,aAAA,EAAe,IAAA,CAAK,aAAA;AAAa,eACtC;AAAA,cACA,QAAA,EAAA;AAAA,gCAAAH,cAAA;AAAA,kBAACI,gBAAA;AAAA,kBAAA;AAAA,oBACG,aAAA,EAAe,CAAA;AAAA,oBACf,KAAA,EAAO;AAAA,sBACH,MAAA,CAAO,KAAA;AAAA,sBACP,EAAC,KAAA,EAAO,SAAA,EAAW,UAAA,EAAY,WAAA,EAAW;AAAA,sBAC1C;AAAA,wBACI,WAAW,IAAA,CAAK,SAAA;AAAA;AAAA;AAAA;AAAA,wBAIhB,gBAAA,EAAkB,QAAS,KAAA,GAAmB;AAAA;AAClD,qBACJ;AAAA,oBACC,QAAA,EAAA;AAAA;AAAA,iBACL;AAAA,gCACAJ,cAAA,CAACK,yBAAU,OAAA,EAAS,IAAA,EAAM,SAAS,EAAA,EAAI,iBAAA,EAAkB,UACrD,QAAA,kBAAAL,cAAA,CAACI,gBAAA,EAAA,EAAK,OAAO,CAAC,MAAA,CAAO,OAAO,EAAC,KAAA,EAAO,cAAa,CAAA,EAAG,oBAAC,CAAA,EACzD;AAAA;AAAA;AAAA,WACJ;AAAA,UACC;AAAA,SAAA,EACL;AAAA;AAER;AAAA,GACJ;AAER;AAEA,MAAM,MAAA,GAASE,uBAAW,MAAA,CAAO;AAAA,EAC7B,IAAA,EAAM;AAAA,IACF,IAAA,EAAM,CAAA;AAAA,IACN,SAAA,EAAW;AAAA,GACf;AAAA,EACA,OAAA,EAAS;AAAA,IACL,KAAA,EAAO,EAAA;AAAA,IACP,MAAA,EAAQ,CAAA;AAAA,IACR,YAAA,EAAc,CAAA;AAAA,IACd,SAAA,EAAW,QAAA;AAAA,IACX,SAAA,EAAW,CAAA;AAAA,IACX,YAAA,EAAc;AAAA,GAClB;AAAA,EACA,MAAA,EAAQ;AAAA,IACJ,UAAA,EAAY,QAAA;AAAA,IACZ,iBAAA,EAAmB,EAAA;AAAA,IACnB,eAAA,EAAiB,EAAA;AAAA,IACjB,iBAAA,EAAmB,CAAA;AAAA,IACnB,GAAA,EAAK;AAAA,GACT;AAAA,EACA,KAAA,EAAO;AAAA,IACH,IAAA,EAAM,CAAA;AAAA,IACN,QAAA,EAAU,EAAA;AAAA,IACV,UAAA,EAAY;AAAA,GAChB;AAAA,EACA,KAAA,EAAO;AAAA,IACH,QAAA,EAAU;AAAA;AAElB,CAAC,CAAA;;;;"}
@@ -61,6 +61,7 @@ import '../../../packages/types/src/Theme/alphaColors.js';
61
61
  import '../../../apps/mobile/src/Factory/helpers/cssVarMap.js';
62
62
  import '../../../apps/mobile/src/Factory/DimensionsContext.js';
63
63
  import { useKeyboardHeight } from '../../../apps/mobile/src/Factory/helpers/useKeyboardHeight.js';
64
+ import { readerEdge } from '../../../apps/mobile/src/Factory/helpers/readerEdge.js';
64
65
  import 'i18next';
65
66
  import 'react-i18next';
66
67
  import '../../../apps/mobile/src/Core/AutoComplete/index.js';
@@ -92,6 +93,7 @@ const SHEET_MIN_HEIGHT = 240;
92
93
  const SelectPopupOverlay = ({ visible, onClose, title, children }) => {
93
94
  const { resolveToken } = useKitsTheme();
94
95
  const { isRTL } = useLanguage();
96
+ const edge = readerEdge(isRTL);
95
97
  const insets = useSafeAreaInsets();
96
98
  const { height: windowHeight } = useWindowDimensions();
97
99
  const headingFont = useThemedFont("heading");
@@ -131,9 +133,17 @@ const SelectPopupOverlay = ({ visible, onClose, title, children }) => {
131
133
  style: [
132
134
  styles.header,
133
135
  { borderBottomColor: borderColor },
134
- // The header mirrors with the reader, like every
135
- // other row this library draws.
136
- isRTL ? styles.headerRtl : styles.headerLtr
136
+ /* ⛔ THE PHYSICAL EDGE IS COMPUTED, NEVER NAMED.
137
+ React Native mirrors `flexDirection: 'row'`
138
+ and `textAlign` when the process is RTL — the
139
+ App calls `I18nManager.forceRTL` — so naming
140
+ the RTL edge for an RTL reader asks for it
141
+ twice and lands on the LTR one. That is why
142
+ this header drew its title LEFT and its ✕
143
+ RIGHT in Arabic while the option rows below
144
+ it, which already went through `readerEdge`,
145
+ were correct. See `readerEdge`. */
146
+ { flexDirection: edge.flexDirection }
137
147
  ],
138
148
  children: [
139
149
  /* @__PURE__ */ jsx(
@@ -143,7 +153,13 @@ const SelectPopupOverlay = ({ visible, onClose, title, children }) => {
143
153
  style: [
144
154
  styles.title,
145
155
  { color: textColor, fontFamily: headingFont },
146
- isRTL ? styles.titleRtl : styles.titleLtr
156
+ {
157
+ textAlign: edge.textAlign,
158
+ /* `writingDirection` is NOT mirrored — it
159
+ orders glyphs inside the line, so it
160
+ takes the reader's own direction. */
161
+ writingDirection: isRTL ? "rtl" : "ltr"
162
+ }
147
163
  ],
148
164
  children: title
149
165
  }
@@ -178,15 +194,11 @@ const styles = StyleSheet.create({
178
194
  borderBottomWidth: 1,
179
195
  gap: 12
180
196
  },
181
- headerLtr: { flexDirection: "row" },
182
- headerRtl: { flexDirection: "row-reverse" },
183
197
  title: {
184
198
  flex: 1,
185
199
  fontSize: 17,
186
200
  fontWeight: "700"
187
201
  },
188
- titleLtr: { textAlign: "left", writingDirection: "ltr" },
189
- titleRtl: { textAlign: "right", writingDirection: "rtl" },
190
202
  close: {
191
203
  fontSize: 18
192
204
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SelectPopupOverlay.js","sources":["../../../../../src/form/selects/helpers/SelectPopupOverlay.native.tsx"],"sourcesContent":["import React from 'react';\nimport {Pressable, StyleSheet, Text, View, useWindowDimensions} from 'react-native';\nimport {useSafeAreaInsets} from 'react-native-safe-area-context';\nimport {useKeyboardHeight} from '@lmb-it/kitsconcertomobile';\nimport KitsDialogControlled from '../../../components/overlay/Dialog';\nimport {useKitsTheme} from '../../../contexts/Theme';\nimport {useLanguage} from '../../../hooks';\nimport useThemedFont from '../../../hooks/useThemedFont';\n\n/**\n * The container a select's options live in when `popup` is on.\n *\n * ⛔ THIS IS NOT A SECOND OVERLAY MECHANISM. It is the library's own\n * `KitsDialogControlled` in bottom-sheet position, so the scrim, the slide\n * animation, the safe-area insets, `dismissableMask` and Android's hardware\n * back all come from the one place that already owns them. The only thing\n * this file adds is the header row and the sizing a picker needs.\n *\n * ⛔ IT USES `content` MODE ON PURPOSE. The Dialog's default template puts its\n * children inside a ScrollView with `maxHeight: 400`. A FlatList inside a\n * ScrollView scrolls badly and warns, and a 400pt cap is the very thing the\n * popup exists to escape. `content` replaces the whole header/body/footer\n * template, so the caller's search field can be pinned and its list can own\n * the remaining height.\n *\n * WHY A FIXED FRACTION OF THE SCREEN. The popup's whole purpose is that its\n * height does not depend on where the trigger happens to sit or on whether the\n * keyboard is up. It takes a fixed share of the window, the search field sits\n * at the top of it, and the list takes the rest.\n */\n\nexport interface ISelectPopupOverlayProps {\n /** Open state. */\n visible: boolean;\n /** Called for every dismissal route — the ✕, the scrim, Android back. */\n onClose: () => void;\n /** Title shown beside the close control. Falls back to the field's label. */\n title?: React.ReactNode;\n /** The search field and the list. */\n children: React.ReactNode;\n}\n\n/** Share of the window height the sheet occupies when the keyboard is down. */\nconst SHEET_HEIGHT_RATIO = 0.75;\n/** Never shorter than this, even on a small screen with the keyboard up. */\nconst SHEET_MIN_HEIGHT = 240;\n\nconst SelectPopupOverlay = ({visible, onClose, title, children}: ISelectPopupOverlayProps) => {\n const {resolveToken} = useKitsTheme();\n const {isRTL} = useLanguage();\n const insets = useSafeAreaInsets();\n const {height: windowHeight} = useWindowDimensions();\n /* Raw RN <Text> does not inherit `fontFamily` through View parents, so a\n consumer that swaps the theme font would see it everywhere except here.\n See useThemedFont's own note. */\n const headingFont = useThemedFont('heading');\n const keyboardHeight = useKeyboardHeight();\n\n /*\n * ⛔ \"OWNS THE SCREEN\" MEANS ABOVE THE KEYBOARD, NOT BEHIND IT. A sheet\n * pinned to the bottom at a fixed 75% still has its lower half under the\n * keyboard the moment the search field takes focus, and the list is back to\n * competing for the gap — the exact fault the popup exists to escape, one\n * layer along. The sheet is capped to what is actually visible.\n *\n * The keyboard replaces the bottom inset rather than adding to it: it\n * covers the home indicator.\n */\n const visibleHeight = windowHeight - Math.max(insets.bottom, keyboardHeight) - insets.top;\n const sheetHeight = Math.max(\n Math.min(SHEET_MIN_HEIGHT, visibleHeight),\n Math.min(Math.round(windowHeight * SHEET_HEIGHT_RATIO), visibleHeight),\n );\n\n const textColor = resolveToken('text');\n const borderColor = resolveToken('border');\n const grabberColor = resolveToken('gray.300');\n const subtextColor = resolveToken('gray.500');\n\n return (\n <KitsDialogControlled\n onHide={onClose}\n state={{\n visible,\n position: 'bottom',\n // Tap-outside dismiss. `onRequestClose` inside the Dialog gives\n // Android's back button the same route.\n dismissableMask: true,\n onClose,\n style: {\n height: sheetHeight,\n // The keyboard already clears the home indicator, so the\n // inset is only owed when the keyboard is down.\n paddingBottom: keyboardHeight > 0 ? 0 : insets.bottom,\n marginBottom: keyboardHeight,\n },\n content: ({hide}: {hide: () => void}) => (\n <View style={styles.root}>\n <View style={[styles.grabber, {backgroundColor: grabberColor}]} />\n <View\n style={[\n styles.header,\n {borderBottomColor: borderColor},\n // The header mirrors with the reader, like every\n // other row this library draws.\n isRTL ? styles.headerRtl : styles.headerLtr,\n ]}>\n <Text\n numberOfLines={1}\n style={[\n styles.title,\n {color: textColor, fontFamily: headingFont},\n isRTL ? styles.titleRtl : styles.titleLtr,\n ]}>\n {title}\n </Text>\n <Pressable onPress={hide} hitSlop={12} accessibilityRole=\"button\">\n <Text style={[styles.close, {color: subtextColor}]}>✕</Text>\n </Pressable>\n </View>\n {children}\n </View>\n ),\n }}\n />\n );\n};\n\nconst styles = StyleSheet.create({\n root: {\n flex: 1,\n minHeight: 0,\n },\n grabber: {\n width: 40,\n height: 4,\n borderRadius: 2,\n alignSelf: 'center',\n marginTop: 8,\n marginBottom: 4,\n },\n header: {\n alignItems: 'center',\n paddingHorizontal: 16,\n paddingVertical: 12,\n borderBottomWidth: 1,\n gap: 12,\n },\n headerLtr: {flexDirection: 'row'},\n headerRtl: {flexDirection: 'row-reverse'},\n title: {\n flex: 1,\n fontSize: 17,\n fontWeight: '700',\n },\n titleLtr: {textAlign: 'left', writingDirection: 'ltr'},\n titleRtl: {textAlign: 'right', writingDirection: 'rtl'},\n close: {\n fontSize: 18,\n },\n});\n\nexport default SelectPopupOverlay;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SelectPopupOverlay.js","sources":["../../../../../src/form/selects/helpers/SelectPopupOverlay.native.tsx"],"sourcesContent":["import React from 'react';\nimport {Pressable, StyleSheet, Text, View, useWindowDimensions} from 'react-native';\nimport {useSafeAreaInsets} from 'react-native-safe-area-context';\nimport {readerEdge, useKeyboardHeight} from '@lmb-it/kitsconcertomobile';\nimport KitsDialogControlled from '../../../components/overlay/Dialog';\nimport {useKitsTheme} from '../../../contexts/Theme';\nimport {useLanguage} from '../../../hooks';\nimport useThemedFont from '../../../hooks/useThemedFont';\n\n/**\n * The container a select's options live in when `popup` is on.\n *\n * ⛔ THIS IS NOT A SECOND OVERLAY MECHANISM. It is the library's own\n * `KitsDialogControlled` in bottom-sheet position, so the scrim, the slide\n * animation, the safe-area insets, `dismissableMask` and Android's hardware\n * back all come from the one place that already owns them. The only thing\n * this file adds is the header row and the sizing a picker needs.\n *\n * ⛔ IT USES `content` MODE ON PURPOSE. The Dialog's default template puts its\n * children inside a ScrollView with `maxHeight: 400`. A FlatList inside a\n * ScrollView scrolls badly and warns, and a 400pt cap is the very thing the\n * popup exists to escape. `content` replaces the whole header/body/footer\n * template, so the caller's search field can be pinned and its list can own\n * the remaining height.\n *\n * WHY A FIXED FRACTION OF THE SCREEN. The popup's whole purpose is that its\n * height does not depend on where the trigger happens to sit or on whether the\n * keyboard is up. It takes a fixed share of the window, the search field sits\n * at the top of it, and the list takes the rest.\n */\n\nexport interface ISelectPopupOverlayProps {\n /** Open state. */\n visible: boolean;\n /** Called for every dismissal route — the ✕, the scrim, Android back. */\n onClose: () => void;\n /** Title shown beside the close control. Falls back to the field's label. */\n title?: React.ReactNode;\n /** The search field and the list. */\n children: React.ReactNode;\n}\n\n/** Share of the window height the sheet occupies when the keyboard is down. */\nconst SHEET_HEIGHT_RATIO = 0.75;\n/** Never shorter than this, even on a small screen with the keyboard up. */\nconst SHEET_MIN_HEIGHT = 240;\n\nconst SelectPopupOverlay = ({visible, onClose, title, children}: ISelectPopupOverlayProps) => {\n const {resolveToken} = useKitsTheme();\n const {isRTL} = useLanguage();\n /* Physical edges to write so the header lands where the reader starts. */\n const edge = readerEdge(isRTL);\n const insets = useSafeAreaInsets();\n const {height: windowHeight} = useWindowDimensions();\n /* Raw RN <Text> does not inherit `fontFamily` through View parents, so a\n consumer that swaps the theme font would see it everywhere except here.\n See useThemedFont's own note. */\n const headingFont = useThemedFont('heading');\n const keyboardHeight = useKeyboardHeight();\n\n /*\n * ⛔ \"OWNS THE SCREEN\" MEANS ABOVE THE KEYBOARD, NOT BEHIND IT. A sheet\n * pinned to the bottom at a fixed 75% still has its lower half under the\n * keyboard the moment the search field takes focus, and the list is back to\n * competing for the gap — the exact fault the popup exists to escape, one\n * layer along. The sheet is capped to what is actually visible.\n *\n * The keyboard replaces the bottom inset rather than adding to it: it\n * covers the home indicator.\n */\n const visibleHeight = windowHeight - Math.max(insets.bottom, keyboardHeight) - insets.top;\n const sheetHeight = Math.max(\n Math.min(SHEET_MIN_HEIGHT, visibleHeight),\n Math.min(Math.round(windowHeight * SHEET_HEIGHT_RATIO), visibleHeight),\n );\n\n const textColor = resolveToken('text');\n const borderColor = resolveToken('border');\n const grabberColor = resolveToken('gray.300');\n const subtextColor = resolveToken('gray.500');\n\n return (\n <KitsDialogControlled\n onHide={onClose}\n state={{\n visible,\n position: 'bottom',\n // Tap-outside dismiss. `onRequestClose` inside the Dialog gives\n // Android's back button the same route.\n dismissableMask: true,\n onClose,\n style: {\n height: sheetHeight,\n // The keyboard already clears the home indicator, so the\n // inset is only owed when the keyboard is down.\n paddingBottom: keyboardHeight > 0 ? 0 : insets.bottom,\n marginBottom: keyboardHeight,\n },\n content: ({hide}: {hide: () => void}) => (\n <View style={styles.root}>\n <View style={[styles.grabber, {backgroundColor: grabberColor}]} />\n <View\n style={[\n styles.header,\n {borderBottomColor: borderColor},\n /* ⛔ THE PHYSICAL EDGE IS COMPUTED, NEVER NAMED.\n React Native mirrors `flexDirection: 'row'`\n and `textAlign` when the process is RTL — the\n App calls `I18nManager.forceRTL` — so naming\n the RTL edge for an RTL reader asks for it\n twice and lands on the LTR one. That is why\n this header drew its title LEFT and its ✕\n RIGHT in Arabic while the option rows below\n it, which already went through `readerEdge`,\n were correct. See `readerEdge`. */\n {flexDirection: edge.flexDirection},\n ]}>\n <Text\n numberOfLines={1}\n style={[\n styles.title,\n {color: textColor, fontFamily: headingFont},\n {\n textAlign: edge.textAlign,\n /* `writingDirection` is NOT mirrored — it\n orders glyphs inside the line, so it\n takes the reader's own direction. */\n writingDirection: isRTL ? ('rtl' as const) : ('ltr' as const),\n },\n ]}>\n {title}\n </Text>\n <Pressable onPress={hide} hitSlop={12} accessibilityRole=\"button\">\n <Text style={[styles.close, {color: subtextColor}]}>✕</Text>\n </Pressable>\n </View>\n {children}\n </View>\n ),\n }}\n />\n );\n};\n\nconst styles = StyleSheet.create({\n root: {\n flex: 1,\n minHeight: 0,\n },\n grabber: {\n width: 40,\n height: 4,\n borderRadius: 2,\n alignSelf: 'center',\n marginTop: 8,\n marginBottom: 4,\n },\n header: {\n alignItems: 'center',\n paddingHorizontal: 16,\n paddingVertical: 12,\n borderBottomWidth: 1,\n gap: 12,\n },\n title: {\n flex: 1,\n fontSize: 17,\n fontWeight: '700',\n },\n close: {\n fontSize: 18,\n },\n});\n\nexport default SelectPopupOverlay;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,MAAM,kBAAA,GAAqB,IAAA;AAE3B,MAAM,gBAAA,GAAmB,GAAA;AAEzB,MAAM,qBAAqB,CAAC,EAAC,SAAS,OAAA,EAAS,KAAA,EAAO,UAAQ,KAAgC;AAC1F,EAAA,MAAM,EAAC,YAAA,EAAY,GAAI,YAAA,EAAa;AACpC,EAAA,MAAM,EAAC,KAAA,EAAK,GAAI,WAAA,EAAY;AAE5B,EAAA,MAAM,IAAA,GAAO,WAAW,KAAK,CAAA;AAC7B,EAAA,MAAM,SAAS,iBAAA,EAAkB;AACjC,EAAA,MAAM,EAAC,MAAA,EAAQ,YAAA,EAAY,GAAI,mBAAA,EAAoB;AAInD,EAAA,MAAM,WAAA,GAAc,cAAc,SAAS,CAAA;AAC3C,EAAA,MAAM,iBAAiB,iBAAA,EAAkB;AAYzC,EAAA,MAAM,aAAA,GAAgB,eAAe,IAAA,CAAK,GAAA,CAAI,OAAO,MAAA,EAAQ,cAAc,IAAI,MAAA,CAAO,GAAA;AACtF,EAAA,MAAM,cAAc,IAAA,CAAK,GAAA;AAAA,IACrB,IAAA,CAAK,GAAA,CAAI,gBAAA,EAAkB,aAAa,CAAA;AAAA,IACxC,KAAK,GAAA,CAAI,IAAA,CAAK,MAAM,YAAA,GAAe,kBAAkB,GAAG,aAAa;AAAA,GACzE;AAEA,EAAA,MAAM,SAAA,GAAY,aAAa,MAAM,CAAA;AACrC,EAAA,MAAM,WAAA,GAAc,aAAa,QAAQ,CAAA;AACzC,EAAA,MAAM,YAAA,GAAe,aAAa,UAAU,CAAA;AAC5C,EAAA,MAAM,YAAA,GAAe,aAAa,UAAU,CAAA;AAE5C,EAAA,uBACI,GAAA;AAAA,IAAC,oBAAA;AAAA,IAAA;AAAA,MACG,MAAA,EAAQ,OAAA;AAAA,MACR,KAAA,EAAO;AAAA,QACH,OAAA;AAAA,QACA,QAAA,EAAU,QAAA;AAAA;AAAA;AAAA,QAGV,eAAA,EAAiB,IAAA;AAAA,QACjB,OAAA;AAAA,QACA,KAAA,EAAO;AAAA,UACH,MAAA,EAAQ,WAAA;AAAA;AAAA;AAAA,UAGR,aAAA,EAAe,cAAA,GAAiB,CAAA,GAAI,CAAA,GAAI,MAAA,CAAO,MAAA;AAAA,UAC/C,YAAA,EAAc;AAAA,SAClB;AAAA,QACA,OAAA,EAAS,CAAC,EAAC,IAAA,uBACP,IAAA,CAAC,IAAA,EAAA,EAAK,KAAA,EAAO,MAAA,CAAO,IAAA,EAChB,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,IAAA,EAAA,EAAK,OAAO,CAAC,MAAA,CAAO,SAAS,EAAC,eAAA,EAAiB,YAAA,EAAa,CAAA,EAAG,CAAA;AAAA,0BAChE,IAAA;AAAA,YAAC,IAAA;AAAA,YAAA;AAAA,cACG,KAAA,EAAO;AAAA,gBACH,MAAA,CAAO,MAAA;AAAA,gBACP,EAAC,mBAAmB,WAAA,EAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAW/B,EAAC,aAAA,EAAe,IAAA,CAAK,aAAA;AAAa,eACtC;AAAA,cACA,QAAA,EAAA;AAAA,gCAAA,GAAA;AAAA,kBAAC,IAAA;AAAA,kBAAA;AAAA,oBACG,aAAA,EAAe,CAAA;AAAA,oBACf,KAAA,EAAO;AAAA,sBACH,MAAA,CAAO,KAAA;AAAA,sBACP,EAAC,KAAA,EAAO,SAAA,EAAW,UAAA,EAAY,WAAA,EAAW;AAAA,sBAC1C;AAAA,wBACI,WAAW,IAAA,CAAK,SAAA;AAAA;AAAA;AAAA;AAAA,wBAIhB,gBAAA,EAAkB,QAAS,KAAA,GAAmB;AAAA;AAClD,qBACJ;AAAA,oBACC,QAAA,EAAA;AAAA;AAAA,iBACL;AAAA,gCACA,GAAA,CAAC,aAAU,OAAA,EAAS,IAAA,EAAM,SAAS,EAAA,EAAI,iBAAA,EAAkB,UACrD,QAAA,kBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,OAAO,CAAC,MAAA,CAAO,OAAO,EAAC,KAAA,EAAO,cAAa,CAAA,EAAG,oBAAC,CAAA,EACzD;AAAA;AAAA;AAAA,WACJ;AAAA,UACC;AAAA,SAAA,EACL;AAAA;AAER;AAAA,GACJ;AAER;AAEA,MAAM,MAAA,GAAS,WAAW,MAAA,CAAO;AAAA,EAC7B,IAAA,EAAM;AAAA,IACF,IAAA,EAAM,CAAA;AAAA,IACN,SAAA,EAAW;AAAA,GACf;AAAA,EACA,OAAA,EAAS;AAAA,IACL,KAAA,EAAO,EAAA;AAAA,IACP,MAAA,EAAQ,CAAA;AAAA,IACR,YAAA,EAAc,CAAA;AAAA,IACd,SAAA,EAAW,QAAA;AAAA,IACX,SAAA,EAAW,CAAA;AAAA,IACX,YAAA,EAAc;AAAA,GAClB;AAAA,EACA,MAAA,EAAQ;AAAA,IACJ,UAAA,EAAY,QAAA;AAAA,IACZ,iBAAA,EAAmB,EAAA;AAAA,IACnB,eAAA,EAAiB,EAAA;AAAA,IACjB,iBAAA,EAAmB,CAAA;AAAA,IACnB,GAAA,EAAK;AAAA,GACT;AAAA,EACA,KAAA,EAAO;AAAA,IACH,IAAA,EAAM,CAAA;AAAA,IACN,QAAA,EAAU,EAAA;AAAA,IACV,UAAA,EAAY;AAAA,GAChB;AAAA,EACA,KAAA,EAAO;AAAA,IACH,QAAA,EAAU;AAAA;AAElB,CAAC,CAAA;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lmb-it/kitsconcerto-native",
3
- "version": "0.1.264",
3
+ "version": "0.1.266",
4
4
  "description": "KitsConcerto — Native (React Native) UI components",
5
5
  "main": "index.cjs",
6
6
  "module": "index.js",