From aebf454937ec9cf6e30fecb809fd26045d00d937 Mon Sep 17 00:00:00 2001 From: Kieran Nichols Date: Fri, 17 May 2024 14:40:48 -0400 Subject: [PATCH] feat(autocomplete): add popoverExpanded prop/attr to base field and update autocomplete to use it (#564) --- src/dev/pages/autocomplete/autocomplete.ejs | 4 +-- src/lib/autocomplete/autocomplete-adapter.ts | 32 ++++++++++++++------ src/lib/field/base/base-field-constants.ts | 1 + src/lib/field/base/base-field-foundation.ts | 12 ++++++++ src/lib/field/base/base-field.ts | 7 +++++ src/lib/field/field-constants.ts | 1 - 6 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/dev/pages/autocomplete/autocomplete.ejs b/src/dev/pages/autocomplete/autocomplete.ejs index a63d1b9b5..c823bc4cd 100644 --- a/src/dev/pages/autocomplete/autocomplete.ejs +++ b/src/dev/pages/autocomplete/autocomplete.ejs @@ -1,12 +1,12 @@
- + + -
diff --git a/src/lib/autocomplete/autocomplete-adapter.ts b/src/lib/autocomplete/autocomplete-adapter.ts index 9210abbad..25d1c8296 100644 --- a/src/lib/autocomplete/autocomplete-adapter.ts +++ b/src/lib/autocomplete/autocomplete-adapter.ts @@ -7,6 +7,7 @@ import { IListDropdown, IListDropdownConfig, ListDropdown } from '../list-dropdo import { CHIP_FIELD_CONSTANTS } from '../chip-field'; import { IPopoverComponent } from '../popover/popover'; import { POPOVER_CONSTANTS } from '../popover'; +import { IFieldComponent } from '../field/field'; export interface IAutocompleteAdapter extends IBaseAdapter { setInputElement(): HTMLInputElement; @@ -285,22 +286,35 @@ export class AutocompleteAdapter extends BaseAdapter imp } private _getDefaultTargetElement(): HTMLElement { - const fieldElements = [ - TEXT_FIELD_CONSTANTS.elementName, - CHIP_FIELD_CONSTANTS.elementName - ]; - // This component is often used with the field-like Forge elements, if so, let's target our popup around one if its internal elements for proper alignment - const textField = this._component.querySelector(`:is(${fieldElements.join(',')})`) as HTMLElement; - if (textField?.popoverTargetElement) { - return textField.popoverTargetElement; + // This component is often used with the field-like Forge elements, if so, let's target our popup + // around one if its internal elements for proper alignment + const fieldLike = this._tryGetFieldLikeChild(); + if (fieldLike?.popoverTargetElement) { + return fieldLike.popoverTargetElement; } return this._component.querySelector('input') || this._component; } private _tryToggleDropdownIconRotation(state: boolean): void { + const fieldLike = this._tryGetFieldLikeChild(); + if (fieldLike?.popoverIcon) { + fieldLike.popoverExpanded = state; + } + + // Deprecated/legacy support + // TODO: Remove in a future release const dropdownIcon = this._component.querySelector(AUTOCOMPLETE_CONSTANTS.selectors.DROPDOWN_ICON) as HTMLElement; if (dropdownIcon) { - toggleAttribute(dropdownIcon, state, AUTOCOMPLETE_CONSTANTS.attributes.DROPDOWN_ICON_OPEN); + dropdownIcon.style.transition = 'transform 120ms linear'; + dropdownIcon.style.transform = state ? 'rotateZ(180deg)' : ''; } } + + private _tryGetFieldLikeChild(): IFieldComponent | null { + const fieldLikeElements = [ + TEXT_FIELD_CONSTANTS.elementName, + CHIP_FIELD_CONSTANTS.elementName + ]; + return this._component.querySelector(`:is(${fieldLikeElements.join(',')})`) as IFieldComponent; + } } diff --git a/src/lib/field/base/base-field-constants.ts b/src/lib/field/base/base-field-constants.ts index 48402dda4..a1f047ca7 100644 --- a/src/lib/field/base/base-field-constants.ts +++ b/src/lib/field/base/base-field-constants.ts @@ -14,6 +14,7 @@ const observedAttributes = { DENSITY: 'density', DENSE: 'dense', POPOVER_ICON: 'popover-icon', + POPOVER_EXPANDED: 'popover-expanded', SUPPORT_TEXT_INSET: 'support-text-inset' }; diff --git a/src/lib/field/base/base-field-foundation.ts b/src/lib/field/base/base-field-foundation.ts index 6108164ea..2d9d55c1f 100644 --- a/src/lib/field/base/base-field-foundation.ts +++ b/src/lib/field/base/base-field-foundation.ts @@ -16,6 +16,7 @@ export interface IBaseFieldFoundation extends ICustomElementFoundation { density: string; dense: boolean; popoverIcon: boolean; + popoverExpanded: boolean; supportTextInset: string; click(): void; applyLabel(value: string | null): void; @@ -35,6 +36,7 @@ export abstract class BaseFieldFoundation implement protected _density = BASE_FIELD_CONSTANTS.defaults.DEFAULT_DENSITY; protected _dense = false; protected _popoverIcon = false; + protected _popoverExpanded = false; protected _supportTextInset = BASE_FIELD_CONSTANTS.defaults.DEFAULT_SUPPORT_TEXT_INSET; protected _permanentlyFloatLabel = false; @@ -213,6 +215,16 @@ export abstract class BaseFieldFoundation implement } } + public get popoverExpanded(): boolean { + return this._popoverExpanded; + } + public set popoverExpanded(value: boolean) { + if (this._popoverExpanded !== value) { + this._popoverExpanded = value; + this._adapter.setFieldProperty('popoverExpanded', value); + } + } + public get supportTextInset(): FieldSupportTextInset { return this._supportTextInset; } diff --git a/src/lib/field/base/base-field.ts b/src/lib/field/base/base-field.ts index bda79ca21..35932a040 100644 --- a/src/lib/field/base/base-field.ts +++ b/src/lib/field/base/base-field.ts @@ -19,6 +19,7 @@ export interface IBaseField extends IWithLabelAwareness { density: FieldDensity; dense: boolean; popoverIcon: boolean; + popoverExpanded: boolean; supportTextInset: FieldSupportTextInset; floatLabelWithoutAnimation(value: boolean): void; } @@ -75,6 +76,9 @@ export abstract class BaseField case BASE_FIELD_CONSTANTS.observedAttributes.POPOVER_ICON: this.popoverIcon = coerceBoolean(newValue); return; + case BASE_FIELD_CONSTANTS.observedAttributes.POPOVER_EXPANDED: + this.popoverExpanded = coerceBoolean(newValue); + return; case BASE_FIELD_CONSTANTS.observedAttributes.SUPPORT_TEXT_INSET: this.supportTextInset = newValue as FieldSupportTextInset; return; @@ -128,6 +132,9 @@ export abstract class BaseField @FoundationProperty() public declare popoverIcon: boolean; + @FoundationProperty() + public declare popoverExpanded: boolean; + @FoundationProperty() public declare supportTextInset: FieldSupportTextInset; diff --git a/src/lib/field/field-constants.ts b/src/lib/field/field-constants.ts index 43343653a..3136d8bfa 100644 --- a/src/lib/field/field-constants.ts +++ b/src/lib/field/field-constants.ts @@ -6,7 +6,6 @@ const elementName: keyof HTMLElementTagNameMap = `${COMPONENT_NAME_PREFIX}field` const observedAttributes = { ...BASE_FIELD_CONSTANTS.observedAttributes, - POPOVER_EXPANDED: 'popover-expanded', MULTILINE: 'multiline', FOCUS_INDICATOR_ALLOW_FOCUS: 'focus-indicator-allow-focus', FOCUS_INDICATOR_FOCUS_MODE: 'focus-indicator-focus-mode'