diff --git a/src/color-chart/README.md b/src/color-chart/README.md index b48b4a05..fb44de59 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 - + @@ -127,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 | diff --git a/src/color-chart/color-chart.css b/src/color-chart/color-chart.css index dae1754a..416be9c8 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(*) { + /* , 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; + + margin-block: .5em .7em; + 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..a72851d5 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("input", this); } disconnectedCallback () { this._el.chart.removeEventListener("colorschange", this, {capture: true}); + this._slots.color_channel.removeEventListener("input", this); } 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(); @@ -239,6 +255,18 @@ 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: {