@design.estate/dees-wcctools 3.1.2 โ 3.3.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 +293 -101
- package/dist_bundle/bundle.js.map +3 -3
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/wcc-dashboard.d.ts +19 -8
- package/dist_ts_web/elements/wcc-dashboard.js +110 -43
- package/dist_ts_web/elements/wcc-sidebar.d.ts +18 -2
- package/dist_ts_web/elements/wcc-sidebar.js +188 -69
- package/dist_ts_web/index.d.ts +21 -1
- package/dist_ts_web/index.js +55 -3
- package/dist_ts_web/wcctools.interfaces.d.ts +29 -0
- package/dist_ts_web/wcctools.interfaces.js +2 -0
- package/dist_watch/bundle.js +1368 -162
- package/dist_watch/bundle.js.map +4 -4
- package/package.json +1 -1
- package/readme.hints.md +62 -0
- package/readme.md +158 -73
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/wcc-dashboard.ts +107 -35
- package/ts_web/elements/wcc-sidebar.ts +219 -85
- package/ts_web/index.ts +67 -2
- package/ts_web/readme.md +55 -5
- package/ts_web/wcctools.interfaces.ts +31 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@design.estate/dees-wcctools",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
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": {
|
package/readme.hints.md
CHANGED
|
@@ -1,5 +1,67 @@
|
|
|
1
1
|
# Project Hints and Findings
|
|
2
2
|
|
|
3
|
+
## Section-based Configuration API (2025-12-27)
|
|
4
|
+
|
|
5
|
+
### Overview
|
|
6
|
+
Refactored `setupWccTools` to accept a section-based configuration object instead of separate elements/pages arguments. This allows multiple custom sections with filtering, sorting, and collapsible headers.
|
|
7
|
+
|
|
8
|
+
### New API
|
|
9
|
+
```typescript
|
|
10
|
+
import * as deesWccTools from '@design.estate/dees-wcctools';
|
|
11
|
+
|
|
12
|
+
deesWccTools.setupWccTools({
|
|
13
|
+
sections: [
|
|
14
|
+
{
|
|
15
|
+
name: 'Pages',
|
|
16
|
+
type: 'pages',
|
|
17
|
+
items: pages,
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: 'Elements',
|
|
21
|
+
type: 'elements',
|
|
22
|
+
items: elements,
|
|
23
|
+
filter: (name, item) => !name.startsWith('internal-'),
|
|
24
|
+
sort: ([a], [b]) => a.localeCompare(b),
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'Views',
|
|
28
|
+
type: 'elements',
|
|
29
|
+
items: elements,
|
|
30
|
+
filter: (name, item) => name.startsWith('view-'),
|
|
31
|
+
icon: 'web',
|
|
32
|
+
collapsed: true, // Start collapsed
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Section Properties
|
|
39
|
+
- `name`: Display name for the section header
|
|
40
|
+
- `type`: `'elements'` (shows demos) or `'pages'` (renders directly)
|
|
41
|
+
- `items`: Record of items (element classes or page factories)
|
|
42
|
+
- `filter`: Optional `(name, item) => boolean` to filter items
|
|
43
|
+
- `sort`: Optional `([name, item], [name, item]) => number` for ordering
|
|
44
|
+
- `icon`: Optional Material icon name for section header
|
|
45
|
+
- `collapsed`: Optional boolean to start section collapsed
|
|
46
|
+
|
|
47
|
+
### Backwards Compatibility
|
|
48
|
+
Legacy format is still supported:
|
|
49
|
+
```typescript
|
|
50
|
+
deesWccTools.setupWccTools(elements, pages); // Still works
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### URL Routing
|
|
54
|
+
Changed from `/wcctools-route/:itemType/:itemName/...` to `/wcctools-route/:sectionName/:itemName/...`
|
|
55
|
+
Section names are URL-encoded. Legacy routes (`element`/`page` as section name) still work for backwards compatibility.
|
|
56
|
+
|
|
57
|
+
### Files Changed
|
|
58
|
+
- `ts_web/wcctools.interfaces.ts` - New types: `IWccSection`, `IWccConfig`
|
|
59
|
+
- `ts_web/index.ts` - Updated `setupWccTools` with backwards compat detection
|
|
60
|
+
- `ts_web/elements/wcc-dashboard.ts` - Uses sections, updated routing
|
|
61
|
+
- `ts_web/elements/wcc-sidebar.ts` - Dynamic section rendering
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
3
65
|
## UI Redesign with Shadcn-like Styles (2025-06-27)
|
|
4
66
|
|
|
5
67
|
### Changes Made
|
package/readme.md
CHANGED
|
@@ -6,12 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
`@design.estate/dees-wcctools` provides a comprehensive development environment for web components, featuring:
|
|
8
8
|
|
|
9
|
-
- ๐จ **Interactive Component Catalogue** โ Live preview with sidebar
|
|
9
|
+
- ๐จ **Interactive Component Catalogue** โ Live preview with customizable sidebar sections
|
|
10
10
|
- ๐ง **Real-time Property Editing** โ Modify component props on the fly with auto-detected editors
|
|
11
11
|
- ๐ **Theme Switching** โ Test light/dark modes instantly
|
|
12
12
|
- ๐ฑ **Responsive Viewport Testing** โ Phone, phablet, tablet, and desktop views
|
|
13
13
|
- ๐ฌ **Screen Recording** โ Record component demos with audio support and video trimming
|
|
14
14
|
- ๐งช **Advanced Demo Tools** โ Post-render hooks for interactive testing
|
|
15
|
+
- ๐ **Section-based Organization** โ Group components into custom sections with filtering and sorting
|
|
15
16
|
- ๐ **Zero-config Setup** โ TypeScript and Lit support out of the box
|
|
16
17
|
|
|
17
18
|
## Issue Reporting and Security
|
|
@@ -57,29 +58,22 @@ export class MyButton extends DeesElement {
|
|
|
57
58
|
padding: 8px 16px;
|
|
58
59
|
border-radius: 4px;
|
|
59
60
|
border: none;
|
|
60
|
-
font-size: 14px;
|
|
61
61
|
cursor: pointer;
|
|
62
|
-
transition: all 0.3s;
|
|
63
62
|
}
|
|
64
63
|
button.primary {
|
|
65
|
-
background: #
|
|
64
|
+
background: #3b82f6;
|
|
66
65
|
color: white;
|
|
67
66
|
}
|
|
68
67
|
button.secondary {
|
|
69
|
-
background: #
|
|
68
|
+
background: #6b7280;
|
|
70
69
|
color: white;
|
|
71
70
|
}
|
|
72
|
-
button:hover {
|
|
73
|
-
opacity: 0.9;
|
|
74
|
-
}
|
|
75
71
|
`
|
|
76
72
|
];
|
|
77
73
|
|
|
78
74
|
public render() {
|
|
79
75
|
return html`
|
|
80
|
-
<button class="${this.variant}">
|
|
81
|
-
${this.label}
|
|
82
|
-
</button>
|
|
76
|
+
<button class="${this.variant}">${this.label}</button>
|
|
83
77
|
`;
|
|
84
78
|
}
|
|
85
79
|
}
|
|
@@ -93,33 +87,32 @@ import { setupWccTools } from '@design.estate/dees-wcctools';
|
|
|
93
87
|
import { html } from 'lit';
|
|
94
88
|
|
|
95
89
|
// Import your components
|
|
96
|
-
import
|
|
97
|
-
import
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
setupWccTools(elements, pages);
|
|
90
|
+
import * as elements from './components/index.js';
|
|
91
|
+
import * as views from './views/index.js';
|
|
92
|
+
import * as pages from './pages/index.js';
|
|
93
|
+
|
|
94
|
+
// Initialize with sections-based configuration
|
|
95
|
+
setupWccTools({
|
|
96
|
+
sections: [
|
|
97
|
+
{
|
|
98
|
+
name: 'Pages',
|
|
99
|
+
type: 'pages',
|
|
100
|
+
items: pages,
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: 'Views',
|
|
104
|
+
type: 'elements',
|
|
105
|
+
items: views,
|
|
106
|
+
icon: 'web',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: 'Elements',
|
|
110
|
+
type: 'elements',
|
|
111
|
+
items: elements,
|
|
112
|
+
sort: ([a], [b]) => a.localeCompare(b),
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
});
|
|
123
116
|
```
|
|
124
117
|
|
|
125
118
|
### 3. Create an HTML Entry Point
|
|
@@ -137,6 +130,69 @@ setupWccTools(elements, pages);
|
|
|
137
130
|
</html>
|
|
138
131
|
```
|
|
139
132
|
|
|
133
|
+
## ๐ Sections Configuration
|
|
134
|
+
|
|
135
|
+
The sections-based API gives you full control over how components are organized in the sidebar.
|
|
136
|
+
|
|
137
|
+
### Section Properties
|
|
138
|
+
|
|
139
|
+
| Property | Type | Description |
|
|
140
|
+
|----------|------|-------------|
|
|
141
|
+
| `name` | `string` | Display name for the section header |
|
|
142
|
+
| `type` | `'elements' \| 'pages'` | How items render (`elements` show demos, `pages` render directly) |
|
|
143
|
+
| `items` | `Record<string, any>` | Object containing element classes or page factories |
|
|
144
|
+
| `filter` | `(name, item) => boolean` | Optional filter function to include/exclude items |
|
|
145
|
+
| `sort` | `([a, itemA], [b, itemB]) => number` | Optional sort function for ordering items |
|
|
146
|
+
| `icon` | `string` | Optional Material Symbols icon name |
|
|
147
|
+
| `collapsed` | `boolean` | Start section collapsed (default: `false`) |
|
|
148
|
+
|
|
149
|
+
### Advanced Example
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
import { setupWccTools } from '@design.estate/dees-wcctools';
|
|
153
|
+
import * as allElements from './elements/index.js';
|
|
154
|
+
import * as pages from './pages/index.js';
|
|
155
|
+
|
|
156
|
+
setupWccTools({
|
|
157
|
+
sections: [
|
|
158
|
+
{
|
|
159
|
+
name: 'Pages',
|
|
160
|
+
type: 'pages',
|
|
161
|
+
items: pages,
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: 'Form Controls',
|
|
165
|
+
type: 'elements',
|
|
166
|
+
items: allElements,
|
|
167
|
+
icon: 'edit_note',
|
|
168
|
+
filter: (name) => name.startsWith('form-') || name.includes('input'),
|
|
169
|
+
sort: ([a], [b]) => a.localeCompare(b),
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
name: 'Layout',
|
|
173
|
+
type: 'elements',
|
|
174
|
+
items: allElements,
|
|
175
|
+
icon: 'dashboard',
|
|
176
|
+
filter: (name) => name.startsWith('layout-') || name.startsWith('grid-'),
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
name: 'Legacy',
|
|
180
|
+
type: 'elements',
|
|
181
|
+
items: allElements,
|
|
182
|
+
filter: (name) => name.startsWith('legacy-'),
|
|
183
|
+
collapsed: true, // Start collapsed
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Legacy API (Still Supported)
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
// The old format still works for simple use cases
|
|
193
|
+
setupWccTools(elements, pages);
|
|
194
|
+
```
|
|
195
|
+
|
|
140
196
|
## Features
|
|
141
197
|
|
|
142
198
|
### ๐ฏ Live Property Editing
|
|
@@ -162,19 +218,7 @@ Test your components across different screen sizes:
|
|
|
162
218
|
|
|
163
219
|
### ๐ Theme Support
|
|
164
220
|
|
|
165
|
-
Components automatically adapt to light/dark themes
|
|
166
|
-
|
|
167
|
-
```typescript
|
|
168
|
-
public render() {
|
|
169
|
-
return html`
|
|
170
|
-
<div class="${this.goBright ? 'light-theme' : 'dark-theme'}">
|
|
171
|
-
<!-- Your component content -->
|
|
172
|
-
</div>
|
|
173
|
-
`;
|
|
174
|
-
}
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
Or use CSS custom properties with the theme manager:
|
|
221
|
+
Components automatically adapt to light/dark themes. Use CSS custom properties with the theme manager:
|
|
178
222
|
|
|
179
223
|
```typescript
|
|
180
224
|
import { cssManager } from '@design.estate/dees-element';
|
|
@@ -182,8 +226,8 @@ import { cssManager } from '@design.estate/dees-element';
|
|
|
182
226
|
public static styles = [
|
|
183
227
|
css`
|
|
184
228
|
:host {
|
|
185
|
-
color: ${cssManager.bdTheme('#
|
|
186
|
-
background: ${cssManager.bdTheme('#
|
|
229
|
+
color: ${cssManager.bdTheme('#1a1a1a', '#e5e5e5')};
|
|
230
|
+
background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')};
|
|
187
231
|
}
|
|
188
232
|
`
|
|
189
233
|
];
|
|
@@ -191,7 +235,7 @@ public static styles = [
|
|
|
191
235
|
|
|
192
236
|
### ๐ฌ Screen Recording
|
|
193
237
|
|
|
194
|
-
Record component demos directly from the catalogue
|
|
238
|
+
Record component demos directly from the catalogue:
|
|
195
239
|
|
|
196
240
|
- **Viewport Recording** โ Record just the component viewport
|
|
197
241
|
- **Full Screen Recording** โ Capture the entire screen
|
|
@@ -232,9 +276,26 @@ export class MyComponent extends DeesElement {
|
|
|
232
276
|
}
|
|
233
277
|
```
|
|
234
278
|
|
|
279
|
+
### ๐ญ Multiple Demos
|
|
280
|
+
|
|
281
|
+
Components can expose multiple demo variations:
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
@customElement('my-button')
|
|
285
|
+
export class MyButton extends DeesElement {
|
|
286
|
+
public static demo = [
|
|
287
|
+
() => html`<my-button variant="primary">Primary</my-button>`,
|
|
288
|
+
() => html`<my-button variant="secondary">Secondary</my-button>`,
|
|
289
|
+
() => html`<my-button variant="danger">Danger</my-button>`,
|
|
290
|
+
];
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Each demo appears as a numbered item in an expandable folder in the sidebar.
|
|
295
|
+
|
|
235
296
|
### โณ Async Demos
|
|
236
297
|
|
|
237
|
-
Return a `Promise` from `demo` for async setup
|
|
298
|
+
Return a `Promise` from `demo` for async setup:
|
|
238
299
|
|
|
239
300
|
```typescript
|
|
240
301
|
public static demo = async () => {
|
|
@@ -243,7 +304,7 @@ public static demo = async () => {
|
|
|
243
304
|
};
|
|
244
305
|
```
|
|
245
306
|
|
|
246
|
-
###
|
|
307
|
+
### ๐ฏ Container Queries
|
|
247
308
|
|
|
248
309
|
Components can respond to their container size using the `wccToolsViewport` container:
|
|
249
310
|
|
|
@@ -269,7 +330,7 @@ public static styles = [
|
|
|
269
330
|
|
|
270
331
|
### Required for Catalogue Display
|
|
271
332
|
|
|
272
|
-
1. Components must expose a static `demo` property returning a Lit template
|
|
333
|
+
1. Components must expose a static `demo` property returning a Lit template (or array of templates)
|
|
273
334
|
2. Use `@property()` decorators with the `accessor` keyword for editable properties
|
|
274
335
|
3. Export component classes for proper detection
|
|
275
336
|
|
|
@@ -278,7 +339,7 @@ public static styles = [
|
|
|
278
339
|
```typescript
|
|
279
340
|
@customElement('best-practice-component')
|
|
280
341
|
export class BestPracticeComponent extends DeesElement {
|
|
281
|
-
// โ
Static demo property
|
|
342
|
+
// โ
Static demo property (single or array)
|
|
282
343
|
public static demo = () => html`
|
|
283
344
|
<best-practice-component
|
|
284
345
|
.complexProp=${{ key: 'value' }}
|
|
@@ -305,23 +366,40 @@ export class BestPracticeComponent extends DeesElement {
|
|
|
305
366
|
The catalogue uses URL routing for deep linking:
|
|
306
367
|
|
|
307
368
|
```
|
|
308
|
-
/wcctools-route/:
|
|
369
|
+
/wcctools-route/:sectionName/:itemName/:demoIndex/:viewport/:theme
|
|
309
370
|
|
|
310
371
|
Examples:
|
|
311
|
-
/wcctools-route/
|
|
312
|
-
/wcctools-route/
|
|
372
|
+
/wcctools-route/Elements/my-button/0/desktop/dark
|
|
373
|
+
/wcctools-route/Views/view-dashboard/0/tablet/bright
|
|
374
|
+
/wcctools-route/Pages/home/0/desktop/dark
|
|
313
375
|
```
|
|
314
376
|
|
|
315
377
|
## API Reference
|
|
316
378
|
|
|
317
|
-
### `setupWccTools(
|
|
379
|
+
### `setupWccTools(config)`
|
|
380
|
+
|
|
381
|
+
Initialize the WCC Tools dashboard with sections configuration.
|
|
318
382
|
|
|
319
|
-
|
|
383
|
+
```typescript
|
|
384
|
+
interface IWccSection {
|
|
385
|
+
name: string;
|
|
386
|
+
type: 'elements' | 'pages';
|
|
387
|
+
items: Record<string, any>;
|
|
388
|
+
filter?: (name: string, item: any) => boolean;
|
|
389
|
+
sort?: (a: [string, any], b: [string, any]) => number;
|
|
390
|
+
icon?: string;
|
|
391
|
+
collapsed?: boolean;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
interface IWccConfig {
|
|
395
|
+
sections: IWccSection[];
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
setupWccTools(config: IWccConfig): void;
|
|
320
399
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
| `pages` | `Record<string, TTemplateFactory>` | Optional map of page names to template functions |
|
|
400
|
+
// Legacy (still supported)
|
|
401
|
+
setupWccTools(elements: Record<string, any>, pages?: Record<string, TTemplateFactory>): void;
|
|
402
|
+
```
|
|
325
403
|
|
|
326
404
|
### `DeesDemoWrapper`
|
|
327
405
|
|
|
@@ -357,14 +435,21 @@ recorder.stopRecording();
|
|
|
357
435
|
## Project Structure
|
|
358
436
|
|
|
359
437
|
```
|
|
360
|
-
my-
|
|
438
|
+
my-component-library/
|
|
361
439
|
โโโ src/
|
|
362
|
-
โ โโโ components
|
|
440
|
+
โ โโโ elements/ # UI components
|
|
363
441
|
โ โ โโโ my-button.ts
|
|
364
|
-
โ โ
|
|
365
|
-
โ โโโ
|
|
366
|
-
โโโ
|
|
367
|
-
โโโ
|
|
442
|
+
โ โ โโโ my-card.ts
|
|
443
|
+
โ โ โโโ index.ts
|
|
444
|
+
โ โโโ views/ # Full-page layouts
|
|
445
|
+
โ โ โโโ view-dashboard.ts
|
|
446
|
+
โ โ โโโ index.ts
|
|
447
|
+
โ โโโ pages/ # Documentation pages
|
|
448
|
+
โ โ โโโ home.ts
|
|
449
|
+
โ โ โโโ index.ts
|
|
450
|
+
โ โโโ catalogue.ts # WCC Tools setup
|
|
451
|
+
โโโ html/
|
|
452
|
+
โ โโโ index.html
|
|
368
453
|
โโโ package.json
|
|
369
454
|
```
|
|
370
455
|
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@design.estate/dees-wcctools',
|
|
6
|
-
version: '3.
|
|
6
|
+
version: '3.3.0',
|
|
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
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DeesElement, property, html, customElement, type TemplateResult, queryAsync, render, domtools } from '@design.estate/dees-element';
|
|
2
2
|
import { resolveTemplateFactory, getDemoAtIndex, getDemoCount, hasMultipleDemos } from './wcctools.helpers.js';
|
|
3
3
|
import type { TTemplateFactory } from './wcctools.helpers.js';
|
|
4
|
+
import type { IWccConfig, IWccSection, TElementType } from '../wcctools.interfaces.js';
|
|
4
5
|
|
|
5
6
|
import * as plugins from '../wcctools.plugins.js';
|
|
6
7
|
|
|
@@ -9,13 +10,37 @@ import './wcc-frame.js';
|
|
|
9
10
|
import './wcc-sidebar.js';
|
|
10
11
|
import './wcc-properties.js';
|
|
11
12
|
import { type TTheme } from './wcc-properties.js';
|
|
12
|
-
import { type TElementType } from './wcc-sidebar.js';
|
|
13
13
|
import { breakpoints } from '@design.estate/dees-domtools';
|
|
14
14
|
import { WccFrame } from './wcc-frame.js';
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Get filtered and sorted items from a section
|
|
18
|
+
*/
|
|
19
|
+
export const getSectionItems = (section: IWccSection): Array<[string, any]> => {
|
|
20
|
+
let entries = Object.entries(section.items);
|
|
21
|
+
|
|
22
|
+
// Apply filter if provided
|
|
23
|
+
if (section.filter) {
|
|
24
|
+
entries = entries.filter(([name, item]) => section.filter(name, item));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Apply sort if provided
|
|
28
|
+
if (section.sort) {
|
|
29
|
+
entries.sort(section.sort);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return entries;
|
|
33
|
+
};
|
|
34
|
+
|
|
16
35
|
@customElement('wcc-dashboard')
|
|
17
36
|
export class WccDashboard extends DeesElement {
|
|
18
37
|
|
|
38
|
+
@property()
|
|
39
|
+
accessor sections: IWccSection[] = [];
|
|
40
|
+
|
|
41
|
+
@property()
|
|
42
|
+
accessor selectedSection: IWccSection | null = null;
|
|
43
|
+
|
|
19
44
|
@property()
|
|
20
45
|
accessor selectedType: TElementType;
|
|
21
46
|
|
|
@@ -39,36 +64,43 @@ export class WccDashboard extends DeesElement {
|
|
|
39
64
|
return this.selectedViewport === 'native';
|
|
40
65
|
}
|
|
41
66
|
|
|
42
|
-
@property()
|
|
43
|
-
accessor pages: Record<string, TTemplateFactory> = {};
|
|
44
|
-
|
|
45
|
-
@property()
|
|
46
|
-
accessor elements: { [key: string]: DeesElement } = {};
|
|
47
|
-
|
|
48
67
|
@property()
|
|
49
68
|
accessor warning: string = null;
|
|
50
|
-
|
|
69
|
+
|
|
51
70
|
private frameScrollY: number = 0;
|
|
52
71
|
private sidebarScrollY: number = 0;
|
|
53
72
|
private scrollPositionsApplied: boolean = false;
|
|
54
|
-
|
|
73
|
+
|
|
55
74
|
@queryAsync('wcc-frame')
|
|
56
75
|
accessor wccFrame: Promise<WccFrame>;
|
|
57
76
|
|
|
58
|
-
constructor(
|
|
59
|
-
elementsArg?: { [key: string]: DeesElement },
|
|
60
|
-
pagesArg?: Record<string, TTemplateFactory>
|
|
61
|
-
) {
|
|
77
|
+
constructor(config?: IWccConfig) {
|
|
62
78
|
super();
|
|
63
|
-
if (
|
|
64
|
-
this.
|
|
65
|
-
console.log('got
|
|
66
|
-
console.log(this.elements);
|
|
79
|
+
if (config && config.sections) {
|
|
80
|
+
this.sections = config.sections;
|
|
81
|
+
console.log('got sections:', this.sections.map(s => s.name));
|
|
67
82
|
}
|
|
83
|
+
}
|
|
68
84
|
|
|
69
|
-
|
|
70
|
-
|
|
85
|
+
/**
|
|
86
|
+
* Find an item by name across all sections, returns the item and its section
|
|
87
|
+
*/
|
|
88
|
+
public findItemByName(name: string): { item: any; section: IWccSection } | null {
|
|
89
|
+
for (const section of this.sections) {
|
|
90
|
+
const entries = getSectionItems(section);
|
|
91
|
+
const found = entries.find(([itemName]) => itemName === name);
|
|
92
|
+
if (found) {
|
|
93
|
+
return { item: found[1], section };
|
|
94
|
+
}
|
|
71
95
|
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Find a section by name (URL-decoded)
|
|
101
|
+
*/
|
|
102
|
+
public findSectionByName(name: string): IWccSection | null {
|
|
103
|
+
return this.sections.find(s => s.name === name) || null;
|
|
72
104
|
}
|
|
73
105
|
|
|
74
106
|
public render(): TemplateResult {
|
|
@@ -159,19 +191,37 @@ export class WccDashboard extends DeesElement {
|
|
|
159
191
|
this.setupScrollListeners();
|
|
160
192
|
}, 500);
|
|
161
193
|
|
|
162
|
-
//
|
|
194
|
+
// New route format with section name
|
|
163
195
|
this.domtools.router.on(
|
|
164
|
-
'/wcctools-route/:
|
|
196
|
+
'/wcctools-route/:sectionName/:itemName/:demoIndex/:viewport/:theme',
|
|
165
197
|
async (routeInfo) => {
|
|
166
|
-
|
|
198
|
+
const sectionName = decodeURIComponent(routeInfo.params.sectionName);
|
|
199
|
+
this.selectedSection = this.findSectionByName(sectionName);
|
|
167
200
|
this.selectedItemName = routeInfo.params.itemName;
|
|
168
201
|
this.selectedDemoIndex = parseInt(routeInfo.params.demoIndex) || 0;
|
|
169
202
|
this.selectedViewport = routeInfo.params.viewport as breakpoints.TViewport;
|
|
170
203
|
this.selectedTheme = routeInfo.params.theme as TTheme;
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
204
|
+
|
|
205
|
+
if (this.selectedSection) {
|
|
206
|
+
// Find item within the section
|
|
207
|
+
const entries = getSectionItems(this.selectedSection);
|
|
208
|
+
const found = entries.find(([name]) => name === routeInfo.params.itemName);
|
|
209
|
+
if (found) {
|
|
210
|
+
this.selectedItem = found[1];
|
|
211
|
+
this.selectedType = this.selectedSection.type === 'elements' ? 'element' : 'page';
|
|
212
|
+
}
|
|
213
|
+
} else {
|
|
214
|
+
// Fallback: try legacy format (element/page as section name)
|
|
215
|
+
const legacyType = routeInfo.params.sectionName;
|
|
216
|
+
if (legacyType === 'element' || legacyType === 'page') {
|
|
217
|
+
this.selectedType = legacyType as TElementType;
|
|
218
|
+
// Find item in any matching section
|
|
219
|
+
const result = this.findItemByName(routeInfo.params.itemName);
|
|
220
|
+
if (result) {
|
|
221
|
+
this.selectedItem = result.item;
|
|
222
|
+
this.selectedSection = result.section;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
175
225
|
}
|
|
176
226
|
|
|
177
227
|
// Restore scroll positions from query parameters
|
|
@@ -201,17 +251,33 @@ export class WccDashboard extends DeesElement {
|
|
|
201
251
|
|
|
202
252
|
// Legacy route without demo index (for backwards compatibility)
|
|
203
253
|
this.domtools.router.on(
|
|
204
|
-
'/wcctools-route/:
|
|
254
|
+
'/wcctools-route/:sectionName/:itemName/:viewport/:theme',
|
|
205
255
|
async (routeInfo) => {
|
|
206
|
-
|
|
256
|
+
const sectionName = decodeURIComponent(routeInfo.params.sectionName);
|
|
257
|
+
this.selectedSection = this.findSectionByName(sectionName);
|
|
207
258
|
this.selectedItemName = routeInfo.params.itemName;
|
|
208
|
-
this.selectedDemoIndex = 0;
|
|
259
|
+
this.selectedDemoIndex = 0;
|
|
209
260
|
this.selectedViewport = routeInfo.params.viewport as breakpoints.TViewport;
|
|
210
261
|
this.selectedTheme = routeInfo.params.theme as TTheme;
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
262
|
+
|
|
263
|
+
if (this.selectedSection) {
|
|
264
|
+
const entries = getSectionItems(this.selectedSection);
|
|
265
|
+
const found = entries.find(([name]) => name === routeInfo.params.itemName);
|
|
266
|
+
if (found) {
|
|
267
|
+
this.selectedItem = found[1];
|
|
268
|
+
this.selectedType = this.selectedSection.type === 'elements' ? 'element' : 'page';
|
|
269
|
+
}
|
|
270
|
+
} else {
|
|
271
|
+
// Fallback: try legacy format
|
|
272
|
+
const legacyType = routeInfo.params.sectionName;
|
|
273
|
+
if (legacyType === 'element' || legacyType === 'page') {
|
|
274
|
+
this.selectedType = legacyType as TElementType;
|
|
275
|
+
const result = this.findItemByName(routeInfo.params.itemName);
|
|
276
|
+
if (result) {
|
|
277
|
+
this.selectedItem = result.item;
|
|
278
|
+
this.selectedSection = result.section;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
215
281
|
}
|
|
216
282
|
|
|
217
283
|
// Restore scroll positions from query parameters
|
|
@@ -297,7 +363,10 @@ export class WccDashboard extends DeesElement {
|
|
|
297
363
|
}
|
|
298
364
|
|
|
299
365
|
public buildUrl() {
|
|
300
|
-
const
|
|
366
|
+
const sectionName = this.selectedSection
|
|
367
|
+
? encodeURIComponent(this.selectedSection.name)
|
|
368
|
+
: this.selectedType; // Fallback for legacy
|
|
369
|
+
const baseUrl = `/wcctools-route/${sectionName}/${this.selectedItemName}/${this.selectedDemoIndex}/${this.selectedViewport}/${this.selectedTheme}`;
|
|
301
370
|
const queryParams = new URLSearchParams();
|
|
302
371
|
|
|
303
372
|
if (this.frameScrollY > 0) {
|
|
@@ -351,7 +420,10 @@ export class WccDashboard extends DeesElement {
|
|
|
351
420
|
}
|
|
352
421
|
|
|
353
422
|
private updateUrlWithScrollState() {
|
|
354
|
-
const
|
|
423
|
+
const sectionName = this.selectedSection
|
|
424
|
+
? encodeURIComponent(this.selectedSection.name)
|
|
425
|
+
: this.selectedType; // Fallback for legacy
|
|
426
|
+
const baseUrl = `/wcctools-route/${sectionName}/${this.selectedItemName}/${this.selectedDemoIndex}/${this.selectedViewport}/${this.selectedTheme}`;
|
|
355
427
|
const queryParams = new URLSearchParams();
|
|
356
428
|
|
|
357
429
|
if (this.frameScrollY > 0) {
|