diff --git a/.changeset/cyan-needles-melt.md b/.changeset/cyan-needles-melt.md
new file mode 100644
index 00000000000..50ba08cfec0
--- /dev/null
+++ b/.changeset/cyan-needles-melt.md
@@ -0,0 +1,7 @@
+---
+"@primer/react": major
+---
+
+- Changes `leadingIcon` and `trailingIcon` to `leadingVisual` and `trailingVisual`
+- Removes `Button.Counter` as a child component, replacing it with a `count` prop. This change allows us to use the `trailingVisual` slot for counters.
+- Removes the `outline` button variant as we wish to only support `invisible` buttons.
diff --git a/docs/content/ActionMenu.mdx b/docs/content/ActionMenu.mdx
index 937a06a07d2..78654d5ac89 100644
--- a/docs/content/ActionMenu.mdx
+++ b/docs/content/ActionMenu.mdx
@@ -182,7 +182,7 @@ const fieldTypes = [
{icon: NumberIcon, name: 'Number'},
{icon: CalendarIcon, name: 'Date'},
{icon: SingleSelectIcon, name: 'Single select'},
- {icon: IterationsIcon, name: 'Iteration'}
+ {icon: IterationsIcon, name: 'Iteration'},
]
const Example = () => {
@@ -191,7 +191,7 @@ const Example = () => {
return (
-
+
{selectedType.name}
@@ -275,7 +275,7 @@ render(
-
+ ,
)
```
@@ -368,7 +368,7 @@ render(
stableApi: true,
addressedApiFeedback: false,
hasDesignGuidelines: true,
- hasFigmaComponent: true
+ hasFigmaComponent: true,
}}
/>
diff --git a/docs/content/Button.mdx b/docs/content/Button.mdx
index 75de1bd279f..d8284b7623d 100644
--- a/docs/content/Button.mdx
+++ b/docs/content/Button.mdx
@@ -29,14 +29,6 @@ The `danger` variant of `Button` is used to warn users about potentially destruc
Danger
```
-### Outline button
-
-The `outline` variant of `Button` is typically used as a secondary button
-
-```jsx live
-Outline
-```
-
### Invisible button
The `invisible` variant of `Button` indicates that the action is a low priority one.
@@ -66,11 +58,11 @@ It is recommended to use an octicon here.
```jsx live
<>
- Search
-
+ Search
+
Search
-
+
Search
>
@@ -96,17 +88,12 @@ A separate component called `IconButton` is used if the action shows only an ico
>
```
-### Counter component
+### Button with counter
-A common use case for primer is a button with a counter component which shows the child count value.
-We provide `Button.Counter` as a composite component which requires you to provide a number as child.
-The counter will match the `variant` styles of the parent button.
+To show a count value as a trailing visual inside `Button`, pass a value to the `count` prop. The counter will match the `variant` styles of the parent button.
```jsx live
-
- Watch
- 1
-
+Watch
```
### Block button
@@ -142,12 +129,12 @@ Native `` HTML attributes are forwarded to the underlying React `button`
/>
diff --git a/src/Button/Button.features.stories.tsx b/src/Button/Button.features.stories.tsx
index c3cacf1472d..36d3ee6bd1a 100644
--- a/src/Button/Button.features.stories.tsx
+++ b/src/Button/Button.features.stories.tsx
@@ -14,18 +14,15 @@ export const Danger = () => Danger
export const Invisible = () => Invisible
-export const Outline = () => Outline
+export const LeadingVisual = () => Leading visual
-export const LeadingVisual = () => Leading visual
-
-export const TrailingVisual = () => Trailing visual
+export const TrailingVisual = () => Trailing visual
export const TrailingCounter = () => {
const [count, setCount] = useState(0)
return (
- setCount(count + 1)}>
+ setCount(count + 1)} trailingVisualCount={count}>
Watch
- {count}
)
}
@@ -47,23 +44,20 @@ export const InvisibleVariants = () => {
return (
Button
-
+
Button
Button
-
+
Button
- {count}
-
+
Button
- {count}
-
+
Button
- {count}
)
diff --git a/src/Button/Button.stories.tsx b/src/Button/Button.stories.tsx
index ca84096b269..1975469b573 100644
--- a/src/Button/Button.stories.tsx
+++ b/src/Button/Button.stories.tsx
@@ -35,8 +35,8 @@ export default {
type: 'boolean',
},
},
- leadingIcon: OcticonArgType([EyeClosedIcon, EyeIcon, SearchIcon, XIcon, HeartIcon]),
- trailingIcon: OcticonArgType([EyeClosedIcon, EyeIcon, SearchIcon, XIcon, HeartIcon]),
+ leadingVisual: OcticonArgType([EyeClosedIcon, EyeIcon, SearchIcon, XIcon, HeartIcon]),
+ trailingVisual: OcticonArgType([EyeClosedIcon, EyeIcon, SearchIcon, XIcon, HeartIcon]),
trailingAction: OcticonArgType([TriangleDownIcon]),
trailingVisualCount: {
control: {
@@ -50,8 +50,8 @@ export default {
disabled: false,
variant: 'default',
alignContent: 'center',
- trailingIcon: null,
- leadingIcon: null,
+ trailingVisual: null,
+ leadingVisual: null,
trailingAction: null,
trailingVisualCount: undefined,
},
diff --git a/src/Button/ButtonBase.tsx b/src/Button/ButtonBase.tsx
index f31fffa79e4..84243010490 100644
--- a/src/Button/ButtonBase.tsx
+++ b/src/Button/ButtonBase.tsx
@@ -6,15 +6,17 @@ import {useTheme} from '../ThemeProvider'
import {ButtonProps, StyledButton} from './types'
import {getVariantStyles, getButtonStyles, getAlignContentSize} from './styles'
import {useRefObjectAsForwardedRef} from '../hooks/useRefObjectAsForwardedRef'
+import CounterLabel from '../CounterLabel'
declare let __DEV__: boolean
const defaultSxProp = {}
const ButtonBase = forwardRef(
({children, as: Component = 'button', sx: sxProp = defaultSxProp, ...props}, forwardedRef): JSX.Element => {
const {
- leadingIcon: LeadingIcon,
- trailingIcon: TrailingIcon,
+ leadingVisual: LeadingVisual,
+ trailingVisual: TrailingVisual,
trailingAction: TrailingAction,
+ trailingVisualCount: trailingVisualCount,
variant = 'default',
size = 'medium',
alignContent = 'center',
@@ -61,20 +63,31 @@ const ButtonBase = forwardRef(
ref={innerRef}
data-component={block ? 'block' : null}
data-size={size === 'small' || size === 'large' ? size : undefined}
- data-no-visuals={!LeadingIcon && !TrailingIcon && !TrailingAction ? true : undefined}
+ data-no-visuals={
+ !LeadingVisual && !TrailingVisual && !TrailingAction && !trailingVisualCount ? true : undefined
+ }
>
- {LeadingIcon && (
+ {LeadingVisual && (
-
+
)}
{children && {children} }
- {TrailingIcon && (
+ {TrailingVisual && (
-
+
)}
+ {trailingVisualCount !== undefined ? (
+
+ {trailingVisualCount}
+
+ ) : TrailingVisual ? (
+
+
+
+ ) : null}
{TrailingAction && (
diff --git a/src/Button/ButtonCounter.tsx b/src/Button/ButtonCounter.tsx
deleted file mode 100644
index bc386530d08..00000000000
--- a/src/Button/ButtonCounter.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import React from 'react'
-import {SxProp} from '../sx'
-import CounterLabel from '../CounterLabel'
-
-export type CounterProps = {
- children: number
-} & SxProp
-
-const Counter = ({children, sx: sxProp = {}, ...props}: CounterProps) => {
- return (
-
- {children}
-
- )
-}
-
-export {Counter}
diff --git a/src/Button/LinkButton.features.stories.tsx b/src/Button/LinkButton.features.stories.tsx
index a6ef0c35987..e01f73112a4 100644
--- a/src/Button/LinkButton.features.stories.tsx
+++ b/src/Button/LinkButton.features.stories.tsx
@@ -30,20 +30,14 @@ export const Invisible = () => (
)
-export const Outline = () => (
-
- Invisible
-
-)
-
export const LeadingVisual = () => (
-
+
Leading visual
)
export const TrailingVisual = () => (
-
+
Trailing visual
)
diff --git a/src/Button/LinkButton.stories.tsx b/src/Button/LinkButton.stories.tsx
index 5ca0dcab065..ee611880bf7 100644
--- a/src/Button/LinkButton.stories.tsx
+++ b/src/Button/LinkButton.stories.tsx
@@ -30,8 +30,8 @@ export default {
type: 'boolean',
},
},
- leadingIcon: OcticonArgType([EyeClosedIcon, EyeIcon, SearchIcon, XIcon, HeartIcon]),
- trailingIcon: OcticonArgType([EyeClosedIcon, EyeIcon, SearchIcon, XIcon, HeartIcon]),
+ leadingVisual: OcticonArgType([EyeClosedIcon, EyeIcon, SearchIcon, XIcon, HeartIcon]),
+ trailingVisual: OcticonArgType([EyeClosedIcon, EyeIcon, SearchIcon, XIcon, HeartIcon]),
trailingAction: OcticonArgType([ChevronRightIcon]),
trailingVisualCount: {
control: {
@@ -45,8 +45,8 @@ export default {
size: 'medium',
variant: 'default',
alignContent: 'center',
- trailingIcon: null,
- leadingIcon: null,
+ trailingVisual: null,
+ leadingVisual: null,
href: '/',
},
} as Meta
diff --git a/src/Button/index.ts b/src/Button/index.ts
index d0519b22e70..85c1d2bb2bf 100644
--- a/src/Button/index.ts
+++ b/src/Button/index.ts
@@ -1,10 +1,7 @@
import {ButtonComponent} from './Button'
-import {Counter} from './ButtonCounter'
import {IconButton} from './IconButton'
import {LinkButton} from './LinkButton'
export type {ButtonProps, IconButtonProps} from './types'
export {IconButton, LinkButton}
-export const Button = Object.assign(ButtonComponent, {
- Counter,
-})
+export const Button = Object.assign(ButtonComponent)
diff --git a/src/Button/styles.ts b/src/Button/styles.ts
index 55f82740a3c..0d43a3a3683 100644
--- a/src/Button/styles.ts
+++ b/src/Button/styles.ts
@@ -127,52 +127,6 @@ export const getVariantStyles = (variant: VariantType = 'default', theme?: Theme
'&[data-no-visuals]': {
color: 'accent.fg',
},
- '&:has([data-component="ButtonCounter"])': {
- color: 'btn.text',
- },
- },
- outline: {
- color: 'btn.outline.text',
- boxShadow: `${theme?.shadows.btn.shadow}`,
- borderColor: 'btn.border',
- backgroundColor: 'btn.bg',
-
- '&:hover:not([disabled])': {
- color: 'btn.outline.hoverText',
- backgroundColor: 'btn.outline.hoverBg',
- borderColor: 'btn.outline.hoverBorder',
- boxShadow: `${theme?.shadows.btn.outline.hoverShadow}`,
- '[data-component=ButtonCounter]': {
- backgroundColor: 'btn.outline.hoverCounterBg',
- color: 'inherit',
- },
- },
- '&:active:not([disabled])': {
- color: 'btn.outline.selectedText',
- backgroundColor: 'btn.outline.selectedBg',
- boxShadow: `${theme?.shadows.btn.outline.selectedShadow}`,
- borderColor: 'btn.outline.selectedBorder',
- },
-
- '&:disabled': {
- color: 'btn.outline.disabledText',
- backgroundColor: 'btn.outline.disabledBg',
- borderColor: 'btn.border',
- '[data-component=ButtonCounter]': {
- backgroundColor: 'btn.outline.disabledCounterBg',
- color: 'inherit',
- },
- },
- '[data-component=ButtonCounter]': {
- backgroundColor: 'btn.outline.counterBg',
- color: 'btn.outline.text',
- },
- '&[aria-expanded=true]': {
- color: 'btn.outline.selectedText',
- backgroundColor: 'btn.outline.selectedBg',
- boxShadow: `${theme?.shadows.btn.outline.selectedShadow}`,
- borderColor: 'btn.outline.selectedBorder',
- },
},
}
return style[variant]
diff --git a/src/Button/types.ts b/src/Button/types.ts
index f746de8b775..61406888446 100644
--- a/src/Button/types.ts
+++ b/src/Button/types.ts
@@ -9,7 +9,7 @@ export const StyledButton = styled.button`
${sx};
`
-export type VariantType = 'default' | 'primary' | 'invisible' | 'danger' | 'outline'
+export type VariantType = 'default' | 'primary' | 'invisible' | 'danger'
export type Size = 'small' | 'medium' | 'large'
@@ -49,11 +49,11 @@ export type ButtonProps = {
/**
* The leading icon comes before button content
*/
- leadingIcon?: React.FunctionComponent>
+ leadingVisual?: React.FunctionComponent>
/**
* The trailing icon comes after button content
*/
- trailingIcon?: React.FunctionComponent>
+ trailingVisual?: React.FunctionComponent>
/**
* Trailing action appears to the right of the trailing visual and is always locked to the end
*/
diff --git a/src/PageHeader/PageHeader.stories.tsx b/src/PageHeader/PageHeader.stories.tsx
index c781473185d..219321ecc9b 100644
--- a/src/PageHeader/PageHeader.stories.tsx
+++ b/src/PageHeader/PageHeader.stories.tsx
@@ -203,7 +203,7 @@ const Template: Story = args => (
-
+
Main
diff --git a/src/PageHeader/examples.stories.tsx b/src/PageHeader/examples.stories.tsx
index f84411de157..9fad6bd7c62 100644
--- a/src/PageHeader/examples.stories.tsx
+++ b/src/PageHeader/examples.stories.tsx
@@ -127,7 +127,7 @@ export const PullRequestPage = () => (
Edit
- Code
+ Code
@@ -182,7 +182,7 @@ export const FilesPage = () => (
Files
-
+
Main
diff --git a/src/UnderlineNav2/styles.ts b/src/UnderlineNav2/styles.ts
index cf39342086f..b26b8a52e3b 100644
--- a/src/UnderlineNav2/styles.ts
+++ b/src/UnderlineNav2/styles.ts
@@ -72,7 +72,7 @@ export const moreBtnStyles = {
boxShadow: 'none',
paddingY: 1,
paddingX: 2,
- '& > span[data-component="trailingIcon"]': {
+ '& > span[data-component="trailingVisual"]': {
marginLeft: 0,
},
}
diff --git a/src/__tests__/Button.types.test.tsx b/src/__tests__/Button.types.test.tsx
index 5509e866d18..6229d249a10 100644
--- a/src/__tests__/Button.types.test.tsx
+++ b/src/__tests__/Button.types.test.tsx
@@ -10,8 +10,8 @@ export function ShouldAcceptKnownButtonPropsAndDomProps() {
return (
<>>}
- trailingIcon={() => <>>}
+ leadingVisual={() => <>>}
+ trailingVisual={() => <>>}
size="medium"
variant="primary"
disabled
diff --git a/src/__tests__/__snapshots__/Button.test.tsx.snap b/src/__tests__/__snapshots__/Button.test.tsx.snap
index d81764ef5c2..814dd347e38 100644
--- a/src/__tests__/__snapshots__/Button.test.tsx.snap
+++ b/src/__tests__/__snapshots__/Button.test.tsx.snap
@@ -1608,10 +1608,6 @@ exports[`Button styles invisible button appropriately 1`] = `
color: accent.fg;
}
-.c0:has([data-component="ButtonCounter"]) {
- color: btn.text;
-}
-
@media (forced-colors:active) {
.c0:focus {
outline: solid 1px transparent;
diff --git a/src/__tests__/__snapshots__/TextInput.test.tsx.snap b/src/__tests__/__snapshots__/TextInput.test.tsx.snap
index 4b72e6ebeb5..b73523e31ab 100644
--- a/src/__tests__/__snapshots__/TextInput.test.tsx.snap
+++ b/src/__tests__/__snapshots__/TextInput.test.tsx.snap
@@ -1426,10 +1426,6 @@ exports[`TextInput renders trailingAction icon button 1`] = `
color: #0969da;
}
-.c4:has([data-component="ButtonCounter"]) {
- color: #24292f;
-}
-
.c4[data-component="IconButton"] {
width: var(--inner-action-size);
height: var(--inner-action-size);
@@ -2053,10 +2049,6 @@ exports[`TextInput renders trailingAction text button 1`] = `
color: #0969da;
}
-.c3:has([data-component="ButtonCounter"]) {
- color: #24292f;
-}
-
.c3[data-component="IconButton"] {
width: var(--inner-action-size);
height: var(--inner-action-size);
@@ -2441,10 +2433,6 @@ exports[`TextInput renders trailingAction text button with a tooltip 1`] = `
color: #0969da;
}
-.c4:has([data-component="ButtonCounter"]) {
- color: #24292f;
-}
-
.c4[data-component="IconButton"] {
width: var(--inner-action-size);
height: var(--inner-action-size);
diff --git a/src/drafts/MarkdownEditor/_Footer.tsx b/src/drafts/MarkdownEditor/_Footer.tsx
index 077b418598f..8b94cc5a295 100644
--- a/src/drafts/MarkdownEditor/_Footer.tsx
+++ b/src/drafts/MarkdownEditor/_Footer.tsx
@@ -64,7 +64,7 @@ const FileUploadButton = memo(({fileDraggedOver, ...props}: Partial
return (
{
@@ -88,7 +88,7 @@ const MarkdownSupportedHint = memo(() => {
return (
) : (
-
+
{label}
)}
diff --git a/src/stories/ActionMenu/examples.stories.tsx b/src/stories/ActionMenu/examples.stories.tsx
index 975e7e13a27..c1b2596a615 100644
--- a/src/stories/ActionMenu/examples.stories.tsx
+++ b/src/stories/ActionMenu/examples.stories.tsx
@@ -89,7 +89,7 @@ export function SingleSelection(): JSX.Element {
This pattern has a single section with the selected value shown in the button
-
+
{selectedType.name}
@@ -122,7 +122,7 @@ export function SingleSelectionWithPlaceholder(): JSX.Element {
This pattern has a placeholder in menu button when no value is selected yet
-
+
{selectedType.name || 'Pick a field type'}
@@ -158,7 +158,7 @@ export function GroupsAndDescription(): JSX.Element {
aria-label="Milestone"
aria-describedby="selected-milestone"
variant="invisible"
- trailingIcon={GearIcon}
+ trailingVisual={GearIcon}
>
Milestone
@@ -243,7 +243,7 @@ export function MultipleSelection(): JSX.Element {
-
+
Assignees
@@ -294,7 +294,7 @@ export function MixedSelection(): JSX.Element {
-
+
{selectedOption ? `Group by ${selectedOption.text}` : 'Group items by'}
diff --git a/src/stories/ActionMenu/fixtures.stories.tsx b/src/stories/ActionMenu/fixtures.stories.tsx
index b0bf0b445cc..70701010381 100644
--- a/src/stories/ActionMenu/fixtures.stories.tsx
+++ b/src/stories/ActionMenu/fixtures.stories.tsx
@@ -64,7 +64,7 @@ export function ActionsStory(): JSX.Element {
Actions
-
+
@@ -548,7 +548,7 @@ export function MemexAddColumn(): JSX.Element {
-
+
{selectedType.name}
diff --git a/src/stories/Overlay.stories.tsx b/src/stories/Overlay.stories.tsx
index d26b57ab871..fac71ecdd70 100644
--- a/src/stories/Overlay.stories.tsx
+++ b/src/stories/Overlay.stories.tsx
@@ -306,7 +306,7 @@ export const NestedOverlays = () => {
variant="invisible"
ref={secondaryButtonRef}
sx={{px: 2, mx: 2, display: 'flex'}}
- leadingIcon={PlusIcon}
+ leadingVisual={PlusIcon}
onClick={() => setCreateListOverlayOpen(!createListOverlayOpen)}
>
Create list
diff --git a/src/stories/deprecated/ActionMenu.stories.tsx b/src/stories/deprecated/ActionMenu.stories.tsx
index c269dd642e8..ed4b2b98343 100644
--- a/src/stories/deprecated/ActionMenu.stories.tsx
+++ b/src/stories/deprecated/ActionMenu.stories.tsx
@@ -196,7 +196,7 @@ export function ComplexListStory(): JSX.Element {
groupId: '1',
renderItem: props => ,
trailingText: '⌘S', // backward compatible
- trailingIcon: ArrowRightIcon, // backward compatible
+ trailingVisual: ArrowRightIcon, // backward compatible
},
{
leadingVisual: NoteIcon,