@pure-ds/core 0.6.10 → 0.6.11
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/custom-elements.json +803 -16
- package/dist/types/pds.d.ts +1 -0
- package/dist/types/public/assets/js/pds-manager.d.ts +98 -1
- package/dist/types/public/assets/js/pds-manager.d.ts.map +1 -1
- package/dist/types/public/assets/js/pds.d.ts.map +1 -1
- package/dist/types/public/assets/pds/components/pds-live-converter.d.ts +8 -0
- package/dist/types/public/assets/pds/components/pds-live-converter.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-live-importer.d.ts +2 -0
- package/dist/types/public/assets/pds/components/pds-live-importer.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-live-template-canvas.d.ts +2 -0
- package/dist/types/public/assets/pds/components/pds-live-template-canvas.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-omnibox.d.ts.map +1 -1
- package/dist/types/public/assets/pds/components/pds-scrollrow.d.ts +20 -0
- package/dist/types/public/assets/pds/components/pds-scrollrow.d.ts.map +1 -1
- package/dist/types/public/assets/pds/components/pds-toaster.d.ts +1 -1
- package/dist/types/public/assets/pds/components/pds-toaster.d.ts.map +1 -1
- package/dist/types/public/assets/pds/components/pds-treeview.d.ts +37 -0
- package/dist/types/public/assets/pds/components/pds-treeview.d.ts.map +1 -0
- package/dist/types/src/js/common/toast.d.ts +8 -0
- package/dist/types/src/js/common/toast.d.ts.map +1 -1
- package/dist/types/src/js/pds-core/pds-enhancers.d.ts.map +1 -1
- package/dist/types/src/js/pds-core/pds-generator.d.ts.map +1 -1
- package/dist/types/src/js/pds-core/pds-live.d.ts +2 -1
- package/dist/types/src/js/pds-core/pds-live.d.ts.map +1 -1
- package/dist/types/src/js/pds-live-manager/conversion-service.d.ts +66 -0
- package/dist/types/src/js/pds-live-manager/conversion-service.d.ts.map +1 -0
- package/dist/types/src/js/pds-live-manager/import-contract.d.ts +15 -0
- package/dist/types/src/js/pds-live-manager/import-contract.d.ts.map +1 -0
- package/dist/types/src/js/pds-live-manager/import-history-service.d.ts +32 -0
- package/dist/types/src/js/pds-live-manager/import-history-service.d.ts.map +1 -0
- package/dist/types/src/js/pds-live-manager/import-service.d.ts +21 -0
- package/dist/types/src/js/pds-live-manager/import-service.d.ts.map +1 -0
- package/dist/types/src/js/pds-live-manager/template-service.d.ts +17 -0
- package/dist/types/src/js/pds-live-manager/template-service.d.ts.map +1 -0
- package/dist/types/src/js/pds-manager.d.ts +4 -0
- package/dist/types/src/js/pds.d.ts.map +1 -1
- package/package.json +6 -2
- package/packages/pds-cli/README.md +51 -0
- package/packages/pds-cli/bin/pds-import.js +176 -0
- package/packages/pds-cli/bin/pds-static.js +15 -0
- package/packages/pds-cli/bin/postinstall.mjs +17 -8
- package/public/assets/js/app.js +15 -139
- package/public/assets/js/pds-manager.js +358 -255
- package/public/assets/js/pds.js +7 -7
- package/public/assets/pds/components/pds-live-converter.js +47 -0
- package/public/assets/pds/components/pds-live-edit.js +760 -43
- package/public/assets/pds/components/pds-live-importer.js +772 -0
- package/public/assets/pds/components/pds-live-template-canvas.js +171 -0
- package/public/assets/pds/components/pds-omnibox.js +136 -2
- package/public/assets/pds/components/pds-scrollrow.js +56 -1
- package/public/assets/pds/components/pds-toaster.js +50 -5
- package/public/assets/pds/components/pds-treeview.js +972 -0
- package/public/assets/pds/custom-elements.json +803 -16
- package/public/assets/pds/pds-css-complete.json +7 -2
- package/public/assets/pds/templates/commerce-scroll-explorer.html +115 -0
- package/public/assets/pds/templates/content-brand-showcase.html +110 -0
- package/public/assets/pds/templates/feedback-ops-dashboard.html +91 -0
- package/public/assets/pds/templates/release-readiness-radar.html +69 -0
- package/public/assets/pds/templates/support-command-center.html +92 -0
- package/public/assets/pds/templates/templates.json +53 -0
- package/public/assets/pds/templates/workspace-settings-lab.html +131 -0
- package/public/assets/pds/vscode-custom-data.json +54 -4
- package/readme.md +34 -0
- package/src/js/pds-core/pds-config.js +9 -9
- package/src/js/pds-core/pds-enhancers.js +146 -0
- package/src/js/pds-core/pds-generator.js +170 -29
- package/src/js/pds-core/pds-live.js +453 -13
- package/src/js/pds-live-manager/conversion-service.js +3136 -0
- package/src/js/pds-live-manager/import-contract.js +57 -0
- package/src/js/pds-live-manager/import-history-service.js +145 -0
- package/src/js/pds-live-manager/import-service.js +255 -0
- package/src/js/pds-live-manager/tailwind-conversion-rules.json +383 -0
- package/src/js/pds-live-manager/template-service.js +170 -0
- package/src/js/pds.d.ts +1 -0
- package/src/js/pds.js +35 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "tw2pds-layout-v4",
|
|
3
|
+
"summary": "Deterministic Tailwind→PDS conversion rules focused on layout intent, semantic primitive mapping, and richer import-* fallback coverage.",
|
|
4
|
+
"governance": [
|
|
5
|
+
{
|
|
6
|
+
"id": "layout.utilities.grid",
|
|
7
|
+
"controls": ["grid", "grid-cols-*", "grid-auto-*"],
|
|
8
|
+
"note": "When false, grid mappings are skipped."
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"id": "layout.utilities.flex",
|
|
12
|
+
"controls": ["flex", "flex-*", "items-*", "justify-*", "grow"],
|
|
13
|
+
"note": "When false, flex mappings are skipped."
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"id": "layout.utilities.spacing",
|
|
17
|
+
"controls": ["gap-*", "stack-*"],
|
|
18
|
+
"note": "When false, spacing mappings are skipped."
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "layout.utilities.container",
|
|
22
|
+
"controls": ["container", "max-w-*"],
|
|
23
|
+
"note": "When false, container mappings are skipped."
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"nonPdsClassPatterns": ["^group(?:[/:].*)?$", "^layout-container$"],
|
|
27
|
+
"neverFallbackTags": ["table", "thead", "tbody", "tfoot", "tr", "th", "td", "caption", "colgroup", "col"],
|
|
28
|
+
"directMappings": [
|
|
29
|
+
{ "id": "layout.flex.base", "tw": "flex", "pds": ["flex"], "gate": "flex" },
|
|
30
|
+
{ "id": "layout.flex.inline", "tw": "inline-flex", "pds": ["flex"], "gate": "flex" },
|
|
31
|
+
{ "id": "layout.flex.row", "tw": "flex-row", "pds": ["flex-row"], "gate": "flex" },
|
|
32
|
+
{ "id": "layout.flex.col", "tw": "flex-col", "pds": ["flex-col"], "gate": "flex" },
|
|
33
|
+
{ "id": "layout.flex.wrap", "tw": "flex-wrap", "pds": ["flex-wrap"], "gate": "flex" },
|
|
34
|
+
{ "id": "layout.flex.grow", "tw": "grow", "pds": ["grow"], "gate": "flex" },
|
|
35
|
+
{ "id": "layout.flex.grow.tw", "tw": "flex-grow", "pds": ["grow"], "gate": "flex" },
|
|
36
|
+
{ "id": "layout.flex.grow1", "tw": "flex-1", "pds": ["grow"], "gate": "flex" },
|
|
37
|
+
{ "id": "layout.items.start", "tw": "items-start", "pds": ["items-start"], "gate": "flex" },
|
|
38
|
+
{ "id": "layout.items.center", "tw": "items-center", "pds": ["items-center"], "gate": "flex" },
|
|
39
|
+
{ "id": "layout.items.end", "tw": "items-end", "pds": ["items-end"], "gate": "flex" },
|
|
40
|
+
{ "id": "layout.items.stretch", "tw": "items-stretch", "pds": ["items-stretch"], "gate": "flex" },
|
|
41
|
+
{ "id": "layout.items.baseline", "tw": "items-baseline", "pds": ["items-baseline"], "gate": "flex" },
|
|
42
|
+
{ "id": "layout.justify.start", "tw": "justify-start", "pds": ["justify-start"], "gate": "flex" },
|
|
43
|
+
{ "id": "layout.justify.center", "tw": "justify-center", "pds": ["justify-center"], "gate": "flex" },
|
|
44
|
+
{ "id": "layout.justify.end", "tw": "justify-end", "pds": ["justify-end"], "gate": "flex" },
|
|
45
|
+
{ "id": "layout.justify.between", "tw": "justify-between", "pds": ["justify-between"], "gate": "flex" },
|
|
46
|
+
{ "id": "layout.justify.around", "tw": "justify-around", "pds": ["justify-around"], "gate": "flex" },
|
|
47
|
+
{ "id": "layout.justify.evenly", "tw": "justify-evenly", "pds": ["justify-evenly"], "gate": "flex" },
|
|
48
|
+
{ "id": "layout.grid.base", "tw": "grid", "pds": ["grid"], "gate": "grid" },
|
|
49
|
+
{ "id": "layout.grid.cols.1", "tw": "grid-cols-1", "pds": ["grid-cols-1"], "gate": "grid" },
|
|
50
|
+
{ "id": "layout.grid.cols.2", "tw": "grid-cols-2", "pds": ["grid-cols-2"], "gate": "grid" },
|
|
51
|
+
{ "id": "layout.grid.cols.3", "tw": "grid-cols-3", "pds": ["grid-cols-3"], "gate": "grid" },
|
|
52
|
+
{ "id": "layout.grid.cols.4", "tw": "grid-cols-4", "pds": ["grid-cols-4"], "gate": "grid" },
|
|
53
|
+
{ "id": "layout.grid.cols.6", "tw": "grid-cols-6", "pds": ["grid-cols-6"], "gate": "grid" },
|
|
54
|
+
{ "id": "layout.container", "tw": "container", "pds": ["container"], "gate": "container" },
|
|
55
|
+
{ "id": "intent.surface.shadow", "tw": "shadow", "pds": ["surface-elevated"] },
|
|
56
|
+
{ "id": "intent.surface.shadow-md", "tw": "shadow-md", "pds": ["surface-elevated"] },
|
|
57
|
+
{ "id": "intent.surface.shadow-lg", "tw": "shadow-lg", "pds": ["surface-elevated"] },
|
|
58
|
+
{ "id": "intent.surface.base", "tw": "bg-white", "pds": ["surface-base"] },
|
|
59
|
+
{ "id": "typography.align.center", "tw": "text-center", "pds": ["text-center"] },
|
|
60
|
+
{ "id": "typography.align.left", "tw": "text-left", "pds": ["text-left"] },
|
|
61
|
+
{ "id": "typography.align.right", "tw": "text-right", "pds": ["text-right"] },
|
|
62
|
+
{ "id": "typography.text.muted.gray500", "tw": "text-gray-500", "pds": ["text-muted"] },
|
|
63
|
+
{ "id": "typography.text.muted.slate500", "tw": "text-slate-500", "pds": ["text-muted"] }
|
|
64
|
+
],
|
|
65
|
+
"ignoredPatterns": [
|
|
66
|
+
{
|
|
67
|
+
"id": "style.color",
|
|
68
|
+
"pattern": "^(?:text|from|to|via|decoration|accent|caret)-|^bg-(?!cover$|center$|no-repeat$)",
|
|
69
|
+
"reason": "Visual style token skipped in favor of semantic PDS styling."
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"id": "style.radius-border-shadow",
|
|
73
|
+
"pattern": "^(?:rounded|ring|border|shadow|outline)-?",
|
|
74
|
+
"reason": "Surface/shape inferred at primitive level."
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "style.typography",
|
|
78
|
+
"pattern": "^(?:font|leading|tracking|uppercase|lowercase|capitalize)-?",
|
|
79
|
+
"reason": "Typography atomic utilities are skipped."
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"id": "style.effects",
|
|
83
|
+
"pattern": "^(?:opacity|blur|backdrop|drop-shadow|mix-blend|filter)-",
|
|
84
|
+
"reason": "Visual effects skipped unless mapped to a PDS utility."
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"id": "style.transitions",
|
|
88
|
+
"pattern": "^(?:transition|duration|ease|delay|animate)-",
|
|
89
|
+
"reason": "Motion is system-defined in PDS."
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"id": "style.spacing.atomic",
|
|
93
|
+
"pattern": "^(?:p|px|py|pt|pb|pl|pr|m|mx|my|mt|mb|ml|mr)-",
|
|
94
|
+
"reason": "Atomic spacing skipped; structural spacing intent is mapped."
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"id": "style.positioning.atomic",
|
|
98
|
+
"pattern": "^(?:absolute|relative|fixed|sticky|inset(?:-[xy])?|top|right|bottom|left|z|translate(?:-[xy])?|-translate-[xy])(?:-|$)",
|
|
99
|
+
"reason": "Atomic positioning/offset utilities are skipped so PDS primitives and layout utilities control placement."
|
|
100
|
+
}
|
|
101
|
+
],
|
|
102
|
+
"intentRules": [
|
|
103
|
+
{
|
|
104
|
+
"id": "intent.layout.responsive-grid-to-auto",
|
|
105
|
+
"summary": "Collapse responsive grid-cols patterns (including base+md two-step patterns) to best-fit grid-auto-*"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"id": "intent.layout.mobile-stack",
|
|
109
|
+
"summary": "Map flex-col + md/lg:flex-row to mobile-stack"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"id": "intent.component.card",
|
|
113
|
+
"summary": "Infer card/surface classes from rounded+shadow+surface signals"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"id": "intent.component.card.normalize",
|
|
117
|
+
"summary": "Detect Tailwind card utility clusters and normalize them to PDS card and surface variants."
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"id": "intent.component.button",
|
|
121
|
+
"summary": "Infer btn-primary / btn-outline / icon-only from CTA patterns"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"id": "intent.component.button.normalize",
|
|
125
|
+
"summary": "Prevents import-* style classes on button-like elements and applies PDS button variants/sizes."
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"id": "intent.component.button.layout-grow",
|
|
129
|
+
"summary": "Preserve CTA row width intent on button-like elements by mapping w-full/flex-1 to grow."
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"id": "intent.icon.color-preserve",
|
|
133
|
+
"summary": "Preserve icon color intent by mapping Tailwind text color utilities on icon-like elements to tokenized import-* classes."
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"id": "intent.component.badge.normalize",
|
|
137
|
+
"summary": "Detects Tailwind badge/pill utility clusters and normalizes them to PDS badge primitives/variants."
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"id": "intent.typography.heading-semantic",
|
|
141
|
+
"summary": "Removes Tailwind heading typography/color utilities so heading semantics and PDS defaults control typography."
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"id": "intent.surface.footer-inverse",
|
|
145
|
+
"summary": "Use surface-inverse for footers with explicit background intent"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"id": "intent.typography.link-treatment",
|
|
149
|
+
"summary": "Apply minimal link treatment for hover/transition-tailwind anchors"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"id": "intent.typography.link-active-preserve",
|
|
153
|
+
"summary": "Preserve anchor text color intent (including active menu states) by mapping Tailwind text utilities to tokenized import-* classes."
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"id": "intent.typography.metric-paragraph-to-div",
|
|
157
|
+
"summary": "Normalize metric display lines from paragraph tags to div tags to avoid default paragraph margins in compact stat layouts."
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"id": "intent.typography.metric-pair-no-stack",
|
|
161
|
+
"summary": "When a compact metric container has two consecutive typography lines, remove stack-sm so spacing follows Tailwind preflight no-margin assumptions."
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"id": "intent.typography.semantic-heading-from-scale",
|
|
165
|
+
"summary": "Map large bold typography scales (text-2xl/text-3xl/text-4xl) to semantic heading tags when possible."
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"id": "intent.typography.bold-to-strong",
|
|
169
|
+
"summary": "Prefer semantic strong tags for bold inline text intent instead of utility-only font-weight classes."
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"id": "intent.preflight.tailwind-runtime-detected",
|
|
173
|
+
"summary": "Detect Tailwind runtime CSS injection and translate key preflight intent"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"id": "intent.preflight.list-reset",
|
|
177
|
+
"summary": "Preserve Tailwind list-reset preflight behavior via scoped fallback class"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"id": "intent.preflight.anchor-reset",
|
|
181
|
+
"summary": "Preserve Tailwind anchor reset preflight behavior via scoped fallback class"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"id": "table.strict-tags.no-classes",
|
|
185
|
+
"summary": "Never emit classes for semantic table tags (table/thead/tbody/tfoot/tr/th/td/caption/colgroup/col)"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"id": "intent.form.nested-label",
|
|
189
|
+
"summary": "Convert sibling label+control pairs into nested labels"
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"id": "fallback.import-style",
|
|
193
|
+
"summary": "Generate import-* classes + local style block for unmapped utility styles"
|
|
194
|
+
}
|
|
195
|
+
],
|
|
196
|
+
"gapScaleMap": {
|
|
197
|
+
"gap-0": "gap-0",
|
|
198
|
+
"gap-1": "gap-xs",
|
|
199
|
+
"gap-2": "gap-sm",
|
|
200
|
+
"gap-3": "gap-sm",
|
|
201
|
+
"gap-4": "gap-md",
|
|
202
|
+
"gap-5": "gap-md",
|
|
203
|
+
"gap-6": "gap-lg",
|
|
204
|
+
"gap-7": "gap-lg",
|
|
205
|
+
"gap-8": "gap-xl",
|
|
206
|
+
"gap-10": "gap-xl",
|
|
207
|
+
"gap-12": "gap-xl"
|
|
208
|
+
},
|
|
209
|
+
"maxWidthMap": {
|
|
210
|
+
"max-w-xs": "max-w-sm",
|
|
211
|
+
"max-w-sm": "max-w-sm",
|
|
212
|
+
"max-w-md": "max-w-md",
|
|
213
|
+
"max-w-lg": "max-w-lg",
|
|
214
|
+
"max-w-xl": "max-w-xl",
|
|
215
|
+
"max-w-2xl": "max-w-xl",
|
|
216
|
+
"max-w-3xl": "max-w-xl",
|
|
217
|
+
"max-w-4xl": "max-w-xl",
|
|
218
|
+
"max-w-5xl": "max-w-xl",
|
|
219
|
+
"max-w-6xl": "max-w-xl",
|
|
220
|
+
"max-w-7xl": "max-w-xl"
|
|
221
|
+
},
|
|
222
|
+
"tailwindSizeScale": {
|
|
223
|
+
"0": "var(--spacing-0)",
|
|
224
|
+
"0.5": "0.125rem",
|
|
225
|
+
"1": "var(--spacing-1)",
|
|
226
|
+
"1.5": "0.375rem",
|
|
227
|
+
"2": "var(--spacing-2)",
|
|
228
|
+
"2.5": "0.625rem",
|
|
229
|
+
"3": "var(--spacing-3)",
|
|
230
|
+
"3.5": "0.875rem",
|
|
231
|
+
"4": "var(--spacing-4)",
|
|
232
|
+
"5": "var(--spacing-5)",
|
|
233
|
+
"6": "var(--spacing-6)",
|
|
234
|
+
"7": "var(--spacing-7)",
|
|
235
|
+
"8": "var(--spacing-8)",
|
|
236
|
+
"9": "var(--spacing-9)",
|
|
237
|
+
"10": "var(--spacing-10)",
|
|
238
|
+
"11": "var(--spacing-11)",
|
|
239
|
+
"12": "var(--spacing-12)",
|
|
240
|
+
"14": "3.5rem",
|
|
241
|
+
"16": "4rem",
|
|
242
|
+
"20": "5rem",
|
|
243
|
+
"24": "6rem",
|
|
244
|
+
"28": "7rem",
|
|
245
|
+
"32": "8rem",
|
|
246
|
+
"36": "9rem",
|
|
247
|
+
"40": "10rem",
|
|
248
|
+
"48": "12rem"
|
|
249
|
+
},
|
|
250
|
+
"tailwindShadeScale": ["50", "100", "200", "300", "400", "500", "600", "700", "800", "900"],
|
|
251
|
+
"defaultTailwindShade": "500",
|
|
252
|
+
"importStyleRules": {
|
|
253
|
+
"mx-auto": "margin-left:auto;margin-right:auto",
|
|
254
|
+
"ml-auto": "margin-left:auto",
|
|
255
|
+
"mr-auto": "margin-right:auto",
|
|
256
|
+
"w-full": "width:100%",
|
|
257
|
+
"w-auto": "width:auto",
|
|
258
|
+
"h-full": "height:100%",
|
|
259
|
+
"h-48": "height:12rem",
|
|
260
|
+
"h-2.5": "height:0.625rem",
|
|
261
|
+
"h-10": "height:var(--spacing-10)",
|
|
262
|
+
"h-2": "height:var(--spacing-2)",
|
|
263
|
+
"w-2": "width:var(--spacing-2)",
|
|
264
|
+
"size-8": "width:var(--spacing-8);height:var(--spacing-8)",
|
|
265
|
+
"size-10": "width:var(--spacing-10);height:var(--spacing-10)",
|
|
266
|
+
"size-full": "width:100%;height:100%",
|
|
267
|
+
"min-h-screen": "min-height:100vh",
|
|
268
|
+
"overflow-hidden": "overflow:hidden",
|
|
269
|
+
"overflow-x-hidden": "overflow-x:hidden",
|
|
270
|
+
"overflow-x-auto": "overflow-x:auto",
|
|
271
|
+
"whitespace-nowrap": "white-space:nowrap",
|
|
272
|
+
"hidden": "display:none",
|
|
273
|
+
"block": "display:block",
|
|
274
|
+
"truncate": "overflow:hidden;text-overflow:ellipsis;white-space:nowrap",
|
|
275
|
+
"justify-items-center": "justify-items:center",
|
|
276
|
+
"justify-items-start": "justify-items:start",
|
|
277
|
+
"justify-items-end": "justify-items:end",
|
|
278
|
+
"justify-items-stretch": "justify-items:stretch",
|
|
279
|
+
"grid-flow-col": "grid-auto-flow:column",
|
|
280
|
+
"aspect-square": "aspect-ratio:1 / 1",
|
|
281
|
+
"bg-center": "background-position:center",
|
|
282
|
+
"bg-cover": "background-size:cover",
|
|
283
|
+
"bg-no-repeat": "background-repeat:no-repeat",
|
|
284
|
+
"transition-colors": "transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:150ms"
|
|
285
|
+
},
|
|
286
|
+
"importStyleDynamicRules": [
|
|
287
|
+
{
|
|
288
|
+
"id": "fallback.import-style.gap-scale",
|
|
289
|
+
"pattern": "^gap-(\\d+)$",
|
|
290
|
+
"summary": "Converts gap scale utilities (including responsive variants like md:gap-6) to generated import-* fallback classes."
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
"id": "fallback.import-style.min-width-arbitrary",
|
|
294
|
+
"pattern": "^min-w-\\[[^\\]]+\\]$",
|
|
295
|
+
"summary": "Converts arbitrary min-width utilities (e.g. min-w-[600px]) to generated import-* fallback classes."
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
"id": "fallback.import-style.max-width-arbitrary",
|
|
299
|
+
"pattern": "^max-w-\\[[^\\]]+\\]$",
|
|
300
|
+
"summary": "Converts arbitrary max-width utilities (e.g. max-w-[480px]) to generated import-* fallback classes."
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
"id": "fallback.import-style.min-height-arbitrary",
|
|
304
|
+
"pattern": "^min-h-\\[[^\\]]+\\]$",
|
|
305
|
+
"summary": "Converts arbitrary min-height utilities (e.g. min-h-[180px]) to generated import-* fallback classes."
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
"id": "fallback.import-style.grid-rows-arbitrary",
|
|
309
|
+
"pattern": "^grid-rows-\\[[^\\]]+\\]$",
|
|
310
|
+
"summary": "Converts arbitrary grid template row utilities (e.g. grid-rows-[1fr_auto]) to generated import-* fallback classes."
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"id": "fallback.import-style.size-scale",
|
|
314
|
+
"pattern": "^size-(\\[[^\\]]+\\]|[0-9.]+)$",
|
|
315
|
+
"summary": "Converts size scale/arbitrary utilities into width+height fallback declarations."
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
"id": "fallback.import-style.width-height-scale",
|
|
319
|
+
"pattern": "^[wh]-(\\[[^\\]]+\\]|[0-9.]+)$",
|
|
320
|
+
"summary": "Converts width/height scale and arbitrary utilities to import-* classes."
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
"id": "fallback.import-style.spacing",
|
|
324
|
+
"pattern": "^-?(?:p|px|py|pt|pb|pl|pr|m|mx|my|mt|mb|ml|mr)-(.+)$",
|
|
325
|
+
"summary": "Converts spacing utilities to directional padding/margin fallback declarations, including responsive variants."
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
"id": "fallback.import-style.text-size",
|
|
329
|
+
"pattern": "^text-(xs|sm|base|lg|xl|2xl|3xl|4xl)$",
|
|
330
|
+
"summary": "Converts common text size utilities to import-* font-size declarations."
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
"id": "fallback.import-style.font-weight",
|
|
334
|
+
"pattern": "^font-(normal|medium|semibold|bold|extrabold|black)$",
|
|
335
|
+
"summary": "Converts common font weight utilities to import-* font-weight declarations."
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
"id": "fallback.import-style.leading-tracking",
|
|
339
|
+
"pattern": "^(leading|tracking)-(none|tight|snug|normal|relaxed|loose|tighter|wide|wider|widest)$",
|
|
340
|
+
"summary": "Converts line-height and letter-spacing utilities to import-* declarations for typography fidelity."
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
"id": "fallback.import-style.bg-tokenized",
|
|
344
|
+
"pattern": "^bg-([a-z]+)-(\\d{2,3})$",
|
|
345
|
+
"summary": "Safeguards Tailwind background color utilities by mapping families like blue/purple/green/red to PDS semantic tokens."
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
"id": "fallback.import-style.bg-semantic",
|
|
349
|
+
"pattern": "^bg-(primary|secondary|accent)$",
|
|
350
|
+
"summary": "Safeguards semantic background utilities by mapping bg-primary/bg-secondary/bg-accent to PDS color tokens."
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
"id": "fallback.import-style.text-tokenized",
|
|
354
|
+
"pattern": "^text-([a-z]+)-(\\d{2,3})$",
|
|
355
|
+
"summary": "Safeguards Tailwind text color utilities by mapping common families to PDS semantic tokens."
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
"id": "fallback.import-style.rounded",
|
|
359
|
+
"pattern": "^rounded(?:-[trbl]{1,2})?(?:-(none|xs|sm|md|lg|xl|2xl|3xl|full))?$",
|
|
360
|
+
"summary": "Safeguards rounded utilities (including rounded-t-sm) by mapping to PDS radius tokens."
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
"id": "fallback.import-style.overlay-alpha",
|
|
364
|
+
"pattern": "^bg-black\\/(\\d{1,3})$",
|
|
365
|
+
"summary": "Converts alpha black overlay classes (e.g. bg-black/50) to tokenized color-mix background overlays."
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
"id": "fallback.import-style.text-inverse",
|
|
369
|
+
"pattern": "^text-white$",
|
|
370
|
+
"summary": "Preserves white foreground intent for text-on-image use cases using inverse-compatible tokens."
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
"id": "fallback.import-style.bg-arbitrary",
|
|
374
|
+
"pattern": "^bg-\\[[^\\]]+\\]$",
|
|
375
|
+
"summary": "Converts arbitrary background colors to import-* fallback classes when values are CSS-safe."
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
"id": "fallback.import-style.text-arbitrary",
|
|
379
|
+
"pattern": "^text-\\[[^\\]]+\\]$",
|
|
380
|
+
"summary": "Converts arbitrary text colors to import-* fallback classes when values are CSS-safe."
|
|
381
|
+
}
|
|
382
|
+
]
|
|
383
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { createImportResult } from "./import-contract.js";
|
|
2
|
+
|
|
3
|
+
const CATALOG_RELATIVE_URL = "../templates/templates.json";
|
|
4
|
+
const CATALOG_ABSOLUTE_URL = "/assets/pds/templates/templates.json";
|
|
5
|
+
const NODE_CWD_CATALOG = ["public", "assets", "pds", "templates", "templates.json"];
|
|
6
|
+
const NODE_PACKAGE_CATALOG_RELATIVE = ["..", "..", "..", "public", "assets", "pds", "templates", "templates.json"];
|
|
7
|
+
|
|
8
|
+
let catalogCache = null;
|
|
9
|
+
|
|
10
|
+
function isNodeRuntime() {
|
|
11
|
+
return Boolean(typeof process !== "undefined" && process?.versions?.node);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function normalizeTemplateMeta(template = {}) {
|
|
15
|
+
return {
|
|
16
|
+
id: String(template.id || "").trim(),
|
|
17
|
+
name: String(template.name || template.id || "Template").trim(),
|
|
18
|
+
description: String(template.description || "").trim(),
|
|
19
|
+
icon: String(template.icon || "layout").trim(),
|
|
20
|
+
file: String(template.file || "").trim(),
|
|
21
|
+
tags: Array.isArray(template.tags) ? template.tags.map((item) => String(item)) : [],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function normalizeCatalog(catalog = {}, sourceInfo = {}) {
|
|
26
|
+
const templatesRaw = Array.isArray(catalog)
|
|
27
|
+
? catalog
|
|
28
|
+
: Array.isArray(catalog?.templates)
|
|
29
|
+
? catalog.templates
|
|
30
|
+
: [];
|
|
31
|
+
|
|
32
|
+
const templates = templatesRaw
|
|
33
|
+
.map(normalizeTemplateMeta)
|
|
34
|
+
.filter((item) => item.id && item.file);
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
version: catalog?.version || "1",
|
|
38
|
+
templates,
|
|
39
|
+
__catalogURL: sourceInfo.catalogURL || null,
|
|
40
|
+
__catalogFilePath: sourceInfo.catalogFilePath || null,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function loadCatalogFromBrowser(options = {}) {
|
|
45
|
+
const configuredUrl = options.catalogURL || globalThis?.PDS?.currentConfig?.templateCatalogURL;
|
|
46
|
+
const candidates = [configuredUrl, CATALOG_RELATIVE_URL, CATALOG_ABSOLUTE_URL].filter(Boolean);
|
|
47
|
+
|
|
48
|
+
for (const candidate of candidates) {
|
|
49
|
+
try {
|
|
50
|
+
const url = new URL(candidate, import.meta.url).href;
|
|
51
|
+
const response = await fetch(url, { credentials: "same-origin" });
|
|
52
|
+
if (!response.ok) continue;
|
|
53
|
+
const json = await response.json();
|
|
54
|
+
return normalizeCatalog(json, { catalogURL: url });
|
|
55
|
+
} catch (error) {}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return normalizeCatalog({ templates: [] });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function loadCatalogFromNode(options = {}) {
|
|
62
|
+
const fsSpecifier = "node:fs/promises";
|
|
63
|
+
const pathSpecifier = "node:path";
|
|
64
|
+
const urlSpecifier = "node:url";
|
|
65
|
+
const [{ readFile }, path, { fileURLToPath }] = await Promise.all([
|
|
66
|
+
import(fsSpecifier),
|
|
67
|
+
import(pathSpecifier),
|
|
68
|
+
import(urlSpecifier),
|
|
69
|
+
]);
|
|
70
|
+
|
|
71
|
+
const candidates = [];
|
|
72
|
+
if (options.catalogPath) {
|
|
73
|
+
candidates.push(path.resolve(options.catalogPath));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
candidates.push(path.resolve(process.cwd(), ...NODE_CWD_CATALOG));
|
|
77
|
+
|
|
78
|
+
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
|
|
79
|
+
candidates.push(path.resolve(moduleDir, ...NODE_PACKAGE_CATALOG_RELATIVE));
|
|
80
|
+
|
|
81
|
+
for (const candidate of candidates) {
|
|
82
|
+
try {
|
|
83
|
+
const raw = await readFile(candidate, "utf8");
|
|
84
|
+
const json = JSON.parse(raw);
|
|
85
|
+
return normalizeCatalog(json, { catalogFilePath: candidate });
|
|
86
|
+
} catch (error) {}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return normalizeCatalog({ templates: [] });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function readTemplateHtml(template, catalog) {
|
|
93
|
+
if (!template?.file) return "";
|
|
94
|
+
|
|
95
|
+
if (!isNodeRuntime()) {
|
|
96
|
+
const baseUrl = catalog?.__catalogURL || CATALOG_ABSOLUTE_URL;
|
|
97
|
+
const templateUrl = new URL(template.file, baseUrl).href;
|
|
98
|
+
const response = await fetch(templateUrl, { credentials: "same-origin" });
|
|
99
|
+
if (!response.ok) {
|
|
100
|
+
throw new Error(`Template file not found: ${template.file}`);
|
|
101
|
+
}
|
|
102
|
+
return (await response.text()).trim();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const fsSpecifier = "node:fs/promises";
|
|
106
|
+
const pathSpecifier = "node:path";
|
|
107
|
+
const [{ readFile }, path] = await Promise.all([
|
|
108
|
+
import(fsSpecifier),
|
|
109
|
+
import(pathSpecifier),
|
|
110
|
+
]);
|
|
111
|
+
const baseDir = catalog?.__catalogFilePath ? path.dirname(catalog.__catalogFilePath) : path.resolve(process.cwd(), "public", "assets", "pds", "templates");
|
|
112
|
+
const templatePath = path.resolve(baseDir, template.file);
|
|
113
|
+
return (await readFile(templatePath, "utf8")).trim();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export async function loadLiveTemplateCatalog(options = {}) {
|
|
117
|
+
if (catalogCache && !options.forceReload) return catalogCache;
|
|
118
|
+
|
|
119
|
+
catalogCache = isNodeRuntime()
|
|
120
|
+
? await loadCatalogFromNode(options)
|
|
121
|
+
: await loadCatalogFromBrowser(options);
|
|
122
|
+
|
|
123
|
+
return catalogCache;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export async function listLiveTemplates(options = {}) {
|
|
127
|
+
const catalog = await loadLiveTemplateCatalog(options);
|
|
128
|
+
return catalog.templates.map(({ id, name, description, icon, file, tags }) => ({
|
|
129
|
+
id,
|
|
130
|
+
name,
|
|
131
|
+
description,
|
|
132
|
+
icon,
|
|
133
|
+
file,
|
|
134
|
+
tags,
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export async function getLiveTemplateById(templateId, options = {}) {
|
|
139
|
+
const catalog = await loadLiveTemplateCatalog(options);
|
|
140
|
+
const template = catalog.templates.find((item) => item.id === templateId) || null;
|
|
141
|
+
if (!template) return null;
|
|
142
|
+
|
|
143
|
+
const html = await readTemplateHtml(template, catalog);
|
|
144
|
+
return { ...template, html };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export async function buildTemplateImportResult(templateId, options = {}) {
|
|
148
|
+
const template = await getLiveTemplateById(templateId, options);
|
|
149
|
+
if (!template) {
|
|
150
|
+
return createImportResult({
|
|
151
|
+
source: "template",
|
|
152
|
+
type: "template",
|
|
153
|
+
confidence: 0,
|
|
154
|
+
issues: [{ severity: "error", message: `Unknown template: ${templateId}` }],
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return createImportResult({
|
|
159
|
+
source: "template",
|
|
160
|
+
type: "template",
|
|
161
|
+
confidence: 1,
|
|
162
|
+
template: {
|
|
163
|
+
id: template.id,
|
|
164
|
+
name: template.name,
|
|
165
|
+
html: template.html,
|
|
166
|
+
icon: template.icon,
|
|
167
|
+
description: template.description,
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
}
|
package/src/js/pds.d.ts
CHANGED
|
@@ -152,6 +152,7 @@ export interface PDSEventMap {
|
|
|
152
152
|
'pds:ready': CustomEvent<{ mode: 'live' | 'static'; generator?: Generator; config: any; theme: string; autoDefiner?: any }>;
|
|
153
153
|
'pds:error': CustomEvent<{ error: any }>;
|
|
154
154
|
'pds:theme:changed': CustomEvent<{ theme: string; requested?: string; source: 'system' | 'programmatic' }>;
|
|
155
|
+
'pds:config-changed': CustomEvent<{ at: number; mode?: 'live' | 'static'; source?: string; preset?: string }>;
|
|
155
156
|
'pds:design:updated': CustomEvent<{ config: any; designer?: any }>;
|
|
156
157
|
'pds:design:field:changed': CustomEvent<{ field: string; config: any }>;
|
|
157
158
|
'pds:inspector:mode:changed': CustomEvent<{ active: boolean }>;
|
package/src/js/pds.js
CHANGED
|
@@ -180,6 +180,36 @@ function __emitPDSReady(detail) {
|
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
+
function __emitPDSConfigChanged(detail = {}) {
|
|
184
|
+
const hasCustomEvent = typeof CustomEvent === "function";
|
|
185
|
+
const payload = {
|
|
186
|
+
at: Date.now(),
|
|
187
|
+
...detail,
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
try {
|
|
191
|
+
const changedEvent = hasCustomEvent
|
|
192
|
+
? new CustomEvent("pds:config-changed", { detail: payload })
|
|
193
|
+
: new Event("pds:config-changed");
|
|
194
|
+
PDS.dispatchEvent(changedEvent);
|
|
195
|
+
} catch (e) {}
|
|
196
|
+
|
|
197
|
+
if (typeof document !== "undefined") {
|
|
198
|
+
if (hasCustomEvent) {
|
|
199
|
+
const eventOptions = { detail: payload, bubbles: true, composed: true };
|
|
200
|
+
try {
|
|
201
|
+
document.dispatchEvent(
|
|
202
|
+
new CustomEvent("pds:config-changed", eventOptions)
|
|
203
|
+
);
|
|
204
|
+
} catch (e) {}
|
|
205
|
+
} else {
|
|
206
|
+
try {
|
|
207
|
+
document.dispatchEvent(new Event("pds:config-changed"));
|
|
208
|
+
} catch (e) {}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
183
213
|
if (typeof window !== "undefined") {
|
|
184
214
|
// @ts-ignore
|
|
185
215
|
window.PDS = PDS;
|
|
@@ -382,6 +412,7 @@ async function start(config) {
|
|
|
382
412
|
const { startLive } = await import(managerUrl);
|
|
383
413
|
return startLive(PDS, rest, {
|
|
384
414
|
emitReady: __emitPDSReady,
|
|
415
|
+
emitConfigChanged: __emitPDSConfigChanged,
|
|
385
416
|
applyResolvedTheme: __applyResolvedTheme,
|
|
386
417
|
setupSystemListenerIfNeeded: __setupSystemListenerIfNeeded,
|
|
387
418
|
});
|
|
@@ -490,6 +521,10 @@ async function staticInit(config) {
|
|
|
490
521
|
(s) => s._pds !== true
|
|
491
522
|
);
|
|
492
523
|
document.adoptedStyleSheets = [...others, stylesSheet];
|
|
524
|
+
__emitPDSConfigChanged({
|
|
525
|
+
mode: "static",
|
|
526
|
+
source: "static:styles-applied",
|
|
527
|
+
});
|
|
493
528
|
}
|
|
494
529
|
} catch (e) {
|
|
495
530
|
__defaultLog.call(PDS, "warn", "Failed to apply static styles:", e);
|