stimeo-ui 0.17.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 +106 -1
- data/README.md +19 -10
- data/dist/cable/index.js +22 -14
- data/dist/controllers/accordion_controller.js +14 -6
- data/dist/controllers/alert_dialog_controller.js +145 -118
- data/dist/controllers/announcer_controller.js +113 -17
- data/dist/controllers/auto_submit_controller.js +185 -60
- data/dist/controllers/avatar_controller.js +55 -43
- data/dist/controllers/bulk_select_controller.js +64 -50
- data/dist/controllers/calendar_controller.js +55 -53
- data/dist/controllers/carousel_controller.js +124 -86
- data/dist/controllers/character_counter_controller.js +291 -95
- data/dist/controllers/checkbox_controller.js +6 -0
- data/dist/controllers/clipboard_controller.js +118 -27
- data/dist/controllers/collapsible_controller.js +52 -49
- data/dist/controllers/color_picker_controller.js +29 -7
- data/dist/controllers/combobox_controller.js +210 -71
- data/dist/controllers/command_palette_controller.js +289 -140
- data/dist/controllers/conditional_fields_controller.js +145 -58
- data/dist/controllers/confirm_controller.js +145 -118
- data/dist/controllers/context_menu_controller.js +138 -73
- data/dist/controllers/countdown_controller.js +109 -21
- data/dist/controllers/currency_input_controller.js +446 -72
- data/dist/controllers/data_grid_controller.js +134 -28
- data/dist/controllers/date_range_picker_controller.js +93 -72
- data/dist/controllers/dialog_controller.js +145 -118
- data/dist/controllers/direct_upload_controller.js +24 -14
- data/dist/controllers/dirty_form_controller.js +68 -31
- data/dist/controllers/dismissible_controller.js +64 -46
- data/dist/controllers/drawer_controller.js +145 -118
- data/dist/controllers/dropdown_controller.js +76 -63
- data/dist/controllers/editable_controller.js +199 -62
- data/dist/controllers/empty_state_controller.js +13 -6
- data/dist/controllers/file_dropzone_controller.js +55 -48
- data/dist/controllers/filter_controller.js +9 -2
- data/dist/controllers/flash_controller.js +66 -33
- data/dist/controllers/focus_controller.js +39 -14
- data/dist/controllers/form_field_controller.js +52 -43
- data/dist/controllers/form_validation_controller.js +18 -11
- data/dist/controllers/frame_loading_controller.js +55 -48
- data/dist/controllers/hover_card_controller.js +67 -61
- data/dist/controllers/idle_controller.js +10 -6
- data/dist/controllers/input_mask_controller.js +411 -24
- data/dist/controllers/intersection_controller.js +3 -0
- data/dist/controllers/lazy_frame_controller.js +15 -3
- data/dist/controllers/listbox_controller.js +260 -79
- data/dist/controllers/local_time_controller.js +48 -13
- data/dist/controllers/masonry_controller.js +11 -4
- data/dist/controllers/menu_controller.js +138 -82
- data/dist/controllers/menubar_controller.js +65 -19
- data/dist/controllers/meter_controller.js +270 -24
- data/dist/controllers/multi_select_controller.js +251 -94
- data/dist/controllers/navigation_menu_controller.js +67 -19
- data/dist/controllers/nested_form_controller.js +98 -64
- data/dist/controllers/network_status_controller.js +70 -52
- data/dist/controllers/number_input_controller.js +344 -94
- data/dist/controllers/optimistic_controller.js +29 -11
- data/dist/controllers/otp_controller.js +502 -104
- data/dist/controllers/overflow_indicator_controller.js +6 -0
- data/dist/controllers/overflow_menu_controller.js +136 -21
- data/dist/controllers/pagination_controller.js +47 -14
- data/dist/controllers/password_reveal_controller.js +52 -49
- data/dist/controllers/password_strength_controller.js +13 -6
- data/dist/controllers/persist_controller.js +48 -128
- data/dist/controllers/pointer_drag_controller.js +249 -23
- data/dist/controllers/popover_controller.js +82 -65
- data/dist/controllers/portal_controller.js +6 -0
- data/dist/controllers/preview_guard_controller.js +14 -3
- data/dist/controllers/progress_controller.js +271 -27
- data/dist/controllers/radio_group_controller.js +167 -80
- data/dist/controllers/range_slider_controller.js +27 -7
- data/dist/controllers/rating_controller.js +93 -57
- data/dist/controllers/read_more_controller.js +10 -6
- data/dist/controllers/reading_progress_controller.js +22 -5
- data/dist/controllers/relative_time_controller.js +75 -11
- data/dist/controllers/reset_on_restore_controller.js +6 -0
- data/dist/controllers/resizable_controller.js +55 -22
- data/dist/controllers/roving_controller.js +10 -4
- data/dist/controllers/scroll_area_controller.js +129 -88
- data/dist/controllers/scroll_restore_controller.js +14 -2
- data/dist/controllers/scroll_visibility_controller.js +93 -60
- data/dist/controllers/scrollspy_controller.js +11 -5
- data/dist/controllers/separator_controller.js +59 -43
- data/dist/controllers/sidebar_controller.js +150 -122
- data/dist/controllers/skeleton_controller.js +55 -48
- data/dist/controllers/slider_controller.js +27 -6
- data/dist/controllers/smart_sticky_header_controller.js +13 -5
- data/dist/controllers/sortable_controller.js +27 -14
- data/dist/controllers/spinner_controller.js +55 -48
- data/dist/controllers/step_indicator_controller.js +6 -0
- data/dist/controllers/stepper_controller.js +6 -0
- data/dist/controllers/stick_to_bottom_controller.js +19 -8
- data/dist/controllers/sticky_observer_controller.js +49 -43
- data/dist/controllers/submit_once_controller.js +145 -85
- data/dist/controllers/switch_controller.js +172 -28
- data/dist/controllers/tabs_controller.js +6 -1
- data/dist/controllers/tags_input_controller.js +157 -28
- data/dist/controllers/textarea_autosize_controller.js +40 -19
- data/dist/controllers/theme_controller.js +10 -4
- data/dist/controllers/time_picker_controller.js +192 -54
- data/dist/controllers/toast_controller.js +58 -27
- data/dist/controllers/toggle_group_controller.js +158 -56
- data/dist/controllers/toolbar_controller.js +150 -21
- data/dist/controllers/tree_view_controller.js +134 -25
- data/dist/index.js +2451 -1312
- data/dist/positioning/index.js +6 -0
- 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 +2 -2
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
import { Controller } from '@hotwired/stimulus';
|
|
2
2
|
|
|
3
|
+
function setAttributeIfChanged(element, name, value, beforeWrite) {
|
|
4
|
+
if (element.getAttribute(name) === value) return false;
|
|
5
|
+
if (value === null) element.removeAttribute(name);
|
|
6
|
+
else element.setAttribute(name, value);
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
|
|
3
10
|
function sharedRegistry(key, create) {
|
|
4
11
|
const symbol = Symbol.for(key);
|
|
5
12
|
const scope = globalThis;
|
|
6
13
|
const existing = scope[symbol];
|
|
7
14
|
if (existing !== void 0) return existing;
|
|
8
|
-
const
|
|
9
|
-
Object.defineProperty(globalThis, symbol, { value:
|
|
10
|
-
return
|
|
15
|
+
const registry2 = create();
|
|
16
|
+
Object.defineProperty(globalThis, symbol, { value: registry2 });
|
|
17
|
+
return registry2;
|
|
11
18
|
}
|
|
12
19
|
|
|
20
|
+
var registry = sharedRegistry(
|
|
21
|
+
"stimeo-ui.attribute-lease.registry.v1",
|
|
22
|
+
() => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
|
|
23
|
+
);
|
|
13
24
|
function isAttributeValue(value) {
|
|
14
25
|
return value === null || typeof value === "string";
|
|
15
26
|
}
|
|
@@ -26,24 +37,46 @@ function readLeaseRecord(element, record) {
|
|
|
26
37
|
return void 0;
|
|
27
38
|
}
|
|
28
39
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
);
|
|
40
|
+
function attributeStack(element, attribute) {
|
|
41
|
+
const byAttribute = registry.stacks.get(element) ?? /* @__PURE__ */ new Map();
|
|
42
|
+
registry.stacks.set(element, byAttribute);
|
|
43
|
+
const known = byAttribute.get(attribute);
|
|
44
|
+
if (known) return known;
|
|
45
|
+
const found = [];
|
|
46
|
+
for (const record of registry.names.get(attribute) ?? []) {
|
|
47
|
+
const read = readLeaseRecord(element, record);
|
|
48
|
+
if (read) found.push({ ...read, record });
|
|
49
|
+
}
|
|
50
|
+
const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
|
|
51
|
+
const stack = found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
|
|
52
|
+
lease: null,
|
|
53
|
+
record,
|
|
54
|
+
written,
|
|
55
|
+
original,
|
|
56
|
+
linked: linked && index > 0
|
|
57
|
+
}));
|
|
58
|
+
byAttribute.set(attribute, stack);
|
|
59
|
+
return stack;
|
|
60
|
+
}
|
|
61
|
+
function findHold(stack, lease, record) {
|
|
62
|
+
return stack.find((held) => held.lease === lease) ?? stack.find((held) => held.lease === null && held.record === record);
|
|
63
|
+
}
|
|
64
|
+
var AttributeLease = class {
|
|
34
65
|
#attribute;
|
|
35
66
|
#record;
|
|
36
67
|
#base;
|
|
68
|
+
#preserveAuthor;
|
|
37
69
|
#held = /* @__PURE__ */ new Set();
|
|
38
70
|
constructor(attribute, owner, options = {}) {
|
|
39
71
|
this.#attribute = attribute;
|
|
40
72
|
this.#record = `data-${owner}-${attribute}-lease`;
|
|
41
73
|
this.#base = options.base === true;
|
|
42
|
-
|
|
74
|
+
this.#preserveAuthor = options.preserveAuthor === true;
|
|
75
|
+
const names = registry.names;
|
|
43
76
|
names.set(attribute, (names.get(attribute) ?? /* @__PURE__ */ new Set()).add(this.#record));
|
|
44
77
|
}
|
|
45
78
|
write(element, value) {
|
|
46
|
-
const stack = this.#
|
|
79
|
+
const stack = attributeStack(element, this.#attribute);
|
|
47
80
|
const hold = this.#take(stack) ?? this.#acquire(element, stack);
|
|
48
81
|
this.#held.add(element);
|
|
49
82
|
const shows = !this.#covered(element, stack, hold);
|
|
@@ -53,8 +86,8 @@ var AttributeLease = class _AttributeLease {
|
|
|
53
86
|
}
|
|
54
87
|
return(element) {
|
|
55
88
|
const held = this.#held.delete(element);
|
|
56
|
-
const known =
|
|
57
|
-
const stack = held || known || element.hasAttribute(this.#record) ? this.#
|
|
89
|
+
const known = registry.stacks.get(element)?.has(this.#attribute);
|
|
90
|
+
const stack = held || known || element.hasAttribute(this.#record) ? attributeStack(element, this.#attribute) : [];
|
|
58
91
|
const hold = this.#take(stack);
|
|
59
92
|
if (!hold) return false;
|
|
60
93
|
const carries = element.getAttribute(this.#attribute) === hold.written;
|
|
@@ -72,31 +105,8 @@ var AttributeLease = class _AttributeLease {
|
|
|
72
105
|
returnAll() {
|
|
73
106
|
for (const element of Array.from(this.#held)) this.return(element);
|
|
74
107
|
}
|
|
75
|
-
#stack(element) {
|
|
76
|
-
const stacks = _AttributeLease.#registry.stacks;
|
|
77
|
-
const byAttribute = stacks.get(element) ?? /* @__PURE__ */ new Map();
|
|
78
|
-
stacks.set(element, byAttribute);
|
|
79
|
-
const stack = byAttribute.get(this.#attribute) ?? this.#seed(element);
|
|
80
|
-
byAttribute.set(this.#attribute, stack);
|
|
81
|
-
return stack;
|
|
82
|
-
}
|
|
83
|
-
#seed(element) {
|
|
84
|
-
const found = [];
|
|
85
|
-
for (const record of _AttributeLease.#registry.names.get(this.#attribute) ?? []) {
|
|
86
|
-
const read = readLeaseRecord(element, record);
|
|
87
|
-
if (read) found.push({ ...read, record });
|
|
88
|
-
}
|
|
89
|
-
const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
|
|
90
|
-
return found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
|
|
91
|
-
lease: null,
|
|
92
|
-
record,
|
|
93
|
-
written,
|
|
94
|
-
original,
|
|
95
|
-
linked: linked && index > 0
|
|
96
|
-
}));
|
|
97
|
-
}
|
|
98
108
|
#take(stack) {
|
|
99
|
-
const hold = stack
|
|
109
|
+
const hold = findHold(stack, this, this.#record);
|
|
100
110
|
if (hold) hold.lease = this;
|
|
101
111
|
return hold;
|
|
102
112
|
}
|
|
@@ -105,7 +115,7 @@ var AttributeLease = class _AttributeLease {
|
|
|
105
115
|
const top = stack.at(-1);
|
|
106
116
|
const bottom = stack[0];
|
|
107
117
|
const over = top?.written === current ? top : void 0;
|
|
108
|
-
const from = this.#base ? bottom : over;
|
|
118
|
+
const from = this.#base ? this.#preserveAuthor && !stack.some((held) => held.written === current) ? void 0 : bottom : over;
|
|
109
119
|
const hold = {
|
|
110
120
|
lease: this,
|
|
111
121
|
record: this.#record,
|
|
@@ -135,15 +145,11 @@ var AttributeLease = class _AttributeLease {
|
|
|
135
145
|
);
|
|
136
146
|
});
|
|
137
147
|
for (const [name, recorded] of records) {
|
|
138
|
-
|
|
139
|
-
if (recorded === null) element.removeAttribute(name);
|
|
140
|
-
else element.setAttribute(name, recorded);
|
|
148
|
+
setAttributeIfChanged(element, name, recorded);
|
|
141
149
|
}
|
|
142
150
|
}
|
|
143
151
|
#reflect(element, value) {
|
|
144
|
-
|
|
145
|
-
if (value === null) element.removeAttribute(this.#attribute);
|
|
146
|
-
else element.setAttribute(this.#attribute, value);
|
|
152
|
+
setAttributeIfChanged(element, this.#attribute, value);
|
|
147
153
|
}
|
|
148
154
|
};
|
|
149
155
|
|
|
@@ -161,25 +167,25 @@ var EscapeLayer = class _EscapeLayer {
|
|
|
161
167
|
#active = null;
|
|
162
168
|
activate(ownerDocument = document, options) {
|
|
163
169
|
this.deactivate();
|
|
164
|
-
let
|
|
165
|
-
if (!
|
|
166
|
-
|
|
167
|
-
_EscapeLayer.#registries.set(ownerDocument,
|
|
168
|
-
ownerDocument.addEventListener("keydown",
|
|
170
|
+
let registry2 = _EscapeLayer.#registries.get(ownerDocument);
|
|
171
|
+
if (!registry2) {
|
|
172
|
+
registry2 = _EscapeLayer.#createRegistry();
|
|
173
|
+
_EscapeLayer.#registries.set(ownerDocument, registry2);
|
|
174
|
+
ownerDocument.addEventListener("keydown", registry2.onKeydown);
|
|
169
175
|
}
|
|
170
176
|
const entry = { onDismiss: options.onDismiss, claims: options.claims ?? null };
|
|
171
|
-
|
|
177
|
+
registry2.stack.push(entry);
|
|
172
178
|
this.#active = { document: ownerDocument, entry };
|
|
173
179
|
}
|
|
174
180
|
deactivate() {
|
|
175
181
|
const active = this.#active;
|
|
176
182
|
if (!active) return;
|
|
177
|
-
const
|
|
178
|
-
if (
|
|
179
|
-
const index =
|
|
180
|
-
if (index >= 0)
|
|
181
|
-
if (
|
|
182
|
-
active.document.removeEventListener("keydown",
|
|
183
|
+
const registry2 = _EscapeLayer.#registries.get(active.document);
|
|
184
|
+
if (registry2) {
|
|
185
|
+
const index = registry2.stack.lastIndexOf(active.entry);
|
|
186
|
+
if (index >= 0) registry2.stack.splice(index, 1);
|
|
187
|
+
if (registry2.stack.length === 0) {
|
|
188
|
+
active.document.removeEventListener("keydown", registry2.onKeydown);
|
|
183
189
|
_EscapeLayer.#registries.delete(active.document);
|
|
184
190
|
}
|
|
185
191
|
}
|
|
@@ -188,22 +194,22 @@ var EscapeLayer = class _EscapeLayer {
|
|
|
188
194
|
get ownsEscape() {
|
|
189
195
|
const active = this.#active;
|
|
190
196
|
if (!active) return false;
|
|
191
|
-
const
|
|
192
|
-
if (!
|
|
193
|
-
return _EscapeLayer.#resolveOwner(
|
|
197
|
+
const registry2 = _EscapeLayer.#registries.get(active.document);
|
|
198
|
+
if (!registry2) return false;
|
|
199
|
+
return _EscapeLayer.#resolveOwner(registry2.stack) === active.entry;
|
|
194
200
|
}
|
|
195
201
|
static #createRegistry() {
|
|
196
|
-
const
|
|
202
|
+
const registry2 = {
|
|
197
203
|
stack: [],
|
|
198
204
|
onKeydown: (event) => {
|
|
199
205
|
if (event.key !== "Escape" || event.defaultPrevented || event.isComposing) return;
|
|
200
|
-
const owner = _EscapeLayer.#resolveOwner(
|
|
206
|
+
const owner = _EscapeLayer.#resolveOwner(registry2.stack);
|
|
201
207
|
if (!owner) return;
|
|
202
208
|
event.preventDefault();
|
|
203
209
|
owner.onDismiss();
|
|
204
210
|
}
|
|
205
211
|
};
|
|
206
|
-
return
|
|
212
|
+
return registry2;
|
|
207
213
|
}
|
|
208
214
|
static #resolveOwner(stack) {
|
|
209
215
|
for (let index = stack.length - 1; index >= 0; index--) {
|
|
@@ -301,6 +307,17 @@ function firstTabStop(root) {
|
|
|
301
307
|
return null;
|
|
302
308
|
}
|
|
303
309
|
|
|
310
|
+
var ListenerSet = class {
|
|
311
|
+
#abort = new AbortController();
|
|
312
|
+
add(target, type, handler, options) {
|
|
313
|
+
target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });
|
|
314
|
+
}
|
|
315
|
+
dispose() {
|
|
316
|
+
this.#abort.abort();
|
|
317
|
+
this.#abort = new AbortController();
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
|
|
304
321
|
function observeScrollDismiss(element, onScroll) {
|
|
305
322
|
const targets = [...scrollParents(element), window];
|
|
306
323
|
const handler = () => onScroll();
|
|
@@ -347,10 +364,11 @@ var PopoverController = class extends Controller {
|
|
|
347
364
|
#shownPanel = null;
|
|
348
365
|
#connected = false;
|
|
349
366
|
#reporting = false;
|
|
367
|
+
#listeners = new ListenerSet();
|
|
350
368
|
connect() {
|
|
351
369
|
this.#close("api");
|
|
352
|
-
|
|
353
|
-
this.element
|
|
370
|
+
this.#listeners.add(document, "click", this.#onOutsideClick, { capture: true });
|
|
371
|
+
this.#listeners.add(this.element, "focusout", this.#onFocusOut);
|
|
354
372
|
this.#connected = true;
|
|
355
373
|
this.#reporting = true;
|
|
356
374
|
}
|
|
@@ -358,8 +376,7 @@ var PopoverController = class extends Controller {
|
|
|
358
376
|
this.#connected = false;
|
|
359
377
|
this.#reporting = false;
|
|
360
378
|
this.#release();
|
|
361
|
-
|
|
362
|
-
this.element.removeEventListener("focusout", this.#onFocusOut);
|
|
379
|
+
this.#listeners.dispose();
|
|
363
380
|
}
|
|
364
381
|
closeOnScrollValueChanged() {
|
|
365
382
|
if (this.#shownPanel) this.#syncScrollDismiss();
|
|
@@ -83,6 +83,9 @@ var MicrotaskCoalescer = class {
|
|
|
83
83
|
this.#queued = false;
|
|
84
84
|
this.#generation += 1;
|
|
85
85
|
}
|
|
86
|
+
get pending() {
|
|
87
|
+
return this.#queued;
|
|
88
|
+
}
|
|
86
89
|
schedule() {
|
|
87
90
|
if (!this.#active || this.#queued) return;
|
|
88
91
|
this.#queued = true;
|
|
@@ -113,6 +116,9 @@ var MorphRenderWatcher = class {
|
|
|
113
116
|
schedule() {
|
|
114
117
|
this.#pass.schedule();
|
|
115
118
|
}
|
|
119
|
+
get pending() {
|
|
120
|
+
return this.#pass.pending;
|
|
121
|
+
}
|
|
116
122
|
disconnect() {
|
|
117
123
|
this.#listeners.dispose();
|
|
118
124
|
this.#pass.cancel();
|
|
@@ -27,6 +27,9 @@ var MicrotaskCoalescer = class {
|
|
|
27
27
|
this.#queued = false;
|
|
28
28
|
this.#generation += 1;
|
|
29
29
|
}
|
|
30
|
+
get pending() {
|
|
31
|
+
return this.#queued;
|
|
32
|
+
}
|
|
30
33
|
schedule() {
|
|
31
34
|
if (!this.#active || this.#queued) return;
|
|
32
35
|
this.#queued = true;
|
|
@@ -57,6 +60,9 @@ var MorphRenderWatcher = class {
|
|
|
57
60
|
schedule() {
|
|
58
61
|
this.#pass.schedule();
|
|
59
62
|
}
|
|
63
|
+
get pending() {
|
|
64
|
+
return this.#pass.pending;
|
|
65
|
+
}
|
|
60
66
|
disconnect() {
|
|
61
67
|
this.#listeners.dispose();
|
|
62
68
|
this.#pass.cancel();
|
|
@@ -64,6 +70,13 @@ var MorphRenderWatcher = class {
|
|
|
64
70
|
}
|
|
65
71
|
};
|
|
66
72
|
|
|
73
|
+
function setAttributeIfChanged(element, name, value, beforeWrite) {
|
|
74
|
+
if (element.getAttribute(name) === value) return false;
|
|
75
|
+
if (value === null) element.removeAttribute(name);
|
|
76
|
+
else element.setAttribute(name, value);
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
|
|
67
80
|
function sharedRegistry(key, create) {
|
|
68
81
|
const symbol = Symbol.for(key);
|
|
69
82
|
const scope = globalThis;
|
|
@@ -203,9 +216,7 @@ var StylePropertyLease = class _StylePropertyLease {
|
|
|
203
216
|
);
|
|
204
217
|
});
|
|
205
218
|
for (const [name, recorded] of records) {
|
|
206
|
-
|
|
207
|
-
if (recorded === null) element.removeAttribute(name);
|
|
208
|
-
else element.setAttribute(name, recorded);
|
|
219
|
+
setAttributeIfChanged(element, name, recorded);
|
|
209
220
|
}
|
|
210
221
|
}
|
|
211
222
|
#carries(element, hold) {
|