Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
151c588
removes Box usage from components, which sometimes includes removing …
mperrotti Sep 8, 2025
b290616
Merge branch 'main' of github.com:primer/react into mp/rm-box-from-co…
mperrotti Sep 8, 2025
d7d0ec6
fixes unsupported 'sx' prop usage in PageHeader.Title and PageHeader.…
mperrotti Sep 8, 2025
3828d07
makes Announce polymorphic again, fixes other issues revealed by unit…
mperrotti Sep 9, 2025
b5acc9d
moves some components to react-styled to continue supporting sx prop
mperrotti Sep 9, 2025
83aab73
Merge branch 'main' of github.com:primer/react into mp/rm-box-from-co…
mperrotti Sep 9, 2025
8702e20
revert sx prop removals that require styled-react additions
mperrotti Sep 10, 2025
15fd6ec
rm styled-react additions
mperrotti Sep 10, 2025
2c3eb6a
fixes type error in Pagination story args
mperrotti Sep 10, 2025
2482917
fixes ScrollableRegion className bug
mperrotti Sep 10, 2025
1b2faed
adds changeset
mperrotti Sep 10, 2025
3a16c86
Merge branch 'main' into mp/rm-box-from-components
mperrotti Sep 11, 2025
a0cfd10
Merge branch 'main' into mp/rm-box-from-components
mperrotti Sep 11, 2025
4014284
Merge branch 'main' into mp/rm-box-from-components
mperrotti Sep 12, 2025
4945a70
Merge branch 'main' of github.com:primer/react into mp/rm-box-from-co…
mperrotti Sep 12, 2025
e530c37
Merge branch 'mp/rm-box-from-components' of github.com:primer/react i…
mperrotti Sep 12, 2025
07c9ef3
replaces polymorphic2 with modern-polymorphic
mperrotti Sep 12, 2025
69e2619
fixes silly typo causing type errors
mperrotti Sep 12, 2025
f234b87
Merge branch 'main' into mp/rm-box-from-components
mperrotti Sep 12, 2025
dc16cc9
fixes type errors in Announce, AriaAlert, and AriaStatus
mperrotti Sep 12, 2025
d7794e5
Merge branch 'mp/rm-box-from-components' of github.com:primer/react i…
mperrotti Sep 12, 2025
e077c32
Merge branch 'main' of github.com:primer/react into mp/rm-box-from-co…
mperrotti Sep 15, 2025
02f350f
reverts changes to BranchName
mperrotti Sep 15, 2025
85482da
Merge branch 'main' into mp/rm-box-from-components
mperrotti Sep 15, 2025
1684a76
Merge branch 'main' into mp/rm-box-from-components
mperrotti Sep 16, 2025
83fdf72
Merge branch 'main' of github.com:primer/react into mp/rm-box-from-co…
mperrotti Sep 24, 2025
5827e14
Merge branch 'main' into mp/rm-box-from-components
mperrotti Sep 24, 2025
7abd43c
Merge branch 'main' into mp/rm-box-from-components
mperrotti Sep 26, 2025
07640ac
Merge branch 'main' into mp/rm-box-from-components
mperrotti Sep 26, 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/yummy-years-greet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': major
---

Removes usage of Box component from other components.
19 changes: 13 additions & 6 deletions packages/react/src/Button/ButtonBase.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, {forwardRef} from 'react'
import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../utils/polymorphic'
import Box from '../Box'
import styled from 'styled-components'
import sx from '../sx'
import type {SxProp} from '../sx'
import type {ButtonProps} from './types'
import {getAlignContentSize} from './styles'
import {useRefObjectAsForwardedRef} from '../hooks/useRefObjectAsForwardedRef'
Expand All @@ -15,6 +17,12 @@ import {clsx} from 'clsx'
import classes from './ButtonBase.module.css'
import {isElement} from 'react-is'

// TODO: remove this when we remove the `sx` prop from buttons
// Styled span component for button content that can handle sx prop
const BoxTemporaryWorkaround = styled.span<SxProp>`
${sx};
`

