Skip to content

Commit

Permalink
fix(list, list-item, list-item-group): honor hidden attribute on list…
Browse files Browse the repository at this point in the history
…-item and list-item-group (#8541)

**Related Issue:** #8539

## Summary

- Adds internal `filterHidden` property to `list-item` and
`list-item-group`
- This property is used to hide an item when it is filtered out instead
of the native `hidden` attribute
  - This allows the `hidden` attribute to be set by an end user
- Renames internal vars
- Adds screenshot tests
- Add e2e tests
- Added a developer discussion topic to consider not modifying global
`hidden` attribute on host elements.
  • Loading branch information
driskull authored Jan 5, 2024
1 parent ed1fe2b commit 3851dc6
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 11 deletions.
16 changes: 16 additions & 0 deletions packages/calcite-components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2845,6 +2845,10 @@ export namespace Components {
* When `true`, the component's drag handle is selected.
*/
"dragSelected": boolean;
/**
* Hides the component when filtered.
*/
"filterHidden": boolean;
/**
* The label text of the component. Displays above the description text.
*/
Expand Down Expand Up @@ -2902,6 +2906,10 @@ export namespace Components {
* When `true`, interaction is prevented and the component is displayed with lower opacity.
*/
"disabled": boolean;
/**
* Hides the component when filtered.
*/
"filterHidden": boolean;
/**
* The header text for all nested `calcite-list-item` rows.
*/
Expand Down Expand Up @@ -10218,6 +10226,10 @@ declare namespace LocalJSX {
* When `true`, the component's drag handle is selected.
*/
"dragSelected"?: boolean;
/**
* Hides the component when filtered.
*/
"filterHidden"?: boolean;
/**
* The label text of the component. Displays above the description text.
*/
Expand Down Expand Up @@ -10294,6 +10306,10 @@ declare namespace LocalJSX {
* When `true`, interaction is prevented and the component is displayed with lower opacity.
*/
"disabled"?: boolean;
/**
* Hides the component when filtered.
*/
"filterHidden"?: boolean;
/**
* The header text for all nested `calcite-list-item` rows.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ describe("calcite-list-item-group", () => {
propertyName: "disabled",
defaultValue: false,
},
{
propertyName: "filterHidden",
defaultValue: false,
},
]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
--calcite-list-item-spacing-indent: theme("spacing.4");
}

:host([filter-hidden]) {
@apply hidden;
}

@include disabled();

.container {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ export class ListItemGroup implements InteractiveComponent {
*/
@Prop({ reflect: true }) disabled = false;

/**
* Hides the component when filtered.
*
* @internal
*/
@Prop({ reflect: true }) filterHidden = false;

/**
* The header text for all nested `calcite-list-item` rows.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ describe("calcite-list-item", () => {
propertyName: "dragSelected",
defaultValue: false,
},
{
propertyName: "filterHidden",
defaultValue: false,
},
]);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
--calcite-list-item-spacing-indent: theme("spacing.4");
}

:host([filter-hidden]) {
@apply hidden;
}

@include disabled();

.container {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,13 @@ export class ListItem
*/
@Prop({ mutable: true, reflect: true }) dragSelected = false;

/**
* Hides the component when filtered.
*
* @internal
*/
@Prop({ reflect: true }) filterHidden = false;

/**
* The label text of the component. Displays above the description text.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ describe("calcite-list", () => {
expect(await list.getProperty("filteredItems")).toHaveLength(3);
expect(await list.getProperty("filteredData")).toHaveLength(3);

const visibleItems = await page.findAll("calcite-list-item:not([hidden])");
const visibleItems = await page.findAll("calcite-list-item:not([filter-hidden])");

expect(visibleItems.map((item) => item.id)).toEqual(["label-match", "description-match", "value-match"]);
});
Expand Down
13 changes: 13 additions & 0 deletions packages/calcite-components/src/components/list/list.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,18 @@ export const richContentFilterEnabled = (): string => html`
</calcite-list>
`;

export const filterEnabledWithHiddenItems = (): string => html`
<calcite-list filter-enabled>
<calcite-list-item-group hidden heading="Layers">
<calcite-list-item hidden label="Hidden item" description="I should not be displayed."> </calcite-list-item>
</calcite-list-item-group>
<calcite-list-item label="Princess Bubblegum" description="Ruler of The Candy Kingdom"> </calcite-list-item>
<calcite-list-item hidden label="Hidden item" description="I should not be displayed."> </calcite-list-item>
<calcite-list-item label="Princess Bubblegum" description="Ruler of The Candy Kingdom"> </calcite-list-item>
<calcite-list-item label="Princess Bubblegum" description="Ruler of The Candy Kingdom"> </calcite-list-item>
</calcite-list>
`;

export const darkModeRTL_TestOnly = (): string => html`
<calcite-list class="calcite-mode-dark" dir="rtl" ${knobsHTML()}>
<calcite-list-item label="Princess Bubblegum" description="Ruler of The Candy Kingdom">
Expand Down Expand Up @@ -505,6 +517,7 @@ export const filteredChildListItems_TestOnly = (): string =>
selection-appearance="border"
selection-mode="single"
>
<calcite-list-item label="Estuaries" value="estuaries" hidden></calcite-list-item>
<calcite-list-item-group heading="Layers">
<calcite-list-item selected label="Hiking trails" value="hiking-trails">
<calcite-dropdown slot="actions-end" overlay-positioning="fixed" placement="bottom-end" scale="s">
Expand Down
20 changes: 10 additions & 10 deletions packages/calcite-components/src/components/list/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ export class List

mutationObserver = createObserver("mutation", () => this.updateListItems());

openItems: HTMLCalciteListItemElement[] = [];
visibleItems: HTMLCalciteListItemElement[] = [];

parentListEl: HTMLCalciteListElement;

Expand Down Expand Up @@ -666,7 +666,7 @@ export class List
};

private updateSelectedItems = (emit = false): void => {
this.selectedItems = this.openItems.filter((item) => item.selected);
this.selectedItems = this.visibleItems.filter((item) => item.selected);
if (emit) {
this.calciteListChange.emit();
}
Expand All @@ -681,10 +681,10 @@ export class List
filteredItems: HTMLCalciteListItemElement[];
visibleParents: WeakSet<HTMLCalciteListItemElement | HTMLCalciteListItemGroupElement>;
}): void {
const hidden =
const filterHidden =
!visibleParents.has(el) && !filteredItems.includes(el as HTMLCalciteListItemElement);

el.hidden = hidden;
el.filterHidden = filterHidden;

const closestParent = el.parentElement.closest(parentSelector) as
| HTMLCalciteListItemElement
Expand All @@ -694,7 +694,7 @@ export class List
return;
}

if (!hidden) {
if (!filterHidden) {
visibleParents.add(closestParent);
}

Expand All @@ -706,16 +706,16 @@ export class List
}

private updateFilteredItems = (emit = false): void => {
const { openItems, filteredData, filterText } = this;
const { visibleItems, filteredData, filterText } = this;

const values = filteredData.map((item) => item.value);

const lastDescendantItems = openItems?.filter((listItem) =>
openItems.every((li) => li === listItem || !listItem.contains(li)),
const lastDescendantItems = visibleItems?.filter((listItem) =>
visibleItems.every((li) => li === listItem || !listItem.contains(li)),
);

const filteredItems =
openItems.filter((item) => !filterText || values.includes(item.value)) || [];
visibleItems.filter((item) => !filterText || values.includes(item.value)) || [];

const visibleParents = new WeakSet<HTMLElement>();

Expand Down Expand Up @@ -811,7 +811,7 @@ export class List
this.filterEl.items = this.dataForFilter;
}
}
this.openItems = this.listItems.filter((item) => !item.closed);
this.visibleItems = this.listItems.filter((item) => !item.closed && !item.hidden);
this.updateFilteredItems(emit);
this.focusableItems = this.filteredItems.filter((item) => !item.disabled);
this.setActiveListItem();
Expand Down

0 comments on commit 3851dc6

Please sign in to comment.