stimeo-ui 0.5.0 → 0.6.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 +116 -0
- data/dist/controllers/aspect_ratio_controller.js +19 -11
- data/dist/controllers/avatar_controller.js +195 -40
- data/dist/controllers/carousel_controller.js +85 -9
- data/dist/controllers/checkbox_controller.js +136 -25
- data/dist/controllers/color_picker_controller.js +35 -9
- data/dist/controllers/date_range_picker_controller.js +157 -30
- data/dist/controllers/file_dropzone_controller.js +26 -3
- data/dist/controllers/idle_controller.js +27 -5
- data/dist/controllers/menubar_controller.js +5 -3
- data/dist/controllers/multi_select_controller.js +460 -151
- data/dist/controllers/number_input_controller.js +275 -51
- data/dist/controllers/overflow_menu_controller.js +4 -0
- data/dist/controllers/pagination_controller.js +33 -0
- data/dist/controllers/password_strength_controller.js +20 -2
- data/dist/controllers/persist_controller.js +24 -5
- data/dist/controllers/radio_group_controller.js +540 -56
- data/dist/controllers/rating_controller.js +272 -89
- data/dist/controllers/resizable_controller.js +33 -0
- data/dist/controllers/roving_controller.js +60 -5
- data/dist/controllers/scroll_area_controller.js +154 -22
- data/dist/controllers/scroll_visibility_controller.js +33 -0
- data/dist/controllers/tags_input_controller.js +356 -120
- data/dist/controllers/time_picker_controller.js +296 -107
- data/dist/controllers/toggle_group_controller.js +378 -55
- data/dist/controllers/toolbar_controller.js +5 -3
- data/dist/controllers/tree_view_controller.js +5 -3
- data/dist/index.js +2637 -781
- data/lib/stimeo/ui/version.rb +1 -1
- metadata +2 -2
|
@@ -12,18 +12,38 @@ var FileDropzoneController = class extends Controller {
|
|
|
12
12
|
static events = ["change", "reject"];
|
|
13
13
|
/** Selected files paired with their rendered item and any preview objectURL. */
|
|
14
14
|
#entries = [];
|
|
15
|
+
/** Prevents initial and teardown target callbacks from binding outside controller lifetime. */
|
|
16
|
+
#connected = false;
|
|
15
17
|
/** Wires file removal as a delegated listener on the list container. */
|
|
16
18
|
connect() {
|
|
17
|
-
|
|
19
|
+
this.#connected = true;
|
|
20
|
+
if (this.hasListTarget) this.#bindList(this.listTarget);
|
|
18
21
|
}
|
|
19
22
|
/** Revokes any outstanding preview URLs so none leaks across navigations. */
|
|
20
23
|
disconnect() {
|
|
21
|
-
|
|
24
|
+
this.#connected = false;
|
|
25
|
+
for (const list of this.listTargets) list.removeEventListener("click", this.#onItemClick);
|
|
22
26
|
for (const entry of this.#entries) {
|
|
23
27
|
if (entry.url) URL.revokeObjectURL(entry.url);
|
|
24
28
|
}
|
|
25
29
|
this.#entries.length = 0;
|
|
26
30
|
}
|
|
31
|
+
/** Rebinds removal and restores client-only previews when Turbo replaces the list target. */
|
|
32
|
+
listTargetConnected(list) {
|
|
33
|
+
if (!this.#connected) return;
|
|
34
|
+
this.#bindList(list);
|
|
35
|
+
}
|
|
36
|
+
/** Releases only the list target that actually disconnected. */
|
|
37
|
+
listTargetDisconnected(list) {
|
|
38
|
+
list.removeEventListener("click", this.#onItemClick);
|
|
39
|
+
}
|
|
40
|
+
/** Binds delegated removal once and moves live preview items into the current list. */
|
|
41
|
+
#bindList(list) {
|
|
42
|
+
list.addEventListener("click", this.#onItemClick);
|
|
43
|
+
for (const entry of this.#entries) {
|
|
44
|
+
if (!list.contains(entry.item)) list.appendChild(entry.item);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
27
47
|
/** Opens the native file dialog. Bound via `data-action` (trigger click). */
|
|
28
48
|
openDialog() {
|
|
29
49
|
this.inputTarget.click();
|
|
@@ -55,8 +75,11 @@ var FileDropzoneController = class extends Controller {
|
|
|
55
75
|
* an item is appended without waiting on Stimulus to wire a freshly created element.
|
|
56
76
|
*/
|
|
57
77
|
#onItemClick = (event) => {
|
|
78
|
+
const list = event.currentTarget;
|
|
58
79
|
const button = event.target.closest("button");
|
|
59
|
-
if (!button || !this.hasListTarget ||
|
|
80
|
+
if (!this.#connected || !list || !button || !this.hasListTarget || list !== this.listTarget || !list.contains(button)) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
60
83
|
const index = this.#entries.findIndex((entry) => entry.item.contains(button));
|
|
61
84
|
if (index !== -1) this.#removeAt(index);
|
|
62
85
|
};
|
|
@@ -55,15 +55,37 @@ var SafeTimeout = class extends TimerRegistry {
|
|
|
55
55
|
}
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
+
// src/utils/string_list.ts
|
|
59
|
+
function parseStringList(raw, fallback = []) {
|
|
60
|
+
const text = raw.trim();
|
|
61
|
+
if (text.length === 0) return [...fallback];
|
|
62
|
+
let parsed;
|
|
63
|
+
try {
|
|
64
|
+
parsed = JSON.parse(text);
|
|
65
|
+
} catch {
|
|
66
|
+
return [...fallback];
|
|
67
|
+
}
|
|
68
|
+
if (!Array.isArray(parsed)) return [...fallback];
|
|
69
|
+
return parsed.filter((entry) => typeof entry === "string");
|
|
70
|
+
}
|
|
71
|
+
|
|
58
72
|
// src/controllers/idle_controller.ts
|
|
73
|
+
var DEFAULT_ACTIVITY_EVENTS = [
|
|
74
|
+
"mousemove",
|
|
75
|
+
"mousedown",
|
|
76
|
+
"keydown",
|
|
77
|
+
"wheel",
|
|
78
|
+
"touchstart",
|
|
79
|
+
"scroll"
|
|
80
|
+
];
|
|
59
81
|
var IdleController = class extends Controller {
|
|
60
82
|
static values = {
|
|
61
83
|
timeout: { type: Number, default: 9e5 },
|
|
62
84
|
promptBefore: { type: Number, default: 0 },
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
85
|
+
// A JSON list read through `parseStringList` rather than Stimulus's `Array`
|
|
86
|
+
// type: that reader throws out of the value observer before any callback
|
|
87
|
+
// runs, so one malformed attribute would stop the detector connecting.
|
|
88
|
+
events: { type: String, default: "" }
|
|
67
89
|
};
|
|
68
90
|
static events = ["prompt", "idle", "active"];
|
|
69
91
|
#timeouts = new SafeTimeout();
|
|
@@ -94,7 +116,7 @@ var IdleController = class extends Controller {
|
|
|
94
116
|
this.#idle = false;
|
|
95
117
|
this.#prompted = false;
|
|
96
118
|
this.element.removeAttribute("data-idle");
|
|
97
|
-
this.#boundEvents =
|
|
119
|
+
this.#boundEvents = parseStringList(this.eventsValue, DEFAULT_ACTIVITY_EVENTS);
|
|
98
120
|
for (const type of this.#boundEvents) {
|
|
99
121
|
document.addEventListener(type, this.#onActivity, { passive: true, capture: true });
|
|
100
122
|
}
|
|
@@ -125,10 +125,12 @@ var RovingTabindex = class {
|
|
|
125
125
|
* "nothing is currently tabbable".
|
|
126
126
|
*
|
|
127
127
|
* @param index - Position of the item to make tabbable.
|
|
128
|
-
* @param options - Pass `{ focus: true }` to also move DOM focus to that item
|
|
128
|
+
* @param options - Pass `{ focus: true }` to also move DOM focus to that item,
|
|
129
|
+
* and `items` to reuse an event-scoped collection snapshot.
|
|
129
130
|
*/
|
|
130
|
-
setActive(index,
|
|
131
|
-
const
|
|
131
|
+
setActive(index, options = {}) {
|
|
132
|
+
const { focus = false } = options;
|
|
133
|
+
const items = options.items ?? this.#getItems();
|
|
132
134
|
items.forEach((item, i) => {
|
|
133
135
|
item.tabIndex = i === index ? 0 : -1;
|
|
134
136
|
});
|