@design.estate/dees-wcctools 3.4.0 → 3.5.1
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 +761 -245
- package/dist_bundle/bundle.js.map +4 -4
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/wcc-contextmenu.d.ts +25 -0
- package/dist_ts_web/elements/wcc-contextmenu.js +257 -0
- package/dist_ts_web/elements/wcc-dashboard.d.ts +2 -0
- package/dist_ts_web/elements/wcc-dashboard.js +97 -5
- package/dist_ts_web/elements/wcc-frame.d.ts +2 -0
- package/dist_ts_web/elements/wcc-frame.js +23 -8
- package/dist_ts_web/elements/wcc-properties.d.ts +1 -0
- package/dist_ts_web/elements/wcc-properties.js +11 -3
- package/dist_ts_web/elements/wcc-sidebar.d.ts +16 -0
- package/dist_ts_web/elements/wcc-sidebar.js +346 -63
- package/dist_watch/bundle.js +1170 -397
- package/dist_watch/bundle.js.map +4 -4
- package/package.json +1 -1
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/wcc-contextmenu.ts +211 -0
- package/ts_web/elements/wcc-dashboard.ts +83 -3
- package/ts_web/elements/wcc-frame.ts +11 -6
- package/ts_web/elements/wcc-properties.ts +4 -1
- package/ts_web/elements/wcc-sidebar.ts +354 -61
|
@@ -4,6 +4,7 @@ import { WccDashboard, getSectionItems } from './wcc-dashboard.js';
|
|
|
4
4
|
import type { TTemplateFactory } from './wcctools.helpers.js';
|
|
5
5
|
import { getDemoCount, hasMultipleDemos } from './wcctools.helpers.js';
|
|
6
6
|
import type { IWccSection, TElementType } from '../wcctools.interfaces.js';
|
|
7
|
+
import { WccContextmenu } from './wcc-contextmenu.js';
|
|
7
8
|
|
|
8
9
|
@customElement('wcc-sidebar')
|
|
9
10
|
export class WccSidebar extends DeesElement {
|
|
@@ -31,6 +32,18 @@ export class WccSidebar extends DeesElement {
|
|
|
31
32
|
@property()
|
|
32
33
|
accessor searchQuery: string = '';
|
|
33
34
|
|
|
35
|
+
// Pinned items as Set of "sectionName::itemName"
|
|
36
|
+
@property({ attribute: false })
|
|
37
|
+
accessor pinnedItems: Set<string> = new Set();
|
|
38
|
+
|
|
39
|
+
// Sidebar width (resizable)
|
|
40
|
+
@property({ type: Number })
|
|
41
|
+
accessor sidebarWidth: number = 200;
|
|
42
|
+
|
|
43
|
+
// Track if currently resizing
|
|
44
|
+
@state()
|
|
45
|
+
accessor isResizing: boolean = false;
|
|
46
|
+
|
|
34
47
|
private sectionsInitialized = false;
|
|
35
48
|
|
|
36
49
|
public render(): TemplateResult {
|
|
@@ -61,7 +74,7 @@ export class WccSidebar extends DeesElement {
|
|
|
61
74
|
box-sizing: border-box;
|
|
62
75
|
position: absolute;
|
|
63
76
|
left: 0px;
|
|
64
|
-
width:
|
|
77
|
+
width: ${this.sidebarWidth}px;
|
|
65
78
|
top: 0px;
|
|
66
79
|
bottom: 0px;
|
|
67
80
|
overflow-y: auto;
|
|
@@ -159,7 +172,11 @@ export class WccSidebar extends DeesElement {
|
|
|
159
172
|
}
|
|
160
173
|
|
|
161
174
|
.selectOption.folder {
|
|
162
|
-
grid-template-columns: 16px
|
|
175
|
+
grid-template-columns: 16px 1fr;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.selectOption.folder .text {
|
|
179
|
+
margin-left: 4px;
|
|
163
180
|
}
|
|
164
181
|
|
|
165
182
|
.selectOption .expand-icon {
|
|
@@ -288,6 +305,90 @@ export class WccSidebar extends DeesElement {
|
|
|
288
305
|
background: rgba(59, 130, 246, 0.3);
|
|
289
306
|
border-radius: 2px;
|
|
290
307
|
}
|
|
308
|
+
|
|
309
|
+
/* Pinned item highlight in original section */
|
|
310
|
+
.selectOption.pinned {
|
|
311
|
+
background: rgba(245, 158, 11, 0.08);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.selectOption.pinned:hover {
|
|
315
|
+
background: rgba(245, 158, 11, 0.12);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.selectOption.pinned.selected {
|
|
319
|
+
background: rgba(245, 158, 11, 0.18);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/* Pinned section styling */
|
|
323
|
+
.section-header.pinned-section {
|
|
324
|
+
background: rgba(245, 158, 11, 0.08);
|
|
325
|
+
color: #f59e0b;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.section-header.pinned-section:hover {
|
|
329
|
+
background: rgba(245, 158, 11, 0.12);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.section-header.pinned-section .section-icon {
|
|
333
|
+
opacity: 0.8;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/* Section tag pill for pinned items */
|
|
337
|
+
.section-tag {
|
|
338
|
+
font-size: 0.5rem;
|
|
339
|
+
color: #888;
|
|
340
|
+
margin-left: auto;
|
|
341
|
+
text-transform: uppercase;
|
|
342
|
+
letter-spacing: 0.02em;
|
|
343
|
+
background: rgba(255, 255, 255, 0.06);
|
|
344
|
+
padding: 0.15rem 0.4rem;
|
|
345
|
+
border-radius: 9999px;
|
|
346
|
+
white-space: nowrap;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/* Group container */
|
|
350
|
+
.item-group {
|
|
351
|
+
margin: 0.375rem 0.375rem;
|
|
352
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
353
|
+
border-radius: 6px;
|
|
354
|
+
padding: 0.25rem 0;
|
|
355
|
+
background: rgba(255, 255, 255, 0.01);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.item-group-legend {
|
|
359
|
+
font-size: 0.55rem;
|
|
360
|
+
text-transform: uppercase;
|
|
361
|
+
letter-spacing: 0.05em;
|
|
362
|
+
color: #555;
|
|
363
|
+
padding: 0.125rem 0.625rem 0.25rem;
|
|
364
|
+
display: block;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.item-group .selectOption {
|
|
368
|
+
margin-left: 0.25rem;
|
|
369
|
+
margin-right: 0.25rem;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/* Resize handle */
|
|
373
|
+
.resize-handle {
|
|
374
|
+
position: absolute;
|
|
375
|
+
top: 0;
|
|
376
|
+
right: 0;
|
|
377
|
+
bottom: 0;
|
|
378
|
+
width: 4px;
|
|
379
|
+
cursor: col-resize;
|
|
380
|
+
background: transparent;
|
|
381
|
+
transition: background 0.15s ease;
|
|
382
|
+
z-index: 10;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.resize-handle:hover {
|
|
386
|
+
background: rgba(59, 130, 246, 0.3);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
.resize-handle.active {
|
|
390
|
+
background: var(--primary);
|
|
391
|
+
}
|
|
291
392
|
</style>
|
|
292
393
|
<div class="search-container">
|
|
293
394
|
<input
|
|
@@ -299,8 +400,13 @@ export class WccSidebar extends DeesElement {
|
|
|
299
400
|
/>
|
|
300
401
|
</div>
|
|
301
402
|
<div class="menu">
|
|
403
|
+
${this.renderPinnedSection()}
|
|
302
404
|
${this.renderSections()}
|
|
303
405
|
</div>
|
|
406
|
+
<div
|
|
407
|
+
class="resize-handle ${this.isResizing ? 'active' : ''}"
|
|
408
|
+
@mousedown=${this.startResize}
|
|
409
|
+
></div>
|
|
304
410
|
`;
|
|
305
411
|
}
|
|
306
412
|
|
|
@@ -308,7 +414,7 @@ export class WccSidebar extends DeesElement {
|
|
|
308
414
|
* Initialize collapsed sections from section config
|
|
309
415
|
*/
|
|
310
416
|
private initCollapsedSections() {
|
|
311
|
-
if (this.sectionsInitialized) return;
|
|
417
|
+
if (this.sectionsInitialized || !this.dashboardRef?.sections) return;
|
|
312
418
|
|
|
313
419
|
const collapsed = new Set<string>();
|
|
314
420
|
for (const section of this.dashboardRef.sections) {
|
|
@@ -320,13 +426,114 @@ export class WccSidebar extends DeesElement {
|
|
|
320
426
|
this.sectionsInitialized = true;
|
|
321
427
|
}
|
|
322
428
|
|
|
429
|
+
// ============ Pinning helpers ============
|
|
430
|
+
|
|
431
|
+
private getPinKey(sectionName: string, itemName: string): string {
|
|
432
|
+
return `${sectionName}::${itemName}`;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
private isPinned(sectionName: string, itemName: string): boolean {
|
|
436
|
+
return this.pinnedItems.has(this.getPinKey(sectionName, itemName));
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
private togglePin(sectionName: string, itemName: string) {
|
|
440
|
+
const key = this.getPinKey(sectionName, itemName);
|
|
441
|
+
const newPinned = new Set(this.pinnedItems);
|
|
442
|
+
if (newPinned.has(key)) {
|
|
443
|
+
newPinned.delete(key);
|
|
444
|
+
} else {
|
|
445
|
+
newPinned.add(key);
|
|
446
|
+
}
|
|
447
|
+
this.pinnedItems = newPinned;
|
|
448
|
+
this.dispatchEvent(new CustomEvent('pinnedChanged', { detail: newPinned }));
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
private showContextMenu(e: MouseEvent, sectionName: string, itemName: string) {
|
|
452
|
+
const isPinned = this.isPinned(sectionName, itemName);
|
|
453
|
+
WccContextmenu.show(e, [
|
|
454
|
+
{
|
|
455
|
+
name: isPinned ? 'Unpin' : 'Pin',
|
|
456
|
+
iconName: isPinned ? 'push_pin' : 'push_pin',
|
|
457
|
+
action: () => this.togglePin(sectionName, itemName),
|
|
458
|
+
},
|
|
459
|
+
]);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Render the PINNED section (only if there are pinned items)
|
|
464
|
+
*/
|
|
465
|
+
private renderPinnedSection() {
|
|
466
|
+
if (!this.dashboardRef?.sections || this.pinnedItems.size === 0) {
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
const isCollapsed = this.collapsedSections.has('__pinned__');
|
|
471
|
+
|
|
472
|
+
// Collect pinned items with their original section info
|
|
473
|
+
// Pinned items are NOT filtered by search - they always remain visible
|
|
474
|
+
const pinnedEntries: Array<{ sectionName: string; itemName: string; item: any; section: IWccSection }> = [];
|
|
475
|
+
|
|
476
|
+
for (const key of this.pinnedItems) {
|
|
477
|
+
const [sectionName, itemName] = key.split('::');
|
|
478
|
+
const section = this.dashboardRef.sections.find(s => s.name === sectionName);
|
|
479
|
+
if (section) {
|
|
480
|
+
const entries = getSectionItems(section);
|
|
481
|
+
const found = entries.find(([name]) => name === itemName);
|
|
482
|
+
if (found) {
|
|
483
|
+
pinnedEntries.push({ sectionName, itemName, item: found[1], section });
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
if (pinnedEntries.length === 0) {
|
|
489
|
+
return null;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
return html`
|
|
493
|
+
<div
|
|
494
|
+
class="section-header pinned-section ${isCollapsed ? 'collapsed' : ''}"
|
|
495
|
+
@click=${() => this.toggleSectionCollapsed('__pinned__')}
|
|
496
|
+
>
|
|
497
|
+
<i class="material-symbols-outlined expand-icon">expand_more</i>
|
|
498
|
+
<i class="material-symbols-outlined section-icon">push_pin</i>
|
|
499
|
+
<span>Pinned</span>
|
|
500
|
+
</div>
|
|
501
|
+
<div class="section-content ${isCollapsed ? 'collapsed' : ''}">
|
|
502
|
+
${pinnedEntries.map(({ sectionName, itemName, item, section }) => {
|
|
503
|
+
const isSelected = this.selectedItem === item;
|
|
504
|
+
const type = section.type === 'elements' ? 'element' : 'page';
|
|
505
|
+
const icon = section.type === 'elements' ? 'featured_video' : 'insert_drive_file';
|
|
506
|
+
|
|
507
|
+
return html`
|
|
508
|
+
<div
|
|
509
|
+
class="selectOption ${isSelected ? 'selected' : ''}"
|
|
510
|
+
@click=${async () => {
|
|
511
|
+
await plugins.deesDomtools.DomTools.setupDomTools();
|
|
512
|
+
this.selectItem(type, itemName, item, 0, section);
|
|
513
|
+
}}
|
|
514
|
+
@contextmenu=${(e: MouseEvent) => this.showContextMenu(e, sectionName, itemName)}
|
|
515
|
+
>
|
|
516
|
+
<i class="material-symbols-outlined">${icon}</i>
|
|
517
|
+
<div class="text">${this.highlightMatch(itemName)}</div>
|
|
518
|
+
<span class="section-tag">${sectionName}</span>
|
|
519
|
+
</div>
|
|
520
|
+
`;
|
|
521
|
+
})}
|
|
522
|
+
</div>
|
|
523
|
+
`;
|
|
524
|
+
}
|
|
525
|
+
|
|
323
526
|
/**
|
|
324
527
|
* Render all sections
|
|
325
528
|
*/
|
|
326
529
|
private renderSections() {
|
|
530
|
+
if (!this.dashboardRef?.sections) {
|
|
531
|
+
return null;
|
|
532
|
+
}
|
|
533
|
+
|
|
327
534
|
this.initCollapsedSections();
|
|
328
535
|
|
|
329
|
-
return this.dashboardRef.sections.map((section
|
|
536
|
+
return this.dashboardRef.sections.map((section) => {
|
|
330
537
|
// Check if section has any matching items
|
|
331
538
|
const entries = getSectionItems(section);
|
|
332
539
|
const filteredEntries = entries.filter(([name]) => this.matchesSearch(name));
|
|
@@ -365,13 +572,15 @@ export class WccSidebar extends DeesElement {
|
|
|
365
572
|
|
|
366
573
|
if (section.type === 'pages') {
|
|
367
574
|
return filteredEntries.map(([pageName, item]) => {
|
|
575
|
+
const isPinned = this.isPinned(section.name, pageName);
|
|
368
576
|
return html`
|
|
369
577
|
<div
|
|
370
|
-
class="selectOption ${this.selectedItem === item ? 'selected' : ''}"
|
|
578
|
+
class="selectOption ${this.selectedItem === item ? 'selected' : ''} ${isPinned ? 'pinned' : ''}"
|
|
371
579
|
@click=${async () => {
|
|
372
580
|
await plugins.deesDomtools.DomTools.setupDomTools();
|
|
373
581
|
this.selectItem('page', pageName, item, 0, section);
|
|
374
582
|
}}
|
|
583
|
+
@contextmenu=${(e: MouseEvent) => this.showContextMenu(e, section.name, pageName)}
|
|
375
584
|
>
|
|
376
585
|
<i class="material-symbols-outlined">insert_drive_file</i>
|
|
377
586
|
<div class="text">${this.highlightMatch(pageName)}</div>
|
|
@@ -379,62 +588,101 @@ export class WccSidebar extends DeesElement {
|
|
|
379
588
|
`;
|
|
380
589
|
});
|
|
381
590
|
} else {
|
|
382
|
-
// type === 'elements'
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
const
|
|
387
|
-
const
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
if (isMultiDemo) {
|
|
391
|
-
// Multi-demo element - render as expandable folder
|
|
392
|
-
return html`
|
|
393
|
-
<div
|
|
394
|
-
class="selectOption folder ${isExpanded ? 'expanded' : ''} ${isSelected ? 'selected' : ''}"
|
|
395
|
-
@click=${() => this.toggleExpanded(elementName)}
|
|
396
|
-
>
|
|
397
|
-
<i class="material-symbols-outlined expand-icon">chevron_right</i>
|
|
398
|
-
<i class="material-symbols-outlined">folder</i>
|
|
399
|
-
<div class="text">${this.highlightMatch(elementName)}</div>
|
|
400
|
-
</div>
|
|
401
|
-
${isExpanded ? html`
|
|
402
|
-
<div class="demo-children">
|
|
403
|
-
${Array.from({ length: demoCount }, (_, i) => {
|
|
404
|
-
const demoIndex = i;
|
|
405
|
-
const isThisDemoSelected = isSelected && this.dashboardRef.selectedDemoIndex === demoIndex;
|
|
406
|
-
return html`
|
|
407
|
-
<div
|
|
408
|
-
class="demo-child ${isThisDemoSelected ? 'selected' : ''}"
|
|
409
|
-
@click=${async () => {
|
|
410
|
-
await plugins.deesDomtools.DomTools.setupDomTools();
|
|
411
|
-
this.selectItem('element', elementName, item, demoIndex, section);
|
|
412
|
-
}}
|
|
413
|
-
>
|
|
414
|
-
<i class="material-symbols-outlined">play_circle</i>
|
|
415
|
-
<div class="text">demo${demoIndex + 1}</div>
|
|
416
|
-
</div>
|
|
417
|
-
`;
|
|
418
|
-
})}
|
|
419
|
-
</div>
|
|
420
|
-
` : null}
|
|
421
|
-
`;
|
|
422
|
-
} else {
|
|
423
|
-
// Single demo element
|
|
424
|
-
return html`
|
|
425
|
-
<div
|
|
426
|
-
class="selectOption ${isSelected ? 'selected' : ''}"
|
|
427
|
-
@click=${async () => {
|
|
428
|
-
await plugins.deesDomtools.DomTools.setupDomTools();
|
|
429
|
-
this.selectItem('element', elementName, item, 0, section);
|
|
430
|
-
}}
|
|
431
|
-
>
|
|
432
|
-
<i class="material-symbols-outlined">featured_video</i>
|
|
433
|
-
<div class="text">${this.highlightMatch(elementName)}</div>
|
|
434
|
-
</div>
|
|
435
|
-
`;
|
|
591
|
+
// type === 'elements' - group by demoGroup
|
|
592
|
+
const groupedItems = new Map<string | null, Array<[string, any]>>();
|
|
593
|
+
|
|
594
|
+
for (const entry of filteredEntries) {
|
|
595
|
+
const [, item] = entry;
|
|
596
|
+
const group = (item as any).demoGroup || null;
|
|
597
|
+
if (!groupedItems.has(group)) {
|
|
598
|
+
groupedItems.set(group, []);
|
|
436
599
|
}
|
|
437
|
-
|
|
600
|
+
groupedItems.get(group)!.push(entry);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
const result: TemplateResult[] = [];
|
|
604
|
+
|
|
605
|
+
// Render ungrouped items first
|
|
606
|
+
const ungrouped = groupedItems.get(null) || [];
|
|
607
|
+
for (const entry of ungrouped) {
|
|
608
|
+
result.push(this.renderElementItem(entry, section));
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// Render grouped items
|
|
612
|
+
for (const [groupName, items] of groupedItems) {
|
|
613
|
+
if (groupName === null) continue;
|
|
614
|
+
|
|
615
|
+
result.push(html`
|
|
616
|
+
<div class="item-group">
|
|
617
|
+
<span class="item-group-legend">${groupName}</span>
|
|
618
|
+
${items.map((entry) => this.renderElementItem(entry, section))}
|
|
619
|
+
</div>
|
|
620
|
+
`);
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
return result;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* Render a single element item (used by renderSectionItems)
|
|
629
|
+
*/
|
|
630
|
+
private renderElementItem(entry: [string, any], section: IWccSection): TemplateResult {
|
|
631
|
+
const [elementName, item] = entry;
|
|
632
|
+
const anonItem = item as any;
|
|
633
|
+
const demoCount = anonItem.demo ? getDemoCount(anonItem.demo) : 0;
|
|
634
|
+
const isMultiDemo = anonItem.demo && hasMultipleDemos(anonItem.demo);
|
|
635
|
+
const isExpanded = this.expandedElements.has(elementName);
|
|
636
|
+
const isSelected = this.selectedItem === item;
|
|
637
|
+
const isPinned = this.isPinned(section.name, elementName);
|
|
638
|
+
|
|
639
|
+
if (isMultiDemo) {
|
|
640
|
+
// Multi-demo element - render as expandable folder
|
|
641
|
+
return html`
|
|
642
|
+
<div
|
|
643
|
+
class="selectOption folder ${isExpanded ? 'expanded' : ''} ${isSelected ? 'selected' : ''} ${isPinned ? 'pinned' : ''}"
|
|
644
|
+
@click=${() => this.toggleExpanded(elementName)}
|
|
645
|
+
@contextmenu=${(e: MouseEvent) => this.showContextMenu(e, section.name, elementName)}
|
|
646
|
+
>
|
|
647
|
+
<i class="material-symbols-outlined expand-icon">chevron_right</i>
|
|
648
|
+
<div class="text">${this.highlightMatch(elementName)}</div>
|
|
649
|
+
</div>
|
|
650
|
+
${isExpanded ? html`
|
|
651
|
+
<div class="demo-children">
|
|
652
|
+
${Array.from({ length: demoCount }, (_, i) => {
|
|
653
|
+
const demoIndex = i;
|
|
654
|
+
const isThisDemoSelected = isSelected && this.dashboardRef.selectedDemoIndex === demoIndex;
|
|
655
|
+
return html`
|
|
656
|
+
<div
|
|
657
|
+
class="demo-child ${isThisDemoSelected ? 'selected' : ''}"
|
|
658
|
+
@click=${async () => {
|
|
659
|
+
await plugins.deesDomtools.DomTools.setupDomTools();
|
|
660
|
+
this.selectItem('element', elementName, item, demoIndex, section);
|
|
661
|
+
}}
|
|
662
|
+
>
|
|
663
|
+
<i class="material-symbols-outlined">play_circle</i>
|
|
664
|
+
<div class="text">demo${demoIndex + 1}</div>
|
|
665
|
+
</div>
|
|
666
|
+
`;
|
|
667
|
+
})}
|
|
668
|
+
</div>
|
|
669
|
+
` : null}
|
|
670
|
+
`;
|
|
671
|
+
} else {
|
|
672
|
+
// Single demo element
|
|
673
|
+
return html`
|
|
674
|
+
<div
|
|
675
|
+
class="selectOption ${isSelected ? 'selected' : ''} ${isPinned ? 'pinned' : ''}"
|
|
676
|
+
@click=${async () => {
|
|
677
|
+
await plugins.deesDomtools.DomTools.setupDomTools();
|
|
678
|
+
this.selectItem('element', elementName, item, 0, section);
|
|
679
|
+
}}
|
|
680
|
+
@contextmenu=${(e: MouseEvent) => this.showContextMenu(e, section.name, elementName)}
|
|
681
|
+
>
|
|
682
|
+
<i class="material-symbols-outlined">featured_video</i>
|
|
683
|
+
<div class="text">${this.highlightMatch(elementName)}</div>
|
|
684
|
+
</div>
|
|
685
|
+
`;
|
|
438
686
|
}
|
|
439
687
|
}
|
|
440
688
|
|
|
@@ -485,7 +733,7 @@ export class WccSidebar extends DeesElement {
|
|
|
485
733
|
super.updated(changedProperties);
|
|
486
734
|
|
|
487
735
|
// Auto-expand folder when a multi-demo element is selected
|
|
488
|
-
if (changedProperties.has('selectedItem') && this.selectedItem) {
|
|
736
|
+
if (changedProperties.has('selectedItem') && this.selectedItem && this.dashboardRef?.sections) {
|
|
489
737
|
// Find the element in any section
|
|
490
738
|
for (const section of this.dashboardRef.sections) {
|
|
491
739
|
if (section.type !== 'elements') continue;
|
|
@@ -508,6 +756,51 @@ export class WccSidebar extends DeesElement {
|
|
|
508
756
|
}
|
|
509
757
|
}
|
|
510
758
|
|
|
759
|
+
// ============ Resize functionality ============
|
|
760
|
+
|
|
761
|
+
private startResize = (e: MouseEvent) => {
|
|
762
|
+
e.preventDefault();
|
|
763
|
+
this.isResizing = true;
|
|
764
|
+
const startX = e.clientX;
|
|
765
|
+
const startWidth = this.sidebarWidth;
|
|
766
|
+
|
|
767
|
+
// Cache references once at start
|
|
768
|
+
const frame = this.dashboardRef?.shadowRoot?.querySelector('wcc-frame') as any;
|
|
769
|
+
const properties = this.dashboardRef?.shadowRoot?.querySelector('wcc-properties') as any;
|
|
770
|
+
|
|
771
|
+
// Disable frame transition during resize
|
|
772
|
+
if (frame) {
|
|
773
|
+
frame.isResizing = true;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
const onMouseMove = (e: MouseEvent) => {
|
|
777
|
+
const newWidth = Math.min(400, Math.max(150, startWidth + (e.clientX - startX)));
|
|
778
|
+
this.sidebarWidth = newWidth;
|
|
779
|
+
// Update frame and properties directly
|
|
780
|
+
if (frame) {
|
|
781
|
+
frame.sidebarWidth = newWidth;
|
|
782
|
+
}
|
|
783
|
+
if (properties) {
|
|
784
|
+
properties.sidebarWidth = newWidth;
|
|
785
|
+
}
|
|
786
|
+
};
|
|
787
|
+
|
|
788
|
+
const onMouseUp = () => {
|
|
789
|
+
this.isResizing = false;
|
|
790
|
+
document.removeEventListener('mousemove', onMouseMove);
|
|
791
|
+
document.removeEventListener('mouseup', onMouseUp);
|
|
792
|
+
// Re-enable frame transition
|
|
793
|
+
if (frame) {
|
|
794
|
+
frame.isResizing = false;
|
|
795
|
+
}
|
|
796
|
+
// Dispatch event on release for URL persistence
|
|
797
|
+
this.dispatchEvent(new CustomEvent('widthChanged', { detail: this.sidebarWidth }));
|
|
798
|
+
};
|
|
799
|
+
|
|
800
|
+
document.addEventListener('mousemove', onMouseMove);
|
|
801
|
+
document.addEventListener('mouseup', onMouseUp);
|
|
802
|
+
};
|
|
803
|
+
|
|
511
804
|
public selectItem(
|
|
512
805
|
typeArg: TElementType,
|
|
513
806
|
itemNameArg: string,
|