Skip to content

Commit 20b81f0

Browse files
[color-chart] First step in <channel-picker> integration (#170)
1 parent 959ea2e commit 20b81f0

File tree

3 files changed

+47
-12
lines changed

3 files changed

+47
-12
lines changed

src/color-chart/README.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,9 @@ The format of this attribute is analogous to the one of [`<color-swatch>`](../co
7373
Reactively changing the Y coordinate:
7474

7575
```html
76-
<label>Coord:
77-
<select onchange="this.parentNode.nextElementSibling.y = this.value">
78-
<option selected>oklch.l</option>
79-
<option>oklch.c</option>
80-
<option>oklch.h</option>
81-
</select>
82-
</label>
76+
<button onclick="this.nextElementSibling.y = 'hwb.w'">
77+
Switch to “HWB Whiteness”
78+
</button>
8379
<color-chart y="oklch.l">
8480
<color-scale colors="Red 50: #fef2f2, Red 100: #fee2e2, Red 200: #fecaca, Red 300: #fca5a5, Red 400: #f87171, Red 500: #ef4444, Red 600: #dc2626, Red 700: #b91c1c, Red 800: #991b1b, Red 900: #7f1d1d, Red 950: #450a0a"></color-scale>
8581
<color-scale colors="Orange 50: #fff7ed, Orange 100: #ffedd5, Orange 200: #fed7aa, Orange 300: #fdba74, Orange 400: #fb923c, Orange 500: #f97316, Orange 600: #ea580c, Orange 700: #c2410c, Orange 800: #9a3412, Orange 900: #7c2d12, Orange 950: #431407"></color-scale>
@@ -127,6 +123,7 @@ Reactively setting/changing the colors:
127123

128124
| Name | Description |
129125
|------|-------------|
126+
| `color-channel` | The default [`<channel-picker>`](../channel-picker/) element, used if the `color-channel` slot has no slotted elements. |
130127
| `axis` | The axis line |
131128
| `ticks` | The container of ticks |
132129
| `tick` | A tick mark |

src/color-chart/color-chart.css

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
:host {
22
display: grid;
33
grid-template-columns: auto 1fr;
4-
grid-template-rows: 1fr auto;
4+
grid-template-rows: auto 1fr auto;
55
height: clamp(0em, 20em, 100vh);
66
contain: size;
77
container-name: chart;
@@ -26,9 +26,19 @@
2626
}
2727
}
2828

29+
[part="color-channel"],
30+
slot[name="color-channel"]::slotted(*) {
31+
/* <channel-picker>, or anything acting like one, should occupy the whole row above the chart so as not to mess up with the rest of the layout */
32+
grid-column: 1 / -1;
33+
justify-self: start;
34+
35+
margin-block: .5em .7em;
36+
font-size: 130%;
37+
}
38+
2939
#x_axis {
3040
grid-column: 2;
31-
grid-row: 2;
41+
grid-row: 3;
3242

3343
.ticks {
3444
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
@@ -43,7 +53,7 @@
4353

4454
#y_axis {
4555
grid-column: 1;
46-
grid-row: 1;
56+
grid-row: 2;
4757

4858
.ticks {
4959
align-items: end;

src/color-chart/color-chart.js

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import "../color-scale/color-scale.js";
2+
import "../channel-picker/channel-picker.js";
23
import ColorElement from "../common/color-element.js";
34

45
const Self = class ColorChart extends ColorElement {
56
static tagName = "color-chart";
67
static url = import.meta.url;
78
static shadowStyle = true;
89
static shadowTemplate = `
10+
<slot name="color-channel">
11+
<channel-picker id="channel_picker" part="color-channel"></channel-picker>
12+
</slot>
913
<div id="chart-container">
1014
<div id="chart">
1115
<slot></slot>
@@ -26,28 +30,40 @@ const Self = class ColorChart extends ColorElement {
2630
super();
2731

2832
this._el = {
29-
slot: this.shadowRoot.querySelector("slot"),
33+
slot: this.shadowRoot.querySelector("slot:not([name])"),
34+
channel_picker: this.shadowRoot.getElementById("channel_picker"),
3035
chart: this.shadowRoot.getElementById("chart"),
3136
xTicks: this.shadowRoot.querySelector("#x_axis .ticks"),
3237
yTicks: this.shadowRoot.querySelector("#y_axis .ticks"),
3338
xLabel: this.shadowRoot.querySelector("#x_axis .label"),
3439
yLabel: this.shadowRoot.querySelector("#y_axis .label"),
3540
};
41+
42+
this._slots = {
43+
color_channel: this.shadowRoot.querySelector("slot[name=color-channel]"),
44+
};
3645
}
3746

3847
connectedCallback () {
3948
super.connectedCallback();
4049
this._el.chart.addEventListener("colorschange", this, {capture: true});
50+
this._slots.color_channel.addEventListener("input", this);
4151
}
4252

4353
disconnectedCallback () {
4454
this._el.chart.removeEventListener("colorschange", this, {capture: true});
55+
this._slots.color_channel.removeEventListener("input", this);
4556
}
4657

4758
handleEvent (evt) {
48-
if (evt.target.tagName === "COLOR-SCALE" && evt.name === "computedColors") {
59+
let source = evt.target;
60+
if (source.tagName === "COLOR-SCALE" && evt.name === "computedColors") {
4961
this.render(evt);
5062
}
63+
64+
if (this._el.channel_picker === source || this._slots.color_channel.assignedElements().includes(source)) {
65+
this.y = source.value;
66+
}
5167
}
5268

5369
series = new WeakMap();
@@ -239,6 +255,18 @@ const Self = class ColorChart extends ColorElement {
239255
static props = {
240256
y: {
241257
default: "oklch.l",
258+
convert (value) {
259+
// Try setting the value to the channel picker. The picker will handle possible erroneous values.
260+
this._el.channel_picker.value = value;
261+
262+
// If the value is not set, that means it's invalid.
263+
// In that case, we are falling back to the picker's current value.
264+
if (this._el.channel_picker.value !== value) {
265+
return this._el.channel_picker.value;
266+
}
267+
268+
return value;
269+
},
242270
},
243271

244272
yResolved: {

0 commit comments

Comments
 (0)