const renderModuleVisual = (
Visual: React.ElementType | React.ReactElement,
loading: boolean,
Expand Down Expand Up @@ -92,7 +100,7 @@ const ButtonBase = forwardRef(
className={block ? classes.ConditionalWrapper : undefined}
data-loading-wrapper
>
<Box
<BoxTemporaryWorkaround
as={Component}
sx={sxProp}
aria-disabled={loading ? true : undefined}
Expand Down Expand Up @@ -129,8 +137,7 @@ const ButtonBase = forwardRef(
)
) : (
<>
<Box
as="span"
<BoxTemporaryWorkaround
data-component="buttonContent"
sx={getAlignContentSize(alignContent)}
className={classes.ButtonContent}
Expand Down Expand Up @@ -182,7 +189,7 @@ const ButtonBase = forwardRef(
)
: null
}
</Box>
</BoxTemporaryWorkaround>
{
/* If there is a trailing action, render it unless the button is in a loading state
and there is no leading or trailing visual to replace with a loading spinner. */
Expand All @@ -196,7 +203,7 @@ const ButtonBase = forwardRef(
}
</>
)}
</Box>
</BoxTemporaryWorkaround>
{loading && (
<VisuallyHidden>
<AriaStatus id={loadingAnnouncementID}>{loadingAnnouncement}</AriaStatus>
Expand Down
2 changes: 2 additions & 0 deletions packages/react/src/Label/Label.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// TODO: merge https://github.com/primer/react/pull/6631 which removes `Box` usage
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll remove this comment now that this PR is "Ready for review"


import {clsx} from 'clsx'
import Box from '../Box'
import classes from './Label.module.css'
Expand Down
14 changes: 14 additions & 0 deletions packages/react/src/LabelGroup/LabelGroup.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.OverlayContainer {
align-items: flex-start;
display: flex;
}

.OverlayInner {
display: flex;
flex-wrap: wrap;
gap: var(--base-size-4);
}

.CloseButton {
flex-shrink: 0;
}
7 changes: 4 additions & 3 deletions packages/react/src/LabelGroup/LabelGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import VisuallyHidden from '../_VisuallyHidden'
import {AnchoredOverlay} from '../AnchoredOverlay'
import {Button, IconButton} from '../Button'
import {useTheme} from '../ThemeProvider'
import classes from './LabelGroup.module.css'

export type LabelGroupProps = {
/** Customize the element type of the rendered container */
Expand Down Expand Up @@ -132,14 +133,14 @@ const OverlayToggle: React.FC<
)}
focusZoneSettings={{disabled: true}}
>
<div style={{alignItems: 'flex-start', display: 'flex', width: overlayWidth, padding: `${overlayPaddingPx}px`}}>
<div style={{display: 'flex', flexWrap: 'wrap', gap: '4px'}}>{children}</div>
<div className={classes.OverlayContainer} style={{width: overlayWidth, padding: `${overlayPaddingPx}px`}}>
<div className={classes.OverlayInner}>{children}</div>
<IconButton
onClick={closeOverflowOverlay}
icon={XIcon}
aria-label="Close"
variant="invisible"
style={{flexShrink: 0}}
className={classes.CloseButton}
/>
</div>
</AnchoredOverlay>
Expand Down
8 changes: 8 additions & 0 deletions packages/react/src/NavList/NavList.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.GroupHeading > a {
color: var(--fgColor-default);
text-decoration: inherit;
}

.GroupHeading > a:hover {
text-decoration: underline;
}
4 changes: 4 additions & 0 deletions packages/react/src/Pagination/Pagination.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@
text-align: center;
}

.TablePaginationSteps {
display: inline-block;
}

