Skip to content

Commit

Permalink
Add DialogHeader to lab (#4298)
Browse files Browse the repository at this point in the history
  • Loading branch information
Fercas123 authored Nov 8, 2024
1 parent ae6e5c9 commit 91973ac
Show file tree
Hide file tree
Showing 10 changed files with 581 additions and 0 deletions.
28 changes: 28 additions & 0 deletions .changeset/plenty-monkeys-give.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
"@salt-ds/lab": minor
---

Added `DialogHeader` component to lab. `DialogHeader`'s update follows our standardized header for container components and app regions, and it can be added to provide a structured header for dialog. The header includes a title and actions that follows our Header Block pattern.

```typescript
<Dialog open={open} onOpenChange={onOpenChange} id={id}>
<DialogHeader
header={<H2>Terms and conditions</H2>}
actions={
<Button
aria-label="Close overlay"
appearance="transparent"
sentiment="neutral"
>
<CloseIcon aria-hidden />
</Button>
}
/>
<DialogContent>
<div>
Only Chase Cards that we determine are eligible can be added to the
Wallet.
</div>
</DialogContent>
</Dialog>;
```
47 changes: 47 additions & 0 deletions packages/lab/src/dialog/DialogHeader.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* Styles applied to the root element */
.saltDialogHeader {
padding-bottom: var(--salt-spacing-300);
padding-left: var(--salt-spacing-300);
padding-right: var(--salt-spacing-300);
align-items: center;
display: flex;
flex-direction: row;
gap: var(--salt-spacing-100);
box-sizing: border-box;
}

.saltDialogHeader-container {
flex-grow: 1;
margin: 0;
display: flex;
flex-direction: column;
gap: var(--salt-spacing-50);
}

.saltDialogHeader-header > .saltText {
margin: 0;
}

.saltDialogHeader-actionsContainer {
align-self: flex-start;
}

/* Styles applied to the status indicator icon overriding its default size */
.saltDialogHeader .saltStatusIndicator.saltIcon {
--icon-size: var(--salt-text-h2-lineHeight);
}

/* Styles applied to DialogHeader when accent={true} */
.saltDialogHeader-withAccent {
position: relative;
}

.saltDialogHeader-withAccent::before {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: var(--salt-spacing-300);
width: var(--salt-size-bar);
background: var(--salt-accent-background);
}
103 changes: 103 additions & 0 deletions packages/lab/src/dialog/DialogHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import {
StatusIndicator,
Text,
type ValidationStatus,
makePrefixer,
useDialogContext,
} from "@salt-ds/core";
import { useComponentCssInjection } from "@salt-ds/styles";
import { useWindow } from "@salt-ds/window";
import { clsx } from "clsx";
import {
type ComponentPropsWithoutRef,
type ReactNode,
forwardRef,
} from "react";
import dialogHeaderCss from "./DialogHeader.css";

const withBaseName = makePrefixer("saltDialogHeader");

export interface DialogHeaderProps extends ComponentPropsWithoutRef<"div"> {
/**
* The status of the Dialog
*/
status?: ValidationStatus | undefined;
/**
* Displays the accent bar in the Dialog Title */
disableAccent?: boolean;
/**
* Displays the header at the top of the Dialog
*/
header: ReactNode;
/**
* Displays the preheader just above the header
**/
preheader?: ReactNode;
/**
* Description text is displayed just below the header
**/
description?: ReactNode;
/**
* Actions to be displayed in header
*/
actions?: ReactNode;
}

export const DialogHeader = forwardRef<HTMLDivElement, DialogHeaderProps>(
function DialogHeader(props, ref) {
const {
className,
description,
disableAccent,
actions,
header,
preheader,
status: statusProp,
...rest
} = props;
const { status: statusContext, id } = useDialogContext();

const targetWindow = useWindow();
useComponentCssInjection({
testId: "salt-dialog-header",
css: dialogHeaderCss,
window: targetWindow,
});

const status = statusProp ?? statusContext;

return (
<div
id={id}
className={clsx(
withBaseName(),
{
[withBaseName("withAccent")]: !disableAccent && !status,
[withBaseName(status ?? "")]: !!status,
},
className,
)}
ref={ref}
{...rest}
>
{status && <StatusIndicator status={status} />}
<div className={withBaseName("container")}>
<div className={withBaseName("header")}>
{preheader && (
<Text className={withBaseName("preheader")}>{preheader}</Text>
)}
{header}
</div>
{description && (
<Text color="secondary" className={withBaseName("description")}>
{description}
</Text>
)}
</div>
{actions && (
<div className={withBaseName("actionsContainer")}>{actions}</div>
)}
</div>
);
},
);
1 change: 1 addition & 0 deletions packages/lab/src/dialog/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./DialogHeader";
1 change: 1 addition & 0 deletions packages/lab/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export * from "./date-input";
export * from "./date-picker";
export * from "./deck-item";
export * from "./deck-layout";
export * from "./dialog";
export * from "./dropdown";
export * from "./editable-label";
export {
Expand Down
75 changes: 75 additions & 0 deletions packages/lab/stories/dialog/dialog.qa.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { Dialog, H2 } from "@salt-ds/core";
import { DialogHeader } from "@salt-ds/lab";
import type { Meta, StoryFn } from "@storybook/react";
import { QAContainer, type QAContainerProps } from "docs/components";

export default {
title: "Lab /Dialog Header/Dialog Header QA",
component: Dialog,
} as Meta<typeof Dialog>;

export const DialogHeaders: StoryFn<QAContainerProps> = () => (
<QAContainer height={600} cols={1} itemPadding={5} width={1200}>
<DialogHeader
header={<H2>Terms and conditions</H2>}
style={{
width: 600,
}}
/>
<DialogHeader
style={{
width: 600,
}}
header={<H2>Terms and conditions</H2>}
preheader="Ensure you read and agree to these Terms"
/>
<DialogHeader
style={{
width: 600,
}}
header={<H2>Terms and conditions</H2>}
preheader="Ensure you read and agree to these Terms"
description="Effective date: August 29, 2024"
/>
<DialogHeader
status="info"
header={<H2>Terms and conditions</H2>}
style={{
width: 600,
}}
/>
<DialogHeader
status="info"
style={{
width: 600,
}}
header={<H2>Terms and conditions</H2>}
preheader="Ensure you read and agree to these Terms"
/>
<DialogHeader
status="info"
style={{
width: 600,
}}
header={<H2>Terms and conditions</H2>}
preheader="Ensure you read and agree to these Terms"
description="Effective date: August 29, 2024"
/>
</QAContainer>
);
DialogHeaders.parameters = {
chromatic: {
disableSnapshot: false,
modes: {
theme: {
themeNext: "disable",
},
themeNext: {
themeNext: "enable",
corner: "rounded",
accent: "teal",
// Ignore headingFont given font is not loaded
},
},
},
};
Loading

0 comments on commit 91973ac

Please sign in to comment.