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,8 +1,158 @@
|
|
|
1
1
|
import { Controller } from '@hotwired/stimulus';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
function setAttributeIfChanged(element, name, value, beforeWrite) {
|
|
4
|
+
if (element.getAttribute(name) === value) return false;
|
|
5
|
+
if (value === null) element.removeAttribute(name);
|
|
6
|
+
else element.setAttribute(name, value);
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function sharedRegistry(key, create) {
|
|
11
|
+
const symbol = Symbol.for(key);
|
|
12
|
+
const scope = globalThis;
|
|
13
|
+
const existing = scope[symbol];
|
|
14
|
+
if (existing !== void 0) return existing;
|
|
15
|
+
const registry2 = create();
|
|
16
|
+
Object.defineProperty(globalThis, symbol, { value: registry2 });
|
|
17
|
+
return registry2;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
var registry = sharedRegistry(
|
|
21
|
+
"stimeo-ui.attribute-lease.registry.v1",
|
|
22
|
+
() => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
|
|
23
|
+
);
|
|
24
|
+
function isAttributeValue(value) {
|
|
25
|
+
return value === null || typeof value === "string";
|
|
26
|
+
}
|
|
27
|
+
function readLeaseRecord(element, record) {
|
|
28
|
+
try {
|
|
29
|
+
const parsed = JSON.parse(element.getAttribute(record) ?? "null");
|
|
30
|
+
if (!Array.isArray(parsed)) return void 0;
|
|
31
|
+
const [original, written, ...rest] = parsed;
|
|
32
|
+
const linked = rest[0] !== false;
|
|
33
|
+
const beneath = linked ? rest : rest.slice(1);
|
|
34
|
+
if (!beneath.every((under) => typeof under === "string")) return void 0;
|
|
35
|
+
return isAttributeValue(original) && isAttributeValue(written) ? { original, written, linked, beneath } : void 0;
|
|
36
|
+
} catch {
|
|
37
|
+
return void 0;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function attributeStack(element, attribute) {
|
|
41
|
+
const byAttribute = registry.stacks.get(element) ?? /* @__PURE__ */ new Map();
|
|
42
|
+
registry.stacks.set(element, byAttribute);
|
|
43
|
+
const known = byAttribute.get(attribute);
|
|
44
|
+
if (known) return known;
|
|
45
|
+
const found = [];
|
|
46
|
+
for (const record of registry.names.get(attribute) ?? []) {
|
|
47
|
+
const read = readLeaseRecord(element, record);
|
|
48
|
+
if (read) found.push({ ...read, record });
|
|
49
|
+
}
|
|
50
|
+
const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
|
|
51
|
+
const stack = found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
|
|
52
|
+
lease: null,
|
|
53
|
+
record,
|
|
54
|
+
written,
|
|
55
|
+
original,
|
|
56
|
+
linked: linked && index > 0
|
|
57
|
+
}));
|
|
58
|
+
byAttribute.set(attribute, stack);
|
|
59
|
+
return stack;
|
|
60
|
+
}
|
|
61
|
+
function findHold(stack, lease, record) {
|
|
62
|
+
return stack.find((held) => held.lease === lease) ?? stack.find((held) => held.lease === null && held.record === record);
|
|
63
|
+
}
|
|
64
|
+
var AttributeLease = class {
|
|
65
|
+
#attribute;
|
|
66
|
+
#record;
|
|
67
|
+
#base;
|
|
68
|
+
#preserveAuthor;
|
|
69
|
+
#held = /* @__PURE__ */ new Set();
|
|
70
|
+
constructor(attribute, owner, options = {}) {
|
|
71
|
+
this.#attribute = attribute;
|
|
72
|
+
this.#record = `data-${owner}-${attribute}-lease`;
|
|
73
|
+
this.#base = options.base === true;
|
|
74
|
+
this.#preserveAuthor = options.preserveAuthor === true;
|
|
75
|
+
const names = registry.names;
|
|
76
|
+
names.set(attribute, (names.get(attribute) ?? /* @__PURE__ */ new Set()).add(this.#record));
|
|
77
|
+
}
|
|
78
|
+
write(element, value) {
|
|
79
|
+
const stack = attributeStack(element, this.#attribute);
|
|
80
|
+
const hold = this.#take(stack) ?? this.#acquire(element, stack);
|
|
81
|
+
this.#held.add(element);
|
|
82
|
+
const shows = !this.#covered(element, stack, hold);
|
|
83
|
+
hold.written = value;
|
|
84
|
+
this.#mark(element, stack);
|
|
85
|
+
if (shows) this.#reflect(element, value);
|
|
86
|
+
}
|
|
87
|
+
return(element) {
|
|
88
|
+
const held = this.#held.delete(element);
|
|
89
|
+
const known = registry.stacks.get(element)?.has(this.#attribute);
|
|
90
|
+
const stack = held || known || element.hasAttribute(this.#record) ? attributeStack(element, this.#attribute) : [];
|
|
91
|
+
const hold = this.#take(stack);
|
|
92
|
+
if (!hold) return false;
|
|
93
|
+
const carries = element.getAttribute(this.#attribute) === hold.written;
|
|
94
|
+
const owns = carries && !this.#covered(element, stack, hold);
|
|
95
|
+
const index = stack.indexOf(hold);
|
|
96
|
+
stack.splice(index, 1);
|
|
97
|
+
const above = stack[index];
|
|
98
|
+
if (above) above.linked &&= hold.linked;
|
|
99
|
+
this.#mark(element, stack);
|
|
100
|
+
if (!owns) return true;
|
|
101
|
+
const below = hold.linked ? stack[index - 1] : void 0;
|
|
102
|
+
this.#reflect(element, below ? below.written : hold.original);
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
returnAll() {
|
|
106
|
+
for (const element of Array.from(this.#held)) this.return(element);
|
|
107
|
+
}
|
|
108
|
+
#take(stack) {
|
|
109
|
+
const hold = findHold(stack, this, this.#record);
|
|
110
|
+
if (hold) hold.lease = this;
|
|
111
|
+
return hold;
|
|
112
|
+
}
|
|
113
|
+
#acquire(element, stack) {
|
|
114
|
+
const current = element.getAttribute(this.#attribute);
|
|
115
|
+
const top = stack.at(-1);
|
|
116
|
+
const bottom = stack[0];
|
|
117
|
+
const over = top?.written === current ? top : void 0;
|
|
118
|
+
const from = this.#base ? this.#preserveAuthor && !stack.some((held) => held.written === current) ? void 0 : bottom : over;
|
|
119
|
+
const hold = {
|
|
120
|
+
lease: this,
|
|
121
|
+
record: this.#record,
|
|
122
|
+
written: current,
|
|
123
|
+
original: from ? from.original : current,
|
|
124
|
+
linked: !this.#base && over !== void 0
|
|
125
|
+
};
|
|
126
|
+
if (this.#base && bottom) {
|
|
127
|
+
bottom.linked = true;
|
|
128
|
+
stack.unshift(hold);
|
|
129
|
+
} else stack.push(hold);
|
|
130
|
+
return hold;
|
|
131
|
+
}
|
|
132
|
+
#covered(element, stack, hold) {
|
|
133
|
+
const current = element.getAttribute(this.#attribute);
|
|
134
|
+
return stack.slice(stack.indexOf(hold) + 1).some((above) => above.written === current);
|
|
135
|
+
}
|
|
136
|
+
#mark(element, stack) {
|
|
137
|
+
const records = /* @__PURE__ */ new Map([[this.#record, null]]);
|
|
138
|
+
stack.forEach((hold, index) => {
|
|
139
|
+
const names = stack.slice(0, index).map((under) => under.record);
|
|
140
|
+
const beneath = [...new Set(names.reverse())].filter((name) => name !== hold.record);
|
|
141
|
+
const marker = hold.linked || beneath.length === 0 ? [] : [false];
|
|
142
|
+
records.set(
|
|
143
|
+
hold.record,
|
|
144
|
+
hold.written === hold.original && beneath.length === 0 && index === stack.length - 1 ? null : JSON.stringify([hold.original, hold.written, ...marker, ...beneath])
|
|
145
|
+
);
|
|
146
|
+
});
|
|
147
|
+
for (const [name, recorded] of records) {
|
|
148
|
+
setAttributeIfChanged(element, name, recorded);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
#reflect(element, value) {
|
|
152
|
+
setAttributeIfChanged(element, this.#attribute, value);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
4
155
|
|
|
5
|
-
// src/utils/state_reason.ts
|
|
6
156
|
var FOCUS_EVENTS = /* @__PURE__ */ new Set(["blur", "focus", "focusin", "focusout"]);
|
|
7
157
|
var POINTER_EVENTS = /* @__PURE__ */ new Set(["mouseenter", "mouseleave", "pointerenter", "pointerleave"]);
|
|
8
158
|
function stateReasonFor(event) {
|
|
@@ -12,16 +162,20 @@ function stateReasonFor(event) {
|
|
|
12
162
|
return "user";
|
|
13
163
|
}
|
|
14
164
|
|
|
15
|
-
|
|
16
|
-
|
|
165
|
+
var StateRegions = class _StateRegions {
|
|
166
|
+
static #registry = sharedRegistry(
|
|
167
|
+
"stimeo-ui.state-regions.registry.v1",
|
|
168
|
+
() => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Set() })
|
|
169
|
+
);
|
|
17
170
|
#whenTrue;
|
|
18
171
|
#whenFalse;
|
|
19
|
-
#
|
|
20
|
-
constructor(options) {
|
|
172
|
+
#record;
|
|
173
|
+
constructor(options, owner) {
|
|
21
174
|
this.#whenTrue = options.whenTrue;
|
|
22
175
|
this.#whenFalse = options.whenFalse ?? null;
|
|
176
|
+
this.#record = `data-${owner}-hidden-region`;
|
|
177
|
+
_StateRegions.#registry.names.add(this.#record);
|
|
23
178
|
}
|
|
24
|
-
/** Shows the regions inside `host` that belong to `isTrue` and hides the others. */
|
|
25
179
|
reflect(host, isTrue) {
|
|
26
180
|
const shown = this.#inside(host, this.#whenTrue());
|
|
27
181
|
if (!this.#whenFalse) {
|
|
@@ -37,59 +191,137 @@ var StateRegions = class {
|
|
|
37
191
|
for (const region of shown) this.#write(region, !isTrue);
|
|
38
192
|
for (const region of hiddenSide) this.#write(region, isTrue);
|
|
39
193
|
}
|
|
40
|
-
|
|
194
|
+
release(host) {
|
|
195
|
+
for (const region of [host, ...host.querySelectorAll("*")]) {
|
|
196
|
+
if (!(region instanceof HTMLElement)) continue;
|
|
197
|
+
const stack = this.#held(region);
|
|
198
|
+
const hold = stack && this.#take(stack);
|
|
199
|
+
if (!stack || !hold) continue;
|
|
200
|
+
const owns = region.hidden === hold.written && !this.#covered(region, stack, hold);
|
|
201
|
+
const index = stack.indexOf(hold);
|
|
202
|
+
stack.splice(index, 1);
|
|
203
|
+
const above = stack[index];
|
|
204
|
+
if (above) above.linked &&= hold.linked;
|
|
205
|
+
if (owns) {
|
|
206
|
+
const below = hold.linked ? stack[index - 1] : void 0;
|
|
207
|
+
if (below) {
|
|
208
|
+
if (region.hidden !== below.written) region.hidden = below.written;
|
|
209
|
+
} else {
|
|
210
|
+
setAttributeIfChanged(region, "hidden", hold.authored);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
this.#mark(region, stack);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
41
216
|
#write(region, hidden) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
217
|
+
const stack = this.#stack(region);
|
|
218
|
+
const hold = this.#take(stack) ?? this.#acquire(region, stack);
|
|
219
|
+
const shows = !this.#covered(region, stack, hold);
|
|
220
|
+
hold.written = hidden;
|
|
221
|
+
if (shows && region.hidden !== hidden) region.hidden = hidden;
|
|
222
|
+
this.#mark(region, stack);
|
|
45
223
|
}
|
|
46
|
-
/** Returns a region this instance hid; one it never hid keeps what it carries. */
|
|
47
224
|
#give(region) {
|
|
48
|
-
|
|
225
|
+
const stack = this.#held(region);
|
|
226
|
+
if (stack && this.#take(stack)?.written) this.#write(region, false);
|
|
227
|
+
}
|
|
228
|
+
#held(region) {
|
|
229
|
+
return _StateRegions.#registry.stacks.has(region) || region.hasAttribute(this.#record) ? this.#stack(region) : void 0;
|
|
230
|
+
}
|
|
231
|
+
#stack(region) {
|
|
232
|
+
const stacks = _StateRegions.#registry.stacks;
|
|
233
|
+
const stack = stacks.get(region) ?? this.#seed(region);
|
|
234
|
+
stacks.set(region, stack);
|
|
235
|
+
return stack;
|
|
236
|
+
}
|
|
237
|
+
#seed(region) {
|
|
238
|
+
const found = [];
|
|
239
|
+
for (const record of _StateRegions.#registry.names) {
|
|
240
|
+
const read = this.#recorded(region, record);
|
|
241
|
+
if (read) found.push({ ...read, record });
|
|
242
|
+
}
|
|
243
|
+
const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
|
|
244
|
+
return found.sort((one, other) => depth(one) - depth(other)).map(({ record, authored, written, linked }, index) => ({
|
|
245
|
+
instance: null,
|
|
246
|
+
record,
|
|
247
|
+
authored,
|
|
248
|
+
written,
|
|
249
|
+
linked: linked && index > 0
|
|
250
|
+
}));
|
|
251
|
+
}
|
|
252
|
+
#take(stack) {
|
|
253
|
+
const hold = stack.find((held) => held.instance === this) ?? stack.find((held) => held.instance === null && held.record === this.#record);
|
|
254
|
+
if (hold) hold.instance = this;
|
|
255
|
+
return hold;
|
|
256
|
+
}
|
|
257
|
+
#covered(region, stack, hold) {
|
|
258
|
+
return stack.slice(stack.indexOf(hold) + 1).some((above) => above.written === region.hidden);
|
|
259
|
+
}
|
|
260
|
+
#acquire(region, stack) {
|
|
261
|
+
const top = stack.at(-1);
|
|
262
|
+
const over = top && region.hidden === top.written ? top : void 0;
|
|
263
|
+
const hold = {
|
|
264
|
+
instance: this,
|
|
265
|
+
record: this.#record,
|
|
266
|
+
authored: over ? over.authored : region.getAttribute("hidden"),
|
|
267
|
+
written: false,
|
|
268
|
+
linked: over !== void 0
|
|
269
|
+
};
|
|
270
|
+
stack.push(hold);
|
|
271
|
+
return hold;
|
|
272
|
+
}
|
|
273
|
+
#mark(region, stack) {
|
|
274
|
+
const records = /* @__PURE__ */ new Map([[this.#record, null]]);
|
|
275
|
+
stack.forEach((hold, index) => {
|
|
276
|
+
const names = stack.slice(0, index).map((under) => under.record);
|
|
277
|
+
const beneath = [...new Set(names.reverse())].filter((name) => name !== hold.record);
|
|
278
|
+
const marker = hold.linked || beneath.length === 0 ? [] : [false];
|
|
279
|
+
records.set(
|
|
280
|
+
hold.record,
|
|
281
|
+
region.getAttribute("hidden") === hold.authored && beneath.length === 0 && index === stack.length - 1 ? null : JSON.stringify([hold.authored, hold.written, ...marker, ...beneath])
|
|
282
|
+
);
|
|
283
|
+
});
|
|
284
|
+
for (const [name, recorded] of records) {
|
|
285
|
+
setAttributeIfChanged(region, name, recorded);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
#recorded(region, name) {
|
|
289
|
+
try {
|
|
290
|
+
const parsed = JSON.parse(region.getAttribute(name) ?? "null");
|
|
291
|
+
if (!Array.isArray(parsed)) return null;
|
|
292
|
+
const [authored, written, ...rest] = parsed;
|
|
293
|
+
if (authored !== null && typeof authored !== "string") return null;
|
|
294
|
+
const linked = rest[0] !== false;
|
|
295
|
+
const beneath = linked ? rest : rest.slice(1);
|
|
296
|
+
if (!beneath.every((under) => typeof under === "string")) return null;
|
|
297
|
+
return typeof written === "boolean" ? { authored, written, linked, beneath } : null;
|
|
298
|
+
} catch {
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
49
301
|
}
|
|
50
|
-
/** The declared regions that sit within `host`, which may be the host itself. */
|
|
51
302
|
#inside(host, regions) {
|
|
52
303
|
return regions.filter((region) => host.contains(region));
|
|
53
304
|
}
|
|
54
305
|
};
|
|
55
306
|
|
|
56
|
-
// src/utils/safe_timeout.ts
|
|
57
307
|
var TimerRegistry = class {
|
|
58
|
-
/** Live timer ids that have not yet been cleared (or, for timeouts, fired). */
|
|
59
308
|
ids = /* @__PURE__ */ new Set();
|
|
60
|
-
/**
|
|
61
|
-
* Cancels a single tracked timer.
|
|
62
|
-
*
|
|
63
|
-
* No-ops if the id is unknown (already cleared, fired, or never owned by this
|
|
64
|
-
* registry), so callers can clear defensively without guarding.
|
|
65
|
-
*/
|
|
66
309
|
clear(id) {
|
|
67
310
|
if (this.ids.delete(id)) {
|
|
68
311
|
this.cancel(id);
|
|
69
312
|
}
|
|
70
313
|
}
|
|
71
|
-
/**
|
|
72
|
-
* Cancels every tracked timer. Call this from a controller's `disconnect()`
|
|
73
|
-
* to guarantee no timer outlives the element.
|
|
74
|
-
*/
|
|
75
314
|
clearAll() {
|
|
76
315
|
for (const id of this.ids) {
|
|
77
316
|
this.cancel(id);
|
|
78
317
|
}
|
|
79
318
|
this.ids.clear();
|
|
80
319
|
}
|
|
81
|
-
/** Number of timers currently tracked (pending). */
|
|
82
320
|
get size() {
|
|
83
321
|
return this.ids.size;
|
|
84
322
|
}
|
|
85
323
|
};
|
|
86
324
|
var SafeTimeout = class extends TimerRegistry {
|
|
87
|
-
/**
|
|
88
|
-
* Schedules `callback` after `delay` ms and returns the timer id.
|
|
89
|
-
*
|
|
90
|
-
* The id is removed from the registry automatically when the timeout fires,
|
|
91
|
-
* so {@link TimerRegistry.size | size} reflects only still-pending timers.
|
|
92
|
-
*/
|
|
93
325
|
set(callback, delay) {
|
|
94
326
|
const id = this.schedule(() => {
|
|
95
327
|
this.ids.delete(id);
|
|
@@ -106,7 +338,6 @@ var SafeTimeout = class extends TimerRegistry {
|
|
|
106
338
|
}
|
|
107
339
|
};
|
|
108
340
|
|
|
109
|
-
// src/utils/transition_completion.ts
|
|
110
341
|
function timeMs(value) {
|
|
111
342
|
const trimmed = value.trim();
|
|
112
343
|
const amount = Number.parseFloat(trimmed);
|
|
@@ -142,13 +373,6 @@ var TransitionCompletion = class {
|
|
|
142
373
|
#complete = null;
|
|
143
374
|
#pendingProperties = null;
|
|
144
375
|
#deadline = 0;
|
|
145
|
-
/**
|
|
146
|
-
* Replaces any prior wait and invokes `complete` synchronously for a 0ms
|
|
147
|
-
* transition (including when `getComputedStyle` is unavailable).
|
|
148
|
-
*
|
|
149
|
-
* With a positive `options.timeoutMs` the synchronous fast-path is skipped and
|
|
150
|
-
* the override replaces the auto-computed fallback (see {@link TransitionWaitOptions}).
|
|
151
|
-
*/
|
|
152
376
|
wait(element, complete, options = {}) {
|
|
153
377
|
this.cancel();
|
|
154
378
|
const requested = options.timeoutMs ?? 0;
|
|
@@ -168,18 +392,10 @@ var TransitionCompletion = class {
|
|
|
168
392
|
element.addEventListener("transitioncancel", this.#onTerminal);
|
|
169
393
|
this.#timers.set(() => this.#finish(), override > 0 ? override : maximum + 50);
|
|
170
394
|
}
|
|
171
|
-
/** Cancels the pending wait without invoking its completion callback. */
|
|
172
395
|
cancel() {
|
|
173
396
|
this.#complete = null;
|
|
174
397
|
this.#teardown();
|
|
175
398
|
}
|
|
176
|
-
/**
|
|
177
|
-
* Handles terminal events from the observed element only.
|
|
178
|
-
*
|
|
179
|
-
* For explicit property lists, every declared positive-time property must
|
|
180
|
-
* settle. For `all`, no reliable property set exists, so an event can finish
|
|
181
|
-
* only after the computed maximum time; the safety timeout owns the usual path.
|
|
182
|
-
*/
|
|
183
399
|
#onTerminal = (event) => {
|
|
184
400
|
if (event.target !== this.#element) return;
|
|
185
401
|
const transitionEvent = event;
|
|
@@ -199,10 +415,6 @@ var TransitionCompletion = class {
|
|
|
199
415
|
}
|
|
200
416
|
if (Date.now() >= this.#deadline) this.#finish();
|
|
201
417
|
};
|
|
202
|
-
/**
|
|
203
|
-
* Returns active CSS transition properties expanded to the names reported by
|
|
204
|
-
* terminal events. CSS animations and pseudo-element effects are excluded.
|
|
205
|
-
*/
|
|
206
418
|
#activeTransitionProperties(element) {
|
|
207
419
|
if (!element || typeof element.getAnimations !== "function") return /* @__PURE__ */ new Set();
|
|
208
420
|
try {
|
|
@@ -220,7 +432,6 @@ var TransitionCompletion = class {
|
|
|
220
432
|
return /* @__PURE__ */ new Set();
|
|
221
433
|
}
|
|
222
434
|
}
|
|
223
|
-
/** Returns explicit positive-time properties, or `null` for the ambiguous `all`. */
|
|
224
435
|
#explicitPendingProperties(timings) {
|
|
225
436
|
if (timings.some(({ property }) => property === "all")) return null;
|
|
226
437
|
const pending = new Set(
|
|
@@ -228,7 +439,6 @@ var TransitionCompletion = class {
|
|
|
228
439
|
);
|
|
229
440
|
return pending.size > 0 ? pending : null;
|
|
230
441
|
}
|
|
231
|
-
/** Completes exactly once, releasing listeners and the fallback before the callback. */
|
|
232
442
|
#finish() {
|
|
233
443
|
const complete = this.#complete;
|
|
234
444
|
if (!complete) return;
|
|
@@ -236,7 +446,6 @@ var TransitionCompletion = class {
|
|
|
236
446
|
this.#teardown();
|
|
237
447
|
complete();
|
|
238
448
|
}
|
|
239
|
-
/** Releases the exact element listeners and timer owned by the current wait. */
|
|
240
449
|
#teardown() {
|
|
241
450
|
this.#timers.clearAll();
|
|
242
451
|
this.#element?.removeEventListener("transitionend", this.#onTerminal);
|
|
@@ -247,7 +456,6 @@ var TransitionCompletion = class {
|
|
|
247
456
|
}
|
|
248
457
|
};
|
|
249
458
|
|
|
250
|
-
// src/controllers/collapsible_controller.ts
|
|
251
459
|
var CollapsibleController = class extends Controller {
|
|
252
460
|
static targets = ["trigger", "content", "expandedLabel", "collapsedLabel"];
|
|
253
461
|
static values = {
|
|
@@ -255,35 +463,24 @@ var CollapsibleController = class extends Controller {
|
|
|
255
463
|
};
|
|
256
464
|
static actions = ["toggle"];
|
|
257
465
|
static events = ["close", "open"];
|
|
258
|
-
|
|
466
|
+
#expanded = new AttributeLease("aria-expanded", this.identifier);
|
|
467
|
+
#contentHidden = new AttributeLease("hidden", this.identifier);
|
|
468
|
+
#contentState = new AttributeLease("data-state", this.identifier);
|
|
259
469
|
#transition = new TransitionCompletion();
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
470
|
+
#labels = new StateRegions(
|
|
471
|
+
{
|
|
472
|
+
whenTrue: () => this.expandedLabelTargets,
|
|
473
|
+
whenFalse: () => this.collapsedLabelTargets
|
|
474
|
+
},
|
|
475
|
+
this.identifier
|
|
476
|
+
);
|
|
266
477
|
#connected = false;
|
|
267
|
-
/** Whether state moves are reported: set once `connect()` settled the baseline. */
|
|
268
478
|
#reporting = false;
|
|
269
|
-
/**
|
|
270
|
-
* Establishes the initial open/closed state without waiting for a close transition.
|
|
271
|
-
*
|
|
272
|
-
* The DOM is the source of truth on reconnect (Turbo cache restore / morph): an
|
|
273
|
-
* **explicit** state attribute — `aria-expanded="true"`/`"false"` (or, with no
|
|
274
|
-
* trigger, `data-state="open"`/`"closed"`) — is honored verbatim so a region the
|
|
275
|
-
* user opened *or* closed survives a back-navigation, even when the declarative
|
|
276
|
-
* `open` Value disagrees. An already-open region remains open without a
|
|
277
|
-
* close/reopen cycle. The Value only seeds a genuinely fresh render where no
|
|
278
|
-
* state attribute is present yet; any opening animation in that case belongs to
|
|
279
|
-
* the consumer's CSS.
|
|
280
|
-
*/
|
|
281
479
|
connect() {
|
|
282
480
|
this.#connected = true;
|
|
283
481
|
this.#apply(this.#initialOpen(), false, "api");
|
|
284
482
|
this.#reporting = true;
|
|
285
483
|
}
|
|
286
|
-
/** Resolves the connect-time state: explicit DOM state wins, else the `open` Value. */
|
|
287
484
|
#initialOpen() {
|
|
288
485
|
if (this.hasTriggerTarget) {
|
|
289
486
|
const expanded = this.triggerTarget.getAttribute("aria-expanded");
|
|
@@ -301,72 +498,66 @@ var CollapsibleController = class extends Controller {
|
|
|
301
498
|
this.#reporting = false;
|
|
302
499
|
this.#transition.cancel();
|
|
303
500
|
}
|
|
304
|
-
/** Reconciles a replacement trigger target with the content's live state. */
|
|
305
501
|
triggerTargetConnected(trigger) {
|
|
306
|
-
if (
|
|
502
|
+
if (this.#connected) this.#reconcileTrigger(trigger);
|
|
503
|
+
}
|
|
504
|
+
triggerTargetDisconnected(trigger) {
|
|
505
|
+
if (!this.triggerTargets.includes(trigger)) {
|
|
506
|
+
this.#expanded.return(trigger);
|
|
507
|
+
this.#labels.release(trigger);
|
|
508
|
+
}
|
|
509
|
+
if (this.#connected && this.hasTriggerTarget) this.#reconcileTrigger(this.triggerTarget);
|
|
510
|
+
}
|
|
511
|
+
#reconcileTrigger(trigger) {
|
|
307
512
|
if (this.hasContentTarget) {
|
|
308
|
-
|
|
309
|
-
|
|
513
|
+
this.#expanded.write(
|
|
514
|
+
trigger,
|
|
310
515
|
this.contentTarget.getAttribute("data-state") === "open" ? "true" : "false"
|
|
311
516
|
);
|
|
312
517
|
}
|
|
313
518
|
this.#labels.reflect(trigger, trigger.getAttribute("aria-expanded") === "true");
|
|
314
519
|
}
|
|
315
|
-
/** Settles a label that arrived after the state it belongs to was written. */
|
|
316
520
|
expandedLabelTargetConnected() {
|
|
317
521
|
this.#reflectLabels();
|
|
318
522
|
}
|
|
319
|
-
/** Settles a label that arrived after the state it belongs to was written. */
|
|
320
523
|
collapsedLabelTargetConnected() {
|
|
321
524
|
this.#reflectLabels();
|
|
322
525
|
}
|
|
323
|
-
/** Shows the label pair's side that belongs to the trigger's expanded state. */
|
|
324
526
|
#reflectLabels() {
|
|
325
527
|
if (this.#connected && this.hasTriggerTarget) {
|
|
326
528
|
this.#labels.reflect(this.triggerTarget, this.#isOpen);
|
|
327
529
|
}
|
|
328
530
|
}
|
|
329
|
-
/** Reconciles a replacement content target with the disclosure's live state. */
|
|
330
531
|
contentTargetConnected(content) {
|
|
331
532
|
if (!this.#connected) return;
|
|
332
533
|
this.#transition.cancel();
|
|
333
|
-
|
|
334
|
-
this.#applyContent(content, open, false);
|
|
534
|
+
this.#reconcileContent(content);
|
|
335
535
|
}
|
|
336
|
-
|
|
337
|
-
contentTargetDisconnected() {
|
|
536
|
+
contentTargetDisconnected(content) {
|
|
338
537
|
this.#transition.cancel();
|
|
538
|
+
if (!this.contentTargets.includes(content)) {
|
|
539
|
+
this.#contentHidden.return(content);
|
|
540
|
+
this.#contentState.return(content);
|
|
541
|
+
}
|
|
542
|
+
if (this.#connected && this.hasContentTarget) this.#reconcileContent(this.contentTarget);
|
|
543
|
+
}
|
|
544
|
+
#reconcileContent(content) {
|
|
545
|
+
const open = this.hasTriggerTarget ? this.triggerTarget.getAttribute("aria-expanded") === "true" : content.getAttribute("data-state") === "open";
|
|
546
|
+
this.#applyContent(content, open, false);
|
|
339
547
|
}
|
|
340
|
-
/** Toggles the region open/closed. Bound via `data-action` (click). */
|
|
341
548
|
toggle(event) {
|
|
342
549
|
this.#apply(!this.#isOpen, true, stateReasonFor(event));
|
|
343
550
|
}
|
|
344
|
-
/**
|
|
345
|
-
* Whether the region is logically open. Read from `aria-expanded` (not the
|
|
346
|
-
* content's `hidden`) so a click *during* a close transition — when `hidden`
|
|
347
|
-
* is still deferred — correctly reopens instead of re-closing.
|
|
348
|
-
*/
|
|
349
551
|
get #isOpen() {
|
|
350
552
|
if (this.hasTriggerTarget) {
|
|
351
553
|
return this.triggerTarget.getAttribute("aria-expanded") === "true";
|
|
352
554
|
}
|
|
353
555
|
return this.hasContentTarget && this.contentTarget.getAttribute("data-state") === "open";
|
|
354
556
|
}
|
|
355
|
-
/**
|
|
356
|
-
* Drives the disclosure to `open`, syncing the trigger's `aria-expanded` and
|
|
357
|
-
* the content's `hidden` / `data-state` / height variable in an order where
|
|
358
|
-
* `hidden` never blocks measurement or the transition.
|
|
359
|
-
*
|
|
360
|
-
* @param open - Target state.
|
|
361
|
-
* @param waitForCloseTransition - When `false` (initial `connect`) the close
|
|
362
|
-
* path applies `hidden` immediately. This flag does not suppress consumer CSS
|
|
363
|
-
* on the open path.
|
|
364
|
-
* @param reason - What drove the move, reported when the state actually moved.
|
|
365
|
-
*/
|
|
366
557
|
#apply(open, waitForCloseTransition, reason) {
|
|
367
558
|
const was = this.#isOpen;
|
|
368
559
|
if (this.hasTriggerTarget) {
|
|
369
|
-
this.triggerTarget
|
|
560
|
+
this.#expanded.write(this.triggerTarget, open ? "true" : "false");
|
|
370
561
|
this.#labels.reflect(this.triggerTarget, open);
|
|
371
562
|
}
|
|
372
563
|
if (this.hasContentTarget) {
|
|
@@ -378,38 +569,31 @@ var CollapsibleController = class extends Controller {
|
|
|
378
569
|
if (open) this.dispatch("open", { detail: { reason }, cancelable: false });
|
|
379
570
|
else this.dispatch("close", { detail: { reason }, cancelable: false });
|
|
380
571
|
}
|
|
381
|
-
/** Reflects one content target without relying on a later target lookup. */
|
|
382
572
|
#applyContent(content, open, waitForCloseTransition) {
|
|
383
573
|
if (open) {
|
|
384
|
-
content
|
|
574
|
+
this.#contentHidden.write(content, null);
|
|
385
575
|
content.style.setProperty(
|
|
386
576
|
"--stimeo--collapsible-content-height",
|
|
387
577
|
`${content.scrollHeight}px`
|
|
388
578
|
);
|
|
389
|
-
|
|
579
|
+
this.#contentState.write(content, "open");
|
|
390
580
|
return;
|
|
391
581
|
}
|
|
392
|
-
|
|
582
|
+
this.#contentState.write(content, "closed");
|
|
393
583
|
if (waitForCloseTransition) {
|
|
394
584
|
this.#applyHiddenAfterTransition(content);
|
|
395
585
|
} else {
|
|
396
|
-
content
|
|
586
|
+
this.#contentHidden.write(content, "");
|
|
397
587
|
}
|
|
398
588
|
}
|
|
399
|
-
/**
|
|
400
|
-
* Re-applies `hidden` once the close transition settles. Guarded against a
|
|
401
|
-
* reopen mid-transition; the shared waiter also guarantees a bounded fallback
|
|
402
|
-
* when the browser emits no terminal transition event.
|
|
403
|
-
*/
|
|
404
589
|
#applyHiddenAfterTransition(content) {
|
|
405
590
|
this.#transition.wait(content, () => {
|
|
406
591
|
if (content.getAttribute("data-state") === "closed") {
|
|
407
|
-
content
|
|
592
|
+
this.#contentHidden.write(content, "");
|
|
408
593
|
}
|
|
409
594
|
});
|
|
410
595
|
}
|
|
411
596
|
};
|
|
412
597
|
|
|
413
598
|
export { CollapsibleController };
|
|
414
|
-
//# sourceMappingURL=collapsible_controller.js.map
|
|
415
599
|
//# sourceMappingURL=collapsible_controller.js.map
|