@loomweaver/shell 0.7.7 → 0.7.9
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/fesm2022/loomweaver-shell.mjs +403 -67
- package/fesm2022/loomweaver-shell.mjs.map +1 -1
- package/i18n/de.json +1 -0
- package/i18n/en.json +1 -0
- package/package.json +2 -2
- package/styles/shell.css +1 -1
- package/styles/theme.css +34 -2
- package/types/loomweaver-shell.d.ts +66 -4
- package/types/loomweaver-shell.d.ts.map +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, signal, computed, Service, inject, makeEnvironmentProviders, ApplicationRef, Injector, effect, untracked, provideEnvironmentInitializer, ErrorHandler,
|
|
2
|
+
import { InjectionToken, isDevMode, signal, computed, Service, inject, makeEnvironmentProviders, ApplicationRef, Injector, effect, untracked, provideEnvironmentInitializer, ErrorHandler, ElementRef, input, booleanAttribute, Directive, CUSTOM_ELEMENTS_SCHEMA, Component, output, EnvironmentInjector, DestroyRef, viewChild, afterRenderEffect, afterNextRender, createComponent, forwardRef, ViewEncapsulation, viewChildren, Injectable, provideZonelessChangeDetection, provideBrowserGlobalErrorListeners, provideAppInitializer } from '@angular/core';
|
|
3
3
|
import { ChildrenOutletContexts, Router, NavigationEnd, ActivatedRoute, convertToParamMap, UrlSegment, RouterOutlet, RouteReuseStrategy, provideRouter, withDisabledInitialNavigation } from '@angular/router';
|
|
4
4
|
import { TranslocoService, TranslocoPipe, provideTransloco, provideTranslocoMissingHandler } from '@jsverse/transloco';
|
|
5
5
|
import { DOCUMENT, NgComponentOutlet, Location, NgTemplateOutlet } from '@angular/common';
|
|
@@ -43,6 +43,40 @@ function provideLayout(layout) {
|
|
|
43
43
|
return { provide: SHELL_LAYOUT, useValue: layout };
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
const warned = new Set();
|
|
47
|
+
function menuOnActivate(item) {
|
|
48
|
+
if (!item.menu || item.menuTrigger === undefined || item.menuTrigger === 'context') {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
return item.workspace === undefined ? item.menu : undefined;
|
|
52
|
+
}
|
|
53
|
+
function menuOnContext(item) {
|
|
54
|
+
if (!item.menu) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
return menuOnActivate(item) && item.menuTrigger === 'primary'
|
|
58
|
+
? undefined
|
|
59
|
+
: item.menu;
|
|
60
|
+
}
|
|
61
|
+
function warnMenuTriggerConflict(item) {
|
|
62
|
+
if (!isDevMode() || warned.has(item.id)) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (item.workspace !== undefined && item.menuTrigger !== undefined && item.menuTrigger !== 'context') {
|
|
66
|
+
warned.add(item.id);
|
|
67
|
+
console.warn(`Item "${item.id}" switches to workspace "${item.workspace}" and asks for its menu on ` +
|
|
68
|
+
`activation — activating it is the switch, so the menu "${item.menu}" stays on the ` +
|
|
69
|
+
`right-click.`);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (menuOnActivate(item) && (item.command !== undefined || item.run !== undefined)) {
|
|
73
|
+
warned.add(item.id);
|
|
74
|
+
console.warn(`Item "${item.id}" opens the menu "${item.menu}" on activation, so its ` +
|
|
75
|
+
`${item.command === undefined ? 'inline behaviour' : `command "${item.command}"`} is ` +
|
|
76
|
+
`never run from here. Reach it from a menu entry, a shortcut or the palette instead.`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
46
80
|
const PRIMARY_PANE = 'main';
|
|
47
81
|
const VIEW_PANE_PREFIX = 'view:';
|
|
48
82
|
const CONTENT_DOCK = 'content';
|
|
@@ -2495,8 +2529,24 @@ function reflectAttribute(element, name, value) {
|
|
|
2495
2529
|
const LW_MENU_TAG = 'lw-menu';
|
|
2496
2530
|
const LW_MENU_ITEM_TAG = 'lw-menu-item';
|
|
2497
2531
|
const VIEWPORT_MARGIN$1 = 4;
|
|
2532
|
+
const MENU_ANCHOR_GAP = 4;
|
|
2498
2533
|
const LW_MENU_SELECT = 'lw-menu-select';
|
|
2499
2534
|
const LW_MENU_DISMISS = 'lw-menu-dismiss';
|
|
2535
|
+
function fits(start, size, limit) {
|
|
2536
|
+
return start >= VIEWPORT_MARGIN$1 && start + size <= limit - VIEWPORT_MARGIN$1;
|
|
2537
|
+
}
|
|
2538
|
+
function clamp(start, size, limit) {
|
|
2539
|
+
return Math.max(VIEWPORT_MARGIN$1, Math.min(start, limit - size - VIEWPORT_MARGIN$1));
|
|
2540
|
+
}
|
|
2541
|
+
function beside(preferred, opposite, size, limit) {
|
|
2542
|
+
if (fits(preferred, size, limit)) {
|
|
2543
|
+
return preferred;
|
|
2544
|
+
}
|
|
2545
|
+
return fits(opposite, size, limit) ? opposite : clamp(preferred, size, limit);
|
|
2546
|
+
}
|
|
2547
|
+
function aligned(near, far, size, limit) {
|
|
2548
|
+
return fits(near, size, limit) ? near : clamp(far - size, size, limit);
|
|
2549
|
+
}
|
|
2500
2550
|
class LwMenuItemElement extends HTMLElement {
|
|
2501
2551
|
static observedAttributes = [
|
|
2502
2552
|
'label',
|
|
@@ -2590,10 +2640,26 @@ class LwMenuElement extends HTMLElement {
|
|
|
2590
2640
|
}
|
|
2591
2641
|
openAt(x, y) {
|
|
2592
2642
|
const { width, height } = this.getBoundingClientRect();
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2643
|
+
this.place(clamp(x, width, window.innerWidth), clamp(y, height, window.innerHeight));
|
|
2644
|
+
}
|
|
2645
|
+
openBeside(rect, side) {
|
|
2646
|
+
const { width, height } = this.getBoundingClientRect();
|
|
2647
|
+
const viewportWidth = window.innerWidth;
|
|
2648
|
+
const viewportHeight = window.innerHeight;
|
|
2649
|
+
const after = { x: rect.right + MENU_ANCHOR_GAP, y: rect.bottom + MENU_ANCHOR_GAP };
|
|
2650
|
+
const before = {
|
|
2651
|
+
x: rect.left - MENU_ANCHOR_GAP - width,
|
|
2652
|
+
y: rect.top - MENU_ANCHOR_GAP - height,
|
|
2653
|
+
};
|
|
2654
|
+
if (side === 'left' || side === 'right') {
|
|
2655
|
+
const preferred = side === 'right' ? after.x : before.x;
|
|
2656
|
+
const opposite = side === 'right' ? before.x : after.x;
|
|
2657
|
+
this.place(beside(preferred, opposite, width, viewportWidth), aligned(rect.top, rect.bottom, height, viewportHeight));
|
|
2658
|
+
return;
|
|
2659
|
+
}
|
|
2660
|
+
const preferred = side === 'bottom' ? after.y : before.y;
|
|
2661
|
+
const opposite = side === 'bottom' ? before.y : after.y;
|
|
2662
|
+
this.place(aligned(rect.left, rect.right, width, viewportWidth), beside(preferred, opposite, height, viewportHeight));
|
|
2597
2663
|
}
|
|
2598
2664
|
onKeydown = (event) => this.handleKeydown(event);
|
|
2599
2665
|
onClick = (event) => {
|
|
@@ -2602,6 +2668,10 @@ class LwMenuElement extends HTMLElement {
|
|
|
2602
2668
|
this.select(item);
|
|
2603
2669
|
}
|
|
2604
2670
|
};
|
|
2671
|
+
place(left, top) {
|
|
2672
|
+
this.style.left = `${left}px`;
|
|
2673
|
+
this.style.top = `${top}px`;
|
|
2674
|
+
}
|
|
2605
2675
|
items() {
|
|
2606
2676
|
return [...this.querySelectorAll('[role^="menuitem"]')].filter((item) => !this.isDisabled(item));
|
|
2607
2677
|
}
|
|
@@ -2678,28 +2748,30 @@ function defineLwMenu() {
|
|
|
2678
2748
|
}
|
|
2679
2749
|
}
|
|
2680
2750
|
|
|
2681
|
-
const MENU_ANCHOR_GAP = 4;
|
|
2682
2751
|
class MenuService {
|
|
2683
2752
|
registry = inject(ContributionRegistry);
|
|
2684
2753
|
commands = inject(CommandService);
|
|
2685
2754
|
transloco = inject(TranslocoService);
|
|
2755
|
+
trigger = signal(null, /* @ts-ignore */
|
|
2756
|
+
...(ngDevMode ? [{ debugName: "trigger" }] : /* istanbul ignore next */ []));
|
|
2686
2757
|
current;
|
|
2687
|
-
|
|
2758
|
+
openTrigger = this.trigger.asReadonly();
|
|
2759
|
+
open(menuId, context, at, options = {}) {
|
|
2688
2760
|
this.close();
|
|
2689
2761
|
const resolved = this.resolve(typeof menuId === 'string' ? [menuId] : menuId, context);
|
|
2690
2762
|
if (resolved.length === 0) {
|
|
2691
2763
|
return;
|
|
2692
2764
|
}
|
|
2693
|
-
const menu = this.createMenu(resolved);
|
|
2765
|
+
const menu = this.createMenu(resolved, options.header);
|
|
2694
2766
|
const byKey = new Map(resolved.map((entry) => [entry.key, entry.item]));
|
|
2695
2767
|
this.present(menu, at, (key) => {
|
|
2696
2768
|
const item = key === null ? undefined : byKey.get(key);
|
|
2697
2769
|
if (item) {
|
|
2698
2770
|
this.run(item, context);
|
|
2699
2771
|
}
|
|
2700
|
-
});
|
|
2772
|
+
}, options.trigger);
|
|
2701
2773
|
}
|
|
2702
|
-
openList(entries, at, onPick) {
|
|
2774
|
+
openList(entries, at, onPick, trigger) {
|
|
2703
2775
|
this.close();
|
|
2704
2776
|
if (entries.length === 0) {
|
|
2705
2777
|
return;
|
|
@@ -2709,7 +2781,7 @@ class MenuService {
|
|
|
2709
2781
|
if (key !== null) {
|
|
2710
2782
|
onPick(key);
|
|
2711
2783
|
}
|
|
2712
|
-
});
|
|
2784
|
+
}, trigger);
|
|
2713
2785
|
}
|
|
2714
2786
|
close() {
|
|
2715
2787
|
const open = this.current;
|
|
@@ -2717,13 +2789,14 @@ class MenuService {
|
|
|
2717
2789
|
return;
|
|
2718
2790
|
}
|
|
2719
2791
|
this.current = undefined;
|
|
2792
|
+
this.trigger.set(null);
|
|
2720
2793
|
clearTimeout(open.listenTimer);
|
|
2721
2794
|
document.removeEventListener('pointerdown', open.onOutside, true);
|
|
2722
2795
|
document.body.classList.remove('lw-menu-open');
|
|
2723
2796
|
open.menu.remove();
|
|
2724
2797
|
open.restore?.focus?.();
|
|
2725
2798
|
}
|
|
2726
|
-
present(menu, at, onSelect) {
|
|
2799
|
+
present(menu, at, onSelect, trigger) {
|
|
2727
2800
|
const restore = document.activeElement;
|
|
2728
2801
|
menu.addEventListener(LW_MENU_SELECT, (event) => {
|
|
2729
2802
|
const key = event.detail
|
|
@@ -2739,7 +2812,13 @@ class MenuService {
|
|
|
2739
2812
|
};
|
|
2740
2813
|
document.body.append(menu);
|
|
2741
2814
|
document.body.classList.add('lw-menu-open');
|
|
2742
|
-
|
|
2815
|
+
if ('rect' in at) {
|
|
2816
|
+
menu.openBeside(at.rect, at.side);
|
|
2817
|
+
}
|
|
2818
|
+
else {
|
|
2819
|
+
menu.openAt(at.x, at.y);
|
|
2820
|
+
}
|
|
2821
|
+
this.trigger.set(trigger ?? null);
|
|
2743
2822
|
const listenTimer = setTimeout(() => document.addEventListener('pointerdown', onOutside, { capture: true }), 0);
|
|
2744
2823
|
this.current = { menu, onOutside, restore, listenTimer };
|
|
2745
2824
|
}
|
|
@@ -2775,11 +2854,14 @@ class MenuService {
|
|
|
2775
2854
|
.filter((entry) => entry !== null)
|
|
2776
2855
|
.toSorted((a, b) => a.group.localeCompare(b.group) || a.order - b.order);
|
|
2777
2856
|
}
|
|
2778
|
-
createMenu(resolved) {
|
|
2857
|
+
createMenu(resolved, header) {
|
|
2779
2858
|
const menu = document.createElement(LW_MENU_TAG);
|
|
2780
2859
|
if (resolved.some((entry) => entry.icon || entry.checkbox)) {
|
|
2781
2860
|
menu.classList.add('lw-menu--leading');
|
|
2782
2861
|
}
|
|
2862
|
+
if (header) {
|
|
2863
|
+
menu.append(this.createHeader(header, menu));
|
|
2864
|
+
}
|
|
2783
2865
|
let lastGroup;
|
|
2784
2866
|
for (const entry of resolved) {
|
|
2785
2867
|
if (lastGroup !== undefined && entry.group !== lastGroup) {
|
|
@@ -2808,6 +2890,66 @@ class MenuService {
|
|
|
2808
2890
|
}
|
|
2809
2891
|
return menu;
|
|
2810
2892
|
}
|
|
2893
|
+
createHeader(header, menu) {
|
|
2894
|
+
const title = this.transloco.translate(header.title);
|
|
2895
|
+
const detail = header.detail
|
|
2896
|
+
? this.transloco.translate(header.detail)
|
|
2897
|
+
: undefined;
|
|
2898
|
+
menu.setAttribute('aria-label', detail ? `${title}, ${detail}` : title);
|
|
2899
|
+
const element = document.createElement('div');
|
|
2900
|
+
element.className = 'lw-menu-header';
|
|
2901
|
+
element.setAttribute('aria-hidden', 'true');
|
|
2902
|
+
const mark = this.createHeaderMark(header);
|
|
2903
|
+
if (mark) {
|
|
2904
|
+
element.append(mark);
|
|
2905
|
+
}
|
|
2906
|
+
const lines = document.createElement('span');
|
|
2907
|
+
lines.className = 'lw-menu-header-lines';
|
|
2908
|
+
const name = document.createElement('span');
|
|
2909
|
+
name.className = 'lw-menu-header-title';
|
|
2910
|
+
name.textContent = title;
|
|
2911
|
+
lines.append(name);
|
|
2912
|
+
if (detail) {
|
|
2913
|
+
const second = document.createElement('span');
|
|
2914
|
+
second.className = 'lw-menu-header-detail';
|
|
2915
|
+
second.textContent = detail;
|
|
2916
|
+
lines.append(second);
|
|
2917
|
+
}
|
|
2918
|
+
element.append(lines);
|
|
2919
|
+
return element;
|
|
2920
|
+
}
|
|
2921
|
+
createHeaderMark(header) {
|
|
2922
|
+
if (!header.image && !header.initials && !header.icon) {
|
|
2923
|
+
return undefined;
|
|
2924
|
+
}
|
|
2925
|
+
const mark = document.createElement('span');
|
|
2926
|
+
mark.className = 'lw-menu-header-mark';
|
|
2927
|
+
mark.append(...this.markContent(header));
|
|
2928
|
+
if (header.image) {
|
|
2929
|
+
const picture = mark.firstElementChild;
|
|
2930
|
+
picture.addEventListener('error', () => mark.replaceChildren(...this.markContent({ ...header, image: undefined })));
|
|
2931
|
+
}
|
|
2932
|
+
return mark;
|
|
2933
|
+
}
|
|
2934
|
+
markContent(header) {
|
|
2935
|
+
if (header.image) {
|
|
2936
|
+
const picture = document.createElement('img');
|
|
2937
|
+
picture.src = header.image;
|
|
2938
|
+
picture.alt = '';
|
|
2939
|
+
picture.className = 'lw-menu-header-picture';
|
|
2940
|
+
return [picture];
|
|
2941
|
+
}
|
|
2942
|
+
if (header.initials) {
|
|
2943
|
+
return [document.createTextNode(header.initials)];
|
|
2944
|
+
}
|
|
2945
|
+
if (header.icon) {
|
|
2946
|
+
const icon = document.createElement('lw-icon');
|
|
2947
|
+
icon.setAttribute('name', header.icon);
|
|
2948
|
+
icon.setAttribute('size', '1rem');
|
|
2949
|
+
return [icon];
|
|
2950
|
+
}
|
|
2951
|
+
return [];
|
|
2952
|
+
}
|
|
2811
2953
|
createListMenu(entries) {
|
|
2812
2954
|
const menu = document.createElement(LW_MENU_TAG);
|
|
2813
2955
|
if (entries.some((entry) => entry.icon || entry.active || entry.checked !== undefined)) {
|
|
@@ -2859,35 +3001,74 @@ function whenMatches(when, context) {
|
|
|
2859
3001
|
return Object.entries(when).every(([key, value]) => context[key] === value);
|
|
2860
3002
|
}
|
|
2861
3003
|
|
|
2862
|
-
|
|
3004
|
+
function names(slots) {
|
|
3005
|
+
return slots !== undefined && slots.length > 0;
|
|
3006
|
+
}
|
|
3007
|
+
class MenuTriggerDirective {
|
|
2863
3008
|
menus = inject(MenuService);
|
|
2864
|
-
|
|
2865
|
-
|
|
3009
|
+
host = inject(ElementRef);
|
|
3010
|
+
menu = input(undefined, { ...(ngDevMode ? { debugName: "menu" } : /* istanbul ignore next */ {}), alias: 'lwMenu' });
|
|
3011
|
+
onActivateMenu = input(undefined, { ...(ngDevMode ? { debugName: "onActivateMenu" } : /* istanbul ignore next */ {}), alias: 'lwMenuOnActivate' });
|
|
3012
|
+
context = input({}, { ...(ngDevMode ? { debugName: "context" } : /* istanbul ignore next */ {}), alias: 'lwMenuContext' });
|
|
3013
|
+
side = input('bottom', { ...(ngDevMode ? { debugName: "side" } : /* istanbul ignore next */ {}), alias: 'lwMenuSide' });
|
|
3014
|
+
header = input(undefined, { ...(ngDevMode ? { debugName: "header" } : /* istanbul ignore next */ {}), alias: 'lwMenuHeader' });
|
|
3015
|
+
state = input(false, { ...(ngDevMode ? { debugName: "state" } : /* istanbul ignore next */ {}), alias: 'lwMenuState',
|
|
3016
|
+
transform: booleanAttribute });
|
|
3017
|
+
announces = computed(() => this.state() || names(this.onActivateMenu()), /* @ts-ignore */
|
|
3018
|
+
...(ngDevMode ? [{ debugName: "announces" }] : /* istanbul ignore next */ []));
|
|
3019
|
+
hasPopup = computed(() => this.announces() ? 'menu' : null, /* @ts-ignore */
|
|
3020
|
+
...(ngDevMode ? [{ debugName: "hasPopup" }] : /* istanbul ignore next */ []));
|
|
3021
|
+
expanded = computed(() => this.announces()
|
|
3022
|
+
? String(this.menus.openTrigger() === this.host.nativeElement)
|
|
3023
|
+
: null, /* @ts-ignore */
|
|
3024
|
+
...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
|
|
2866
3025
|
onContextMenu(event) {
|
|
2867
|
-
const
|
|
2868
|
-
if (!
|
|
3026
|
+
const slots = this.menu();
|
|
3027
|
+
if (!names(slots)) {
|
|
2869
3028
|
return;
|
|
2870
3029
|
}
|
|
2871
3030
|
event.preventDefault();
|
|
2872
3031
|
event.stopPropagation();
|
|
2873
|
-
this.menus.open(
|
|
3032
|
+
this.menus.open(slots, this.context(), {
|
|
2874
3033
|
x: event.clientX,
|
|
2875
3034
|
y: event.clientY,
|
|
2876
3035
|
});
|
|
2877
3036
|
}
|
|
2878
|
-
|
|
2879
|
-
|
|
3037
|
+
onActivate(event) {
|
|
3038
|
+
const slots = this.onActivateMenu();
|
|
3039
|
+
if (!names(slots)) {
|
|
3040
|
+
return;
|
|
3041
|
+
}
|
|
3042
|
+
event.preventDefault();
|
|
3043
|
+
event.stopPropagation();
|
|
3044
|
+
const control = this.host.nativeElement;
|
|
3045
|
+
this.menus.open(slots, this.context(), { rect: control.getBoundingClientRect(), side: this.side() }, { trigger: control, header: this.header() });
|
|
3046
|
+
}
|
|
3047
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MenuTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
3048
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.0", type: MenuTriggerDirective, isStandalone: true, selector: "[lwMenu], [lwMenuOnActivate], [lwMenuState]", inputs: { menu: { classPropertyName: "menu", publicName: "lwMenu", isSignal: true, isRequired: false, transformFunction: null }, onActivateMenu: { classPropertyName: "onActivateMenu", publicName: "lwMenuOnActivate", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "lwMenuContext", isSignal: true, isRequired: false, transformFunction: null }, side: { classPropertyName: "side", publicName: "lwMenuSide", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "lwMenuHeader", isSignal: true, isRequired: false, transformFunction: null }, state: { classPropertyName: "state", publicName: "lwMenuState", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "contextmenu": "onContextMenu($event)", "click": "onActivate($event)" }, properties: { "attr.aria-haspopup": "hasPopup()", "attr.aria-expanded": "expanded()" } }, ngImport: i0 });
|
|
2880
3049
|
}
|
|
2881
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type:
|
|
3050
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MenuTriggerDirective, decorators: [{
|
|
2882
3051
|
type: Directive,
|
|
2883
3052
|
args: [{
|
|
2884
|
-
selector: '[
|
|
2885
|
-
host: {
|
|
3053
|
+
selector: '[lwMenu], [lwMenuOnActivate], [lwMenuState]',
|
|
3054
|
+
host: {
|
|
3055
|
+
'(contextmenu)': 'onContextMenu($event)',
|
|
3056
|
+
'(click)': 'onActivate($event)',
|
|
3057
|
+
'[attr.aria-haspopup]': 'hasPopup()',
|
|
3058
|
+
'[attr.aria-expanded]': 'expanded()',
|
|
3059
|
+
},
|
|
2886
3060
|
}]
|
|
2887
|
-
}], propDecorators: { menu: [{ type: i0.Input, args: [{ isSignal: true, alias: "
|
|
3061
|
+
}], propDecorators: { menu: [{ type: i0.Input, args: [{ isSignal: true, alias: "lwMenu", required: false }] }], onActivateMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "lwMenuOnActivate", required: false }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "lwMenuContext", required: false }] }], side: [{ type: i0.Input, args: [{ isSignal: true, alias: "lwMenuSide", required: false }] }], header: [{ type: i0.Input, args: [{ isSignal: true, alias: "lwMenuHeader", required: false }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "lwMenuState", required: false }] }] } });
|
|
2888
3062
|
|
|
2889
3063
|
const BAR_CONTEXT = new InjectionToken('BAR_CONTEXT');
|
|
2890
3064
|
|
|
3065
|
+
const MENU_SIDE_BY_DOCK = {
|
|
3066
|
+
top: 'bottom',
|
|
3067
|
+
bottom: 'top',
|
|
3068
|
+
left: 'right',
|
|
3069
|
+
right: 'left',
|
|
3070
|
+
center: 'bottom',
|
|
3071
|
+
};
|
|
2891
3072
|
class ShellBarItem {
|
|
2892
3073
|
item = input.required(/* @ts-ignore */
|
|
2893
3074
|
...(ngDevMode ? [{ debugName: "item" }] : /* istanbul ignore next */ []));
|
|
@@ -2906,8 +3087,22 @@ class ShellBarItem {
|
|
|
2906
3087
|
return 'component' in item ? null : item;
|
|
2907
3088
|
}, /* @ts-ignore */
|
|
2908
3089
|
...(ngDevMode ? [{ debugName: "asButton" }] : /* istanbul ignore next */ []));
|
|
3090
|
+
brokenPicture = signal(false, /* @ts-ignore */
|
|
3091
|
+
...(ngDevMode ? [{ debugName: "brokenPicture" }] : /* istanbul ignore next */ []));
|
|
2909
3092
|
tooltipPosition = computed(() => this.dock() === 'bottom' ? 'top' : 'bottom', /* @ts-ignore */
|
|
2910
3093
|
...(ngDevMode ? [{ debugName: "tooltipPosition" }] : /* istanbul ignore next */ []));
|
|
3094
|
+
menuSide = computed(() => MENU_SIDE_BY_DOCK[this.dock()], /* @ts-ignore */
|
|
3095
|
+
...(ngDevMode ? [{ debugName: "menuSide" }] : /* istanbul ignore next */ []));
|
|
3096
|
+
contextMenu = computed(() => {
|
|
3097
|
+
const button = this.asButton();
|
|
3098
|
+
return button ? menuOnContext(button) : undefined;
|
|
3099
|
+
}, /* @ts-ignore */
|
|
3100
|
+
...(ngDevMode ? [{ debugName: "contextMenu" }] : /* istanbul ignore next */ []));
|
|
3101
|
+
activateMenu = computed(() => {
|
|
3102
|
+
const button = this.asButton();
|
|
3103
|
+
return button ? menuOnActivate(button) : undefined;
|
|
3104
|
+
}, /* @ts-ignore */
|
|
3105
|
+
...(ngDevMode ? [{ debugName: "activateMenu" }] : /* istanbul ignore next */ []));
|
|
2911
3106
|
componentInjector = computed(() => {
|
|
2912
3107
|
const item = this.item();
|
|
2913
3108
|
return Injector.create({
|
|
@@ -2931,17 +3126,27 @@ class ShellBarItem {
|
|
|
2931
3126
|
return this.commands.shortcutOf(this.commands.commands().find((entry) => entry.id === button.command));
|
|
2932
3127
|
}, /* @ts-ignore */
|
|
2933
3128
|
...(ngDevMode ? [{ debugName: "shortcut" }] : /* istanbul ignore next */ []));
|
|
3129
|
+
pictureOf(button) {
|
|
3130
|
+
return this.brokenPicture() ? undefined : button.image;
|
|
3131
|
+
}
|
|
3132
|
+
onPictureError() {
|
|
3133
|
+
this.brokenPicture.set(true);
|
|
3134
|
+
}
|
|
2934
3135
|
run(button) {
|
|
2935
3136
|
if (this.disabled())
|
|
2936
3137
|
return;
|
|
3138
|
+
warnMenuTriggerConflict(button);
|
|
3139
|
+
if (menuOnActivate(button)) {
|
|
3140
|
+
return;
|
|
3141
|
+
}
|
|
2937
3142
|
this.commands.trigger(button);
|
|
2938
3143
|
}
|
|
2939
3144
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: ShellBarItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2940
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: ShellBarItem, isStandalone: true, selector: "lw-shell-bar-item", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, dock: { classPropertyName: "dock", publicName: "dock", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@if (asButton(); as btn) {\n <button\n type=\"button\"\n (click)=\"run(btn)\"\n [disabled]=\"disabled()\"\n [
|
|
3145
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: ShellBarItem, isStandalone: true, selector: "lw-shell-bar-item", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, dock: { classPropertyName: "dock", publicName: "dock", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@if (asButton(); as btn) {\n <button\n type=\"button\"\n (click)=\"run(btn)\"\n [disabled]=\"disabled()\"\n [lwMenu]=\"contextMenu()\"\n [lwMenuOnActivate]=\"activateMenu()\"\n [lwMenuHeader]=\"btn.menuHeader\"\n [lwMenuSide]=\"menuSide()\"\n [lwMenuContext]=\"{ targetKind: 'bar-item', id: btn.id, bar: btn.bar }\"\n class=\"relative flex items-center gap-1 rounded px-1.5 py-0.5 text-content-faint transition-colors hover:bg-surface-overlay hover:text-content disabled:pointer-events-none disabled:opacity-40\"\n [attr.aria-label]=\"(btn.tooltip ?? btn.label ?? '') | transloco\"\n >\n @if (pictureOf(btn); as picture) {\n <img\n [src]=\"picture\"\n alt=\"\"\n aria-hidden=\"true\"\n data-testid=\"bar-picture\"\n class=\"lw-chrome-picture h-5 w-5\"\n (error)=\"onPictureError()\"\n />\n } @else if (btn.initials) {\n <span aria-hidden=\"true\" data-testid=\"bar-initials\" class=\"lw-rail-initials\">{{\n btn.initials\n }}</span>\n } @else if (btn.icon; as icon) {\n <lw-icon [name]=\"icon\" size=\"1rem\" />\n }\n @if (btn.label; as label) {\n <span>{{ label | transloco }}</span>\n }\n @if (shortcut(); as chord) {\n <kbd\n class=\"rounded border border-border bg-surface-overlay px-1 text-[0.6875rem] leading-tight text-content-muted\"\n >{{ chord }}</kbd\n >\n }\n @if (btn.tooltip ?? btn.label; as tip) {\n <lw-tooltip [text]=\"tip | transloco\" [position]=\"tooltipPosition()\" />\n }\n </button>\n} @else if (asComponent(); as comp) {\n <ng-container\n *ngComponentOutlet=\"comp.component; injector: componentInjector()\"\n ></ng-container>\n}\n", dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: MenuTriggerDirective, selector: "[lwMenu], [lwMenuOnActivate], [lwMenuState]", inputs: ["lwMenu", "lwMenuOnActivate", "lwMenuContext", "lwMenuSide", "lwMenuHeader", "lwMenuState"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
2941
3146
|
}
|
|
2942
3147
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: ShellBarItem, decorators: [{
|
|
2943
3148
|
type: Component,
|
|
2944
|
-
args: [{ selector: 'lw-shell-bar-item', imports: [NgComponentOutlet, TranslocoPipe,
|
|
3149
|
+
args: [{ selector: 'lw-shell-bar-item', imports: [NgComponentOutlet, TranslocoPipe, MenuTriggerDirective], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "@if (asButton(); as btn) {\n <button\n type=\"button\"\n (click)=\"run(btn)\"\n [disabled]=\"disabled()\"\n [lwMenu]=\"contextMenu()\"\n [lwMenuOnActivate]=\"activateMenu()\"\n [lwMenuHeader]=\"btn.menuHeader\"\n [lwMenuSide]=\"menuSide()\"\n [lwMenuContext]=\"{ targetKind: 'bar-item', id: btn.id, bar: btn.bar }\"\n class=\"relative flex items-center gap-1 rounded px-1.5 py-0.5 text-content-faint transition-colors hover:bg-surface-overlay hover:text-content disabled:pointer-events-none disabled:opacity-40\"\n [attr.aria-label]=\"(btn.tooltip ?? btn.label ?? '') | transloco\"\n >\n @if (pictureOf(btn); as picture) {\n <img\n [src]=\"picture\"\n alt=\"\"\n aria-hidden=\"true\"\n data-testid=\"bar-picture\"\n class=\"lw-chrome-picture h-5 w-5\"\n (error)=\"onPictureError()\"\n />\n } @else if (btn.initials) {\n <span aria-hidden=\"true\" data-testid=\"bar-initials\" class=\"lw-rail-initials\">{{\n btn.initials\n }}</span>\n } @else if (btn.icon; as icon) {\n <lw-icon [name]=\"icon\" size=\"1rem\" />\n }\n @if (btn.label; as label) {\n <span>{{ label | transloco }}</span>\n }\n @if (shortcut(); as chord) {\n <kbd\n class=\"rounded border border-border bg-surface-overlay px-1 text-[0.6875rem] leading-tight text-content-muted\"\n >{{ chord }}</kbd\n >\n }\n @if (btn.tooltip ?? btn.label; as tip) {\n <lw-tooltip [text]=\"tip | transloco\" [position]=\"tooltipPosition()\" />\n }\n </button>\n} @else if (asComponent(); as comp) {\n <ng-container\n *ngComponentOutlet=\"comp.component; injector: componentInjector()\"\n ></ng-container>\n}\n" }]
|
|
2945
3150
|
}], propDecorators: { item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: true }] }], dock: [{ type: i0.Input, args: [{ isSignal: true, alias: "dock", required: true }] }] } });
|
|
2946
3151
|
|
|
2947
3152
|
class ShellBar {
|
|
@@ -2965,7 +3170,9 @@ class ShellBar {
|
|
|
2965
3170
|
.barItems()
|
|
2966
3171
|
.filter((item) => item.bar === this.region().id && item.slot === slot)
|
|
2967
3172
|
.filter((item) => this.auth.visible(item.access))
|
|
2968
|
-
.filter((item) => 'component' in item ||
|
|
3173
|
+
.filter((item) => 'component' in item ||
|
|
3174
|
+
menuOnActivate(item) !== undefined ||
|
|
3175
|
+
this.commands.triggerable(item))
|
|
2969
3176
|
.toSorted((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
|
2970
3177
|
}
|
|
2971
3178
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: ShellBar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
@@ -6155,13 +6362,17 @@ class ShellRail {
|
|
|
6155
6362
|
...(ngDevMode ? [{ debugName: "connectedRails" }] : /* istanbul ignore next */ []));
|
|
6156
6363
|
labelKey = computed(() => this.region().dock === 'right' ? 'rail.labelRight' : 'rail.label', /* @ts-ignore */
|
|
6157
6364
|
...(ngDevMode ? [{ debugName: "labelKey" }] : /* istanbul ignore next */ []));
|
|
6365
|
+
menuSide = computed(() => this.region().dock === 'right' ? 'left' : 'right', /* @ts-ignore */
|
|
6366
|
+
...(ngDevMode ? [{ debugName: "menuSide" }] : /* istanbul ignore next */ []));
|
|
6158
6367
|
reorderable = this.features.reorder;
|
|
6159
6368
|
draggable = this.features.reorder || this.features.moveItems;
|
|
6160
6369
|
registered = computed(() => this.registry
|
|
6161
6370
|
.railItems()
|
|
6162
6371
|
.filter((item) => this.railItems.regionOf(item.id, item.rail) === this.region().id)
|
|
6163
6372
|
.filter((item) => this.auth.visible(item.access))
|
|
6164
|
-
.filter((item) => item.workspace !== undefined ||
|
|
6373
|
+
.filter((item) => item.workspace !== undefined ||
|
|
6374
|
+
menuOnActivate(item) !== undefined ||
|
|
6375
|
+
this.commands.triggerable(item))
|
|
6165
6376
|
.toSorted((a, b) => (a.order ?? 0) - (b.order ?? 0)), /* @ts-ignore */
|
|
6166
6377
|
...(ngDevMode ? [{ debugName: "registered" }] : /* istanbul ignore next */ []));
|
|
6167
6378
|
items = computed(() => {
|
|
@@ -6174,16 +6385,26 @@ class ShellRail {
|
|
|
6174
6385
|
return [...top, ...bottom];
|
|
6175
6386
|
}, /* @ts-ignore */
|
|
6176
6387
|
...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
6388
|
+
brokenPictures = signal(new Set(), /* @ts-ignore */
|
|
6389
|
+
...(ngDevMode ? [{ debugName: "brokenPictures" }] : /* istanbul ignore next */ []));
|
|
6177
6390
|
firstBottomId = computed(() => this.items().find((item) => item.anchor === 'bottom')?.id, /* @ts-ignore */
|
|
6178
6391
|
...(ngDevMode ? [{ debugName: "firstBottomId" }] : /* istanbul ignore next */ []));
|
|
6179
6392
|
enterPredicate = (_drag, list) => list.id === this.dropListId() ? this.reorderable : this.features.moveItems;
|
|
6393
|
+
pictureOf(item) {
|
|
6394
|
+
return this.brokenPictures().has(item.id) ? undefined : item.image;
|
|
6395
|
+
}
|
|
6396
|
+
onPictureError(item) {
|
|
6397
|
+
this.brokenPictures.update((broken) => new Set(broken).add(item.id));
|
|
6398
|
+
}
|
|
6180
6399
|
disabled(item) {
|
|
6181
6400
|
return this.auth.disabled(item.access);
|
|
6182
6401
|
}
|
|
6183
6402
|
menusFor(item) {
|
|
6184
|
-
|
|
6185
|
-
|
|
6186
|
-
|
|
6403
|
+
const own = menuOnContext(item);
|
|
6404
|
+
return own ? [RAIL_ITEM_CONTEXT_MENU, own] : [RAIL_ITEM_CONTEXT_MENU];
|
|
6405
|
+
}
|
|
6406
|
+
activateMenuFor(item) {
|
|
6407
|
+
return menuOnActivate(item);
|
|
6187
6408
|
}
|
|
6188
6409
|
onKeydown(event) {
|
|
6189
6410
|
const dock = this.dockForChord(event);
|
|
@@ -6205,6 +6426,10 @@ class ShellRail {
|
|
|
6205
6426
|
run(item) {
|
|
6206
6427
|
if (this.disabled(item))
|
|
6207
6428
|
return;
|
|
6429
|
+
warnMenuTriggerConflict(item);
|
|
6430
|
+
if (menuOnActivate(item)) {
|
|
6431
|
+
return;
|
|
6432
|
+
}
|
|
6208
6433
|
const workspace = item.workspace;
|
|
6209
6434
|
if (workspace !== undefined) {
|
|
6210
6435
|
void this.workspaces.switchTo(workspace);
|
|
@@ -6242,7 +6467,7 @@ class ShellRail {
|
|
|
6242
6467
|
return event.key === 'ArrowLeft' ? 'left' : null;
|
|
6243
6468
|
}
|
|
6244
6469
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: ShellRail, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6245
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: ShellRail, isStandalone: true, selector: "lw-shell-rail", inputs: { region: { classPropertyName: "region", publicName: "region", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<nav\n class=\"flex h-full w-10 shrink-0 flex-col items-center gap-1 bg-surface py-2\"\n [attr.aria-label]=\"labelKey() | transloco\"\n cdkDropList\n cdkDropListOrientation=\"vertical\"\n [id]=\"dropListId()\"\n [cdkDropListConnectedTo]=\"connectedRails()\"\n [cdkDropListDisabled]=\"!draggable\"\n [cdkDropListSortingDisabled]=\"!reorderable\"\n [cdkDropListEnterPredicate]=\"enterPredicate\"\n [cdkDropListSortPredicate]=\"sortPredicate\"\n (cdkDropListDropped)=\"onDrop($event)\"\n [lwReorderable]=\"containerId()\"\n [lwReorderableEnabled]=\"reorderable\"\n (reorder)=\"onReorder($event)\"\n [
|
|
6470
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: ShellRail, isStandalone: true, selector: "lw-shell-rail", inputs: { region: { classPropertyName: "region", publicName: "region", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<nav\n class=\"flex h-full w-10 shrink-0 flex-col items-center gap-1 bg-surface py-2\"\n [attr.aria-label]=\"labelKey() | transloco\"\n cdkDropList\n cdkDropListOrientation=\"vertical\"\n [id]=\"dropListId()\"\n [cdkDropListConnectedTo]=\"connectedRails()\"\n [cdkDropListDisabled]=\"!draggable\"\n [cdkDropListSortingDisabled]=\"!reorderable\"\n [cdkDropListEnterPredicate]=\"enterPredicate\"\n [cdkDropListSortPredicate]=\"sortPredicate\"\n (cdkDropListDropped)=\"onDrop($event)\"\n [lwReorderable]=\"containerId()\"\n [lwReorderableEnabled]=\"reorderable\"\n (reorder)=\"onReorder($event)\"\n [lwMenu]=\"railMenu\"\n>\n @for (item of items(); track item.id) {\n <button\n type=\"button\"\n cdkDrag\n [cdkDragData]=\"item.id\"\n [cdkDragDisabled]=\"!draggable\"\n [disabled]=\"disabled(item)\"\n (click)=\"run(item)\"\n (keydown)=\"onKeydown($event)\"\n [lwMenu]=\"menusFor(item)\"\n [lwMenuOnActivate]=\"activateMenuFor(item)\"\n [lwMenuHeader]=\"item.menuHeader\"\n [lwMenuSide]=\"menuSide()\"\n [lwMenuContext]=\"{ targetKind: 'rail-item', id: item.id, region: region().id }\"\n [attr.aria-label]=\"item.title | transloco\"\n [attr.aria-current]=\"current(item) ? 'true' : null\"\n [attr.data-rail-item]=\"item.id\"\n [attr.data-reorder-id]=\"reorderable ? item.id : null\"\n [attr.data-reorder-band]=\"item.anchor ?? 'top'\"\n [class.mt-auto]=\"item.id === firstBottomId()\"\n [class.text-content]=\"current(item)\"\n [class.bg-surface-overlay]=\"current(item)\"\n class=\"relative flex h-9 w-9 items-center justify-center rounded-lg text-content-faint transition-colors hover:bg-surface-overlay hover:text-content disabled:pointer-events-none disabled:opacity-40\"\n >\n @if (current(item)) {\n <span\n aria-hidden=\"true\"\n class=\"absolute inset-y-1 w-0.5 rounded-full bg-brand\"\n [class.left-0]=\"region().dock !== 'right'\"\n [class.right-0]=\"region().dock === 'right'\"\n ></span>\n }\n @if (pictureOf(item); as picture) {\n <img\n [src]=\"picture\"\n alt=\"\"\n aria-hidden=\"true\"\n data-testid=\"rail-picture\"\n class=\"lw-chrome-picture h-6 w-6\"\n (error)=\"onPictureError(item)\"\n />\n } @else if (item.initials) {\n <span\n aria-hidden=\"true\"\n data-testid=\"rail-initials\"\n class=\"lw-rail-initials\"\n >{{ item.initials }}</span\n >\n } @else {\n <lw-icon [name]=\"item.icon\" size=\"1rem\" />\n }\n <lw-tooltip [text]=\"item.title | transloco\" [position]=\"region().dock === 'right' ? 'left' : 'right'\" />\n </button>\n }\n</nav>\n", dependencies: [{ kind: "directive", type: Reorderable, selector: "[lwReorderable]", inputs: ["lwReorderable", "lwReorderableEnabled"], outputs: ["reorder"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: MenuTriggerDirective, selector: "[lwMenu], [lwMenuOnActivate], [lwMenuState]", inputs: ["lwMenu", "lwMenuOnActivate", "lwMenuContext", "lwMenuSide", "lwMenuHeader", "lwMenuState"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
6246
6471
|
}
|
|
6247
6472
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: ShellRail, decorators: [{
|
|
6248
6473
|
type: Component,
|
|
@@ -6251,8 +6476,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
6251
6476
|
Reorderable,
|
|
6252
6477
|
CdkDropList,
|
|
6253
6478
|
CdkDrag,
|
|
6254
|
-
|
|
6255
|
-
], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<nav\n class=\"flex h-full w-10 shrink-0 flex-col items-center gap-1 bg-surface py-2\"\n [attr.aria-label]=\"labelKey() | transloco\"\n cdkDropList\n cdkDropListOrientation=\"vertical\"\n [id]=\"dropListId()\"\n [cdkDropListConnectedTo]=\"connectedRails()\"\n [cdkDropListDisabled]=\"!draggable\"\n [cdkDropListSortingDisabled]=\"!reorderable\"\n [cdkDropListEnterPredicate]=\"enterPredicate\"\n [cdkDropListSortPredicate]=\"sortPredicate\"\n (cdkDropListDropped)=\"onDrop($event)\"\n [lwReorderable]=\"containerId()\"\n [lwReorderableEnabled]=\"reorderable\"\n (reorder)=\"onReorder($event)\"\n [
|
|
6479
|
+
MenuTriggerDirective,
|
|
6480
|
+
], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<nav\n class=\"flex h-full w-10 shrink-0 flex-col items-center gap-1 bg-surface py-2\"\n [attr.aria-label]=\"labelKey() | transloco\"\n cdkDropList\n cdkDropListOrientation=\"vertical\"\n [id]=\"dropListId()\"\n [cdkDropListConnectedTo]=\"connectedRails()\"\n [cdkDropListDisabled]=\"!draggable\"\n [cdkDropListSortingDisabled]=\"!reorderable\"\n [cdkDropListEnterPredicate]=\"enterPredicate\"\n [cdkDropListSortPredicate]=\"sortPredicate\"\n (cdkDropListDropped)=\"onDrop($event)\"\n [lwReorderable]=\"containerId()\"\n [lwReorderableEnabled]=\"reorderable\"\n (reorder)=\"onReorder($event)\"\n [lwMenu]=\"railMenu\"\n>\n @for (item of items(); track item.id) {\n <button\n type=\"button\"\n cdkDrag\n [cdkDragData]=\"item.id\"\n [cdkDragDisabled]=\"!draggable\"\n [disabled]=\"disabled(item)\"\n (click)=\"run(item)\"\n (keydown)=\"onKeydown($event)\"\n [lwMenu]=\"menusFor(item)\"\n [lwMenuOnActivate]=\"activateMenuFor(item)\"\n [lwMenuHeader]=\"item.menuHeader\"\n [lwMenuSide]=\"menuSide()\"\n [lwMenuContext]=\"{ targetKind: 'rail-item', id: item.id, region: region().id }\"\n [attr.aria-label]=\"item.title | transloco\"\n [attr.aria-current]=\"current(item) ? 'true' : null\"\n [attr.data-rail-item]=\"item.id\"\n [attr.data-reorder-id]=\"reorderable ? item.id : null\"\n [attr.data-reorder-band]=\"item.anchor ?? 'top'\"\n [class.mt-auto]=\"item.id === firstBottomId()\"\n [class.text-content]=\"current(item)\"\n [class.bg-surface-overlay]=\"current(item)\"\n class=\"relative flex h-9 w-9 items-center justify-center rounded-lg text-content-faint transition-colors hover:bg-surface-overlay hover:text-content disabled:pointer-events-none disabled:opacity-40\"\n >\n @if (current(item)) {\n <span\n aria-hidden=\"true\"\n class=\"absolute inset-y-1 w-0.5 rounded-full bg-brand\"\n [class.left-0]=\"region().dock !== 'right'\"\n [class.right-0]=\"region().dock === 'right'\"\n ></span>\n }\n @if (pictureOf(item); as picture) {\n <img\n [src]=\"picture\"\n alt=\"\"\n aria-hidden=\"true\"\n data-testid=\"rail-picture\"\n class=\"lw-chrome-picture h-6 w-6\"\n (error)=\"onPictureError(item)\"\n />\n } @else if (item.initials) {\n <span\n aria-hidden=\"true\"\n data-testid=\"rail-initials\"\n class=\"lw-rail-initials\"\n >{{ item.initials }}</span\n >\n } @else {\n <lw-icon [name]=\"item.icon\" size=\"1rem\" />\n }\n <lw-tooltip [text]=\"item.title | transloco\" [position]=\"region().dock === 'right' ? 'left' : 'right'\" />\n </button>\n }\n</nav>\n" }]
|
|
6256
6481
|
}], propDecorators: { region: [{ type: i0.Input, args: [{ isSignal: true, alias: "region", required: true }] }] } });
|
|
6257
6482
|
|
|
6258
6483
|
const STORAGE_PREFIX$2 = 'lw.shell.view-state:';
|
|
@@ -6567,8 +6792,9 @@ class ViewInstanceSwitcher {
|
|
|
6567
6792
|
if (!this.viewInstances.isDefault(viewId, activeId)) {
|
|
6568
6793
|
entries.push({ key: 'rename', label: t('viewInstance.rename') }, { key: 'delete', label: t('viewInstance.delete') });
|
|
6569
6794
|
}
|
|
6570
|
-
const
|
|
6571
|
-
|
|
6795
|
+
const control = event.currentTarget;
|
|
6796
|
+
const rect = control.getBoundingClientRect();
|
|
6797
|
+
this.menu.openList(entries, { x: rect.left, y: rect.bottom + MENU_ANCHOR_GAP }, (key) => this.onPick(key), control);
|
|
6572
6798
|
}
|
|
6573
6799
|
onPick(key) {
|
|
6574
6800
|
const viewId = this.view().id;
|
|
@@ -6641,11 +6867,11 @@ class ViewInstanceSwitcher {
|
|
|
6641
6867
|
};
|
|
6642
6868
|
}
|
|
6643
6869
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: ViewInstanceSwitcher, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6644
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: ViewInstanceSwitcher, isStandalone: true, selector: "lw-view-instance-switcher", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { beforeSwitch: "beforeSwitch" }, host: { classAttribute: "flex min-w-0 flex-1" }, ngImport: i0, template: "<button\n type=\"button\"\n class=\"flex min-w-0 flex-1 items-center gap-1 truncate rounded px-1 py-0.5 text-left text-xs font-semibold tracking-wide text-content-faint uppercase transition-colors hover:bg-surface-overlay hover:text-content\"\n (click)=\"openSwitcher($event)\"\n [attr.aria-label]=\"'viewInstance.switcher' | transloco\"\n data-testid=\"view-switcher\"\n>\n <span class=\"truncate\">{{ activeName() || ('viewInstance.default' | transloco) }}</span>\n <lw-icon name=\"chevronDown\" size=\"0.85rem\" class=\"shrink-0\" />\n</button>\n", dependencies: [{ kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
6870
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: ViewInstanceSwitcher, isStandalone: true, selector: "lw-view-instance-switcher", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { beforeSwitch: "beforeSwitch" }, host: { classAttribute: "flex min-w-0 flex-1" }, ngImport: i0, template: "<button\n type=\"button\"\n class=\"flex min-w-0 flex-1 items-center gap-1 truncate rounded px-1 py-0.5 text-left text-xs font-semibold tracking-wide text-content-faint uppercase transition-colors hover:bg-surface-overlay hover:text-content\"\n (click)=\"openSwitcher($event)\"\n lwMenuState\n [attr.aria-label]=\"'viewInstance.switcher' | transloco\"\n data-testid=\"view-switcher\"\n>\n <span class=\"truncate\">{{ activeName() || ('viewInstance.default' | transloco) }}</span>\n <lw-icon name=\"chevronDown\" size=\"0.85rem\" class=\"shrink-0\" />\n</button>\n", dependencies: [{ kind: "directive", type: MenuTriggerDirective, selector: "[lwMenu], [lwMenuOnActivate], [lwMenuState]", inputs: ["lwMenu", "lwMenuOnActivate", "lwMenuContext", "lwMenuSide", "lwMenuHeader", "lwMenuState"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
6645
6871
|
}
|
|
6646
6872
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: ViewInstanceSwitcher, decorators: [{
|
|
6647
6873
|
type: Component,
|
|
6648
|
-
args: [{ selector: 'lw-view-instance-switcher', imports: [TranslocoPipe], schemas: [CUSTOM_ELEMENTS_SCHEMA], host: { class: 'flex min-w-0 flex-1' }, template: "<button\n type=\"button\"\n class=\"flex min-w-0 flex-1 items-center gap-1 truncate rounded px-1 py-0.5 text-left text-xs font-semibold tracking-wide text-content-faint uppercase transition-colors hover:bg-surface-overlay hover:text-content\"\n (click)=\"openSwitcher($event)\"\n [attr.aria-label]=\"'viewInstance.switcher' | transloco\"\n data-testid=\"view-switcher\"\n>\n <span class=\"truncate\">{{ activeName() || ('viewInstance.default' | transloco) }}</span>\n <lw-icon name=\"chevronDown\" size=\"0.85rem\" class=\"shrink-0\" />\n</button>\n" }]
|
|
6874
|
+
args: [{ selector: 'lw-view-instance-switcher', imports: [TranslocoPipe, MenuTriggerDirective], schemas: [CUSTOM_ELEMENTS_SCHEMA], host: { class: 'flex min-w-0 flex-1' }, template: "<button\n type=\"button\"\n class=\"flex min-w-0 flex-1 items-center gap-1 truncate rounded px-1 py-0.5 text-left text-xs font-semibold tracking-wide text-content-faint uppercase transition-colors hover:bg-surface-overlay hover:text-content\"\n (click)=\"openSwitcher($event)\"\n lwMenuState\n [attr.aria-label]=\"'viewInstance.switcher' | transloco\"\n data-testid=\"view-switcher\"\n>\n <span class=\"truncate\">{{ activeName() || ('viewInstance.default' | transloco) }}</span>\n <lw-icon name=\"chevronDown\" size=\"0.85rem\" class=\"shrink-0\" />\n</button>\n" }]
|
|
6649
6875
|
}], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], beforeSwitch: [{ type: i0.Output, args: ["beforeSwitch"] }] } });
|
|
6650
6876
|
|
|
6651
6877
|
class PaneChromeService {
|
|
@@ -7172,7 +7398,8 @@ class PaneTabStrip {
|
|
|
7172
7398
|
this.paneDrag.stop();
|
|
7173
7399
|
}
|
|
7174
7400
|
openOverflow(event) {
|
|
7175
|
-
const
|
|
7401
|
+
const control = event.currentTarget;
|
|
7402
|
+
const anchor = control.getBoundingClientRect();
|
|
7176
7403
|
const entries = this.tabs().map((tab) => ({
|
|
7177
7404
|
key: tab.path,
|
|
7178
7405
|
label: this.label(tab),
|
|
@@ -7184,7 +7411,7 @@ class PaneTabStrip {
|
|
|
7184
7411
|
if (tab) {
|
|
7185
7412
|
this.selectTab.emit(tab);
|
|
7186
7413
|
}
|
|
7187
|
-
});
|
|
7414
|
+
}, control);
|
|
7188
7415
|
}
|
|
7189
7416
|
onSelectTab(tab) {
|
|
7190
7417
|
if (tab.path !== this.activeId()) {
|
|
@@ -7297,19 +7524,19 @@ class PaneTabStrip {
|
|
|
7297
7524
|
return resolveTitle(tab, (key) => this.transloco.translate(key));
|
|
7298
7525
|
}
|
|
7299
7526
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: PaneTabStrip, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7300
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: PaneTabStrip, isStandalone: true, selector: "lw-pane-tab-strip", inputs: { tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: true, transformFunction: null }, activeId: { classPropertyName: "activeId", publicName: "activeId", isSignal: true, isRequired: true, transformFunction: null }, reorderable: { classPropertyName: "reorderable", publicName: "reorderable", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, acceptsTabs: { classPropertyName: "acceptsTabs", publicName: "acceptsTabs", isSignal: true, isRequired: false, transformFunction: null }, source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: true, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, urlDriven: { classPropertyName: "urlDriven", publicName: "urlDriven", isSignal: true, isRequired: false, transformFunction: null }, contextMenuSlot: { classPropertyName: "contextMenuSlot", publicName: "contextMenuSlot", isSignal: true, isRequired: false, transformFunction: null }, viewContextMenuSlot: { classPropertyName: "viewContextMenuSlot", publicName: "viewContextMenuSlot", isSignal: true, isRequired: false, transformFunction: null }, contextGroup: { classPropertyName: "contextGroup", publicName: "contextGroup", isSignal: true, isRequired: false, transformFunction: null }, overflow: { classPropertyName: "overflow", publicName: "overflow", isSignal: true, isRequired: false, transformFunction: null }, canAddTab: { classPropertyName: "canAddTab", publicName: "canAddTab", isSignal: true, isRequired: false, transformFunction: null }, paneActions: { classPropertyName: "paneActions", publicName: "paneActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectTab: "selectTab", escalate: "escalate", closeTab: "closeTab", unpinTab: "unpinTab", reorderTabs: "reorderTabs", runAction: "runAction", addTab: "addTab", revealRequest: "revealRequest" }, viewQueries: [{ propertyName: "strip", first: true, predicate: ["tabStrip"], descendants: true, isSignal: true }], ngImport: i0, template: "<div [class]=\"bandClass()\">\n <div\n #tabStrip\n class=\"flex min-w-0 flex-1 items-center gap-0.5 overflow-hidden\"\n [class.px-2]=\"!icons()\"\n [class.px-1]=\"icons()\"\n role=\"tablist\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n [id]=\"stripId()\"\n [cdkDropListSortingDisabled]=\"!reorderable()\"\n [cdkDropListEnterPredicate]=\"enterPredicate\"\n [cdkDropListConnectedTo]=\"dragZoneIds()\"\n [cdkDropListSortPredicate]=\"sortPredicate\"\n (cdkDropListDropped)=\"onDrop($event)\"\n [lwReorderable]=\"stripId()\"\n [lwReorderableEnabled]=\"reorderable()\"\n (reorder)=\"reorderTabs.emit($event)\"\n >\n @for (tab of tabs(); track tab.path) {\n @let title = tab.literalTitle ? tab.title : (tab.title | transloco);\n @if (icons()) {\n <button\n type=\"button\"\n role=\"tab\"\n cdkDrag\n [cdkDragData]=\"tab.path\"\n [cdkDragDisabled]=\"!canDrag(tab)\"\n (cdkDragStarted)=\"onDragStarted(tab)\"\n (cdkDragEnded)=\"onDragEnded()\"\n [lwContextMenu]=\"menuSlotFor(tab)\"\n [lwContextMenuContext]=\"tabContext(tab)\"\n [attr.aria-selected]=\"isActive(tab)\"\n [attr.aria-label]=\"title\"\n [attr.data-reorder-id]=\"canReorder(tab) ? tab.path : null\"\n [attr.data-reorder-band]=\"tab.pinned ? 'pinned' : 'dynamic'\"\n [attr.data-tab-path]=\"tab.path\"\n (click)=\"onSelectTab(tab)\"\n (dblclick)=\"escalate.emit(tab)\"\n class=\"lw-icon-btn h-10 w-10 rounded-md md:h-7 md:w-7\"\n [class.bg-surface-overlay]=\"isActive(tab)\"\n [class.text-content]=\"isActive(tab)\"\n >\n <lw-icon [name]=\"tab.icon ?? 'document'\" size=\"1rem\" />\n <lw-tooltip [text]=\"title\" position=\"bottom\" />\n </button>\n } @else {\n <div\n class=\"flex max-w-52 min-w-28 items-center border-b-2 transition-colors\"\n cdkDrag\n [cdkDragData]=\"tab.path\"\n [cdkDragDisabled]=\"!canDrag(tab)\"\n (cdkDragStarted)=\"onDragStarted(tab)\"\n (cdkDragEnded)=\"onDragEnded()\"\n [class.border-brand]=\"isActive(tab) && urlDriven()\"\n [class.border-content-faint]=\"isActive(tab) && !urlDriven()\"\n [class.border-transparent]=\"!isActive(tab)\"\n [lwContextMenu]=\"menuSlotFor(tab)\"\n [lwContextMenuContext]=\"tabContext(tab)\"\n >\n <button\n type=\"button\"\n role=\"tab\"\n cdkDragHandle\n [attr.aria-selected]=\"isActive(tab)\"\n [attr.aria-label]=\"title\"\n [attr.data-reorder-id]=\"canReorder(tab) ? tab.path : null\"\n [attr.data-reorder-band]=\"tab.pinned ? 'pinned' : 'dynamic'\"\n [attr.data-tab-path]=\"tab.path\"\n [attr.aria-keyshortcuts]=\"tab.closable && !tab.pinned ? 'Delete' : null\"\n (click)=\"onSelectTab(tab)\"\n (dblclick)=\"escalate.emit(tab)\"\n (keydown)=\"onTabKeydown($event, tab)\"\n class=\"relative flex min-w-0 items-center gap-1.5 py-2 pr-1 pl-3 text-sm transition-colors\"\n [class.text-content]=\"isActive(tab)\"\n [class.text-content-faint]=\"!isActive(tab)\"\n [class.italic]=\"tab.preview\"\n >\n @if (tab.preview) {\n <lw-icon name=\"preview\" size=\"1rem\" />\n } @else if (tab.icon) {\n <lw-icon [name]=\"tab.icon\" size=\"1rem\" />\n }\n <span class=\"min-w-0 truncate\">{{ title }}</span>\n\n <lw-tooltip\n [text]=\"\n tab.preview && escalatable\n ? title + ' \u2014 ' + ('content.previewHint' | transloco)\n : title\n \"\n position=\"bottom\"\n />\n </button>\n\n @if (tab.pinned) {\n <span\n aria-hidden=\"true\"\n data-testid=\"tab-unpin\"\n (click)=\"onUnpin($event, tab)\"\n class=\"relative mr-1 flex h-6 w-6 cursor-pointer items-center justify-center rounded text-brand opacity-90 transition-colors hover:bg-surface-overlay hover:opacity-100\"\n >\n <lw-icon name=\"pin\" size=\"0.85rem\" />\n <lw-tooltip [text]=\"'content.pinnedHint' | transloco\" position=\"bottom\" />\n </span>\n } @else if (tab.closable) {\n <span\n aria-hidden=\"true\"\n data-testid=\"tab-close\"\n (click)=\"onClose($event, tab)\"\n class=\"lw-icon-btn mr-1 h-6 w-6 cursor-pointer opacity-70 hover:opacity-100\"\n >\n <lw-icon name=\"close\" size=\"0.85rem\" />\n <lw-tooltip [text]=\"'content.closeTab' | transloco\" position=\"bottom\" />\n </span>\n }\n </div>\n }\n }\n </div>\n\n @if (canAddTab()) {\n <button\n type=\"button\"\n (click)=\"addTab.emit($event)\"\n class=\"lw-icon-btn w-8\"\n [class.self-stretch]=\"icons()\"\n [attr.aria-label]=\"'content.split.newTab' | transloco\"\n data-testid=\"pane-add-tab\"\n >\n <lw-icon name=\"add\" size=\"1rem\" />\n <lw-tooltip [text]=\"'content.split.newTab' | transloco\" position=\"bottom\" />\n </button>\n }\n\n @if (overflow() && overflowing()) {\n <button\n type=\"button\"\n (click)=\"openOverflow($event)\"\n class=\"lw-icon-btn w-8\"\n [class.self-stretch]=\"icons()\"\n [attr.aria-label]=\"'content.moreTabs' | transloco\"\n >\n <lw-icon name=\"chevronDown\" size=\"1rem\" />\n <lw-tooltip [text]=\"'content.moreTabs' | transloco\" position=\"bottom\" />\n </button>\n }\n\n @if (paneActions(); as actions) {\n <ng-container [ngTemplateOutlet]=\"actions\" />\n }\n @if (activeActions().length) {\n <div class=\"flex shrink-0 items-center gap-0.5 border-l border-border px-2\">\n @for (action of activeActions(); track action.id) {\n <button\n type=\"button\"\n (click)=\"runAction.emit(action)\"\n class=\"lw-icon-btn h-8 w-8 rounded-md\"\n [attr.aria-label]=\"action.title | transloco\"\n >\n <lw-icon [name]=\"action.icon\" size=\"1rem\" />\n <lw-tooltip [text]=\"action.title | transloco\" position=\"bottom\" />\n </button>\n }\n </div>\n }\n</div>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: ContextMenuDirective, selector: "[lwContextMenu]", inputs: ["lwContextMenu", "lwContextMenuContext"] }, { kind: "directive", type: Reorderable, selector: "[lwReorderable]", inputs: ["lwReorderable", "lwReorderableEnabled"], outputs: ["reorder"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
7527
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: PaneTabStrip, isStandalone: true, selector: "lw-pane-tab-strip", inputs: { tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: true, transformFunction: null }, activeId: { classPropertyName: "activeId", publicName: "activeId", isSignal: true, isRequired: true, transformFunction: null }, reorderable: { classPropertyName: "reorderable", publicName: "reorderable", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, acceptsTabs: { classPropertyName: "acceptsTabs", publicName: "acceptsTabs", isSignal: true, isRequired: false, transformFunction: null }, source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: true, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, urlDriven: { classPropertyName: "urlDriven", publicName: "urlDriven", isSignal: true, isRequired: false, transformFunction: null }, contextMenuSlot: { classPropertyName: "contextMenuSlot", publicName: "contextMenuSlot", isSignal: true, isRequired: false, transformFunction: null }, viewContextMenuSlot: { classPropertyName: "viewContextMenuSlot", publicName: "viewContextMenuSlot", isSignal: true, isRequired: false, transformFunction: null }, contextGroup: { classPropertyName: "contextGroup", publicName: "contextGroup", isSignal: true, isRequired: false, transformFunction: null }, overflow: { classPropertyName: "overflow", publicName: "overflow", isSignal: true, isRequired: false, transformFunction: null }, canAddTab: { classPropertyName: "canAddTab", publicName: "canAddTab", isSignal: true, isRequired: false, transformFunction: null }, paneActions: { classPropertyName: "paneActions", publicName: "paneActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectTab: "selectTab", escalate: "escalate", closeTab: "closeTab", unpinTab: "unpinTab", reorderTabs: "reorderTabs", runAction: "runAction", addTab: "addTab", revealRequest: "revealRequest" }, viewQueries: [{ propertyName: "strip", first: true, predicate: ["tabStrip"], descendants: true, isSignal: true }], ngImport: i0, template: "<div [class]=\"bandClass()\">\n <div\n #tabStrip\n class=\"flex min-w-0 flex-1 items-center gap-0.5 overflow-hidden\"\n [class.px-2]=\"!icons()\"\n [class.px-1]=\"icons()\"\n role=\"tablist\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n [id]=\"stripId()\"\n [cdkDropListSortingDisabled]=\"!reorderable()\"\n [cdkDropListEnterPredicate]=\"enterPredicate\"\n [cdkDropListConnectedTo]=\"dragZoneIds()\"\n [cdkDropListSortPredicate]=\"sortPredicate\"\n (cdkDropListDropped)=\"onDrop($event)\"\n [lwReorderable]=\"stripId()\"\n [lwReorderableEnabled]=\"reorderable()\"\n (reorder)=\"reorderTabs.emit($event)\"\n >\n @for (tab of tabs(); track tab.path) {\n @let title = tab.literalTitle ? tab.title : (tab.title | transloco);\n @if (icons()) {\n <button\n type=\"button\"\n role=\"tab\"\n cdkDrag\n [cdkDragData]=\"tab.path\"\n [cdkDragDisabled]=\"!canDrag(tab)\"\n (cdkDragStarted)=\"onDragStarted(tab)\"\n (cdkDragEnded)=\"onDragEnded()\"\n [lwMenu]=\"menuSlotFor(tab)\"\n [lwMenuContext]=\"tabContext(tab)\"\n [attr.aria-selected]=\"isActive(tab)\"\n [attr.aria-label]=\"title\"\n [attr.data-reorder-id]=\"canReorder(tab) ? tab.path : null\"\n [attr.data-reorder-band]=\"tab.pinned ? 'pinned' : 'dynamic'\"\n [attr.data-tab-path]=\"tab.path\"\n (click)=\"onSelectTab(tab)\"\n (dblclick)=\"escalate.emit(tab)\"\n class=\"lw-icon-btn h-10 w-10 rounded-md md:h-7 md:w-7\"\n [class.bg-surface-overlay]=\"isActive(tab)\"\n [class.text-content]=\"isActive(tab)\"\n >\n <lw-icon [name]=\"tab.icon ?? 'document'\" size=\"1rem\" />\n <lw-tooltip [text]=\"title\" position=\"bottom\" />\n </button>\n } @else {\n <div\n class=\"flex max-w-52 min-w-28 items-center border-b-2 transition-colors\"\n cdkDrag\n [cdkDragData]=\"tab.path\"\n [cdkDragDisabled]=\"!canDrag(tab)\"\n (cdkDragStarted)=\"onDragStarted(tab)\"\n (cdkDragEnded)=\"onDragEnded()\"\n [class.border-brand]=\"isActive(tab) && urlDriven()\"\n [class.border-content-faint]=\"isActive(tab) && !urlDriven()\"\n [class.border-transparent]=\"!isActive(tab)\"\n [lwMenu]=\"menuSlotFor(tab)\"\n [lwMenuContext]=\"tabContext(tab)\"\n >\n <button\n type=\"button\"\n role=\"tab\"\n cdkDragHandle\n [attr.aria-selected]=\"isActive(tab)\"\n [attr.aria-label]=\"title\"\n [attr.data-reorder-id]=\"canReorder(tab) ? tab.path : null\"\n [attr.data-reorder-band]=\"tab.pinned ? 'pinned' : 'dynamic'\"\n [attr.data-tab-path]=\"tab.path\"\n [attr.aria-keyshortcuts]=\"tab.closable && !tab.pinned ? 'Delete' : null\"\n (click)=\"onSelectTab(tab)\"\n (dblclick)=\"escalate.emit(tab)\"\n (keydown)=\"onTabKeydown($event, tab)\"\n class=\"relative flex min-w-0 items-center gap-1.5 py-2 pr-1 pl-3 text-sm transition-colors\"\n [class.text-content]=\"isActive(tab)\"\n [class.text-content-faint]=\"!isActive(tab)\"\n [class.italic]=\"tab.preview\"\n >\n @if (tab.preview) {\n <lw-icon name=\"preview\" size=\"1rem\" />\n } @else if (tab.icon) {\n <lw-icon [name]=\"tab.icon\" size=\"1rem\" />\n }\n <span class=\"min-w-0 truncate\">{{ title }}</span>\n\n <lw-tooltip\n [text]=\"\n tab.preview && escalatable\n ? title + ' \u2014 ' + ('content.previewHint' | transloco)\n : title\n \"\n position=\"bottom\"\n />\n </button>\n\n @if (tab.pinned) {\n <span\n aria-hidden=\"true\"\n data-testid=\"tab-unpin\"\n (click)=\"onUnpin($event, tab)\"\n class=\"relative mr-1 flex h-6 w-6 cursor-pointer items-center justify-center rounded text-brand opacity-90 transition-colors hover:bg-surface-overlay hover:opacity-100\"\n >\n <lw-icon name=\"pin\" size=\"0.85rem\" />\n <lw-tooltip [text]=\"'content.pinnedHint' | transloco\" position=\"bottom\" />\n </span>\n } @else if (tab.closable) {\n <span\n aria-hidden=\"true\"\n data-testid=\"tab-close\"\n (click)=\"onClose($event, tab)\"\n class=\"lw-icon-btn mr-1 h-6 w-6 cursor-pointer opacity-70 hover:opacity-100\"\n >\n <lw-icon name=\"close\" size=\"0.85rem\" />\n <lw-tooltip [text]=\"'content.closeTab' | transloco\" position=\"bottom\" />\n </span>\n }\n </div>\n }\n }\n </div>\n\n @if (canAddTab()) {\n <button\n type=\"button\"\n (click)=\"addTab.emit($event)\"\n lwMenuState\n class=\"lw-icon-btn w-8\"\n [class.self-stretch]=\"icons()\"\n [attr.aria-label]=\"'content.split.newTab' | transloco\"\n data-testid=\"pane-add-tab\"\n >\n <lw-icon name=\"add\" size=\"1rem\" />\n <lw-tooltip [text]=\"'content.split.newTab' | transloco\" position=\"bottom\" />\n </button>\n }\n\n @if (overflow() && overflowing()) {\n <button\n type=\"button\"\n (click)=\"openOverflow($event)\"\n lwMenuState\n class=\"lw-icon-btn w-8\"\n [class.self-stretch]=\"icons()\"\n [attr.aria-label]=\"'content.moreTabs' | transloco\"\n >\n <lw-icon name=\"chevronDown\" size=\"1rem\" />\n <lw-tooltip [text]=\"'content.moreTabs' | transloco\" position=\"bottom\" />\n </button>\n }\n\n @if (paneActions(); as actions) {\n <ng-container [ngTemplateOutlet]=\"actions\" />\n }\n @if (activeActions().length) {\n <div class=\"flex shrink-0 items-center gap-0.5 border-l border-border px-2\">\n @for (action of activeActions(); track action.id) {\n <button\n type=\"button\"\n (click)=\"runAction.emit(action)\"\n class=\"lw-icon-btn h-8 w-8 rounded-md\"\n [attr.aria-label]=\"action.title | transloco\"\n >\n <lw-icon [name]=\"action.icon\" size=\"1rem\" />\n <lw-tooltip [text]=\"action.title | transloco\" position=\"bottom\" />\n </button>\n }\n </div>\n }\n</div>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: MenuTriggerDirective, selector: "[lwMenu], [lwMenuOnActivate], [lwMenuState]", inputs: ["lwMenu", "lwMenuOnActivate", "lwMenuContext", "lwMenuSide", "lwMenuHeader", "lwMenuState"] }, { kind: "directive", type: Reorderable, selector: "[lwReorderable]", inputs: ["lwReorderable", "lwReorderableEnabled"], outputs: ["reorder"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
7301
7528
|
}
|
|
7302
7529
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: PaneTabStrip, decorators: [{
|
|
7303
7530
|
type: Component,
|
|
7304
7531
|
args: [{ selector: 'lw-pane-tab-strip', imports: [
|
|
7305
7532
|
NgTemplateOutlet,
|
|
7306
7533
|
TranslocoPipe,
|
|
7307
|
-
|
|
7534
|
+
MenuTriggerDirective,
|
|
7308
7535
|
Reorderable,
|
|
7309
7536
|
CdkDropList,
|
|
7310
7537
|
CdkDrag,
|
|
7311
7538
|
CdkDragHandle,
|
|
7312
|
-
], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<div [class]=\"bandClass()\">\n <div\n #tabStrip\n class=\"flex min-w-0 flex-1 items-center gap-0.5 overflow-hidden\"\n [class.px-2]=\"!icons()\"\n [class.px-1]=\"icons()\"\n role=\"tablist\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n [id]=\"stripId()\"\n [cdkDropListSortingDisabled]=\"!reorderable()\"\n [cdkDropListEnterPredicate]=\"enterPredicate\"\n [cdkDropListConnectedTo]=\"dragZoneIds()\"\n [cdkDropListSortPredicate]=\"sortPredicate\"\n (cdkDropListDropped)=\"onDrop($event)\"\n [lwReorderable]=\"stripId()\"\n [lwReorderableEnabled]=\"reorderable()\"\n (reorder)=\"reorderTabs.emit($event)\"\n >\n @for (tab of tabs(); track tab.path) {\n @let title = tab.literalTitle ? tab.title : (tab.title | transloco);\n @if (icons()) {\n <button\n type=\"button\"\n role=\"tab\"\n cdkDrag\n [cdkDragData]=\"tab.path\"\n [cdkDragDisabled]=\"!canDrag(tab)\"\n (cdkDragStarted)=\"onDragStarted(tab)\"\n (cdkDragEnded)=\"onDragEnded()\"\n [
|
|
7539
|
+
], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<div [class]=\"bandClass()\">\n <div\n #tabStrip\n class=\"flex min-w-0 flex-1 items-center gap-0.5 overflow-hidden\"\n [class.px-2]=\"!icons()\"\n [class.px-1]=\"icons()\"\n role=\"tablist\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n [id]=\"stripId()\"\n [cdkDropListSortingDisabled]=\"!reorderable()\"\n [cdkDropListEnterPredicate]=\"enterPredicate\"\n [cdkDropListConnectedTo]=\"dragZoneIds()\"\n [cdkDropListSortPredicate]=\"sortPredicate\"\n (cdkDropListDropped)=\"onDrop($event)\"\n [lwReorderable]=\"stripId()\"\n [lwReorderableEnabled]=\"reorderable()\"\n (reorder)=\"reorderTabs.emit($event)\"\n >\n @for (tab of tabs(); track tab.path) {\n @let title = tab.literalTitle ? tab.title : (tab.title | transloco);\n @if (icons()) {\n <button\n type=\"button\"\n role=\"tab\"\n cdkDrag\n [cdkDragData]=\"tab.path\"\n [cdkDragDisabled]=\"!canDrag(tab)\"\n (cdkDragStarted)=\"onDragStarted(tab)\"\n (cdkDragEnded)=\"onDragEnded()\"\n [lwMenu]=\"menuSlotFor(tab)\"\n [lwMenuContext]=\"tabContext(tab)\"\n [attr.aria-selected]=\"isActive(tab)\"\n [attr.aria-label]=\"title\"\n [attr.data-reorder-id]=\"canReorder(tab) ? tab.path : null\"\n [attr.data-reorder-band]=\"tab.pinned ? 'pinned' : 'dynamic'\"\n [attr.data-tab-path]=\"tab.path\"\n (click)=\"onSelectTab(tab)\"\n (dblclick)=\"escalate.emit(tab)\"\n class=\"lw-icon-btn h-10 w-10 rounded-md md:h-7 md:w-7\"\n [class.bg-surface-overlay]=\"isActive(tab)\"\n [class.text-content]=\"isActive(tab)\"\n >\n <lw-icon [name]=\"tab.icon ?? 'document'\" size=\"1rem\" />\n <lw-tooltip [text]=\"title\" position=\"bottom\" />\n </button>\n } @else {\n <div\n class=\"flex max-w-52 min-w-28 items-center border-b-2 transition-colors\"\n cdkDrag\n [cdkDragData]=\"tab.path\"\n [cdkDragDisabled]=\"!canDrag(tab)\"\n (cdkDragStarted)=\"onDragStarted(tab)\"\n (cdkDragEnded)=\"onDragEnded()\"\n [class.border-brand]=\"isActive(tab) && urlDriven()\"\n [class.border-content-faint]=\"isActive(tab) && !urlDriven()\"\n [class.border-transparent]=\"!isActive(tab)\"\n [lwMenu]=\"menuSlotFor(tab)\"\n [lwMenuContext]=\"tabContext(tab)\"\n >\n <button\n type=\"button\"\n role=\"tab\"\n cdkDragHandle\n [attr.aria-selected]=\"isActive(tab)\"\n [attr.aria-label]=\"title\"\n [attr.data-reorder-id]=\"canReorder(tab) ? tab.path : null\"\n [attr.data-reorder-band]=\"tab.pinned ? 'pinned' : 'dynamic'\"\n [attr.data-tab-path]=\"tab.path\"\n [attr.aria-keyshortcuts]=\"tab.closable && !tab.pinned ? 'Delete' : null\"\n (click)=\"onSelectTab(tab)\"\n (dblclick)=\"escalate.emit(tab)\"\n (keydown)=\"onTabKeydown($event, tab)\"\n class=\"relative flex min-w-0 items-center gap-1.5 py-2 pr-1 pl-3 text-sm transition-colors\"\n [class.text-content]=\"isActive(tab)\"\n [class.text-content-faint]=\"!isActive(tab)\"\n [class.italic]=\"tab.preview\"\n >\n @if (tab.preview) {\n <lw-icon name=\"preview\" size=\"1rem\" />\n } @else if (tab.icon) {\n <lw-icon [name]=\"tab.icon\" size=\"1rem\" />\n }\n <span class=\"min-w-0 truncate\">{{ title }}</span>\n\n <lw-tooltip\n [text]=\"\n tab.preview && escalatable\n ? title + ' \u2014 ' + ('content.previewHint' | transloco)\n : title\n \"\n position=\"bottom\"\n />\n </button>\n\n @if (tab.pinned) {\n <span\n aria-hidden=\"true\"\n data-testid=\"tab-unpin\"\n (click)=\"onUnpin($event, tab)\"\n class=\"relative mr-1 flex h-6 w-6 cursor-pointer items-center justify-center rounded text-brand opacity-90 transition-colors hover:bg-surface-overlay hover:opacity-100\"\n >\n <lw-icon name=\"pin\" size=\"0.85rem\" />\n <lw-tooltip [text]=\"'content.pinnedHint' | transloco\" position=\"bottom\" />\n </span>\n } @else if (tab.closable) {\n <span\n aria-hidden=\"true\"\n data-testid=\"tab-close\"\n (click)=\"onClose($event, tab)\"\n class=\"lw-icon-btn mr-1 h-6 w-6 cursor-pointer opacity-70 hover:opacity-100\"\n >\n <lw-icon name=\"close\" size=\"0.85rem\" />\n <lw-tooltip [text]=\"'content.closeTab' | transloco\" position=\"bottom\" />\n </span>\n }\n </div>\n }\n }\n </div>\n\n @if (canAddTab()) {\n <button\n type=\"button\"\n (click)=\"addTab.emit($event)\"\n lwMenuState\n class=\"lw-icon-btn w-8\"\n [class.self-stretch]=\"icons()\"\n [attr.aria-label]=\"'content.split.newTab' | transloco\"\n data-testid=\"pane-add-tab\"\n >\n <lw-icon name=\"add\" size=\"1rem\" />\n <lw-tooltip [text]=\"'content.split.newTab' | transloco\" position=\"bottom\" />\n </button>\n }\n\n @if (overflow() && overflowing()) {\n <button\n type=\"button\"\n (click)=\"openOverflow($event)\"\n lwMenuState\n class=\"lw-icon-btn w-8\"\n [class.self-stretch]=\"icons()\"\n [attr.aria-label]=\"'content.moreTabs' | transloco\"\n >\n <lw-icon name=\"chevronDown\" size=\"1rem\" />\n <lw-tooltip [text]=\"'content.moreTabs' | transloco\" position=\"bottom\" />\n </button>\n }\n\n @if (paneActions(); as actions) {\n <ng-container [ngTemplateOutlet]=\"actions\" />\n }\n @if (activeActions().length) {\n <div class=\"flex shrink-0 items-center gap-0.5 border-l border-border px-2\">\n @for (action of activeActions(); track action.id) {\n <button\n type=\"button\"\n (click)=\"runAction.emit(action)\"\n class=\"lw-icon-btn h-8 w-8 rounded-md\"\n [attr.aria-label]=\"action.title | transloco\"\n >\n <lw-icon [name]=\"action.icon\" size=\"1rem\" />\n <lw-tooltip [text]=\"action.title | transloco\" position=\"bottom\" />\n </button>\n }\n </div>\n }\n</div>\n" }]
|
|
7313
7540
|
}], ctorParameters: () => [], propDecorators: { tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: true }] }], activeId: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeId", required: true }] }], reorderable: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderable", required: false }] }], draggable: [{ type: i0.Input, args: [{ isSignal: true, alias: "draggable", required: false }] }], acceptsTabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "acceptsTabs", required: false }] }], source: [{ type: i0.Input, args: [{ isSignal: true, alias: "source", required: true }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], urlDriven: [{ type: i0.Input, args: [{ isSignal: true, alias: "urlDriven", required: false }] }], contextMenuSlot: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextMenuSlot", required: false }] }], viewContextMenuSlot: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewContextMenuSlot", required: false }] }], contextGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextGroup", required: false }] }], overflow: [{ type: i0.Input, args: [{ isSignal: true, alias: "overflow", required: false }] }], canAddTab: [{ type: i0.Input, args: [{ isSignal: true, alias: "canAddTab", required: false }] }], paneActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "paneActions", required: false }] }], selectTab: [{ type: i0.Output, args: ["selectTab"] }], escalate: [{ type: i0.Output, args: ["escalate"] }], closeTab: [{ type: i0.Output, args: ["closeTab"] }], unpinTab: [{ type: i0.Output, args: ["unpinTab"] }], reorderTabs: [{ type: i0.Output, args: ["reorderTabs"] }], runAction: [{ type: i0.Output, args: ["runAction"] }], addTab: [{ type: i0.Output, args: ["addTab"] }], revealRequest: [{ type: i0.Output, args: ["revealRequest"] }], strip: [{ type: i0.ViewChild, args: ['tabStrip', { isSignal: true }] }] } });
|
|
7314
7541
|
|
|
7315
7542
|
class PaneToolbar {
|
|
@@ -8669,6 +8896,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
8669
8896
|
args: [{ selector: '[lwRetainedComponent]' }]
|
|
8670
8897
|
}], ctorParameters: () => [], propDecorators: { lwRetainedComponent: [{ type: i0.Input, args: [{ isSignal: true, alias: "lwRetainedComponent", required: true }] }], componentInjector: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentInjector", required: true }] }], retentionKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "retentionKey", required: true }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], retain: [{ type: i0.Input, args: [{ isSignal: true, alias: "retain", required: false }] }] } });
|
|
8671
8898
|
|
|
8899
|
+
const SURFACE_PADDING = new InjectionToken('lw.surface-padding', {
|
|
8900
|
+
providedIn: 'root',
|
|
8901
|
+
factory: () => 'none',
|
|
8902
|
+
});
|
|
8903
|
+
function effectivePadding(declared, fallback) {
|
|
8904
|
+
return declared === undefined ? fallback === 'inset' : declared;
|
|
8905
|
+
}
|
|
8906
|
+
|
|
8672
8907
|
class ContentSecondaryPane {
|
|
8673
8908
|
path = input.required(/* @ts-ignore */
|
|
8674
8909
|
...(ngDevMode ? [{ debugName: "path" }] : /* istanbul ignore next */ []));
|
|
@@ -8680,6 +8915,7 @@ class ContentSecondaryPane {
|
|
|
8680
8915
|
...(ngDevMode ? [{ debugName: "retentionScope" }] : /* istanbul ignore next */ []));
|
|
8681
8916
|
instanceReleased = output();
|
|
8682
8917
|
registry = inject(ContributionRegistry);
|
|
8918
|
+
padding = inject(SURFACE_PADDING);
|
|
8683
8919
|
viewMount = inject(ViewMountService);
|
|
8684
8920
|
componentLoader = inject(ComponentLoader);
|
|
8685
8921
|
auth = inject(AuthContext);
|
|
@@ -8707,7 +8943,7 @@ class ContentSecondaryPane {
|
|
|
8707
8943
|
...(ngDevMode ? [{ debugName: "declaredRoute" }] : /* istanbul ignore next */ []));
|
|
8708
8944
|
isContainerSurface = computed(() => this.declaredRoute()?.container !== undefined, /* @ts-ignore */
|
|
8709
8945
|
...(ngDevMode ? [{ debugName: "isContainerSurface" }] : /* istanbul ignore next */ []));
|
|
8710
|
-
padded = computed(() => this.declared()?.padded
|
|
8946
|
+
padded = computed(() => effectivePadding(this.declared()?.padded, this.padding), /* @ts-ignore */
|
|
8711
8947
|
...(ngDevMode ? [{ debugName: "padded" }] : /* istanbul ignore next */ []));
|
|
8712
8948
|
hostClass = computed(() => {
|
|
8713
8949
|
if (this.isContainerSurface()) {
|
|
@@ -8868,7 +9104,7 @@ class PaneTargetPicker {
|
|
|
8868
9104
|
present(targets, anchor, onPick) {
|
|
8869
9105
|
const rect = anchor.getBoundingClientRect();
|
|
8870
9106
|
const entries = paneTargetEntries(targets, (key) => this.transloco.translate(key));
|
|
8871
|
-
this.menu.openList(entries, { x: rect.left, y: rect.bottom + MENU_ANCHOR_GAP }, onPick);
|
|
9107
|
+
this.menu.openList(entries, { x: rect.left, y: rect.bottom + MENU_ANCHOR_GAP }, onPick, anchor);
|
|
8872
9108
|
}
|
|
8873
9109
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: PaneTargetPicker, deps: [], target: i0.ɵɵFactoryTarget.Service });
|
|
8874
9110
|
static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.0", ngImport: i0, type: PaneTargetPicker });
|
|
@@ -10075,11 +10311,11 @@ class ShellSidebarHeader {
|
|
|
10075
10311
|
return this.layout.regions.find((r) => r.type === 'panel' && r.dock === dock && r.id !== this.region().id);
|
|
10076
10312
|
}
|
|
10077
10313
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: ShellSidebarHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10078
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: ShellSidebarHeader, isStandalone: true, selector: "lw-shell-sidebar-header", inputs: { region: { classPropertyName: "region", publicName: "region", isSignal: true, isRequired: true, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (showHamburger()) {\n\n <div\n class=\"flex h-12 w-10 shrink-0 items-center justify-center border-b border-border bg-surface\"\n >\n <button\n type=\"button\"\n (click)=\"open()\"\n class=\"lw-icon-btn h-9 w-9 rounded-md\"\n [attr.aria-label]=\"'panel.open' | transloco\"\n >\n <lw-icon name=\"menu\" size=\"1rem\" />\n <lw-tooltip [text]=\"'panel.open' | transloco\" position=\"bottom\" />\n </button>\n </div>\n} @else if (showExpand()) {\n\n <div\n class=\"flex h-12 items-center overflow-hidden border-b border-border bg-surface px-1.5\"\n >\n <button\n type=\"button\"\n (click)=\"expand()\"\n class=\"lw-icon-btn h-7 w-7 rounded-md\"\n [attr.aria-label]=\"'panel.expand' | transloco\"\n >\n <lw-icon [name]=\"expandIcon()\" size=\"1rem\" />\n <lw-tooltip [text]=\"'panel.expand' | transloco\" position=\"bottom\" />\n </button>\n </div>\n} @else if (!collapsed()) {\n\n <lw-pane-tab-strip\n class=\"block h-12\"\n [id]=\"hostId()\"\n variant=\"icons\"\n [tabs]=\"stripTabs()\"\n [activeId]=\"activeTabPath()\"\n [source]=\"source()\"\n [reorderable]=\"viewsReorderable\"\n [draggable]=\"viewsDraggable\"\n [acceptsTabs]=\"acceptsTab\"\n [viewContextMenuSlot]=\"viewContextMenu\"\n [contextGroup]=\"region().id\"\n [overflow]=\"true\"\n [paneActions]=\"trailing\"\n (selectTab)=\"select($event)\"\n (reorderTabs)=\"onReorder($event)\"\n (keydown)=\"onStripKeydown($event)\"\n [
|
|
10314
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: ShellSidebarHeader, isStandalone: true, selector: "lw-shell-sidebar-header", inputs: { region: { classPropertyName: "region", publicName: "region", isSignal: true, isRequired: true, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (showHamburger()) {\n\n <div\n class=\"flex h-12 w-10 shrink-0 items-center justify-center border-b border-border bg-surface\"\n >\n <button\n type=\"button\"\n (click)=\"open()\"\n class=\"lw-icon-btn h-9 w-9 rounded-md\"\n [attr.aria-label]=\"'panel.open' | transloco\"\n >\n <lw-icon name=\"menu\" size=\"1rem\" />\n <lw-tooltip [text]=\"'panel.open' | transloco\" position=\"bottom\" />\n </button>\n </div>\n} @else if (showExpand()) {\n\n <div\n class=\"flex h-12 items-center overflow-hidden border-b border-border bg-surface px-1.5\"\n >\n <button\n type=\"button\"\n (click)=\"expand()\"\n class=\"lw-icon-btn h-7 w-7 rounded-md\"\n [attr.aria-label]=\"'panel.expand' | transloco\"\n >\n <lw-icon [name]=\"expandIcon()\" size=\"1rem\" />\n <lw-tooltip [text]=\"'panel.expand' | transloco\" position=\"bottom\" />\n </button>\n </div>\n} @else if (!collapsed()) {\n\n <lw-pane-tab-strip\n class=\"block h-12\"\n [id]=\"hostId()\"\n variant=\"icons\"\n [tabs]=\"stripTabs()\"\n [activeId]=\"activeTabPath()\"\n [source]=\"source()\"\n [reorderable]=\"viewsReorderable\"\n [draggable]=\"viewsDraggable\"\n [acceptsTabs]=\"acceptsTab\"\n [viewContextMenuSlot]=\"viewContextMenu\"\n [contextGroup]=\"region().id\"\n [overflow]=\"true\"\n [paneActions]=\"trailing\"\n (selectTab)=\"select($event)\"\n (reorderTabs)=\"onReorder($event)\"\n (keydown)=\"onStripKeydown($event)\"\n [lwMenu]=\"stripMenu\"\n />\n <ng-template #trailing>\n @if (canCollapse()) {\n <button\n type=\"button\"\n (click)=\"trailingAction()\"\n class=\"lw-icon-btn h-10 w-10 self-center rounded-md md:h-7 md:w-7\"\n [attr.aria-label]=\"(viewport.compact() ? 'panel.close' : 'panel.collapse') | transloco\"\n >\n <lw-icon [name]=\"viewport.compact() ? 'close' : collapseIcon()\" size=\"1rem\" />\n <lw-tooltip [text]=\"(viewport.compact() ? 'panel.close' : 'panel.collapse') | transloco\" position=\"bottom\" />\n </button>\n }\n </ng-template>\n}\n", dependencies: [{ kind: "component", type: PaneTabStrip, selector: "lw-pane-tab-strip", inputs: ["tabs", "activeId", "reorderable", "draggable", "acceptsTabs", "source", "variant", "urlDriven", "contextMenuSlot", "viewContextMenuSlot", "contextGroup", "overflow", "canAddTab", "paneActions"], outputs: ["selectTab", "escalate", "closeTab", "unpinTab", "reorderTabs", "runAction", "addTab", "revealRequest"] }, { kind: "directive", type: MenuTriggerDirective, selector: "[lwMenu], [lwMenuOnActivate], [lwMenuState]", inputs: ["lwMenu", "lwMenuOnActivate", "lwMenuContext", "lwMenuSide", "lwMenuHeader", "lwMenuState"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
10079
10315
|
}
|
|
10080
10316
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: ShellSidebarHeader, decorators: [{
|
|
10081
10317
|
type: Component,
|
|
10082
|
-
args: [{ selector: 'lw-shell-sidebar-header', imports: [TranslocoPipe, PaneTabStrip,
|
|
10318
|
+
args: [{ selector: 'lw-shell-sidebar-header', imports: [TranslocoPipe, PaneTabStrip, MenuTriggerDirective], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "@if (showHamburger()) {\n\n <div\n class=\"flex h-12 w-10 shrink-0 items-center justify-center border-b border-border bg-surface\"\n >\n <button\n type=\"button\"\n (click)=\"open()\"\n class=\"lw-icon-btn h-9 w-9 rounded-md\"\n [attr.aria-label]=\"'panel.open' | transloco\"\n >\n <lw-icon name=\"menu\" size=\"1rem\" />\n <lw-tooltip [text]=\"'panel.open' | transloco\" position=\"bottom\" />\n </button>\n </div>\n} @else if (showExpand()) {\n\n <div\n class=\"flex h-12 items-center overflow-hidden border-b border-border bg-surface px-1.5\"\n >\n <button\n type=\"button\"\n (click)=\"expand()\"\n class=\"lw-icon-btn h-7 w-7 rounded-md\"\n [attr.aria-label]=\"'panel.expand' | transloco\"\n >\n <lw-icon [name]=\"expandIcon()\" size=\"1rem\" />\n <lw-tooltip [text]=\"'panel.expand' | transloco\" position=\"bottom\" />\n </button>\n </div>\n} @else if (!collapsed()) {\n\n <lw-pane-tab-strip\n class=\"block h-12\"\n [id]=\"hostId()\"\n variant=\"icons\"\n [tabs]=\"stripTabs()\"\n [activeId]=\"activeTabPath()\"\n [source]=\"source()\"\n [reorderable]=\"viewsReorderable\"\n [draggable]=\"viewsDraggable\"\n [acceptsTabs]=\"acceptsTab\"\n [viewContextMenuSlot]=\"viewContextMenu\"\n [contextGroup]=\"region().id\"\n [overflow]=\"true\"\n [paneActions]=\"trailing\"\n (selectTab)=\"select($event)\"\n (reorderTabs)=\"onReorder($event)\"\n (keydown)=\"onStripKeydown($event)\"\n [lwMenu]=\"stripMenu\"\n />\n <ng-template #trailing>\n @if (canCollapse()) {\n <button\n type=\"button\"\n (click)=\"trailingAction()\"\n class=\"lw-icon-btn h-10 w-10 self-center rounded-md md:h-7 md:w-7\"\n [attr.aria-label]=\"(viewport.compact() ? 'panel.close' : 'panel.collapse') | transloco\"\n >\n <lw-icon [name]=\"viewport.compact() ? 'close' : collapseIcon()\" size=\"1rem\" />\n <lw-tooltip [text]=\"(viewport.compact() ? 'panel.close' : 'panel.collapse') | transloco\" position=\"bottom\" />\n </button>\n }\n </ng-template>\n}\n" }]
|
|
10083
10319
|
}], propDecorators: { region: [{ type: i0.Input, args: [{ isSignal: true, alias: "region", required: true }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }] } });
|
|
10084
10320
|
|
|
10085
10321
|
const TAB_CONTEXT_MENU = 'content/tab/context';
|
|
@@ -10232,6 +10468,7 @@ class ContentArea {
|
|
|
10232
10468
|
auth = inject(AuthContext);
|
|
10233
10469
|
features = inject(SHELL_FEATURES).content;
|
|
10234
10470
|
retention = inject(SURFACE_RETENTION);
|
|
10471
|
+
padding = inject(SURFACE_PADDING);
|
|
10235
10472
|
componentLoader = inject(ComponentLoader);
|
|
10236
10473
|
surfaceInjectorFor = surfaceInjectorFactory(inject(Injector), inject(EnvironmentInjector), { urlDriven: true });
|
|
10237
10474
|
urlPaneId = computed(() => this.layout.primaryId(CONTENT_DOCK), /* @ts-ignore */
|
|
@@ -10317,7 +10554,7 @@ class ContentArea {
|
|
|
10317
10554
|
return false;
|
|
10318
10555
|
}
|
|
10319
10556
|
const route = matchRoute(this.registry.contentRoutes(), this.tabs.activeTabRoot());
|
|
10320
|
-
return route?.padded
|
|
10557
|
+
return effectivePadding(route?.padded, this.padding);
|
|
10321
10558
|
}, /* @ts-ignore */
|
|
10322
10559
|
...(ngDevMode ? [{ debugName: "activeIsPadded" }] : /* istanbul ignore next */ []));
|
|
10323
10560
|
canMinimize = computed(() => this.features.minimize && this.isSplit() && !this.maximized(), /* @ts-ignore */
|
|
@@ -11369,7 +11606,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
11369
11606
|
// GENERATED — do not edit by hand.
|
|
11370
11607
|
// Written by tools/stamp-version.mjs from <Version> in Directory.Build.props.
|
|
11371
11608
|
// Single source of truth: Directory.Build.props (bump via scripts/bump-version.sh).
|
|
11372
|
-
const APP_VERSION = '0.7.
|
|
11609
|
+
const APP_VERSION = '0.7.9';
|
|
11373
11610
|
|
|
11374
11611
|
/**
|
|
11375
11612
|
* The running build's version, sourced from `<Version>` in Directory.Build.props
|
|
@@ -13386,6 +13623,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
13386
13623
|
args: [{ selector: 'lw-text-size-toggle', imports: [TranslocoPipe], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<fieldset class=\"lw-segmented\" [attr.aria-label]=\"'textSize.label' | transloco\">\n @for (s of scales; track s) {\n <button\n type=\"button\"\n (click)=\"select(s)\"\n [attr.aria-pressed]=\"scale() === s\"\n [attr.aria-label]=\"'textSize.' + s | transloco\"\n class=\"lw-segmented-item font-semibold\"\n >\n <span [class]=\"glyphClass(s)\" aria-hidden=\"true\">A</span>\n <lw-tooltip [text]=\"'textSize.' + s | transloco\" position=\"bottom\" />\n </button>\n }\n</fieldset>\n" }]
|
|
13387
13624
|
}] });
|
|
13388
13625
|
|
|
13626
|
+
/**
|
|
13627
|
+
* The plugins this distribution declared not optional. Defaults to **none** — every plugin is the
|
|
13628
|
+
* user's to switch off until a distribution says otherwise.
|
|
13629
|
+
*/
|
|
13630
|
+
const REQUIRED_PLUGINS = new InjectionToken('REQUIRED_PLUGINS', { providedIn: 'root', factory: () => [] });
|
|
13631
|
+
/**
|
|
13632
|
+
* A distribution declares which of the plugins it composes its application cannot run without. Such
|
|
13633
|
+
* a plugin is listed in the permissions settings with what it holds, and **without a switch to turn
|
|
13634
|
+
* it off**; it stays active whatever the user chose before.
|
|
13635
|
+
*
|
|
13636
|
+
* This is the distribution's statement and not the plugin's, and deliberately so: everything a plugin
|
|
13637
|
+
* declares about itself is a request the distribution grants, so a manifest field here would be the
|
|
13638
|
+
* one exemption a plugin could award itself.
|
|
13639
|
+
*
|
|
13640
|
+
* It withholds the plugin's own switch and nothing else. The capabilities such a plugin was granted
|
|
13641
|
+
* stay revocable, because needing a plugin says nothing about needing everything it asked for — which
|
|
13642
|
+
* is what distinguishes this from a plugin the operator deployed, where both are withheld.
|
|
13643
|
+
*
|
|
13644
|
+
* Naming a plugin this distribution does not compose — neither one it provides in-process nor an
|
|
13645
|
+
* isolated one it declares — is a composition mistake, not a failure: it is reported in development
|
|
13646
|
+
* and otherwise ignored, the same way a capability granted to a plugin that never declared it is. The
|
|
13647
|
+
* report happens once the composed plugins are registered, which is the only moment that set is
|
|
13648
|
+
* settled: a plugin the store installs arrives later and is the user's to switch off in any case.
|
|
13649
|
+
*
|
|
13650
|
+
* @example
|
|
13651
|
+
* provideRequiredPlugins('sign-in')
|
|
13652
|
+
*/
|
|
13653
|
+
function provideRequiredPlugins(...pluginIds) {
|
|
13654
|
+
return { provide: REQUIRED_PLUGINS, useValue: pluginIds };
|
|
13655
|
+
}
|
|
13656
|
+
|
|
13389
13657
|
const STORAGE_KEY$3 = 'lw.shell.disabled-plugins';
|
|
13390
13658
|
/**
|
|
13391
13659
|
* Whether each plugin is turned on — plugin enable/disable, distinct from capability revocation. Disabling a plugin is coarse: it does not restrict a power, it unloads the
|
|
@@ -13399,15 +13667,27 @@ const STORAGE_KEY$3 = 'lw.shell.disabled-plugins';
|
|
|
13399
13667
|
class PluginEnablementService {
|
|
13400
13668
|
store = inject(SETTINGS_STORE);
|
|
13401
13669
|
sync = inject(StateSyncService);
|
|
13670
|
+
required = new Set(inject(REQUIRED_PLUGINS));
|
|
13402
13671
|
disabledSet = signal(parseIdSet(this.store.peek?.(STORAGE_KEY$3)), /* @ts-ignore */
|
|
13403
13672
|
...(ngDevMode ? [{ debugName: "disabledSet" }] : /* istanbul ignore next */ []));
|
|
13404
13673
|
names = signal(new Map(), /* @ts-ignore */
|
|
13405
13674
|
...(ngDevMode ? [{ debugName: "names" }] : /* istanbul ignore next */ []));
|
|
13406
|
-
/**
|
|
13407
|
-
|
|
13675
|
+
/**
|
|
13676
|
+
* The disabled plugin ids (reactive) — a runtime reconciles activation against this. A plugin the
|
|
13677
|
+
* distribution declared its application cannot run without never appears here, whatever is stored,
|
|
13678
|
+
* so the runtime and the permissions surface read one answer rather than two.
|
|
13679
|
+
*/
|
|
13680
|
+
disabled = computed(() => {
|
|
13681
|
+
const stored = this.disabledSet();
|
|
13682
|
+
if (this.required.size === 0) {
|
|
13683
|
+
return stored;
|
|
13684
|
+
}
|
|
13685
|
+
return new Set([...stored].filter((id) => !this.required.has(id)));
|
|
13686
|
+
}, /* @ts-ignore */
|
|
13687
|
+
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
13408
13688
|
/** Every known plugin with its enabled state, for the permissions settings surface. */
|
|
13409
13689
|
plugins = computed(() => {
|
|
13410
|
-
const disabled = this.
|
|
13690
|
+
const disabled = this.disabled();
|
|
13411
13691
|
return [...this.names().entries()]
|
|
13412
13692
|
.map(([id, name]) => ({ id, name, enabled: !disabled.has(id) }))
|
|
13413
13693
|
.toSorted((a, b) => a.name.localeCompare(b.name));
|
|
@@ -13417,6 +13697,10 @@ class PluginEnablementService {
|
|
|
13417
13697
|
hydrateAsync(this.store, STORAGE_KEY$3, (raw) => this.disabledSet.set(parseIdSet(raw)));
|
|
13418
13698
|
this.sync.register('settings', STORAGE_KEY$3, (raw) => this.disabledSet.set(parseIdSet(raw)));
|
|
13419
13699
|
}
|
|
13700
|
+
/** Whether the distribution declared it cannot run without this plugin. */
|
|
13701
|
+
isRequired(id) {
|
|
13702
|
+
return this.required.has(id);
|
|
13703
|
+
}
|
|
13420
13704
|
/** Records a plugin so the permissions surface can list it (enabled or not). Idempotent. A runtime calls it for every plugin it knows. */
|
|
13421
13705
|
register(id, name) {
|
|
13422
13706
|
this.names.update((map) => map.has(id) ? map : new Map(map).set(id, name));
|
|
@@ -13434,10 +13718,17 @@ class PluginEnablementService {
|
|
|
13434
13718
|
}
|
|
13435
13719
|
/** Whether `id` is currently enabled (default: yes — a plugin is on until the user turns it off). */
|
|
13436
13720
|
isEnabled(id) {
|
|
13437
|
-
return !this.
|
|
13721
|
+
return !this.disabled().has(id);
|
|
13438
13722
|
}
|
|
13439
|
-
/**
|
|
13723
|
+
/**
|
|
13724
|
+
* Turns a whole plugin on or off (persisted). The runtimes react by loading/unloading it. Turning
|
|
13725
|
+
* off a plugin the distribution declared it cannot run without does nothing: the surface offers no
|
|
13726
|
+
* switch for one, and this is the same answer read from anywhere else.
|
|
13727
|
+
*/
|
|
13440
13728
|
setEnabled(id, enabled) {
|
|
13729
|
+
if (!enabled && this.required.has(id)) {
|
|
13730
|
+
return;
|
|
13731
|
+
}
|
|
13441
13732
|
const next = toggledIdSet(this.disabledSet(), id, !enabled);
|
|
13442
13733
|
this.disabledSet.set(next);
|
|
13443
13734
|
void this.store.set(STORAGE_KEY$3, JSON.stringify([...next]));
|
|
@@ -13651,10 +13942,12 @@ class PermissionsSettings {
|
|
|
13651
13942
|
const caps = this.grants.permissions();
|
|
13652
13943
|
return this.enablement.plugins().map((plugin) => {
|
|
13653
13944
|
const provided = this.deployment.isDeployed(plugin.id);
|
|
13945
|
+
const required = this.enablement.isRequired(plugin.id);
|
|
13654
13946
|
return {
|
|
13655
13947
|
...plugin,
|
|
13656
13948
|
enabled: provided || plugin.enabled,
|
|
13657
13949
|
provided,
|
|
13950
|
+
required,
|
|
13658
13951
|
rungNote: rungNoteKey(this.isolation.rungOf(plugin.id)),
|
|
13659
13952
|
capabilities: caps.find((entry) => entry.pluginId === plugin.id)?.capabilities ??
|
|
13660
13953
|
[],
|
|
@@ -13669,11 +13962,11 @@ class PermissionsSettings {
|
|
|
13669
13962
|
this.grants.setGranted(pluginId, capability, event.target.checked);
|
|
13670
13963
|
}
|
|
13671
13964
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: PermissionsSettings, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
13672
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: PermissionsSettings, isStandalone: true, selector: "lw-permissions-settings", ngImport: i0, template: "<p class=\"mb-4 text-sm text-content-muted\">\n {{ 'settings.permissionsDesc' | transloco }}\n</p>\n@if (plugins().length === 0) {\n <p class=\"text-sm text-content-muted\">\n {{ 'settings.permissionsEmpty' | transloco }}\n </p>\n} @else {\n <div class=\"flex flex-col gap-6\">\n @for (plugin of plugins(); track plugin.id) {\n <section class=\"flex flex-col gap-3\">\n <div class=\"flex items-center justify-between gap-4\">\n <h3 class=\"text-sm font-semibold text-content\">\n {{ plugin.name }}\n </h3>\n @if (!plugin.provided) {\n <input\n type=\"checkbox\"\n role=\"switch\"\n class=\"lw-switch shrink-0\"\n [checked]=\"plugin.enabled\"\n [attr.aria-checked]=\"plugin.enabled\"\n [attr.aria-label]=\"'settings.pluginEnabled' | transloco\"\n [attr.data-testid]=\"'plugin-enabled-' + plugin.id\"\n (change)=\"togglePlugin(plugin.id, $event)\"\n />\n }\n </div>\n @if (plugin.rungNote; as rungNote) {\n <p\n class=\"text-xs text-content-muted\"\n [attr.data-testid]=\"'perm-level-' + plugin.id\"\n >\n {{ rungNote | transloco }}\n </p>\n }\n @if (plugin.provided) {\n <p\n class=\"text-xs text-content-muted\"\n [attr.data-testid]=\"'perm-provided-' + plugin.id\"\n >\n {{ 'settings.permissionsProvided' | transloco }}\n </p>\n }\n @if (plugin.enabled) {\n <ul class=\"flex flex-col gap-3\">\n @for (cap of plugin.capabilities; track cap.capability) {\n <li class=\"flex items-start justify-between gap-4\">\n <div class=\"flex flex-col\">\n <span class=\"text-sm text-content\">{{\n 'settings.capability.' + cap.capability | transloco\n }}</span>\n <span class=\"text-xs text-content-muted\">{{\n 'settings.capabilityDesc.' + cap.capability | transloco\n }}</span>\n </div>\n @if (!plugin.provided) {\n <input\n type=\"checkbox\"\n role=\"switch\"\n class=\"lw-switch shrink-0\"\n [checked]=\"cap.effective\"\n [attr.aria-checked]=\"cap.effective\"\n [attr.aria-label]=\"\n 'settings.capability.' + cap.capability | transloco\n \"\n [attr.data-testid]=\"\n 'perm-' + plugin.id + '-' + cap.capability\n \"\n (change)=\"\n toggleCapability(plugin.id, cap.capability, $event)\n \"\n />\n }\n </li>\n }\n </ul>\n } @else {\n <p class=\"text-xs text-content-muted\">\n {{ 'settings.pluginDisabled' | transloco }}\n </p>\n }\n </section>\n }\n </div>\n}\n", dependencies: [{ kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
13965
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: PermissionsSettings, isStandalone: true, selector: "lw-permissions-settings", ngImport: i0, template: "<p class=\"mb-4 text-sm text-content-muted\">\n {{ 'settings.permissionsDesc' | transloco }}\n</p>\n@if (plugins().length === 0) {\n <p class=\"text-sm text-content-muted\">\n {{ 'settings.permissionsEmpty' | transloco }}\n </p>\n} @else {\n <div class=\"flex flex-col gap-6\">\n @for (plugin of plugins(); track plugin.id) {\n <section class=\"flex flex-col gap-3\">\n <div class=\"flex items-center justify-between gap-4\">\n <h3 class=\"text-sm font-semibold text-content\">\n {{ plugin.name }}\n </h3>\n @if (!plugin.provided && !plugin.required) {\n <input\n type=\"checkbox\"\n role=\"switch\"\n class=\"lw-switch shrink-0\"\n [checked]=\"plugin.enabled\"\n [attr.aria-checked]=\"plugin.enabled\"\n [attr.aria-label]=\"'settings.pluginEnabled' | transloco\"\n [attr.data-testid]=\"'plugin-enabled-' + plugin.id\"\n (change)=\"togglePlugin(plugin.id, $event)\"\n />\n }\n </div>\n @if (plugin.rungNote; as rungNote) {\n <p\n class=\"text-xs text-content-muted\"\n [attr.data-testid]=\"'perm-level-' + plugin.id\"\n >\n {{ rungNote | transloco }}\n </p>\n }\n @if (plugin.provided) {\n <p\n class=\"text-xs text-content-muted\"\n [attr.data-testid]=\"'perm-provided-' + plugin.id\"\n >\n {{ 'settings.permissionsProvided' | transloco }}\n </p>\n } @else if (plugin.required) {\n <p\n class=\"text-xs text-content-muted\"\n [attr.data-testid]=\"'perm-required-' + plugin.id\"\n >\n {{ 'settings.permissionsRequired' | transloco }}\n </p>\n }\n @if (plugin.enabled) {\n <ul class=\"flex flex-col gap-3\">\n @for (cap of plugin.capabilities; track cap.capability) {\n <li class=\"flex items-start justify-between gap-4\">\n <div class=\"flex flex-col\">\n <span class=\"text-sm text-content\">{{\n 'settings.capability.' + cap.capability | transloco\n }}</span>\n <span class=\"text-xs text-content-muted\">{{\n 'settings.capabilityDesc.' + cap.capability | transloco\n }}</span>\n </div>\n @if (!plugin.provided) {\n <input\n type=\"checkbox\"\n role=\"switch\"\n class=\"lw-switch shrink-0\"\n [checked]=\"cap.effective\"\n [attr.aria-checked]=\"cap.effective\"\n [attr.aria-label]=\"\n 'settings.capability.' + cap.capability | transloco\n \"\n [attr.data-testid]=\"\n 'perm-' + plugin.id + '-' + cap.capability\n \"\n (change)=\"\n toggleCapability(plugin.id, cap.capability, $event)\n \"\n />\n }\n </li>\n }\n </ul>\n } @else {\n <p class=\"text-xs text-content-muted\">\n {{ 'settings.pluginDisabled' | transloco }}\n </p>\n }\n </section>\n }\n </div>\n}\n", dependencies: [{ kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
13673
13966
|
}
|
|
13674
13967
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: PermissionsSettings, decorators: [{
|
|
13675
13968
|
type: Component,
|
|
13676
|
-
args: [{ selector: 'lw-permissions-settings', imports: [TranslocoPipe], template: "<p class=\"mb-4 text-sm text-content-muted\">\n {{ 'settings.permissionsDesc' | transloco }}\n</p>\n@if (plugins().length === 0) {\n <p class=\"text-sm text-content-muted\">\n {{ 'settings.permissionsEmpty' | transloco }}\n </p>\n} @else {\n <div class=\"flex flex-col gap-6\">\n @for (plugin of plugins(); track plugin.id) {\n <section class=\"flex flex-col gap-3\">\n <div class=\"flex items-center justify-between gap-4\">\n <h3 class=\"text-sm font-semibold text-content\">\n {{ plugin.name }}\n </h3>\n @if (!plugin.provided) {\n <input\n type=\"checkbox\"\n role=\"switch\"\n class=\"lw-switch shrink-0\"\n [checked]=\"plugin.enabled\"\n [attr.aria-checked]=\"plugin.enabled\"\n [attr.aria-label]=\"'settings.pluginEnabled' | transloco\"\n [attr.data-testid]=\"'plugin-enabled-' + plugin.id\"\n (change)=\"togglePlugin(plugin.id, $event)\"\n />\n }\n </div>\n @if (plugin.rungNote; as rungNote) {\n <p\n class=\"text-xs text-content-muted\"\n [attr.data-testid]=\"'perm-level-' + plugin.id\"\n >\n {{ rungNote | transloco }}\n </p>\n }\n @if (plugin.provided) {\n <p\n class=\"text-xs text-content-muted\"\n [attr.data-testid]=\"'perm-provided-' + plugin.id\"\n >\n {{ 'settings.permissionsProvided' | transloco }}\n </p>\n }\n @if (plugin.enabled) {\n <ul class=\"flex flex-col gap-3\">\n @for (cap of plugin.capabilities; track cap.capability) {\n <li class=\"flex items-start justify-between gap-4\">\n <div class=\"flex flex-col\">\n <span class=\"text-sm text-content\">{{\n 'settings.capability.' + cap.capability | transloco\n }}</span>\n <span class=\"text-xs text-content-muted\">{{\n 'settings.capabilityDesc.' + cap.capability | transloco\n }}</span>\n </div>\n @if (!plugin.provided) {\n <input\n type=\"checkbox\"\n role=\"switch\"\n class=\"lw-switch shrink-0\"\n [checked]=\"cap.effective\"\n [attr.aria-checked]=\"cap.effective\"\n [attr.aria-label]=\"\n 'settings.capability.' + cap.capability | transloco\n \"\n [attr.data-testid]=\"\n 'perm-' + plugin.id + '-' + cap.capability\n \"\n (change)=\"\n toggleCapability(plugin.id, cap.capability, $event)\n \"\n />\n }\n </li>\n }\n </ul>\n } @else {\n <p class=\"text-xs text-content-muted\">\n {{ 'settings.pluginDisabled' | transloco }}\n </p>\n }\n </section>\n }\n </div>\n}\n" }]
|
|
13969
|
+
args: [{ selector: 'lw-permissions-settings', imports: [TranslocoPipe], template: "<p class=\"mb-4 text-sm text-content-muted\">\n {{ 'settings.permissionsDesc' | transloco }}\n</p>\n@if (plugins().length === 0) {\n <p class=\"text-sm text-content-muted\">\n {{ 'settings.permissionsEmpty' | transloco }}\n </p>\n} @else {\n <div class=\"flex flex-col gap-6\">\n @for (plugin of plugins(); track plugin.id) {\n <section class=\"flex flex-col gap-3\">\n <div class=\"flex items-center justify-between gap-4\">\n <h3 class=\"text-sm font-semibold text-content\">\n {{ plugin.name }}\n </h3>\n @if (!plugin.provided && !plugin.required) {\n <input\n type=\"checkbox\"\n role=\"switch\"\n class=\"lw-switch shrink-0\"\n [checked]=\"plugin.enabled\"\n [attr.aria-checked]=\"plugin.enabled\"\n [attr.aria-label]=\"'settings.pluginEnabled' | transloco\"\n [attr.data-testid]=\"'plugin-enabled-' + plugin.id\"\n (change)=\"togglePlugin(plugin.id, $event)\"\n />\n }\n </div>\n @if (plugin.rungNote; as rungNote) {\n <p\n class=\"text-xs text-content-muted\"\n [attr.data-testid]=\"'perm-level-' + plugin.id\"\n >\n {{ rungNote | transloco }}\n </p>\n }\n @if (plugin.provided) {\n <p\n class=\"text-xs text-content-muted\"\n [attr.data-testid]=\"'perm-provided-' + plugin.id\"\n >\n {{ 'settings.permissionsProvided' | transloco }}\n </p>\n } @else if (plugin.required) {\n <p\n class=\"text-xs text-content-muted\"\n [attr.data-testid]=\"'perm-required-' + plugin.id\"\n >\n {{ 'settings.permissionsRequired' | transloco }}\n </p>\n }\n @if (plugin.enabled) {\n <ul class=\"flex flex-col gap-3\">\n @for (cap of plugin.capabilities; track cap.capability) {\n <li class=\"flex items-start justify-between gap-4\">\n <div class=\"flex flex-col\">\n <span class=\"text-sm text-content\">{{\n 'settings.capability.' + cap.capability | transloco\n }}</span>\n <span class=\"text-xs text-content-muted\">{{\n 'settings.capabilityDesc.' + cap.capability | transloco\n }}</span>\n </div>\n @if (!plugin.provided) {\n <input\n type=\"checkbox\"\n role=\"switch\"\n class=\"lw-switch shrink-0\"\n [checked]=\"cap.effective\"\n [attr.aria-checked]=\"cap.effective\"\n [attr.aria-label]=\"\n 'settings.capability.' + cap.capability | transloco\n \"\n [attr.data-testid]=\"\n 'perm-' + plugin.id + '-' + cap.capability\n \"\n (change)=\"\n toggleCapability(plugin.id, cap.capability, $event)\n \"\n />\n }\n </li>\n }\n </ul>\n } @else {\n <p class=\"text-xs text-content-muted\">\n {{ 'settings.pluginDisabled' | transloco }}\n </p>\n }\n </section>\n }\n </div>\n}\n" }]
|
|
13677
13970
|
}] });
|
|
13678
13971
|
|
|
13679
13972
|
function registerDefaultSettings(settings) {
|
|
@@ -14491,6 +14784,9 @@ function provideShell(options = {}) {
|
|
|
14491
14784
|
...(options.retention === undefined
|
|
14492
14785
|
? []
|
|
14493
14786
|
: [{ provide: SURFACE_RETENTION, useValue: options.retention }]),
|
|
14787
|
+
...(options.padding === undefined
|
|
14788
|
+
? []
|
|
14789
|
+
: [{ provide: SURFACE_PADDING, useValue: options.padding }]),
|
|
14494
14790
|
...(options.serviceWorker === false
|
|
14495
14791
|
? []
|
|
14496
14792
|
: [
|
|
@@ -14955,6 +15251,7 @@ class ContentRouter {
|
|
|
14955
15251
|
lastRoutes = [];
|
|
14956
15252
|
lastOmitted = [];
|
|
14957
15253
|
pendingDeepLink = null;
|
|
15254
|
+
parkedOnPlaceholder = false;
|
|
14958
15255
|
userNavigated = false;
|
|
14959
15256
|
start() {
|
|
14960
15257
|
if (this.started) {
|
|
@@ -14978,9 +15275,10 @@ class ContentRouter {
|
|
|
14978
15275
|
}
|
|
14979
15276
|
this.lastRoutes = routes;
|
|
14980
15277
|
this.lastOmitted = omitted;
|
|
15278
|
+
const wasParked = this.parkedOnPlaceholder;
|
|
14981
15279
|
this.applyConfig(routes, omitted);
|
|
14982
15280
|
this.reuse.pruneExcept((key) => matchRoute(routes, key) !== undefined);
|
|
14983
|
-
this.retryDeepLink();
|
|
15281
|
+
this.retryDeepLink(wasParked);
|
|
14984
15282
|
}, { injector: this.injector });
|
|
14985
15283
|
let firstAuthRun = true;
|
|
14986
15284
|
effect(() => {
|
|
@@ -15001,18 +15299,40 @@ class ContentRouter {
|
|
|
15001
15299
|
}, { injector: this.injector });
|
|
15002
15300
|
}
|
|
15003
15301
|
applyConfig(routes, omitted) {
|
|
15302
|
+
const pending = this.pendingPlaceholder(routes);
|
|
15303
|
+
this.parkedOnPlaceholder = pending.length > 0;
|
|
15004
15304
|
this.router.resetConfig([
|
|
15005
15305
|
{ path: `${POPOUT_PREFIX}/**`, component: PopoutView },
|
|
15006
15306
|
...buildContentRoutes(routes, omitted, this.retention),
|
|
15307
|
+
...pending,
|
|
15007
15308
|
]);
|
|
15008
15309
|
}
|
|
15009
|
-
|
|
15310
|
+
pendingPlaceholder(routes) {
|
|
15311
|
+
const target = this.pendingDeepLink;
|
|
15312
|
+
if (target === null) {
|
|
15313
|
+
return [];
|
|
15314
|
+
}
|
|
15315
|
+
const path = normalizePath(target);
|
|
15316
|
+
const matched = matchRoute(routes, path);
|
|
15317
|
+
if (path === '' || segmentsOf(matched?.path ?? '').length > 0) {
|
|
15318
|
+
return [];
|
|
15319
|
+
}
|
|
15320
|
+
return [
|
|
15321
|
+
{
|
|
15322
|
+
path,
|
|
15323
|
+
component: RouteUnavailableView,
|
|
15324
|
+
canActivate: [keepPopout],
|
|
15325
|
+
data: { content: true, routePlaceholder: true },
|
|
15326
|
+
},
|
|
15327
|
+
];
|
|
15328
|
+
}
|
|
15329
|
+
retryDeepLink(wasParked) {
|
|
15010
15330
|
const target = this.pendingDeepLink;
|
|
15011
15331
|
if (!target) {
|
|
15012
15332
|
return;
|
|
15013
15333
|
}
|
|
15014
15334
|
const here = normalizePath(this.router.url);
|
|
15015
|
-
if (here === normalizePath(target) || this.userNavigated) {
|
|
15335
|
+
if ((here === normalizePath(target) && !wasParked) || this.userNavigated) {
|
|
15016
15336
|
this.pendingDeepLink = null;
|
|
15017
15337
|
return;
|
|
15018
15338
|
}
|
|
@@ -15021,7 +15341,7 @@ class ContentRouter {
|
|
|
15021
15341
|
return;
|
|
15022
15342
|
}
|
|
15023
15343
|
void this.router
|
|
15024
|
-
.navigateByUrl(target)
|
|
15344
|
+
.navigateByUrl(target, { onSameUrlNavigation: 'reload' })
|
|
15025
15345
|
.then((ok) => {
|
|
15026
15346
|
if (ok) {
|
|
15027
15347
|
this.pendingDeepLink = null;
|
|
@@ -15759,6 +16079,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
15759
16079
|
type: Service
|
|
15760
16080
|
}] });
|
|
15761
16081
|
|
|
16082
|
+
/** Multi-provider token: each contribution adds one sandboxed plugin to load. */
|
|
16083
|
+
const FRAME_PLUGIN = new InjectionToken('FRAME_PLUGIN');
|
|
16084
|
+
|
|
15762
16085
|
/** Multi-provider token: each contribution adds one plugin to load. */
|
|
15763
16086
|
const PLUGIN = new InjectionToken('PLUGIN');
|
|
15764
16087
|
/**
|
|
@@ -15769,6 +16092,8 @@ const PLUGIN = new InjectionToken('PLUGIN');
|
|
|
15769
16092
|
class PluginRuntime {
|
|
15770
16093
|
grants = inject(CapabilityGrantService);
|
|
15771
16094
|
enablement = inject(PluginEnablementService);
|
|
16095
|
+
required = inject(REQUIRED_PLUGINS);
|
|
16096
|
+
framePlugins = inject(FRAME_PLUGIN, { optional: true }) ?? [];
|
|
15772
16097
|
factory = inject(HostContextFactory);
|
|
15773
16098
|
injector = inject(EnvironmentInjector);
|
|
15774
16099
|
plugins = inject(PLUGIN, { optional: true }) ?? [];
|
|
@@ -15782,6 +16107,7 @@ class PluginRuntime {
|
|
|
15782
16107
|
for (const plugin of this.plugins) {
|
|
15783
16108
|
this.enablement.register(plugin.manifest.id, plugin.manifest.name ?? plugin.manifest.id);
|
|
15784
16109
|
}
|
|
16110
|
+
this.reportUncomposedRequirements();
|
|
15785
16111
|
this.reconcile(this.enablement.disabled());
|
|
15786
16112
|
effect(() => {
|
|
15787
16113
|
const disabled = this.enablement.disabled();
|
|
@@ -15848,6 +16174,19 @@ class PluginRuntime {
|
|
|
15848
16174
|
this.active.delete(id);
|
|
15849
16175
|
console.error(`Plugin "${id}" activation failed`, error);
|
|
15850
16176
|
}
|
|
16177
|
+
reportUncomposedRequirements() {
|
|
16178
|
+
if (!isDevMode()) {
|
|
16179
|
+
return;
|
|
16180
|
+
}
|
|
16181
|
+
const composed = new Set([
|
|
16182
|
+
...this.plugins.map((plugin) => plugin.manifest.id),
|
|
16183
|
+
...this.framePlugins.map((plugin) => plugin.id),
|
|
16184
|
+
]);
|
|
16185
|
+
const missing = this.required.filter((id) => !composed.has(id));
|
|
16186
|
+
if (missing.length > 0) {
|
|
16187
|
+
console.warn(`provideRequiredPlugins names ${missing.join(', ')}, which this distribution does not compose — ignored.`);
|
|
16188
|
+
}
|
|
16189
|
+
}
|
|
15851
16190
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: PluginRuntime, deps: [], target: i0.ɵɵFactoryTarget.Service });
|
|
15852
16191
|
static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.0", ngImport: i0, type: PluginRuntime });
|
|
15853
16192
|
}
|
|
@@ -15866,9 +16205,6 @@ function providePlugins(...plugins) {
|
|
|
15866
16205
|
];
|
|
15867
16206
|
}
|
|
15868
16207
|
|
|
15869
|
-
/** Multi-provider token: each contribution adds one sandboxed plugin to load. */
|
|
15870
|
-
const FRAME_PLUGIN = new InjectionToken('FRAME_PLUGIN');
|
|
15871
|
-
|
|
15872
16208
|
const STORAGE_KEY = 'lw.shell.installed-plugins';
|
|
15873
16209
|
/**
|
|
15874
16210
|
* The user's installed community plugins. Holds only the state: which catalog entries the
|
|
@@ -16036,7 +16372,7 @@ function sanitizeRpcSurface(pluginId, surface, permitted) {
|
|
|
16036
16372
|
: undefined,
|
|
16037
16373
|
saveOn: raw['saveOn'] === 'hide' ? 'hide' : undefined,
|
|
16038
16374
|
closable: raw['closable'] === false ? false : undefined,
|
|
16039
|
-
padded: raw['padded'] ===
|
|
16375
|
+
padded: typeof raw['padded'] === 'boolean' ? raw['padded'] : undefined,
|
|
16040
16376
|
routable,
|
|
16041
16377
|
docks,
|
|
16042
16378
|
};
|
|
@@ -17272,5 +17608,5 @@ function provideIcons(icons) {
|
|
|
17272
17608
|
* Generated bundle index. Do not edit.
|
|
17273
17609
|
*/
|
|
17274
17610
|
|
|
17275
|
-
export { AUTH_SOURCE, AuthContext, BAR_ITEM, CAPABILITY_GRANTS, COMMAND_INVOKER, CapabilityGrantService, CommandInvocationService, CommandService, ContentTabsService, ContributionRegistry, DEFAULT_LAYOUT, DEFAULT_SHELL_FEATURES, DEVICE_LEVEL_KEYS, DialogOutlet, DialogService, FRAME_PLUGIN, FramePluginRuntime, KeybindingService, LW_BUTTON_TAG, LW_ICON_TAG, LW_MARKDOWN_TAG, LW_TOOLTIP_TAG, LocalStorageStore, LwButton, LwButtonElement, LwIconElement, LwMarkdownElement, LwSettingRow, LwSpinner, LwTooltipElement, LwVersion, NotificationService, PLUGIN, PLUGIN_CATALOG, PluginEnablementService, PluginInstallService, PluginRuntime, PopoutService, RAIL_ITEM, SETTINGS_STORE, SHELL_FEATURES, SHELL_LAYOUT, SettingsService, Shell, StateSyncService, TRANSLATION_NAMESPACES, TRANSLATION_OVERRIDES, ThemeService, ToastOutlet, UpdateBadge, UpdateService, VIEW, VersionService, WORKING_STATE_STORE, WORKSPACE_DEFINITIONS, defineLwButton, defineLwIcon, defineLwMarkdown, defineLwTooltip, effectiveCapabilities, formatChord, provideAuthSource, provideBarItems, provideCapabilityGrants, provideCommandPaletteEntry, provideFramePlugins, provideIcons, provideIdentityScopedStores, provideLayout, providePluginCatalog, providePlugins, provideQuickOpenEntry, provideRailItems, provideSettingsStore, provideShell, provideShellFeatures, provideShellRouter, provideTabAddressResolver, provideTranslationNamespaces, provideTranslationOverrides, provideUnauthorizedRedirect, provideViews, provideWorkingStateStore, provideWorkspaces, urlPluginCatalog };
|
|
17611
|
+
export { AUTH_SOURCE, AuthContext, BAR_ITEM, CAPABILITY_GRANTS, COMMAND_INVOKER, CapabilityGrantService, CommandInvocationService, CommandService, ContentTabsService, ContributionRegistry, DEFAULT_LAYOUT, DEFAULT_SHELL_FEATURES, DEVICE_LEVEL_KEYS, DialogOutlet, DialogService, FRAME_PLUGIN, FramePluginRuntime, KeybindingService, LW_BUTTON_TAG, LW_ICON_TAG, LW_MARKDOWN_TAG, LW_TOOLTIP_TAG, LocalStorageStore, LwButton, LwButtonElement, LwIconElement, LwMarkdownElement, LwSettingRow, LwSpinner, LwTooltipElement, LwVersion, NotificationService, PLUGIN, PLUGIN_CATALOG, PluginEnablementService, PluginInstallService, PluginRuntime, PopoutService, RAIL_ITEM, REQUIRED_PLUGINS, SETTINGS_STORE, SHELL_FEATURES, SHELL_LAYOUT, SettingsService, Shell, StateSyncService, TRANSLATION_NAMESPACES, TRANSLATION_OVERRIDES, ThemeService, ToastOutlet, UpdateBadge, UpdateService, VIEW, VersionService, WORKING_STATE_STORE, WORKSPACE_DEFINITIONS, defineLwButton, defineLwIcon, defineLwMarkdown, defineLwTooltip, effectiveCapabilities, formatChord, provideAuthSource, provideBarItems, provideCapabilityGrants, provideCommandPaletteEntry, provideFramePlugins, provideIcons, provideIdentityScopedStores, provideLayout, providePluginCatalog, providePlugins, provideQuickOpenEntry, provideRailItems, provideRequiredPlugins, provideSettingsStore, provideShell, provideShellFeatures, provideShellRouter, provideTabAddressResolver, provideTranslationNamespaces, provideTranslationOverrides, provideUnauthorizedRedirect, provideViews, provideWorkingStateStore, provideWorkspaces, urlPluginCatalog };
|
|
17276
17612
|
//# sourceMappingURL=loomweaver-shell.mjs.map
|