Releases: primer/react
@primer/react@38.27.0
Minor Changes
-
#7900
49a546fThanks @mattcosta7! -PageLayout.Sidebar(andSplitPageLayout.Sidebar): add controlled-width support viacurrentWidth+onResizeEnd, matching the discriminated-union API already onPageLayout.Pane. The underlyingusePaneWidthhook already supported these options; this wires them through the component's prop surface. Existing usage is unchanged — the props are opt-in and the uncontrolled (default orwidthStorageKey-backed) behavior is preserved exactly. -
#7906
adc5299Thanks @jonrohan! - Text: AddwhiteSpaceprop to control the CSSwhite-spaceproperty
Patch Changes
-
#7915
f58e448Thanks @jonrohan! - Dialog: FixEscapekey not closing the dialog on the first keypress when the close button is focused -
#7908
e9a2254Thanks @jonrohan! -KeybindingHint: display theMetakey correctly on platforms other than macOS and Windows. TheMeta,Alt, andModkeys are now resolved based on the detected platform: Apple platforms (macOS and iOS) show⌘/⌥, Windows showsWin, and all other platforms showMeta/Alt. -
#7894
af4541dThanks @mattcosta7! - ActionList: Replace:has(...)selectors onActionList.Item,InactiveButtonWrap, andTrailingActionButtonwith JS-derived data attributes (data-has-trailing-action,data-trailing-action-loading,data-position,data-has-label). Reduces style-recalculation cost on lists that render many items. No visual or behavioral changes. -
#7899
9659ce7Thanks @mattcosta7! -TreeView: make rows safer to use withcontain: paint/content-visibility: autoand reduce style-recalc cost on hover/focus in large trees. No visual or layout changes; all changes are either invisible at the default rendering or behind an opt-in CSS containment property the consumer sets.- The current-item indicator (positioned at
left: -8pxof the row container) was being clipped when a consumer appliedcontain: paintto the<li>or when the documentedcontainIntrinsicSizeprop onTreeView.Itemtriggeredcontent-visibility: autoon the row container — including forcurrentitems. Both.TreeViewItemand.TreeViewItemContainernow declareoverflow-clip-margin: var(--base-size-8), which extends the paint-clip edge by 8px on the side the indicator paints. The property is a no-op when no paint containment is active, so default rendering is byte-identical. - Skeleton-row hover suppression no longer relies on
:has(.TreeViewItemSkeleton), which forced subtree invalidation on every row.LoadingItemnow communicates with the placeholderItemvia a module-private context that emits a positivedata-loadingattribute on the<li>, and the CSS selector targets that directly. No new public prop. - Nesting indicator lines no longer use a root-scope
:hover/:focus-withindescendant selector. Color is driven by an inherited--tree-line-colorcustom property set on the root<ul>, so a hover or focus change inside the tree updates one property on one element instead of re-matching.TreeViewItemLevelLineselectors against every level line in the tree. - Fixed a unitless
outline-offset: -2in the forced-colors focus-ring fallback that browsers were silently dropping (so forced-colors users now actually get a focus indicator on tree items). .TreeViewItemContainer'sgrid-template-columnsnow declares thetrailingActioncolumn explicitly (auto) so it matches the 5-areagrid-template-areasdeclaration (previously the trailing column was implicitauto).
- The current-item indicator (positioned at
@primer/react@38.26.0
Minor Changes
-
#7869
23fba52Thanks @adierkens! - Slot system consistency improvements:- Remove orphan
__SLOT__markers from root components that no parent scans for:ActionMenu(rootMenu),UnderlinePanels(root),Autocompleteis unchanged (still used as aFormControlchild),PageLayout(root),SegmentedControl(root),RadioGroup(root),CheckboxGroup(root), andDialog(root). Sub-component markers are intentionally retained so consumers can keep wrapping them. - Standardize
Symbol(...)descriptions used as slot markers to theParent.Slotconvention:CheckboxOrRadioGroupLabel→CheckboxOrRadioGroup.Label,CheckboxOrRadioGroupCaption→CheckboxOrRadioGroup.Caption,CheckboxOrRadioGroupValidation→CheckboxOrRadioGroup.Validation,DEPRECATED_Tooltip→Tooltip, andTable→DataTable.Table. - Migrate
PageHeader,NavList.Item, and the internalCheckboxOrRadioGroupto use theuseSlotshook instead of hand-rollingReact.Childrentraversal withisSlot. TheCheckboxOrRadioGroupmigration also removes duplicated work whereuseSlotswas already called but slots were re-extracted by hand immediately after. - Export
useSlots,isSlot,asSlot, and theWithSlotMarker/FCWithSlotMarkertypes publicly from@primer/reactso downstream consumers can build their own slot-aware compound components. - Add
asSlot(component, slotSource)helper: a typed utility that copies a__SLOT__marker from a source slot component onto a wrapper component, replacing the cast-heavy(Wrapper as typeof Wrapper & {__SLOT__?: symbol}).__SLOT__ = Source.__SLOT__pattern. - Add a dev-mode warning in
useSlotswhen a child'sdisplayNamematches a slot component'sdisplayNamebut the child is missing the__SLOT__marker — a common footgun when wrapping slot components.
- Remove orphan
-
#7898
da27739Thanks @francinelucca! - ThemeProvider: AddcontextOnlyprop to opt out of rendering the wrapping<div>withdata-*theme attributes -
#7886
64dfbd3Thanks @janmaarten-a11y! - AddTimeline.Actionssub-component for rendering action buttons, links, SHAs, status labels, and similar right-aligned content on aTimeline.Item. Renders as a horizontal flex row pushed to the right edge of the item withgap: 8pxbetween children andmin-heightmatching the badge so contents vertically center against it. -
#7885
9d2cb53Thanks @janmaarten-a11y! - AddTimeline.Avatarsub-component for rendering an actor avatar in the left gutter of aTimeline.Item. Accepts any React children and is absolutely positioned so it does not affect badge or body layout. Consumers must reserve roughly 72px of left padding around theTimelinefor the avatar to be visible.
Patch Changes
-
#7864
e7205eaThanks @mattcosta7! - Eliminate nested-update cascades inuseFocus,PageLayout.Pane, and
AnchoredOverlay:useFocusno longer produces a second re-render after focusing; one
focus()call now results in exactly one render instead of two.PageLayout.Pane(resizable) no longer triggers a forced re-render
before paint on mount. The CSS variable and ARIA attributes are still
updated synchronously in the layout effect; the React state sync is
wrapped instartTransitionso it runs in the transition lane rather
than as part of the layout-effect commit.AnchoredOverlayno longer keepsuseAnchoredPosition's scroll
listeners andResizeObserverattached while it is closed. After an
open→close cycle, the first scroll/resize event no longer fires a
spurioussetPosition(undefined)that re-renders the closed overlay.
Also adds a profiler-based test harness at
src/utils/testing/profiler.tsxso future regressions can be pinned with
counter.updateCountandcounter.nestedUpdateCountassertions. -
#7892
4dd08afThanks @TylerJDev! - AnchoredOverlay: Disable CSS anchor positioning if related CSS rules are not supported -
#7878
8c468fdThanks @mattcosta7! - FilteredActionList: Guard againstundefineditems in the virtualizer'sgetItemKeycallback to prevent a crash when@tanstack/react-virtualinvokes it with an index whose item was just removed (e.g. when filtering shrinks the items list). -
#7893
0eef204Thanks @mattcosta7! - Button: Replace the icon-only-with-counter:has(...):not(:has(...))selector with adata-icon-only-counterattribute computed from props. Reduces style-recalculation cost on pages that render many Buttons. No visual or behavioral changes. -
#7896
673514bThanks @mattcosta7! - TextInput / TextInputWithTokens / Select / Autocomplete: Replace chained:not([data-leading-visual]),:not([data-trailing-visual]), and:not([data-trailing-action])attribute negations inTextInputWrapperstyles with positivedata-no-leading-visual,data-no-trailing-visual, anddata-no-trailing-actionmarkers emitted by the wrapper components. Eliminates the 2- and 3-deep:not()chains that previously evaluated against every input on every state change. No visual or behavioral changes. -
#7876
980e94cThanks @mattcosta7! - UnderlinePanels: Eliminate the empty-tablist frame on mount and the cascading
re-render when icons toggle. Tabs and panels are now derived in render
(previously stored in state synced viauseEffect), the list width is kept
in a ref instead of state, andiconsVisible/loadingCountersflow to
each tab via context — combined withReact.memo(Tab), that makes
resize-driven icon toggles update only the part of each tab that depends on
the change, not the whole tablist subtree. Behavior is unchanged. -
#7874
8cc7e99Thanks @mattcosta7! - Dev-only effects (theif (__DEV__) { useEffect(...) }pattern with an
eslint-disable react-hooks/rules-of-hookscomment at every call site) are
now expressed via a new internaluseDevOnlyEffecthook. The lint
suppression lives in the wrapper, the effect is dropped from production by
the consumer'sprocess.env.NODE_ENVreplacement, and call sites get
react-hooks/exhaustive-depslint viaadditionalEffectHooks. No public
API changes.
@primer/react@38.25.0
Minor Changes
- #7852
5504680Thanks @liuliu-dev! - Card: Adddata-componentattributes toCardand its subcomponents (Icon,Image,Heading,Description,Metadata,Menu). Add anasprop ('div' | 'section') so standalone Cards can render as a labelled region landmark;as="section"requiresaria-labeloraria-labelledby.Cardnow requireschildren. Also improves docs and stories.
Patch Changes
-
#7858
1ce2906Thanks @TylerJDev! - AnchoredOverlay: Add additional fallbacks for CSS Anchor Positioning -
#7843
fc571fdThanks @joshblack! - Update useMergedRefs so that in React 18 no warning is emitted
@primer/react@38.24.0
Minor Changes
-
#7829
228019cThanks @adierkens! - ActionList: AddActionList.GroupHeading.TrailingActionfor header-level actions on grouped lists. Closes #2043.When the
primer_react_action_list_group_heading_trailing_actionfeature flag is enabled, you can place anActionList.GroupHeading.TrailingAction(a small invisibleIconButton) insideActionList.GroupHeadingto render a uniform square action target next to the group's heading. Only supported inside anActionListwith the defaultlistrole — using it insideActionMenuor withrole="listbox"will throw.<ActionList> <ActionList.Group> <ActionList.GroupHeading as="h3"> Custom fields <ActionList.GroupHeading.TrailingAction label="New field" icon={PlusIcon} /> </ActionList.GroupHeading> <ActionList.Item>...</ActionList.Item> </ActionList.Group> </ActionList>
-
#7838
8ddf1b0Thanks @llastflowers! - Add data-component attributes and associated tests for Hidden, InlineMessage, KeybindingHint, Label, and LabelGroup -
#7776
d6f61c1Thanks @llastflowers! - Adddata-componentattributes for Blankslate, BranchName, Breadcrumbs, ButtonGroup, Checkbox, CheckboxGroup, CircleBadge, ConfirmationDialog, CounterLabel, and Dialog to provide stable selectors. -
#7816
aef8548Thanks @iansan5653! - ReplaceActionBaroverflow calculations with CSS wrapping approach to improve performance and stability -
#7831
0de97c2Thanks @liuliu-dev! - Dialog: Support custom width values. -
#7819
8ed6149Thanks @llastflowers! - Adddata-componentattributes for Details, Flash, FormControl (+ update InputValidation to forward from FormControl.Validation), Header, and Heading.
Patch Changes
-
#7842
635357eThanks @joshblack! - DataTable: Treat zero as a populated value when sorting numeric columns -
#7824
6889235Thanks @jonrohan! - FixusePaneWidthtriggering unnecessary React re-renders on every window resize -
#7833
dfed7caThanks @copilot-swe-agent! - Timeline: Remove border override from TimelineBadge when variant is set
@primer/styled-react@1.0.8
Patch Changes
- #7800
ce88bdfThanks @francinelucca! - chore: forward @primer/react theming from @primer/styled-react under feature flag
@primer/react@38.23.0
Minor Changes
- #7817
51a7a28Thanks @francinelucca! - - ActionList: ExpandselectableRolesandlistRoleTypesto includetreeitemandtree.- Export
ActionListContainerContextasActionList.ContainerContext. - Export
useRovingTabIndexfrom the public API with additional configuration options (preventScrollanddependencies).
- Export
Patch Changes
-
#7805
8f8844eThanks @TylerJDev! - AnchoredOverlay: Disables CSS anchor positioning ifportalContainerNameis true. (behindprimer_react_css_anchor_positioningfeature flag) -
#7800
ce88bdfThanks @francinelucca! - chore: addprimer_react_styled_react_use_primer_theme_providersfeature flag to DefaultFeatureFlags -
#7802
872bf46Thanks @TylerJDev! - AnchoredOverlay: Ensure overlay fits within viewport by calculating viewport height + width (behindprimer_react_css_anchor_positioningfeature flag)
@primer/react@38.22.0
Minor Changes
- #7755
0e868f9Thanks @francinelucca! - feat: add ActionList, SelectPanel primitives exports and new FilteredActionList.Input components
Patch Changes
-
#7797
3e05935Thanks @liuliu-dev! - Breadcrumbs overflow menu no longer appears when there are only two crumb items. -
#7511
eb73deeThanks @RSoeborg! - Fix NavList parent item flicker during static-to-interactive transitions when navigating between current sub-items in a SubNav. -
#7619
68aaf61Thanks @hectahertz! - Memoize ActionMenu context values to prevent unnecessary re-renders of menu items -
#7708
d0fa0ffThanks @hectahertz! - perf(css): audit :has() selectors and add stylelint guard for Safari -
#7775
4b7e4caThanks @TylerJDev! - AnchoredOverlay: Ensure styles persist on anchors even when re-mounted (behind feature flag) -
#7780
8330aadThanks @francinelucca! - fix: Checkbox indeterminate state now persists on click if the state didn't change
@primer/react@38.21.1
@primer/react@38.21.0
Minor Changes
-
#7760
b2e0efdThanks @siddharthkp! - Deprecate theuseResponsiveValuehook. -
#7724
d813099Thanks @francinelucca! - Add stabledata-componentselectors to multiple components following ADR-023:- ActionBar
- ActionList and friends
- Button
- FilteredActionList and friends
- Link
- LinkButton
- Pagination
- SelectPanel and friends
- Table and friends
- TextInput
- TextInputWithTokens
- TooltipV2
This enables consumers to query and test components using stable selectors like
[data-component="Table.Row"]. -
#7766
b3f06f1Thanks @TylerJDev! - AnchoredOverlay: (Behind feature flag) Make popover API usage opt-in -
#7763
b288d6eThanks @liuliu-dev! - Add borderRadius prop to Card component.
Patch Changes
-
#7714
e974d9fThanks @hectahertz! - perf(ActionList): replace :has() selector with JS-computed attribute -
#7754
9e3fe4bThanks @liuliu-dev! - Breadcrumbs: On narrow viewports, only show the current page breadcrumb and the overflow menu whenoverflow="menu"is set. -
#7757
ed82a1eThanks @liuliu-dev! - SelectPanel: Lock body scroll when modal variant is on. -
#7734
421ebf0Thanks @llastflowers! - add data-component attributes for Avatar, AvatarStack, Banner, & BaseStyles
@primer/styled-react@1.0.6
Patch Changes
-
#7738
f5f2869Thanks @francinelucca! - ActionMenu, Table: Fix component mutation issue whereObject.assignwas modifying original@primer/reactcomponents. Now uses wrapper components to avoid side effects. -
#7728
6eb03b5Thanks @jonrohan! - Remove Overlay, CounterLabel, and ActionMenu from styled-react package -
#7743
8550be3Thanks @jonrohan! - Remove Token and Tooltip from@primer/styled-react -
#7726
2edb05aThanks @copilot-swe-agent! - Remove PageHeader from @primer/styled-react