Skip to content

Commit

Permalink
feat(list-item): Add content slot for specialized content (#5876)
Browse files Browse the repository at this point in the history
**Related Issue:** #3032

## Summary

feat(list-item): Add slot for specialized content #3032

- Adds a new `content` slot to the `list-item` for customized content.
- `content` slot takes precedence over `label` and `description`
properties.
  • Loading branch information
driskull committed Dec 5, 2022
1 parent 23259f2 commit a510773
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 7 deletions.
16 changes: 16 additions & 0 deletions src/components/list-item/list-item.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,22 @@ describe("calcite-list-item", () => {
expect(contentNode).toBeNull();
});

it("renders custom content in place of label and description", async () => {
const page = await newE2EPage({
html: `<calcite-list-item label="test" description="test"><div slot="content">My custom content</div></calcite-list-item>`
});

await page.waitForChanges();

const contentNode = await page.find(`calcite-list-item >>> .${CSS.content}`);

expect(contentNode).toBeNull();

const customContentNode = await page.find(`calcite-list-item >>> .${CSS.customContent}`);

expect(customContentNode).not.toBeNull();
});

it("emits calciteListItemSelect on click", async () => {
const page = await newE2EPage({
html: `<calcite-list-item label="hello" description="world"></calcite-list-item>`
Expand Down
3 changes: 2 additions & 1 deletion src/components/list-item/list-item.scss
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ td:focus {
@apply focus-normal z-sticky;
}

.content {
.content,
.custom-content {
@apply text-n2-wrap
flex
flex-auto
Expand Down
33 changes: 27 additions & 6 deletions src/components/list-item/list-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
* @slot - A slot for adding `calcite-list-item` and `calcite-list-item-group` elements.
* @slot actions-start - A slot for adding actionable `calcite-action` elements before the content of the component.
* @slot content-start - A slot for adding non-actionable elements before the label and description of the component.
* @slot content - A slot for adding non-actionable, centered content in place of the `label` and `description` of the component.
* @slot content-end - A slot for adding non-actionable elements after the label and description of the component.
* @slot actions-end - A slot for adding actionable `calcite-action` elements after the content of the component.
*/
Expand Down Expand Up @@ -175,6 +176,8 @@ export class ListItem implements InteractiveComponent, LoadableComponent {

@State() hasActionsEnd = false;

@State() hasCustomContent = false;

@State() hasContentStart = false;

@State() hasContentEnd = false;
Expand Down Expand Up @@ -321,6 +324,15 @@ export class ListItem implements InteractiveComponent, LoadableComponent {
);
}

renderCustomContent(): VNode {
const { hasCustomContent } = this;
return (
<div class={CSS.customContent} hidden={!hasCustomContent}>
<slot name={SLOTS.content} onSlotchange={this.handleContentSlotChange} />
</div>
);
}

renderContentEnd(): VNode {
const { hasContentEnd } = this;
return (
Expand All @@ -330,10 +342,10 @@ export class ListItem implements InteractiveComponent, LoadableComponent {
);
}

renderContent(): VNode {
const { label, description } = this;
renderContentProperties(): VNode {
const { label, description, hasCustomContent } = this;

return !!label || !!description ? (
return !hasCustomContent && (!!label || !!description) ? (
<div class={CSS.content} key="content">
{label ? (
<div class={CSS.label} key="label">
Expand All @@ -350,9 +362,14 @@ export class ListItem implements InteractiveComponent, LoadableComponent {
}

renderContentContainer(): VNode {
const { description, label, selectionMode } = this;
const hasCenterContent = !!label || !!description;
const content = [this.renderContentStart(), this.renderContent(), this.renderContentEnd()];
const { description, label, selectionMode, hasCustomContent } = this;
const hasCenterContent = hasCustomContent || !!label || !!description;
const content = [
this.renderContentStart(),
this.renderCustomContent(),
this.renderContentProperties(),
this.renderContentEnd()
];

return (
<td
Expand Down Expand Up @@ -435,6 +452,10 @@ export class ListItem implements InteractiveComponent, LoadableComponent {
//
// --------------------------------------------------------------------------

handleContentSlotChange = (event: Event): void => {
this.hasCustomContent = slotChangeHasAssignedElement(event);
};

handleActionsStartSlotChange = (event: Event): void => {
this.hasActionsStart = slotChangeHasAssignedElement(event);
};
Expand Down
2 changes: 2 additions & 0 deletions src/components/list-item/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const CSS = {
nestedContainer: "nested-container",
nestedContainerHidden: "nested-container--hidden",
content: "content",
customContent: "custom-content",
actionsStart: "actions-start",
contentStart: "content-start",
label: "label",
Expand All @@ -21,6 +22,7 @@ export const CSS = {
export const SLOTS = {
actionsStart: "actions-start",
contentStart: "content-start",
content: "content",
contentEnd: "content-end",
actionsEnd: "actions-end"
};
Expand Down
21 changes: 21 additions & 0 deletions src/components/list/list.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,24 @@ export const disabled_TestOnly = (): string => html`<calcite-list disabled>
"
></calcite-list-item>
</calcite-list>`;

export const customContent_TestOnly = (): string => html`<calcite-list disabled>
<calcite-list-item>
<div slot="content">
<strong>Cras iaculis ultricies nulla.</strong>
<div>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</div>
</div></calcite-list-item
>
<calcite-list-item disabled>
<div slot="content">
<strong>Cras iaculis ultricies nulla.</strong>
<div>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</div>
</div></calcite-list-item
>
<calcite-list-item
><div slot="content">
<strong>Cras iaculis ultricies nulla.</strong>
<div>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</div>
</div></calcite-list-item
>
</calcite-list>`;

0 comments on commit a510773

Please sign in to comment.