@kubex/zinc 1.1.97 → 1.1.99
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/AGENTS.md +5 -0
- package/CLAUDE.md +5 -0
- package/dist/chunks/zn.R2EAU6OS.js +1 -0
- package/dist/custom-elements.json +14747 -12528
- package/dist/vscode.html-custom-data.json +386 -61
- package/dist/web-types.json +1232 -481
- package/dist/zn.d.ts +529 -11
- package/dist/zn.min.js +649 -478
- package/docs/pages/components/background.md +143 -0
- package/docs/pages/components/button.md +11 -1
- package/docs/pages/components/chart.md +165 -3
- package/docs/pages/components/checkbox-group.md +13 -1
- package/docs/pages/components/checkbox.md +59 -1
- package/docs/pages/components/icon-picker.md +8 -0
- package/docs/pages/components/radio-group.md +12 -0
- package/docs/pages/components/radio.md +188 -0
- package/docs/pages/components/remarkd-editor.md +22 -0
- package/docs/pages/components/scroll-container.md +14 -15
- package/docs/pages/components/thumbnail-group.md +216 -0
- package/docs/pages/components/thumbnail.md +349 -0
- package/docs/pages/components/well.md +34 -0
- package/package.json +1 -1
- package/src/components/background/background.component.ts +111 -0
- package/src/components/background/background.scss +236 -0
- package/src/components/background/background.test.ts +120 -0
- package/src/components/background/index.ts +12 -0
- package/src/components/button/button.component.ts +8 -0
- package/src/components/chart/builders.test.ts +190 -1
- package/src/components/chart/builders.ts +246 -4
- package/src/components/chart/chart.component.ts +33 -1
- package/src/components/chart/chart.test.ts +66 -1
- package/src/components/chart/echarts-loader.ts +10 -0
- package/src/components/checkbox/checkbox.component.ts +62 -6
- package/src/components/checkbox/checkbox.scss +1 -0
- package/src/components/checkbox/checkbox.test.ts +56 -0
- package/src/components/checkbox-group/checkbox-group.component.ts +15 -0
- package/src/components/checkbox-group/checkbox-group.scss +23 -5
- package/src/components/checkbox-group/checkbox-group.test.ts +15 -0
- package/src/components/collapsible/collapsible.component.ts +49 -4
- package/src/components/collapsible/collapsible.scss +33 -14
- package/src/components/confirm/confirm.component.ts +3 -3
- package/src/components/confirm/confirm.test.ts +15 -0
- package/src/components/dialog/dialog.component.ts +3 -2
- package/src/components/editor/editor.component.ts +7 -6
- package/src/components/header/header.scss +2 -2
- package/src/components/icon-picker/icon-picker.component.ts +3 -0
- package/src/components/icon-picker/lucide-icons.ts +1756 -0
- package/src/components/navbar/navbar.scss +11 -0
- package/src/components/page/page.scss +1 -1
- package/src/components/radio/radio.component.ts +63 -7
- package/src/components/radio/radio.scss +1 -0
- package/src/components/radio/radio.test.ts +56 -0
- package/src/components/radio-group/radio-group.component.ts +16 -3
- package/src/components/radio-group/radio-group.scss +23 -4
- package/src/components/radio-group/radio-group.test.ts +15 -0
- package/src/components/remarkd-editor/remarkd-editor.component.ts +118 -5
- package/src/components/remarkd-editor/remarkd-editor.scss +8 -1
- package/src/components/remarkd-editor/remarkd-editor.test.ts +135 -0
- package/src/components/scroll-container/scroll-container.component.ts +15 -1
- package/src/components/scroll-container/scroll-container.scss +4 -2
- package/src/components/scroll-container/scroll-container.test.ts +13 -0
- package/src/components/slideout/slideout.component.ts +3 -2
- package/src/components/split-pane/split-pane.scss +21 -15
- package/src/components/thumbnail/index.ts +12 -0
- package/src/components/thumbnail/thumbnail.component.ts +460 -0
- package/src/components/thumbnail/thumbnail.scss +360 -0
- package/src/components/thumbnail/thumbnail.test.ts +379 -0
- package/src/components/thumbnail-group/index.ts +12 -0
- package/src/components/thumbnail-group/thumbnail-group.component.ts +268 -0
- package/src/components/thumbnail-group/thumbnail-group.scss +86 -0
- package/src/components/thumbnail-group/thumbnail-group.test.ts +151 -0
- package/src/components/tile/tile.scss +4 -2
- package/src/components/translation-group/translation-group.test.ts +22 -0
- package/src/components/translations/translations.component.ts +18 -3
- package/src/components/well/well.component.ts +22 -4
- package/src/components/well/well.scss +24 -0
- package/src/components/well/well.test.ts +43 -0
- package/src/form-control.scss +3 -1
- package/src/internal/conditional.ts +2 -2
- package/src/internal/form.ts +2 -1
- package/src/internal/selection-card.ts +19 -0
- package/src/selection-card.scss +187 -0
- package/src/utilities/query.test.ts +18 -1
- package/src/utilities/query.ts +8 -0
- package/src/zinc.ts +3 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
@use "../../wc";
|
|
2
|
+
|
|
3
|
+
// Defaults live in var() fallbacks rather than on :host, so a wrapper or a zn-thumbnail-group
|
|
4
|
+
// can set any of these once for every thumbnail beneath it.
|
|
5
|
+
$aspect-ratio: var(--zn-thumbnail-aspect-ratio, 16 / 9);
|
|
6
|
+
$radius: var(--zn-thumbnail-radius, var(--zn-border-radius));
|
|
7
|
+
|
|
8
|
+
// A badge, an action or the preview trigger — each one its own chip floating on the media, so
|
|
9
|
+
// several of them read as separate icons rather than one grouped container.
|
|
10
|
+
@mixin chip {
|
|
11
|
+
display: inline-flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
justify-content: center;
|
|
14
|
+
min-width: 20px;
|
|
15
|
+
min-height: 20px;
|
|
16
|
+
padding: 2px;
|
|
17
|
+
border: none;
|
|
18
|
+
border-radius: var(--zn-thumbnail-chip-radius, var(--zn-border-radius));
|
|
19
|
+
background-color: var(--zn-thumbnail-chip-background, rgba(0, 0, 0, 0.6));
|
|
20
|
+
color: var(--zn-thumbnail-chip-color, #fff);
|
|
21
|
+
line-height: 0;
|
|
22
|
+
transition: background-color var(--zn-transition-fast) ease-in-out;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Actions and the preview trigger are controls, so they take the pointer.
|
|
26
|
+
@mixin chip-interactive {
|
|
27
|
+
@include chip;
|
|
28
|
+
|
|
29
|
+
cursor: pointer;
|
|
30
|
+
|
|
31
|
+
&:hover {
|
|
32
|
+
background-color: var(--zn-thumbnail-chip-background-hover, rgba(0, 0, 0, 0.8));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
:host {
|
|
37
|
+
display: block;
|
|
38
|
+
min-width: 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.thumbnail {
|
|
42
|
+
position: relative;
|
|
43
|
+
min-width: 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.thumbnail__link {
|
|
47
|
+
display: flex;
|
|
48
|
+
flex-direction: column;
|
|
49
|
+
gap: var(--zn-spacing-x-small);
|
|
50
|
+
min-width: 0;
|
|
51
|
+
color: inherit;
|
|
52
|
+
text-decoration: none;
|
|
53
|
+
outline: none;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.thumbnail--interactive .thumbnail__link {
|
|
57
|
+
cursor: pointer;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.thumbnail__media {
|
|
61
|
+
position: relative;
|
|
62
|
+
aspect-ratio: #{$aspect-ratio};
|
|
63
|
+
width: 100%;
|
|
64
|
+
overflow: hidden;
|
|
65
|
+
border-radius: #{$radius};
|
|
66
|
+
background-color: rgb(var(--zn-panel));
|
|
67
|
+
// One ring, driven by custom properties the state rules below reassign. Routing every state
|
|
68
|
+
// through the same declaration avoids specificity fights between hover and the
|
|
69
|
+
// selected / active states.
|
|
70
|
+
--thumbnail-ring-color: rgb(var(--zn-border-color));
|
|
71
|
+
--thumbnail-ring-width: 1px;
|
|
72
|
+
--thumbnail-ring-gap: 0px;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// The ring is drawn on a pseudo-element rather than on the frame itself: an inset shadow paints
|
|
76
|
+
// under the frame's content, so the image would cover it. Positioning this above the media keeps
|
|
77
|
+
// the ring visible over the image while staying out of layout, so the group's horizontal
|
|
78
|
+
// scroller can't clip it.
|
|
79
|
+
//
|
|
80
|
+
// The gap ring is painted under the accent ring, so only the part of it that the accent
|
|
81
|
+
// doesn't cover shows — holding the accent off the image. At a 0 gap the two spreads match
|
|
82
|
+
// and the gap ring disappears entirely.
|
|
83
|
+
.thumbnail__media::after {
|
|
84
|
+
content: '';
|
|
85
|
+
position: absolute;
|
|
86
|
+
inset: 0;
|
|
87
|
+
z-index: 1;
|
|
88
|
+
border-radius: inherit;
|
|
89
|
+
pointer-events: none;
|
|
90
|
+
box-shadow:
|
|
91
|
+
inset 0 0 0 var(--thumbnail-ring-width) var(--thumbnail-ring-color),
|
|
92
|
+
inset 0 0 0 calc(var(--thumbnail-ring-width) + var(--thumbnail-ring-gap)) rgb(var(--zn-body));
|
|
93
|
+
transition: box-shadow var(--zn-transition-fast) ease-in-out;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.thumbnail__image {
|
|
97
|
+
display: block;
|
|
98
|
+
width: 100%;
|
|
99
|
+
height: 100%;
|
|
100
|
+
object-fit: cover;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Slotted media fills the frame; anything else (an icon placeholder, a label) is centred
|
|
104
|
+
// at its natural size.
|
|
105
|
+
.thumbnail__slotted-media {
|
|
106
|
+
display: grid;
|
|
107
|
+
place-items: center;
|
|
108
|
+
width: 100%;
|
|
109
|
+
height: 100%;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.thumbnail__slotted-media::slotted(img),
|
|
113
|
+
.thumbnail__slotted-media::slotted(video),
|
|
114
|
+
.thumbnail__slotted-media::slotted(canvas),
|
|
115
|
+
.thumbnail__slotted-media::slotted(picture),
|
|
116
|
+
.thumbnail__slotted-media::slotted(div) {
|
|
117
|
+
width: 100%;
|
|
118
|
+
height: 100%;
|
|
119
|
+
object-fit: cover;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.thumbnail__caption {
|
|
123
|
+
@include wc.text-style(table-content);
|
|
124
|
+
|
|
125
|
+
min-width: 0;
|
|
126
|
+
overflow: hidden;
|
|
127
|
+
text-align: center;
|
|
128
|
+
text-overflow: ellipsis;
|
|
129
|
+
white-space: nowrap;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* Overlay
|
|
133
|
+
*
|
|
134
|
+
* A layer over the media frame only — it mirrors the media's width and aspect ratio rather than
|
|
135
|
+
* covering the caption too. It sits outside the link, and is transparent to pointer events except
|
|
136
|
+
* on the chips themselves, so slotted actions keep their own click behaviour while the rest of the
|
|
137
|
+
* media still activates the link.
|
|
138
|
+
*/
|
|
139
|
+
|
|
140
|
+
.thumbnail__overlay {
|
|
141
|
+
position: absolute;
|
|
142
|
+
top: 0;
|
|
143
|
+
left: 0;
|
|
144
|
+
right: 0;
|
|
145
|
+
aspect-ratio: #{$aspect-ratio};
|
|
146
|
+
border-radius: #{$radius};
|
|
147
|
+
overflow: hidden;
|
|
148
|
+
pointer-events: none;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.thumbnail__badge,
|
|
152
|
+
.thumbnail__actions,
|
|
153
|
+
.thumbnail__preview-button {
|
|
154
|
+
position: absolute;
|
|
155
|
+
display: flex;
|
|
156
|
+
align-items: center;
|
|
157
|
+
// Adjacent markers are spaced apart rather than sharing one container.
|
|
158
|
+
gap: var(--zn-thumbnail-chip-gap, var(--zn-spacing-2x-small));
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.thumbnail__badge {
|
|
162
|
+
bottom: var(--zn-spacing-2x-small);
|
|
163
|
+
left: var(--zn-spacing-2x-small);
|
|
164
|
+
pointer-events: none;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.thumbnail__actions,
|
|
168
|
+
.thumbnail__preview-button {
|
|
169
|
+
pointer-events: auto;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.thumbnail__actions {
|
|
173
|
+
bottom: var(--zn-spacing-2x-small);
|
|
174
|
+
right: var(--zn-spacing-2x-small);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.thumbnail__preview-button {
|
|
178
|
+
@include chip-interactive;
|
|
179
|
+
|
|
180
|
+
top: var(--zn-spacing-2x-small);
|
|
181
|
+
right: var(--zn-spacing-2x-small);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// The slots themselves disappear so each slotted item becomes a flex item of its positioner,
|
|
185
|
+
// picking up the gap between markers.
|
|
186
|
+
.thumbnail__badge-items,
|
|
187
|
+
.thumbnail__action-items {
|
|
188
|
+
display: contents;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// A badge describes the asset rather than doing something, so it shares the chip's shape but is
|
|
192
|
+
// held back on opacity — enough to read as a marker instead of a control sitting next to real ones.
|
|
193
|
+
.thumbnail__badge-icon,
|
|
194
|
+
.thumbnail__badge-items::slotted(*) {
|
|
195
|
+
@include chip;
|
|
196
|
+
|
|
197
|
+
cursor: default;
|
|
198
|
+
opacity: var(--zn-thumbnail-badge-opacity, 0.65);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.thumbnail__action-items::slotted(*) {
|
|
202
|
+
@include chip-interactive;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/* Ring states
|
|
206
|
+
*
|
|
207
|
+
* Hover is excluded on a thumbnail that already carries a state ring, so hovering a selected or
|
|
208
|
+
* active thumbnail can't repaint its ring in the hover colour.
|
|
209
|
+
*/
|
|
210
|
+
|
|
211
|
+
.thumbnail:hover:not(.thumbnail--disabled):not(.thumbnail--selected):not(.thumbnail--active) .thumbnail__media {
|
|
212
|
+
--thumbnail-ring-color: rgb(var(--zn-primary));
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.thumbnail--selected .thumbnail__media {
|
|
216
|
+
--thumbnail-ring-color: var(--zn-thumbnail-selected-color, rgb(var(--zn-primary)));
|
|
217
|
+
--thumbnail-ring-width: 2px;
|
|
218
|
+
--thumbnail-ring-gap: 1px;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Listed after `selected` so an active-and-selected thumbnail shows the active colour.
|
|
222
|
+
.thumbnail--active .thumbnail__media {
|
|
223
|
+
--thumbnail-ring-color: var(--zn-thumbnail-active-color, rgb(var(--zn-color-success)));
|
|
224
|
+
--thumbnail-ring-width: 2px;
|
|
225
|
+
--thumbnail-ring-gap: 1px;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/* Focus */
|
|
229
|
+
|
|
230
|
+
.thumbnail__link:focus-visible .thumbnail__media {
|
|
231
|
+
outline: var(--zn-focus-ring);
|
|
232
|
+
outline-offset: calc(-1 * var(--zn-focus-ring-width));
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.thumbnail__preview-button:focus-visible,
|
|
236
|
+
.thumbnail__action-items::slotted(*:focus-visible) {
|
|
237
|
+
outline: var(--zn-focus-ring);
|
|
238
|
+
outline-offset: 1px;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/* Disabled */
|
|
242
|
+
|
|
243
|
+
.thumbnail--disabled {
|
|
244
|
+
.thumbnail__link {
|
|
245
|
+
cursor: not-allowed;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.thumbnail__media,
|
|
249
|
+
.thumbnail__caption {
|
|
250
|
+
opacity: 0.5;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/* Preview
|
|
255
|
+
*
|
|
256
|
+
* A native modal dialog, so it lands in the top layer and escapes the group's scroll container
|
|
257
|
+
* and any ancestor stacking context. The dialog is a transparent full-screen stage; the visible
|
|
258
|
+
* backdrop is a plain element inside it so its fade can be animated alongside the panel.
|
|
259
|
+
*/
|
|
260
|
+
|
|
261
|
+
.thumbnail__preview {
|
|
262
|
+
position: fixed;
|
|
263
|
+
inset: 0;
|
|
264
|
+
display: none;
|
|
265
|
+
width: 100%;
|
|
266
|
+
max-width: none;
|
|
267
|
+
height: 100%;
|
|
268
|
+
max-height: none;
|
|
269
|
+
padding: 0;
|
|
270
|
+
border: none;
|
|
271
|
+
background: transparent;
|
|
272
|
+
overflow: hidden;
|
|
273
|
+
|
|
274
|
+
&[open] {
|
|
275
|
+
display: grid;
|
|
276
|
+
place-items: center;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
&::backdrop {
|
|
280
|
+
background: transparent;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.thumbnail__preview-backdrop {
|
|
285
|
+
position: fixed;
|
|
286
|
+
inset: 0;
|
|
287
|
+
background: var(--zn-overlay-background-color);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.thumbnail__preview-frame {
|
|
291
|
+
// The panel takes the asset's own aspect ratio — measured in JS and published as
|
|
292
|
+
// --zn-thumbnail-preview-measured-ratio — so it wraps the image rather than letterboxing it in a
|
|
293
|
+
// fixed-ratio box. That also puts the close button on the image's corner rather than a container's.
|
|
294
|
+
--preview-max-width: var(--zn-thumbnail-preview-max-width, 70vw);
|
|
295
|
+
--preview-max-height: var(--zn-thumbnail-preview-max-height, 70vh);
|
|
296
|
+
--preview-ratio: var(--zn-thumbnail-preview-aspect-ratio,
|
|
297
|
+
var(--zn-thumbnail-preview-measured-ratio, #{$aspect-ratio}));
|
|
298
|
+
|
|
299
|
+
position: relative;
|
|
300
|
+
// Grow to the width cap, unless the ratio would then push the height past its own cap — in which
|
|
301
|
+
// case the height leads and the width follows it. Sizing the panel from viewport units rather
|
|
302
|
+
// than from the image keeps it layout-determined, so the grow animation can measure its target
|
|
303
|
+
// before the full-size asset has loaded.
|
|
304
|
+
width: min(var(--preview-max-width), calc(var(--preview-max-height) * (var(--preview-ratio))));
|
|
305
|
+
max-width: var(--preview-max-width);
|
|
306
|
+
max-height: var(--preview-max-height);
|
|
307
|
+
aspect-ratio: var(--preview-ratio);
|
|
308
|
+
overflow: hidden;
|
|
309
|
+
border-radius: var(--zn-thumbnail-preview-radius, var(--zn-border-radius));
|
|
310
|
+
background-color: rgb(var(--zn-panel));
|
|
311
|
+
box-shadow: var(--zn-shadow-x-large);
|
|
312
|
+
// The panel is scaled down onto the thumbnail's box to open, so it has to transform
|
|
313
|
+
// about its own centre.
|
|
314
|
+
transform-origin: center center;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.thumbnail__preview-image,
|
|
318
|
+
.thumbnail__preview-placeholder {
|
|
319
|
+
display: block;
|
|
320
|
+
width: 100%;
|
|
321
|
+
height: 100%;
|
|
322
|
+
object-fit: contain;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Held behind the full-size asset so the panel is never empty while it loads. Covered rather than
|
|
326
|
+
// contained, and slightly overscaled, so the blur's soft edge stays inside the panel.
|
|
327
|
+
.thumbnail__preview-placeholder {
|
|
328
|
+
position: absolute;
|
|
329
|
+
inset: 0;
|
|
330
|
+
object-fit: cover;
|
|
331
|
+
filter: blur(12px);
|
|
332
|
+
transform: scale(1.05);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
.thumbnail__preview-media::slotted(*) {
|
|
336
|
+
position: relative;
|
|
337
|
+
display: block;
|
|
338
|
+
width: 100%;
|
|
339
|
+
height: 100%;
|
|
340
|
+
object-fit: contain;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.thumbnail__preview-image {
|
|
344
|
+
position: relative;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
.thumbnail__preview-close {
|
|
348
|
+
@include chip-interactive;
|
|
349
|
+
|
|
350
|
+
position: absolute;
|
|
351
|
+
top: var(--zn-spacing-x-small);
|
|
352
|
+
right: var(--zn-spacing-x-small);
|
|
353
|
+
min-width: 28px;
|
|
354
|
+
min-height: 28px;
|
|
355
|
+
|
|
356
|
+
&:focus-visible {
|
|
357
|
+
outline: var(--zn-focus-ring);
|
|
358
|
+
outline-offset: 1px;
|
|
359
|
+
}
|
|
360
|
+
}
|