stimeo-ui 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +178 -0
- package/README.md +120 -0
- package/dist/cable/index.js +63 -15
- package/dist/cable/index.js.map +1 -1
- package/dist/controllers/accordion_controller.d.ts +30 -3
- package/dist/controllers/accordion_controller.js +98 -9
- package/dist/controllers/accordion_controller.js.map +1 -1
- package/dist/controllers/alert_dialog_controller.d.ts +8 -7
- package/dist/controllers/alert_dialog_controller.js.map +1 -1
- package/dist/controllers/announcer_controller.d.ts +3 -2
- package/dist/controllers/announcer_controller.js +8 -1
- package/dist/controllers/announcer_controller.js.map +1 -1
- package/dist/controllers/auto_submit_controller.js +43 -2
- package/dist/controllers/auto_submit_controller.js.map +1 -1
- package/dist/controllers/avatar_controller.js +1 -1
- package/dist/controllers/avatar_controller.js.map +1 -1
- package/dist/controllers/breadcrumb_controller.d.ts +10 -7
- package/dist/controllers/breadcrumb_controller.js +9 -8
- package/dist/controllers/breadcrumb_controller.js.map +1 -1
- package/dist/controllers/bulk_select_controller.d.ts +4 -4
- package/dist/controllers/bulk_select_controller.js +7 -6
- package/dist/controllers/bulk_select_controller.js.map +1 -1
- package/dist/controllers/calendar_controller.d.ts +85 -23
- package/dist/controllers/calendar_controller.js +323 -123
- package/dist/controllers/calendar_controller.js.map +1 -1
- package/dist/controllers/carousel_controller.d.ts +67 -22
- package/dist/controllers/carousel_controller.js +263 -38
- package/dist/controllers/carousel_controller.js.map +1 -1
- package/dist/controllers/character_counter_controller.d.ts +1 -1
- package/dist/controllers/character_counter_controller.js +40 -2
- package/dist/controllers/character_counter_controller.js.map +1 -1
- package/dist/controllers/checkbox_controller.js +54 -10
- package/dist/controllers/checkbox_controller.js.map +1 -1
- package/dist/controllers/clipboard_controller.d.ts +28 -2
- package/dist/controllers/clipboard_controller.js +63 -5
- package/dist/controllers/clipboard_controller.js.map +1 -1
- package/dist/controllers/collapsible_controller.d.ts +25 -1
- package/dist/controllers/collapsible_controller.js +99 -14
- package/dist/controllers/collapsible_controller.js.map +1 -1
- package/dist/controllers/color_picker_controller.d.ts +29 -8
- package/dist/controllers/color_picker_controller.js +80 -34
- package/dist/controllers/color_picker_controller.js.map +1 -1
- package/dist/controllers/combobox_controller.d.ts +10 -1
- package/dist/controllers/combobox_controller.js +106 -16
- package/dist/controllers/combobox_controller.js.map +1 -1
- package/dist/controllers/command_palette_controller.d.ts +3 -3
- package/dist/controllers/command_palette_controller.js +35 -3
- package/dist/controllers/command_palette_controller.js.map +1 -1
- package/dist/controllers/conditional_fields_controller.js +56 -11
- package/dist/controllers/conditional_fields_controller.js.map +1 -1
- package/dist/controllers/confirm_controller.js +3 -0
- package/dist/controllers/confirm_controller.js.map +1 -1
- package/dist/controllers/context_menu_controller.d.ts +6 -0
- package/dist/controllers/context_menu_controller.js +32 -12
- package/dist/controllers/context_menu_controller.js.map +1 -1
- package/dist/controllers/countdown_controller.d.ts +30 -1
- package/dist/controllers/countdown_controller.js +129 -26
- package/dist/controllers/countdown_controller.js.map +1 -1
- package/dist/controllers/currency_input_controller.d.ts +74 -15
- package/dist/controllers/currency_input_controller.js +205 -58
- package/dist/controllers/currency_input_controller.js.map +1 -1
- package/dist/controllers/data_grid_controller.d.ts +63 -18
- package/dist/controllers/data_grid_controller.js +195 -29
- package/dist/controllers/data_grid_controller.js.map +1 -1
- package/dist/controllers/date_range_picker_controller.d.ts +34 -6
- package/dist/controllers/date_range_picker_controller.js +139 -27
- package/dist/controllers/date_range_picker_controller.js.map +1 -1
- package/dist/controllers/dialog_controller.d.ts +10 -3
- package/dist/controllers/dialog_controller.js +35 -8
- package/dist/controllers/dialog_controller.js.map +1 -1
- package/dist/controllers/direct_upload_controller.js +22 -4
- package/dist/controllers/direct_upload_controller.js.map +1 -1
- package/dist/controllers/dirty_form_controller.d.ts +2 -2
- package/dist/controllers/dirty_form_controller.js +14 -1
- package/dist/controllers/dirty_form_controller.js.map +1 -1
- package/dist/controllers/dismissible_controller.js +1 -0
- package/dist/controllers/dismissible_controller.js.map +1 -1
- package/dist/controllers/drawer_controller.d.ts +18 -10
- package/dist/controllers/drawer_controller.js +54 -19
- package/dist/controllers/drawer_controller.js.map +1 -1
- package/dist/controllers/dropdown_controller.d.ts +9 -3
- package/dist/controllers/dropdown_controller.js +36 -9
- package/dist/controllers/dropdown_controller.js.map +1 -1
- package/dist/controllers/editable_controller.js +34 -0
- package/dist/controllers/editable_controller.js.map +1 -1
- package/dist/controllers/file_dropzone_controller.js +144 -51
- package/dist/controllers/file_dropzone_controller.js.map +1 -1
- package/dist/controllers/filter_controller.d.ts +10 -4
- package/dist/controllers/filter_controller.js +20 -6
- package/dist/controllers/filter_controller.js.map +1 -1
- package/dist/controllers/flash_controller.d.ts +26 -6
- package/dist/controllers/flash_controller.js +305 -46
- package/dist/controllers/flash_controller.js.map +1 -1
- package/dist/controllers/focus_controller.js +1 -0
- package/dist/controllers/focus_controller.js.map +1 -1
- package/dist/controllers/form_field_controller.js +7 -5
- package/dist/controllers/form_field_controller.js.map +1 -1
- package/dist/controllers/form_validation_controller.js +19 -13
- package/dist/controllers/form_validation_controller.js.map +1 -1
- package/dist/controllers/frame_loading_controller.js +16 -2
- package/dist/controllers/frame_loading_controller.js.map +1 -1
- package/dist/controllers/highlight_controller.js +19 -2
- package/dist/controllers/highlight_controller.js.map +1 -1
- package/dist/controllers/hover_card_controller.d.ts +10 -2
- package/dist/controllers/hover_card_controller.js +40 -14
- package/dist/controllers/hover_card_controller.js.map +1 -1
- package/dist/controllers/idle_controller.d.ts +16 -3
- package/dist/controllers/idle_controller.js +90 -5
- package/dist/controllers/idle_controller.js.map +1 -1
- package/dist/controllers/input_mask_controller.d.ts +5 -2
- package/dist/controllers/input_mask_controller.js +65 -9
- package/dist/controllers/input_mask_controller.js.map +1 -1
- package/dist/controllers/intersection_controller.js +3 -0
- package/dist/controllers/intersection_controller.js.map +1 -1
- package/dist/controllers/lazy_frame_controller.js +11 -2
- package/dist/controllers/lazy_frame_controller.js.map +1 -1
- package/dist/controllers/listbox_controller.d.ts +50 -8
- package/dist/controllers/listbox_controller.js +203 -45
- package/dist/controllers/listbox_controller.js.map +1 -1
- package/dist/controllers/masonry_controller.js +0 -2
- package/dist/controllers/masonry_controller.js.map +1 -1
- package/dist/controllers/menu_controller.d.ts +9 -3
- package/dist/controllers/menu_controller.js +45 -16
- package/dist/controllers/menu_controller.js.map +1 -1
- package/dist/controllers/menubar_controller.d.ts +11 -0
- package/dist/controllers/menubar_controller.js +58 -24
- package/dist/controllers/menubar_controller.js.map +1 -1
- package/dist/controllers/meter_controller.js +9 -5
- package/dist/controllers/meter_controller.js.map +1 -1
- package/dist/controllers/multi_select_controller.d.ts +18 -3
- package/dist/controllers/multi_select_controller.js +278 -104
- package/dist/controllers/multi_select_controller.js.map +1 -1
- package/dist/controllers/navigation_menu_controller.d.ts +11 -0
- package/dist/controllers/navigation_menu_controller.js +48 -15
- package/dist/controllers/navigation_menu_controller.js.map +1 -1
- package/dist/controllers/nested_form_controller.js +37 -8
- package/dist/controllers/nested_form_controller.js.map +1 -1
- package/dist/controllers/network_status_controller.js +9 -1
- package/dist/controllers/network_status_controller.js.map +1 -1
- package/dist/controllers/number_input_controller.d.ts +36 -8
- package/dist/controllers/number_input_controller.js +124 -21
- package/dist/controllers/number_input_controller.js.map +1 -1
- package/dist/controllers/optimistic_controller.js +14 -1
- package/dist/controllers/optimistic_controller.js.map +1 -1
- package/dist/controllers/otp_controller.d.ts +22 -7
- package/dist/controllers/otp_controller.js +198 -55
- package/dist/controllers/otp_controller.js.map +1 -1
- package/dist/controllers/overflow_indicator_controller.d.ts +8 -12
- package/dist/controllers/overflow_indicator_controller.js +84 -13
- package/dist/controllers/overflow_indicator_controller.js.map +1 -1
- package/dist/controllers/overflow_menu_controller.d.ts +26 -6
- package/dist/controllers/overflow_menu_controller.js +112 -41
- package/dist/controllers/overflow_menu_controller.js.map +1 -1
- package/dist/controllers/pagination_controller.d.ts +19 -11
- package/dist/controllers/pagination_controller.js +74 -28
- package/dist/controllers/pagination_controller.js.map +1 -1
- package/dist/controllers/password_reveal_controller.d.ts +15 -1
- package/dist/controllers/password_reveal_controller.js +59 -2
- package/dist/controllers/password_reveal_controller.js.map +1 -1
- package/dist/controllers/persist_controller.js +30 -8
- package/dist/controllers/persist_controller.js.map +1 -1
- package/dist/controllers/pointer_drag_controller.js +131 -52
- package/dist/controllers/pointer_drag_controller.js.map +1 -1
- package/dist/controllers/popover_controller.d.ts +9 -3
- package/dist/controllers/popover_controller.js +45 -11
- package/dist/controllers/popover_controller.js.map +1 -1
- package/dist/controllers/portal_controller.d.ts +1 -1
- package/dist/controllers/portal_controller.js +6 -2
- package/dist/controllers/portal_controller.js.map +1 -1
- package/dist/controllers/preview_guard_controller.js +16 -1
- package/dist/controllers/preview_guard_controller.js.map +1 -1
- package/dist/controllers/progress_controller.js +8 -4
- package/dist/controllers/progress_controller.js.map +1 -1
- package/dist/controllers/radio_group_controller.d.ts +6 -4
- package/dist/controllers/radio_group_controller.js +42 -17
- package/dist/controllers/radio_group_controller.js.map +1 -1
- package/dist/controllers/range_slider_controller.d.ts +49 -1
- package/dist/controllers/range_slider_controller.js +88 -42
- package/dist/controllers/range_slider_controller.js.map +1 -1
- package/dist/controllers/rating_controller.d.ts +14 -3
- package/dist/controllers/rating_controller.js +39 -15
- package/dist/controllers/rating_controller.js.map +1 -1
- package/dist/controllers/read_more_controller.d.ts +24 -2
- package/dist/controllers/read_more_controller.js +69 -2
- package/dist/controllers/read_more_controller.js.map +1 -1
- package/dist/controllers/resizable_controller.d.ts +16 -2
- package/dist/controllers/resizable_controller.js +82 -22
- package/dist/controllers/resizable_controller.js.map +1 -1
- package/dist/controllers/scroll_area_controller.js +5 -1
- package/dist/controllers/scroll_area_controller.js.map +1 -1
- package/dist/controllers/scroll_visibility_controller.js +0 -1
- package/dist/controllers/scroll_visibility_controller.js.map +1 -1
- package/dist/controllers/scrollspy_controller.d.ts +3 -2
- package/dist/controllers/scrollspy_controller.js +6 -0
- package/dist/controllers/scrollspy_controller.js.map +1 -1
- package/dist/controllers/separator_controller.d.ts +41 -14
- package/dist/controllers/separator_controller.js +66 -37
- package/dist/controllers/separator_controller.js.map +1 -1
- package/dist/controllers/sidebar_controller.d.ts +20 -3
- package/dist/controllers/sidebar_controller.js +77 -18
- package/dist/controllers/sidebar_controller.js.map +1 -1
- package/dist/controllers/skeleton_controller.js +6 -1
- package/dist/controllers/skeleton_controller.js.map +1 -1
- package/dist/controllers/slider_controller.d.ts +45 -7
- package/dist/controllers/slider_controller.js +82 -47
- package/dist/controllers/slider_controller.js.map +1 -1
- package/dist/controllers/smart_sticky_header_controller.js +11 -1
- package/dist/controllers/smart_sticky_header_controller.js.map +1 -1
- package/dist/controllers/sortable_controller.js +17 -2
- package/dist/controllers/sortable_controller.js.map +1 -1
- package/dist/controllers/spinner_controller.js +10 -2
- package/dist/controllers/spinner_controller.js.map +1 -1
- package/dist/controllers/step_indicator_controller.d.ts +19 -17
- package/dist/controllers/step_indicator_controller.js +18 -17
- package/dist/controllers/step_indicator_controller.js.map +1 -1
- package/dist/controllers/stepper_controller.d.ts +34 -9
- package/dist/controllers/stepper_controller.js +101 -19
- package/dist/controllers/stepper_controller.js.map +1 -1
- package/dist/controllers/stick_to_bottom_controller.d.ts +19 -0
- package/dist/controllers/stick_to_bottom_controller.js +75 -5
- package/dist/controllers/stick_to_bottom_controller.js.map +1 -1
- package/dist/controllers/submit_once_controller.d.ts +3 -2
- package/dist/controllers/submit_once_controller.js +16 -3
- package/dist/controllers/submit_once_controller.js.map +1 -1
- package/dist/controllers/switch_controller.d.ts +29 -7
- package/dist/controllers/switch_controller.js +101 -10
- package/dist/controllers/switch_controller.js.map +1 -1
- package/dist/controllers/tabs_controller.d.ts +12 -0
- package/dist/controllers/tabs_controller.js +21 -2
- package/dist/controllers/tabs_controller.js.map +1 -1
- package/dist/controllers/tags_input_controller.d.ts +15 -3
- package/dist/controllers/tags_input_controller.js +209 -59
- package/dist/controllers/tags_input_controller.js.map +1 -1
- package/dist/controllers/theme_controller.d.ts +20 -3
- package/dist/controllers/theme_controller.js +64 -14
- package/dist/controllers/theme_controller.js.map +1 -1
- package/dist/controllers/time_picker_controller.js +23 -8
- package/dist/controllers/time_picker_controller.js.map +1 -1
- package/dist/controllers/toast_controller.d.ts +52 -15
- package/dist/controllers/toast_controller.js +337 -54
- package/dist/controllers/toast_controller.js.map +1 -1
- package/dist/controllers/toggle_group_controller.d.ts +49 -7
- package/dist/controllers/toggle_group_controller.js +159 -23
- package/dist/controllers/toggle_group_controller.js.map +1 -1
- package/dist/controllers/toolbar_controller.js +32 -0
- package/dist/controllers/toolbar_controller.js.map +1 -1
- package/dist/controllers/tooltip_controller.d.ts +8 -0
- package/dist/controllers/tooltip_controller.js +39 -13
- package/dist/controllers/tooltip_controller.js.map +1 -1
- package/dist/controllers/transition_controller.js +4 -0
- package/dist/controllers/transition_controller.js.map +1 -1
- package/dist/controllers/tree_view_controller.d.ts +39 -8
- package/dist/controllers/tree_view_controller.js +169 -16
- package/dist/controllers/tree_view_controller.js.map +1 -1
- package/dist/index.d.ts +28 -1
- package/dist/index.js +4588 -1535
- package/dist/index.js.map +1 -1
- package/dist/inspector/cli.d.ts +72 -6
- package/dist/inspector/cli.js +262 -51
- package/dist/inspector/cli.js.map +1 -1
- package/dist/inspector/cli_bin.js +309 -51
- package/dist/inspector/cli_bin.js.map +1 -1
- package/dist/inspector/examples.json +40 -40
- package/dist/inspector/manifest.json +525 -59
- package/dist/positioning/index.js +2 -0
- package/dist/positioning/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/aria_ids.ts","../../src/utils/logical_scroll.ts","../../src/utils/arrow_step.ts","../../src/utils/attribute_lease.ts","../../src/utils/before_cache_reset.ts","../../src/utils/composition_tracker.ts","../../src/utils/declared_value.ts","../../src/utils/half_width.ts","../../src/utils/microtask_coalescer.ts","../../src/controllers/otp_controller.ts"],"names":[],"mappings":"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","file":"otp_controller.js","sourcesContent":["/**\n * Minimal id primitives for wiring ARIA relationships.\n *\n * Accessible relationships such as `aria-describedby`, `aria-errormessage`,\n * `aria-labelledby`, and `aria-activedescendant` reference their targets by DOM\n * `id`. When a controller must establish such a relationship but the consumer's\n * markup left the target without an `id`, it needs to mint one that is stable for\n * the page's lifetime and guaranteed not to collide with another generated id.\n *\n * These helpers own *only* id generation/assignment. The linking policy (which\n * attribute, what order, when to add or remove it) stays in each controller —\n * this deliberately avoids a premature generic \"ARIA linker\" abstraction.\n */\n\n/**\n * Monotonic counter backing {@link uniqueId}. Module-scoped so every generated\n * id is unique across all controller instances sharing this module in a document.\n */\nlet counter = 0;\n\n/**\n * Returns a unique, DOM-id-safe string of the form `` `${prefix}-${n}` `` where\n * `n` increases on each call.\n *\n * The counter alone guarantees uniqueness against other *generated* ids, but a\n * consumer-authored element could already own `` `${prefix}-${n}` ``. When a\n * `document` is available the candidate is therefore advanced until no element\n * with that id exists, so a generated id never collides with author markup\n * either — the minimal \"id registry\" guarantee these helpers exist to provide.\n *\n * @param prefix - Leading segment of the id (e.g. a controller's identifier).\n * Defaults to `\"stimeo\"`.\n */\nexport function uniqueId(prefix = \"stimeo\"): string {\n let candidate: string;\n do {\n counter += 1;\n candidate = `${prefix}-${counter}`;\n } while (typeof document !== \"undefined\" && document.getElementById(candidate) !== null);\n return candidate;\n}\n\n/**\n * Returns `element`'s existing `id`, or assigns it a freshly generated\n * {@link uniqueId} (with the given `prefix`) and returns that. Idempotent: an\n * element that already has an id keeps it, so consumer-authored ids are never\n * overwritten.\n *\n * @param element - The element to read or stamp an `id` onto.\n * @param prefix - Prefix forwarded to {@link uniqueId} when one must be generated.\n * @returns The element's id (existing or newly assigned).\n */\nexport function ensureId(element: Element, prefix = \"stimeo\"): string {\n if (element.id) return element.id;\n const id = uniqueId(prefix);\n element.id = id;\n return id;\n}\n","/** Normalized scroll position and maximum distance on one logical axis. */\nexport interface LogicalScrollMetrics {\n position: number;\n max: number;\n}\n\n/**\n * Whether horizontal scrolling on `element` follows right-to-left inline flow.\n *\n * Resolved from the **computed** `direction`, so the authoring contract is the\n * usual `dir=\"rtl\"` (or a stylesheet) on the element or any ancestor.\n *\n * Scope: horizontal writing modes. A vertical writing mode (`writing-mode:\n * vertical-rl`) also inverts the horizontal axis, which this check does not\n * model — vertical writing modes are out of scope for the scroll utilities\n * (their consumers describe axes as horizontal/vertical, not inline/block).\n */\nexport function isRtl(element: Element): boolean {\n return window.getComputedStyle(element).direction === \"rtl\";\n}\n\n/**\n * Returns scroll distance from the logical start edge.\n *\n * CSSOM View exposes standards-mode RTL horizontal offsets as `0` at the inline\n * start (right) and increasingly negative values toward the inline end (left).\n * The normalized position is always clamped to `[0, max]`, which also absorbs\n * Safari's elastic overscroll values.\n */\nexport function logicalScrollMetrics(\n element: HTMLElement,\n horizontal: boolean,\n): LogicalScrollMetrics {\n const max = Math.max(\n 0,\n horizontal\n ? element.scrollWidth - element.clientWidth\n : element.scrollHeight - element.clientHeight,\n );\n const raw = horizontal ? element.scrollLeft : element.scrollTop;\n const position = horizontal && isRtl(element) ? -raw : raw;\n return { position: Math.min(max, Math.max(0, position)), max };\n}\n\n/**\n * Converts a logical start/end delta to the physical value accepted by\n * `Element.scrollBy`.\n */\nexport function physicalScrollDelta(\n element: HTMLElement,\n horizontal: boolean,\n logicalDelta: number,\n): number {\n return horizontal && isRtl(element) ? -logicalDelta : logicalDelta;\n}\n","import { isRtl } from \"./logical_scroll\";\n\n/**\n * Turns an arrow key into a **logical** step: `+1` for \"next\", `-1` for\n * \"previous\", `0` when the key names neither.\n *\n * APG defines the horizontal pair as *next / previous* and says a vertical\n * arrangement swaps in Down/Up for the same meaning — so the pair is one axis's\n * spelling of an order, and the order reverses with the writing direction. Only\n * the horizontal pair reverses. Down/Up name an axis the writing direction does\n * not mirror, and returning them unchanged is the point: many controllers fold\n * both pairs into one branch, where swapping the branches under RTL would flip\n * the vertical axis too — a bug that reads as \"the arrows work\" until someone\n * presses Down.\n *\n * **Direction is read from the element the caller passes, which should be the\n * container that lays the items out** — not the focused child. A child may carry\n * its own `dir` (an LTR input inside an RTL form is ordinary authoring), and\n * probing per handler makes two handlers disagree at the boundary between them.\n *\n * This decides direction only. Whether the axis is even active (an\n * `orientation=\"horizontal\"` widget ignoring Down/Up), how far the step lands,\n * and what wrapping does all stay with the caller.\n *\n * **It encodes the list-order convention: `ArrowDown` is *next*.** Widgets that\n * pair the arrows by *value* instead — `ArrowUp` meaning \"more\", as a rating or a\n * slider does — must not use this, or their vertical axis inverts. Reverse the\n * horizontal pair on its own there.\n *\n * @example\n * ```ts\n * const step = logicalArrowStep(event.key, this.element);\n * if (step === 0) return;\n * this.#roving.setActive(rovingMove(current, length, step, \"wrap\"), { focus: true });\n * ```\n */\nexport function logicalArrowStep(key: string, element: Element): 1 | -1 | 0 {\n if (key === \"ArrowDown\") return 1;\n if (key === \"ArrowUp\") return -1;\n if (key !== \"ArrowRight\" && key !== \"ArrowLeft\") return 0;\n const forward = isRtl(element) ? \"ArrowLeft\" : \"ArrowRight\";\n return key === forward ? 1 : -1;\n}\n\n/**\n * Rewrites `key` so an existing LTR-shaped branch keeps working under RTL:\n * `ArrowRight` and `ArrowLeft` trade places, everything else passes through.\n *\n * The alternative — negating a delta — silently breaks handlers whose two\n * horizontal branches are **not mirror images**. A grid that clamps one edge but\n * not the other, or a segmented field guarding `index > 0` on one side and\n * `index < length - 1` on the other, ends up applying the wrong guard to the\n * wrong direction. Swapping the key leaves each branch, guards and all, exactly\n * where its author put it.\n *\n * Same rule as {@link logicalArrowStep} about which element to read: pass the\n * container that lays the items out, not the focused child.\n *\n * @example\n * ```ts\n * switch (logicalArrowKey(event.key, this.element)) {\n * case \"ArrowLeft\": // \"previous\" — whatever direction that is on screen\n * ```\n */\nexport function logicalArrowKey(key: string, element: Element): string {\n if (key !== \"ArrowRight\" && key !== \"ArrowLeft\") return key;\n if (!isRtl(element)) return key;\n return key === \"ArrowRight\" ? \"ArrowLeft\" : \"ArrowRight\";\n}\n\n/** Modifiers a widget may claim on an arrow key, named for the `allow` list. */\nexport type ArrowModifier = \"alt\" | \"ctrl\" | \"meta\" | \"shift\";\n\n/**\n * True when an arrow key arrived carrying a modifier the widget must leave to\n * the browser: return without calling `preventDefault()` and without moving any\n * state.\n *\n * A bare arrow belongs to the widget; a chorded one usually does not.\n * `Alt`/`Meta` plus a horizontal arrow is history back/forward on every desktop\n * browser, and a widget that swallows it makes the shortcut work or not\n * depending on where focus happens to sit — a coin-flip the user cannot see.\n *\n * `allow` is for the combinations APG assigns to a pattern **and the widget\n * actually implements** — today only Combobox's optional `Alt+Down`/`Alt+Up`.\n * Listing one the widget does not implement defeats the point: the chord then\n * runs the plain-arrow branch, which is exactly what this guard exists to stop.\n * Non-arrow keys return `false`, so chorded letters and\n * `Control+Home`/`Control+End` are untouched.\n *\n * @example\n * ```ts\n * if (isReservedArrowChord(event)) return;\n * ```\n */\nexport function isReservedArrowChord(\n event: KeyboardEvent,\n allow: readonly ArrowModifier[] = [],\n): boolean {\n if (!event.key.startsWith(\"Arrow\")) return false;\n return (\n (event.altKey && !allow.includes(\"alt\")) ||\n (event.ctrlKey && !allow.includes(\"ctrl\")) ||\n (event.metaKey && !allow.includes(\"meta\")) ||\n (event.shiftKey && !allow.includes(\"shift\"))\n );\n}\n\n/**\n * True when a press arrived carrying any modifier, for the keys the browser and\n * the OS own outright: return without calling `preventDefault()` and without\n * moving any state.\n *\n * `Control+Home` and `Control+End` jump the document to its ends, and a widget\n * that swallows them makes the shortcut work or not depending on where focus\n * happens to sit. {@link isReservedArrowChord} answers the same question for the\n * arrows, but returns `false` for every other key so that this one can decide.\n *\n * There is no `allow` list here on purpose. APG assigns no modifier chord to\n * `Home`/`End`, so a widget that wanted one would be claiming a combination the\n * pattern never gave it.\n *\n * @example\n * ```ts\n * case \"Home\":\n * case \"End\":\n * if (hasModifierChord(event)) return;\n * ```\n */\nexport function hasModifierChord(event: KeyboardEvent): boolean {\n return event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;\n}\n","/** One temporarily controlled attribute value and the authored value it displaced. */\ninterface AttributeLeaseRecord {\n readonly original: string | null;\n written: string | null;\n}\n\n/**\n * Temporarily controls one attribute across a changing set of elements.\n *\n * The first write remembers the authored value, including the distinction between\n * an absent attribute and an authored empty string. Returning a lease restores that\n * value only while the attribute still matches the controller's last write. If a\n * consumer changed it in the meantime, the consumer owns the new value and teardown\n * leaves it alone.\n *\n * A `null` write deliberately removes the attribute while retaining the lease. This\n * is useful for derived ARIA whose valid absence is itself controller state, such as\n * an unbounded `aria-valuemin` or a blank spinbutton's `aria-valuenow`.\n *\n * The lease has no lifecycle of its own, so it never subscribes to document events.\n * A consumer that must not let a derived value become the authored baseline of a\n * cached page returns its leases from its own `turbo:before-cache` rewind, where the\n * matching `disconnect()` also releases the subscription.\n */\nexport class AttributeLease<T extends Element = Element> {\n readonly #attribute: string;\n readonly #records = new Map<T, AttributeLeaseRecord>();\n\n /** @param attribute - The attribute whose temporary values this lease owns. */\n constructor(attribute: string) {\n this.#attribute = attribute;\n }\n\n /** Writes or removes the leased attribute while preserving its authored value. */\n write(element: T, value: string | null): void {\n const existing = this.#records.get(element);\n if (existing) {\n existing.written = value;\n } else {\n this.#records.set(element, {\n original: element.getAttribute(this.#attribute),\n written: value,\n });\n }\n\n this.#reflect(element, value);\n }\n\n /** Returns one lease without overwriting a value subsequently authored by a consumer. */\n return(element: T): void {\n const record = this.#records.get(element);\n if (!record) return;\n this.#records.delete(element);\n const stillOwned = element.getAttribute(this.#attribute) === record.written;\n if (stillOwned) this.#reflect(element, record.original);\n }\n\n /** Reflects only a real value transition, avoiding self-triggered mutation work. */\n #reflect(element: T, value: string | null): void {\n if (element.getAttribute(this.#attribute) === value) return;\n if (value === null) element.removeAttribute(this.#attribute);\n else element.setAttribute(this.#attribute, value);\n }\n\n /** Returns every outstanding lease using the same ownership check as {@link return}. */\n returnAll(): void {\n for (const element of Array.from(this.#records.keys())) this.return(element);\n }\n}\n","/**\n * Runs a controller's \"return to the initial state\" pass just before Turbo\n * caches the page.\n *\n * **`disconnect()` cannot do this job, for two independent reasons.** Turbo\n * queues the clone from this event rather than taking it here, and the body swap\n * that runs the controller's `disconnect()` is queued separately — so which of\n * the two lands first is not something a controller can rely on, and a rewind\n * written in `disconnect()` may reach only the DOM being thrown away. In the\n * other direction, `disconnect()` also fires on an in-page move (Stimulus tears\n * down and reconnects the same element), where rewinding would wipe a\n * legitimately in-progress interaction — a spinner mid-load would vanish. One\n * timing is unreliable, the other is too eager; `turbo:before-cache` is the only\n * point that is exactly \"the page is about to be frozen\".\n *\n * Scope is the subscription only: registering on `activate()`, unregistering on\n * `deactivate()`, and one shared document listener no matter how many instances\n * are live. *What* to return to its initial state — which `data-state`, which\n * `hidden`, which `aria-busy` — stays in the controller, because no two\n * consumers answer it the same way.\n *\n * **Rewind state, not appearance.** The pass writes attributes the controller\n * itself owns; the visual result of those attributes is the consumer's CSS, and\n * a library that reached for style or class names would be guessing at markup\n * it does not own.\n *\n * Both entry points are idempotent, so the lifecycle hooks can call them\n * unconditionally: a second `activate()` does not double-subscribe and does not\n * make the callback run twice, and `deactivate()` on an instance that never\n * subscribed is a no-op.\n *\n * This file's own doc block is dropped from `dist`, but every member comment is\n * inlined into each consumer entry (`tsup` builds with `splitting: false`), so\n * rationale belongs here and only the contract belongs on the members.\n *\n * @example\n * ```ts\n * readonly #beforeCache = new BeforeCacheReset(() => this.#rewind());\n *\n * connect() { this.#beforeCache.activate(); }\n * disconnect() { this.#beforeCache.deactivate(); }\n * ```\n */\nexport class BeforeCacheReset {\n /** Every subscribed instance, iterated by the one shared document listener. */\n static readonly #subscribers = new Set<BeforeCacheReset>();\n\n /** The shared listener; installed while at least one instance is subscribed. */\n static readonly #onBeforeCache = (): void => {\n for (const subscriber of BeforeCacheReset.#subscribers) subscriber.#rewind();\n };\n\n readonly #rewind: () => void;\n\n /** @param rewind - the pass that returns this controller's state to its initial form. */\n constructor(rewind: () => void) {\n this.#rewind = rewind;\n }\n\n /** Subscribes to `turbo:before-cache`; call from `connect()`. Idempotent. */\n activate(): void {\n const first = BeforeCacheReset.#subscribers.size === 0;\n BeforeCacheReset.#subscribers.add(this);\n if (first) {\n document.addEventListener(\"turbo:before-cache\", BeforeCacheReset.#onBeforeCache);\n }\n }\n\n /** Unsubscribes; call from `disconnect()`. Safe when never subscribed. */\n deactivate(): void {\n BeforeCacheReset.#subscribers.delete(this);\n if (BeforeCacheReset.#subscribers.size > 0) return;\n document.removeEventListener(\"turbo:before-cache\", BeforeCacheReset.#onBeforeCache);\n }\n}\n","/** Minimal event shape carrying the platform's per-event composition signal. */\nexport interface CompositionSignal {\n readonly isComposing?: boolean;\n}\n\n/** Hooks that keep component-specific work outside {@link CompositionTracker}. */\nexport interface CompositionTrackerOptions {\n /** Runs after lifecycle state is set for a `compositionstart` event. */\n readonly onStart?: (event: Event) => void;\n /** Runs after lifecycle state is cleared for a `compositionend` event. */\n readonly onEnd?: (event: Event) => void;\n}\n\n/**\n * Owns IME composition listeners and transient state for one or more event targets.\n *\n * Some browsers omit `KeyboardEvent.isComposing` on the keydown that confirms a\n * conversion. Tracking `compositionstart` through `compositionend` supplies the\n * missing lifecycle signal without relying on deprecated numeric key codes.\n * Component policy stays with the consumer: filtering, validation, and submission\n * belong in the optional {@link CompositionTrackerOptions.onEnd} callback.\n *\n * @example\n * ```ts\n * #composition = new CompositionTracker({ onEnd: () => this.filter() });\n *\n * connect(): void {\n * this.#composition.observe(this.inputTarget);\n * }\n *\n * disconnect(): void {\n * this.#composition.disconnect();\n * }\n *\n * onKeydown(event: KeyboardEvent): void {\n * if (this.#composition.isComposing(event)) return;\n * }\n * ```\n */\nexport class CompositionTracker {\n readonly #observedTargets = new Set<EventTarget>();\n readonly #activeTargets = new Set<EventTarget>();\n readonly #onStart: ((event: Event) => void) | undefined;\n readonly #onEnd: ((event: Event) => void) | undefined;\n\n constructor(options: CompositionTrackerOptions = {}) {\n this.#onStart = options.onStart;\n this.#onEnd = options.onEnd;\n }\n\n /** Starts lifecycle tracking for `target`; repeated calls are idempotent. */\n observe(target: EventTarget): void {\n if (this.#observedTargets.has(target)) return;\n target.addEventListener(\"compositionstart\", this.#handleStart);\n target.addEventListener(\"compositionend\", this.#handleEnd);\n this.#observedTargets.add(target);\n }\n\n /** Stops tracking one target and clears any active composition it owned. */\n unobserve(target: EventTarget): void {\n if (!this.#observedTargets.delete(target)) return;\n target.removeEventListener(\"compositionstart\", this.#handleStart);\n target.removeEventListener(\"compositionend\", this.#handleEnd);\n this.#activeTargets.delete(target);\n }\n\n /** Releases every listener and clears state so reconnect starts cleanly. */\n disconnect(): void {\n for (const target of this.#observedTargets) {\n target.removeEventListener(\"compositionstart\", this.#handleStart);\n target.removeEventListener(\"compositionend\", this.#handleEnd);\n }\n this.#observedTargets.clear();\n this.#activeTargets.clear();\n }\n\n /** True when lifecycle tracking or the current event reports composition. */\n isComposing(event?: CompositionSignal): boolean {\n return this.#activeTargets.size > 0 || event?.isComposing === true;\n }\n\n readonly #handleStart = (event: Event): void => {\n if (event.currentTarget) this.#activeTargets.add(event.currentTarget);\n this.#onStart?.(event);\n };\n\n readonly #handleEnd = (event: Event): void => {\n if (event.currentTarget) this.#activeTargets.delete(event.currentTarget);\n this.#onEnd?.(event);\n };\n}\n","/**\n * Readers for the String Values whose text can only be checked by handing it to\n * a parser: a CSS selector, a regular-expression source, a JSON object.\n *\n * Stimulus reads each of them as an ordinary string, so the controller connects\n * and the flaw surfaces later, inside the first handler that consumes the value\n * (a `SyntaxError` from `new RegExp`, a `DOMException` from the selector engine),\n * where it takes the whole handler down on every event. Parsing here, once, in\n * the `<name>ValueChanged` callback keeps the failure local to the declaration:\n * an unreadable value falls back to its default, the element stays alive, and\n * the hot path only ever receives a value that parsed.\n *\n * Which default a broken declaration falls back to is the caller's contract, so\n * every reader takes (or returns) the fallback rather than choosing one.\n */\n\n/**\n * The result of `parse(raw)`, or `fallback` when `parse` throws.\n *\n * Any exception counts as \"does not parse\": the parsers these Values feed\n * (`RegExp`, `JSON.parse`, the selector engine) all report a malformed input by\n * throwing, and none of them throws for another reason.\n */\nexport function parseDeclared<T>(raw: string, parse: (raw: string) => T, fallback: T): T {\n try {\n return parse(raw);\n } catch {\n return fallback;\n }\n}\n\n/** What {@link validSelector} needs of the element it probes with. */\nexport interface SelectorProbe {\n matches(selector: string): boolean;\n}\n\n/**\n * `raw` when it is a non-empty selector the DOM accepts, otherwise `fallback`.\n *\n * `element.matches` is the probe: the engine parses the selector and throws for\n * one it cannot read. Whether the selector actually matches `element` plays no\n * part, so a selector aimed at another element still passes.\n *\n * The parameter names the one method the probe uses rather than `Element`, so\n * this module carries no DOM type and the readers below stay importable from\n * the Node-side Inspector, which checks the same declarations statically.\n */\nexport function validSelector(element: SelectorProbe, raw: string, fallback: string): string {\n if (raw.length === 0) return fallback;\n return parseDeclared(\n raw,\n (selector) => {\n element.matches(selector);\n return selector;\n },\n fallback,\n );\n}\n\n/** How `compileRegExp` wraps a source before compiling it. */\nexport type RegExpAnchor = \"none\" | \"exact\";\n\n/**\n * `source` compiled as a `RegExp`, or `null` when it does not compile.\n *\n * `\"exact\"` wraps the source as `^(?:source)$`, so the whole input has to match\n * and an alternation inside the source cannot escape the anchors. The source is\n * compiled on its own first, because an unbalanced source can be made to parse\n * by the wrapper's own parentheses — `0)|(1` becomes `^(?:0)|(1)$` — which would\n * accept a declaration that is not a regular expression and leave half of it\n * outside the anchors. The default that replaces a broken source is the\n * caller's, so `null` is returned rather than a fallback pattern.\n */\nexport function compileRegExp(source: string, anchor: RegExpAnchor = \"none\"): RegExp | null {\n return parseDeclared(\n source,\n (text) => {\n const bare = new RegExp(text);\n return anchor === \"exact\" ? new RegExp(`^(?:${text})$`) : bare;\n },\n null,\n );\n}\n\n/**\n * The JSON object `raw` declares, or `null` when the text does not parse or\n * parses to something other than a plain object (`null`, an array, a scalar).\n * Values are returned as parsed; narrowing them is the caller's contract.\n */\nexport function parseJsonObject(raw: string): Record<string, unknown> | null {\n const parsed = parseDeclared<unknown>(raw, (text) => JSON.parse(text), null);\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) return null;\n return parsed as Record<string, unknown>;\n}\n","/** The distance between a full-width ASCII code point and its half-width twin. */\nconst FULL_WIDTH_SHIFT = 0xfee0;\n\n/**\n * The half-width form of `char`, or `char` itself when it has none.\n *\n * An IME confirming in full-width mode produces U+FF01–U+FF5E (and U+3000 for\n * the space) where the page means ASCII — the digits of a phone number, the\n * letters of a code, the separators between them. Reading those as their ASCII\n * equivalents keeps confirmed text usable instead of discarding it. Characters\n * outside that block, including kana and astral code points, are returned\n * unchanged, so this never rewrites text a consumer meant to keep as typed.\n */\nexport function halfWidthChar(char: string): string {\n if (char >= \"!\" && char <= \"~\") {\n return String.fromCharCode(char.charCodeAt(0) - FULL_WIDTH_SHIFT);\n }\n return char === \" \" ? \" \" : char;\n}\n\n/** Every full-width ASCII character in `text` rewritten by {@link halfWidthChar}. */\nexport function toHalfWidth(text: string): string {\n let out = \"\";\n for (const char of text) out += halfWidthChar(char);\n return out;\n}\n","/**\n * Collapses many Stimulus lifecycle callbacks from one DOM mutation into a\n * single pass.\n *\n * Stimulus fires `<name>TargetConnected` / `Disconnected` once per element and\n * `<name>ValueChanged` once per changed attribute. Replacing a list of N options\n * or morphing several render Values therefore delivers N callbacks — but the\n * useful unit of work is \"reconcile against the resulting declarative input\",\n * once, after the batch has settled. Every controller with reconcilable targets\n * or render Values needs the same shape: a `queued` flag plus `queueMicrotask`.\n *\n * **A microtask is the right horizon, and the reason is specific.** Stimulus\n * drives these callbacks from a `MutationObserver`, whose own callback already\n * runs as a microtask with the whole batch in hand; scheduling one more lands\n * after the last sibling callback of that batch and still before paint or any\n * event handler. A timer would be later than it needs to be, and reconciling\n * synchronously would run once per element against a half-applied DOM.\n *\n * **The two guards are not the same guard.** Scheduling is refused before the\n * controller connects, and running is refused after it disconnects:\n *\n * - **Before `connect()`** — Stimulus delivers initial target and Value callbacks\n * ahead of `connect()`. Reconciling there would compute output against a\n * controller whose own state has not been initialised, and `connect()` is\n * about to do a full pass anyway.\n * - **After `disconnect()`** — Stimulus fires a callback for **every** target\n * during teardown, and a microtask queued just before it would otherwise run\n * against a detached tree. {@link MicrotaskCoalescer.cancel} exists for the\n * teardown path to drop the pending pass outright.\n *\n * Both guards are part of one contract here rather than something each consumer\n * has to remember separately.\n *\n * Scope is the scheduling only. *What* to reconcile — keep the surviving active\n * option, fall back to the next / previous / first visible one, rebuild derived\n * chips or hidden fields — stays in the controller, because no two consumers\n * answer it the same way.\n *\n * This file's own doc block is dropped from `dist`, but every member comment is\n * inlined into each consumer entry (`tsup` builds with `splitting: false`), so\n * rationale belongs here and only the contract belongs on the members.\n *\n * @example\n * ```ts\n * readonly #reconcile = new MicrotaskCoalescer(() => this.#reconcileOptions());\n *\n * connect() { this.#reconcile.activate(); }\n * disconnect() { this.#reconcile.cancel(); }\n *\n * optionTargetConnected() { this.#reconcile.schedule(); }\n * optionTargetDisconnected() { this.#reconcile.schedule(); }\n * ```\n */\nexport class MicrotaskCoalescer {\n readonly #run: () => void;\n #queued = false;\n #active = false;\n #generation = 0;\n\n /** @param run - the single reconciliation pass, invoked at most once per batch. */\n constructor(run: () => void) {\n this.#run = run;\n }\n\n /** Opens the window in which {@link schedule} is honoured; call from `connect()`. */\n activate(): void {\n this.#active = true;\n }\n\n /** Closes the window and drops any pending pass; call from `disconnect()`. */\n cancel(): void {\n this.#active = false;\n this.#queued = false;\n this.#generation += 1;\n }\n\n /** Requests one pass after the batch settles. Idempotent; inert outside the window. */\n schedule(): void {\n if (!this.#active || this.#queued) return;\n this.#queued = true;\n const generation = this.#generation;\n queueMicrotask(() => {\n // A cancelled callback must not consume a pass queued after reconnect.\n if (generation !== this.#generation || !this.#queued || !this.#active) return;\n this.#queued = false;\n this.#run();\n });\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { ensureId } from \"../utils/aria_ids\";\nimport { isReservedArrowChord, logicalArrowKey } from \"../utils/arrow_step\";\nimport { AttributeLease } from \"../utils/attribute_lease\";\nimport { BeforeCacheReset } from \"../utils/before_cache_reset\";\nimport { CompositionTracker } from \"../utils/composition_tracker\";\nimport { compileRegExp } from \"../utils/declared_value\";\nimport { toHalfWidth } from \"../utils/half_width\";\nimport { MicrotaskCoalescer } from \"../utils/microtask_coalescer\";\n\n/** Single-character pattern used when a `pattern` declaration cannot compile. */\nconst DEFAULT_PATTERN = \"[0-9]\";\n\n/**\n * {@link DEFAULT_PATTERN} compiled, in the same whole-input form\n * `compileRegExp(…, \"exact\")` produces. A literal character class always\n * compiles, so the fallback is a value rather than another parse.\n */\nconst DEFAULT_MATCHER = new RegExp(`^(?:${DEFAULT_PATTERN})$`);\n\n/** Whether a press carries a modifier, which makes it the document's to handle. */\nfunction hasModifier(event: KeyboardEvent): boolean {\n return event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;\n}\n\n/**\n * The controller-derived state a consumer can observe.\n *\n * The combined value alone does not identify it: the same string spread over a\n * different number of fields reads as a different `data-state`, so completeness\n * is carried alongside the value rather than inferred from it.\n */\ninterface OtpState {\n readonly value: string;\n readonly state: string;\n}\n\n/** Compares exactly the derived state the root publishes. */\nfunction statesDiffer(left: OtpState, right: OtpState): boolean {\n return left.value !== right.value || left.state !== right.state;\n}\n\n/**\n * Headless, accessible One-Time Password / PIN input logic.\n *\n * Markup contract (identifier: `stimeo--otp`):\n * <div data-controller=\"stimeo--otp\"\n * data-stimeo--otp-pattern-value=\"[0-9]\"\n * role=\"group\" aria-label=\"One-time passcode\">\n * <input data-stimeo--otp-target=\"field\" inputmode=\"numeric\" maxlength=\"1\"\n * autocomplete=\"one-time-code\" aria-label=\"Digit 1\"\n * data-action=\"input->stimeo--otp#onInput\n * keydown->stimeo--otp#onKeydown\n * paste->stimeo--otp#onPaste\n * pointerdown->stimeo--otp#onPointerDown\" />\n * <!-- repeat one field per digit -->\n * <p data-stimeo--otp-target=\"error\" hidden>Digits only.</p>\n * <input type=\"hidden\" data-stimeo--otp-target=\"value\" name=\"otp\" />\n * </div>\n *\n * The passcode length is the number of connected `field` targets, so nothing has\n * to declare it twice and fields added or removed at runtime are absorbed.\n *\n * Entry rules:\n * - Text carrying more than one accepted character — an OS `one-time-code`\n * autofill, a password manager, an IME committing several digits, a paste —\n * is spread across the following writable fields from the entry point.\n * - `disabled` and `readonly` fields keep their value: they are never written\n * and never receive auto-advance focus, matching what the platform allows a\n * user to do by hand.\n * - Input that lands nowhere rolls the field back to the digit it last\n * committed, and is the only thing that reports `invalid` or reveals the\n * `error` target. Discarding a separator inside otherwise usable text\n * (`\"1234-56\"`) is a successful entry.\n * - Pointing at an empty field ahead of an earlier empty one lands on the\n * earliest empty field instead, so a passcode fills in order. Keyboard focus\n * is never redirected.\n *\n * `change` and `complete` dispatch `{ value: string }` and fire only when the\n * combined value actually moves — one confirmed IME character emits one event,\n * and a passcode re-completed with a different digit reports the new value.\n * State moved by adding or removing fields is the page's doing rather than an\n * edit, so it is reported as `reconcile` with the same `{ value: string }`.\n * Completeness belongs to that state: dropping a trailing empty field completes\n * a passcode whose combined value never moved, and that transition is reported\n * too, so a consumer reading `data-state` is never left behind a silent move.\n * `invalid` dispatches `{ pattern: string }` carrying the compiled pattern.\n *\n * Controller-owned output: `data-filled` on each entered field, `data-state`\n * (`empty` / `partial` / `complete`) on the root, and — while input is being\n * reported invalid — `aria-invalid`, `aria-errormessage`, `aria-describedby`,\n * and the `error` target's `hidden`. Those four are leased, so authored values\n * return on teardown and before the page is cached.\n *\n * @remarks\n * Behavior only. `connect()` reads the fields back as the source of truth, which\n * is what restores consistency after a `type=\"password\"` field returns from the\n * Turbo cache emptied, or after a native form reset. A `pattern` that cannot\n * compile falls back to `[0-9]`; the compiled matcher is built once per\n * declaration rather than per keystroke.\n */\nexport class OtpController extends Controller<HTMLElement> {\n static override targets = [\"field\", \"value\", \"error\"];\n static override values = {\n pattern: { type: String, default: DEFAULT_PATTERN },\n };\n static actions = [\"onInput\", \"onKeydown\", \"onPaste\", \"onPointerDown\", \"clear\"] as const;\n static events = [\"change\", \"complete\", \"invalid\", \"reconcile\"] as const;\n\n declare readonly fieldTargets: HTMLInputElement[];\n declare readonly valueTarget: HTMLInputElement;\n declare readonly errorTarget: HTMLElement;\n declare readonly hasValueTarget: boolean;\n declare readonly hasErrorTarget: boolean;\n\n declare patternValue: string;\n\n /** Validated matcher; the hot path never compiles a raw declaration. */\n #pattern = DEFAULT_MATCHER;\n /** Source of {@link #pattern}, reported in `invalid` so consumers can word it. */\n #patternSource = DEFAULT_PATTERN;\n /** Public state carried by the last dispatch; keeps a no-op sync silent. */\n #published: OtpState | null = null;\n /** Field whose confirming `input` after `compositionend` is already handled. */\n #confirmedField: HTMLInputElement | null = null;\n /** True between connect and disconnect, so pre-connect Value changes stay silent. */\n #connected = false;\n /** Digit each field last committed, restored when rejected input replaced it. */\n readonly #committed = new WeakMap<HTMLInputElement, string>();\n\n /** Collapses one batch of field target callbacks into a single reconciliation. */\n readonly #reconcile = new MicrotaskCoalescer(() => this.#reconcileFields());\n\n readonly #ariaInvalid = new AttributeLease<HTMLInputElement>(\"aria-invalid\");\n readonly #ariaErrorMessage = new AttributeLease<HTMLInputElement>(\"aria-errormessage\");\n readonly #ariaDescribedBy = new AttributeLease<HTMLInputElement>(\"aria-describedby\");\n readonly #errorHidden = new AttributeLease<HTMLElement>(\"hidden\");\n readonly #state = new AttributeLease<HTMLElement>(\"data-state\");\n\n /** Rewinds the transient error surface before Turbo freezes the page. */\n readonly #beforeCache = new BeforeCacheReset(() => this.#clearError());\n\n /** Owns IME lifecycle state across every digit field. */\n readonly #composition = new CompositionTracker({\n onStart: () => {\n this.#confirmedField = null;\n },\n onEnd: (event) => {\n const input = this.#fieldFrom(event);\n if (!input) return;\n // The browser follows a commit with one more `input` carrying the same\n // text; marking the field lets that echo be dropped instead of rerun.\n this.#confirmedField = input;\n // `maxlength` has already cut the field down to one character, but the\n // commit itself carries the whole confirmed string — so a conversion that\n // ends in several characters still reaches the fields after this one.\n const committed = (event as CompositionEvent).data ?? \"\";\n this.#accept(input, committed.length > input.value.length ? committed : input.value);\n },\n });\n\n override connect(): void {\n this.#connected = true;\n for (const field of this.fieldTargets) this.#bind(field);\n document.addEventListener(\"reset\", this.#onReset, true);\n this.#beforeCache.activate();\n this.#reconcile.activate();\n this.#adopt();\n this.#sync();\n }\n\n override disconnect(): void {\n this.#connected = false;\n for (const field of this.fieldTargets) this.#unbind(field);\n this.#composition.disconnect();\n document.removeEventListener(\"reset\", this.#onReset, true);\n this.#beforeCache.deactivate();\n this.#reconcile.cancel();\n this.#clearError();\n this.#state.return(this.element);\n }\n\n /**\n * Stimulus lifecycle callback when a new field target enters the DOM.\n * Wires the new field and folds the wider digit count into one reconciliation,\n * which stays inert until `connect()` opens the window.\n */\n fieldTargetConnected(element: HTMLInputElement): void {\n this.#bind(element);\n this.#adoptField(element);\n this.#reconcile.schedule();\n }\n\n /** Releases a dropped field's listeners and leases, then reconciles the rest. */\n fieldTargetDisconnected(element: HTMLInputElement): void {\n this.#unbind(element);\n this.#returnFieldLeases(element);\n this.#reconcile.schedule();\n }\n\n /**\n * Re-validates a changed `pattern` declaration once and drops any entered digit\n * the new pattern no longer accepts, so the combined value stays interpretable.\n */\n patternValueChanged(): void {\n const compiled = compileRegExp(this.patternValue, \"exact\");\n this.#patternSource = compiled ? this.patternValue : DEFAULT_PATTERN;\n this.#pattern = compiled ?? DEFAULT_MATCHER;\n if (!this.#connected) return;\n\n let dropped = false;\n for (const field of this.fieldTargets) {\n if (field.value === \"\" || !this.#isWritable(field)) continue;\n if (this.#pattern.test(field.value)) continue;\n this.#writeField(field, \"\");\n dropped = true;\n }\n if (dropped) this.#syncAndDispatch();\n }\n\n /** Handles keystroke inputs, distributes autofilled text, and advances focus. */\n onInput(event: Event): void {\n const input = this.#fieldFrom(event);\n if (!input) return;\n\n const confirmed = this.#confirmedField;\n this.#confirmedField = null;\n if (confirmed === input) return;\n\n // Guard during active composition to prevent premature focus switching\n if (this.#composition.isComposing(event as InputEvent)) return;\n\n this.#accept(input);\n }\n\n /** Handles Backspace clearing, arrows, and home/end navigation. */\n onKeydown(event: KeyboardEvent): void {\n if (isReservedArrowChord(event)) return;\n const input = this.#fieldFrom(event);\n if (!input) return;\n\n // A keyed edit always starts with this event, so no post-commit echo is pending\n this.#confirmedField = null;\n // Do not trigger keydown actions during composition\n if (this.#composition.isComposing(event)) return;\n\n const index = this.fieldTargets.indexOf(input);\n const fields = this.fieldTargets;\n // Logical, not physical. The key is normalised rather than the\n // delta negated: these two branches are not mirror images — their bounds\n // guards differ — so swapping the key keeps each guard with its own direction.\n\n switch (logicalArrowKey(event.key, this.element)) {\n case \"Backspace\":\n if (hasModifier(event)) break;\n if (input.value && this.#isWritable(input)) {\n // Filled field: clear it where it stands\n event.preventDefault();\n this.#writeField(input, \"\");\n this.#clearError();\n this.#syncAndDispatch();\n } else {\n // Empty field: step back to the previous writable digit and wipe it\n const previous = this.#writableBefore(index);\n if (previous) {\n event.preventDefault();\n this.#writeField(previous, \"\");\n previous.focus();\n this.#clearError();\n this.#syncAndDispatch();\n }\n }\n break;\n\n case \"ArrowLeft\": {\n const previous = this.#focusableBefore(index);\n if (previous) {\n event.preventDefault();\n previous.focus();\n }\n break;\n }\n\n case \"ArrowRight\": {\n const next = this.#focusableAfter(index);\n if (next) {\n event.preventDefault();\n next.focus();\n }\n break;\n }\n\n case \"Home\": {\n // Control+Home belongs to the document, not to the digit group\n if (hasModifier(event)) break;\n const first = fields.find((field) => this.#isFocusable(field));\n if (first) {\n event.preventDefault();\n first.focus();\n }\n break;\n }\n\n case \"End\": {\n if (hasModifier(event)) break;\n const last = fields\n .slice()\n .reverse()\n .find((field) => this.#isFocusable(field));\n if (last) {\n event.preventDefault();\n last.focus();\n }\n break;\n }\n\n default:\n break;\n }\n }\n\n /** Divides pasted string characters across the available input fields. */\n onPaste(event: ClipboardEvent): void {\n const input = this.#fieldFrom(event);\n if (!input) return;\n\n event.preventDefault();\n this.#confirmedField = null;\n this.#distribute(input, toHalfWidth(event.clipboardData?.getData(\"text\") ?? \"\"));\n }\n\n /**\n * Redirects a pointer landing on an empty field to the earliest empty one, so\n * a passcode is entered in order. Filled fields stay directly reachable for\n * correction, and keyboard focus is left alone.\n */\n onPointerDown(event: Event): void {\n const input = this.#fieldFrom(event);\n if (input?.value !== \"\") return;\n\n const first = this.fieldTargets.find((field) => this.#isWritable(field) && field.value === \"\");\n if (!first || first === input) return;\n\n event.preventDefault();\n first.focus();\n }\n\n /** Empties every writable field and restarts entry at the first of them. */\n clear(): void {\n for (const field of this.fieldTargets) {\n if (this.#isWritable(field)) this.#writeField(field, \"\");\n }\n this.#clearError();\n this.fieldTargets.find((field) => this.#isWritable(field))?.focus();\n this.#syncAndDispatch();\n }\n\n readonly #onFieldFocus = (event: FocusEvent): void => {\n const input = event.currentTarget as HTMLInputElement | null;\n if (input) {\n // Auto-selection enables effortless character overwrites\n input.select();\n }\n };\n\n /** Reconciles derived state after a non-cancelled reset restores the fields. */\n readonly #onReset = (event: Event): void => {\n const form = event.target;\n if (!(form instanceof HTMLFormElement) || !this.#ownedBy(form)) return;\n queueMicrotask(() => {\n if (event.defaultPrevented) return;\n this.#adopt();\n this.#syncAndDispatch();\n });\n };\n\n /** Whether a form owns at least one field or the hidden combined value. */\n #ownedBy(form: HTMLFormElement): boolean {\n if (this.fieldTargets.some((field) => field.form === form)) return true;\n return this.hasValueTarget && this.valueTarget.form === form;\n }\n\n #bind(field: HTMLInputElement): void {\n field.addEventListener(\"focus\", this.#onFieldFocus);\n this.#composition.observe(field);\n }\n\n #unbind(field: HTMLInputElement): void {\n field.removeEventListener(\"focus\", this.#onFieldFocus);\n this.#composition.unobserve(field);\n if (this.#confirmedField === field) this.#confirmedField = null;\n }\n\n /** Reads every field back so a restored or reset group starts consistent. */\n #adopt(): void {\n for (const field of this.fieldTargets) this.#adoptField(field);\n this.#clearError();\n // Nothing has been rejected yet, whatever visibility the restored DOM carries\n if (this.hasErrorTarget) this.errorTarget.setAttribute(\"hidden\", \"\");\n }\n\n /** Takes one field's current value as the truth behind its derived state. */\n #adoptField(field: HTMLInputElement): void {\n this.#committed.set(field, field.value);\n this.#markFilled(field, field.value);\n }\n\n /**\n * Absorbs a batch of field additions or removals as one state transition.\n *\n * The page, not the user, moved the state here, so it is reported as\n * `reconcile`: automation listening for `change` must not read a re-render as\n * an edit, and a passcode that happens to end up full must not fire the\n * `complete` that submits it.\n *\n * Completeness moves on its own when the field count changes: dropping a\n * trailing empty field completes a passcode whose combined value never moved,\n * and adding one un-completes it. Comparing the whole derived state, not the\n * string it contains, is what makes those transitions reportable.\n */\n #reconcileFields(): void {\n const previous = this.#published;\n const current = this.#sync();\n if (previous && !statesDiffer(previous, current)) return;\n this.dispatch(\"reconcile\", { detail: { value: current.value } });\n }\n\n /**\n * Validates the text an entry point received and distributes what it accepts.\n * `text` defaults to the field's own value; a confirmation passes the string it\n * committed, which `maxlength` would otherwise have truncated.\n */\n #accept(input: HTMLInputElement, text: string = input.value): void {\n const raw = toHalfWidth(text);\n if (raw === \"\") {\n // Emptying a field is a legitimate edit, not rejected input\n this.#writeField(input, \"\");\n this.#clearError();\n this.#syncAndDispatch();\n return;\n }\n\n this.#distribute(input, raw);\n }\n\n /**\n * Fills `text`'s accepted characters into the writable fields at and after the\n * entry point, then leaves focus on the field after the last one filled.\n */\n #distribute(from: HTMLInputElement, text: string): void {\n const accepted = Array.from(text).filter((char) => this.#pattern.test(char));\n let reached = false;\n const slots = this.fieldTargets.filter((field) => {\n reached ||= field === from;\n return reached && this.#isWritable(field);\n });\n const filled = Math.min(accepted.length, slots.length);\n\n if (filled === 0) {\n // Nothing landed: restore the digit the entry point had committed\n this.#restore(from);\n this.#showError();\n this.#sync();\n return;\n }\n\n for (let i = 0; i < filled; i++) {\n const field = slots[i];\n const char = accepted[i];\n if (field && char) this.#writeField(field, char);\n }\n\n const last = slots[filled - 1];\n if (last) (this.#writableAfter(last) ?? last).focus();\n\n this.#clearError();\n this.#syncAndDispatch();\n }\n\n /** Restores the digit a field committed before rejected input replaced it. */\n #restore(field: HTMLInputElement): void {\n this.#writeField(field, this.#committed.get(field) ?? \"\");\n }\n\n /** Commits one field's value and the derived hook that reports it as entered. */\n #writeField(field: HTMLInputElement, value: string): void {\n field.value = value;\n this.#committed.set(field, value);\n this.#markFilled(field, value);\n }\n\n #markFilled(field: HTMLInputElement, value: string): void {\n if (value) field.setAttribute(\"data-filled\", \"true\");\n else field.removeAttribute(\"data-filled\");\n }\n\n #isWritable(field: HTMLInputElement): boolean {\n return !field.disabled && !field.readOnly;\n }\n\n #isFocusable(field: HTMLInputElement): boolean {\n return !field.disabled;\n }\n\n #writableAfter(field: HTMLInputElement): HTMLInputElement | null {\n const fields = this.fieldTargets;\n return fields.slice(fields.indexOf(field) + 1).find((next) => this.#isWritable(next)) ?? null;\n }\n\n #writableBefore(index: number): HTMLInputElement | null {\n return this.#before(index).find((field) => this.#isWritable(field)) ?? null;\n }\n\n #focusableAfter(index: number): HTMLInputElement | null {\n return this.fieldTargets.slice(index + 1).find((field) => this.#isFocusable(field)) ?? null;\n }\n\n #focusableBefore(index: number): HTMLInputElement | null {\n return this.#before(index).find((field) => this.#isFocusable(field)) ?? null;\n }\n\n /** Fields before `index`, nearest first; empty at the first field. */\n #before(index: number): HTMLInputElement[] {\n return this.fieldTargets.slice(0, Math.max(index, 0)).reverse();\n }\n\n /** The event's field target, or `null` when the wiring points somewhere else. */\n #fieldFrom(event: Event): HTMLInputElement | null {\n const input = event.currentTarget;\n return this.fieldTargets.find((field) => field === input) ?? null;\n }\n\n #combinedValue(): string {\n return this.fieldTargets.map((field) => field.value).join(\"\");\n }\n\n /** Every field carries a character, and there is at least one field. */\n #isComplete(): boolean {\n const fields = this.fieldTargets;\n return fields.length > 0 && fields.every((field) => field.value.length > 0);\n }\n\n /**\n * Mirrors the combined value into the form and the root's readable state, and\n * records what was published so the next pass can compare against it.\n */\n #sync(): OtpState {\n const combined = this.#combinedValue();\n\n if (this.hasValueTarget) {\n this.valueTarget.value = combined;\n }\n const state = this.#stateName(combined);\n this.#state.write(this.element, state);\n\n const published: OtpState = { value: combined, state };\n this.#published = published;\n return published;\n }\n\n #stateName(combined: string): string {\n if (combined.length === 0) return \"empty\";\n return this.#isComplete() ? \"complete\" : \"partial\";\n }\n\n #syncAndDispatch(): void {\n const previous = this.#published;\n const { value: combined } = this.#sync();\n if (previous?.value === combined) return;\n\n this.dispatch(\"change\", { detail: { value: combined } });\n\n // Completed state when every field carries a character\n if (this.#isComplete()) {\n this.dispatch(\"complete\", { detail: { value: combined } });\n }\n }\n\n /** Surfaces rejected input on every field and on the optional error target. */\n #showError(): void {\n const errorId = this.hasErrorTarget ? ensureId(this.errorTarget, \"stimeo--otp-error\") : null;\n\n for (const field of this.fieldTargets) {\n this.#ariaInvalid.write(field, \"true\");\n if (!errorId) continue;\n this.#ariaErrorMessage.write(field, errorId);\n // Assistive tech without aria-errormessage support still reads a description\n this.#ariaDescribedBy.write(field, this.#describedByWith(field, errorId));\n }\n if (this.hasErrorTarget) this.#errorHidden.write(this.errorTarget, null);\n\n // Behavior only: emit a neutral payload and let the consumer compose/localize\n // the user-facing message. The pattern is reported so consumers can word it.\n this.dispatch(\"invalid\", { detail: { pattern: this.#patternSource } });\n }\n\n /** Returns every error lease, restoring the authored error surface. */\n #clearError(): void {\n this.#ariaInvalid.returnAll();\n this.#ariaErrorMessage.returnAll();\n this.#ariaDescribedBy.returnAll();\n this.#errorHidden.returnAll();\n }\n\n #returnFieldLeases(field: HTMLInputElement): void {\n this.#ariaInvalid.return(field);\n this.#ariaErrorMessage.return(field);\n this.#ariaDescribedBy.return(field);\n }\n\n /** The field's own description tokens with the error id appended once. */\n #describedByWith(field: HTMLInputElement, errorId: string): string {\n const tokens = (field.getAttribute(\"aria-describedby\") ?? \"\")\n .split(/\\s+/)\n .filter((token) => token.length > 0 && token !== errorId);\n return [...tokens, errorId].join(\" \");\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/aria_ids.ts","../../src/utils/logical_scroll.ts","../../src/utils/arrow_step.ts","../../src/utils/attribute_lease.ts","../../src/utils/before_cache_reset.ts","../../src/utils/composition_tracker.ts","../../src/utils/declared_value.ts","../../src/utils/form_reset_watcher.ts","../../src/utils/half_width.ts","../../src/utils/microtask_coalescer.ts","../../src/controllers/otp_controller.ts"],"names":[],"mappings":"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","file":"otp_controller.js","sourcesContent":["/**\n * Minimal id primitives for wiring ARIA relationships.\n *\n * Accessible relationships such as `aria-describedby`, `aria-errormessage`,\n * `aria-labelledby`, and `aria-activedescendant` reference their targets by DOM\n * `id`. When a controller must establish such a relationship but the consumer's\n * markup left the target without an `id`, it needs to mint one that is stable for\n * the page's lifetime and guaranteed not to collide with another generated id.\n *\n * These helpers own *only* id generation/assignment. The linking policy (which\n * attribute, what order, when to add or remove it) stays in each controller —\n * this deliberately avoids a premature generic \"ARIA linker\" abstraction.\n */\n\n/**\n * Monotonic counter backing {@link uniqueId}. Module-scoped so every generated\n * id is unique across all controller instances sharing this module in a document.\n */\nlet counter = 0;\n\n/**\n * Returns a unique, DOM-id-safe string of the form `` `${prefix}-${n}` `` where\n * `n` increases on each call.\n *\n * The counter alone guarantees uniqueness against other *generated* ids, but a\n * consumer-authored element could already own `` `${prefix}-${n}` ``. When a\n * `document` is available the candidate is therefore advanced until no element\n * with that id exists, so a generated id never collides with author markup\n * either — the minimal \"id registry\" guarantee these helpers exist to provide.\n *\n * @param prefix - Leading segment of the id (e.g. a controller's identifier).\n * Defaults to `\"stimeo\"`.\n */\nexport function uniqueId(prefix = \"stimeo\"): string {\n let candidate: string;\n do {\n counter += 1;\n candidate = `${prefix}-${counter}`;\n } while (typeof document !== \"undefined\" && document.getElementById(candidate) !== null);\n return candidate;\n}\n\n/**\n * Returns `element`'s existing `id`, or assigns it a freshly generated\n * {@link uniqueId} (with the given `prefix`) and returns that. Idempotent: an\n * element that already has an id keeps it, so consumer-authored ids are never\n * overwritten.\n *\n * @param element - The element to read or stamp an `id` onto.\n * @param prefix - Prefix forwarded to {@link uniqueId} when one must be generated.\n * @returns The element's id (existing or newly assigned).\n */\nexport function ensureId(element: Element, prefix = \"stimeo\"): string {\n if (element.id) return element.id;\n const id = uniqueId(prefix);\n element.id = id;\n return id;\n}\n","/** Normalized scroll position and maximum distance on one logical axis. */\nexport interface LogicalScrollMetrics {\n position: number;\n max: number;\n}\n\n/**\n * Whether horizontal scrolling on `element` follows right-to-left inline flow.\n *\n * Resolved from the **computed** `direction`, so the authoring contract is the\n * usual `dir=\"rtl\"` (or a stylesheet) on the element or any ancestor.\n *\n * Scope: horizontal writing modes. A vertical writing mode (`writing-mode:\n * vertical-rl`) also inverts the horizontal axis, which this check does not\n * model — vertical writing modes are out of scope for the scroll utilities\n * (their consumers describe axes as horizontal/vertical, not inline/block).\n */\nexport function isRtl(element: Element): boolean {\n return window.getComputedStyle(element).direction === \"rtl\";\n}\n\n/**\n * Returns scroll distance from the logical start edge.\n *\n * CSSOM View exposes standards-mode RTL horizontal offsets as `0` at the inline\n * start (right) and increasingly negative values toward the inline end (left).\n * The normalized position is always clamped to `[0, max]`, which also absorbs\n * Safari's elastic overscroll values.\n */\nexport function logicalScrollMetrics(\n element: HTMLElement,\n horizontal: boolean,\n): LogicalScrollMetrics {\n const max = Math.max(\n 0,\n horizontal\n ? element.scrollWidth - element.clientWidth\n : element.scrollHeight - element.clientHeight,\n );\n const raw = horizontal ? element.scrollLeft : element.scrollTop;\n const position = horizontal && isRtl(element) ? -raw : raw;\n return { position: Math.min(max, Math.max(0, position)), max };\n}\n\n/**\n * Converts a logical start/end delta to the physical value accepted by\n * `Element.scrollBy`.\n */\nexport function physicalScrollDelta(\n element: HTMLElement,\n horizontal: boolean,\n logicalDelta: number,\n): number {\n return horizontal && isRtl(element) ? -logicalDelta : logicalDelta;\n}\n","import { isRtl } from \"./logical_scroll\";\n\n/**\n * Turns an arrow key into a **logical** step: `+1` for \"next\", `-1` for\n * \"previous\", `0` when the key names neither.\n *\n * APG defines the horizontal pair as *next / previous* and says a vertical\n * arrangement swaps in Down/Up for the same meaning — so the pair is one axis's\n * spelling of an order, and the order reverses with the writing direction. Only\n * the horizontal pair reverses. Down/Up name an axis the writing direction does\n * not mirror, and returning them unchanged is the point: many controllers fold\n * both pairs into one branch, where swapping the branches under RTL would flip\n * the vertical axis too — a bug that reads as \"the arrows work\" until someone\n * presses Down.\n *\n * **Direction is read from the element the caller passes, which should be the\n * container that lays the items out** — not the focused child. A child may carry\n * its own `dir` (an LTR input inside an RTL form is ordinary authoring), and\n * probing per handler makes two handlers disagree at the boundary between them.\n *\n * This decides direction only. Whether the axis is even active (an\n * `orientation=\"horizontal\"` widget ignoring Down/Up), how far the step lands,\n * and what wrapping does all stay with the caller.\n *\n * **It encodes the list-order convention: `ArrowDown` is *next*.** Widgets that\n * pair the arrows by *value* instead — `ArrowUp` meaning \"more\", as a rating or a\n * slider does — must not use this, or their vertical axis inverts. Reverse the\n * horizontal pair on its own there.\n *\n * @example\n * ```ts\n * const step = logicalArrowStep(event.key, this.element);\n * if (step === 0) return;\n * this.#roving.setActive(rovingMove(current, length, step, \"wrap\"), { focus: true });\n * ```\n */\nexport function logicalArrowStep(key: string, element: Element): 1 | -1 | 0 {\n if (key === \"ArrowDown\") return 1;\n if (key === \"ArrowUp\") return -1;\n if (key !== \"ArrowRight\" && key !== \"ArrowLeft\") return 0;\n const forward = isRtl(element) ? \"ArrowLeft\" : \"ArrowRight\";\n return key === forward ? 1 : -1;\n}\n\n/**\n * Rewrites `key` so an existing LTR-shaped branch keeps working under RTL:\n * `ArrowRight` and `ArrowLeft` trade places, everything else passes through.\n *\n * The alternative — negating a delta — silently breaks handlers whose two\n * horizontal branches are **not mirror images**. A grid that clamps one edge but\n * not the other, or a segmented field guarding `index > 0` on one side and\n * `index < length - 1` on the other, ends up applying the wrong guard to the\n * wrong direction. Swapping the key leaves each branch, guards and all, exactly\n * where its author put it.\n *\n * Same rule as {@link logicalArrowStep} about which element to read: pass the\n * container that lays the items out, not the focused child.\n *\n * @example\n * ```ts\n * switch (logicalArrowKey(event.key, this.element)) {\n * case \"ArrowLeft\": // \"previous\" — whatever direction that is on screen\n * ```\n */\nexport function logicalArrowKey(key: string, element: Element): string {\n if (key !== \"ArrowRight\" && key !== \"ArrowLeft\") return key;\n if (!isRtl(element)) return key;\n return key === \"ArrowRight\" ? \"ArrowLeft\" : \"ArrowRight\";\n}\n\n/** Modifiers a widget may claim on an arrow key, named for the `allow` list. */\nexport type ArrowModifier = \"alt\" | \"ctrl\" | \"meta\" | \"shift\";\n\n/**\n * True when an arrow key arrived carrying a modifier the widget must leave to\n * the browser: return without calling `preventDefault()` and without moving any\n * state.\n *\n * A bare arrow belongs to the widget; a chorded one usually does not.\n * `Alt`/`Meta` plus a horizontal arrow is history back/forward on every desktop\n * browser, and a widget that swallows it makes the shortcut work or not\n * depending on where focus happens to sit — a coin-flip the user cannot see.\n *\n * `allow` is for the combinations APG assigns to a pattern **and the widget\n * actually implements** — today only Combobox's optional `Alt+Down`/`Alt+Up`.\n * Listing one the widget does not implement defeats the point: the chord then\n * runs the plain-arrow branch, which is exactly what this guard exists to stop.\n * Non-arrow keys return `false`, so chorded letters and\n * `Control+Home`/`Control+End` are untouched.\n *\n * @example\n * ```ts\n * if (isReservedArrowChord(event)) return;\n * ```\n */\nexport function isReservedArrowChord(\n event: KeyboardEvent,\n allow: readonly ArrowModifier[] = [],\n): boolean {\n if (!event.key.startsWith(\"Arrow\")) return false;\n return (\n (event.altKey && !allow.includes(\"alt\")) ||\n (event.ctrlKey && !allow.includes(\"ctrl\")) ||\n (event.metaKey && !allow.includes(\"meta\")) ||\n (event.shiftKey && !allow.includes(\"shift\"))\n );\n}\n\n/**\n * True when a press arrived carrying any modifier, for the keys the browser and\n * the OS own outright: return without calling `preventDefault()` and without\n * moving any state.\n *\n * `Control+Home` and `Control+End` jump the document to its ends, and a widget\n * that swallows them makes the shortcut work or not depending on where focus\n * happens to sit. {@link isReservedArrowChord} answers the same question for the\n * arrows, but returns `false` for every other key so that this one can decide.\n *\n * There is no `allow` list here on purpose. APG assigns no modifier chord to\n * `Home`/`End`, so a widget that wanted one would be claiming a combination the\n * pattern never gave it.\n *\n * @example\n * ```ts\n * case \"Home\":\n * case \"End\":\n * if (hasModifierChord(event)) return;\n * ```\n */\nexport function hasModifierChord(event: KeyboardEvent): boolean {\n return event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;\n}\n","/** One temporarily controlled attribute value and the authored value it displaced. */\ninterface AttributeLeaseRecord {\n readonly original: string | null;\n written: string | null;\n}\n\n/**\n * Temporarily controls one attribute across a changing set of elements.\n *\n * The first write remembers the authored value, including the distinction between\n * an absent attribute and an authored empty string. Returning a lease restores that\n * value only while the attribute still matches the controller's last write. If a\n * consumer changed it in the meantime, the consumer owns the new value and teardown\n * leaves it alone.\n *\n * A `null` write deliberately removes the attribute while retaining the lease. This\n * is useful for derived ARIA whose valid absence is itself controller state, such as\n * an unbounded `aria-valuemin` or a blank spinbutton's `aria-valuenow`.\n *\n * The lease has no lifecycle of its own, so it never subscribes to document events.\n * A consumer that must not let a derived value become the authored baseline of a\n * cached page returns its leases from its own `turbo:before-cache` rewind, where the\n * matching `disconnect()` also releases the subscription.\n */\nexport class AttributeLease<T extends Element = Element> {\n readonly #attribute: string;\n readonly #records = new Map<T, AttributeLeaseRecord>();\n\n /** @param attribute - The attribute whose temporary values this lease owns. */\n constructor(attribute: string) {\n this.#attribute = attribute;\n }\n\n /** Writes or removes the leased attribute while preserving its authored value. */\n write(element: T, value: string | null): void {\n const existing = this.#records.get(element);\n if (existing) {\n existing.written = value;\n } else {\n this.#records.set(element, {\n original: element.getAttribute(this.#attribute),\n written: value,\n });\n }\n\n this.#reflect(element, value);\n }\n\n /** Returns one lease without overwriting a value subsequently authored by a consumer. */\n return(element: T): void {\n const record = this.#records.get(element);\n if (!record) return;\n this.#records.delete(element);\n const stillOwned = element.getAttribute(this.#attribute) === record.written;\n if (stillOwned) this.#reflect(element, record.original);\n }\n\n /** Reflects only a real value transition, avoiding self-triggered mutation work. */\n #reflect(element: T, value: string | null): void {\n if (element.getAttribute(this.#attribute) === value) return;\n if (value === null) element.removeAttribute(this.#attribute);\n else element.setAttribute(this.#attribute, value);\n }\n\n /** Returns every outstanding lease using the same ownership check as {@link return}. */\n returnAll(): void {\n for (const element of Array.from(this.#records.keys())) this.return(element);\n }\n}\n","/**\n * Runs a controller's \"return to the initial state\" pass just before Turbo\n * caches the page.\n *\n * **`disconnect()` cannot do this job, for two independent reasons.** Turbo\n * queues the clone from this event rather than taking it here, and the body swap\n * that runs the controller's `disconnect()` is queued separately — so which of\n * the two lands first is not something a controller can rely on, and a rewind\n * written in `disconnect()` may reach only the DOM being thrown away. In the\n * other direction, `disconnect()` also fires on an in-page move (Stimulus tears\n * down and reconnects the same element), where rewinding would wipe a\n * legitimately in-progress interaction — a spinner mid-load would vanish. One\n * timing is unreliable, the other is too eager; `turbo:before-cache` is the only\n * point that is exactly \"the page is about to be frozen\".\n *\n * Scope is the subscription only: registering on `activate()`, unregistering on\n * `deactivate()`, and one shared document listener no matter how many instances\n * are live. *What* to return to its initial state — which `data-state`, which\n * `hidden`, which `aria-busy` — stays in the controller, because no two\n * consumers answer it the same way.\n *\n * **Rewind state, not appearance.** The pass writes attributes the controller\n * itself owns; the visual result of those attributes is the consumer's CSS, and\n * a library that reached for style or class names would be guessing at markup\n * it does not own.\n *\n * Both entry points are idempotent, so the lifecycle hooks can call them\n * unconditionally: a second `activate()` does not double-subscribe and does not\n * make the callback run twice, and `deactivate()` on an instance that never\n * subscribed is a no-op.\n *\n * This file's own doc block is dropped from `dist`, but every member comment is\n * inlined into each consumer entry (`tsup` builds with `splitting: false`), so\n * rationale belongs here and only the contract belongs on the members.\n *\n * @example\n * ```ts\n * readonly #beforeCache = new BeforeCacheReset(() => this.#rewind());\n *\n * connect() { this.#beforeCache.activate(); }\n * disconnect() { this.#beforeCache.deactivate(); }\n * ```\n */\nexport class BeforeCacheReset {\n /** Every subscribed instance, iterated by the one shared document listener. */\n static readonly #subscribers = new Set<BeforeCacheReset>();\n\n /** The shared listener; installed while at least one instance is subscribed. */\n static readonly #onBeforeCache = (): void => {\n for (const subscriber of BeforeCacheReset.#subscribers) subscriber.#rewind();\n };\n\n readonly #rewind: () => void;\n\n /** @param rewind - the pass that returns this controller's state to its initial form. */\n constructor(rewind: () => void) {\n this.#rewind = rewind;\n }\n\n /** Subscribes to `turbo:before-cache`; call from `connect()`. Idempotent. */\n activate(): void {\n const first = BeforeCacheReset.#subscribers.size === 0;\n BeforeCacheReset.#subscribers.add(this);\n if (first) {\n document.addEventListener(\"turbo:before-cache\", BeforeCacheReset.#onBeforeCache);\n }\n }\n\n /** Unsubscribes; call from `disconnect()`. Safe when never subscribed. */\n deactivate(): void {\n BeforeCacheReset.#subscribers.delete(this);\n if (BeforeCacheReset.#subscribers.size > 0) return;\n document.removeEventListener(\"turbo:before-cache\", BeforeCacheReset.#onBeforeCache);\n }\n}\n","/** Minimal event shape carrying the platform's per-event composition signal. */\nexport interface CompositionSignal {\n readonly isComposing?: boolean;\n}\n\n/** Minimal `input` shape needed to tell a composition echo from a fresh edit. */\nexport interface ConfirmedInputSignal {\n readonly target: EventTarget | null;\n readonly inputType?: string;\n}\n\n/**\n * The `inputType` values an engine reports on an `input` that belongs to a\n * composition rather than to an edit the user just made.\n */\nconst COMPOSITION_INPUT_TYPES = new Set([\n \"insertCompositionText\",\n \"insertFromComposition\",\n \"deleteCompositionText\",\n \"deleteByComposition\",\n]);\n\n/** Hooks that keep component-specific work outside {@link CompositionTracker}. */\nexport interface CompositionTrackerOptions {\n /** Runs after lifecycle state is set for a `compositionstart` event. */\n readonly onStart?: (event: Event) => void;\n /** Runs after lifecycle state is cleared for a `compositionend` event. */\n readonly onEnd?: (event: Event) => void;\n}\n\n/**\n * Owns IME composition listeners and transient state for one or more event targets.\n *\n * Some browsers omit `KeyboardEvent.isComposing` on the keydown that confirms a\n * conversion. Tracking `compositionstart` through `compositionend` supplies the\n * missing lifecycle signal without relying on deprecated numeric key codes.\n * Component policy stays with the consumer: filtering, validation, and submission\n * belong in the optional {@link CompositionTrackerOptions.onEnd} callback.\n *\n * The tracker also owns the other half of that lifecycle: **the `input` some\n * engines send after `compositionend` to echo the text just confirmed.** A\n * consumer that ran `onEnd` and then handled the echo would commit the same\n * confirmation twice, so {@link CompositionTracker.consumesConfirmedInput} tells\n * the echo apart and the consumer returns early on it.\n *\n * **What the echo is not, is the harder half.** Not every engine sends one —\n * Chromium ends a confirmation at `compositionend` with no `input` after it — so\n * a window that waits for the echo and only closes on the next key would swallow\n * the first edit that arrives without one: dictation, autofill, a drop,\n * `insertText`. Two things keep that from happening. The window closes on the\n * next anything — a key, a new composition, any `input`, losing the field — and\n * an `input` that reports an `inputType` outside {@link COMPOSITION_INPUT_TYPES}\n * is an edit, so it is never folded. Only an engine that reports no `inputType`\n * at all is left relying on the window alone.\n *\n * @example\n * ```ts\n * #composition = new CompositionTracker({ onEnd: () => this.filter() });\n *\n * connect(): void {\n * this.#composition.observe(this.inputTarget);\n * }\n *\n * disconnect(): void {\n * this.#composition.disconnect();\n * }\n *\n * onInput(event: InputEvent): void {\n * if (this.#composition.consumesConfirmedInput(event)) return;\n * if (this.#composition.isComposing(event)) return;\n * }\n *\n * onKeydown(event: KeyboardEvent): void {\n * if (this.#composition.isComposing(event)) return;\n * }\n * ```\n */\nexport class CompositionTracker {\n readonly #observedTargets = new Set<EventTarget>();\n readonly #activeTargets = new Set<EventTarget>();\n readonly #onStart: ((event: Event) => void) | undefined;\n readonly #onEnd: ((event: Event) => void) | undefined;\n /** The field whose confirming `input` is still owed, while the window is open. */\n #confirmedTarget: EventTarget | null = null;\n\n constructor(options: CompositionTrackerOptions = {}) {\n this.#onStart = options.onStart;\n this.#onEnd = options.onEnd;\n }\n\n /** Starts lifecycle tracking for `target`; repeated calls are idempotent. */\n observe(target: EventTarget): void {\n if (this.#observedTargets.has(target)) return;\n target.addEventListener(\"compositionstart\", this.#handleStart);\n target.addEventListener(\"compositionend\", this.#handleEnd);\n target.addEventListener(\"keydown\", this.#handleKeydown);\n this.#observedTargets.add(target);\n }\n\n /** Stops tracking one target and clears any active composition it owned. */\n unobserve(target: EventTarget): void {\n if (!this.#observedTargets.delete(target)) return;\n target.removeEventListener(\"compositionstart\", this.#handleStart);\n target.removeEventListener(\"compositionend\", this.#handleEnd);\n target.removeEventListener(\"keydown\", this.#handleKeydown);\n this.#activeTargets.delete(target);\n if (this.#confirmedTarget === target) this.#confirmedTarget = null;\n }\n\n /** Releases every listener and clears state so reconnect starts cleanly. */\n disconnect(): void {\n for (const target of this.#observedTargets) {\n target.removeEventListener(\"compositionstart\", this.#handleStart);\n target.removeEventListener(\"compositionend\", this.#handleEnd);\n target.removeEventListener(\"keydown\", this.#handleKeydown);\n }\n this.#observedTargets.clear();\n this.#activeTargets.clear();\n this.#confirmedTarget = null;\n }\n\n /** True when lifecycle tracking or the current event reports composition. */\n isComposing(event?: CompositionSignal): boolean {\n return this.#activeTargets.size > 0 || event?.isComposing === true;\n }\n\n /**\n * Whether `event` is the `input` echoing the composition just confirmed.\n *\n * Asking closes the window either way, so one confirmation is folded at most\n * once and a consumer asks once per `input`.\n */\n consumesConfirmedInput(event: ConfirmedInputSignal): boolean {\n const confirmed = this.#confirmedTarget;\n this.#confirmedTarget = null;\n if (confirmed === null || confirmed !== event.target) return false;\n // An engine that reports no kind at all leaves `inputType` empty, and the\n // window is then the only signal there is.\n const inputType = event.inputType;\n return !inputType || COMPOSITION_INPUT_TYPES.has(inputType);\n }\n\n readonly #handleStart = (event: Event): void => {\n this.#confirmedTarget = null;\n if (event.currentTarget) this.#activeTargets.add(event.currentTarget);\n this.#onStart?.(event);\n };\n\n readonly #handleEnd = (event: Event): void => {\n if (event.currentTarget) this.#activeTargets.delete(event.currentTarget);\n this.#confirmedTarget = event.target;\n this.#onEnd?.(event);\n };\n\n /** A key on an observed field opens an edit of its own, so no echo is owed. */\n readonly #handleKeydown = (): void => {\n this.#confirmedTarget = null;\n };\n}\n","/**\n * Readers for the String Values whose text can only be checked by handing it to\n * a parser: a CSS selector, a regular-expression source, a JSON object.\n *\n * Stimulus reads each of them as an ordinary string, so the controller connects\n * and the flaw surfaces later, inside the first handler that consumes the value\n * (a `SyntaxError` from `new RegExp`, a `DOMException` from the selector engine),\n * where it takes the whole handler down on every event. Parsing here, once, in\n * the `<name>ValueChanged` callback keeps the failure local to the declaration:\n * an unreadable value falls back to its default, the element stays alive, and\n * the hot path only ever receives a value that parsed.\n *\n * Which default a broken declaration falls back to is the caller's contract, so\n * every reader takes (or returns) the fallback rather than choosing one.\n */\n\n/**\n * The result of `parse(raw)`, or `fallback` when `parse` throws.\n *\n * Any exception counts as \"does not parse\": the parsers these Values feed\n * (`RegExp`, `JSON.parse`, the selector engine) all report a malformed input by\n * throwing, and none of them throws for another reason.\n */\nexport function parseDeclared<T>(raw: string, parse: (raw: string) => T, fallback: T): T {\n try {\n return parse(raw);\n } catch {\n return fallback;\n }\n}\n\n/** What {@link validSelector} needs of the element it probes with. */\nexport interface SelectorProbe {\n matches(selector: string): boolean;\n}\n\n/**\n * `raw` when it is a non-empty selector the DOM accepts, otherwise `fallback`.\n *\n * `element.matches` is the probe: the engine parses the selector and throws for\n * one it cannot read. Whether the selector actually matches `element` plays no\n * part, so a selector aimed at another element still passes.\n *\n * The parameter names the one method the probe uses rather than `Element`, so\n * this module carries no DOM type and the readers below stay importable from\n * the Node-side Inspector, which checks the same declarations statically.\n */\nexport function validSelector(element: SelectorProbe, raw: string, fallback: string): string {\n if (raw.length === 0) return fallback;\n return parseDeclared(\n raw,\n (selector) => {\n element.matches(selector);\n return selector;\n },\n fallback,\n );\n}\n\n/** How `compileRegExp` wraps a source before compiling it. */\nexport type RegExpAnchor = \"none\" | \"exact\";\n\n/**\n * `source` compiled as a `RegExp`, or `null` when it does not compile.\n *\n * `\"exact\"` wraps the source as `^(?:source)$`, so the whole input has to match\n * and an alternation inside the source cannot escape the anchors. The source is\n * compiled on its own first, because an unbalanced source can be made to parse\n * by the wrapper's own parentheses — `0)|(1` becomes `^(?:0)|(1)$` — which would\n * accept a declaration that is not a regular expression and leave half of it\n * outside the anchors. The default that replaces a broken source is the\n * caller's, so `null` is returned rather than a fallback pattern.\n */\nexport function compileRegExp(source: string, anchor: RegExpAnchor = \"none\"): RegExp | null {\n return parseDeclared(\n source,\n (text) => {\n const bare = new RegExp(text);\n return anchor === \"exact\" ? new RegExp(`^(?:${text})$`) : bare;\n },\n null,\n );\n}\n\n/**\n * The JSON object `raw` declares, or `null` when the text does not parse or\n * parses to something other than a plain object (`null`, an array, a scalar).\n * Values are returned as parsed; narrowing them is the caller's contract.\n */\nexport function parseJsonObject(raw: string): Record<string, unknown> | null {\n const parsed = parseDeclared<unknown>(raw, (text) => JSON.parse(text), null);\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) return null;\n return parsed as Record<string, unknown>;\n}\n","/**\n * Runs a controller's reconciliation pass after a native form reset has\n * restored the form's own controls.\n *\n * **A microtask alone is not \"after the reset\", and the reason is where the\n * dispatch came from.** `form.reset()` fires the event and restores the\n * controls inside one script frame, so a microtask queued from a listener lands\n * after both. A reset the user triggers — activating a `reset` button — is\n * dispatched by the browser with an empty script stack, so the microtask\n * checkpoint runs the moment the listener returns: still inside the dispatch,\n * before the controls are restored and before a later listener has had its\n * chance to cancel. Reconciling there reads the pre-reset values and treats a\n * cancelled reset as a real one.\n *\n * The event itself tells the two origins apart. `eventPhase` returns to\n * `Event.NONE` at the end of dispatch, so a microtask that sees `NONE` is\n * already past the default action and settles on the spot — that is the\n * scripted path, and its timing is exactly a microtask. A microtask\n * that still sees a dispatch phase is the browser-driven path and settles on\n * the next animation frame instead: the default action completes before that\n * frame, and `defaultPrevented` has reached its final value. A frame is only\n * ever reached from a real user interaction, which requires a rendered\n * document, so the frame cannot starve.\n *\n * Pending frames are held per handle rather than collapsed into one slot: a set\n * needs no branch to stay accurate, and every handle in it is cancellable at\n * teardown.\n *\n * Scope is the timing and the ownership test only. *What* to reconcile — an\n * aggregate, a visibility pass, a re-read of every field — stays in the\n * controller, because no two consumers answer it the same way. Ownership stays\n * there too: a control associated through `form=` is reached by the consumer's\n * own `control.form` read.\n *\n * This file's own doc block is dropped from `dist`, but every member comment is\n * inlined into each consumer entry (`tsup` builds with `splitting: false`), so\n * rationale belongs here and only the contract belongs on the members.\n *\n * @example\n * ```ts\n * readonly #formReset = new FormResetWatcher(\n * (form) => this.fieldTargets.some((field) => field.form === form),\n * () => this.#reconcile.schedule(),\n * );\n *\n * connect() { this.#formReset.observe(); }\n * disconnect() { this.#formReset.disconnect(); }\n * ```\n */\nexport class FormResetWatcher {\n readonly #owns: (form: HTMLFormElement) => boolean;\n readonly #onReset: () => void;\n readonly #frames = new Set<number>();\n #generation = 0;\n\n /**\n * @param owns - whether `form` owns a control this controller derives from.\n * @param onReset - the reconciliation pass, run once per honoured reset.\n */\n constructor(owns: (form: HTMLFormElement) => boolean, onReset: () => void) {\n this.#owns = owns;\n this.#onReset = onReset;\n }\n\n /** Subscribes to `reset` at the document; call from `connect()`. Idempotent. */\n observe(): void {\n document.addEventListener(\"reset\", this.#handleReset, true);\n }\n\n /** Unsubscribes and drops every pending pass; call from `disconnect()`. */\n disconnect(): void {\n document.removeEventListener(\"reset\", this.#handleReset, true);\n this.#generation += 1;\n for (const frame of this.#frames) cancelAnimationFrame(frame);\n this.#frames.clear();\n }\n\n readonly #handleReset = (event: Event): void => {\n const form = event.target;\n if (!(form instanceof HTMLFormElement) || !this.#owns(form)) return;\n const generation = this.#generation;\n queueMicrotask(() => {\n // A pass queued before teardown must not reach a disconnected controller.\n if (generation !== this.#generation) return;\n if (event.eventPhase === Event.NONE) {\n this.#settle(event);\n return;\n }\n const frame = requestAnimationFrame(() => {\n this.#frames.delete(frame);\n this.#settle(event);\n });\n this.#frames.add(frame);\n });\n };\n\n /** Runs the pass unless a listener cancelled the reset before it landed. */\n #settle(event: Event): void {\n if (!event.defaultPrevented) this.#onReset();\n }\n}\n","/** The distance between a full-width ASCII code point and its half-width twin. */\nconst FULL_WIDTH_SHIFT = 0xfee0;\n\n/**\n * The half-width form of `char`, or `char` itself when it has none.\n *\n * An IME confirming in full-width mode produces U+FF01–U+FF5E (and U+3000 for\n * the space) where the page means ASCII — the digits of a phone number, the\n * letters of a code, the separators between them. Reading those as their ASCII\n * equivalents keeps confirmed text usable instead of discarding it. Characters\n * outside that block, including kana and astral code points, are returned\n * unchanged, so this never rewrites text a consumer meant to keep as typed.\n */\nexport function halfWidthChar(char: string): string {\n if (char >= \"!\" && char <= \"~\") {\n return String.fromCharCode(char.charCodeAt(0) - FULL_WIDTH_SHIFT);\n }\n return char === \" \" ? \" \" : char;\n}\n\n/** Every full-width ASCII character in `text` rewritten by {@link halfWidthChar}. */\nexport function toHalfWidth(text: string): string {\n let out = \"\";\n for (const char of text) out += halfWidthChar(char);\n return out;\n}\n","/**\n * Collapses many Stimulus lifecycle callbacks from one DOM mutation into a\n * single pass.\n *\n * Stimulus fires `<name>TargetConnected` / `Disconnected` once per element and\n * `<name>ValueChanged` once per changed attribute. Replacing a list of N options\n * or morphing several render Values therefore delivers N callbacks — but the\n * useful unit of work is \"reconcile against the resulting declarative input\",\n * once, after the batch has settled. Every controller with reconcilable targets\n * or render Values needs the same shape: a `queued` flag plus `queueMicrotask`.\n *\n * **A microtask is the right horizon, and the reason is specific.** Stimulus\n * drives these callbacks from a `MutationObserver`, whose own callback already\n * runs as a microtask with the whole batch in hand; scheduling one more lands\n * after the last sibling callback of that batch and still before paint or any\n * event handler. A timer would be later than it needs to be, and reconciling\n * synchronously would run once per element against a half-applied DOM.\n *\n * **The two guards are not the same guard.** Scheduling is refused before the\n * controller connects, and running is refused after it disconnects:\n *\n * - **Before `connect()`** — Stimulus delivers initial target and Value callbacks\n * ahead of `connect()`. Reconciling there would compute output against a\n * controller whose own state has not been initialised, and `connect()` is\n * about to do a full pass anyway.\n * - **After `disconnect()`** — Stimulus fires a callback for **every** target\n * during teardown, and a microtask queued just before it would otherwise run\n * against a detached tree. {@link MicrotaskCoalescer.cancel} exists for the\n * teardown path to drop the pending pass outright.\n *\n * Both guards are part of one contract here rather than something each consumer\n * has to remember separately.\n *\n * Scope is the scheduling only. *What* to reconcile — keep the surviving active\n * option, fall back to the next / previous / first visible one, rebuild derived\n * chips or hidden fields — stays in the controller, because no two consumers\n * answer it the same way.\n *\n * This file's own doc block is dropped from `dist`, but every member comment is\n * inlined into each consumer entry (`tsup` builds with `splitting: false`), so\n * rationale belongs here and only the contract belongs on the members.\n *\n * @example\n * ```ts\n * readonly #reconcile = new MicrotaskCoalescer(() => this.#reconcileOptions());\n *\n * connect() { this.#reconcile.activate(); }\n * disconnect() { this.#reconcile.cancel(); }\n *\n * optionTargetConnected() { this.#reconcile.schedule(); }\n * optionTargetDisconnected() { this.#reconcile.schedule(); }\n * ```\n */\nexport class MicrotaskCoalescer {\n readonly #run: () => void;\n #queued = false;\n #active = false;\n #generation = 0;\n\n /** @param run - the single reconciliation pass, invoked at most once per batch. */\n constructor(run: () => void) {\n this.#run = run;\n }\n\n /** Opens the window in which {@link schedule} is honoured; call from `connect()`. */\n activate(): void {\n this.#active = true;\n }\n\n /** Closes the window and drops any pending pass; call from `disconnect()`. */\n cancel(): void {\n this.#active = false;\n this.#queued = false;\n this.#generation += 1;\n }\n\n /** Requests one pass after the batch settles. Idempotent; inert outside the window. */\n schedule(): void {\n if (!this.#active || this.#queued) return;\n this.#queued = true;\n const generation = this.#generation;\n queueMicrotask(() => {\n // A cancelled callback must not consume a pass queued after reconnect.\n if (generation !== this.#generation || !this.#queued || !this.#active) return;\n this.#queued = false;\n this.#run();\n });\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { ensureId } from \"../utils/aria_ids\";\nimport { isReservedArrowChord, logicalArrowKey } from \"../utils/arrow_step\";\nimport { AttributeLease } from \"../utils/attribute_lease\";\nimport { BeforeCacheReset } from \"../utils/before_cache_reset\";\nimport { CompositionTracker } from \"../utils/composition_tracker\";\nimport { compileRegExp } from \"../utils/declared_value\";\nimport { FormResetWatcher } from \"../utils/form_reset_watcher\";\nimport { toHalfWidth } from \"../utils/half_width\";\nimport { MicrotaskCoalescer } from \"../utils/microtask_coalescer\";\n\n/** The error attributes this component writes on each field while input is rejected. */\ntype ErrorAttribute = \"aria-invalid\" | \"aria-errormessage\" | \"aria-describedby\";\n\n/**\n * Each error attribute's lease, kept on the field itself.\n *\n * `AttributeLease` keeps its records in memory, which the connection that adopts\n * a restored DOM does not have. These records travel with the markup instead,\n * so any connection can give the authored value back — and only while the\n * attribute still holds what this component last wrote there, so a value a\n * consumer changed in the meantime is theirs and stays.\n */\nconst LEASE_MARKERS: Readonly<Record<ErrorAttribute, string>> = {\n \"aria-invalid\": \"data-otp-invalid-lease\",\n \"aria-errormessage\": \"data-otp-errormessage-lease\",\n \"aria-describedby\": \"data-otp-describedby-lease\",\n};\n\n/** What an error attribute carried before this component wrote it, and what it wrote. */\ninterface ErrorLease {\n readonly authored: string | null;\n readonly written: string;\n}\n\n/** Whether a parsed marker holds a lease this component could have recorded. */\nfunction isErrorLease(value: unknown): value is ErrorLease {\n const lease = value as Partial<Record<keyof ErrorLease, unknown>> | null;\n return (\n typeof lease?.written === \"string\" &&\n (lease.authored === null || typeof lease.authored === \"string\")\n );\n}\n\n/** Reads the lease a field carries; a marker holding anything else is not one. */\nfunction readLease(field: Element, marker: string): ErrorLease | null {\n try {\n const parsed: unknown = JSON.parse(field.getAttribute(marker) ?? \"null\");\n return isErrorLease(parsed) ? parsed : null;\n } catch {\n return null;\n }\n}\n\n/** The field's own description tokens with the error id appended once. */\nfunction describedByWith(described: string | null, errorId: string): string {\n const tokens = (described ?? \"\")\n .split(/\\s+/)\n .filter((token) => token.length > 0 && token !== errorId);\n return [...tokens, errorId].join(\" \");\n}\n\n/** Single-character pattern used when a `pattern` declaration cannot compile. */\nconst DEFAULT_PATTERN = \"[0-9]\";\n\n/**\n * {@link DEFAULT_PATTERN} compiled, in the same whole-input form\n * `compileRegExp(…, \"exact\")` produces. A literal character class always\n * compiles, so the fallback is a value rather than another parse.\n */\nconst DEFAULT_MATCHER = new RegExp(`^(?:${DEFAULT_PATTERN})$`);\n\n/** Whether a press carries a modifier, which makes it the document's to handle. */\nfunction hasModifier(event: KeyboardEvent): boolean {\n return event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;\n}\n\n/**\n * The controller-derived state a consumer can observe.\n *\n * The combined value alone does not identify it: the same string spread over a\n * different number of fields reads as a different `data-state`, so completeness\n * is carried alongside the value rather than inferred from it.\n */\ninterface OtpState {\n readonly value: string;\n readonly state: string;\n}\n\n/** Compares exactly the derived state the root publishes. */\nfunction statesDiffer(left: OtpState, right: OtpState): boolean {\n return left.value !== right.value || left.state !== right.state;\n}\n\n/**\n * Headless, accessible One-Time Password / PIN input logic.\n *\n * Markup contract (identifier: `stimeo--otp`):\n * <div data-controller=\"stimeo--otp\"\n * data-stimeo--otp-pattern-value=\"[0-9]\"\n * role=\"group\" aria-label=\"One-time passcode\">\n * <input data-stimeo--otp-target=\"field\" inputmode=\"numeric\" maxlength=\"1\"\n * autocomplete=\"one-time-code\" aria-label=\"Digit 1\"\n * data-action=\"input->stimeo--otp#onInput\n * keydown->stimeo--otp#onKeydown\n * paste->stimeo--otp#onPaste\n * pointerdown->stimeo--otp#onPointerDown\" />\n * <!-- repeat one field per digit -->\n * <p data-stimeo--otp-target=\"error\" hidden>Digits only.</p>\n * <input type=\"hidden\" data-stimeo--otp-target=\"value\" name=\"otp\" />\n * </div>\n *\n * The passcode length is the number of connected `field` targets, so nothing has\n * to declare it twice and fields added or removed at runtime are absorbed.\n *\n * Entry rules:\n * - Text carrying more than one accepted character — an OS `one-time-code`\n * autofill, a password manager, an IME committing several digits, a paste —\n * is spread across the following writable fields from the entry point.\n * - `disabled` and `readonly` fields keep their value: they are never written\n * and never receive auto-advance focus, matching what the platform allows a\n * user to do by hand.\n * - Input that lands nowhere rolls the field back to the digit it last\n * committed, and is the only thing that reports `invalid` or reveals the\n * `error` target. Discarding a separator inside otherwise usable text\n * (`\"1234-56\"`) is a successful entry.\n * - Pointing at an empty field ahead of an earlier empty one lands on the\n * earliest empty field instead, so a passcode fills in order. Keyboard focus\n * is never redirected.\n *\n * `change` and `complete` dispatch `{ value: string }` and fire only when the\n * combined value actually moves — one confirmed IME character emits one event,\n * and a passcode re-completed with a different digit reports the new value.\n * State moved by adding or removing fields, by a `pattern` change dropping\n * entered digits it no longer accepts, or by a native form reset restoring the\n * fields is not an edit of the passcode, so it is reported as `reconcile` with\n * the same `{ value: string }` — once per change, after it settles — and never\n * as `change` or `complete`. While a field is composing, the IME's uncommitted\n * text is neither read nor written: a change already in the DOM — fields added\n * or removed, a reset — is reported at once, counting that field by the\n * character it had committed, while a `pattern` change's drop waits for the\n * composition to end and is then applied and reported before the commit is\n * taken. A composition that ends on the text the field held when it began was\n * cancelled: no edit, so it reports nothing and focus stays.\n * Completeness belongs to that state: dropping a trailing empty field completes\n * a passcode whose combined value never moved, and that transition is reported\n * too, so a consumer reading `data-state` is never left behind a silent move.\n * `invalid` dispatches `{ pattern: string }` carrying the compiled pattern.\n *\n * Controller-owned output: `data-filled` on each entered field, `data-state`\n * (`empty` / `partial` / `complete`) on the root, and — while input is being\n * reported invalid — `aria-invalid`, `aria-errormessage`, `aria-describedby`,\n * and the `error` target's `hidden`. Authored values return on teardown and\n * before the page is cached: the three ARIA attributes keep their lease on the\n * field itself, so a connection that adopts a restored DOM can give them back\n * too, and the `hidden` is leased.\n *\n * @remarks\n * Behavior only. `connect()` reads the fields back as the source of truth, which\n * is what restores consistency after a `type=\"password\"` field returns from the\n * Turbo cache emptied; a native form reset is read back the same way once the\n * browser has restored the fields. A `pattern` that cannot compile falls back to\n * `[0-9]`; the compiled matcher is built once per declaration rather than per\n * keystroke.\n */\nexport class OtpController extends Controller<HTMLElement> {\n static override targets = [\"field\", \"value\", \"error\"];\n static override values = {\n pattern: { type: String, default: DEFAULT_PATTERN },\n };\n static actions = [\"onInput\", \"onKeydown\", \"onPaste\", \"onPointerDown\", \"clear\"] as const;\n static events = [\"change\", \"complete\", \"invalid\", \"reconcile\"] as const;\n\n declare readonly fieldTargets: HTMLInputElement[];\n declare readonly valueTarget: HTMLInputElement;\n declare readonly errorTarget: HTMLElement;\n declare readonly hasValueTarget: boolean;\n declare readonly hasErrorTarget: boolean;\n\n declare patternValue: string;\n\n /** Validated matcher; the hot path never compiles a raw declaration. */\n #pattern = DEFAULT_MATCHER;\n /** Source of {@link #pattern}, reported in `invalid` so consumers can word it. */\n #patternSource = DEFAULT_PATTERN;\n /** Public state carried by the last dispatch; keeps a no-op sync silent. */\n #published: OtpState | null = null;\n /** True between connect and disconnect, so pre-connect Value changes stay silent. */\n #connected = false;\n /** Digit each field last committed, restored when rejected input replaced it. */\n readonly #committed = new WeakMap<HTMLInputElement, string>();\n /** The field being composed, and the text it held when the composition began. */\n #composing: { readonly field: HTMLInputElement; readonly before: string } | null = null;\n /** A `pattern` change whose rejected characters wait for the composition to end. */\n #dropHeld = false;\n\n /**\n * Collapses one batch of page changes — field target and `pattern` callbacks, a\n * form reset — into a single reconciliation.\n */\n readonly #reconcile = new MicrotaskCoalescer(() => this.#reconcileFields());\n\n readonly #errorHidden = new AttributeLease<HTMLElement>(\"hidden\");\n readonly #state = new AttributeLease<HTMLElement>(\"data-state\");\n\n /** Rewinds the transient error surface before Turbo freezes the page. */\n readonly #beforeCache = new BeforeCacheReset(() => this.#clearError());\n /** Reads the fields back once a native reset restored them, as a reconciliation. */\n readonly #formReset = new FormResetWatcher(\n (form) => this.#ownedBy(form),\n () => {\n this.#adopt();\n this.#reconcile.schedule();\n },\n );\n\n /**\n * Owns IME lifecycle state across every digit field. When a composition ends, a\n * `pattern` drop it held back applies first — it was declared first — and the\n * user's commit is taken after it.\n */\n readonly #composition = new CompositionTracker({\n onStart: (event) => {\n const field = this.#fieldFrom(event);\n if (field) this.#composing = { field, before: field.value };\n },\n onEnd: (event) => {\n const composing = this.#composing;\n this.#composing = null;\n const input = this.#fieldFrom(event);\n // `maxlength` has already cut the field down to one character, but the\n // commit itself carries the whole confirmed string — so a conversion that\n // ends in several characters still reaches the fields after this one.\n const data = (event as CompositionEvent).data ?? \"\";\n const text = input && data.length <= input.value.length ? input.value : data;\n // A composition that ends on the text the field held when it began was\n // cancelled: the user entered nothing, so there is nothing to take.\n const commit = input !== null && (composing?.field !== input || text !== composing.before);\n if (this.#dropHeld) {\n // The drop judges what the fields had committed; the commit waits aside.\n if (input && commit) input.value = this.#committed.get(input) ?? \"\";\n this.#reconcileFields();\n }\n if (input && commit) this.#accept(input, text);\n },\n });\n\n override connect(): void {\n this.#connected = true;\n for (const field of this.fieldTargets) this.#bind(field);\n this.#formReset.observe();\n this.#beforeCache.activate();\n this.#reconcile.activate();\n this.#adopt();\n this.#sync();\n }\n\n override disconnect(): void {\n this.#connected = false;\n for (const field of this.fieldTargets) this.#unbind(field);\n this.#composition.disconnect();\n this.#formReset.disconnect();\n this.#beforeCache.deactivate();\n this.#reconcile.cancel();\n // A drop a composition held goes with the connection, like a pending pass.\n this.#dropHeld = false;\n this.#clearError();\n this.#state.return(this.element);\n }\n\n /**\n * Stimulus lifecycle callback when a new field target enters the DOM.\n * Wires the new field and folds the wider digit count into one reconciliation,\n * which stays inert until `connect()` opens the window.\n */\n fieldTargetConnected(element: HTMLInputElement): void {\n this.#bind(element);\n this.#adoptField(element);\n this.#reconcile.schedule();\n }\n\n /** Releases a dropped field's listeners and leases, then reconciles the rest. */\n fieldTargetDisconnected(element: HTMLInputElement): void {\n this.#unbind(element);\n this.#returnLeases(element);\n this.#reconcile.schedule();\n }\n\n /**\n * Re-validates a changed `pattern` declaration once and drops any entered digit\n * the new pattern no longer accepts, so the combined value stays interpretable.\n * The page changed the declaration, so the move joins the same reconciliation\n * as fields added or removed in that mutation. While a field is composing, its\n * text is the IME's, and the drop waits for the composition to end.\n */\n patternValueChanged(): void {\n const compiled = compileRegExp(this.patternValue, \"exact\");\n this.#patternSource = compiled ? this.patternValue : DEFAULT_PATTERN;\n this.#pattern = compiled ?? DEFAULT_MATCHER;\n if (!this.#connected) return;\n if (this.#composing !== null) {\n this.#dropHeld = true;\n return;\n }\n if (this.#dropRejected()) this.#reconcile.schedule();\n }\n\n /** Empties every writable field holding a character the pattern rejects; whether one did. */\n #dropRejected(): boolean {\n let dropped = false;\n for (const field of this.fieldTargets) {\n if (field.value === \"\" || !this.#isWritable(field)) continue;\n if (this.#pattern.test(field.value)) continue;\n this.#writeField(field, \"\");\n dropped = true;\n }\n return dropped;\n }\n\n /** Handles keystroke inputs, distributes autofilled text, and advances focus. */\n onInput(event: Event): void {\n const input = this.#fieldFrom(event);\n if (!input) return;\n\n // The browser may follow a commit with one more `input` carrying the same\n // text; running it again would spread the commit twice.\n if (this.#composition.consumesConfirmedInput(event)) return;\n\n // Guard during active composition to prevent premature focus switching\n if (this.#composition.isComposing(event as InputEvent)) return;\n\n this.#accept(input);\n }\n\n /** Handles Backspace clearing, arrows, and home/end navigation. */\n onKeydown(event: KeyboardEvent): void {\n if (isReservedArrowChord(event)) return;\n const input = this.#fieldFrom(event);\n if (!input) return;\n\n // Do not trigger keydown actions during composition\n if (this.#composition.isComposing(event)) return;\n\n const index = this.fieldTargets.indexOf(input);\n const fields = this.fieldTargets;\n // Logical, not physical. The key is normalised rather than the\n // delta negated: these two branches are not mirror images — their bounds\n // guards differ — so swapping the key keeps each guard with its own direction.\n\n switch (logicalArrowKey(event.key, this.element)) {\n case \"Backspace\":\n if (hasModifier(event)) break;\n if (input.value && this.#isWritable(input)) {\n // Filled field: clear it where it stands\n event.preventDefault();\n this.#writeField(input, \"\");\n this.#clearError();\n this.#syncAndDispatch();\n } else {\n // Empty field: step back to the previous writable digit and wipe it\n const previous = this.#writableBefore(index);\n if (previous) {\n event.preventDefault();\n this.#writeField(previous, \"\");\n previous.focus();\n this.#clearError();\n this.#syncAndDispatch();\n }\n }\n break;\n\n case \"ArrowLeft\": {\n const previous = this.#focusableBefore(index);\n if (previous) {\n event.preventDefault();\n previous.focus();\n }\n break;\n }\n\n case \"ArrowRight\": {\n const next = this.#focusableAfter(index);\n if (next) {\n event.preventDefault();\n next.focus();\n }\n break;\n }\n\n case \"Home\": {\n // Control+Home belongs to the document, not to the digit group\n if (hasModifier(event)) break;\n const first = fields.find((field) => this.#isFocusable(field));\n if (first) {\n event.preventDefault();\n first.focus();\n }\n break;\n }\n\n case \"End\": {\n if (hasModifier(event)) break;\n const last = fields\n .slice()\n .reverse()\n .find((field) => this.#isFocusable(field));\n if (last) {\n event.preventDefault();\n last.focus();\n }\n break;\n }\n\n default:\n break;\n }\n }\n\n /** Divides pasted string characters across the available input fields. */\n onPaste(event: ClipboardEvent): void {\n const input = this.#fieldFrom(event);\n if (!input) return;\n\n event.preventDefault();\n this.#distribute(input, toHalfWidth(event.clipboardData?.getData(\"text\") ?? \"\"));\n }\n\n /**\n * Redirects a pointer landing on an empty field to the earliest empty one, so\n * a passcode is entered in order. Filled fields stay directly reachable for\n * correction, and keyboard focus is left alone.\n */\n onPointerDown(event: Event): void {\n const input = this.#fieldFrom(event);\n if (input?.value !== \"\") return;\n\n const first = this.fieldTargets.find((field) => this.#isWritable(field) && field.value === \"\");\n if (!first || first === input) return;\n\n event.preventDefault();\n first.focus();\n }\n\n /** Empties every writable field and restarts entry at the first of them. */\n clear(): void {\n for (const field of this.fieldTargets) {\n if (this.#isWritable(field)) this.#writeField(field, \"\");\n }\n this.#clearError();\n this.fieldTargets.find((field) => this.#isWritable(field))?.focus();\n this.#syncAndDispatch();\n }\n\n readonly #onFieldFocus = (event: FocusEvent): void => {\n const input = event.currentTarget as HTMLInputElement | null;\n if (input) {\n // Auto-selection enables effortless character overwrites\n input.select();\n }\n };\n\n /** Whether a form owns at least one field or the hidden combined value. */\n #ownedBy(form: HTMLFormElement): boolean {\n if (this.fieldTargets.some((field) => field.form === form)) return true;\n return this.hasValueTarget && this.valueTarget.form === form;\n }\n\n #bind(field: HTMLInputElement): void {\n field.addEventListener(\"focus\", this.#onFieldFocus);\n this.#composition.observe(field);\n }\n\n #unbind(field: HTMLInputElement): void {\n field.removeEventListener(\"focus\", this.#onFieldFocus);\n this.#composition.unobserve(field);\n // A field that leaves mid-composition never ends that composition here.\n if (this.#composing?.field === field) this.#composing = null;\n }\n\n /** Reads every field back so a restored or reset group starts consistent. */\n #adopt(): void {\n for (const field of this.fieldTargets) this.#adoptField(field);\n this.#clearError();\n // Nothing has been rejected yet, whatever visibility the restored DOM carries\n if (this.hasErrorTarget) this.errorTarget.setAttribute(\"hidden\", \"\");\n }\n\n /** Writes one error attribute, keeping the first authored value it displaces. */\n #lease(field: HTMLInputElement, attribute: ErrorAttribute, value: string): void {\n const marker = LEASE_MARKERS[attribute];\n const held = readLease(field, marker);\n const authored = held ? held.authored : field.getAttribute(attribute);\n field.setAttribute(marker, JSON.stringify({ authored, written: value }));\n field.setAttribute(attribute, value);\n }\n\n /** Gives one field's error attributes back where they still hold what this wrote. */\n #returnLeases(field: HTMLInputElement): void {\n for (const [attribute, marker] of Object.entries(LEASE_MARKERS)) {\n const held = readLease(field, marker);\n if (!held) continue;\n field.removeAttribute(marker);\n if (field.getAttribute(attribute) !== held.written) continue;\n if (held.authored === null) field.removeAttribute(attribute);\n else field.setAttribute(attribute, held.authored);\n }\n }\n\n /** Takes one field's current value as the truth behind its derived state. */\n #adoptField(field: HTMLInputElement): void {\n this.#committed.set(field, field.value);\n this.#markFilled(field, field.value);\n }\n\n /**\n * Absorbs one batch of page changes — fields added or removed, entered digits a\n * new `pattern` rejects, fields a native form reset restored — as one state\n * transition.\n *\n * Nobody edited the passcode here, so the move is reported as `reconcile`:\n * automation listening for `change` must not read a re-render or a reset as an\n * edit, and a passcode that happens to end up full must not fire the\n * `complete` that submits it.\n *\n * Completeness moves on its own when the field count changes: dropping a\n * trailing empty field completes a passcode whose combined value never moved,\n * and adding one un-completes it. Comparing the whole derived state, not the\n * string it contains, is what makes those transitions reportable.\n *\n * A change already in the DOM — a field added or removed, a reset — is\n * published at once, even while a field is composing: that field counts by the\n * character it had committed, never by the IME's uncommitted text. Only a\n * `pattern` drop waits for the composition to end.\n */\n #reconcileFields(): void {\n if (this.#dropHeld && this.#composing === null) {\n this.#dropHeld = false;\n this.#dropRejected();\n }\n const previous = this.#published;\n const current = this.#sync();\n if (previous && !statesDiffer(previous, current)) return;\n this.dispatch(\"reconcile\", { detail: { value: current.value } });\n }\n\n /**\n * Validates the text an entry point received and distributes what it accepts.\n * `text` defaults to the field's own value; a confirmation passes the string it\n * committed, which `maxlength` would otherwise have truncated.\n */\n #accept(input: HTMLInputElement, text: string = input.value): void {\n const raw = toHalfWidth(text);\n if (raw === \"\") {\n // Emptying a field is a legitimate edit, not rejected input\n this.#writeField(input, \"\");\n this.#clearError();\n this.#syncAndDispatch();\n return;\n }\n\n this.#distribute(input, raw);\n }\n\n /**\n * Fills `text`'s accepted characters into the writable fields at and after the\n * entry point, then leaves focus on the field after the last one filled.\n */\n #distribute(from: HTMLInputElement, text: string): void {\n const accepted = Array.from(text).filter((char) => this.#pattern.test(char));\n let reached = false;\n const slots = this.fieldTargets.filter((field) => {\n reached ||= field === from;\n return reached && this.#isWritable(field);\n });\n const filled = Math.min(accepted.length, slots.length);\n\n if (filled === 0) {\n // Nothing landed: restore the digit the entry point had committed\n this.#restore(from);\n this.#showError();\n this.#sync();\n return;\n }\n\n for (let i = 0; i < filled; i++) {\n const field = slots[i];\n const char = accepted[i];\n if (field && char) this.#writeField(field, char);\n }\n\n const last = slots[filled - 1];\n if (last) (this.#writableAfter(last) ?? last).focus();\n\n this.#clearError();\n this.#syncAndDispatch();\n }\n\n /** Restores the digit a field committed before rejected input replaced it. */\n #restore(field: HTMLInputElement): void {\n this.#writeField(field, this.#committed.get(field) ?? \"\");\n }\n\n /** Commits one field's value and the derived hook that reports it as entered. */\n #writeField(field: HTMLInputElement, value: string): void {\n field.value = value;\n this.#committed.set(field, value);\n this.#markFilled(field, value);\n }\n\n #markFilled(field: HTMLInputElement, value: string): void {\n if (value) field.setAttribute(\"data-filled\", \"true\");\n else field.removeAttribute(\"data-filled\");\n }\n\n #isWritable(field: HTMLInputElement): boolean {\n return !field.disabled && !field.readOnly;\n }\n\n #isFocusable(field: HTMLInputElement): boolean {\n return !field.disabled;\n }\n\n #writableAfter(field: HTMLInputElement): HTMLInputElement | null {\n const fields = this.fieldTargets;\n return fields.slice(fields.indexOf(field) + 1).find((next) => this.#isWritable(next)) ?? null;\n }\n\n #writableBefore(index: number): HTMLInputElement | null {\n return this.#before(index).find((field) => this.#isWritable(field)) ?? null;\n }\n\n #focusableAfter(index: number): HTMLInputElement | null {\n return this.fieldTargets.slice(index + 1).find((field) => this.#isFocusable(field)) ?? null;\n }\n\n #focusableBefore(index: number): HTMLInputElement | null {\n return this.#before(index).find((field) => this.#isFocusable(field)) ?? null;\n }\n\n /** Fields before `index`, nearest first; empty at the first field. */\n #before(index: number): HTMLInputElement[] {\n return this.fieldTargets.slice(0, Math.max(index, 0)).reverse();\n }\n\n /** The event's field target, or `null` when the wiring points somewhere else. */\n #fieldFrom(event: Event): HTMLInputElement | null {\n const input = event.currentTarget;\n return this.fieldTargets.find((field) => field === input) ?? null;\n }\n\n #combinedValue(): string {\n return this.fieldTargets.map((field) => this.#publishedText(field)).join(\"\");\n }\n\n /** Every field carries a character, and there is at least one field. */\n #isComplete(): boolean {\n const fields = this.fieldTargets;\n return fields.length > 0 && fields.every((field) => this.#publishedText(field).length > 0);\n }\n\n /** A field's text as the combined value counts it: a composing field by its committed character. */\n #publishedText(field: HTMLInputElement): string {\n return field === this.#composing?.field ? (this.#committed.get(field) ?? \"\") : field.value;\n }\n\n /**\n * Mirrors the combined value into the form and the root's readable state, and\n * records what was published so the next pass can compare against it.\n */\n #sync(): OtpState {\n const combined = this.#combinedValue();\n\n if (this.hasValueTarget) {\n this.valueTarget.value = combined;\n }\n const state = this.#stateName(combined);\n this.#state.write(this.element, state);\n\n const published: OtpState = { value: combined, state };\n this.#published = published;\n return published;\n }\n\n #stateName(combined: string): string {\n if (combined.length === 0) return \"empty\";\n return this.#isComplete() ? \"complete\" : \"partial\";\n }\n\n #syncAndDispatch(): void {\n const previous = this.#published;\n const { value: combined } = this.#sync();\n if (previous?.value === combined) return;\n\n this.dispatch(\"change\", { detail: { value: combined } });\n\n // Completed state when every field carries a character\n if (this.#isComplete()) {\n this.dispatch(\"complete\", { detail: { value: combined } });\n }\n }\n\n /** Surfaces rejected input on every field and on the optional error target. */\n #showError(): void {\n const errorId = this.hasErrorTarget ? ensureId(this.errorTarget, \"stimeo--otp-error\") : null;\n\n for (const field of this.fieldTargets) {\n this.#lease(field, \"aria-invalid\", \"true\");\n if (!errorId) continue;\n this.#lease(field, \"aria-errormessage\", errorId);\n // Assistive tech without aria-errormessage support still reads a description\n const described = field.getAttribute(\"aria-describedby\");\n this.#lease(field, \"aria-describedby\", describedByWith(described, errorId));\n }\n if (this.hasErrorTarget) this.#errorHidden.write(this.errorTarget, null);\n\n // Behavior only: emit a neutral payload and let the consumer compose/localize\n // the user-facing message. The pattern is reported so consumers can word it.\n this.dispatch(\"invalid\", { detail: { pattern: this.#patternSource } });\n }\n\n /** Returns every error lease, restoring the authored error surface. */\n #clearError(): void {\n for (const field of this.fieldTargets) this.#returnLeases(field);\n this.#errorHidden.returnAll();\n }\n}\n"]}
|
|
@@ -13,7 +13,6 @@ import { Controller } from '@hotwired/stimulus';
|
|
|
13
13
|
* data-stimeo--overflow-indicator-direction-param="start"
|
|
14
14
|
* data-action="click->stimeo--overflow-indicator#scrollByPage">‹</button>
|
|
15
15
|
* <div data-stimeo--overflow-indicator-target="viewport"
|
|
16
|
-
* data-action="scroll->stimeo--overflow-indicator#update"
|
|
17
16
|
* tabindex="0" role="region" aria-label="Products"
|
|
18
17
|
* style="overflow-x: auto;"><!-- items --></div>
|
|
19
18
|
* <button type="button" aria-label="Next"
|
|
@@ -21,11 +20,13 @@ import { Controller } from '@hotwired/stimulus';
|
|
|
21
20
|
* data-action="click->stimeo--overflow-indicator#scrollByPage">›</button>
|
|
22
21
|
* </div>
|
|
23
22
|
*
|
|
24
|
-
* The viewport's scroll position and size are watched
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
23
|
+
* The viewport's scroll position and size are watched by the controller itself:
|
|
24
|
+
* a passive `scroll` listener on the viewport, coalesced to one measurement per
|
|
25
|
+
* animation frame, plus `LayoutObserver` for viewport/content resize, a
|
|
26
|
+
* {@link MutationObserver}, and descendant load events. Nothing about the
|
|
27
|
+
* measurement is the consumer's to wire. Optional page buttons scroll one logical
|
|
28
|
+
* viewport page at a time (including RTL) and have their disabled state synced to
|
|
29
|
+
* the matching direction's remaining room.
|
|
29
30
|
*
|
|
30
31
|
* `change` dispatches `{ start: boolean, end: boolean }`.
|
|
31
32
|
*
|
|
@@ -49,7 +50,7 @@ declare class OverflowIndicatorController extends Controller<HTMLElement> {
|
|
|
49
50
|
default: number;
|
|
50
51
|
};
|
|
51
52
|
};
|
|
52
|
-
static actions: readonly ["scrollByPage"
|
|
53
|
+
static actions: readonly ["scrollByPage"];
|
|
53
54
|
static events: readonly ["change"];
|
|
54
55
|
readonly viewportTarget: HTMLElement;
|
|
55
56
|
readonly hasViewportTarget: boolean;
|
|
@@ -61,11 +62,6 @@ declare class OverflowIndicatorController extends Controller<HTMLElement> {
|
|
|
61
62
|
viewportTargetDisconnected(viewport: HTMLElement): void;
|
|
62
63
|
orientationValueChanged(): void;
|
|
63
64
|
thresholdValueChanged(): void;
|
|
64
|
-
/**
|
|
65
|
-
* Re-measures remaining scroll room and reflects the state hooks.
|
|
66
|
-
* Public so it can be wired to the viewport's `scroll`.
|
|
67
|
-
*/
|
|
68
|
-
update(): void;
|
|
69
65
|
/** Scrolls one viewport page toward the `direction` param (`start`/`end`). */
|
|
70
66
|
scrollByPage(event: Event): void;
|
|
71
67
|
}
|