@sky.ui/core 0.0.58 → 0.0.60

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 (39) hide show
  1. package/auto-import.js +1 -0
  2. package/dist/custom-elements.json +3644 -3068
  3. package/dist/helper/controllers/animation-controller.js.map +1 -1
  4. package/dist/helper/controllers/popover-controller.d.ts +6 -0
  5. package/dist/helper/controllers/popover-controller.js +1 -1
  6. package/dist/helper/controllers/popover-controller.js.map +1 -1
  7. package/dist/helper/controllers/preset-controller.js.map +1 -1
  8. package/dist/helper/iconify-offline.js.map +1 -1
  9. package/dist/helper/styles/focus-ring.js.map +1 -1
  10. package/dist/helper/utils/component-presets.js.map +1 -1
  11. package/dist/helper/utils/size-resolver.js.map +1 -1
  12. package/dist/index.d.ts +1 -0
  13. package/dist/index.js +1 -1
  14. package/dist/sky-avatar/sky-avatar.js.map +1 -1
  15. package/dist/sky-button/sky-button.js +6 -1
  16. package/dist/sky-button/sky-button.js.map +1 -1
  17. package/dist/sky-chip/sky-chip.js.map +1 -1
  18. package/dist/sky-color-picker/color-model.d.ts +26 -0
  19. package/dist/sky-color-picker/color-model.js +2 -0
  20. package/dist/sky-color-picker/color-model.js.map +1 -0
  21. package/dist/sky-color-picker/index.d.ts +1 -0
  22. package/dist/sky-color-picker/index.js +1 -0
  23. package/dist/sky-color-picker/index.js.map +1 -0
  24. package/dist/sky-color-picker/sky-color-picker.d.ts +101 -0
  25. package/dist/sky-color-picker/sky-color-picker.js +418 -0
  26. package/dist/sky-color-picker/sky-color-picker.js.map +1 -0
  27. package/dist/sky-flexbox/sky-flexbox.js.map +1 -1
  28. package/dist/sky-form/sky-form.js.map +1 -1
  29. package/dist/sky-image/sky-image.js.map +1 -1
  30. package/dist/sky-image/srcset-utils.js.map +1 -1
  31. package/dist/sky-input/sky-input.d.ts +3 -0
  32. package/dist/sky-input/sky-input.js +36 -11
  33. package/dist/sky-input/sky-input.js.map +1 -1
  34. package/dist/sky-list/sky-list.js.map +1 -1
  35. package/dist/sky-listitem/sky-listitem.js.map +1 -1
  36. package/dist/sky-simple-table/sky-simple-table.js.map +1 -1
  37. package/dist/sky-theme-provider/sky-theme-provider.js +1 -1
  38. package/dist/sky-theme-provider/sky-theme-provider.js.map +1 -1
  39. package/package.json +11 -1
