From c71bbe546d8f5f849c0bf53d5714e31d1b64a380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benny=20Powers=20-=20=D7=A2=D7=9D=20=D7=99=D7=A9=D7=A8?= =?UTF-8?q?=D7=90=D7=9C=20=D7=97=D7=99!?= Date: Wed, 6 Dec 2023 10:47:52 +0200 Subject: [PATCH] feat(text-area): add pf-text-area (#2639) * feat(core): internals controller improvements * feat(text-area): add pf-text-area * fix(text-area): styles still to do: validations, icons, auto-resize * fix(text-area): styles and states still to do: success and warning states, autoresize * fix: allow for build * refactor(core): remove comments and empty blocks * docs(text-area): add css prop docs * fix(text-area): resize class * fix(text-area): add resize both css rule * test(text-area): disable function tests --------- Co-authored-by: Steven Spriggs --- ...nternals-controller-computed-label-text.md | 4 + .changeset/internals-controller-props.md | 4 + .changeset/pf-text-area.md | 16 ++ .../controllers/internals-controller.ts | 161 ++++++++--- elements/package.json | 1 + elements/pf-button/BaseButton.ts | 2 +- elements/pf-text-area/README.md | 11 + elements/pf-text-area/demo/auto-resizing.html | 6 + elements/pf-text-area/demo/disabled.html | 6 + .../demo/horizontally-resizable.html | 6 + elements/pf-text-area/demo/invalid.html | 9 + elements/pf-text-area/demo/pf-text-area.html | 6 + elements/pf-text-area/demo/readonly.html | 6 + elements/pf-text-area/demo/validated.html | 13 + .../demo/vertically-resizable.html | 6 + elements/pf-text-area/docs/pf-text-area.md | 17 ++ elements/pf-text-area/pf-text-area.css | 193 +++++++++++++ elements/pf-text-area/pf-text-area.ts | 254 ++++++++++++++++++ .../pf-text-area/test/pf-text-area.e2e.ts | 12 + .../pf-text-area/test/pf-text-area.spec.ts | 97 +++++++ elements/pf-text-input/pf-text-input.ts | 21 +- 21 files changed, 790 insertions(+), 61 deletions(-) create mode 100644 .changeset/internals-controller-computed-label-text.md create mode 100644 .changeset/internals-controller-props.md create mode 100644 .changeset/pf-text-area.md create mode 100644 elements/pf-text-area/README.md create mode 100644 elements/pf-text-area/demo/auto-resizing.html create mode 100644 elements/pf-text-area/demo/disabled.html create mode 100644 elements/pf-text-area/demo/horizontally-resizable.html create mode 100644 elements/pf-text-area/demo/invalid.html create mode 100644 elements/pf-text-area/demo/pf-text-area.html create mode 100644 elements/pf-text-area/demo/readonly.html create mode 100644 elements/pf-text-area/demo/validated.html create mode 100644 elements/pf-text-area/demo/vertically-resizable.html create mode 100644 elements/pf-text-area/docs/pf-text-area.md create mode 100644 elements/pf-text-area/pf-text-area.css create mode 100644 elements/pf-text-area/pf-text-area.ts create mode 100644 elements/pf-text-area/test/pf-text-area.e2e.ts create mode 100644 elements/pf-text-area/test/pf-text-area.spec.ts diff --git a/.changeset/internals-controller-computed-label-text.md b/.changeset/internals-controller-computed-label-text.md new file mode 100644 index 0000000000..f54ef38597 --- /dev/null +++ b/.changeset/internals-controller-computed-label-text.md @@ -0,0 +1,4 @@ +--- +"@patternfly/pfe-core": minor +--- +`InternalsController`: added `computedLabelText` read-only property diff --git a/.changeset/internals-controller-props.md b/.changeset/internals-controller-props.md new file mode 100644 index 0000000000..a5bb82e69b --- /dev/null +++ b/.changeset/internals-controller-props.md @@ -0,0 +1,4 @@ +--- +"@patternfly/pfe-core": minor +--- +`InternalsController`: reflect all methods and properties from `ElementInternals` diff --git a/.changeset/pf-text-area.md b/.changeset/pf-text-area.md new file mode 100644 index 0000000000..67838811c2 --- /dev/null +++ b/.changeset/pf-text-area.md @@ -0,0 +1,16 @@ +--- +"@patternfly/elements": minor +--- +✨ Added `` + +```html +
+ +
+``` diff --git a/core/pfe-core/controllers/internals-controller.ts b/core/pfe-core/controllers/internals-controller.ts index a7be52c2d3..34ba88907c 100644 --- a/core/pfe-core/controllers/internals-controller.ts +++ b/core/pfe-core/controllers/internals-controller.ts @@ -1,10 +1,63 @@ import type { ReactiveController, ReactiveControllerHost } from 'lit'; +interface FACE extends HTMLElement { + formDisabledCallback?(disabled: boolean): void | Promise; + formResetCallback?(): void | Promise; + formStateRestoreCallback?(state: string, mode: string): void | Promise; +} + +const READONLY_KEYS_LIST = [ + 'form', + 'labels', + 'shadowRoot', + 'states', + 'validationMessage', + 'validity', + 'willValidate', +] as const; +const READONLY_KEYS = new Set(READONLY_KEYS_LIST); +const METHODS_LIST = [ + 'checkValidity', + 'reportValidity', + 'setFormValue', + 'setValidity', +] as const; +const METHODS_KEYS = new Set(METHODS_LIST); + +type ReadonlyInternalsProp = (typeof READONLY_KEYS_LIST)[number]; + +function isReadonlyInternalsProp(key: string): key is ReadonlyInternalsProp { + return READONLY_KEYS.has(key as ReadonlyInternalsProp); +} + function isARIAMixinProp(key: string): key is keyof ARIAMixin { return key === 'role' || key.startsWith('aria'); } +function isInternalsMethod(key: string): key is keyof ElementInternals { + return METHODS_KEYS.has(key as unknown as (typeof METHODS_LIST)[number]); +} + +function getLabelText(label: HTMLElement) { + if (label.hidden) { + return ''; + } else { + const ariaLabel = label.getAttribute?.('aria-label'); + return ariaLabel ?? label.textContent; + } +} + export class InternalsController implements ReactiveController, ARIAMixin { + static protos = new WeakMap(); + + declare readonly form: ElementInternals['form']; + declare readonly labels: ElementInternals['labels']; + declare readonly shadowRoot: ElementInternals['shadowRoot']; + // https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/states + declare readonly states: unknown; + declare readonly validity: ElementInternals['validity']; + declare readonly willValidate: ElementInternals['willValidate']; + declare role: ARIAMixin['role']; declare ariaAtomic: ARIAMixin['ariaAtomic']; declare ariaAutoComplete: ARIAMixin['ariaAutoComplete']; @@ -46,6 +99,13 @@ export class InternalsController implements ReactiveController, ARIAMixin { declare ariaValueNow: ARIAMixin['ariaValueNow']; declare ariaValueText: ARIAMixin['ariaValueText']; + declare checkValidity: (...args: Parameters) => boolean; + declare reportValidity: (...args: Parameters) => boolean; + declare setFormValue: (...args: Parameters) => void; + declare setValidity: (...args: Parameters) => void; + + hostConnected?(): void + #internals: ElementInternals; #formDisabled = false; @@ -55,66 +115,81 @@ export class InternalsController implements ReactiveController, ARIAMixin { return this.host.matches(':disabled') || this.#formDisabled; } - static protos = new WeakMap(); - - get labels() { - return this.#internals.labels; - } - - get validity() { - return this.#internals.validity; + /** A best-attempt based on observed behaviour in FireFox 115 on fedora 38 */ + get computedLabelText() { + return this.#internals.ariaLabel || + Array.from(this.#internals.labels as NodeListOf) + .reduce((acc, label) => + `${acc}${getLabelText(label)}`, ''); } constructor( - public host: ReactiveControllerHost & HTMLElement, - options?: Partial + public host: ReactiveControllerHost & FACE, + private options?: Partial ) { this.#internals = host.attachInternals(); - // We need to polyfill :disabled - // see https://github.com/calebdwilliams/element-internals-polyfill/issues/88 - const orig = (host as HTMLElement & { formDisabledCallback?(disabled: boolean): void }).formDisabledCallback; - (host as HTMLElement & { formDisabledCallback?(disabled: boolean): void }).formDisabledCallback = disabled => { + this.#polyfillDisabledPseudo(); + this.#defineInternalsProps(); + } + + /** + * We need to polyfill :disabled + * see https://github.com/calebdwilliams/element-internals-polyfill/issues/88 + */ + #polyfillDisabledPseudo() { + const orig = this.host.formDisabledCallback; + this.host.formDisabledCallback = disabled => { this.#formDisabled = disabled; - orig?.call(host, disabled); + orig?.call(this.host, disabled); }; - // proxy the internals object's aria prototype - for (const key of Object.keys(Object.getPrototypeOf(this.#internals))) { - if (isARIAMixinProp(key)) { - Object.defineProperty(this, key, { - get() { - return this.#internals[key]; - }, - set(value) { - this.#internals[key] = value; - this.host.requestUpdate(); - } - }); - } - } + } - for (const [key, val] of Object.entries(options ?? {})) { + /** Reflect the internals object's aria prototype */ + #defineInternalsProps() { + // TODO(bennypowers): can we define these statically on the prototype instead? + for (const key in this.#internals) { if (isARIAMixinProp(key)) { - this[key] = val; + this.#defineARIAMixinProp(key); + } else if (isReadonlyInternalsProp(key)) { + this.#defineReadonlyProp(key); + } else if (isInternalsMethod(key)) { + this.#defineMethod(key); } } } - hostConnected?(): void - - setFormValue(...args: Parameters) { - return this.#internals.setFormValue(...args); - } - - setValidity(...args: Parameters) { - return this.#internals.setValidity(...args); + #defineARIAMixinProp(key: keyof ARIAMixin) { + Object.defineProperty(this, key, { + get: () => this.#internals[key], + set: value => { + this.#internals[key] = value; + this.host.requestUpdate(); + } + }); + if (this.options && key in this.options) { + this[key as unknown as 'role'] = this.options?.[key] as string; + } } - checkValidity(...args: Parameters) { - return this.#internals.checkValidity(...args); + #defineReadonlyProp(key: ReadonlyInternalsProp) { + Object.defineProperty(this, key, { + enumerable: true, + configurable: false, + get: () => this.#internals[key as Exclude], + }); } - reportValidity(...args: Parameters) { - return this.#internals.reportValidity(...args); + #defineMethod(key: keyof ElementInternals) { + Object.defineProperty(this, key, { + enumerable: true, + configurable: false, + writable: false, + value: (...args: unknown[]) => { + const val = this.#internals[key as 'setValidity'](...args as []); + this.host.requestUpdate(); + return val; + } + }); } submit() { diff --git a/elements/package.json b/elements/package.json index 98933cf996..7f5e86daa3 100644 --- a/elements/package.json +++ b/elements/package.json @@ -60,6 +60,7 @@ "./pf-tabs/pf-tab-panel.js": "./pf-tabs/pf-tab-panel.js", "./pf-tabs/pf-tab.js": "./pf-tabs/pf-tab.js", "./pf-tabs/pf-tabs.js": "./pf-tabs/pf-tabs.js", + "./pf-text-area/pf-text-area.js": "./pf-text-area/pf-text-area.js", "./pf-text-input/pf-text-input.js": "./pf-text-input/pf-text-input.js", "./pf-tile/BaseTile.js": "./pf-tile/BaseTile.js", "./pf-tile/pf-tile.js": "./pf-tile/pf-tile.js", diff --git a/elements/pf-button/BaseButton.ts b/elements/pf-button/BaseButton.ts index f32f1bd7b3..d1cada1120 100644 --- a/elements/pf-button/BaseButton.ts +++ b/elements/pf-button/BaseButton.ts @@ -70,7 +70,7 @@ export abstract class BaseButton extends LitElement { `; } - protected async formDisabledCallback() { + async formDisabledCallback() { await this.updateComplete; this.requestUpdate(); } diff --git a/elements/pf-text-area/README.md b/elements/pf-text-area/README.md new file mode 100644 index 0000000000..e1774bb0a3 --- /dev/null +++ b/elements/pf-text-area/README.md @@ -0,0 +1,11 @@ +# Text Area +Add a description of the component here. + +## Usage +Describe how best to use this web component along with best practices. + +```html + + + +``` diff --git a/elements/pf-text-area/demo/auto-resizing.html b/elements/pf-text-area/demo/auto-resizing.html new file mode 100644 index 0000000000..b3c1966f3d --- /dev/null +++ b/elements/pf-text-area/demo/auto-resizing.html @@ -0,0 +1,6 @@ + + + + diff --git a/elements/pf-text-area/demo/disabled.html b/elements/pf-text-area/demo/disabled.html new file mode 100644 index 0000000000..9f2c5a71b2 --- /dev/null +++ b/elements/pf-text-area/demo/disabled.html @@ -0,0 +1,6 @@ + + + + diff --git a/elements/pf-text-area/demo/horizontally-resizable.html b/elements/pf-text-area/demo/horizontally-resizable.html new file mode 100644 index 0000000000..71b914a159 --- /dev/null +++ b/elements/pf-text-area/demo/horizontally-resizable.html @@ -0,0 +1,6 @@ + + + + diff --git a/elements/pf-text-area/demo/invalid.html b/elements/pf-text-area/demo/invalid.html new file mode 100644 index 0000000000..f615ed2519 --- /dev/null +++ b/elements/pf-text-area/demo/invalid.html @@ -0,0 +1,9 @@ + + + + diff --git a/elements/pf-text-area/demo/pf-text-area.html b/elements/pf-text-area/demo/pf-text-area.html new file mode 100644 index 0000000000..19561aaa7f --- /dev/null +++ b/elements/pf-text-area/demo/pf-text-area.html @@ -0,0 +1,6 @@ + + + + diff --git a/elements/pf-text-area/demo/readonly.html b/elements/pf-text-area/demo/readonly.html new file mode 100644 index 0000000000..eed70e21be --- /dev/null +++ b/elements/pf-text-area/demo/readonly.html @@ -0,0 +1,6 @@ + + + + diff --git a/elements/pf-text-area/demo/validated.html b/elements/pf-text-area/demo/validated.html new file mode 100644 index 0000000000..db1561b9db --- /dev/null +++ b/elements/pf-text-area/demo/validated.html @@ -0,0 +1,13 @@ +
+ + Validate +
+ + + diff --git a/elements/pf-text-area/demo/vertically-resizable.html b/elements/pf-text-area/demo/vertically-resizable.html new file mode 100644 index 0000000000..b112a982a2 --- /dev/null +++ b/elements/pf-text-area/demo/vertically-resizable.html @@ -0,0 +1,6 @@ + + + + diff --git a/elements/pf-text-area/docs/pf-text-area.md b/elements/pf-text-area/docs/pf-text-area.md new file mode 100644 index 0000000000..3c555f467b --- /dev/null +++ b/elements/pf-text-area/docs/pf-text-area.md @@ -0,0 +1,17 @@ +{% renderOverview %} + +{% endrenderOverview %} + +{% band header="Usage" %}{% endband %} + +{% renderSlots %}{% endrenderSlots %} + +{% renderAttributes %}{% endrenderAttributes %} + +{% renderMethods %}{% endrenderMethods %} + +{% renderEvents %}{% endrenderEvents %} + +{% renderCssCustomProperties %}{% endrenderCssCustomProperties %} + +{% renderCssParts %}{% endrenderCssParts %} diff --git a/elements/pf-text-area/pf-text-area.css b/elements/pf-text-area/pf-text-area.css new file mode 100644 index 0000000000..ee79d455b1 --- /dev/null +++ b/elements/pf-text-area/pf-text-area.css @@ -0,0 +1,193 @@ +:host { + display: block; + + /* .pf-c-form-control */ + --pf-c-form-control--Color: var(--pf-global--Color--100, #151515); + --pf-c-form-control--FontSize: var(--pf-global--FontSize--md, 1rem); + --pf-c-form-control--LineHeight: var(--pf-global--LineHeight--md, 1.5); + --pf-c-form-control--BorderWidth: var(--pf-global--BorderWidth--sm, 1px); + --pf-c-form-control--BorderTopColor: var(--pf-global--BorderColor--300, #f0f0f0); + --pf-c-form-control--BorderRightColor: var(--pf-global--BorderColor--300, #f0f0f0); + --pf-c-form-control--BorderBottomColor: var(--pf-global--BorderColor--200, #8a8d90); + --pf-c-form-control--BorderLeftColor: var(--pf-global--BorderColor--300, #f0f0f0); + --pf-c-form-control--BorderRadius: 0; + --pf-c-form-control--BackgroundColor: var(--pf-global--BackgroundColor--100, #fff); + --pf-c-form-control--Width: 100%; + --pf-c-form-control--Height: calc(var(--pf-c-form-control--FontSize) * var(--pf-c-form-control--LineHeight) + var(--pf-c-form-control--BorderWidth) * 2 + var(--pf-c-form-control--PaddingTop) + var(--pf-c-form-control--PaddingBottom)); + --pf-c-form-control--inset--base: var(--pf-global--spacer--sm, 0.5rem); + --pf-c-form-control--PaddingTop: calc(var(--pf-global--spacer--form-element, 0.375rem) - var(--pf-global--BorderWidth--sm)); + --pf-c-form-control--PaddingBottom: calc(var(--pf-global--spacer--form-element, 0.375rem) - var(--pf-global--BorderWidth--sm)); + --pf-c-form-control--PaddingRight: var(--pf-c-form-control--inset--base); + --pf-c-form-control--PaddingLeft: var(--pf-c-form-control--inset--base); + --pf-c-form-control--hover--BorderBottomColor: var(--pf-global--primary-color--100, #06c); + --pf-c-form-control--focus--BorderBottomWidth: var(--pf-global--BorderWidth--md, 2px); + --pf-c-form-control--focus--PaddingBottom: calc(var(--pf-global--spacer--form-element, 0.375rem) - var(--pf-c-form-control--focus--BorderBottomWidth)); + --pf-c-form-control--focus--BorderBottomColor: var(--pf-global--primary-color--100, #06c); + --pf-c-form-control--m-expanded--BorderBottomWidth: var(--pf-global--BorderWidth--md, 2px); + --pf-c-form-control--m-expanded--PaddingBottom: calc(var(--pf-global--spacer--form-element, 0.375rem) - var(--pf-c-form-control--focus--BorderBottomWidth)); + --pf-c-form-control--m-expanded--BorderBottomColor: var(--pf-global--primary-color--100, #06c); + --pf-c-form-control--placeholder--Color: var(--pf-global--Color--dark-200, #6a6e73); + --pf-c-form-control--placeholder--child--Color: var(--pf-global--Color--100, #151515); + --pf-c-form-control--disabled--Color: var(--pf-global--disabled-color--100, #6a6e73); + --pf-c-form-control--disabled--BackgroundColor: var(--pf-global--disabled-color--300, #f0f0f0); + --pf-c-form-control--disabled--BorderColor: transparent; + --pf-c-form-control--readonly--BackgroundColor: var(--pf-global--disabled-color--300, #f0f0f0); + --pf-c-form-control--readonly--hover--BorderBottomColor: var(--pf-global--BorderColor--200, #8a8d90); + --pf-c-form-control--readonly--focus--PaddingBottom: calc(var(--pf-global--spacer--form-element, 0.375rem) - var(--pf-global--BorderWidth--sm)); + --pf-c-form-control--readonly--focus--BorderBottomWidth: var(--pf-global--BorderWidth--sm, 1px); + --pf-c-form-control--readonly--focus--BorderBottomColor: var(--pf-global--BorderColor--200, #8a8d90); + --pf-c-form-control--readonly--m-plain--BackgroundColor: transparent; + --pf-c-form-control--readonly--m-plain--inset--base: 0; + --pf-c-form-control--success--BorderBottomWidth: var(--pf-global--BorderWidth--md, 2px); + --pf-c-form-control--success--PaddingBottom: calc(var(--pf-global--spacer--form-element, 0.375rem) - var(--pf-c-form-control--success--BorderBottomWidth)); + --pf-c-form-control--success--BorderBottomColor: var(--pf-global--success-color--100, #3e8635); + --pf-c-form-control--success--PaddingRight: var(--pf-global--spacer--xl, 2rem); + --pf-c-form-control--success--BackgroundPositionX: calc(100% - var(--pf-c-form-control--PaddingLeft)); + --pf-c-form-control--success--BackgroundPositionY: center; + --pf-c-form-control--success--BackgroundPosition: var(--pf-c-form-control--success--BackgroundPositionX) var(--pf-c-form-control--success--BackgroundPositionY); + --pf-c-form-control--success--BackgroundSizeX: var(--pf-c-form-control--FontSize); + --pf-c-form-control--success--BackgroundSizeY: var(--pf-c-form-control--FontSize); + --pf-c-form-control--success--BackgroundSize: var(--pf-c-form-control--success--BackgroundSizeX) var(--pf-c-form-control--success--BackgroundSizeY); + --pf-c-form-control--success--BackgroundUrl: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%235ba352' d='M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z'/%3E%3C/svg%3E"); + --pf-c-form-control--m-warning--BorderBottomWidth: var(--pf-global--BorderWidth--md, 2px); + --pf-c-form-control--m-warning--PaddingBottom: calc(var(--pf-global--spacer--form-element, 0.375rem) - var(--pf-c-form-control--m-warning--BorderBottomWidth)); + --pf-c-form-control--m-warning--BorderBottomColor: var(--pf-global--warning-color--100, #f0ab00); + --pf-c-form-control--m-warning--PaddingRight: var(--pf-global--spacer--xl, 2rem); + --pf-c-form-control--m-warning--BackgroundPositionX: calc(100% - calc(var(--pf-c-form-control--PaddingLeft) - 0.0625rem)); + --pf-c-form-control--m-warning--BackgroundPositionY: center; + --pf-c-form-control--m-warning--BackgroundPosition: var(--pf-c-form-control--m-warning--BackgroundPositionX) var(--pf-c-form-control--m-warning--BackgroundPositionY); + --pf-c-form-control--m-warning--BackgroundSizeX: 1.25rem; + --pf-c-form-control--m-warning--BackgroundSizeY: var(--pf-c-form-control--FontSize); + --pf-c-form-control--m-warning--BackgroundSize: var(--pf-c-form-control--m-warning--BackgroundSizeX) var(--pf-c-form-control--m-warning--BackgroundSizeY); + --pf-c-form-control--m-warning--BackgroundUrl: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23f0ab00' d='M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z'/%3E%3C/svg%3E"); + --pf-c-form-control--invalid--BorderBottomWidth: var(--pf-global--BorderWidth--md, 2px); + --pf-c-form-control--invalid--PaddingBottom: calc(var(--pf-global--spacer--form-element, 0.375rem) - var(--pf-c-form-control--invalid--BorderBottomWidth)); + --pf-c-form-control--invalid--BorderBottomColor: var(--pf-global--danger-color--100, #c9190b); + --pf-c-form-control--invalid--PaddingRight: var(--pf-global--spacer--xl, 2rem); + --pf-c-form-control--invalid--BackgroundPositionX: calc(100% - var(--pf-c-form-control--PaddingLeft)); + --pf-c-form-control--invalid--BackgroundPositionY: center; + --pf-c-form-control--invalid--BackgroundPosition: var(--pf-c-form-control--invalid--BackgroundPositionX) var(--pf-c-form-control--invalid--BackgroundPositionY); + --pf-c-form-control--invalid--BackgroundSizeX: var(--pf-c-form-control--FontSize); + --pf-c-form-control--invalid--BackgroundSizeY: var(--pf-c-form-control--FontSize); + --pf-c-form-control--invalid--BackgroundSize: var(--pf-c-form-control--invalid--BackgroundSizeX) var(--pf-c-form-control--invalid--BackgroundSizeY); + --pf-c-form-control--invalid--BackgroundUrl: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23fe5142' d='M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z'/%3E%3C/svg%3E"); + --pf-c-form-control--invalid--exclamation--Background: var(--pf-c-form-control--invalid--BackgroundUrl) var(--pf-c-form-control--invalid--BackgroundPosition) / var(--pf-c-form-control--invalid--BackgroundSize) no-repeat; + --pf-c-form-control--invalid--Background: var(--pf-c-form-control--BackgroundColor) var(--pf-c-form-control--invalid--exclamation--Background); + --pf-c-form-control--m-search--PaddingLeft: var(--pf-global--spacer--xl, 2rem); + --pf-c-form-control--m-search--BackgroundPosition: var(--pf-c-form-control--PaddingRight); + --pf-c-form-control--m-search--BackgroundSize: var(--pf-c-form-control--FontSize) var(--pf-c-form-control--FontSize); + --pf-c-form-control--m-search--BackgroundUrl: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23aaabac' d='M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z'/%3E%3C/svg%3E"); + --pf-c-form-control--m-icon--PaddingRight: calc(var(--pf-c-form-control--inset--base) + var(--pf-c-form-control--m-icon--BackgroundSizeX) + var(--pf-c-form-control--m-icon--icon--spacer)); + --pf-c-form-control--m-icon--BackgroundUrl: none; + --pf-c-form-control--m-icon--BackgroundPositionX: calc(100% - var(--pf-c-form-control--inset--base)); + --pf-c-form-control--m-icon--BackgroundPositionY: center; + --pf-c-form-control--m-icon--BackgroundSizeX: var(--pf-c-form-control--FontSize); + --pf-c-form-control--m-icon--BackgroundSizeY: var(--pf-c-form-control--FontSize); + --pf-c-form-control--m-icon--icon--spacer: var(--pf-global--spacer--sm, 0.5rem); + --pf-c-form-control--m-icon--icon--PaddingRight: calc(var(--pf-c-form-control--inset--base) + var(--pf-c-form-control--invalid--BackgroundSizeX) + var(--pf-c-form-control--m-icon--icon--spacer) + var(--pf-c-form-control--m-icon--BackgroundSizeX) + var(--pf-c-form-control--m-icon--icon--spacer)); + --pf-c-form-control--m-icon--icon--BackgroundPositionX: calc(var(--pf-c-form-control--m-icon--BackgroundPositionX) - var(--pf-c-form-control--m-icon--icon--spacer) - var(--pf-c-form-control--invalid--BackgroundSizeX)); + --pf-c-form-control--m-icon--invalid--BackgroundUrl: var(--pf-c-form-control--invalid--BackgroundUrl), var(--pf-c-form-control--m-icon--BackgroundUrl); + --pf-c-form-control--m-icon--invalid--BackgroundPosition: var(--pf-c-form-control--invalid--BackgroundPosition), var(--pf-c-form-control--m-icon--icon--BackgroundPositionX) var(--pf-c-form-control--m-icon--BackgroundPositionY); + --pf-c-form-control--m-icon--invalid--BackgroundSize: var(--pf-c-form-control--invalid--BackgroundSize), var(--pf-c-form-control--m-icon--BackgroundSizeX) var(--pf-c-form-control--m-icon--BackgroundSizeY); + --pf-c-form-control--m-icon--success--BackgroundUrl: var(--pf-c-form-control--success--BackgroundUrl), var(--pf-c-form-control--m-icon--BackgroundUrl); + --pf-c-form-control--m-icon--success--BackgroundPosition: var(--pf-c-form-control--success--BackgroundPosition), var(--pf-c-form-control--m-icon--icon--BackgroundPositionX) var(--pf-c-form-control--m-icon--BackgroundPositionY); + --pf-c-form-control--m-icon--success--BackgroundSize: var(--pf-c-form-control--success--BackgroundSize), var(--pf-c-form-control--m-icon--BackgroundSizeX) var(--pf-c-form-control--m-icon--BackgroundSizeY); + --pf-c-form-control--m-icon--m-warning--BackgroundUrl: var(--pf-c-form-control--m-warning--BackgroundUrl), var(--pf-c-form-control--m-icon--BackgroundUrl); + --pf-c-form-control--m-icon--m-warning--BackgroundPosition: var(--pf-c-form-control--m-warning--BackgroundPosition), var(--pf-c-form-control--m-icon--icon--BackgroundPositionX) var(--pf-c-form-control--m-icon--BackgroundPositionY); + --pf-c-form-control--m-icon--m-warning--BackgroundSize: var(--pf-c-form-control--m-warning--BackgroundSize), var(--pf-c-form-control--m-icon--BackgroundSizeX) var(--pf-c-form-control--m-icon--BackgroundSizeY); + --pf-c-form-control--m-calendar--BackgroundUrl: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23aaabac' d='M0 464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V192H0v272zm320-196c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zm0 128c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zM192 268c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zm0 128c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zM64 268c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zm0 128c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM400 64h-48V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v48H160V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v48H48C21.5 64 0 85.5 0 112v48h448v-48c0-26.5-21.5-48-48-48z'/%3E%3C/svg%3E"); + --pf-c-form-control--m-clock--BackgroundUrl: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23aaabac' d='M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm61.8-104.4l-84.9-61.7c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v141.7l66.8 48.6c5.4 3.9 6.5 11.4 2.6 16.8L334.6 349c-3.9 5.3-11.4 6.5-16.8 2.6z'/%3E%3C/svg%3E"); + --pf-c-form-control__select--PaddingRight: calc(var(--pf-global--spacer--lg, 1.5rem) + var(--pf-c-form-control--BorderWidth) + var(--pf-c-form-control--BorderWidth)); + --pf-c-form-control__select--PaddingLeft: calc(var(--pf-global--spacer--sm, 0.5rem) - var(--pf-c-form-control--BorderWidth)); + --pf-c-form-control__select--BackgroundUrl: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 512'%3E%3Cpath fill='%23urrentColor' d='M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z'/%3E%3C/svg%3E"); + --pf-c-form-control__select--BackgroundSize: .625em; + --pf-c-form-control__select--BackgroundPositionX: calc(100% - var(--pf-global--spacer--md, 1rem) + 1px); + --pf-c-form-control__select--BackgroundPositionY: center; + --pf-c-form-control__select--BackgroundPosition: var(--pf-c-form-control__select--BackgroundPositionX) var(--pf-c-form-control__select--BackgroundPositionY); + --pf-c-form-control__select--success--PaddingRight: var(--pf-global--spacer--3xl, 4rem); + --pf-c-form-control__select--success--BackgroundPosition: calc(var(--pf-c-form-control__select--BackgroundPositionX) - var(--pf-global--spacer--lg, 1.5rem)); + --pf-c-form-control__select--m-warning--PaddingRight: var(--pf-global--spacer--3xl, 4rem); + --pf-c-form-control__select--m-warning--BackgroundPosition: calc(var(--pf-c-form-control__select--BackgroundPositionX) - var(--pf-global--spacer--lg, 1.5rem) + 0.0625rem); + --pf-c-form-control__select--invalid--PaddingRight: var(--pf-global--spacer--3xl, 4rem); + --pf-c-form-control__select--invalid--BackgroundPosition: calc(var(--pf-c-form-control__select--BackgroundPositionX) - var(--pf-global--spacer--lg, 1.5rem)); + --pf-c-form-control--textarea--Width: var(--pf-c-form-control--Width); + --pf-c-form-control--textarea--Height: auto; + --pf-c-form-control--textarea--success--BackgroundPositionY: var(--pf-c-form-control--PaddingLeft); + --pf-c-form-control--textarea--m-warning--BackgroundPositionY: var(--pf-c-form-control--PaddingLeft); + --pf-c-form-control--textarea--invalid--BackgroundPositionY: var(--pf-c-form-control--PaddingLeft); + --pf-c-form-control--m-icon-sprite--success--BackgroundUrl: url(/v4/images/status-icon-sprite.4fee9fefc3971799d2dd4de0a15617f0.svg#success); + --pf-c-form-control--m-icon-sprite--m-warning--BackgroundUrl: url(/v4/images/status-icon-sprite.4fee9fefc3971799d2dd4de0a15617f0.svg#warning); + --pf-c-form-control--m-icon-sprite--invalid--BackgroundUrl: url(/v4/images/status-icon-sprite.4fee9fefc3971799d2dd4de0a15617f0.svg#invalid); + --pf-c-form-control--m-icon-sprite__select--BackgroundUrl: url(/v4/images/status-icon-sprite.4fee9fefc3971799d2dd4de0a15617f0.svg#select); + --pf-c-form-control--m-icon-sprite--m-search--BackgroundUrl: url(/v4/images/status-icon-sprite.4fee9fefc3971799d2dd4de0a15617f0.svg#search); + --pf-c-form-control--m-icon-sprite--m-calendar--BackgroundUrl: url(/v4/images/status-icon-sprite.4fee9fefc3971799d2dd4de0a15617f0.svg#calendar); + --pf-c-form-control--m-icon-sprite--m-clock--BackgroundUrl: url(/v4/images/status-icon-sprite.4fee9fefc3971799d2dd4de0a15617f0.svg#clock); + --pf-c-form-control--m-icon-sprite__select--BackgroundSize: var(--pf-c-form-control--FontSize); + --pf-c-form-control--m-icon-sprite__select--BackgroundPositionX: calc(100% - var(--pf-global--spacer--md, 1rem) + 7px); + --pf-c-form-control--m-icon-sprite__select--success--BackgroundPosition: calc(100% - var(--pf-global--spacer--md, 1rem) + 1px - var(--pf-global--spacer--lg)); + --pf-c-form-control--m-icon-sprite__select--m-warning--BackgroundPosition: calc(100% - var(--pf-global--spacer--md, 1rem) - var(--pf-global--spacer--lg) + 0.0625rem); + --pf-c-form-control--m-icon-sprite__select--invalid--BackgroundPosition: calc(100% - var(--pf-global--spacer--md, 1rem) - var(--pf-global--spacer--lg)); +} + +textarea { + --pf-c-form-control--success--BackgroundPositionY: var(--pf-c-form-control--textarea--success--BackgroundPositionY); + --pf-c-form-control--invalid--BackgroundPositionY: var(--pf-c-form-control--textarea--invalid--BackgroundPositionY); + --pf-c-form-control--m-warning--BackgroundPositionY: var(--pf-c-form-control--textarea--m-warning--BackgroundPositionY); + + width: var(--pf-c-form-control--textarea--Width); + height: var(--pf-c-form-control--textarea--Height); + vertical-align: bottom; + color: var(--pf-c-form-control--Color); + width: var(--pf-c-form-control--Width); + padding: var(--pf-c-form-control--PaddingTop) var(--pf-c-form-control--PaddingRight) var(--pf-c-form-control--PaddingBottom) var(--pf-c-form-control--PaddingLeft); + font-size: var(--pf-c-form-control--FontSize); + line-height: var(--pf-c-form-control--LineHeight); + background-color: var(--pf-c-form-control--BackgroundColor); + background-repeat: no-repeat; + border: var(--pf-c-form-control--BorderWidth) solid; + border-color: var(--pf-c-form-control--BorderTopColor) var(--pf-c-form-control--BorderRightColor) var(--pf-c-form-control--BorderBottomColor) var(--pf-c-form-control--BorderLeftColor); + border-radius: var(--pf-c-form-control--BorderRadius); + appearance: none; +} + +textarea::placeholder { + color: var(--pf-c-form-control--placeholder--Color); +} + +textarea:hover { + --pf-c-form-control--BorderBottomColor: var(--pf-c-form-control--hover--BorderBottomColor); +} + +textarea:focus { + --pf-c-form-control--BorderBottomColor: var(--pf-c-form-control--focus--BorderBottomColor); + + padding-bottom: var(--pf-c-form-control--focus--PaddingBottom); + border-bottom-width: var(--pf-c-form-control--focus--BorderBottomWidth); +} + +textarea:invalid { + --pf-c-form-control--PaddingRight: var(--pf-c-form-control--invalid--PaddingRight); + --pf-c-form-control--BorderBottomColor: var(--pf-c-form-control--invalid--BorderBottomColor); + + padding-bottom: var(--pf-c-form-control--invalid--PaddingBottom); + background-image: var(--pf-c-form-control--invalid--BackgroundUrl); + background-position: var(--pf-c-form-control--invalid--BackgroundPosition); + background-size: var(--pf-c-form-control--invalid--BackgroundSize); + border-bottom-width: var(--pf-c-form-control--invalid--BorderBottomWidth); +} + +textarea:disabled { + --pf-c-form-control--BackgroundColor: var(--pf-c-form-control--disabled--BackgroundColor); + color: var(--pf-c-form-control--disabled--Color); + cursor: not-allowed; + border-color: var(--pf-c-form-control--disabled--BorderColor); +} + +textarea[readonly] { + background-color: var(--pf-c-form-control--readonly--BackgroundColor); +} + +.vertical { resize: vertical; } +.horizontal { resize: horizontal; } +.both { resize: both; } + diff --git a/elements/pf-text-area/pf-text-area.ts b/elements/pf-text-area/pf-text-area.ts new file mode 100644 index 0000000000..bc70d9987d --- /dev/null +++ b/elements/pf-text-area/pf-text-area.ts @@ -0,0 +1,254 @@ +import { LitElement, html } from 'lit'; +import { customElement } from 'lit/decorators/custom-element.js'; +import { property } from 'lit/decorators/property.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; +import { classMap } from 'lit/directives/class-map.js'; + +import { InternalsController } from '@patternfly/pfe-core/controllers/internals-controller.js'; + +import styles from './pf-text-area.css'; +import { Logger } from '@patternfly/pfe-core/controllers/logger.js'; + +/** + * A **text area** component is used for entering a paragraph of text that is longer than one line. + * + * @cssprop --pf-c-form-control--Color - {@default var(--pf-global--Color--100, #151515)} + * @cssprop --pf-c-form-control--FontSize - {@default var(--pf-global--FontSize--md, 1rem)} + * @cssprop --pf-c-form-control--LineHeight - {@default var(--pf-global--LineHeight--md, 1.5)} + * @cssprop --pf-c-form-control--BorderWidth - {@default var(--pf-global--BorderWidth--sm, 1px)} + * @cssprop --pf-c-form-control--BorderTopColor - {@default var(--pf-global--BorderColor--300, #f0f0f0)} + * @cssprop --pf-c-form-control--BorderRightColor - {@default var(--pf-global--BorderColor--300, #f0f0f0)} + * @cssprop --pf-c-form-control--BorderBottomColor - {@default var(--pf-global--BorderColor--200, #8a8d90)} + * @cssprop --pf-c-form-control--BorderLeftColor - {@default var(--pf-global--BorderColor--300, #f0f0f0)} + * @cssprop --pf-c-form-control--BorderRadius - {@default 0} + * @cssprop --pf-c-form-control--BackgroundColor - {@default var(--pf-global--BackgroundColor--100, #fff)} + * @cssprop --pf-c-form-control--Width - {@default 100%} + * @cssprop --pf-c-form-control--Height - {@default calc(var(--pf-c-form-control--FontSize) * var(--pf-c-form-control--LineHeight) + var(--pf-c-form-control--BorderWidth) * 2 + var(--pf-c-form-control--PaddingTop) + var(--pf-c-form-control--PaddingBottom))} + * @cssprop --pf-c-form-control--inset--base - {@default var(--pf-global--spacer--sm, 0.5rem)} + * @cssprop --pf-c-form-control--PaddingTop - {@default calc(var(--pf-global--spacer--form-element, 0.375rem) - var(--pf-global--BorderWidth--sm, 1px))} + * @cssprop --pf-c-form-control--PaddingBottom - {@default calc(var(--pf-global--spacer--form-element, 0.375rem) - var(--pf-global--BorderWidth--sm, 1px))} + * @cssprop --pf-c-form-control--PaddingRight - {@default var(--pf-c-form-control--inset--base)} + * @cssprop --pf-c-form-control--PaddingLeft - {@default var(--pf-c-form-control--inset--base)} + * @cssprop --pf-c-form-control--hover--BorderBottomColor - {@default var(--pf-global--primary-color--100, #06c)} + * @cssprop --pf-c-form-control--focus--BorderBottomWidth - {@default var(--pf-global--BorderWidth--md, 2px)} + * @cssprop --pf-c-form-control--focus--PaddingBottom - {@default calc(var(--pf-global--spacer--form-element, 0.375rem) - var(--pf-c-form-control--focus--BorderBottomWidth))} + * @cssprop --pf-c-form-control--focus--BorderBottomColor - {@default var(--pf-global--primary-color--100, #06c)} + * @cssprop --pf-c-form-control--m-expanded--BorderBottomWidth - {@default var(--pf-global--BorderWidth--md, 2px)} + * @cssprop --pf-c-form-control--m-expanded--PaddingBottom - {@default calc(var(--pf-global--spacer--form-element, 0.375rem) - var(--pf-c-form-control--focus--BorderBottomWidth))} + * @cssprop --pf-c-form-control--m-expanded--BorderBottomColor - {@default var(--pf-global--primary-color--100, #06c)} + * @cssprop --pf-c-form-control--placeholder--Color - {@default var(--pf-global--Color--dark-200, #6a6e73)} + * @cssprop --pf-c-form-control--placeholder--child--Color - {@default var(--pf-global--Color--100, #151515)} + * @cssprop --pf-c-form-control--disabled--Color - {@default var(--pf-global--disabled-color--100, #6a6e73)} + * @cssprop --pf-c-form-control--disabled--BackgroundColor - {@default var(--pf-global--disabled-color--300, #f0f0f0)} + * @cssprop --pf-c-form-control--disabled--BorderColor - {@default transparent} + * @cssprop --pf-c-form-control--readonly--BackgroundColor - {@default var(--pf-global--disabled-color--300, #f0f0f0)} + * @cssprop --pf-c-form-control--readonly--hover--BorderBottomColor - {@default var(--pf-global--BorderColor--200, #8a8d90)} + * @cssprop --pf-c-form-control--readonly--focus--PaddingBottom - {@default calc(var(--pf-global--spacer--form-element, 0.375rem) - var(--pf-global--BorderWidth--sm, 1px))} + * @cssprop --pf-c-form-control--readonly--focus--BorderBottomWidth - {@default var(--pf-global--BorderWidth--sm, 1px)} + * @cssprop --pf-c-form-control--readonly--focus--BorderBottomColor - {@default var(--pf-global--BorderColor--200, #8a8d90)} + * @cssprop --pf-c-form-control--readonly--m-plain--BackgroundColor - {@default transparent} + * @cssprop --pf-c-form-control--readonly--m-plain--inset--base - {@default 0} + * @cssprop --pf-c-form-control--success--BorderBottomWidth - {@default var(--pf-global--BorderWidth--md, 2px)} + * @cssprop --pf-c-form-control--success--PaddingBottom - {@default calc(var(--pf-global--spacer--form-element, 0.375rem) - var(--pf-c-form-control--success--BorderBottomWidth))} + * @cssprop --pf-c-form-control--success--BorderBottomColor - {@default var(--pf-global--success-color--100, #3e8635)} + * @cssprop --pf-c-form-control--success--PaddingRight - {@default var(--pf-global--spacer--xl, 2rem)} + * @cssprop --pf-c-form-control--success--BackgroundPositionX - {@default calc(100% - var(--pf-c-form-control--PaddingLeft))} + * @cssprop --pf-c-form-control--success--BackgroundPositionY - {@default center} + * @cssprop --pf-c-form-control--success--BackgroundPosition - {@default var(--pf-c-form-control--success--BackgroundPositionX) var(--pf-c-form-control--success--BackgroundPositionY)} + * @cssprop --pf-c-form-control--success--BackgroundSizeX - {@default var(--pf-c-form-control--FontSize)} + * @cssprop --pf-c-form-control--success--BackgroundSizeY - {@default var(--pf-c-form-control--FontSize)} + * @cssprop --pf-c-form-control--success--BackgroundSize - {@default var(--pf-c-form-control--success--BackgroundSizeX) var(--pf-c-form-control--success--BackgroundSizeY)} + * @cssprop --pf-c-form-control--success--BackgroundUrl - {@default url('data:image/svg+xml;charset=utf8,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"%3E%3Cpath fill="%235ba352" d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"/%3E%3C/svg%3E')} + * @cssprop --pf-c-form-control--m-warning--BorderBottomWidth - {@default var(--pf-global--BorderWidth--md, 2px)} + * @cssprop --pf-c-form-control--m-warning--PaddingBottom - {@default calc(var(--pf-global--spacer--form-element, 0.375rem) - var(--pf-c-form-control--m-warning--BorderBottomWidth))} + * @cssprop --pf-c-form-control--m-warning--BorderBottomColor - {@default var(--pf-global--warning-color--100, #f0ab00)} + * @cssprop --pf-c-form-control--m-warning--PaddingRight - {@default var(--pf-global--spacer--xl, 2rem)} + * @cssprop --pf-c-form-control--m-warning--BackgroundPositionX - {@default calc(100% - calc(var(--pf-c-form-control--PaddingLeft) - 0.0625rem))} + * @cssprop --pf-c-form-control--m-warning--BackgroundPositionY - {@default center} + * @cssprop --pf-c-form-control--m-warning--BackgroundPosition - {@default var(--pf-c-form-control--m-warning--BackgroundPositionX) var(--pf-c-form-control--m-warning--BackgroundPositionY)} + * @cssprop --pf-c-form-control--m-warning--BackgroundSizeX - {@default 1.25rem} + * @cssprop --pf-c-form-control--m-warning--BackgroundSizeY - {@default var(--pf-c-form-control--FontSize)} + * @cssprop --pf-c-form-control--m-warning--BackgroundSize - {@default var(--pf-c-form-control--m-warning--BackgroundSizeX) var(--pf-c-form-control--m-warning--BackgroundSizeY)} + * @cssprop --pf-c-form-control--m-warning--BackgroundUrl - {@default url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23f0ab00' d='M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z'/%3E%3C/svg%3E")} + * @cssprop --pf-c-form-control--invalid--BorderBottomWidth - {@default var(--pf-global--BorderWidth--md, 2px)} + * @cssprop --pf-c-form-control--invalid--PaddingBottom - {@default calc(var(--pf-global--spacer--form-element, 0.375rem) - var(--pf-c-form-control--invalid--BorderBottomWidth))} + * @cssprop --pf-c-form-control--invalid--BorderBottomColor - {@default var(--pf-global--danger-color--100, #c9190b)} + * @cssprop --pf-c-form-control--invalid--PaddingRight - {@default var(--pf-global--spacer--xl, 2rem)} + * @cssprop --pf-c-form-control--invalid--BackgroundPositionX - {@default calc(100% - var(--pf-c-form-control--PaddingLeft))} + * @cssprop --pf-c-form-control--invalid--BackgroundPositionY - {@default center} + * @cssprop --pf-c-form-control--invalid--BackgroundPosition - {@default var(--pf-c-form-control--invalid--BackgroundPositionX) var(--pf-c-form-control--invalid--BackgroundPositionY)} + * @cssprop --pf-c-form-control--invalid--BackgroundSizeX - {@default var(--pf-c-form-control--FontSize)} + * @cssprop --pf-c-form-control--invalid--BackgroundSizeY - {@default var(--pf-c-form-control--FontSize)} + * @cssprop --pf-c-form-control--invalid--BackgroundSize - {@default var(--pf-c-form-control--invalid--BackgroundSizeX) var(--pf-c-form-control--invalid--BackgroundSizeY)} + * @cssprop --pf-c-form-control--invalid--BackgroundUrl - {@default url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23fe5142' d='M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z'/%3E%3C/svg%3E")} + * @cssprop --pf-c-form-control--invalid--exclamation--Background - {@default var(--pf-c-form-control--invalid--BackgroundUrl) var(--pf-c-form-control--invalid--BackgroundPosition) / var(--pf-c-form-control--invalid--BackgroundSize) no-repeat} + * @cssprop --pf-c-form-control--invalid--Background - {@default var(--pf-c-form-control--BackgroundColor) var(--pf-c-form-control--invalid--exclamation--Background)} + * @cssprop --pf-c-form-control--m-search--PaddingLeft - {@default var(--pf-global--spacer--xl, 2rem)} + * @cssprop --pf-c-form-control--m-search--BackgroundPosition - {@default var(--pf-c-form-control--PaddingRight)} + * @cssprop --pf-c-form-control--m-search--BackgroundSize - {@default var(--pf-c-form-control--FontSize) var(--pf-c-form-control--FontSize)} + * @cssprop --pf-c-form-control--m-search--BackgroundUrl - {@default url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23aaabac' d='M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z'/%3E%3C/svg%3E")} + * @cssprop --pf-c-form-control--m-icon--PaddingRight - {@default calc(var(--pf-c-form-control--inset--base) + var(--pf-c-form-control--m-icon--BackgroundSizeX) + var(--pf-c-form-control--m-icon--icon--spacer))} + * @cssprop --pf-c-form-control--m-icon--BackgroundUrl - {@default none} + * @cssprop --pf-c-form-control--m-icon--BackgroundPositionX - {@default calc(100% - var(--pf-c-form-control--inset--base))} + * @cssprop --pf-c-form-control--m-icon--BackgroundPositionY - {@default center} + * @cssprop --pf-c-form-control--m-icon--BackgroundSizeX - {@default var(--pf-c-form-control--FontSize)} + * @cssprop --pf-c-form-control--m-icon--BackgroundSizeY - {@default var(--pf-c-form-control--FontSize)} + * @cssprop --pf-c-form-control--m-icon--icon--spacer - {@default var(--pf-global--spacer--sm, 0.5rem)} + * @cssprop --pf-c-form-control--m-icon--icon--PaddingRight - {@default calc(var(--pf-c-form-control--inset--base) + var(--pf-c-form-control--invalid--BackgroundSizeX) + var(--pf-c-form-control--m-icon--icon--spacer) + var(--pf-c-form-control--m-icon--BackgroundSizeX) + var(--pf-c-form-control--m-icon--icon--spacer))} + * @cssprop --pf-c-form-control--m-icon--icon--BackgroundPositionX - {@default calc(var(--pf-c-form-control--m-icon--BackgroundPositionX) - var(--pf-c-form-control--m-icon--icon--spacer) - var(--pf-c-form-control--invalid--BackgroundSizeX))} + * @cssprop --pf-c-form-control--m-icon--invalid--BackgroundUrl - {@default var(--pf-c-form-control--invalid--BackgroundUrl), var(--pf-c-form-control--m-icon--BackgroundUrl)} + * @cssprop --pf-c-form-control--m-icon--invalid--BackgroundPosition - {@default var(--pf-c-form-control--invalid--BackgroundPosition), var(--pf-c-form-control--m-icon--icon--BackgroundPositionX) var(--pf-c-form-control--m-icon--BackgroundPositionY)} + * @cssprop --pf-c-form-control--m-icon--invalid--BackgroundSize - {@default var(--pf-c-form-control--invalid--BackgroundSize), var(--pf-c-form-control--m-icon--BackgroundSizeX) var(--pf-c-form-control--m-icon--BackgroundSizeY)} + * @cssprop --pf-c-form-control--m-icon--success--BackgroundUrl - {@default var(--pf-c-form-control--success--BackgroundUrl), var(--pf-c-form-control--m-icon--BackgroundUrl)} + * @cssprop --pf-c-form-control--m-icon--success--BackgroundPosition - {@default var(--pf-c-form-control--success--BackgroundPosition), var(--pf-c-form-control--m-icon--icon--BackgroundPositionX) var(--pf-c-form-control--m-icon--BackgroundPositionY)} + * @cssprop --pf-c-form-control--m-icon--success--BackgroundSize - {@default var(--pf-c-form-control--success--BackgroundSize), var(--pf-c-form-control--m-icon--BackgroundSizeX) var(--pf-c-form-control--m-icon--BackgroundSizeY)} + * @cssprop --pf-c-form-control--m-icon--m-warning--BackgroundUrl - {@default var(--pf-c-form-control--m-warning--BackgroundUrl), var(--pf-c-form-control--m-icon--BackgroundUrl)} + * @cssprop --pf-c-form-control--m-icon--m-warning--BackgroundPosition - {@default var(--pf-c-form-control--m-warning--BackgroundPosition), var(--pf-c-form-control--m-icon--icon--BackgroundPositionX) var(--pf-c-form-control--m-icon--BackgroundPositionY)} + * @cssprop --pf-c-form-control--m-icon--m-warning--BackgroundSize - {@default var(--pf-c-form-control--m-warning--BackgroundSize), var(--pf-c-form-control--m-icon--BackgroundSizeX) var(--pf-c-form-control--m-icon--BackgroundSizeY)} + * @cssprop --pf-c-form-control--m-calendar--BackgroundUrl - {@default url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23aaabac' d='M0 464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V192H0v272zm320-196c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zm0 128c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zM192 268c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zm0 128c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zM64 268c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zm0 128c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM400 64h-48V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v48H160V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v48H48C21.5 64 0 85.5 0 112v48h448v-48c0-26.5-21.5-48-48-48z'/%3E%3C/svg%3E")} + * @cssprop --pf-c-form-control--m-clock--BackgroundUrl - {@default url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23aaabac' d='M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm61.8-104.4l-84.9-61.7c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v141.7l66.8 48.6c5.4 3.9 6.5 11.4 2.6 16.8L334.6 349c-3.9 5.3-11.4 6.5-16.8 2.6z'/%3E%3C/svg%3E")} + * @cssprop --pf-c-form-control__select--PaddingRight - {@default calc(var(--pf-global--spacer--lg, 1.5rem) + var(--pf-c-form-control--BorderWidth) + var(--pf-c-form-control--BorderWidth))} + * @cssprop --pf-c-form-control__select--PaddingLeft - {@default calc(var(--pf-global--spacer--sm, 0.5rem) - var(--pf-c-form-control--BorderWidth))} + * @cssprop --pf-c-form-control__select--BackgroundUrl - {@default url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 512'%3E%3Cpath fill='%23urrentColor' d='M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z'/%3E%3C/svg%3E")} + * @cssprop --pf-c-form-control__select--BackgroundSize - {@default .625em} + * @cssprop --pf-c-form-control__select--BackgroundPositionX - {@default calc(100% - var(--pf-global--spacer--md, 1rem) + 1px)} + * @cssprop --pf-c-form-control__select--BackgroundPositionY - {@default center} + * @cssprop --pf-c-form-control__select--BackgroundPosition - {@default var(--pf-c-form-control__select--BackgroundPositionX) var(--pf-c-form-control__select--BackgroundPositionY)} + * @cssprop --pf-c-form-control__select--success--PaddingRight - {@default var(--pf-global--spacer--3xl, 4rem)} + * @cssprop --pf-c-form-control__select--success--BackgroundPosition - {@default calc(var(--pf-c-form-control__select--BackgroundPositionX) - var(--pf-global--spacer--lg, 1.5rem))} + * @cssprop --pf-c-form-control__select--m-warning--PaddingRight - {@default var(--pf-global--spacer--3xl, 4rem)} + * @cssprop --pf-c-form-control__select--m-warning--BackgroundPosition - {@default calc(var(--pf-c-form-control__select--BackgroundPositionX) - var(--pf-global--spacer--lg, 1.5rem) + 0.0625rem)} + * @cssprop --pf-c-form-control__select--invalid--PaddingRight - {@default var(--pf-global--spacer--3xl, 4rem)} + * @cssprop --pf-c-form-control__select--invalid--BackgroundPosition - {@default calc(var(--pf-c-form-control__select--BackgroundPositionX) - var(--pf-global--spacer--lg, 1.5rem))} + * @cssprop --pf-c-form-control--textarea--Width - {@default var(--pf-c-form-control--Width)} + * @cssprop --pf-c-form-control--textarea--Height - {@default auto} + * @cssprop --pf-c-form-control--textarea--success--BackgroundPositionY - {@default var(--pf-c-form-control--PaddingLeft)} + * @cssprop --pf-c-form-control--textarea--m-warning--BackgroundPositionY - {@default var(--pf-c-form-control--PaddingLeft)} + * @cssprop --pf-c-form-control--textarea--invalid--BackgroundPositionY - {@default var(--pf-c-form-control--PaddingLeft)} + * @cssprop --pf-c-form-control--m-icon-sprite--success--BackgroundUrl - {@default url(/v4/images/status-icon-sprite.4fee9fefc3971799d2dd4de0a15617f0.svg#success)} + * @cssprop --pf-c-form-control--m-icon-sprite--m-warning--BackgroundUrl - {@default url(/v4/images/status-icon-sprite.4fee9fefc3971799d2dd4de0a15617f0.svg#warning)} + * @cssprop --pf-c-form-control--m-icon-sprite--invalid--BackgroundUrl - {@default url(/v4/images/status-icon-sprite.4fee9fefc3971799d2dd4de0a15617f0.svg#invalid)} + * @cssprop --pf-c-form-control--m-icon-sprite__select--BackgroundUrl - {@default url(/v4/images/status-icon-sprite.4fee9fefc3971799d2dd4de0a15617f0.svg#select)} + * @cssprop --pf-c-form-control--m-icon-sprite--m-search--BackgroundUrl - {@default url(/v4/images/status-icon-sprite.4fee9fefc3971799d2dd4de0a15617f0.svg#search)} + * @cssprop --pf-c-form-control--m-icon-sprite--m-calendar--BackgroundUrl - {@default url(/v4/images/status-icon-sprite.4fee9fefc3971799d2dd4de0a15617f0.svg#calendar)} + * @cssprop --pf-c-form-control--m-icon-sprite--m-clock--BackgroundUrl - {@default url(/v4/images/status-icon-sprite.4fee9fefc3971799d2dd4de0a15617f0.svg#clock)} + * @cssprop --pf-c-form-control--m-icon-sprite__select--BackgroundSize - {@default var(--pf-c-form-control--FontSize)} + * @cssprop --pf-c-form-control--m-icon-sprite__select--BackgroundPositionX - {@default calc(100% - var(--pf-global--spacer--md, 1rem) + 7px)} + * @cssprop --pf-c-form-control--m-icon-sprite__select--success--BackgroundPosition - {@default calc(100% - var(--pf-global--spacer--md, 1rem) + 1px - var(--pf-global--spacer--lg, 1.5rem))} + * @cssprop --pf-c-form-control--m-icon-sprite__select--m-warning--BackgroundPosition - {@default calc(100% - var(--pf-global--spacer--md, 1rem) - var(--pf-global--spacer--lg, 1.5rem) + 0.0625rem)} + * @cssprop --pf-c-form-control--m-icon-sprite__select--invalid--BackgroundPosition - {@default calc(100% - var(--pf-global--spacer--md, 1rem) - var(--pf-global--spacer--lg, 1.5rem))} + */ +@customElement('pf-text-area') +export class PfTextArea extends LitElement { + static readonly styles = [styles]; + + static readonly formAssociated = true; + + static override shadowRootOptions: ShadowRootInit = { ...LitElement.shadowRootOptions, delegatesFocus: true }; + + /** Accessible label for the input when no `