diff --git a/.changeset/heavy-insects-love.md b/.changeset/heavy-insects-love.md new file mode 100644 index 000000000..9e822f352 --- /dev/null +++ b/.changeset/heavy-insects-love.md @@ -0,0 +1,7 @@ +--- +"@getflip/swirl-components": minor +"@getflip/swirl-components-angular": minor +"@getflip/swirl-components-react": minor +--- + +Add color picker to swirl-color-input diff --git a/packages/swirl-components/package.json b/packages/swirl-components/package.json index 84433e4f4..f15f6c783 100644 --- a/packages/swirl-components/package.json +++ b/packages/swirl-components/package.json @@ -59,6 +59,7 @@ "pdfjs-dist": "^2.16.105", "shave": "^5.0.2", "sortablejs": "^1.15.0", + "vanilla-colorful": "^0.7.2", "wc-datepicker": "^0.5.1" }, "devDependencies": { diff --git a/packages/swirl-components/src/components.d.ts b/packages/swirl-components/src/components.d.ts index 5498a58ea..091241429 100644 --- a/packages/swirl-components/src/components.d.ts +++ b/packages/swirl-components/src/components.d.ts @@ -380,6 +380,8 @@ export namespace Components { "disabled"?: boolean; "inline"?: boolean; "invalid"?: boolean; + "pickerButtonLabel"?: string; + "pickerLabel"?: string; "placeholder"?: string; "required"?: boolean; "swirlAriaDescribedby"?: string; @@ -4331,6 +4333,8 @@ declare namespace LocalJSX { "onInputBlur"?: (event: SwirlColorInputCustomEvent) => void; "onInputFocus"?: (event: SwirlColorInputCustomEvent) => void; "onValueChange"?: (event: SwirlColorInputCustomEvent) => void; + "pickerButtonLabel"?: string; + "pickerLabel"?: string; "placeholder"?: string; "required"?: boolean; "swirlAriaDescribedby"?: string; diff --git a/packages/swirl-components/src/components/swirl-color-input/swirl-color-input.css b/packages/swirl-components/src/components/swirl-color-input/swirl-color-input.css index 1571660ba..a4562f20e 100644 --- a/packages/swirl-components/src/components/swirl-color-input/swirl-color-input.css +++ b/packages/swirl-components/src/components/swirl-color-input/swirl-color-input.css @@ -21,12 +21,12 @@ } .color-input--inline { - & .color-input__preview { + & .color-input__preview-button { width: 1.5rem; height: 1.5rem; margin-top: -0.125rem; - margin-bottom: -0.125rem; margin-right: -0.25rem; + margin-bottom: -0.125rem; } } @@ -59,11 +59,13 @@ } } -.color-input__preview { +.color-input__preview-button { width: 2.75rem; height: 2.75rem; margin-top: -1.25rem; flex-shrink: 0; border: 0.0625rem solid var(--s-border-default); border-radius: var(--s-border-radius-s); + cursor: pointer; + appearance: none; } diff --git a/packages/swirl-components/src/components/swirl-color-input/swirl-color-input.spec.tsx b/packages/swirl-components/src/components/swirl-color-input/swirl-color-input.spec.tsx index f3d145c70..885dae536 100644 --- a/packages/swirl-components/src/components/swirl-color-input/swirl-color-input.spec.tsx +++ b/packages/swirl-components/src/components/swirl-color-input/swirl-color-input.spec.tsx @@ -27,12 +27,19 @@ describe("swirl-color-input", () => { aria-invalid="true" class="color-input__input" disabled="" - maxlength="9" + maxlength="7" required="" spellcheck="false" type="text" value="#ff0000"> - + + + + + + + + `); @@ -53,7 +60,7 @@ describe("swirl-color-input", () => { await page.waitForChanges(); expect( - page.root.querySelector(".color-input__preview").style + page.root.querySelector(".color-input__preview-button").style .backgroundColor ).toEqual("#ccddee"); }); diff --git a/packages/swirl-components/src/components/swirl-color-input/swirl-color-input.tsx b/packages/swirl-components/src/components/swirl-color-input/swirl-color-input.tsx index 9bc4f30a5..ad482feb7 100644 --- a/packages/swirl-components/src/components/swirl-color-input/swirl-color-input.tsx +++ b/packages/swirl-components/src/components/swirl-color-input/swirl-color-input.tsx @@ -7,7 +7,10 @@ import { Prop, Watch, } from "@stencil/core"; +import { v4 as uuid } from "uuid"; import classnames from "classnames"; +import "vanilla-colorful"; +import type { HexColorPicker } from "vanilla-colorful"; @Component({ /** @@ -28,6 +31,8 @@ export class SwirlColorInput { @Prop() swirlAriaDescribedby?: string; @Prop() inline?: boolean; @Prop() invalid?: boolean; + @Prop() pickerButtonLabel?: string = "Open color picker"; + @Prop() pickerLabel?: string = "Color picker"; @Prop() placeholder?: string; @Prop() required?: boolean; @Prop({ mutable: true, reflect: true }) value?: string; @@ -37,6 +42,8 @@ export class SwirlColorInput { @Event() valueChange: EventEmitter; private inputEl: HTMLInputElement; + private picker: HexColorPicker; + private pickerId = uuid(); componentDidLoad() { // see https://stackoverflow.com/a/27314017 @@ -45,6 +52,12 @@ export class SwirlColorInput { this.inputEl.focus(); }); } + + this.picker.addEventListener("color-changed", this.onPickerChange); + } + + disconnectedCallback() { + this.picker?.removeEventListener("color-changed", this.onPickerChange); } @Watch("value") @@ -54,6 +67,10 @@ export class SwirlColorInput { } } + private onPickerChange = (event: CustomEvent<{ value: string }>) => { + this.value = event.detail.value; + }; + private onChange = (event: Event) => { const el = event.target as HTMLInputElement; @@ -101,7 +118,7 @@ export class SwirlColorInput { autoFocus={this.autoFocus} class="color-input__input" disabled={this.disabled} - maxLength={9} + maxLength={7} onBlur={this.onBlur} onFocus={this.onFocus} onInput={this.onInput} @@ -112,14 +129,37 @@ export class SwirlColorInput { type="text" value={this.value} /> - + + + + + + (this.picker = el)} + > + + ); diff --git a/packages/swirl-components/stencil.config.ts b/packages/swirl-components/stencil.config.ts index a6ef645ec..60fc617eb 100644 --- a/packages/swirl-components/stencil.config.ts +++ b/packages/swirl-components/stencil.config.ts @@ -10,6 +10,8 @@ import { Config } from "@stencil/core"; import { postcss } from "@stencil/postcss"; import { reactOutputTarget } from "@stencil/react-output-target"; +const esModules = ["vanilla-colorful"].join("|"); + const angularValueAccessorBindings: ValueAccessorConfig[] = [ { elementSelectors: [ @@ -93,7 +95,7 @@ export const config: Config = { }, reactOutputTarget({ componentCorePackage: "@getflip/swirl-components", - excludeComponents: ["wc-datepicker"], + excludeComponents: ["hex-color-picker", "wc-datepicker"], proxiesFile: "../swirl-components-react/lib/stencil-generated/index.ts", includeDefineCustomElements: true, }), @@ -103,7 +105,7 @@ export const config: Config = { "../swirl-components-angular/projects/component-library/src/lib/stencil-generated/components.ts", directivesArrayFile: "../swirl-components-angular/projects/component-library/src/lib/stencil-generated/index.ts", - excludeComponents: ["wc-datepicker"], + excludeComponents: ["hex-color-picker", "wc-datepicker"], includeImportCustomElements: false, valueAccessorConfigs: angularValueAccessorBindings, }), @@ -117,5 +119,12 @@ export const config: Config = { }), ], sourceMap: false, + testing: { + // https://github.com/ionic-team/stencil/issues/2178#issuecomment-1289389916 + transform: { + "^.+\\.(ts|tsx|js|jsx|css)$": "@stencil/core/testing/jest-preprocessor", + }, + transformIgnorePatterns: [`/node_modules/(?!${esModules})`], + }, watchIgnoredRegex: [/pdf\.worker\.min\.js/, /vscode-data\.json/], }; diff --git a/packages/swirl-components/vscode-data.json b/packages/swirl-components/vscode-data.json index e283fd78d..2c5d8f18f 100644 --- a/packages/swirl-components/vscode-data.json +++ b/packages/swirl-components/vscode-data.json @@ -1536,6 +1536,14 @@ "name": "invalid", "description": "" }, + { + "name": "picker-button-label", + "description": "" + }, + { + "name": "picker-label", + "description": "" + }, { "name": "placeholder", "description": "" diff --git a/yarn.lock b/yarn.lock index 0e90cea31..a32e283b4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21695,6 +21695,11 @@ validator@^13.7.0: resolved "https://registry.yarnpkg.com/validator/-/validator-13.7.0.tgz#4f9658ba13ba8f3d82ee881d3516489ea85c0857" integrity sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw== +vanilla-colorful@^0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/vanilla-colorful/-/vanilla-colorful-0.7.2.tgz#3fb1f4b9f15b797e20fd1ce8e0364f33b073f4a2" + integrity sha512-z2YZusTFC6KnLERx1cgoIRX2CjPRP0W75N+3CC6gbvdX5Ch47rZkEMGO2Xnf+IEmi3RiFLxS18gayMA27iU7Kg== + varstream@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/varstream/-/varstream-0.3.2.tgz#18ac6494765f3ff1a35ad9a4be053bec188a5de1"