@kubex/zinc 1.1.68 → 1.1.70

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.
Files changed (37) hide show
  1. package/dist/custom-elements.json +1719 -282
  2. package/dist/vscode.html-custom-data.json +160 -29
  3. package/dist/web-types.json +395 -70
  4. package/dist/zn.d.ts +395 -16
  5. package/dist/zn.min.js +580 -408
  6. package/docs/pages/components/collapsible.md +6 -2
  7. package/docs/pages/components/icon-picker.md +14 -0
  8. package/docs/pages/components/input.md +19 -1
  9. package/docs/pages/components/preview-frame-demo.njk +33 -4
  10. package/docs/pages/components/preview-frame.md +20 -0
  11. package/docs/pages/components/theme-editor.md +303 -0
  12. package/docs/superpowers/plans/2026-08-03-theme-editor.md +1536 -0
  13. package/docs/superpowers/specs/2026-08-03-theme-editor-design.md +327 -0
  14. package/package.json +1 -1
  15. package/src/components/collapsible/collapsible.component.ts +21 -23
  16. package/src/components/dropdown/dropdown.component.ts +9 -0
  17. package/src/components/editor/editor.component.ts +20 -21
  18. package/src/components/file/file.component.ts +15 -0
  19. package/src/components/icon-picker/icon-picker.component.ts +150 -16
  20. package/src/components/icon-picker/icon-picker.scss +32 -0
  21. package/src/components/input/input.component.ts +44 -21
  22. package/src/components/input/input.scss +134 -42
  23. package/src/components/input/input.test.ts +45 -0
  24. package/src/components/preview-frame/preview-frame.component.ts +126 -16
  25. package/src/components/preview-frame/preview-frame.scss +27 -0
  26. package/src/components/preview-frame/preview-frame.test.ts +253 -0
  27. package/src/components/theme-editor/index.ts +12 -0
  28. package/src/components/theme-editor/theme-editor.component.ts +918 -0
  29. package/src/components/theme-editor/theme-editor.scss +309 -0
  30. package/src/components/theme-editor/theme-editor.test.ts +1752 -0
  31. package/src/events/events.ts +2 -0
  32. package/src/events/zn-theme-change.ts +13 -0
  33. package/src/events/zn-theme-submit.ts +9 -0
  34. package/src/types/web-test-runner-commands.d.ts +6 -0
  35. package/src/zinc.ts +1 -0
  36. package/tsconfig.json +7 -1
  37. package/web-test-runner.config.js +3 -1
