color-elements 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +30 -0
- package/.editorconfig +8 -0
- package/.prettierrc +17 -0
- package/.vscode/settings.json +7 -0
- package/README.md +27 -18
- package/_build/copy-config.js +15 -14
- package/_build/copy-config.json +4 -9
- package/_build/eleventy.js +8 -8
- package/_includes/component.njk +9 -14
- package/_includes/plain.njk +5 -0
- package/_redirects +1 -1
- package/assets/css/style.css +4 -4
- package/debug.html +46 -0
- package/package.json +19 -8
- package/src/channel-picker/channel-picker.css +4 -4
- package/src/channel-picker/channel-picker.js +15 -11
- package/src/channel-slider/channel-slider.css +14 -7
- package/src/channel-slider/channel-slider.js +13 -5
- package/src/color-chart/README.md +36 -5
- package/src/color-chart/color-chart-global.css +13 -12
- package/src/color-chart/color-chart-shadow.css +123 -0
- package/src/color-chart/color-chart.css +2 -112
- package/src/color-chart/color-chart.js +307 -103
- package/src/color-inline/color-inline.css +21 -16
- package/src/color-inline/color-inline.js +2 -3
- package/src/color-inline/style.css +1 -1
- package/src/color-picker/color-picker.css +3 -3
- package/src/color-picker/color-picker.js +14 -7
- package/src/color-scale/README.md +42 -2
- package/src/color-scale/color-scale.css +1 -1
- package/src/color-scale/color-scale.js +12 -9
- package/src/color-slider/README.md +17 -3
- package/src/color-slider/color-slider.css +54 -33
- package/src/color-slider/color-slider.js +9 -7
- package/src/color-swatch/color-swatch.css +41 -32
- package/src/color-swatch/color-swatch.js +17 -9
- package/src/common/color-element.js +34 -76
- package/src/common/dom.js +4 -2
- package/src/common/util.js +1 -1
- package/src/gamut-badge/gamut-badge.css +33 -13
- package/src/gamut-badge/gamut-badge.js +9 -7
- package/src/space-picker/space-picker.css +3 -3
- package/src/space-picker/space-picker.js +28 -10
- package/src/src.json +1 -1
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
#space_picker {
|
|
8
|
-
margin-inline-start:
|
|
8
|
+
margin-inline-start: -0.7em; /* align with the channel names */
|
|
9
9
|
font-size: 150%;
|
|
10
|
-
transition: border-color .2s;
|
|
10
|
+
transition: border-color 0.2s;
|
|
11
11
|
|
|
12
12
|
&:not(:hover) {
|
|
13
13
|
border-color: transparent;
|
|
@@ -24,7 +24,7 @@ slot[name="color-space"]::slotted(*) {
|
|
|
24
24
|
display: flex;
|
|
25
25
|
flex-flow: column;
|
|
26
26
|
justify-content: space-between;
|
|
27
|
-
gap: .3em;
|
|
27
|
+
gap: 0.3em;
|
|
28
28
|
min-inline-size: 10em;
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -63,14 +63,17 @@ const Self = class ColorPicker extends ColorElement {
|
|
|
63
63
|
}
|
|
64
64
|
this.color = this._el.swatch.color;
|
|
65
65
|
}
|
|
66
|
-
else if (
|
|
66
|
+
else if (
|
|
67
|
+
this._el.space_picker.contains(source) ||
|
|
68
|
+
this._slots.color_space.assignedElements().includes(source)
|
|
69
|
+
) {
|
|
67
70
|
this.spaceId = event.target.value;
|
|
68
71
|
}
|
|
69
72
|
|
|
70
|
-
this.dispatchEvent(new event.constructor(event.type, {...event}));
|
|
73
|
+
this.dispatchEvent(new event.constructor(event.type, { ...event }));
|
|
71
74
|
}
|
|
72
75
|
|
|
73
|
-
propChangedCallback ({name, prop, detail: change}) {
|
|
76
|
+
propChangedCallback ({ name, prop, detail: change }) {
|
|
74
77
|
if (name === "space" || name === "alpha") {
|
|
75
78
|
let space = this.space;
|
|
76
79
|
|
|
@@ -91,7 +94,10 @@ const Self = class ColorPicker extends ColorElement {
|
|
|
91
94
|
slider.channel = channel;
|
|
92
95
|
}
|
|
93
96
|
else {
|
|
94
|
-
this._el.sliders.insertAdjacentHTML(
|
|
97
|
+
this._el.sliders.insertAdjacentHTML(
|
|
98
|
+
"beforeend",
|
|
99
|
+
`<channel-slider space="${space.id}" channel="${channel}" part="channel-slider"></channel-slider>`,
|
|
100
|
+
);
|
|
95
101
|
}
|
|
96
102
|
}
|
|
97
103
|
|
|
@@ -130,7 +136,7 @@ const Self = class ColorPicker extends ColorElement {
|
|
|
130
136
|
|
|
131
137
|
return value + "";
|
|
132
138
|
},
|
|
133
|
-
changed ({parsedValue, source, ...change}) {
|
|
139
|
+
changed ({ parsedValue, source, ...change }) {
|
|
134
140
|
if (!parsedValue && source !== "default") {
|
|
135
141
|
// Something went wrong. We should always have a value. Falling back to the current space
|
|
136
142
|
this.spaceId = this.space.id;
|
|
@@ -152,7 +158,7 @@ const Self = class ColorPicker extends ColorElement {
|
|
|
152
158
|
return this._el.space_picker.selectedSpace;
|
|
153
159
|
},
|
|
154
160
|
set: true,
|
|
155
|
-
changed ({parsedValue, ...change}) {
|
|
161
|
+
changed ({ parsedValue, ...change }) {
|
|
156
162
|
if (parsedValue === undefined) {
|
|
157
163
|
// this.spaceId changed
|
|
158
164
|
if (this._el.space_picker.value !== this.spaceId) {
|
|
@@ -167,7 +173,8 @@ const Self = class ColorPicker extends ColorElement {
|
|
|
167
173
|
return;
|
|
168
174
|
}
|
|
169
175
|
|
|
170
|
-
parsedValue =
|
|
176
|
+
parsedValue =
|
|
177
|
+
parsedValue instanceof Self.Color.Space ? parsedValue.id : parsedValue;
|
|
171
178
|
if (this.spaceId !== parsedValue) {
|
|
172
179
|
this._el.space_picker.value = parsedValue;
|
|
173
180
|
this.spaceId = parsedValue;
|
|
@@ -36,7 +36,6 @@ You can also give them optional names:
|
|
|
36
36
|
"></color-scale>
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
|
|
40
39
|
You can only specify your core colors, and insert steps via interpolation:
|
|
41
40
|
|
|
42
41
|
```html
|
|
@@ -58,7 +57,6 @@ You can specify the `info` attribute to show additional information about the co
|
|
|
58
57
|
|
|
59
58
|
You can also create compact color scales, by simply setting `--details-style: compact`:
|
|
60
59
|
|
|
61
|
-
|
|
62
60
|
```html
|
|
63
61
|
<color-scale space="oklch" info="L: oklch.l, C: oklch.c, H: oklch.h"
|
|
64
62
|
style="--details-style: compact"
|
|
@@ -73,3 +71,45 @@ If you want to insert interpolated colors only in specific places, you can use e
|
|
|
73
71
|
```html
|
|
74
72
|
<color-scale space="oklch" colors="#e3fafc, , , , , , , , , #0b7285"></color-scale>
|
|
75
73
|
``` -->
|
|
74
|
+
|
|
75
|
+
## Reference
|
|
76
|
+
|
|
77
|
+
### Attributes & Properties
|
|
78
|
+
|
|
79
|
+
| Attribute | Property | Property type | Default value | Description |
|
|
80
|
+
| --------- | -------- | ------------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
81
|
+
| `colors` | `colors` | `{ [string]: Color }` | `string` | - | Object or comma-separated string defining the colors and their optional names. |
|
|
82
|
+
| `space` | `space` | `ColorSpace` | `string` | `oklch` | The color space to use for interpolation. |
|
|
83
|
+
| `steps` | `steps` | `number` | `0` | Number of interpolated steps to insert between each pair of colors. |
|
|
84
|
+
| `info` | `info` | `string` | - | Comma-separated list of coords of the colors to be shown. Passed to generated [`<color-swatch>`](../color-swatch/) elements. |
|
|
85
|
+
|
|
86
|
+
### Getters
|
|
87
|
+
|
|
88
|
+
These properties are read-only.
|
|
89
|
+
|
|
90
|
+
| Property | Type | Description |
|
|
91
|
+
| ---------------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
92
|
+
| `computedColors` | `Array<{name: string, color: Color}>` | `null` | The array of color objects after processing interpolation and steps. Returns `null` if `this.colors` is not defined. |
|
|
93
|
+
|
|
94
|
+
### CSS variables
|
|
95
|
+
|
|
96
|
+
The styling of `<color-scale>` is fully customizable via CSS variables provided by the [`<color-swatch>`](../color-swatch/#css-variables) elements it generates.
|
|
97
|
+
|
|
98
|
+
| Name | Type | Description |
|
|
99
|
+
| ----------------- | ----------------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
100
|
+
| `--details-style` | `compact` | `normal` (default) | Controls how color information is displayed. Inherited by child [`<color-swatch>`](../color-swatch/) elements. |
|
|
101
|
+
|
|
102
|
+
### Parts
|
|
103
|
+
|
|
104
|
+
| Name | Description |
|
|
105
|
+
| -------------- | --------------------------------------------------------------------------------------------------- |
|
|
106
|
+
| `color-swatch` | Each individual [`<color-swatch>`](../color-swatch/) element generated for the colors in the scale. |
|
|
107
|
+
|
|
108
|
+
The component also exports parts from its child `<color-swatch>` elements: `swatch`, `info`, `gamut`, and `swatch-label` (exported as `label`). See the [`<color-swatch>` parts table](../color-swatch/#parts) for details.
|
|
109
|
+
|
|
110
|
+
### Events
|
|
111
|
+
|
|
112
|
+
| Name | Description |
|
|
113
|
+
| -------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
114
|
+
| `colorschange` | Fired when the computed colors change for any reason, and once during initialization. |
|
|
115
|
+
| `colorchange` | Fired when any individual color swatch changes (bubbled from child [`<color-swatch>`](../color-swatch/) elements). |
|
|
@@ -21,19 +21,19 @@ const Self = class ColorScale extends ColorElement {
|
|
|
21
21
|
|
|
22
22
|
connectedCallback () {
|
|
23
23
|
super.connectedCallback?.();
|
|
24
|
-
this._el.swatches.addEventListener("colorchange", this, {capture: true});
|
|
24
|
+
this._el.swatches.addEventListener("colorchange", this, { capture: true });
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
disconnectedCallback () {
|
|
28
28
|
this.#swatches = [];
|
|
29
|
-
this._el.swatches.removeEventListener("colorchange", this, {capture: true});
|
|
29
|
+
this._el.swatches.removeEventListener("colorchange", this, { capture: true });
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
handleEvent (event) {
|
|
33
|
-
this.dispatchEvent(new event.constructor(event.type, {...event}));
|
|
33
|
+
this.dispatchEvent(new event.constructor(event.type, { ...event }));
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
propChangedCallback ({name, prop, detail: change}) {
|
|
36
|
+
propChangedCallback ({ name, prop, detail: change }) {
|
|
37
37
|
if (name === "computedColors") {
|
|
38
38
|
// Re-render swatches
|
|
39
39
|
this.render();
|
|
@@ -53,8 +53,8 @@ const Self = class ColorScale extends ColorElement {
|
|
|
53
53
|
|
|
54
54
|
let i = 0;
|
|
55
55
|
let newSwatches = [];
|
|
56
|
-
for (let {name, color} of colors) {
|
|
57
|
-
let swatch = this.#swatches[i] = this._el.swatches.children[i];
|
|
56
|
+
for (let { name, color } of colors) {
|
|
57
|
+
let swatch = (this.#swatches[i] = this._el.swatches.children[i]);
|
|
58
58
|
|
|
59
59
|
if (!swatch) {
|
|
60
60
|
this.#swatches[i] = swatch = document.createElement("color-swatch");
|
|
@@ -118,7 +118,7 @@ const Self = class ColorScale extends ColorElement {
|
|
|
118
118
|
return null;
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
let colors = Object.entries(this.colors).map(([name, color]) => ({name, color}));
|
|
121
|
+
let colors = Object.entries(this.colors).map(([name, color]) => ({ name, color }));
|
|
122
122
|
|
|
123
123
|
if (this.steps > 0) {
|
|
124
124
|
// Insert intermediate steps
|
|
@@ -127,11 +127,14 @@ const Self = class ColorScale extends ColorElement {
|
|
|
127
127
|
for (let i = 1; i < colors.length; i++) {
|
|
128
128
|
let start = colors[i - 1];
|
|
129
129
|
let end = colors[i];
|
|
130
|
-
let steps = ColorScale.Color.steps(start.color, end.color, {
|
|
130
|
+
let steps = ColorScale.Color.steps(start.color, end.color, {
|
|
131
|
+
space: this.space,
|
|
132
|
+
steps: this.steps + 2,
|
|
133
|
+
});
|
|
131
134
|
|
|
132
135
|
steps.shift();
|
|
133
136
|
steps.pop();
|
|
134
|
-
steps = steps.map(color => ({name: color + "", color}));
|
|
137
|
+
steps = steps.map(color => ({ name: color + "", color }));
|
|
135
138
|
|
|
136
139
|
tessellated.push(start, ...steps);
|
|
137
140
|
|
|
@@ -118,10 +118,24 @@ You can style it to look quite different:
|
|
|
118
118
|
### CSS-only usage
|
|
119
119
|
|
|
120
120
|
If you just want the styling of `<color-slider>` and not any of the API (or are fine dealing with the lower level details on your own),
|
|
121
|
-
you *can* just use the CSS file
|
|
121
|
+
you *can* just use the CSS file.
|
|
122
|
+
|
|
123
|
+
If using a local-first dependency manager (e.g. [Nudeps](https://nudeps.dev)), you can import the CSS file using a plain local URL:
|
|
124
|
+
|
|
125
|
+
```css
|
|
126
|
+
@import "/client_modules/color-elements/color-slider.css";
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Or with a bundler that supports CSS imports:
|
|
130
|
+
|
|
131
|
+
```css
|
|
132
|
+
@import "color-elements/color-slider.css";
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Otherwise, use a CDN:
|
|
122
136
|
|
|
123
137
|
```css
|
|
124
|
-
@import url("https://
|
|
138
|
+
@import url("https://esm.sh/color-elements/color-slider.css");
|
|
125
139
|
```
|
|
126
140
|
|
|
127
141
|
This is perfect for when the gradient is more of a visual aid than a functional part of your UI,
|
|
@@ -217,4 +231,4 @@ These properties are read-only.
|
|
|
217
231
|
|
|
218
232
|
## Planned features
|
|
219
233
|
|
|
220
|
-
- Discrete scales & steps
|
|
234
|
+
- Discrete scales & steps
|
|
@@ -6,37 +6,47 @@
|
|
|
6
6
|
.color-slider,
|
|
7
7
|
.slider-tooltip {
|
|
8
8
|
--transparency-cell-size: 1.5em;
|
|
9
|
-
--_transparency-cell-size: var(--transparency-cell-size, .5em);
|
|
9
|
+
--_transparency-cell-size: var(--transparency-cell-size, 0.5em);
|
|
10
10
|
--_transparency-background: var(--transparency-background, transparent);
|
|
11
11
|
--_transparency-darkness: var(--transparency-darkness, 5%);
|
|
12
|
-
--_transparency-grid: var(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
--_transparency-grid: var(
|
|
13
|
+
--transparency-grid,
|
|
14
|
+
repeating-conic-gradient(
|
|
15
|
+
transparent 0 25%,
|
|
16
|
+
rgb(0 0 0 / var(--_transparency-darkness)) 0 50%
|
|
17
|
+
)
|
|
18
|
+
0 0 / calc(2 * var(--_transparency-cell-size)) calc(2 * var(--_transparency-cell-size))
|
|
19
|
+
content-box border-box var(--_transparency-background)
|
|
16
20
|
);
|
|
17
21
|
|
|
18
22
|
--_slider-color-stops: var(--slider-color-stops, transparent 0% 100%);
|
|
19
|
-
--_slider-gradient: var(
|
|
23
|
+
--_slider-gradient: var(
|
|
24
|
+
--slider-gradient,
|
|
25
|
+
linear-gradient(to right var(--in-space,), var(--_slider-color-stops))
|
|
26
|
+
);
|
|
20
27
|
--_slider-height: var(--slider-height, 2.2em);
|
|
21
28
|
|
|
22
29
|
--_slider-thumb-width: var(--slider-thumb-width, 1em);
|
|
23
30
|
--_slider-thumb-height-offset: var(--slider-thumb-height-offset, 2px);
|
|
24
|
-
--_slider-thumb-height: var(
|
|
25
|
-
|
|
31
|
+
--_slider-thumb-height: var(
|
|
32
|
+
--slider-thumb-height,
|
|
33
|
+
calc(var(--_slider-height) + var(--_slider-thumb-height-offset))
|
|
34
|
+
);
|
|
35
|
+
--_slider-thumb-radius: var(--slider-thumb-radius, 0.16em);
|
|
26
36
|
--_slider-thumb-background: var(--slider-thumb-background, var(--color, transparent));
|
|
27
|
-
--_slider-thumb-border: var(--slider-thumb-border, 1px solid oklab(.2 0 0));
|
|
28
|
-
--_slider-thumb-border-active: var(--slider-thumb-border-active, 2px solid oklab(.4 0 0));
|
|
37
|
+
--_slider-thumb-border: var(--slider-thumb-border, 1px solid oklab(0.2 0 0));
|
|
38
|
+
--_slider-thumb-border-active: var(--slider-thumb-border-active, 2px solid oklab(0.4 0 0));
|
|
29
39
|
--_slider-thumb-scale-active: var(--slider-thumb-scale-active, 1.1);
|
|
30
40
|
|
|
31
41
|
--_tooltip-background: var(--tooltip-background, hsl(0 0 0 / 80%));
|
|
32
|
-
--_tooltip-border-radius: var(--tooltip-border-radius, .3em);
|
|
33
|
-
--_tooltip-pointer-height: var(--tooltip-pointer-height, .3em);
|
|
42
|
+
--_tooltip-border-radius: var(--tooltip-border-radius, 0.3em);
|
|
43
|
+
--_tooltip-pointer-height: var(--tooltip-pointer-height, 0.3em);
|
|
34
44
|
--_tooltip-pointer-angle: var(--tooltip-pointer-angle, 90deg);
|
|
35
45
|
}
|
|
36
46
|
|
|
37
47
|
.color-slider {
|
|
38
48
|
@supports (background: linear-gradient(in oklab, red, tan)) {
|
|
39
|
-
--in-space: in var(--color-space, oklab) var(--hue-interpolation,
|
|
49
|
+
--in-space: in var(--color-space, oklab) var(--hue-interpolation,);
|
|
40
50
|
}
|
|
41
51
|
|
|
42
52
|
display: block;
|
|
@@ -48,7 +58,7 @@
|
|
|
48
58
|
background-origin: border-box;
|
|
49
59
|
background-clip: border-box;
|
|
50
60
|
height: var(--_slider-height);
|
|
51
|
-
border-radius: .3em;
|
|
61
|
+
border-radius: 0.3em;
|
|
52
62
|
border: 1px solid rgb(0 0 0 / 8%);
|
|
53
63
|
|
|
54
64
|
&::-webkit-slider-thumb {
|
|
@@ -60,7 +70,9 @@
|
|
|
60
70
|
border: var(--_slider-thumb-border);
|
|
61
71
|
box-shadow: 0 0 0 1px white;
|
|
62
72
|
background: var(--color, transparent);
|
|
63
|
-
transition:
|
|
73
|
+
transition:
|
|
74
|
+
200ms,
|
|
75
|
+
0s background;
|
|
64
76
|
}
|
|
65
77
|
|
|
66
78
|
&::-moz-range-thumb {
|
|
@@ -71,13 +83,15 @@
|
|
|
71
83
|
border: var(--_slider-thumb-border);
|
|
72
84
|
box-shadow: 0 0 0 1px white;
|
|
73
85
|
background: var(--color, transparent);
|
|
74
|
-
transition:
|
|
86
|
+
transition:
|
|
87
|
+
200ms,
|
|
88
|
+
0s background;
|
|
75
89
|
}
|
|
76
90
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
91
|
+
&::-moz-range-thumb:active {
|
|
92
|
+
border: var(--_slider-thumb-border-active);
|
|
93
|
+
scale: var(--_slider-thumb-scale-active);
|
|
94
|
+
}
|
|
81
95
|
|
|
82
96
|
&::-moz-range-track {
|
|
83
97
|
background: none;
|
|
@@ -93,22 +107,29 @@
|
|
|
93
107
|
|
|
94
108
|
.slider-tooltip {
|
|
95
109
|
position: absolute;
|
|
96
|
-
left: clamp(
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
110
|
+
left: clamp(
|
|
111
|
+
-20%,
|
|
112
|
+
100% * var(--progress) - (var(--progress) - 0.5) * var(--_slider-thumb-width) / 2
|
|
113
|
+
/* center on slider thumb */,
|
|
114
|
+
100%
|
|
115
|
+
);
|
|
100
116
|
bottom: calc(100% + 3px);
|
|
101
117
|
translate: -50%;
|
|
102
118
|
transform-origin: bottom;
|
|
103
119
|
display: flex;
|
|
104
|
-
padding-block: .3em;
|
|
105
|
-
padding-inline: .4em;
|
|
120
|
+
padding-block: 0.3em;
|
|
121
|
+
padding-inline: 0.4em;
|
|
106
122
|
border: var(--_tooltip-pointer-height) solid transparent;
|
|
107
123
|
border-radius: calc(var(--_tooltip-border-radius) + var(--_tooltip-pointer-height));
|
|
108
124
|
text-align: center;
|
|
109
125
|
color: white;
|
|
110
126
|
background:
|
|
111
|
-
conic-gradient(
|
|
127
|
+
conic-gradient(
|
|
128
|
+
from calc(-1 * var(--_tooltip-pointer-angle) / 2) at bottom,
|
|
129
|
+
var(--_tooltip-background) var(--_tooltip-pointer-angle),
|
|
130
|
+
transparent 0
|
|
131
|
+
)
|
|
132
|
+
border-box bottom / 100% var(--_tooltip-pointer-height) no-repeat,
|
|
112
133
|
var(--_tooltip-background) padding-box;
|
|
113
134
|
color-scheme: dark;
|
|
114
135
|
transition:
|
|
@@ -116,7 +137,7 @@
|
|
|
116
137
|
opacity 200ms,
|
|
117
138
|
scale 200ms,
|
|
118
139
|
width 100ms,
|
|
119
|
-
left 200ms cubic-bezier(.17
|
|
140
|
+
left 200ms cubic-bezier(0.17, 0.67, 0.49, 1.48);
|
|
120
141
|
|
|
121
142
|
&::after {
|
|
122
143
|
content: var(--tooltip-suffix);
|
|
@@ -125,14 +146,14 @@
|
|
|
125
146
|
input {
|
|
126
147
|
all: unset;
|
|
127
148
|
|
|
128
|
-
&:where([type=number]) {
|
|
149
|
+
&:where([type="number"]) {
|
|
129
150
|
--content-width: calc(var(--value-length) * 1ch);
|
|
130
151
|
width: calc(var(--content-width, 2ch) + 1.2em);
|
|
131
152
|
min-width: calc(2ch + 1.2em);
|
|
132
153
|
box-sizing: content-box;
|
|
133
154
|
|
|
134
155
|
&::-webkit-textfield-decoration-container {
|
|
135
|
-
gap: .2em;
|
|
156
|
+
gap: 0.2em;
|
|
136
157
|
}
|
|
137
158
|
|
|
138
159
|
@container style(--tooltip-suffix) {
|
|
@@ -154,14 +175,14 @@
|
|
|
154
175
|
|
|
155
176
|
/* Prevent input from moving all over the place as we type */
|
|
156
177
|
&:focus {
|
|
157
|
-
transition-delay: .5s;
|
|
178
|
+
transition-delay: 0.5s;
|
|
158
179
|
}
|
|
159
180
|
}
|
|
160
181
|
|
|
161
182
|
&:not(:is(:focus-within, :hover) > *, .color-slider:is(:focus, :hover) + *, :focus, :hover) {
|
|
162
183
|
visibility: hidden;
|
|
163
184
|
opacity: 0;
|
|
164
|
-
scale: .5;
|
|
185
|
+
scale: 0.5;
|
|
165
186
|
}
|
|
166
187
|
}
|
|
167
188
|
|
|
@@ -171,4 +192,4 @@
|
|
|
171
192
|
|
|
172
193
|
:host([tooltip="progress"]) .slider-tooltip {
|
|
173
194
|
--tooltip-suffix: "%";
|
|
174
|
-
}
|
|
195
|
+
}
|
|
@@ -49,11 +49,11 @@ const Self = class ColorSlider extends ColorElement {
|
|
|
49
49
|
this.value = event.target.value;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
this.dispatchEvent(new event.constructor(event.type, {...event}));
|
|
52
|
+
this.dispatchEvent(new event.constructor(event.type, { ...event }));
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
propChangedCallback ({name, prop, detail: change}) {
|
|
56
|
+
propChangedCallback ({ name, prop, detail: change }) {
|
|
57
57
|
if (["min", "max", "step", "value", "defaultValue"].includes(name)) {
|
|
58
58
|
prop.applyChange(this._el.slider, change);
|
|
59
59
|
|
|
@@ -64,10 +64,10 @@ const Self = class ColorSlider extends ColorElement {
|
|
|
64
64
|
}
|
|
65
65
|
else {
|
|
66
66
|
// Spinner values when tooltip is "progress"
|
|
67
|
-
value =
|
|
67
|
+
value = { min: 1, max: 100, step: 1 }[name];
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
-
prop.applyChange(this._el.spinner, {...change, value: +(+value).toPrecision(4)});
|
|
70
|
+
prop.applyChange(this._el.spinner, { ...change, value: +(+value).toPrecision(4) });
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
if (name === "stops") {
|
|
@@ -106,7 +106,7 @@ const Self = class ColorSlider extends ColorElement {
|
|
|
106
106
|
else if (name === "space" && supports.inSpace) {
|
|
107
107
|
let space = this.space;
|
|
108
108
|
let spaceId = space.id;
|
|
109
|
-
let supported = CSS.supports("background", `linear-gradient(in ${
|
|
109
|
+
let supported = CSS.supports("background", `linear-gradient(in ${spaceId}, red, tan)`);
|
|
110
110
|
|
|
111
111
|
if (!supported) {
|
|
112
112
|
spaceId = this.space.isPolar ? "oklch" : "oklab";
|
|
@@ -135,7 +135,9 @@ const Self = class ColorSlider extends ColorElement {
|
|
|
135
135
|
let values = this;
|
|
136
136
|
if (change.value === "progress") {
|
|
137
137
|
values = {
|
|
138
|
-
min: 1,
|
|
138
|
+
min: 1,
|
|
139
|
+
max: 100,
|
|
140
|
+
step: 1,
|
|
139
141
|
value: +(this.progress * 100).toPrecision(4),
|
|
140
142
|
};
|
|
141
143
|
}
|
|
@@ -307,7 +309,7 @@ const Self = class ColorSlider extends ColorElement {
|
|
|
307
309
|
},
|
|
308
310
|
};
|
|
309
311
|
|
|
310
|
-
static
|
|
312
|
+
static formBehavior = {
|
|
311
313
|
like: el => el._el.slider,
|
|
312
314
|
role: "slider",
|
|
313
315
|
valueProp: "value",
|
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
:host {
|
|
2
|
-
--_transparency-cell-size: var(--transparency-cell-size, .5em);
|
|
2
|
+
--_transparency-cell-size: var(--transparency-cell-size, 0.5em);
|
|
3
3
|
--_transparency-background: var(--transparency-background, transparent);
|
|
4
4
|
--_transparency-darkness: var(--transparency-darkness, 5%);
|
|
5
|
-
--_transparency-grid: var(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
--_transparency-grid: var(
|
|
6
|
+
--transparency-grid,
|
|
7
|
+
repeating-conic-gradient(
|
|
8
|
+
transparent 0 25%,
|
|
9
|
+
rgb(0 0 0 / var(--_transparency-darkness)) 0 50%
|
|
10
|
+
)
|
|
11
|
+
0 0 / calc(2 * var(--_transparency-cell-size)) calc(2 * var(--_transparency-cell-size))
|
|
12
|
+
content-box border-box var(--_transparency-background)
|
|
9
13
|
);
|
|
10
14
|
|
|
11
15
|
position: relative;
|
|
12
16
|
display: inline-flex;
|
|
13
|
-
gap: .3em;
|
|
17
|
+
gap: 0.3em;
|
|
14
18
|
width: var(--color-swatch-width, fit-content);
|
|
15
|
-
margin: .3em;
|
|
16
|
-
border-radius: var(--color-swatch-radius, .2rem);
|
|
19
|
+
margin: 0.3em;
|
|
20
|
+
border-radius: var(--color-swatch-radius, 0.2rem);
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
:host([size="large"]) {
|
|
20
24
|
flex-flow: column;
|
|
21
|
-
inline-size: 11em;
|
|
25
|
+
inline-size: min(11em, 100%);
|
|
22
26
|
min-block-size: 6em;
|
|
23
27
|
contain: inline-size;
|
|
24
28
|
container-name: color-swatch;
|
|
@@ -37,7 +41,7 @@ slot {
|
|
|
37
41
|
position: absolute;
|
|
38
42
|
top: 0;
|
|
39
43
|
right: 0;
|
|
40
|
-
margin: .5rem;
|
|
44
|
+
margin: 0.5rem;
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
&:not(:host([size="large"]) *) {
|
|
@@ -46,7 +50,7 @@ slot {
|
|
|
46
50
|
font-size: 50%;
|
|
47
51
|
top: 0;
|
|
48
52
|
right: 0;
|
|
49
|
-
margin: .2rem;
|
|
53
|
+
margin: 0.2rem;
|
|
50
54
|
}
|
|
51
55
|
|
|
52
56
|
&:is(.static *) {
|
|
@@ -54,8 +58,6 @@ slot {
|
|
|
54
58
|
}
|
|
55
59
|
}
|
|
56
60
|
|
|
57
|
-
|
|
58
|
-
|
|
59
61
|
&[style*="--gamut-level: 0"] {
|
|
60
62
|
display: none;
|
|
61
63
|
}
|
|
@@ -65,12 +67,12 @@ slot {
|
|
|
65
67
|
margin: 0;
|
|
66
68
|
display: inline-flex;
|
|
67
69
|
display: none;
|
|
68
|
-
gap: .5em;
|
|
70
|
+
gap: 0.5em;
|
|
69
71
|
|
|
70
72
|
&:is(:host([size="large"]) &) {
|
|
71
73
|
display: grid;
|
|
72
74
|
grid-template-columns: max-content auto;
|
|
73
|
-
gap: .1em .2em;
|
|
75
|
+
gap: 0.1em 0.2em;
|
|
74
76
|
font-size: max(9px, 80%);
|
|
75
77
|
justify-content: start;
|
|
76
78
|
|
|
@@ -81,7 +83,7 @@ slot {
|
|
|
81
83
|
|
|
82
84
|
.coord {
|
|
83
85
|
display: flex;
|
|
84
|
-
gap: .2em;
|
|
86
|
+
gap: 0.2em;
|
|
85
87
|
|
|
86
88
|
dd {
|
|
87
89
|
margin: 0;
|
|
@@ -114,8 +116,11 @@ slot {
|
|
|
114
116
|
}
|
|
115
117
|
|
|
116
118
|
@container style(--details-style: compact) {
|
|
117
|
-
--_border-color: var(
|
|
118
|
-
|
|
119
|
+
--_border-color: var(
|
|
120
|
+
--border-color,
|
|
121
|
+
color-mix(in oklab, buttonborder 20%, oklab(none none none / 0%))
|
|
122
|
+
);
|
|
123
|
+
--_pointer-height: var(--pointer-height, 0.5em);
|
|
119
124
|
--_transition-duration: var(--transition-duration, 400ms);
|
|
120
125
|
--_details-popup-width: var(--details-popup-width, max-content);
|
|
121
126
|
|
|
@@ -124,13 +129,13 @@ slot {
|
|
|
124
129
|
z-index: 2;
|
|
125
130
|
translate: -50% 0;
|
|
126
131
|
bottom: 100%;
|
|
127
|
-
margin-bottom: calc(var(--_pointer-height) * .8);
|
|
132
|
+
margin-bottom: calc(var(--_pointer-height) * 0.8);
|
|
128
133
|
width: var(--_details-popup-width);
|
|
129
134
|
background: canvas;
|
|
130
135
|
border: 1px solid var(--_border-color);
|
|
131
|
-
padding: .6em 1em;
|
|
132
|
-
border-radius: .2rem;
|
|
133
|
-
box-shadow: 0 .05em 1em
|
|
136
|
+
padding: 0.6em 1em;
|
|
137
|
+
border-radius: 0.2rem;
|
|
138
|
+
box-shadow: 0 0.05em 1em -0.7em black;
|
|
134
139
|
transition: var(--_transition-duration) allow-discrete;
|
|
135
140
|
transition-property: all, display;
|
|
136
141
|
transition-delay: 0s, var(--_transition-duration);
|
|
@@ -165,8 +170,14 @@ slot {
|
|
|
165
170
|
clip-path: polygon(0 0, 0 100%, 100% 100%);
|
|
166
171
|
}
|
|
167
172
|
|
|
168
|
-
|
|
169
|
-
|
|
173
|
+
/*
|
|
174
|
+
More straightforward selector:
|
|
175
|
+
&:not(:is(:host(:hover), :host(:focus-within), :host(:active), :host(:target), :host([open])) *)
|
|
176
|
+
doesn't work in Safari!
|
|
177
|
+
See https://bugs.webkit.org/show_bug.cgi?id=296577
|
|
178
|
+
*/
|
|
179
|
+
&:is(:host(:not(:hover):not(:focus-within):not(:active):not(:target):not([open])) *),
|
|
180
|
+
&:is(:host([open="false"]) *) {
|
|
170
181
|
display: none;
|
|
171
182
|
opacity: 0;
|
|
172
183
|
scale: 0;
|
|
@@ -176,7 +187,7 @@ slot {
|
|
|
176
187
|
|
|
177
188
|
[part="color"] {
|
|
178
189
|
display: flex;
|
|
179
|
-
gap: .2em;
|
|
190
|
+
gap: 0.2em;
|
|
180
191
|
}
|
|
181
192
|
|
|
182
193
|
[part="label"] {
|
|
@@ -199,25 +210,23 @@ slot:not([name]) {
|
|
|
199
210
|
}
|
|
200
211
|
|
|
201
212
|
[part="color-wrapper"],
|
|
202
|
-
slot[name=swatch]::slotted(*),
|
|
213
|
+
slot[name="swatch"]::slotted(*),
|
|
203
214
|
#swatch {
|
|
204
215
|
border-radius: inherit;
|
|
205
216
|
}
|
|
206
217
|
|
|
207
|
-
slot[name=swatch]::slotted(*),
|
|
218
|
+
slot[name="swatch"]::slotted(*),
|
|
208
219
|
#swatch {
|
|
209
220
|
flex: 1;
|
|
210
221
|
display: flex;
|
|
211
222
|
flex-flow: column;
|
|
212
223
|
align-items: center;
|
|
213
224
|
justify-content: center;
|
|
214
|
-
padding: .5em;
|
|
225
|
+
padding: 0.5em;
|
|
215
226
|
display: flex;
|
|
216
227
|
flex-flow: column;
|
|
217
228
|
flex: 1;
|
|
218
|
-
background:
|
|
219
|
-
linear-gradient(var(--color) 0 100%),
|
|
220
|
-
var(--_transparency-grid);
|
|
229
|
+
background: linear-gradient(var(--color) 0 100%), var(--_transparency-grid);
|
|
221
230
|
|
|
222
231
|
&:is(:host([size="large"]) *) {
|
|
223
232
|
min-block-size: 3em;
|
|
@@ -232,7 +241,7 @@ slot[name=swatch]::slotted(*),
|
|
|
232
241
|
}
|
|
233
242
|
}
|
|
234
243
|
|
|
235
|
-
slot[name=swatch-content] {
|
|
244
|
+
slot[name="swatch-content"] {
|
|
236
245
|
/* See https://lea.verou.me/blog/2024/contrast-color/ */
|
|
237
246
|
--l: clamp(0, (var(--l-threshold, 0.7) / l - 1) * infinity, 1);
|
|
238
247
|
color: oklch(from var(--color) var(--l) 0 h);
|