@media screen and (--viewportRange-narrow) {
.TablePaginationSteps[data-hidden-viewport-ranges*='narrow'] > *:not(:first-child):not(:last-child) {
display: none;
Expand Down
6 changes: 0 additions & 6 deletions packages/react/src/Pagination/Pagination.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,4 @@ Playground.argTypes = {
disable: true,
},
},
theme: {
control: false,
table: {
disable: true,
},
},
}
28 changes: 8 additions & 20 deletions packages/react/src/Pagination/Pagination.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import React from 'react'
import Box from '../Box'
import {buildComponentData, buildPaginationModel, type PageDataProps} from './model'
import type {ResponsiveValue} from '../hooks/useResponsiveValue'
import {viewportRanges} from '../hooks/useResponsiveValue'
import {clsx} from 'clsx'
import classes from './Pagination.module.css'
import {BoxWithFallback} from '../internal/components/BoxWithFallback'

const getViewportRangesToHidePages = (showPages: PaginationProps['showPages']) => {
if (showPages && typeof showPages !== 'boolean') {
Expand Down Expand Up @@ -33,7 +31,6 @@ export type PageProps = {
} & Omit<PageDataProps['props'], 'as' | 'role'>

type UsePaginationPagesParameters = {
theme?: Record<string, unknown> // set to theme type once /src/theme.js is converted
pageCount: number
currentPage: number
onPageChange: (e: React.MouseEvent, n: number) => void
Expand All @@ -45,7 +42,6 @@ type UsePaginationPagesParameters = {
}

function usePaginationPages({
theme,
pageCount,
currentPage,
onPageChange,
Expand All @@ -67,22 +63,22 @@ function usePaginationPages({
if (renderPage && props.as !== 'span') {
return renderPage({key, children: content, number: page.num, className: classes.Page, ...props})
}
const Component = props.as || 'a'

return (
// @ts-ignore giving me grief about children and "as" props
<BoxWithFallback as="a" key={key} theme={theme} className={clsx(classes.Page)} {...props}>
<Component key={key} className={clsx(classes.Page)} {...props}>
{content}
</BoxWithFallback>
</Component>
)
})
}, [model, hrefBuilder, pageChange, renderPage, theme])
}, [model, hrefBuilder, pageChange, renderPage])

return children
}