@@ -0,0 +1,309 @@
1
+ @use "../../wc";
2
+
3
+ :host {
4
+ display: block;
5
+ // Matches page-builder's --palette-col.
6
+ --zn-theme-editor-controls-width: 343px;
7
+ }
8
+
9
+ .editor {
10
+ --controls-col: var(--zn-theme-editor-controls-width);
11
+
12
+ display: flex;
13
+ align-items: stretch;
14
+
15
+ &--controls-collapsed {
16
+ --controls-col: 0px;
17
+
18
+ .editor__controls {
19
+ border-right: none;
20
+ }
21
+
22
+ .editor__controls-header,
23
+ .editor__controls-body {
24
+ padding: 0;
25
+ }
26
+ }
27
+ }
28
+
29
+ // Clips the sidebar's left corners and the toolbar's top-right corner to the panel's own radius.
30
+ :host([standalone]) .editor {
31
+ background: rgb(var(--zn-panel));
32
+ border: 1px solid rgb(var(--zn-border-color));
33
+ border-radius: 8px;
34
+ overflow: hidden;
35
+ }
36
+
37
+ // Same box model as .editor__controls-header so the tab strip lines up with the preview's top edge.
38
+ .editor__toolbar {
39
+ display: flex;
40
+ align-items: center;
41
+ min-height: 44px;
42
+ gap: var(--zn-spacing-small);
43
+ padding: var(--zn-spacing-small) var(--zn-spacing-medium);
44
+ border-bottom: 1px solid rgb(var(--zn-border-color));
45
+ }
46
+
47
+ .editor__toolbar-actions {
48
+ display: flex;
49
+ align-items: center;
50
+ gap: var(--zn-spacing-small);
51
+ margin-left: auto;
52
+ }
53
+
54
+ .editor__caption {
55
+ font-size: 14px;
56
+ font-weight: 600;
57
+ line-height: 16px;
58
+ color: rgb(var(--zn-text));
59
+ }
60
+
61
+ .editor__controls {
62
+ display: flex;
63
+ flex-direction: column;
64
+ flex: 0 0 var(--controls-col);
65
+ min-width: 0;
66
+ max-width: 100%;
67
+ background: rgb(var(--zn-panel));
68
+ border-right: 1px solid rgb(var(--zn-border-color));
69
+ overflow: hidden;
70
+ transition: flex-basis 0.2s ease;
71
+ }
72
+
73
+ .editor__controls-header {
74
+ display: flex;
75
+ align-items: center;
76
+ min-height: 44px;
77
+ padding: var(--zn-spacing-small) var(--zn-spacing-medium);
78
+ }
79
+
80
+ .editor__controls-body {
81
+ display: flex;
82
+ flex-direction: column;
83
+ gap: var(--zn-spacing-medium);
84
+ flex: 1 1 auto;
85
+ }
86
+
87
+ .editor__main {
88
+ position: relative;
89
+ display: flex;
90
+ flex-direction: column;
91
+ flex: 1 1 auto;
92
+ min-width: 0;
93
+ }
94
+
95
+ .editor__fields {
96
+ display: flex;
97
+ flex-direction: column;
98
+ gap: var(--zn-spacing-medium);
99
+ }
100
+
101
+ // Supports an author hand-slotting a bare zn-collapsible into the default slot.
102
+ ::slotted(zn-collapsible) {
103
+ width: 100%;
104
+ }
105
+
106
+ // Nothing above the first section, so its divider would double the toolbar's.
107
+ .editor__fields--sections-only .editor__section:first-of-type {
108
+ border-top: none;
109
+ }
110
+
111
+ .editor__section {
112
+ display: block;
113
+ border-top: 1px solid rgba(var(--zn-border-color), .5);
114
+
115
+ // The !important beats zn-collapsible's internal .header class specificity.
116
+ &::part(header) {
117
+ align-items: center !important;
118
+ padding-block: calc(var(--zn-base-px) * 2) !important;
119
+ }
120
+
121
+ &::part(caption) {
122
+ font-size: 14px;
123
+ font-weight: 600;
124
+ line-height: 16px;
125
+ color: rgb(var(--zn-text));
126
+ }
127
+ }
128
+
129
+ .editor__section-fields {
130
+ display: flex;
131
+ flex-direction: column;
132
+ gap: var(--zn-spacing-medium);
133
+ }
134
+
135
+ // zn-tabs owns the tablist's presentation, keyboard behaviour and overflow.
136
+ .editor__tabs {
137
+ display: block;
138
+ }
139
+
140
+ .editor__section-slot {
141
+ padding-top: var(--zn-spacing-sm);
142
+ }
143
+
144
+ .editor__tab-panel {
145
+ display: flex;
146
+ flex-direction: column;
147
+ }
148
+
149
+ .editor__footer {
150
+ display: flex;
151
+ gap: var(--zn-spacing-small);
152
+ padding-top: var(--zn-spacing-small);
153
+ border-top: 1px solid rgb(var(--zn-border-color));
154
+ margin-top: auto;
155
+ }
156
+
157
+ .editor__preview {
158
+ overflow: visible;
159
+ flex: 1 1 auto;
160
+ min-width: 0;
161
+ display: flex;
162
+ flex-direction: column;
163
+ }
164
+
165
+ // A pull tab flush against the controls/main seam, rather than a dot floating
166
+ // over it, positioned against .editor__main (not .editor__preview) so it stays
167
+ // centred on the full-height seam rather than just the preview's portion of it.
168
+ // Collapsed there is no seam to attach to, so it becomes a small pill.
169
+ .panel-toggle {
170
+ position: absolute;
171
+ top: 50%;
172
+ left: 0;
173
+ z-index: 6;
174
+ transform: translateY(-50%);
175
+ display: flex;
176
+ align-items: center;
177
+ justify-content: center;
178
+ width: 18px;
179
+ height: 44px;
180
+ padding: 0;
181
+ border: 1px solid rgb(var(--zn-border-color));
182
+ border-left: 0;
183
+ border-radius: 0 6px 6px 0;
184
+ color: rgb(var(--zn-color-muted-text));
185
+ background: rgb(var(--zn-panel));
186
+ cursor: pointer;
187
+ transition: left 0.2s ease, color 0.12s ease, border-color 0.12s ease;
188
+
189
+ &:hover {
190
+ color: rgb(var(--zn-text));
191
+ background: rgba(var(--zn-border-color), 0.4);
192
+ }
193
+
194
+ &--tucked {
195
+ left: var(--zn-spacing-small);
196
+ border-left: 1px solid rgb(var(--zn-border-color));
197
+ border-radius: 6px;
198
+ }
199
+ }
200
+
201
+ .editor__devices {
202
+ display: flex;
203
+ border: 1px solid rgb(var(--zn-border-color));
204
+ border-radius: 4px;
205
+ overflow: hidden;
206
+ }
207
+
208
+ .editor__device,
209
+ .editor__mode {
210
+ display: flex;
211
+ align-items: center;
212
+ justify-content: center;
213
+ width: 30px;
214
+ height: 28px;
215
+ padding: 0;
216
+ border: 0;
217
+ background: transparent;
218
+ color: rgb(var(--zn-text));
219
+ cursor: pointer;
220
+ }
221
+
222
+ .editor__device + .editor__device {
223
+ border-left: 1px solid rgb(var(--zn-border-color));
224
+ }
225
+
226
+ .editor__device:hover,
227
+ .editor__mode:hover {
228
+ background: rgba(var(--zn-border-color), 0.5);
229
+ }
230
+
231
+ .editor__device[aria-pressed="true"] {
232
+ background: rgb(var(--zn-primary));
233
+ color: white;
234
+ }
235
+
236
+ .editor__mode {
237
+ border: 1px solid rgb(var(--zn-border-color));
238
+ border-radius: 4px;
239
+ // Sole occupant of .editor__controls-header's right side, beside the caption.
240
+ margin-left: auto;
241
+ }
242
+
243
+ .editor__sources {
244
+ width: auto;
245
+ max-width: 160px;
246
+
247
+ // Accessible name only - the label text stays out of the compact toolbar row.
248
+ &::part(form-control-label) {
249
+ position: absolute;
250
+ width: 1px;
251
+ height: 1px;
252
+ overflow: hidden;
253
+ clip: rect(0, 0, 0, 0);
254
+ white-space: nowrap;
255
+ }
256
+ }
257
+
258
+ .editor__error {
259
+ padding: var(--zn-spacing-small);
260
+ margin-bottom: var(--zn-spacing-small);
261
+ border-radius: 4px;
262
+ background: rgba(var(--zn-color-error), 0.1);
263
+ border: 1px solid rgb(var(--zn-color-error));
264
+ color: rgb(var(--zn-color-error));
265
+ font-size: 0.8125rem;
266
+ }
267
+
268
+ // 768 must match STACKED_QUERY in theme-editor.component.ts.
269
+ @media (max-width: 768px) {
270
+ .editor {
271
+ flex-direction: column;
272
+ }
273
+
274
+ .editor__controls {
275
+ flex-basis: auto;
276
+ width: 100%;
277
+ border-right: none;
278
+ border-bottom: 1px solid rgb(var(--zn-border-color));
279
+ }
280
+
281
+ .editor--controls-collapsed .editor__controls {
282
+ display: none;
283
+ }
284
+
285
+ .editor__main {
286
+ width: 100%;
287
+ // Gap between the stacked controls' bottom border and the toolbar below.
288
+ padding-top: var(--zn-spacing-medium);
289
+ }
290
+
291
+ // Stacked: the seam is horizontal, so the tab attaches to the top edge instead.
292
+ .panel-toggle {
293
+ top: 0;
294
+ left: 50%;
295
+ width: 44px;
296
+ height: 18px;
297
+ border: 1px solid rgb(var(--zn-border-color));
298
+ border-top: 0;
299
+ border-radius: 0 0 6px 6px;
300
+ transform: translateX(-50%);
301
+ }
302
+
303
+ .panel-toggle--tucked {
304
+ top: var(--zn-spacing-small);
305
+ left: 50%;
306
+ border-top: 1px solid rgb(var(--zn-border-color));
307
+ border-radius: 6px;
308
+ }
309
+ }