diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index e90ba835d18..f252ef12215 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -882,9 +882,6 @@ export namespace Components { "setFocus": () => Promise; } interface CalciteColorPicker { - /** - * When `true`, an empty color (`null`) will be allowed as a `value`. When `false`, a color value is enforced, and clearing the input or blurring will restore the last valid `value`. - */ "allowEmpty": boolean; /** * When `true`, the component will allow updates to the color's alpha value. @@ -894,6 +891,10 @@ export namespace Components { * When `true`, hides the RGB/HSV channel inputs. */ "channelsDisabled": boolean; + /** + * When `true`, an empty color (`null`) will be allowed as a `value`. When `false`, a color value is enforced, and clearing the input or blurring will restore the last valid `value`. + */ + "clearable": boolean; /** * Internal prop for advanced use-cases. */ @@ -8277,9 +8278,6 @@ declare namespace LocalJSX { >; } interface CalciteColorPicker { - /** - * When `true`, an empty color (`null`) will be allowed as a `value`. When `false`, a color value is enforced, and clearing the input or blurring will restore the last valid `value`. - */ "allowEmpty"?: boolean; /** * When `true`, the component will allow updates to the color's alpha value. @@ -8289,6 +8287,10 @@ declare namespace LocalJSX { * When `true`, hides the RGB/HSV channel inputs. */ "channelsDisabled"?: boolean; + /** + * When `true`, an empty color (`null`) will be allowed as a `value`. When `false`, a color value is enforced, and clearing the input or blurring will restore the last valid `value`. + */ + "clearable"?: boolean; /** * Internal prop for advanced use-cases. */ diff --git a/packages/calcite-components/src/components/color-picker/color-picker.e2e.ts b/packages/calcite-components/src/components/color-picker/color-picker.e2e.ts index 7de8a6f7a0b..2b1d43be9aa 100644 --- a/packages/calcite-components/src/components/color-picker/color-picker.e2e.ts +++ b/packages/calcite-components/src/components/color-picker/color-picker.e2e.ts @@ -50,7 +50,7 @@ describe("calcite-color-picker", () => { describe("accessible", () => { accessible("calcite-color-picker"); - accessible(""); + accessible(""); }); describe("honors hidden attribute", () => { @@ -84,6 +84,10 @@ describe("calcite-color-picker", () => { propertyName: "channelsDisabled", defaultValue: false, }, + { + propertyName: "clearable", + defaultValue: false, + }, { propertyName: "format", defaultValue: "auto", @@ -1094,7 +1098,7 @@ describe("calcite-color-picker", () => { describe("when no-color", () => { it("color gets propagated to hex, RGB & HSV inputs", async () => { const page = await newE2EPage(); - await page.setContent(html``); + await page.setContent(html``); const hexInput = await page.find(`calcite-color-picker >>> calcite-color-picker-hex-input`); @@ -1125,9 +1129,7 @@ describe("calcite-color-picker", () => { beforeEach(async () => { page = await newE2EPage(); - await page.setContent( - ``, - ); + await page.setContent(``); }); it("restores previous color to RGB inputs", async () => { @@ -1185,9 +1187,7 @@ describe("calcite-color-picker", () => { it("changes the value to the specified format after being empty", async () => { const page = await newE2EPage(); - await page.setContent( - html``, - ); + await page.setContent(html``); const color = await page.find("calcite-color-picker"); const hexInput = await page.find(`calcite-color-picker >>> calcite-color-picker-hex-input`); @@ -1199,7 +1199,7 @@ describe("calcite-color-picker", () => { describe("clearing color via supporting inputs", () => { it("clears color via hex input", async () => { const page = await newE2EPage(); - await page.setContent(html``); + await page.setContent(html``); const picker = await page.find("calcite-color-picker"); const hexInput = await page.find(`calcite-color-picker >>> calcite-color-picker-hex-input`); @@ -1210,7 +1210,7 @@ describe("calcite-color-picker", () => { it("clears color via RGB channel inputs", async () => { const page = await newE2EPage(); - await page.setContent(html``); + await page.setContent(html``); const picker = await page.find("calcite-color-picker"); const [rgbModeButton] = await page.findAll(`calcite-color-picker >>> .${CSS.colorMode}`); @@ -1229,7 +1229,7 @@ describe("calcite-color-picker", () => { it("clears color via HSV channel inputs", async () => { const page = await newE2EPage(); - await page.setContent(html``); + await page.setContent(html``); const picker = await page.find("calcite-color-picker"); const [, hsvModeButton] = await page.findAll(`calcite-color-picker >>> .${CSS.colorMode}`); @@ -1647,9 +1647,7 @@ describe("calcite-color-picker", () => { describe("when no-color", () => { it("color gets propagated to hex, RGB, HSV & opacity inputs", async () => { const page = await newE2EPage(); - await page.setContent( - html``, - ); + await page.setContent(html``); const hexInput = await page.find(`calcite-color-picker >>> calcite-color-picker-hex-input`); @@ -1683,7 +1681,7 @@ describe("calcite-color-picker", () => { beforeEach(async () => { page = await newE2EPage(); await page.setContent( - ``, + ``, ); }); @@ -1776,7 +1774,7 @@ describe("calcite-color-picker", () => { it("changes the value to the specified format after being empty", async () => { const page = await newE2EPage(); await page.setContent( - "", + "", ); const color = await page.find("calcite-color-picker"); @@ -1790,7 +1788,7 @@ describe("calcite-color-picker", () => { it("clears color via hex input", async () => { const page = await newE2EPage(); await page.setContent( - "", + "", ); const picker = await page.find("calcite-color-picker"); @@ -1803,7 +1801,7 @@ describe("calcite-color-picker", () => { it("clears color via RGB channel inputs", async () => { const page = await newE2EPage(); await page.setContent( - "", + "", ); const picker = await page.find("calcite-color-picker"); @@ -1827,7 +1825,7 @@ describe("calcite-color-picker", () => { it("clears color via HSV channel inputs", async () => { const page = await newE2EPage(); await page.setContent( - "", + "", ); const picker = await page.find("calcite-color-picker"); @@ -1963,7 +1961,7 @@ describe("calcite-color-picker", () => { it("does not allow saving/removing when no-color is set", async () => { const page = await newE2EPage(); - await page.setContent(``); + await page.setContent(``); const saveColor = await page.find(`calcite-color-picker >>> .${CSS.saveColor}`); const removeColor = await page.find(`calcite-color-picker >>> .${CSS.deleteColor}`); @@ -2063,7 +2061,7 @@ describe("calcite-color-picker", () => { it("does not allow saving/removing when no-color is set", async () => { const page = await newE2EPage(); - await page.setContent(``); + await page.setContent(``); const saveColor = await page.find(`calcite-color-picker >>> .${CSS.saveColor}`); const removeColor = await page.find(`calcite-color-picker >>> .${CSS.deleteColor}`); @@ -2076,7 +2074,7 @@ describe("calcite-color-picker", () => { it("allows setting no-color", async () => { const page = await newE2EPage(); - await page.setContent(``); + await page.setContent(``); const color = await page.find("calcite-color-picker"); @@ -2152,7 +2150,7 @@ describe("calcite-color-picker", () => { describe("keyboard", () => { it("allows editing color field via keyboard", async () => { const page = await newE2EPage(); - await page.setContent(``); + await page.setContent(``); const picker = await page.find("calcite-color-picker"); const scope = await page.find(`calcite-color-picker >>> .${CSS.colorFieldScope}`); @@ -2232,7 +2230,7 @@ describe("calcite-color-picker", () => { it("allows editing hue slider via keyboard", async () => { const page = await newE2EPage(); - await page.setContent(``); + await page.setContent(``); const picker = await page.find("calcite-color-picker"); const hueScope = await page.find(`calcite-color-picker >>> .${CSS.hueScope}`); diff --git a/packages/calcite-components/src/components/color-picker/color-picker.stories.ts b/packages/calcite-components/src/components/color-picker/color-picker.stories.ts index 55a5ba783c2..95393f996f5 100644 --- a/packages/calcite-components/src/components/color-picker/color-picker.stories.ts +++ b/packages/calcite-components/src/components/color-picker/color-picker.stories.ts @@ -66,8 +66,8 @@ const createColorAttributes: (options?: { exceptions: string[] }) => Attributes export const simple = (): string => create("calcite-color-picker", [ { - name: "allow-empty", - value: boolean("allow-empty", false), + name: "clearable", + value: boolean("clearable", false), }, ...createColorAttributes(), { diff --git a/packages/calcite-components/src/components/color-picker/color-picker.tsx b/packages/calcite-components/src/components/color-picker/color-picker.tsx index e12d1c8c840..9026ea6c2f8 100644 --- a/packages/calcite-components/src/components/color-picker/color-picker.tsx +++ b/packages/calcite-components/src/components/color-picker/color-picker.tsx @@ -98,9 +98,17 @@ export class ColorPicker * When `true`, an empty color (`null`) will be allowed as a `value`. * * When `false`, a color value is enforced, and clearing the input or blurring will restore the last valid `value`. + * + * @deprecated Use `clearable` instead */ @Prop({ reflect: true }) allowEmpty = false; + @Watch("allowEmpty") + @Watch("clearable") + handleAllowEmptyOrClearableChange(): void { + this.isClearable = this.clearable || this.allowEmpty; + } + /** * When `true`, the component will allow updates to the color's alpha value. */ @@ -121,6 +129,13 @@ export class ColorPicker /** When `true`, hides the RGB/HSV channel inputs. */ @Prop() channelsDisabled = false; + /** + * When `true`, an empty color (`null`) will be allowed as a `value`. + * + * When `false`, a color value is enforced, and clearing the input or blurring will restore the last valid `value`. + */ + @Prop({ reflect: true }) clearable = false; + /** * Internal prop for advanced use-cases. * @@ -225,8 +240,8 @@ export class ColorPicker @Watch("value") handleValueChange(value: ColorValue | null, oldValue: ColorValue | null): void { - const { allowEmpty, format } = this; - const checkMode = !allowEmpty || value; + const { isClearable, format } = this; + const checkMode = !isClearable || value; let modeChanged = false; if (checkMode) { @@ -258,7 +273,7 @@ export class ColorPicker } const color = - allowEmpty && !value + isClearable && !value ? null : Color( value != null && typeof value === "object" && alphaCompatible(this.mode) @@ -305,6 +320,8 @@ export class ColorPicker private internalColorUpdateContext: "internal" | "initial" | "user-interaction" | null = null; + private isClearable: boolean; + private mode: SupportedMode = CSSColorMode.HEX; private opacityScopeNode: HTMLDivElement; @@ -417,11 +434,11 @@ export class ColorPicker private handleHexInputChange = (event: Event): void => { event.stopPropagation(); - const { allowEmpty, color } = this; + const { isClearable, color } = this; const input = event.target as HTMLCalciteColorPickerHexInputElement; const hex = input.value; - if (allowEmpty && !hex) { + if (isClearable && !hex) { this.internalColorSet(null); return; } @@ -451,7 +468,7 @@ export class ColorPicker let inputValue: string; - if (this.allowEmpty && !input.value) { + if (this.isClearable && !input.value) { inputValue = ""; } else { const value = Number(input.value); @@ -508,7 +525,7 @@ export class ColorPicker const channelIndex = Number(input.getAttribute("data-channel-index")); const channels = [...this.channels] as this["channels"]; - const shouldClearChannels = this.allowEmpty && !input.value; + const shouldClearChannels = this.isClearable && !input.value; if (shouldClearChannels) { this.channels = [null, null, null, null]; @@ -666,9 +683,10 @@ export class ColorPicker async componentWillLoad(): Promise { setUpLoadableComponent(this); - const { allowEmpty, color, format, value } = this; + this.handleAllowEmptyOrClearableChange(); - const willSetNoColor = allowEmpty && !value; + const { isClearable, color, format, value } = this; + const willSetNoColor = isClearable && !value; const parsedMode = parseMode(value); const valueIsCompatible = willSetNoColor || (format === "auto" && parsedMode) || format === parsedMode; @@ -677,7 +695,6 @@ export class ColorPicker if (!valueIsCompatible) { this.showIncompatibleColorWarning(value, format); } - this.setMode(format, false); this.internalColorSet(initialColor, false, "initial"); @@ -722,7 +739,6 @@ export class ColorPicker render(): VNode { const { - allowEmpty, channelsDisabled, color, colorFieldScopeLeft, @@ -862,7 +878,7 @@ export class ColorPicker {noHex ? null : (
{ - const { allowEmpty, channelMode: activeChannelMode, channels, messages, alphaChannel } = this; + const { isClearable, channelMode: activeChannelMode, channels, messages, alphaChannel } = this; const selected = channelMode === activeChannelMode; const isRgb = channelMode === "rgb"; const channelAriaLabels = isRgb @@ -990,7 +1006,7 @@ export class ColorPicker if (isAlphaChannel) { channelValue = - allowEmpty && !channelValue ? channelValue : alphaToOpacity(channelValue); + isClearable && !channelValue ? channelValue : alphaToOpacity(channelValue); } /* the channel container is ltr, so we apply the host's direction */