export type PaginationProps = {
className?: string
theme?: Record<string, unknown>
pageCount: number
currentPage: number
onPageChange?: (e: React.MouseEvent, n: number) => void
Expand All @@ -95,7 +91,6 @@ export type PaginationProps = {

function Pagination({
className,
theme: _theme,
pageCount,
currentPage,
onPageChange = noop,
Expand All @@ -107,7 +102,6 @@ function Pagination({
...rest
}: PaginationProps) {
const pageElements = usePaginationPages({
theme: _theme,
pageCount,
currentPage,
onPageChange,
Expand All @@ -119,20 +113,14 @@ function Pagination({
})

return (
<BoxWithFallback
as="nav"
className={clsx(classes.PaginationContainer, className)}
aria-label="Pagination"
{...rest}
>
<Box
display="inline-block"
<nav className={clsx(classes.PaginationContainer, className)} aria-label="Pagination" {...rest}>
<div
className={classes.TablePaginationSteps}
data-hidden-viewport-ranges={getViewportRangesToHidePages(showPages).join(' ')}
>
{pageElements}
</Box>
</BoxWithFallback>
</div>
</nav>
)
}

Expand Down
13 changes: 13 additions & 0 deletions packages/react/src/Placeholder.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.Placeholder {
/* these are set in the component */
--placeholder-width: ;
--placeholder-height: ;

width: var(--placeholder-width, 100%);
height: var(--placeholder-height);
display: grid;
place-items: center;
background-color: var(--bgColor-inset);
border-radius: var(--borderRadius-medium);
border: var(--borderWidth-thin) solid var(--borderColor-muted);
}
23 changes: 10 additions & 13 deletions packages/react/src/Placeholder.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Box} from '.'
import type React from 'react'
import classes from './Placeholder.module.css'

/** Private component used to render placeholders in storybook and documentation examples */
export const Placeholder: React.FC<
Expand All @@ -11,20 +11,17 @@ export const Placeholder: React.FC<
}>
> = ({width, height, id, label}) => {
return (
<Box
<div
id={id}
sx={{
width: width ?? '100%',
height,
display: 'grid',
placeItems: 'center',
bg: 'canvas.inset',
borderRadius: 2,
border: '1px solid',
borderColor: 'border.subtle',
}}
className={classes.Placeholder}
style={
{
'--placeholder-width': typeof width === 'number' ? `${width}px` : width,
'--placeholder-height': typeof height === 'number' ? `${height}px` : height,
} as React.CSSProperties
}
>
{label}
</Box>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.ScrollableRegion {
/* When setting overflow, we also set `position: relative` to avoid
* `position: absolute` items breaking out of the container and causing
* scrollbars on the page. This can occur with common classes like `sr-only`
* and can cause difficult to track down layout issues */
position: relative;
overflow: auto;
}
17 changes: 5 additions & 12 deletions packages/react/src/ScrollableRegion/ScrollableRegion.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react'
import Box from '../Box'
import {clsx} from 'clsx'
import {useOverflow} from '../hooks/useOverflow'
import classes from './ScrollableRegion.module.css'

type Labelled =
| {
Expand All @@ -14,19 +15,11 @@ type Labelled =

type ScrollableRegionProps = React.ComponentPropsWithoutRef<'div'> & Labelled

const defaultStyles = {
// When setting overflow, we also set `position: relative` to avoid
// `position: absolute` items breaking out of the container and causing
// scrollbars on the page. This can occur with common classes like `sr-only`
// and can cause difficult to track down layout issues
position: 'relative',
overflow: 'auto',
}

function ScrollableRegion({
'aria-label': label,
'aria-labelledby': labelledby,
children,
className,
...rest
}: ScrollableRegionProps) {
const ref = React.useRef(null)
Expand All @@ -41,9 +34,9 @@ function ScrollableRegion({
: {}

return (
<Box {...rest} {...regionProps} ref={ref} sx={defaultStyles}>
<div {...rest} {...regionProps} ref={ref} className={clsx(classes.ScrollableRegion, className)}>
{children}
</Box>
</div>
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ exports[`TextInput > renders trailingAction icon button 1`] = `
<button
aria-describedby=":r23:-loading-announcement"
aria-labelledby=":r22:"
class="sc-aXZVg prc-Button-ButtonBase-Eb8-K prc-components-Invisible-6q42n prc-Button-IconButton-GE6m6"
class="sc-gEvEer dEeFcy prc-Button-ButtonBase-Eb8-K prc-components-Invisible-6q42n prc-Button-IconButton-GE6m6"
data-component="IconButton"
data-loading="false"
data-no-visuals="true"
Expand Down Expand Up @@ -352,15 +352,15 @@ exports[`TextInput > renders trailingAction text button 1`] = `
>
<button
aria-describedby=":r1p:-loading-announcement"
class="sc-aXZVg prc-Button-ButtonBase-Eb8-K prc-components-Invisible-6q42n"
class="sc-gEvEer dEeFcy prc-Button-ButtonBase-Eb8-K prc-components-Invisible-6q42n"
data-loading="false"
data-no-visuals="true"
data-size="medium"
data-variant="invisible"
type="button"
>
<span
class="sc-aXZVg jjaNhq prc-Button-ButtonContent-KZ5Bz"
class="sc-gEvEer bLWYQi prc-Button-ButtonContent-KZ5Bz"
data-component="buttonContent"
>
<span
Expand Down Expand Up @@ -395,15 +395,15 @@ exports[`TextInput > renders trailingAction text button with a tooltip 1`] = `
>
<button
aria-describedby=":r1u:-loading-announcement :r1t:"
class="sc-aXZVg prc-Button-ButtonBase-Eb8-K prc-components-Invisible-6q42n"
class="sc-gEvEer dEeFcy prc-Button-ButtonBase-Eb8-K prc-components-Invisible-6q42n"
data-loading="false"
data-no-visuals="true"
data-size="medium"
data-variant="invisible"
type="button"
>
<span
class="sc-aXZVg jjaNhq prc-Button-ButtonContent-KZ5Bz"
class="sc-gEvEer bLWYQi prc-Button-ButtonContent-KZ5Bz"
data-component="buttonContent"
>
<span
Expand Down
Loading
Loading