UNPKG

@primer/react

Version:

An implementation of GitHub's Primer Design System using React

596 lines 613 kB
{ "schemaVersion": 2, "components": { "dialog": { "id": "dialog", "docsId": "dialog", "name": "Dialog", "status": "alpha", "a11yReviewed": false, "stories": [ { "id": "components-dialog--default", "code": "() => {\n const [isOpen, setIsOpen] = useState(false)\n const returnFocusRef = useRef(null)\n return (\n <div>\n <Button\n data-testid=\"trigger-button\"\n ref={returnFocusRef}\n onClick={() => setIsOpen(true)}\n >\n Show Dialog\n </Button>\n <Dialog\n returnFocusRef={returnFocusRef}\n isOpen={isOpen}\n onDismiss={() => setIsOpen(false)}\n aria-labelledby=\"header\"\n >\n <div data-testid=\"inner\">\n <Dialog.Header id=\"header\">Title</Dialog.Header>\n <Box p={3}>\n <Text>Some content</Text>\n </Box>\n </div>\n </Dialog>\n </div>\n )\n}" } ], "importPath": "@primer/react", "props": [ { "name": "isOpen", "type": "boolean", "description": "Whether or not the dialog is open" }, { "name": "onDismiss", "type": "() => void", "description": "Function that will be called when the dialog is closed" }, { "name": "returnFocusRef", "type": " React.RefObject<HTMLElement>", "description": "The element to restore focus back to after the `Dialog` is closed" }, { "name": "initialFocusRef", "type": " React.RefObject<HTMLElement>", "description": "Element inside of the `Dialog` you'd like to be focused when the Dialog is opened. If nothing is passed to `initialFocusRef` the close button is focused." }, { "name": "aria-labelledby", "type": "string", "description": "Pass an id to use for the aria-label. Use either a `aria-label` or an `aria-labelledby` but not both." }, { "name": "aria-label", "type": "string", "description": "Pass a label to be used to describe the Dialog. Use either a `aria-label` or an `aria-labelledby` but not both." }, { "name": "sx", "type": "SystemStyleObject" } ], "subcomponents": [ { "name": "Dialog.Header", "props": [ { "name": "sx", "type": "SystemStyleObject" } ] } ] }, "actionbar": { "id": "actionbar", "name": "ActionBar", "status": "alpha", "a11yReviewed": true, "stories": [ { "id": "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": "size", "type": "'small' | 'medium' | 'large'", "required": false, "description": "Size of the action bar" }, { "name": "aria-label", "type": "string", "description": "When provided, a label is added to the action bar" }, { "name": "children", "type": "React.ReactElement", "required": true } ], "subcomponents": [ { "name": "ActionBar.Icon", "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." }, { "name": "sx", "type": "SystemStyleObject" } ] }, { "name": "ActionBar.Divider", "props": [] } ] }, "action_list": { "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\">Filter by</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 <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--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 <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 <>\n <ActionList.Heading\n as=\"h1\"\n sx={{\n fontSize: 1,\n }}\n >\n Details\n </ActionList.Heading>\n <ActionList>\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--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>\n This description gets truncated because it is inline\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) => <button {...props}>toggle overlay</button>}\n >\n <ActionList>\n <ActionList.Item>\n Use your arrow keys\n <ActionList.TrailingVisual>↓</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n keep going\n <ActionList.TrailingVisual>↓</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n more more\n <ActionList.TrailingVisual>↓</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Divider />\n <ActionList.Item variant=\"danger\">\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--action-list-with-button-semantics", "code": "() => {\n return (\n <FeatureFlags\n flags={{\n primer_react_action_list_item_as_button: true,\n }}\n >\n <ActionList>\n <ActionList.Item>Copy link</ActionList.Item>\n <ActionList.Item inactiveText=\"Nothing to quote\">\n Quote reply\n </ActionList.Item>\n <ActionList.Item disabled>Edit comment</ActionList.Item>\n <ActionList.Divider />\n <ActionList.Item variant=\"danger\">Delete file</ActionList.Item>\n <ActionList.LinkItem href=\"https://github.com/primer/react#readme\">\n Support\n <ActionList.TrailingVisual>\n <LinkExternalIcon />\n </ActionList.TrailingVisual>\n </ActionList.LinkItem>\n </ActionList>\n </FeatureFlags>\n )\n}" }, { "id": "components-actionlist-features--with-trailing-action", "code": "() => {\n return (\n <FeatureFlags\n flags={{\n primer_react_action_list_item_as_button: true,\n }}\n >\n <ActionList>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <FileDirectoryIcon />\n </ActionList.LeadingVisual>\n Item 1 (with default TrailingAction)\n <ActionList.TrailingAction\n label=\"Expand sidebar\"\n icon={ArrowLeftIcon}\n />\n </ActionList.Item>\n <ActionList.Item>\n Item 2 (with link TrailingAction)\n <ActionList.TrailingAction\n as=\"a\"\n href=\"#\"\n label=\"Some action 1\"\n icon={ArrowRightIcon}\n />\n </ActionList.Item>\n <ActionList.Item>\n Item 3\n <ActionList.Description>\n This is an inline description.\n </ActionList.Description>\n <ActionList.TrailingAction label=\"Some action 2\" icon={BookIcon} />\n </ActionList.Item>\n <ActionList.Item>\n Item 4\n <ActionList.Description variant=\"block\">\n This is a block description.\n </ActionList.Description>\n <ActionList.TrailingAction label=\"Some action 3\" icon={BookIcon} />\n </ActionList.Item>\n <ActionList.Item>\n Item 5\n <ActionList.Description variant=\"block\">\n This is a block description.\n </ActionList.Description>\n <ActionList.TrailingAction label=\"Some action 4\" />\n </ActionList.Item>\n <ActionList.Item>\n Item 6\n <ActionList.TrailingAction href=\"#\" as=\"a\" label=\"Some action 5\" />\n </ActionList.Item>\n <ActionList.LinkItem href=\"#\">\n LinkItem 1\n <ActionList.Description>\n with TrailingAction this is a long description and should not cause\n horizontal scroll on smaller screen sizes\n </ActionList.Description>\n <ActionList.TrailingAction label=\"Another action\" />\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"#\">\n LinkItem 2\n <ActionList.Description>\n with TrailingVisual this is a long description and should not cause\n horizontal scroll on smaller screen sizes\n </ActionList.Description>\n <ActionList.TrailingVisual>\n <TableIcon />\n </ActionList.TrailingVisual>\n </ActionList.LinkItem>\n <ActionList.Item inactiveText=\"Unavailable due to an outage\">\n Inactive Item\n <ActionList.Description>With TrailingAction</ActionList.Description>\n <ActionList.TrailingAction\n as=\"a\"\n href=\"#\"\n label=\"Some action 8\"\n icon={ArrowRightIcon}\n />\n </ActionList.Item>\n </ActionList>\n </FeatureFlags>\n )\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": "showDivider", "type": "boolean", "defaultValue": "false", "description": "Display a divider above each item in this list when it does not follow a header or divider." }, { "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": "" }, { "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": "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": "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": "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": "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": "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" } ] } ] }, "action_menu": { "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 <Act