@iris-ui-kit/vue 0.2.25 → 0.2.27
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/dist/admin.cjs +547 -236
- package/dist/admin.cjs.map +1 -1
- package/dist/admin.d.cts +4 -2
- package/dist/admin.d.ts +4 -2
- package/dist/admin.js +2 -2
- package/dist/behaviors.cjs +49 -0
- package/dist/behaviors.cjs.map +1 -1
- package/dist/behaviors.d.cts +57 -1
- package/dist/behaviors.d.ts +57 -1
- package/dist/behaviors.js +1 -1
- package/dist/{chunk-QQ25RKOO.js → chunk-ASFDGYIR.js} +543 -240
- package/dist/chunk-ASFDGYIR.js.map +1 -0
- package/dist/{chunk-WL67XCH5.js → chunk-IN3DQ55U.js} +2 -2
- package/dist/chunk-IN3DQ55U.js.map +1 -0
- package/dist/{chunk-7L6UB6MD.js → chunk-IOMKC5OI.js} +53 -5
- package/dist/chunk-IOMKC5OI.js.map +1 -0
- package/dist/{chunk-3FJUCHCC.js → chunk-IPR5JAVF.js} +11 -3
- package/dist/chunk-IPR5JAVF.js.map +1 -0
- package/dist/{chunk-BEPH6PPL.js → chunk-LWABTQCB.js} +57 -37
- package/dist/chunk-LWABTQCB.js.map +1 -0
- package/dist/{chunk-DNRQVM3Q.js → chunk-QBFYIDY7.js} +3 -2
- package/dist/chunk-QBFYIDY7.js.map +1 -0
- package/dist/data.cjs +1 -0
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.cts +4 -2
- package/dist/data.d.ts +4 -2
- package/dist/data.js +1 -1
- package/dist/floating.cjs +9 -1
- package/dist/floating.cjs.map +1 -1
- package/dist/floating.d.cts +6 -0
- package/dist/floating.d.ts +6 -0
- package/dist/floating.js +1 -1
- package/dist/index.cjs +2063 -745
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +172 -8
- package/dist/index.d.ts +172 -8
- package/dist/index.js +1412 -475
- package/dist/index.js.map +1 -1
- package/dist/layouts.cjs.map +1 -1
- package/dist/layouts.d.cts +1 -1
- package/dist/layouts.d.ts +1 -1
- package/dist/layouts.js +1 -1
- package/dist/skeletons.cjs +55 -35
- package/dist/skeletons.cjs.map +1 -1
- package/dist/skeletons.js +1 -1
- package/package.json +5 -5
- package/dist/chunk-3FJUCHCC.js.map +0 -1
- package/dist/chunk-7L6UB6MD.js.map +0 -1
- package/dist/chunk-BEPH6PPL.js.map +0 -1
- package/dist/chunk-DNRQVM3Q.js.map +0 -1
- package/dist/chunk-QQ25RKOO.js.map +0 -1
- package/dist/chunk-WL67XCH5.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useFloating, useDismiss } from './chunk-
|
|
1
|
+
import { useFloating, useDismiss } from './chunk-IPR5JAVF.js';
|
|
2
2
|
import { useMachine } from './chunk-NNOF7KUH.js';
|
|
3
3
|
import { findFirstElement, mergeSlotProps } from './chunk-F77KIPOH.js';
|
|
4
4
|
import { IrisHeaderLayout, IrisSidebarLayout } from './chunk-3V46HGRC.js';
|
|
@@ -6,8 +6,8 @@ import { IrisThemeKey } from './chunk-ZTPIXL7Q.js';
|
|
|
6
6
|
import { IrisSortable } from './chunk-W3B6E5GN.js';
|
|
7
7
|
import { useStore } from './chunk-75GSYEJS.js';
|
|
8
8
|
import { useI18n } from './chunk-TCAXRWT6.js';
|
|
9
|
-
import { defineComponent, inject, h, computed, shallowRef, onBeforeUnmount, watch,
|
|
10
|
-
import { visibleNav, findNavPath, createExpansion, branchTrail, createFloatingMachine,
|
|
9
|
+
import { defineComponent, inject, h, computed, shallowRef, onBeforeUnmount, watch, provide, useId, ref, nextTick, Teleport, Fragment, watchEffect, toValue, onMounted } from 'vue';
|
|
10
|
+
import { visibleNav, findNavPath, createExpansion, branchTrail, createFloatingMachine, isBranch, findNavNode, firstLeaf, matchTypeahead, nextEnabledIndex, isClosable, createAdminShell } from '@iris-ui-kit/core';
|
|
11
11
|
export { createAdminPreferences, createTabsNav, filterNavByAccess, findNavNode, findNavPath, firstLeaf, flattenNav, isBranch, isClosable, localStorageAdminPreferencesStorage, nodeAllowsRoles, visibleNav } from '@iris-ui-kit/core';
|
|
12
12
|
import { defaultIconRegistry, resolveThemedIcon } from '@iris-ui-kit/icons';
|
|
13
13
|
|
|
@@ -73,7 +73,7 @@ var __NAV_MENU_STYLE_ID = "iris-nav-menu-styles";
|
|
|
73
73
|
var CSS = `
|
|
74
74
|
:where(.iris-nav-menu) {
|
|
75
75
|
--iris-nav-indent-step: 16px;
|
|
76
|
-
--iris-nav-item-padding-inline:
|
|
76
|
+
--iris-nav-item-padding-inline: 12px;
|
|
77
77
|
--iris-nav-item-padding-block: 8px;
|
|
78
78
|
--iris-nav-item-border-radius: var(--iris-radius-md, 6px);
|
|
79
79
|
--iris-nav-item-hover: var(--iris-surface-hover, var(--iris-surface));
|
|
@@ -81,7 +81,7 @@ var CSS = `
|
|
|
81
81
|
display: flex;
|
|
82
82
|
flex-direction: column;
|
|
83
83
|
align-items: stretch;
|
|
84
|
-
gap:
|
|
84
|
+
gap: var(--iris-space-xxs, 4px);
|
|
85
85
|
width: 100%;
|
|
86
86
|
}
|
|
87
87
|
|
|
@@ -106,16 +106,16 @@ var CSS = `
|
|
|
106
106
|
border: none;
|
|
107
107
|
border-radius: var(--iris-nav-item-border-radius);
|
|
108
108
|
background: transparent;
|
|
109
|
-
color: var(--iris-foreground
|
|
109
|
+
color: var(--iris-foreground);
|
|
110
110
|
font: inherit;
|
|
111
|
-
font-size: 14px;
|
|
111
|
+
font-size: var(--iris-font-size-md, 14px);
|
|
112
112
|
line-height: 1.2;
|
|
113
113
|
font-weight: 400;
|
|
114
114
|
text-align: start;
|
|
115
115
|
cursor: pointer;
|
|
116
116
|
opacity: 1;
|
|
117
117
|
margin: 0;
|
|
118
|
-
gap:
|
|
118
|
+
gap: var(--iris-space-sm, 12px);
|
|
119
119
|
padding-block: var(--iris-nav-item-padding-block);
|
|
120
120
|
padding-inline: var(--iris-nav-item-padding-inline);
|
|
121
121
|
text-overflow: ellipsis;
|
|
@@ -128,7 +128,7 @@ var CSS = `
|
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
:where(.iris-nav-menu-item[data-depth='0']) {
|
|
131
|
-
--iris-nav-item-padding-inline-start:
|
|
131
|
+
--iris-nav-item-padding-inline-start: 12px;
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
:where(.iris-nav-menu-item[data-depth='1']) {
|
|
@@ -176,7 +176,7 @@ var CSS = `
|
|
|
176
176
|
background: var(--iris-nav-item-hover);
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
|
|
179
|
+
.iris-nav-menu-item[data-active='true'] {
|
|
180
180
|
background: var(--iris-primary);
|
|
181
181
|
color: var(--iris-primary-foreground, #fff);
|
|
182
182
|
font-weight: 600;
|
|
@@ -205,13 +205,13 @@ var CSS = `
|
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
:where(.iris-nav-menu-badge) {
|
|
208
|
-
margin-inline-start:
|
|
209
|
-
font-size:
|
|
208
|
+
margin-inline-start: var(--iris-space-xs, 8px);
|
|
209
|
+
font-size: var(--iris-font-size-xs, 12px);
|
|
210
210
|
line-height: 1;
|
|
211
|
-
padding:
|
|
211
|
+
padding: var(--iris-space-xxs, 4px) var(--iris-space-xs, 8px);
|
|
212
212
|
border-radius: 999px;
|
|
213
|
-
background: var(--iris-danger, #
|
|
214
|
-
color: #fff;
|
|
213
|
+
background: var(--iris-danger, #ef4444);
|
|
214
|
+
color: var(--iris-primary-foreground, #fff);
|
|
215
215
|
flex: 0 0 auto;
|
|
216
216
|
}
|
|
217
217
|
|
|
@@ -241,44 +241,68 @@ var CSS = `
|
|
|
241
241
|
opacity: 0.75;
|
|
242
242
|
}
|
|
243
243
|
|
|
244
|
-
|
|
245
|
-
|
|
244
|
+
/* Vertical branches stay in the DOM and animate height via the grid-rows
|
|
245
|
+
trick (0fr \u2192 1fr); the inner wrapper provides the overflow clipping so the
|
|
246
|
+
transition is a smooth accordion without a max-height cap. */
|
|
247
|
+
:where(.iris-nav-menu--vertical .iris-nav-menu-group > .iris-nav-menu-children) {
|
|
248
|
+
display: grid;
|
|
249
|
+
grid-template-rows: 0fr;
|
|
250
|
+
opacity: 0;
|
|
251
|
+
visibility: hidden;
|
|
252
|
+
transition:
|
|
253
|
+
grid-template-rows 200ms ease,
|
|
254
|
+
opacity 150ms ease,
|
|
255
|
+
visibility 0s linear 200ms;
|
|
246
256
|
}
|
|
247
257
|
|
|
248
|
-
:where(.iris-nav-menu-group
|
|
249
|
-
:
|
|
250
|
-
:
|
|
251
|
-
:where(.iris-nav-menu-group--depth-4 > .iris-nav-menu-children),
|
|
252
|
-
:where(.iris-nav-menu-group--depth-5 > .iris-nav-menu-children),
|
|
253
|
-
:where(.iris-nav-menu-group--depth-6 > .iris-nav-menu-children),
|
|
254
|
-
:where(.iris-nav-menu-group--depth-7 > .iris-nav-menu-children),
|
|
255
|
-
:where(.iris-nav-menu-group--depth-8 > .iris-nav-menu-children),
|
|
256
|
-
:where(.iris-nav-menu-group--depth-9 > .iris-nav-menu-children),
|
|
257
|
-
:where(.iris-nav-menu-group > .iris-nav-menu-children) {
|
|
258
|
-
display: none;
|
|
258
|
+
:where(.iris-nav-menu--vertical .iris-nav-menu-group > .iris-nav-menu-children > .iris-nav-menu-children-inner) {
|
|
259
|
+
overflow: hidden;
|
|
260
|
+
min-height: 0;
|
|
259
261
|
}
|
|
260
262
|
|
|
261
|
-
:where(.iris-nav-menu-group[data-open='true'] > .iris-nav-menu-children) {
|
|
262
|
-
|
|
263
|
+
:where(.iris-nav-menu--vertical .iris-nav-menu-group[data-open='true'] > .iris-nav-menu-children) {
|
|
264
|
+
grid-template-rows: 1fr;
|
|
265
|
+
opacity: 1;
|
|
266
|
+
visibility: visible;
|
|
267
|
+
transition:
|
|
268
|
+
grid-template-rows 200ms ease,
|
|
269
|
+
opacity 150ms ease;
|
|
263
270
|
}
|
|
264
271
|
|
|
265
|
-
|
|
272
|
+
/* Flyout popups (horizontal mode + the collapsed rail) share the popup chrome
|
|
273
|
+
and are hard-hidden when closed (no height animation needed). */
|
|
274
|
+
:where(.iris-nav-menu--horizontal .iris-nav-menu-group > .iris-nav-menu-children),
|
|
275
|
+
:where(.iris-nav-menu--collapsed .iris-nav-menu-group > .iris-nav-menu-children) {
|
|
276
|
+
display: none;
|
|
266
277
|
position: absolute;
|
|
267
278
|
min-width: 220px;
|
|
268
|
-
padding:
|
|
279
|
+
padding: var(--iris-space-xs, 8px);
|
|
269
280
|
border: 1px solid var(--iris-border);
|
|
270
281
|
border-radius: var(--iris-radius-md, 6px);
|
|
271
282
|
background: var(--iris-surface);
|
|
272
283
|
box-shadow: var(--iris-shadow-md);
|
|
273
284
|
}
|
|
274
285
|
|
|
286
|
+
:where(.iris-nav-menu--horizontal .iris-nav-menu-group[data-open='true'] > .iris-nav-menu-children),
|
|
287
|
+
:where(.iris-nav-menu--collapsed .iris-nav-menu-group[data-open='true'] > .iris-nav-menu-children) {
|
|
288
|
+
display: block;
|
|
289
|
+
}
|
|
290
|
+
|
|
275
291
|
:where(.iris-nav-menu--horizontal .iris-nav-menu-group[data-depth='0'] > .iris-nav-menu-children) {
|
|
276
292
|
inset-block-start: 100%;
|
|
277
293
|
inset-inline-start: 0;
|
|
278
294
|
z-index: 60;
|
|
279
295
|
}
|
|
280
296
|
|
|
281
|
-
|
|
297
|
+
/* A9: the collapsed rail popup opens to the right of the icon. */
|
|
298
|
+
:where(.iris-nav-menu--collapsed .iris-nav-menu-group[data-depth='0'] > .iris-nav-menu-children) {
|
|
299
|
+
inset-block-start: 0;
|
|
300
|
+
inset-inline-start: 100%;
|
|
301
|
+
z-index: 60;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
:where(.iris-nav-menu--horizontal .iris-nav-menu-group[data-depth]:not([data-depth='0']) > .iris-nav-menu-children),
|
|
305
|
+
:where(.iris-nav-menu--collapsed .iris-nav-menu-group[data-depth]:not([data-depth='0']) > .iris-nav-menu-children) {
|
|
282
306
|
inset-block-start: 0;
|
|
283
307
|
inset-inline-start: 100%;
|
|
284
308
|
z-index: 61;
|
|
@@ -294,10 +318,20 @@ var CSS = `
|
|
|
294
318
|
padding-inline: var(--iris-nav-item-padding-inline);
|
|
295
319
|
}
|
|
296
320
|
|
|
321
|
+
/* A9: the collapsed rail stays centered even though rows carry data-depth
|
|
322
|
+
(the vertical indent rules would otherwise win the specificity tie). */
|
|
323
|
+
:where(.iris-nav-menu--collapsed .iris-nav-menu-item[data-depth]) {
|
|
324
|
+
justify-content: center;
|
|
325
|
+
padding-inline: var(--iris-nav-item-padding-inline);
|
|
326
|
+
}
|
|
327
|
+
|
|
297
328
|
@media (prefers-reduced-motion: reduce) {
|
|
298
329
|
:where(.iris-nav-menu-arrow) {
|
|
299
330
|
transition: none;
|
|
300
331
|
}
|
|
332
|
+
:where(.iris-nav-menu--vertical .iris-nav-menu-group > .iris-nav-menu-children) {
|
|
333
|
+
transition: none;
|
|
334
|
+
}
|
|
301
335
|
}
|
|
302
336
|
`.trim();
|
|
303
337
|
var installed = false;
|
|
@@ -314,6 +348,315 @@ function installNavMenuStyles() {
|
|
|
314
348
|
document.head.appendChild(style);
|
|
315
349
|
installed = true;
|
|
316
350
|
}
|
|
351
|
+
var HOVER_OPEN_DELAY_VAL = 60;
|
|
352
|
+
var HOVER_CLOSE_DELAY_VAL = 150;
|
|
353
|
+
function createNavMenuFlyout(ctx) {
|
|
354
|
+
const hovered = ref(null);
|
|
355
|
+
const hoveredBranches = ref([]);
|
|
356
|
+
const focusedBranches = ref([]);
|
|
357
|
+
const clickedBranches = ref([]);
|
|
358
|
+
let suppressFocusOpen = false;
|
|
359
|
+
let openTimer = null;
|
|
360
|
+
const closeTimers = /* @__PURE__ */ new Map();
|
|
361
|
+
const clearOpenTimer = () => {
|
|
362
|
+
if (openTimer) {
|
|
363
|
+
clearTimeout(openTimer);
|
|
364
|
+
openTimer = null;
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
const cancelClose = (key) => {
|
|
368
|
+
const timer = closeTimers.get(key);
|
|
369
|
+
if (timer) {
|
|
370
|
+
clearTimeout(timer);
|
|
371
|
+
closeTimers.delete(key);
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
const cancelAllTimers = () => {
|
|
375
|
+
clearOpenTimer();
|
|
376
|
+
for (const timer of closeTimers.values()) clearTimeout(timer);
|
|
377
|
+
closeTimers.clear();
|
|
378
|
+
};
|
|
379
|
+
onBeforeUnmount(cancelAllTimers);
|
|
380
|
+
const flyoutTriggers = /* @__PURE__ */ new Map();
|
|
381
|
+
const flyoutPanels = /* @__PURE__ */ new Map();
|
|
382
|
+
const setFlyoutRef = (map, key, el) => {
|
|
383
|
+
if (el instanceof HTMLElement) map.set(key, el);
|
|
384
|
+
else map.delete(key);
|
|
385
|
+
};
|
|
386
|
+
const positionFlyout = (key) => {
|
|
387
|
+
const trigger = flyoutTriggers.get(key);
|
|
388
|
+
const panel = flyoutPanels.get(key);
|
|
389
|
+
if (!trigger || !panel || typeof document === "undefined") return;
|
|
390
|
+
const rect = trigger.getBoundingClientRect();
|
|
391
|
+
const dir = getComputedStyle(trigger).direction;
|
|
392
|
+
panel.style.position = "fixed";
|
|
393
|
+
panel.style.top = `${ctx.collapsed ? rect.top : rect.bottom}px`;
|
|
394
|
+
if (dir === "rtl") {
|
|
395
|
+
panel.style.left = "";
|
|
396
|
+
panel.style.right = `${window.innerWidth - (ctx.collapsed ? rect.left : rect.right)}px`;
|
|
397
|
+
} else {
|
|
398
|
+
panel.style.right = "";
|
|
399
|
+
panel.style.left = `${ctx.collapsed ? rect.right : rect.left}px`;
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
onBeforeUnmount(() => {
|
|
403
|
+
detachViewportListeners();
|
|
404
|
+
flyoutTriggers.clear();
|
|
405
|
+
flyoutPanels.clear();
|
|
406
|
+
});
|
|
407
|
+
const isolateAtDepth = (key) => {
|
|
408
|
+
const depth = findNavPath(ctx.items, key).length - 1;
|
|
409
|
+
const isSameDepthOther = (k) => k !== key && findNavPath(ctx.items, k).length - 1 === depth;
|
|
410
|
+
for (const state of [hoveredBranches, clickedBranches, focusedBranches]) {
|
|
411
|
+
if (state.value.some(isSameDepthOther)) {
|
|
412
|
+
state.value = state.value.filter((k) => !isSameDepthOther(k));
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
const scheduleOpen = (key) => {
|
|
417
|
+
clearOpenTimer();
|
|
418
|
+
openTimer = setTimeout(() => {
|
|
419
|
+
openTimer = null;
|
|
420
|
+
isolateAtDepth(key);
|
|
421
|
+
setBranchInteraction(hoveredBranches, key, true);
|
|
422
|
+
}, HOVER_OPEN_DELAY_VAL);
|
|
423
|
+
};
|
|
424
|
+
const scheduleClose = (key) => {
|
|
425
|
+
cancelClose(key);
|
|
426
|
+
closeTimers.set(
|
|
427
|
+
key,
|
|
428
|
+
setTimeout(() => {
|
|
429
|
+
closeTimers.delete(key);
|
|
430
|
+
setBranchInteraction(hoveredBranches, key, false);
|
|
431
|
+
}, HOVER_CLOSE_DELAY_VAL)
|
|
432
|
+
);
|
|
433
|
+
};
|
|
434
|
+
const closeHorizontalMenus = () => {
|
|
435
|
+
if (!ctx.flyoutMode.value) return;
|
|
436
|
+
cancelAllTimers();
|
|
437
|
+
hovered.value = null;
|
|
438
|
+
hoveredBranches.value = [];
|
|
439
|
+
focusedBranches.value = [];
|
|
440
|
+
clickedBranches.value = [];
|
|
441
|
+
};
|
|
442
|
+
const select = (node) => {
|
|
443
|
+
if (node.disabled) return;
|
|
444
|
+
closeHorizontalMenus();
|
|
445
|
+
ctx.emitSelect(node.key, node);
|
|
446
|
+
};
|
|
447
|
+
const toggleFlyout = (key) => {
|
|
448
|
+
cancelAllTimers();
|
|
449
|
+
const current = clickedBranches.value;
|
|
450
|
+
if (current.includes(key)) {
|
|
451
|
+
clickedBranches.value = current.filter((k) => k !== key);
|
|
452
|
+
setBranchInteraction(hoveredBranches, key, false);
|
|
453
|
+
setBranchInteraction(focusedBranches, key, false);
|
|
454
|
+
} else {
|
|
455
|
+
isolateAtDepth(key);
|
|
456
|
+
clickedBranches.value = [...clickedBranches.value, key];
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
const openFlyout = (key) => {
|
|
460
|
+
cancelAllTimers();
|
|
461
|
+
isolateAtDepth(key);
|
|
462
|
+
setBranchInteraction(focusedBranches, key, true);
|
|
463
|
+
};
|
|
464
|
+
const setBranchInteraction = (state, key, enabled) => {
|
|
465
|
+
const current = state.value;
|
|
466
|
+
if (enabled) {
|
|
467
|
+
if (!current.includes(key)) state.value = [...current, key];
|
|
468
|
+
} else if (current.includes(key)) {
|
|
469
|
+
state.value = current.filter((item) => item !== key);
|
|
470
|
+
}
|
|
471
|
+
};
|
|
472
|
+
const keepsPointerInside = (container, event) => {
|
|
473
|
+
if (!container || !(container instanceof HTMLElement)) return false;
|
|
474
|
+
const next = event.relatedTarget;
|
|
475
|
+
return !!(next && next instanceof Node && container.contains(next));
|
|
476
|
+
};
|
|
477
|
+
const interactionKeyAtDepth = (keys, depth) => keys.find((key) => findNavPath(ctx.items, key).length === depth + 1);
|
|
478
|
+
const horizontalBranchVisible = (key, depth) => {
|
|
479
|
+
const hoveredAtDepth = interactionKeyAtDepth(hoveredBranches.value, depth);
|
|
480
|
+
if (hoveredAtDepth) return hoveredAtDepth === key;
|
|
481
|
+
const clickedAtDepth = interactionKeyAtDepth(clickedBranches.value, depth);
|
|
482
|
+
if (clickedAtDepth) return clickedAtDepth === key;
|
|
483
|
+
return interactionKeyAtDepth(focusedBranches.value, depth) === key;
|
|
484
|
+
};
|
|
485
|
+
const shownFlyoutKeys = computed(() => {
|
|
486
|
+
if (!ctx.flyoutMode.value) return [];
|
|
487
|
+
const keys = [];
|
|
488
|
+
for (const node of ctx.tree.value) {
|
|
489
|
+
if (isBranch(node) && horizontalBranchVisible(node.key, 0)) keys.push(node.key);
|
|
490
|
+
}
|
|
491
|
+
return keys;
|
|
492
|
+
});
|
|
493
|
+
const repositionOpenFlyouts = () => {
|
|
494
|
+
for (const key of shownFlyoutKeys.value) positionFlyout(key);
|
|
495
|
+
};
|
|
496
|
+
let viewportListenersActive = false;
|
|
497
|
+
const attachViewportListeners = () => {
|
|
498
|
+
if (viewportListenersActive || typeof document === "undefined") return;
|
|
499
|
+
viewportListenersActive = true;
|
|
500
|
+
document.addEventListener("scroll", repositionOpenFlyouts, true);
|
|
501
|
+
window.addEventListener("resize", repositionOpenFlyouts);
|
|
502
|
+
};
|
|
503
|
+
const detachViewportListeners = () => {
|
|
504
|
+
if (!viewportListenersActive || typeof document === "undefined") return;
|
|
505
|
+
viewportListenersActive = false;
|
|
506
|
+
document.removeEventListener("scroll", repositionOpenFlyouts, true);
|
|
507
|
+
window.removeEventListener("resize", repositionOpenFlyouts);
|
|
508
|
+
};
|
|
509
|
+
watch(
|
|
510
|
+
shownFlyoutKeys,
|
|
511
|
+
(keys, prev) => {
|
|
512
|
+
if (keys.length > 0 && prev.length === 0) attachViewportListeners();
|
|
513
|
+
else if (keys.length === 0 && prev.length > 0) detachViewportListeners();
|
|
514
|
+
for (const key of keys) positionFlyout(key);
|
|
515
|
+
},
|
|
516
|
+
{ flush: "post" }
|
|
517
|
+
);
|
|
518
|
+
return {
|
|
519
|
+
hovered,
|
|
520
|
+
hoveredBranches,
|
|
521
|
+
focusedBranches,
|
|
522
|
+
clickedBranches,
|
|
523
|
+
select,
|
|
524
|
+
toggleFlyout,
|
|
525
|
+
openFlyout,
|
|
526
|
+
closeHorizontalMenus,
|
|
527
|
+
setBranchInteraction,
|
|
528
|
+
keepsPointerInside,
|
|
529
|
+
interactionKeyAtDepth,
|
|
530
|
+
horizontalBranchVisible,
|
|
531
|
+
shownFlyoutKeys,
|
|
532
|
+
setFlyoutRef,
|
|
533
|
+
flyoutTriggers,
|
|
534
|
+
flyoutPanels,
|
|
535
|
+
suppressFocusOpen: { get: () => suppressFocusOpen },
|
|
536
|
+
setSuppressFocusOpen: (value) => {
|
|
537
|
+
suppressFocusOpen = value;
|
|
538
|
+
},
|
|
539
|
+
cancelClose,
|
|
540
|
+
scheduleOpen,
|
|
541
|
+
scheduleClose,
|
|
542
|
+
cancelAllTimers
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
function createNavMenuKeydownHandler(deps) {
|
|
546
|
+
const {
|
|
547
|
+
items,
|
|
548
|
+
flyoutMode,
|
|
549
|
+
expanded,
|
|
550
|
+
toggle,
|
|
551
|
+
openFlyout,
|
|
552
|
+
closeHorizontalMenus,
|
|
553
|
+
horizontalBranchVisible,
|
|
554
|
+
setBranchInteraction,
|
|
555
|
+
focusedBranches,
|
|
556
|
+
collapsed,
|
|
557
|
+
hoveredBranches,
|
|
558
|
+
clickedBranches,
|
|
559
|
+
setSuppressFocusOpen
|
|
560
|
+
} = deps;
|
|
561
|
+
return (e) => {
|
|
562
|
+
const root = e.currentTarget;
|
|
563
|
+
const buttons = Array.from(root.querySelectorAll("[data-iris-nav-item]")).filter(
|
|
564
|
+
(button) => !button.closest('[data-iris-nav-children][aria-hidden="true"]')
|
|
565
|
+
);
|
|
566
|
+
if (buttons.length === 0) return;
|
|
567
|
+
const idx = buttons.indexOf(document.activeElement);
|
|
568
|
+
const focusAt = (i) => buttons[(i + buttons.length) % buttons.length]?.focus();
|
|
569
|
+
const key = idx >= 0 ? buttons[idx]?.getAttribute("data-key") : void 0;
|
|
570
|
+
const node = key ? findNavNode(items, key) : void 0;
|
|
571
|
+
const depth = idx >= 0 ? Number(buttons[idx]?.getAttribute("data-depth") ?? 0) : 0;
|
|
572
|
+
switch (e.key) {
|
|
573
|
+
case "ArrowDown": {
|
|
574
|
+
e.preventDefault();
|
|
575
|
+
if (flyoutMode() && node && isBranch(node)) {
|
|
576
|
+
openFlyout(key);
|
|
577
|
+
const group = buttons[idx].closest("[data-iris-nav-group]");
|
|
578
|
+
void nextTick(() => {
|
|
579
|
+
group?.querySelector("[data-iris-nav-children] [data-iris-nav-item]")?.focus();
|
|
580
|
+
});
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
focusAt(idx < 0 ? 0 : idx + 1);
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
case "ArrowUp": {
|
|
587
|
+
e.preventDefault();
|
|
588
|
+
if (flyoutMode() && node && isBranch(node) && horizontalBranchVisible(key, depth)) {
|
|
589
|
+
setBranchInteraction(focusedBranches, key, false);
|
|
590
|
+
setBranchInteraction(clickedBranches, key, false);
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
focusAt(idx < 0 ? buttons.length - 1 : idx - 1);
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
case "Home":
|
|
597
|
+
e.preventDefault();
|
|
598
|
+
buttons[0]?.focus();
|
|
599
|
+
return;
|
|
600
|
+
case "End":
|
|
601
|
+
e.preventDefault();
|
|
602
|
+
buttons[buttons.length - 1]?.focus();
|
|
603
|
+
return;
|
|
604
|
+
case "Escape": {
|
|
605
|
+
if (flyoutMode()) {
|
|
606
|
+
const openKeys = [
|
|
607
|
+
...hoveredBranches.value,
|
|
608
|
+
...clickedBranches.value,
|
|
609
|
+
...focusedBranches.value
|
|
610
|
+
];
|
|
611
|
+
if (openKeys.length > 0) {
|
|
612
|
+
e.preventDefault();
|
|
613
|
+
const openTop = openKeys.find((k) => findNavPath(items, k).length === 1);
|
|
614
|
+
closeHorizontalMenus();
|
|
615
|
+
if (openTop) {
|
|
616
|
+
setSuppressFocusOpen(true);
|
|
617
|
+
buttons.find((b) => b.getAttribute("data-key") === openTop)?.focus();
|
|
618
|
+
void nextTick(() => {
|
|
619
|
+
setSuppressFocusOpen(false);
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
if (collapsed || idx < 0 || !key || !node) return;
|
|
628
|
+
if (e.key === "ArrowRight") {
|
|
629
|
+
e.preventDefault();
|
|
630
|
+
if (isBranch(node)) {
|
|
631
|
+
if (flyoutMode() || !expanded().includes(key)) {
|
|
632
|
+
if (flyoutMode()) openFlyout(key);
|
|
633
|
+
else toggle(key);
|
|
634
|
+
const group = buttons[idx].closest("[data-iris-nav-group]");
|
|
635
|
+
void nextTick(() => {
|
|
636
|
+
group?.querySelector("[data-iris-nav-children] [data-iris-nav-item]")?.focus();
|
|
637
|
+
});
|
|
638
|
+
} else {
|
|
639
|
+
focusAt(idx + 1);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
} else if (e.key === "ArrowLeft") {
|
|
643
|
+
e.preventDefault();
|
|
644
|
+
if (flyoutMode() && isBranch(node)) {
|
|
645
|
+
setBranchInteraction(focusedBranches, key, false);
|
|
646
|
+
setBranchInteraction(clickedBranches, key, false);
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
if (isBranch(node) && expanded().includes(key)) {
|
|
650
|
+
toggle(key);
|
|
651
|
+
} else {
|
|
652
|
+
const parentKey = findNavPath(items, key).at(-2)?.key;
|
|
653
|
+
if (parentKey) {
|
|
654
|
+
buttons.find((b) => b.getAttribute("data-key") === parentKey)?.focus();
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
};
|
|
659
|
+
}
|
|
317
660
|
|
|
318
661
|
// src/admin/NavMenu.ts
|
|
319
662
|
var IrisNavMenu = defineComponent({
|
|
@@ -347,6 +690,7 @@ var IrisNavMenu = defineComponent({
|
|
|
347
690
|
const activePath = computed(
|
|
348
691
|
() => props.activeKey ? findNavPath(props.items, props.activeKey).map((n) => n.key) : []
|
|
349
692
|
);
|
|
693
|
+
const flyoutMode = computed(() => props.orientation === "horizontal" || props.collapsed);
|
|
350
694
|
const isControlled = computed(() => props.expandedKeys !== void 0);
|
|
351
695
|
const model = createExpansion({
|
|
352
696
|
mode: "multiple",
|
|
@@ -361,12 +705,9 @@ var IrisNavMenu = defineComponent({
|
|
|
361
705
|
const expanded = computed(
|
|
362
706
|
() => isControlled.value ? props.expandedKeys : internalExpanded.value
|
|
363
707
|
);
|
|
364
|
-
watch(
|
|
365
|
-
()
|
|
366
|
-
|
|
367
|
-
if (!isControlled.value) model.merge(key ? branchTrail(props.items, key) : []);
|
|
368
|
-
}
|
|
369
|
-
);
|
|
708
|
+
watch([() => props.activeKey, () => props.items], ([key]) => {
|
|
709
|
+
if (!isControlled.value) model.merge(key ? branchTrail(props.items, key) : []);
|
|
710
|
+
});
|
|
370
711
|
const toggle = (key) => {
|
|
371
712
|
if (isControlled.value) {
|
|
372
713
|
const cur = props.expandedKeys;
|
|
@@ -379,39 +720,35 @@ var IrisNavMenu = defineComponent({
|
|
|
379
720
|
emit("update:expandedKeys", model.get());
|
|
380
721
|
}
|
|
381
722
|
};
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
};
|
|
391
|
-
const
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
const hoveredAtDepth = interactionKeyAtDepth(hoveredBranches.value, depth);
|
|
412
|
-
if (hoveredAtDepth) return hoveredAtDepth === key;
|
|
413
|
-
return interactionKeyAtDepth(focusedBranches.value, depth) === key;
|
|
414
|
-
};
|
|
723
|
+
const flyout = createNavMenuFlyout({
|
|
724
|
+
items: props.items,
|
|
725
|
+
tree,
|
|
726
|
+
expanded,
|
|
727
|
+
flyoutMode: { value: flyoutMode.value },
|
|
728
|
+
collapsed: props.collapsed,
|
|
729
|
+
toggle,
|
|
730
|
+
emitSelect: (key, node) => emit("select", key, node)
|
|
731
|
+
});
|
|
732
|
+
const {
|
|
733
|
+
hovered,
|
|
734
|
+
hoveredBranches,
|
|
735
|
+
focusedBranches,
|
|
736
|
+
clickedBranches,
|
|
737
|
+
select,
|
|
738
|
+
toggleFlyout,
|
|
739
|
+
openFlyout,
|
|
740
|
+
closeHorizontalMenus,
|
|
741
|
+
setBranchInteraction,
|
|
742
|
+
keepsPointerInside,
|
|
743
|
+
horizontalBranchVisible,
|
|
744
|
+
setFlyoutRef,
|
|
745
|
+
flyoutTriggers,
|
|
746
|
+
flyoutPanels,
|
|
747
|
+
suppressFocusOpen,
|
|
748
|
+
cancelClose,
|
|
749
|
+
scheduleOpen,
|
|
750
|
+
scheduleClose
|
|
751
|
+
} = flyout;
|
|
415
752
|
const itemClass = (opts) => {
|
|
416
753
|
const depth = Math.min(9, opts.depth);
|
|
417
754
|
return [
|
|
@@ -434,81 +771,47 @@ var IrisNavMenu = defineComponent({
|
|
|
434
771
|
},
|
|
435
772
|
String(node.badge)
|
|
436
773
|
) : null;
|
|
437
|
-
const
|
|
774
|
+
const renderItem = (node, depth) => {
|
|
438
775
|
const branch = isBranch(node);
|
|
439
|
-
const
|
|
440
|
-
|
|
776
|
+
const horizontal = flyoutMode.value;
|
|
777
|
+
const open = expanded.value.includes(node.key);
|
|
778
|
+
const shown = horizontal ? horizontalBranchVisible(node.key, depth) : open;
|
|
779
|
+
const active = node.key === props.activeKey;
|
|
780
|
+
const trail = branch && !active && activePath.value.includes(node.key);
|
|
781
|
+
const rowHovered = hovered.value === node.key || horizontal && shown;
|
|
782
|
+
const arrowReversed = branch && !node.disabled && (active || trail || shown || rowHovered);
|
|
783
|
+
const isFlyoutRoot = horizontal && branch && depth === 0;
|
|
784
|
+
const row = h(
|
|
441
785
|
"button",
|
|
442
786
|
{
|
|
443
|
-
key: node.key,
|
|
444
787
|
type: "button",
|
|
788
|
+
ref: (el) => {
|
|
789
|
+
if (isFlyoutRoot) setFlyoutRef(flyoutTriggers, node.key, el);
|
|
790
|
+
},
|
|
445
791
|
class: [
|
|
446
792
|
...itemClass({
|
|
447
|
-
depth
|
|
793
|
+
depth,
|
|
448
794
|
active,
|
|
449
|
-
trail
|
|
450
|
-
hovered:
|
|
451
|
-
open: false,
|
|
795
|
+
trail,
|
|
796
|
+
hovered: rowHovered,
|
|
797
|
+
open: branch ? shown : false,
|
|
452
798
|
disabled: !!node.disabled,
|
|
453
799
|
branch
|
|
454
800
|
}),
|
|
455
|
-
"is-collapsed"
|
|
801
|
+
...props.collapsed && depth === 0 ? ["is-collapsed"] : []
|
|
456
802
|
],
|
|
457
803
|
"data-iris-nav-item": "",
|
|
458
804
|
"data-key": node.key,
|
|
459
|
-
"data-active": active ? "true" : void 0,
|
|
460
|
-
"data-branch": branch ? "true" : void 0,
|
|
461
|
-
"data-hovered": hovered.value === node.key ? "true" : void 0,
|
|
462
|
-
disabled: node.disabled,
|
|
463
|
-
title: node.title,
|
|
464
|
-
"aria-label": branch ? `${node.title} (section)` : node.title,
|
|
465
|
-
"aria-current": active && !branch ? "page" : void 0,
|
|
466
|
-
onMouseenter: () => {
|
|
467
|
-
if (!node.disabled) hovered.value = node.key;
|
|
468
|
-
},
|
|
469
|
-
onMouseleave: (event) => {
|
|
470
|
-
if (hovered.value === node.key && !keepsPointerInside(event.currentTarget, event)) {
|
|
471
|
-
hovered.value = null;
|
|
472
|
-
}
|
|
473
|
-
},
|
|
474
|
-
onClick: () => select(branch ? firstLeaf(node) : node)
|
|
475
|
-
},
|
|
476
|
-
[
|
|
477
|
-
iconNode(node, 20) ?? h("span", { class: "iris-nav-menu-fallback-icon" }, node.title.charAt(0))
|
|
478
|
-
]
|
|
479
|
-
);
|
|
480
|
-
});
|
|
481
|
-
const renderItem = (node, depth) => {
|
|
482
|
-
const branch = isBranch(node);
|
|
483
|
-
const open = expanded.value.includes(node.key);
|
|
484
|
-
const horizontal = props.orientation === "horizontal";
|
|
485
|
-
const shown = horizontal ? horizontalBranchVisible(node.key, depth) : open;
|
|
486
|
-
const active = node.key === props.activeKey;
|
|
487
|
-
const trail = branch && !active && activePath.value.includes(node.key);
|
|
488
|
-
const arrowReversed = branch && !node.disabled && (active || trail || shown || hovered.value === node.key);
|
|
489
|
-
const row = h(
|
|
490
|
-
"button",
|
|
491
|
-
{
|
|
492
|
-
type: "button",
|
|
493
|
-
class: itemClass({
|
|
494
|
-
depth,
|
|
495
|
-
active,
|
|
496
|
-
trail,
|
|
497
|
-
hovered: hovered.value === node.key,
|
|
498
|
-
open: branch ? shown : false,
|
|
499
|
-
disabled: !!node.disabled,
|
|
500
|
-
branch
|
|
501
|
-
}),
|
|
502
|
-
"data-iris-nav-item": "",
|
|
503
|
-
"data-key": node.key,
|
|
504
805
|
"data-branch": branch ? "true" : void 0,
|
|
505
806
|
"data-active": active ? "true" : void 0,
|
|
506
807
|
"data-active-trail": trail ? "true" : void 0,
|
|
507
808
|
"data-open": branch && shown ? "true" : void 0,
|
|
508
|
-
"data-hovered":
|
|
809
|
+
"data-hovered": rowHovered ? "true" : void 0,
|
|
509
810
|
"data-depth": String(depth),
|
|
510
811
|
"data-orientation": props.orientation,
|
|
511
812
|
disabled: node.disabled,
|
|
813
|
+
title: props.collapsed ? node.title : void 0,
|
|
814
|
+
"aria-label": props.collapsed ? branch ? `${node.title} (section)` : node.title : void 0,
|
|
512
815
|
"aria-expanded": branch ? shown ? "true" : "false" : void 0,
|
|
513
816
|
"aria-current": active ? "page" : void 0,
|
|
514
817
|
onMouseenter: () => {
|
|
@@ -519,7 +822,17 @@ var IrisNavMenu = defineComponent({
|
|
|
519
822
|
hovered.value = null;
|
|
520
823
|
}
|
|
521
824
|
},
|
|
522
|
-
onClick: () =>
|
|
825
|
+
onClick: () => {
|
|
826
|
+
if (props.collapsed && branch) {
|
|
827
|
+
select(firstLeaf(node));
|
|
828
|
+
} else if (horizontal && branch) {
|
|
829
|
+
toggleFlyout(node.key);
|
|
830
|
+
} else if (branch) {
|
|
831
|
+
toggle(node.key);
|
|
832
|
+
} else {
|
|
833
|
+
select(node);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
523
836
|
},
|
|
524
837
|
[
|
|
525
838
|
iconNode(node),
|
|
@@ -531,54 +844,49 @@ var IrisNavMenu = defineComponent({
|
|
|
531
844
|
node.title
|
|
532
845
|
),
|
|
533
846
|
badgeNode(node),
|
|
534
|
-
branch ? h(IrisIcon, {
|
|
535
|
-
name: horizontal && depth === 0 ? "chevron-down" : "chevron-right",
|
|
847
|
+
branch && !(props.collapsed && depth === 0) ? h(IrisIcon, {
|
|
848
|
+
name: horizontal && depth === 0 && !props.collapsed ? "chevron-down" : "chevron-right",
|
|
536
849
|
size: 16,
|
|
537
850
|
class: "iris-nav-menu-arrow",
|
|
538
851
|
"data-reversed": arrowReversed ? "true" : void 0
|
|
539
852
|
}) : null
|
|
540
853
|
]
|
|
541
854
|
);
|
|
542
|
-
if (!branch || !horizontal && !open)
|
|
543
|
-
return h(
|
|
544
|
-
"div",
|
|
545
|
-
{
|
|
546
|
-
key: node.key,
|
|
547
|
-
"data-iris-nav-group": branch ? "" : void 0,
|
|
548
|
-
class: ["iris-nav-menu-group", `iris-nav-menu-group--depth-${Math.min(9, depth)}`]
|
|
549
|
-
},
|
|
550
|
-
[row]
|
|
551
|
-
);
|
|
552
855
|
return h(
|
|
553
856
|
"div",
|
|
554
857
|
{
|
|
555
858
|
key: node.key,
|
|
556
|
-
"data-iris-nav-group": "",
|
|
557
|
-
"data-open": shown ? "true" : void 0,
|
|
859
|
+
"data-iris-nav-group": branch ? "" : void 0,
|
|
860
|
+
"data-open": branch && shown ? "true" : void 0,
|
|
558
861
|
"data-depth": String(depth),
|
|
559
862
|
class: ["iris-nav-menu-group", `iris-nav-menu-group--depth-${Math.min(9, depth)}`],
|
|
560
|
-
...horizontal ? {
|
|
863
|
+
...horizontal && branch ? {
|
|
561
864
|
onMouseenter: (event) => {
|
|
562
|
-
if (!keepsPointerInside(event.currentTarget, event)) {
|
|
563
|
-
|
|
865
|
+
if (!node.disabled && !keepsPointerInside(event.currentTarget, event)) {
|
|
866
|
+
cancelClose(node.key);
|
|
867
|
+
scheduleOpen(node.key);
|
|
564
868
|
}
|
|
565
869
|
},
|
|
566
870
|
onMouseover: (event) => {
|
|
567
|
-
if (!keepsPointerInside(event.currentTarget, event)) {
|
|
568
|
-
|
|
871
|
+
if (!node.disabled && !keepsPointerInside(event.currentTarget, event)) {
|
|
872
|
+
cancelClose(node.key);
|
|
873
|
+
scheduleOpen(node.key);
|
|
569
874
|
}
|
|
570
875
|
},
|
|
571
876
|
onMouseout: (event) => {
|
|
572
|
-
if (!keepsPointerInside(event.currentTarget, event)) {
|
|
573
|
-
|
|
877
|
+
if (!node.disabled && !keepsPointerInside(event.currentTarget, event)) {
|
|
878
|
+
scheduleClose(node.key);
|
|
574
879
|
}
|
|
575
880
|
},
|
|
576
881
|
onMouseleave: (event) => {
|
|
577
|
-
if (!keepsPointerInside(event.currentTarget, event)) {
|
|
578
|
-
|
|
882
|
+
if (!node.disabled && !keepsPointerInside(event.currentTarget, event)) {
|
|
883
|
+
scheduleClose(node.key);
|
|
579
884
|
}
|
|
580
885
|
},
|
|
581
|
-
onFocusin: () =>
|
|
886
|
+
onFocusin: () => {
|
|
887
|
+
if (suppressFocusOpen.get()) return;
|
|
888
|
+
setBranchInteraction(focusedBranches, node.key, true);
|
|
889
|
+
},
|
|
582
890
|
onFocusout: (event) => {
|
|
583
891
|
const group = event.currentTarget;
|
|
584
892
|
const next = event.relatedTarget;
|
|
@@ -590,66 +898,62 @@ var IrisNavMenu = defineComponent({
|
|
|
590
898
|
},
|
|
591
899
|
[
|
|
592
900
|
row,
|
|
593
|
-
h(
|
|
901
|
+
branch ? h(
|
|
594
902
|
"div",
|
|
595
903
|
{
|
|
596
904
|
class: "iris-nav-menu-children",
|
|
597
905
|
"data-iris-nav-children": "",
|
|
906
|
+
ref: (el) => {
|
|
907
|
+
if (isFlyoutRoot) setFlyoutRef(flyoutPanels, node.key, el);
|
|
908
|
+
},
|
|
598
909
|
role: "group",
|
|
599
|
-
"aria-hidden":
|
|
910
|
+
"aria-hidden": shown ? void 0 : "true"
|
|
600
911
|
},
|
|
601
|
-
|
|
602
|
-
|
|
912
|
+
[
|
|
913
|
+
h(
|
|
914
|
+
"div",
|
|
915
|
+
{ class: "iris-nav-menu-children-inner" },
|
|
916
|
+
(node.children ?? []).map((child) => renderItem(child, depth + 1))
|
|
917
|
+
)
|
|
918
|
+
]
|
|
919
|
+
) : null
|
|
603
920
|
]
|
|
604
921
|
);
|
|
605
922
|
};
|
|
606
|
-
const
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
return;
|
|
619
|
-
case "ArrowUp":
|
|
620
|
-
e.preventDefault();
|
|
621
|
-
focusAt(idx < 0 ? buttons.length - 1 : idx - 1);
|
|
622
|
-
return;
|
|
623
|
-
case "Home":
|
|
624
|
-
e.preventDefault();
|
|
625
|
-
buttons[0]?.focus();
|
|
626
|
-
return;
|
|
627
|
-
case "End":
|
|
628
|
-
e.preventDefault();
|
|
629
|
-
buttons[buttons.length - 1]?.focus();
|
|
630
|
-
return;
|
|
631
|
-
}
|
|
632
|
-
if (props.collapsed || idx < 0) return;
|
|
633
|
-
const key = buttons[idx]?.getAttribute("data-key");
|
|
634
|
-
if (!key) return;
|
|
635
|
-
const node = findNavNode(props.items, key);
|
|
636
|
-
if (e.key === "ArrowRight" && node && isBranch(node)) {
|
|
637
|
-
e.preventDefault();
|
|
638
|
-
if (!expanded.value.includes(key)) toggle(key);
|
|
639
|
-
else focusAt(idx + 1);
|
|
640
|
-
} else if (e.key === "ArrowLeft") {
|
|
641
|
-
if (node && isBranch(node) && expanded.value.includes(key)) {
|
|
642
|
-
e.preventDefault();
|
|
643
|
-
toggle(key);
|
|
644
|
-
} else {
|
|
645
|
-
const parentKey = findNavPath(props.items, key).at(-2)?.key;
|
|
646
|
-
if (parentKey) {
|
|
647
|
-
e.preventDefault();
|
|
648
|
-
buttons.find((b) => b.getAttribute("data-key") === parentKey)?.focus();
|
|
649
|
-
}
|
|
923
|
+
const rootRef = shallowRef(null);
|
|
924
|
+
watch(
|
|
925
|
+
[() => props.activeKey, () => props.items],
|
|
926
|
+
() => {
|
|
927
|
+
if (!props.activeKey) return;
|
|
928
|
+
const root = rootRef.value;
|
|
929
|
+
if (!root) return;
|
|
930
|
+
const el = root.querySelector('[data-iris-nav-item][data-active="true"]');
|
|
931
|
+
if (!el || typeof el.scrollIntoView !== "function") return;
|
|
932
|
+
let behavior = "auto";
|
|
933
|
+
if (typeof window !== "undefined" && typeof window.matchMedia === "function" && !window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
|
934
|
+
behavior = "smooth";
|
|
650
935
|
}
|
|
651
|
-
|
|
652
|
-
|
|
936
|
+
el.scrollIntoView({ block: "nearest", inline: "nearest", behavior });
|
|
937
|
+
},
|
|
938
|
+
{ flush: "post" }
|
|
939
|
+
);
|
|
940
|
+
const onKeydown = createNavMenuKeydownHandler({
|
|
941
|
+
items: props.items,
|
|
942
|
+
flyoutMode: () => flyoutMode.value,
|
|
943
|
+
expanded: () => expanded.value,
|
|
944
|
+
toggle,
|
|
945
|
+
openFlyout,
|
|
946
|
+
closeHorizontalMenus,
|
|
947
|
+
horizontalBranchVisible,
|
|
948
|
+
setBranchInteraction,
|
|
949
|
+
focusedBranches,
|
|
950
|
+
hoveredBranches,
|
|
951
|
+
clickedBranches,
|
|
952
|
+
setSuppressFocusOpen: (v) => {
|
|
953
|
+
flyout.setSuppressFocusOpen(v);
|
|
954
|
+
},
|
|
955
|
+
collapsed: props.collapsed
|
|
956
|
+
});
|
|
653
957
|
const menuClass = [
|
|
654
958
|
"iris-nav-menu",
|
|
655
959
|
`iris-nav-menu--${props.orientation}`,
|
|
@@ -659,6 +963,9 @@ var IrisNavMenu = defineComponent({
|
|
|
659
963
|
"nav",
|
|
660
964
|
{
|
|
661
965
|
...attrs,
|
|
966
|
+
ref: (el) => {
|
|
967
|
+
rootRef.value = el ?? null;
|
|
968
|
+
},
|
|
662
969
|
class: [...menuClass, attrs.class],
|
|
663
970
|
"data-iris-nav-menu": "",
|
|
664
971
|
"data-collapsed": props.collapsed ? "true" : void 0,
|
|
@@ -667,7 +974,7 @@ var IrisNavMenu = defineComponent({
|
|
|
667
974
|
onKeydown,
|
|
668
975
|
style: attrs.style
|
|
669
976
|
},
|
|
670
|
-
|
|
977
|
+
tree.value.map((node) => renderItem(node, 0))
|
|
671
978
|
);
|
|
672
979
|
}
|
|
673
980
|
});
|
|
@@ -737,11 +1044,11 @@ var IrisBreadcrumb = defineComponent({
|
|
|
737
1044
|
style: {
|
|
738
1045
|
display: "inline-flex",
|
|
739
1046
|
alignItems: "center",
|
|
740
|
-
gap: "
|
|
1047
|
+
gap: "var(--iris-space-xs, 8px)",
|
|
741
1048
|
margin: "0",
|
|
742
1049
|
padding: "0",
|
|
743
1050
|
listStyle: "none",
|
|
744
|
-
fontSize: "14px"
|
|
1051
|
+
fontSize: "var(--iris-font-size-md, 14px)"
|
|
745
1052
|
}
|
|
746
1053
|
},
|
|
747
1054
|
items
|
|
@@ -1069,12 +1376,12 @@ var IrisDropdownMenu = defineComponent({
|
|
|
1069
1376
|
onKeydown: onKeyDown,
|
|
1070
1377
|
style: {
|
|
1071
1378
|
...floatingStyles.value,
|
|
1072
|
-
background: "var(--iris-surface)",
|
|
1379
|
+
background: "var(--iris-surface-floating)",
|
|
1073
1380
|
color: "var(--iris-foreground)",
|
|
1074
1381
|
border: "1px solid var(--iris-border)",
|
|
1075
1382
|
borderRadius: "var(--iris-radius-md)",
|
|
1076
1383
|
padding: "var(--iris-padding-sm)",
|
|
1077
|
-
boxShadow: "
|
|
1384
|
+
boxShadow: "var(--iris-shadow-lg)",
|
|
1078
1385
|
minWidth: "160px",
|
|
1079
1386
|
outline: "none",
|
|
1080
1387
|
zIndex: "1000",
|
|
@@ -1139,14 +1446,14 @@ var IrisDropdownItem = defineComponent({
|
|
|
1139
1446
|
display: "flex",
|
|
1140
1447
|
alignItems: "center",
|
|
1141
1448
|
gap: "var(--iris-gap-sm)",
|
|
1142
|
-
padding: "6px var(--iris-padding-md)",
|
|
1449
|
+
padding: "var(--iris-padding-sm, 6px) var(--iris-padding-md)",
|
|
1143
1450
|
borderRadius: "var(--iris-radius-sm)",
|
|
1144
1451
|
cursor: props.disabled ? "not-allowed" : "pointer",
|
|
1145
1452
|
opacity: props.disabled ? "0.5" : "1",
|
|
1146
1453
|
background: hovered.value && !props.disabled ? "var(--iris-surface-hover)" : "transparent",
|
|
1147
1454
|
color: "inherit",
|
|
1148
1455
|
outline: "none",
|
|
1149
|
-
fontSize: "14px",
|
|
1456
|
+
fontSize: "var(--iris-font-size-md, 14px)",
|
|
1150
1457
|
transition: "background-color 80ms ease",
|
|
1151
1458
|
...attrs.style ?? {}
|
|
1152
1459
|
}
|
|
@@ -1259,12 +1566,12 @@ var IrisAdminTabs = defineComponent({
|
|
|
1259
1566
|
style: {
|
|
1260
1567
|
display: "inline-flex",
|
|
1261
1568
|
alignItems: "center",
|
|
1262
|
-
gap: "
|
|
1569
|
+
gap: "var(--iris-space-xs, 8px)",
|
|
1263
1570
|
border: "none",
|
|
1264
1571
|
background: "transparent",
|
|
1265
1572
|
color: "inherit",
|
|
1266
1573
|
font: "inherit",
|
|
1267
|
-
fontSize: "13px",
|
|
1574
|
+
fontSize: "var(--iris-font-size-sm, 13px)",
|
|
1268
1575
|
cursor: "pointer",
|
|
1269
1576
|
padding: "0"
|
|
1270
1577
|
},
|
|
@@ -1314,7 +1621,7 @@ var IrisAdminTabs = defineComponent({
|
|
|
1314
1621
|
display: "inline-flex",
|
|
1315
1622
|
alignItems: "center",
|
|
1316
1623
|
gap: "4px",
|
|
1317
|
-
padding: "
|
|
1624
|
+
padding: "var(--iris-padding-sm, 6px) var(--iris-space-xs, 8px) var(--iris-padding-sm, 6px) var(--iris-space-sm, 12px)",
|
|
1318
1625
|
borderRadius: "var(--iris-radius-md, 6px)",
|
|
1319
1626
|
border: `1px solid ${active ? "var(--iris-primary)" : "var(--iris-border)"}`,
|
|
1320
1627
|
background: active ? "var(--iris-primary)" : "var(--iris-surface)",
|
|
@@ -1330,27 +1637,23 @@ var IrisAdminTabs = defineComponent({
|
|
|
1330
1637
|
default: () => [
|
|
1331
1638
|
h(
|
|
1332
1639
|
IrisDropdownTrigger,
|
|
1333
|
-
{ "aria-label": tr("admin.tabActions") },
|
|
1334
1640
|
{
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
},
|
|
1352
|
-
[h(IrisIcon, { name: "more-horizontal", size: 16 })]
|
|
1353
|
-
)
|
|
1641
|
+
"aria-label": tr("admin.tabActions"),
|
|
1642
|
+
style: {
|
|
1643
|
+
display: "inline-flex",
|
|
1644
|
+
alignItems: "center",
|
|
1645
|
+
justifyContent: "center",
|
|
1646
|
+
width: "28px",
|
|
1647
|
+
height: "28px",
|
|
1648
|
+
borderRadius: "var(--iris-radius-md, 6px)",
|
|
1649
|
+
border: "1px solid var(--iris-border)",
|
|
1650
|
+
background: "var(--iris-surface)",
|
|
1651
|
+
color: "var(--iris-foreground)",
|
|
1652
|
+
cursor: "pointer"
|
|
1653
|
+
}
|
|
1654
|
+
},
|
|
1655
|
+
{
|
|
1656
|
+
default: () => h(IrisIcon, { name: "more-horizontal", size: 16 })
|
|
1354
1657
|
}
|
|
1355
1658
|
),
|
|
1356
1659
|
h(IrisDropdownMenu, null, {
|
|
@@ -1379,8 +1682,8 @@ var IrisAdminTabs = defineComponent({
|
|
|
1379
1682
|
style: {
|
|
1380
1683
|
display: "flex",
|
|
1381
1684
|
alignItems: "center",
|
|
1382
|
-
gap: "
|
|
1383
|
-
padding: "
|
|
1685
|
+
gap: "var(--iris-space-xs, 8px)",
|
|
1686
|
+
padding: "var(--iris-space-xs, 8px) var(--iris-space-sm, 12px)",
|
|
1384
1687
|
borderBottom: "1px solid var(--iris-border)",
|
|
1385
1688
|
background: "var(--iris-background)",
|
|
1386
1689
|
...attrs.style ?? {}
|
|
@@ -1410,7 +1713,7 @@ var IrisAdminTabs = defineComponent({
|
|
|
1410
1713
|
orientation: "horizontal",
|
|
1411
1714
|
style: {
|
|
1412
1715
|
alignItems: "center",
|
|
1413
|
-
gap: "
|
|
1716
|
+
gap: "var(--iris-space-xs, 8px)",
|
|
1414
1717
|
width: "max-content"
|
|
1415
1718
|
}
|
|
1416
1719
|
},
|
|
@@ -1537,12 +1840,12 @@ var IrisAdminLayout = defineComponent({
|
|
|
1537
1840
|
style: {
|
|
1538
1841
|
display: "flex",
|
|
1539
1842
|
alignItems: "center",
|
|
1540
|
-
gap: "
|
|
1843
|
+
gap: "var(--iris-space-sm, 12px)",
|
|
1541
1844
|
height: "52px",
|
|
1542
|
-
padding: "0 16px",
|
|
1845
|
+
padding: "0 var(--iris-space-md, 16px)",
|
|
1543
1846
|
color: "var(--iris-foreground)",
|
|
1544
1847
|
fontWeight: "700",
|
|
1545
|
-
fontSize: "16px",
|
|
1848
|
+
fontSize: "var(--iris-font-size-lg, 16px)",
|
|
1546
1849
|
whiteSpace: "nowrap",
|
|
1547
1850
|
overflow: "hidden",
|
|
1548
1851
|
flexShrink: 0
|
|
@@ -1821,5 +2124,5 @@ function useAdminPreferences(preferences, hydrate = true) {
|
|
|
1821
2124
|
}
|
|
1822
2125
|
|
|
1823
2126
|
export { DropdownContextKey, IrisAdminBreadcrumb, IrisAdminLayout, IrisAdminTabs, IrisBreadcrumb, IrisBreadcrumbItem, IrisDropdown, IrisDropdownItem, IrisDropdownMenu, IrisDropdownSeparator, IrisDropdownTrigger, IrisIcon, IrisNavMenu, useAdminPreferences, useAdminShell, useTabsNav };
|
|
1824
|
-
//# sourceMappingURL=chunk-
|
|
1825
|
-
//# sourceMappingURL=chunk-
|
|
2127
|
+
//# sourceMappingURL=chunk-ASFDGYIR.js.map
|
|
2128
|
+
//# sourceMappingURL=chunk-ASFDGYIR.js.map
|