Skip to content

Commit da07ab1

Browse files
authored
feat(list): Add slots for filter actions (#7183)
**Related Issue:** #6600 ## Summary - adds slot `filter-actions-start`. - adds slot `filter-actions-end`. - Uses `calcite-stack` internally for layout. - Adds story - Updates demo file
1 parent 35d4bbb commit da07ab1

File tree

5 files changed

+133
-19
lines changed

5 files changed

+133
-19
lines changed

packages/calcite-components/src/components/list/list.scss

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525
@apply w-full border-collapse;
2626
}
2727

28+
.stack {
29+
--calcite-stack-padding-inline: 0;
30+
--calcite-stack-padding-block: 0;
31+
}
32+
2833
::slotted(calcite-list-item) {
2934
@apply shadow-border-bottom mb-px;
3035
}
@@ -34,12 +39,11 @@
3439
}
3540

3641
.sticky-pos {
37-
@apply sticky top-0 z-sticky;
42+
@apply sticky
43+
top-0
44+
z-sticky
45+
bg-foreground-1;
3846
& th {
3947
@apply p-0;
4048
}
4149
}
42-
43-
calcite-filter {
44-
@apply mb-px;
45-
}

packages/calcite-components/src/components/list/list.stories.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,3 +543,50 @@ export const filteredChildListItems_TestOnly = (): string => html` <calcite-list
543543
</calcite-list-item>
544544
</calcite-list-item-group>
545545
</calcite-list>`;
546+
547+
export const filterActions_TestOnly = (): string => html`<calcite-list
548+
selection-mode="single"
549+
label="test"
550+
filter-enabled
551+
>
552+
<calcite-action
553+
appearance="transparent"
554+
icon="banana"
555+
text="menu"
556+
label="menu"
557+
slot="filter-actions-start"
558+
></calcite-action>
559+
<calcite-action
560+
appearance="transparent"
561+
icon="ellipsis"
562+
text="menu"
563+
label="menu"
564+
slot="filter-actions-start"
565+
></calcite-action>
566+
<calcite-action
567+
appearance="transparent"
568+
icon="filter"
569+
text="menu"
570+
label="menu"
571+
slot="filter-actions-end"
572+
></calcite-action>
573+
<calcite-action
574+
appearance="transparent"
575+
icon="sort-ascending"
576+
text="menu"
577+
label="menu"
578+
slot="filter-actions-end"
579+
></calcite-action>
580+
<calcite-list-item label="test1" value="test1" description="hello world 1">
581+
<calcite-icon icon="banana" slot="content-start" style="color: var(--calcite-ui-success)"></calcite-icon>
582+
</calcite-list-item>
583+
<calcite-list-item label="test2" value="test2" description="hello world 2">
584+
<calcite-icon icon="compass" slot="content-start" style="color: var(--calcite-ui-success)"></calcite-icon>
585+
</calcite-list-item>
586+
<calcite-list-item label="test3" value="test3" description="hello world 3">
587+
<calcite-icon icon="compass" slot="content-start" style="color: var(--calcite-ui-success)"></calcite-icon>
588+
</calcite-list-item>
589+
<calcite-list-item disabled label="test4" value="test4" description="hello world 4">
590+
<calcite-icon icon="compass" slot="content-start" style="color: var(--calcite-ui-success)"></calcite-icon>
591+
</calcite-list-item>
592+
</calcite-list>`;

