stimeo-ui 0.15.0 → 0.17.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 +209 -0
- data/README.md +128 -1
- data/dist/cable/index.js +392 -417
- data/dist/controllers/accordion_controller.js +228 -28
- data/dist/controllers/alert_dialog_controller.js +862 -221
- data/dist/controllers/announcer_controller.js +135 -191
- data/dist/controllers/aspect_ratio_controller.js +0 -10
- data/dist/controllers/auto_submit_controller.js +295 -110
- data/dist/controllers/avatar_controller.js +172 -106
- data/dist/controllers/breadcrumb_controller.js +0 -129
- data/dist/controllers/bulk_select_controller.js +264 -53
- data/dist/controllers/calendar_controller.js +346 -180
- data/dist/controllers/carousel_controller.js +587 -300
- data/dist/controllers/character_counter_controller.js +271 -143
- data/dist/controllers/checkbox_controller.js +77 -75
- data/dist/controllers/clipboard_controller.js +187 -108
- data/dist/controllers/collapsible_controller.js +374 -108
- data/dist/controllers/color_picker_controller.js +183 -127
- data/dist/controllers/combobox_controller.js +426 -109
- data/dist/controllers/command_palette_controller.js +994 -350
- data/dist/controllers/conditional_fields_controller.js +212 -125
- data/dist/controllers/confirm_controller.js +939 -245
- data/dist/controllers/context_menu_controller.js +275 -127
- data/dist/controllers/count_up_controller.js +73 -21
- data/dist/controllers/countdown_controller.js +235 -97
- data/dist/controllers/currency_input_controller.js +241 -118
- data/dist/controllers/data_grid_controller.js +229 -135
- data/dist/controllers/date_range_picker_controller.js +359 -165
- data/dist/controllers/dialog_controller.js +887 -225
- data/dist/controllers/direct_upload_controller.js +80 -142
- data/dist/controllers/dirty_form_controller.js +26 -47
- data/dist/controllers/dismissible_controller.js +175 -20
- data/dist/controllers/drawer_controller.js +963 -336
- data/dist/controllers/dropdown_controller.js +342 -85
- data/dist/controllers/editable_controller.js +182 -58
- data/dist/controllers/empty_state_controller.js +67 -53
- data/dist/controllers/file_dropzone_controller.js +426 -229
- data/dist/controllers/filter_controller.js +78 -36
- data/dist/controllers/flash_controller.js +328 -211
- data/dist/controllers/focus_controller.js +654 -239
- data/dist/controllers/form_field_controller.js +153 -136
- data/dist/controllers/form_validation_controller.js +29 -96
- data/dist/controllers/frame_loading_controller.js +263 -198
- data/dist/controllers/highlight_controller.js +119 -70
- data/dist/controllers/hover_card_controller.js +335 -118
- data/dist/controllers/idle_controller.js +316 -65
- data/dist/controllers/input_mask_controller.js +116 -61
- data/dist/controllers/intersection_controller.js +147 -103
- data/dist/controllers/lazy_frame_controller.js +9 -56
- data/dist/controllers/listbox_controller.js +413 -153
- data/dist/controllers/local_time_controller.js +54 -64
- data/dist/controllers/masonry_controller.js +70 -95
- data/dist/controllers/menu_controller.js +254 -167
- data/dist/controllers/menubar_controller.js +206 -331
- data/dist/controllers/meter_controller.js +159 -71
- data/dist/controllers/multi_select_controller.js +797 -388
- data/dist/controllers/navigation_menu_controller.js +156 -231
- data/dist/controllers/nested_form_controller.js +373 -174
- data/dist/controllers/network_status_controller.js +241 -45
- data/dist/controllers/number_input_controller.js +387 -227
- data/dist/controllers/optimistic_controller.js +28 -75
- data/dist/controllers/otp_controller.js +344 -196
- data/dist/controllers/overflow_indicator_controller.js +167 -93
- data/dist/controllers/overflow_menu_controller.js +408 -277
- data/dist/controllers/pagination_controller.js +342 -120
- data/dist/controllers/password_reveal_controller.js +424 -99
- data/dist/controllers/password_strength_controller.js +99 -153
- data/dist/controllers/persist_controller.js +252 -96
- data/dist/controllers/pointer_drag_controller.js +263 -164
- data/dist/controllers/popover_controller.js +267 -94
- data/dist/controllers/portal_controller.js +209 -72
- data/dist/controllers/preview_guard_controller.js +243 -112
- data/dist/controllers/progress_controller.js +132 -59
- data/dist/controllers/radio_group_controller.js +138 -133
- data/dist/controllers/range_slider_controller.js +245 -112
- data/dist/controllers/rating_controller.js +429 -194
- data/dist/controllers/read_more_controller.js +185 -47
- data/dist/controllers/reading_progress_controller.js +147 -135
- data/dist/controllers/relative_time_controller.js +145 -110
- data/dist/controllers/{reset_before_cache_controller.js → reset_on_restore_controller.js} +97 -38
- data/dist/controllers/resizable_controller.js +294 -118
- data/dist/controllers/roving_controller.js +39 -84
- data/dist/controllers/scroll_area_controller.js +428 -221
- data/dist/controllers/scroll_restore_controller.js +0 -53
- data/dist/controllers/scroll_visibility_controller.js +395 -146
- data/dist/controllers/scrollspy_controller.js +181 -236
- data/dist/controllers/separator_controller.js +288 -132
- data/dist/controllers/sidebar_controller.js +1071 -375
- data/dist/controllers/skeleton_controller.js +248 -92
- data/dist/controllers/slider_controller.js +211 -96
- data/dist/controllers/smart_sticky_header_controller.js +163 -54
- data/dist/controllers/sortable_controller.js +13 -110
- data/dist/controllers/spinner_controller.js +277 -161
- data/dist/controllers/step_indicator_controller.js +107 -53
- data/dist/controllers/stepper_controller.js +171 -48
- data/dist/controllers/stick_to_bottom_controller.js +310 -116
- data/dist/controllers/sticky_observer_controller.js +214 -49
- data/dist/controllers/submit_once_controller.js +294 -192
- data/dist/controllers/switch_controller.js +107 -43
- data/dist/controllers/tabs_controller.js +50 -25
- data/dist/controllers/tags_input_controller.js +290 -149
- data/dist/controllers/textarea_autosize_controller.js +71 -58
- data/dist/controllers/theme_controller.js +148 -80
- data/dist/controllers/time_picker_controller.js +162 -81
- data/dist/controllers/toast_controller.js +365 -193
- data/dist/controllers/toggle_group_controller.js +194 -99
- data/dist/controllers/toolbar_controller.js +92 -90
- data/dist/controllers/tooltip_controller.js +185 -125
- data/dist/controllers/transition_controller.js +123 -115
- data/dist/controllers/tree_view_controller.js +248 -290
- data/dist/index.js +8649 -8572
- data/dist/positioning/index.js +148 -45
- data/lib/stimeo/ui/version.rb +1 -1
- metadata +3 -3
|
@@ -1,108 +1,264 @@
|
|
|
1
1
|
import { Controller } from '@hotwired/stimulus';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
var ListenerSet = class {
|
|
4
|
+
#abort = new AbortController();
|
|
5
|
+
add(target, type, handler, options) {
|
|
6
|
+
target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });
|
|
7
|
+
}
|
|
8
|
+
dispose() {
|
|
9
|
+
this.#abort.abort();
|
|
10
|
+
this.#abort = new AbortController();
|
|
11
|
+
}
|
|
12
|
+
};
|
|
4
13
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
};
|
|
13
|
-
#rewind;
|
|
14
|
-
/** @param rewind - the pass that returns this controller's state to its initial form. */
|
|
15
|
-
constructor(rewind) {
|
|
16
|
-
this.#rewind = rewind;
|
|
14
|
+
var MicrotaskCoalescer = class {
|
|
15
|
+
#run;
|
|
16
|
+
#queued = false;
|
|
17
|
+
#active = false;
|
|
18
|
+
#generation = 0;
|
|
19
|
+
constructor(run) {
|
|
20
|
+
this.#run = run;
|
|
17
21
|
}
|
|
18
|
-
/** Subscribes to `turbo:before-cache`; call from `connect()`. Idempotent. */
|
|
19
22
|
activate() {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
this.#active = true;
|
|
24
|
+
}
|
|
25
|
+
cancel() {
|
|
26
|
+
this.#active = false;
|
|
27
|
+
this.#queued = false;
|
|
28
|
+
this.#generation += 1;
|
|
25
29
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
schedule() {
|
|
31
|
+
if (!this.#active || this.#queued) return;
|
|
32
|
+
this.#queued = true;
|
|
33
|
+
const generation = this.#generation;
|
|
34
|
+
queueMicrotask(() => {
|
|
35
|
+
if (generation !== this.#generation || !this.#queued || !this.#active) return;
|
|
36
|
+
this.#queued = false;
|
|
37
|
+
this.#run();
|
|
38
|
+
});
|
|
31
39
|
}
|
|
32
40
|
};
|
|
33
41
|
|
|
34
|
-
|
|
35
|
-
|
|
42
|
+
var MorphRenderWatcher = class {
|
|
43
|
+
#listeners = new ListenerSet();
|
|
44
|
+
#pass;
|
|
45
|
+
#element = null;
|
|
46
|
+
#onMorph = () => this.#pass.schedule();
|
|
47
|
+
constructor(run) {
|
|
48
|
+
this.#pass = new MicrotaskCoalescer(run);
|
|
49
|
+
}
|
|
50
|
+
observe(element) {
|
|
51
|
+
if (this.#element === element) return;
|
|
52
|
+
this.disconnect();
|
|
53
|
+
this.#element = element;
|
|
54
|
+
this.#pass.activate();
|
|
55
|
+
this.#listeners.add(element, "turbo:morph-element", this.#onMorph);
|
|
56
|
+
}
|
|
57
|
+
schedule() {
|
|
58
|
+
this.#pass.schedule();
|
|
59
|
+
}
|
|
60
|
+
disconnect() {
|
|
61
|
+
this.#listeners.dispose();
|
|
62
|
+
this.#pass.cancel();
|
|
63
|
+
this.#element = null;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
function sharedRegistry(key, create) {
|
|
68
|
+
const symbol = Symbol.for(key);
|
|
69
|
+
const scope = globalThis;
|
|
70
|
+
const existing = scope[symbol];
|
|
71
|
+
if (existing !== void 0) return existing;
|
|
72
|
+
const registry = create();
|
|
73
|
+
Object.defineProperty(globalThis, symbol, { value: registry });
|
|
74
|
+
return registry;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
var StylePropertyLease = class _StylePropertyLease {
|
|
78
|
+
static #registry = sharedRegistry(
|
|
79
|
+
"stimeo-ui.style-property-lease.registry.v1",
|
|
80
|
+
() => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
|
|
81
|
+
);
|
|
36
82
|
#property;
|
|
37
|
-
#
|
|
38
|
-
|
|
39
|
-
constructor(property) {
|
|
83
|
+
#record;
|
|
84
|
+
#held = /* @__PURE__ */ new Set();
|
|
85
|
+
constructor(property, owner) {
|
|
40
86
|
this.#property = property;
|
|
87
|
+
this.#record = `data-${owner}-style-${property}-lease`;
|
|
88
|
+
const names = _StylePropertyLease.#registry.names;
|
|
89
|
+
names.set(property, (names.get(property) ?? /* @__PURE__ */ new Set()).add(this.#record));
|
|
41
90
|
}
|
|
42
|
-
/** Writes or removes the leased declaration while preserving its authored value. */
|
|
43
91
|
write(element, value, priority = "") {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
writtenValue: value,
|
|
53
|
-
writtenPriority: value === null ? "" : priority
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
this.#reflect(element, value, priority);
|
|
92
|
+
const stack = this.#stack(element);
|
|
93
|
+
const hold = this.#take(stack) ?? this.#acquire(element, stack);
|
|
94
|
+
this.#held.add(element);
|
|
95
|
+
const shows = !this.#covered(element, stack, hold);
|
|
96
|
+
hold.writtenValue = value;
|
|
97
|
+
hold.writtenPriority = value === null ? "" : priority;
|
|
98
|
+
this.#mark(element, stack);
|
|
99
|
+
if (shows) this.#show(element, value, hold.writtenPriority);
|
|
57
100
|
}
|
|
58
|
-
/** Returns one lease without overwriting a later consumer declaration. */
|
|
59
101
|
return(element) {
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
this.#
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
102
|
+
const held = this.#held.delete(element);
|
|
103
|
+
const known = _StylePropertyLease.#registry.stacks.get(element)?.has(this.#property);
|
|
104
|
+
const stack = held || known || element.hasAttribute(this.#record) ? this.#stack(element) : [];
|
|
105
|
+
const hold = this.#take(stack);
|
|
106
|
+
if (!hold) return;
|
|
107
|
+
const owns = this.#carries(element, hold) && !this.#covered(element, stack, hold);
|
|
108
|
+
const index = stack.indexOf(hold);
|
|
109
|
+
stack.splice(index, 1);
|
|
110
|
+
const above = stack[index];
|
|
111
|
+
if (above) above.linked &&= hold.linked;
|
|
112
|
+
this.#mark(element, stack);
|
|
113
|
+
if (!owns) return;
|
|
114
|
+
const below = hold.linked ? stack[index - 1] : void 0;
|
|
115
|
+
if (below) this.#show(element, below.writtenValue, below.writtenPriority);
|
|
116
|
+
else this.#show(element, hold.originalValue, hold.originalPriority);
|
|
68
117
|
}
|
|
69
|
-
/** Returns every outstanding declaration lease. */
|
|
70
118
|
returnAll() {
|
|
71
|
-
for (const element of Array.from(this.#
|
|
119
|
+
for (const element of Array.from(this.#held)) this.return(element);
|
|
120
|
+
}
|
|
121
|
+
#recorded(element, name) {
|
|
122
|
+
try {
|
|
123
|
+
const parsed = JSON.parse(element.getAttribute(name) ?? "null");
|
|
124
|
+
if (!Array.isArray(parsed)) return null;
|
|
125
|
+
const [originalValue, originalPriority, writtenValue, writtenPriority, ...rest] = parsed;
|
|
126
|
+
if (typeof originalValue !== "string" || typeof originalPriority !== "string") return null;
|
|
127
|
+
if (typeof writtenValue !== "string" && writtenValue !== null) return null;
|
|
128
|
+
if (typeof writtenPriority !== "string") return null;
|
|
129
|
+
const linked = rest[0] !== false;
|
|
130
|
+
const beneath = linked ? rest : rest.slice(1);
|
|
131
|
+
if (!beneath.every((under) => typeof under === "string")) return null;
|
|
132
|
+
return { originalValue, originalPriority, writtenValue, writtenPriority, linked, beneath };
|
|
133
|
+
} catch {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
#stack(element) {
|
|
138
|
+
const stacks = _StylePropertyLease.#registry.stacks;
|
|
139
|
+
const byProperty = stacks.get(element) ?? /* @__PURE__ */ new Map();
|
|
140
|
+
stacks.set(element, byProperty);
|
|
141
|
+
const stack = byProperty.get(this.#property) ?? this.#seed(element);
|
|
142
|
+
byProperty.set(this.#property, stack);
|
|
143
|
+
return stack;
|
|
144
|
+
}
|
|
145
|
+
#seed(element) {
|
|
146
|
+
const found = [];
|
|
147
|
+
for (const record of _StylePropertyLease.#registry.names.get(this.#property) ?? []) {
|
|
148
|
+
const read = this.#recorded(element, record);
|
|
149
|
+
if (read) found.push({ ...read, record });
|
|
150
|
+
}
|
|
151
|
+
const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
|
|
152
|
+
return found.sort((one, other) => depth(one) - depth(other)).map((entry, index) => ({
|
|
153
|
+
lease: null,
|
|
154
|
+
record: entry.record,
|
|
155
|
+
writtenValue: entry.writtenValue,
|
|
156
|
+
writtenPriority: entry.writtenPriority,
|
|
157
|
+
originalValue: entry.originalValue,
|
|
158
|
+
originalPriority: entry.originalPriority,
|
|
159
|
+
linked: entry.linked && index > 0
|
|
160
|
+
}));
|
|
161
|
+
}
|
|
162
|
+
#take(stack) {
|
|
163
|
+
const hold = stack.find((held) => held.lease === this) ?? stack.find((held) => held.lease === null && held.record === this.#record);
|
|
164
|
+
if (hold) hold.lease = this;
|
|
165
|
+
return hold;
|
|
72
166
|
}
|
|
73
|
-
|
|
74
|
-
|
|
167
|
+
#acquire(element, stack) {
|
|
168
|
+
const top = stack.at(-1);
|
|
169
|
+
const over = top && this.#carries(element, top) ? top : void 0;
|
|
75
170
|
const style = element.style;
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
171
|
+
const hold = {
|
|
172
|
+
lease: this,
|
|
173
|
+
record: this.#record,
|
|
174
|
+
writtenValue: null,
|
|
175
|
+
writtenPriority: "",
|
|
176
|
+
originalValue: over ? over.originalValue : style.getPropertyValue(this.#property),
|
|
177
|
+
originalPriority: over ? over.originalPriority : style.getPropertyPriority(this.#property),
|
|
178
|
+
linked: over !== void 0
|
|
179
|
+
};
|
|
180
|
+
stack.push(hold);
|
|
181
|
+
return hold;
|
|
182
|
+
}
|
|
183
|
+
#covered(element, stack, hold) {
|
|
184
|
+
return stack.slice(stack.indexOf(hold) + 1).some((above) => this.#carries(element, above));
|
|
185
|
+
}
|
|
186
|
+
#mark(element, stack) {
|
|
187
|
+
const records = /* @__PURE__ */ new Map([[this.#record, null]]);
|
|
188
|
+
stack.forEach((hold, index) => {
|
|
189
|
+
const names = stack.slice(0, index).map((under) => under.record);
|
|
190
|
+
const beneath = [...new Set(names.reverse())].filter((name) => name !== hold.record);
|
|
191
|
+
const marker = hold.linked || beneath.length === 0 ? [] : [false];
|
|
192
|
+
const { originalValue, originalPriority, writtenValue, writtenPriority } = hold;
|
|
193
|
+
records.set(
|
|
194
|
+
hold.record,
|
|
195
|
+
(writtenValue ?? "") === originalValue && writtenPriority === originalPriority && beneath.length === 0 && index === stack.length - 1 ? null : JSON.stringify([
|
|
196
|
+
originalValue,
|
|
197
|
+
originalPriority,
|
|
198
|
+
writtenValue,
|
|
199
|
+
writtenPriority,
|
|
200
|
+
...marker,
|
|
201
|
+
...beneath
|
|
202
|
+
])
|
|
203
|
+
);
|
|
204
|
+
});
|
|
205
|
+
for (const [name, recorded] of records) {
|
|
206
|
+
if (element.getAttribute(name) === recorded) continue;
|
|
207
|
+
if (recorded === null) element.removeAttribute(name);
|
|
208
|
+
else element.setAttribute(name, recorded);
|
|
80
209
|
}
|
|
81
|
-
|
|
82
|
-
|
|
210
|
+
}
|
|
211
|
+
#carries(element, hold) {
|
|
212
|
+
return this.#holds(element, hold.writtenValue ?? "", hold.writtenPriority);
|
|
213
|
+
}
|
|
214
|
+
#holds(element, value, priority) {
|
|
215
|
+
const style = element.style;
|
|
216
|
+
return style.getPropertyValue(this.#property) === value && style.getPropertyPriority(this.#property) === priority;
|
|
217
|
+
}
|
|
218
|
+
#show(element, value, priority) {
|
|
219
|
+
if (this.#holds(element, value ?? "", priority)) return;
|
|
220
|
+
if (value === null) element.style.removeProperty(this.#property);
|
|
221
|
+
else element.style.setProperty(this.#property, value, priority);
|
|
83
222
|
}
|
|
84
223
|
};
|
|
85
224
|
|
|
86
|
-
|
|
225
|
+
var TransientHooks = class {
|
|
226
|
+
#attributes;
|
|
227
|
+
constructor(options) {
|
|
228
|
+
this.#attributes = options.attributes;
|
|
229
|
+
}
|
|
230
|
+
reset(element) {
|
|
231
|
+
for (const attribute of this.#attributes) element.removeAttribute(attribute);
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
var TRANSIENT = new TransientHooks({ attributes: ["data-preview-hidden"] });
|
|
236
|
+
var CONTENT_RECORD = "content";
|
|
87
237
|
var PreviewGuardController = class extends Controller {
|
|
88
238
|
static values = {
|
|
89
239
|
placeholder: { type: String, default: "" }
|
|
90
240
|
};
|
|
91
241
|
static events = ["hide", "show"];
|
|
92
|
-
#visibility = new StylePropertyLease("visibility");
|
|
93
|
-
#beforeCache = new BeforeCacheReset(() => this.#restore());
|
|
242
|
+
#visibility = new StylePropertyLease("visibility", this.identifier);
|
|
94
243
|
#observer = null;
|
|
95
244
|
#connected = false;
|
|
96
245
|
#hidden = false;
|
|
97
|
-
/** Child nodes a placeholder displaced; non-null marks that content — not visibility — was swapped. */
|
|
98
246
|
#savedNodes = null;
|
|
99
|
-
/** The descendant that held focus when the guard went up, so show can hand it back. */
|
|
100
247
|
#focused = null;
|
|
248
|
+
#morphRender = new MorphRenderWatcher(() => {
|
|
249
|
+
this.#sync();
|
|
250
|
+
if (this.#hidden) this.#reguard();
|
|
251
|
+
});
|
|
101
252
|
connect() {
|
|
253
|
+
this.#morphRender.observe(this.element);
|
|
102
254
|
this.#connected = true;
|
|
103
|
-
if (this.#hidden)
|
|
104
|
-
|
|
105
|
-
|
|
255
|
+
if (this.#hidden) {
|
|
256
|
+
this.#reguard();
|
|
257
|
+
} else {
|
|
258
|
+
if (this.element.hasAttribute("data-preview-hidden")) this.#restoreRecordedContent();
|
|
259
|
+
this.#visibility.return(this.element);
|
|
260
|
+
TRANSIENT.reset(this.element);
|
|
261
|
+
}
|
|
106
262
|
if (typeof MutationObserver !== "undefined") {
|
|
107
263
|
this.#observer = new MutationObserver(() => this.#sync());
|
|
108
264
|
this.#observer.observe(document.documentElement, {
|
|
@@ -113,24 +269,15 @@ var PreviewGuardController = class extends Controller {
|
|
|
113
269
|
this.#sync();
|
|
114
270
|
}
|
|
115
271
|
disconnect() {
|
|
272
|
+
this.#morphRender.disconnect();
|
|
116
273
|
this.#connected = false;
|
|
117
|
-
this.#beforeCache.deactivate();
|
|
118
274
|
this.#observer?.disconnect();
|
|
119
275
|
this.#observer = null;
|
|
120
276
|
}
|
|
121
|
-
/**
|
|
122
|
-
* Re-guards to match a `placeholder` changed at runtime — the value is the content on
|
|
123
|
-
* display while the guard is up, so a morph that swaps it must not leave the old one.
|
|
124
|
-
*/
|
|
125
277
|
placeholderValueChanged() {
|
|
126
278
|
if (!this.#connected || !this.#hidden) return;
|
|
127
279
|
this.#reguard();
|
|
128
280
|
}
|
|
129
|
-
/**
|
|
130
|
-
* Reflects the current `data-turbo-preview` state onto the element.
|
|
131
|
-
*
|
|
132
|
-
* @stimeoRenderRoot
|
|
133
|
-
*/
|
|
134
281
|
#sync() {
|
|
135
282
|
const previewing = document.documentElement.hasAttribute("data-turbo-preview");
|
|
136
283
|
if (previewing && !this.#hidden) this.#hide();
|
|
@@ -141,28 +288,33 @@ var PreviewGuardController = class extends Controller {
|
|
|
141
288
|
this.#applyGuard();
|
|
142
289
|
this.dispatch("hide", { detail: {} });
|
|
143
290
|
}
|
|
144
|
-
/** Puts the guard up in the form the current `placeholder` calls for. */
|
|
145
291
|
#applyGuard() {
|
|
146
292
|
this.#hidden = true;
|
|
147
293
|
if (this.placeholderValue === "") {
|
|
148
294
|
this.#visibility.write(this.element, "hidden");
|
|
149
295
|
} else {
|
|
296
|
+
this.element.setAttribute(this.#contentRecord, JSON.stringify(this.element.innerHTML));
|
|
150
297
|
this.#savedNodes = document.createDocumentFragment();
|
|
151
298
|
this.#savedNodes.append(...this.element.childNodes);
|
|
152
299
|
this.element.textContent = this.placeholderValue;
|
|
153
300
|
}
|
|
154
301
|
this.element.setAttribute("data-preview-hidden", "true");
|
|
155
302
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
303
|
+
get #contentRecord() {
|
|
304
|
+
return `data-${this.identifier}-${CONTENT_RECORD}`;
|
|
305
|
+
}
|
|
306
|
+
#restoreRecordedContent() {
|
|
307
|
+
const raw = this.element.getAttribute(this.#contentRecord) ?? "null";
|
|
308
|
+
this.element.removeAttribute(this.#contentRecord);
|
|
309
|
+
let content = null;
|
|
310
|
+
try {
|
|
311
|
+
content = JSON.parse(raw);
|
|
312
|
+
} catch {
|
|
313
|
+
}
|
|
314
|
+
if (typeof content === "string") this.element.innerHTML = content;
|
|
315
|
+
}
|
|
165
316
|
#reguard() {
|
|
317
|
+
this.element.setAttribute("data-preview-hidden", "true");
|
|
166
318
|
if (this.#savedNodes && this.placeholderValue !== "") {
|
|
167
319
|
this.element.textContent = this.placeholderValue;
|
|
168
320
|
return;
|
|
@@ -176,46 +328,26 @@ var PreviewGuardController = class extends Controller {
|
|
|
176
328
|
this.#restore();
|
|
177
329
|
this.dispatch("show", { detail: {} });
|
|
178
330
|
}
|
|
179
|
-
/** Reverts the guard and hands focus back. Used by show and by the snapshot rewind. */
|
|
180
331
|
#restore() {
|
|
181
332
|
this.#revert();
|
|
182
333
|
this.#refocus();
|
|
183
334
|
}
|
|
184
|
-
/**
|
|
185
|
-
* Puts the element back the way the guard found it.
|
|
186
|
-
*
|
|
187
|
-
* Every step is a no-op on an element this controller never guarded: the lease returns
|
|
188
|
-
* only declarations it recorded, and the hook is removed whether or not it is there.
|
|
189
|
-
*/
|
|
190
335
|
#revert() {
|
|
191
336
|
this.#hidden = false;
|
|
192
337
|
if (this.#savedNodes) {
|
|
193
338
|
this.element.textContent = "";
|
|
194
339
|
this.element.append(this.#savedNodes);
|
|
195
340
|
this.#savedNodes = null;
|
|
341
|
+
this.element.removeAttribute(this.#contentRecord);
|
|
196
342
|
} else {
|
|
197
343
|
this.#visibility.return(this.element);
|
|
198
344
|
}
|
|
199
345
|
this.element.removeAttribute("data-preview-hidden");
|
|
200
346
|
}
|
|
201
|
-
/**
|
|
202
|
-
* The focused element the guard is about to make unfocusable, if any.
|
|
203
|
-
*
|
|
204
|
-
* The element itself counts as well as its descendants: guarding takes focus either way
|
|
205
|
-
* — a `visibility: hidden` subtree cannot hold it, and a placeholder displaces the nodes
|
|
206
|
-
* outright — so the browser drops focus to `<body>` the moment the guard goes up.
|
|
207
|
-
*/
|
|
208
347
|
#focusedInside() {
|
|
209
348
|
const active = document.activeElement;
|
|
210
349
|
return active instanceof HTMLElement && this.element.contains(active) ? active : null;
|
|
211
350
|
}
|
|
212
|
-
/**
|
|
213
|
-
* Hands focus back to the element the guard took it from.
|
|
214
|
-
*
|
|
215
|
-
* Only when that element is still in the document and focus has not moved on since —
|
|
216
|
-
* anything else is the user's or another controller's, and putting it back would be
|
|
217
|
-
* taking it.
|
|
218
|
-
*/
|
|
219
351
|
#refocus() {
|
|
220
352
|
const target = this.#focused;
|
|
221
353
|
this.#focused = null;
|
|
@@ -225,5 +357,4 @@ var PreviewGuardController = class extends Controller {
|
|
|
225
357
|
};
|
|
226
358
|
|
|
227
359
|
export { PreviewGuardController };
|
|
228
|
-
//# sourceMappingURL=preview_guard_controller.js.map
|
|
229
360
|
//# sourceMappingURL=preview_guard_controller.js.map
|