stimeo-ui 0.16.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +136 -0
- package/README.md +27 -11
- package/dist/cable/index.d.ts +88 -31
- package/dist/cable/index.js +384 -449
- package/dist/cable/index.js.map +1 -1
- package/dist/coerce-JtZVNG5h.d.ts +20 -0
- package/dist/controllers/accordion_controller.d.ts +4 -2
- package/dist/controllers/accordion_controller.js +174 -55
- package/dist/controllers/accordion_controller.js.map +1 -1
- package/dist/controllers/alert_dialog_controller.d.ts +12 -2
- package/dist/controllers/alert_dialog_controller.js +903 -235
- package/dist/controllers/alert_dialog_controller.js.map +1 -1
- package/dist/controllers/announcer_controller.d.ts +37 -5
- package/dist/controllers/announcer_controller.js +238 -205
- package/dist/controllers/announcer_controller.js.map +1 -1
- package/dist/controllers/aspect_ratio_controller.js +0 -10
- package/dist/controllers/aspect_ratio_controller.js.map +1 -1
- package/dist/controllers/auto_submit_controller.d.ts +30 -6
- package/dist/controllers/auto_submit_controller.js +414 -145
- package/dist/controllers/auto_submit_controller.js.map +1 -1
- package/dist/controllers/avatar_controller.js +185 -107
- package/dist/controllers/avatar_controller.js.map +1 -1
- package/dist/controllers/breadcrumb_controller.js +0 -130
- package/dist/controllers/breadcrumb_controller.js.map +1 -1
- package/dist/controllers/bulk_select_controller.d.ts +21 -3
- package/dist/controllers/bulk_select_controller.js +282 -58
- package/dist/controllers/bulk_select_controller.js.map +1 -1
- package/dist/controllers/calendar_controller.d.ts +38 -16
- package/dist/controllers/calendar_controller.js +228 -260
- package/dist/controllers/calendar_controller.js.map +1 -1
- package/dist/controllers/carousel_controller.d.ts +43 -12
- package/dist/controllers/carousel_controller.js +536 -436
- package/dist/controllers/carousel_controller.js.map +1 -1
- package/dist/controllers/character_counter_controller.d.ts +44 -7
- package/dist/controllers/character_counter_controller.js +493 -207
- package/dist/controllers/character_counter_controller.js.map +1 -1
- package/dist/controllers/checkbox_controller.d.ts +7 -2
- package/dist/controllers/checkbox_controller.js +38 -74
- package/dist/controllers/checkbox_controller.js.map +1 -1
- package/dist/controllers/clipboard_controller.d.ts +16 -5
- package/dist/controllers/clipboard_controller.js +261 -149
- package/dist/controllers/clipboard_controller.js.map +1 -1
- package/dist/controllers/collapsible_controller.d.ts +17 -5
- package/dist/controllers/collapsible_controller.js +304 -120
- package/dist/controllers/collapsible_controller.js.map +1 -1
- package/dist/controllers/color_picker_controller.d.ts +18 -6
- package/dist/controllers/color_picker_controller.js +178 -146
- package/dist/controllers/color_picker_controller.js.map +1 -1
- package/dist/controllers/combobox_controller.d.ts +24 -6
- package/dist/controllers/combobox_controller.js +522 -156
- package/dist/controllers/combobox_controller.js.map +1 -1
- package/dist/controllers/command_palette_controller.d.ts +51 -20
- package/dist/controllers/command_palette_controller.js +1156 -395
- package/dist/controllers/command_palette_controller.js.map +1 -1
- package/dist/controllers/conditional_fields_controller.d.ts +15 -2
- package/dist/controllers/conditional_fields_controller.js +300 -171
- package/dist/controllers/conditional_fields_controller.js.map +1 -1
- package/dist/controllers/confirm_controller.d.ts +49 -12
- package/dist/controllers/confirm_controller.js +980 -262
- package/dist/controllers/confirm_controller.js.map +1 -1
- package/dist/controllers/context_menu_controller.d.ts +80 -18
- package/dist/controllers/context_menu_controller.js +346 -153
- package/dist/controllers/context_menu_controller.js.map +1 -1
- package/dist/controllers/count_up_controller.d.ts +13 -1
- package/dist/controllers/count_up_controller.js +73 -21
- package/dist/controllers/count_up_controller.js.map +1 -1
- package/dist/controllers/countdown_controller.d.ts +47 -3
- package/dist/controllers/countdown_controller.js +281 -158
- package/dist/controllers/countdown_controller.js.map +1 -1
- package/dist/controllers/currency_input_controller.d.ts +93 -10
- package/dist/controllers/currency_input_controller.js +575 -225
- package/dist/controllers/currency_input_controller.js.map +1 -1
- package/dist/controllers/data_grid_controller.d.ts +25 -12
- package/dist/controllers/data_grid_controller.js +248 -214
- package/dist/controllers/data_grid_controller.js.map +1 -1
- package/dist/controllers/date_range_picker_controller.d.ts +42 -14
- package/dist/controllers/date_range_picker_controller.js +338 -235
- package/dist/controllers/date_range_picker_controller.js.map +1 -1
- package/dist/controllers/dialog_controller.d.ts +17 -6
- package/dist/controllers/dialog_controller.js +899 -237
- package/dist/controllers/dialog_controller.js.map +1 -1
- package/dist/controllers/direct_upload_controller.d.ts +25 -8
- package/dist/controllers/direct_upload_controller.js +97 -167
- package/dist/controllers/direct_upload_controller.js.map +1 -1
- package/dist/controllers/dirty_form_controller.d.ts +6 -1
- package/dist/controllers/dirty_form_controller.js +72 -69
- package/dist/controllers/dirty_form_controller.js.map +1 -1
- package/dist/controllers/dismissible_controller.d.ts +19 -0
- package/dist/controllers/dismissible_controller.js +196 -24
- package/dist/controllers/dismissible_controller.js.map +1 -1
- package/dist/controllers/drawer_controller.d.ts +39 -11
- package/dist/controllers/drawer_controller.js +974 -355
- package/dist/controllers/drawer_controller.js.map +1 -1
- package/dist/controllers/dropdown_controller.d.ts +31 -1
- package/dist/controllers/dropdown_controller.js +339 -96
- package/dist/controllers/dropdown_controller.js.map +1 -1
- package/dist/controllers/editable_controller.d.ts +12 -1
- package/dist/controllers/editable_controller.js +315 -88
- package/dist/controllers/editable_controller.js.map +1 -1
- package/dist/controllers/empty_state_controller.js +79 -58
- package/dist/controllers/empty_state_controller.js.map +1 -1
- package/dist/controllers/file_dropzone_controller.d.ts +63 -18
- package/dist/controllers/file_dropzone_controller.js +322 -211
- package/dist/controllers/file_dropzone_controller.js.map +1 -1
- package/dist/controllers/filter_controller.js +77 -42
- package/dist/controllers/filter_controller.js.map +1 -1
- package/dist/controllers/flash_controller.d.ts +35 -12
- package/dist/controllers/flash_controller.js +238 -347
- package/dist/controllers/flash_controller.js.map +1 -1
- package/dist/controllers/focus_controller.d.ts +15 -6
- package/dist/controllers/focus_controller.js +679 -240
- package/dist/controllers/focus_controller.js.map +1 -1
- package/dist/controllers/form_field_controller.js +156 -132
- package/dist/controllers/form_field_controller.js.map +1 -1
- package/dist/controllers/form_validation_controller.d.ts +3 -3
- package/dist/controllers/form_validation_controller.js +31 -97
- package/dist/controllers/form_validation_controller.js.map +1 -1
- package/dist/controllers/frame_loading_controller.d.ts +47 -14
- package/dist/controllers/frame_loading_controller.js +275 -217
- package/dist/controllers/frame_loading_controller.js.map +1 -1
- package/dist/controllers/highlight_controller.d.ts +27 -6
- package/dist/controllers/highlight_controller.js +107 -75
- package/dist/controllers/highlight_controller.js.map +1 -1
- package/dist/controllers/hover_card_controller.d.ts +60 -4
- package/dist/controllers/hover_card_controller.js +327 -130
- package/dist/controllers/hover_card_controller.js.map +1 -1
- package/dist/controllers/idle_controller.d.ts +48 -6
- package/dist/controllers/idle_controller.js +271 -101
- package/dist/controllers/idle_controller.js.map +1 -1
- package/dist/controllers/input_mask_controller.d.ts +30 -13
- package/dist/controllers/input_mask_controller.js +483 -97
- package/dist/controllers/input_mask_controller.js.map +1 -1
- package/dist/controllers/intersection_controller.d.ts +32 -13
- package/dist/controllers/intersection_controller.js +150 -106
- package/dist/controllers/intersection_controller.js.map +1 -1
- package/dist/controllers/lazy_frame_controller.d.ts +19 -2
- package/dist/controllers/lazy_frame_controller.js +24 -68
- package/dist/controllers/lazy_frame_controller.js.map +1 -1
- package/dist/controllers/listbox_controller.d.ts +44 -9
- package/dist/controllers/listbox_controller.js +523 -240
- package/dist/controllers/listbox_controller.js.map +1 -1
- package/dist/controllers/local_time_controller.d.ts +9 -7
- package/dist/controllers/local_time_controller.js +102 -77
- package/dist/controllers/local_time_controller.js.map +1 -1
- package/dist/controllers/masonry_controller.d.ts +11 -3
- package/dist/controllers/masonry_controller.js +80 -96
- package/dist/controllers/masonry_controller.js.map +1 -1
- package/dist/controllers/menu_controller.d.ts +55 -11
- package/dist/controllers/menu_controller.js +302 -188
- package/dist/controllers/menu_controller.js.map +1 -1
- package/dist/controllers/menubar_controller.d.ts +51 -9
- package/dist/controllers/menubar_controller.js +232 -345
- package/dist/controllers/menubar_controller.js.map +1 -1
- package/dist/controllers/meter_controller.d.ts +33 -20
- package/dist/controllers/meter_controller.js +417 -87
- package/dist/controllers/meter_controller.js.map +1 -1
- package/dist/controllers/multi_select_controller.d.ts +48 -18
- package/dist/controllers/multi_select_controller.js +785 -393
- package/dist/controllers/multi_select_controller.js.map +1 -1
- package/dist/controllers/navigation_menu_controller.d.ts +27 -6
- package/dist/controllers/navigation_menu_controller.js +190 -250
- package/dist/controllers/navigation_menu_controller.js.map +1 -1
- package/dist/controllers/nested_form_controller.d.ts +10 -0
- package/dist/controllers/nested_form_controller.js +396 -192
- package/dist/controllers/nested_form_controller.js.map +1 -1
- package/dist/controllers/network_status_controller.d.ts +23 -0
- package/dist/controllers/network_status_controller.js +268 -62
- package/dist/controllers/network_status_controller.js.map +1 -1
- package/dist/controllers/number_input_controller.d.ts +50 -8
- package/dist/controllers/number_input_controller.js +610 -303
- package/dist/controllers/number_input_controller.js.map +1 -1
- package/dist/controllers/optimistic_controller.d.ts +8 -5
- package/dist/controllers/optimistic_controller.js +45 -87
- package/dist/controllers/optimistic_controller.js.map +1 -1
- package/dist/controllers/otp_controller.d.ts +55 -8
- package/dist/controllers/otp_controller.js +658 -255
- package/dist/controllers/otp_controller.js.map +1 -1
- package/dist/controllers/overflow_indicator_controller.d.ts +5 -0
- package/dist/controllers/overflow_indicator_controller.js +122 -113
- package/dist/controllers/overflow_indicator_controller.js.map +1 -1
- package/dist/controllers/overflow_menu_controller.d.ts +58 -20
- package/dist/controllers/overflow_menu_controller.js +470 -295
- package/dist/controllers/overflow_menu_controller.js.map +1 -1
- package/dist/controllers/pagination_controller.d.ts +37 -7
- package/dist/controllers/pagination_controller.js +332 -123
- package/dist/controllers/pagination_controller.js.map +1 -1
- package/dist/controllers/password_reveal_controller.d.ts +46 -8
- package/dist/controllers/password_reveal_controller.js +392 -121
- package/dist/controllers/password_reveal_controller.js.map +1 -1
- package/dist/controllers/password_strength_controller.d.ts +15 -6
- package/dist/controllers/password_strength_controller.js +111 -158
- package/dist/controllers/password_strength_controller.js.map +1 -1
- package/dist/controllers/persist_controller.d.ts +11 -4
- package/dist/controllers/persist_controller.js +165 -111
- package/dist/controllers/persist_controller.js.map +1 -1
- package/dist/controllers/pointer_drag_controller.d.ts +35 -12
- package/dist/controllers/pointer_drag_controller.js +434 -188
- package/dist/controllers/pointer_drag_controller.js.map +1 -1
- package/dist/controllers/popover_controller.d.ts +41 -5
- package/dist/controllers/popover_controller.js +269 -113
- package/dist/controllers/popover_controller.js.map +1 -1
- package/dist/controllers/portal_controller.d.ts +44 -4
- package/dist/controllers/portal_controller.js +215 -76
- package/dist/controllers/portal_controller.js.map +1 -1
- package/dist/controllers/preview_guard_controller.d.ts +10 -4
- package/dist/controllers/preview_guard_controller.js +243 -116
- package/dist/controllers/preview_guard_controller.js.map +1 -1
- package/dist/controllers/progress_controller.d.ts +20 -19
- package/dist/controllers/progress_controller.js +391 -78
- package/dist/controllers/progress_controller.js.map +1 -1
- package/dist/controllers/radio_group_controller.d.ts +21 -9
- package/dist/controllers/radio_group_controller.js +278 -211
- package/dist/controllers/radio_group_controller.js.map +1 -1
- package/dist/controllers/range_slider_controller.d.ts +47 -6
- package/dist/controllers/range_slider_controller.js +220 -113
- package/dist/controllers/range_slider_controller.js.map +1 -1
- package/dist/controllers/rating_controller.d.ts +20 -4
- package/dist/controllers/rating_controller.js +458 -211
- package/dist/controllers/rating_controller.js.map +1 -1
- package/dist/controllers/read_more_controller.d.ts +2 -0
- package/dist/controllers/read_more_controller.js +138 -63
- package/dist/controllers/read_more_controller.js.map +1 -1
- package/dist/controllers/reading_progress_controller.d.ts +1 -1
- package/dist/controllers/reading_progress_controller.js +166 -137
- package/dist/controllers/reading_progress_controller.js.map +1 -1
- package/dist/controllers/relative_time_controller.d.ts +20 -6
- package/dist/controllers/relative_time_controller.js +211 -112
- package/dist/controllers/relative_time_controller.js.map +1 -1
- package/dist/controllers/reset_on_restore_controller.d.ts +85 -0
- package/dist/controllers/{reset_before_cache_controller.js → reset_on_restore_controller.js} +103 -38
- package/dist/controllers/reset_on_restore_controller.js.map +1 -0
- package/dist/controllers/resizable_controller.d.ts +31 -2
- package/dist/controllers/resizable_controller.js +299 -150
- package/dist/controllers/resizable_controller.js.map +1 -1
- package/dist/controllers/roving_controller.d.ts +3 -3
- package/dist/controllers/roving_controller.js +49 -88
- package/dist/controllers/roving_controller.js.map +1 -1
- package/dist/controllers/scroll_area_controller.d.ts +7 -3
- package/dist/controllers/scroll_area_controller.js +490 -246
- package/dist/controllers/scroll_area_controller.js.map +1 -1
- package/dist/controllers/scroll_restore_controller.d.ts +3 -3
- package/dist/controllers/scroll_restore_controller.js +14 -55
- package/dist/controllers/scroll_restore_controller.js.map +1 -1
- package/dist/controllers/scroll_visibility_controller.d.ts +28 -12
- package/dist/controllers/scroll_visibility_controller.js +432 -149
- package/dist/controllers/scroll_visibility_controller.js.map +1 -1
- package/dist/controllers/scrollspy_controller.d.ts +6 -1
- package/dist/controllers/scrollspy_controller.js +193 -248
- package/dist/controllers/scrollspy_controller.js.map +1 -1
- package/dist/controllers/separator_controller.d.ts +20 -5
- package/dist/controllers/separator_controller.js +285 -142
- package/dist/controllers/separator_controller.js.map +1 -1
- package/dist/controllers/sidebar_controller.d.ts +65 -8
- package/dist/controllers/sidebar_controller.js +1069 -404
- package/dist/controllers/sidebar_controller.js.map +1 -1
- package/dist/controllers/skeleton_controller.d.ts +23 -0
- package/dist/controllers/skeleton_controller.js +259 -101
- package/dist/controllers/skeleton_controller.js.map +1 -1
- package/dist/controllers/slider_controller.d.ts +29 -2
- package/dist/controllers/slider_controller.js +187 -86
- package/dist/controllers/slider_controller.js.map +1 -1
- package/dist/controllers/smart_sticky_header_controller.d.ts +22 -4
- package/dist/controllers/smart_sticky_header_controller.js +173 -66
- package/dist/controllers/smart_sticky_header_controller.js.map +1 -1
- package/dist/controllers/sortable_controller.d.ts +4 -4
- package/dist/controllers/sortable_controller.js +26 -125
- package/dist/controllers/sortable_controller.js.map +1 -1
- package/dist/controllers/spinner_controller.d.ts +39 -4
- package/dist/controllers/spinner_controller.js +288 -173
- package/dist/controllers/spinner_controller.js.map +1 -1
- package/dist/controllers/step_indicator_controller.d.ts +9 -4
- package/dist/controllers/step_indicator_controller.js +105 -46
- package/dist/controllers/step_indicator_controller.js.map +1 -1
- package/dist/controllers/stepper_controller.d.ts +14 -6
- package/dist/controllers/stepper_controller.js +120 -73
- package/dist/controllers/stepper_controller.js.map +1 -1
- package/dist/controllers/stick_to_bottom_controller.d.ts +9 -1
- package/dist/controllers/stick_to_bottom_controller.js +275 -140
- package/dist/controllers/stick_to_bottom_controller.js.map +1 -1
- package/dist/controllers/sticky_observer_controller.d.ts +11 -0
- package/dist/controllers/sticky_observer_controller.js +220 -49
- package/dist/controllers/sticky_observer_controller.js.map +1 -1
- package/dist/controllers/submit_once_controller.d.ts +24 -8
- package/dist/controllers/submit_once_controller.js +376 -227
- package/dist/controllers/submit_once_controller.js.map +1 -1
- package/dist/controllers/switch_controller.d.ts +18 -4
- package/dist/controllers/switch_controller.js +201 -84
- package/dist/controllers/switch_controller.js.map +1 -1
- package/dist/controllers/tabs_controller.d.ts +9 -6
- package/dist/controllers/tabs_controller.js +41 -30
- package/dist/controllers/tabs_controller.js.map +1 -1
- package/dist/controllers/tags_input_controller.d.ts +16 -3
- package/dist/controllers/tags_input_controller.js +293 -173
- package/dist/controllers/tags_input_controller.js.map +1 -1
- package/dist/controllers/textarea_autosize_controller.d.ts +11 -1
- package/dist/controllers/textarea_autosize_controller.js +108 -74
- package/dist/controllers/textarea_autosize_controller.js.map +1 -1
- package/dist/controllers/theme_controller.d.ts +24 -11
- package/dist/controllers/theme_controller.js +140 -116
- package/dist/controllers/theme_controller.js.map +1 -1
- package/dist/controllers/time_picker_controller.d.ts +55 -5
- package/dist/controllers/time_picker_controller.js +331 -127
- package/dist/controllers/time_picker_controller.js.map +1 -1
- package/dist/controllers/toast_controller.d.ts +40 -16
- package/dist/controllers/toast_controller.js +244 -324
- package/dist/controllers/toast_controller.js.map +1 -1
- package/dist/controllers/toggle_group_controller.d.ts +14 -6
- package/dist/controllers/toggle_group_controller.js +252 -191
- package/dist/controllers/toggle_group_controller.js.map +1 -1
- package/dist/controllers/toolbar_controller.d.ts +8 -6
- package/dist/controllers/toolbar_controller.js +219 -120
- package/dist/controllers/toolbar_controller.js.map +1 -1
- package/dist/controllers/tooltip_controller.d.ts +49 -4
- package/dist/controllers/tooltip_controller.js +158 -124
- package/dist/controllers/tooltip_controller.js.map +1 -1
- package/dist/controllers/transition_controller.d.ts +22 -4
- package/dist/controllers/transition_controller.js +123 -119
- package/dist/controllers/transition_controller.js.map +1 -1
- package/dist/controllers/tree_view_controller.d.ts +22 -12
- package/dist/controllers/tree_view_controller.js +283 -369
- package/dist/controllers/tree_view_controller.js.map +1 -1
- package/dist/index.d.ts +10 -5
- package/dist/index.js +8573 -10410
- package/dist/index.js.map +1 -1
- package/dist/inspector/cli.d.ts +38 -14
- package/dist/inspector/cli.js +108 -40
- package/dist/inspector/cli.js.map +1 -1
- package/dist/inspector/cli_bin.js +145 -64
- package/dist/inspector/cli_bin.js.map +1 -1
- package/dist/inspector/examples.json +20 -20
- package/dist/inspector/manifest.json +802 -101
- package/dist/positioning/index.d.ts +15 -7
- package/dist/positioning/index.js +154 -47
- package/dist/positioning/index.js.map +1 -1
- package/package.json +11 -10
- package/dist/controllers/reset_before_cache_controller.d.ts +0 -76
- package/dist/controllers/reset_before_cache_controller.js.map +0 -1
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { Controller } from '@hotwired/stimulus';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
function fillTemplate(template, values) {
|
|
4
|
+
return template.replace(/\{([a-zA-Z][a-zA-Z0-9]*)\}/g, (match, name) => {
|
|
5
|
+
const replacement = Object.hasOwn(values, name) ? values[name] : void 0;
|
|
6
|
+
return replacement === void 0 ? match : String(replacement);
|
|
7
|
+
});
|
|
8
|
+
}
|
|
4
9
|
|
|
5
|
-
// src/utils/announce.ts
|
|
6
10
|
function announce(message, options = {}) {
|
|
7
11
|
const text = message.trim();
|
|
8
12
|
if (text.length === 0) return;
|
|
@@ -12,41 +16,66 @@ function announce(message, options = {}) {
|
|
|
12
16
|
})
|
|
13
17
|
);
|
|
14
18
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
var NUMBER_BOUNDS = {
|
|
21
|
+
finite: { finite: true }};
|
|
22
|
+
function matchesNumberBounds(value, bounds) {
|
|
23
|
+
if (!Number.isFinite(value)) {
|
|
24
|
+
const direction = value === Infinity ? "positive" : value === -Infinity ? "negative" : null;
|
|
25
|
+
if (direction === null) return false;
|
|
26
|
+
if (bounds.allowInfinity !== "both" && bounds.allowInfinity !== direction) return false;
|
|
27
|
+
}
|
|
28
|
+
if (bounds.min !== void 0 && value < bounds.min) return false;
|
|
29
|
+
if (bounds.max !== void 0 && value > bounds.max) return false;
|
|
30
|
+
if (bounds.exclusiveMin !== void 0 && value <= bounds.exclusiveMin) return false;
|
|
31
|
+
if (bounds.integer && !Number.isInteger(value)) return false;
|
|
32
|
+
if (bounds.allowedValues !== void 0 && !bounds.allowedValues.includes(value)) return false;
|
|
33
|
+
return true;
|
|
20
34
|
}
|
|
21
35
|
|
|
22
|
-
|
|
36
|
+
function eventNumber(event) {
|
|
37
|
+
return toFiniteNumber(event.params?.amount ?? event.detail?.value);
|
|
38
|
+
}
|
|
23
39
|
function toFiniteNumber(raw) {
|
|
24
|
-
if (
|
|
25
|
-
|
|
40
|
+
if (typeof raw !== "number" && typeof raw !== "string") return null;
|
|
41
|
+
if (typeof raw === "string" && raw.trim().length === 0) return null;
|
|
42
|
+
const value = Number(raw);
|
|
26
43
|
return Number.isFinite(value) ? value : null;
|
|
27
44
|
}
|
|
45
|
+
function readNumber(raw, fallback, bounds) {
|
|
46
|
+
return matchesNumberBounds(raw, bounds) ? raw : fallback;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
var ListenerSet = class {
|
|
50
|
+
#abort = new AbortController();
|
|
51
|
+
add(target, type, handler, options) {
|
|
52
|
+
target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });
|
|
53
|
+
}
|
|
54
|
+
dispose() {
|
|
55
|
+
this.#abort.abort();
|
|
56
|
+
this.#abort = new AbortController();
|
|
57
|
+
}
|
|
58
|
+
};
|
|
28
59
|
|
|
29
|
-
// src/utils/microtask_coalescer.ts
|
|
30
60
|
var MicrotaskCoalescer = class {
|
|
31
61
|
#run;
|
|
32
62
|
#queued = false;
|
|
33
63
|
#active = false;
|
|
34
64
|
#generation = 0;
|
|
35
|
-
/** @param run - the single reconciliation pass, invoked at most once per batch. */
|
|
36
65
|
constructor(run) {
|
|
37
66
|
this.#run = run;
|
|
38
67
|
}
|
|
39
|
-
/** Opens the window in which {@link schedule} is honoured; call from `connect()`. */
|
|
40
68
|
activate() {
|
|
41
69
|
this.#active = true;
|
|
42
70
|
}
|
|
43
|
-
/** Closes the window and drops any pending pass; call from `disconnect()`. */
|
|
44
71
|
cancel() {
|
|
45
72
|
this.#active = false;
|
|
46
73
|
this.#queued = false;
|
|
47
74
|
this.#generation += 1;
|
|
48
75
|
}
|
|
49
|
-
|
|
76
|
+
get pending() {
|
|
77
|
+
return this.#queued;
|
|
78
|
+
}
|
|
50
79
|
schedule() {
|
|
51
80
|
if (!this.#active || this.#queued) return;
|
|
52
81
|
this.#queued = true;
|
|
@@ -59,11 +88,62 @@ var MicrotaskCoalescer = class {
|
|
|
59
88
|
}
|
|
60
89
|
};
|
|
61
90
|
|
|
62
|
-
|
|
91
|
+
var MorphRenderWatcher = class {
|
|
92
|
+
#listeners = new ListenerSet();
|
|
93
|
+
#pass;
|
|
94
|
+
#element = null;
|
|
95
|
+
#onMorph = () => this.#pass.schedule();
|
|
96
|
+
constructor(run) {
|
|
97
|
+
this.#pass = new MicrotaskCoalescer(run);
|
|
98
|
+
}
|
|
99
|
+
observe(element) {
|
|
100
|
+
if (this.#element === element) return;
|
|
101
|
+
this.disconnect();
|
|
102
|
+
this.#element = element;
|
|
103
|
+
this.#pass.activate();
|
|
104
|
+
this.#listeners.add(element, "turbo:morph-element", this.#onMorph);
|
|
105
|
+
}
|
|
106
|
+
schedule() {
|
|
107
|
+
this.#pass.schedule();
|
|
108
|
+
}
|
|
109
|
+
get pending() {
|
|
110
|
+
return this.#pass.pending;
|
|
111
|
+
}
|
|
112
|
+
disconnect() {
|
|
113
|
+
this.#listeners.dispose();
|
|
114
|
+
this.#pass.cancel();
|
|
115
|
+
this.#element = null;
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
var NumberValueReader = class {
|
|
120
|
+
#lastRejected = /* @__PURE__ */ new Map();
|
|
121
|
+
read(owner, name, raw, fallback, bounds) {
|
|
122
|
+
const resolved = readNumber(raw, fallback, bounds);
|
|
123
|
+
if (matchesNumberBounds(raw, bounds)) {
|
|
124
|
+
this.#lastRejected.delete(name);
|
|
125
|
+
return resolved;
|
|
126
|
+
}
|
|
127
|
+
const attribute = `data-${owner.identifier}-${name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}-value`;
|
|
128
|
+
const literal = owner.element.getAttribute(attribute);
|
|
129
|
+
if (literal === null) {
|
|
130
|
+
this.#lastRejected.delete(name);
|
|
131
|
+
return resolved;
|
|
132
|
+
}
|
|
133
|
+
if (this.#lastRejected.get(name) !== literal) {
|
|
134
|
+
this.#lastRejected.set(name, literal);
|
|
135
|
+
console.warn(
|
|
136
|
+
`Stimeo UI: "${owner.identifier}" has an invalid number Value "${name}" declaration ${JSON.stringify(literal)}; using ${fallback}.`
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
return resolved;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
63
143
|
function rangeFraction(value, min, max) {
|
|
64
144
|
const span = max - min;
|
|
65
145
|
if (!(span > 0)) return 0;
|
|
66
|
-
const clamped =
|
|
146
|
+
const clamped = clampRange(value, min, max);
|
|
67
147
|
let fraction;
|
|
68
148
|
if (Number.isFinite(span)) {
|
|
69
149
|
fraction = (clamped - min) / span;
|
|
@@ -74,14 +154,254 @@ function rangeFraction(value, min, max) {
|
|
|
74
154
|
if (!Number.isFinite(fraction)) return 0;
|
|
75
155
|
return Math.min(1, Math.max(0, fraction));
|
|
76
156
|
}
|
|
157
|
+
function clampRange(value, min, max) {
|
|
158
|
+
return Math.min(max, Math.max(min, value));
|
|
159
|
+
}
|
|
77
160
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
161
|
+
function setAttributeIfChanged(element, name, value, beforeWrite) {
|
|
162
|
+
if (element.getAttribute(name) === value) return false;
|
|
163
|
+
if (value === null) element.removeAttribute(name);
|
|
164
|
+
else element.setAttribute(name, value);
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function sharedRegistry(key, create) {
|
|
169
|
+
const symbol = Symbol.for(key);
|
|
170
|
+
const scope = globalThis;
|
|
171
|
+
const existing = scope[symbol];
|
|
172
|
+
if (existing !== void 0) return existing;
|
|
173
|
+
const registry2 = create();
|
|
174
|
+
Object.defineProperty(globalThis, symbol, { value: registry2 });
|
|
175
|
+
return registry2;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
var registry = sharedRegistry(
|
|
179
|
+
"stimeo-ui.attribute-lease.registry.v1",
|
|
180
|
+
() => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
|
|
181
|
+
);
|
|
182
|
+
function isAttributeValue(value) {
|
|
183
|
+
return value === null || typeof value === "string";
|
|
184
|
+
}
|
|
185
|
+
function readLeaseRecord(element, record) {
|
|
186
|
+
try {
|
|
187
|
+
const parsed = JSON.parse(element.getAttribute(record) ?? "null");
|
|
188
|
+
if (!Array.isArray(parsed)) return void 0;
|
|
189
|
+
const [original, written, ...rest] = parsed;
|
|
190
|
+
const linked = rest[0] !== false;
|
|
191
|
+
const beneath = linked ? rest : rest.slice(1);
|
|
192
|
+
if (!beneath.every((under) => typeof under === "string")) return void 0;
|
|
193
|
+
return isAttributeValue(original) && isAttributeValue(written) ? { original, written, linked, beneath } : void 0;
|
|
194
|
+
} catch {
|
|
195
|
+
return void 0;
|
|
84
196
|
}
|
|
197
|
+
}
|
|
198
|
+
function attributeStack(element, attribute) {
|
|
199
|
+
const byAttribute = registry.stacks.get(element) ?? /* @__PURE__ */ new Map();
|
|
200
|
+
registry.stacks.set(element, byAttribute);
|
|
201
|
+
const known = byAttribute.get(attribute);
|
|
202
|
+
if (known) return known;
|
|
203
|
+
const found = [];
|
|
204
|
+
for (const record of registry.names.get(attribute) ?? []) {
|
|
205
|
+
const read = readLeaseRecord(element, record);
|
|
206
|
+
if (read) found.push({ ...read, record });
|
|
207
|
+
}
|
|
208
|
+
const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
|
|
209
|
+
const stack = found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
|
|
210
|
+
lease: null,
|
|
211
|
+
record,
|
|
212
|
+
written,
|
|
213
|
+
original,
|
|
214
|
+
linked: linked && index > 0
|
|
215
|
+
}));
|
|
216
|
+
byAttribute.set(attribute, stack);
|
|
217
|
+
return stack;
|
|
218
|
+
}
|
|
219
|
+
function findHold(stack, lease, record) {
|
|
220
|
+
return stack.find((held) => held.lease === lease) ?? stack.find((held) => held.lease === null && held.record === record);
|
|
221
|
+
}
|
|
222
|
+
function readAttributeLease(element, attribute, owner, lease, expected) {
|
|
223
|
+
const stack = attributeStack(element, attribute);
|
|
224
|
+
const hold = findHold(stack, lease, `data-${owner}-${attribute}-lease`);
|
|
225
|
+
const current = element.getAttribute(attribute);
|
|
226
|
+
const covering = [...stack].reverse().find((other) => other.written === current);
|
|
227
|
+
const original = (hold ?? covering)?.original;
|
|
228
|
+
const authored = original === void 0 ? current : original;
|
|
229
|
+
return {
|
|
230
|
+
original: authored,
|
|
231
|
+
allowed: hold ? current === hold.written || stack.slice(stack.indexOf(hold) + 1).some((above) => above.written === current) : authored === expected
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
var AttributeLease = class {
|
|
235
|
+
#attribute;
|
|
236
|
+
#record;
|
|
237
|
+
#base;
|
|
238
|
+
#preserveAuthor;
|
|
239
|
+
#held = /* @__PURE__ */ new Set();
|
|
240
|
+
constructor(attribute, owner, options = {}) {
|
|
241
|
+
this.#attribute = attribute;
|
|
242
|
+
this.#record = `data-${owner}-${attribute}-lease`;
|
|
243
|
+
this.#base = options.base === true;
|
|
244
|
+
this.#preserveAuthor = options.preserveAuthor === true;
|
|
245
|
+
const names = registry.names;
|
|
246
|
+
names.set(attribute, (names.get(attribute) ?? /* @__PURE__ */ new Set()).add(this.#record));
|
|
247
|
+
}
|
|
248
|
+
write(element, value) {
|
|
249
|
+
const stack = attributeStack(element, this.#attribute);
|
|
250
|
+
const hold = this.#take(stack) ?? this.#acquire(element, stack);
|
|
251
|
+
this.#held.add(element);
|
|
252
|
+
const shows = !this.#covered(element, stack, hold);
|
|
253
|
+
hold.written = value;
|
|
254
|
+
this.#mark(element, stack);
|
|
255
|
+
if (shows) this.#reflect(element, value);
|
|
256
|
+
}
|
|
257
|
+
return(element) {
|
|
258
|
+
const held = this.#held.delete(element);
|
|
259
|
+
const known = registry.stacks.get(element)?.has(this.#attribute);
|
|
260
|
+
const stack = held || known || element.hasAttribute(this.#record) ? attributeStack(element, this.#attribute) : [];
|
|
261
|
+
const hold = this.#take(stack);
|
|
262
|
+
if (!hold) return false;
|
|
263
|
+
const carries = element.getAttribute(this.#attribute) === hold.written;
|
|
264
|
+
const owns = carries && !this.#covered(element, stack, hold);
|
|
265
|
+
const index = stack.indexOf(hold);
|
|
266
|
+
stack.splice(index, 1);
|
|
267
|
+
const above = stack[index];
|
|
268
|
+
if (above) above.linked &&= hold.linked;
|
|
269
|
+
this.#mark(element, stack);
|
|
270
|
+
if (!owns) return true;
|
|
271
|
+
const below = hold.linked ? stack[index - 1] : void 0;
|
|
272
|
+
this.#reflect(element, below ? below.written : hold.original);
|
|
273
|
+
return true;
|
|
274
|
+
}
|
|
275
|
+
returnAll() {
|
|
276
|
+
for (const element of Array.from(this.#held)) this.return(element);
|
|
277
|
+
}
|
|
278
|
+
#take(stack) {
|
|
279
|
+
const hold = findHold(stack, this, this.#record);
|
|
280
|
+
if (hold) hold.lease = this;
|
|
281
|
+
return hold;
|
|
282
|
+
}
|
|
283
|
+
#acquire(element, stack) {
|
|
284
|
+
const current = element.getAttribute(this.#attribute);
|
|
285
|
+
const top = stack.at(-1);
|
|
286
|
+
const bottom = stack[0];
|
|
287
|
+
const over = top?.written === current ? top : void 0;
|
|
288
|
+
const from = this.#base ? this.#preserveAuthor && !stack.some((held) => held.written === current) ? void 0 : bottom : over;
|
|
289
|
+
const hold = {
|
|
290
|
+
lease: this,
|
|
291
|
+
record: this.#record,
|
|
292
|
+
written: current,
|
|
293
|
+
original: from ? from.original : current,
|
|
294
|
+
linked: !this.#base && over !== void 0
|
|
295
|
+
};
|
|
296
|
+
if (this.#base && bottom) {
|
|
297
|
+
bottom.linked = true;
|
|
298
|
+
stack.unshift(hold);
|
|
299
|
+
} else stack.push(hold);
|
|
300
|
+
return hold;
|
|
301
|
+
}
|
|
302
|
+
#covered(element, stack, hold) {
|
|
303
|
+
const current = element.getAttribute(this.#attribute);
|
|
304
|
+
return stack.slice(stack.indexOf(hold) + 1).some((above) => above.written === current);
|
|
305
|
+
}
|
|
306
|
+
#mark(element, stack) {
|
|
307
|
+
const records = /* @__PURE__ */ new Map([[this.#record, null]]);
|
|
308
|
+
stack.forEach((hold, index) => {
|
|
309
|
+
const names = stack.slice(0, index).map((under) => under.record);
|
|
310
|
+
const beneath = [...new Set(names.reverse())].filter((name) => name !== hold.record);
|
|
311
|
+
const marker = hold.linked || beneath.length === 0 ? [] : [false];
|
|
312
|
+
records.set(
|
|
313
|
+
hold.record,
|
|
314
|
+
hold.written === hold.original && beneath.length === 0 && index === stack.length - 1 ? null : JSON.stringify([hold.original, hold.written, ...marker, ...beneath])
|
|
315
|
+
);
|
|
316
|
+
});
|
|
317
|
+
for (const [name, recorded] of records) {
|
|
318
|
+
setAttributeIfChanged(element, name, recorded);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
#reflect(element, value) {
|
|
322
|
+
setAttributeIfChanged(element, this.#attribute, value);
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
var TemplateAttributeLease = class {
|
|
327
|
+
#lease;
|
|
328
|
+
#record;
|
|
329
|
+
#attribute;
|
|
330
|
+
#owner;
|
|
331
|
+
#states = /* @__PURE__ */ new WeakMap();
|
|
332
|
+
constructor(attribute, owner) {
|
|
333
|
+
this.#attribute = attribute;
|
|
334
|
+
this.#owner = owner;
|
|
335
|
+
this.#lease = new AttributeLease(attribute, owner, { base: true, preserveAuthor: true });
|
|
336
|
+
this.#record = `data-${owner}-${attribute}-template`;
|
|
337
|
+
}
|
|
338
|
+
render(element, source, value) {
|
|
339
|
+
let state = this.#read(element);
|
|
340
|
+
if (!state && source.length === 0) {
|
|
341
|
+
this.#lease.return(element);
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (!state || state.source !== source) {
|
|
345
|
+
this.#lease.return(element);
|
|
346
|
+
state = { source, expected: this.#view(element, null).original, yielded: false };
|
|
347
|
+
}
|
|
348
|
+
if (source.length === 0 || value === null) {
|
|
349
|
+
this.#states.set(element, state);
|
|
350
|
+
this.release(element);
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
if (!state.yielded && this.#continues(element, state)) {
|
|
354
|
+
this.#lease.write(element, value);
|
|
355
|
+
state.expected = value;
|
|
356
|
+
} else {
|
|
357
|
+
state.yielded = true;
|
|
358
|
+
this.#lease.return(element);
|
|
359
|
+
}
|
|
360
|
+
this.#mark(element, state);
|
|
361
|
+
}
|
|
362
|
+
release(element) {
|
|
363
|
+
const state = this.#read(element);
|
|
364
|
+
if (state && !state.yielded) {
|
|
365
|
+
state.yielded = !this.#continues(element, state);
|
|
366
|
+
if (!state.yielded) state.expected = this.#view(element, null).original;
|
|
367
|
+
}
|
|
368
|
+
this.#lease.return(element);
|
|
369
|
+
if (state) this.#mark(element, state);
|
|
370
|
+
}
|
|
371
|
+
#continues(element, state) {
|
|
372
|
+
const view = this.#view(element, state.expected);
|
|
373
|
+
return view.allowed || !element.hasAttribute(this.#record) && element.getAttribute(this.#attribute) === view.original;
|
|
374
|
+
}
|
|
375
|
+
#view(element, expected) {
|
|
376
|
+
return readAttributeLease(element, this.#attribute, this.#owner, this.#lease, expected);
|
|
377
|
+
}
|
|
378
|
+
#read(element) {
|
|
379
|
+
const live = this.#states.get(element);
|
|
380
|
+
if (live) return live;
|
|
381
|
+
try {
|
|
382
|
+
const parsed = JSON.parse(element.getAttribute(this.#record) ?? "null");
|
|
383
|
+
if (!Array.isArray(parsed) || parsed.length !== 3) return void 0;
|
|
384
|
+
const [source, expected, yielded] = parsed;
|
|
385
|
+
if (typeof source !== "string" || expected !== null && typeof expected !== "string" || typeof yielded !== "boolean")
|
|
386
|
+
return void 0;
|
|
387
|
+
return { source, expected, yielded };
|
|
388
|
+
} catch {
|
|
389
|
+
return void 0;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
#mark(element, state) {
|
|
393
|
+
this.#states.set(element, state);
|
|
394
|
+
setAttributeIfChanged(
|
|
395
|
+
element,
|
|
396
|
+
this.#record,
|
|
397
|
+
JSON.stringify([state.source, state.expected, state.yielded])
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
var MeterController = class _MeterController extends Controller {
|
|
403
|
+
#numbers = new NumberValueReader();
|
|
404
|
+
#valueText = new TemplateAttributeLease("aria-valuetext", this.identifier);
|
|
85
405
|
static targets = ["bar"];
|
|
86
406
|
static values = {
|
|
87
407
|
announceText: { type: String, default: "" },
|
|
@@ -93,129 +413,139 @@ var MeterController = class extends Controller {
|
|
|
93
413
|
optimum: { type: Number, default: 0 },
|
|
94
414
|
valueText: { type: String, default: "" }
|
|
95
415
|
};
|
|
416
|
+
static valueConstraints = {
|
|
417
|
+
value: NUMBER_BOUNDS.finite,
|
|
418
|
+
min: NUMBER_BOUNDS.finite,
|
|
419
|
+
max: NUMBER_BOUNDS.finite,
|
|
420
|
+
low: NUMBER_BOUNDS.finite,
|
|
421
|
+
high: NUMBER_BOUNDS.finite,
|
|
422
|
+
optimum: NUMBER_BOUNDS.finite
|
|
423
|
+
};
|
|
96
424
|
static actions = ["setValue"];
|
|
97
425
|
static events = ["change"];
|
|
98
|
-
|
|
99
|
-
* Collapses a morph that swaps several render inputs at once into one repaint.
|
|
100
|
-
* A single update usually rewrites the whole set, and each Value would otherwise
|
|
101
|
-
* repaint on its own.
|
|
102
|
-
*/
|
|
103
|
-
#repaint = new MicrotaskCoalescer(() => {
|
|
426
|
+
#repaint = new MorphRenderWatcher(() => {
|
|
104
427
|
this.#render();
|
|
105
428
|
});
|
|
106
|
-
|
|
107
|
-
#announcedState = null;
|
|
429
|
+
#shownState = null;
|
|
108
430
|
connect() {
|
|
109
|
-
this.#repaint.
|
|
431
|
+
this.#repaint.observe(this.element);
|
|
110
432
|
this.#render();
|
|
111
433
|
}
|
|
112
|
-
/** Closes the window in which a queued repaint may still run. */
|
|
113
434
|
disconnect() {
|
|
114
|
-
this.#repaint.
|
|
435
|
+
this.#repaint.disconnect();
|
|
436
|
+
this.#valueText.release(this.element);
|
|
115
437
|
}
|
|
116
|
-
/**
|
|
117
|
-
* Updates the measured value from an action param (`amount`) or a
|
|
118
|
-
* `detail.value` CustomEvent, syncs ARIA and `data-state`, and dispatches
|
|
119
|
-
* `change` with the value, ratio, and computed segment.
|
|
120
|
-
*/
|
|
121
438
|
setValue(event) {
|
|
122
|
-
const next =
|
|
439
|
+
const next = eventNumber(event);
|
|
123
440
|
if (next === null) return;
|
|
124
441
|
this.valueValue = this.#clamp(next);
|
|
442
|
+
const shown = this.#shownState;
|
|
125
443
|
const reading = this.#render();
|
|
126
444
|
this.dispatch("change", { detail: reading });
|
|
127
|
-
if (reading.state !==
|
|
128
|
-
this.#announcedState = reading.state;
|
|
445
|
+
if (reading.state !== shown) {
|
|
129
446
|
announce(
|
|
130
447
|
fillTemplate(this.announceTextValue, { state: reading.state, value: reading.value })
|
|
131
448
|
);
|
|
132
449
|
}
|
|
133
450
|
}
|
|
134
|
-
/** Repaints when application code (or a Turbo morph) changes `value` at runtime. */
|
|
135
451
|
valueValueChanged() {
|
|
136
452
|
this.#repaint.schedule();
|
|
137
453
|
}
|
|
138
|
-
/** Repaints when application code (or a Turbo morph) changes `min` at runtime. */
|
|
139
454
|
minValueChanged() {
|
|
140
455
|
this.#repaint.schedule();
|
|
141
456
|
}
|
|
142
|
-
/** Repaints when application code (or a Turbo morph) changes `max` at runtime. */
|
|
143
457
|
maxValueChanged() {
|
|
144
458
|
this.#repaint.schedule();
|
|
145
459
|
}
|
|
146
|
-
/** Repaints when application code (or a Turbo morph) changes `low` at runtime. */
|
|
147
460
|
lowValueChanged() {
|
|
148
461
|
this.#repaint.schedule();
|
|
149
462
|
}
|
|
150
|
-
/** Repaints when application code (or a Turbo morph) changes `high` at runtime. */
|
|
151
463
|
highValueChanged() {
|
|
152
464
|
this.#repaint.schedule();
|
|
153
465
|
}
|
|
154
|
-
/** Repaints when application code (or a Turbo morph) changes `valueText` at runtime. */
|
|
155
466
|
valueTextValueChanged() {
|
|
156
467
|
this.#repaint.schedule();
|
|
157
468
|
}
|
|
158
|
-
/** Clamps `raw` into the configured `[min, max]` range. */
|
|
159
469
|
#clamp(raw) {
|
|
160
|
-
return
|
|
470
|
+
return clampRange(raw, this.#safeMin, this.#safeMax);
|
|
161
471
|
}
|
|
162
|
-
/** Whether a threshold attribute is present (absent = no threshold). */
|
|
163
472
|
#hasThreshold(name) {
|
|
164
473
|
return this.element.hasAttribute(`data-${this.identifier}-${name}-value`);
|
|
165
474
|
}
|
|
166
|
-
/**
|
|
167
|
-
* Classifies `value` into a `low`/`medium`/`high` segment. Values at or below
|
|
168
|
-
* `low` are `low`; at or above `high` are `high`; otherwise `medium`. With
|
|
169
|
-
* neither threshold present, everything is `medium`.
|
|
170
|
-
*/
|
|
171
475
|
#stateOf(value) {
|
|
172
|
-
if (this.#hasThreshold("low") && value <= this
|
|
173
|
-
if (this.#hasThreshold("high") && value >= this
|
|
476
|
+
if (this.#hasThreshold("low") && value <= this.#safeLow) return "low";
|
|
477
|
+
if (this.#hasThreshold("high") && value >= this.#safeHigh) return "high";
|
|
174
478
|
return "medium";
|
|
175
479
|
}
|
|
176
|
-
/**
|
|
177
|
-
* Reflects value/range onto ARIA, the segment onto `data-state`, and the ratio.
|
|
178
|
-
* The reading is derived once and returned, so the `change` detail reports the
|
|
179
|
-
* same numbers the DOM just received.
|
|
180
|
-
*
|
|
181
|
-
* @stimeoRenderRoot
|
|
182
|
-
*/
|
|
183
480
|
#render() {
|
|
184
|
-
const value = this.#clamp(this
|
|
481
|
+
const value = this.#clamp(this.#safeValue);
|
|
185
482
|
const reading = {
|
|
186
483
|
value,
|
|
187
|
-
ratio: rangeFraction(value, this
|
|
484
|
+
ratio: rangeFraction(value, this.#safeMin, this.#safeMax),
|
|
188
485
|
state: this.#stateOf(value)
|
|
189
486
|
};
|
|
190
|
-
this.element.setAttribute("aria-valuemin", String(this
|
|
191
|
-
this.element.setAttribute("aria-valuemax", String(this
|
|
487
|
+
this.element.setAttribute("aria-valuemin", String(this.#safeMin));
|
|
488
|
+
this.element.setAttribute("aria-valuemax", String(this.#safeMax));
|
|
192
489
|
this.element.setAttribute("aria-valuenow", String(reading.value));
|
|
193
490
|
this.element.style.setProperty("--stimeo--meter-ratio", String(reading.ratio));
|
|
194
491
|
this.element.setAttribute("data-state", reading.state);
|
|
195
492
|
this.#applyValueText(reading);
|
|
493
|
+
this.#shownState = reading.state;
|
|
196
494
|
return reading;
|
|
197
495
|
}
|
|
198
|
-
/**
|
|
199
|
-
* Sets `aria-valuetext` from the consumer-provided template, substituting
|
|
200
|
-
* `{value}`, `{percent}`, and `{state}`. Kept i18n-neutral in the library.
|
|
201
|
-
* With no template the attribute belongs to the consumer, so only a text this
|
|
202
|
-
* controller wrote is taken back ({@link OWNED_VALUE_TEXT}).
|
|
203
|
-
*/
|
|
204
496
|
#applyValueText({ value, ratio, state }) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
497
|
+
this.#valueText.render(
|
|
498
|
+
this.element,
|
|
499
|
+
this.valueTextValue,
|
|
500
|
+
fillTemplate(this.valueTextValue, { value, percent: Math.round(ratio * 100), state })
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
get #safeValue() {
|
|
504
|
+
return this.#numbers.read(
|
|
505
|
+
this,
|
|
506
|
+
"value",
|
|
507
|
+
this.valueValue,
|
|
508
|
+
_MeterController.values.value.default,
|
|
509
|
+
_MeterController.valueConstraints.value
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
get #safeMin() {
|
|
513
|
+
return this.#numbers.read(
|
|
514
|
+
this,
|
|
515
|
+
"min",
|
|
516
|
+
this.minValue,
|
|
517
|
+
_MeterController.values.min.default,
|
|
518
|
+
_MeterController.valueConstraints.min
|
|
519
|
+
);
|
|
520
|
+
}
|
|
521
|
+
get #safeMax() {
|
|
522
|
+
return this.#numbers.read(
|
|
523
|
+
this,
|
|
524
|
+
"max",
|
|
525
|
+
this.maxValue,
|
|
526
|
+
_MeterController.values.max.default,
|
|
527
|
+
_MeterController.valueConstraints.max
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
get #safeLow() {
|
|
531
|
+
return this.#numbers.read(
|
|
532
|
+
this,
|
|
533
|
+
"low",
|
|
534
|
+
this.lowValue,
|
|
535
|
+
_MeterController.values.low.default,
|
|
536
|
+
_MeterController.valueConstraints.low
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
get #safeHigh() {
|
|
540
|
+
return this.#numbers.read(
|
|
541
|
+
this,
|
|
542
|
+
"high",
|
|
543
|
+
this.highValue,
|
|
544
|
+
_MeterController.values.high.default,
|
|
545
|
+
_MeterController.valueConstraints.high
|
|
546
|
+
);
|
|
216
547
|
}
|
|
217
548
|
};
|
|
218
549
|
|
|
219
550
|
export { MeterController };
|
|
220
|
-
//# sourceMappingURL=meter_controller.js.map
|
|
221
551
|
//# sourceMappingURL=meter_controller.js.map
|