@design.estate/dees-wcctools 3.5.0 → 3.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@design.estate/dees-wcctools",
3
- "version": "3.5.0",
3
+ "version": "3.5.2",
4
4
  "private": false,
5
5
  "description": "A set of web component tools for creating element catalogues, enabling the structured development and documentation of custom elements and pages.",
6
6
  "exports": {
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@design.estate/dees-wcctools',
6
- version: '3.5.0',
6
+ version: '3.5.2',
7
7
  description: 'A set of web component tools for creating element catalogues, enabling the structured development and documentation of custom elements and pages.'
8
8
  }
@@ -66,6 +66,10 @@ export class WccDashboard extends DeesElement {
66
66
  @property({ attribute: false })
67
67
  accessor pinnedItems: Set<string> = new Set();
68
68
 
69
+ // Sidebar width (resizable)
70
+ @property({ type: Number })
71
+ accessor sidebarWidth: number = 200;
72
+
69
73
  // Derived from selectedViewport - no need for separate property
70
74
  public get isNative(): boolean {
71
75
  return this.selectedViewport === 'native';
@@ -127,6 +131,7 @@ export class WccDashboard extends DeesElement {
127
131
  .selectedItem=${this.selectedItem}
128
132
  .searchQuery=${this.searchQuery}
129
133
  .pinnedItems=${this.pinnedItems}
134
+ .sidebarWidth=${this.sidebarWidth}
130
135
  .isNative=${this.isNative}
131
136
  @selectedType=${(eventArg) => {
132
137
  this.selectedType = eventArg.detail;
@@ -145,6 +150,15 @@ export class WccDashboard extends DeesElement {
145
150
  this.pinnedItems = eventArg.detail;
146
151
  this.updateUrlWithScrollState();
147
152
  }}
153
+ @widthChanged=${async (eventArg: CustomEvent) => {
154
+ this.sidebarWidth = eventArg.detail;
155
+ this.updateUrlWithScrollState();
156
+ const frame = await this.wccFrame;
157
+ if (frame) {
158
+ frame.sidebarWidth = eventArg.detail;
159
+ frame.requestUpdate();
160
+ }
161
+ }}
148
162
  ></wcc-sidebar>
149
163
  <wcc-properties
150
164
  .dashboardRef=${this}
@@ -153,6 +167,7 @@ export class WccDashboard extends DeesElement {
153
167
  .selectedViewport=${this.selectedViewport}
154
168
  .selectedTheme=${this.selectedTheme}
155
169
  .isNative=${this.isNative}
170
+ .sidebarWidth=${this.sidebarWidth}
156
171
  @selectedViewport=${(eventArg) => {
157
172
  this.selectedViewport = eventArg.detail;
158
173
  this.scheduleUpdate();
@@ -171,7 +186,7 @@ export class WccDashboard extends DeesElement {
171
186
  this.toggleNative();
172
187
  }}
173
188
  ></wcc-properties>
174
- <wcc-frame id="wccFrame" viewport=${this.selectedViewport} .isNative=${this.isNative}>
189
+ <wcc-frame id="wccFrame" viewport=${this.selectedViewport} .isNative=${this.isNative} .sidebarWidth=${this.sidebarWidth}>
175
190
  </wcc-frame>
176
191
  `;
177
192
  }
@@ -247,6 +262,7 @@ export class WccDashboard extends DeesElement {
247
262
  const frameScrollY = routeInfo.queryParams.frameScrollY;
248
263
  const sidebarScrollY = routeInfo.queryParams.sidebarScrollY;
249
264
  const pinned = routeInfo.queryParams.pinned;
265
+ const sidebarWidth = routeInfo.queryParams.sidebarWidth;
250
266
 
251
267
  if (search) {
252
268
  this.searchQuery = search;
@@ -269,10 +285,19 @@ export class WccDashboard extends DeesElement {
269
285
  } else if (this.pinnedItems.size > 0) {
270
286
  this.pinnedItems = new Set();
271
287
  }
288
+ if (sidebarWidth) {
289
+ this.sidebarWidth = parseInt(sidebarWidth, 10);
290
+ }
272
291
 
273
- // Apply scroll positions after a short delay to ensure DOM is ready
274
- setTimeout(() => {
292
+ // Apply scroll positions and update frame after a short delay to ensure DOM is ready
293
+ setTimeout(async () => {
275
294
  this.applyScrollPositions();
295
+ // Ensure frame gets the sidebarWidth
296
+ const frame = await this.wccFrame;
297
+ if (frame) {
298
+ frame.sidebarWidth = this.sidebarWidth;
299
+ frame.requestUpdate();
300
+ }
276
301
  }, 100);
277
302
  } else {
278
303
  this.searchQuery = '';
@@ -326,6 +351,7 @@ export class WccDashboard extends DeesElement {
326
351
  const frameScrollY = routeInfo.queryParams.frameScrollY;
327
352
  const sidebarScrollY = routeInfo.queryParams.sidebarScrollY;
328
353
  const pinned = routeInfo.queryParams.pinned;
354
+ const sidebarWidth = routeInfo.queryParams.sidebarWidth;
329
355
 
330
356
  if (search) {
331
357
  this.searchQuery = search;
@@ -348,6 +374,9 @@ export class WccDashboard extends DeesElement {
348
374
  } else if (this.pinnedItems.size > 0) {
349
375
  this.pinnedItems = new Set();
350
376
  }
377
+ if (sidebarWidth) {
378
+ this.sidebarWidth = parseInt(sidebarWidth, 10);
379
+ }
351
380
 
352
381
  // Apply scroll positions after a short delay to ensure DOM is ready
353
382
  setTimeout(() => {
@@ -444,6 +473,9 @@ export class WccDashboard extends DeesElement {
444
473
  if (this.pinnedItems.size > 0) {
445
474
  queryParams.set('pinned', Array.from(this.pinnedItems).join(','));
446
475
  }
476
+ if (this.sidebarWidth !== 200) {
477
+ queryParams.set('sidebarWidth', this.sidebarWidth.toString());
478
+ }
447
479
 
448
480
  const queryString = queryParams.toString();
449
481
  const fullUrl = queryString ? `${baseUrl}?${queryString}` : baseUrl;
@@ -507,6 +539,9 @@ export class WccDashboard extends DeesElement {
507
539
  if (this.pinnedItems.size > 0) {
508
540
  queryParams.set('pinned', Array.from(this.pinnedItems).join(','));
509
541
  }
542
+ if (this.sidebarWidth !== 200) {
543
+ queryParams.set('sidebarWidth', this.sidebarWidth.toString());
544
+ }
510
545
 
511
546
  const queryString = queryParams.toString();
512
547
  const fullUrl = queryString ? `${baseUrl}?${queryString}` : baseUrl;
@@ -19,13 +19,18 @@ export class WccFrame extends DeesElement {
19
19
  @property({ type: Boolean })
20
20
  accessor isNative: boolean = false;
21
21
 
22
+ @property({ type: Number })
23
+ accessor sidebarWidth: number = 200;
24
+
25
+ @property({ type: Boolean })
26
+ accessor isResizing: boolean = false;
27
+
22
28
  public static styles = [
23
29
  css`
24
30
  :host {
25
- border: 10px solid #ffaeaf;
31
+ border: 10px solid rgba(255, 174, 175, 1);
26
32
  position: absolute;
27
33
  background: ${cssManager.bdTheme('#333', '#000')};
28
- left: 200px;
29
34
  right: 0px;
30
35
  top: 0px;
31
36
  overflow-y: auto;
@@ -47,17 +52,17 @@ export class WccFrame extends DeesElement {
47
52
  <style>
48
53
  :host {
49
54
  ${this.isNative ? `
50
- border: none !important;
55
+ border: 0px solid rgba(255, 174, 175, 0) !important;
51
56
  left: 0px !important;
52
57
  right: 0px !important;
53
58
  top: 0px !important;
54
59
  bottom: 0px !important;
55
60
  ` : `
56
61
  bottom: ${this.advancedEditorOpen ? '400px' : '100px'};
57
- border: 10px solid #ffaeaf;
58
- left: 200px;
62
+ border: 10px solid rgba(255, 174, 175, 1);
63
+ left: ${this.sidebarWidth}px;
59
64
  `}
60
- transition: all 0.3s ease;
65
+ transition: ${this.isResizing ? 'none' : 'all 0.3s ease'};
61
66
  ${this.isNative ? 'padding: 0px;' : (() => {
62
67
  switch (this.viewport) {
63
68
  case 'desktop':
@@ -67,19 +72,19 @@ export class WccFrame extends DeesElement {
67
72
  case 'tablet':
68
73
  return `
69
74
  padding: 0px ${
70
- (document.body.clientWidth - 200 - domtools.breakpoints.tablet) / 2
75
+ (document.body.clientWidth - this.sidebarWidth - domtools.breakpoints.tablet) / 2
71
76
  }px;
72
77
  `;
73
78
  case 'phablet':
74
79
  return `
75
80
  padding: 0px ${
76
- (document.body.clientWidth - 200 - domtools.breakpoints.phablet) / 2
81
+ (document.body.clientWidth - this.sidebarWidth - domtools.breakpoints.phablet) / 2
77
82
  }px;
78
83
  `;
79
84
  case 'phone':
80
85
  return `
81
86
  padding: 0px ${
82
- (document.body.clientWidth - 200 - domtools.breakpoints.phone) / 2
87
+ (document.body.clientWidth - this.sidebarWidth - domtools.breakpoints.phone) / 2
83
88
  }px;
84
89
  `;
85
90
  }
@@ -37,6 +37,9 @@ export class WccProperties extends DeesElement {
37
37
  @property()
38
38
  accessor isNative: boolean = false;
39
39
 
40
+ @property({ type: Number })
41
+ accessor sidebarWidth: number = 200;
42
+
40
43
  @state()
41
44
  accessor propertyContent: TemplateResult[] = [];
42
45
 
@@ -60,6 +63,10 @@ export class WccProperties extends DeesElement {
60
63
  @state()
61
64
  accessor recordingDuration: number = 0;
62
65
 
66
+ // Delayed hide for native mode transition
67
+ @state()
68
+ accessor isHidden: boolean = false;
69
+
63
70
  public editorHeight: number = 300;
64
71
 
65
72
  public render(): TemplateResult {
@@ -89,14 +96,14 @@ export class WccProperties extends DeesElement {
89
96
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
90
97
  box-sizing: border-box;
91
98
  position: absolute;
92
- left: 200px;
99
+ left: ${this.sidebarWidth}px;
93
100
  height: ${this.editingProperties.length > 0 ? 100 + this.editorHeight : 100}px;
94
101
  bottom: 0px;
95
102
  right: 0px;
96
103
  overflow: hidden;
97
104
  background: var(--background);
98
105
  color: var(--foreground);
99
- display: ${this.isNative ? 'none' : 'block'};
106
+ display: ${this.isHidden ? 'none' : 'block'};
100
107
  }
101
108
  .grid {
102
109
  display: grid;
@@ -928,6 +935,19 @@ export class WccProperties extends DeesElement {
928
935
  protected updated(changedProperties: Map<string, unknown>) {
929
936
  super.updated(changedProperties);
930
937
 
938
+ // Handle delayed hide for native mode transition
939
+ if (changedProperties.has('isNative')) {
940
+ if (this.isNative) {
941
+ // Delay hiding until frame animation completes
942
+ setTimeout(() => {
943
+ this.isHidden = true;
944
+ }, 300);
945
+ } else {
946
+ // Show immediately when exiting native mode
947
+ this.isHidden = false;
948
+ }
949
+ }
950
+
931
951
  // Only recreate properties when selectedItem changes
932
952
  if (changedProperties.has('selectedItem')) {
933
953
  this.createProperties().catch(error => {
@@ -36,6 +36,18 @@ export class WccSidebar extends DeesElement {
36
36
  @property({ attribute: false })
37
37
  accessor pinnedItems: Set<string> = new Set();
38
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
+
47
+ // Delayed hide for native mode transition
48
+ @state()
49
+ accessor isHidden: boolean = false;
50
+
39
51
  private sectionsInitialized = false;
40
52
 
41
53
  public render(): TemplateResult {
@@ -59,14 +71,14 @@ export class WccSidebar extends DeesElement {
59
71
  --ring: #3b82f6;
60
72
  --radius: 4px;
61
73
 
62
- display: ${this.isNative ? 'none' : 'block'};
74
+ display: ${this.isHidden ? 'none' : 'block'};
63
75
  border-right: 1px solid rgba(255, 255, 255, 0.08);
64
76
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
65
77
  font-size: 14px;
66
78
  box-sizing: border-box;
67
79
  position: absolute;
68
80
  left: 0px;
69
- width: 200px;
81
+ width: ${this.sidebarWidth}px;
70
82
  top: 0px;
71
83
  bottom: 0px;
72
84
  overflow-y: auto;
@@ -167,6 +179,10 @@ export class WccSidebar extends DeesElement {
167
179
  grid-template-columns: 16px 1fr;
168
180
  }
169
181
 
182
+ .selectOption.folder .text {
183
+ margin-left: 4px;
184
+ }
185
+
170
186
  .selectOption .expand-icon {
171
187
  font-size: 14px;
172
188
  opacity: 0.5;
@@ -321,13 +337,17 @@ export class WccSidebar extends DeesElement {
321
337
  opacity: 0.8;
322
338
  }
323
339
 
324
- /* Section tag for pinned items */
340
+ /* Section tag pill for pinned items */
325
341
  .section-tag {
326
- font-size: 0.55rem;
327
- color: #555;
342
+ font-size: 0.5rem;
343
+ color: #888;
328
344
  margin-left: auto;
329
345
  text-transform: uppercase;
330
- letter-spacing: 0.03em;
346
+ letter-spacing: 0.02em;
347
+ background: rgba(255, 255, 255, 0.06);
348
+ padding: 0.15rem 0.4rem;
349
+ border-radius: 9999px;
350
+ white-space: nowrap;
331
351
  }
332
352
 
333
353
  /* Group container */
@@ -352,6 +372,27 @@ export class WccSidebar extends DeesElement {
352
372
  margin-left: 0.25rem;
353
373
  margin-right: 0.25rem;
354
374
  }
375
+
376
+ /* Resize handle */
377
+ .resize-handle {
378
+ position: absolute;
379
+ top: 0;
380
+ right: 0;
381
+ bottom: 0;
382
+ width: 4px;
383
+ cursor: col-resize;
384
+ background: transparent;
385
+ transition: background 0.15s ease;
386
+ z-index: 10;
387
+ }
388
+
389
+ .resize-handle:hover {
390
+ background: rgba(59, 130, 246, 0.3);
391
+ }
392
+
393
+ .resize-handle.active {
394
+ background: var(--primary);
395
+ }
355
396
  </style>
356
397
  <div class="search-container">
357
398
  <input
@@ -366,6 +407,10 @@ export class WccSidebar extends DeesElement {
366
407
  ${this.renderPinnedSection()}
367
408
  ${this.renderSections()}
368
409
  </div>
410
+ <div
411
+ class="resize-handle ${this.isResizing ? 'active' : ''}"
412
+ @mousedown=${this.startResize}
413
+ ></div>
369
414
  `;
370
415
  }
371
416
 
@@ -429,6 +474,7 @@ export class WccSidebar extends DeesElement {
429
474
  const isCollapsed = this.collapsedSections.has('__pinned__');
430
475
 
431
476
  // Collect pinned items with their original section info
477
+ // Pinned items are NOT filtered by search - they always remain visible
432
478
  const pinnedEntries: Array<{ sectionName: string; itemName: string; item: any; section: IWccSection }> = [];
433
479
 
434
480
  for (const key of this.pinnedItems) {
@@ -443,10 +489,7 @@ export class WccSidebar extends DeesElement {
443
489
  }
444
490
  }
445
491
 
446
- // Filter by search
447
- const filteredEntries = pinnedEntries.filter(e => this.matchesSearch(e.itemName));
448
-
449
- if (filteredEntries.length === 0 && this.searchQuery) {
492
+ if (pinnedEntries.length === 0) {
450
493
  return null;
451
494
  }
452
495
 
@@ -460,7 +503,7 @@ export class WccSidebar extends DeesElement {
460
503
  <span>Pinned</span>
461
504
  </div>
462
505
  <div class="section-content ${isCollapsed ? 'collapsed' : ''}">
463
- ${filteredEntries.map(({ sectionName, itemName, item, section }) => {
506
+ ${pinnedEntries.map(({ sectionName, itemName, item, section }) => {
464
507
  const isSelected = this.selectedItem === item;
465
508
  const type = section.type === 'elements' ? 'element' : 'page';
466
509
  const icon = section.type === 'elements' ? 'featured_video' : 'insert_drive_file';
@@ -693,6 +736,19 @@ export class WccSidebar extends DeesElement {
693
736
  protected updated(changedProperties: Map<string, unknown>) {
694
737
  super.updated(changedProperties);
695
738
 
739
+ // Handle delayed hide for native mode transition
740
+ if (changedProperties.has('isNative')) {
741
+ if (this.isNative) {
742
+ // Delay hiding until frame animation completes
743
+ setTimeout(() => {
744
+ this.isHidden = true;
745
+ }, 300);
746
+ } else {
747
+ // Show immediately when exiting native mode
748
+ this.isHidden = false;
749
+ }
750
+ }
751
+
696
752
  // Auto-expand folder when a multi-demo element is selected
697
753
  if (changedProperties.has('selectedItem') && this.selectedItem && this.dashboardRef?.sections) {
698
754
  // Find the element in any section
@@ -717,6 +773,51 @@ export class WccSidebar extends DeesElement {
717
773
  }
718
774
  }
719
775
 
776
+ // ============ Resize functionality ============
777
+
778
+ private startResize = (e: MouseEvent) => {
779
+ e.preventDefault();
780
+ this.isResizing = true;
781
+ const startX = e.clientX;
782
+ const startWidth = this.sidebarWidth;
783
+
784
+ // Cache references once at start
785
+ const frame = this.dashboardRef?.shadowRoot?.querySelector('wcc-frame') as any;
786
+ const properties = this.dashboardRef?.shadowRoot?.querySelector('wcc-properties') as any;
787
+
788
+ // Disable frame transition during resize
789
+ if (frame) {
790
+ frame.isResizing = true;
791
+ }
792
+
793
+ const onMouseMove = (e: MouseEvent) => {
794
+ const newWidth = Math.min(400, Math.max(150, startWidth + (e.clientX - startX)));
795
+ this.sidebarWidth = newWidth;
796
+ // Update frame and properties directly
797
+ if (frame) {
798
+ frame.sidebarWidth = newWidth;
799
+ }
800
+ if (properties) {
801
+ properties.sidebarWidth = newWidth;
802
+ }
803
+ };
804
+
805
+ const onMouseUp = () => {
806
+ this.isResizing = false;
807
+ document.removeEventListener('mousemove', onMouseMove);
808
+ document.removeEventListener('mouseup', onMouseUp);
809
+ // Re-enable frame transition
810
+ if (frame) {
811
+ frame.isResizing = false;
812
+ }
813
+ // Dispatch event on release for URL persistence
814
+ this.dispatchEvent(new CustomEvent('widthChanged', { detail: this.sidebarWidth }));
815
+ };
816
+
817
+ document.addEventListener('mousemove', onMouseMove);
818
+ document.addEventListener('mouseup', onMouseUp);
819
+ };
820
+
720
821
  public selectItem(
721
822
  typeArg: TElementType,
722
823
  itemNameArg: string,