in src/stories/ActionList2/fixtures.stories.tsx [170:578]
export function WithDescription(): JSX.Element {
return (
<>
<h1>With Description & Dividers</h1>
<ErsatzOverlay>
<ActionList showDividers>
{users.map(user => (
<ActionList.Item key={user.login}>
<ActionList.LeadingVisual>
<Avatar src={`https://github.com/${user.login}.png`} />
</ActionList.LeadingVisual>
{user.login}
<ActionList.Description>{user.name}</ActionList.Description>
</ActionList.Item>
))}
<ActionList.Divider />
{labels.map((label, index) => (
<ActionList.Item key={index}>
<ActionList.LeadingVisual>
<LabelColor color={label.color} />
</ActionList.LeadingVisual>
{label.name}
<ActionList.Description variant="block">{label.description}</ActionList.Description>
</ActionList.Item>
))}
</ActionList>
</ErsatzOverlay>
</>
)
}
WithDescription.storyName = 'With Description & Dividers'
const projects = [
{name: 'Primer Backlog', scope: 'GitHub'},
{name: 'Accessibility', scope: 'GitHub'},
{name: 'Octicons', scope: 'github/primer'},
{name: 'Primer React', scope: 'github/primer'}
]
export function DisabledStory(): JSX.Element {
const [selectedIndex, setSelectedIndex] = React.useState(0)
return (
<>
<h1>Disabled Items</h1>
<ErsatzOverlay>
<ActionList selectionVariant="single" showDividers role="listbox" aria-label="Select a project">
{projects.map((project, index) => (
<ActionList.Item
key={index}
role="option"
selected={index === selectedIndex}
onSelect={() => setSelectedIndex(index)}
disabled={index === 1}
>
<ActionList.LeadingVisual>
<TableIcon />
</ActionList.LeadingVisual>
{project.name}
<ActionList.Description variant="block">{project.scope}</ActionList.Description>
</ActionList.Item>
))}
</ActionList>
</ErsatzOverlay>
</>
)
}
DisabledStory.storyName = 'Disabled Items'
export function GroupsStory(): JSX.Element {
const [assignees, setAssignees] = React.useState(users.slice(0, 1))
const toggleAssignee = (assignee: typeof users[number]) => {
const assigneeIndex = assignees.findIndex(a => a.login === assignee.login)
if (assigneeIndex === -1) setAssignees([...assignees, assignee])
else setAssignees(assignees.filter((_, index) => index !== assigneeIndex))
}
return (
<>
<h1>Groups</h1>
<ErsatzOverlay>
<ActionList selectionVariant="multiple" showDividers aria-label="Select reviewers">
<ActionList.Group title="Suggestions" variant="filled" role="listbox">
{users.slice(0, 2).map(user => (
<ActionList.Item
key={user.login}
role="option"
selected={Boolean(assignees.find(assignee => assignee.login === user.login))}
onSelect={() => toggleAssignee(user)}
>
<ActionList.LeadingVisual>
<Avatar src={`https://github.com/${user.login}.png`} />
</ActionList.LeadingVisual>
{user.login}
<ActionList.Description>{user.name}</ActionList.Description>
<ActionList.Description variant="block">Recently edited these files</ActionList.Description>
</ActionList.Item>
))}
</ActionList.Group>
<ActionList.Group title="Everyone" variant="filled" role="listbox">
{users.slice(2).map(user => (
<ActionList.Item
role="option"
key={user.login}
selected={Boolean(assignees.find(assignee => assignee.login === user.login))}
onSelect={() => toggleAssignee(user)}
>
<ActionList.LeadingVisual>
<Avatar src={`https://github.com/${user.login}.png`} />
</ActionList.LeadingVisual>
{user.login}
<ActionList.Description>{user.name}</ActionList.Description>
</ActionList.Item>
))}
</ActionList.Group>
</ActionList>
</ErsatzOverlay>
</>
)
}
GroupsStory.storyName = 'Groups'
export function ActionsStory(): JSX.Element {
return (
<>
<h1>Actions</h1>
<ErsatzOverlay>
<ActionList showDividers>
<ActionList.Item>
<ActionList.LeadingVisual>
<ServerIcon />
</ActionList.LeadingVisual>
Open current Codespace
<ActionList.Description variant="block">
Your existing Codespace will be opened to its previous state, and you'll be asked to manually switch
to new-branch.
</ActionList.Description>
</ActionList.Item>
<ActionList.Item>
<ActionList.LeadingVisual>
<PlusCircleIcon />
</ActionList.LeadingVisual>
Create new Codespace
<ActionList.Description variant="block">
Create a brand new Codespace with a fresh image and checkout this branch.
</ActionList.Description>
</ActionList.Item>
</ActionList>
</ErsatzOverlay>
</>
)
}
ActionsStory.storyName = 'Actions'
export function ComplexListInsetVariantStory(): JSX.Element {
return (
<>
<h1>Complex List</h1>
<h2>Inset Variant</h2>
<ErsatzOverlay>
<ActionList showDividers>
<ActionList.Item>
<ActionList.LeadingVisual>
<TypographyIcon />
</ActionList.LeadingVisual>
Rename
</ActionList.Item>
<ActionList.Item>
<ActionList.LeadingVisual>
<VersionsIcon />
</ActionList.LeadingVisual>
Duplicate
<ActionList.Description>Create a copy</ActionList.Description>
</ActionList.Item>
<ActionList.Group title="Live query" variant="filled">
<ActionList.Item style={{color: 'rebeccapurple'}}>
<ActionList.LeadingVisual>
<SearchIcon />
</ActionList.LeadingVisual>
repo:github/memex,github/github
</ActionList.Item>
</ActionList.Group>
<ActionList.Divider />
<ActionList.Group title="Layout" variant="subtle">
<ActionList.Item>
<ActionList.LeadingVisual>
<NoteIcon />
</ActionList.LeadingVisual>
Table
<ActionList.Description variant="block">
Information-dense table optimized for operations across teams
</ActionList.Description>
</ActionList.Item>
<ActionList.Item role="listitem">
<ActionList.LeadingVisual>
<ProjectIcon />
</ActionList.LeadingVisual>
Board
<ActionList.Description variant="block">
Kanban-style board focused on visual states
</ActionList.Description>
</ActionList.Item>
</ActionList.Group>
<ActionList.Divider />
<ActionList.Group>
<ActionList.Item style={{fontWeight: 'bold'}}>
<ActionList.LeadingVisual>
<FilterIcon />
</ActionList.LeadingVisual>
Save sort and filters to current view
</ActionList.Item>
<ActionList.Item style={{fontWeight: 'bold'}}>
<ActionList.LeadingVisual>
<FilterIcon />
</ActionList.LeadingVisual>
Save sort and filters to new view
</ActionList.Item>
</ActionList.Group>
<ActionList.Divider />
<ActionList.Group sx={{backgroundColor: 'accent.emphasis'}}>
<ActionList.Item sx={{color: 'white'}}>
<ActionList.LeadingVisual sx={{color: 'white'}}>
<GearIcon />
</ActionList.LeadingVisual>
View settings
</ActionList.Item>
</ActionList.Group>
</ActionList>
</ErsatzOverlay>
</>
)
}
ComplexListInsetVariantStory.storyName = 'Complex List — Inset Variant'
export function ComplexListFullVariantStory(): JSX.Element {
return (
<>
<h1>Complex List</h1>
<h2>Full Variant</h2>
<ErsatzOverlay>
<ActionList variant="full">
<ActionList.Item>
<ActionList.LeadingVisual>
<TypographyIcon />
</ActionList.LeadingVisual>
Rename
</ActionList.Item>
<ActionList.Item>
<ActionList.LeadingVisual>
<VersionsIcon />
</ActionList.LeadingVisual>
Duplicate
<ActionList.Description>Create a copy</ActionList.Description>
</ActionList.Item>
<ActionList.Group title="Live query" variant="filled">
<ActionList.Item style={{color: 'rebeccapurple'}}>
<ActionList.LeadingVisual>
<SearchIcon />
</ActionList.LeadingVisual>
repo:github/memex,github/github
</ActionList.Item>
</ActionList.Group>
<ActionList.Divider />
<ActionList.Group title="Layout" variant="subtle">
<ActionList.Item>
<ActionList.LeadingVisual>
<NoteIcon />
</ActionList.LeadingVisual>
Table
<ActionList.Description variant="block">
Information-dense table optimized for operations across teams
</ActionList.Description>
</ActionList.Item>
<ActionList.Item>
<ActionList.LeadingVisual>
<ProjectIcon />
</ActionList.LeadingVisual>
Board
<ActionList.Description variant="block">
Kanban-style board focused on visual states
</ActionList.Description>
</ActionList.Item>
</ActionList.Group>
<ActionList.Divider />
<ActionList.Group>
<ActionList.Item style={{fontWeight: 'bold'}}>
<ActionList.LeadingVisual>
<FilterIcon />
</ActionList.LeadingVisual>
Save sort and filters to current view
</ActionList.Item>
<ActionList.Item style={{fontWeight: 'bold'}}>
<ActionList.LeadingVisual>
<FilterIcon />
</ActionList.LeadingVisual>
Save sort and filters to new view
</ActionList.Item>
</ActionList.Group>
<ActionList.Divider />
<ActionList.Group sx={{backgroundColor: 'accent.emphasis'}}>
<ActionList.Item sx={{color: 'white'}}>
<ActionList.LeadingVisual sx={{color: 'white'}}>
<GearIcon />
</ActionList.LeadingVisual>
View settings
</ActionList.Item>
</ActionList.Group>
</ActionList>
</ErsatzOverlay>
</>
)
}
ComplexListFullVariantStory.storyName = 'Complex List — Full Variant'
type ReactRouterLikeLinkProps = {to: string; children: React.ReactNode}
const ReactRouterLikeLink = forwardRef<HTMLAnchorElement, ReactRouterLikeLinkProps>(
({to, ...props}: {to: string; children: React.ReactNode}, ref) => {
// eslint-disable-next-line jsx-a11y/anchor-has-content
return <a ref={ref} href={to} {...props} />
}
)
const NextJSLikeLink = forwardRef(
({href, children}: {href: string; children: React.ReactNode}, ref): React.ReactElement => {
const child = React.Children.only(children)
const childProps = {
ref,
href
}
return <>{React.isValidElement(child) ? React.cloneElement(child, childProps) : null}</>
}
)
export function LinkItemStory(): JSX.Element {
return (
<>
<h1>List with LinkItem</h1>
<ErsatzOverlay>
<ActionList showDividers>
<ActionList.Item>
<ActionList.LeadingVisual>
<XIcon />
</ActionList.LeadingVisual>
not a link, just an Item for comparison
</ActionList.Item>
<ActionList.LinkItem href="https://github.com/primer">
<ActionList.LeadingVisual>
<LinkIcon />
</ActionList.LeadingVisual>
ActionList.LinkItem
</ActionList.LinkItem>
<ActionList.LinkItem href="https://github.com/primer" target="_blank" rel="noopener noreferrer">
<ActionList.LeadingVisual>
<LinkIcon />
</ActionList.LeadingVisual>
ActionList.LinkItem with anchor attributes
</ActionList.LinkItem>
<ActionList.LinkItem
as={ReactRouterLikeLink}
to="?path=/story/composite-components-actionlist2--simple-list-story"
>
<ActionList.LeadingVisual>
<LinkIcon />
</ActionList.LeadingVisual>
as ReactRouterLink
</ActionList.LinkItem>
<NextJSLikeLink href="?path=/story/composite-components-actionlist2--simple-list-story">
<ActionList.LinkItem>
<ActionList.LeadingVisual>
<LinkIcon />
</ActionList.LeadingVisual>
NextJS style Link
</ActionList.LinkItem>
</NextJSLikeLink>
<ActionList.LinkItem href="?path=/story/composite-components-actionlist2--simple-list-story">
<ActionList.LeadingVisual>
<LinkIcon />
</ActionList.LeadingVisual>
ActionList.LinkItem with everything
<ActionList.Description variant="inline">inline description</ActionList.Description>
<ActionList.Description variant="block">Block description</ActionList.Description>
<ActionList.TrailingVisual>⌘ + L</ActionList.TrailingVisual>
</ActionList.LinkItem>
</ActionList>
</ErsatzOverlay>
</>
)
}
LinkItemStory.storyName = 'List with LinkItem'
export function DOMPropsStory(): JSX.Element {
return (
<>
<h1>Simple List</h1>
<ErsatzOverlay>
<ActionList>
{/* eslint-disable-next-line @typescript-eslint/no-explicit-any */}
<ActionList.Item id="something" onClick={(event: any) => alert(`Id is '${event.target.id}'`)}>
Has an id
</ActionList.Item>
</ActionList>
</ErsatzOverlay>
</>
)
}