stimeo-ui 0.16.0 → 0.18.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 +136 -0
- package/README.md +27 -11
- package/dist/cable/index.d.ts +88 -31
- package/dist/cable/index.js +384 -449
- package/dist/cable/index.js.map +1 -1
- package/dist/coerce-JtZVNG5h.d.ts +20 -0
- package/dist/controllers/accordion_controller.d.ts +4 -2
- package/dist/controllers/accordion_controller.js +174 -55
- package/dist/controllers/accordion_controller.js.map +1 -1
- package/dist/controllers/alert_dialog_controller.d.ts +12 -2
- package/dist/controllers/alert_dialog_controller.js +903 -235
- package/dist/controllers/alert_dialog_controller.js.map +1 -1
- package/dist/controllers/announcer_controller.d.ts +37 -5
- package/dist/controllers/announcer_controller.js +238 -205
- package/dist/controllers/announcer_controller.js.map +1 -1
- package/dist/controllers/aspect_ratio_controller.js +0 -10
- package/dist/controllers/aspect_ratio_controller.js.map +1 -1
- package/dist/controllers/auto_submit_controller.d.ts +30 -6
- package/dist/controllers/auto_submit_controller.js +414 -145
- package/dist/controllers/auto_submit_controller.js.map +1 -1
- package/dist/controllers/avatar_controller.js +185 -107
- package/dist/controllers/avatar_controller.js.map +1 -1
- package/dist/controllers/breadcrumb_controller.js +0 -130
- package/dist/controllers/breadcrumb_controller.js.map +1 -1
- package/dist/controllers/bulk_select_controller.d.ts +21 -3
- package/dist/controllers/bulk_select_controller.js +282 -58
- package/dist/controllers/bulk_select_controller.js.map +1 -1
- package/dist/controllers/calendar_controller.d.ts +38 -16
- package/dist/controllers/calendar_controller.js +228 -260
- package/dist/controllers/calendar_controller.js.map +1 -1
- package/dist/controllers/carousel_controller.d.ts +43 -12
- package/dist/controllers/carousel_controller.js +536 -436
- package/dist/controllers/carousel_controller.js.map +1 -1
- package/dist/controllers/character_counter_controller.d.ts +44 -7
- package/dist/controllers/character_counter_controller.js +493 -207
- package/dist/controllers/character_counter_controller.js.map +1 -1
- package/dist/controllers/checkbox_controller.d.ts +7 -2
- package/dist/controllers/checkbox_controller.js +38 -74
- package/dist/controllers/checkbox_controller.js.map +1 -1
- package/dist/controllers/clipboard_controller.d.ts +16 -5
- package/dist/controllers/clipboard_controller.js +261 -149
- package/dist/controllers/clipboard_controller.js.map +1 -1
- package/dist/controllers/collapsible_controller.d.ts +17 -5
- package/dist/controllers/collapsible_controller.js +304 -120
- package/dist/controllers/collapsible_controller.js.map +1 -1
- package/dist/controllers/color_picker_controller.d.ts +18 -6
- package/dist/controllers/color_picker_controller.js +178 -146
- package/dist/controllers/color_picker_controller.js.map +1 -1
- package/dist/controllers/combobox_controller.d.ts +24 -6
- package/dist/controllers/combobox_controller.js +522 -156
- package/dist/controllers/combobox_controller.js.map +1 -1
- package/dist/controllers/command_palette_controller.d.ts +51 -20
- package/dist/controllers/command_palette_controller.js +1156 -395
- package/dist/controllers/command_palette_controller.js.map +1 -1
- package/dist/controllers/conditional_fields_controller.d.ts +15 -2
- package/dist/controllers/conditional_fields_controller.js +300 -171
- package/dist/controllers/conditional_fields_controller.js.map +1 -1
- package/dist/controllers/confirm_controller.d.ts +49 -12
- package/dist/controllers/confirm_controller.js +980 -262
- package/dist/controllers/confirm_controller.js.map +1 -1
- package/dist/controllers/context_menu_controller.d.ts +80 -18
- package/dist/controllers/context_menu_controller.js +346 -153
- package/dist/controllers/context_menu_controller.js.map +1 -1
- package/dist/controllers/count_up_controller.d.ts +13 -1
- package/dist/controllers/count_up_controller.js +73 -21
- package/dist/controllers/count_up_controller.js.map +1 -1
- package/dist/controllers/countdown_controller.d.ts +47 -3
- package/dist/controllers/countdown_controller.js +281 -158
- package/dist/controllers/countdown_controller.js.map +1 -1
- package/dist/controllers/currency_input_controller.d.ts +93 -10
- package/dist/controllers/currency_input_controller.js +575 -225
- package/dist/controllers/currency_input_controller.js.map +1 -1
- package/dist/controllers/data_grid_controller.d.ts +25 -12
- package/dist/controllers/data_grid_controller.js +248 -214
- package/dist/controllers/data_grid_controller.js.map +1 -1
- package/dist/controllers/date_range_picker_controller.d.ts +42 -14
- package/dist/controllers/date_range_picker_controller.js +338 -235
- package/dist/controllers/date_range_picker_controller.js.map +1 -1
- package/dist/controllers/dialog_controller.d.ts +17 -6
- package/dist/controllers/dialog_controller.js +899 -237
- package/dist/controllers/dialog_controller.js.map +1 -1
- package/dist/controllers/direct_upload_controller.d.ts +25 -8
- package/dist/controllers/direct_upload_controller.js +97 -167
- package/dist/controllers/direct_upload_controller.js.map +1 -1
- package/dist/controllers/dirty_form_controller.d.ts +6 -1
- package/dist/controllers/dirty_form_controller.js +72 -69
- package/dist/controllers/dirty_form_controller.js.map +1 -1
- package/dist/controllers/dismissible_controller.d.ts +19 -0
- package/dist/controllers/dismissible_controller.js +196 -24
- package/dist/controllers/dismissible_controller.js.map +1 -1
- package/dist/controllers/drawer_controller.d.ts +39 -11
- package/dist/controllers/drawer_controller.js +974 -355
- package/dist/controllers/drawer_controller.js.map +1 -1
- package/dist/controllers/dropdown_controller.d.ts +31 -1
- package/dist/controllers/dropdown_controller.js +339 -96
- package/dist/controllers/dropdown_controller.js.map +1 -1
- package/dist/controllers/editable_controller.d.ts +12 -1
- package/dist/controllers/editable_controller.js +315 -88
- package/dist/controllers/editable_controller.js.map +1 -1
- package/dist/controllers/empty_state_controller.js +79 -58
- package/dist/controllers/empty_state_controller.js.map +1 -1
- package/dist/controllers/file_dropzone_controller.d.ts +63 -18
- package/dist/controllers/file_dropzone_controller.js +322 -211
- package/dist/controllers/file_dropzone_controller.js.map +1 -1
- package/dist/controllers/filter_controller.js +77 -42
- package/dist/controllers/filter_controller.js.map +1 -1
- package/dist/controllers/flash_controller.d.ts +35 -12
- package/dist/controllers/flash_controller.js +238 -347
- package/dist/controllers/flash_controller.js.map +1 -1
- package/dist/controllers/focus_controller.d.ts +15 -6
- package/dist/controllers/focus_controller.js +679 -240
- package/dist/controllers/focus_controller.js.map +1 -1
- package/dist/controllers/form_field_controller.js +156 -132
- package/dist/controllers/form_field_controller.js.map +1 -1
- package/dist/controllers/form_validation_controller.d.ts +3 -3
- package/dist/controllers/form_validation_controller.js +31 -97
- package/dist/controllers/form_validation_controller.js.map +1 -1
- package/dist/controllers/frame_loading_controller.d.ts +47 -14
- package/dist/controllers/frame_loading_controller.js +275 -217
- package/dist/controllers/frame_loading_controller.js.map +1 -1
- package/dist/controllers/highlight_controller.d.ts +27 -6
- package/dist/controllers/highlight_controller.js +107 -75
- package/dist/controllers/highlight_controller.js.map +1 -1
- package/dist/controllers/hover_card_controller.d.ts +60 -4
- package/dist/controllers/hover_card_controller.js +327 -130
- package/dist/controllers/hover_card_controller.js.map +1 -1
- package/dist/controllers/idle_controller.d.ts +48 -6
- package/dist/controllers/idle_controller.js +271 -101
- package/dist/controllers/idle_controller.js.map +1 -1
- package/dist/controllers/input_mask_controller.d.ts +30 -13
- package/dist/controllers/input_mask_controller.js +483 -97
- package/dist/controllers/input_mask_controller.js.map +1 -1
- package/dist/controllers/intersection_controller.d.ts +32 -13
- package/dist/controllers/intersection_controller.js +150 -106
- package/dist/controllers/intersection_controller.js.map +1 -1
- package/dist/controllers/lazy_frame_controller.d.ts +19 -2
- package/dist/controllers/lazy_frame_controller.js +24 -68
- package/dist/controllers/lazy_frame_controller.js.map +1 -1
- package/dist/controllers/listbox_controller.d.ts +44 -9
- package/dist/controllers/listbox_controller.js +523 -240
- package/dist/controllers/listbox_controller.js.map +1 -1
- package/dist/controllers/local_time_controller.d.ts +9 -7
- package/dist/controllers/local_time_controller.js +102 -77
- package/dist/controllers/local_time_controller.js.map +1 -1
- package/dist/controllers/masonry_controller.d.ts +11 -3
- package/dist/controllers/masonry_controller.js +80 -96
- package/dist/controllers/masonry_controller.js.map +1 -1
- package/dist/controllers/menu_controller.d.ts +55 -11
- package/dist/controllers/menu_controller.js +302 -188
- package/dist/controllers/menu_controller.js.map +1 -1
- package/dist/controllers/menubar_controller.d.ts +51 -9
- package/dist/controllers/menubar_controller.js +232 -345
- package/dist/controllers/menubar_controller.js.map +1 -1
- package/dist/controllers/meter_controller.d.ts +33 -20
- package/dist/controllers/meter_controller.js +417 -87
- package/dist/controllers/meter_controller.js.map +1 -1
- package/dist/controllers/multi_select_controller.d.ts +48 -18
- package/dist/controllers/multi_select_controller.js +785 -393
- package/dist/controllers/multi_select_controller.js.map +1 -1
- package/dist/controllers/navigation_menu_controller.d.ts +27 -6
- package/dist/controllers/navigation_menu_controller.js +190 -250
- package/dist/controllers/navigation_menu_controller.js.map +1 -1
- package/dist/controllers/nested_form_controller.d.ts +10 -0
- package/dist/controllers/nested_form_controller.js +396 -192
- package/dist/controllers/nested_form_controller.js.map +1 -1
- package/dist/controllers/network_status_controller.d.ts +23 -0
- package/dist/controllers/network_status_controller.js +268 -62
- package/dist/controllers/network_status_controller.js.map +1 -1
- package/dist/controllers/number_input_controller.d.ts +50 -8
- package/dist/controllers/number_input_controller.js +610 -303
- package/dist/controllers/number_input_controller.js.map +1 -1
- package/dist/controllers/optimistic_controller.d.ts +8 -5
- package/dist/controllers/optimistic_controller.js +45 -87
- package/dist/controllers/optimistic_controller.js.map +1 -1
- package/dist/controllers/otp_controller.d.ts +55 -8
- package/dist/controllers/otp_controller.js +658 -255
- package/dist/controllers/otp_controller.js.map +1 -1
- package/dist/controllers/overflow_indicator_controller.d.ts +5 -0
- package/dist/controllers/overflow_indicator_controller.js +122 -113
- package/dist/controllers/overflow_indicator_controller.js.map +1 -1
- package/dist/controllers/overflow_menu_controller.d.ts +58 -20
- package/dist/controllers/overflow_menu_controller.js +470 -295
- package/dist/controllers/overflow_menu_controller.js.map +1 -1
- package/dist/controllers/pagination_controller.d.ts +37 -7
- package/dist/controllers/pagination_controller.js +332 -123
- package/dist/controllers/pagination_controller.js.map +1 -1
- package/dist/controllers/password_reveal_controller.d.ts +46 -8
- package/dist/controllers/password_reveal_controller.js +392 -121
- package/dist/controllers/password_reveal_controller.js.map +1 -1
- package/dist/controllers/password_strength_controller.d.ts +15 -6
- package/dist/controllers/password_strength_controller.js +111 -158
- package/dist/controllers/password_strength_controller.js.map +1 -1
- package/dist/controllers/persist_controller.d.ts +11 -4
- package/dist/controllers/persist_controller.js +165 -111
- package/dist/controllers/persist_controller.js.map +1 -1
- package/dist/controllers/pointer_drag_controller.d.ts +35 -12
- package/dist/controllers/pointer_drag_controller.js +434 -188
- package/dist/controllers/pointer_drag_controller.js.map +1 -1
- package/dist/controllers/popover_controller.d.ts +41 -5
- package/dist/controllers/popover_controller.js +269 -113
- package/dist/controllers/popover_controller.js.map +1 -1
- package/dist/controllers/portal_controller.d.ts +44 -4
- package/dist/controllers/portal_controller.js +215 -76
- package/dist/controllers/portal_controller.js.map +1 -1
- package/dist/controllers/preview_guard_controller.d.ts +10 -4
- package/dist/controllers/preview_guard_controller.js +243 -116
- package/dist/controllers/preview_guard_controller.js.map +1 -1
- package/dist/controllers/progress_controller.d.ts +20 -19
- package/dist/controllers/progress_controller.js +391 -78
- package/dist/controllers/progress_controller.js.map +1 -1
- package/dist/controllers/radio_group_controller.d.ts +21 -9
- package/dist/controllers/radio_group_controller.js +278 -211
- package/dist/controllers/radio_group_controller.js.map +1 -1
- package/dist/controllers/range_slider_controller.d.ts +47 -6
- package/dist/controllers/range_slider_controller.js +220 -113
- package/dist/controllers/range_slider_controller.js.map +1 -1
- package/dist/controllers/rating_controller.d.ts +20 -4
- package/dist/controllers/rating_controller.js +458 -211
- package/dist/controllers/rating_controller.js.map +1 -1
- package/dist/controllers/read_more_controller.d.ts +2 -0
- package/dist/controllers/read_more_controller.js +138 -63
- package/dist/controllers/read_more_controller.js.map +1 -1
- package/dist/controllers/reading_progress_controller.d.ts +1 -1
- package/dist/controllers/reading_progress_controller.js +166 -137
- package/dist/controllers/reading_progress_controller.js.map +1 -1
- package/dist/controllers/relative_time_controller.d.ts +20 -6
- package/dist/controllers/relative_time_controller.js +211 -112
- package/dist/controllers/relative_time_controller.js.map +1 -1
- package/dist/controllers/reset_on_restore_controller.d.ts +85 -0
- package/dist/controllers/{reset_before_cache_controller.js → reset_on_restore_controller.js} +103 -38
- package/dist/controllers/reset_on_restore_controller.js.map +1 -0
- package/dist/controllers/resizable_controller.d.ts +31 -2
- package/dist/controllers/resizable_controller.js +299 -150
- package/dist/controllers/resizable_controller.js.map +1 -1
- package/dist/controllers/roving_controller.d.ts +3 -3
- package/dist/controllers/roving_controller.js +49 -88
- package/dist/controllers/roving_controller.js.map +1 -1
- package/dist/controllers/scroll_area_controller.d.ts +7 -3
- package/dist/controllers/scroll_area_controller.js +490 -246
- package/dist/controllers/scroll_area_controller.js.map +1 -1
- package/dist/controllers/scroll_restore_controller.d.ts +3 -3
- package/dist/controllers/scroll_restore_controller.js +14 -55
- package/dist/controllers/scroll_restore_controller.js.map +1 -1
- package/dist/controllers/scroll_visibility_controller.d.ts +28 -12
- package/dist/controllers/scroll_visibility_controller.js +432 -149
- package/dist/controllers/scroll_visibility_controller.js.map +1 -1
- package/dist/controllers/scrollspy_controller.d.ts +6 -1
- package/dist/controllers/scrollspy_controller.js +193 -248
- package/dist/controllers/scrollspy_controller.js.map +1 -1
- package/dist/controllers/separator_controller.d.ts +20 -5
- package/dist/controllers/separator_controller.js +285 -142
- package/dist/controllers/separator_controller.js.map +1 -1
- package/dist/controllers/sidebar_controller.d.ts +65 -8
- package/dist/controllers/sidebar_controller.js +1069 -404
- package/dist/controllers/sidebar_controller.js.map +1 -1
- package/dist/controllers/skeleton_controller.d.ts +23 -0
- package/dist/controllers/skeleton_controller.js +259 -101
- package/dist/controllers/skeleton_controller.js.map +1 -1
- package/dist/controllers/slider_controller.d.ts +29 -2
- package/dist/controllers/slider_controller.js +187 -86
- package/dist/controllers/slider_controller.js.map +1 -1
- package/dist/controllers/smart_sticky_header_controller.d.ts +22 -4
- package/dist/controllers/smart_sticky_header_controller.js +173 -66
- package/dist/controllers/smart_sticky_header_controller.js.map +1 -1
- package/dist/controllers/sortable_controller.d.ts +4 -4
- package/dist/controllers/sortable_controller.js +26 -125
- package/dist/controllers/sortable_controller.js.map +1 -1
- package/dist/controllers/spinner_controller.d.ts +39 -4
- package/dist/controllers/spinner_controller.js +288 -173
- package/dist/controllers/spinner_controller.js.map +1 -1
- package/dist/controllers/step_indicator_controller.d.ts +9 -4
- package/dist/controllers/step_indicator_controller.js +105 -46
- package/dist/controllers/step_indicator_controller.js.map +1 -1
- package/dist/controllers/stepper_controller.d.ts +14 -6
- package/dist/controllers/stepper_controller.js +120 -73
- package/dist/controllers/stepper_controller.js.map +1 -1
- package/dist/controllers/stick_to_bottom_controller.d.ts +9 -1
- package/dist/controllers/stick_to_bottom_controller.js +275 -140
- package/dist/controllers/stick_to_bottom_controller.js.map +1 -1
- package/dist/controllers/sticky_observer_controller.d.ts +11 -0
- package/dist/controllers/sticky_observer_controller.js +220 -49
- package/dist/controllers/sticky_observer_controller.js.map +1 -1
- package/dist/controllers/submit_once_controller.d.ts +24 -8
- package/dist/controllers/submit_once_controller.js +376 -227
- package/dist/controllers/submit_once_controller.js.map +1 -1
- package/dist/controllers/switch_controller.d.ts +18 -4
- package/dist/controllers/switch_controller.js +201 -84
- package/dist/controllers/switch_controller.js.map +1 -1
- package/dist/controllers/tabs_controller.d.ts +9 -6
- package/dist/controllers/tabs_controller.js +41 -30
- package/dist/controllers/tabs_controller.js.map +1 -1
- package/dist/controllers/tags_input_controller.d.ts +16 -3
- package/dist/controllers/tags_input_controller.js +293 -173
- package/dist/controllers/tags_input_controller.js.map +1 -1
- package/dist/controllers/textarea_autosize_controller.d.ts +11 -1
- package/dist/controllers/textarea_autosize_controller.js +108 -74
- package/dist/controllers/textarea_autosize_controller.js.map +1 -1
- package/dist/controllers/theme_controller.d.ts +24 -11
- package/dist/controllers/theme_controller.js +140 -116
- package/dist/controllers/theme_controller.js.map +1 -1
- package/dist/controllers/time_picker_controller.d.ts +55 -5
- package/dist/controllers/time_picker_controller.js +331 -127
- package/dist/controllers/time_picker_controller.js.map +1 -1
- package/dist/controllers/toast_controller.d.ts +40 -16
- package/dist/controllers/toast_controller.js +244 -324
- package/dist/controllers/toast_controller.js.map +1 -1
- package/dist/controllers/toggle_group_controller.d.ts +14 -6
- package/dist/controllers/toggle_group_controller.js +252 -191
- package/dist/controllers/toggle_group_controller.js.map +1 -1
- package/dist/controllers/toolbar_controller.d.ts +8 -6
- package/dist/controllers/toolbar_controller.js +219 -120
- package/dist/controllers/toolbar_controller.js.map +1 -1
- package/dist/controllers/tooltip_controller.d.ts +49 -4
- package/dist/controllers/tooltip_controller.js +158 -124
- package/dist/controllers/tooltip_controller.js.map +1 -1
- package/dist/controllers/transition_controller.d.ts +22 -4
- package/dist/controllers/transition_controller.js +123 -119
- package/dist/controllers/transition_controller.js.map +1 -1
- package/dist/controllers/tree_view_controller.d.ts +22 -12
- package/dist/controllers/tree_view_controller.js +283 -369
- package/dist/controllers/tree_view_controller.js.map +1 -1
- package/dist/index.d.ts +10 -5
- package/dist/index.js +8573 -10410
- package/dist/index.js.map +1 -1
- package/dist/inspector/cli.d.ts +38 -14
- package/dist/inspector/cli.js +108 -40
- package/dist/inspector/cli.js.map +1 -1
- package/dist/inspector/cli_bin.js +145 -64
- package/dist/inspector/cli_bin.js.map +1 -1
- package/dist/inspector/examples.json +20 -20
- package/dist/inspector/manifest.json +802 -101
- package/dist/positioning/index.d.ts +15 -7
- package/dist/positioning/index.js +154 -47
- package/dist/positioning/index.js.map +1 -1
- package/package.json +11 -10
- package/dist/controllers/reset_before_cache_controller.d.ts +0 -76
- package/dist/controllers/reset_before_cache_controller.js.map +0 -1
|
@@ -1,87 +1,190 @@
|
|
|
1
1
|
import { Controller } from '@hotwired/stimulus';
|
|
2
2
|
|
|
3
|
-
// src/controllers/input_mask_controller.ts
|
|
4
|
-
|
|
5
|
-
// src/utils/composition_tracker.ts
|
|
6
3
|
var COMPOSITION_INPUT_TYPES = /* @__PURE__ */ new Set([
|
|
7
4
|
"insertCompositionText",
|
|
8
5
|
"insertFromComposition",
|
|
9
6
|
"deleteCompositionText",
|
|
10
7
|
"deleteByComposition"
|
|
11
8
|
]);
|
|
9
|
+
function isCompositionInputType(inputType) {
|
|
10
|
+
return inputType !== void 0 && COMPOSITION_INPUT_TYPES.has(inputType);
|
|
11
|
+
}
|
|
12
|
+
var BEFORE_MORPH_ATTRIBUTE = "turbo:before-morph-attribute";
|
|
13
|
+
var textOf = (element) => element.value;
|
|
14
|
+
var holdsFocus = (element) => element instanceof Node && element.getRootNode().activeElement === element;
|
|
12
15
|
var CompositionTracker = class {
|
|
13
16
|
#observedTargets = /* @__PURE__ */ new Set();
|
|
14
|
-
#
|
|
17
|
+
#composition = null;
|
|
15
18
|
#onStart;
|
|
16
19
|
#onEnd;
|
|
17
|
-
|
|
20
|
+
#onAbandon;
|
|
18
21
|
#confirmedTarget = null;
|
|
22
|
+
#keyComposing = false;
|
|
23
|
+
#connected = false;
|
|
24
|
+
#abandoned = null;
|
|
19
25
|
constructor(options = {}) {
|
|
20
26
|
this.#onStart = options.onStart;
|
|
21
27
|
this.#onEnd = options.onEnd;
|
|
28
|
+
this.#onAbandon = options.onAbandon;
|
|
22
29
|
}
|
|
23
|
-
/** Starts lifecycle tracking for `target`; repeated calls are idempotent. */
|
|
24
30
|
observe(target) {
|
|
31
|
+
this.#connected = true;
|
|
25
32
|
if (this.#observedTargets.has(target)) return;
|
|
26
33
|
target.addEventListener("compositionstart", this.#handleStart);
|
|
27
34
|
target.addEventListener("compositionend", this.#handleEnd);
|
|
28
|
-
target.addEventListener("keydown", this.#handleKeydown);
|
|
35
|
+
target.addEventListener("keydown", this.#handleKeydown, true);
|
|
36
|
+
target.addEventListener("beforeinput", this.#handleBeforeInput, true);
|
|
37
|
+
target.addEventListener("input", this.#handleInput, true);
|
|
38
|
+
target.addEventListener("blur", this.#handleBlur, true);
|
|
39
|
+
target.addEventListener(BEFORE_MORPH_ATTRIBUTE, this.#handleBeforeMorphAttribute);
|
|
29
40
|
this.#observedTargets.add(target);
|
|
30
41
|
}
|
|
31
|
-
/** Stops tracking one target and clears any active composition it owned. */
|
|
32
42
|
unobserve(target) {
|
|
33
43
|
if (!this.#observedTargets.delete(target)) return;
|
|
34
|
-
|
|
35
|
-
target
|
|
36
|
-
target.removeEventListener("keydown", this.#handleKeydown);
|
|
37
|
-
this.#activeTargets.delete(target);
|
|
44
|
+
this.#release(target);
|
|
45
|
+
if (this.#composition?.target === target) this.#letGo();
|
|
38
46
|
if (this.#confirmedTarget === target) this.#confirmedTarget = null;
|
|
39
47
|
}
|
|
40
|
-
/** Releases every listener and clears state so reconnect starts cleanly. */
|
|
41
48
|
disconnect() {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
target.removeEventListener("compositionend", this.#handleEnd);
|
|
45
|
-
target.removeEventListener("keydown", this.#handleKeydown);
|
|
46
|
-
}
|
|
49
|
+
this.#connected = false;
|
|
50
|
+
for (const target of this.#observedTargets) this.#release(target);
|
|
47
51
|
this.#observedTargets.clear();
|
|
48
|
-
this.#
|
|
52
|
+
this.#letGo();
|
|
49
53
|
this.#confirmedTarget = null;
|
|
54
|
+
this.#keyComposing = false;
|
|
55
|
+
this.#abandoned = null;
|
|
50
56
|
}
|
|
51
|
-
/** True when lifecycle tracking or the current event reports composition. */
|
|
52
57
|
isComposing(event) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
this.#settle();
|
|
59
|
+
return event?.isComposing === true || this.#composition !== null;
|
|
60
|
+
}
|
|
61
|
+
composingElement() {
|
|
62
|
+
this.#settle();
|
|
63
|
+
return this.#composition?.element ?? null;
|
|
64
|
+
}
|
|
65
|
+
owns(event) {
|
|
66
|
+
const element = this.composingElement();
|
|
67
|
+
return event.isComposing === true || element !== null && element === event.target;
|
|
68
|
+
}
|
|
61
69
|
consumesConfirmedInput(event) {
|
|
62
70
|
const confirmed = this.#confirmedTarget;
|
|
63
71
|
this.#confirmedTarget = null;
|
|
64
72
|
if (confirmed === null || confirmed !== event.target) return false;
|
|
65
73
|
const inputType = event.inputType;
|
|
66
|
-
return !inputType ||
|
|
74
|
+
return !inputType || isCompositionInputType(inputType);
|
|
75
|
+
}
|
|
76
|
+
#release(target) {
|
|
77
|
+
target.removeEventListener("compositionstart", this.#handleStart);
|
|
78
|
+
target.removeEventListener("compositionend", this.#handleEnd);
|
|
79
|
+
target.removeEventListener("keydown", this.#handleKeydown, true);
|
|
80
|
+
target.removeEventListener("beforeinput", this.#handleBeforeInput, true);
|
|
81
|
+
target.removeEventListener("input", this.#handleInput, true);
|
|
82
|
+
target.removeEventListener("blur", this.#handleBlur, true);
|
|
83
|
+
target.removeEventListener(BEFORE_MORPH_ATTRIBUTE, this.#handleBeforeMorphAttribute);
|
|
67
84
|
}
|
|
85
|
+
#letGo() {
|
|
86
|
+
const composition = this.#composition;
|
|
87
|
+
if (composition === null) return;
|
|
88
|
+
if (!holdsFocus(composition.element)) {
|
|
89
|
+
this.#composition = null;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
queueMicrotask(() => {
|
|
93
|
+
if (this.#composition !== composition || this.#observedTargets.has(composition.target)) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
this.#composition = null;
|
|
97
|
+
if (!this.#connected) return;
|
|
98
|
+
this.#abandoned = { element: composition.element, inPlace: true };
|
|
99
|
+
this.#runAbandon();
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
#settle() {
|
|
103
|
+
const composition = this.#composition;
|
|
104
|
+
if (composition === null) return;
|
|
105
|
+
const { target, element, text } = composition;
|
|
106
|
+
if (target instanceof Node && element instanceof Node && !target.contains(element)) {
|
|
107
|
+
this.#composition = null;
|
|
108
|
+
} else if (textOf(element) !== text) {
|
|
109
|
+
this.#abandon(false);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
#abandon(inPlace) {
|
|
113
|
+
this.#owe(inPlace);
|
|
114
|
+
this.#composition = null;
|
|
115
|
+
queueMicrotask(this.#runAbandon);
|
|
116
|
+
}
|
|
117
|
+
#owe(inPlace) {
|
|
118
|
+
const composition = this.#composition;
|
|
119
|
+
if (composition !== null) this.#abandoned = { element: composition.element, inPlace };
|
|
120
|
+
}
|
|
121
|
+
#runAbandon = () => {
|
|
122
|
+
const abandoned = this.#abandoned;
|
|
123
|
+
if (abandoned === null) return;
|
|
124
|
+
this.#abandoned = null;
|
|
125
|
+
this.#onAbandon?.(abandoned.element, abandoned.inPlace);
|
|
126
|
+
};
|
|
68
127
|
#handleStart = (event) => {
|
|
69
128
|
this.#confirmedTarget = null;
|
|
70
|
-
|
|
129
|
+
this.#settle();
|
|
130
|
+
this.#owe(true);
|
|
131
|
+
const target = event.currentTarget;
|
|
132
|
+
const element = event.target;
|
|
133
|
+
this.#composition = { target, element, text: textOf(element) };
|
|
134
|
+
this.#runAbandon();
|
|
71
135
|
this.#onStart?.(event);
|
|
72
136
|
};
|
|
73
137
|
#handleEnd = (event) => {
|
|
74
|
-
|
|
138
|
+
this.#runAbandon();
|
|
139
|
+
if (this.#composition?.target === event.currentTarget) this.#composition = null;
|
|
75
140
|
this.#confirmedTarget = event.target;
|
|
76
141
|
this.#onEnd?.(event);
|
|
77
142
|
};
|
|
78
|
-
|
|
79
|
-
|
|
143
|
+
#handleKeydown = (event) => {
|
|
144
|
+
this.#settle();
|
|
145
|
+
this.#runAbandon();
|
|
80
146
|
this.#confirmedTarget = null;
|
|
147
|
+
this.#keyComposing = event.isComposing === true;
|
|
148
|
+
};
|
|
149
|
+
#handleBeforeInput = (event) => {
|
|
150
|
+
const keyComposing = this.#keyComposing;
|
|
151
|
+
this.#keyComposing = false;
|
|
152
|
+
this.#settle();
|
|
153
|
+
const { isComposing, inputType } = event;
|
|
154
|
+
if (this.#composition !== null && !keyComposing && !isComposing && inputType && !isCompositionInputType(inputType)) {
|
|
155
|
+
this.#abandon(true);
|
|
156
|
+
}
|
|
157
|
+
this.#runAbandon();
|
|
158
|
+
};
|
|
159
|
+
#handleInput = (event) => {
|
|
160
|
+
const composition = this.#composition;
|
|
161
|
+
const { isTrusted, isComposing, inputType } = event;
|
|
162
|
+
if (composition !== null && event.target === composition.element && (isTrusted || isComposing || isCompositionInputType(inputType))) {
|
|
163
|
+
composition.text = textOf(composition.element);
|
|
164
|
+
} else {
|
|
165
|
+
this.#settle();
|
|
166
|
+
}
|
|
167
|
+
this.#runAbandon();
|
|
168
|
+
};
|
|
169
|
+
#handleBlur = (event) => {
|
|
170
|
+
this.#settle();
|
|
171
|
+
this.#runAbandon();
|
|
172
|
+
const composition = this.#composition;
|
|
173
|
+
if (composition === null || composition.target === composition.element) return;
|
|
174
|
+
const { element } = composition;
|
|
175
|
+
if (!(element instanceof Node) || event.target !== element) return;
|
|
176
|
+
const root = element.getRootNode();
|
|
177
|
+
if (root.activeElement !== element) this.#composition = null;
|
|
178
|
+
};
|
|
179
|
+
#handleBeforeMorphAttribute = (event) => {
|
|
180
|
+
this.#settle();
|
|
181
|
+
const composition = this.#composition;
|
|
182
|
+
if (composition?.target !== event.currentTarget || event.target !== composition.element) return;
|
|
183
|
+
const detail = event.detail;
|
|
184
|
+
if (detail?.attributeName === "value") event.preventDefault();
|
|
81
185
|
};
|
|
82
186
|
};
|
|
83
187
|
|
|
84
|
-
// src/utils/declared_value.ts
|
|
85
188
|
function parseDeclared(raw, parse, fallback) {
|
|
86
189
|
try {
|
|
87
190
|
return parse(raw);
|
|
@@ -105,7 +208,43 @@ function parseJsonObject(raw) {
|
|
|
105
208
|
return parsed;
|
|
106
209
|
}
|
|
107
210
|
|
|
108
|
-
|
|
211
|
+
var DetachGate = class _DetachGate {
|
|
212
|
+
#pending = false;
|
|
213
|
+
get pending() {
|
|
214
|
+
return this.#pending;
|
|
215
|
+
}
|
|
216
|
+
static isDetached(host) {
|
|
217
|
+
return !host.element.isConnected || !_DetachGate.#listed(host);
|
|
218
|
+
}
|
|
219
|
+
disconnected(host, teardown) {
|
|
220
|
+
const carried = _DetachGate.#carried(host);
|
|
221
|
+
if (!carried && _DetachGate.isDetached(host)) {
|
|
222
|
+
this.#pending = false;
|
|
223
|
+
teardown();
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
this.#pending = true;
|
|
227
|
+
const probe = () => {
|
|
228
|
+
if (!this.#pending) return;
|
|
229
|
+
this.#pending = false;
|
|
230
|
+
teardown();
|
|
231
|
+
};
|
|
232
|
+
if (carried) setTimeout(probe, 0);
|
|
233
|
+
else queueMicrotask(probe);
|
|
234
|
+
}
|
|
235
|
+
static #carried(host) {
|
|
236
|
+
const element = host.element;
|
|
237
|
+
return !element.isConnected && element.closest("[data-turbo-permanent]") !== null && _DetachGate.#listed(host);
|
|
238
|
+
}
|
|
239
|
+
static #listed(host) {
|
|
240
|
+
const tokens = (host.element.getAttribute("data-controller") ?? "").split(/\s+/);
|
|
241
|
+
return tokens.includes(host.identifier);
|
|
242
|
+
}
|
|
243
|
+
cancel() {
|
|
244
|
+
this.#pending = false;
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
|
|
109
248
|
function inheritsFieldsetDisabled(control) {
|
|
110
249
|
let fieldset = control.closest("fieldset[disabled]");
|
|
111
250
|
while (fieldset) {
|
|
@@ -116,7 +255,120 @@ function inheritsFieldsetDisabled(control) {
|
|
|
116
255
|
return false;
|
|
117
256
|
}
|
|
118
257
|
|
|
119
|
-
|
|
258
|
+
function sharedRegistry(key, create) {
|
|
259
|
+
const symbol = Symbol.for(key);
|
|
260
|
+
const scope = globalThis;
|
|
261
|
+
const existing = scope[symbol];
|
|
262
|
+
if (existing !== void 0) return existing;
|
|
263
|
+
const registry = create();
|
|
264
|
+
Object.defineProperty(globalThis, symbol, { value: registry });
|
|
265
|
+
return registry;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
var PREFIX = "__stimeo_raw_v1_";
|
|
269
|
+
var documents = sharedRegistry(
|
|
270
|
+
"stimeo-ui.form-data-projection.registry.v1",
|
|
271
|
+
() => /* @__PURE__ */ new WeakMap()
|
|
272
|
+
);
|
|
273
|
+
function decodedName(key) {
|
|
274
|
+
if (!key.startsWith(PREFIX)) return null;
|
|
275
|
+
const separator = PREFIX.length + 32;
|
|
276
|
+
if (key[separator] !== ":") return null;
|
|
277
|
+
try {
|
|
278
|
+
const name = JSON.parse(key.slice(separator + 1));
|
|
279
|
+
return typeof name === "string" ? name : null;
|
|
280
|
+
} catch {
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
function projectedFieldName(name) {
|
|
285
|
+
return decodedName(name) ?? name;
|
|
286
|
+
}
|
|
287
|
+
function forDocument(document2) {
|
|
288
|
+
const existing = documents.get(document2);
|
|
289
|
+
if (existing) return existing;
|
|
290
|
+
const state = {
|
|
291
|
+
fields: /* @__PURE__ */ new Map(),
|
|
292
|
+
byField: /* @__PURE__ */ new WeakMap(),
|
|
293
|
+
handle: (event) => {
|
|
294
|
+
const data = event.formData;
|
|
295
|
+
if (!data) return;
|
|
296
|
+
const entries = [...data.entries()];
|
|
297
|
+
let changed = false;
|
|
298
|
+
const projected = entries.map(([key, value]) => {
|
|
299
|
+
const name = decodedName(key);
|
|
300
|
+
if (name === null) return [key, value];
|
|
301
|
+
changed = true;
|
|
302
|
+
const field = state.fields.get(key);
|
|
303
|
+
const live = field && field.field.name === key && field.field.form === event.target;
|
|
304
|
+
return [name, live ? field.project(value) : ""];
|
|
305
|
+
});
|
|
306
|
+
if (!changed) return;
|
|
307
|
+
for (const key of new Set(data.keys())) data.delete(key);
|
|
308
|
+
for (const [name, value] of projected) data.append(name, value);
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
documents.set(document2, state);
|
|
312
|
+
document2.addEventListener("formdata", state.handle, { capture: true });
|
|
313
|
+
return state;
|
|
314
|
+
}
|
|
315
|
+
function prepareFormDataProjection(form) {
|
|
316
|
+
const state = forDocument(form.ownerDocument);
|
|
317
|
+
form.addEventListener("formdata", state.handle, { capture: true });
|
|
318
|
+
}
|
|
319
|
+
var FormDataProjection = class {
|
|
320
|
+
#held = null;
|
|
321
|
+
hold(field, project) {
|
|
322
|
+
const held = this.#held;
|
|
323
|
+
if (held?.field === field && held.key === field.name && held.document === field.ownerDocument) {
|
|
324
|
+
if (field.form) prepareFormDataProjection(field.form);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
this.release();
|
|
328
|
+
const name = projectedFieldName(field.name);
|
|
329
|
+
if (name === "" || field.type === "hidden" && name.toLowerCase() === "_charset_") return;
|
|
330
|
+
const state = forDocument(field.ownerDocument);
|
|
331
|
+
if (field.form) prepareFormDataProjection(field.form);
|
|
332
|
+
const previous = state.byField.get(field);
|
|
333
|
+
if (previous) {
|
|
334
|
+
state.fields.delete(previous.key);
|
|
335
|
+
field.removeEventListener("turbo:morph-element", previous.restore);
|
|
336
|
+
}
|
|
337
|
+
const nonce = Array.from(
|
|
338
|
+
crypto.getRandomValues(new Uint8Array(16)),
|
|
339
|
+
(value) => value.toString(16).padStart(2, "0")
|
|
340
|
+
).join("");
|
|
341
|
+
const key = `${PREFIX}${nonce}:${JSON.stringify(name)}`;
|
|
342
|
+
const projection = {
|
|
343
|
+
field,
|
|
344
|
+
key,
|
|
345
|
+
name,
|
|
346
|
+
project,
|
|
347
|
+
document: field.ownerDocument,
|
|
348
|
+
state,
|
|
349
|
+
restore: () => {
|
|
350
|
+
if (field.name === name) field.name = key;
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
state.fields.set(key, projection);
|
|
354
|
+
state.byField.set(field, projection);
|
|
355
|
+
this.#held = projection;
|
|
356
|
+
field.name = key;
|
|
357
|
+
field.addEventListener("turbo:morph-element", projection.restore);
|
|
358
|
+
}
|
|
359
|
+
release() {
|
|
360
|
+
const held = this.#held;
|
|
361
|
+
this.#held = null;
|
|
362
|
+
if (held === null) return;
|
|
363
|
+
held.field.removeEventListener("turbo:morph-element", held.restore);
|
|
364
|
+
const state = held.state;
|
|
365
|
+
if (state.byField.get(held.field) !== held) return;
|
|
366
|
+
state.fields.delete(held.key);
|
|
367
|
+
state.byField.delete(held.field);
|
|
368
|
+
if (held.field.name === held.key) held.field.name = held.name;
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
|
|
120
372
|
var FULL_WIDTH_SHIFT = 65248;
|
|
121
373
|
function halfWidthChar(char) {
|
|
122
374
|
if (char >= "\uFF01" && char <= "\uFF5E") {
|
|
@@ -125,13 +377,123 @@ function halfWidthChar(char) {
|
|
|
125
377
|
return char === "\u3000" ? " " : char;
|
|
126
378
|
}
|
|
127
379
|
|
|
128
|
-
|
|
380
|
+
var ListenerSet = class {
|
|
381
|
+
#abort = new AbortController();
|
|
382
|
+
add(target, type, handler, options) {
|
|
383
|
+
target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });
|
|
384
|
+
}
|
|
385
|
+
dispose() {
|
|
386
|
+
this.#abort.abort();
|
|
387
|
+
this.#abort = new AbortController();
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
var MicrotaskCoalescer = class {
|
|
392
|
+
#run;
|
|
393
|
+
#queued = false;
|
|
394
|
+
#active = false;
|
|
395
|
+
#generation = 0;
|
|
396
|
+
constructor(run) {
|
|
397
|
+
this.#run = run;
|
|
398
|
+
}
|
|
399
|
+
activate() {
|
|
400
|
+
this.#active = true;
|
|
401
|
+
}
|
|
402
|
+
cancel() {
|
|
403
|
+
this.#active = false;
|
|
404
|
+
this.#queued = false;
|
|
405
|
+
this.#generation += 1;
|
|
406
|
+
}
|
|
407
|
+
get pending() {
|
|
408
|
+
return this.#queued;
|
|
409
|
+
}
|
|
410
|
+
schedule() {
|
|
411
|
+
if (!this.#active || this.#queued) return;
|
|
412
|
+
this.#queued = true;
|
|
413
|
+
const generation = this.#generation;
|
|
414
|
+
queueMicrotask(() => {
|
|
415
|
+
if (generation !== this.#generation || !this.#queued || !this.#active) return;
|
|
416
|
+
this.#queued = false;
|
|
417
|
+
this.#run();
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
var MorphRenderWatcher = class {
|
|
423
|
+
#listeners = new ListenerSet();
|
|
424
|
+
#pass;
|
|
425
|
+
#element = null;
|
|
426
|
+
#onMorph = () => this.#pass.schedule();
|
|
427
|
+
constructor(run) {
|
|
428
|
+
this.#pass = new MicrotaskCoalescer(run);
|
|
429
|
+
}
|
|
430
|
+
observe(element) {
|
|
431
|
+
if (this.#element === element) return;
|
|
432
|
+
this.disconnect();
|
|
433
|
+
this.#element = element;
|
|
434
|
+
this.#pass.activate();
|
|
435
|
+
this.#listeners.add(element, "turbo:morph-element", this.#onMorph);
|
|
436
|
+
}
|
|
437
|
+
schedule() {
|
|
438
|
+
this.#pass.schedule();
|
|
439
|
+
}
|
|
440
|
+
get pending() {
|
|
441
|
+
return this.#pass.pending;
|
|
442
|
+
}
|
|
443
|
+
disconnect() {
|
|
444
|
+
this.#listeners.dispose();
|
|
445
|
+
this.#pass.cancel();
|
|
446
|
+
this.#element = null;
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
var TimerRegistry = class {
|
|
451
|
+
ids = /* @__PURE__ */ new Set();
|
|
452
|
+
clear(id) {
|
|
453
|
+
if (this.ids.delete(id)) {
|
|
454
|
+
this.cancel(id);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
clearAll() {
|
|
458
|
+
for (const id of this.ids) {
|
|
459
|
+
this.cancel(id);
|
|
460
|
+
}
|
|
461
|
+
this.ids.clear();
|
|
462
|
+
}
|
|
463
|
+
get size() {
|
|
464
|
+
return this.ids.size;
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
var SafeTimeout = class extends TimerRegistry {
|
|
468
|
+
set(callback, delay) {
|
|
469
|
+
const id = this.schedule(() => {
|
|
470
|
+
this.ids.delete(id);
|
|
471
|
+
callback();
|
|
472
|
+
}, delay);
|
|
473
|
+
this.ids.add(id);
|
|
474
|
+
return id;
|
|
475
|
+
}
|
|
476
|
+
schedule(callback, delay) {
|
|
477
|
+
return window.setTimeout(callback, delay);
|
|
478
|
+
}
|
|
479
|
+
cancel(id) {
|
|
480
|
+
window.clearTimeout(id);
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
|
|
484
|
+
function prepareInputMaskForm(form) {
|
|
485
|
+
prepareFormDataProjection(form);
|
|
486
|
+
}
|
|
129
487
|
var DEFAULT_TOKENS = {
|
|
130
488
|
"9": "\\d",
|
|
131
489
|
a: "[A-Za-z]",
|
|
132
490
|
"*": "[A-Za-z0-9]"
|
|
133
491
|
};
|
|
134
492
|
var UNMASK_ATTR = "unmask";
|
|
493
|
+
var rawWriters = sharedRegistry(
|
|
494
|
+
"stimeo-ui.input-mask-raw-writer.registry.v1",
|
|
495
|
+
() => /* @__PURE__ */ new WeakMap()
|
|
496
|
+
);
|
|
135
497
|
function acceptedForm(regex, char) {
|
|
136
498
|
if (regex.test(char)) return char;
|
|
137
499
|
const half = halfWidthChar(char);
|
|
@@ -208,7 +570,6 @@ function tokenCharOffset(tokenFlags, n) {
|
|
|
208
570
|
return -1;
|
|
209
571
|
}
|
|
210
572
|
var InputMaskController = class extends Controller {
|
|
211
|
-
/** The attribute above, in the namespace this controller is registered under. */
|
|
212
573
|
get #unmaskAttribute() {
|
|
213
574
|
return `data-${this.identifier}-${UNMASK_ATTR}`;
|
|
214
575
|
}
|
|
@@ -219,19 +580,16 @@ var InputMaskController = class extends Controller {
|
|
|
219
580
|
};
|
|
220
581
|
static actions = ["format"];
|
|
221
582
|
static events = ["change", "reconcile"];
|
|
222
|
-
/** The value this controller last committed, and the baseline both events compare. */
|
|
223
583
|
#lastValue = null;
|
|
224
584
|
#started = false;
|
|
225
|
-
|
|
585
|
+
#rawSink = null;
|
|
586
|
+
#rawValue = "";
|
|
587
|
+
#rawSourceForm = null;
|
|
588
|
+
#submission = new FormDataProjection();
|
|
226
589
|
#tokens = compileTokens("");
|
|
227
|
-
/** The field's text when the running composition began. */
|
|
228
590
|
#textBeforeComposition = "";
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
* and formats the confirmed text once when the composition ends. A composition
|
|
232
|
-
* that ends on the text it began with committed nothing, so a re-format then is
|
|
233
|
-
* the page's: the mask changed while it ran.
|
|
234
|
-
*/
|
|
591
|
+
#formatted = null;
|
|
592
|
+
#shown = { result: null, empty: true };
|
|
235
593
|
#composition = new CompositionTracker({
|
|
236
594
|
onStart: () => {
|
|
237
595
|
this.#textBeforeComposition = this.element.value;
|
|
@@ -239,9 +597,11 @@ var InputMaskController = class extends Controller {
|
|
|
239
597
|
onEnd: () => {
|
|
240
598
|
const committedNothing = this.element.value === this.#textBeforeComposition;
|
|
241
599
|
this.#reformat(committedNothing ? "reconcile" : "edit");
|
|
600
|
+
},
|
|
601
|
+
onAbandon: () => {
|
|
602
|
+
if (this.#formatted !== this.#declared) this.#reformat("reconcile");
|
|
242
603
|
}
|
|
243
604
|
});
|
|
244
|
-
/** Re-parses the declaration and re-formats under the tokens it now selects. */
|
|
245
605
|
tokensValueChanged() {
|
|
246
606
|
this.#tokens = compileTokens(this.tokensValue);
|
|
247
607
|
if (this.#started) this.#reformat("reconcile");
|
|
@@ -249,41 +609,55 @@ var InputMaskController = class extends Controller {
|
|
|
249
609
|
patternValueChanged() {
|
|
250
610
|
if (this.#started) this.#reformat("reconcile");
|
|
251
611
|
}
|
|
252
|
-
/** Clears a sink it stops maintaining so a submit cannot carry a stale raw value. */
|
|
253
612
|
unmaskToHiddenValueChanged() {
|
|
254
613
|
if (!this.#started) return;
|
|
255
|
-
if (!this.unmaskToHiddenValue)
|
|
256
|
-
const sink = this.#resolveSink();
|
|
257
|
-
if (sink) sink.value = "";
|
|
258
|
-
}
|
|
614
|
+
if (!this.unmaskToHiddenValue) this.#withdraw();
|
|
259
615
|
this.#reformat("reconcile");
|
|
260
616
|
}
|
|
617
|
+
#withdraw() {
|
|
618
|
+
if (this.#retractRaw() && this.#composition.isComposing()) this.#formatted = null;
|
|
619
|
+
}
|
|
620
|
+
#morph = new MorphRenderWatcher(() => this.#reformat("reconcile"));
|
|
621
|
+
#gate = new DetachGate();
|
|
622
|
+
#adoption = new SafeTimeout();
|
|
261
623
|
connect() {
|
|
624
|
+
this.#gate.cancel();
|
|
625
|
+
this.#morph.observe(this.element);
|
|
262
626
|
this.#started = true;
|
|
263
627
|
this.#composition.observe(this.element);
|
|
628
|
+
if (!this.unmaskToHiddenValue) this.#withdraw();
|
|
629
|
+
if (this.#composition.isComposing()) {
|
|
630
|
+
this.#reformat("reconcile");
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
264
633
|
this.#lastValue = this.element.value;
|
|
265
634
|
this.#reformat("reconcile");
|
|
635
|
+
if (this.unmaskToHiddenValue && this.#rawSink === null) {
|
|
636
|
+
this.#adoption.set(() => this.#adoptSink(), 0);
|
|
637
|
+
}
|
|
266
638
|
}
|
|
267
639
|
disconnect() {
|
|
640
|
+
this.#morph.disconnect();
|
|
268
641
|
this.#started = false;
|
|
269
642
|
this.#composition.disconnect();
|
|
643
|
+
this.#adoption.clearAll();
|
|
644
|
+
this.#gate.disconnected(this, () => this.#retractRaw());
|
|
270
645
|
}
|
|
271
|
-
/** Formats the field on input, preserving the caret. Bound via `data-action`. */
|
|
272
646
|
format(event) {
|
|
273
647
|
if (this.#composition.isComposing(event)) return;
|
|
274
648
|
this.#reformat("edit", deletionOf(event));
|
|
275
649
|
}
|
|
276
|
-
/**
|
|
277
|
-
* Core reformat: mask the current value, restore the caret, sync the sink and
|
|
278
|
-
* the state hooks, and report a moved value under the event `cause` selects.
|
|
279
|
-
*
|
|
280
|
-
* @stimeoRenderRoot
|
|
281
|
-
*/
|
|
282
650
|
#reformat(cause, deletion = null) {
|
|
283
|
-
if (this.#composition.isComposing())
|
|
651
|
+
if (this.#composition.isComposing()) {
|
|
652
|
+
this.#showAgain();
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
this.#formatted = this.#declared;
|
|
284
656
|
const input = this.element;
|
|
285
657
|
const raw = input.value;
|
|
286
658
|
if (this.patternValue === "") {
|
|
659
|
+
this.#retractRaw();
|
|
660
|
+
this.#shown = { result: null, empty: raw.length === 0 };
|
|
287
661
|
this.#flag("data-mask-complete", false);
|
|
288
662
|
this.#flag("data-mask-empty", raw.length === 0);
|
|
289
663
|
this.#lastValue = raw;
|
|
@@ -309,8 +683,10 @@ var InputMaskController = class extends Controller {
|
|
|
309
683
|
this.#lastValue = raw;
|
|
310
684
|
return;
|
|
311
685
|
}
|
|
312
|
-
input.value
|
|
313
|
-
|
|
686
|
+
if (input.value !== result.masked) {
|
|
687
|
+
input.value = result.masked;
|
|
688
|
+
this.#restoreCaret(result.tokenFlags, anchor);
|
|
689
|
+
}
|
|
314
690
|
this.#publish(result, result.masked);
|
|
315
691
|
if (result.masked === this.#lastValue) return;
|
|
316
692
|
this.#lastValue = result.masked;
|
|
@@ -318,24 +694,59 @@ var InputMaskController = class extends Controller {
|
|
|
318
694
|
if (cause === "edit") this.dispatch("change", { detail });
|
|
319
695
|
else this.dispatch("reconcile", { detail });
|
|
320
696
|
}
|
|
321
|
-
|
|
697
|
+
get #declared() {
|
|
698
|
+
return JSON.stringify([this.patternValue, this.tokensValue, this.unmaskToHiddenValue]);
|
|
699
|
+
}
|
|
322
700
|
#publish(result, shown) {
|
|
701
|
+
this.#shown = { result, empty: shown.length === 0 };
|
|
323
702
|
if (this.unmaskToHiddenValue) {
|
|
324
703
|
const sink = this.#resolveSink();
|
|
325
|
-
if (sink
|
|
704
|
+
if (sink !== this.#rawSink) this.#retractRaw();
|
|
705
|
+
if (sink) {
|
|
706
|
+
sink.value = result.unmasked;
|
|
707
|
+
rawWriters.set(sink, this);
|
|
708
|
+
this.#rawSink = sink;
|
|
709
|
+
this.#rawValue = result.unmasked;
|
|
710
|
+
this.#rawSourceForm = this.element.form;
|
|
711
|
+
this.#submission.hold(sink, (value) => this.#submittedValue(sink, value));
|
|
712
|
+
}
|
|
326
713
|
}
|
|
327
714
|
this.#flag("data-mask-complete", result.complete);
|
|
328
715
|
this.#flag("data-mask-empty", shown.length === 0);
|
|
329
716
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
717
|
+
#showAgain() {
|
|
718
|
+
const shown = this.#shown;
|
|
719
|
+
const sink = this.#rawSink;
|
|
720
|
+
if (shown.result !== null && this.unmaskToHiddenValue && sink !== null && rawWriters.get(sink) === this && this.#resolveSink() === sink) {
|
|
721
|
+
sink.value = shown.result.unmasked;
|
|
722
|
+
}
|
|
723
|
+
this.#flag("data-mask-complete", shown.result?.complete ?? false);
|
|
724
|
+
this.#flag("data-mask-empty", shown.empty);
|
|
725
|
+
}
|
|
726
|
+
#retractRaw() {
|
|
727
|
+
const sink = this.#rawSink;
|
|
728
|
+
this.#rawSink = null;
|
|
729
|
+
this.#submission.release();
|
|
730
|
+
if (sink === null || rawWriters.get(sink) !== this) return false;
|
|
731
|
+
rawWriters.delete(sink);
|
|
732
|
+
if (sink.value === this.#rawValue) sink.value = "";
|
|
733
|
+
return true;
|
|
734
|
+
}
|
|
735
|
+
#submittedValue(sink, value) {
|
|
736
|
+
if (rawWriters.get(sink) !== this || sink.value !== this.#rawValue || value !== this.#rawValue)
|
|
737
|
+
return value;
|
|
738
|
+
const source = this.element;
|
|
739
|
+
const listed = (source.getAttribute("data-controller") ?? "").split(/\s+/).includes(this.identifier);
|
|
740
|
+
const associated = source.form === null ? this.#rawSourceForm === null : source.form === sink.form;
|
|
741
|
+
const eligible = source.isConnected && this.application.element.contains(source) && listed && this.unmaskToHiddenValue && associated;
|
|
742
|
+
return eligible ? value : "";
|
|
743
|
+
}
|
|
744
|
+
#adoptSink() {
|
|
745
|
+
if (this.#resolveSink() !== null) this.#reformat("reconcile");
|
|
746
|
+
}
|
|
335
747
|
#significantBefore(prefix) {
|
|
336
748
|
return applyMask(prefix, this.patternValue, this.#tokens).unmasked.length;
|
|
337
749
|
}
|
|
338
|
-
/** Places the caret after the `n`-th token char (skipping following literals). */
|
|
339
750
|
#restoreCaret(tokenFlags, n) {
|
|
340
751
|
let position;
|
|
341
752
|
if (n <= 0) {
|
|
@@ -357,23 +768,6 @@ var InputMaskController = class extends Controller {
|
|
|
357
768
|
} catch {
|
|
358
769
|
}
|
|
359
770
|
}
|
|
360
|
-
/**
|
|
361
|
-
* The hidden raw-value sink for this input, resolved so several masked inputs
|
|
362
|
-
* can coexist in one form:
|
|
363
|
-
*
|
|
364
|
-
* 1. **Explicit pairing** — a sink whose attribute value names this input's
|
|
365
|
-
* `id` (`data-stimeo--input-mask-unmask="zip"`).
|
|
366
|
-
* 2. **Nearest container** — otherwise, walking up from the input, the first
|
|
367
|
-
* *value-less* sink in the closest ancestor. Wrapped input+sink pairs each
|
|
368
|
-
* find their own sink, and a single form-level sink is found the same
|
|
369
|
-
* way. A sink claimed by another input's id is never matched here.
|
|
370
|
-
*
|
|
371
|
-
* Both steps only ever consider the associated form's own controls, so a sink
|
|
372
|
-
* belonging to a different form (or to none) is never written, while one the
|
|
373
|
-
* `form` attribute associates from elsewhere in the document still resolves —
|
|
374
|
-
* for either the input or the sink, neither of which needs to contain or be
|
|
375
|
-
* contained by the form. A form-less input reads the document instead.
|
|
376
|
-
*/
|
|
377
771
|
#resolveSink() {
|
|
378
772
|
const candidates = this.#sinkCandidates();
|
|
379
773
|
const id = this.element.id;
|
|
@@ -389,12 +783,6 @@ var InputMaskController = class extends Controller {
|
|
|
389
783
|
}
|
|
390
784
|
return null;
|
|
391
785
|
}
|
|
392
|
-
/**
|
|
393
|
-
* Every sink the input's form owns, in document order — one collection read per
|
|
394
|
-
* resolution, so the cost tracks the form's own controls and not the depth of
|
|
395
|
-
* the markup around it. `form.elements` lists controls the `form` attribute
|
|
396
|
-
* associates from anywhere in the document, and lists nothing another form owns.
|
|
397
|
-
*/
|
|
398
786
|
#sinkCandidates() {
|
|
399
787
|
const form = this.element.form;
|
|
400
788
|
if (form === null) {
|
|
@@ -406,13 +794,11 @@ var InputMaskController = class extends Controller {
|
|
|
406
794
|
(element) => element instanceof HTMLInputElement && element.hasAttribute(this.#unmaskAttribute)
|
|
407
795
|
);
|
|
408
796
|
}
|
|
409
|
-
/** Sets a boolean `data-*` flag to `"true"` when `on`, else removes it. */
|
|
410
797
|
#flag(name, on) {
|
|
411
798
|
if (on) this.element.setAttribute(name, "true");
|
|
412
799
|
else this.element.removeAttribute(name);
|
|
413
800
|
}
|
|
414
801
|
};
|
|
415
802
|
|
|
416
|
-
export { InputMaskController, applyMask };
|
|
417
|
-
//# sourceMappingURL=input_mask_controller.js.map
|
|
803
|
+
export { InputMaskController, applyMask, prepareInputMaskForm };
|
|
418
804
|
//# sourceMappingURL=input_mask_controller.js.map
|