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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +136 -0
- data/README.md +27 -11
- data/dist/cable/index.js +384 -449
- data/dist/controllers/accordion_controller.js +174 -55
- data/dist/controllers/alert_dialog_controller.js +903 -235
- data/dist/controllers/announcer_controller.js +238 -205
- data/dist/controllers/aspect_ratio_controller.js +0 -10
- data/dist/controllers/auto_submit_controller.js +414 -145
- data/dist/controllers/avatar_controller.js +185 -107
- data/dist/controllers/breadcrumb_controller.js +0 -130
- data/dist/controllers/bulk_select_controller.js +282 -58
- data/dist/controllers/calendar_controller.js +228 -260
- data/dist/controllers/carousel_controller.js +536 -436
- data/dist/controllers/character_counter_controller.js +493 -207
- data/dist/controllers/checkbox_controller.js +38 -74
- data/dist/controllers/clipboard_controller.js +261 -149
- data/dist/controllers/collapsible_controller.js +304 -120
- data/dist/controllers/color_picker_controller.js +178 -146
- data/dist/controllers/combobox_controller.js +522 -156
- data/dist/controllers/command_palette_controller.js +1156 -395
- data/dist/controllers/conditional_fields_controller.js +300 -171
- data/dist/controllers/confirm_controller.js +980 -262
- data/dist/controllers/context_menu_controller.js +346 -153
- data/dist/controllers/count_up_controller.js +73 -21
- data/dist/controllers/countdown_controller.js +281 -158
- data/dist/controllers/currency_input_controller.js +575 -225
- data/dist/controllers/data_grid_controller.js +248 -214
- data/dist/controllers/date_range_picker_controller.js +338 -235
- data/dist/controllers/dialog_controller.js +899 -237
- data/dist/controllers/direct_upload_controller.js +97 -167
- data/dist/controllers/dirty_form_controller.js +72 -69
- data/dist/controllers/dismissible_controller.js +196 -24
- data/dist/controllers/drawer_controller.js +974 -355
- data/dist/controllers/dropdown_controller.js +339 -96
- data/dist/controllers/editable_controller.js +315 -88
- data/dist/controllers/empty_state_controller.js +79 -58
- data/dist/controllers/file_dropzone_controller.js +322 -211
- data/dist/controllers/filter_controller.js +77 -42
- data/dist/controllers/flash_controller.js +238 -347
- data/dist/controllers/focus_controller.js +679 -240
- data/dist/controllers/form_field_controller.js +156 -132
- data/dist/controllers/form_validation_controller.js +31 -97
- data/dist/controllers/frame_loading_controller.js +275 -217
- data/dist/controllers/highlight_controller.js +107 -75
- data/dist/controllers/hover_card_controller.js +327 -130
- data/dist/controllers/idle_controller.js +271 -101
- data/dist/controllers/input_mask_controller.js +483 -97
- data/dist/controllers/intersection_controller.js +150 -106
- data/dist/controllers/lazy_frame_controller.js +24 -68
- data/dist/controllers/listbox_controller.js +523 -240
- data/dist/controllers/local_time_controller.js +102 -77
- data/dist/controllers/masonry_controller.js +80 -96
- data/dist/controllers/menu_controller.js +302 -188
- data/dist/controllers/menubar_controller.js +232 -345
- data/dist/controllers/meter_controller.js +417 -87
- data/dist/controllers/multi_select_controller.js +785 -393
- data/dist/controllers/navigation_menu_controller.js +190 -250
- data/dist/controllers/nested_form_controller.js +396 -192
- data/dist/controllers/network_status_controller.js +268 -62
- data/dist/controllers/number_input_controller.js +610 -303
- data/dist/controllers/optimistic_controller.js +45 -87
- data/dist/controllers/otp_controller.js +658 -255
- data/dist/controllers/overflow_indicator_controller.js +122 -113
- data/dist/controllers/overflow_menu_controller.js +470 -295
- data/dist/controllers/pagination_controller.js +332 -123
- data/dist/controllers/password_reveal_controller.js +392 -121
- data/dist/controllers/password_strength_controller.js +111 -158
- data/dist/controllers/persist_controller.js +165 -111
- data/dist/controllers/pointer_drag_controller.js +434 -188
- data/dist/controllers/popover_controller.js +269 -113
- data/dist/controllers/portal_controller.js +215 -76
- data/dist/controllers/preview_guard_controller.js +243 -116
- data/dist/controllers/progress_controller.js +391 -78
- data/dist/controllers/radio_group_controller.js +278 -211
- data/dist/controllers/range_slider_controller.js +220 -113
- data/dist/controllers/rating_controller.js +458 -211
- data/dist/controllers/read_more_controller.js +138 -63
- data/dist/controllers/reading_progress_controller.js +166 -137
- data/dist/controllers/relative_time_controller.js +211 -112
- data/dist/controllers/{reset_before_cache_controller.js → reset_on_restore_controller.js} +103 -38
- data/dist/controllers/resizable_controller.js +299 -150
- data/dist/controllers/roving_controller.js +49 -88
- data/dist/controllers/scroll_area_controller.js +490 -246
- data/dist/controllers/scroll_restore_controller.js +14 -55
- data/dist/controllers/scroll_visibility_controller.js +432 -149
- data/dist/controllers/scrollspy_controller.js +193 -248
- data/dist/controllers/separator_controller.js +285 -142
- data/dist/controllers/sidebar_controller.js +1069 -404
- data/dist/controllers/skeleton_controller.js +259 -101
- data/dist/controllers/slider_controller.js +187 -86
- data/dist/controllers/smart_sticky_header_controller.js +173 -66
- data/dist/controllers/sortable_controller.js +26 -125
- data/dist/controllers/spinner_controller.js +288 -173
- data/dist/controllers/step_indicator_controller.js +105 -46
- data/dist/controllers/stepper_controller.js +120 -73
- data/dist/controllers/stick_to_bottom_controller.js +275 -140
- data/dist/controllers/sticky_observer_controller.js +220 -49
- data/dist/controllers/submit_once_controller.js +376 -227
- data/dist/controllers/switch_controller.js +201 -84
- data/dist/controllers/tabs_controller.js +41 -30
- data/dist/controllers/tags_input_controller.js +293 -173
- data/dist/controllers/textarea_autosize_controller.js +108 -74
- data/dist/controllers/theme_controller.js +140 -116
- data/dist/controllers/time_picker_controller.js +331 -127
- data/dist/controllers/toast_controller.js +244 -324
- data/dist/controllers/toggle_group_controller.js +252 -191
- data/dist/controllers/toolbar_controller.js +219 -120
- data/dist/controllers/tooltip_controller.js +158 -124
- data/dist/controllers/transition_controller.js +123 -119
- data/dist/controllers/tree_view_controller.js +283 -369
- data/dist/index.js +8573 -10410
- data/dist/positioning/index.js +154 -47
- data/lib/generators/stimeo/install/install_generator.rb +7 -2
- data/lib/generators/stimeo/install/templates/stimeo.js +19 -6
- data/lib/stimeo/ui/version.rb +1 -1
- metadata +3 -3
|
@@ -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,14 +16,77 @@ function announce(message, options = {}) {
|
|
|
12
16
|
})
|
|
13
17
|
);
|
|
14
18
|
}
|
|
15
|
-
function fillTemplate(template, values) {
|
|
16
|
-
return template.replace(/\{([a-zA-Z][a-zA-Z0-9]*)\}/g, (match, name) => {
|
|
17
|
-
const replacement = values[name];
|
|
18
|
-
return replacement === void 0 ? match : String(replacement);
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
var ListenerSet = class {
|
|
21
|
+
#abort = new AbortController();
|
|
22
|
+
add(target, type, handler, options) {
|
|
23
|
+
target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });
|
|
24
|
+
}
|
|
25
|
+
dispose() {
|
|
26
|
+
this.#abort.abort();
|
|
27
|
+
this.#abort = new AbortController();
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
var MicrotaskCoalescer = class {
|
|
32
|
+
#run;
|
|
33
|
+
#queued = false;
|
|
34
|
+
#active = false;
|
|
35
|
+
#generation = 0;
|
|
36
|
+
constructor(run) {
|
|
37
|
+
this.#run = run;
|
|
38
|
+
}
|
|
39
|
+
activate() {
|
|
40
|
+
this.#active = true;
|
|
41
|
+
}
|
|
42
|
+
cancel() {
|
|
43
|
+
this.#active = false;
|
|
44
|
+
this.#queued = false;
|
|
45
|
+
this.#generation += 1;
|
|
46
|
+
}
|
|
47
|
+
get pending() {
|
|
48
|
+
return this.#queued;
|
|
49
|
+
}
|
|
50
|
+
schedule() {
|
|
51
|
+
if (!this.#active || this.#queued) return;
|
|
52
|
+
this.#queued = true;
|
|
53
|
+
const generation = this.#generation;
|
|
54
|
+
queueMicrotask(() => {
|
|
55
|
+
if (generation !== this.#generation || !this.#queued || !this.#active) return;
|
|
56
|
+
this.#queued = false;
|
|
57
|
+
this.#run();
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
var MorphRenderWatcher = class {
|
|
63
|
+
#listeners = new ListenerSet();
|
|
64
|
+
#pass;
|
|
65
|
+
#element = null;
|
|
66
|
+
#onMorph = () => this.#pass.schedule();
|
|
67
|
+
constructor(run) {
|
|
68
|
+
this.#pass = new MicrotaskCoalescer(run);
|
|
69
|
+
}
|
|
70
|
+
observe(element) {
|
|
71
|
+
if (this.#element === element) return;
|
|
72
|
+
this.disconnect();
|
|
73
|
+
this.#element = element;
|
|
74
|
+
this.#pass.activate();
|
|
75
|
+
this.#listeners.add(element, "turbo:morph-element", this.#onMorph);
|
|
76
|
+
}
|
|
77
|
+
schedule() {
|
|
78
|
+
this.#pass.schedule();
|
|
79
|
+
}
|
|
80
|
+
get pending() {
|
|
81
|
+
return this.#pass.pending;
|
|
82
|
+
}
|
|
83
|
+
disconnect() {
|
|
84
|
+
this.#listeners.dispose();
|
|
85
|
+
this.#pass.cancel();
|
|
86
|
+
this.#element = null;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
23
90
|
var EmptyStateController = class extends Controller {
|
|
24
91
|
static targets = ["list", "empty"];
|
|
25
92
|
static values = {
|
|
@@ -29,68 +96,40 @@ var EmptyStateController = class extends Controller {
|
|
|
29
96
|
};
|
|
30
97
|
static events = ["change"];
|
|
31
98
|
#observer = null;
|
|
32
|
-
/** Whether the controller is between `connect()` and `disconnect()`. */
|
|
33
99
|
#connected = false;
|
|
34
|
-
/** Last applied empty state; `null` until the first sync so connect emits nothing. */
|
|
35
100
|
#empty = null;
|
|
101
|
+
#morphRender = new MorphRenderWatcher(() => this.#resync());
|
|
36
102
|
connect() {
|
|
103
|
+
this.#morphRender.observe(this.element);
|
|
37
104
|
this.#connected = true;
|
|
38
105
|
this.#syncObservation();
|
|
39
106
|
this.#update();
|
|
40
107
|
}
|
|
41
108
|
disconnect() {
|
|
109
|
+
this.#morphRender.disconnect();
|
|
42
110
|
this.#connected = false;
|
|
43
111
|
this.#stopObserving();
|
|
44
112
|
}
|
|
45
|
-
/** Follows a `list` element swapped in at runtime (Turbo Stream `replace` / morph). */
|
|
46
113
|
listTargetConnected() {
|
|
47
114
|
this.#resync();
|
|
48
115
|
}
|
|
49
|
-
/** Releases the observation when the `list` element leaves the target set. */
|
|
50
116
|
listTargetDisconnected() {
|
|
51
117
|
this.#resync();
|
|
52
118
|
}
|
|
53
|
-
/** Syncs an `empty` element that arrives — or is replaced — at runtime. */
|
|
54
119
|
emptyTargetConnected() {
|
|
55
120
|
this.#resync();
|
|
56
121
|
}
|
|
57
|
-
/**
|
|
58
|
-
* Syncs the `empty` element that remains when one leaves the target set. A
|
|
59
|
-
* single-target getter resolves to the first `empty` element in document order,
|
|
60
|
-
* so a swap that inserts the replacement *before* removing the original (Turbo
|
|
61
|
-
* Stream `after` / `before` / `append` followed by `remove`) leaves the
|
|
62
|
-
* replacement untouched until the original goes — this callback is that moment.
|
|
63
|
-
*/
|
|
64
122
|
emptyTargetDisconnected() {
|
|
65
123
|
this.#resync();
|
|
66
124
|
}
|
|
67
|
-
/** Re-renders when application code (or a Turbo morph) changes `itemSelector` at runtime. */
|
|
68
125
|
itemSelectorValueChanged() {
|
|
69
126
|
this.#resync();
|
|
70
127
|
}
|
|
71
|
-
/**
|
|
72
|
-
* Re-points the observation and re-renders after a target or selector change.
|
|
73
|
-
* The `#connected` guard is load-bearing: Stimulus runs value and target
|
|
74
|
-
* callbacks for the initial markup *before* `connect()` and runs target
|
|
75
|
-
* callbacks during teardown *after* `disconnect()`, and re-observing there
|
|
76
|
-
* would outlive the controller.
|
|
77
|
-
*/
|
|
78
128
|
#resync() {
|
|
79
129
|
if (!this.#connected) return;
|
|
80
130
|
this.#syncObservation();
|
|
81
131
|
this.#update();
|
|
82
132
|
}
|
|
83
|
-
/**
|
|
84
|
-
* Points the mutation observation at the current `list` target — re-resolved on
|
|
85
|
-
* every sync rather than captured at connect, so an element swapped in at
|
|
86
|
-
* runtime is observed instead of the detached original.
|
|
87
|
-
*
|
|
88
|
-
* The observation covers exactly what the count predicate reads. With no
|
|
89
|
-
* `itemSelector` the count is the child element count, which only `childList`
|
|
90
|
-
* can change. With one, the predicate reads the children themselves, so
|
|
91
|
-
* attribute and descendant mutations are watched too — and the controller's own
|
|
92
|
-
* writes are filtered back out, or toggling `hidden` would re-enter the render.
|
|
93
|
-
*/
|
|
94
133
|
#syncObservation() {
|
|
95
134
|
this.#stopObserving();
|
|
96
135
|
if (!this.hasListTarget || typeof MutationObserver === "undefined") return;
|
|
@@ -108,21 +147,11 @@ var EmptyStateController = class extends Controller {
|
|
|
108
147
|
this.#observer?.disconnect();
|
|
109
148
|
this.#observer = null;
|
|
110
149
|
}
|
|
111
|
-
/**
|
|
112
|
-
* Whether a mutation can change the item count. An attribute written on a
|
|
113
|
-
* target this controller owns is its own echo — `hidden` on `list` / `empty`,
|
|
114
|
-
* and the hooks on the controller element when the list *is* that element.
|
|
115
|
-
*/
|
|
116
150
|
#affectsCount(record) {
|
|
117
151
|
if (record.type !== "attributes") return true;
|
|
118
152
|
const own = record.target === this.listTarget || this.hasEmptyTarget && record.target === this.emptyTarget;
|
|
119
153
|
return !own;
|
|
120
154
|
}
|
|
121
|
-
/**
|
|
122
|
-
* Renders the count, then reports a crossed boundary. The announcement copy is
|
|
123
|
-
* read here rather than while rendering: it is the wording of the report, not
|
|
124
|
-
* an input to what is displayed.
|
|
125
|
-
*/
|
|
126
155
|
#update() {
|
|
127
156
|
const count = this.#render();
|
|
128
157
|
if (count === null) return;
|
|
@@ -135,12 +164,6 @@ var EmptyStateController = class extends Controller {
|
|
|
135
164
|
fillTemplate(empty ? this.announceTextValue : this.announceFilledTextValue, { count })
|
|
136
165
|
);
|
|
137
166
|
}
|
|
138
|
-
/**
|
|
139
|
-
* Syncs visibility and the state hooks to the current item count, and returns
|
|
140
|
-
* it. `null` when there is no `list` target to count.
|
|
141
|
-
*
|
|
142
|
-
* @stimeoRenderRoot
|
|
143
|
-
*/
|
|
144
167
|
#render() {
|
|
145
168
|
if (!this.hasListTarget) return null;
|
|
146
169
|
const count = this.#count();
|
|
@@ -155,7 +178,6 @@ var EmptyStateController = class extends Controller {
|
|
|
155
178
|
if (this.hasEmptyTarget) this.emptyTarget.hidden = !empty;
|
|
156
179
|
return count;
|
|
157
180
|
}
|
|
158
|
-
/** Item count: element children matching `itemSelector`, or all element children. */
|
|
159
181
|
#count() {
|
|
160
182
|
const selector = this.itemSelectorValue;
|
|
161
183
|
if (selector.length === 0) return this.listTarget.childElementCount;
|
|
@@ -168,5 +190,4 @@ var EmptyStateController = class extends Controller {
|
|
|
168
190
|
};
|
|
169
191
|
|
|
170
192
|
export { EmptyStateController };
|
|
171
|
-
//# sourceMappingURL=empty_state_controller.js.map
|
|
172
193
|
//# sourceMappingURL=empty_state_controller.js.map
|