Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
1e2f576
draft: LinkItemContainerNoBox, replaced all LinkItem in ActionList st…
liuliu-dev Oct 10, 2025
d779acf
add back _PrivateItemWrapper, change api in stories and test the dom …
liuliu-dev Oct 13, 2025
1f686e8
fix tests for missing role
liuliu-dev Oct 13, 2025
1704d0d
Merge remote-tracking branch 'origin/main' into liuliu/merge-linkitem…
liuliu-dev Oct 13, 2025
e1a6a6b
fix lint
liuliu-dev Oct 13, 2025
35dc470
test(vrt): update snapshots
liuliu-dev Oct 13, 2025
24995ef
update Breadcrumbs, NavList, UnderlineNav to use ActionList.Item
liuliu-dev Oct 14, 2025
02f7861
Merge branch 'liuliu/merge-linkitem-and-item-in-actionlist' of https:…
liuliu-dev Oct 14, 2025
1c904ac
some clean up and add changeset
liuliu-dev Oct 14, 2025
ebb427f
Merge remote-tracking branch 'origin/main' into liuliu/merge-linkitem…
liuliu-dev Oct 14, 2025
9883e75
test(vrt): update snapshots
liuliu-dev Oct 14, 2025
e0635c6
type fix
liuliu-dev Oct 15, 2025
aa6f7f2
Merge branch 'liuliu/merge-linkitem-and-item-in-actionlist' of https:…
liuliu-dev Oct 15, 2025
61ea3c1
remove unused type prop
liuliu-dev Oct 15, 2025
94a2c7d
Merge remote-tracking branch 'origin/main' into liuliu/merge-linkitem…
liuliu-dev Oct 15, 2025
66d6bcb
onClick?
liuliu-dev Oct 15, 2025
d03d6c9
seperate props
liuliu-dev Oct 15, 2025
a79c620
props order
liuliu-dev Oct 15, 2025
5ab6dd6
clean up and docs.json
liuliu-dev Oct 15, 2025
81a27de
lint fix
liuliu-dev Oct 15, 2025
47de2b6
remove to
liuliu-dev Oct 16, 2025
33b46fe
resolve conflicts
liuliu-dev Oct 17, 2025
61eb1f1
h4 -> h2, not exporting MenuItemProps
liuliu-dev Oct 20, 2025
2a1be72
Merge remote-tracking branch 'origin/main' into liuliu/merge-linkitem…
liuliu-dev Oct 21, 2025
d1f1272
check for href and to on as a, clean up props logic, add back 1 linki…
liuliu-dev Oct 21, 2025
54ee453
remove href check for a
liuliu-dev Oct 21, 2025
c6f608b
Merge branch 'main' into liuliu/merge-linkitem-and-item-in-actionlist
liuliu-dev Oct 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/shiny-pianos-wash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': major
---

ActionList.Item now supports link functionality through href and other anchor attributes, deprecating the separate ActionList.LinkItem component.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi!

What does the deprecation show up as? Does it show up as an error in CI for github-ui or only a soft suggestion in vscode?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would only be a suggestion in vscode like this:

Screenshot 2025-10-16 at 9 26 10 AM

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 6 additions & 7 deletions packages/react/src/ActionList/ActionList.dev.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React from 'react'
import type {Meta} from '@storybook/react-vite'
import {ActionList} from '.'
import {Item} from './Item'
import {LinkItem} from './LinkItem'
import {Group} from './Group'
import {Divider} from './Divider'
import {Description} from './Description'
Expand All @@ -14,7 +13,7 @@ import {AnchoredOverlay} from '../AnchoredOverlay'
export default {
title: 'Components/ActionList/Dev',
component: ActionList,
subcomponents: {Item, LinkItem, Group, Divider, Description},
subcomponents: {Item, Group, Divider, Description},
} as Meta<typeof ActionList>

