Skip to content

feat(modal): Adds slots for the left and right side of modal title #621

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 33 additions & 10 deletions src/lib/components/Modal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
let showHeader: boolean;
$: showHeader = nonNullish($$slots.title);

let showHeaderLeft: boolean;
$: showHeaderLeft = nonNullish($$slots["header-left"]);

/**
* @deprecated according new design there should be no sticky footer
*/
Expand Down Expand Up @@ -62,16 +65,27 @@
>
{#if showHeader}
<div class="header">
{#if showHeaderLeft}
<div class="header-left">
<slot name="header-left" />
</div>
{/if}

<h2 id={modalTitleId} data-tid="modal-title">
<slot name="title" />
</h2>
{#if !disablePointerEvents}
<button
data-tid="close-modal"
on:click|stopPropagation={close}
aria-label={$i18n.core.close}><IconClose size="24px" /></button
>
{/if}

<div class="header-right">
<slot name="header-right" />

{#if !disablePointerEvents}
<button
data-tid="close-modal"
on:click|stopPropagation={close}
aria-label={$i18n.core.close}><IconClose size="24px" /></button
>
{/if}
</div>
</div>
{/if}

Expand Down Expand Up @@ -222,20 +236,29 @@

position: relative;

.header-left {
display: flex;
justify-content: flex-start;
align-items: center;
}

h2 {
@include text.truncate;
grid-column-start: 2;
text-align: center;
}

.header-right {
display: flex;
justify-content: flex-end;
align-items: center;
}

button {
display: flex;
justify-content: center;
align-items: center;
padding: 0;

justify-self: flex-end;

&:active,
&:focus,
&:hover {
Expand Down
14 changes: 8 additions & 6 deletions src/routes/(split)/components/modal/+page.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ A Modal is a dialog that appears on top of the app's content, and must be dismis

## Slots

| Slot name | Description |
| ------------ | -------------------------------------------------------------------------------------------- |
| Default slot | The content of the modal. |
| `title` | The title of the modal. Displayed in a toolbar with a "Close" icon button on the right side. |
| `toolbar` | A sticky toolbar displayed at the bottom of the modal. Available for "alert" only. |
| `sub-title` | A slot below the title but outside of the content card. |
| Slot name | Description |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Default slot | The content of the modal. |
| `title` | The title of the modal. Displayed in a toolbar with a "Close" icon button on the right side. |
| `header-left` | Position content on the left side of the header title, such as additional buttons. |
| `header-right` | Position content on the right side of the header title, such as additional buttons, or replace the close button with a custom button by setting `disablePointerEvents` to `true`. |
| `toolbar` | A sticky toolbar displayed at the bottom of the modal. Available for "alert" only. |
| `sub-title` | A slot below the title but outside of the content card. |

## Events

Expand Down
16 changes: 16 additions & 0 deletions src/tests/lib/components/Modal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,4 +215,20 @@ describe("Modal", () => {

expect(() => getByTestId("close-modal")).toThrow();
});

it("should render header-left and header-right slots", () => {
const { container } = render(ModalTest, { props: { ...props } });

const headerLeftElement = container.querySelector(
'[data-tid="header-left-content"]',
);
const headerRightElement = container.querySelector(
'[data-tid="header-right-content"]',
);

expect(headerLeftElement).not.toBeNull();
expect(headerLeftElement?.textContent).toBe("Left Header Content");
expect(headerRightElement).not.toBeNull();
expect(headerRightElement?.textContent).toBe("Right Header Content");
});
});
6 changes: 6 additions & 0 deletions src/tests/lib/components/ModalTest.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,10 @@
<Modal {visible} {disablePointerEvents} on:nnsClose>
<h3 slot="title">Test</h3>
<p slot="sub-title">{subTitle}</p>
<span slot="header-left" data-tid="header-left-content"
>Left Header Content</span
>
<span slot="header-right" data-tid="header-right-content"
>Right Header Content</span
>
</Modal>
Loading