stimeo-ui 0.17.0 → 0.18.1
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 -2
- package/README.md +19 -10
- package/dist/cable/index.d.ts +11 -9
- package/dist/cable/index.js +22 -14
- package/dist/cable/index.js.map +1 -1
- package/dist/coerce-JtZVNG5h.d.ts +20 -0
- package/dist/controllers/accordion_controller.js +14 -6
- package/dist/controllers/accordion_controller.js.map +1 -1
- package/dist/controllers/alert_dialog_controller.js +145 -118
- package/dist/controllers/alert_dialog_controller.js.map +1 -1
- package/dist/controllers/announcer_controller.d.ts +5 -3
- package/dist/controllers/announcer_controller.js +113 -17
- package/dist/controllers/announcer_controller.js.map +1 -1
- package/dist/controllers/auto_submit_controller.js +185 -60
- package/dist/controllers/auto_submit_controller.js.map +1 -1
- package/dist/controllers/avatar_controller.js +55 -43
- package/dist/controllers/avatar_controller.js.map +1 -1
- package/dist/controllers/breadcrumb_controller.js.map +1 -1
- package/dist/controllers/bulk_select_controller.d.ts +3 -3
- package/dist/controllers/bulk_select_controller.js +64 -50
- package/dist/controllers/bulk_select_controller.js.map +1 -1
- package/dist/controllers/calendar_controller.d.ts +15 -12
- package/dist/controllers/calendar_controller.js +55 -53
- package/dist/controllers/calendar_controller.js.map +1 -1
- package/dist/controllers/carousel_controller.d.ts +9 -5
- package/dist/controllers/carousel_controller.js +124 -86
- package/dist/controllers/carousel_controller.js.map +1 -1
- package/dist/controllers/character_counter_controller.d.ts +27 -6
- package/dist/controllers/character_counter_controller.js +291 -95
- package/dist/controllers/character_counter_controller.js.map +1 -1
- package/dist/controllers/checkbox_controller.js +6 -0
- package/dist/controllers/checkbox_controller.js.map +1 -1
- package/dist/controllers/clipboard_controller.js +118 -27
- package/dist/controllers/clipboard_controller.js.map +1 -1
- package/dist/controllers/collapsible_controller.d.ts +1 -1
- package/dist/controllers/collapsible_controller.js +52 -49
- package/dist/controllers/collapsible_controller.js.map +1 -1
- package/dist/controllers/color_picker_controller.js +29 -7
- package/dist/controllers/color_picker_controller.js.map +1 -1
- package/dist/controllers/combobox_controller.d.ts +1 -1
- package/dist/controllers/combobox_controller.js +210 -71
- package/dist/controllers/combobox_controller.js.map +1 -1
- package/dist/controllers/command_palette_controller.d.ts +9 -9
- package/dist/controllers/command_palette_controller.js +290 -140
- package/dist/controllers/command_palette_controller.js.map +1 -1
- package/dist/controllers/conditional_fields_controller.js +145 -58
- package/dist/controllers/conditional_fields_controller.js.map +1 -1
- package/dist/controllers/confirm_controller.js +145 -118
- package/dist/controllers/confirm_controller.js.map +1 -1
- package/dist/controllers/context_menu_controller.d.ts +49 -14
- package/dist/controllers/context_menu_controller.js +138 -73
- package/dist/controllers/context_menu_controller.js.map +1 -1
- package/dist/controllers/count_up_controller.js.map +1 -1
- package/dist/controllers/countdown_controller.d.ts +2 -2
- package/dist/controllers/countdown_controller.js +109 -21
- package/dist/controllers/countdown_controller.js.map +1 -1
- package/dist/controllers/currency_input_controller.d.ts +75 -11
- package/dist/controllers/currency_input_controller.js +446 -72
- package/dist/controllers/currency_input_controller.js.map +1 -1
- package/dist/controllers/data_grid_controller.d.ts +10 -8
- package/dist/controllers/data_grid_controller.js +134 -28
- package/dist/controllers/data_grid_controller.js.map +1 -1
- package/dist/controllers/date_range_picker_controller.d.ts +12 -9
- package/dist/controllers/date_range_picker_controller.js +93 -72
- package/dist/controllers/date_range_picker_controller.js.map +1 -1
- package/dist/controllers/dialog_controller.d.ts +4 -5
- package/dist/controllers/dialog_controller.js +145 -118
- package/dist/controllers/dialog_controller.js.map +1 -1
- package/dist/controllers/direct_upload_controller.d.ts +1 -1
- package/dist/controllers/direct_upload_controller.js +24 -14
- 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 +68 -31
- package/dist/controllers/dirty_form_controller.js.map +1 -1
- package/dist/controllers/dismissible_controller.js +66 -46
- package/dist/controllers/dismissible_controller.js.map +1 -1
- package/dist/controllers/drawer_controller.js +145 -118
- package/dist/controllers/drawer_controller.js.map +1 -1
- package/dist/controllers/dropdown_controller.js +76 -63
- package/dist/controllers/dropdown_controller.js.map +1 -1
- package/dist/controllers/editable_controller.js +200 -62
- package/dist/controllers/editable_controller.js.map +1 -1
- package/dist/controllers/empty_state_controller.js +13 -6
- package/dist/controllers/empty_state_controller.js.map +1 -1
- package/dist/controllers/file_dropzone_controller.d.ts +3 -0
- package/dist/controllers/file_dropzone_controller.js +55 -48
- package/dist/controllers/file_dropzone_controller.js.map +1 -1
- package/dist/controllers/filter_controller.js +9 -2
- package/dist/controllers/filter_controller.js.map +1 -1
- package/dist/controllers/flash_controller.d.ts +4 -4
- package/dist/controllers/flash_controller.js +66 -33
- package/dist/controllers/flash_controller.js.map +1 -1
- package/dist/controllers/focus_controller.d.ts +3 -3
- package/dist/controllers/focus_controller.js +39 -14
- package/dist/controllers/focus_controller.js.map +1 -1
- package/dist/controllers/form_field_controller.d.ts +2 -1
- package/dist/controllers/form_field_controller.js +52 -43
- 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 +18 -11
- package/dist/controllers/form_validation_controller.js.map +1 -1
- package/dist/controllers/frame_loading_controller.d.ts +13 -12
- package/dist/controllers/frame_loading_controller.js +55 -48
- package/dist/controllers/frame_loading_controller.js.map +1 -1
- package/dist/controllers/highlight_controller.d.ts +5 -4
- package/dist/controllers/highlight_controller.js.map +1 -1
- package/dist/controllers/hover_card_controller.d.ts +4 -1
- package/dist/controllers/hover_card_controller.js +67 -61
- package/dist/controllers/hover_card_controller.js.map +1 -1
- package/dist/controllers/idle_controller.d.ts +6 -5
- package/dist/controllers/idle_controller.js +10 -6
- package/dist/controllers/idle_controller.js.map +1 -1
- package/dist/controllers/input_mask_controller.d.ts +31 -13
- package/dist/controllers/input_mask_controller.js +434 -24
- package/dist/controllers/input_mask_controller.js.map +1 -1
- package/dist/controllers/intersection_controller.js +3 -0
- package/dist/controllers/intersection_controller.js.map +1 -1
- package/dist/controllers/lazy_frame_controller.d.ts +3 -2
- package/dist/controllers/lazy_frame_controller.js +15 -3
- package/dist/controllers/lazy_frame_controller.js.map +1 -1
- package/dist/controllers/listbox_controller.d.ts +10 -7
- package/dist/controllers/listbox_controller.js +260 -79
- package/dist/controllers/listbox_controller.js.map +1 -1
- package/dist/controllers/local_time_controller.d.ts +8 -6
- package/dist/controllers/local_time_controller.js +48 -13
- package/dist/controllers/local_time_controller.js.map +1 -1
- package/dist/controllers/masonry_controller.js +11 -4
- package/dist/controllers/masonry_controller.js.map +1 -1
- package/dist/controllers/menu_controller.d.ts +24 -5
- package/dist/controllers/menu_controller.js +138 -82
- package/dist/controllers/menu_controller.js.map +1 -1
- package/dist/controllers/menubar_controller.d.ts +49 -7
- package/dist/controllers/menubar_controller.js +65 -19
- package/dist/controllers/menubar_controller.js.map +1 -1
- package/dist/controllers/meter_controller.d.ts +13 -20
- package/dist/controllers/meter_controller.js +270 -24
- package/dist/controllers/meter_controller.js.map +1 -1
- package/dist/controllers/multi_select_controller.d.ts +19 -16
- package/dist/controllers/multi_select_controller.js +272 -95
- package/dist/controllers/multi_select_controller.js.map +1 -1
- package/dist/controllers/navigation_menu_controller.d.ts +19 -5
- package/dist/controllers/navigation_menu_controller.js +67 -19
- package/dist/controllers/navigation_menu_controller.js.map +1 -1
- package/dist/controllers/nested_form_controller.js +98 -64
- package/dist/controllers/nested_form_controller.js.map +1 -1
- package/dist/controllers/network_status_controller.js +70 -52
- package/dist/controllers/network_status_controller.js.map +1 -1
- package/dist/controllers/number_input_controller.d.ts +24 -6
- package/dist/controllers/number_input_controller.js +344 -94
- 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 +29 -11
- package/dist/controllers/optimistic_controller.js.map +1 -1
- package/dist/controllers/otp_controller.d.ts +35 -4
- package/dist/controllers/otp_controller.js +502 -104
- package/dist/controllers/otp_controller.js.map +1 -1
- package/dist/controllers/overflow_indicator_controller.js +6 -0
- package/dist/controllers/overflow_indicator_controller.js.map +1 -1
- package/dist/controllers/overflow_menu_controller.d.ts +10 -9
- package/dist/controllers/overflow_menu_controller.js +136 -21
- package/dist/controllers/overflow_menu_controller.js.map +1 -1
- package/dist/controllers/pagination_controller.d.ts +3 -2
- package/dist/controllers/pagination_controller.js +47 -14
- package/dist/controllers/pagination_controller.js.map +1 -1
- package/dist/controllers/password_reveal_controller.d.ts +5 -4
- package/dist/controllers/password_reveal_controller.js +52 -49
- package/dist/controllers/password_reveal_controller.js.map +1 -1
- package/dist/controllers/password_strength_controller.d.ts +1 -1
- package/dist/controllers/password_strength_controller.js +13 -6
- package/dist/controllers/password_strength_controller.js.map +1 -1
- package/dist/controllers/persist_controller.js +48 -128
- package/dist/controllers/persist_controller.js.map +1 -1
- package/dist/controllers/pointer_drag_controller.d.ts +20 -8
- package/dist/controllers/pointer_drag_controller.js +255 -24
- package/dist/controllers/pointer_drag_controller.js.map +1 -1
- package/dist/controllers/popover_controller.d.ts +9 -5
- package/dist/controllers/popover_controller.js +91 -65
- package/dist/controllers/popover_controller.js.map +1 -1
- package/dist/controllers/portal_controller.js +6 -0
- package/dist/controllers/portal_controller.js.map +1 -1
- package/dist/controllers/preview_guard_controller.js +14 -3
- package/dist/controllers/preview_guard_controller.js.map +1 -1
- package/dist/controllers/progress_controller.d.ts +9 -19
- package/dist/controllers/progress_controller.js +271 -27
- package/dist/controllers/progress_controller.js.map +1 -1
- package/dist/controllers/radio_group_controller.d.ts +11 -8
- package/dist/controllers/radio_group_controller.js +167 -80
- package/dist/controllers/radio_group_controller.js.map +1 -1
- package/dist/controllers/range_slider_controller.d.ts +4 -3
- package/dist/controllers/range_slider_controller.js +27 -7
- package/dist/controllers/range_slider_controller.js.map +1 -1
- package/dist/controllers/rating_controller.js +93 -57
- package/dist/controllers/rating_controller.js.map +1 -1
- package/dist/controllers/read_more_controller.js +10 -6
- package/dist/controllers/read_more_controller.js.map +1 -1
- package/dist/controllers/reading_progress_controller.js +22 -5
- package/dist/controllers/reading_progress_controller.js.map +1 -1
- package/dist/controllers/relative_time_controller.d.ts +4 -4
- package/dist/controllers/relative_time_controller.js +75 -11
- package/dist/controllers/relative_time_controller.js.map +1 -1
- package/dist/controllers/reset_on_restore_controller.d.ts +3 -3
- package/dist/controllers/reset_on_restore_controller.js +6 -0
- package/dist/controllers/reset_on_restore_controller.js.map +1 -1
- package/dist/controllers/resizable_controller.d.ts +3 -0
- package/dist/controllers/resizable_controller.js +55 -22
- package/dist/controllers/resizable_controller.js.map +1 -1
- package/dist/controllers/roving_controller.d.ts +3 -3
- package/dist/controllers/roving_controller.js +10 -4
- package/dist/controllers/roving_controller.js.map +1 -1
- package/dist/controllers/scroll_area_controller.js +129 -88
- 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 -2
- package/dist/controllers/scroll_restore_controller.js.map +1 -1
- package/dist/controllers/scroll_visibility_controller.js +93 -60
- package/dist/controllers/scroll_visibility_controller.js.map +1 -1
- package/dist/controllers/scrollspy_controller.js +11 -5
- package/dist/controllers/scrollspy_controller.js.map +1 -1
- package/dist/controllers/separator_controller.d.ts +1 -1
- package/dist/controllers/separator_controller.js +59 -43
- package/dist/controllers/separator_controller.js.map +1 -1
- package/dist/controllers/sidebar_controller.d.ts +1 -1
- package/dist/controllers/sidebar_controller.js +150 -122
- package/dist/controllers/sidebar_controller.js.map +1 -1
- package/dist/controllers/skeleton_controller.js +55 -48
- package/dist/controllers/skeleton_controller.js.map +1 -1
- package/dist/controllers/slider_controller.d.ts +2 -1
- package/dist/controllers/slider_controller.js +27 -6
- package/dist/controllers/slider_controller.js.map +1 -1
- package/dist/controllers/smart_sticky_header_controller.d.ts +1 -1
- package/dist/controllers/smart_sticky_header_controller.js +13 -5
- 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 +27 -14
- package/dist/controllers/sortable_controller.js.map +1 -1
- package/dist/controllers/spinner_controller.js +55 -48
- package/dist/controllers/spinner_controller.js.map +1 -1
- package/dist/controllers/step_indicator_controller.d.ts +4 -4
- package/dist/controllers/step_indicator_controller.js +6 -0
- package/dist/controllers/step_indicator_controller.js.map +1 -1
- package/dist/controllers/stepper_controller.d.ts +2 -3
- package/dist/controllers/stepper_controller.js +6 -0
- package/dist/controllers/stepper_controller.js.map +1 -1
- package/dist/controllers/stick_to_bottom_controller.d.ts +3 -1
- package/dist/controllers/stick_to_bottom_controller.js +19 -8
- package/dist/controllers/stick_to_bottom_controller.js.map +1 -1
- package/dist/controllers/sticky_observer_controller.js +49 -43
- package/dist/controllers/sticky_observer_controller.js.map +1 -1
- package/dist/controllers/submit_once_controller.d.ts +2 -1
- package/dist/controllers/submit_once_controller.js +145 -85
- package/dist/controllers/submit_once_controller.js.map +1 -1
- package/dist/controllers/switch_controller.d.ts +7 -4
- package/dist/controllers/switch_controller.js +172 -28
- package/dist/controllers/switch_controller.js.map +1 -1
- package/dist/controllers/tabs_controller.d.ts +7 -4
- package/dist/controllers/tabs_controller.js +6 -1
- package/dist/controllers/tabs_controller.js.map +1 -1
- package/dist/controllers/tags_input_controller.d.ts +4 -3
- package/dist/controllers/tags_input_controller.js +157 -28
- package/dist/controllers/tags_input_controller.js.map +1 -1
- package/dist/controllers/textarea_autosize_controller.d.ts +1 -1
- package/dist/controllers/textarea_autosize_controller.js +40 -19
- package/dist/controllers/textarea_autosize_controller.js.map +1 -1
- package/dist/controllers/theme_controller.d.ts +3 -2
- package/dist/controllers/theme_controller.js +10 -4
- package/dist/controllers/theme_controller.js.map +1 -1
- package/dist/controllers/time_picker_controller.d.ts +38 -5
- package/dist/controllers/time_picker_controller.js +192 -54
- package/dist/controllers/time_picker_controller.js.map +1 -1
- package/dist/controllers/toast_controller.d.ts +4 -5
- package/dist/controllers/toast_controller.js +58 -27
- package/dist/controllers/toast_controller.js.map +1 -1
- package/dist/controllers/toggle_group_controller.d.ts +2 -3
- package/dist/controllers/toggle_group_controller.js +158 -56
- 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 +150 -21
- package/dist/controllers/toolbar_controller.js.map +1 -1
- package/dist/controllers/tooltip_controller.d.ts +4 -1
- package/dist/controllers/tooltip_controller.js.map +1 -1
- package/dist/controllers/transition_controller.js.map +1 -1
- package/dist/controllers/tree_view_controller.d.ts +1 -1
- package/dist/controllers/tree_view_controller.js +134 -25
- package/dist/controllers/tree_view_controller.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +2515 -1315
- package/dist/index.js.map +1 -1
- package/dist/inspector/cli.d.ts +25 -12
- package/dist/inspector/cli.js +21 -3
- package/dist/inspector/cli.js.map +1 -1
- package/dist/inspector/cli_bin.d.ts +1 -1
- package/dist/inspector/cli_bin.js +62 -8
- package/dist/inspector/cli_bin.js.map +1 -1
- package/dist/inspector/examples.json +13 -13
- package/dist/inspector/manifest.json +19 -5
- package/dist/positioning/index.d.ts +9 -8
- package/dist/positioning/index.js +6 -0
- package/dist/positioning/index.js.map +1 -1
- package/package.json +11 -10
|
@@ -6,7 +6,8 @@ import { Controller } from '@hotwired/stimulus';
|
|
|
6
6
|
* Markup contract (identifier: `stimeo--context-menu`):
|
|
7
7
|
* <div data-controller="stimeo--context-menu">
|
|
8
8
|
* <div data-stimeo--context-menu-target="region" tabindex="0"
|
|
9
|
-
*
|
|
9
|
+
* role="group" aria-label="Files"
|
|
10
|
+
* aria-keyshortcuts="Shift+F10" aria-controls="ctx"
|
|
10
11
|
* data-action="contextmenu->stimeo--context-menu#open
|
|
11
12
|
* keydown->stimeo--context-menu#onRegionKeydown">…</div>
|
|
12
13
|
* <ul id="ctx" role="menu" data-stimeo--context-menu-target="menu" hidden>
|
|
@@ -32,12 +33,25 @@ import { Controller } from '@hotwired/stimulus';
|
|
|
32
33
|
* required). Viewport-edge flip/shift is delegated to the opt-in
|
|
33
34
|
* `stimeo-ui/positioning` module, which this controller never imports.
|
|
34
35
|
*
|
|
36
|
+
* The region's role and name are the author's: a `role="group"` with
|
|
37
|
+
* `aria-label`, or an element that has a role of its own (a table row, a list
|
|
38
|
+
* item, a button), chosen to match what the region holds. The controller writes
|
|
39
|
+
* no role. The author also points `aria-controls` at the menu and advertises the
|
|
40
|
+
* opening key with `aria-keyshortcuts="Shift+F10"`. The region carries no
|
|
41
|
+
* `aria-haspopup`, whatever its role. On a role that supports it, such as a
|
|
42
|
+
* button, the attribute conveys what ARIA 1.2's note says its visual
|
|
43
|
+
* counterparts, such as a downward-pointing triangle, signal: that activating
|
|
44
|
+
* the control (a click, `Enter`) displays a popup. This menu opens on a
|
|
45
|
+
* `contextmenu` event or the `Shift+F10` / `ContextMenu` key instead, so the
|
|
46
|
+
* attribute would point to the wrong gesture. On a role that does not, such as
|
|
47
|
+
* `generic`, `group`, `row` or `listitem`, it would be a global use of the
|
|
48
|
+
* attribute, which ARIA 1.2 deprecates.
|
|
49
|
+
*
|
|
35
50
|
* Open state is exposed on the region as `data-state` (`open`/`closed`) — a CSS
|
|
36
|
-
* hook, not an ARIA one. `aria-expanded` is deliberately *not* set on the region
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* `role="menu"`.
|
|
51
|
+
* hook, not an ARIA one. `aria-expanded` is deliberately *not* set on the region:
|
|
52
|
+
* the role is the author's, and ARIA 1.2 lists neither `generic` nor `group`
|
|
53
|
+
* among the roles that support that state. Assistive tech perceives the open
|
|
54
|
+
* state when focus moves into the `role="menu"`.
|
|
41
55
|
*
|
|
42
56
|
* Behavior provided:
|
|
43
57
|
* - `contextmenu` on the region suppresses the browser menu and opens this one at
|
|
@@ -45,8 +59,17 @@ import { Controller } from '@hotwired/stimulus';
|
|
|
45
59
|
* - On open, focus moves to the first item; the region's `data-state` syncs.
|
|
46
60
|
* - Roving focus inside the menu: `ArrowUp`/`ArrowDown` (wrapping), `Home`/`End`.
|
|
47
61
|
* - Activating an enabled item (click / native `Enter`/`Space` on the button)
|
|
48
|
-
* closes the menu and restores focus to the region. `
|
|
49
|
-
*
|
|
62
|
+
* closes the menu and restores focus to the region. An item that is `hidden`,
|
|
63
|
+
* natively `disabled`, or `aria-disabled="true"` itself or through an ancestor
|
|
64
|
+
* is not activated on any path, and a click on an `aria-disabled` one is also
|
|
65
|
+
* stopped, in a capture listener on the controller element, before the click
|
|
66
|
+
* handlers inside that element run. Items can nest, and an event is
|
|
67
|
+
* refused when any item holding its target refuses. A click is judged once, in
|
|
68
|
+
* that capture pass, so a consumer handler that disables the item while the
|
|
69
|
+
* click runs does not take back the activation. The verdict holds only for an
|
|
70
|
+
* item that held the click's target when it was taken: an item it was not taken
|
|
71
|
+
* for — a handler moved the target into another one — is judged when
|
|
72
|
+
* {@link activate} runs, as is any other event.
|
|
50
73
|
* - `Escape` closes and restores focus to the region. While open the menu is a
|
|
51
74
|
* layer on the shared `EscapeLayer` stack; it claims a press only while
|
|
52
75
|
* focus is inside the controller or fell to the body, so one keypress closes
|
|
@@ -66,10 +89,11 @@ import { Controller } from '@hotwired/stimulus';
|
|
|
66
89
|
* normalization in {@link connect}, a region or a menu that takes over, and
|
|
67
90
|
* {@link disconnect} are all silent.
|
|
68
91
|
*
|
|
69
|
-
* Roving focus skips `hidden` and natively `disabled` items. An
|
|
70
|
-
* `aria-disabled="true"`
|
|
71
|
-
* attribute precisely for controls that must remain
|
|
72
|
-
* activation is suppressed, so it announces itself and
|
|
92
|
+
* Roving focus skips `hidden` and natively `disabled` items. An item that
|
|
93
|
+
* `aria-disabled="true"` reaches, on the item or an ancestor, stays reachable by
|
|
94
|
+
* arrow keys — APG marks that attribute precisely for controls that must remain
|
|
95
|
+
* discoverable — while its activation is suppressed, so it announces itself and
|
|
96
|
+
* does nothing.
|
|
73
97
|
*/
|
|
74
98
|
declare class ContextMenuController extends Controller<HTMLElement> {
|
|
75
99
|
#private;
|
|
@@ -114,8 +138,19 @@ declare class ContextMenuController extends Controller<HTMLElement> {
|
|
|
114
138
|
onRegionKeydown(event: KeyboardEvent): void;
|
|
115
139
|
/** Roving focus and closing keys inside the menu. */
|
|
116
140
|
onItemKeydown(event: KeyboardEvent): void;
|
|
117
|
-
/**
|
|
118
|
-
|
|
141
|
+
/**
|
|
142
|
+
* Closes after an item is activated and restores focus to the region. An event
|
|
143
|
+
* whose target lies in an item that is `hidden`, natively `disabled`, or
|
|
144
|
+
* `aria-disabled="true"` itself or through an ancestor does nothing: the menu
|
|
145
|
+
* stays open, nothing is dispatched and focus stays where it is. Every item
|
|
146
|
+
* holding the target counts, so an item nested in another one refuses for both,
|
|
147
|
+
* wherever the action is bound. A click is judged as its capture pass found the
|
|
148
|
+
* items, before the handlers inside the controller element ran, when the
|
|
149
|
+
* item this resolves was among them; an item that was not, and any other event, is
|
|
150
|
+
* judged when this runs.
|
|
151
|
+
* An event that resolves to no item, and a call with no event, always close.
|
|
152
|
+
*/
|
|
153
|
+
activate(event?: Event): void;
|
|
119
154
|
}
|
|
120
155
|
|
|
121
156
|
export { ContextMenuController };
|
|
@@ -22,21 +22,42 @@ function actionSource(source) {
|
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
function isAriaDisabled(element) {
|
|
26
|
+
for (let current = element; current; current = current.parentElement) {
|
|
27
|
+
if (current.getAttribute("aria-disabled") === "true") return true;
|
|
28
|
+
}
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
|
|
25
32
|
function isReservedArrowChord(event, allow = []) {
|
|
26
33
|
if (!event.key.startsWith("Arrow")) return false;
|
|
27
34
|
return event.altKey && !allow.includes("alt") || event.ctrlKey && !allow.includes("ctrl") || event.metaKey && !allow.includes("meta") || event.shiftKey && !allow.includes("shift");
|
|
28
35
|
}
|
|
36
|
+
function hasModifierChord(event) {
|
|
37
|
+
return event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function setAttributeIfChanged(element, name, value, beforeWrite) {
|
|
41
|
+
if (element.getAttribute(name) === value) return false;
|
|
42
|
+
if (value === null) element.removeAttribute(name);
|
|
43
|
+
else element.setAttribute(name, value);
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
29
46
|
|
|
30
47
|
function sharedRegistry(key, create) {
|
|
31
48
|
const symbol = Symbol.for(key);
|
|
32
49
|
const scope = globalThis;
|
|
33
50
|
const existing = scope[symbol];
|
|
34
51
|
if (existing !== void 0) return existing;
|
|
35
|
-
const
|
|
36
|
-
Object.defineProperty(globalThis, symbol, { value:
|
|
37
|
-
return
|
|
52
|
+
const registry2 = create();
|
|
53
|
+
Object.defineProperty(globalThis, symbol, { value: registry2 });
|
|
54
|
+
return registry2;
|
|
38
55
|
}
|
|
39
56
|
|
|
57
|
+
var registry = sharedRegistry(
|
|
58
|
+
"stimeo-ui.attribute-lease.registry.v1",
|
|
59
|
+
() => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
|
|
60
|
+
);
|
|
40
61
|
function isAttributeValue(value) {
|
|
41
62
|
return value === null || typeof value === "string";
|
|
42
63
|
}
|
|
@@ -53,24 +74,46 @@ function readLeaseRecord(element, record) {
|
|
|
53
74
|
return void 0;
|
|
54
75
|
}
|
|
55
76
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
);
|
|
77
|
+
function attributeStack(element, attribute) {
|
|
78
|
+
const byAttribute = registry.stacks.get(element) ?? /* @__PURE__ */ new Map();
|
|
79
|
+
registry.stacks.set(element, byAttribute);
|
|
80
|
+
const known = byAttribute.get(attribute);
|
|
81
|
+
if (known) return known;
|
|
82
|
+
const found = [];
|
|
83
|
+
for (const record of registry.names.get(attribute) ?? []) {
|
|
84
|
+
const read = readLeaseRecord(element, record);
|
|
85
|
+
if (read) found.push({ ...read, record });
|
|
86
|
+
}
|
|
87
|
+
const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
|
|
88
|
+
const stack = found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
|
|
89
|
+
lease: null,
|
|
90
|
+
record,
|
|
91
|
+
written,
|
|
92
|
+
original,
|
|
93
|
+
linked: linked && index > 0
|
|
94
|
+
}));
|
|
95
|
+
byAttribute.set(attribute, stack);
|
|
96
|
+
return stack;
|
|
97
|
+
}
|
|
98
|
+
function findHold(stack, lease, record) {
|
|
99
|
+
return stack.find((held) => held.lease === lease) ?? stack.find((held) => held.lease === null && held.record === record);
|
|
100
|
+
}
|
|
101
|
+
var AttributeLease = class {
|
|
61
102
|
#attribute;
|
|
62
103
|
#record;
|
|
63
104
|
#base;
|
|
105
|
+
#preserveAuthor;
|
|
64
106
|
#held = /* @__PURE__ */ new Set();
|
|
65
107
|
constructor(attribute, owner, options = {}) {
|
|
66
108
|
this.#attribute = attribute;
|
|
67
109
|
this.#record = `data-${owner}-${attribute}-lease`;
|
|
68
110
|
this.#base = options.base === true;
|
|
69
|
-
|
|
111
|
+
this.#preserveAuthor = options.preserveAuthor === true;
|
|
112
|
+
const names = registry.names;
|
|
70
113
|
names.set(attribute, (names.get(attribute) ?? /* @__PURE__ */ new Set()).add(this.#record));
|
|
71
114
|
}
|
|
72
115
|
write(element, value) {
|
|
73
|
-
const stack = this.#
|
|
116
|
+
const stack = attributeStack(element, this.#attribute);
|
|
74
117
|
const hold = this.#take(stack) ?? this.#acquire(element, stack);
|
|
75
118
|
this.#held.add(element);
|
|
76
119
|
const shows = !this.#covered(element, stack, hold);
|
|
@@ -80,8 +123,8 @@ var AttributeLease = class _AttributeLease {
|
|
|
80
123
|
}
|
|
81
124
|
return(element) {
|
|
82
125
|
const held = this.#held.delete(element);
|
|
83
|
-
const known =
|
|
84
|
-
const stack = held || known || element.hasAttribute(this.#record) ? this.#
|
|
126
|
+
const known = registry.stacks.get(element)?.has(this.#attribute);
|
|
127
|
+
const stack = held || known || element.hasAttribute(this.#record) ? attributeStack(element, this.#attribute) : [];
|
|
85
128
|
const hold = this.#take(stack);
|
|
86
129
|
if (!hold) return false;
|
|
87
130
|
const carries = element.getAttribute(this.#attribute) === hold.written;
|
|
@@ -99,31 +142,8 @@ var AttributeLease = class _AttributeLease {
|
|
|
99
142
|
returnAll() {
|
|
100
143
|
for (const element of Array.from(this.#held)) this.return(element);
|
|
101
144
|
}
|
|
102
|
-
#stack(element) {
|
|
103
|
-
const stacks = _AttributeLease.#registry.stacks;
|
|
104
|
-
const byAttribute = stacks.get(element) ?? /* @__PURE__ */ new Map();
|
|
105
|
-
stacks.set(element, byAttribute);
|
|
106
|
-
const stack = byAttribute.get(this.#attribute) ?? this.#seed(element);
|
|
107
|
-
byAttribute.set(this.#attribute, stack);
|
|
108
|
-
return stack;
|
|
109
|
-
}
|
|
110
|
-
#seed(element) {
|
|
111
|
-
const found = [];
|
|
112
|
-
for (const record of _AttributeLease.#registry.names.get(this.#attribute) ?? []) {
|
|
113
|
-
const read = readLeaseRecord(element, record);
|
|
114
|
-
if (read) found.push({ ...read, record });
|
|
115
|
-
}
|
|
116
|
-
const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
|
|
117
|
-
return found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
|
|
118
|
-
lease: null,
|
|
119
|
-
record,
|
|
120
|
-
written,
|
|
121
|
-
original,
|
|
122
|
-
linked: linked && index > 0
|
|
123
|
-
}));
|
|
124
|
-
}
|
|
125
145
|
#take(stack) {
|
|
126
|
-
const hold = stack
|
|
146
|
+
const hold = findHold(stack, this, this.#record);
|
|
127
147
|
if (hold) hold.lease = this;
|
|
128
148
|
return hold;
|
|
129
149
|
}
|
|
@@ -132,7 +152,7 @@ var AttributeLease = class _AttributeLease {
|
|
|
132
152
|
const top = stack.at(-1);
|
|
133
153
|
const bottom = stack[0];
|
|
134
154
|
const over = top?.written === current ? top : void 0;
|
|
135
|
-
const from = this.#base ? bottom : over;
|
|
155
|
+
const from = this.#base ? this.#preserveAuthor && !stack.some((held) => held.written === current) ? void 0 : bottom : over;
|
|
136
156
|
const hold = {
|
|
137
157
|
lease: this,
|
|
138
158
|
record: this.#record,
|
|
@@ -162,15 +182,23 @@ var AttributeLease = class _AttributeLease {
|
|
|
162
182
|
);
|
|
163
183
|
});
|
|
164
184
|
for (const [name, recorded] of records) {
|
|
165
|
-
|
|
166
|
-
if (recorded === null) element.removeAttribute(name);
|
|
167
|
-
else element.setAttribute(name, recorded);
|
|
185
|
+
setAttributeIfChanged(element, name, recorded);
|
|
168
186
|
}
|
|
169
187
|
}
|
|
170
188
|
#reflect(element, value) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
189
|
+
setAttributeIfChanged(element, this.#attribute, value);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
var ClickVerdicts = class {
|
|
194
|
+
#verdicts = /* @__PURE__ */ new WeakMap();
|
|
195
|
+
record(event, entries, refused) {
|
|
196
|
+
this.#verdicts.set(event, { entries, refused });
|
|
197
|
+
}
|
|
198
|
+
for(event, entry) {
|
|
199
|
+
const verdict = event && this.#verdicts.get(event);
|
|
200
|
+
if (!verdict?.entries.includes(entry)) return void 0;
|
|
201
|
+
return verdict.refused;
|
|
174
202
|
}
|
|
175
203
|
};
|
|
176
204
|
|
|
@@ -188,25 +216,25 @@ var EscapeLayer = class _EscapeLayer {
|
|
|
188
216
|
#active = null;
|
|
189
217
|
activate(ownerDocument = document, options) {
|
|
190
218
|
this.deactivate();
|
|
191
|
-
let
|
|
192
|
-
if (!
|
|
193
|
-
|
|
194
|
-
_EscapeLayer.#registries.set(ownerDocument,
|
|
195
|
-
ownerDocument.addEventListener("keydown",
|
|
219
|
+
let registry2 = _EscapeLayer.#registries.get(ownerDocument);
|
|
220
|
+
if (!registry2) {
|
|
221
|
+
registry2 = _EscapeLayer.#createRegistry();
|
|
222
|
+
_EscapeLayer.#registries.set(ownerDocument, registry2);
|
|
223
|
+
ownerDocument.addEventListener("keydown", registry2.onKeydown);
|
|
196
224
|
}
|
|
197
225
|
const entry = { onDismiss: options.onDismiss, claims: options.claims ?? null };
|
|
198
|
-
|
|
226
|
+
registry2.stack.push(entry);
|
|
199
227
|
this.#active = { document: ownerDocument, entry };
|
|
200
228
|
}
|
|
201
229
|
deactivate() {
|
|
202
230
|
const active = this.#active;
|
|
203
231
|
if (!active) return;
|
|
204
|
-
const
|
|
205
|
-
if (
|
|
206
|
-
const index =
|
|
207
|
-
if (index >= 0)
|
|
208
|
-
if (
|
|
209
|
-
active.document.removeEventListener("keydown",
|
|
232
|
+
const registry2 = _EscapeLayer.#registries.get(active.document);
|
|
233
|
+
if (registry2) {
|
|
234
|
+
const index = registry2.stack.lastIndexOf(active.entry);
|
|
235
|
+
if (index >= 0) registry2.stack.splice(index, 1);
|
|
236
|
+
if (registry2.stack.length === 0) {
|
|
237
|
+
active.document.removeEventListener("keydown", registry2.onKeydown);
|
|
210
238
|
_EscapeLayer.#registries.delete(active.document);
|
|
211
239
|
}
|
|
212
240
|
}
|
|
@@ -215,22 +243,22 @@ var EscapeLayer = class _EscapeLayer {
|
|
|
215
243
|
get ownsEscape() {
|
|
216
244
|
const active = this.#active;
|
|
217
245
|
if (!active) return false;
|
|
218
|
-
const
|
|
219
|
-
if (!
|
|
220
|
-
return _EscapeLayer.#resolveOwner(
|
|
246
|
+
const registry2 = _EscapeLayer.#registries.get(active.document);
|
|
247
|
+
if (!registry2) return false;
|
|
248
|
+
return _EscapeLayer.#resolveOwner(registry2.stack) === active.entry;
|
|
221
249
|
}
|
|
222
250
|
static #createRegistry() {
|
|
223
|
-
const
|
|
251
|
+
const registry2 = {
|
|
224
252
|
stack: [],
|
|
225
253
|
onKeydown: (event) => {
|
|
226
254
|
if (event.key !== "Escape" || event.defaultPrevented || event.isComposing) return;
|
|
227
|
-
const owner = _EscapeLayer.#resolveOwner(
|
|
255
|
+
const owner = _EscapeLayer.#resolveOwner(registry2.stack);
|
|
228
256
|
if (!owner) return;
|
|
229
257
|
event.preventDefault();
|
|
230
258
|
owner.onDismiss();
|
|
231
259
|
}
|
|
232
260
|
};
|
|
233
|
-
return
|
|
261
|
+
return registry2;
|
|
234
262
|
}
|
|
235
263
|
static #resolveOwner(stack) {
|
|
236
264
|
for (let index = stack.length - 1; index >= 0; index--) {
|
|
@@ -243,6 +271,29 @@ var EscapeLayer = class _EscapeLayer {
|
|
|
243
271
|
}
|
|
244
272
|
};
|
|
245
273
|
|
|
274
|
+
function ownerIndex(candidates, node) {
|
|
275
|
+
if (!(node instanceof Node)) return -1;
|
|
276
|
+
return candidates.findIndex((candidate) => candidate.contains(node));
|
|
277
|
+
}
|
|
278
|
+
function ownerOf(candidates, node) {
|
|
279
|
+
return candidates[ownerIndex(candidates, node)] ?? null;
|
|
280
|
+
}
|
|
281
|
+
function ownersOf(candidates, node) {
|
|
282
|
+
if (!(node instanceof Node)) return [];
|
|
283
|
+
return candidates.filter((candidate) => candidate.contains(node));
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
var ListenerSet = class {
|
|
287
|
+
#abort = new AbortController();
|
|
288
|
+
add(target, type, handler, options) {
|
|
289
|
+
target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });
|
|
290
|
+
}
|
|
291
|
+
dispose() {
|
|
292
|
+
this.#abort.abort();
|
|
293
|
+
this.#abort = new AbortController();
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
|
|
246
297
|
var TimerRegistry = class {
|
|
247
298
|
ids = /* @__PURE__ */ new Set();
|
|
248
299
|
clear(id) {
|
|
@@ -289,11 +340,13 @@ var ContextMenuController = class _ContextMenuController extends Controller {
|
|
|
289
340
|
#menu = null;
|
|
290
341
|
#connected = false;
|
|
291
342
|
#reporting = false;
|
|
343
|
+
#clickVerdicts = new ClickVerdicts();
|
|
344
|
+
#listeners = new ListenerSet();
|
|
292
345
|
connect() {
|
|
293
346
|
this.#closeMenu("api");
|
|
294
|
-
this.element
|
|
295
|
-
|
|
296
|
-
|
|
347
|
+
this.#listeners.add(this.element, "click", this.#onItemClickCapture, { capture: true });
|
|
348
|
+
this.#listeners.add(document, "click", this.#onOutsidePointer, { capture: true });
|
|
349
|
+
this.#listeners.add(document, "contextmenu", this.#onOutsidePointer, { capture: true });
|
|
297
350
|
this.#connected = true;
|
|
298
351
|
this.#reporting = true;
|
|
299
352
|
}
|
|
@@ -302,9 +355,7 @@ var ContextMenuController = class _ContextMenuController extends Controller {
|
|
|
302
355
|
this.#reporting = false;
|
|
303
356
|
this.#timers.clearAll();
|
|
304
357
|
this.#escapeLayer.deactivate();
|
|
305
|
-
this.
|
|
306
|
-
document.removeEventListener("click", this.#onOutsidePointer, true);
|
|
307
|
-
document.removeEventListener("contextmenu", this.#onOutsidePointer, true);
|
|
358
|
+
this.#listeners.dispose();
|
|
308
359
|
}
|
|
309
360
|
regionTargetConnected() {
|
|
310
361
|
if (this.#connected) this.#reflectRegion();
|
|
@@ -342,6 +393,7 @@ var ContextMenuController = class _ContextMenuController extends Controller {
|
|
|
342
393
|
onItemKeydown(event) {
|
|
343
394
|
if (event.defaultPrevented) return;
|
|
344
395
|
if (isReservedArrowChord(event)) return;
|
|
396
|
+
if ((event.key === "Home" || event.key === "End") && hasModifierChord(event)) return;
|
|
345
397
|
const items = this.#navigableItems;
|
|
346
398
|
const currentIndex = items.indexOf(event.currentTarget);
|
|
347
399
|
switch (event.key) {
|
|
@@ -373,9 +425,18 @@ var ContextMenuController = class _ContextMenuController extends Controller {
|
|
|
373
425
|
break;
|
|
374
426
|
}
|
|
375
427
|
}
|
|
376
|
-
activate() {
|
|
428
|
+
activate(event) {
|
|
429
|
+
const item = ownerOf(this.itemTargets, event?.target);
|
|
430
|
+
if (item !== null && this.#refuses(item, event)) return;
|
|
377
431
|
this.#closeAndRestore("select");
|
|
378
432
|
}
|
|
433
|
+
#refuses(item, event) {
|
|
434
|
+
const recorded = this.#clickVerdicts.for(event, item);
|
|
435
|
+
if (recorded !== void 0) return recorded;
|
|
436
|
+
return ownersOf(this.itemTargets, event?.target).some(
|
|
437
|
+
(owner) => this.#isActivationDisabled(owner)
|
|
438
|
+
);
|
|
439
|
+
}
|
|
379
440
|
#openAt(x, y, reason) {
|
|
380
441
|
if (!this.hasMenuTarget) return;
|
|
381
442
|
this.#timers.clearAll();
|
|
@@ -435,12 +496,13 @@ var ContextMenuController = class _ContextMenuController extends Controller {
|
|
|
435
496
|
if (this.#isOpen && !this.element.contains(event.target)) this.#closeMenu("outside");
|
|
436
497
|
};
|
|
437
498
|
#onItemClickCapture = (event) => {
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
499
|
+
const items = ownersOf(this.itemTargets, event.target);
|
|
500
|
+
this.#clickVerdicts.record(
|
|
501
|
+
event,
|
|
502
|
+
items,
|
|
503
|
+
items.some((item) => this.#isActivationDisabled(item))
|
|
442
504
|
);
|
|
443
|
-
if (!
|
|
505
|
+
if (!items.some((item) => isAriaDisabled(item))) return;
|
|
444
506
|
event.preventDefault();
|
|
445
507
|
event.stopImmediatePropagation();
|
|
446
508
|
};
|
|
@@ -451,6 +513,9 @@ var ContextMenuController = class _ContextMenuController extends Controller {
|
|
|
451
513
|
if (item.hasAttribute("hidden")) return false;
|
|
452
514
|
return !item.disabled;
|
|
453
515
|
}
|
|
516
|
+
#isActivationDisabled(item) {
|
|
517
|
+
return !this.#isNavigable(item) || isAriaDisabled(item);
|
|
518
|
+
}
|
|
454
519
|
get #isOpen() {
|
|
455
520
|
return this.hasMenuTarget && !this.menuTarget.hidden;
|
|
456
521
|
}
|