const users = [
Expand Down Expand Up @@ -261,15 +260,15 @@ export const ItemLabelStylesWithMixedDescriptions = () => (
Item with inline description
<ActionList.Description variant="block">Block description</ActionList.Description>
</ActionList.LinkItem>
<ActionList.LinkItem>
<ActionList.Item>
Item with inline description
<ActionList.Description variant="block">Block description</ActionList.Description>
</ActionList.LinkItem>
<ActionList.LinkItem>Item with no description</ActionList.LinkItem>
<ActionList.LinkItem>
</ActionList.Item>
<ActionList.Item>Item with no description</ActionList.Item>
<ActionList.Item>
Item with inline description
<ActionList.Description variant="block">Block description</ActionList.Description>
</ActionList.LinkItem>
</ActionList.Item>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should keep one story for LinkItem in ActionList.dev.stories so that we don't accidentally break it before it's time to remove ActionList.LinkItem.

</ActionList>
</Stack.Item>
</Stack>
Expand Down
29 changes: 27 additions & 2 deletions packages/react/src/ActionList/ActionList.docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,33 @@
"required": false,
"description": "id to attach to the root element of the Item",
"defaultValue": ""
},
{
"name": "href",
"type": "string",
"required": false,
"description": "URL to navigate to when the item is clicked. When provided, the item will render as a link.",
"defaultValue": ""
},
{
"name": "as",
"type": "React.ElementType",
"defaultValue": "\"a\"",
"required": false,
"description": "The underlying element to render."
},
{
"name": "to",
"type": "string",
"required": false,
"description": "Destination for React Router or other client-side routing libraries. When provided, the item will render as a link.",
"defaultValue": ""
}
]
],
"passthrough": {
"element": "a",
"url": "https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#Attributes"
}
},
{
"name": "ActionList.Heading",
Expand Down Expand Up @@ -349,4 +374,4 @@
]
}
]
}
}
32 changes: 16 additions & 16 deletions packages/react/src/ActionList/ActionList.examples.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,53 +51,53 @@ export const ListLinkItem = () => (
</ActionList.LeadingVisual>
not a link, just an Item for comparison
</ActionList.Item>
<ActionList.LinkItem href="https://github.com/primer" aria-keyshortcuts="g">
<ActionList.Item href="https://github.com/primer" aria-keyshortcuts="g">
<ActionList.LeadingVisual>
<LinkIcon />
</ActionList.LeadingVisual>
ActionList.LinkItem
</ActionList.LinkItem>
<ActionList.LinkItem href="https://github.com/primer" target="_blank" rel="noopener noreferrer">
ActionList.Item with href
</ActionList.Item>
<ActionList.Item 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/components-actionlist--default">
ActionList.Item with anchor attributes
</ActionList.Item>
<ActionList.Item as={ReactRouterLikeLink} to="?path=/story/components-actionlist--default">
<ActionList.LeadingVisual>
<LinkIcon />
</ActionList.LeadingVisual>
as ReactRouterLink
</ActionList.LinkItem>
</ActionList.Item>
<NextJSLikeLink href="?path=/story/components-actionlist--default">
<ActionList.LinkItem>
<ActionList.Item>
<ActionList.LeadingVisual>
<LinkIcon />
</ActionList.LeadingVisual>
NextJS style Link
</ActionList.LinkItem>
</ActionList.Item>
</NextJSLikeLink>
<ActionList.LinkItem href="?path=/story/components-actionlist--default">
<ActionList.Item href="?path=/story/components-actionlist--default">
<ActionList.LeadingVisual>
<LinkIcon />
</ActionList.LeadingVisual>
With inline description
<ActionList.Description variant="inline">inline description</ActionList.Description>
</ActionList.LinkItem>
<ActionList.LinkItem href="?path=/story/components-actionlist--default">
</ActionList.Item>
<ActionList.Item href="?path=/story/components-actionlist--default">
<ActionList.LeadingVisual>
<LinkIcon />
</ActionList.LeadingVisual>
With block description
<ActionList.Description variant="block">Block description</ActionList.Description>
</ActionList.LinkItem>
<ActionList.LinkItem href="?path=/story/components-actionlist--default">
</ActionList.Item>
<ActionList.Item href="?path=/story/components-actionlist--default">
<ActionList.LeadingVisual>
<LinkIcon />
</ActionList.LeadingVisual>
Trailing visual
<ActionList.TrailingVisual>⌘ + L</ActionList.TrailingVisual>
</ActionList.LinkItem>
</ActionList.Item>
</ActionList>
)
ListLinkItem.storyName = 'Link Item'
Expand Down
51 changes: 25 additions & 26 deletions packages/react/src/ActionList/ActionList.features.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React from 'react'
import type {Meta} from '@storybook/react-vite'
import {ActionList} from '.'
import {Item} from './Item'
import {LinkItem} from './LinkItem'
import {Group} from './Group'
import {Divider} from './Divider'
import {Description} from './Description'
Expand Down Expand Up @@ -35,7 +34,7 @@ import classes from './ActionList.features.stories.module.css'
export default {
title: 'Components/ActionList/Features',
component: ActionList,
subcomponents: {Item, LinkItem, Group, Divider, Description},
subcomponents: {Item, Group, Divider, Description},
} as Meta<typeof ActionList>

