@primer/react
Version:
An implementation of GitHub's Primer Design System using React
621 lines • 645 kB
JSON
{
"schemaVersion": 2,
"components": {
"actionbar": {
"source": "https://github.com/primer/react/tree/main/packages/react/src/ActionBar",
"id": "actionbar",
"name": "ActionBar",
"status": "alpha",
"a11yReviewed": true,
"stories": [
{
"id": "experimental-components-actionbar--default",
"code": "() => (\n <ActionBar aria-label=\"Toolbar\">\n <ActionBar.IconButton\n icon={BoldIcon}\n aria-label=\"Bold\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={ItalicIcon}\n aria-label=\"Italic\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={CodeIcon}\n aria-label=\"Code\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={LinkIcon}\n aria-label=\"Link\"\n ></ActionBar.IconButton>\n <ActionBar.Divider />\n <ActionBar.IconButton\n icon={FileAddedIcon}\n aria-label=\"File Added\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={SearchIcon}\n aria-label=\"Search\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={QuoteIcon}\n aria-label=\"Insert Quote\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={ListUnorderedIcon}\n aria-label=\"Unordered List\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={ListOrderedIcon}\n aria-label=\"Ordered List\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={TasklistIcon}\n aria-label=\"Task List\"\n ></ActionBar.IconButton>\n </ActionBar>\n)"
}
],
"importPath": "@primer/react",
"props": [
{
"name": "aria-label",
"type": "string",
"required": false,
"description": "When provided, a label is added to the action bar",
"defaultValue": ""
},
{
"name": "aria-labelledby",
"type": "string",
"required": false,
"description": "When provided, uses the element with that ID as the accessible name for the ActionBar",
"defaultValue": ""
},
{
"name": "children",
"type": "ReactNode",
"required": false,
"description": "Buttons in the action bar",
"defaultValue": ""
},
{
"name": "size",
"type": "'small' | 'large' | 'medium'",
"required": false,
"description": "Size of the action bar",
"defaultValue": ""
},
{
"name": "flush",
"type": "boolean",
"required": false,
"description": "Allows ActionBar to be flush with the container",
"defaultValue": "false"
},
{
"name": "className",
"type": "string",
"required": false,
"description": "Custom className",
"defaultValue": ""
}
],
"subcomponents": [
{
"name": "ActionBar.IconButton",
"props": [
{
"name": "children",
"type": "React.ReactNode",
"defaultValue": "",
"required": true,
"description": "This will be the Button description."
},
{
"name": "icon",
"type": "Component",
"defaultValue": "",
"description": "Provide an octicon. It will be placed in the center of the button"
},
{
"name": "aria-label",
"type": "string",
"defaultValue": "",
"description": "Use an aria label to describe the functionality of the button. Please refer to [our guidance on alt text](https://primer.style/guides/accessibility/alternative-text-for-images) for tips on writing good alternative text."
}
],
"passthrough": {
"element": "IconButton",
"url": "/react/IconButton"
}
},
{
"name": "ActionBar.Divider",
"props": []
}
]
},
"action_list": {
"source": "https://github.com/primer/react/tree/main/packages/react/src/ActionList",
"id": "action_list",
"name": "ActionList",
"status": "beta",
"a11yReviewed": false,
"stories": [
{
"id": "components-actionlist--default",
"code": "() => (\n <ActionList>\n <ActionList.Item>Copy link</ActionList.Item>\n <ActionList.Item>Quote reply</ActionList.Item>\n <ActionList.Item>Edit comment</ActionList.Item>\n </ActionList>\n)"
},
{
"id": "components-actionlist-features--simple-list",
"code": "() => (\n <ActionList>\n <ActionList.Item>Copy link</ActionList.Item>\n <ActionList.Item>Quote reply</ActionList.Item>\n <ActionList.Item>Edit comment</ActionList.Item>\n <ActionList.Divider />\n <ActionList.Item variant=\"danger\">Delete file</ActionList.Item>\n </ActionList>\n)"
},
{
"id": "components-actionlist-features--with-visual-list-heading",
"code": "() => (\n <ActionList>\n <ActionList.Heading as=\"h2\" size=\"small\">\n Filter by\n </ActionList.Heading>\n <ActionList.Group>\n <ActionList.GroupHeading as=\"h3\">Repositories</ActionList.GroupHeading>\n <ActionList.Item onClick={() => {}}>\n <ActionList.LeadingVisual>\n <FileDirectoryIcon />\n </ActionList.LeadingVisual>\n app/assets/modules\n </ActionList.Item>\n <ActionList.Item onClick={() => {}}>\n <ActionList.LeadingVisual>\n <FileDirectoryIcon />\n </ActionList.LeadingVisual>\n src/react/components\n </ActionList.Item>\n <ActionList.Item onClick={() => {}}>\n <ActionList.LeadingVisual>\n <FileDirectoryIcon />\n </ActionList.LeadingVisual>\n memex/shared-ui/components\n </ActionList.Item>\n <ActionList.Item onClick={() => {}}>\n <ActionList.LeadingVisual>\n <FileDirectoryIcon />\n </ActionList.LeadingVisual>\n views/assets/modules\n </ActionList.Item>\n </ActionList.Group>\n\n <ActionList.Group>\n <ActionList.GroupHeading as=\"h3\">Advanced</ActionList.GroupHeading>\n <ActionList.Item onClick={() => {}}>\n <ActionList.LeadingVisual>\n <PlusCircleIcon />\n </ActionList.LeadingVisual>\n Owner\n </ActionList.Item>\n <ActionList.Item onClick={() => {}}>\n <ActionList.LeadingVisual>\n <PlusCircleIcon />\n </ActionList.LeadingVisual>\n Symbol\n </ActionList.Item>\n <ActionList.Item onClick={() => {}}>\n <ActionList.LeadingVisual>\n <PlusCircleIcon />\n </ActionList.LeadingVisual>\n Exclude archived\n </ActionList.Item>\n </ActionList.Group>\n </ActionList>\n)"
},
{
"id": "components-actionlist-features--with-custom-heading",
"code": "() => (\n <>\n <Heading\n as=\"h1\"\n id=\"list-heading\"\n sx={{\n fontSize: 3,\n marginX: 3,\n }}\n >\n Details\n </Heading>\n <ActionList aria-labelledby=\"list-heading\">\n <ActionList.LinkItem href=\"https://github.com/primer/react#readme\">\n <ActionList.LeadingVisual>\n <BookIcon />\n </ActionList.LeadingVisual>\n Readme\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"https://github.com/primer/react/blob/main/LICENSE\">\n <ActionList.LeadingVisual>\n <LawIcon />\n </ActionList.LeadingVisual>\n MIT License\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"https://github.com/primer/react/stargazers\">\n <ActionList.LeadingVisual>\n <StarIcon />\n </ActionList.LeadingVisual>\n <strong>1.5k</strong> stars\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"https://github.com/primer/react/watchers\">\n <ActionList.LeadingVisual>\n <EyeIcon />\n </ActionList.LeadingVisual>\n <strong>21</strong> watching\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"https://github.com/primer/react/network/members\">\n <ActionList.LeadingVisual>\n <RepoForkedIcon />\n </ActionList.LeadingVisual>\n <strong>225</strong> forks\n </ActionList.LinkItem>\n </ActionList>\n </>\n)"
},
{
"id": "components-actionlist-features--with-icons",
"code": "() => (\n <ActionList>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <LinkIcon />\n </ActionList.LeadingVisual>\n github.com/primer\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <LawIcon />\n </ActionList.LeadingVisual>\n MIT License\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <StarIcon />\n </ActionList.LeadingVisual>\n 256 stars\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <RepoForkedIcon />\n </ActionList.LeadingVisual>\n 3 forks\n </ActionList.Item>\n <ActionList.Item variant=\"danger\">\n <ActionList.LeadingVisual>\n <AlertIcon />\n </ActionList.LeadingVisual>\n 4 vulnerabilities\n </ActionList.Item>\n </ActionList>\n)"
},
{
"id": "components-actionlist-features--with-avatars",
"code": "() => (\n <ActionList>\n {users.map((user) => (\n <ActionList.Item key={user.login}>\n <ActionList.LeadingVisual>\n <Avatar src={`https://github.com/${user.login}.png`} />\n </ActionList.LeadingVisual>\n {user.login}\n </ActionList.Item>\n ))}\n </ActionList>\n)"
},
{
"id": "components-actionlist-features--item-dividers",
"code": "() => (\n <ActionList showDividers>\n <ActionList.Item>Copy link</ActionList.Item>\n <ActionList.Item>Quote reply</ActionList.Item>\n <ActionList.Item>Edit comment</ActionList.Item>\n </ActionList>\n)"
},
{
"id": "components-actionlist-features--single-divider",
"code": "() => (\n <ActionList>\n <ActionList.Item>Copy link</ActionList.Item>\n <ActionList.Item>Quote reply</ActionList.Item>\n <ActionList.Item>Edit comment</ActionList.Item>\n <ActionList.Divider />\n <ActionList.Item variant=\"danger\">Delete file</ActionList.Item>\n </ActionList>\n)"
},
{
"id": "components-actionlist-features--inline-description",
"code": "() => (\n <ActionList>\n {users.map((user) => (\n <ActionList.Item key={user.login}>\n <ActionList.LeadingVisual>\n <Avatar src={`https://github.com/${user.login}.png`} />\n </ActionList.LeadingVisual>\n {user.login}\n <ActionList.Description>{user.name}</ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n)"
},
{
"id": "components-actionlist-features--block-description",
"code": "() => (\n <ActionList>\n {users.map((user) => (\n <ActionList.Item key={user.login}>\n <ActionList.LeadingVisual>\n <Avatar src={`https://github.com/${user.login}.png`} />\n </ActionList.LeadingVisual>\n {user.login}\n <ActionList.Description variant=\"block\">\n {user.name}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n)"
},
{
"id": "components-actionlist-features--single-select",
"code": "() => {\n const [selectedIndex, setSelectedIndex] = React.useState(0)\n return (\n <ActionList\n selectionVariant=\"single\"\n showDividers\n role=\"menu\"\n aria-label=\"Project\"\n >\n {projects.map((project, index) => (\n <ActionList.Item\n key={index}\n role=\"menuitemradio\"\n selected={index === selectedIndex}\n aria-checked={index === selectedIndex}\n onSelect={() => setSelectedIndex(index)}\n >\n <ActionList.LeadingVisual>\n <TableIcon />\n </ActionList.LeadingVisual>\n {project.name}\n <ActionList.Description variant=\"block\">\n {project.scope}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n )\n}"
},
{
"id": "components-actionlist-features--inactive-single-select",
"code": "() => {\n const [selectedIndex, setSelectedIndex] = React.useState(1)\n return (\n <ActionList\n selectionVariant=\"single\"\n showDividers\n role=\"menu\"\n aria-label=\"Project\"\n >\n {/* menuitem because state is inactive */}\n <ActionList.Item\n role=\"menuitem\"\n selected={false}\n inactiveText=\"Unavailable due to an outage\"\n >\n Inactive item\n </ActionList.Item>\n <ActionList.Item\n role=\"menuitemradio\"\n selected={selectedIndex === 1}\n aria-checked={selectedIndex === 1}\n onSelect={() => setSelectedIndex(1)}\n >\n Item 2\n </ActionList.Item>\n </ActionList>\n )\n}"
},
{
"id": "components-actionlist-features--multi-select",
"code": "() => {\n const [selectedIndices, setSelectedIndices] = React.useState<number[]>([0])\n const handleSelect = (index: number) => {\n if (selectedIndices.includes(index)) {\n setSelectedIndices(selectedIndices.filter((i) => i !== index))\n } else {\n setSelectedIndices([...selectedIndices, index])\n }\n }\n return (\n <ActionList\n selectionVariant=\"multiple\"\n showDividers\n role=\"menu\"\n aria-label=\"Project\"\n >\n {projects.map((project, index) => (\n <ActionList.Item\n key={index}\n role=\"menuitemcheckbox\"\n selected={selectedIndices.includes(index)}\n aria-checked={selectedIndices.includes(index)}\n onSelect={() => handleSelect(index)}\n disabled={index === 3 ? true : undefined}\n >\n <ActionList.LeadingVisual>\n <TableIcon />\n </ActionList.LeadingVisual>\n {project.name}\n <ActionList.Description variant=\"block\">\n {project.scope}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n )\n}"
},
{
"id": "components-actionlist-features--list-box-multi-select",
"code": "() => {\n const [selectedIndices, setSelectedIndices] = React.useState<number[]>([0])\n const handleSelect = (index: number) => {\n if (selectedIndices.includes(index)) {\n setSelectedIndices(selectedIndices.filter((i) => i !== index))\n } else {\n setSelectedIndices([...selectedIndices, index])\n }\n }\n return (\n <ActionList role=\"menu\" selectionVariant=\"multiple\" aria-label=\"Project\">\n {projects.map((project, index) => (\n <ActionList.Item\n key={index}\n role=\"menuitemcheckbox\"\n selected={selectedIndices.includes(index)}\n aria-checked={selectedIndices.includes(index)}\n onSelect={() => handleSelect(index)}\n disabled={index === 3 ? true : undefined}\n >\n <ActionList.LeadingVisual>\n <TableIcon />\n </ActionList.LeadingVisual>\n {project.name}\n <ActionList.Description variant=\"block\">\n {project.scope}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n )\n}"
},
{
"id": "components-actionlist-features--with-dynamic-content",
"code": "() => {\n const [isTrue, setIsTrue] = React.useState(false)\n return (\n <FeatureFlags\n flags={{\n primer_react_action_list_item_as_button: true,\n }}\n >\n <ActionList>\n <ActionList.Item\n onSelect={() => {\n setIsTrue(!isTrue)\n }}\n >\n Activated? {isTrue ? 'Yes' : 'No'}\n </ActionList.Item>\n </ActionList>\n </FeatureFlags>\n )\n}"
},
{
"id": "components-actionlist-features--disabled-selected-multiselect",
"code": "() => (\n <ActionList selectionVariant=\"multiple\" role=\"menu\" aria-label=\"Project\">\n <ActionList.Item role=\"menuitemcheckbox\" selected aria-checked disabled>\n Selected disabled item\n </ActionList.Item>\n <ActionList.Item\n role=\"menuitemcheckbox\"\n selected={false}\n aria-checked={false}\n >\n Item 2\n </ActionList.Item>\n </ActionList>\n)"
},
{
"id": "components-actionlist-features--disabled-multiselect",
"code": "() => (\n <ActionList selectionVariant=\"multiple\" role=\"menu\" aria-label=\"Project\">\n <ActionList.Item\n role=\"menuitemcheckbox\"\n selected={false}\n aria-checked={false}\n disabled\n >\n Disabled item\n </ActionList.Item>\n <ActionList.Item\n role=\"menuitemcheckbox\"\n selected={false}\n aria-checked={false}\n >\n Item 2\n </ActionList.Item>\n </ActionList>\n)"
},
{
"id": "components-actionlist-features--inactive-multiselect",
"code": "() => {\n const [selectedIndices, setSelectedIndices] = React.useState<number[]>([0])\n const handleSelect = (index: number) => {\n if (selectedIndices.includes(index)) {\n setSelectedIndices(selectedIndices.filter((i) => i !== index))\n } else {\n setSelectedIndices([...selectedIndices, index])\n }\n }\n return (\n <ActionList selectionVariant=\"multiple\" role=\"menu\" aria-label=\"Project\">\n {/* menuitem because state is inactive */}\n <ActionList.Item\n role=\"menuitem\"\n selected={false}\n inactiveText=\"Unavailable due to an outage\"\n >\n Inactive item\n </ActionList.Item>\n <ActionList.Item\n role=\"menuitemcheckbox\"\n selected={selectedIndices.includes(1)}\n aria-checked={selectedIndices.includes(1)}\n onSelect={() => handleSelect(1)}\n >\n Item 2\n </ActionList.Item>\n </ActionList>\n )\n}"
},
{
"id": "components-actionlist-features--disabled-item",
"code": "() => {\n const [selectedIndex, setSelectedIndex] = React.useState(0)\n return (\n <ActionList\n selectionVariant=\"single\"\n showDividers\n role=\"menu\"\n aria-label=\"Project\"\n >\n {projects.map((project, index) => (\n <ActionList.Item\n key={index}\n role=\"menuitemradio\"\n selected={index === selectedIndex}\n aria-checked={index === selectedIndex}\n onSelect={() => setSelectedIndex(index)}\n disabled={index === 1}\n >\n <ActionList.LeadingVisual>\n <TableIcon />\n </ActionList.LeadingVisual>\n {project.name}\n <ActionList.Description variant=\"block\">\n {project.scope}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n )\n}"
},
{
"id": "components-actionlist-features--inactive-item",
"code": "() => {\n return (\n <ActionList aria-label=\"Project\">\n {projects.map((project, index) => (\n <ActionList.Item\n key={index}\n inactiveText={\n index === 1 ? 'Unavailable due to an outage' : undefined\n }\n >\n <ActionList.LeadingVisual>\n <TableIcon />\n </ActionList.LeadingVisual>\n {project.name}\n <ActionList.Description variant=\"block\">\n {project.scope}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n )\n}"
},
{
"id": "components-actionlist-features--loading-item",
"code": "() => {\n return (\n <ActionList aria-label=\"Project\">\n {projects.map((project, index) => (\n <ActionList.Item key={index} loading={index === 1}>\n {project.name}\n <ActionList.Description variant=\"block\">\n {project.scope}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n )\n}"
},
{
"id": "components-actionlist-features--links",
"code": "() => (\n <ActionList>\n <ActionList.Heading\n as=\"h1\"\n sx={{\n fontSize: 1,\n }}\n >\n Details\n </ActionList.Heading>\n <ActionList.LinkItem href=\"https://github.com/primer/react#readme\">\n <ActionList.LeadingVisual>\n <BookIcon />\n </ActionList.LeadingVisual>\n Readme\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"https://github.com/primer/react/blob/main/LICENSE\">\n <ActionList.LeadingVisual>\n <LawIcon />\n </ActionList.LeadingVisual>\n MIT License\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"https://github.com/primer/react/stargazers\">\n <ActionList.LeadingVisual>\n <StarIcon />\n </ActionList.LeadingVisual>\n <strong>1.5k</strong> stars\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"https://github.com/primer/react/watchers\">\n <ActionList.LeadingVisual>\n <EyeIcon />\n </ActionList.LeadingVisual>\n <strong>21</strong> watching\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"https://github.com/primer/react/network/members\">\n <ActionList.LeadingVisual>\n <RepoForkedIcon />\n </ActionList.LeadingVisual>\n <strong>225</strong> forks\n </ActionList.LinkItem>\n </ActionList>\n)"
},
{
"id": "components-actionlist-features--custom-item-children",
"code": "() => (\n <ActionList>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <ArrowRightIcon />\n </ActionList.LeadingVisual>\n <Label>Choose this one</Label>\n <ActionList.TrailingVisual>\n <ArrowLeftIcon />\n </ActionList.TrailingVisual>\n </ActionList.Item>\n </ActionList>\n)"
},
{
"id": "components-actionlist-features--text-wrap-and-truncation",
"code": "() => (\n <Box maxWidth=\"300px\">\n <ActionList showDividers>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <ArrowRightIcon />\n </ActionList.LeadingVisual>\n Block Description. Long text should wrap\n <ActionList.Description variant=\"block\">\n This description is long, but it is block so it wraps\n </ActionList.Description>\n <ActionList.TrailingVisual>\n <ArrowLeftIcon />\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <ArrowRightIcon />\n </ActionList.LeadingVisual>\n Inline Description\n <ActionList.Description truncate>\n This description gets truncated because it is inline with truncation\n </ActionList.Description>\n <ActionList.TrailingVisual>\n <ArrowLeftIcon />\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <ArrowRightIcon />\n </ActionList.LeadingVisual>\n Inline Description\n <ActionList.Description>\n This description wraps because it is inline without truncation\n </ActionList.Description>\n <ActionList.TrailingVisual>\n <ArrowLeftIcon />\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <ArrowRightIcon />\n </ActionList.LeadingVisual>\n Really long text without a description should wrap so it wraps\n <ActionList.TrailingVisual>\n <ArrowLeftIcon />\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <ArrowRightIcon />\n </ActionList.LeadingVisual>\n SomethingSomething/SomethingElse.Some.Thing.Lalala.la\n <ActionList.TrailingVisual>\n <ArrowLeftIcon />\n </ActionList.TrailingVisual>\n </ActionList.Item>\n </ActionList>\n </Box>\n)"
},
{
"id": "components-actionlist-features--conditional-children",
"code": "() => {\n type reviewerType = {\n name: string\n id?: string\n type?: string\n login?: string\n slug?: string\n members?: number\n }\n const potentialReviewers: reviewerType[] = [...teams, ...users]\n return (\n <ActionList showDividers>\n {potentialReviewers.map((reviewer, index) => (\n <ActionList.Item key={index}>\n <ActionList.LeadingVisual>\n {reviewer.type === 'team' ? (\n <Avatar\n src={`https://avatars.githubusercontent.com/t/${reviewer.id}`}\n />\n ) : (\n <Avatar\n src={`https://avatars.githubusercontent.com/${reviewer.login}`}\n />\n )}\n </ActionList.LeadingVisual>\n {reviewer.login || reviewer.slug}\n {reviewer.type === 'team' ? (\n <ActionList.Description variant=\"block\">\n {reviewer.name}\n </ActionList.Description>\n ) : (\n <ActionList.Description>{reviewer.name}</ActionList.Description>\n )}\n {reviewer.type === 'team' && (\n <ActionList.TrailingVisual>\n <PeopleIcon />\n {reviewer.members}\n </ActionList.TrailingVisual>\n )}\n </ActionList.Item>\n ))}\n </ActionList>\n )\n}"
},
{
"id": "components-actionlist-features--child-with-side-effects",
"code": "() => {\n const user = users[0]\n const [selected, setSelected] = React.useState(true)\n const SideEffectDescription = () => {\n const [seconds, setSeconds] = React.useState(0)\n React.useEffect(() => {\n const fn = () => setSeconds((s) => s + 1)\n const interval = window.setInterval(fn, 1000)\n return () => window.clearInterval(interval)\n }, [])\n return <>{seconds} seconds passed</>\n }\n return (\n <ActionList\n selectionVariant=\"multiple\"\n role=\"listbox\"\n aria-label=\"Assignees\"\n >\n <ActionList.Item\n selected={selected}\n onSelect={() => setSelected(!selected)}\n role=\"option\"\n >\n <ActionList.LeadingVisual>\n <Avatar src={`https://avatars.githubusercontent.com/${user.login}`} />\n </ActionList.LeadingVisual>\n {user.login}\n <ActionList.Description>\n <SideEffectDescription />\n </ActionList.Description>\n </ActionList.Item>\n </ActionList>\n )\n}"
},
{
"id": "components-actionlist-features--inside-overlay",
"code": "() => {\n const [open, setOpen] = React.useState(false)\n const toggle = () => setOpen(!open)\n return (\n <AnchoredOverlay\n open={open}\n onOpen={toggle}\n onClose={toggle}\n renderAnchor={(props) => (\n <button type=\"button\" {...props}>\n toggle overlay\n </button>\n )}\n >\n <ActionList role=\"menu\">\n <ActionList.Item role=\"menuitem\">\n Use your arrow keys\n <ActionList.TrailingVisual>↓</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item role=\"menuitem\">\n keep going\n <ActionList.TrailingVisual>↓</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item role=\"menuitem\">\n more more\n <ActionList.TrailingVisual>↓</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Divider />\n <ActionList.Item variant=\"danger\" role=\"menuitem\">\n now go up!\n <ActionList.TrailingVisual>↑</ActionList.TrailingVisual>\n </ActionList.Item>\n </ActionList>\n </AnchoredOverlay>\n )\n}"
},
{
"id": "components-actionlist-features--group-with-subtle-title",
"code": "() => {\n const [assignees, setAssignees] = React.useState(users.slice(0, 1))\n const toggleAssignee = (assignee: (typeof users)[number]) => {\n const assigneeIndex = assignees.findIndex((a) => a.login === assignee.login)\n if (assigneeIndex === -1) setAssignees([...assignees, assignee])\n else setAssignees(assignees.filter((_, index) => index !== assigneeIndex))\n }\n return (\n <ActionList\n selectionVariant=\"multiple\"\n role=\"menu\"\n showDividers\n aria-label=\"Reviewers\"\n >\n <ActionList.Group>\n <ActionList.GroupHeading>Everyone</ActionList.GroupHeading>\n {users.slice(2).map((user) => (\n <ActionList.Item\n role=\"menuitemcheckbox\"\n key={user.login}\n selected={Boolean(\n assignees.find((assignee) => assignee.login === user.login),\n )}\n aria-checked={Boolean(\n assignees.find((assignee) => assignee.login === user.login),\n )}\n onSelect={() => toggleAssignee(user)}\n >\n <ActionList.LeadingVisual>\n <Avatar src={`https://github.com/${user.login}.png`} />\n </ActionList.LeadingVisual>\n {user.login}\n <ActionList.Description>{user.name}</ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList.Group>\n </ActionList>\n )\n}"
},
{
"id": "components-actionlist-features--group-with-filled-title",
"code": "() => {\n const [assignees, setAssignees] = React.useState(users.slice(0, 1))\n const toggleAssignee = (assignee: (typeof users)[number]) => {\n const assigneeIndex = assignees.findIndex((a) => a.login === assignee.login)\n if (assigneeIndex === -1) setAssignees([...assignees, assignee])\n else setAssignees(assignees.filter((_, index) => index !== assigneeIndex))\n }\n return (\n <ActionList\n selectionVariant=\"multiple\"\n role=\"menu\"\n showDividers\n aria-label=\"Reviewers\"\n >\n <ActionList.Group>\n <ActionList.GroupHeading variant=\"filled\">\n Everyone\n </ActionList.GroupHeading>\n {users.slice(2).map((user) => (\n <ActionList.Item\n role=\"menuitemcheckbox\"\n key={user.login}\n selected={Boolean(\n assignees.find((assignee) => assignee.login === user.login),\n )}\n aria-checked={Boolean(\n assignees.find((assignee) => assignee.login === user.login),\n )}\n onSelect={() => toggleAssignee(user)}\n >\n <ActionList.LeadingVisual>\n <Avatar src={`https://github.com/${user.login}.png`} />\n </ActionList.LeadingVisual>\n {user.login}\n <ActionList.Description>{user.name}</ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList.Group>\n </ActionList>\n )\n}"
},
{
"id": "components-actionlist-features--with-custom-trailing-visuals",
"code": "() => (\n <ActionList>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <IssueOpenedIcon />\n </ActionList.LeadingVisual>\n Issues\n <ActionList.TrailingVisual>\n <CounterLabel>20</CounterLabel>\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <GitPullRequestIcon />\n </ActionList.LeadingVisual>\n PRs\n <ActionList.TrailingVisual>\n <CounterLabel>12</CounterLabel>\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <ProjectIcon />\n </ActionList.LeadingVisual>\n Projects\n <ActionList.TrailingVisual>\n <CounterLabel>2</CounterLabel>\n </ActionList.TrailingVisual>\n </ActionList.Item>\n </ActionList>\n)"
},
{
"id": "components-actionlist-features--full-variant",
"code": "() => (\n <ActionList variant=\"full\">\n <ActionList.Item>Copy link</ActionList.Item>\n <ActionList.Item>Quote reply</ActionList.Item>\n <ActionList.Item>Edit comment</ActionList.Item>\n <ActionList.Divider />\n <ActionList.Item variant=\"danger\">Delete file</ActionList.Item>\n </ActionList>\n)"
}
],
"importPath": "@primer/react",
"props": [
{
"name": "children",
"type": "ActionList.Item[] | ActionList.LinkItem[] | ActionList.Group[]",
"defaultValue": "",
"required": true,
"description": ""
},
{
"name": "variant",
"type": "'inset' | 'full'",
"defaultValue": "'inset'",
"description": "`inset` children are offset (vertically and horizontally) from list edges. `full` children are flush (vertically and horizontally) with list edges"
},
{
"name": "selectionVariant",
"type": "'single' | 'multiple'",
"defaultValue": "",
"description": "Whether multiple items or a single item can be selected."
},
{
"name": "showDividers",
"type": "boolean",
"description": "Display a divider above each `Item` in this `List` when it does not follow a `Header` or `Divider`.",
"defaultValue": ""
},
{
"name": "role",
"type": "AriaRole",
"defaultValue": "",
"description": "ARIA role describing the function of the list. `listbox` and `menu` are a common values."
},
{
"name": "sx",
"type": "SystemStyleObject"
}
],
"subcomponents": [
{
"name": "ActionList.Item",
"props": [
{
"name": "children",
"type": "React.ReactNode | ActionList.LeadingVisual | ActionList.Description | ActionList.TrailingVisual",
"defaultValue": "",
"required": true,
"description": "Primary content for an Item"
},
{
"name": "variant",
"type": "'default' | 'danger'",
"defaultValue": "'default'",
"description": "`danger` indicates that the item is destructive."
},
{
"name": "onSelect",
"type": "(event: React.MouseEvent<HTMLLIElement> | React.KeyboardEvent<HTMLLIElement>) => void",
"defaultValue": "",
"description": "Callback that is called when the item is selected using either the mouse or keyboard. `event.preventDefault()` will prevent a menu from closing when within an `<ActionMenu />`. This is not called for disabled or inactive items."
},
{
"name": "selected",
"type": "boolean",
"defaultValue": "false",
"description": "Indicate whether the item is selected. Only applies to items that can be selected."
},
{
"name": "active",
"type": "boolean",
"defaultValue": "false",
"description": "Indicate whether the item is active. There should never be more than one active item."
},
{
"name": "disabled",
"type": "boolean",
"defaultValue": "false",
"description": "Items that are disabled can not be clicked, selected, or navigated to."
},
{
"name": "inactiveText",
"type": "string",
"defaultValue": "",
"description": "Text describing why the item is inactive. This may be used when an item's usual functionality is unavailable due to a system error such as a database outage. \nIf there is a leading visual, the alert icon will replace the leading visual. \n If there is a trailing visual, it will replace the trailing visual.\n If there is no visual passed, it will be shown in the trailing visual slot to preserve left alignment of item content. \nText will appear in a tooltip triggered by the alert icon in ActionList items, but text will appear below the description or title on ActionMenu items."
},
{
"name": "loading",
"type": "boolean",
"description": "Whether the item is loading."
},
{
"name": "role",
"type": "AriaRole",
"defaultValue": "",
"description": "ARIA role describing the function of the item. `option` is a common value."
},
{
"name": "id",
"type": "string",
"required": false,
"description": "id to attach to the root element of the Item",
"defaultValue": ""
},
{
"name": "sx",
"type": "SystemStyleObject"
}
]
},
{
"name": "ActionList.Heading",
"props": [
{
"name": "children",
"type": "React.ReactNode",
"defaultValue": "",
"required": true,
"description": "Use to give a heading to list"
},
{
"name": "as",
"type": "h1 | h2 | h3 | h4 | h5 | h6",
"defaultValue": "h3",
"required": false,
"description": "The level of the heading"
},
{
"name": "visuallyHidden",
"type": "boolean",
"required": false,
"description": "",
"defaultValue": ""
},
{
"name": "sx",
"type": "SystemStyleObject"
}
]
},
{
"name": "ActionList.LinkItem",
"props": [
{
"name": "children",
"type": "React.ReactNode | ActionList.LeadingVisual | ActionList.Description | ActionList.TrailingVisual",
"defaultValue": "",
"required": true,
"description": ""
},
{
"name": "active",
"type": "boolean",
"defaultValue": "false",
"description": "Indicate whether the item is active. There should never be more than one active item."
},
{
"name": "ref",
"type": "React.RefObject<HTMLAnchorElement>"
},
{
"name": "as",
"type": "React.ElementType",
"defaultValue": "\"a\""
},
{
"name": "inactiveText",
"type": "string",
"required": false,
"description": "Text describing why the item is inactive. This may be used when an item's usual functionality\nis unavailable due to a system error such as a database outage.",
"defaultValue": ""
},
{
"name": "sx",
"type": "SystemStyleObject"
}
],
"passthrough": {
"element": "a",
"url": "https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#Attributes"
}
},
{
"name": "ActionList.LeadingVisual",
"props": [
{
"name": "children",
"type": "React.ReactNode",
"defaultValue": "",
"required": true,
"description": "Icon (or similar) positioned before item text."
},
{
"name": "sx",
"type": "SystemStyleObject"
}
]
},
{
"name": "ActionList.TrailingVisual",
"props": [
{
"name": "children",
"type": "React.ReactNode",
"defaultValue": "",
"required": true,
"description": "Visual positioned after item text."
},
{
"name": "sx",
"type": "SystemStyleObject"
}
]
},
{
"name": "ActionList.TrailingAction",
"props": [
{
"name": "as",
"type": "a | button",
"defaultValue": "button",
"required": false,
"description": "HTML element to render as."
},
{
"name": "label",
"type": "string",
"defaultValue": "",
"required": true,
"description": "Acccessible name for the control."
},
{
"name": "icon",
"type": "string",
"defaultValue": "",
"required": true,
"description": "Octicon to pass into IconButton. When this is not set, TrailingAction renders as a `Button` instead of an `IconButton`."
},
{
"name": "href",
"type": "string",
"description": "href when the TrailingAction is rendered as a link."
}
]
},
{
"name": "ActionList.Description",
"props": [
{
"name": "children",
"type": "React.ReactNode",
"defaultValue": "",
"required": true,
"description": ""
},
{
"name": "variant",
"type": "'inline' | 'block'",
"defaultValue": "'inline'",
"description": "`inline` descriptions are positioned beside primary text. `block` descriptions are positioned below primary text."
},
{
"name": "sx",
"type": "SystemStyleObject"
},
{
"name": "className",
"type": "string | undefined",
"defaultValue": "",
"description": "CSS string"
},
{
"name": "truncate",
"type": "boolean",
"defaultValue": "false",
"description": "Whether the inline description should truncate the text on overflow."
}
]
},
{
"name": "ActionList.GroupHeading",
"props": [
{
"name": "children",
"type": "React.ReactNode",
"defaultValue": "",
"required": true,
"description": "Use to give a heading to the groups"
},
{
"name": "variant",
"type": "'filled' | 'subtle'",
"defaultValue": "'subtle'",
"description": "`filled` style has a background color and top and bottom borders. Subtle style has no background or borders."
},
{
"name": "auxiliaryText",
"type": "string",
"required": false,
"description": "Secondary text which provides additional information about a `Group`.",
"defaultValue": ""
},
{
"name": "visuallyHidden",
"type": "boolean",
"required": false,
"description": "",
"defaultValue": ""
},
{
"name": "as",
"type": "h1 | h2 | h3 | h4 | h5 | h6",
"defaultValue": "h3",
"required": false,
"description": "The level of the heading and it is only required (enforce by runtime warning) for lists. (i.e. not required for ActionMenu or listbox roles)"
},
{
"name": "sx",
"type": "SystemStyleObject"
}
]
},
{
"name": "ActionList.Group",
"props": [
{
"name": "children",
"type": "ActionList.Item[] | ActionList.LinkItem[]",
"defaultValue": "",
"required": true,
"description": ""
},
{
"name": "title",
"type": "string",
"defaultValue": "",
"description": "Please use `ActionList.GroupHeading` instead.",
"deprecated": true
},
{
"name": "auxiliaryText",
"type": "string",
"defaultValue": "",
"description": "Secondary text that provides additional information about the group."
},
{
"name": "variant",
"type": "'filled' | 'subtle'",
"defaultValue": "'subtle'",
"description": "`inline` descriptions are positioned beside primary text. `block` descriptions are positioned below primary text."
},
{
"name": "selectionVariant",
"type": "'single' | 'multiple' | false",
"defaultValue": "",
"description": "Set `selectionVariant` at the group level."
},
{
"name": "role",
"type": "AriaRole",
"defaultValue": "",
"description": "ARIA role describing the function of the list inside the group. `listbox` and `menu` are a common values."
},
{
"name": "sx",
"type": "SystemStyleObject"
}
]
},
{
"filePath": "/Users/mperrotti/work-dir/react/packages/react/src/ActionList/Divider.tsx",
"name": "ActionList.Divider",
"props": [
{
"name": "sx",
"type": "SystemStyleObject"
}
]
}
]
},
"action_menu": {
"source": "https://github.com/primer/react/tree/main/packages/react/src/ActionMenu",
"id": "action_menu",
"name": "ActionMenu",
"status": "beta",
"a11yReviewed": false,
"stories": [
{
"id": "components-actionmenu--default",
"code": "() => (\n <ActionMenu>\n <ActionMenu.Button>Open menu</ActionMenu.Button>\n <ActionMenu.Overlay width=\"medium\">\n <ActionList>\n <ActionList.Item onSelect={() => alert('Copy link clicked')}>\n Copy link\n <ActionList.TrailingVisual>⌘C</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Quote reply clicked')}>\n Quote reply\n <ActionList.TrailingVisual>⌘Q</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Edit comment clicked')}>\n Edit comment\n <ActionList.TrailingVisual>⌘E</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Divider />\n <ActionList.Item\n variant=\"danger\"\n onSelect={() => alert('Delete file clicked')}\n >\n Delete file\n <ActionList.TrailingVisual>⌘D</ActionList.TrailingVisual>\n </ActionList.Item>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n)"
},
{
"id": "components-actionmenu-features--links-and-actions",
"code": "() => (\n <ActionMenu>\n <ActionMenu.Button>Open menu</ActionMenu.Button>\n <ActionMenu.Overlay width=\"auto\">\n <ActionList>\n <ActionList.Item onSelect={() => alert('Workflows clicked')}>\n Workflows\n <ActionList.LeadingVisual>\n <WorkflowIcon />\n </ActionList.LeadingVisual>\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Archived items clicked')}>\n Archived items\n <ActionList.LeadingVisual>\n <ArchiveIcon />\n </ActionList.LeadingVisual>\n </ActionList.Item>\n <ActionList.LinkItem href=\"/\">\n Settings\n <ActionList.LeadingVisual>\n <GearIcon />\n </ActionList.LeadingVisual>\n </ActionList.LinkItem>\n <ActionList.Item onSelect={() => alert('Make a copy clicked')}>\n Make a copy\n <ActionList.LeadingVisual>\n <CopyIcon />\n </ActionList.LeadingVisual>\n </ActionList.Item>\n <ActionList.Divider />\n <ActionList.Group>\n <ActionList.GroupHeading>GitHub projects</ActionList.GroupHeading>\n <ActionList.LinkItem href=\"/\">\n What's new\n <ActionList.LeadingVisual>\n <RocketIcon />\n </ActionList.LeadingVisual>\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"/\">\n Give feedback\n <ActionList.LeadingVisual>\n <CommentIcon />\n </ActionList.LeadingVisual>\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"/\">\n GitHub Docs\n <ActionList.LeadingVisual>\n <BookIcon />\n </ActionList.LeadingVisual>\n </ActionList.LinkItem>\n </ActionList