@sky.ui/core 0.0.57 → 0.0.59

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.
@@ -0,0 +1,417 @@
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
+ border-radius: var(--sky-radius-secondary, 8px);
266
+ overflow: hidden;
267
+ cursor: crosshair;
268
+ touch-action: none;
269
+ border: var(--sky-border-tertiary, 1px solid color-mix(in oklch, var(--sky-text-primary) 12%, transparent));
270
+ }
271
+
272
+ .sv-fill {
273
+ position: absolute;
274
+ inset: 0;
275
+ background:
276
+ linear-gradient(to bottom, transparent, #000),
277
+ linear-gradient(to right, #fff, var(--cp-hue));
278
+ }
279
+
280
+ .thumb {
281
+ position: absolute;
282
+ width: 12px;
283
+ height: 12px;
284
+ border-radius: 50%;
285
+ border: 1.5px solid #fff;
286
+ box-shadow: 0 0 0 1px color-mix(in oklch, var(--sky-text-primary) 28%, transparent);
287
+ transform: translate(-50%, -50%);
288
+ pointer-events: none;
289
+ }
290
+
291
+ .tools {
292
+ display: flex;
293
+ align-items: center;
294
+ gap: var(--sky-space-2, 8px);
295
+ min-width: 0;
296
+ }
297
+
298
+ .eye {
299
+ flex-shrink: 0;
300
+ }
301
+
302
+ .track {
303
+ position: relative;
304
+ flex: 1;
305
+ min-width: 0;
306
+ height: 8px;
307
+ border-radius: 999px;
308
+ overflow: visible;
309
+ touch-action: none;
310
+ cursor: pointer;
311
+ }
312
+
313
+ .track-fill {
314
+ position: absolute;
315
+ inset: 0;
316
+ border-radius: inherit;
317
+ border: var(--sky-border-tertiary, 1px solid color-mix(in oklch, var(--sky-text-primary) 12%, transparent));
318
+ }
319
+
320
+ .hue-fill {
321
+ background: linear-gradient(
322
+ to right,
323
+ #f00,
324
+ #ff0,
325
+ #0f0,
326
+ #0ff,
327
+ #00f,
328
+ #f0f,
329
+ #f00
330
+ );
331
+ }
332
+
333
+ .track .thumb {
334
+ top: 50%;
335
+ width: 12px;
336
+ height: 12px;
337
+ }
338
+
339
+ .values {
340
+ display: grid;
341
+ grid-template-columns: auto minmax(0, 1fr);
342
+ gap: var(--sky-space-1, 4px) var(--sky-space-2, 8px);
343
+ align-items: center;
344
+ min-width: 0;
345
+ }
346
+
347
+ .format-dd {
348
+ display: block;
349
+ min-width: 4.5rem;
350
+ }
351
+
352
+ .format-dd::part(trigger) {
353
+ display: block;
354
+ width: 100%;
355
+ }
356
+
357
+ .format-dd sky-button {
358
+ display: block;
359
+ width: 100%;
360
+ box-sizing: border-box;
361
+ }
362
+
363
+ .format-dd::part(content) {
364
+ box-sizing: border-box;
365
+ padding: var(--sky-space-2, 8px);
366
+ width: var(--sky-dd-width, max-content);
367
+ min-width: var(--sky-dd-width, auto);
368
+ max-width: var(--sky-dd-width, none);
369
+ }
370
+
371
+ .format-dd::part(content-inner) {
372
+ overflow: visible;
373
+ max-height: none;
374
+ max-width: 100%;
375
+ }
376
+
377
+ .format-dd sky-dropdown-item {
378
+ --di-pad-x: 12px;
379
+ --di-pad-y: 6px;
380
+ }
381
+
382
+ .format-dd sky-dropdown-item::part(root) {
383
+ padding: 0.4rem 0.75rem;
384
+ border-radius: 6px;
385
+ }
386
+
387
+ .field,
388
+ .pct {
389
+ display: block;
390
+ width: 100%;
391
+ min-width: 0;
392
+ }
393
+
394
+ .triple {
395
+ display: grid;
396
+ grid-template-columns: repeat(3, minmax(0, 1fr));
397
+ gap: var(--sky-space-1, 4px);
398
+ min-width: 0;
399
+ }
400
+
401
+ .alpha-row {
402
+ display: grid;
403
+ grid-template-columns: minmax(0, 1fr) 5rem;
404
+ gap: var(--sky-space-2, 8px);
405
+ align-items: center;
406
+ grid-column: 1 / -1;
407
+ min-width: 0;
408
+ }
409
+
410
+ .actions {
411
+ display: flex;
412
+ justify-content: flex-end;
413
+ align-items: center;
414
+ gap: var(--sky-space-1, 4px);
415
+ }
416
+ `,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};
417
+ //# 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 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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"}
@@ -87,6 +87,9 @@ export type SkyInputIconClickDetail = {
87
87
  * @csspart file-info - File count and size info below the file input.
88
88
  * @csspart input-prefix - Inline prefix fragment inside the field.
89
89
  * @csspart input-suffix - Inline suffix fragment inside the field.
90
+ * @csspart number-btn - Wrapper around increment/decrement controls.
91
+ * @csspart increment-btn - Increase-value control.
92
+ * @csspart decrement-btn - Decrease-value control.
90
93
  *
91
94
  * @Behavior
92
95
  * - Extends `FormControlBase` for automatic form association and validation integration
@@ -149,9 +149,10 @@ import{css as t,LitElement as e,html as i,nothing as a}from"lit";import{ifDefine
149
149
  role=${s(this.nativeInputRole())}
150
150
  />
151
151
  `,x=()=>r&&this.showNumberButtons?i`
152
- <div class="number-btn">
152
+ <div class="number-btn" part="number-btn">
153
153
  <button
154
154
  class="decrement-btn"
155
+ part="decrement-btn"
155
156
  type="button"
156
157
  tabindex="-1"
157
158
  @mousedown=${this.keepInputFocused}
@@ -159,10 +160,11 @@ import{css as t,LitElement as e,html as i,nothing as a}from"lit";import{ifDefine
159
160
  @click=${t=>{t.stopPropagation(),this.decrementValue()}}
160
161
  aria-label="Decrease value"
161
162
  >
162
- <sky-icon icon="ion:minus"></sky-icon>
163
+ <sky-icon icon="ion:chevron-down" width=${this.compact?"12":"14"} height=${this.compact?"12":"14"}></sky-icon>
163
164
  </button>
164
165
  <button
165
166
  class="increment-btn"
167
+ part="increment-btn"
166
168
  type="button"
167
169
  tabindex="-1"
168
170
  @mousedown=${this.keepInputFocused}
@@ -170,7 +172,7 @@ import{css as t,LitElement as e,html as i,nothing as a}from"lit";import{ifDefine
170
172
  @click=${t=>{t.stopPropagation(),this.incrementValue()}}
171
173
  aria-label="Increase value"
172
174
  >
173
- <sky-icon icon="ion:add"></sky-icon>
175
+ <sky-icon icon="ion:chevron-up" width=${this.compact?"12":"14"} height=${this.compact?"12":"14"}></sky-icon>
174
176
  </button>
175
177
  </div>
176
178
  `:null,w=()=>n&&this.showPasswordToggle?i`
@@ -713,6 +715,15 @@ import{css as t,LitElement as e,html as i,nothing as a}from"lit";import{ifDefine
713
715
  gap: var(--sky-input-gap);
714
716
  }
715
717
 
718
+ .input-wrapper[compact] .number-btn {
719
+ flex-direction: column-reverse;
720
+ align-self: stretch;
721
+ width: 1.05rem;
722
+ margin-inline-end: 0;
723
+ gap: 0;
724
+ border: 0;
725
+ }
726
+
716
727
  :dir(rtl).number-btn {
717
728
  margin-inline-end: var(--sky-input-pad-x-sm);
718
729
  }
@@ -731,23 +742,37 @@ import{css as t,LitElement as e,html as i,nothing as a}from"lit";import{ifDefine
731
742
 
732
743
  .increment-btn,
733
744
  .decrement-btn {
734
- background: var(--sky-glass-solid);
735
- color: var(--sky-text-primary);
736
- border: var(--sky-border-primary);
737
- border-radius: var(--sky-radius-primary);
745
+ background: transparent;
746
+ color: var(--sky-text-tertiary);
747
+ border: 0;
748
+ box-shadow: none;
749
+ border-radius: var(--sky-radius-sm, 4px);
738
750
  display: flex;
739
751
  align-items: center;
740
752
  justify-content: center;
741
753
  padding: var(--sky-input-pad-x-xs) var(--sky-input-pad-x-sm);
742
754
  font-size: var(--sky-font-size-sm);
743
755
  cursor: pointer;
744
- transition: color var(--sky-transition-normal, 200ms ease);
756
+ transition: color var(--sky-transition-normal, 200ms ease),
757
+ background-color var(--sky-transition-normal, 200ms ease);
745
758
  font-family: var(--sky-font);
746
759
  }
747
760
 
761
+ .input-wrapper[compact] .increment-btn,
762
+ .input-wrapper[compact] .decrement-btn {
763
+ flex: 1 1 auto;
764
+ width: 100%;
765
+ min-height: 0;
766
+ padding: 0;
767
+ border: 0;
768
+ border-radius: 0;
769
+ background: transparent;
770
+ }
771
+
748
772
  .increment-btn:hover,
749
773
  .decrement-btn:hover {
750
- color: var(--sky-input-color);
774
+ color: var(--sky-text-primary);
775
+ background: color-mix(in srgb, var(--sky-text-primary) 6%, transparent);
751
776
  }
752
777
 
753
778
  .toggle-password {
@@ -802,8 +827,8 @@ import{css as t,LitElement as e,html as i,nothing as a}from"lit";import{ifDefine
802
827
  padding-inline-end: var(--sky-input-pad-x);
803
828
  }
804
829
 
805
- .input-wrapper[compact] .input-affix {
806
- font-size: var(--sky-font-size-sm);
830
+ .input-wrapper[compact] .input-affix.suffix {
831
+ padding-inline-end: var(--sky-input-pad-x-sm);
807
832
  }
808
833
 
809
834
  .input-wrapper:has(.input-affix.prefix) input,