@wpmoo/ui 1.3.0 → 1.4.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/ASSET_LICENSE.md +1 -1
- package/README.md +28 -4
- package/certification.json +2 -1
- package/dist/assets/css/moo-ui.css +149 -13
- package/dist/assets/css/moo-ui.min.css +2 -2
- package/dist/assets/css/moo.css +137 -1
- package/dist/assets/css/moo.min.css +2 -2
- package/dist/js/chart.js +1 -1
- package/dist/js/chart.min.js +1 -1
- package/dist/js/combobox.js +1 -1
- package/dist/js/context-menu.js +1 -1
- package/dist/js/datatable.js +1 -1
- package/dist/js/datepicker.js +1 -1
- package/dist/js/datepicker.min.js +1 -1
- package/dist/js/moo-ui.js +304 -1
- package/dist/js/moo-ui.min.js +2 -2
- package/dist/js/overlay-scrollbar.js +308 -0
- package/dist/js/sheet.js +1 -1
- package/dist/js/sidebar.js +1 -1
- package/dist/js/slider.js +1 -1
- package/dist/js/state.js +1 -1
- package/dist/js/table-of-contents.js +1 -1
- package/dist/js/toc.js +1 -1
- package/dist/release-manifest.json +4 -4
- package/package.json +3 -1
- package/scss/foundations/_globals.scss +1 -0
- package/scss/foundations/_scope.scss +2 -0
- package/scss/mixins/_banner.scss +1 -1
- package/scss/moo-core.scss +2 -0
- package/scss/moo-ui.scss +3 -0
- package/scss/settings/_component_variables.scss +2 -0
- package/scss/utilities/_overlay_scrollbar.scss +68 -0
- package/scss/utilities/_overlay_scrollbar_native.scss +1 -0
- package/scss/utilities/_text_alignment.scss +29 -0
package/dist/js/chart.js
CHANGED
package/dist/js/chart.min.js
CHANGED
package/dist/js/combobox.js
CHANGED
package/dist/js/context-menu.js
CHANGED
package/dist/js/datatable.js
CHANGED
package/dist/js/datepicker.js
CHANGED
package/dist/js/moo-ui.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Moo UI moo-ui.js v1.
|
|
2
|
+
* Moo UI moo-ui.js v1.4.0 (https://wpmoo.org/)
|
|
3
3
|
* Copyright 2026 WPMoo Authors
|
|
4
4
|
* Licensed under MIT (https://github.com/wpmoo-org/ui/blob/main/LICENSE)
|
|
5
5
|
*/
|
|
@@ -4068,6 +4068,307 @@ var TableOfContents = class _TableOfContents {
|
|
|
4068
4068
|
}
|
|
4069
4069
|
};
|
|
4070
4070
|
|
|
4071
|
+
// src/js/components/overlay-scrollbar.js
|
|
4072
|
+
var instances7 = /* @__PURE__ */ new WeakMap();
|
|
4073
|
+
var nextId = 0;
|
|
4074
|
+
var OverlayScrollbar = class _OverlayScrollbar {
|
|
4075
|
+
static getInstance(owner, scrollElement = owner?.ownerDocument?.scrollingElement) {
|
|
4076
|
+
const instance = scrollElement && instances7.get(scrollElement);
|
|
4077
|
+
return instance?._owner === owner ? instance : null;
|
|
4078
|
+
}
|
|
4079
|
+
static getOrCreateInstance(owner, options = {}) {
|
|
4080
|
+
return _OverlayScrollbar.getInstance(owner, options.scrollElement) || new _OverlayScrollbar(owner, options);
|
|
4081
|
+
}
|
|
4082
|
+
constructor(owner, { scrollElement = null, hideDelay = 900, label = "Page scroll position" } = {}) {
|
|
4083
|
+
if (!owner?.matches?.('.moo-ui[data-bs-theme="light"], .moo-ui[data-bs-theme="dark"]') || !owner.isConnected) {
|
|
4084
|
+
throw new TypeError("OverlayScrollbar requires a connected, resolved .moo-ui theme owner.");
|
|
4085
|
+
}
|
|
4086
|
+
if (!Number.isFinite(hideDelay) || hideDelay < 0 || typeof label !== "string" || !label.trim()) {
|
|
4087
|
+
throw new TypeError("OverlayScrollbar requires a nonnegative hideDelay and a nonempty label.");
|
|
4088
|
+
}
|
|
4089
|
+
const document2 = owner.ownerDocument;
|
|
4090
|
+
const root = scrollElement ?? document2.scrollingElement;
|
|
4091
|
+
const isDocument = root === document2.scrollingElement;
|
|
4092
|
+
if (root?.nodeType !== 1 || !root.isConnected || root.ownerDocument !== document2 || !isDocument && (!owner.contains(root) || root.closest('.moo-ui[data-bs-theme="light"], .moo-ui[data-bs-theme="dark"]') !== owner)) {
|
|
4093
|
+
throw new TypeError("OverlayScrollbar scrollElement must belong to the same resolved theme owner.");
|
|
4094
|
+
}
|
|
4095
|
+
const existing = instances7.get(root);
|
|
4096
|
+
if (existing) {
|
|
4097
|
+
if (existing._owner === owner) return existing;
|
|
4098
|
+
throw new Error("Only one OverlayScrollbar theme owner may control a scroll element.");
|
|
4099
|
+
}
|
|
4100
|
+
this._owner = owner;
|
|
4101
|
+
this._document = document2;
|
|
4102
|
+
this._window = document2.defaultView;
|
|
4103
|
+
this._root = root;
|
|
4104
|
+
this._isDocument = isDocument;
|
|
4105
|
+
if (isDocument && root !== document2.documentElement) {
|
|
4106
|
+
throw new TypeError("OverlayScrollbar requires a standards-mode document scroll root.");
|
|
4107
|
+
}
|
|
4108
|
+
this._hideDelay = hideDelay;
|
|
4109
|
+
this._listeners = [];
|
|
4110
|
+
this._frame = 0;
|
|
4111
|
+
this._timer = 0;
|
|
4112
|
+
this._disposed = false;
|
|
4113
|
+
this._originalNativeClass = this._root.classList.contains("scrollbar-overlay-native");
|
|
4114
|
+
this._originalId = this._root.getAttribute("id");
|
|
4115
|
+
this._forcedColors = this._window.matchMedia("(forced-colors: active)");
|
|
4116
|
+
this._bar = document2.createElement("div");
|
|
4117
|
+
this._bar.className = "scrollbar-overlay";
|
|
4118
|
+
this._bar.tabIndex = 0;
|
|
4119
|
+
this._bar.setAttribute("role", "scrollbar");
|
|
4120
|
+
this._bar.setAttribute("aria-label", label);
|
|
4121
|
+
this._bar.setAttribute("aria-orientation", "vertical");
|
|
4122
|
+
this._bar.setAttribute("aria-valuemin", "0");
|
|
4123
|
+
this._thumb = document2.createElement("div");
|
|
4124
|
+
this._thumb.className = "scrollbar-overlay-thumb";
|
|
4125
|
+
this._thumb.setAttribute("aria-hidden", "true");
|
|
4126
|
+
this._bar.append(this._thumb);
|
|
4127
|
+
owner.append(this._bar);
|
|
4128
|
+
if (this._window.getComputedStyle(this._bar).position !== "fixed") {
|
|
4129
|
+
this._bar.remove();
|
|
4130
|
+
throw new Error("OverlayScrollbar requires the Moo UI overlay scrollbar stylesheet.");
|
|
4131
|
+
}
|
|
4132
|
+
if (!this._originalId) {
|
|
4133
|
+
do {
|
|
4134
|
+
this._generatedId = `scrollbar-overlay-page-${++nextId}`;
|
|
4135
|
+
} while (document2.getElementById(this._generatedId));
|
|
4136
|
+
this._root.id = this._generatedId;
|
|
4137
|
+
}
|
|
4138
|
+
this._bar.setAttribute("aria-controls", this._root.id);
|
|
4139
|
+
instances7.set(root, this);
|
|
4140
|
+
try {
|
|
4141
|
+
this._listen(isDocument ? this._window : root, "scroll", () => {
|
|
4142
|
+
this._reveal();
|
|
4143
|
+
this._queue();
|
|
4144
|
+
}, { passive: true });
|
|
4145
|
+
if (!isDocument) {
|
|
4146
|
+
this._listen(document2, "scroll", () => this._queue(), { passive: true, capture: true });
|
|
4147
|
+
}
|
|
4148
|
+
this._listen(this._window, "resize", () => this._queue());
|
|
4149
|
+
this._listen(document2, "pointermove", (event) => this._onPointerMove(event), { passive: true });
|
|
4150
|
+
this._listen(document2, "pointerout", (event) => {
|
|
4151
|
+
if (event.pointerType === "mouse" && !event.relatedTarget) {
|
|
4152
|
+
this._nearEdge = false;
|
|
4153
|
+
if (!this._drag) delete this._bar.dataset.scrollbarInteractive;
|
|
4154
|
+
this._hideLater();
|
|
4155
|
+
}
|
|
4156
|
+
});
|
|
4157
|
+
this._listen(this._bar, "pointerdown", (event) => this._onPointerDown(event));
|
|
4158
|
+
this._listen(this._bar, "pointerup", () => this._finishDrag());
|
|
4159
|
+
this._listen(this._bar, "pointercancel", () => this._finishDrag());
|
|
4160
|
+
this._listen(this._bar, "lostpointercapture", () => this._finishDrag());
|
|
4161
|
+
this._listen(this._bar, "focus", () => this._reveal());
|
|
4162
|
+
this._listen(this._bar, "blur", () => this._hideLater());
|
|
4163
|
+
this._listen(this._bar, "keydown", (event) => this._onKeyDown(event));
|
|
4164
|
+
this._listen(this._forcedColors, "change", () => this.refresh());
|
|
4165
|
+
this._listen(this._window, "beforeprint", () => {
|
|
4166
|
+
this._printing = true;
|
|
4167
|
+
this.refresh();
|
|
4168
|
+
});
|
|
4169
|
+
this._listen(this._window, "afterprint", () => {
|
|
4170
|
+
this._printing = false;
|
|
4171
|
+
this.refresh();
|
|
4172
|
+
});
|
|
4173
|
+
this._resize = new this._window.ResizeObserver(() => this._queue());
|
|
4174
|
+
this._resize.observe(this._root);
|
|
4175
|
+
this._resize.observe(document2.body);
|
|
4176
|
+
this._mutations = new this._window.MutationObserver(() => this._queue());
|
|
4177
|
+
this._mutations.observe(this._root, { attributes: true, attributeFilter: ["class", "style", "dir"] });
|
|
4178
|
+
if (!isDocument) {
|
|
4179
|
+
this._mutations.observe(document2.documentElement, { attributes: true, attributeFilter: ["class", "style", "dir"] });
|
|
4180
|
+
}
|
|
4181
|
+
this._mutations.observe(document2.body, {
|
|
4182
|
+
attributes: true,
|
|
4183
|
+
attributeFilter: ["class", "style"]
|
|
4184
|
+
});
|
|
4185
|
+
this._mutations.observe(owner, { attributes: true, attributeFilter: ["class", "style", "dir", "data-bs-theme"] });
|
|
4186
|
+
this._contentMutations = new this._window.MutationObserver((records) => {
|
|
4187
|
+
if (records.some((record) => record.target !== this._bar && !this._bar.contains(record.target))) this._queue();
|
|
4188
|
+
});
|
|
4189
|
+
this._contentMutations.observe(isDocument ? document2.body : root, {
|
|
4190
|
+
childList: true,
|
|
4191
|
+
subtree: true,
|
|
4192
|
+
attributes: true,
|
|
4193
|
+
attributeFilter: ["class", "style", "hidden"]
|
|
4194
|
+
});
|
|
4195
|
+
this._listen(root, "load", () => this._queue(), { capture: true });
|
|
4196
|
+
if (document2.fonts) this._listen(document2.fonts, "loadingdone", () => this._queue());
|
|
4197
|
+
this.refresh();
|
|
4198
|
+
} catch (error) {
|
|
4199
|
+
this.dispose();
|
|
4200
|
+
throw error;
|
|
4201
|
+
}
|
|
4202
|
+
}
|
|
4203
|
+
refresh() {
|
|
4204
|
+
if (this._disposed) return this;
|
|
4205
|
+
const window2 = this._window;
|
|
4206
|
+
const root = this._root;
|
|
4207
|
+
const eligible = !this._forcedColors.matches && !this._printing;
|
|
4208
|
+
if (eligible) root.classList.add("scrollbar-overlay-native");
|
|
4209
|
+
const enabled = eligible && root.scrollWidth <= root.clientWidth + 1;
|
|
4210
|
+
root.classList.toggle("scrollbar-overlay-native", this._originalNativeClass || enabled);
|
|
4211
|
+
this._mutations?.takeRecords();
|
|
4212
|
+
this._contentMutations?.takeRecords();
|
|
4213
|
+
const locked = (this._isDocument ? [root, this._document.body] : [root]).some((element) => ["hidden", "clip"].includes(window2.getComputedStyle(element).overflowY));
|
|
4214
|
+
this._maximum = Math.max(0, root.scrollHeight - root.clientHeight);
|
|
4215
|
+
const visible = this._position();
|
|
4216
|
+
this._bar.hidden = !enabled || locked || !visible || this._maximum <= 0;
|
|
4217
|
+
if (this._bar.hidden) {
|
|
4218
|
+
if (this._document.activeElement === this._bar) this._bar.blur();
|
|
4219
|
+
delete this._bar.dataset.scrollbarVisible;
|
|
4220
|
+
delete this._bar.dataset.scrollbarInteractive;
|
|
4221
|
+
return this;
|
|
4222
|
+
}
|
|
4223
|
+
const minimum = this._bar.clientWidth;
|
|
4224
|
+
const height = this._bar.clientHeight;
|
|
4225
|
+
const thumbHeight = Math.min(height, Math.max(minimum, height * root.clientHeight / root.scrollHeight));
|
|
4226
|
+
this._travel = Math.max(0, height - thumbHeight);
|
|
4227
|
+
const position = Math.min(this._maximum, Math.max(0, root.scrollTop));
|
|
4228
|
+
this._thumb.style.height = `${thumbHeight}px`;
|
|
4229
|
+
this._thumb.style.transform = `translateY(${this._travel * position / this._maximum}px)`;
|
|
4230
|
+
this._bar.setAttribute("aria-valuemax", String(Math.round(this._maximum)));
|
|
4231
|
+
this._bar.setAttribute("aria-valuenow", String(Math.round(position)));
|
|
4232
|
+
return this;
|
|
4233
|
+
}
|
|
4234
|
+
_position() {
|
|
4235
|
+
if (this._isDocument) return true;
|
|
4236
|
+
const root = this._root;
|
|
4237
|
+
const bounds = root.getBoundingClientRect();
|
|
4238
|
+
const top = Math.max(0, bounds.top + root.clientTop);
|
|
4239
|
+
const bottom = Math.min(this._window.innerHeight, bounds.top + root.clientTop + root.clientHeight);
|
|
4240
|
+
const width = parseFloat(this._window.getComputedStyle(this._bar).inlineSize);
|
|
4241
|
+
const rtl = this._window.getComputedStyle(root).direction === "rtl";
|
|
4242
|
+
const left = bounds.left + root.clientLeft + (rtl ? 0 : root.clientWidth - width);
|
|
4243
|
+
Object.assign(this._bar.style, {
|
|
4244
|
+
insetInlineEnd: "auto",
|
|
4245
|
+
bottom: "auto",
|
|
4246
|
+
top: `${top}px`,
|
|
4247
|
+
height: `${Math.max(0, bottom - top)}px`,
|
|
4248
|
+
left: `${Math.max(0, Math.min(this._window.innerWidth - width, left))}px`,
|
|
4249
|
+
direction: rtl ? "rtl" : "ltr"
|
|
4250
|
+
});
|
|
4251
|
+
return bounds.width > 0 && bottom > top && left < this._window.innerWidth && left + width > 0;
|
|
4252
|
+
}
|
|
4253
|
+
dispose() {
|
|
4254
|
+
if (this._disposed) return;
|
|
4255
|
+
this._disposed = true;
|
|
4256
|
+
for (const [target, type, handler, options] of this._listeners) {
|
|
4257
|
+
target.removeEventListener(type, handler, options);
|
|
4258
|
+
}
|
|
4259
|
+
this._listeners = [];
|
|
4260
|
+
this._resize?.disconnect();
|
|
4261
|
+
this._mutations?.disconnect();
|
|
4262
|
+
this._contentMutations?.disconnect();
|
|
4263
|
+
this._window.cancelAnimationFrame(this._frame);
|
|
4264
|
+
this._window.clearTimeout(this._timer);
|
|
4265
|
+
if (this._drag && this._bar.hasPointerCapture(this._drag.id)) this._bar.releasePointerCapture(this._drag.id);
|
|
4266
|
+
this._drag = null;
|
|
4267
|
+
this._bar.remove();
|
|
4268
|
+
this._root.classList.toggle("scrollbar-overlay-native", this._originalNativeClass);
|
|
4269
|
+
if (this._generatedId && this._root.id === this._generatedId) {
|
|
4270
|
+
if (this._originalId === null) this._root.removeAttribute("id");
|
|
4271
|
+
else this._root.setAttribute("id", this._originalId);
|
|
4272
|
+
}
|
|
4273
|
+
if (instances7.get(this._root) === this) instances7.delete(this._root);
|
|
4274
|
+
}
|
|
4275
|
+
_listen(target, type, handler, options) {
|
|
4276
|
+
target.addEventListener(type, handler, options);
|
|
4277
|
+
this._listeners.push([target, type, handler, options]);
|
|
4278
|
+
}
|
|
4279
|
+
_queue() {
|
|
4280
|
+
if (this._disposed || this._frame) return;
|
|
4281
|
+
this._frame = this._window.requestAnimationFrame(() => {
|
|
4282
|
+
this._frame = 0;
|
|
4283
|
+
this.refresh();
|
|
4284
|
+
});
|
|
4285
|
+
}
|
|
4286
|
+
_reveal() {
|
|
4287
|
+
if (this._disposed || this._bar.hidden) return;
|
|
4288
|
+
this._bar.dataset.scrollbarVisible = "true";
|
|
4289
|
+
this._hideLater();
|
|
4290
|
+
}
|
|
4291
|
+
_hideLater() {
|
|
4292
|
+
this._window.clearTimeout(this._timer);
|
|
4293
|
+
this._timer = 0;
|
|
4294
|
+
if (this._disposed) return;
|
|
4295
|
+
if (!this._bar.hasAttribute("data-scrollbar-visible")) return;
|
|
4296
|
+
this._timer = this._window.setTimeout(() => {
|
|
4297
|
+
this._timer = 0;
|
|
4298
|
+
if (this._disposed || this._nearEdge || this._drag || this._bar.matches(":focus-visible")) return;
|
|
4299
|
+
delete this._bar.dataset.scrollbarVisible;
|
|
4300
|
+
}, this._hideDelay);
|
|
4301
|
+
}
|
|
4302
|
+
_onPointerMove(event) {
|
|
4303
|
+
if (this._disposed) return;
|
|
4304
|
+
if (this._drag?.id === event.pointerId) {
|
|
4305
|
+
if (this._travel) this._scroll(this._drag.top + (event.clientY - this._drag.y) * this._maximum / this._travel);
|
|
4306
|
+
return;
|
|
4307
|
+
}
|
|
4308
|
+
if (event.pointerType !== "mouse") {
|
|
4309
|
+
this._nearEdge = false;
|
|
4310
|
+
if (!this._drag) delete this._bar.dataset.scrollbarInteractive;
|
|
4311
|
+
return;
|
|
4312
|
+
}
|
|
4313
|
+
const bounds = this._bar.getBoundingClientRect();
|
|
4314
|
+
const nearEdge = !this._bar.hidden && event.clientX >= bounds.left && event.clientX <= bounds.right && event.clientY >= bounds.top && event.clientY <= bounds.bottom;
|
|
4315
|
+
if (nearEdge) {
|
|
4316
|
+
this._nearEdge = true;
|
|
4317
|
+
this._bar.dataset.scrollbarInteractive = "true";
|
|
4318
|
+
this._reveal();
|
|
4319
|
+
} else if (this._nearEdge) {
|
|
4320
|
+
this._nearEdge = false;
|
|
4321
|
+
if (!this._drag) delete this._bar.dataset.scrollbarInteractive;
|
|
4322
|
+
this._hideLater();
|
|
4323
|
+
}
|
|
4324
|
+
}
|
|
4325
|
+
_onPointerDown(event) {
|
|
4326
|
+
if (event.button !== 0 || this._bar.hidden || event.pointerType === "touch") return;
|
|
4327
|
+
event.preventDefault();
|
|
4328
|
+
this._reveal();
|
|
4329
|
+
const thumb = this._thumb.getBoundingClientRect();
|
|
4330
|
+
if (event.clientY >= thumb.top && event.clientY <= thumb.bottom) {
|
|
4331
|
+
this._drag = { id: event.pointerId, y: event.clientY, top: this._root.scrollTop };
|
|
4332
|
+
this._bar.setPointerCapture(event.pointerId);
|
|
4333
|
+
} else {
|
|
4334
|
+
const direction = event.clientY < this._thumb.getBoundingClientRect().top ? -1 : 1;
|
|
4335
|
+
this._scroll(this._root.scrollTop + direction * this._root.clientHeight);
|
|
4336
|
+
}
|
|
4337
|
+
}
|
|
4338
|
+
_finishDrag() {
|
|
4339
|
+
if (!this._drag || this._disposed) return;
|
|
4340
|
+
const id = this._drag.id;
|
|
4341
|
+
this._drag = null;
|
|
4342
|
+
if (!this._nearEdge) delete this._bar.dataset.scrollbarInteractive;
|
|
4343
|
+
if (this._bar.hasPointerCapture(id)) this._bar.releasePointerCapture(id);
|
|
4344
|
+
this._hideLater();
|
|
4345
|
+
}
|
|
4346
|
+
_onKeyDown(event) {
|
|
4347
|
+
if (event.altKey || event.ctrlKey || event.metaKey) return;
|
|
4348
|
+
this.refresh();
|
|
4349
|
+
const step = parseFloat(this._window.getComputedStyle(this._root).lineHeight) || 16;
|
|
4350
|
+
const page = this._root.clientHeight;
|
|
4351
|
+
const targets = {
|
|
4352
|
+
ArrowUp: this._root.scrollTop - step,
|
|
4353
|
+
ArrowDown: this._root.scrollTop + step,
|
|
4354
|
+
PageUp: this._root.scrollTop - page,
|
|
4355
|
+
PageDown: this._root.scrollTop + page,
|
|
4356
|
+
Home: 0,
|
|
4357
|
+
End: this._maximum,
|
|
4358
|
+
" ": this._root.scrollTop + (event.shiftKey ? -page : page)
|
|
4359
|
+
};
|
|
4360
|
+
if (!Object.hasOwn(targets, event.key)) return;
|
|
4361
|
+
event.preventDefault();
|
|
4362
|
+
this._scroll(targets[event.key]);
|
|
4363
|
+
this._reveal();
|
|
4364
|
+
}
|
|
4365
|
+
_scroll(top) {
|
|
4366
|
+
const target = this._isDocument ? this._window : this._root;
|
|
4367
|
+
target.scrollTo({ top: Math.min(this._maximum, Math.max(0, top)), behavior: "instant" });
|
|
4368
|
+
this._queue();
|
|
4369
|
+
}
|
|
4370
|
+
};
|
|
4371
|
+
|
|
4071
4372
|
// src/js/components/sheet.js
|
|
4072
4373
|
var states = /* @__PURE__ */ new WeakMap();
|
|
4073
4374
|
function initSheets(root = document) {
|
|
@@ -4122,6 +4423,7 @@ var MooUI = {
|
|
|
4122
4423
|
Sidebar,
|
|
4123
4424
|
Slider: MooSlider,
|
|
4124
4425
|
TableOfContents,
|
|
4426
|
+
OverlayScrollbar,
|
|
4125
4427
|
initSheets
|
|
4126
4428
|
};
|
|
4127
4429
|
var moo_ui_default = MooUI;
|
|
@@ -4132,6 +4434,7 @@ export {
|
|
|
4132
4434
|
MooDatepicker as Datepicker,
|
|
4133
4435
|
MooCalendar,
|
|
4134
4436
|
MooDateRangePicker,
|
|
4437
|
+
OverlayScrollbar,
|
|
4135
4438
|
Sidebar,
|
|
4136
4439
|
MooSlider as Slider,
|
|
4137
4440
|
TableOfContents,
|