From 616255bfe60a226007fb131e309e27037ac808d8 Mon Sep 17 00:00:00 2001 From: Dmitry Sharabin Date: Sun, 24 Nov 2024 18:10:24 +0100 Subject: [PATCH 1/7] [color-chart] First step in `` integration --- src/color-chart/README.md | 10 +++------- src/color-chart/color-chart.css | 16 +++++++++++++--- src/color-chart/color-chart.js | 34 ++++++++++++++++++++++++++++++--- 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/color-chart/README.md b/src/color-chart/README.md index b48b4a05..44c98b64 100644 --- a/src/color-chart/README.md +++ b/src/color-chart/README.md @@ -73,13 +73,9 @@ The format of this attribute is analogous to the one of [``](../co Reactively changing the Y coordinate: ```html - + diff --git a/src/color-chart/color-chart.css b/src/color-chart/color-chart.css index dae1754a..39d3e29b 100644 --- a/src/color-chart/color-chart.css +++ b/src/color-chart/color-chart.css @@ -1,7 +1,7 @@ :host { display: grid; grid-template-columns: auto 1fr; - grid-template-rows: 1fr auto; + grid-template-rows: auto 1fr auto; height: clamp(0em, 20em, 100vh); contain: size; container-name: chart; @@ -26,9 +26,19 @@ } } +[part="color-channel"], +slot[name="color-channel"]::slotted(*) { + grid-column: 1 / -1; + justify-self: start; + + margin-block: .5em .7em; + /* margin-inline-start: -.5em; */ + font-size: 130%; +} + #x_axis { grid-column: 2; - grid-row: 2; + grid-row: 3; .ticks { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); @@ -43,7 +53,7 @@ #y_axis { grid-column: 1; - grid-row: 1; + grid-row: 2; .ticks { align-items: end; diff --git a/src/color-chart/color-chart.js b/src/color-chart/color-chart.js index 356cc5b6..c8e4642b 100644 --- a/src/color-chart/color-chart.js +++ b/src/color-chart/color-chart.js @@ -1,4 +1,5 @@ import "../color-scale/color-scale.js"; +import "../channel-picker/channel-picker.js"; import ColorElement from "../common/color-element.js"; const Self = class ColorChart extends ColorElement { @@ -6,6 +7,9 @@ const Self = class ColorChart extends ColorElement { static url = import.meta.url; static shadowStyle = true; static shadowTemplate = ` + + +
@@ -26,28 +30,40 @@ const Self = class ColorChart extends ColorElement { super(); this._el = { - slot: this.shadowRoot.querySelector("slot"), + slot: this.shadowRoot.querySelector("slot:not([name])"), + channel_picker: this.shadowRoot.getElementById("channel_picker"), chart: this.shadowRoot.getElementById("chart"), xTicks: this.shadowRoot.querySelector("#x_axis .ticks"), yTicks: this.shadowRoot.querySelector("#y_axis .ticks"), xLabel: this.shadowRoot.querySelector("#x_axis .label"), yLabel: this.shadowRoot.querySelector("#y_axis .label"), }; + + this._slots = { + color_channel: this.shadowRoot.querySelector("slot[name=color-channel]"), + }; } connectedCallback () { super.connectedCallback(); this._el.chart.addEventListener("colorschange", this, {capture: true}); + this._slots.color_channel.addEventListener("change", this, {capture: true}); } disconnectedCallback () { this._el.chart.removeEventListener("colorschange", this, {capture: true}); + this._slots.color_channel.removeEventListener("change", this, {capture: true}); } handleEvent (evt) { - if (evt.target.tagName === "COLOR-SCALE" && evt.name === "computedColors") { + let source = evt.target; + if (source.tagName === "COLOR-SCALE" && evt.name === "computedColors") { this.render(evt); } + + if (this._el.channel_picker === source || this._slots.color_channel.assignedElements().includes(source)) { + this.y = source.value; + } } series = new WeakMap(); @@ -224,6 +240,10 @@ const Self = class ColorChart extends ColorElement { propChangedCallback (evt) { let {name, prop, detail: change} = evt; + if (name === "y") { + this._el.channel_picker.value = change.value; + } + if (["yResolved", "yMinAsNumber", "yMaxAsNumber"].includes(name)) { // Re-render swatches this.render(evt); @@ -243,7 +263,15 @@ const Self = class ColorChart extends ColorElement { yResolved: { get () { - return Self.Color.Space.resolveCoord(this.y, "oklch"); + try { + return Self.Color.Space.resolveCoord(this.y, "oklch"); + } + catch { + // Falling back to the channel picker's current value or the default one + let y = this._el.channel_picker?.value ?? "oklch.l"; + this.y = y; + return Self.Color.Space.resolveCoord(y); + } }, // rawProp: "coord", }, From 78138796288517efaf620776756b5af2fd605c37 Mon Sep 17 00:00:00 2001 From: Dmitry Sharabin Date: Wed, 27 Nov 2024 11:26:45 +0100 Subject: [PATCH 2/7] Address feedback: Listen to `input` events instead of `change` --- src/color-chart/color-chart.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/color-chart/color-chart.js b/src/color-chart/color-chart.js index c8e4642b..31a38bca 100644 --- a/src/color-chart/color-chart.js +++ b/src/color-chart/color-chart.js @@ -47,12 +47,12 @@ const Self = class ColorChart extends ColorElement { connectedCallback () { super.connectedCallback(); this._el.chart.addEventListener("colorschange", this, {capture: true}); - this._slots.color_channel.addEventListener("change", this, {capture: true}); + this._slots.color_channel.addEventListener("input", this, {capture: true}); } disconnectedCallback () { this._el.chart.removeEventListener("colorschange", this, {capture: true}); - this._slots.color_channel.removeEventListener("change", this, {capture: true}); + this._slots.color_channel.removeEventListener("input", this, {capture: true}); } handleEvent (evt) { From bd879ab4135e68f5502c56dc5e5e0790f719e89d Mon Sep 17 00:00:00 2001 From: Dmitry Sharabin Date: Wed, 27 Nov 2024 11:27:21 +0100 Subject: [PATCH 3/7] Remove commented-out rules --- src/color-chart/color-chart.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/color-chart/color-chart.css b/src/color-chart/color-chart.css index 39d3e29b..e471868e 100644 --- a/src/color-chart/color-chart.css +++ b/src/color-chart/color-chart.css @@ -32,7 +32,6 @@ slot[name="color-channel"]::slotted(*) { justify-self: start; margin-block: .5em .7em; - /* margin-inline-start: -.5em; */ font-size: 130%; } From 67ebb1b3e137b26fc994f0759126d6eb89004613 Mon Sep 17 00:00:00 2001 From: Dmitry Sharabin Date: Thu, 28 Nov 2024 12:00:42 +0100 Subject: [PATCH 4/7] Address feedback: `input` bubbles, so we shouldn't need `capture` --- src/color-chart/color-chart.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/color-chart/color-chart.js b/src/color-chart/color-chart.js index 31a38bca..b499f509 100644 --- a/src/color-chart/color-chart.js +++ b/src/color-chart/color-chart.js @@ -47,12 +47,12 @@ const Self = class ColorChart extends ColorElement { connectedCallback () { super.connectedCallback(); this._el.chart.addEventListener("colorschange", this, {capture: true}); - this._slots.color_channel.addEventListener("input", this, {capture: true}); + this._slots.color_channel.addEventListener("input", this); } disconnectedCallback () { this._el.chart.removeEventListener("colorschange", this, {capture: true}); - this._slots.color_channel.removeEventListener("input", this, {capture: true}); + this._slots.color_channel.removeEventListener("input", this); } handleEvent (evt) { From a3cec7dabb256abb429bf50bcb82c891bec342e7 Mon Sep 17 00:00:00 2001 From: Dmitry Sharabin Date: Thu, 28 Nov 2024 12:05:43 +0100 Subject: [PATCH 5/7] Address feedback: Add comment --- src/color-chart/color-chart.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/color-chart/color-chart.css b/src/color-chart/color-chart.css index e471868e..416be9c8 100644 --- a/src/color-chart/color-chart.css +++ b/src/color-chart/color-chart.css @@ -28,6 +28,7 @@ [part="color-channel"], slot[name="color-channel"]::slotted(*) { + /* , 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 */ grid-column: 1 / -1; justify-self: start; From f067ec901fe4dac9ba2e664fb12a3cf09f588f0f Mon Sep 17 00:00:00 2001 From: Dmitry Sharabin Date: Wed, 4 Dec 2024 13:43:05 +0100 Subject: [PATCH 6/7] Handle invalid values of `y` before they go to `yResolved` --- src/color-chart/color-chart.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/color-chart/color-chart.js b/src/color-chart/color-chart.js index b499f509..a72851d5 100644 --- a/src/color-chart/color-chart.js +++ b/src/color-chart/color-chart.js @@ -240,10 +240,6 @@ const Self = class ColorChart extends ColorElement { propChangedCallback (evt) { let {name, prop, detail: change} = evt; - if (name === "y") { - this._el.channel_picker.value = change.value; - } - if (["yResolved", "yMinAsNumber", "yMaxAsNumber"].includes(name)) { // Re-render swatches this.render(evt); @@ -259,19 +255,23 @@ const Self = class ColorChart extends ColorElement { static props = { y: { default: "oklch.l", + convert (value) { + // Try setting the value to the channel picker. The picker will handle possible erroneous values. + this._el.channel_picker.value = value; + + // If the value is not set, that means it's invalid. + // In that case, we are falling back to the picker's current value. + if (this._el.channel_picker.value !== value) { + return this._el.channel_picker.value; + } + + return value; + }, }, yResolved: { get () { - try { - return Self.Color.Space.resolveCoord(this.y, "oklch"); - } - catch { - // Falling back to the channel picker's current value or the default one - let y = this._el.channel_picker?.value ?? "oklch.l"; - this.y = y; - return Self.Color.Space.resolveCoord(y); - } + return Self.Color.Space.resolveCoord(this.y, "oklch"); }, // rawProp: "coord", }, From e93fa18232535e1623a56ffa94561461dbee0c61 Mon Sep 17 00:00:00 2001 From: Dmitry Sharabin Date: Wed, 4 Dec 2024 14:03:27 +0100 Subject: [PATCH 7/7] Add `color-channel` to the list of parts --- src/color-chart/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/color-chart/README.md b/src/color-chart/README.md index 44c98b64..fb44de59 100644 --- a/src/color-chart/README.md +++ b/src/color-chart/README.md @@ -123,6 +123,7 @@ Reactively setting/changing the colors: | Name | Description | |------|-------------| +| `color-channel` | The default [``](../channel-picker/) element, used if the `color-channel` slot has no slotted elements. | | `axis` | The axis line | | `ticks` | The container of ticks | | `tick` | A tick mark |