From b5fa7f40b489bb71d01dfd9bb3697c05c8c68d5c Mon Sep 17 00:00:00 2001 From: Eliza Khachatryan Date: Thu, 24 Aug 2023 12:29:12 -0700 Subject: [PATCH] refactor(dropdown, dropdown-item-group, dropdown-item): `getElementProp` is refactored out in favor of inheritable props set directly on parent (#7582) **Related Issue:** #6038 ## Summary `getElementProp` is refactored out across child components as an outdated pattern in favor of inheritable props set directly on the parent. The logic for setting these props thus moves to the parent, getting rid of the `getElementProp` altogether. The parent component gets a `mutationObserver` to do this as well as `watchers` for when it needs to modify the children. Inherited props addressed: - [x] `scale` is inherited from `dropdown`, - [x] `selectionMode` is inherited from `dropdown-item-group`, so there can be a mix of types within one dropdown. --- .../dropdown-group/dropdown-group.e2e.ts | 20 +- .../dropdown-group/dropdown-group.tsx | 49 +- .../components/dropdown-group/resources.ts | 5 - .../dropdown-item/dropdown-item.tsx | 36 +- .../src/components/dropdown-item/resources.ts | 4 +- .../src/components/dropdown/dropdown.e2e.ts | 2075 +++++++++-------- .../src/components/dropdown/dropdown.tsx | 16 +- 7 files changed, 1139 insertions(+), 1066 deletions(-) delete mode 100644 packages/calcite-components/src/components/dropdown-group/resources.ts diff --git a/packages/calcite-components/src/components/dropdown-group/dropdown-group.e2e.ts b/packages/calcite-components/src/components/dropdown-group/dropdown-group.e2e.ts index eb2d3871d58..bd4f35a409c 100644 --- a/packages/calcite-components/src/components/dropdown-group/dropdown-group.e2e.ts +++ b/packages/calcite-components/src/components/dropdown-group/dropdown-group.e2e.ts @@ -1,6 +1,24 @@ -import { renders, hidden } from "../../tests/commonTests"; +import { defaults, hidden, reflects, renders } from "../../tests/commonTests"; describe("calcite-dropdown-group", () => { + describe("defaults", () => { + defaults("calcite-dropdown-group", [ + { + propertyName: "selectionMode", + defaultValue: "single", + }, + ]); + }); + + describe("reflects", () => { + reflects("calcite-dropdown-group", [ + { + propertyName: "selectionMode", + value: "single", + }, + ]); + }); + describe("renders", () => { renders("calcite-dropdown-group", { display: "block" }); }); diff --git a/packages/calcite-components/src/components/dropdown-group/dropdown-group.tsx b/packages/calcite-components/src/components/dropdown-group/dropdown-group.tsx index 79eb28e1c44..bc7d9e8dc58 100644 --- a/packages/calcite-components/src/components/dropdown-group/dropdown-group.tsx +++ b/packages/calcite-components/src/components/dropdown-group/dropdown-group.tsx @@ -8,11 +8,13 @@ import { Listen, Prop, VNode, + Watch, } from "@stencil/core"; -import { getElementProp } from "../../utils/dom"; import { Scale, SelectionMode } from "../interfaces"; import { RequestedItem } from "./interfaces"; -import { CSS } from "./resources"; +import { createObserver } from "../../utils/observers"; +import { CSS } from "../dropdown-item/resources"; + /** * @slot - A slot for adding `calcite-dropdown-item`s. */ @@ -34,18 +36,25 @@ export class DropdownGroup { @Prop({ reflect: true }) groupTitle: string; /** - * Specifies the component's selection mode, where - * `"multiple"` allows any number of (or no) selected `calcite-dropdown-item`s, - * `"single"` allows and requires one selected `calcite-dropdown-item`, and - * `"none"` does not allow selection on `calcite-dropdown-item`s. + * Specifies the size of the component inherited from the parent `calcite-dropdown`, defaults to `m`. + * + * @internal */ - @Prop({ reflect: true }) selectionMode: Extract<"single" | "none" | "multiple", SelectionMode> = - "single"; + @Prop() scale: Scale = "m"; /** - * Specifies the size of the component. + * Specifies the selection mode for `calcite-dropdown-item` children, defaults to `single`: + * - `multiple` allows any number of selected items, + * - `single` allows only one selection (default), + * - `none` doesn't allow for any selection. */ - @Prop({ reflect: true }) scale: Scale; + @Prop({ reflect: true }) selectionMode: Extract<"none" | "single" | "multiple", SelectionMode> = + "single"; + + @Watch("selectionMode") + handlePropsChange(): void { + this.updateItems(); + } //-------------------------------------------------------------------------- // @@ -64,12 +73,15 @@ export class DropdownGroup { // //-------------------------------------------------------------------------- + connectedCallback(): void { + this.updateItems(); + } + componentWillLoad(): void { this.groupPosition = this.getGroupPosition(); } render(): VNode { - const scale: Scale = this.scale || getElementProp(this.el, "scale", "m"); const groupTitle = this.groupTitle ? (