export const SimpleList = () => (
Expand Down Expand Up @@ -111,36 +110,36 @@ export const WithCustomHeading = () => (
Details
</Heading>
<ActionList aria-labelledby="list-heading">
<ActionList.LinkItem href="https://github.com/primer/react#readme">
<ActionList.Item href="https://github.com/primer/react#readme">
<ActionList.LeadingVisual>
<BookIcon />
</ActionList.LeadingVisual>
Readme
</ActionList.LinkItem>
<ActionList.LinkItem href="https://github.com/primer/react/blob/main/LICENSE">
</ActionList.Item>
<ActionList.Item href="https://github.com/primer/react/blob/main/LICENSE">
<ActionList.LeadingVisual>
<LawIcon />
</ActionList.LeadingVisual>
MIT License
</ActionList.LinkItem>
<ActionList.LinkItem href="https://github.com/primer/react/stargazers">
</ActionList.Item>
<ActionList.Item href="https://github.com/primer/react/stargazers">
<ActionList.LeadingVisual>
<StarIcon />
</ActionList.LeadingVisual>
<strong>1.5k</strong> stars
</ActionList.LinkItem>
<ActionList.LinkItem href="https://github.com/primer/react/watchers">
</ActionList.Item>
<ActionList.Item href="https://github.com/primer/react/watchers">
<ActionList.LeadingVisual>
<EyeIcon />
</ActionList.LeadingVisual>
<strong>21</strong> watching
</ActionList.LinkItem>
<ActionList.LinkItem href="https://github.com/primer/react/network/members">
</ActionList.Item>
<ActionList.Item href="https://github.com/primer/react/network/members">
<ActionList.LeadingVisual>
<RepoForkedIcon />
</ActionList.LeadingVisual>
<strong>225</strong> forks
</ActionList.LinkItem>
</ActionList.Item>
</ActionList>
</>
)
Expand Down Expand Up @@ -513,36 +512,36 @@ export const Links = () => (
<ActionList.Heading as="h1" className={classes.HeadingSmall}>
Details
</ActionList.Heading>
<ActionList.LinkItem href="https://github.com/primer/react#readme">
<ActionList.Item href="https://github.com/primer/react#readme">
<ActionList.LeadingVisual>
<BookIcon />
</ActionList.LeadingVisual>
Readme
</ActionList.LinkItem>
<ActionList.LinkItem href="https://github.com/primer/react/blob/main/LICENSE">
</ActionList.Item>
<ActionList.Item href="https://github.com/primer/react/blob/main/LICENSE">
<ActionList.LeadingVisual>
<LawIcon />
</ActionList.LeadingVisual>
MIT License
</ActionList.LinkItem>
<ActionList.LinkItem href="https://github.com/primer/react/stargazers">
</ActionList.Item>
<ActionList.Item href="https://github.com/primer/react/stargazers">
<ActionList.LeadingVisual>
<StarIcon />
</ActionList.LeadingVisual>
<strong>1.5k</strong> stars
</ActionList.LinkItem>
<ActionList.LinkItem href="https://github.com/primer/react/watchers">
</ActionList.Item>
<ActionList.Item href="https://github.com/primer/react/watchers">
<ActionList.LeadingVisual>
<EyeIcon />
</ActionList.LeadingVisual>
<strong>21</strong> watching
</ActionList.LinkItem>
<ActionList.LinkItem href="https://github.com/primer/react/network/members">
</ActionList.Item>
<ActionList.Item href="https://github.com/primer/react/network/members">
<ActionList.LeadingVisual>
<RepoForkedIcon />
</ActionList.LeadingVisual>
<strong>225</strong> forks
</ActionList.LinkItem>
</ActionList.Item>
</ActionList>
)

Expand Down Expand Up @@ -909,15 +908,15 @@ export const WithTrailingAction = () => {
</ActionList.Description>
<ActionList.TrailingAction label="Apply settings" loading={loadingState} />
</ActionList.Item>
<ActionList.LinkItem href="#">
<ActionList.Item href="#">
LinkItem 1
<ActionList.Description>
with TrailingAction this is a long description and should not cause horizontal scroll on smaller screen
sizes
</ActionList.Description>
<ActionList.TrailingAction label="Another action" />
</ActionList.LinkItem>
<ActionList.LinkItem href="#">
</ActionList.Item>
<ActionList.Item href="#">
LinkItem 2
<ActionList.Description>
with TrailingVisual this is a long description and should not cause horizontal scroll on smaller screen
Expand All @@ -926,7 +925,7 @@ export const WithTrailingAction = () => {
<ActionList.TrailingVisual>
<TableIcon />
</ActionList.TrailingVisual>
</ActionList.LinkItem>
</ActionList.Item>
<ActionList.Item inactiveText="Unavailable due to an outage">
Inactive Item<ActionList.Description>With TrailingAction</ActionList.Description>
<ActionList.TrailingAction as="a" href="#" label="Some action 8" icon={ArrowRightIcon} />
Expand Down
7 changes: 3 additions & 4 deletions packages/react/src/ActionList/ActionList.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type {StoryFn, Meta} from '@storybook/react-vite'
import type {ActionListProps, ActionListGroupProps} from '.'
import {ActionList} from '.'
import {Item} from './Item'
import {LinkItem} from './LinkItem'
import {Group} from './Group'
import {Divider} from './Divider'
import {Description} from './Description'
Expand All @@ -11,7 +10,7 @@ import {TypographyIcon, VersionsIcon, SearchIcon, ArrowRightIcon, ArrowLeftIcon}
export default {
title: 'Components/ActionList',
component: ActionList,
subcomponents: {Item, LinkItem, Group, Divider, Description},
subcomponents: {Item, Group, Divider, Description},
} as Meta<typeof ActionList>

export const Default = () => (
Expand Down Expand Up @@ -214,11 +213,11 @@ export const LinkItemPlayground = args => {

return (
<ActionList>
<ActionList.LinkItem {...args}>
<ActionList.Item {...args}>
{leadingVisual && <ActionList.LeadingVisual>{leadingVisual}</ActionList.LeadingVisual>}
Action list item
{trailingVisual && <ActionList.TrailingVisual>{trailingVisual}</ActionList.TrailingVisual>}
</ActionList.LinkItem>
</ActionList.Item>
</ActionList>
)
}
Expand Down
16 changes: 8 additions & 8 deletions packages/react/src/ActionList/ActionList.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ describe('ActionList', () => {
</ActionList.TrailingAction>
</ActionList.Item>
<ActionList.Divider className="divider" />
<ActionList.LinkItem className="link" href="//github.com" title="anchor" aria-keyshortcuts="d">
<ActionList.Item className="link" href="//github.com" title="anchor" aria-keyshortcuts="d">
Link Item
</ActionList.LinkItem>
</ActionList.Item>
<ActionList.Group className="group">
<ActionList.GroupHeading as="h2" className="group_heading">
Group Heading
Expand Down Expand Up @@ -177,16 +177,16 @@ describe('ActionList', () => {
expect(descriptions[2]).not.toHaveAttribute('title')
})

it('should support size prop on LinkItem', () => {
it('should support size prop on Item', () => {
const {container} = HTMLRender(
<ActionList>
<ActionList.LinkItem href="//github.com" size="large">
<ActionList.Item href="//github.com" size="large">
Large Link Item
</ActionList.LinkItem>
<ActionList.LinkItem href="//github.com" size="medium">
</ActionList.Item>
<ActionList.Item href="//github.com" size="medium">
Medium Link Item
</ActionList.LinkItem>
<ActionList.LinkItem href="//github.com">Default Link Item</ActionList.LinkItem>
</ActionList.Item>
<ActionList.Item href="//github.com">Default Link Item</ActionList.Item>
</ActionList>,
)

Expand Down
9 changes: 5 additions & 4 deletions packages/react/src/ActionList/Item.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ function SimpleActionList(): JSX.Element {
<ActionList.Item>Copy link</ActionList.Item>
<ActionList.Item>Edit file</ActionList.Item>
<ActionList.Item variant="danger">Delete file</ActionList.Item>
<ActionList.LinkItem href="//github.com" title="anchor" aria-keyshortcuts="d">
<ActionList.Item href="//github.com" title="anchor" aria-keyshortcuts="d">
Link Item
</ActionList.LinkItem>
</ActionList.Item>
<ActionList.Item inactiveText="Unavailable due to an outage">Inactive item</ActionList.Item>
<ActionList.Item inactiveText="Unavailable due to an outage" loading>
Loading and inactive item
Expand Down Expand Up @@ -185,9 +185,10 @@ describe('ActionList.Item', () => {
const onClick = vi.fn()
const component = HTMLRender(
<ActionList role="listbox">
<ActionList.LinkItem role="link" onClick={onClick}>
{/* eslint-disable-next-line primer-react/prefer-action-list-item-onselect */}
<ActionList.Item role="link" onClick={onClick}>
Primer React
</ActionList.LinkItem>
</ActionList.Item>
</ActionList>,
)
const link = await waitFor(() => component.getByRole('link'))
Expand Down
Loading
Loading