@pure-ds/core 0.4.26 → 0.4.28
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/.cursorrules +180 -86
- package/.github/copilot-instructions.md +26 -118
- package/dist/types/pds.d.ts +470 -109
- package/dist/types/public/assets/js/pds.d.ts +2 -2
- package/dist/types/public/assets/js/pds.d.ts.map +1 -1
- package/dist/types/src/js/pds-core/pds-enhancers.d.ts +14 -0
- package/dist/types/src/js/pds-core/pds-enhancers.d.ts.map +1 -1
- package/package.json +1 -1
- package/packages/pds-cli/bin/pds-setup-copilot.js +1 -1
- package/packages/pds-cli/bin/pds-static.js +27 -2
- package/packages/pds-cli/bin/postinstall.mjs +1 -1
- package/public/assets/js/app.js +45 -45
- package/public/assets/js/pds.js +19 -19
- package/public/assets/pds/custom-elements.json +168 -164
- package/src/js/pds-core/pds-enhancers.js +136 -3
- package/src/js/pds.js +7 -1
- package/CSS-INTELLISENSE-LIMITATION.md +0 -98
- package/CSS-INTELLISENSE-QUICK-REF.md +0 -238
- package/src/js/pds-core/pds-enhancer-metadata.js +0 -96
package/.cursorrules
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# PDS (Pure Design System) -
|
|
1
|
+
# PDS (Pure Design System) - AI Generation Instructions
|
|
2
2
|
|
|
3
|
-
> **CRITICAL**: This workspace uses **Pure Design System (PDS)**. All code generation MUST follow PDS patterns. Never use
|
|
3
|
+
> **CRITICAL**: This workspace uses **Pure Design System (PDS)**. All code generation MUST follow PDS and vanilla Web Platform patterns. Never use 3rd party framework patterns, non-PDS utility classes, inline styles, or hardcoded CSS values.
|
|
4
4
|
|
|
5
5
|
## Philosophy
|
|
6
6
|
|
|
@@ -31,7 +31,7 @@ PDS follows the [Pure Web Manifesto](https://pureweb.dev/manifesto): "The browse
|
|
|
31
31
|
| **Web Components** | `custom-elements.json` | Complete component APIs, attributes, methods, events, slots |
|
|
32
32
|
| **HTML Tags** | `public/assets/pds/vscode-custom-data.json` | Component HTML structure, attribute values |
|
|
33
33
|
| **Primitives & Utilities** | `src/js/pds-core/pds-ontology.js` | `.card`, `.badge`, `.btn-*`, `.flex`, `.gap-*`, `.surface-*` |
|
|
34
|
-
| **Enhancements** | `src/js/pds-core/pds-
|
|
34
|
+
| **Enhancements** | `src/js/pds-core/pds-enhancers.js` | Enhancement metadata (`defaultPDSEnhancerMetadata`) + runtime (`defaultPDSEnhancers`) |
|
|
35
35
|
| **Generator Logic** | `src/js/pds-core/pds-generator.js` | How CSS is generated, token naming conventions |
|
|
36
36
|
| **Config** | `pds.config.js` | What's enabled in this workspace |
|
|
37
37
|
|
|
@@ -94,95 +94,147 @@ async function simulateSubmit(data) {
|
|
|
94
94
|
}
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
-
### 3.
|
|
97
|
+
### 3. Adding `data-required` to pds-form generated form: simply add the attribute to the pds-form tag
|
|
98
98
|
|
|
99
99
|
```html
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
100
|
+
<pds-form data-required id="myForm" hide-actions></pds-form>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 4. Placeholders - ALWAYS include examples
|
|
104
|
+
|
|
105
|
+
**Placeholders improve UX significantly. Try to add 'examples' array to schema properties:**
|
|
106
|
+
|
|
107
|
+
**Rule: When generating a form, infer appropriate placeholders based on field name/type if not specified.**
|
|
107
108
|
|
|
108
|
-
|
|
109
|
-
|
|
109
|
+
### 5. Smart Icons - Infer from field semantics
|
|
110
|
+
|
|
111
|
+
**When generating forms, automatically add appropriate icons based on field names and semantics.**
|
|
112
|
+
|
|
113
|
+
**Sources of truth for available icons:**
|
|
114
|
+
- Check `pds.config.js` for project-specific icon configuration
|
|
115
|
+
- Consult icon sprite at `public/assets/img/icons/pds-icons.svg` for available icons
|
|
116
|
+
- See `public/assets/pds/vscode-custom-data.json` for icon attribute values
|
|
117
|
+
|
|
118
|
+
**Use semantic reasoning to match field names to appropriate icons:**
|
|
119
|
+
|
|
120
|
+
```javascript
|
|
121
|
+
// ✅ CORRECT: Infer icons based on field semantics
|
|
122
|
+
const uiSchema = {
|
|
123
|
+
"/email": { 'ui:icon': 'envelope', 'ui:autocomplete': 'email' },
|
|
124
|
+
"/phone": { 'ui:icon': 'phone', 'ui:autocomplete': 'tel' },
|
|
125
|
+
"/name": { 'ui:icon': 'user', 'ui:autocomplete': 'name' },
|
|
126
|
+
"/password": { 'ui:icon': 'lock', 'ui:widget': 'password' },
|
|
127
|
+
"/website": { 'ui:icon': 'link' },
|
|
128
|
+
"/address": { 'ui:icon': 'map-pin' },
|
|
129
|
+
"/date": { 'ui:icon': 'calendar' },
|
|
130
|
+
"/message": { 'ui:widget': 'textarea', 'ui:icon': 'message' }
|
|
131
|
+
};
|
|
110
132
|
```
|
|
111
133
|
|
|
112
|
-
|
|
134
|
+
**Rule: When generating forms, analyze field names/types and select semantically appropriate icons from the available icon set.**
|
|
135
|
+
|
|
136
|
+
### 6. Submit Handler Pattern - ALWAYS provide working async handler
|
|
137
|
+
|
|
138
|
+
**When generating a pds-form, ALWAYS include a complete, iteration-ready submit handler with:**
|
|
139
|
+
- `pw:submit` event (NOT native submit)
|
|
140
|
+
- `btn-working` class for loading state
|
|
141
|
+
- `PDS.toast()` for user feedback
|
|
142
|
+
- Error handling
|
|
143
|
+
- Realistic async simulation
|
|
113
144
|
|
|
114
145
|
```javascript
|
|
115
|
-
// ✅ CORRECT:
|
|
116
|
-
|
|
117
|
-
type
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
146
|
+
// ✅ CORRECT: Complete submit handler pattern
|
|
147
|
+
form.addEventListener('pw:submit', async (e) => {
|
|
148
|
+
const submitBtn = form.querySelector('button[type="submit"]');
|
|
149
|
+
submitBtn?.classList.add('btn-working');
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
// Simulate async operation (replace with real API call)
|
|
153
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
154
|
+
|
|
155
|
+
// Log the data for debugging
|
|
156
|
+
console.log('Submitted data:', e.detail.json);
|
|
157
|
+
|
|
158
|
+
// Show success toast
|
|
159
|
+
await PDS.toast('Form submitted successfully!', { type: 'success' });
|
|
160
|
+
|
|
161
|
+
// Optionally reset form
|
|
162
|
+
form.reset();
|
|
163
|
+
} catch (error) {
|
|
164
|
+
// Show error toast
|
|
165
|
+
await PDS.toast('Submission failed: ' + error.message, { type: 'error' });
|
|
166
|
+
} finally {
|
|
167
|
+
// Always remove loading state
|
|
168
|
+
submitBtn?.classList.remove('btn-working');
|
|
135
169
|
}
|
|
136
|
-
};
|
|
170
|
+
});
|
|
137
171
|
|
|
138
|
-
// ❌ WRONG:
|
|
172
|
+
// ❌ WRONG: Native submit event
|
|
173
|
+
form.addEventListener('submit', (e) => { /* Won't work */ });
|
|
174
|
+
|
|
175
|
+
// ❌ WRONG: No loading state
|
|
176
|
+
form.addEventListener('pw:submit', async (e) => {
|
|
177
|
+
await fetch('/api'); // No visual feedback!
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// ❌ WRONG: Browser dialogs
|
|
181
|
+
form.addEventListener('pw:submit', async (e) => {
|
|
182
|
+
alert('Submitted!'); // Use PDS.toast() instead
|
|
183
|
+
});
|
|
139
184
|
```
|
|
140
185
|
|
|
141
|
-
|
|
186
|
+
**PDS.toast() is available globally via window.PDS:**
|
|
187
|
+
|
|
188
|
+
```javascript
|
|
189
|
+
// All toast types
|
|
190
|
+
await PDS.toast('Success message', { type: 'success' });
|
|
191
|
+
await PDS.toast('Error occurred', { type: 'error' });
|
|
192
|
+
await PDS.toast('Warning message', { type: 'warning' });
|
|
193
|
+
await PDS.toast('Info message', { type: 'information' });
|
|
142
194
|
|
|
143
|
-
|
|
195
|
+
// Custom duration (auto-calculated by default based on message length)
|
|
196
|
+
await PDS.toast('Quick message', { type: 'info', duration: 3000 });
|
|
197
|
+
|
|
198
|
+
// Persistent (requires manual close)
|
|
199
|
+
await PDS.toast('Important notice', { type: 'warning', persistent: true });
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### 7. Conditional "Other" Fields - Auto-generate ui:visibleWhen
|
|
203
|
+
|
|
204
|
+
**When a schema has an "Other" enum option, ALWAYS auto-generate a conditional text field:**
|
|
144
205
|
|
|
145
206
|
```javascript
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
207
|
+
const schema = {
|
|
208
|
+
type: "object",
|
|
209
|
+
properties: {
|
|
210
|
+
reason: {
|
|
211
|
+
type: "string",
|
|
212
|
+
title: "How did you hear about us?",
|
|
213
|
+
oneOf: [
|
|
214
|
+
{ const: "search", title: "Search Engine" },
|
|
215
|
+
{ const: "social", title: "Social Media" },
|
|
216
|
+
{ const: "friend", title: "Friend Referral" },
|
|
217
|
+
{ const: "other", title: "Other... (please specify)" }, // ← "Other" option
|
|
218
|
+
],
|
|
219
|
+
},
|
|
220
|
+
otherReason: { // ← Conditional field for "Other"
|
|
221
|
+
type: "string",
|
|
222
|
+
title: "Please specify",
|
|
223
|
+
examples: ["Tell us more..."],
|
|
224
|
+
},
|
|
225
|
+
},
|
|
163
226
|
};
|
|
164
227
|
|
|
165
228
|
const uiSchema = {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
'ui:autocomplete': 'email'
|
|
171
|
-
},
|
|
172
|
-
phone: {
|
|
173
|
-
'ui:widget': 'tel',
|
|
174
|
-
'ui:icon': 'phone',
|
|
175
|
-
'ui:autocomplete': 'tel'
|
|
229
|
+
// ✅ ALWAYS add these when "other" enum exists
|
|
230
|
+
"/otherReason": {
|
|
231
|
+
"ui:visibleWhen": { "/reason": "other" },
|
|
232
|
+
"ui:requiredWhen": { "/reason": "other" },
|
|
176
233
|
},
|
|
177
|
-
message: {
|
|
178
|
-
'ui:widget': 'textarea',
|
|
179
|
-
'ui:rows': 4,
|
|
180
|
-
'ui:icon': 'message'
|
|
181
|
-
}
|
|
182
234
|
};
|
|
183
235
|
```
|
|
184
236
|
|
|
185
|
-
###
|
|
237
|
+
### 8. Complete Working Example
|
|
186
238
|
|
|
187
239
|
```javascript
|
|
188
240
|
// Schema with examples for placeholders
|
|
@@ -213,9 +265,9 @@ const contactSchema = {
|
|
|
213
265
|
|
|
214
266
|
// UI schema with smart icons
|
|
215
267
|
const uiSchema = {
|
|
216
|
-
name: { 'ui:icon': 'user' },
|
|
217
|
-
email: { 'ui:icon': 'envelope' },
|
|
218
|
-
message: {
|
|
268
|
+
"/name": { 'ui:icon': 'user' },
|
|
269
|
+
"/email": { 'ui:icon': 'envelope' },
|
|
270
|
+
"/message": {
|
|
219
271
|
'ui:widget': 'textarea',
|
|
220
272
|
'ui:rows': 4,
|
|
221
273
|
'ui:icon': 'message'
|
|
@@ -296,6 +348,45 @@ const schema = {
|
|
|
296
348
|
|
|
297
349
|
---
|
|
298
350
|
|
|
351
|
+
## ⚡ Lit Components & Import Maps
|
|
352
|
+
|
|
353
|
+
**Components that require Lit:** `pds-form`
|
|
354
|
+
|
|
355
|
+
This component uses `import { ... } from "#pds/lit"` and **requires** an import map:
|
|
356
|
+
|
|
357
|
+
```html
|
|
358
|
+
<!-- REQUIRED in HTML <head> for Lit components -->
|
|
359
|
+
<script type="importmap">
|
|
360
|
+
{
|
|
361
|
+
"imports": {
|
|
362
|
+
"#pds/lit": "/assets/js/lit.js"
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
</script>
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
**When generating code with lazy-loaded components, ALWAYS wait for definition:**
|
|
369
|
+
|
|
370
|
+
```javascript
|
|
371
|
+
// ✅ CORRECT: Wait for component to load
|
|
372
|
+
await customElements.whenDefined('pds-form');
|
|
373
|
+
const form = document.querySelector('pds-form');
|
|
374
|
+
form.getFormData(); // Safe
|
|
375
|
+
|
|
376
|
+
// ✅ CORRECT: Alternative pattern
|
|
377
|
+
const FormClass = await customElements.get('pds-form');
|
|
378
|
+
if (FormClass) {
|
|
379
|
+
const form = document.createElement('pds-form');
|
|
380
|
+
// ...
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// ❌ WRONG: Direct access without waiting
|
|
384
|
+
const form = document.querySelector('pds-form');
|
|
385
|
+
form.getFormData(); // May throw error
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
299
390
|
## ✅ Quick Reference Patterns
|
|
300
391
|
|
|
301
392
|
```html
|
|
@@ -324,7 +415,7 @@ const schema = {
|
|
|
324
415
|
<pds-icon icon="heart" size="sm"></pds-icon>
|
|
325
416
|
<pds-icon icon="check" size="lg" color="var(--color-success-500)"></pds-icon>
|
|
326
417
|
|
|
327
|
-
<!-- Enhancements: data attributes (see pds-
|
|
418
|
+
<!-- Enhancements: data attributes (see pds-enhancers.js → defaultPDSEnhancerMetadata) -->
|
|
328
419
|
<nav data-dropdown>
|
|
329
420
|
<button>Menu</button>
|
|
330
421
|
<menu><li><a href="#">Item</a></li></menu>
|
|
@@ -341,10 +432,12 @@ const schema = {
|
|
|
341
432
|
|
|
342
433
|
<!-- Tabs: web component -->
|
|
343
434
|
<pds-tabstrip>
|
|
344
|
-
<
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
<
|
|
435
|
+
<pds-tabpanel label="Tab 1">
|
|
436
|
+
<p>Content for Tab 1</p>
|
|
437
|
+
</pds-tabpanel>
|
|
438
|
+
<pds-tabpanel label="Tab 2">
|
|
439
|
+
<p>Content for Tab 2</p>
|
|
440
|
+
</pds-tabpanel>
|
|
348
441
|
</pds-tabstrip>
|
|
349
442
|
```
|
|
350
443
|
|
|
@@ -369,14 +462,15 @@ const results = await PDS.query("border gradient classes");
|
|
|
369
462
|
## 📚 Additional Resources
|
|
370
463
|
|
|
371
464
|
**For comprehensive pds-form documentation:**
|
|
372
|
-
- Read [pds-form-docs.md](pds-form-docs.md) for complete API reference
|
|
373
|
-
- See [packages/pds-storybook/stories/components/PdsForm.stories.js](packages/pds-storybook/stories/components/PdsForm.stories.js) for real examples
|
|
374
|
-
- Check [custom-elements.json](custom-elements.json) for component API details
|
|
465
|
+
- Read [pds-form-docs.md](../pds-form-docs.md) for complete API reference
|
|
466
|
+
- See [packages/pds-storybook/stories/components/PdsForm.stories.js](../packages/pds-storybook/stories/components/PdsForm.stories.js) for real examples
|
|
467
|
+
- Check [custom-elements.json](../custom-elements.json) for component API details
|
|
375
468
|
|
|
376
469
|
**For toast notifications:**
|
|
377
|
-
- Use `PDS.toast()` method (see [src/js/common/toast.js](src/js/common/toast.js) for implementation)
|
|
470
|
+
- Use `PDS.toast()` method (see [src/js/common/toast.js](../src/js/common/toast.js) for implementation)
|
|
378
471
|
- Automatically ensures pds-toaster exists and is loaded before displaying
|
|
379
|
-
- See pds-toaster component API in [custom-elements.json](custom-elements.json)
|
|
472
|
+
- See pds-toaster component API in [custom-elements.json](../custom-elements.json)
|
|
473
|
+
|
|
380
474
|
---
|
|
381
475
|
|
|
382
476
|
## How to Look Things Up
|
|
@@ -387,7 +481,7 @@ const results = await PDS.query("border gradient classes");
|
|
|
387
481
|
| "What components are available?" | Read `custom-elements.json` |
|
|
388
482
|
| "What utility classes exist?" | Read `pds-ontology.js` → `layoutPatterns`, `utilities` |
|
|
389
483
|
| "What primitives exist?" | Read `pds-ontology.js` → `primitives` |
|
|
390
|
-
| "How do I enhance HTML?" | Read `pds-
|
|
484
|
+
| "How do I enhance HTML?" | Read `pds-enhancers.js` → `defaultPDSEnhancerMetadata` → `demoHtml` |
|
|
391
485
|
| "How are tokens named?" | Read `pds-generator.js` or `pds.css-data.json` |
|
|
392
486
|
|
|
393
487
|
---
|
|
@@ -401,7 +495,7 @@ Before generating code:
|
|
|
401
495
|
3. ✅ **No hardcoded values** — Colors, spacing, radii all have tokens
|
|
402
496
|
4. ✅ **No alert/confirm/prompt** — Use `PDS.ask()` and `PDS.toast()`
|
|
403
497
|
5. ✅ **Use semantic HTML** — `<button>`, `<nav>`, `<article>`, `<label>`, `<details>`
|
|
404
|
-
6. ✅ **Apply enhancements via data-* attributes** — See `pds-
|
|
498
|
+
6. ✅ **Apply enhancements via data-* attributes** — See `pds-enhancers.js` → `defaultPDSEnhancerMetadata`
|
|
405
499
|
7. ✅ **Components as last resort** — Only when native HTML can't achieve it
|
|
406
500
|
8. ✅ **Prefer primitives** — `.card`, `.badge`, `.alert` over custom components
|
|
407
501
|
9. ✅ **Wait for lazy components** — Use `await customElements.whenDefined()` before accessing APIs
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# PDS (Pure Design System) -
|
|
1
|
+
# PDS (Pure Design System) - AI Generation Instructions
|
|
2
2
|
|
|
3
3
|
> **CRITICAL**: This workspace uses **Pure Design System (PDS)**. All code generation MUST follow PDS and vanilla Web Platform patterns. Never use 3rd party framework patterns, non-PDS utility classes, inline styles, or hardcoded CSS values.
|
|
4
4
|
|
|
@@ -31,7 +31,7 @@ PDS follows the [Pure Web Manifesto](https://pureweb.dev/manifesto): "The browse
|
|
|
31
31
|
| **Web Components** | `custom-elements.json` | Complete component APIs, attributes, methods, events, slots |
|
|
32
32
|
| **HTML Tags** | `public/assets/pds/vscode-custom-data.json` | Component HTML structure, attribute values |
|
|
33
33
|
| **Primitives & Utilities** | `src/js/pds-core/pds-ontology.js` | `.card`, `.badge`, `.btn-*`, `.flex`, `.gap-*`, `.surface-*` |
|
|
34
|
-
| **Enhancements** | `src/js/pds-core/pds-
|
|
34
|
+
| **Enhancements** | `src/js/pds-core/pds-enhancers.js` | Enhancement metadata (`defaultPDSEnhancerMetadata`) + runtime (`defaultPDSEnhancers`) |
|
|
35
35
|
| **Generator Logic** | `src/js/pds-core/pds-generator.js` | How CSS is generated, token naming conventions |
|
|
36
36
|
| **Config** | `pds.config.js` | What's enabled in this workspace |
|
|
37
37
|
|
|
@@ -94,138 +94,44 @@ async function simulateSubmit(data) {
|
|
|
94
94
|
}
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
-
### 3.
|
|
97
|
+
### 3. Adding `data-required` to pds-form generated form: simply add the attribute to the pds-form tag
|
|
98
98
|
|
|
99
99
|
```html
|
|
100
|
-
|
|
101
|
-
<form data-required>
|
|
102
|
-
<pds-form id="myForm" hide-actions></pds-form>
|
|
103
|
-
<div class="form-actions">
|
|
104
|
-
<button type="submit" class="btn-primary">Submit</button>
|
|
105
|
-
</div>
|
|
106
|
-
</form>
|
|
107
|
-
|
|
108
|
-
<!-- ❌ WRONG: No data-required enhancement -->
|
|
109
|
-
<pds-form id="myForm"></pds-form>
|
|
100
|
+
<pds-form data-required id="myForm" hide-actions></pds-form>
|
|
110
101
|
```
|
|
111
102
|
|
|
112
103
|
### 4. Placeholders - ALWAYS include examples
|
|
113
104
|
|
|
114
|
-
**Placeholders improve UX significantly.
|
|
105
|
+
**Placeholders improve UX significantly. Try to add 'examples' array to schema properties:**
|
|
115
106
|
|
|
116
|
-
|
|
117
|
-
// ✅ CORRECT: Every field has an example (becomes placeholder)
|
|
118
|
-
const schema = {
|
|
119
|
-
type: "object",
|
|
120
|
-
properties: {
|
|
121
|
-
name: {
|
|
122
|
-
type: "string",
|
|
123
|
-
title: "Full Name",
|
|
124
|
-
examples: ["John Doe"] // First example becomes placeholder
|
|
125
|
-
},
|
|
126
|
-
email: {
|
|
127
|
-
type: "string",
|
|
128
|
-
format: "email",
|
|
129
|
-
title: "Email Address",
|
|
130
|
-
examples: ["john@example.com"] // Shows expected format
|
|
131
|
-
},
|
|
132
|
-
phone: {
|
|
133
|
-
type: "string",
|
|
134
|
-
title: "Phone Number",
|
|
135
|
-
examples: ["+1 (555) 123-4567"] // Pattern example
|
|
136
|
-
},
|
|
137
|
-
age: {
|
|
138
|
-
type: "integer",
|
|
139
|
-
title: "Age",
|
|
140
|
-
examples: [25] // Works for numbers too
|
|
141
|
-
},
|
|
142
|
-
bio: {
|
|
143
|
-
type: "string",
|
|
144
|
-
title: "About You",
|
|
145
|
-
examples: ["Tell us about yourself..."] // Long text hint
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
};
|
|
107
|
+
**Rule: When generating a form, infer appropriate placeholders based on field name/type if not specified.**
|
|
149
108
|
|
|
150
|
-
|
|
151
|
-
const badSchema = {
|
|
152
|
-
type: "object",
|
|
153
|
-
properties: {
|
|
154
|
-
email: { type: "string", format: "email" } // No placeholder!
|
|
155
|
-
}
|
|
156
|
-
};
|
|
157
|
-
```
|
|
109
|
+
### 5. Smart Icons - Infer from field semantics
|
|
158
110
|
|
|
159
|
-
**
|
|
111
|
+
**When generating forms, automatically add appropriate icons based on field names and semantics.**
|
|
160
112
|
|
|
161
|
-
|
|
113
|
+
**Sources of truth for available icons:**
|
|
114
|
+
- Check `pds.config.js` for project-specific icon configuration
|
|
115
|
+
- Consult icon sprite at `public/assets/img/icons/pds-icons.svg` for available icons
|
|
116
|
+
- See `public/assets/pds/vscode-custom-data.json` for icon attribute values
|
|
162
117
|
|
|
163
|
-
**
|
|
118
|
+
**Use semantic reasoning to match field names to appropriate icons:**
|
|
164
119
|
|
|
165
120
|
```javascript
|
|
166
|
-
//
|
|
167
|
-
const iconInference = {
|
|
168
|
-
// Contact & Identity
|
|
169
|
-
'email': 'envelope',
|
|
170
|
-
'phone': 'phone',
|
|
171
|
-
'mobile': 'phone',
|
|
172
|
-
'name': 'user',
|
|
173
|
-
'username': 'user',
|
|
174
|
-
'firstname': 'user',
|
|
175
|
-
'lastname': 'user',
|
|
176
|
-
'password': 'lock',
|
|
177
|
-
|
|
178
|
-
// Location
|
|
179
|
-
'address': 'map-pin',
|
|
180
|
-
'street': 'map-pin',
|
|
181
|
-
'city': 'building',
|
|
182
|
-
'location': 'map-marker',
|
|
183
|
-
'country': 'globe',
|
|
184
|
-
|
|
185
|
-
// Communication
|
|
186
|
-
'message': 'message',
|
|
187
|
-
'comment': 'comment',
|
|
188
|
-
'feedback': 'comment',
|
|
189
|
-
|
|
190
|
-
// Web & Links
|
|
191
|
-
'website': 'link',
|
|
192
|
-
'url': 'link',
|
|
193
|
-
'link': 'link',
|
|
194
|
-
|
|
195
|
-
// Time & Dates
|
|
196
|
-
'date': 'calendar',
|
|
197
|
-
'birthday': 'calendar',
|
|
198
|
-
'time': 'clock',
|
|
199
|
-
|
|
200
|
-
// Categorization
|
|
201
|
-
'subject': 'tag',
|
|
202
|
-
'tag': 'tag',
|
|
203
|
-
'category': 'folder',
|
|
204
|
-
'priority': 'flag',
|
|
205
|
-
|
|
206
|
-
// Files
|
|
207
|
-
'file': 'file',
|
|
208
|
-
'upload': 'upload',
|
|
209
|
-
'image': 'image',
|
|
210
|
-
'photo': 'image',
|
|
211
|
-
|
|
212
|
-
// Search
|
|
213
|
-
'search': 'search',
|
|
214
|
-
'query': 'search'
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
// ✅ CORRECT: Auto-generate uiSchema with icons
|
|
121
|
+
// ✅ CORRECT: Infer icons based on field semantics
|
|
218
122
|
const uiSchema = {
|
|
219
123
|
"/email": { 'ui:icon': 'envelope', 'ui:autocomplete': 'email' },
|
|
220
124
|
"/phone": { 'ui:icon': 'phone', 'ui:autocomplete': 'tel' },
|
|
221
125
|
"/name": { 'ui:icon': 'user', 'ui:autocomplete': 'name' },
|
|
222
126
|
"/password": { 'ui:icon': 'lock', 'ui:widget': 'password' },
|
|
223
127
|
"/website": { 'ui:icon': 'link' },
|
|
128
|
+
"/address": { 'ui:icon': 'map-pin' },
|
|
129
|
+
"/date": { 'ui:icon': 'calendar' },
|
|
224
130
|
"/message": { 'ui:widget': 'textarea', 'ui:icon': 'message' }
|
|
225
131
|
};
|
|
226
132
|
```
|
|
227
133
|
|
|
228
|
-
**Rule: When generating
|
|
134
|
+
**Rule: When generating forms, analyze field names/types and select semantically appropriate icons from the available icon set.**
|
|
229
135
|
|
|
230
136
|
### 6. Submit Handler Pattern - ALWAYS provide working async handler
|
|
231
137
|
|
|
@@ -509,7 +415,7 @@ form.getFormData(); // May throw error
|
|
|
509
415
|
<pds-icon icon="heart" size="sm"></pds-icon>
|
|
510
416
|
<pds-icon icon="check" size="lg" color="var(--color-success-500)"></pds-icon>
|
|
511
417
|
|
|
512
|
-
<!-- Enhancements: data attributes (see pds-
|
|
418
|
+
<!-- Enhancements: data attributes (see pds-enhancers.js → defaultPDSEnhancerMetadata) -->
|
|
513
419
|
<nav data-dropdown>
|
|
514
420
|
<button>Menu</button>
|
|
515
421
|
<menu><li><a href="#">Item</a></li></menu>
|
|
@@ -526,10 +432,12 @@ form.getFormData(); // May throw error
|
|
|
526
432
|
|
|
527
433
|
<!-- Tabs: web component -->
|
|
528
434
|
<pds-tabstrip>
|
|
529
|
-
<
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
<
|
|
435
|
+
<pds-tabpanel label="Tab 1">
|
|
436
|
+
<p>Content for Tab 1</p>
|
|
437
|
+
</pds-tabpanel>
|
|
438
|
+
<pds-tabpanel label="Tab 2">
|
|
439
|
+
<p>Content for Tab 2</p>
|
|
440
|
+
</pds-tabpanel>
|
|
533
441
|
</pds-tabstrip>
|
|
534
442
|
```
|
|
535
443
|
|
|
@@ -573,7 +481,7 @@ const results = await PDS.query("border gradient classes");
|
|
|
573
481
|
| "What components are available?" | Read `custom-elements.json` |
|
|
574
482
|
| "What utility classes exist?" | Read `pds-ontology.js` → `layoutPatterns`, `utilities` |
|
|
575
483
|
| "What primitives exist?" | Read `pds-ontology.js` → `primitives` |
|
|
576
|
-
| "How do I enhance HTML?" | Read `pds-
|
|
484
|
+
| "How do I enhance HTML?" | Read `pds-enhancers.js` → `defaultPDSEnhancerMetadata` → `demoHtml` |
|
|
577
485
|
| "How are tokens named?" | Read `pds-generator.js` or `pds.css-data.json` |
|
|
578
486
|
|
|
579
487
|
---
|
|
@@ -587,7 +495,7 @@ Before generating code:
|
|
|
587
495
|
3. ✅ **No hardcoded values** — Colors, spacing, radii all have tokens
|
|
588
496
|
4. ✅ **No alert/confirm/prompt** — Use `PDS.ask()` and `PDS.toast()`
|
|
589
497
|
5. ✅ **Use semantic HTML** — `<button>`, `<nav>`, `<article>`, `<label>`, `<details>`
|
|
590
|
-
6. ✅ **Apply enhancements via data-* attributes** — See `pds-
|
|
498
|
+
6. ✅ **Apply enhancements via data-* attributes** — See `pds-enhancers.js` → `defaultPDSEnhancerMetadata`
|
|
591
499
|
7. ✅ **Components as last resort** — Only when native HTML can't achieve it
|
|
592
500
|
8. ✅ **Prefer primitives** — `.card`, `.badge`, `.alert` over custom components
|
|
593
501
|
9. ✅ **Wait for lazy components** — Use `await customElements.whenDefined()` before accessing APIs
|