packages/calcite-components/src/components/list/list.tsx

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
Watch
1313
} from "@stencil/core";
1414
import { debounce } from "lodash-es";
15-
import { toAriaBoolean } from "../../utils/dom";
15+
import { slotChangeHasAssignedElement, toAriaBoolean } from "../../utils/dom";
1616
import {
1717
connectInteractive,
1818
disconnectInteractive,
@@ -24,7 +24,8 @@ import { SelectionMode } from "../interfaces";
2424
import { ItemData } from "../list-item/interfaces";
2525
import { MAX_COLUMNS } from "../list-item/resources";
2626
import { getListItemChildren, updateListItemChildren } from "../list-item/utils";
27-
import { CSS, debounceTimeout, SelectionAppearance } from "./resources";
27+
import { CSS, debounceTimeout, SelectionAppearance, SLOTS } from "./resources";
28+
import { SLOTS as STACK_SLOTS } from "../stack/resources";
2829

2930
const listItemSelector = "calcite-list-item";
3031
const parentSelector = "calcite-list-item-group, calcite-list-item";
@@ -40,6 +41,8 @@ import {
4041
* A general purpose list that enables users to construct list items that conform to Calcite styling.
4142
*
4243
* @slot - A slot for adding `calcite-list-item` elements.
44+
* @slot filter-actions-start - A slot for adding actionable `calcite-action` elements before the filter component.
45+
* @slot filter-actions-end - A slot for adding actionable `calcite-action` elements after the filter component.
4346
*/
4447
@Component({
4548
tag: "calcite-list",
@@ -247,6 +250,10 @@ export class List implements InteractiveComponent, LoadableComponent {
247250

248251
@State() dataForFilter: ItemData = [];
249252

253+
@State() hasFilterActionsStart = false;
254+
255+
@State() hasFilterActionsEnd = false;
256+
250257
filterEl: HTMLCalciteFilterElement;
251258

252259
// --------------------------------------------------------------------------
@@ -276,7 +283,9 @@ export class List implements InteractiveComponent, LoadableComponent {
276283
dataForFilter,
277284
filterEnabled,
278285
filterPlaceholder,
279-
filterText
286+
filterText,
287+
hasFilterActionsStart,
288+
hasFilterActionsEnd
280289
} = this;
281290
return (
282291
<div class={CSS.container}>
@@ -288,20 +297,32 @@ export class List implements InteractiveComponent, LoadableComponent {
288297
onKeyDown={this.handleListKeydown}
289298
role="treegrid"
290299
>
291-
{filterEnabled ? (
300+
{filterEnabled || hasFilterActionsStart || hasFilterActionsEnd ? (
292301
<thead>
293302
<tr class={{ [CSS.sticky]: true }}>
294303
<th colSpan={MAX_COLUMNS}>
295-
<calcite-filter
296-
aria-label={filterPlaceholder}
297-
disabled={loading || disabled}
298-
items={dataForFilter}
299-
onCalciteFilterChange={this.handleFilterChange}
300-
placeholder={filterPlaceholder}
301-
value={filterText}
302-
// eslint-disable-next-line react/jsx-sort-props
303-
ref={this.setFilterEl}
304-
/>
304+
<calcite-stack class={CSS.stack}>
305+
<slot
306+
name={SLOTS.filterActionsStart}
307+
onSlotchange={this.handleFilterActionsStartSlotChange}
308+
slot={STACK_SLOTS.actionsStart}
309+
/>
310+
<calcite-filter
311+
aria-label={filterPlaceholder}
312+
disabled={loading || disabled}
313+
items={dataForFilter}
314+
onCalciteFilterChange={this.handleFilterChange}
315+
placeholder={filterPlaceholder}
316+
value={filterText}
317+
// eslint-disable-next-line react/jsx-sort-props
318+
ref={this.setFilterEl}
319+
/>
320+
<slot
321+
name={SLOTS.filterActionsEnd}
322+
onSlotchange={this.handleFilterActionsEndSlotChange}
323+
slot={STACK_SLOTS.actionsEnd}
324+
/>
325+
</calcite-stack>
305326
</th>
306327
</tr>
307328
</thead>
@@ -324,6 +345,14 @@ export class List implements InteractiveComponent, LoadableComponent {
324345
updateListItemChildren(getListItemChildren(event));
325346
};
326347

348+
private handleFilterActionsStartSlotChange = (event: Event): void => {
349+
this.hasFilterActionsStart = slotChangeHasAssignedElement(event);
350+
};
351+
352+
private handleFilterActionsEndSlotChange = (event: Event): void => {
353+
this.hasFilterActionsEnd = slotChangeHasAssignedElement(event);
354+
};
355+
327356
private setActiveListItem = (): void => {
328357
const { enabledListItems } = this;
329358

packages/calcite-components/src/components/list/resources.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,16 @@ export const CSS = {
22
container: "container",
33
table: "table",
44
scrim: "scrim",
5+
stack: "stack",
56
tableContainer: "table-container",
67
sticky: "sticky-pos"
78
};
89

910
export const debounceTimeout = 0;
1011

1112
export type SelectionAppearance = "border" | "icon";
13+
14+
export const SLOTS = {
15+
filterActionsStart: "filter-actions-start",
16+
filterActionsEnd: "filter-actions-end"
17+
};

packages/calcite-components/src/demos/list.html

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,34 @@ <h1 style="margin: 0 auto; text-align: center">List</h1>
3939

4040
<div class="child">
4141
<calcite-list selection-mode="single" label="test" filter-enabled>
42+
<calcite-action
43+
appearance="transparent"
44+
icon="banana"
45+
text="menu"
46+
label="menu"
47+
slot="filter-actions-start"
48+
></calcite-action>
49+
<calcite-action
50+
appearance="transparent"
51+
icon="ellipsis"
52+
text="menu"
53+
label="menu"
54+
slot="filter-actions-start"
55+
></calcite-action>
56+
<calcite-action
57+
appearance="transparent"
58+
icon="filter"
59+
text="menu"
60+
label="menu"
61+
slot="filter-actions-end"
62+
></calcite-action>
63+
<calcite-action
64+
appearance="transparent"
65+
icon="sort-ascending"
66+
text="menu"
67+
label="menu"
68+
slot="filter-actions-end"
69+
></calcite-action>
4270
<calcite-list-item label="test1" value="test1" description="hello world 1">
4371
<calcite-icon icon="banana" slot="content-start" style="color: var(--calcite-ui-success)"></calcite-icon>
4472
</calcite-list-item>

0 commit comments

Comments
 (0)