vira 31.16.1 → 31.16.2
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.
|
@@ -3,6 +3,7 @@ import { type FullSpaRoute, type GenericTreePaths, type SpaRouter } from 'spa-ro
|
|
|
3
3
|
import { type ViraIconSvg } from '../icons/icon-svg.js';
|
|
4
4
|
import { ViraColorVariant } from '../styles/form-variants.js';
|
|
5
5
|
import { ViraThemeColorName } from '../styles/vira-color-theme-object.js';
|
|
6
|
+
import { type HorizontalAnchor, type PopUpOffset } from './pop-up/vira-pop-up-trigger.element.js';
|
|
6
7
|
/**
|
|
7
8
|
* Controls which edge of the tab the selection indicator bar appears on.
|
|
8
9
|
*
|
|
@@ -45,7 +46,7 @@ export type ViraTab = {
|
|
|
45
46
|
*/
|
|
46
47
|
export declare const ViraTabs: import("element-vir").DeclarativeElementDefinition<"vira-tabs", {
|
|
47
48
|
tabs: ReadonlyArray<Readonly<ViraTab>>;
|
|
48
|
-
router: Pick<SpaRouter<any, any, any>, "createRouteUrl" | "setRouteOnDirectNavigation"
|
|
49
|
+
router: Pick<SpaRouter<any, any, any>, "createRouteUrl" | "setRouteOnDirectNavigation">;
|
|
49
50
|
currentRoute: Readonly<FullSpaRoute>;
|
|
50
51
|
} & PartialWithUndefined<{
|
|
51
52
|
/**
|
|
@@ -68,18 +69,22 @@ export declare const ViraTabs: import("element-vir").DeclarativeElementDefinitio
|
|
|
68
69
|
* @default ViraTabsIconLayout.Vertical
|
|
69
70
|
*/
|
|
70
71
|
iconLayout: ViraTabsIconLayout;
|
|
72
|
+
/**
|
|
73
|
+
* Horizontal anchor for the dropdown menu. Only used when tabs overflow into a dropdown.
|
|
74
|
+
*
|
|
75
|
+
* @default HorizontalAnchor.Left
|
|
76
|
+
*/
|
|
77
|
+
menuHorizontalAnchor: HorizontalAnchor;
|
|
78
|
+
/** Whether the dropdown trigger is disabled. Only used when tabs overflow into a dropdown. */
|
|
79
|
+
menuIsDisabled: boolean;
|
|
80
|
+
/** Offset for the dropdown pop-up. Only used when tabs overflow into a dropdown. */
|
|
81
|
+
menuPopUpOffset: Readonly<PopUpOffset>;
|
|
71
82
|
/** When true, tabs and their container expand to fill all available horizontal space. */
|
|
72
83
|
shouldFillWidth: boolean;
|
|
73
84
|
}>, {
|
|
74
85
|
isOverflowing: boolean;
|
|
75
86
|
/** A callback to remove all internal observers. */
|
|
76
87
|
cleanupObserver: undefined | (() => void);
|
|
77
|
-
/**
|
|
78
|
-
* Captured at the moment the overflow select is opened (mousedown or keydown on the
|
|
79
|
-
* select). Once the native picker opens, the OS owns keyboard input, so modifier state
|
|
80
|
-
* must be captured before that.
|
|
81
|
-
*/
|
|
82
|
-
modifierKeyHeld: boolean;
|
|
83
88
|
}, {
|
|
84
89
|
/** Fires when a tab is clicked with the corresponding tab entry. */
|
|
85
90
|
tabSelect: import("element-vir").DefineEvent<Readonly<ViraTab>>;
|
|
@@ -10,9 +10,12 @@ import { noNativeFormStyles, noUserSelect, viraDisabledStyles, viraTheme } from
|
|
|
10
10
|
import { viraThemeByKeys, ViraThemeColorName } from '../styles/vira-color-theme-object.js';
|
|
11
11
|
import { defineViraElement } from '../util/define-vira-element.js';
|
|
12
12
|
import { createOverflowObserver } from '../util/overflow-observer.js';
|
|
13
|
+
import { renderMenuItemEntries } from '../util/pop-up-helpers.js';
|
|
14
|
+
import { ViraMenuTrigger } from './pop-up/vira-menu-trigger.element.js';
|
|
15
|
+
import { ViraMenuCornerStyle } from './pop-up/vira-menu.element.js';
|
|
16
|
+
import { ViraButton } from './vira-button.element.js';
|
|
13
17
|
import { ViraIcon } from './vira-icon.element.js';
|
|
14
18
|
import { ViraLink } from './vira-link.element.js';
|
|
15
|
-
import { ViraSelect } from './vira-select.element.js';
|
|
16
19
|
/**
|
|
17
20
|
* Controls which edge of the tab the selection indicator bar appears on.
|
|
18
21
|
*
|
|
@@ -53,12 +56,6 @@ export const ViraTabs = defineViraElement()({
|
|
|
53
56
|
isOverflowing: false,
|
|
54
57
|
/** A callback to remove all internal observers. */
|
|
55
58
|
cleanupObserver: undefined,
|
|
56
|
-
/**
|
|
57
|
-
* Captured at the moment the overflow select is opened (mousedown or keydown on the
|
|
58
|
-
* select). Once the native picker opens, the OS owns keyboard input, so modifier state
|
|
59
|
-
* must be captured before that.
|
|
60
|
-
*/
|
|
61
|
-
modifierKeyHeld: false,
|
|
62
59
|
};
|
|
63
60
|
},
|
|
64
61
|
hostClasses: {
|
|
@@ -145,7 +142,6 @@ export const ViraTabs = defineViraElement()({
|
|
|
145
142
|
return css `
|
|
146
143
|
:host {
|
|
147
144
|
display: flex;
|
|
148
|
-
position: relative;
|
|
149
145
|
box-sizing: border-box;
|
|
150
146
|
${noUserSelect};
|
|
151
147
|
width: 100%;
|
|
@@ -296,19 +292,18 @@ export const ViraTabs = defineViraElement()({
|
|
|
296
292
|
|
|
297
293
|
${hostClasses['vira-tabs-overflowing'].selector} .tabs-container {
|
|
298
294
|
visibility: hidden;
|
|
299
|
-
position: absolute;
|
|
300
295
|
height: 0;
|
|
301
296
|
}
|
|
302
297
|
|
|
303
|
-
|
|
298
|
+
.overflow-menu {
|
|
304
299
|
display: none;
|
|
305
300
|
}
|
|
306
301
|
|
|
307
|
-
${hostClasses['vira-tabs-overflowing'].selector}
|
|
308
|
-
display:
|
|
302
|
+
${hostClasses['vira-tabs-overflowing'].selector} .overflow-menu {
|
|
303
|
+
display: flex;
|
|
309
304
|
align-items: center;
|
|
310
305
|
width: fit-content;
|
|
311
|
-
|
|
306
|
+
padding-left: 8px;
|
|
312
307
|
}
|
|
313
308
|
|
|
314
309
|
${hostClasses['vira-tabs-fill-width'].selector} {
|
|
@@ -334,6 +329,10 @@ export const ViraTabs = defineViraElement()({
|
|
|
334
329
|
display: flex;
|
|
335
330
|
padding: 8px 16px;
|
|
336
331
|
}
|
|
332
|
+
|
|
333
|
+
${ViraMenuTrigger} {
|
|
334
|
+
margin: 3px 0;
|
|
335
|
+
}
|
|
337
336
|
`;
|
|
338
337
|
},
|
|
339
338
|
cleanup({ state }) {
|
|
@@ -393,53 +392,53 @@ export const ViraTabs = defineViraElement()({
|
|
|
393
392
|
`;
|
|
394
393
|
}, check.isTruthy);
|
|
395
394
|
const selectedTab = inputs.tabs.find((tab) => routeHasPaths(inputs.currentRoute, tab.paths));
|
|
396
|
-
const
|
|
395
|
+
const menuItems = renderMenuItemEntries(filterMap(inputs.tabs, (tab) => {
|
|
397
396
|
if (tab.isHidden) {
|
|
398
397
|
return undefined;
|
|
399
398
|
}
|
|
399
|
+
const isSelected = routeHasPaths(inputs.currentRoute, tab.paths);
|
|
400
400
|
return {
|
|
401
|
-
|
|
402
|
-
|
|
401
|
+
content: html `
|
|
402
|
+
<${ViraLink.assign({
|
|
403
|
+
route: {
|
|
404
|
+
router: inputs.router,
|
|
405
|
+
route: {
|
|
406
|
+
paths: tab.paths.fullPaths,
|
|
407
|
+
},
|
|
408
|
+
scrollToTop: true,
|
|
409
|
+
},
|
|
410
|
+
disableLinkStyles: true,
|
|
411
|
+
})}>
|
|
412
|
+
${tab.label}
|
|
413
|
+
</${ViraLink}>
|
|
414
|
+
`,
|
|
415
|
+
selected: isSelected,
|
|
403
416
|
disabled: tab.isDisabled,
|
|
417
|
+
onClick() {
|
|
418
|
+
if (!tab.isDisabled) {
|
|
419
|
+
dispatch(new events.tabSelect(tab));
|
|
420
|
+
}
|
|
421
|
+
},
|
|
404
422
|
};
|
|
405
|
-
}, check.isTruthy);
|
|
406
|
-
function captureModifierState(event) {
|
|
407
|
-
updateState({
|
|
408
|
-
modifierKeyHeld: event.ctrlKey || event.metaKey || event.shiftKey,
|
|
409
|
-
});
|
|
410
|
-
}
|
|
423
|
+
}, check.isTruthy));
|
|
411
424
|
return html `
|
|
412
|
-
<${
|
|
413
|
-
|
|
414
|
-
|
|
425
|
+
<${ViraMenuTrigger.assign({
|
|
426
|
+
horizontalAnchor: inputs.menuHorizontalAnchor,
|
|
427
|
+
isDisabled: inputs.menuIsDisabled,
|
|
428
|
+
popUpOffset: inputs.menuPopUpOffset,
|
|
429
|
+
menuCornerStyle: ViraMenuCornerStyle.AllRounded,
|
|
415
430
|
})}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
if (!tab || tab.isDisabled) {
|
|
423
|
-
return;
|
|
424
|
-
}
|
|
425
|
-
dispatch(new events.tabSelect(tab));
|
|
426
|
-
const route = {
|
|
427
|
-
paths: tab.paths.fullPaths,
|
|
428
|
-
};
|
|
429
|
-
if (state.modifierKeyHeld) {
|
|
430
|
-
globalThis.open(inputs.router.createRouteUrl(route), '_blank', 'noopener,noreferrer');
|
|
431
|
-
}
|
|
432
|
-
else {
|
|
433
|
-
inputs.router.setRoute(route);
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
finally {
|
|
437
|
-
updateState({
|
|
438
|
-
modifierKeyHeld: false,
|
|
439
|
-
});
|
|
440
|
-
}
|
|
431
|
+
class="overflow-menu"
|
|
432
|
+
>
|
|
433
|
+
<${ViraButton.assign({
|
|
434
|
+
text: selectedTab?.label || '',
|
|
435
|
+
showMenuCaret: true,
|
|
436
|
+
color: ViraColorVariant.Neutral,
|
|
441
437
|
})}
|
|
442
|
-
|
|
438
|
+
slot=${ViraMenuTrigger.slotNames.trigger}
|
|
439
|
+
></${ViraButton}>
|
|
440
|
+
${menuItems}
|
|
441
|
+
</${ViraMenuTrigger}>
|
|
443
442
|
<ul
|
|
444
443
|
class="tabs-container"
|
|
445
444
|
role="tablist"
|