@@ -0,0 +1,418 @@
1
+ import{css as t,LitElement as e,nothing as i,html as s}from"lit";import{property as a,state as r,query as o,customElement as n}from"lit/decorators.js";import{live as l}from"lit/directives/live.js";import{hsva as h,parseCssColor as p,hsvaToCss as d,hsvaToHex6 as c,clamp as v,hexToHsva as u,hsvaToRgba as m,rgbaToHsva as y,hueCss as _}from"./color-model.js";var b=Object.defineProperty,g=Object.getOwnPropertyDescriptor,f=(t,e,i,s)=>{for(var a,r=s>1?void 0:s?g(e,i):e,o=t.length-1;o>=0;o--)(a=t[o])&&(r=(s?a(e,i,r):a(r))||r);return s&&r&&b(e,i,r),r};let k=class extends e{constructor(){super(...arguments),this.value="#000000",this.format="hex",this.alpha=!0,this.eyedropper=!0,this.actions=!0,this._hsva=h(0,1,1,1),this._hexDraft="#000000",this._drag=null,this._origin="",this._syncedFromProp="",this._onSvDown=t=>{t.preventDefault(),this._drag="sv",t.currentTarget.setPointerCapture?.(t.pointerId),this._svFromEvent(t)},this._onHueDown=t=>{t.preventDefault(),this._drag="hue",t.currentTarget.setPointerCapture?.(t.pointerId),this._hueFromEvent(t)},this._onAlphaDown=t=>{t.preventDefault(),this._drag="alpha",t.currentTarget.setPointerCapture?.(t.pointerId),this._alphaFromEvent(t)},this._onWinMove=t=>{this._drag&&("sv"===this._drag?this._svFromEvent(t):"hue"===this._drag?this._hueFromEvent(t):this._alphaFromEvent(t))},this._onWinUp=()=>{this._drag&&(this._drag=null,this.actions||this._emit("color-change",!0))},this._stopBubble=t=>{t.stopPropagation()}}connectedCallback(){super.connectedCallback(),this._origin=this.value,this._applyValue(this.value,!0),window.addEventListener("pointermove",this._onWinMove),window.addEventListener("pointerup",this._onWinUp),window.addEventListener("pointercancel",this._onWinUp)}disconnectedCallback(){window.removeEventListener("pointermove",this._onWinMove),window.removeEventListener("pointerup",this._onWinUp),window.removeEventListener("pointercancel",this._onWinUp),super.disconnectedCallback()}willUpdate(t){t.has("value")&&null==this._drag&&this.value!==this._syncedFromProp&&this._applyValue(this.value,!1)}_hsvaEq(t,e){return t.h===e.h&&t.s===e.s&&t.v===e.v&&t.a===e.a}_applyValue(t,e){const i=p(t)??h(0,0,0,1),s=d(i);this._hsvaEq(this._hsva,i)||(this._hsva=i),this._hexDraft!==s&&(this._hexDraft=s),this._syncedFromProp=s,e&&(this._origin=t)}get _css(){return this.alpha?d(this._hsva):c(this._hsva)}_emit(t,e){const i=this._css;this._syncedFromProp=i,this.dispatchEvent(new CustomEvent(t,{detail:{value:i},bubbles:!0,composed:!0})),!e&&this.actions||this.dispatchEvent(new CustomEvent("color-change",{detail:{value:i},bubbles:!0,composed:!0}))}_setHsva(t,e){const i=d(t);this._hsvaEq(this._hsva,t)&&this._hexDraft===i||(this._hsva=t,this._hexDraft=i,this._emit("color-input",!this.actions&&e))}_ratio(t,e,i){if(!t)return 0;const s=t.getBoundingClientRect();return v("x"===i?(e.clientX-s.left)/s.width:(e.clientY-s.top)/s.height,0,1)}_svFromEvent(t){const e=this._ratio(this._svEl,t,"x"),i=1-this._ratio(this._svEl,t,"y");this._setHsva({...this._hsva,s:e,v:i},!0)}_hueFromEvent(t){const e=360*this._ratio(this._hueEl,t,"x");this._setHsva({...this._hsva,h:e},!0)}_alphaFromEvent(t){const e=this._ratio(this._alphaEl,t,"x");this._setHsva({...this._hsva,a:e},!0)}_eventValue(t){const e=t.detail;return String(e&&"value"in e?e.value??"":t.target?.value??"")}_onHexInput(t){if(this._drag)return;const e=this._eventValue(t);this._hexDraft=e;const i=u(e.startsWith("#")?e:`#${e}`);i&&this._setHsva(i,!0)}_onRgb(t,e){if(this._drag)return;const i=v(Number(this._eventValue(e)),0,255),s=m(this._hsva);s[t]=i,this._setHsva(y(s),!0)}_onHsb(t,e){if(this._drag)return;const i=Number(this._eventValue(e));"h"===t?this._setHsva({...this._hsva,h:v(i,0,360)},!0):this._setHsva({...this._hsva,[t]:v(i,0,100)/100},!0)}_onPct(t){if(this._drag)return;const e=v(Number(this._eventValue(t)),0,100);this._setHsva({...this._hsva,a:e/100},!0)}async _eyedrop(){const t=window.EyeDropper;if(t)try{const{sRGBHex:e}=await(new t).open(),i=p(e);i&&this._setHsva({...i,a:this._hsva.a},!0)}catch{}}_done(){this._origin=this._css,this._emit("color-done",!0)}_cancel(){this._applyValue(this._origin,!1),this.dispatchEvent(new CustomEvent("color-cancel",{detail:{value:this._origin},bubbles:!0,composed:!0}))}_onFormatSelect(t){t.stopPropagation();const e=t.detail?.value;"hex"!==e&&"hsb"!==e&&"rgb"!==e||(this.format=e)}get _formatLabel(){return"hex"===this.format?"Hex":"hsb"===this.format?"HSB":"RGB"}get _canEye(){return this.eyedropper&&"undefined"!=typeof window&&"EyeDropper"in window}render(){const{h:t,s:e,v:a,a:r}=this._hsva,o=m(this._hsva),n=_(t),h=c(this._hsva);return s`
2
+ <div class="root" style="--cp-hue:${n}">
3
+ <div
4
+ part="field"
5
+ class="sv checker"
6
+ @pointerdown=${this._onSvDown}
7
+ >
8
+ <div class="sv-fill" style="opacity:${this.alpha?r:1}"></div>
9
+ <div class="thumb" style="left:${100*e}%;top:${100*(1-a)}%"></div>
10
+ </div>
11
+
12
+ <div class="tools">
13
+ <sky-button
14
+ class="eye"
15
+ type="button"
16
+ size="xs"
17
+ variant="transparent"
18
+ color="default"
19
+ animation="none"
20
+ .iconOnly=${!0}
21
+ .iconL=${"mdi:eyedropper"}
22
+ label="Sample a color"
23
+ title="Sample a color"
24
+ ?disabled=${!this._canEye}
25
+ @click=${this._eyedrop}
26
+ ></sky-button>
27
+ <div part="hue" class="track" @pointerdown=${this._onHueDown}>
28
+ <div class="track-fill hue-fill"></div>
29
+ <div class="thumb" style="left:${t/360*100}%"></div>
30
+ </div>
31
+ </div>
32
+
33
+ <div class="values">
34
+ <sky-dropdown
35
+ part="format"
36
+ class="format-dd"
37
+ trigger="click"
38
+ placement="bottom"
39
+ align="start"
40
+ .width=${"trigger"}
41
+ .closeOnClick=${!0}
42
+ .maxHeight=${"none"}
43
+ .value=${this.format}
44
+ @open=${this._stopBubble}
45
+ @close=${this._stopBubble}
46
+ @open-change=${this._stopBubble}
47
+ @dropdown-item-click=${this._stopBubble}
48
+ @dropdown-select=${this._onFormatSelect}
49
+ >
50
+ <sky-button
51
+ slot="trigger"
52
+ type="button"
53
+ size="xs"
54
+ variant="bordered"
55
+ color="default"
56
+ animation="none"
57
+ .iconR=${"mdi:chevron-down"}
58
+ .label=${this._formatLabel}
59
+ ></sky-button>
60
+ <sky-dropdown-item
61
+ value="hex"
62
+ label="Hex"
63
+ size="sm"
64
+ ?selected=${"hex"===this.format}
65
+ ></sky-dropdown-item>
66
+ <sky-dropdown-item
67
+ value="hsb"
68
+ label="HSB"
69
+ size="sm"
70
+ ?selected=${"hsb"===this.format}
71
+ ></sky-dropdown-item>
72
+ <sky-dropdown-item
73
+ value="rgb"
74
+ label="RGB"
75
+ size="sm"
76
+ ?selected=${"rgb"===this.format}
77
+ ></sky-dropdown-item>
78
+ </sky-dropdown>
79
+
80
+ ${"hex"===this.format?s`
81
+ <sky-input
82
+ class="field"
83
+ .compact=${!0}
84
+ spellcheck="false"
85
+ .ariaLabel=${"Hex color"}
86
+ .value=${l(this._hexDraft)}
87
+ @value-changed=${this._onHexInput}
88
+ ></sky-input>
89
+ `:"hsb"===this.format?s`
90
+ <div class="triple">
91
+ <sky-input
92
+ class="field"
93
+ .compact=${!0}
94
+ type="number"
95
+ min="0"
96
+ max="360"
97
+ step="1"
98
+ .ariaLabel=${"Hue"}
99
+ .value=${String(Math.round(t))}
100
+ @value-changed=${t=>this._onHsb("h",t)}
101
+ ></sky-input>
102
+ <sky-input
103
+ class="field"
104
+ .compact=${!0}
105
+ type="number"
106
+ min="0"
107
+ max="100"
108
+ step="1"
109
+ .ariaLabel=${"Saturation"}
110
+ .value=${String(Math.round(100*e))}
111
+ @value-changed=${t=>this._onHsb("s",t)}
112
+ ></sky-input>
113
+ <sky-input
114
+ class="field"
115
+ .compact=${!0}
116
+ type="number"
117
+ min="0"
118
+ max="100"
119
+ step="1"
120
+ .ariaLabel=${"Brightness"}
121
+ .value=${String(Math.round(100*a))}
122
+ @value-changed=${t=>this._onHsb("v",t)}
123
+ ></sky-input>
124
+ </div>
125
+ `:s`
126
+ <div class="triple">
127
+ <sky-input
128
+ class="field"
129
+ .compact=${!0}
130
+ type="number"
131
+ min="0"
132
+ max="255"
133
+ step="1"
134
+ .ariaLabel=${"Red"}
135
+ .value=${String(o.r)}
136
+ @value-changed=${t=>this._onRgb("r",t)}
137
+ ></sky-input>
138
+ <sky-input
139
+ class="field"
140
+ .compact=${!0}
141
+ type="number"
142
+ min="0"
143
+ max="255"
144
+ step="1"
145
+ .ariaLabel=${"Green"}
146
+ .value=${String(o.g)}
147
+ @value-changed=${t=>this._onRgb("g",t)}
148
+ ></sky-input>
149
+ <sky-input
150
+ class="field"
151
+ .compact=${!0}
152
+ type="number"
153
+ min="0"
154
+ max="255"
155
+ step="1"
156
+ .ariaLabel=${"Blue"}
157
+ .value=${String(o.b)}
158
+ @value-changed=${t=>this._onRgb("b",t)}
159
+ ></sky-input>
160
+ </div>
161
+ `}
162
+
163
+ ${this.alpha?s`
164
+ <div class="alpha-row">
165
+ <div part="alpha" class="track checker" @pointerdown=${this._onAlphaDown}>
166
+ <div
167
+ class="track-fill"
168
+ style="background:linear-gradient(to right, transparent, ${h})"
169
+ ></div>
170
+ <div class="thumb" style="left:${100*r}%"></div>
171
+ </div>
172
+ <sky-input
173
+ class="pct"
174
+ .compact=${!0}
175
+ type="number"
176
+ min="0"
177
+ max="100"
178
+ step="1"
179
+ suffix="%"
180
+ .ariaLabel=${"Opacity percent"}
181
+ .value=${String(Math.round(100*r))}
182
+ @value-changed=${this._onPct}
183
+ ></sky-input>
184
+ </div>
185
+ `:i}
186
+ </div>
187
+
188
+ ${this.actions?s`
189
+ <div class="actions">
190
+ <sky-button
191
+ type="button"
192
+ size="xs"
193
+ variant="transparent"
194
+ color="default"
195
+ animation="none"
196
+ label="Cancel"
197
+ @click=${this._cancel}
198
+ ></sky-button>
199
+ <sky-button
200
+ part="done"
201
+ type="button"
202
+ size="xs"
203
+ variant="solid"
204
+ color="primary"
205
+ animation="none"
206
+ label="Done"
207
+ @click=${this._done}
208
+ ></sky-button>
209
+ </div>
210
+ `:i}
211
+ </div>
212
+ `}};k.styles=t`
213
+ :host {
214
+ display: block;
215
+ width: 100%;
216
+ min-width: 0;
217
+ box-sizing: border-box;
218
+ padding: var(--sky-space-3, 12px);
219
+ font-family: var(--sky-font, inherit);
220
+ font-size: var(--sky-font-size-sm, 0.875rem);
221
+ font-weight: var(--sky-font-weight-normal, 400);
222
+ line-height: var(--sky-line-height-normal, 1.4);
223
+ color: var(--sky-text-primary, #15202b);
224
+ user-select: none;
225
+ --sky-focus-ring: 0 0 0 3px color-mix(
226
+ in oklch,
227
+ var(--sky-focus-ring-color, var(--sky-active-primary)) 42%,
228
+ transparent
229
+ );
230
+ }
231
+
232
+ *,
233
+ *::before,
234
+ *::after {
235
+ box-sizing: border-box;
236
+ }
237
+
238
+ .root {
239
+ display: flex;
240
+ flex-direction: column;
241
+ gap: var(--sky-space-2, 8px);
242
+ min-width: 0;
243
+ width: 100%;
244
+ }
245
+
246
+ .checker {
247
+ background-color: var(--sky-glass-solid, #fff);
248
+ background-image:
249
+ linear-gradient(45deg, color-mix(in oklch, var(--sky-text-primary) 12%, transparent) 25%, transparent 25%),
250
+ linear-gradient(-45deg, color-mix(in oklch, var(--sky-text-primary) 12%, transparent) 25%, transparent 25%),
251
+ linear-gradient(45deg, transparent 75%, color-mix(in oklch, var(--sky-text-primary) 12%, transparent) 75%),
252
+ linear-gradient(-45deg, transparent 75%, color-mix(in oklch, var(--sky-text-primary) 12%, transparent) 75%);
253
+ background-size: 8px 8px;
254
+ background-position:
255
+ 0 0,
256
+ 0 4px,
257
+ 4px -4px,
258
+ -4px 0;
259
+ }
260
+
261
+ .sv {
262
+ position: relative;
263
+ width: 100%;
264
+ aspect-ratio: 1.2 / 1;
265
+ max-height: var(--sky-color-sv-max-h, none);
266
+ border-radius: var(--sky-radius-secondary, 8px);
267
+ overflow: hidden;
268
+ cursor: crosshair;
269
+ touch-action: none;
270
+ border: var(--sky-border-tertiary, 1px solid color-mix(in oklch, var(--sky-text-primary) 12%, transparent));
271
+ }
272
+
273
+ .sv-fill {
274
+ position: absolute;
275
+ inset: 0;
276
+ background:
277
+ linear-gradient(to bottom, transparent, #000),
278
+ linear-gradient(to right, #fff, var(--cp-hue));
279
+ }
280
+
281
+ .thumb {
282
+ position: absolute;
283
+ width: 12px;
284
+ height: 12px;
285
+ border-radius: 50%;
286
+ border: 1.5px solid #fff;
287
+ box-shadow: 0 0 0 1px color-mix(in oklch, var(--sky-text-primary) 28%, transparent);
288
+ transform: translate(-50%, -50%);
289
+ pointer-events: none;
290
+ }
291
+
292
+ .tools {
293
+ display: flex;
294
+ align-items: center;
295
+ gap: var(--sky-space-2, 8px);
296
+ min-width: 0;
297
+ }
298
+
299
+ .eye {
300
+ flex-shrink: 0;
301
+ }
302
+
303
+ .track {
304
+ position: relative;
305
+ flex: 1;
306
+ min-width: 0;
307
+ height: 8px;
308
+ border-radius: 999px;
309
+ overflow: visible;
310
+ touch-action: none;
311
+ cursor: pointer;
312
+ }
313
+
314
+ .track-fill {
315
+ position: absolute;
316
+ inset: 0;
317
+ border-radius: inherit;
318
+ border: var(--sky-border-tertiary, 1px solid color-mix(in oklch, var(--sky-text-primary) 12%, transparent));
319
+ }
320
+
321
+ .hue-fill {
322
+ background: linear-gradient(
323
+ to right,
324
+ #f00,
325
+ #ff0,
326
+ #0f0,
327
+ #0ff,
328
+ #00f,
329
+ #f0f,
330
+ #f00
331
+ );
332
+ }
333
+
334
+ .track .thumb {
335
+ top: 50%;
336
+ width: 12px;
337
+ height: 12px;
338
+ }
339
+
340
+ .values {
341
+ display: grid;
342
+ grid-template-columns: auto minmax(0, 1fr);
343
+ gap: var(--sky-space-1, 4px) var(--sky-space-2, 8px);
344
+ align-items: center;
345
+ min-width: 0;
346
+ }
347
+
348
+ .format-dd {
349
+ display: block;
350
+ min-width: 4.5rem;
351
+ }
352
+
353
+ .format-dd::part(trigger) {
354
+ display: block;
355
+ width: 100%;
356
+ }
357
+
358
+ .format-dd sky-button {
359
+ display: block;
360
+ width: 100%;
361
+ box-sizing: border-box;
362
+ }
363
+
364
+ .format-dd::part(content) {
365
+ box-sizing: border-box;
366
+ padding: var(--sky-space-2, 8px);
367
+ width: var(--sky-dd-width, max-content);
368
+ min-width: var(--sky-dd-width, auto);
369
+ max-width: var(--sky-dd-width, none);
370
+ }
371
+
372
+ .format-dd::part(content-inner) {
373
+ overflow: visible;
374
+ max-height: none;
375
+ max-width: 100%;
376
+ }
377
+
378
+ .format-dd sky-dropdown-item {
379
+ --di-pad-x: 12px;
380
+ --di-pad-y: 6px;
381
+ }
382
+
383
+ .format-dd sky-dropdown-item::part(root) {
384
+ padding: 0.4rem 0.75rem;
385
+ border-radius: 6px;
386
+ }
387
+
388
+ .field,
389
+ .pct {
390
+ display: block;
391
+ width: 100%;
392
+ min-width: 0;
393
+ }
394
+
395
+ .triple {
396
+ display: grid;
397
+ grid-template-columns: repeat(3, minmax(0, 1fr));
398
+ gap: var(--sky-space-1, 4px);
399
+ min-width: 0;
400
+ }
401
+
402
+ .alpha-row {
403
+ display: grid;
404
+ grid-template-columns: minmax(0, 1fr) 5rem;
405
+ gap: var(--sky-space-2, 8px);
406
+ align-items: center;
407
+ grid-column: 1 / -1;
408
+ min-width: 0;
409
+ }
410
+
411
+ .actions {
412
+ display: flex;
413
+ justify-content: flex-end;
414
+ align-items: center;
415
+ gap: var(--sky-space-1, 4px);
416
+ }
417
+ `,f([a({type:String})],k.prototype,"value",2),f([a({type:String,reflect:!0})],k.prototype,"format",2),f([a({type:Boolean})],k.prototype,"alpha",2),f([a({type:Boolean})],k.prototype,"eyedropper",2),f([a({type:Boolean})],k.prototype,"actions",2),f([r()],k.prototype,"_hsva",2),f([r()],k.prototype,"_hexDraft",2),f([o('[part="field"]')],k.prototype,"_svEl",2),f([o('[part="hue"]')],k.prototype,"_hueEl",2),f([o('[part="alpha"]')],k.prototype,"_alphaEl",2),k=f([n("sky-color-picker")],k);export{k as SkyColorPicker};
418
+ //# sourceMappingURL=sky-color-picker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sky-color-picker.js","sources":["../../src/sky-color-picker/sky-color-picker.ts"],"sourcesContent":["import { LitElement, html, css, nothing, type PropertyValues } from 'lit'\r\nimport { customElement, property, state, query } from 'lit/decorators.js'\r\nimport { live } from 'lit/directives/live.js'\r\nimport {\r\n type ColorFormat,\r\n type Hsva,\r\n clamp,\r\n hexToHsva,\r\n hsva,\r\n hsvaToCss,\r\n hsvaToHex6,\r\n hsvaToRgba,\r\n hueCss,\r\n parseCssColor,\r\n rgbaToHsva,\r\n} from './color-model.js'\r\n\r\nexport type SkyColorPickerDetail = { value: string }\r\n\r\ntype DragTarget = 'sv' | 'hue' | 'alpha' | null\r\n\r\n/**\r\n * @element sky-color-picker\r\n *\r\n * @summary Saturation/brightness field, hue + opacity sliders, Hex/HSB/RGB, and optional eyedropper — a custom picker the native OS dialog cannot match.\r\n *\r\n * @status stable\r\n * @since 1.0.0\r\n *\r\n * @documentation https://sky-ui.com/components/color-picker\r\n *\r\n * @dependency sky-button\r\n * @dependency sky-input\r\n * @dependency sky-dropdown\r\n * @dependency sky-dropdown-item\r\n *\r\n * @csspart field - Saturation/brightness square.\r\n * @csspart hue - Hue slider track.\r\n * @csspart alpha - Opacity slider track.\r\n * @csspart format - Hex / HSB / RGB dropdown.\r\n * @csspart done - Confirm button.\r\n *\r\n * @uiVModel value color-change detail=value\r\n *\r\n * @property {string} value - CSS color (`#rgb`, `#rrggbb`, `#rrggbbaa`, `rgb()`, `rgba()`, `transparent`). Default: `\"#000000\"`.\r\n * @property {ColorFormat} format - Numeric display mode. Default: `\"hex\"`.\r\n * @property {boolean} alpha - Show opacity slider and emit hex8 when a < 1. Default: `true`.\r\n * @property {boolean} eyedropper - Show eyedropper when `EyeDropper` exists. Default: `true`.\r\n * @property {boolean} actions - Show Done / Cancel. Default: `true`.\r\n *\r\n * @event {CustomEvent<SkyColorPickerDetail>} color-input - Live while dragging (does not commit v-model).\r\n * @event {CustomEvent<SkyColorPickerDetail>} color-change - Committed value (Done, or live when `actions` is false).\r\n * @event {CustomEvent<SkyColorPickerDetail>} color-done - Done pressed.\r\n * @event {CustomEvent<SkyColorPickerDetail>} color-cancel - Cancel pressed (original value).\r\n *\r\n * @fires {CustomEvent<SkyColorPickerDetail>} color-input\r\n * @fires {CustomEvent<SkyColorPickerDetail>} color-change\r\n * @fires {CustomEvent<SkyColorPickerDetail>} color-done\r\n * @fires {CustomEvent<SkyColorPickerDetail>} color-cancel\r\n *\r\n * @example\r\n * ```html\r\n * <sky-color-picker value=\"#a23a3a94\"></sky-color-picker>\r\n * ```\r\n */\r\n@customElement('sky-color-picker')\r\nexport class SkyColorPicker extends LitElement {\r\n @property({ type: String })\r\n value = '#000000'\r\n\r\n @property({ type: String, reflect: true })\r\n format: ColorFormat = 'hex'\r\n\r\n @property({ type: Boolean })\r\n alpha = true\r\n\r\n @property({ type: Boolean })\r\n eyedropper = true\r\n\r\n @property({ type: Boolean })\r\n actions = true\r\n\r\n @state()\r\n private _hsva: Hsva = hsva(0, 1, 1, 1)\r\n\r\n @state()\r\n private _hexDraft = '#000000'\r\n\r\n @query('[part=\"field\"]')\r\n private _svEl?: HTMLElement\r\n\r\n @query('[part=\"hue\"]')\r\n private _hueEl?: HTMLElement\r\n\r\n @query('[part=\"alpha\"]')\r\n private _alphaEl?: HTMLElement\r\n\r\n private _drag: DragTarget = null\r\n private _origin = ''\r\n private _syncedFromProp = ''\r\n\r\n static override styles = css`\r\n :host {\r\n display: block;\r\n width: 100%;\r\n min-width: 0;\r\n box-sizing: border-box;\r\n padding: var(--sky-space-3, 12px);\r\n font-family: var(--sky-font, inherit);\r\n font-size: var(--sky-font-size-sm, 0.875rem);\r\n font-weight: var(--sky-font-weight-normal, 400);\r\n line-height: var(--sky-line-height-normal, 1.4);\r\n color: var(--sky-text-primary, #15202b);\r\n user-select: none;\r\n --sky-focus-ring: 0 0 0 3px color-mix(\r\n in oklch,\r\n var(--sky-focus-ring-color, var(--sky-active-primary)) 42%,\r\n transparent\r\n );\r\n }\r\n\r\n *,\r\n *::before,\r\n *::after {\r\n box-sizing: border-box;\r\n }\r\n\r\n .root {\r\n display: flex;\r\n flex-direction: column;\r\n gap: var(--sky-space-2, 8px);\r\n min-width: 0;\r\n width: 100%;\r\n }\r\n\r\n .checker {\r\n background-color: var(--sky-glass-solid, #fff);\r\n background-image:\r\n linear-gradient(45deg, color-mix(in oklch, var(--sky-text-primary) 12%, transparent) 25%, transparent 25%),\r\n linear-gradient(-45deg, color-mix(in oklch, var(--sky-text-primary) 12%, transparent) 25%, transparent 25%),\r\n linear-gradient(45deg, transparent 75%, color-mix(in oklch, var(--sky-text-primary) 12%, transparent) 75%),\r\n linear-gradient(-45deg, transparent 75%, color-mix(in oklch, var(--sky-text-primary) 12%, transparent) 75%);\r\n background-size: 8px 8px;\r\n background-position:\r\n 0 0,\r\n 0 4px,\r\n 4px -4px,\r\n -4px 0;\r\n }\r\n\r\n .sv {\r\n position: relative;\r\n width: 100%;\r\n aspect-ratio: 1.2 / 1;\r\n max-height: var(--sky-color-sv-max-h, none);\r\n border-radius: var(--sky-radius-secondary, 8px);\r\n overflow: hidden;\r\n cursor: crosshair;\r\n touch-action: none;\r\n border: var(--sky-border-tertiary, 1px solid color-mix(in oklch, var(--sky-text-primary) 12%, transparent));\r\n }\r\n\r\n .sv-fill {\r\n position: absolute;\r\n inset: 0;\r\n background:\r\n linear-gradient(to bottom, transparent, #000),\r\n linear-gradient(to right, #fff, var(--cp-hue));\r\n }\r\n\r\n .thumb {\r\n position: absolute;\r\n width: 12px;\r\n height: 12px;\r\n border-radius: 50%;\r\n border: 1.5px solid #fff;\r\n box-shadow: 0 0 0 1px color-mix(in oklch, var(--sky-text-primary) 28%, transparent);\r\n transform: translate(-50%, -50%);\r\n pointer-events: none;\r\n }\r\n\r\n .tools {\r\n display: flex;\r\n align-items: center;\r\n gap: var(--sky-space-2, 8px);\r\n min-width: 0;\r\n }\r\n\r\n .eye {\r\n flex-shrink: 0;\r\n }\r\n\r\n .track {\r\n position: relative;\r\n flex: 1;\r\n min-width: 0;\r\n height: 8px;\r\n border-radius: 999px;\r\n overflow: visible;\r\n touch-action: none;\r\n cursor: pointer;\r\n }\r\n\r\n .track-fill {\r\n position: absolute;\r\n inset: 0;\r\n border-radius: inherit;\r\n border: var(--sky-border-tertiary, 1px solid color-mix(in oklch, var(--sky-text-primary) 12%, transparent));\r\n }\r\n\r\n .hue-fill {\r\n background: linear-gradient(\r\n to right,\r\n #f00,\r\n #ff0,\r\n #0f0,\r\n #0ff,\r\n #00f,\r\n #f0f,\r\n #f00\r\n );\r\n }\r\n\r\n .track .thumb {\r\n top: 50%;\r\n width: 12px;\r\n height: 12px;\r\n }\r\n\r\n .values {\r\n display: grid;\r\n grid-template-columns: auto minmax(0, 1fr);\r\n gap: var(--sky-space-1, 4px) var(--sky-space-2, 8px);\r\n align-items: center;\r\n min-width: 0;\r\n }\r\n\r\n .format-dd {\r\n display: block;\r\n min-width: 4.5rem;\r\n }\r\n\r\n .format-dd::part(trigger) {\r\n display: block;\r\n width: 100%;\r\n }\r\n\r\n .format-dd sky-button {\r\n display: block;\r\n width: 100%;\r\n box-sizing: border-box;\r\n }\r\n\r\n .format-dd::part(content) {\r\n box-sizing: border-box;\r\n padding: var(--sky-space-2, 8px);\r\n width: var(--sky-dd-width, max-content);\r\n min-width: var(--sky-dd-width, auto);\r\n max-width: var(--sky-dd-width, none);\r\n }\r\n\r\n .format-dd::part(content-inner) {\r\n overflow: visible;\r\n max-height: none;\r\n max-width: 100%;\r\n }\r\n\r\n .format-dd sky-dropdown-item {\r\n --di-pad-x: 12px;\r\n --di-pad-y: 6px;\r\n }\r\n\r\n .format-dd sky-dropdown-item::part(root) {\r\n padding: 0.4rem 0.75rem;\r\n border-radius: 6px;\r\n }\r\n\r\n .field,\r\n .pct {\r\n display: block;\r\n width: 100%;\r\n min-width: 0;\r\n }\r\n\r\n .triple {\r\n display: grid;\r\n grid-template-columns: repeat(3, minmax(0, 1fr));\r\n gap: var(--sky-space-1, 4px);\r\n min-width: 0;\r\n }\r\n\r\n .alpha-row {\r\n display: grid;\r\n grid-template-columns: minmax(0, 1fr) 5rem;\r\n gap: var(--sky-space-2, 8px);\r\n align-items: center;\r\n grid-column: 1 / -1;\r\n min-width: 0;\r\n }\r\n\r\n .actions {\r\n display: flex;\r\n justify-content: flex-end;\r\n align-items: center;\r\n gap: var(--sky-space-1, 4px);\r\n }\r\n `\r\n\r\n override connectedCallback(): void {\r\n super.connectedCallback()\r\n this._origin = this.value\r\n this._applyValue(this.value, true)\r\n window.addEventListener('pointermove', this._onWinMove)\r\n window.addEventListener('pointerup', this._onWinUp)\r\n window.addEventListener('pointercancel', this._onWinUp)\r\n }\r\n\r\n override disconnectedCallback(): void {\r\n window.removeEventListener('pointermove', this._onWinMove)\r\n window.removeEventListener('pointerup', this._onWinUp)\r\n window.removeEventListener('pointercancel', this._onWinUp)\r\n super.disconnectedCallback()\r\n }\r\n\r\n protected override willUpdate(changed: PropertyValues<this>): void {\r\n if (changed.has('value') && this._drag == null && this.value !== this._syncedFromProp) {\r\n this._applyValue(this.value, false)\r\n }\r\n }\r\n\r\n private _hsvaEq(a: Hsva, b: Hsva) {\r\n return a.h === b.h && a.s === b.s && a.v === b.v && a.a === b.a\r\n }\r\n\r\n private _applyValue(raw: string, asOrigin: boolean) {\r\n const parsed = parseCssColor(raw) ?? hsva(0, 0, 0, 1)\r\n const css = hsvaToCss(parsed)\r\n if (!this._hsvaEq(this._hsva, parsed)) this._hsva = parsed\r\n if (this._hexDraft !== css) this._hexDraft = css\r\n this._syncedFromProp = css\r\n if (asOrigin) this._origin = raw\r\n }\r\n\r\n private get _css(): string {\r\n return this.alpha ? hsvaToCss(this._hsva) : hsvaToHex6(this._hsva)\r\n }\r\n\r\n private _emit(name: string, commit: boolean) {\r\n const value = this._css\r\n this._syncedFromProp = value\r\n this.dispatchEvent(\r\n new CustomEvent<SkyColorPickerDetail>(name, {\r\n detail: { value },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n )\r\n if (commit || !this.actions) {\r\n this.dispatchEvent(\r\n new CustomEvent<SkyColorPickerDetail>('color-change', {\r\n detail: { value },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n )\r\n }\r\n }\r\n\r\n private _setHsva(next: Hsva, isLive: boolean) {\r\n const css = hsvaToCss(next)\r\n if (this._hsvaEq(this._hsva, next) && this._hexDraft === css) return\r\n this._hsva = next\r\n this._hexDraft = css\r\n this._emit('color-input', !this.actions && isLive)\r\n }\r\n\r\n private _onSvDown = (e: PointerEvent) => {\r\n e.preventDefault()\r\n this._drag = 'sv'\r\n ;(e.currentTarget as HTMLElement).setPointerCapture?.(e.pointerId)\r\n this._svFromEvent(e)\r\n }\r\n\r\n private _onHueDown = (e: PointerEvent) => {\r\n e.preventDefault()\r\n this._drag = 'hue'\r\n ;(e.currentTarget as HTMLElement).setPointerCapture?.(e.pointerId)\r\n this._hueFromEvent(e)\r\n }\r\n\r\n private _onAlphaDown = (e: PointerEvent) => {\r\n e.preventDefault()\r\n this._drag = 'alpha'\r\n ;(e.currentTarget as HTMLElement).setPointerCapture?.(e.pointerId)\r\n this._alphaFromEvent(e)\r\n }\r\n\r\n private _onWinMove = (e: PointerEvent) => {\r\n if (!this._drag) return\r\n if (this._drag === 'sv') this._svFromEvent(e)\r\n else if (this._drag === 'hue') this._hueFromEvent(e)\r\n else this._alphaFromEvent(e)\r\n }\r\n\r\n private _onWinUp = () => {\r\n if (!this._drag) return\r\n this._drag = null\r\n if (!this.actions) this._emit('color-change', true)\r\n }\r\n\r\n private _ratio(el: HTMLElement | undefined, e: PointerEvent, axis: 'x' | 'y') {\r\n if (!el) return 0\r\n const r = el.getBoundingClientRect()\r\n if (axis === 'x') return clamp((e.clientX - r.left) / r.width, 0, 1)\r\n return clamp((e.clientY - r.top) / r.height, 0, 1)\r\n }\r\n\r\n private _svFromEvent(e: PointerEvent) {\r\n const s = this._ratio(this._svEl, e, 'x')\r\n const v = 1 - this._ratio(this._svEl, e, 'y')\r\n this._setHsva({ ...this._hsva, s, v }, true)\r\n }\r\n\r\n private _hueFromEvent(e: PointerEvent) {\r\n const h = this._ratio(this._hueEl, e, 'x') * 360\r\n this._setHsva({ ...this._hsva, h }, true)\r\n }\r\n\r\n private _alphaFromEvent(e: PointerEvent) {\r\n const a = this._ratio(this._alphaEl, e, 'x')\r\n this._setHsva({ ...this._hsva, a }, true)\r\n }\r\n\r\n private _eventValue(e: Event): string {\r\n const d = (e as CustomEvent<{ value?: unknown }>).detail\r\n if (d && 'value' in d) return String(d.value ?? '')\r\n return String((e.target as HTMLInputElement | null)?.value ?? '')\r\n }\r\n\r\n private _onHexInput(e: Event) {\r\n if (this._drag) return\r\n const raw = this._eventValue(e)\r\n this._hexDraft = raw\r\n const parsed = hexToHsva(raw.startsWith('#') ? raw : `#${raw}`)\r\n if (parsed) this._setHsva(parsed, true)\r\n }\r\n\r\n private _onRgb(channel: 'r' | 'g' | 'b', e: Event) {\r\n if (this._drag) return\r\n const n = clamp(Number(this._eventValue(e)), 0, 255)\r\n const rgb = hsvaToRgba(this._hsva)\r\n rgb[channel] = n\r\n this._setHsva(rgbaToHsva(rgb), true)\r\n }\r\n\r\n private _onHsb(channel: 'h' | 's' | 'v', e: Event) {\r\n if (this._drag) return\r\n const n = Number(this._eventValue(e))\r\n if (channel === 'h') this._setHsva({ ...this._hsva, h: clamp(n, 0, 360) }, true)\r\n else this._setHsva({ ...this._hsva, [channel]: clamp(n, 0, 100) / 100 }, true)\r\n }\r\n\r\n private _onPct(e: Event) {\r\n if (this._drag) return\r\n const n = clamp(Number(this._eventValue(e)), 0, 100)\r\n this._setHsva({ ...this._hsva, a: n / 100 }, true)\r\n }\r\n\r\n private async _eyedrop() {\r\n const Eye = (window as Window & { EyeDropper?: new () => { open: () => Promise<{ sRGBHex: string }> } }).EyeDropper\r\n if (!Eye) return\r\n try {\r\n const { sRGBHex } = await new Eye().open()\r\n const parsed = parseCssColor(sRGBHex)\r\n if (parsed) this._setHsva({ ...parsed, a: this._hsva.a }, true)\r\n } catch {\r\n /* user cancelled */\r\n }\r\n }\r\n\r\n private _done() {\r\n this._origin = this._css\r\n this._emit('color-done', true)\r\n }\r\n\r\n private _cancel() {\r\n this._applyValue(this._origin, false)\r\n this.dispatchEvent(\r\n new CustomEvent<SkyColorPickerDetail>('color-cancel', {\r\n detail: { value: this._origin },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n )\r\n }\r\n\r\n /** Nested sky-dropdown open/close is composed; stop it so the mixer parent stays open. */\r\n private _stopBubble = (e: Event) => {\r\n e.stopPropagation()\r\n }\r\n\r\n private _onFormatSelect(e: Event) {\r\n e.stopPropagation()\r\n const value = (e as CustomEvent<{ value?: string }>).detail?.value\r\n if (value === 'hex' || value === 'hsb' || value === 'rgb') this.format = value\r\n }\r\n\r\n private get _formatLabel() {\r\n return this.format === 'hex' ? 'Hex' : this.format === 'hsb' ? 'HSB' : 'RGB'\r\n }\r\n\r\n private get _canEye() {\r\n return this.eyedropper && typeof window !== 'undefined' && 'EyeDropper' in window\r\n }\r\n\r\n protected override render() {\r\n const { h, s, v, a } = this._hsva\r\n const rgb = hsvaToRgba(this._hsva)\r\n const hue = hueCss(h)\r\n const opaque = hsvaToHex6(this._hsva)\r\n\r\n return html`\r\n <div class=\"root\" style=\"--cp-hue:${hue}\">\r\n <div\r\n part=\"field\"\r\n class=\"sv checker\"\r\n @pointerdown=${this._onSvDown}\r\n >\r\n <div class=\"sv-fill\" style=\"opacity:${this.alpha ? a : 1}\"></div>\r\n <div class=\"thumb\" style=\"left:${s * 100}%;top:${(1 - v) * 100}%\"></div>\r\n </div>\r\n\r\n <div class=\"tools\">\r\n <sky-button\r\n class=\"eye\"\r\n type=\"button\"\r\n size=\"xs\"\r\n variant=\"transparent\"\r\n color=\"default\"\r\n animation=\"none\"\r\n .iconOnly=${true}\r\n .iconL=${'mdi:eyedropper'}\r\n label=\"Sample a color\"\r\n title=\"Sample a color\"\r\n ?disabled=${!this._canEye}\r\n @click=${this._eyedrop}\r\n ></sky-button>\r\n <div part=\"hue\" class=\"track\" @pointerdown=${this._onHueDown}>\r\n <div class=\"track-fill hue-fill\"></div>\r\n <div class=\"thumb\" style=\"left:${(h / 360) * 100}%\"></div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"values\">\r\n <sky-dropdown\r\n part=\"format\"\r\n class=\"format-dd\"\r\n trigger=\"click\"\r\n placement=\"bottom\"\r\n align=\"start\"\r\n .width=${'trigger'}\r\n .closeOnClick=${true}\r\n .maxHeight=${'none'}\r\n .value=${this.format}\r\n @open=${this._stopBubble}\r\n @close=${this._stopBubble}\r\n @open-change=${this._stopBubble}\r\n @dropdown-item-click=${this._stopBubble}\r\n @dropdown-select=${this._onFormatSelect}\r\n >\r\n <sky-button\r\n slot=\"trigger\"\r\n type=\"button\"\r\n size=\"xs\"\r\n variant=\"bordered\"\r\n color=\"default\"\r\n animation=\"none\"\r\n .iconR=${'mdi:chevron-down'}\r\n .label=${this._formatLabel}\r\n ></sky-button>\r\n <sky-dropdown-item\r\n value=\"hex\"\r\n label=\"Hex\"\r\n size=\"sm\"\r\n ?selected=${this.format === 'hex'}\r\n ></sky-dropdown-item>\r\n <sky-dropdown-item\r\n value=\"hsb\"\r\n label=\"HSB\"\r\n size=\"sm\"\r\n ?selected=${this.format === 'hsb'}\r\n ></sky-dropdown-item>\r\n <sky-dropdown-item\r\n value=\"rgb\"\r\n label=\"RGB\"\r\n size=\"sm\"\r\n ?selected=${this.format === 'rgb'}\r\n ></sky-dropdown-item>\r\n </sky-dropdown>\r\n\r\n ${this.format === 'hex'\r\n ? html`\r\n <sky-input\r\n class=\"field\"\r\n .compact=${true}\r\n spellcheck=\"false\"\r\n .ariaLabel=${'Hex color'}\r\n .value=${live(this._hexDraft)}\r\n @value-changed=${this._onHexInput}\r\n ></sky-input>\r\n `\r\n : this.format === 'hsb'\r\n ? html`\r\n <div class=\"triple\">\r\n <sky-input\r\n class=\"field\"\r\n .compact=${true}\r\n type=\"number\"\r\n min=\"0\"\r\n max=\"360\"\r\n step=\"1\"\r\n .ariaLabel=${'Hue'}\r\n .value=${String(Math.round(h))}\r\n @value-changed=${(e: Event) => this._onHsb('h', e)}\r\n ></sky-input>\r\n <sky-input\r\n class=\"field\"\r\n .compact=${true}\r\n type=\"number\"\r\n min=\"0\"\r\n max=\"100\"\r\n step=\"1\"\r\n .ariaLabel=${'Saturation'}\r\n .value=${String(Math.round(s * 100))}\r\n @value-changed=${(e: Event) => this._onHsb('s', e)}\r\n ></sky-input>\r\n <sky-input\r\n class=\"field\"\r\n .compact=${true}\r\n type=\"number\"\r\n min=\"0\"\r\n max=\"100\"\r\n step=\"1\"\r\n .ariaLabel=${'Brightness'}\r\n .value=${String(Math.round(v * 100))}\r\n @value-changed=${(e: Event) => this._onHsb('v', e)}\r\n ></sky-input>\r\n </div>\r\n `\r\n : html`\r\n <div class=\"triple\">\r\n <sky-input\r\n class=\"field\"\r\n .compact=${true}\r\n type=\"number\"\r\n min=\"0\"\r\n max=\"255\"\r\n step=\"1\"\r\n .ariaLabel=${'Red'}\r\n .value=${String(rgb.r)}\r\n @value-changed=${(e: Event) => this._onRgb('r', e)}\r\n ></sky-input>\r\n <sky-input\r\n class=\"field\"\r\n .compact=${true}\r\n type=\"number\"\r\n min=\"0\"\r\n max=\"255\"\r\n step=\"1\"\r\n .ariaLabel=${'Green'}\r\n .value=${String(rgb.g)}\r\n @value-changed=${(e: Event) => this._onRgb('g', e)}\r\n ></sky-input>\r\n <sky-input\r\n class=\"field\"\r\n .compact=${true}\r\n type=\"number\"\r\n min=\"0\"\r\n max=\"255\"\r\n step=\"1\"\r\n .ariaLabel=${'Blue'}\r\n .value=${String(rgb.b)}\r\n @value-changed=${(e: Event) => this._onRgb('b', e)}\r\n ></sky-input>\r\n </div>\r\n `}\r\n\r\n ${this.alpha\r\n ? html`\r\n <div class=\"alpha-row\">\r\n <div part=\"alpha\" class=\"track checker\" @pointerdown=${this._onAlphaDown}>\r\n <div\r\n class=\"track-fill\"\r\n style=\"background:linear-gradient(to right, transparent, ${opaque})\"\r\n ></div>\r\n <div class=\"thumb\" style=\"left:${a * 100}%\"></div>\r\n </div>\r\n <sky-input\r\n class=\"pct\"\r\n .compact=${true}\r\n type=\"number\"\r\n min=\"0\"\r\n max=\"100\"\r\n step=\"1\"\r\n suffix=\"%\"\r\n .ariaLabel=${'Opacity percent'}\r\n .value=${String(Math.round(a * 100))}\r\n @value-changed=${this._onPct}\r\n ></sky-input>\r\n </div>\r\n `\r\n : nothing}\r\n </div>\r\n\r\n ${this.actions\r\n ? html`\r\n <div class=\"actions\">\r\n <sky-button\r\n type=\"button\"\r\n size=\"xs\"\r\n variant=\"transparent\"\r\n color=\"default\"\r\n animation=\"none\"\r\n label=\"Cancel\"\r\n @click=${this._cancel}\r\n ></sky-button>\r\n <sky-button\r\n part=\"done\"\r\n type=\"button\"\r\n size=\"xs\"\r\n variant=\"solid\"\r\n color=\"primary\"\r\n animation=\"none\"\r\n label=\"Done\"\r\n @click=${this._done}\r\n ></sky-button>\r\n </div>\r\n `\r\n : nothing}\r\n </div>\r\n `\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n 'sky-color-picker': SkyColorPicker\r\n }\r\n}\r\n"],"names":["SkyColorPicker","LitElement","constructor","super","arguments","this","value","format","alpha","eyedropper","actions","_hsva","hsva","_hexDraft","_drag","_origin","_syncedFromProp","_onSvDown","e","preventDefault","currentTarget","setPointerCapture","pointerId","_svFromEvent","_onHueDown","_hueFromEvent","_onAlphaDown","_alphaFromEvent","_onWinMove","_onWinUp","_emit","_stopBubble","stopPropagation","connectedCallback","_applyValue","window","addEventListener","disconnectedCallback","removeEventListener","willUpdate","changed","has","_hsvaEq","a","b","h","s","v","raw","asOrigin","parsed","parseCssColor","css","hsvaToCss","_css","hsvaToHex6","name","commit","dispatchEvent","CustomEvent","detail","bubbles","composed","_setHsva","next","isLive","_ratio","el","axis","r","getBoundingClientRect","clamp","clientX","left","width","clientY","top","height","_svEl","_hueEl","_alphaEl","_eventValue","d","String","target","_onHexInput","hexToHsva","startsWith","_onRgb","channel","n","Number","rgb","hsvaToRgba","rgbaToHsva","_onHsb","_onPct","_eyedrop","Eye","EyeDropper","sRGBHex","open","_done","_cancel","_onFormatSelect","_formatLabel","_canEye","render","hue","hueCss","opaque","html","live","Math","round","g","nothing","styles","__decorateClass","property","type","prototype","reflect","Boolean","state","query","customElement"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sky-flexbox.js","sources":["../../src/sky-flexbox/sky-flexbox.ts"],"sourcesContent":["import { LitElement, html, css } from \"lit\";\r\nimport { customElement, property } from \"lit/decorators.js\";\r\nimport { PresetController } from \"../helper/controllers/preset-controller\";\r\n\r\nexport type SkyFlexboxDirection = \"row\" | \"row-reverse\" | \"column\" | \"column-reverse\";\r\nexport type SkyFlexboxWrap = \"nowrap\" | \"wrap\" | \"wrap-reverse\";\r\nexport type SkyFlexboxJustify =\r\n | \"flex-start\"\r\n | \"center\"\r\n | \"flex-end\"\r\n | \"space-between\"\r\n | \"space-around\"\r\n | \"space-evenly\";\r\nexport type SkyFlexboxAlign = \"stretch\" | \"flex-start\" | \"center\" | \"flex-end\" | \"baseline\";\r\nexport type SkyFlexboxAlignContent =\r\n | \"normal\"\r\n | \"stretch\"\r\n | \"center\"\r\n | \"start\"\r\n | \"end\"\r\n | \"flex-start\"\r\n | \"flex-end\"\r\n | \"space-between\"\r\n | \"space-around\"\r\n | \"space-evenly\";\r\n\r\n/**\r\n * @element sky-flexbox\r\n *\r\n * @summary Flexbox container with grid-like span support for slotted children.\r\n *\r\n * @status stable\r\n * @since 1.0.0\r\n *\r\n * @documentation https://sky-ui.com/components/flexbox\r\n *\r\n * @slot - Default slot for flex items (`<sky-flexcol>` or plain elements with `span` attributes).\r\n *\r\n * @property {SkyFlexboxDirection} direction - Flex direction.\r\n * @property {SkyFlexboxWrap} wrap - Flex wrap behavior.\r\n * @property {SkyFlexboxJustify} justify - Main-axis alignment.\r\n * @property {SkyFlexboxAlign} align - Cross-axis alignment.\r\n * @property {SkyFlexboxAlignContent} alignContent - Multi-line cross-axis distribution.\r\n * @property {string} gap - Shared row/column gap value.\r\n * @property {string | undefined} gapX - Horizontal gap override.\r\n * @property {string | undefined} gapY - Vertical gap override.\r\n * @property {number} col - Total column count used for span calculations.\r\n * @property {string} preset - Named prop preset from nearest `sky-config-provider`. Default: `\"\"`.\r\n *\r\n * @fires {Event} slotchange - Fired when slotted children change.\r\n * @method recalculateSpans Recomputes slotted child span CSS variables.\r\n *\r\n * @csspart container - The flex container element.\r\n *\r\n * @Behavior\r\n * - Implements CSS Flexbox with custom property-based configuration\r\n * - Supports responsive span calculations based on column grid system\r\n * - Automatically manages CSS custom properties for child elements\r\n * - Handles responsive breakpoints through span attributes\r\n *\r\n * - Uses a configurable column count (default: 12)\r\n * - Calculates item widths based on span values (1-col through total columns)\r\n * - Supports responsive spans: `span-lg`, `span-md`, `span-sm`, `span-xs`\r\n * - Clamps span values to valid range (1 to column count)\r\n *\r\n * - Supports unified `gap` property\r\n * - Optional `gapX` and `gapY` for separate horizontal/vertical spacing\r\n * - Gap values can use any CSS unit (px, rem, em, %, etc.)\r\n *\r\n * @example\r\n * ```html\r\n * <sky-flexbox col=\"12\" gap=\"16px\">\r\n * <sky-flexcol span=\"8\" span-md=\"12\">\r\n * Main content\r\n * </sky-flexcol>\r\n * <sky-flexcol span=\"4\" span-md=\"12\">\r\n * Sidebar\r\n * </sky-flexcol>\r\n * </sky-flexbox>\r\n * ```\r\n * ```vue\r\n * <template>\r\n * <sky-flexbox col=\"12\" gap=\"16px\">\r\n * <sky-flexcol span=\"8\" span-md=\"12\">Main content</sky-flexcol>\r\n * <sky-flexcol span=\"4\" span-md=\"12\">Sidebar</sky-flexcol>\r\n * </sky-flexbox>\r\n * </template>\r\n * ```\r\n * ```jsx\r\n * export default function Demo() {\r\n * return (\r\n * <sky-flexbox col=\"12\" gap=\"16px\">\r\n * <sky-flexcol span=\"8\" span-md=\"12\">Main content</sky-flexcol>\r\n * <sky-flexcol span=\"4\" span-md=\"12\">Sidebar</sky-flexcol>\r\n * </sky-flexbox>\r\n * );\r\n * }\r\n * ```\r\n */\r\n@customElement(\"sky-flexbox\")\r\nexport class SkyFlexbox extends LitElement {\r\n /**\r\n * Flex direction.\r\n * @public\r\n */\r\n @property({ type: String })\r\n direction: SkyFlexboxDirection = \"row\";\r\n\r\n /**\r\n * Wrap behavior.\r\n * @public\r\n */\r\n @property({ type: String })\r\n wrap: SkyFlexboxWrap = \"wrap\";\r\n\r\n /**\r\n * Main axis justification.\r\n * @public\r\n */\r\n @property({ type: String })\r\n justify: SkyFlexboxJustify = \"flex-start\";\r\n\r\n /**\r\n * Cross axis alignment.\r\n * @public\r\n */\r\n @property({ type: String })\r\n align: SkyFlexboxAlign = \"stretch\";\r\n\r\n /**\r\n * Multi-line alignment (when wrapping).\r\n * @public\r\n */\r\n @property({ type: String })\r\n alignContent: SkyFlexboxAlignContent = \"normal\";\r\n\r\n /**\r\n * Shorthand gap; used if gapX/gapY not provided.\r\n * @public\r\n */\r\n @property({ type: String }) gap: string = \"16px\";\r\n\r\n /**\r\n * Column gap.\r\n * @public\r\n */\r\n @property({ type: String })\r\n gapX?: string;\r\n\r\n /**\r\n * Row gap.\r\n * @public\r\n */\r\n @property({ type: String })\r\n gapY?: string;\r\n\r\n /**\r\n * Total columns used for span calculation.\r\n * @public\r\n */\r\n @property({ type: Number }) col: number = 12;\r\n\r\n\r\n /** Named prop preset from nearest `sky-config-provider`. */\r\n @property({ type: String, reflect: true }) preset = \"\";\r\n\r\n private _presets = new PresetController(this);\r\n\r\n static override styles = css`\r\n :host {\r\n display: block;\r\n }\r\n\r\n .flex-container {\r\n display: flex;\r\n box-sizing: border-box;\r\n flex-wrap: var(--wrap, wrap);\r\n gap: var(--gap-y, var(--gap, 16px)) var(--gap-x, var(--gap, 16px));\r\n justify-content: var(--justify, flex-start);\r\n align-items: var(--align, stretch);\r\n align-content: var(--align-content, normal);\r\n flex-direction: var(--direction, row);\r\n }\r\n\r\n /* Default behaviour for any slotted child: */\r\n ::slotted(*) {\r\n box-sizing: border-box;\r\n min-width: 0;\r\n }\r\n\r\n .flex-container.is-row ::slotted(*) {\r\n flex-grow: 0;\r\n flex-shrink: 1;\r\n flex-basis: auto;\r\n max-width: none;\r\n }\r\n\r\n .flex-container.is-row ::slotted([data-flex-span]) {\r\n flex-shrink: 0;\r\n --span-current: var(--span, 1);\r\n --span-width: calc(\r\n 100% * var(--span-current) / var(--columns, 12) -\r\n var(--gap-x, var(--gap, 16px)) *\r\n (var(--columns, 12) - var(--span-current)) / var(--columns, 12)\r\n );\r\n\r\n flex-basis: var(--span-width);\r\n width: var(--span-width);\r\n max-width: var(--span-width);\r\n }\r\n\r\n .flex-container.is-column ::slotted(*) {\r\n width: 100%;\r\n flex-basis: auto;\r\n max-width: none;\r\n flex-shrink: 0;\r\n }\r\n\r\n @media (max-width: 1200px) {\r\n .flex-container.is-row ::slotted([data-flex-span]) {\r\n --span-current: var(--span-lg, var(--span-current));\r\n }\r\n }\r\n\r\n @media (max-width: 992px) {\r\n .flex-container.is-row ::slotted([data-flex-span]) {\r\n --span-current: var(--span-md, var(--span-current));\r\n }\r\n }\r\n\r\n @media (max-width: 768px) {\r\n .flex-container.is-row ::slotted([data-flex-span]) {\r\n --span-current: var(--span-sm, var(--span-current));\r\n }\r\n }\r\n\r\n @media (max-width: 576px) {\r\n .flex-container.is-row ::slotted([data-flex-span]) {\r\n --span-current: var(--span-xs, var(--span-current));\r\n }\r\n }\r\n `;\r\n\r\n /** @private */\r\n private _childMo?: MutationObserver;\r\n private _spansRaf = 0;\r\n\r\n /** @protected */\r\n override connectedCallback() {\r\n super.connectedCallback();\r\n this._childMo = new MutationObserver(() => this._scheduleUpdateSpans());\r\n this._childMo.observe(this, {\r\n childList: true,\r\n subtree: true,\r\n attributes: true,\r\n attributeFilter: [\"span\", \"span-lg\", \"span-md\", \"span-sm\", \"span-xs\"],\r\n });\r\n }\r\n\r\n /** @protected */\r\n override disconnectedCallback() {\r\n super.disconnectedCallback();\r\n if (this._spansRaf) {\r\n cancelAnimationFrame(this._spansRaf);\r\n this._spansRaf = 0;\r\n }\r\n this._childMo?.disconnect();\r\n }\r\n\r\n /** @protected */\r\n override firstUpdated() {\r\n this.syncVars();\r\n this.updateSpans(); // initial\r\n }\r\n\r\n /** @protected */\r\n override updated(changed: Map<string | number | symbol, unknown>) {\r\n if (\r\n changed.has(\"wrap\") ||\r\n changed.has(\"gap\") ||\r\n changed.has(\"gapX\") ||\r\n changed.has(\"gapY\") ||\r\n changed.has(\"col\") ||\r\n changed.has(\"justify\") ||\r\n changed.has(\"direction\") ||\r\n changed.has(\"align\") ||\r\n changed.has(\"alignContent\")\r\n ) {\r\n this.syncVars();\r\n }\r\n if (changed.has(\"col\")) {\r\n this.updateSpans(); // re-validate span bounds when column count changes\r\n }\r\n }\r\n\r\n /**\r\n * Syncs component properties to CSS custom properties.\r\n * @private\r\n */\r\n private syncVars() {\r\n const styles = {\r\n \"--wrap\": this.wrap,\r\n \"--gap\": this.gap,\r\n \"--gap-x\": this.gapX ?? this.gap,\r\n \"--gap-y\": this.gapY ?? this.gap,\r\n \"--columns\": String(this.col),\r\n \"--justify\": this.justify,\r\n \"--direction\": this.direction,\r\n \"--align\": this.align,\r\n \"--align-content\": this.alignContent,\r\n } as Record<string, string>;\r\n Object.entries(styles).forEach(([k, v]) => this.style.setProperty(k, v));\r\n }\r\n\r\n /**\r\n * Forces recalculation of spans for all child elements.\r\n * Useful when dynamically adding/removing items.\r\n * @public\r\n */\r\n public recalculateSpans() {\r\n this.updateSpans();\r\n }\r\n\r\n /** @protected */\r\n override render() {\r\n const isColumn =\r\n this.direction === \"column\" || this.direction === \"column-reverse\";\r\n\r\n return html`\r\n <div\r\n class=\"flex-container ${isColumn ? \"is-column\" : \"is-row\"}\"\r\n part=\"container\"\r\n >\r\n <slot @slotchange=${this.updateSpans}></slot>\r\n </div>\r\n `;\r\n }\r\n\r\n private _scheduleUpdateSpans = () => {\r\n if (this._spansRaf) return;\r\n this._spansRaf = requestAnimationFrame(() => {\r\n this._spansRaf = 0;\r\n this.updateSpans();\r\n });\r\n };\r\n\r\n /**\r\n * Reads span attributes off slotted children and maps them to CSS vars:\r\n * span, span-lg, span-md, span-sm, span-xs\r\n * @private\r\n */\r\n private updateSpans = () => {\r\n const nodes =\r\n this.shadowRoot\r\n ?.querySelector(\"slot\")\r\n ?.assignedElements({ flatten: true }) ?? [];\r\n for (const el of nodes) {\r\n if (!(el instanceof HTMLElement)) continue;\r\n\r\n this.applySpanVar(el, \"--span\", this.readSpanRaw(el, \"span\", \"span\"));\r\n this.applySpanVar(el, \"--span-lg\", this.readSpanRaw(el, \"span-lg\", \"spanLg\"));\r\n this.applySpanVar(el, \"--span-md\", this.readSpanRaw(el, \"span-md\", \"spanMd\"));\r\n this.applySpanVar(el, \"--span-sm\", this.readSpanRaw(el, \"span-sm\", \"spanSm\"));\r\n this.applySpanVar(el, \"--span-xs\", this.readSpanRaw(el, \"span-xs\", \"spanXs\"));\r\n\r\n const hasSpan =\r\n this.readSpanRaw(el, \"span\", \"span\") != null ||\r\n this.readSpanRaw(el, \"span-lg\", \"spanLg\") != null ||\r\n this.readSpanRaw(el, \"span-md\", \"spanMd\") != null ||\r\n this.readSpanRaw(el, \"span-sm\", \"spanSm\") != null ||\r\n this.readSpanRaw(el, \"span-xs\", \"spanXs\") != null;\r\n\r\n if (hasSpan) el.dataset.flexSpan = \"\";\r\n else delete el.dataset.flexSpan;\r\n }\r\n };\r\n\r\n /**\r\n * Reads a span value from an HTML attribute or element property.\r\n * @private\r\n */\r\n private readSpanRaw(\r\n el: HTMLElement,\r\n attrName: string,\r\n propName: string,\r\n ): string | null {\r\n const fromAttr = el.getAttribute(attrName);\r\n if (fromAttr != null && fromAttr !== \"\") return fromAttr;\r\n const fromProp = (el as unknown as Record<string, unknown>)[propName];\r\n if (fromProp != null && fromProp !== \"\") return String(fromProp);\r\n return null;\r\n }\r\n\r\n /**\r\n * Sets or clears a span CSS variable on a slotted child.\r\n * @private\r\n */\r\n private applySpanVar(\r\n el: HTMLElement,\r\n cssVar: string,\r\n raw: string | null,\r\n ): void {\r\n const value = this.clampSpan(raw);\r\n if (value) el.style.setProperty(cssVar, String(value));\r\n else el.style.removeProperty(cssVar);\r\n }\r\n\r\n /**\r\n * Clamps span value to valid range (1 to column count).\r\n * @param raw - Raw span value from attribute\r\n * @returns Clamped number or null if invalid\r\n * @private\r\n */\r\n private clampSpan(raw: string | null): number | null {\r\n if (!raw) return null;\r\n const n = Math.max(1, Math.min(this.col, Number(raw) || 1));\r\n return n;\r\n }\r\n}\r\n"],"names":["SkyFlexbox","LitElement","constructor","super","arguments","this","direction","wrap","justify","align","alignContent","gap","col","preset","_presets","PresetController","_spansRaf","_scheduleUpdateSpans","requestAnimationFrame","updateSpans","nodes","shadowRoot","querySelector","assignedElements","flatten","el","HTMLElement","applySpanVar","readSpanRaw","dataset","flexSpan","connectedCallback","_childMo","MutationObserver","observe","childList","subtree","attributes","attributeFilter","disconnectedCallback","cancelAnimationFrame","disconnect","firstUpdated","syncVars","updated","changed","has","styles","gapX","gapY","String","Object","entries","forEach","k","v","style","setProperty","recalculateSpans","render","isColumn","html","attrName","propName","fromAttr","getAttribute","fromProp","cssVar","raw","value","clampSpan","removeProperty","Math","max","min","Number","css","__decorateClass","property","type","prototype","reflect","customElement"],"mappings":"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"}
1
+ {"version":3,"file":"sky-flexbox.js","sources":["../../src/sky-flexbox/sky-flexbox.ts"],"sourcesContent":["import { LitElement, html, css } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { PresetController } from \"../helper/controllers/preset-controller\";\n\nexport type SkyFlexboxDirection = \"row\" | \"row-reverse\" | \"column\" | \"column-reverse\";\nexport type SkyFlexboxWrap = \"nowrap\" | \"wrap\" | \"wrap-reverse\";\nexport type SkyFlexboxJustify =\n | \"flex-start\"\n | \"center\"\n | \"flex-end\"\n | \"space-between\"\n | \"space-around\"\n | \"space-evenly\";\nexport type SkyFlexboxAlign = \"stretch\" | \"flex-start\" | \"center\" | \"flex-end\" | \"baseline\";\nexport type SkyFlexboxAlignContent =\n | \"normal\"\n | \"stretch\"\n | \"center\"\n | \"start\"\n | \"end\"\n | \"flex-start\"\n | \"flex-end\"\n | \"space-between\"\n | \"space-around\"\n | \"space-evenly\";\n\n/**\n * @element sky-flexbox\n *\n * @summary Flexbox container with grid-like span support for slotted children.\n *\n * @status stable\n * @since 1.0.0\n *\n * @documentation https://sky-ui.com/components/flexbox\n *\n * @slot - Default slot for flex items (`<sky-flexcol>` or plain elements with `span` attributes).\n *\n * @property {SkyFlexboxDirection} direction - Flex direction.\n * @property {SkyFlexboxWrap} wrap - Flex wrap behavior.\n * @property {SkyFlexboxJustify} justify - Main-axis alignment.\n * @property {SkyFlexboxAlign} align - Cross-axis alignment.\n * @property {SkyFlexboxAlignContent} alignContent - Multi-line cross-axis distribution.\n * @property {string} gap - Shared row/column gap value.\n * @property {string | undefined} gapX - Horizontal gap override.\n * @property {string | undefined} gapY - Vertical gap override.\n * @property {number} col - Total column count used for span calculations.\n * @property {string} preset - Named prop preset from nearest `sky-config-provider`. Default: `\"\"`.\n *\n * @fires {Event} slotchange - Fired when slotted children change.\n * @method recalculateSpans Recomputes slotted child span CSS variables.\n *\n * @csspart container - The flex container element.\n *\n * @Behavior\n * - Implements CSS Flexbox with custom property-based configuration\n * - Supports responsive span calculations based on column grid system\n * - Automatically manages CSS custom properties for child elements\n * - Handles responsive breakpoints through span attributes\n *\n * - Uses a configurable column count (default: 12)\n * - Calculates item widths based on span values (1-col through total columns)\n * - Supports responsive spans: `span-lg`, `span-md`, `span-sm`, `span-xs`\n * - Clamps span values to valid range (1 to column count)\n *\n * - Supports unified `gap` property\n * - Optional `gapX` and `gapY` for separate horizontal/vertical spacing\n * - Gap values can use any CSS unit (px, rem, em, %, etc.)\n *\n * @example\n * ```html\n * <sky-flexbox col=\"12\" gap=\"16px\">\n * <sky-flexcol span=\"8\" span-md=\"12\">\n * Main content\n * </sky-flexcol>\n * <sky-flexcol span=\"4\" span-md=\"12\">\n * Sidebar\n * </sky-flexcol>\n * </sky-flexbox>\n * ```\n * ```vue\n * <template>\n * <sky-flexbox col=\"12\" gap=\"16px\">\n * <sky-flexcol span=\"8\" span-md=\"12\">Main content</sky-flexcol>\n * <sky-flexcol span=\"4\" span-md=\"12\">Sidebar</sky-flexcol>\n * </sky-flexbox>\n * </template>\n * ```\n * ```jsx\n * export default function Demo() {\n * return (\n * <sky-flexbox col=\"12\" gap=\"16px\">\n * <sky-flexcol span=\"8\" span-md=\"12\">Main content</sky-flexcol>\n * <sky-flexcol span=\"4\" span-md=\"12\">Sidebar</sky-flexcol>\n * </sky-flexbox>\n * );\n * }\n * ```\n */\n@customElement(\"sky-flexbox\")\nexport class SkyFlexbox extends LitElement {\n /**\n * Flex direction.\n * @public\n */\n @property({ type: String })\n direction: SkyFlexboxDirection = \"row\";\n\n /**\n * Wrap behavior.\n * @public\n */\n @property({ type: String })\n wrap: SkyFlexboxWrap = \"wrap\";\n\n /**\n * Main axis justification.\n * @public\n */\n @property({ type: String })\n justify: SkyFlexboxJustify = \"flex-start\";\n\n /**\n * Cross axis alignment.\n * @public\n */\n @property({ type: String })\n align: SkyFlexboxAlign = \"stretch\";\n\n /**\n * Multi-line alignment (when wrapping).\n * @public\n */\n @property({ type: String })\n alignContent: SkyFlexboxAlignContent = \"normal\";\n\n /**\n * Shorthand gap; used if gapX/gapY not provided.\n * @public\n */\n @property({ type: String }) gap: string = \"16px\";\n\n /**\n * Column gap.\n * @public\n */\n @property({ type: String })\n gapX?: string;\n\n /**\n * Row gap.\n * @public\n */\n @property({ type: String })\n gapY?: string;\n\n /**\n * Total columns used for span calculation.\n * @public\n */\n @property({ type: Number }) col: number = 12;\n\n\n /** Named prop preset from nearest `sky-config-provider`. */\n @property({ type: String, reflect: true }) preset = \"\";\n\n private _presets = new PresetController(this);\n\n static override styles = css`\n :host {\n display: block;\n }\n\n .flex-container {\n display: flex;\n box-sizing: border-box;\n flex-wrap: var(--wrap, wrap);\n gap: var(--gap-y, var(--gap, 16px)) var(--gap-x, var(--gap, 16px));\n justify-content: var(--justify, flex-start);\n align-items: var(--align, stretch);\n align-content: var(--align-content, normal);\n flex-direction: var(--direction, row);\n }\n\n /* Default behaviour for any slotted child: */\n ::slotted(*) {\n box-sizing: border-box;\n min-width: 0;\n }\n\n .flex-container.is-row ::slotted(*) {\n flex-grow: 0;\n flex-shrink: 1;\n flex-basis: auto;\n max-width: none;\n }\n\n .flex-container.is-row ::slotted([data-flex-span]) {\n flex-shrink: 0;\n --span-current: var(--span, 1);\n --span-width: calc(\n 100% * var(--span-current) / var(--columns, 12) -\n var(--gap-x, var(--gap, 16px)) *\n (var(--columns, 12) - var(--span-current)) / var(--columns, 12)\n );\n\n flex-basis: var(--span-width);\n width: var(--span-width);\n max-width: var(--span-width);\n }\n\n .flex-container.is-column ::slotted(*) {\n width: 100%;\n flex-basis: auto;\n max-width: none;\n flex-shrink: 0;\n }\n\n @media (max-width: 1200px) {\n .flex-container.is-row ::slotted([data-flex-span]) {\n --span-current: var(--span-lg, var(--span-current));\n }\n }\n\n @media (max-width: 992px) {\n .flex-container.is-row ::slotted([data-flex-span]) {\n --span-current: var(--span-md, var(--span-current));\n }\n }\n\n @media (max-width: 768px) {\n .flex-container.is-row ::slotted([data-flex-span]) {\n --span-current: var(--span-sm, var(--span-current));\n }\n }\n\n @media (max-width: 576px) {\n .flex-container.is-row ::slotted([data-flex-span]) {\n --span-current: var(--span-xs, var(--span-current));\n }\n }\n `;\n\n /** @private */\n private _childMo?: MutationObserver;\n private _spansRaf = 0;\n\n /** @protected */\n override connectedCallback() {\n super.connectedCallback();\n this._childMo = new MutationObserver(() => this._scheduleUpdateSpans());\n this._childMo.observe(this, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"span\", \"span-lg\", \"span-md\", \"span-sm\", \"span-xs\"],\n });\n }\n\n /** @protected */\n override disconnectedCallback() {\n super.disconnectedCallback();\n if (this._spansRaf) {\n cancelAnimationFrame(this._spansRaf);\n this._spansRaf = 0;\n }\n this._childMo?.disconnect();\n }\n\n /** @protected */\n override firstUpdated() {\n this.syncVars();\n this.updateSpans(); // initial\n }\n\n /** @protected */\n override updated(changed: Map<string | number | symbol, unknown>) {\n if (\n changed.has(\"wrap\") ||\n changed.has(\"gap\") ||\n changed.has(\"gapX\") ||\n changed.has(\"gapY\") ||\n changed.has(\"col\") ||\n changed.has(\"justify\") ||\n changed.has(\"direction\") ||\n changed.has(\"align\") ||\n changed.has(\"alignContent\")\n ) {\n this.syncVars();\n }\n if (changed.has(\"col\")) {\n this.updateSpans(); // re-validate span bounds when column count changes\n }\n }\n\n /**\n * Syncs component properties to CSS custom properties.\n * @private\n */\n private syncVars() {\n const styles = {\n \"--wrap\": this.wrap,\n \"--gap\": this.gap,\n \"--gap-x\": this.gapX ?? this.gap,\n \"--gap-y\": this.gapY ?? this.gap,\n \"--columns\": String(this.col),\n \"--justify\": this.justify,\n \"--direction\": this.direction,\n \"--align\": this.align,\n \"--align-content\": this.alignContent,\n } as Record<string, string>;\n Object.entries(styles).forEach(([k, v]) => this.style.setProperty(k, v));\n }\n\n /**\n * Forces recalculation of spans for all child elements.\n * Useful when dynamically adding/removing items.\n * @public\n */\n public recalculateSpans() {\n this.updateSpans();\n }\n\n /** @protected */\n override render() {\n const isColumn =\n this.direction === \"column\" || this.direction === \"column-reverse\";\n\n return html`\n <div\n class=\"flex-container ${isColumn ? \"is-column\" : \"is-row\"}\"\n part=\"container\"\n >\n <slot @slotchange=${this.updateSpans}></slot>\n </div>\n `;\n }\n\n private _scheduleUpdateSpans = () => {\n if (this._spansRaf) return;\n this._spansRaf = requestAnimationFrame(() => {\n this._spansRaf = 0;\n this.updateSpans();\n });\n };\n\n /**\n * Reads span attributes off slotted children and maps them to CSS vars:\n * span, span-lg, span-md, span-sm, span-xs\n * @private\n */\n private updateSpans = () => {\n const nodes =\n this.shadowRoot\n ?.querySelector(\"slot\")\n ?.assignedElements({ flatten: true }) ?? [];\n for (const el of nodes) {\n if (!(el instanceof HTMLElement)) continue;\n\n this.applySpanVar(el, \"--span\", this.readSpanRaw(el, \"span\", \"span\"));\n this.applySpanVar(el, \"--span-lg\", this.readSpanRaw(el, \"span-lg\", \"spanLg\"));\n this.applySpanVar(el, \"--span-md\", this.readSpanRaw(el, \"span-md\", \"spanMd\"));\n this.applySpanVar(el, \"--span-sm\", this.readSpanRaw(el, \"span-sm\", \"spanSm\"));\n this.applySpanVar(el, \"--span-xs\", this.readSpanRaw(el, \"span-xs\", \"spanXs\"));\n\n const hasSpan =\n this.readSpanRaw(el, \"span\", \"span\") != null ||\n this.readSpanRaw(el, \"span-lg\", \"spanLg\") != null ||\n this.readSpanRaw(el, \"span-md\", \"spanMd\") != null ||\n this.readSpanRaw(el, \"span-sm\", \"spanSm\") != null ||\n this.readSpanRaw(el, \"span-xs\", \"spanXs\") != null;\n\n if (hasSpan) el.dataset.flexSpan = \"\";\n else delete el.dataset.flexSpan;\n }\n };\n\n /**\n * Reads a span value from an HTML attribute or element property.\n * @private\n */\n private readSpanRaw(\n el: HTMLElement,\n attrName: string,\n propName: string,\n ): string | null {\n const fromAttr = el.getAttribute(attrName);\n if (fromAttr != null && fromAttr !== \"\") return fromAttr;\n const fromProp = (el as unknown as Record<string, unknown>)[propName];\n if (fromProp != null && fromProp !== \"\") return String(fromProp);\n return null;\n }\n\n /**\n * Sets or clears a span CSS variable on a slotted child.\n * @private\n */\n private applySpanVar(\n el: HTMLElement,\n cssVar: string,\n raw: string | null,\n ): void {\n const value = this.clampSpan(raw);\n if (value) el.style.setProperty(cssVar, String(value));\n else el.style.removeProperty(cssVar);\n }\n\n /**\n * Clamps span value to valid range (1 to column count).\n * @param raw - Raw span value from attribute\n * @returns Clamped number or null if invalid\n * @private\n */\n private clampSpan(raw: string | null): number | null {\n if (!raw) return null;\n const n = Math.max(1, Math.min(this.col, Number(raw) || 1));\n return n;\n }\n}\n"],"names":["SkyFlexbox","LitElement","constructor","super","arguments","this","direction","wrap","justify","align","alignContent","gap","col","preset","_presets","PresetController","_spansRaf","_scheduleUpdateSpans","requestAnimationFrame","updateSpans","nodes","shadowRoot","querySelector","assignedElements","flatten","el","HTMLElement","applySpanVar","readSpanRaw","dataset","flexSpan","connectedCallback","_childMo","MutationObserver","observe","childList","subtree","attributes","attributeFilter","disconnectedCallback","cancelAnimationFrame","disconnect","firstUpdated","syncVars","updated","changed","has","styles","gapX","gapY","String","Object","entries","forEach","k","v","style","setProperty","recalculateSpans","render","isColumn","html","attrName","propName","fromAttr","getAttribute","fromProp","cssVar","raw","value","clampSpan","removeProperty","Math","max","min","Number","css","__decorateClass","property","type","prototype","reflect","customElement"],"mappings":"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"}