@design.estate/dees-catalog 3.43.4 → 3.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_bundle/bundle.js +206 -53
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/00group-appui/dees-appui/dees-appui.d.ts +10 -0
- package/dist_ts_web/elements/00group-appui/dees-appui/dees-appui.js +32 -2
- package/dist_ts_web/elements/00group-appui/dees-appui-maincontent/dees-appui-maincontent.d.ts +2 -0
- package/dist_ts_web/elements/00group-appui/dees-appui-maincontent/dees-appui-maincontent.js +20 -2
- package/dist_ts_web/elements/00group-appui/dees-appui-tabs/dees-appui-tabs.d.ts +7 -0
- package/dist_ts_web/elements/00group-appui/dees-appui-tabs/dees-appui-tabs.demo.js +33 -25
- package/dist_ts_web/elements/00group-appui/dees-appui-tabs/dees-appui-tabs.js +146 -16
- package/dist_ts_web/elements/interfaces/appconfig.d.ts +3 -1
- package/dist_ts_web/elements/interfaces/tab.d.ts +7 -0
- package/dist_watch/bundle.js +204 -51
- package/dist_watch/bundle.js.map +3 -3
- package/package.json +1 -1
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/00group-appui/dees-appui/dees-appui.ts +22 -0
- package/ts_web/elements/00group-appui/dees-appui-maincontent/dees-appui-maincontent.ts +8 -0
- package/ts_web/elements/00group-appui/dees-appui-tabs/dees-appui-tabs.demo.ts +36 -24
- package/ts_web/elements/00group-appui/dees-appui-tabs/dees-appui-tabs.ts +135 -15
- package/ts_web/elements/interfaces/appconfig.ts +3 -1
- package/ts_web/elements/interfaces/tab.ts +8 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@design.estate/dees-catalog",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.44.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.",
|
|
6
6
|
"main": "dist_ts_web/index.js",
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@design.estate/dees-catalog',
|
|
6
|
-
version: '3.
|
|
6
|
+
version: '3.44.0',
|
|
7
7
|
description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
|
|
8
8
|
}
|
|
@@ -143,6 +143,12 @@ export class DeesAppui extends DeesElement {
|
|
|
143
143
|
@property({ type: Object })
|
|
144
144
|
accessor maincontentSelectedTab: interfaces.IMenuItem | undefined = undefined;
|
|
145
145
|
|
|
146
|
+
@property({ type: Array })
|
|
147
|
+
accessor contentTabActionsLeft: interfaces.ITabAction[] = [];
|
|
148
|
+
|
|
149
|
+
@property({ type: Array })
|
|
150
|
+
accessor contentTabActionsRight: interfaces.ITabAction[] = [];
|
|
151
|
+
|
|
146
152
|
// References to child components
|
|
147
153
|
@state()
|
|
148
154
|
accessor appbar: DeesAppuiBar | undefined = undefined;
|
|
@@ -306,6 +312,8 @@ export class DeesAppui extends DeesElement {
|
|
|
306
312
|
.showTabs=${this.maincontentTabsVisible}
|
|
307
313
|
.tabsAutoHide=${this.contentTabsAutoHide}
|
|
308
314
|
.tabsAutoHideThreshold=${this.contentTabsAutoHideThreshold}
|
|
315
|
+
.tabActionsLeft=${this.contentTabActionsLeft}
|
|
316
|
+
.tabActionsRight=${this.contentTabActionsRight}
|
|
309
317
|
@tab-select=${(e: CustomEvent) => this.handleContentTabSelect(e)}
|
|
310
318
|
@tab-close=${(e: CustomEvent) => this.handleContentTabClose(e)}
|
|
311
319
|
>
|
|
@@ -699,6 +707,20 @@ export class DeesAppui extends DeesElement {
|
|
|
699
707
|
return this.maincontentSelectedTab;
|
|
700
708
|
}
|
|
701
709
|
|
|
710
|
+
/**
|
|
711
|
+
* Set content tab action buttons on the left side
|
|
712
|
+
*/
|
|
713
|
+
public setContentTabActionsLeft(actions: interfaces.ITabAction[]): void {
|
|
714
|
+
this.contentTabActionsLeft = [...actions];
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* Set content tab action buttons on the right side
|
|
719
|
+
*/
|
|
720
|
+
public setContentTabActionsRight(actions: interfaces.ITabAction[]): void {
|
|
721
|
+
this.contentTabActionsRight = [...actions];
|
|
722
|
+
}
|
|
723
|
+
|
|
702
724
|
// ==========================================
|
|
703
725
|
// PROGRAMMATIC API: ACTIVITY LOG
|
|
704
726
|
// ==========================================
|
|
@@ -53,6 +53,12 @@ export class DeesAppuiMaincontent extends DeesElement {
|
|
|
53
53
|
@property({ type: Number })
|
|
54
54
|
accessor tabsAutoHideThreshold: number = 0;
|
|
55
55
|
|
|
56
|
+
@property({ type: Array })
|
|
57
|
+
accessor tabActionsLeft: interfaces.ITabAction[] = [];
|
|
58
|
+
|
|
59
|
+
@property({ type: Array })
|
|
60
|
+
accessor tabActionsRight: interfaces.ITabAction[] = [];
|
|
61
|
+
|
|
56
62
|
public static styles = [
|
|
57
63
|
themeDefaultStyles,
|
|
58
64
|
cssManager.defaultStyles,
|
|
@@ -106,6 +112,8 @@ export class DeesAppuiMaincontent extends DeesElement {
|
|
|
106
112
|
.tabStyle=${'horizontal'}
|
|
107
113
|
.autoHide=${this.tabsAutoHide}
|
|
108
114
|
.autoHideThreshold=${this.tabsAutoHideThreshold}
|
|
115
|
+
.actionsLeft=${this.tabActionsLeft}
|
|
116
|
+
.actionsRight=${this.tabActionsRight}
|
|
109
117
|
@tab-select=${(e: CustomEvent) => this.handleTabSelect(e)}
|
|
110
118
|
@tab-close=${(e: CustomEvent) => this.handleTabClose(e)}
|
|
111
119
|
></dees-appui-tabs>
|
|
@@ -2,7 +2,7 @@ import { html, cssManager, css, DeesElement, customElement, state } from '@desig
|
|
|
2
2
|
import * as interfaces from '../../interfaces/index.js';
|
|
3
3
|
import type { DeesAppuiTabs } from './dees-appui-tabs.js';
|
|
4
4
|
|
|
5
|
-
// Interactive demo component for closeable tabs
|
|
5
|
+
// Interactive demo component for closeable tabs with action buttons
|
|
6
6
|
@customElement('demo-closeable-tabs')
|
|
7
7
|
class DemoCloseableTabs extends DeesElement {
|
|
8
8
|
@state()
|
|
@@ -18,24 +18,6 @@ class DemoCloseableTabs extends DeesElement {
|
|
|
18
18
|
:host {
|
|
19
19
|
display: block;
|
|
20
20
|
}
|
|
21
|
-
.controls {
|
|
22
|
-
display: flex;
|
|
23
|
-
gap: 8px;
|
|
24
|
-
margin-top: 16px;
|
|
25
|
-
}
|
|
26
|
-
button {
|
|
27
|
-
background: ${cssManager.bdTheme('rgba(59, 130, 246, 0.1)', 'rgba(59, 130, 246, 0.1)')};
|
|
28
|
-
border: 1px solid ${cssManager.bdTheme('rgba(59, 130, 246, 0.3)', 'rgba(59, 130, 246, 0.3)')};
|
|
29
|
-
color: ${cssManager.bdTheme('#3b82f6', '#60a5fa')};
|
|
30
|
-
padding: 8px 16px;
|
|
31
|
-
border-radius: 6px;
|
|
32
|
-
cursor: pointer;
|
|
33
|
-
font-size: 13px;
|
|
34
|
-
transition: all 0.15s ease;
|
|
35
|
-
}
|
|
36
|
-
button:hover {
|
|
37
|
-
background: ${cssManager.bdTheme('rgba(59, 130, 246, 0.2)', 'rgba(59, 130, 246, 0.2)')};
|
|
38
|
-
}
|
|
39
21
|
.info {
|
|
40
22
|
margin-top: 16px;
|
|
41
23
|
padding: 12px 16px;
|
|
@@ -66,17 +48,27 @@ class DemoCloseableTabs extends DeesElement {
|
|
|
66
48
|
this.tabs = this.tabs.filter(t => t.key !== tabKey);
|
|
67
49
|
}
|
|
68
50
|
|
|
51
|
+
private clearAll() {
|
|
52
|
+
const tabsEl = this.shadowRoot!.querySelector('dees-appui-tabs') as DeesAppuiTabs;
|
|
53
|
+
tabsEl?.clear();
|
|
54
|
+
this.tabs = [];
|
|
55
|
+
this.tabCounter = 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
69
58
|
render() {
|
|
59
|
+
const rightActions: interfaces.ITabAction[] = [
|
|
60
|
+
{ id: 'add', iconName: 'lucide:plus', action: () => this.addTab(), tooltip: 'New Tab' },
|
|
61
|
+
{ id: 'clear', iconName: 'lucide:trash2', action: () => this.clearAll(), tooltip: 'Clear All Tabs' },
|
|
62
|
+
];
|
|
63
|
+
|
|
70
64
|
return html`
|
|
71
65
|
<dees-appui-tabs
|
|
72
66
|
.tabs=${this.tabs}
|
|
67
|
+
.actionsRight=${rightActions}
|
|
73
68
|
@tab-close=${(e: CustomEvent) => this.removeTab(e.detail.tab.key)}
|
|
74
69
|
></dees-appui-tabs>
|
|
75
|
-
<div class="controls">
|
|
76
|
-
<button @click=${() => this.addTab()}>+ Add New Tab</button>
|
|
77
|
-
</div>
|
|
78
70
|
<div class="info">
|
|
79
|
-
Click the X button on tabs to close them.
|
|
71
|
+
Click the X button on tabs to close them. Use the + button to add tabs and the trash button to clear all.
|
|
80
72
|
<br>Current tabs: ${this.tabs.length}
|
|
81
73
|
</div>
|
|
82
74
|
`;
|
|
@@ -232,6 +224,16 @@ export const demoFunc = () => {
|
|
|
232
224
|
{ key: 'Archived', action: () => console.log('Archived clicked') },
|
|
233
225
|
];
|
|
234
226
|
|
|
227
|
+
const actionsLeft: interfaces.ITabAction[] = [
|
|
228
|
+
{ id: 'back', iconName: 'lucide:arrowLeft', action: () => console.log('Back'), tooltip: 'Go Back' },
|
|
229
|
+
];
|
|
230
|
+
|
|
231
|
+
const actionsRight: interfaces.ITabAction[] = [
|
|
232
|
+
{ id: 'add', iconName: 'lucide:plus', action: () => console.log('Add tab'), tooltip: 'New Tab' },
|
|
233
|
+
{ id: 'search', iconName: 'lucide:search', action: () => console.log('Search'), tooltip: 'Search Tabs' },
|
|
234
|
+
{ id: 'disabled', iconName: 'lucide:lock', action: () => {}, tooltip: 'Disabled Action', disabled: true },
|
|
235
|
+
];
|
|
236
|
+
|
|
235
237
|
const demoContent = (text: string) => html`
|
|
236
238
|
<div style="padding: 24px; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};">
|
|
237
239
|
${text}
|
|
@@ -279,7 +281,17 @@ export const demoFunc = () => {
|
|
|
279
281
|
</div>
|
|
280
282
|
|
|
281
283
|
<div class="section">
|
|
282
|
-
<div class="section-title">
|
|
284
|
+
<div class="section-title">Tabs with Action Buttons</div>
|
|
285
|
+
<dees-appui-tabs
|
|
286
|
+
.tabs=${horizontalTabs}
|
|
287
|
+
.actionsLeft=${actionsLeft}
|
|
288
|
+
.actionsRight=${actionsRight}
|
|
289
|
+
></dees-appui-tabs>
|
|
290
|
+
${demoContent('Action buttons can be placed on either side of the tab bar. They remain fixed while tabs scroll. The lock icon shows a disabled action.')}
|
|
291
|
+
</div>
|
|
292
|
+
|
|
293
|
+
<div class="section">
|
|
294
|
+
<div class="section-title">Closeable Tabs with Actions</div>
|
|
283
295
|
<demo-closeable-tabs></demo-closeable-tabs>
|
|
284
296
|
</div>
|
|
285
297
|
|
|
@@ -41,6 +41,12 @@ export class DeesAppuiTabs extends DeesElement {
|
|
|
41
41
|
@property({ type: Number })
|
|
42
42
|
accessor autoHideThreshold: number = 0;
|
|
43
43
|
|
|
44
|
+
@property({ type: Array })
|
|
45
|
+
accessor actionsLeft: interfaces.ITabAction[] = [];
|
|
46
|
+
|
|
47
|
+
@property({ type: Array })
|
|
48
|
+
accessor actionsRight: interfaces.ITabAction[] = [];
|
|
49
|
+
|
|
44
50
|
// Scroll state for fade indicators
|
|
45
51
|
@state()
|
|
46
52
|
private accessor canScrollLeft: boolean = false;
|
|
@@ -73,6 +79,8 @@ export class DeesAppuiTabs extends DeesElement {
|
|
|
73
79
|
border-bottom: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
|
74
80
|
box-sizing: border-box;
|
|
75
81
|
overflow: hidden;
|
|
82
|
+
display: flex;
|
|
83
|
+
align-items: stretch;
|
|
76
84
|
}
|
|
77
85
|
|
|
78
86
|
/* Scroll fade indicators */
|
|
@@ -105,6 +113,72 @@ export class DeesAppuiTabs extends DeesElement {
|
|
|
105
113
|
opacity: 1;
|
|
106
114
|
}
|
|
107
115
|
|
|
116
|
+
.scroll-area {
|
|
117
|
+
position: relative;
|
|
118
|
+
flex: 1;
|
|
119
|
+
min-width: 0;
|
|
120
|
+
overflow: hidden;
|
|
121
|
+
display: flex;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/* Tab action buttons */
|
|
125
|
+
.tab-actions {
|
|
126
|
+
display: flex;
|
|
127
|
+
align-items: center;
|
|
128
|
+
gap: 2px;
|
|
129
|
+
flex-shrink: 0;
|
|
130
|
+
padding: 0 4px;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.tab-actions.left {
|
|
134
|
+
padding-left: 12px;
|
|
135
|
+
padding-right: 8px;
|
|
136
|
+
border-right: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.tab-actions.right {
|
|
140
|
+
padding-right: 12px;
|
|
141
|
+
padding-left: 8px;
|
|
142
|
+
border-left: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.tab-action-button {
|
|
146
|
+
display: flex;
|
|
147
|
+
align-items: center;
|
|
148
|
+
justify-content: center;
|
|
149
|
+
width: 32px;
|
|
150
|
+
height: 32px;
|
|
151
|
+
border-radius: 6px;
|
|
152
|
+
cursor: pointer;
|
|
153
|
+
transition: background 0.15s ease, color 0.15s ease;
|
|
154
|
+
background: transparent;
|
|
155
|
+
color: ${cssManager.bdTheme('#71717a', '#71717a')};
|
|
156
|
+
flex-shrink: 0;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.tab-action-button:hover {
|
|
160
|
+
background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.06)', 'rgba(255, 255, 255, 0.06)')};
|
|
161
|
+
color: ${cssManager.bdTheme('#09090b', '#fafafa')};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.tab-action-button:active {
|
|
165
|
+
background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.1)', 'rgba(255, 255, 255, 0.1)')};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.tab-action-button.disabled {
|
|
169
|
+
opacity: 0.4;
|
|
170
|
+
cursor: not-allowed;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.tab-action-button.disabled:hover {
|
|
174
|
+
background: transparent;
|
|
175
|
+
color: ${cssManager.bdTheme('#71717a', '#71717a')};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.tab-action-button dees-icon {
|
|
179
|
+
font-size: 16px;
|
|
180
|
+
}
|
|
181
|
+
|
|
108
182
|
.tabsContainer {
|
|
109
183
|
position: relative;
|
|
110
184
|
user-select: none;
|
|
@@ -121,12 +195,14 @@ export class DeesAppuiTabs extends DeesElement {
|
|
|
121
195
|
scrollbar-width: thin;
|
|
122
196
|
scrollbar-color: transparent transparent;
|
|
123
197
|
height: 100%;
|
|
198
|
+
width: 100%;
|
|
124
199
|
padding: 0 16px;
|
|
125
200
|
gap: 4px;
|
|
126
201
|
}
|
|
127
202
|
|
|
128
203
|
/* Show scrollbar on hover */
|
|
129
|
-
.tabs-wrapper:hover .tabsContainer.horizontal
|
|
204
|
+
.tabs-wrapper:hover .tabsContainer.horizontal,
|
|
205
|
+
.scroll-area:hover .tabsContainer.horizontal {
|
|
130
206
|
scrollbar-color: ${cssManager.bdTheme('rgba(0,0,0,0.2)', 'rgba(255,255,255,0.2)')} transparent;
|
|
131
207
|
}
|
|
132
208
|
|
|
@@ -144,11 +220,13 @@ export class DeesAppuiTabs extends DeesElement {
|
|
|
144
220
|
transition: background 0.2s ease;
|
|
145
221
|
}
|
|
146
222
|
|
|
147
|
-
.tabs-wrapper:hover .tabsContainer.horizontal::-webkit-scrollbar-thumb
|
|
223
|
+
.tabs-wrapper:hover .tabsContainer.horizontal::-webkit-scrollbar-thumb,
|
|
224
|
+
.scroll-area:hover .tabsContainer.horizontal::-webkit-scrollbar-thumb {
|
|
148
225
|
background: ${cssManager.bdTheme('rgba(0,0,0,0.2)', 'rgba(255,255,255,0.2)')};
|
|
149
226
|
}
|
|
150
227
|
|
|
151
|
-
.tabs-wrapper:hover .tabsContainer.horizontal::-webkit-scrollbar-thumb:hover
|
|
228
|
+
.tabs-wrapper:hover .tabsContainer.horizontal::-webkit-scrollbar-thumb:hover,
|
|
229
|
+
.scroll-area:hover .tabsContainer.horizontal::-webkit-scrollbar-thumb:hover {
|
|
152
230
|
background: ${cssManager.bdTheme('rgba(0,0,0,0.35)', 'rgba(255,255,255,0.35)')};
|
|
153
231
|
}
|
|
154
232
|
|
|
@@ -331,13 +409,20 @@ export class DeesAppuiTabs extends DeesElement {
|
|
|
331
409
|
const containerClass = `tabsContainer ${this.tabStyle}`;
|
|
332
410
|
|
|
333
411
|
if (isHorizontal) {
|
|
412
|
+
const hasLeftActions = this.actionsLeft && this.actionsLeft.length > 0;
|
|
413
|
+
const hasRightActions = this.actionsRight && this.actionsRight.length > 0;
|
|
414
|
+
|
|
334
415
|
return html`
|
|
335
416
|
<div class="${wrapperClass}">
|
|
336
|
-
|
|
337
|
-
<div class="
|
|
338
|
-
${this.
|
|
417
|
+
${hasLeftActions ? this.renderActions(this.actionsLeft, 'left') : ''}
|
|
418
|
+
<div class="scroll-area">
|
|
419
|
+
<div class="scroll-fade scroll-fade-left ${this.canScrollLeft ? 'visible' : ''}"></div>
|
|
420
|
+
<div class="${containerClass}" @scroll=${this.handleScroll}>
|
|
421
|
+
${this.tabs.map(tab => this.renderTab(tab, isHorizontal))}
|
|
422
|
+
</div>
|
|
423
|
+
<div class="scroll-fade scroll-fade-right ${this.canScrollRight ? 'visible' : ''}"></div>
|
|
339
424
|
</div>
|
|
340
|
-
|
|
425
|
+
${hasRightActions ? this.renderActions(this.actionsRight, 'right') : ''}
|
|
341
426
|
${this.showTabIndicator ? html`<div class="tabIndicator"></div>` : ''}
|
|
342
427
|
</div>
|
|
343
428
|
`;
|
|
@@ -353,6 +438,22 @@ export class DeesAppuiTabs extends DeesElement {
|
|
|
353
438
|
`;
|
|
354
439
|
}
|
|
355
440
|
|
|
441
|
+
private renderActions(actions: interfaces.ITabAction[], position: 'left' | 'right'): TemplateResult {
|
|
442
|
+
return html`
|
|
443
|
+
<div class="tab-actions ${position}">
|
|
444
|
+
${actions.map(action => html`
|
|
445
|
+
<div
|
|
446
|
+
class="tab-action-button ${action.disabled ? 'disabled' : ''}"
|
|
447
|
+
title="${action.tooltip || action.id}"
|
|
448
|
+
@click=${() => !action.disabled && action.action()}
|
|
449
|
+
>
|
|
450
|
+
<dees-icon .icon=${action.iconName}></dees-icon>
|
|
451
|
+
</div>
|
|
452
|
+
`)}
|
|
453
|
+
</div>
|
|
454
|
+
`;
|
|
455
|
+
}
|
|
456
|
+
|
|
356
457
|
private renderTab(tab: interfaces.IMenuItem, isHorizontal: boolean): TemplateResult {
|
|
357
458
|
const isSelected = tab === this.selectedTab;
|
|
358
459
|
const classes = `tab ${isSelected ? 'selectedTab' : ''}`;
|
|
@@ -406,6 +507,14 @@ export class DeesAppuiTabs extends DeesElement {
|
|
|
406
507
|
}));
|
|
407
508
|
}
|
|
408
509
|
|
|
510
|
+
/**
|
|
511
|
+
* Clear all tabs and reset selection.
|
|
512
|
+
*/
|
|
513
|
+
public clear(): void {
|
|
514
|
+
this.tabs = [];
|
|
515
|
+
this.selectedTab = null;
|
|
516
|
+
}
|
|
517
|
+
|
|
409
518
|
private closeTab(e: Event, tab: interfaces.IMenuItem) {
|
|
410
519
|
e.stopPropagation(); // Don't select tab when closing
|
|
411
520
|
|
|
@@ -423,14 +532,9 @@ export class DeesAppuiTabs extends DeesElement {
|
|
|
423
532
|
}
|
|
424
533
|
|
|
425
534
|
firstUpdated() {
|
|
426
|
-
|
|
427
|
-
this.selectTab(this.tabs[0]);
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
// Set up ResizeObserver for scroll state updates
|
|
535
|
+
// Tab selection is handled by updated() lifecycle
|
|
431
536
|
this.setupResizeObserver();
|
|
432
537
|
|
|
433
|
-
// Initial scroll state check
|
|
434
538
|
requestAnimationFrame(() => {
|
|
435
539
|
this.updateScrollState();
|
|
436
540
|
});
|
|
@@ -503,8 +607,24 @@ export class DeesAppuiTabs extends DeesElement {
|
|
|
503
607
|
async updated(changedProperties: Map<string, any>) {
|
|
504
608
|
super.updated(changedProperties);
|
|
505
609
|
|
|
506
|
-
if (changedProperties.has('tabs')
|
|
507
|
-
this.
|
|
610
|
+
if (changedProperties.has('tabs')) {
|
|
611
|
+
if (!this.tabs || this.tabs.length === 0) {
|
|
612
|
+
// Tabs are empty => reset selection
|
|
613
|
+
if (this.selectedTab !== null) {
|
|
614
|
+
this.selectedTab = null;
|
|
615
|
+
this.dispatchEvent(new CustomEvent('tab-select', {
|
|
616
|
+
detail: { tab: null },
|
|
617
|
+
bubbles: true,
|
|
618
|
+
composed: true,
|
|
619
|
+
}));
|
|
620
|
+
}
|
|
621
|
+
} else if (this.selectedTab && !this.tabs.includes(this.selectedTab)) {
|
|
622
|
+
// Selected tab was removed => select first available
|
|
623
|
+
this.selectTab(this.tabs[0]);
|
|
624
|
+
} else if (!this.selectedTab) {
|
|
625
|
+
// Tabs exist but nothing selected => select first
|
|
626
|
+
this.selectTab(this.tabs[0]);
|
|
627
|
+
}
|
|
508
628
|
}
|
|
509
629
|
|
|
510
630
|
if (changedProperties.has('selectedTab') || changedProperties.has('tabs')) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { TemplateResult } from '@design.estate/dees-element';
|
|
2
2
|
import type { IAppBarMenuItem } from './appbarmenuitem.js';
|
|
3
|
-
import type { IMenuItem } from './tab.js';
|
|
3
|
+
import type { IMenuItem, ITabAction } from './tab.js';
|
|
4
4
|
import type { IMenuGroup } from './menugroup.js';
|
|
5
5
|
import type { ISecondaryMenuGroup, ISecondaryMenuItem } from './secondarymenu.js';
|
|
6
6
|
|
|
@@ -134,6 +134,8 @@ export type TDeesAppui = HTMLElement & {
|
|
|
134
134
|
removeContentTab: (tabKey: string) => void;
|
|
135
135
|
selectContentTab: (tabKey: string) => void;
|
|
136
136
|
getSelectedContentTab: () => IMenuItem | undefined;
|
|
137
|
+
setContentTabActionsLeft: (actions: ITabAction[]) => void;
|
|
138
|
+
setContentTabActionsRight: (actions: ITabAction[]) => void;
|
|
137
139
|
activityLog: IActivityLogAPI;
|
|
138
140
|
setActivityLogVisible: (visible: boolean) => void;
|
|
139
141
|
toggleActivityLog: () => void;
|