stimeo-ui 0.16.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 +31 -0
- package/README.md +8 -1
- package/dist/cable/index.d.ts +79 -23
- package/dist/cable/index.js +363 -436
- package/dist/cable/index.js.map +1 -1
- package/dist/controllers/accordion_controller.d.ts +4 -2
- package/dist/controllers/accordion_controller.js +166 -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 +862 -221
- package/dist/controllers/alert_dialog_controller.js.map +1 -1
- package/dist/controllers/announcer_controller.d.ts +35 -5
- package/dist/controllers/announcer_controller.js +135 -198
- 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 +271 -127
- package/dist/controllers/auto_submit_controller.js.map +1 -1
- package/dist/controllers/avatar_controller.js +171 -105
- 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 +18 -0
- package/dist/controllers/bulk_select_controller.js +262 -52
- package/dist/controllers/bulk_select_controller.js.map +1 -1
- package/dist/controllers/calendar_controller.d.ts +24 -5
- package/dist/controllers/calendar_controller.js +175 -209
- package/dist/controllers/calendar_controller.js.map +1 -1
- package/dist/controllers/carousel_controller.d.ts +34 -7
- package/dist/controllers/carousel_controller.js +461 -399
- package/dist/controllers/carousel_controller.js.map +1 -1
- package/dist/controllers/character_counter_controller.d.ts +17 -1
- package/dist/controllers/character_counter_controller.js +246 -156
- 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 +32 -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 +168 -147
- package/dist/controllers/clipboard_controller.js.map +1 -1
- package/dist/controllers/collapsible_controller.d.ts +16 -4
- package/dist/controllers/collapsible_controller.js +301 -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 +149 -139
- package/dist/controllers/color_picker_controller.js.map +1 -1
- package/dist/controllers/combobox_controller.d.ts +23 -5
- package/dist/controllers/combobox_controller.js +360 -133
- 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 +970 -358
- 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 +166 -124
- 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 -248
- package/dist/controllers/confirm_controller.js.map +1 -1
- package/dist/controllers/context_menu_controller.d.ts +31 -4
- package/dist/controllers/context_menu_controller.js +256 -128
- 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 +45 -1
- package/dist/controllers/countdown_controller.js +183 -148
- package/dist/controllers/countdown_controller.js.map +1 -1
- package/dist/controllers/currency_input_controller.d.ts +21 -2
- package/dist/controllers/currency_input_controller.js +134 -158
- package/dist/controllers/currency_input_controller.js.map +1 -1
- package/dist/controllers/data_grid_controller.d.ts +15 -4
- package/dist/controllers/data_grid_controller.js +114 -186
- package/dist/controllers/data_grid_controller.js.map +1 -1
- package/dist/controllers/date_range_picker_controller.d.ts +30 -5
- package/dist/controllers/date_range_picker_controller.js +288 -206
- package/dist/controllers/date_range_picker_controller.js.map +1 -1
- package/dist/controllers/dialog_controller.d.ts +13 -1
- package/dist/controllers/dialog_controller.js +858 -223
- 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 +73 -153
- package/dist/controllers/direct_upload_controller.js.map +1 -1
- package/dist/controllers/dirty_form_controller.js +14 -48
- 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 -21
- package/dist/controllers/dismissible_controller.js.map +1 -1
- package/dist/controllers/drawer_controller.d.ts +39 -11
- package/dist/controllers/drawer_controller.js +933 -341
- package/dist/controllers/drawer_controller.js.map +1 -1
- package/dist/controllers/dropdown_controller.d.ts +31 -1
- package/dist/controllers/dropdown_controller.js +312 -82
- package/dist/controllers/dropdown_controller.js.map +1 -1
- package/dist/controllers/editable_controller.d.ts +12 -1
- package/dist/controllers/editable_controller.js +158 -68
- 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 +311 -207
- package/dist/controllers/file_dropzone_controller.js.map +1 -1
- package/dist/controllers/filter_controller.js +67 -39
- package/dist/controllers/filter_controller.js.map +1 -1
- package/dist/controllers/flash_controller.d.ts +31 -8
- package/dist/controllers/flash_controller.js +172 -314
- 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 -240
- package/dist/controllers/focus_controller.js.map +1 -1
- package/dist/controllers/form_field_controller.js +147 -132
- package/dist/controllers/form_field_controller.js.map +1 -1
- package/dist/controllers/form_validation_controller.js +13 -86
- 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 +264 -213
- 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 +107 -75
- package/dist/controllers/highlight_controller.js.map +1 -1
- package/dist/controllers/hover_card_controller.d.ts +56 -3
- package/dist/controllers/hover_card_controller.js +309 -118
- package/dist/controllers/hover_card_controller.js.map +1 -1
- package/dist/controllers/idle_controller.d.ts +42 -1
- package/dist/controllers/idle_controller.js +267 -101
- package/dist/controllers/idle_controller.js.map +1 -1
- package/dist/controllers/input_mask_controller.js +71 -72
- 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 -106
- 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 -65
- package/dist/controllers/lazy_frame_controller.js.map +1 -1
- package/dist/controllers/listbox_controller.d.ts +34 -2
- package/dist/controllers/listbox_controller.js +306 -204
- 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 -93
- package/dist/controllers/masonry_controller.js.map +1 -1
- package/dist/controllers/menu_controller.d.ts +32 -7
- package/dist/controllers/menu_controller.js +214 -156
- package/dist/controllers/menu_controller.js.map +1 -1
- package/dist/controllers/menubar_controller.d.ts +4 -4
- package/dist/controllers/menubar_controller.js +170 -329
- package/dist/controllers/menubar_controller.js.map +1 -1
- package/dist/controllers/meter_controller.d.ts +20 -0
- package/dist/controllers/meter_controller.js +151 -67
- package/dist/controllers/meter_controller.js.map +1 -1
- package/dist/controllers/multi_select_controller.d.ts +32 -4
- package/dist/controllers/multi_select_controller.js +593 -358
- package/dist/controllers/multi_select_controller.js.map +1 -1
- package/dist/controllers/navigation_menu_controller.d.ts +8 -1
- package/dist/controllers/navigation_menu_controller.js +124 -232
- 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 +352 -182
- 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 +242 -54
- package/dist/controllers/network_status_controller.js.map +1 -1
- package/dist/controllers/number_input_controller.d.ts +26 -2
- package/dist/controllers/number_input_controller.js +320 -263
- package/dist/controllers/number_input_controller.js.map +1 -1
- package/dist/controllers/optimistic_controller.js +16 -76
- package/dist/controllers/optimistic_controller.js.map +1 -1
- package/dist/controllers/otp_controller.d.ts +20 -4
- package/dist/controllers/otp_controller.js +198 -193
- 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 +116 -113
- package/dist/controllers/overflow_indicator_controller.js.map +1 -1
- package/dist/controllers/overflow_menu_controller.d.ts +48 -11
- package/dist/controllers/overflow_menu_controller.js +343 -283
- package/dist/controllers/overflow_menu_controller.js.map +1 -1
- package/dist/controllers/pagination_controller.d.ts +35 -6
- package/dist/controllers/pagination_controller.js +295 -119
- package/dist/controllers/pagination_controller.js.map +1 -1
- package/dist/controllers/password_reveal_controller.d.ts +45 -8
- package/dist/controllers/password_reveal_controller.js +389 -121
- 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 +237 -103
- 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 +185 -165
- package/dist/controllers/pointer_drag_controller.js.map +1 -1
- package/dist/controllers/popover_controller.d.ts +38 -2
- package/dist/controllers/popover_controller.js +236 -97
- 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 -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 +232 -116
- 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 +125 -56
- package/dist/controllers/progress_controller.js.map +1 -1
- package/dist/controllers/radio_group_controller.d.ts +14 -5
- package/dist/controllers/radio_group_controller.js +117 -137
- package/dist/controllers/radio_group_controller.js.map +1 -1
- package/dist/controllers/range_slider_controller.d.ts +43 -3
- package/dist/controllers/range_slider_controller.js +192 -105
- 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 +418 -207
- 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 +134 -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 +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 +28 -2
- package/dist/controllers/resizable_controller.js +255 -139
- 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 -225
- 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 -145
- 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 +181 -242
- package/dist/controllers/scrollspy_controller.js.map +1 -1
- package/dist/controllers/separator_controller.d.ts +19 -4
- package/dist/controllers/separator_controller.js +267 -140
- package/dist/controllers/separator_controller.js.map +1 -1
- package/dist/controllers/sidebar_controller.d.ts +64 -7
- package/dist/controllers/sidebar_controller.js +1023 -386
- 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 -97
- package/dist/controllers/skeleton_controller.js.map +1 -1
- package/dist/controllers/slider_controller.d.ts +27 -1
- package/dist/controllers/slider_controller.js +159 -79
- 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 +162 -63
- package/dist/controllers/smart_sticky_header_controller.js.map +1 -1
- package/dist/controllers/sortable_controller.js +0 -112
- 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 -169
- package/dist/controllers/spinner_controller.js.map +1 -1
- package/dist/controllers/step_indicator_controller.d.ts +5 -0
- package/dist/controllers/step_indicator_controller.js +99 -46
- package/dist/controllers/step_indicator_controller.js.map +1 -1
- package/dist/controllers/stepper_controller.d.ts +12 -3
- package/dist/controllers/stepper_controller.js +114 -73
- package/dist/controllers/stepper_controller.js.map +1 -1
- package/dist/controllers/stick_to_bottom_controller.d.ts +6 -0
- package/dist/controllers/stick_to_bottom_controller.js +262 -138
- 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 +23 -8
- package/dist/controllers/submit_once_controller.js +294 -205
- package/dist/controllers/submit_once_controller.js.map +1 -1
- package/dist/controllers/switch_controller.d.ts +12 -1
- package/dist/controllers/switch_controller.js +33 -60
- package/dist/controllers/switch_controller.js.map +1 -1
- package/dist/controllers/tabs_controller.d.ts +2 -2
- package/dist/controllers/tabs_controller.js +35 -29
- package/dist/controllers/tabs_controller.js.map +1 -1
- package/dist/controllers/tags_input_controller.d.ts +12 -0
- package/dist/controllers/tags_input_controller.js +136 -145
- 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 +21 -9
- package/dist/controllers/theme_controller.js +130 -112
- 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 +146 -80
- package/dist/controllers/time_picker_controller.js.map +1 -1
- package/dist/controllers/toast_controller.d.ts +36 -11
- package/dist/controllers/toast_controller.js +186 -297
- package/dist/controllers/toast_controller.js.map +1 -1
- package/dist/controllers/toggle_group_controller.d.ts +12 -3
- package/dist/controllers/toggle_group_controller.js +95 -136
- package/dist/controllers/toggle_group_controller.js.map +1 -1
- package/dist/controllers/toolbar_controller.js +68 -98
- package/dist/controllers/toolbar_controller.js.map +1 -1
- package/dist/controllers/tooltip_controller.d.ts +45 -3
- 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 +21 -11
- package/dist/controllers/tree_view_controller.js +150 -345
- package/dist/controllers/tree_view_controller.js.map +1 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.js +6370 -9346
- package/dist/index.js.map +1 -1
- package/dist/inspector/cli.d.ts +23 -3
- package/dist/inspector/cli.js +92 -37
- package/dist/inspector/cli.js.map +1 -1
- package/dist/inspector/cli_bin.js +92 -56
- package/dist/inspector/cli_bin.js.map +1 -1
- package/dist/inspector/examples.json +8 -8
- package/dist/inspector/manifest.json +787 -100
- package/dist/positioning/index.d.ts +8 -0
- package/dist/positioning/index.js +148 -47
- package/dist/positioning/index.js.map +1 -1
- package/package.json +6 -6
- 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,152 @@
|
|
|
1
1
|
import { Controller } from '@hotwired/stimulus';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
function sharedRegistry(key, create) {
|
|
4
|
+
const symbol = Symbol.for(key);
|
|
5
|
+
const scope = globalThis;
|
|
6
|
+
const existing = scope[symbol];
|
|
7
|
+
if (existing !== void 0) return existing;
|
|
8
|
+
const registry = create();
|
|
9
|
+
Object.defineProperty(globalThis, symbol, { value: registry });
|
|
10
|
+
return registry;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function isAttributeValue(value) {
|
|
14
|
+
return value === null || typeof value === "string";
|
|
15
|
+
}
|
|
16
|
+
function readLeaseRecord(element, record) {
|
|
17
|
+
try {
|
|
18
|
+
const parsed = JSON.parse(element.getAttribute(record) ?? "null");
|
|
19
|
+
if (!Array.isArray(parsed)) return void 0;
|
|
20
|
+
const [original, written, ...rest] = parsed;
|
|
21
|
+
const linked = rest[0] !== false;
|
|
22
|
+
const beneath = linked ? rest : rest.slice(1);
|
|
23
|
+
if (!beneath.every((under) => typeof under === "string")) return void 0;
|
|
24
|
+
return isAttributeValue(original) && isAttributeValue(written) ? { original, written, linked, beneath } : void 0;
|
|
25
|
+
} catch {
|
|
26
|
+
return void 0;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
var AttributeLease = class _AttributeLease {
|
|
30
|
+
static #registry = sharedRegistry(
|
|
31
|
+
"stimeo-ui.attribute-lease.registry.v1",
|
|
32
|
+
() => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
|
|
33
|
+
);
|
|
34
|
+
#attribute;
|
|
35
|
+
#record;
|
|
36
|
+
#base;
|
|
37
|
+
#held = /* @__PURE__ */ new Set();
|
|
38
|
+
constructor(attribute, owner, options = {}) {
|
|
39
|
+
this.#attribute = attribute;
|
|
40
|
+
this.#record = `data-${owner}-${attribute}-lease`;
|
|
41
|
+
this.#base = options.base === true;
|
|
42
|
+
const names = _AttributeLease.#registry.names;
|
|
43
|
+
names.set(attribute, (names.get(attribute) ?? /* @__PURE__ */ new Set()).add(this.#record));
|
|
44
|
+
}
|
|
45
|
+
write(element, value) {
|
|
46
|
+
const stack = this.#stack(element);
|
|
47
|
+
const hold = this.#take(stack) ?? this.#acquire(element, stack);
|
|
48
|
+
this.#held.add(element);
|
|
49
|
+
const shows = !this.#covered(element, stack, hold);
|
|
50
|
+
hold.written = value;
|
|
51
|
+
this.#mark(element, stack);
|
|
52
|
+
if (shows) this.#reflect(element, value);
|
|
53
|
+
}
|
|
54
|
+
return(element) {
|
|
55
|
+
const held = this.#held.delete(element);
|
|
56
|
+
const known = _AttributeLease.#registry.stacks.get(element)?.has(this.#attribute);
|
|
57
|
+
const stack = held || known || element.hasAttribute(this.#record) ? this.#stack(element) : [];
|
|
58
|
+
const hold = this.#take(stack);
|
|
59
|
+
if (!hold) return false;
|
|
60
|
+
const carries = element.getAttribute(this.#attribute) === hold.written;
|
|
61
|
+
const owns = carries && !this.#covered(element, stack, hold);
|
|
62
|
+
const index = stack.indexOf(hold);
|
|
63
|
+
stack.splice(index, 1);
|
|
64
|
+
const above = stack[index];
|
|
65
|
+
if (above) above.linked &&= hold.linked;
|
|
66
|
+
this.#mark(element, stack);
|
|
67
|
+
if (!owns) return true;
|
|
68
|
+
const below = hold.linked ? stack[index - 1] : void 0;
|
|
69
|
+
this.#reflect(element, below ? below.written : hold.original);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
returnAll() {
|
|
73
|
+
for (const element of Array.from(this.#held)) this.return(element);
|
|
74
|
+
}
|
|
75
|
+
#stack(element) {
|
|
76
|
+
const stacks = _AttributeLease.#registry.stacks;
|
|
77
|
+
const byAttribute = stacks.get(element) ?? /* @__PURE__ */ new Map();
|
|
78
|
+
stacks.set(element, byAttribute);
|
|
79
|
+
const stack = byAttribute.get(this.#attribute) ?? this.#seed(element);
|
|
80
|
+
byAttribute.set(this.#attribute, stack);
|
|
81
|
+
return stack;
|
|
82
|
+
}
|
|
83
|
+
#seed(element) {
|
|
84
|
+
const found = [];
|
|
85
|
+
for (const record of _AttributeLease.#registry.names.get(this.#attribute) ?? []) {
|
|
86
|
+
const read = readLeaseRecord(element, record);
|
|
87
|
+
if (read) found.push({ ...read, record });
|
|
88
|
+
}
|
|
89
|
+
const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
|
|
90
|
+
return found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
|
|
91
|
+
lease: null,
|
|
92
|
+
record,
|
|
93
|
+
written,
|
|
94
|
+
original,
|
|
95
|
+
linked: linked && index > 0
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
#take(stack) {
|
|
99
|
+
const hold = stack.find((held) => held.lease === this) ?? stack.find((held) => held.lease === null && held.record === this.#record);
|
|
100
|
+
if (hold) hold.lease = this;
|
|
101
|
+
return hold;
|
|
102
|
+
}
|
|
103
|
+
#acquire(element, stack) {
|
|
104
|
+
const current = element.getAttribute(this.#attribute);
|
|
105
|
+
const top = stack.at(-1);
|
|
106
|
+
const bottom = stack[0];
|
|
107
|
+
const over = top?.written === current ? top : void 0;
|
|
108
|
+
const from = this.#base ? bottom : over;
|
|
109
|
+
const hold = {
|
|
110
|
+
lease: this,
|
|
111
|
+
record: this.#record,
|
|
112
|
+
written: current,
|
|
113
|
+
original: from ? from.original : current,
|
|
114
|
+
linked: !this.#base && over !== void 0
|
|
115
|
+
};
|
|
116
|
+
if (this.#base && bottom) {
|
|
117
|
+
bottom.linked = true;
|
|
118
|
+
stack.unshift(hold);
|
|
119
|
+
} else stack.push(hold);
|
|
120
|
+
return hold;
|
|
121
|
+
}
|
|
122
|
+
#covered(element, stack, hold) {
|
|
123
|
+
const current = element.getAttribute(this.#attribute);
|
|
124
|
+
return stack.slice(stack.indexOf(hold) + 1).some((above) => above.written === current);
|
|
125
|
+
}
|
|
126
|
+
#mark(element, stack) {
|
|
127
|
+
const records = /* @__PURE__ */ new Map([[this.#record, null]]);
|
|
128
|
+
stack.forEach((hold, index) => {
|
|
129
|
+
const names = stack.slice(0, index).map((under) => under.record);
|
|
130
|
+
const beneath = [...new Set(names.reverse())].filter((name) => name !== hold.record);
|
|
131
|
+
const marker = hold.linked || beneath.length === 0 ? [] : [false];
|
|
132
|
+
records.set(
|
|
133
|
+
hold.record,
|
|
134
|
+
hold.written === hold.original && beneath.length === 0 && index === stack.length - 1 ? null : JSON.stringify([hold.original, hold.written, ...marker, ...beneath])
|
|
135
|
+
);
|
|
136
|
+
});
|
|
137
|
+
for (const [name, recorded] of records) {
|
|
138
|
+
if (element.getAttribute(name) === recorded) continue;
|
|
139
|
+
if (recorded === null) element.removeAttribute(name);
|
|
140
|
+
else element.setAttribute(name, recorded);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
#reflect(element, value) {
|
|
144
|
+
if (element.getAttribute(this.#attribute) === value) return;
|
|
145
|
+
if (value === null) element.removeAttribute(this.#attribute);
|
|
146
|
+
else element.setAttribute(this.#attribute, value);
|
|
147
|
+
}
|
|
148
|
+
};
|
|
4
149
|
|
|
5
|
-
// src/utils/state_reason.ts
|
|
6
150
|
var FOCUS_EVENTS = /* @__PURE__ */ new Set(["blur", "focus", "focusin", "focusout"]);
|
|
7
151
|
var POINTER_EVENTS = /* @__PURE__ */ new Set(["mouseenter", "mouseleave", "pointerenter", "pointerleave"]);
|
|
8
152
|
function stateReasonFor(event) {
|
|
@@ -12,16 +156,20 @@ function stateReasonFor(event) {
|
|
|
12
156
|
return "user";
|
|
13
157
|
}
|
|
14
158
|
|
|
15
|
-
|
|
16
|
-
|
|
159
|
+
var StateRegions = class _StateRegions {
|
|
160
|
+
static #registry = sharedRegistry(
|
|
161
|
+
"stimeo-ui.state-regions.registry.v1",
|
|
162
|
+
() => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Set() })
|
|
163
|
+
);
|
|
17
164
|
#whenTrue;
|
|
18
165
|
#whenFalse;
|
|
19
|
-
#
|
|
20
|
-
constructor(options) {
|
|
166
|
+
#record;
|
|
167
|
+
constructor(options, owner) {
|
|
21
168
|
this.#whenTrue = options.whenTrue;
|
|
22
169
|
this.#whenFalse = options.whenFalse ?? null;
|
|
170
|
+
this.#record = `data-${owner}-hidden-region`;
|
|
171
|
+
_StateRegions.#registry.names.add(this.#record);
|
|
23
172
|
}
|
|
24
|
-
/** Shows the regions inside `host` that belong to `isTrue` and hides the others. */
|
|
25
173
|
reflect(host, isTrue) {
|
|
26
174
|
const shown = this.#inside(host, this.#whenTrue());
|
|
27
175
|
if (!this.#whenFalse) {
|
|
@@ -37,59 +185,140 @@ var StateRegions = class {
|
|
|
37
185
|
for (const region of shown) this.#write(region, !isTrue);
|
|
38
186
|
for (const region of hiddenSide) this.#write(region, isTrue);
|
|
39
187
|
}
|
|
40
|
-
|
|
188
|
+
release(host) {
|
|
189
|
+
for (const region of [host, ...host.querySelectorAll("*")]) {
|
|
190
|
+
if (!(region instanceof HTMLElement)) continue;
|
|
191
|
+
const stack = this.#held(region);
|
|
192
|
+
const hold = stack && this.#take(stack);
|
|
193
|
+
if (!stack || !hold) continue;
|
|
194
|
+
const owns = region.hidden === hold.written && !this.#covered(region, stack, hold);
|
|
195
|
+
const index = stack.indexOf(hold);
|
|
196
|
+
stack.splice(index, 1);
|
|
197
|
+
const above = stack[index];
|
|
198
|
+
if (above) above.linked &&= hold.linked;
|
|
199
|
+
if (owns) {
|
|
200
|
+
const below = hold.linked ? stack[index - 1] : void 0;
|
|
201
|
+
if (below) {
|
|
202
|
+
if (region.hidden !== below.written) region.hidden = below.written;
|
|
203
|
+
} else if (region.getAttribute("hidden") !== hold.authored) {
|
|
204
|
+
if (hold.authored === null) region.removeAttribute("hidden");
|
|
205
|
+
else region.setAttribute("hidden", hold.authored);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
this.#mark(region, stack);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
41
211
|
#write(region, hidden) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
212
|
+
const stack = this.#stack(region);
|
|
213
|
+
const hold = this.#take(stack) ?? this.#acquire(region, stack);
|
|
214
|
+
const shows = !this.#covered(region, stack, hold);
|
|
215
|
+
hold.written = hidden;
|
|
216
|
+
if (shows && region.hidden !== hidden) region.hidden = hidden;
|
|
217
|
+
this.#mark(region, stack);
|
|
45
218
|
}
|
|
46
|
-
/** Returns a region this instance hid; one it never hid keeps what it carries. */
|
|
47
219
|
#give(region) {
|
|
48
|
-
|
|
220
|
+
const stack = this.#held(region);
|
|
221
|
+
if (stack && this.#take(stack)?.written) this.#write(region, false);
|
|
222
|
+
}
|
|
223
|
+
#held(region) {
|
|
224
|
+
return _StateRegions.#registry.stacks.has(region) || region.hasAttribute(this.#record) ? this.#stack(region) : void 0;
|
|
225
|
+
}
|
|
226
|
+
#stack(region) {
|
|
227
|
+
const stacks = _StateRegions.#registry.stacks;
|
|
228
|
+
const stack = stacks.get(region) ?? this.#seed(region);
|
|
229
|
+
stacks.set(region, stack);
|
|
230
|
+
return stack;
|
|
231
|
+
}
|
|
232
|
+
#seed(region) {
|
|
233
|
+
const found = [];
|
|
234
|
+
for (const record of _StateRegions.#registry.names) {
|
|
235
|
+
const read = this.#recorded(region, record);
|
|
236
|
+
if (read) found.push({ ...read, record });
|
|
237
|
+
}
|
|
238
|
+
const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
|
|
239
|
+
return found.sort((one, other) => depth(one) - depth(other)).map(({ record, authored, written, linked }, index) => ({
|
|
240
|
+
instance: null,
|
|
241
|
+
record,
|
|
242
|
+
authored,
|
|
243
|
+
written,
|
|
244
|
+
linked: linked && index > 0
|
|
245
|
+
}));
|
|
246
|
+
}
|
|
247
|
+
#take(stack) {
|
|
248
|
+
const hold = stack.find((held) => held.instance === this) ?? stack.find((held) => held.instance === null && held.record === this.#record);
|
|
249
|
+
if (hold) hold.instance = this;
|
|
250
|
+
return hold;
|
|
251
|
+
}
|
|
252
|
+
#covered(region, stack, hold) {
|
|
253
|
+
return stack.slice(stack.indexOf(hold) + 1).some((above) => above.written === region.hidden);
|
|
254
|
+
}
|
|
255
|
+
#acquire(region, stack) {
|
|
256
|
+
const top = stack.at(-1);
|
|
257
|
+
const over = top && region.hidden === top.written ? top : void 0;
|
|
258
|
+
const hold = {
|
|
259
|
+
instance: this,
|
|
260
|
+
record: this.#record,
|
|
261
|
+
authored: over ? over.authored : region.getAttribute("hidden"),
|
|
262
|
+
written: false,
|
|
263
|
+
linked: over !== void 0
|
|
264
|
+
};
|
|
265
|
+
stack.push(hold);
|
|
266
|
+
return hold;
|
|
267
|
+
}
|
|
268
|
+
#mark(region, stack) {
|
|
269
|
+
const records = /* @__PURE__ */ new Map([[this.#record, null]]);
|
|
270
|
+
stack.forEach((hold, index) => {
|
|
271
|
+
const names = stack.slice(0, index).map((under) => under.record);
|
|
272
|
+
const beneath = [...new Set(names.reverse())].filter((name) => name !== hold.record);
|
|
273
|
+
const marker = hold.linked || beneath.length === 0 ? [] : [false];
|
|
274
|
+
records.set(
|
|
275
|
+
hold.record,
|
|
276
|
+
region.getAttribute("hidden") === hold.authored && beneath.length === 0 && index === stack.length - 1 ? null : JSON.stringify([hold.authored, hold.written, ...marker, ...beneath])
|
|
277
|
+
);
|
|
278
|
+
});
|
|
279
|
+
for (const [name, recorded] of records) {
|
|
280
|
+
if (region.getAttribute(name) === recorded) continue;
|
|
281
|
+
if (recorded === null) region.removeAttribute(name);
|
|
282
|
+
else region.setAttribute(name, recorded);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
#recorded(region, name) {
|
|
286
|
+
try {
|
|
287
|
+
const parsed = JSON.parse(region.getAttribute(name) ?? "null");
|
|
288
|
+
if (!Array.isArray(parsed)) return null;
|
|
289
|
+
const [authored, written, ...rest] = parsed;
|
|
290
|
+
if (authored !== null && typeof authored !== "string") return null;
|
|
291
|
+
const linked = rest[0] !== false;
|
|
292
|
+
const beneath = linked ? rest : rest.slice(1);
|
|
293
|
+
if (!beneath.every((under) => typeof under === "string")) return null;
|
|
294
|
+
return typeof written === "boolean" ? { authored, written, linked, beneath } : null;
|
|
295
|
+
} catch {
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
49
298
|
}
|
|
50
|
-
/** The declared regions that sit within `host`, which may be the host itself. */
|
|
51
299
|
#inside(host, regions) {
|
|
52
300
|
return regions.filter((region) => host.contains(region));
|
|
53
301
|
}
|
|
54
302
|
};
|
|
55
303
|
|
|
56
|
-
// src/utils/safe_timeout.ts
|
|
57
304
|
var TimerRegistry = class {
|
|
58
|
-
/** Live timer ids that have not yet been cleared (or, for timeouts, fired). */
|
|
59
305
|
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
306
|
clear(id) {
|
|
67
307
|
if (this.ids.delete(id)) {
|
|
68
308
|
this.cancel(id);
|
|
69
309
|
}
|
|
70
310
|
}
|
|
71
|
-
/**
|
|
72
|
-
* Cancels every tracked timer. Call this from a controller's `disconnect()`
|
|
73
|
-
* to guarantee no timer outlives the element.
|
|
74
|
-
*/
|
|
75
311
|
clearAll() {
|
|
76
312
|
for (const id of this.ids) {
|
|
77
313
|
this.cancel(id);
|
|
78
314
|
}
|
|
79
315
|
this.ids.clear();
|
|
80
316
|
}
|
|
81
|
-
/** Number of timers currently tracked (pending). */
|
|
82
317
|
get size() {
|
|
83
318
|
return this.ids.size;
|
|
84
319
|
}
|
|
85
320
|
};
|
|
86
321
|
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
322
|
set(callback, delay) {
|
|
94
323
|
const id = this.schedule(() => {
|
|
95
324
|
this.ids.delete(id);
|
|
@@ -106,7 +335,6 @@ var SafeTimeout = class extends TimerRegistry {
|
|
|
106
335
|
}
|
|
107
336
|
};
|
|
108
337
|
|
|
109
|
-
// src/utils/transition_completion.ts
|
|
110
338
|
function timeMs(value) {
|
|
111
339
|
const trimmed = value.trim();
|
|
112
340
|
const amount = Number.parseFloat(trimmed);
|
|
@@ -142,13 +370,6 @@ var TransitionCompletion = class {
|
|
|
142
370
|
#complete = null;
|
|
143
371
|
#pendingProperties = null;
|
|
144
372
|
#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
373
|
wait(element, complete, options = {}) {
|
|
153
374
|
this.cancel();
|
|
154
375
|
const requested = options.timeoutMs ?? 0;
|
|
@@ -168,18 +389,10 @@ var TransitionCompletion = class {
|
|
|
168
389
|
element.addEventListener("transitioncancel", this.#onTerminal);
|
|
169
390
|
this.#timers.set(() => this.#finish(), override > 0 ? override : maximum + 50);
|
|
170
391
|
}
|
|
171
|
-
/** Cancels the pending wait without invoking its completion callback. */
|
|
172
392
|
cancel() {
|
|
173
393
|
this.#complete = null;
|
|
174
394
|
this.#teardown();
|
|
175
395
|
}
|
|
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
396
|
#onTerminal = (event) => {
|
|
184
397
|
if (event.target !== this.#element) return;
|
|
185
398
|
const transitionEvent = event;
|
|
@@ -199,10 +412,6 @@ var TransitionCompletion = class {
|
|
|
199
412
|
}
|
|
200
413
|
if (Date.now() >= this.#deadline) this.#finish();
|
|
201
414
|
};
|
|
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
415
|
#activeTransitionProperties(element) {
|
|
207
416
|
if (!element || typeof element.getAnimations !== "function") return /* @__PURE__ */ new Set();
|
|
208
417
|
try {
|
|
@@ -220,7 +429,6 @@ var TransitionCompletion = class {
|
|
|
220
429
|
return /* @__PURE__ */ new Set();
|
|
221
430
|
}
|
|
222
431
|
}
|
|
223
|
-
/** Returns explicit positive-time properties, or `null` for the ambiguous `all`. */
|
|
224
432
|
#explicitPendingProperties(timings) {
|
|
225
433
|
if (timings.some(({ property }) => property === "all")) return null;
|
|
226
434
|
const pending = new Set(
|
|
@@ -228,7 +436,6 @@ var TransitionCompletion = class {
|
|
|
228
436
|
);
|
|
229
437
|
return pending.size > 0 ? pending : null;
|
|
230
438
|
}
|
|
231
|
-
/** Completes exactly once, releasing listeners and the fallback before the callback. */
|
|
232
439
|
#finish() {
|
|
233
440
|
const complete = this.#complete;
|
|
234
441
|
if (!complete) return;
|
|
@@ -236,7 +443,6 @@ var TransitionCompletion = class {
|
|
|
236
443
|
this.#teardown();
|
|
237
444
|
complete();
|
|
238
445
|
}
|
|
239
|
-
/** Releases the exact element listeners and timer owned by the current wait. */
|
|
240
446
|
#teardown() {
|
|
241
447
|
this.#timers.clearAll();
|
|
242
448
|
this.#element?.removeEventListener("transitionend", this.#onTerminal);
|
|
@@ -247,7 +453,6 @@ var TransitionCompletion = class {
|
|
|
247
453
|
}
|
|
248
454
|
};
|
|
249
455
|
|
|
250
|
-
// src/controllers/collapsible_controller.ts
|
|
251
456
|
var CollapsibleController = class extends Controller {
|
|
252
457
|
static targets = ["trigger", "content", "expandedLabel", "collapsedLabel"];
|
|
253
458
|
static values = {
|
|
@@ -255,35 +460,24 @@ var CollapsibleController = class extends Controller {
|
|
|
255
460
|
};
|
|
256
461
|
static actions = ["toggle"];
|
|
257
462
|
static events = ["close", "open"];
|
|
258
|
-
|
|
463
|
+
#expanded = new AttributeLease("aria-expanded", this.identifier);
|
|
464
|
+
#contentHidden = new AttributeLease("hidden", this.identifier);
|
|
465
|
+
#contentState = new AttributeLease("data-state", this.identifier);
|
|
259
466
|
#transition = new TransitionCompletion();
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
467
|
+
#labels = new StateRegions(
|
|
468
|
+
{
|
|
469
|
+
whenTrue: () => this.expandedLabelTargets,
|
|
470
|
+
whenFalse: () => this.collapsedLabelTargets
|
|
471
|
+
},
|
|
472
|
+
this.identifier
|
|
473
|
+
);
|
|
266
474
|
#connected = false;
|
|
267
|
-
/** Whether state moves are reported: set once `connect()` settled the baseline. */
|
|
268
475
|
#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
476
|
connect() {
|
|
282
477
|
this.#connected = true;
|
|
283
478
|
this.#apply(this.#initialOpen(), false, "api");
|
|
284
479
|
this.#reporting = true;
|
|
285
480
|
}
|
|
286
|
-
/** Resolves the connect-time state: explicit DOM state wins, else the `open` Value. */
|
|
287
481
|
#initialOpen() {
|
|
288
482
|
if (this.hasTriggerTarget) {
|
|
289
483
|
const expanded = this.triggerTarget.getAttribute("aria-expanded");
|
|
@@ -301,72 +495,66 @@ var CollapsibleController = class extends Controller {
|
|
|
301
495
|
this.#reporting = false;
|
|
302
496
|
this.#transition.cancel();
|
|
303
497
|
}
|
|
304
|
-
/** Reconciles a replacement trigger target with the content's live state. */
|
|
305
498
|
triggerTargetConnected(trigger) {
|
|
306
|
-
if (
|
|
499
|
+
if (this.#connected) this.#reconcileTrigger(trigger);
|
|
500
|
+
}
|
|
501
|
+
triggerTargetDisconnected(trigger) {
|
|
502
|
+
if (!this.triggerTargets.includes(trigger)) {
|
|
503
|
+
this.#expanded.return(trigger);
|
|
504
|
+
this.#labels.release(trigger);
|
|
505
|
+
}
|
|
506
|
+
if (this.#connected && this.hasTriggerTarget) this.#reconcileTrigger(this.triggerTarget);
|
|
507
|
+
}
|
|
508
|
+
#reconcileTrigger(trigger) {
|
|
307
509
|
if (this.hasContentTarget) {
|
|
308
|
-
|
|
309
|
-
|
|
510
|
+
this.#expanded.write(
|
|
511
|
+
trigger,
|
|
310
512
|
this.contentTarget.getAttribute("data-state") === "open" ? "true" : "false"
|
|
311
513
|
);
|
|
312
514
|
}
|
|
313
515
|
this.#labels.reflect(trigger, trigger.getAttribute("aria-expanded") === "true");
|
|
314
516
|
}
|
|
315
|
-
/** Settles a label that arrived after the state it belongs to was written. */
|
|
316
517
|
expandedLabelTargetConnected() {
|
|
317
518
|
this.#reflectLabels();
|
|
318
519
|
}
|
|
319
|
-
/** Settles a label that arrived after the state it belongs to was written. */
|
|
320
520
|
collapsedLabelTargetConnected() {
|
|
321
521
|
this.#reflectLabels();
|
|
322
522
|
}
|
|
323
|
-
/** Shows the label pair's side that belongs to the trigger's expanded state. */
|
|
324
523
|
#reflectLabels() {
|
|
325
524
|
if (this.#connected && this.hasTriggerTarget) {
|
|
326
525
|
this.#labels.reflect(this.triggerTarget, this.#isOpen);
|
|
327
526
|
}
|
|
328
527
|
}
|
|
329
|
-
/** Reconciles a replacement content target with the disclosure's live state. */
|
|
330
528
|
contentTargetConnected(content) {
|
|
331
529
|
if (!this.#connected) return;
|
|
332
530
|
this.#transition.cancel();
|
|
333
|
-
|
|
334
|
-
this.#applyContent(content, open, false);
|
|
531
|
+
this.#reconcileContent(content);
|
|
335
532
|
}
|
|
336
|
-
|
|
337
|
-
contentTargetDisconnected() {
|
|
533
|
+
contentTargetDisconnected(content) {
|
|
338
534
|
this.#transition.cancel();
|
|
535
|
+
if (!this.contentTargets.includes(content)) {
|
|
536
|
+
this.#contentHidden.return(content);
|
|
537
|
+
this.#contentState.return(content);
|
|
538
|
+
}
|
|
539
|
+
if (this.#connected && this.hasContentTarget) this.#reconcileContent(this.contentTarget);
|
|
540
|
+
}
|
|
541
|
+
#reconcileContent(content) {
|
|
542
|
+
const open = this.hasTriggerTarget ? this.triggerTarget.getAttribute("aria-expanded") === "true" : content.getAttribute("data-state") === "open";
|
|
543
|
+
this.#applyContent(content, open, false);
|
|
339
544
|
}
|
|
340
|
-
/** Toggles the region open/closed. Bound via `data-action` (click). */
|
|
341
545
|
toggle(event) {
|
|
342
546
|
this.#apply(!this.#isOpen, true, stateReasonFor(event));
|
|
343
547
|
}
|
|
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
548
|
get #isOpen() {
|
|
350
549
|
if (this.hasTriggerTarget) {
|
|
351
550
|
return this.triggerTarget.getAttribute("aria-expanded") === "true";
|
|
352
551
|
}
|
|
353
552
|
return this.hasContentTarget && this.contentTarget.getAttribute("data-state") === "open";
|
|
354
553
|
}
|
|
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
554
|
#apply(open, waitForCloseTransition, reason) {
|
|
367
555
|
const was = this.#isOpen;
|
|
368
556
|
if (this.hasTriggerTarget) {
|
|
369
|
-
this.triggerTarget
|
|
557
|
+
this.#expanded.write(this.triggerTarget, open ? "true" : "false");
|
|
370
558
|
this.#labels.reflect(this.triggerTarget, open);
|
|
371
559
|
}
|
|
372
560
|
if (this.hasContentTarget) {
|
|
@@ -378,38 +566,31 @@ var CollapsibleController = class extends Controller {
|
|
|
378
566
|
if (open) this.dispatch("open", { detail: { reason }, cancelable: false });
|
|
379
567
|
else this.dispatch("close", { detail: { reason }, cancelable: false });
|
|
380
568
|
}
|
|
381
|
-
/** Reflects one content target without relying on a later target lookup. */
|
|
382
569
|
#applyContent(content, open, waitForCloseTransition) {
|
|
383
570
|
if (open) {
|
|
384
|
-
content
|
|
571
|
+
this.#contentHidden.write(content, null);
|
|
385
572
|
content.style.setProperty(
|
|
386
573
|
"--stimeo--collapsible-content-height",
|
|
387
574
|
`${content.scrollHeight}px`
|
|
388
575
|
);
|
|
389
|
-
|
|
576
|
+
this.#contentState.write(content, "open");
|
|
390
577
|
return;
|
|
391
578
|
}
|
|
392
|
-
|
|
579
|
+
this.#contentState.write(content, "closed");
|
|
393
580
|
if (waitForCloseTransition) {
|
|
394
581
|
this.#applyHiddenAfterTransition(content);
|
|
395
582
|
} else {
|
|
396
|
-
content
|
|
583
|
+
this.#contentHidden.write(content, "");
|
|
397
584
|
}
|
|
398
585
|
}
|
|
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
586
|
#applyHiddenAfterTransition(content) {
|
|
405
587
|
this.#transition.wait(content, () => {
|
|
406
588
|
if (content.getAttribute("data-state") === "closed") {
|
|
407
|
-
content
|
|
589
|
+
this.#contentHidden.write(content, "");
|
|
408
590
|
}
|
|
409
591
|
});
|
|
410
592
|
}
|
|
411
593
|
};
|
|
412
594
|
|
|
413
595
|
export { CollapsibleController };
|
|
414
|
-
//# sourceMappingURL=collapsible_controller.js.map
|
|
415
596
|
//# sourceMappingURL=collapsible_controller.js.map
|