Conversation
Co-authored-by: Keith Cirkel <keithamus@users.noreply.github.com>
Co-authored-by: Keith Cirkel <keithamus@users.noreply.github.com>
Co-authored-by: Keith Cirkel <keithamus@users.noreply.github.com>
Co-authored-by: Keith Cirkel <keithamus@users.noreply.github.com>
Co-authored-by: Keith Cirkel <keithamus@users.noreply.github.com>
Co-authored-by: Keith Cirkel <keithamus@users.noreply.github.com>
Co-authored-by: Keith Cirkel <keithamus@users.noreply.github.com>
Co-authored-by: Keith Cirkel <keithamus@users.noreply.github.com>
Co-authored-by: Keith Cirkel <keithamus@users.noreply.github.com>
Co-authored-by: Keith Cirkel <keithamus@users.noreply.github.com>
There was a problem hiding this comment.
This is looking really good but I'd recommend some refinements.
One general comment is that there's a mix of whitespace. All of these files should probably use tabs for indentation, perhaps we should install prettier?
Also index.html doesn't link to this page at all, so that would be really nice!
| <h3>Usage</h3> | ||
| <pre> | ||
| <code> | ||
| <open-swatch-picker></open-swatch-picker> |
There was a problem hiding this comment.
Tiny nit but you could get away with just < here and others.
| <open-swatch-picker></open-swatch-picker> | |
| <open-swatch-picker></open-swatch-picker> |
| if (this.#value !== newValue) { | ||
| this.#value = newValue; | ||
| this.onValueChange(newValue); // Call the watcher function | ||
| } |
There was a problem hiding this comment.
Having this guard prevents the picker from picking the same color twice. STR:
- Open the page
- Click "Choose color"
- Click on the first button
- Observe dialog is closed, button is populated.
- Click the button to open the dialog again
- Click the first button (i.e. same button as first choice)
- Observe the dialog does not close. Only choice is to pick another color or press Escape.
| get hideOutputLabel() { | ||
| return this.getAttribute('hide-output-label'); | ||
| } |
There was a problem hiding this comment.
Perhaps output-label="" is a more ergonomic way to handle this? As in <open-swatch-picker output-label="">
Perhaps we can do more interest things with a string attribute later on?
(This is non blocking, just a note).
| <main> | ||
| ${scales.map(scale=>makeScale(scale)).join('')} | ||
| </main> | ||
| </dialog> |
There was a problem hiding this comment.
This dialog has no label, making it a little tricky for screen readers to navigate. Also main is redundant. Some options:
- Add an aria-label, offers little customisation of the label but also the simplest:
| </dialog> | |
| <dialog closedby="any" id="select-color-dialog" aria-label="Color Picker"> | |
| ${scales.map(scale=>makeScale(scale)).join('')} | |
| </dialog> |
- Add a named slot so consumers can customise:
| </dialog> | |
| <dialog closedby="any" id="select-color-dialog"> | |
| <slot name="header" part="dialog-header"><h1>Color picker</h1></slot> | |
| ${scales.map(scale=>makeScale(scale)).join('')} | |
| </dialog> |
| } | ||
|
|
||
| get outputType() { | ||
| return this.getAttribute('output-type'); |
There was a problem hiding this comment.
This has no validation which is a little awkward. I'd prefer something like:
| return this.getAttribute('output-type'); | |
| const type = this.getAttribute('output-type'); | |
| if (type == 'hex' || type == 'rgb' || type == 'oklch' || type == 'var') return type; | |
| return 'var'; |
This way you can check in JS if something went wrong by setting the value and reading it back.
| } | ||
| } | ||
|
|
||
| get outputType() { |
There was a problem hiding this comment.
This should also have a setter:
| get outputType() { | |
| set outputType(type) { | |
| this.setAttribute('output-type', type); | |
| } | |
| get outputType() { |
| let outputVal = this.value; | ||
|
|
||
| if(this.outputType === 'hex') outputVal = this.hexValue; | ||
| if(this.outputType === 'rgb') outputVal = this.rgbValue; | ||
| if(this.outputType === 'oklch') outputVal = this.oklchValue; |
There was a problem hiding this comment.
Having var(--emerald-6) is nice but perhaps it's also nice to just get the ident without var(), so you can for e.g. make your own var(--emerald-6, var(--fallback)) or similar.
So perhaps a new output type of 'ident' would be useful here.
This is non blocking.
| shadowRoot = this.attachShadow({ mode: "open" }); | ||
|
|
||
| #value = ''; | ||
| dialog = null; |
There was a problem hiding this comment.
This could be a getter, and it probably should be private:
| dialog = null; | |
| get #dialog() { return this.shadowRoot.querySelector('dialog') } |
|
|
||
| this.shadowRoot | ||
| .querySelector('span[part="label"]') | ||
| .textContent = this.getAttribute('label') || 'Choose Color'; |
There was a problem hiding this comment.
label is not reactive, so if I change it, the shadowRoot is not updated. I'd recommend something like:
export class OpenSwatchPicker extends HTMLElement {
static observedAttributes = ['label']
//...
#updateValue() {
this.shadowRoot
.querySelector('span[part="label"]')
.textContent = this.getAttribute('label') || 'Choose Color';
}
attributeChangedCallback(name, oldValue, newValue) {
if (name == 'value') this.#updateValue()
}
connectedCallback() {
//...
this.#updateValue()
//...
}
}The same is also likely true for things like output-type, which might have some nice emergent properties if that was reactive.
| const swatchStyle = getComputedStyle(e.target); | ||
| const swatchColor = swatchStyle.backgroundColor; | ||
|
|
||
| this.oklchValue = swatchColor; |
There was a problem hiding this comment.
Nit, this is probably as readable, but either way is fine:
| const swatchStyle = getComputedStyle(e.target); | |
| const swatchColor = swatchStyle.backgroundColor; | |
| this.oklchValue = swatchColor; | |
| this.oklchValue = getComputedStyle(e.target).backgroundColor; |
| } | ||
|
|
||
| updateFormControls() { | ||
| for (const el of this.getRootNode().querySelectorAll('input[open-swatch-picker],output[for]')) { |
There was a problem hiding this comment.
Might be nice to handle inputs too:
| for (const el of this.getRootNode().querySelectorAll('input[open-swatch-picker],output[for]')) { | |
| for (const el of this.getRootNode().querySelectorAll('input[open-swatch-picker],input[for],output[for]')) { |
No description provided.