stimeo-ui 0.15.0 → 0.17.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 +209 -0
- package/README.md +128 -1
- package/dist/cable/index.d.ts +79 -23
- package/dist/cable/index.js +392 -417
- package/dist/cable/index.js.map +1 -1
- package/dist/controllers/accordion_controller.d.ts +34 -5
- package/dist/controllers/accordion_controller.js +228 -28
- package/dist/controllers/accordion_controller.js.map +1 -1
- package/dist/controllers/alert_dialog_controller.d.ts +20 -9
- package/dist/controllers/alert_dialog_controller.js +862 -221
- package/dist/controllers/alert_dialog_controller.js.map +1 -1
- package/dist/controllers/announcer_controller.d.ts +38 -7
- package/dist/controllers/announcer_controller.js +135 -191
- 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 +295 -110
- package/dist/controllers/auto_submit_controller.js.map +1 -1
- package/dist/controllers/avatar_controller.js +172 -106
- package/dist/controllers/avatar_controller.js.map +1 -1
- package/dist/controllers/breadcrumb_controller.d.ts +10 -7
- package/dist/controllers/breadcrumb_controller.js +0 -129
- package/dist/controllers/breadcrumb_controller.js.map +1 -1
- package/dist/controllers/bulk_select_controller.d.ts +22 -4
- package/dist/controllers/bulk_select_controller.js +264 -53
- package/dist/controllers/bulk_select_controller.js.map +1 -1
- package/dist/controllers/calendar_controller.d.ts +109 -28
- package/dist/controllers/calendar_controller.js +346 -180
- package/dist/controllers/calendar_controller.js.map +1 -1
- package/dist/controllers/carousel_controller.d.ts +99 -27
- package/dist/controllers/carousel_controller.js +587 -300
- package/dist/controllers/carousel_controller.js.map +1 -1
- package/dist/controllers/character_counter_controller.d.ts +18 -2
- package/dist/controllers/character_counter_controller.js +271 -143
- 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 +77 -75
- package/dist/controllers/checkbox_controller.js.map +1 -1
- package/dist/controllers/clipboard_controller.d.ts +44 -7
- package/dist/controllers/clipboard_controller.js +187 -108
- package/dist/controllers/clipboard_controller.js.map +1 -1
- package/dist/controllers/collapsible_controller.d.ts +41 -5
- package/dist/controllers/collapsible_controller.js +374 -108
- package/dist/controllers/collapsible_controller.js.map +1 -1
- package/dist/controllers/color_picker_controller.d.ts +47 -14
- package/dist/controllers/color_picker_controller.js +183 -127
- package/dist/controllers/color_picker_controller.js.map +1 -1
- package/dist/controllers/combobox_controller.d.ts +33 -6
- package/dist/controllers/combobox_controller.js +426 -109
- package/dist/controllers/combobox_controller.js.map +1 -1
- package/dist/controllers/command_palette_controller.d.ts +45 -14
- package/dist/controllers/command_palette_controller.js +994 -350
- 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 +212 -125
- 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 +939 -245
- package/dist/controllers/confirm_controller.js.map +1 -1
- package/dist/controllers/context_menu_controller.d.ts +36 -3
- package/dist/controllers/context_menu_controller.js +275 -127
- 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 +75 -2
- package/dist/controllers/countdown_controller.js +235 -97
- package/dist/controllers/countdown_controller.js.map +1 -1
- package/dist/controllers/currency_input_controller.d.ts +93 -15
- package/dist/controllers/currency_input_controller.js +241 -118
- package/dist/controllers/currency_input_controller.js.map +1 -1
- package/dist/controllers/data_grid_controller.d.ts +78 -22
- package/dist/controllers/data_grid_controller.js +229 -135
- package/dist/controllers/data_grid_controller.js.map +1 -1
- package/dist/controllers/date_range_picker_controller.d.ts +64 -11
- package/dist/controllers/date_range_picker_controller.js +359 -165
- package/dist/controllers/date_range_picker_controller.js.map +1 -1
- package/dist/controllers/dialog_controller.d.ts +22 -3
- package/dist/controllers/dialog_controller.js +887 -225
- package/dist/controllers/dialog_controller.js.map +1 -1
- package/dist/controllers/direct_upload_controller.d.ts +24 -7
- package/dist/controllers/direct_upload_controller.js +80 -142
- 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 +26 -47
- 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 +175 -20
- package/dist/controllers/dismissible_controller.js.map +1 -1
- package/dist/controllers/drawer_controller.d.ts +52 -16
- package/dist/controllers/drawer_controller.js +963 -336
- package/dist/controllers/drawer_controller.js.map +1 -1
- package/dist/controllers/dropdown_controller.d.ts +39 -3
- package/dist/controllers/dropdown_controller.js +342 -85
- package/dist/controllers/dropdown_controller.js.map +1 -1
- package/dist/controllers/editable_controller.d.ts +12 -1
- package/dist/controllers/editable_controller.js +182 -58
- package/dist/controllers/editable_controller.js.map +1 -1
- package/dist/controllers/empty_state_controller.js +67 -53
- package/dist/controllers/empty_state_controller.js.map +1 -1
- package/dist/controllers/file_dropzone_controller.d.ts +60 -18
- package/dist/controllers/file_dropzone_controller.js +426 -229
- 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 +78 -36
- package/dist/controllers/filter_controller.js.map +1 -1
- package/dist/controllers/flash_controller.d.ts +57 -14
- package/dist/controllers/flash_controller.js +328 -211
- package/dist/controllers/flash_controller.js.map +1 -1
- package/dist/controllers/focus_controller.d.ts +12 -3
- package/dist/controllers/focus_controller.js +654 -239
- package/dist/controllers/focus_controller.js.map +1 -1
- package/dist/controllers/form_field_controller.js +153 -136
- package/dist/controllers/form_field_controller.js.map +1 -1
- package/dist/controllers/form_validation_controller.js +29 -96
- package/dist/controllers/form_validation_controller.js.map +1 -1
- package/dist/controllers/frame_loading_controller.d.ts +41 -9
- package/dist/controllers/frame_loading_controller.js +263 -198
- package/dist/controllers/frame_loading_controller.js.map +1 -1
- package/dist/controllers/highlight_controller.d.ts +22 -2
- package/dist/controllers/highlight_controller.js +119 -70
- package/dist/controllers/highlight_controller.js.map +1 -1
- package/dist/controllers/hover_card_controller.d.ts +65 -4
- package/dist/controllers/hover_card_controller.js +335 -118
- package/dist/controllers/hover_card_controller.js.map +1 -1
- package/dist/controllers/idle_controller.d.ts +58 -4
- package/dist/controllers/idle_controller.js +316 -65
- 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 +116 -61
- 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 +147 -103
- package/dist/controllers/intersection_controller.js.map +1 -1
- package/dist/controllers/lazy_frame_controller.d.ts +16 -0
- package/dist/controllers/lazy_frame_controller.js +9 -56
- package/dist/controllers/lazy_frame_controller.js.map +1 -1
- package/dist/controllers/listbox_controller.d.ts +84 -10
- package/dist/controllers/listbox_controller.js +413 -153
- package/dist/controllers/listbox_controller.js.map +1 -1
- package/dist/controllers/local_time_controller.d.ts +1 -1
- package/dist/controllers/local_time_controller.js +54 -64
- 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 +70 -95
- package/dist/controllers/masonry_controller.js.map +1 -1
- package/dist/controllers/menu_controller.d.ts +40 -9
- package/dist/controllers/menu_controller.js +254 -167
- package/dist/controllers/menu_controller.js.map +1 -1
- package/dist/controllers/menubar_controller.d.ts +15 -4
- package/dist/controllers/menubar_controller.js +206 -331
- package/dist/controllers/menubar_controller.js.map +1 -1
- package/dist/controllers/meter_controller.d.ts +20 -0
- package/dist/controllers/meter_controller.js +159 -71
- package/dist/controllers/meter_controller.js.map +1 -1
- package/dist/controllers/multi_select_controller.d.ts +50 -7
- package/dist/controllers/multi_select_controller.js +797 -388
- package/dist/controllers/multi_select_controller.js.map +1 -1
- package/dist/controllers/navigation_menu_controller.d.ts +19 -1
- package/dist/controllers/navigation_menu_controller.js +156 -231
- 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 +373 -174
- 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 +241 -45
- package/dist/controllers/network_status_controller.js.map +1 -1
- package/dist/controllers/number_input_controller.d.ts +62 -10
- package/dist/controllers/number_input_controller.js +387 -227
- package/dist/controllers/number_input_controller.js.map +1 -1
- package/dist/controllers/optimistic_controller.js +28 -75
- package/dist/controllers/optimistic_controller.js.map +1 -1
- package/dist/controllers/otp_controller.d.ts +38 -7
- package/dist/controllers/otp_controller.js +344 -196
- package/dist/controllers/otp_controller.js.map +1 -1
- package/dist/controllers/overflow_indicator_controller.d.ts +13 -12
- package/dist/controllers/overflow_indicator_controller.js +167 -93
- package/dist/controllers/overflow_indicator_controller.js.map +1 -1
- package/dist/controllers/overflow_menu_controller.d.ts +66 -9
- package/dist/controllers/overflow_menu_controller.js +408 -277
- package/dist/controllers/overflow_menu_controller.js.map +1 -1
- package/dist/controllers/pagination_controller.d.ts +52 -15
- package/dist/controllers/pagination_controller.js +342 -120
- package/dist/controllers/pagination_controller.js.map +1 -1
- package/dist/controllers/password_reveal_controller.d.ts +60 -9
- package/dist/controllers/password_reveal_controller.js +424 -99
- package/dist/controllers/password_reveal_controller.js.map +1 -1
- package/dist/controllers/password_strength_controller.d.ts +14 -5
- package/dist/controllers/password_strength_controller.js +99 -153
- 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 +252 -96
- package/dist/controllers/persist_controller.js.map +1 -1
- package/dist/controllers/pointer_drag_controller.d.ts +19 -7
- package/dist/controllers/pointer_drag_controller.js +263 -164
- package/dist/controllers/pointer_drag_controller.js.map +1 -1
- package/dist/controllers/popover_controller.d.ts +46 -4
- package/dist/controllers/popover_controller.js +267 -94
- package/dist/controllers/popover_controller.js.map +1 -1
- package/dist/controllers/portal_controller.d.ts +44 -4
- package/dist/controllers/portal_controller.js +209 -72
- 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 -112
- package/dist/controllers/preview_guard_controller.js.map +1 -1
- package/dist/controllers/progress_controller.d.ts +11 -0
- package/dist/controllers/progress_controller.js +132 -59
- package/dist/controllers/progress_controller.js.map +1 -1
- package/dist/controllers/radio_group_controller.d.ts +19 -8
- package/dist/controllers/radio_group_controller.js +138 -133
- package/dist/controllers/radio_group_controller.js.map +1 -1
- package/dist/controllers/range_slider_controller.d.ts +92 -4
- package/dist/controllers/range_slider_controller.js +245 -112
- package/dist/controllers/range_slider_controller.js.map +1 -1
- package/dist/controllers/rating_controller.d.ts +33 -6
- package/dist/controllers/rating_controller.js +429 -194
- package/dist/controllers/rating_controller.js.map +1 -1
- package/dist/controllers/read_more_controller.d.ts +26 -2
- package/dist/controllers/read_more_controller.js +185 -47
- 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 +147 -135
- package/dist/controllers/reading_progress_controller.js.map +1 -1
- package/dist/controllers/relative_time_controller.d.ts +18 -4
- package/dist/controllers/relative_time_controller.js +145 -110
- 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} +97 -38
- package/dist/controllers/reset_on_restore_controller.js.map +1 -0
- package/dist/controllers/resizable_controller.d.ts +44 -4
- package/dist/controllers/resizable_controller.js +294 -118
- package/dist/controllers/resizable_controller.js.map +1 -1
- package/dist/controllers/roving_controller.js +39 -84
- 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 +428 -221
- package/dist/controllers/scroll_area_controller.js.map +1 -1
- package/dist/controllers/scroll_restore_controller.js +0 -53
- 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 +395 -146
- package/dist/controllers/scroll_visibility_controller.js.map +1 -1
- package/dist/controllers/scrollspy_controller.d.ts +9 -3
- package/dist/controllers/scrollspy_controller.js +181 -236
- package/dist/controllers/scrollspy_controller.js.map +1 -1
- package/dist/controllers/separator_controller.d.ts +59 -17
- package/dist/controllers/separator_controller.js +288 -132
- package/dist/controllers/separator_controller.js.map +1 -1
- package/dist/controllers/sidebar_controller.d.ts +81 -7
- package/dist/controllers/sidebar_controller.js +1071 -375
- package/dist/controllers/sidebar_controller.js.map +1 -1
- package/dist/controllers/skeleton_controller.d.ts +23 -0
- package/dist/controllers/skeleton_controller.js +248 -92
- package/dist/controllers/skeleton_controller.js.map +1 -1
- package/dist/controllers/slider_controller.d.ts +72 -8
- package/dist/controllers/slider_controller.js +211 -96
- package/dist/controllers/slider_controller.js.map +1 -1
- package/dist/controllers/smart_sticky_header_controller.d.ts +21 -3
- package/dist/controllers/smart_sticky_header_controller.js +163 -54
- package/dist/controllers/smart_sticky_header_controller.js.map +1 -1
- package/dist/controllers/sortable_controller.js +13 -110
- package/dist/controllers/sortable_controller.js.map +1 -1
- package/dist/controllers/spinner_controller.d.ts +39 -4
- package/dist/controllers/spinner_controller.js +277 -161
- package/dist/controllers/spinner_controller.js.map +1 -1
- package/dist/controllers/step_indicator_controller.d.ts +24 -17
- package/dist/controllers/step_indicator_controller.js +107 -53
- package/dist/controllers/step_indicator_controller.js.map +1 -1
- package/dist/controllers/stepper_controller.d.ts +43 -9
- package/dist/controllers/stepper_controller.js +171 -48
- package/dist/controllers/stepper_controller.js.map +1 -1
- package/dist/controllers/stick_to_bottom_controller.d.ts +25 -0
- package/dist/controllers/stick_to_bottom_controller.js +310 -116
- 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 +214 -49
- package/dist/controllers/sticky_observer_controller.js.map +1 -1
- package/dist/controllers/submit_once_controller.d.ts +22 -6
- package/dist/controllers/submit_once_controller.js +294 -192
- package/dist/controllers/submit_once_controller.js.map +1 -1
- package/dist/controllers/switch_controller.d.ts +40 -7
- package/dist/controllers/switch_controller.js +107 -43
- package/dist/controllers/switch_controller.js.map +1 -1
- package/dist/controllers/tabs_controller.d.ts +13 -1
- package/dist/controllers/tabs_controller.js +50 -25
- package/dist/controllers/tabs_controller.js.map +1 -1
- package/dist/controllers/tags_input_controller.d.ts +27 -3
- package/dist/controllers/tags_input_controller.js +290 -149
- package/dist/controllers/tags_input_controller.js.map +1 -1
- package/dist/controllers/textarea_autosize_controller.d.ts +10 -0
- package/dist/controllers/textarea_autosize_controller.js +71 -58
- package/dist/controllers/textarea_autosize_controller.js.map +1 -1
- package/dist/controllers/theme_controller.d.ts +37 -8
- package/dist/controllers/theme_controller.js +148 -80
- package/dist/controllers/theme_controller.js.map +1 -1
- package/dist/controllers/time_picker_controller.d.ts +18 -1
- package/dist/controllers/time_picker_controller.js +162 -81
- package/dist/controllers/time_picker_controller.js.map +1 -1
- package/dist/controllers/toast_controller.d.ts +85 -23
- package/dist/controllers/toast_controller.js +365 -193
- package/dist/controllers/toast_controller.js.map +1 -1
- package/dist/controllers/toggle_group_controller.d.ts +60 -9
- package/dist/controllers/toggle_group_controller.js +194 -99
- package/dist/controllers/toggle_group_controller.js.map +1 -1
- package/dist/controllers/toolbar_controller.js +92 -90
- package/dist/controllers/toolbar_controller.js.map +1 -1
- package/dist/controllers/tooltip_controller.d.ts +52 -2
- package/dist/controllers/tooltip_controller.js +185 -125
- 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 -115
- package/dist/controllers/transition_controller.js.map +1 -1
- package/dist/controllers/tree_view_controller.d.ts +59 -18
- package/dist/controllers/tree_view_controller.js +248 -290
- package/dist/controllers/tree_view_controller.js.map +1 -1
- package/dist/index.d.ts +33 -3
- package/dist/index.js +8649 -8572
- package/dist/index.js.map +1 -1
- package/dist/inspector/cli.d.ts +95 -9
- package/dist/inspector/cli.js +343 -77
- package/dist/inspector/cli.js.map +1 -1
- package/dist/inspector/cli_bin.js +390 -96
- package/dist/inspector/cli_bin.js.map +1 -1
- package/dist/inspector/examples.json +45 -45
- package/dist/inspector/manifest.json +1308 -155
- package/dist/positioning/index.d.ts +8 -0
- package/dist/positioning/index.js +148 -45
- package/dist/positioning/index.js.map +1 -1
- package/package.json +7 -7
- package/dist/controllers/reset_before_cache_controller.d.ts +0 -76
- package/dist/controllers/reset_before_cache_controller.js.map +0 -1
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { Controller } from '@hotwired/stimulus';
|
|
2
2
|
|
|
3
|
-
// src/controllers/form_field_controller.ts
|
|
4
|
-
|
|
5
|
-
// src/utils/announce.ts
|
|
6
3
|
function announce(message, options = {}) {
|
|
7
4
|
const text = message.trim();
|
|
8
5
|
if (text.length === 0) return;
|
|
@@ -13,13 +10,22 @@ function announce(message, options = {}) {
|
|
|
13
10
|
);
|
|
14
11
|
}
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
function sharedRegistry(key, create) {
|
|
14
|
+
const symbol = Symbol.for(key);
|
|
15
|
+
const scope = globalThis;
|
|
16
|
+
const existing = scope[symbol];
|
|
17
|
+
if (existing !== void 0) return existing;
|
|
18
|
+
const registry = create();
|
|
19
|
+
Object.defineProperty(globalThis, symbol, { value: registry });
|
|
20
|
+
return registry;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var ids = sharedRegistry("stimeo-ui.aria-ids.registry.v1", () => ({ counter: 0 }));
|
|
18
24
|
function uniqueId(prefix = "stimeo") {
|
|
19
25
|
let candidate;
|
|
20
26
|
do {
|
|
21
|
-
counter += 1;
|
|
22
|
-
candidate = `${prefix}-${counter}`;
|
|
27
|
+
ids.counter += 1;
|
|
28
|
+
candidate = `${prefix}-${ids.counter}`;
|
|
23
29
|
} while (typeof document !== "undefined" && document.getElementById(candidate) !== null);
|
|
24
30
|
return candidate;
|
|
25
31
|
}
|
|
@@ -30,103 +36,164 @@ function ensureId(element, prefix = "stimeo") {
|
|
|
30
36
|
return id;
|
|
31
37
|
}
|
|
32
38
|
|
|
33
|
-
|
|
34
|
-
|
|
39
|
+
function isAttributeValue(value) {
|
|
40
|
+
return value === null || typeof value === "string";
|
|
41
|
+
}
|
|
42
|
+
function readLeaseRecord(element, record) {
|
|
43
|
+
try {
|
|
44
|
+
const parsed = JSON.parse(element.getAttribute(record) ?? "null");
|
|
45
|
+
if (!Array.isArray(parsed)) return void 0;
|
|
46
|
+
const [original, written, ...rest] = parsed;
|
|
47
|
+
const linked = rest[0] !== false;
|
|
48
|
+
const beneath = linked ? rest : rest.slice(1);
|
|
49
|
+
if (!beneath.every((under) => typeof under === "string")) return void 0;
|
|
50
|
+
return isAttributeValue(original) && isAttributeValue(written) ? { original, written, linked, beneath } : void 0;
|
|
51
|
+
} catch {
|
|
52
|
+
return void 0;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
var AttributeLease = class _AttributeLease {
|
|
56
|
+
static #registry = sharedRegistry(
|
|
57
|
+
"stimeo-ui.attribute-lease.registry.v1",
|
|
58
|
+
() => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
|
|
59
|
+
);
|
|
35
60
|
#attribute;
|
|
36
|
-
#
|
|
37
|
-
|
|
38
|
-
|
|
61
|
+
#record;
|
|
62
|
+
#base;
|
|
63
|
+
#held = /* @__PURE__ */ new Set();
|
|
64
|
+
constructor(attribute, owner, options = {}) {
|
|
39
65
|
this.#attribute = attribute;
|
|
66
|
+
this.#record = `data-${owner}-${attribute}-lease`;
|
|
67
|
+
this.#base = options.base === true;
|
|
68
|
+
const names = _AttributeLease.#registry.names;
|
|
69
|
+
names.set(attribute, (names.get(attribute) ?? /* @__PURE__ */ new Set()).add(this.#record));
|
|
40
70
|
}
|
|
41
|
-
/** Writes or removes the leased attribute while preserving its authored value. */
|
|
42
71
|
write(element, value) {
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
this.#reflect(element, value);
|
|
72
|
+
const stack = this.#stack(element);
|
|
73
|
+
const hold = this.#take(stack) ?? this.#acquire(element, stack);
|
|
74
|
+
this.#held.add(element);
|
|
75
|
+
const shows = !this.#covered(element, stack, hold);
|
|
76
|
+
hold.written = value;
|
|
77
|
+
this.#mark(element, stack);
|
|
78
|
+
if (shows) this.#reflect(element, value);
|
|
53
79
|
}
|
|
54
|
-
/** Returns one lease without overwriting a value subsequently authored by a consumer. */
|
|
55
80
|
return(element) {
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
this.#
|
|
59
|
-
const
|
|
60
|
-
if (
|
|
81
|
+
const held = this.#held.delete(element);
|
|
82
|
+
const known = _AttributeLease.#registry.stacks.get(element)?.has(this.#attribute);
|
|
83
|
+
const stack = held || known || element.hasAttribute(this.#record) ? this.#stack(element) : [];
|
|
84
|
+
const hold = this.#take(stack);
|
|
85
|
+
if (!hold) return false;
|
|
86
|
+
const carries = element.getAttribute(this.#attribute) === hold.written;
|
|
87
|
+
const owns = carries && !this.#covered(element, stack, hold);
|
|
88
|
+
const index = stack.indexOf(hold);
|
|
89
|
+
stack.splice(index, 1);
|
|
90
|
+
const above = stack[index];
|
|
91
|
+
if (above) above.linked &&= hold.linked;
|
|
92
|
+
this.#mark(element, stack);
|
|
93
|
+
if (!owns) return true;
|
|
94
|
+
const below = hold.linked ? stack[index - 1] : void 0;
|
|
95
|
+
this.#reflect(element, below ? below.written : hold.original);
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
returnAll() {
|
|
99
|
+
for (const element of Array.from(this.#held)) this.return(element);
|
|
100
|
+
}
|
|
101
|
+
#stack(element) {
|
|
102
|
+
const stacks = _AttributeLease.#registry.stacks;
|
|
103
|
+
const byAttribute = stacks.get(element) ?? /* @__PURE__ */ new Map();
|
|
104
|
+
stacks.set(element, byAttribute);
|
|
105
|
+
const stack = byAttribute.get(this.#attribute) ?? this.#seed(element);
|
|
106
|
+
byAttribute.set(this.#attribute, stack);
|
|
107
|
+
return stack;
|
|
108
|
+
}
|
|
109
|
+
#seed(element) {
|
|
110
|
+
const found = [];
|
|
111
|
+
for (const record of _AttributeLease.#registry.names.get(this.#attribute) ?? []) {
|
|
112
|
+
const read = readLeaseRecord(element, record);
|
|
113
|
+
if (read) found.push({ ...read, record });
|
|
114
|
+
}
|
|
115
|
+
const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
|
|
116
|
+
return found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
|
|
117
|
+
lease: null,
|
|
118
|
+
record,
|
|
119
|
+
written,
|
|
120
|
+
original,
|
|
121
|
+
linked: linked && index > 0
|
|
122
|
+
}));
|
|
123
|
+
}
|
|
124
|
+
#take(stack) {
|
|
125
|
+
const hold = stack.find((held) => held.lease === this) ?? stack.find((held) => held.lease === null && held.record === this.#record);
|
|
126
|
+
if (hold) hold.lease = this;
|
|
127
|
+
return hold;
|
|
128
|
+
}
|
|
129
|
+
#acquire(element, stack) {
|
|
130
|
+
const current = element.getAttribute(this.#attribute);
|
|
131
|
+
const top = stack.at(-1);
|
|
132
|
+
const bottom = stack[0];
|
|
133
|
+
const over = top?.written === current ? top : void 0;
|
|
134
|
+
const from = this.#base ? bottom : over;
|
|
135
|
+
const hold = {
|
|
136
|
+
lease: this,
|
|
137
|
+
record: this.#record,
|
|
138
|
+
written: current,
|
|
139
|
+
original: from ? from.original : current,
|
|
140
|
+
linked: !this.#base && over !== void 0
|
|
141
|
+
};
|
|
142
|
+
if (this.#base && bottom) {
|
|
143
|
+
bottom.linked = true;
|
|
144
|
+
stack.unshift(hold);
|
|
145
|
+
} else stack.push(hold);
|
|
146
|
+
return hold;
|
|
147
|
+
}
|
|
148
|
+
#covered(element, stack, hold) {
|
|
149
|
+
const current = element.getAttribute(this.#attribute);
|
|
150
|
+
return stack.slice(stack.indexOf(hold) + 1).some((above) => above.written === current);
|
|
151
|
+
}
|
|
152
|
+
#mark(element, stack) {
|
|
153
|
+
const records = /* @__PURE__ */ new Map([[this.#record, null]]);
|
|
154
|
+
stack.forEach((hold, index) => {
|
|
155
|
+
const names = stack.slice(0, index).map((under) => under.record);
|
|
156
|
+
const beneath = [...new Set(names.reverse())].filter((name) => name !== hold.record);
|
|
157
|
+
const marker = hold.linked || beneath.length === 0 ? [] : [false];
|
|
158
|
+
records.set(
|
|
159
|
+
hold.record,
|
|
160
|
+
hold.written === hold.original && beneath.length === 0 && index === stack.length - 1 ? null : JSON.stringify([hold.original, hold.written, ...marker, ...beneath])
|
|
161
|
+
);
|
|
162
|
+
});
|
|
163
|
+
for (const [name, recorded] of records) {
|
|
164
|
+
if (element.getAttribute(name) === recorded) continue;
|
|
165
|
+
if (recorded === null) element.removeAttribute(name);
|
|
166
|
+
else element.setAttribute(name, recorded);
|
|
167
|
+
}
|
|
61
168
|
}
|
|
62
|
-
/** Reflects only a real value transition, avoiding self-triggered mutation work. */
|
|
63
169
|
#reflect(element, value) {
|
|
64
170
|
if (element.getAttribute(this.#attribute) === value) return;
|
|
65
171
|
if (value === null) element.removeAttribute(this.#attribute);
|
|
66
172
|
else element.setAttribute(this.#attribute, value);
|
|
67
173
|
}
|
|
68
|
-
/** Returns every outstanding lease using the same ownership check as {@link return}. */
|
|
69
|
-
returnAll() {
|
|
70
|
-
for (const element of Array.from(this.#records.keys())) this.return(element);
|
|
71
|
-
}
|
|
72
174
|
};
|
|
73
175
|
|
|
74
|
-
// src/utils/before_cache_reset.ts
|
|
75
|
-
var BeforeCacheReset = class _BeforeCacheReset {
|
|
76
|
-
/** Every subscribed instance, iterated by the one shared document listener. */
|
|
77
|
-
static #subscribers = /* @__PURE__ */ new Set();
|
|
78
|
-
/** The shared listener; installed while at least one instance is subscribed. */
|
|
79
|
-
static #onBeforeCache = () => {
|
|
80
|
-
for (const subscriber of _BeforeCacheReset.#subscribers) subscriber.#rewind();
|
|
81
|
-
};
|
|
82
|
-
#rewind;
|
|
83
|
-
/** @param rewind - the pass that returns this controller's state to its initial form. */
|
|
84
|
-
constructor(rewind) {
|
|
85
|
-
this.#rewind = rewind;
|
|
86
|
-
}
|
|
87
|
-
/** Subscribes to `turbo:before-cache`; call from `connect()`. Idempotent. */
|
|
88
|
-
activate() {
|
|
89
|
-
const first = _BeforeCacheReset.#subscribers.size === 0;
|
|
90
|
-
_BeforeCacheReset.#subscribers.add(this);
|
|
91
|
-
if (first) {
|
|
92
|
-
document.addEventListener("turbo:before-cache", _BeforeCacheReset.#onBeforeCache);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
/** Unsubscribes; call from `disconnect()`. Safe when never subscribed. */
|
|
96
|
-
deactivate() {
|
|
97
|
-
_BeforeCacheReset.#subscribers.delete(this);
|
|
98
|
-
if (_BeforeCacheReset.#subscribers.size > 0) return;
|
|
99
|
-
document.removeEventListener("turbo:before-cache", _BeforeCacheReset.#onBeforeCache);
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
// src/utils/event_owner.ts
|
|
104
176
|
function ownerIndex(candidates, node) {
|
|
105
177
|
if (!(node instanceof Node)) return -1;
|
|
106
178
|
return candidates.findIndex((candidate) => candidate.contains(node));
|
|
107
179
|
}
|
|
108
180
|
|
|
109
|
-
// src/utils/microtask_coalescer.ts
|
|
110
181
|
var MicrotaskCoalescer = class {
|
|
111
182
|
#run;
|
|
112
183
|
#queued = false;
|
|
113
184
|
#active = false;
|
|
114
185
|
#generation = 0;
|
|
115
|
-
/** @param run - the single reconciliation pass, invoked at most once per batch. */
|
|
116
186
|
constructor(run) {
|
|
117
187
|
this.#run = run;
|
|
118
188
|
}
|
|
119
|
-
/** Opens the window in which {@link schedule} is honoured; call from `connect()`. */
|
|
120
189
|
activate() {
|
|
121
190
|
this.#active = true;
|
|
122
191
|
}
|
|
123
|
-
/** Closes the window and drops any pending pass; call from `disconnect()`. */
|
|
124
192
|
cancel() {
|
|
125
193
|
this.#active = false;
|
|
126
194
|
this.#queued = false;
|
|
127
195
|
this.#generation += 1;
|
|
128
196
|
}
|
|
129
|
-
/** Requests one pass after the batch settles. Idempotent; inert outside the window. */
|
|
130
197
|
schedule() {
|
|
131
198
|
if (!this.#active || this.#queued) return;
|
|
132
199
|
this.#queued = true;
|
|
@@ -139,25 +206,29 @@ var MicrotaskCoalescer = class {
|
|
|
139
206
|
}
|
|
140
207
|
};
|
|
141
208
|
|
|
142
|
-
// src/controllers/form_field_controller.ts
|
|
143
209
|
var OBSERVED_ATTRIBUTES = ["hidden", "id"];
|
|
144
|
-
var FormFieldController = class
|
|
210
|
+
var FormFieldController = class extends Controller {
|
|
145
211
|
static targets = ["control", "description", "error"];
|
|
146
212
|
static values = {
|
|
147
213
|
focusOnError: { type: Boolean, default: false }
|
|
148
214
|
};
|
|
149
215
|
static actions = ["clearError", "setError"];
|
|
150
216
|
static events = ["validate"];
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
217
|
+
get #invalidAttribute() {
|
|
218
|
+
return `data-${this.identifier}-invalid`;
|
|
219
|
+
}
|
|
154
220
|
#reconcile = new MicrotaskCoalescer(() => this.#reconcileDom());
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
#ariaErrorMessage = new AttributeLease(
|
|
159
|
-
|
|
160
|
-
|
|
221
|
+
#ariaDescribedBy = new AttributeLease("aria-describedby", this.identifier, {
|
|
222
|
+
base: true
|
|
223
|
+
});
|
|
224
|
+
#ariaErrorMessage = new AttributeLease(
|
|
225
|
+
"aria-errormessage",
|
|
226
|
+
this.identifier,
|
|
227
|
+
{ base: true }
|
|
228
|
+
);
|
|
229
|
+
#ariaInvalid = new AttributeLease("aria-invalid", this.identifier, {
|
|
230
|
+
base: true
|
|
231
|
+
});
|
|
161
232
|
#observer = new MutationObserver((records) => {
|
|
162
233
|
if (records.some((record) => this.#isRelevantMutation(record))) {
|
|
163
234
|
this.#reconcile.schedule();
|
|
@@ -167,13 +238,10 @@ var FormFieldController = class _FormFieldController extends Controller {
|
|
|
167
238
|
#baseDescribedBy = [];
|
|
168
239
|
#explicitInvalid = false;
|
|
169
240
|
#initialized = false;
|
|
170
|
-
/** Wires the initial graph and starts retained-target reconciliation. */
|
|
171
241
|
connect() {
|
|
172
242
|
this.#reconcile.activate();
|
|
173
|
-
this.#ensureAssociationIds();
|
|
174
|
-
this.#beforeCache.activate();
|
|
175
243
|
if (!this.#initialized) {
|
|
176
|
-
this.#explicitInvalid = this.element.hasAttribute(
|
|
244
|
+
this.#explicitInvalid = this.element.hasAttribute(this.#invalidAttribute) && this.#shownErrors().length === 0;
|
|
177
245
|
this.#initialized = true;
|
|
178
246
|
}
|
|
179
247
|
this.#reconcileDom();
|
|
@@ -185,49 +253,29 @@ var FormFieldController = class _FormFieldController extends Controller {
|
|
|
185
253
|
subtree: true
|
|
186
254
|
});
|
|
187
255
|
}
|
|
188
|
-
/** Releases observers, queued work, and ARIA borrowed on the current control. */
|
|
189
256
|
disconnect() {
|
|
190
257
|
this.#reconcile.cancel();
|
|
191
258
|
this.#observer.disconnect();
|
|
192
|
-
this.#beforeCache.deactivate();
|
|
193
259
|
this.#activeControl && this.#releaseControl(this.#activeControl);
|
|
194
260
|
}
|
|
195
|
-
/** Reconciles a control inserted or replaced at runtime. */
|
|
196
261
|
controlTargetConnected() {
|
|
197
262
|
this.#reconcile.schedule();
|
|
198
263
|
}
|
|
199
|
-
/** Schedules restoration of authored ARIA when a control leaves this field. */
|
|
200
264
|
controlTargetDisconnected() {
|
|
201
265
|
this.#reconcile.schedule();
|
|
202
266
|
}
|
|
203
|
-
/** Reconciles a description inserted or replaced at runtime. */
|
|
204
267
|
descriptionTargetConnected() {
|
|
205
268
|
this.#reconcile.schedule();
|
|
206
269
|
}
|
|
207
|
-
/** Removes a departed description from the control's association graph. */
|
|
208
270
|
descriptionTargetDisconnected() {
|
|
209
271
|
this.#reconcile.schedule();
|
|
210
272
|
}
|
|
211
|
-
/** Reconciles an error region inserted or replaced at runtime. */
|
|
212
273
|
errorTargetConnected() {
|
|
213
274
|
this.#reconcile.schedule();
|
|
214
275
|
}
|
|
215
|
-
/** Removes a departed error from invalid state and the association graph. */
|
|
216
276
|
errorTargetDisconnected() {
|
|
217
277
|
this.#reconcile.schedule();
|
|
218
278
|
}
|
|
219
|
-
/**
|
|
220
|
-
* Marks the field invalid and shows the error message. Bound via `data-action`
|
|
221
|
-
* (`#setError`) or callable directly.
|
|
222
|
-
*
|
|
223
|
-
* A non-empty shown message is announced exactly once through the shared
|
|
224
|
-
* assertive announcer. Initial/server reconciliation is deliberately silent.
|
|
225
|
-
*
|
|
226
|
-
* @param arg - Either the message string, or the action event whose
|
|
227
|
-
* `data-stimeo--form-field-message-param` supplies it. When no message is
|
|
228
|
-
* resolvable, any already-populated error targets are simply (re)shown.
|
|
229
|
-
* @param options - Programmatic overrides. Stimulus actions use the Values.
|
|
230
|
-
*/
|
|
231
279
|
setError(arg, options = {}) {
|
|
232
280
|
const message = this.#resolveMessage(arg);
|
|
233
281
|
if (message !== null && this.hasErrorTarget) {
|
|
@@ -244,13 +292,6 @@ var FormFieldController = class _FormFieldController extends Controller {
|
|
|
244
292
|
announce(shownMessage, { assertive: true });
|
|
245
293
|
if (options.focus ?? this.focusOnErrorValue) this.#activeControl?.focus();
|
|
246
294
|
}
|
|
247
|
-
/**
|
|
248
|
-
* Clears the error: empties and hides every error target and marks the field
|
|
249
|
-
* valid. Bound via `data-action` (`#clearError`) or callable directly.
|
|
250
|
-
*
|
|
251
|
-
* Clearing is silent: the visual/ARIA state and validation event are sufficient,
|
|
252
|
-
* while success wording remains an explicit consumer announcement.
|
|
253
|
-
*/
|
|
254
295
|
clearError() {
|
|
255
296
|
for (const error of this.errorTargets) {
|
|
256
297
|
error.replaceChildren();
|
|
@@ -261,16 +302,12 @@ var FormFieldController = class _FormFieldController extends Controller {
|
|
|
261
302
|
const detail = { valid: true, message: "" };
|
|
262
303
|
this.dispatch("validate", { detail });
|
|
263
304
|
}
|
|
264
|
-
/**
|
|
265
|
-
* Rebuilds ids and derived ARIA from the settled target graph without reporting
|
|
266
|
-
* a user validation action.
|
|
267
|
-
*/
|
|
268
305
|
#reconcileDom() {
|
|
269
306
|
this.#ensureAssociationIds();
|
|
270
307
|
this.#adoptCurrentControl();
|
|
271
308
|
const shown = this.#shownErrors();
|
|
272
309
|
const invalid = this.#explicitInvalid || shown.length > 0;
|
|
273
|
-
this.element.toggleAttribute(
|
|
310
|
+
this.element.toggleAttribute(this.#invalidAttribute, invalid);
|
|
274
311
|
const control = this.#activeControl;
|
|
275
312
|
if (!control) return;
|
|
276
313
|
this.#ariaInvalid.write(control, invalid ? "true" : "false");
|
|
@@ -282,7 +319,6 @@ var FormFieldController = class _FormFieldController extends Controller {
|
|
|
282
319
|
const describedBy = this.#uniqueTokens([...this.#baseDescribedBy, ...associationIds]);
|
|
283
320
|
this.#ariaDescribedBy.write(control, describedBy.length > 0 ? describedBy.join(" ") : null);
|
|
284
321
|
}
|
|
285
|
-
/** Assigns stable ids before either capture or reflection uses them. */
|
|
286
322
|
#ensureAssociationIds() {
|
|
287
323
|
for (const description of this.descriptionTargets) {
|
|
288
324
|
ensureId(description, "stimeo--form-field-desc");
|
|
@@ -291,7 +327,6 @@ var FormFieldController = class _FormFieldController extends Controller {
|
|
|
291
327
|
ensureId(error, "stimeo--form-field-error");
|
|
292
328
|
}
|
|
293
329
|
}
|
|
294
|
-
/** Switches ARIA ownership when the singular current control target changes. */
|
|
295
330
|
#adoptCurrentControl() {
|
|
296
331
|
const next = this.hasControlTarget ? this.controlTarget : null;
|
|
297
332
|
if (next === this.#activeControl) return;
|
|
@@ -299,7 +334,6 @@ var FormFieldController = class _FormFieldController extends Controller {
|
|
|
299
334
|
this.#activeControl = next;
|
|
300
335
|
this.#baseDescribedBy = next ? this.#externalDescribedByTokens(next) : [];
|
|
301
336
|
}
|
|
302
|
-
/** Restores one departed control without overwriting later consumer edits. */
|
|
303
337
|
#releaseControl(control) {
|
|
304
338
|
this.#ariaDescribedBy.return(control);
|
|
305
339
|
this.#ariaErrorMessage.return(control);
|
|
@@ -309,26 +343,19 @@ var FormFieldController = class _FormFieldController extends Controller {
|
|
|
309
343
|
this.#baseDescribedBy = [];
|
|
310
344
|
}
|
|
311
345
|
}
|
|
312
|
-
/** Error targets currently visible and non-empty, in document order. */
|
|
313
346
|
#shownErrors() {
|
|
314
347
|
return this.#orderedElements(
|
|
315
348
|
this.errorTargets.filter((error) => !error.hidden && (error.textContent ?? "").trim() !== "")
|
|
316
349
|
);
|
|
317
350
|
}
|
|
318
|
-
/** Text of the first shown error, for validation detail and announcement. */
|
|
319
351
|
#shownMessage() {
|
|
320
352
|
return (this.#shownErrors()[0]?.textContent ?? "").trim();
|
|
321
353
|
}
|
|
322
|
-
/** Resolves a message from a string argument or an action event's params. */
|
|
323
354
|
#resolveMessage(arg) {
|
|
324
355
|
if (typeof arg === "string") return arg;
|
|
325
356
|
const message = arg?.params?.message;
|
|
326
357
|
return typeof message === "string" ? message : null;
|
|
327
358
|
}
|
|
328
|
-
/**
|
|
329
|
-
* Tokens authored on a newly adopted control, excluding ids this controller
|
|
330
|
-
* owns through its current description/error targets.
|
|
331
|
-
*/
|
|
332
359
|
#externalDescribedByTokens(control) {
|
|
333
360
|
const owned = /* @__PURE__ */ new Set([
|
|
334
361
|
...this.descriptionTargets.map((description) => description.id),
|
|
@@ -339,7 +366,6 @@ var FormFieldController = class _FormFieldController extends Controller {
|
|
|
339
366
|
existing.split(/\s+/).filter((token) => token.length > 0 && !owned.has(token))
|
|
340
367
|
);
|
|
341
368
|
}
|
|
342
|
-
/** Deduplicates ARIA tokens without disturbing their first occurrence. */
|
|
343
369
|
#uniqueTokens(tokens) {
|
|
344
370
|
const seen = /* @__PURE__ */ new Set();
|
|
345
371
|
return tokens.filter((token) => {
|
|
@@ -348,14 +374,12 @@ var FormFieldController = class _FormFieldController extends Controller {
|
|
|
348
374
|
return true;
|
|
349
375
|
});
|
|
350
376
|
}
|
|
351
|
-
/** Returns unique current targets in DOM order before serializing IDREF lists. */
|
|
352
377
|
#orderedElements(elements) {
|
|
353
378
|
const candidates = new Set(elements);
|
|
354
379
|
return [this.element, ...this.element.querySelectorAll("*")].filter(
|
|
355
380
|
(element) => candidates.has(element)
|
|
356
381
|
);
|
|
357
382
|
}
|
|
358
|
-
/** Whether one retained-node mutation can alter this controller's derived state. */
|
|
359
383
|
#isRelevantMutation(record) {
|
|
360
384
|
const target = record.target;
|
|
361
385
|
if (record.type === "attributes") {
|
|
@@ -365,14 +389,7 @@ var FormFieldController = class _FormFieldController extends Controller {
|
|
|
365
389
|
}
|
|
366
390
|
return ownerIndex(this.errorTargets, target) !== -1;
|
|
367
391
|
}
|
|
368
|
-
/** Returns borrowed control ARIA before Turbo snapshots the page. */
|
|
369
|
-
#rewindForCache() {
|
|
370
|
-
this.#ariaDescribedBy.returnAll();
|
|
371
|
-
this.#ariaErrorMessage.returnAll();
|
|
372
|
-
this.#ariaInvalid.returnAll();
|
|
373
|
-
}
|
|
374
392
|
};
|
|
375
393
|
|
|
376
394
|
export { FormFieldController };
|
|
377
|
-
//# sourceMappingURL=form_field_controller.js.map
|
|
378
395
|
//# sourceMappingURL=form_field_controller.js.map
|