@wpmoo/ui 1.0.0-rc.5 → 1.0.0-rc.7
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 +5 -6
- package/certification.json +1 -1
- package/dist/assets/css/moo-ui.css +7748 -8075
- package/dist/assets/css/moo-ui.min.css +2 -2
- package/dist/assets/css/moo.css +289 -285
- package/dist/assets/css/moo.min.css +2 -2
- package/dist/js/chart.js +57 -5
- package/dist/js/chart.min.js +3 -3
- package/dist/js/combobox.js +1 -1
- package/dist/js/context-menu.js +1 -1
- package/dist/js/datatable.js +114 -213
- package/dist/js/datepicker.js +79 -37
- package/dist/js/datepicker.min.js +2 -2
- package/dist/js/moo-ui.js +193 -51
- package/dist/js/moo-ui.min.js +3 -3
- package/dist/js/sidebar.js +145 -170
- package/dist/js/slider.js +1 -1
- package/package.json +8 -8
- package/scss/components/_alert.scss +1 -2
- package/scss/components/_card.scss +5 -5
- package/scss/components/_close_button.scss +8 -3
- package/scss/components/_datatable.scss +27 -3
- package/scss/components/_dialog.scss +16 -0
- package/scss/components/_dropdown.scss +38 -3
- package/scss/components/_switch.scss +13 -5
- package/scss/components/_table.scss +6 -0
- package/scss/components/_tabs.scss +1 -1
- package/scss/components/sidebar/_collapsed.scss +28 -19
- package/scss/components/sidebar/_inset.scss +14 -44
- package/scss/components/sidebar/_layout.scss +86 -11
- package/scss/foundations/_backdrop.scss +128 -0
- package/scss/foundations/_scope.scss +5 -0
- package/scss/mixins/_banner.scss +3 -0
- package/scss/moo-core.scss +6 -34
- package/scss/moo-ui.scss +6 -6
- package/scss/settings/_bootstrap_overrides.scss +4 -0
- package/scss/settings/_component_variables.scss +13 -1
- package/scss/settings/_options.scss +2 -0
- package/scss/settings/_palette.scss +1 -1
- package/scss/themes/_forms.scss +15 -0
- package/scss/themes/_root.scss +16 -0
- package/scss/themes/_standalone.scss +5 -0
- package/scss/themes/{_scoped_core.scss → _theme.scss} +1 -0
- package/scss/foundations/_core_state_layer.scss +0 -25
- package/scss/foundations/_overlay_backdrop.scss +0 -19
- package/scss/themes/_standalone_root.scss +0 -119
- /package/scss/foundations/{_core_global_primitives.scss → _globals.scss} +0 -0
package/dist/js/moo-ui.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Moo UI moo-ui.js v1.0.0-rc.
|
|
2
|
+
* Moo UI moo-ui.js v1.0.0-rc.7 (https://ui.wpmoo.org/)
|
|
3
3
|
* Copyright 2026 WPMoo (https://wpmoo.org)
|
|
4
4
|
* Licensed under MIT (https://github.com/wpmoo-org/ui/blob/main/LICENSE)
|
|
5
5
|
*/
|
|
@@ -14562,12 +14562,57 @@ function readThemeColors(themeElement, window2) {
|
|
|
14562
14562
|
return colors2;
|
|
14563
14563
|
}
|
|
14564
14564
|
function resolveThemeElement(element) {
|
|
14565
|
-
|
|
14565
|
+
const scoped = element?.closest?.("[data-bs-theme]");
|
|
14566
|
+
if (scoped) return scoped;
|
|
14567
|
+
const documentBody = element?.ownerDocument?.body;
|
|
14568
|
+
if (documentBody?.hasAttribute?.("data-bs-theme")) {
|
|
14569
|
+
return documentBody;
|
|
14570
|
+
}
|
|
14571
|
+
return element?.ownerDocument?.documentElement || null;
|
|
14566
14572
|
}
|
|
14567
14573
|
function themeElementIsDark(element) {
|
|
14568
14574
|
const theme = element?.getAttribute?.("data-bs-theme") || element?.dataset?.bsTheme;
|
|
14569
14575
|
return theme === "dark";
|
|
14570
14576
|
}
|
|
14577
|
+
function clampColorChannel(value) {
|
|
14578
|
+
return Math.min(255, Math.max(0, Math.round(value)));
|
|
14579
|
+
}
|
|
14580
|
+
function normalizeColorComponent(value) {
|
|
14581
|
+
const component = String(value).trim();
|
|
14582
|
+
if (component.endsWith("%")) {
|
|
14583
|
+
const percentage = Number.parseFloat(component.slice(0, -1));
|
|
14584
|
+
return Number.isFinite(percentage) ? clampColorChannel(percentage / 100 * 255) : null;
|
|
14585
|
+
}
|
|
14586
|
+
const normalized = Number.parseFloat(component);
|
|
14587
|
+
return Number.isFinite(normalized) ? clampColorChannel(normalized * 255) : null;
|
|
14588
|
+
}
|
|
14589
|
+
function normalizeColorAlpha(value) {
|
|
14590
|
+
if (value === void 0) return 1;
|
|
14591
|
+
const alpha2 = String(value).trim();
|
|
14592
|
+
if (alpha2.endsWith("%")) {
|
|
14593
|
+
const percentage = Number.parseFloat(alpha2.slice(0, -1));
|
|
14594
|
+
return Number.isFinite(percentage) ? Math.min(1, Math.max(0, percentage / 100)) : null;
|
|
14595
|
+
}
|
|
14596
|
+
const numeric = Number.parseFloat(alpha2);
|
|
14597
|
+
return Number.isFinite(numeric) ? Math.min(1, Math.max(0, numeric)) : null;
|
|
14598
|
+
}
|
|
14599
|
+
function normalizeCanvasColor(value) {
|
|
14600
|
+
if (typeof value !== "string") return null;
|
|
14601
|
+
const color2 = value.trim();
|
|
14602
|
+
const match = color2.match(
|
|
14603
|
+
/^color\(\s*srgb\s+([^\s/]+)\s+([^\s/]+)\s+([^\s/]+)(?:\s*\/\s*([^\s)]+))?\s*\)$/i
|
|
14604
|
+
);
|
|
14605
|
+
if (!match) return color2 || null;
|
|
14606
|
+
const channels = match.slice(1, 4).map(normalizeColorComponent);
|
|
14607
|
+
const alpha2 = normalizeColorAlpha(match[4]);
|
|
14608
|
+
if (channels.some((channel) => channel === null) || alpha2 === null) {
|
|
14609
|
+
return null;
|
|
14610
|
+
}
|
|
14611
|
+
if (alpha2 >= 1) {
|
|
14612
|
+
return `rgb(${channels.join(", ")})`;
|
|
14613
|
+
}
|
|
14614
|
+
return `rgba(${channels.join(", ")}, ${Number(alpha2.toFixed(3))})`;
|
|
14615
|
+
}
|
|
14571
14616
|
function resolveCanvasColor(document2, window2, value, fallback, themeElement) {
|
|
14572
14617
|
const createElement = document2?.createElement;
|
|
14573
14618
|
const getComputedStyle3 = window2?.getComputedStyle;
|
|
@@ -14581,7 +14626,7 @@ function resolveCanvasColor(document2, window2, value, fallback, themeElement) {
|
|
|
14581
14626
|
parent.appendChild(probe);
|
|
14582
14627
|
try {
|
|
14583
14628
|
const resolved = getComputedStyle3.call(window2, probe).color;
|
|
14584
|
-
return resolved || fallback;
|
|
14629
|
+
return normalizeCanvasColor(resolved) || fallback;
|
|
14585
14630
|
} finally {
|
|
14586
14631
|
probe.remove();
|
|
14587
14632
|
}
|
|
@@ -14853,7 +14898,7 @@ function applyThemeToChart(chart, theme, metadata, explicitColorFields = []) {
|
|
|
14853
14898
|
chart.options.plugins.tooltip.bodyColor = theme.secondaryText;
|
|
14854
14899
|
chart.options.plugins.tooltip.borderColor = theme.borderColor;
|
|
14855
14900
|
}
|
|
14856
|
-
chart.update(
|
|
14901
|
+
chart.update();
|
|
14857
14902
|
}
|
|
14858
14903
|
function themedGrid(theme) {
|
|
14859
14904
|
return {
|
|
@@ -15174,9 +15219,16 @@ var MooChart = class _MooChart {
|
|
|
15174
15219
|
}
|
|
15175
15220
|
});
|
|
15176
15221
|
});
|
|
15177
|
-
|
|
15222
|
+
const observerOptions = {
|
|
15178
15223
|
attributes: true,
|
|
15179
15224
|
attributeFilter: ["data-bs-theme", "style"]
|
|
15225
|
+
};
|
|
15226
|
+
const observerTargets = [
|
|
15227
|
+
this._themeElement,
|
|
15228
|
+
this._document?.documentElement
|
|
15229
|
+
].filter((target, index2, targets) => target && targets.indexOf(target) === index2);
|
|
15230
|
+
observerTargets.forEach((target) => {
|
|
15231
|
+
this._observer.observe(target, observerOptions);
|
|
15180
15232
|
});
|
|
15181
15233
|
}
|
|
15182
15234
|
instances2.set(element, this);
|
|
@@ -15947,6 +15999,37 @@ var ContextMenu = class _ContextMenu {
|
|
|
15947
15999
|
}
|
|
15948
16000
|
};
|
|
15949
16001
|
|
|
16002
|
+
// src/js/theme-owner.js
|
|
16003
|
+
var OWNER_SELECTOR = '.moo-ui[data-bs-theme="light"], .moo-ui[data-bs-theme="dark"]';
|
|
16004
|
+
var PORTAL_SELECTOR = "[data-moo-overlay-portal-host]";
|
|
16005
|
+
function documentFor(node) {
|
|
16006
|
+
if (node?.nodeType === 9) return node;
|
|
16007
|
+
if (node?.ownerDocument) return node.ownerDocument;
|
|
16008
|
+
return typeof document === "undefined" ? null : document;
|
|
16009
|
+
}
|
|
16010
|
+
function isResolvedOwner(node) {
|
|
16011
|
+
return Boolean(node?.matches?.(OWNER_SELECTOR));
|
|
16012
|
+
}
|
|
16013
|
+
function ownerRootFor(node) {
|
|
16014
|
+
const ownerDocument = documentFor(node);
|
|
16015
|
+
if (node?.nodeType === 9 || node === ownerDocument?.body) {
|
|
16016
|
+
return ownerDocument?.body?.firstElementChild || null;
|
|
16017
|
+
}
|
|
16018
|
+
return node;
|
|
16019
|
+
}
|
|
16020
|
+
function findThemeOwner(node = typeof document === "undefined" ? null : document) {
|
|
16021
|
+
const start = ownerRootFor(node);
|
|
16022
|
+
if (!start) return null;
|
|
16023
|
+
if (isResolvedOwner(start)) return start;
|
|
16024
|
+
return start.closest?.(OWNER_SELECTOR) || null;
|
|
16025
|
+
}
|
|
16026
|
+
function ownerPortalRoot(owner) {
|
|
16027
|
+
if (!owner) return null;
|
|
16028
|
+
return Array.from(owner.children || []).find(
|
|
16029
|
+
(child) => child.matches?.(PORTAL_SELECTOR)
|
|
16030
|
+
) || owner;
|
|
16031
|
+
}
|
|
16032
|
+
|
|
15950
16033
|
// src/js/components/datatable.js
|
|
15951
16034
|
var instances5 = /* @__PURE__ */ new WeakMap();
|
|
15952
16035
|
function normalize2(value) {
|
|
@@ -16036,7 +16119,8 @@ var DataTable = class _DataTable {
|
|
|
16036
16119
|
this._listeners.push({ target, type, handler, options });
|
|
16037
16120
|
}
|
|
16038
16121
|
// Row menus are authored next to their trigger so the public HTML stays
|
|
16039
|
-
// inspectable, but when opened they are temporarily moved
|
|
16122
|
+
// inspectable, but when opened they are temporarily moved to their nearest
|
|
16123
|
+
// Moo owner portal.
|
|
16040
16124
|
// That keeps the menu out of the scroll wrapper's layout math, so Safari
|
|
16041
16125
|
// cannot clip it at the rounded frame edge or shift the visible table
|
|
16042
16126
|
// slice while Popper positions it against the viewport.
|
|
@@ -16156,10 +16240,11 @@ var DataTable = class _DataTable {
|
|
|
16156
16240
|
this._reparentedRowMenus.set(menu, {
|
|
16157
16241
|
parent: menu.parentNode,
|
|
16158
16242
|
nextSibling: menu.nextSibling,
|
|
16159
|
-
trigger
|
|
16243
|
+
trigger,
|
|
16244
|
+
owner: findThemeOwner(trigger)
|
|
16160
16245
|
});
|
|
16161
16246
|
this._reparentedRowMenuByTrigger.set(trigger, menu);
|
|
16162
|
-
this.
|
|
16247
|
+
this._portalRoot(trigger).appendChild(menu);
|
|
16163
16248
|
}
|
|
16164
16249
|
_restoreRowActionMenuForTrigger(trigger) {
|
|
16165
16250
|
const menu = this._reparentedRowMenuByTrigger.get(trigger) || this._rowActionMenuForTrigger(trigger);
|
|
@@ -16172,8 +16257,10 @@ var DataTable = class _DataTable {
|
|
|
16172
16257
|
if (!original) {
|
|
16173
16258
|
return;
|
|
16174
16259
|
}
|
|
16175
|
-
const { parent, nextSibling, trigger } = original;
|
|
16176
|
-
if (
|
|
16260
|
+
const { parent, nextSibling, trigger, owner } = original;
|
|
16261
|
+
if (owner?.isConnected === false) {
|
|
16262
|
+
menu.remove();
|
|
16263
|
+
} else if (parent?.isConnected) {
|
|
16177
16264
|
if (nextSibling?.parentNode === parent) {
|
|
16178
16265
|
parent.insertBefore(menu, nextSibling);
|
|
16179
16266
|
} else {
|
|
@@ -16211,10 +16298,11 @@ var DataTable = class _DataTable {
|
|
|
16211
16298
|
parent: menu.parentNode,
|
|
16212
16299
|
nextSibling: menu.nextSibling,
|
|
16213
16300
|
trigger,
|
|
16214
|
-
owner: trigger.closest(".datatable-sort")
|
|
16301
|
+
owner: trigger.closest(".datatable-sort"),
|
|
16302
|
+
themeOwner: findThemeOwner(trigger)
|
|
16215
16303
|
});
|
|
16216
16304
|
this._reparentedSortMenuByTrigger.set(trigger, menu);
|
|
16217
|
-
this.
|
|
16305
|
+
this._portalRoot(trigger).appendChild(menu);
|
|
16218
16306
|
}
|
|
16219
16307
|
_restoreSortMenuForTrigger(trigger) {
|
|
16220
16308
|
const menu = this._reparentedSortMenuByTrigger.get(trigger) || this._sortMenuForTrigger(trigger);
|
|
@@ -16227,8 +16315,10 @@ var DataTable = class _DataTable {
|
|
|
16227
16315
|
if (!original) {
|
|
16228
16316
|
return;
|
|
16229
16317
|
}
|
|
16230
|
-
const { parent, nextSibling, trigger } = original;
|
|
16231
|
-
if (
|
|
16318
|
+
const { parent, nextSibling, trigger, themeOwner } = original;
|
|
16319
|
+
if (themeOwner?.isConnected === false) {
|
|
16320
|
+
menu.remove();
|
|
16321
|
+
} else if (parent?.isConnected) {
|
|
16232
16322
|
if (nextSibling?.parentNode === parent) {
|
|
16233
16323
|
parent.insertBefore(menu, nextSibling);
|
|
16234
16324
|
} else {
|
|
@@ -16250,6 +16340,9 @@ var DataTable = class _DataTable {
|
|
|
16250
16340
|
_bootstrap(name) {
|
|
16251
16341
|
return this._window.bootstrap?.[name] || null;
|
|
16252
16342
|
}
|
|
16343
|
+
_portalRoot(trigger = this._element) {
|
|
16344
|
+
return ownerPortalRoot(findThemeOwner(trigger)) || this._document.body || this._document.documentElement;
|
|
16345
|
+
}
|
|
16253
16346
|
// The bulk-actions bar's icon-only buttons carry data-bs-title instead of
|
|
16254
16347
|
// a bare title attribute so Bootstrap's own Tooltip owns the hover/focus
|
|
16255
16348
|
// affordance (matching the rest of Moo's icon-button contracts) rather
|
|
@@ -16267,7 +16360,10 @@ var DataTable = class _DataTable {
|
|
|
16267
16360
|
return;
|
|
16268
16361
|
}
|
|
16269
16362
|
this._element.querySelectorAll('[data-datatable-bulk-actions] [data-bs-title]:not([data-bs-toggle="dropdown"])').forEach((trigger) => {
|
|
16270
|
-
this._tooltips.push(Tooltip2.getOrCreateInstance(trigger, {
|
|
16363
|
+
this._tooltips.push(Tooltip2.getOrCreateInstance(trigger, {
|
|
16364
|
+
animation: false,
|
|
16365
|
+
container: this._portalRoot(trigger)
|
|
16366
|
+
}));
|
|
16271
16367
|
});
|
|
16272
16368
|
}
|
|
16273
16369
|
_hideBulkTooltips({ blur = false } = {}) {
|
|
@@ -17358,42 +17454,54 @@ function datepickerContains(instance, target) {
|
|
|
17358
17454
|
);
|
|
17359
17455
|
}
|
|
17360
17456
|
function syncPortaledPopoverContext(instance) {
|
|
17361
|
-
const
|
|
17362
|
-
const
|
|
17457
|
+
const owner = findThemeOwner(instance._trigger);
|
|
17458
|
+
const theme = owner?.getAttribute("data-bs-theme") || null;
|
|
17459
|
+
const direction = instance._document.defaultView?.getComputedStyle(
|
|
17460
|
+
instance._trigger
|
|
17461
|
+
).direction;
|
|
17363
17462
|
if (theme) {
|
|
17364
17463
|
instance._popover.setAttribute("data-bs-theme", theme);
|
|
17464
|
+
} else {
|
|
17465
|
+
instance._popover.removeAttribute("data-bs-theme");
|
|
17365
17466
|
}
|
|
17366
|
-
if (direction === "rtl") {
|
|
17367
|
-
instance._popover.setAttribute("dir",
|
|
17467
|
+
if (direction === "ltr" || direction === "rtl") {
|
|
17468
|
+
instance._popover.setAttribute("dir", direction);
|
|
17469
|
+
} else {
|
|
17470
|
+
instance._popover.removeAttribute("dir");
|
|
17368
17471
|
}
|
|
17369
17472
|
}
|
|
17370
17473
|
function portalDatepickerPopover(instance) {
|
|
17371
17474
|
const popover = instance._popover;
|
|
17372
|
-
|
|
17475
|
+
const owner = findThemeOwner(instance._trigger);
|
|
17476
|
+
const portalRoot = ownerPortalRoot(owner) || instance._document.body || instance._document.documentElement;
|
|
17477
|
+
if (!portalRoot) {
|
|
17478
|
+
return;
|
|
17479
|
+
}
|
|
17480
|
+
if (instance._popoverPortal?.portal === portalRoot && popover.parentElement === portalRoot) {
|
|
17373
17481
|
syncPortaledPopoverContext(instance);
|
|
17374
17482
|
return;
|
|
17375
17483
|
}
|
|
17376
|
-
|
|
17377
|
-
host.className = "moo-ui";
|
|
17378
|
-
host.dataset.datepickerPortalHost = "";
|
|
17484
|
+
restoreDatepickerPopover(instance);
|
|
17379
17485
|
instance._popoverPortal = {
|
|
17380
17486
|
parent: popover.parentNode,
|
|
17381
17487
|
nextSibling: popover.nextSibling,
|
|
17382
|
-
|
|
17488
|
+
owner,
|
|
17489
|
+
portal: portalRoot,
|
|
17383
17490
|
hadTheme: popover.hasAttribute("data-bs-theme"),
|
|
17384
17491
|
theme: popover.getAttribute("data-bs-theme"),
|
|
17385
17492
|
hadDirection: popover.hasAttribute("dir"),
|
|
17386
17493
|
direction: popover.getAttribute("dir")
|
|
17387
17494
|
};
|
|
17388
|
-
|
|
17389
|
-
instance._document.body.appendChild(host);
|
|
17495
|
+
portalRoot.appendChild(popover);
|
|
17390
17496
|
syncPortaledPopoverContext(instance);
|
|
17391
17497
|
}
|
|
17392
17498
|
function restoreDatepickerPopover(instance) {
|
|
17393
17499
|
const portal = instance._popoverPortal;
|
|
17394
17500
|
if (!portal) return;
|
|
17395
17501
|
const popover = instance._popover;
|
|
17396
|
-
if (portal.
|
|
17502
|
+
if (portal.owner?.isConnected === false) {
|
|
17503
|
+
popover.remove();
|
|
17504
|
+
} else if (portal.parent?.isConnected) {
|
|
17397
17505
|
if (portal.nextSibling?.parentNode === portal.parent) {
|
|
17398
17506
|
portal.parent.insertBefore(popover, portal.nextSibling);
|
|
17399
17507
|
} else {
|
|
@@ -17402,7 +17510,6 @@ function restoreDatepickerPopover(instance) {
|
|
|
17402
17510
|
} else {
|
|
17403
17511
|
popover.remove();
|
|
17404
17512
|
}
|
|
17405
|
-
portal.host?.remove();
|
|
17406
17513
|
if (portal.hadTheme) {
|
|
17407
17514
|
popover.setAttribute("data-bs-theme", portal.theme);
|
|
17408
17515
|
} else {
|
|
@@ -18315,7 +18422,8 @@ var Sidebar = class _Sidebar {
|
|
|
18315
18422
|
this._element = element;
|
|
18316
18423
|
this._document = element.ownerDocument;
|
|
18317
18424
|
this._window = this._document.defaultView;
|
|
18318
|
-
this.
|
|
18425
|
+
this._documentElement = this._document.documentElement;
|
|
18426
|
+
this._root = findThemeOwner(element) || this._document.body || this._documentElement;
|
|
18319
18427
|
this._sidebar = element.querySelector('[data-slot="sidebar"]');
|
|
18320
18428
|
this._config = {
|
|
18321
18429
|
breakpoint: "(min-width: 992px)",
|
|
@@ -18360,6 +18468,9 @@ var Sidebar = class _Sidebar {
|
|
|
18360
18468
|
_bootstrap(name) {
|
|
18361
18469
|
return this._window.bootstrap?.[name] || null;
|
|
18362
18470
|
}
|
|
18471
|
+
_portalRoot(trigger = this._element) {
|
|
18472
|
+
return ownerPortalRoot(findThemeOwner(trigger)) || this._document.body || this._documentElement;
|
|
18473
|
+
}
|
|
18363
18474
|
_isDesktop() {
|
|
18364
18475
|
return this._window.matchMedia(this._config.breakpoint).matches;
|
|
18365
18476
|
}
|
|
@@ -18384,7 +18495,7 @@ var Sidebar = class _Sidebar {
|
|
|
18384
18495
|
this._closeFlyouts();
|
|
18385
18496
|
this._syncTooltips();
|
|
18386
18497
|
});
|
|
18387
|
-
this._directionObserver.observe(this.
|
|
18498
|
+
this._directionObserver.observe(this._documentElement, {
|
|
18388
18499
|
attributes: true,
|
|
18389
18500
|
attributeFilter: ["dir"]
|
|
18390
18501
|
});
|
|
@@ -18476,7 +18587,9 @@ var Sidebar = class _Sidebar {
|
|
|
18476
18587
|
}
|
|
18477
18588
|
delete item.dataset.sidebarDropdownPositioned;
|
|
18478
18589
|
item.style.removeProperty("--moo-sidebar-dropdown-block-start");
|
|
18479
|
-
item.style.removeProperty("--moo-sidebar-dropdown-
|
|
18590
|
+
item.style.removeProperty("--moo-sidebar-dropdown-block-end");
|
|
18591
|
+
item.style.removeProperty("--moo-sidebar-dropdown-left");
|
|
18592
|
+
item.style.removeProperty("--moo-sidebar-dropdown-right");
|
|
18480
18593
|
}
|
|
18481
18594
|
_closeDropdowns(exceptControl = null) {
|
|
18482
18595
|
const Dropdown = this._bootstrap("Dropdown");
|
|
@@ -18496,22 +18609,44 @@ var Sidebar = class _Sidebar {
|
|
|
18496
18609
|
_positionDropdown(control) {
|
|
18497
18610
|
const item = control?.closest?.(".sidebar-menu-item");
|
|
18498
18611
|
const isHeaderWorkspace = control?.classList.contains("sidebar-menu-button--workspace") && control.closest('[data-slot="sidebar-header"]');
|
|
18499
|
-
|
|
18612
|
+
const isFooterAccount = control?.classList.contains("sidebar-menu-button--account") && control.closest('[data-slot="sidebar-footer"]');
|
|
18613
|
+
if (!control || !item || !(isHeaderWorkspace || isFooterAccount) || !this._isDesktop()) {
|
|
18500
18614
|
this._clearDropdownPosition(control);
|
|
18501
18615
|
return;
|
|
18502
18616
|
}
|
|
18503
18617
|
this._closeFlyouts();
|
|
18504
18618
|
const rect = control.getBoundingClientRect();
|
|
18505
18619
|
const gap = 4;
|
|
18506
|
-
const
|
|
18507
|
-
|
|
18508
|
-
|
|
18509
|
-
|
|
18510
|
-
|
|
18511
|
-
|
|
18512
|
-
|
|
18513
|
-
|
|
18514
|
-
|
|
18620
|
+
const sidebar = control.closest('[data-slot="sidebar"]');
|
|
18621
|
+
const side = sidebar?.dataset.side || "left";
|
|
18622
|
+
if (side === "right") {
|
|
18623
|
+
const right = this._window.innerWidth - rect.left + gap;
|
|
18624
|
+
item.style.setProperty(
|
|
18625
|
+
"--moo-sidebar-dropdown-right",
|
|
18626
|
+
`${Math.round(right)}px`
|
|
18627
|
+
);
|
|
18628
|
+
item.style.removeProperty("--moo-sidebar-dropdown-left");
|
|
18629
|
+
} else {
|
|
18630
|
+
const left = rect.right + gap;
|
|
18631
|
+
item.style.setProperty(
|
|
18632
|
+
"--moo-sidebar-dropdown-left",
|
|
18633
|
+
`${Math.round(left)}px`
|
|
18634
|
+
);
|
|
18635
|
+
item.style.removeProperty("--moo-sidebar-dropdown-right");
|
|
18636
|
+
}
|
|
18637
|
+
if (isHeaderWorkspace) {
|
|
18638
|
+
item.style.setProperty(
|
|
18639
|
+
"--moo-sidebar-dropdown-block-start",
|
|
18640
|
+
`${Math.round(rect.bottom + gap)}px`
|
|
18641
|
+
);
|
|
18642
|
+
item.style.removeProperty("--moo-sidebar-dropdown-block-end");
|
|
18643
|
+
} else {
|
|
18644
|
+
item.style.setProperty(
|
|
18645
|
+
"--moo-sidebar-dropdown-block-end",
|
|
18646
|
+
`${Math.round(this._window.innerHeight - rect.top + gap)}px`
|
|
18647
|
+
);
|
|
18648
|
+
item.style.removeProperty("--moo-sidebar-dropdown-block-start");
|
|
18649
|
+
}
|
|
18515
18650
|
item.dataset.sidebarDropdownPositioned = "";
|
|
18516
18651
|
}
|
|
18517
18652
|
_removeFlyoutPortal() {
|
|
@@ -18527,7 +18662,7 @@ var Sidebar = class _Sidebar {
|
|
|
18527
18662
|
this._element.querySelectorAll(".sidebar-menu-item--flyout-open").forEach((item) => {
|
|
18528
18663
|
item.classList.remove("sidebar-menu-item--flyout-open");
|
|
18529
18664
|
item.style.removeProperty("--moo-sidebar-flyout-block-start");
|
|
18530
|
-
item.style.removeProperty("--moo-sidebar-flyout-
|
|
18665
|
+
item.style.removeProperty("--moo-sidebar-flyout-left");
|
|
18531
18666
|
this._resetFlyoutTrigger(item, false);
|
|
18532
18667
|
});
|
|
18533
18668
|
}
|
|
@@ -18543,8 +18678,9 @@ var Sidebar = class _Sidebar {
|
|
|
18543
18678
|
this._closeDropdowns();
|
|
18544
18679
|
this._closeFlyouts();
|
|
18545
18680
|
const rect = item.getBoundingClientRect();
|
|
18681
|
+
const sidebar = this._sidebar;
|
|
18682
|
+
const sidebarRect = sidebar?.getBoundingClientRect() || rect;
|
|
18546
18683
|
const gap = 4;
|
|
18547
|
-
const inlineStart = this._root.dir === "rtl" ? this._window.innerWidth - rect.left + gap : rect.right + gap;
|
|
18548
18684
|
const flyout = submenu.cloneNode(true);
|
|
18549
18685
|
flyout.removeAttribute("id");
|
|
18550
18686
|
flyout.classList.remove("collapse", "show", "collapsing");
|
|
@@ -18552,12 +18688,12 @@ var Sidebar = class _Sidebar {
|
|
|
18552
18688
|
flyout.dataset.sidebarFlyout = "";
|
|
18553
18689
|
flyout.removeAttribute("style");
|
|
18554
18690
|
flyout.style.setProperty("--moo-sidebar-flyout-block-start", `${Math.round(rect.top)}px`);
|
|
18555
|
-
|
|
18556
|
-
|
|
18557
|
-
|
|
18558
|
-
|
|
18559
|
-
const
|
|
18560
|
-
|
|
18691
|
+
const side = sidebar?.dataset.side || "left";
|
|
18692
|
+
this._portalRoot(item).appendChild(flyout);
|
|
18693
|
+
const flyoutWidth = flyout.getBoundingClientRect().width;
|
|
18694
|
+
const left = side === "right" ? sidebarRect.left - flyoutWidth - gap : sidebarRect.right + gap;
|
|
18695
|
+
const boundedLeft = Math.max(0, Math.min(this._window.innerWidth - flyoutWidth, left));
|
|
18696
|
+
flyout.style.setProperty("--moo-sidebar-flyout-left", `${Math.round(boundedLeft)}px`);
|
|
18561
18697
|
this._flyout = flyout;
|
|
18562
18698
|
this._flyoutOwner = item;
|
|
18563
18699
|
item.classList.add("sidebar-menu-item--flyout-open");
|
|
@@ -18588,7 +18724,8 @@ var Sidebar = class _Sidebar {
|
|
|
18588
18724
|
return;
|
|
18589
18725
|
}
|
|
18590
18726
|
const collapsed = this._isCollapsed();
|
|
18591
|
-
const
|
|
18727
|
+
const side = this._sidebar?.dataset.side || "left";
|
|
18728
|
+
const placement = side === "right" ? "left" : "right";
|
|
18592
18729
|
this._element.querySelectorAll("[data-sidebar-tooltip]").forEach((control) => {
|
|
18593
18730
|
this._disposeTooltip(control);
|
|
18594
18731
|
if (!collapsed || this._isIdentityTrigger(control) || control.closest(".sidebar-menu-item")?.querySelector(":scope > .sidebar-menu-sub")) {
|
|
@@ -18598,7 +18735,12 @@ var Sidebar = class _Sidebar {
|
|
|
18598
18735
|
new Tooltip2(anchor, {
|
|
18599
18736
|
title: control.getAttribute("data-sidebar-tooltip"),
|
|
18600
18737
|
placement,
|
|
18601
|
-
|
|
18738
|
+
// Bootstrap's default tooltip offset is 6px. The icon rail's
|
|
18739
|
+
// boundary calculation still lets the tooltip box overlap the
|
|
18740
|
+
// physical Sidebar edge at that distance, so keep an explicit 8px
|
|
18741
|
+
// separation for both physical placements.
|
|
18742
|
+
offset: [0, 8],
|
|
18743
|
+
container: this._portalRoot(control),
|
|
18602
18744
|
trigger: "hover focus"
|
|
18603
18745
|
});
|
|
18604
18746
|
this._tooltipAnchors.add(anchor);
|