-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Tom Hazledine <[email protected]> Co-authored-by: Josh Wooding <[email protected]>
- Loading branch information
1 parent
b4a7888
commit e7b0406
Showing
10 changed files
with
380 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
--- | ||
"@salt-ds/lab": minor | ||
--- | ||
|
||
Added `OverlayHeader` component to lab. | ||
|
||
```tsx | ||
<Overlay {...args}> | ||
<OverlayTrigger> | ||
<Button>Show Overlay</Button> | ||
</OverlayTrigger> | ||
<OverlayPanel aria-labelledby={id}> | ||
<OverlayHeader | ||
id={id} | ||
header="Title" | ||
actions={ | ||
<Button | ||
aria-label="Close overlay" | ||
appearance="transparent" | ||
sentiment="neutral" | ||
> | ||
<CloseIcon aria-hidden /> | ||
</Button> | ||
} | ||
/> | ||
<OverlayPanelContent>Content of Overlay</OverlayPanelContent> | ||
</OverlayPanel> | ||
</Overlay> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
.saltOverlayHeader { | ||
padding: var(--salt-spacing-100); | ||
width: 100%; | ||
align-items: center; | ||
display: flex; | ||
flex-direction: row; | ||
justify-content: stretch; | ||
gap: var(--salt-spacing-100); | ||
box-sizing: border-box; | ||
} | ||
|
||
.saltOverlayHeader-container { | ||
flex-grow: 1; | ||
margin: 0; | ||
display: flex; | ||
flex-direction: column; | ||
gap: var(--salt-spacing-50); | ||
} | ||
|
||
.saltOverlayHeader-header > .saltText { | ||
margin: 0; | ||
} | ||
|
||
.saltOverlayHeader-actionsContainer { | ||
align-self: flex-start; | ||
} | ||
|
||
/* Overrides */ | ||
.saltOverlayHeader ~ .saltOverlayPanelContent { | ||
padding-top: 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { Text, makePrefixer } 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 overlayHeaderCss from "./OverlayHeader.css"; | ||
|
||
const withBaseName = makePrefixer("saltOverlayHeader"); | ||
|
||
export interface OverlayHeaderProps extends ComponentPropsWithoutRef<"div"> { | ||
/** | ||
* Description text is displayed just below the header | ||
**/ | ||
description?: ReactNode; | ||
/** | ||
* Actions to be displayed in header | ||
*/ | ||
actions?: ReactNode; | ||
/** | ||
* Header text | ||
*/ | ||
header?: ReactNode; | ||
/** | ||
* Preheader text is displayed just above the header | ||
**/ | ||
preheader?: ReactNode; | ||
} | ||
|
||
export const OverlayHeader = forwardRef<HTMLDivElement, OverlayHeaderProps>( | ||
function OverlayHeader(props, ref) { | ||
const targetWindow = useWindow(); | ||
useComponentCssInjection({ | ||
testId: "salt-overlay-header", | ||
css: overlayHeaderCss, | ||
window: targetWindow, | ||
}); | ||
|
||
const { className, description, header, actions, preheader, ...rest } = | ||
props; | ||
|
||
return ( | ||
<div className={clsx(withBaseName(), className)} {...rest} ref={ref}> | ||
<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> | ||
); | ||
}, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./OverlayHeader"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { | ||
Button, | ||
H4, | ||
Overlay, | ||
OverlayPanel, | ||
OverlayPanelContent, | ||
OverlayTrigger, | ||
} from "@salt-ds/core"; | ||
import { CloseIcon } from "@salt-ds/icons"; | ||
import { OverlayHeader } from "@salt-ds/lab"; | ||
import type { Meta, StoryFn } from "@storybook/react"; | ||
import { QAContainer, type QAContainerProps } from "docs/components"; | ||
|
||
export default { | ||
title: "Lab/Overlay Header/Overlay Header QA", | ||
component: Overlay, | ||
} as Meta<typeof Overlay>; | ||
|
||
export const Default: StoryFn<QAContainerProps> = (props) => { | ||
const CloseButton = () => ( | ||
<Button | ||
aria-label="Close overlay" | ||
appearance="transparent" | ||
sentiment="neutral" | ||
> | ||
<CloseIcon aria-hidden /> | ||
</Button> | ||
); | ||
return ( | ||
<QAContainer | ||
height={800} | ||
cols={5} | ||
itemPadding={50} | ||
itemWidthAuto | ||
width={1200} | ||
{...props} | ||
> | ||
<Overlay open> | ||
<OverlayTrigger> | ||
<Button>Show Overlay</Button> | ||
</OverlayTrigger> | ||
<OverlayPanel> | ||
<OverlayHeader | ||
preheader="Preheader" | ||
description="Description" | ||
header={<H4>Header block</H4>} | ||
actions={<CloseButton />} | ||
/> | ||
<OverlayPanelContent> | ||
<div>Content of Overlay</div> | ||
</OverlayPanelContent> | ||
</OverlayPanel> | ||
</Overlay> | ||
</QAContainer> | ||
); | ||
}; | ||
|
||
Default.parameters = { | ||
chromatic: { | ||
disableSnapshot: false, | ||
modes: { | ||
theme: { | ||
themeNext: "disable", | ||
}, | ||
themeNext: { | ||
themeNext: "enable", | ||
corner: "rounded", | ||
accent: "teal", | ||
// Ignore headingFont given font is not loaded | ||
}, | ||
}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import { | ||
Button, | ||
H4, | ||
Overlay, | ||
OverlayPanel, | ||
OverlayPanelContent, | ||
type OverlayProps, | ||
OverlayTrigger, | ||
StackLayout, | ||
Text, | ||
Tooltip, | ||
useId, | ||
} from "@salt-ds/core"; | ||
import { CloseIcon } from "@salt-ds/icons"; | ||
import { OverlayHeader } from "@salt-ds/lab"; | ||
import type { Meta } from "@storybook/react"; | ||
import { useState } from "react"; | ||
|
||
export default { | ||
title: "Lab/Overlay Header", | ||
} as Meta<typeof Overlay>; | ||
|
||
export const Header = ({ onOpenChange }: OverlayProps) => { | ||
const [open, setOpen] = useState(false); | ||
const id = useId(); | ||
|
||
const onChange = (newOpen: boolean) => { | ||
setOpen(newOpen); | ||
onOpenChange?.(newOpen); | ||
}; | ||
|
||
return ( | ||
<Overlay open={open} onOpenChange={onChange}> | ||
<OverlayTrigger> | ||
<Button>Show Overlay</Button> | ||
</OverlayTrigger> | ||
<OverlayPanel | ||
aria-labelledby={id} | ||
style={{ | ||
width: 500, | ||
}} | ||
> | ||
<OverlayHeader header={<H4 id={id}>Header block</H4>} /> | ||
<OverlayPanelContent> | ||
<StackLayout gap={1}> | ||
<Text> | ||
Content of Overlay. Lorem Ipsum is simply dummy text of the | ||
printing and typesetting industry. Lorem Ipsum has been the | ||
industry's standard dummy text ever since the 1500s. When an | ||
unknown printer took a galley of type and scrambled it to make a | ||
type specimen book. | ||
</Text> | ||
<div> | ||
<Tooltip content={"I'm a tooltip"}> | ||
<Button>hover me</Button> | ||
</Tooltip> | ||
</div> | ||
</StackLayout> | ||
</OverlayPanelContent> | ||
</OverlayPanel> | ||
</Overlay> | ||
); | ||
}; | ||
|
||
export const HeaderWithCloseButton = ({ onOpenChange }: OverlayProps) => { | ||
const [open, setOpen] = useState(false); | ||
const id = useId(); | ||
|
||
const onChange = (newOpen: boolean) => { | ||
setOpen(newOpen); | ||
onOpenChange?.(newOpen); | ||
}; | ||
|
||
const handleClose = () => setOpen(false); | ||
|
||
const CloseButton = () => ( | ||
<Button | ||
aria-label="Close overlay" | ||
appearance="transparent" | ||
sentiment="neutral" | ||
onClick={handleClose} | ||
> | ||
<CloseIcon aria-hidden /> | ||
</Button> | ||
); | ||
|
||
return ( | ||
<Overlay open={open} onOpenChange={onChange}> | ||
<OverlayTrigger> | ||
<Button>Show Overlay</Button> | ||
</OverlayTrigger> | ||
<OverlayPanel | ||
aria-labelledby={id} | ||
style={{ | ||
width: 500, | ||
}} | ||
> | ||
<OverlayHeader | ||
preheader="Preheader" | ||
description="Description" | ||
header={<H4 id={id}>Header block</H4>} | ||
actions={<CloseButton />} | ||
/> | ||
<OverlayPanelContent> | ||
<StackLayout gap={1}> | ||
<Text> | ||
Content of Overlay. Lorem Ipsum is simply dummy text of the | ||
printing and typesetting industry. Lorem Ipsum has been the | ||
industry's standard dummy text ever since the 1500s. When an | ||
unknown printer took a galley of type and scrambled it to make a | ||
type specimen book. | ||
</Text> | ||
<div> | ||
<Tooltip content={"I'm a tooltip"}> | ||
<Button>hover me</Button> | ||
</Tooltip> | ||
</div> | ||
</StackLayout> | ||
</OverlayPanelContent> | ||
</OverlayPanel> | ||
</Overlay> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { | ||
Button, | ||
Overlay, | ||
OverlayPanel, | ||
OverlayPanelContent, | ||
OverlayTrigger, | ||
useId, | ||
} from "@salt-ds/core"; | ||
import { CloseIcon } from "@salt-ds/icons"; | ||
import { OverlayHeader } from "@salt-ds/lab"; | ||
import { type ReactElement, useState } from "react"; | ||
|
||
export const WithHeader = (): ReactElement => { | ||
const [open, setOpen] = useState(false); | ||
const id = useId(); | ||
|
||
const onOpenChange = (newOpen: boolean) => setOpen(newOpen); | ||
|
||
const handleClose = () => setOpen(false); | ||
|
||
const headerActions = ( | ||
<Button | ||
aria-label="Close overlay" | ||
appearance="transparent" | ||
onClick={handleClose} | ||
> | ||
<CloseIcon aria-hidden /> | ||
</Button> | ||
); | ||
return ( | ||
<Overlay placement="right" open={open} onOpenChange={onOpenChange}> | ||
<OverlayTrigger> | ||
<Button>Show Overlay</Button> | ||
</OverlayTrigger> | ||
<OverlayPanel aria-labelledby={id}> | ||
<OverlayHeader | ||
header={<h4 id={id}>Title</h4>} | ||
actions={headerActions} | ||
/> | ||
<OverlayPanelContent> | ||
<div>Content of Overlay</div> | ||
</OverlayPanelContent> | ||
</OverlayPanel> | ||
</Overlay> | ||
); | ||
}; |
Oops, something went wrong.