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
|
@@ -27,11 +27,22 @@ import { Controller } from '@hotwired/stimulus';
|
|
|
27
27
|
* non-focusable menu content), so a press aimed at another layer never closes
|
|
28
28
|
* the menu or steals focus, and one keypress closes exactly one layer.
|
|
29
29
|
* - A click outside the controller element closes the menu.
|
|
30
|
+
* - A trigger or a menu that takes over — in one task, or after an earlier one leaves
|
|
31
|
+
* in a later task — carries the open state, and an `aria-controls` this controller
|
|
32
|
+
* supplied names the menu that is first. With no menu left the dropdown reads
|
|
33
|
+
* closed and leaves the Escape stack. One that stops resolving as the target gets
|
|
34
|
+
* back what it carried before this controller wrote on it.
|
|
35
|
+
* - A Turbo morph that keeps the elements drops the attributes the server did not
|
|
36
|
+
* send — the menu's `hidden`, the trigger's `aria-expanded` and the
|
|
37
|
+
* `aria-controls` this controller supplied. They are written back from the open
|
|
38
|
+
* state the controller holds, so a closed menu does not show up and an open one
|
|
39
|
+
* stays described.
|
|
30
40
|
* - Each move of the open state is reported: `stimeo--dropdown:open` and
|
|
31
41
|
* `stimeo--dropdown:close` dispatch `{ reason: StateReason }`, after the
|
|
32
42
|
* attributes above are written. Both are informational, so neither is
|
|
33
43
|
* cancelable. A call that leaves the state where it already was, the
|
|
34
|
-
* normalization in {@link connect},
|
|
44
|
+
* normalization in {@link connect}, a trigger or a menu that takes over, the
|
|
45
|
+
* repair after a morph, and {@link disconnect} are all silent.
|
|
35
46
|
*/
|
|
36
47
|
declare class DropdownController extends Controller<HTMLElement> {
|
|
37
48
|
#private;
|
|
@@ -39,13 +50,32 @@ declare class DropdownController extends Controller<HTMLElement> {
|
|
|
39
50
|
static actions: readonly ["close", "open", "toggle"];
|
|
40
51
|
static events: readonly ["close", "open"];
|
|
41
52
|
readonly triggerTarget: HTMLButtonElement;
|
|
53
|
+
readonly triggerTargets: HTMLButtonElement[];
|
|
42
54
|
readonly menuTarget: HTMLElement;
|
|
55
|
+
readonly menuTargets: HTMLElement[];
|
|
43
56
|
readonly hasMenuTarget: boolean;
|
|
44
57
|
readonly hasTriggerTarget: boolean;
|
|
45
58
|
/** Starts in the closed state and registers outside-click handling. */
|
|
46
59
|
connect(): void;
|
|
47
60
|
/** Removes the listeners registered in {@link connect}. */
|
|
48
61
|
disconnect(): void;
|
|
62
|
+
/** Brings a trigger that arrives after connect to the open state and names the menu from it. */
|
|
63
|
+
triggerTargetConnected(): void;
|
|
64
|
+
/**
|
|
65
|
+
* Gives a trigger that no longer resolves as one its own `aria-expanded` and `aria-controls`
|
|
66
|
+
* back — after `disconnect()` too, since dropping the identifier leaves the element on the
|
|
67
|
+
* page — and brings the trigger that stays to the open state.
|
|
68
|
+
*/
|
|
69
|
+
triggerTargetDisconnected(trigger: HTMLButtonElement): void;
|
|
70
|
+
/** Applies the open state to a menu that arrives after connect in front of the others. */
|
|
71
|
+
menuTargetConnected(): void;
|
|
72
|
+
/**
|
|
73
|
+
* Applies the open state to the menu left, then gives a menu that no longer resolves as the
|
|
74
|
+
* target its own `hidden` back — after `disconnect()` too, since dropping the identifier
|
|
75
|
+
* leaves the element on the page. The open state is read off the departing menu first,
|
|
76
|
+
* while it still carries it.
|
|
77
|
+
*/
|
|
78
|
+
menuTargetDisconnected(menu: HTMLElement): void;
|
|
49
79
|
/** Toggles the menu between open and closed. Bound via `data-action`. */
|
|
50
80
|
toggle(event?: Event): void;
|
|
51
81
|
/** Reveals the menu and reflects the open state on the trigger. */
|
|
@@ -1,14 +1,21 @@
|
|
|
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 registry2 = create();
|
|
9
|
+
Object.defineProperty(globalThis, symbol, { value: registry2 });
|
|
10
|
+
return registry2;
|
|
11
|
+
}
|
|
4
12
|
|
|
5
|
-
|
|
6
|
-
var counter = 0;
|
|
13
|
+
var ids = sharedRegistry("stimeo-ui.aria-ids.registry.v1", () => ({ counter: 0 }));
|
|
7
14
|
function uniqueId(prefix = "stimeo") {
|
|
8
15
|
let candidate;
|
|
9
16
|
do {
|
|
10
|
-
counter += 1;
|
|
11
|
-
candidate = `${prefix}-${counter}`;
|
|
17
|
+
ids.counter += 1;
|
|
18
|
+
candidate = `${prefix}-${ids.counter}`;
|
|
12
19
|
} while (typeof document !== "undefined" && document.getElementById(candidate) !== null);
|
|
13
20
|
return candidate;
|
|
14
21
|
}
|
|
@@ -19,7 +26,149 @@ function ensureId(element, prefix = "stimeo") {
|
|
|
19
26
|
return id;
|
|
20
27
|
}
|
|
21
28
|
|
|
22
|
-
|
|
29
|
+
function setAttributeIfChanged(element, name, value, beforeWrite) {
|
|
30
|
+
if (element.getAttribute(name) === value) return false;
|
|
31
|
+
if (value === null) element.removeAttribute(name);
|
|
32
|
+
else element.setAttribute(name, value);
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
var registry = sharedRegistry(
|
|
37
|
+
"stimeo-ui.attribute-lease.registry.v1",
|
|
38
|
+
() => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
|
|
39
|
+
);
|
|
40
|
+
function isAttributeValue(value) {
|
|
41
|
+
return value === null || typeof value === "string";
|
|
42
|
+
}
|
|
43
|
+
function readLeaseRecord(element, record) {
|
|
44
|
+
try {
|
|
45
|
+
const parsed = JSON.parse(element.getAttribute(record) ?? "null");
|
|
46
|
+
if (!Array.isArray(parsed)) return void 0;
|
|
47
|
+
const [original, written, ...rest] = parsed;
|
|
48
|
+
const linked = rest[0] !== false;
|
|
49
|
+
const beneath = linked ? rest : rest.slice(1);
|
|
50
|
+
if (!beneath.every((under) => typeof under === "string")) return void 0;
|
|
51
|
+
return isAttributeValue(original) && isAttributeValue(written) ? { original, written, linked, beneath } : void 0;
|
|
52
|
+
} catch {
|
|
53
|
+
return void 0;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function attributeStack(element, attribute) {
|
|
57
|
+
const byAttribute = registry.stacks.get(element) ?? /* @__PURE__ */ new Map();
|
|
58
|
+
registry.stacks.set(element, byAttribute);
|
|
59
|
+
const known = byAttribute.get(attribute);
|
|
60
|
+
if (known) return known;
|
|
61
|
+
const found = [];
|
|
62
|
+
for (const record of registry.names.get(attribute) ?? []) {
|
|
63
|
+
const read = readLeaseRecord(element, record);
|
|
64
|
+
if (read) found.push({ ...read, record });
|
|
65
|
+
}
|
|
66
|
+
const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
|
|
67
|
+
const stack = found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
|
|
68
|
+
lease: null,
|
|
69
|
+
record,
|
|
70
|
+
written,
|
|
71
|
+
original,
|
|
72
|
+
linked: linked && index > 0
|
|
73
|
+
}));
|
|
74
|
+
byAttribute.set(attribute, stack);
|
|
75
|
+
return stack;
|
|
76
|
+
}
|
|
77
|
+
function findHold(stack, lease, record) {
|
|
78
|
+
return stack.find((held) => held.lease === lease) ?? stack.find((held) => held.lease === null && held.record === record);
|
|
79
|
+
}
|
|
80
|
+
var AttributeLease = class {
|
|
81
|
+
#attribute;
|
|
82
|
+
#record;
|
|
83
|
+
#base;
|
|
84
|
+
#preserveAuthor;
|
|
85
|
+
#held = /* @__PURE__ */ new Set();
|
|
86
|
+
constructor(attribute, owner, options = {}) {
|
|
87
|
+
this.#attribute = attribute;
|
|
88
|
+
this.#record = `data-${owner}-${attribute}-lease`;
|
|
89
|
+
this.#base = options.base === true;
|
|
90
|
+
this.#preserveAuthor = options.preserveAuthor === true;
|
|
91
|
+
const names = registry.names;
|
|
92
|
+
names.set(attribute, (names.get(attribute) ?? /* @__PURE__ */ new Set()).add(this.#record));
|
|
93
|
+
}
|
|
94
|
+
write(element, value) {
|
|
95
|
+
const stack = attributeStack(element, this.#attribute);
|
|
96
|
+
const hold = this.#take(stack) ?? this.#acquire(element, stack);
|
|
97
|
+
this.#held.add(element);
|
|
98
|
+
const shows = !this.#covered(element, stack, hold);
|
|
99
|
+
hold.written = value;
|
|
100
|
+
this.#mark(element, stack);
|
|
101
|
+
if (shows) this.#reflect(element, value);
|
|
102
|
+
}
|
|
103
|
+
return(element) {
|
|
104
|
+
const held = this.#held.delete(element);
|
|
105
|
+
const known = registry.stacks.get(element)?.has(this.#attribute);
|
|
106
|
+
const stack = held || known || element.hasAttribute(this.#record) ? attributeStack(element, this.#attribute) : [];
|
|
107
|
+
const hold = this.#take(stack);
|
|
108
|
+
if (!hold) return false;
|
|
109
|
+
const carries = element.getAttribute(this.#attribute) === hold.written;
|
|
110
|
+
const owns = carries && !this.#covered(element, stack, hold);
|
|
111
|
+
const index = stack.indexOf(hold);
|
|
112
|
+
stack.splice(index, 1);
|
|
113
|
+
const above = stack[index];
|
|
114
|
+
if (above) above.linked &&= hold.linked;
|
|
115
|
+
this.#mark(element, stack);
|
|
116
|
+
if (!owns) return true;
|
|
117
|
+
const below = hold.linked ? stack[index - 1] : void 0;
|
|
118
|
+
this.#reflect(element, below ? below.written : hold.original);
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
returnAll() {
|
|
122
|
+
for (const element of Array.from(this.#held)) this.return(element);
|
|
123
|
+
}
|
|
124
|
+
#take(stack) {
|
|
125
|
+
const hold = findHold(stack, this, this.#record);
|
|
126
|
+
if (hold) hold.lease = this;
|
|
127
|
+
return hold;
|
|
128
|
+
}
|
|
129
|
+
#acquire(element, stack) {
|
|
130
|
+
const current = element.getAttribute(this.#attribute);
|
|
131
|
+
const top = stack.at(-1);
|
|
132
|
+
const bottom = stack[0];
|
|
133
|
+
const over = top?.written === current ? top : void 0;
|
|
134
|
+
const from = this.#base ? this.#preserveAuthor && !stack.some((held) => held.written === current) ? void 0 : bottom : over;
|
|
135
|
+
const hold = {
|
|
136
|
+
lease: this,
|
|
137
|
+
record: this.#record,
|
|
138
|
+
written: current,
|
|
139
|
+
original: from ? from.original : current,
|
|
140
|
+
linked: !this.#base && over !== void 0
|
|
141
|
+
};
|
|
142
|
+
if (this.#base && bottom) {
|
|
143
|
+
bottom.linked = true;
|
|
144
|
+
stack.unshift(hold);
|
|
145
|
+
} else stack.push(hold);
|
|
146
|
+
return hold;
|
|
147
|
+
}
|
|
148
|
+
#covered(element, stack, hold) {
|
|
149
|
+
const current = element.getAttribute(this.#attribute);
|
|
150
|
+
return stack.slice(stack.indexOf(hold) + 1).some((above) => above.written === current);
|
|
151
|
+
}
|
|
152
|
+
#mark(element, stack) {
|
|
153
|
+
const records = /* @__PURE__ */ new Map([[this.#record, null]]);
|
|
154
|
+
stack.forEach((hold, index) => {
|
|
155
|
+
const names = stack.slice(0, index).map((under) => under.record);
|
|
156
|
+
const beneath = [...new Set(names.reverse())].filter((name) => name !== hold.record);
|
|
157
|
+
const marker = hold.linked || beneath.length === 0 ? [] : [false];
|
|
158
|
+
records.set(
|
|
159
|
+
hold.record,
|
|
160
|
+
hold.written === hold.original && beneath.length === 0 && index === stack.length - 1 ? null : JSON.stringify([hold.original, hold.written, ...marker, ...beneath])
|
|
161
|
+
);
|
|
162
|
+
});
|
|
163
|
+
for (const [name, recorded] of records) {
|
|
164
|
+
setAttributeIfChanged(element, name, recorded);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
#reflect(element, value) {
|
|
168
|
+
setAttributeIfChanged(element, this.#attribute, value);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
|
|
23
172
|
function claimsWhileFocusWithin(element) {
|
|
24
173
|
return () => {
|
|
25
174
|
const active = element.ownerDocument.activeElement;
|
|
@@ -27,89 +176,138 @@ function claimsWhileFocusWithin(element) {
|
|
|
27
176
|
};
|
|
28
177
|
}
|
|
29
178
|
var EscapeLayer = class _EscapeLayer {
|
|
30
|
-
static #registries =
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
#claims = null;
|
|
36
|
-
/**
|
|
37
|
-
* Activates this layer at the top of its document's Escape stack, installing
|
|
38
|
-
* the document's shared resolver listener if this is its first layer.
|
|
39
|
-
* Re-activating an already-active layer moves it to the top.
|
|
40
|
-
*/
|
|
179
|
+
static #registries = sharedRegistry(
|
|
180
|
+
"stimeo-ui.escape-layer.registry.v1",
|
|
181
|
+
() => /* @__PURE__ */ new WeakMap()
|
|
182
|
+
);
|
|
183
|
+
#active = null;
|
|
41
184
|
activate(ownerDocument = document, options) {
|
|
42
185
|
this.deactivate();
|
|
43
|
-
let
|
|
44
|
-
if (!
|
|
45
|
-
|
|
46
|
-
_EscapeLayer.#registries.set(ownerDocument,
|
|
47
|
-
ownerDocument.addEventListener("keydown",
|
|
186
|
+
let registry2 = _EscapeLayer.#registries.get(ownerDocument);
|
|
187
|
+
if (!registry2) {
|
|
188
|
+
registry2 = _EscapeLayer.#createRegistry();
|
|
189
|
+
_EscapeLayer.#registries.set(ownerDocument, registry2);
|
|
190
|
+
ownerDocument.addEventListener("keydown", registry2.onKeydown);
|
|
48
191
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
this.#
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Removes this layer from its document's Escape stack, uninstalling the
|
|
56
|
-
* shared listener when the stack empties. Safe to call when inactive.
|
|
57
|
-
*/
|
|
192
|
+
const entry = { onDismiss: options.onDismiss, claims: options.claims ?? null };
|
|
193
|
+
registry2.stack.push(entry);
|
|
194
|
+
this.#active = { document: ownerDocument, entry };
|
|
195
|
+
}
|
|
58
196
|
deactivate() {
|
|
59
|
-
const
|
|
60
|
-
if (!
|
|
61
|
-
const
|
|
62
|
-
if (
|
|
63
|
-
const index =
|
|
64
|
-
if (index >= 0)
|
|
65
|
-
if (
|
|
66
|
-
|
|
67
|
-
_EscapeLayer.#registries.delete(
|
|
197
|
+
const active = this.#active;
|
|
198
|
+
if (!active) return;
|
|
199
|
+
const registry2 = _EscapeLayer.#registries.get(active.document);
|
|
200
|
+
if (registry2) {
|
|
201
|
+
const index = registry2.stack.lastIndexOf(active.entry);
|
|
202
|
+
if (index >= 0) registry2.stack.splice(index, 1);
|
|
203
|
+
if (registry2.stack.length === 0) {
|
|
204
|
+
active.document.removeEventListener("keydown", registry2.onKeydown);
|
|
205
|
+
_EscapeLayer.#registries.delete(active.document);
|
|
68
206
|
}
|
|
69
207
|
}
|
|
70
|
-
this.#
|
|
71
|
-
|
|
72
|
-
this.#claims = null;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Whether this active layer would own a press right now: it is the topmost
|
|
76
|
-
* layer whose {@link EscapeLayerOptions.claims} passes. Exposed for tests
|
|
77
|
-
* and diagnostics — production dismissal goes through the shared listener.
|
|
78
|
-
*/
|
|
208
|
+
this.#active = null;
|
|
209
|
+
}
|
|
79
210
|
get ownsEscape() {
|
|
80
|
-
const
|
|
81
|
-
if (!
|
|
82
|
-
const
|
|
83
|
-
if (!
|
|
84
|
-
return _EscapeLayer.#resolveOwner(
|
|
211
|
+
const active = this.#active;
|
|
212
|
+
if (!active) return false;
|
|
213
|
+
const registry2 = _EscapeLayer.#registries.get(active.document);
|
|
214
|
+
if (!registry2) return false;
|
|
215
|
+
return _EscapeLayer.#resolveOwner(registry2.stack) === active.entry;
|
|
85
216
|
}
|
|
86
|
-
/** Builds a document's registry with its shared resolver listener. */
|
|
87
217
|
static #createRegistry() {
|
|
88
|
-
const
|
|
218
|
+
const registry2 = {
|
|
89
219
|
stack: [],
|
|
90
220
|
onKeydown: (event) => {
|
|
91
221
|
if (event.key !== "Escape" || event.defaultPrevented || event.isComposing) return;
|
|
92
|
-
const owner = _EscapeLayer.#resolveOwner(
|
|
222
|
+
const owner = _EscapeLayer.#resolveOwner(registry2.stack);
|
|
93
223
|
if (!owner) return;
|
|
94
224
|
event.preventDefault();
|
|
95
|
-
owner
|
|
225
|
+
owner.onDismiss();
|
|
96
226
|
}
|
|
97
227
|
};
|
|
98
|
-
return
|
|
228
|
+
return registry2;
|
|
99
229
|
}
|
|
100
|
-
/** The topmost stack layer whose claims predicate passes, or `null`. */
|
|
101
230
|
static #resolveOwner(stack) {
|
|
102
231
|
for (let index = stack.length - 1; index >= 0; index--) {
|
|
103
232
|
const layer = stack[index];
|
|
104
233
|
if (!layer) continue;
|
|
105
|
-
if (layer
|
|
234
|
+
if (layer.claims && !layer.claims()) continue;
|
|
106
235
|
return layer;
|
|
107
236
|
}
|
|
108
237
|
return null;
|
|
109
238
|
}
|
|
110
239
|
};
|
|
111
240
|
|
|
112
|
-
|
|
241
|
+
var ListenerSet = class {
|
|
242
|
+
#abort = new AbortController();
|
|
243
|
+
add(target, type, handler, options) {
|
|
244
|
+
target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });
|
|
245
|
+
}
|
|
246
|
+
dispose() {
|
|
247
|
+
this.#abort.abort();
|
|
248
|
+
this.#abort = new AbortController();
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
var MicrotaskCoalescer = class {
|
|
253
|
+
#run;
|
|
254
|
+
#queued = false;
|
|
255
|
+
#active = false;
|
|
256
|
+
#generation = 0;
|
|
257
|
+
constructor(run) {
|
|
258
|
+
this.#run = run;
|
|
259
|
+
}
|
|
260
|
+
activate() {
|
|
261
|
+
this.#active = true;
|
|
262
|
+
}
|
|
263
|
+
cancel() {
|
|
264
|
+
this.#active = false;
|
|
265
|
+
this.#queued = false;
|
|
266
|
+
this.#generation += 1;
|
|
267
|
+
}
|
|
268
|
+
get pending() {
|
|
269
|
+
return this.#queued;
|
|
270
|
+
}
|
|
271
|
+
schedule() {
|
|
272
|
+
if (!this.#active || this.#queued) return;
|
|
273
|
+
this.#queued = true;
|
|
274
|
+
const generation = this.#generation;
|
|
275
|
+
queueMicrotask(() => {
|
|
276
|
+
if (generation !== this.#generation || !this.#queued || !this.#active) return;
|
|
277
|
+
this.#queued = false;
|
|
278
|
+
this.#run();
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
var MorphRenderWatcher = class {
|
|
284
|
+
#listeners = new ListenerSet();
|
|
285
|
+
#pass;
|
|
286
|
+
#element = null;
|
|
287
|
+
#onMorph = () => this.#pass.schedule();
|
|
288
|
+
constructor(run) {
|
|
289
|
+
this.#pass = new MicrotaskCoalescer(run);
|
|
290
|
+
}
|
|
291
|
+
observe(element) {
|
|
292
|
+
if (this.#element === element) return;
|
|
293
|
+
this.disconnect();
|
|
294
|
+
this.#element = element;
|
|
295
|
+
this.#pass.activate();
|
|
296
|
+
this.#listeners.add(element, "turbo:morph-element", this.#onMorph);
|
|
297
|
+
}
|
|
298
|
+
schedule() {
|
|
299
|
+
this.#pass.schedule();
|
|
300
|
+
}
|
|
301
|
+
get pending() {
|
|
302
|
+
return this.#pass.pending;
|
|
303
|
+
}
|
|
304
|
+
disconnect() {
|
|
305
|
+
this.#listeners.dispose();
|
|
306
|
+
this.#pass.cancel();
|
|
307
|
+
this.#element = null;
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
|
|
113
311
|
var FOCUS_EVENTS = /* @__PURE__ */ new Set(["blur", "focus", "focusin", "focusout"]);
|
|
114
312
|
var POINTER_EVENTS = /* @__PURE__ */ new Set(["mouseenter", "mouseleave", "pointerenter", "pointerleave"]);
|
|
115
313
|
function stateReasonFor(event) {
|
|
@@ -119,35 +317,57 @@ function stateReasonFor(event) {
|
|
|
119
317
|
return "user";
|
|
120
318
|
}
|
|
121
319
|
|
|
122
|
-
// src/controllers/dropdown_controller.ts
|
|
123
320
|
var DropdownController = class extends Controller {
|
|
124
321
|
static targets = ["trigger", "menu"];
|
|
125
322
|
static actions = ["close", "open", "toggle"];
|
|
126
323
|
static events = ["close", "open"];
|
|
127
|
-
/** Escape-stack membership while open; the shared resolver dismisses via it. */
|
|
128
324
|
#escapeLayer = new EscapeLayer();
|
|
129
|
-
|
|
325
|
+
#menuHidden = new AttributeLease("hidden", this.identifier);
|
|
326
|
+
#expanded = new AttributeLease("aria-expanded", this.identifier);
|
|
327
|
+
#suppliedControls = /* @__PURE__ */ new WeakMap();
|
|
328
|
+
#menu = null;
|
|
329
|
+
#connected = false;
|
|
130
330
|
#reporting = false;
|
|
131
|
-
|
|
331
|
+
#openState = false;
|
|
332
|
+
#morphRender = new MorphRenderWatcher(() => this.#repair());
|
|
132
333
|
#onOutsideClick = (event) => {
|
|
133
334
|
if (!this.element.contains(event.target)) {
|
|
134
335
|
this.#close("outside");
|
|
135
336
|
}
|
|
136
337
|
};
|
|
137
|
-
|
|
338
|
+
#listeners = new ListenerSet();
|
|
138
339
|
connect() {
|
|
139
340
|
this.#associateTriggerWithMenu();
|
|
140
341
|
this.#close("api");
|
|
141
|
-
|
|
342
|
+
this.#listeners.add(document, "click", this.#onOutsideClick, { capture: true });
|
|
343
|
+
this.#morphRender.observe(this.element);
|
|
344
|
+
this.#connected = true;
|
|
142
345
|
this.#reporting = true;
|
|
143
346
|
}
|
|
144
|
-
/** Removes the listeners registered in {@link connect}. */
|
|
145
347
|
disconnect() {
|
|
348
|
+
this.#connected = false;
|
|
146
349
|
this.#reporting = false;
|
|
147
350
|
this.#escapeLayer.deactivate();
|
|
148
|
-
|
|
351
|
+
this.#listeners.dispose();
|
|
352
|
+
this.#morphRender.disconnect();
|
|
353
|
+
}
|
|
354
|
+
triggerTargetConnected() {
|
|
355
|
+
if (this.#connected) this.#reflectTrigger();
|
|
356
|
+
}
|
|
357
|
+
triggerTargetDisconnected(trigger) {
|
|
358
|
+
if (!this.triggerTargets.includes(trigger)) {
|
|
359
|
+
this.#expanded.return(trigger);
|
|
360
|
+
this.#withdrawControls(trigger);
|
|
361
|
+
}
|
|
362
|
+
if (this.#connected) this.#reflectTrigger();
|
|
363
|
+
}
|
|
364
|
+
menuTargetConnected() {
|
|
365
|
+
this.#adoptMenu();
|
|
366
|
+
}
|
|
367
|
+
menuTargetDisconnected(menu) {
|
|
368
|
+
this.#adoptMenu();
|
|
369
|
+
if (!this.menuTargets.includes(menu)) this.#menuHidden.return(menu);
|
|
149
370
|
}
|
|
150
|
-
/** Toggles the menu between open and closed. Bound via `data-action`. */
|
|
151
371
|
toggle(event) {
|
|
152
372
|
if (this.#isOpen) {
|
|
153
373
|
this.close(event);
|
|
@@ -155,62 +375,85 @@ var DropdownController = class extends Controller {
|
|
|
155
375
|
this.open(event);
|
|
156
376
|
}
|
|
157
377
|
}
|
|
158
|
-
/** Reveals the menu and reflects the open state on the trigger. */
|
|
159
378
|
open(event) {
|
|
160
379
|
this.#open(stateReasonFor(event));
|
|
161
380
|
}
|
|
162
|
-
/** Hides the menu and reflects the closed state on the trigger. */
|
|
163
381
|
close(event) {
|
|
164
382
|
this.#close(stateReasonFor(event));
|
|
165
383
|
}
|
|
166
|
-
/** Reveals the menu, reflects the open state, and reports a move. */
|
|
167
384
|
#open(reason) {
|
|
168
385
|
if (!this.hasMenuTarget) return;
|
|
386
|
+
const menu = this.menuTarget;
|
|
169
387
|
const was = this.#isOpen;
|
|
170
388
|
this.#escapeLayer.activate(document, {
|
|
171
389
|
onDismiss: () => this.#closeAndRestore(),
|
|
172
390
|
claims: claimsWhileFocusWithin(this.element)
|
|
173
391
|
});
|
|
174
|
-
this.
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
392
|
+
this.#menuHidden.write(menu, null);
|
|
393
|
+
this.#menu = menu;
|
|
394
|
+
this.#openState = true;
|
|
395
|
+
if (this.hasTriggerTarget) this.#expanded.write(this.triggerTarget, "true");
|
|
178
396
|
if (!was && this.#reporting) this.dispatch("open", { detail: { reason }, cancelable: false });
|
|
179
397
|
}
|
|
180
|
-
/** Hides the menu, reflects the closed state, and reports a move. */
|
|
181
398
|
#close(reason) {
|
|
182
399
|
const was = this.#isOpen;
|
|
183
400
|
this.#escapeLayer.deactivate();
|
|
184
|
-
|
|
185
|
-
this.menuTarget
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
401
|
+
this.#openState = false;
|
|
402
|
+
const menu = this.hasMenuTarget ? this.menuTarget : null;
|
|
403
|
+
this.#menu = menu;
|
|
404
|
+
if (!menu) return;
|
|
405
|
+
this.#menuHidden.write(menu, "");
|
|
406
|
+
if (this.hasTriggerTarget) this.#expanded.write(this.triggerTarget, "false");
|
|
189
407
|
if (was && this.#reporting) this.dispatch("close", { detail: { reason }, cancelable: false });
|
|
190
408
|
}
|
|
191
|
-
|
|
409
|
+
#adoptMenu() {
|
|
410
|
+
if (!this.#connected) return;
|
|
411
|
+
const menu = this.hasMenuTarget ? this.menuTarget : null;
|
|
412
|
+
const previous = this.#menu;
|
|
413
|
+
this.#menu = menu;
|
|
414
|
+
if (!menu) {
|
|
415
|
+
this.#escapeLayer.deactivate();
|
|
416
|
+
this.#openState = false;
|
|
417
|
+
} else if (menu !== previous) {
|
|
418
|
+
this.#menuHidden.write(menu, previous?.hidden ?? true ? "" : null);
|
|
419
|
+
}
|
|
420
|
+
this.#reflectTrigger();
|
|
421
|
+
}
|
|
422
|
+
#reflectTrigger() {
|
|
423
|
+
if (!this.hasTriggerTarget) return;
|
|
424
|
+
this.#expanded.write(this.triggerTarget, String(this.#isOpen));
|
|
425
|
+
this.#associateTriggerWithMenu();
|
|
426
|
+
}
|
|
427
|
+
#repair() {
|
|
428
|
+
if (!this.hasMenuTarget) return;
|
|
429
|
+
this.#menuHidden.write(this.menuTarget, this.#openState ? null : "");
|
|
430
|
+
this.#reflectTrigger();
|
|
431
|
+
}
|
|
192
432
|
#closeAndRestore() {
|
|
193
433
|
this.#close("escape");
|
|
194
434
|
if (this.hasTriggerTarget) this.triggerTarget.focus();
|
|
195
435
|
}
|
|
196
|
-
/** Whether the menu is currently visible. */
|
|
197
436
|
get #isOpen() {
|
|
198
437
|
return this.hasMenuTarget && !this.menuTarget.hidden;
|
|
199
438
|
}
|
|
200
|
-
/**
|
|
201
|
-
* Associates the disclosure trigger and controlled region without clobbering
|
|
202
|
-
* authored markup.
|
|
203
|
-
*/
|
|
204
439
|
#associateTriggerWithMenu() {
|
|
205
440
|
if (!this.hasTriggerTarget || !this.hasMenuTarget) return;
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
);
|
|
441
|
+
const trigger = this.triggerTarget;
|
|
442
|
+
const controls = trigger.getAttribute("aria-controls");
|
|
443
|
+
if (controls !== null && controls !== this.#suppliedControls.get(trigger)) return;
|
|
444
|
+
const id = ensureId(this.menuTarget, "stimeo--dropdown-menu");
|
|
445
|
+
if (controls === id) return;
|
|
446
|
+
trigger.setAttribute("aria-controls", id);
|
|
447
|
+
this.#suppliedControls.set(trigger, id);
|
|
448
|
+
}
|
|
449
|
+
#withdrawControls(trigger) {
|
|
450
|
+
const supplied = this.#suppliedControls.get(trigger);
|
|
451
|
+
this.#suppliedControls.delete(trigger);
|
|
452
|
+
if (supplied !== void 0 && trigger.getAttribute("aria-controls") === supplied) {
|
|
453
|
+
trigger.removeAttribute("aria-controls");
|
|
454
|
+
}
|
|
211
455
|
}
|
|
212
456
|
};
|
|
213
457
|
|
|
214
458
|
export { DropdownController };
|
|
215
|
-
//# sourceMappingURL=dropdown_controller.js.map
|
|
216
459
|
//# sourceMappingURL=dropdown_controller.js.map
|