diff --git a/docs/components/color-picker.md b/docs/components/color-picker.md index b3ac54157..922b102ff 100644 --- a/docs/components/color-picker.md +++ b/docs/components/color-picker.md @@ -70,6 +70,34 @@ const App = () => ( ); ``` +### Swatches + +Use the `swatches` attribute to add convenient presets to the color picker. Any format the color picker can parse is acceptable (including CSS color names), but each value must be separated by a semicolon (`;`). Alternatively, you can pass an array of color values to this property using JavaScript. + +```html preview + +``` + +```jsx react +import { SlColorPicker } from '@shoelace-style/shoelace/dist/react'; + +const App = () => ( + +); +``` + ### Sizes Use the `size` attribute to change the color picker's trigger size. diff --git a/docs/resources/changelog.md b/docs/resources/changelog.md index 017920c2f..47bdb7543 100644 --- a/docs/resources/changelog.md +++ b/docs/resources/changelog.md @@ -20,8 +20,10 @@ This release includes a complete rewrite of `` to improve accessibili - Many parts have been removed or renamed (please see the docs for more details) - 🚨 BREAKING: removed the `sl-label-change` event from `` (listen for `slotchange` instead) - 🚨 BREAKING: removed type to select logic from `` (this was added specifically for `` which no longer uses ``) +- 🚨 BREAKING: swatches in `` are no longer present by default (but you can set them using the `swatches` attribute now) - Added the `` component - Added Traditional Chinese translation [#1086](https://github.com/shoelace-style/shoelace/pull/1086) +- Added support for `swatches` to be an attribute of `` so swatches can be defined declaratively (it was previously a property; use a `;` to separate color values) - Fixed a bug in `` where the checked/indeterminate states could get out of sync when using the `multiple` option [#1076](https://github.com/shoelace-style/shoelace/issues/1076) - Fixed a bug in `` that caused `sl-selection-change` to emit before the DOM updated [#1096](https://github.com/shoelace-style/shoelace/issues/1096) - Fixed a bug that prevented `` from submitting a default value of `on` when no value was provided [#1103](https://github.com/shoelace-style/shoelace/discussions/1103) diff --git a/src/components/color-picker/color-picker.test.ts b/src/components/color-picker/color-picker.test.ts index 5bfd5ade9..b03a8677b 100644 --- a/src/components/color-picker/color-picker.test.ts +++ b/src/components/color-picker/color-picker.test.ts @@ -93,8 +93,33 @@ describe('', () => { expect(inputHandler).to.have.been.calledOnce; }); - it('should emit sl-change and sl-input when clicking on a swatch', async () => { + it('should render the correct swatches when passing a string of color values', async () => { + const el = await fixture( + html` ` + ); + const swatches = [...el.shadowRoot!.querySelectorAll('[part~="swatch"] > div')]; + + expect(swatches.length).to.equal(3); + expect(getComputedStyle(swatches[0]).backgroundColor).to.equal('rgb(255, 0, 0)'); + expect(getComputedStyle(swatches[1]).backgroundColor).to.equal('rgb(0, 128, 0)'); + expect(getComputedStyle(swatches[2]).backgroundColor).to.equal('rgb(0, 0, 255)'); + }); + + it('should render the correct swatches when passing an array of color values', async () => { const el = await fixture(html` `); + el.swatches = ['red', '#008000', 'rgb(0,0,255)']; + await el.updateComplete; + + const swatches = [...el.shadowRoot!.querySelectorAll('[part~="swatch"] > div')]; + + expect(swatches.length).to.equal(3); + expect(getComputedStyle(swatches[0]).backgroundColor).to.equal('rgb(255, 0, 0)'); + expect(getComputedStyle(swatches[1]).backgroundColor).to.equal('rgb(0, 128, 0)'); + expect(getComputedStyle(swatches[2]).backgroundColor).to.equal('rgb(0, 0, 255)'); + }); + + it('should emit sl-change and sl-input when clicking on a swatch', async () => { + const el = await fixture(html` `); const trigger = el.shadowRoot!.querySelector('[part~="trigger"]')!; const swatch = el.shadowRoot!.querySelector('[part~="swatch"]')!; const changeHandler = sinon.spy(); diff --git a/src/components/color-picker/color-picker.ts b/src/components/color-picker/color-picker.ts index 935fd0425..1040dd6e5 100644 --- a/src/components/color-picker/color-picker.ts +++ b/src/components/color-picker/color-picker.ts @@ -158,27 +158,11 @@ export default class SlColorPicker extends ShoelaceElement implements ShoelaceFo @property({ type: Boolean }) uppercase = false; /** - * An array of predefined color swatches to display. Can include any format the color picker can parse, including - * HEX(A), RGB(A), HSL(A), HSV(A), and CSS color names. + * One or more predefined color swatches to display as presets in the color picker. Can include any format the color + * picker can parse, including HEX(A), RGB(A), HSL(A), HSV(A), and CSS color names. Each color must be separated by a + * semicolon (`;`). Alternatively, you can pass an array of color values to this property using JavaScript. */ - @property({ attribute: false }) swatches: string[] = [ - '#d0021b', - '#f5a623', - '#f8e71c', - '#8b572a', - '#7ed321', - '#417505', - '#bd10e0', - '#9013fe', - '#4a90e2', - '#50e3c2', - '#b8e986', - '#000', - '#444', - '#888', - '#ccc', - '#fff' - ]; + @property() swatches: string | string[] = ''; connectedCallback() { super.connectedCallback(); @@ -721,6 +705,9 @@ export default class SlColorPicker extends ShoelaceElement implements ShoelaceFo render() { const gridHandleX = this.saturation; const gridHandleY = 100 - this.brightness; + const swatches = Array.isArray(this.swatches) + ? this.swatches // allow arrays for legacy purposes + : this.swatches.split(';').filter(color => color !== ''); const colorPicker = html`
- ${this.swatches.length > 0 + ${swatches.length > 0 ? html`
- ${this.swatches.map(swatch => { + ${swatches.map(swatch => { + const parsedColor = this.parseColor(swatch); + + // If we can't parse it, skip it + if (!parsedColor) { + console.error(`Unable to parse swatch color: "${swatch}"`, this); + return ''; + } + return html`
this.selectSwatch(swatch)} @keydown=${(event: KeyboardEvent) => - !this.disabled && event.key === 'Enter' && this.setColor(swatch)} + !this.disabled && event.key === 'Enter' && this.setColor(parsedColor.hexa)} > -
+
`; })}