{ "version": 3, "sources": ["../../assets/js/lib/scroll_lock.js", "../../assets/js/lib/overlay_registry.js", "../../assets/js/lib/turbo.js", "../../assets/js/lib/sugar_controller.js", "../../assets/js/lib/collapse.js", "../../assets/js/lib/persist.js", "../../assets/js/controllers/accordion_controller.js", "../../assets/js/lib/transition.js", "../../assets/js/lib/focus_trap.js", "../../assets/js/lib/uid.js", "../../assets/js/controllers/dialog_controller.js", "../../assets/js/controllers/alert_dialog_controller.js", "../../assets/js/lib/dates.js", "../../assets/js/controllers/calendar_controller.js", "../../assets/js/controllers/carousel_controller.js", "../../assets/js/controllers/checkbox_controller.js", "../../assets/js/controllers/collapsible_controller.js", "../../assets/js/controllers/date_picker_controller.js", "../../assets/js/controllers/drawer_controller.js", "../../assets/js/lib/anchor.js", "../../assets/js/controllers/dropdown_menu_controller.js", "../../assets/js/controllers/dropdown_menu_checkbox_item_controller.js", "../../assets/js/controllers/dropdown_menu_radio_group_controller.js", "../../assets/js/controllers/dropdown_menu_sub_controller.js", "../../assets/js/controllers/hover_card_controller.js", "../../assets/js/controllers/input_otp_controller.js", "../../assets/js/controllers/popover_controller.js", "../../assets/js/controllers/radio_group_controller.js", "../../assets/js/controllers/resizable_controller.js", "../../assets/js/controllers/scroll_area_controller.js", "../../assets/js/controllers/select_controller.js", "../../assets/js/controllers/slider_controller.js", "../../assets/js/controllers/sheet_controller.js", "../../assets/js/controllers/sonner_controller.js", "../../assets/js/controllers/sonner_trigger_controller.js", "../../assets/js/controllers/switch_controller.js", "../../assets/js/controllers/tabs_controller.js", "../../assets/js/controllers/toggle_controller.js", "../../assets/js/controllers/toggle_group_controller.js", "../../assets/js/controllers/toggle_group_item_controller.js", "../../assets/js/controllers/tooltip_controller.js", "../../assets/js/index.js"], "sourcesContent": ["// Body-scroll lock \u2014 one shared, ref-counted implementation.\n//\n// Every overlay that should freeze the page while open (Dropdown Menu,\n// Dialog, AlertDialog, Drawer, Sheet, Select) routes through this single\n// counter. ONE global count is the entire point: it is the only thing\n// that keeps two overlays whose open windows overlap \u2014 switching between\n// two dropdowns, opening a dialog from a menu item, a select layered over\n// a dropdown \u2014 in a consistent state. The first lock snapshots 's\n// overflow / padding-right and applies `overflow:hidden`; the last unlock\n// restores them. Locks in between only bump the counter.\n//\n// Both styles go on the ROOT element (), never
: is the\n// scroll container, and padding on would shrink its content box\n// ~15px and drag mx-auto / calc(50% \u2026) layouts sideways on every open.\n// When the page already reserves a stable scrollbar gutter we only toggle\n// overflow and skip the padding compensation (there is no shift to\n// counter).\n//\n// State lives on `window` so that even if two copies of this module load\n// (importmap source + minified bundle) they still share one counter.\n\nexport function scrollLockState() {\n if (!window.__sugarScrollLock) {\n window.__sugarScrollLock = { count: 0, overflow: '', paddingRight: '' };\n }\n return window.__sugarScrollLock;\n}\n\n// Controllers currently holding a lock unit. Used by the Turbo render\n// reconciler to distinguish a genuine lock (a data-default-open modal that\n// re-locked while connecting on the new page) from a stranded one.\nexport const lockHolders = new Set();\n\nexport function lockBodyScroll() {\n const s = scrollLockState();\n if (s.count === 0) {\n const root = document.documentElement;\n s.overflow = root.style.overflow;\n s.paddingRight = root.style.paddingRight;\n const scrollbarWidth = window.innerWidth - root.clientWidth;\n let gutter = '';\n try { gutter = window.getComputedStyle(root).scrollbarGutter || ''; } catch (e) { /* older browsers */ }\n root.style.overflow = 'hidden';\n if (scrollbarWidth > 0 && (gutter === '' || gutter === 'auto')) {\n root.style.paddingRight = scrollbarWidth + 'px';\n }\n }\n s.count++;\n}\n\nexport function unlockBodyScroll() {\n const s = scrollLockState();\n if (s.count <= 0) return;\n s.count--;\n if (s.count === 0) {\n const root = document.documentElement;\n root.style.overflow = s.overflow || '';\n root.style.paddingRight = s.paddingRight || '';\n s.overflow = '';\n s.paddingRight = '';\n }\n}\n\n// Force the lock fully open and restore , regardless of count. Used\n// before a Turbo body swap so a navigation fired while an overlay is still\n// open can never leave the next page unscrollable.\nexport function resetBodyScroll() {\n const s = scrollLockState();\n if (s.count === 0) return;\n const root = document.documentElement;\n root.style.overflow = s.overflow || '';\n root.style.paddingRight = s.paddingRight || '';\n s.count = 0;\n s.overflow = '';\n s.paddingRight = '';\n}\n\n// Give an overlay controller idempotent, teardown-safe page-scroll locking.\n//\n// Adds a per-instance `scrollLocked` flag plus `lockScroll()` /\n// `unlockScroll()` that each no-op unless they actually change that flag,\n// so a controller contributes AT MOST one unit to the shared counter and\n// always removes exactly its own unit \u2014 no matter how many open/close\n// paths or value callbacks fire. That alone kills double-count drift.\n//\n// The disconnect wrap is the safety net: Stimulus calls disconnect() on\n// EVERY removal path \u2014 Turbo body swaps, Turbo Frame renders, a parent\n// innerHTML swap \u2014 so a controller torn out of the DOM while `open` is\n// still true can never leak its lock unit and strand the page at\n// overflow:hidden.\n//\n// Call once, from connect() or initialize(); repeated calls no-op (the\n// same controller instance is reused across disconnect/reconnect cycles).\nexport function useScrollLock(controller) {\n if (controller.__scrollLockInstalled) return;\n controller.__scrollLockInstalled = true;\n controller.scrollLocked = false;\n controller.lockScroll = function () {\n if (this.scrollLocked) return;\n this.scrollLocked = true;\n lockHolders.add(this);\n lockBodyScroll();\n };\n controller.unlockScroll = function () {\n if (!this.scrollLocked) return;\n this.scrollLocked = false;\n lockHolders.delete(this);\n unlockBodyScroll();\n };\n const originalDisconnect = controller.disconnect.bind(controller);\n controller.disconnect = function () {\n this.unlockScroll();\n originalDisconnect();\n };\n}\n", "// Registry of currently-open overlay controllers.\n//\n// Every controller with transient open state (Dialog family, Popover,\n// DropdownMenu + Sub, HoverCard, Tooltip, Select, DatePicker) adds itself\n// when it opens and removes itself when it closes or disconnects. Each\n// registrant MUST expose a synchronous `closeNow()` that skips transitions\n// and clears its own timers.\n//\n// The Turbo before-cache hook simply closes the O(open) entries here \u2014\n// no DOM walking \u2014 so snapshots never contain a stuck-open overlay.\n//\n// Persisted-open state never enters this registry (persistence applies to\n// disclosure widgets \u2014 tabs/accordion/collapsible \u2014 which are not\n// overlays), so closing everything here can't clobber user intent.\n\nexport const openOverlays = new Set();\n\nexport function registerOpenOverlay(controller) {\n openOverlays.add(controller);\n}\n\nexport function unregisterOpenOverlay(controller) {\n openOverlays.delete(controller);\n}\n", "// Turbo Drive integration \u2014 the ONLY place in the runtime that listens to\n// turbo:* events. Installed once (idempotent) by registerControllers();\n// every listener is inert when Turbo isn't on the page, so the library\n// stays fully optional-Turbo.\n//\n// This file is small on purpose:\n// Stimulus disconnects every controller in the outgoing body on any DOM\n// removal \u2014 Turbo body swaps included \u2014 so per-instance cleanup (scroll\n// lock release, anchor listener removal, focus-trap release, timers) rides\n// on disconnect() and needs no Turbo-specific code. And with no teleported\n// nodes (floating content stays inside its component root), the old\n// purge-teleports and detach-anchor-listeners sweeps have nothing left to\n// do.\n//\n// What genuinely still needs Turbo hooks:\n//\n// 1. before-cache / before-render: close open overlays SYNCHRONOUSLY.\n// Turbo serializes the body into its back/forward cache right after\n// turbo:before-cache; a dialog left open would be snapshotted with\n// data-state=\"open\" and reappear \"stuck open\" on back navigation\n// (its enter-state markup restored, but mid-transition classes and\n// aria state stale). closeNow() skips transitions and clears timers so\n// the snapshot is clean before serialization. Then force the shared\n// scroll lock back to a clean slate: closing releases each unit, but\n// resetBodyScroll() also covers a navigation fired from INSIDE an open\n// overlay where teardown ordering could otherwise strand at\n// overflow:hidden (Turbo never replaces , so a missed reset\n// freezes scroll for the rest of the session).\n//\n// 2. render / load: reconcile the scroll lock against reality. If the\n// count is still positive but no connected controller holds a lock\n// unit, the count is by definition stranded \u2014 force it clean. A\n// data-default-open modal that legitimately re-locked while connecting\n// on the new page registers itself in lockHolders and is left alone.\n// This never fights a genuine lock and self-heals every navigation\n// path.\n//\n// 3. morph (Turbo 8 page refresh): controllers derive their rendering\n// from data-*-value attributes, so a morphed value attribute re-fires\n// its *ValueChanged callback automatically. But morph can also revert\n// controller-written presentation attributes (aria-expanded, inline\n// display) back to the server-rendered markup without touching the\n// value attribute. After a morph completes, ask every ready component\n// to re-render from its current values via a broadcast event that\n// controllers opt into with:\n// data-action=\"sugar:morph@document->st-tabs#render\"\n\nimport { resetBodyScroll, scrollLockState, lockHolders } from './scroll_lock.js';\nimport { openOverlays } from './overlay_registry.js';\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Snapshot defaults \u2014 reset Stimulus value attributes before caching.\n//\n// Stimulus stores values in DOM attributes, so a user interaction (picking\n// a tab, expanding a collapsible) mutates markup that Turbo would serialize\n// into its back/forward cache \u2014 and the restored page would re-initialize\n// from the MUTATED value, silently persisting state that was never opted\n// into persistence. The intended semantics: only explicitly persisted\n// state survives navigation; everything else re-initializes from the\n// server-rendered defaults.\n//\n// To get there, every SugarController captures its\n// server-rendered `data-