Skip to content

Releases: primer/react

@primer/react@38.32.0

Choose a tag to compare

@primer primer released this 13 Jul 14:07
Immutable release. Only release title and notes can be modified.
c11a00e

Minor Changes

  • #8133 0cb8e17 Thanks @iansan5653! - UnderlineNav: Replaced dynamic icon visibility with static breakpoints to avoid flickering. Breakpoints customizable via the hideIconsBreakpoint prop.

  • #8112 50face0 Thanks @llastflowers! - Add data-component attributes and associated tests for:

    SplitPageLayout
    Stack
    StateLabel
    SubNav
    TabNav
    Text
    TextArea
    ThemeProvider

Patch Changes

  • #7901 8288ed9 Thanks @mattcosta7! - PageHeader: improve rendering performance by removing expensive :has() selectors. No visual or API changes.

  • #8115 07c530a Thanks @mattcosta7! - Improve rendering performance in Safari by removing expensive :has() selectors from ActionList/NavList, Breadcrumbs, SelectPanel, and SegmentedControl. No visual or API changes.

  • #8024 18e3b7d Thanks @mattcosta7! - ToggleSwitch: Fire onChange from the user interaction instead of an effect, so it no longer fires on mount or when a controlled checked value changes externally.

  • #8035 723f4d6 Thanks @mattcosta7! - UnderlineNav, ActionBar: Detect item overflow with a single shared IntersectionObserver per component instead of one observer per item, reducing observer churn during resize. No public API changes.

  • #8001 4edc824 Thanks @mattcosta7! - useMedia now reads the live matchMedia value on the first client render instead of after an effect, removing a redundant render pass. defaultState is only used for the SSR/hydration snapshot (no public API changes).

  • #8023 71fa75c Thanks @mattcosta7! - FormControl: Avoid an extra re-render when showing a validation message.

@primer/react@38.31.0

Choose a tag to compare

@primer primer released this 06 Jul 16:32
Immutable release. Only release title and notes can be modified.
a360e09

Minor Changes

  • #8057 0b9c81e Thanks @francinelucca! - ThemeProvider: Remove primer_react_theme_provider_remove_ssr_handoff feature flag.

  • #8105 be2950f Thanks @joshblack! - React Compiler: Enable compiler output for Banner, ConfirmationDialog, PageLayout, Pagination, UnderlineNav, useMergedRefs, and useScrollFlash

Patch Changes

  • #8066 dd66aa2 Thanks @janmaarten-a11y! - Fix invalid HTML nesting in ActionList.Heading by applying the visually-hidden styles directly to the heading element instead of wrapping it in a span.

  • #8054 1775f2e Thanks @joshblack! - AvatarStack: Improve rendering performance with React Compiler support

  • #8053 b2151ae Thanks @joshblack! - Checkbox, CheckboxGroup, and RadioGroup: Improve rendering performance with React Compiler support

  • #8052 a1b24cf Thanks @joshblack! - Heading, Link, Pagehead, Portal, and SideNav: Improve rendering performance with React Compiler support

@primer/react@38.30.0

Choose a tag to compare

@primer primer released this 29 Jun 08:15
Immutable release. Only release title and notes can be modified.
0d3d8a2

Minor Changes

  • #8048 0add561 Thanks @copilot-swe-agent! - ActionBar: Add ActionBar.Button for rendering text buttons that overflow into the menu, alongside the existing ActionBar.IconButton

  • #8031 cb79351 Thanks @janmaarten-a11y! - Add a NavList.Heading slot that names the navigation region. It renders an h2
    by default (configurable to h3 via as), supports a visuallyHidden variant,
    labels the nav landmark via aria-labelledby, and makes NavList.Group
    headings default to one level deeper (h3, or h4 under an h3 heading) for a
    correct heading hierarchy.

  • #7991 b906268 Thanks @llastflowers! - Add data-component attributes and associated tests for:

    Radio
    RadioGroup
    RelativeTime
    ScrollableRegion
    SegmentedControl
    Select
    SideNav
    SkeletonBox
    SkeletonAvatar
    SkeletonText
    Spinner

  • #8026 73a45df Thanks @TylerJDev! - SelectPanel: Add cssAnchorPositioningSettings prop to customize CSS anchor positioning behavior

  • #7506 e58907c Thanks @iansan5653! - Refactors UnderlineNav overflow handling to use CSS-based overflow detection instead of JavaScript width measurements, eliminating layout shift (CLS) issues and improving performance. The overflow menu is now implemented with ActionMenu, and item registration uses a descendant registry instead of the React.Children API. Consumer-facing changes: items can now be wrapped in fragments or wrapper components; the current item may appear in the overflow menu when the viewport is narrow; and the overflow menu button is right-aligned.

Patch Changes

  • #8021 6131a94 Thanks @mattcosta7! - Announce, AriaStatus, AriaAlert: Avoid an extra React render on every content change (e.g. per keystroke when tied to an input)

  • #7935 5b3c806 Thanks @copilot-swe-agent! - ConfirmationDialog: useConfirm/confirm now removes its host element from document.body after the dialog is closed, and uses a fresh host element per call, so the empty container no longer lingers or leaks into other components and tests

  • #8007 f052126 Thanks @copilot-swe-agent! - Improve style-recalc performance by making ButtonGroup, DataTable Pagination, and Checkbox CSS selectors bucketable (removing universal */:not([attr]) subjects and :is() selector-list merges)

  • #8021 6131a94 Thanks @mattcosta7! - Textarea: Improve typing performance by deriving the character counter in render instead of in effects, removing extra re-renders on each keystroke.

  • #8021 6131a94 Thanks @mattcosta7! - TextInput: Improve typing performance by deriving the character counter in render instead of in effects, removing extra re-renders on each keystroke.

@primer/mcp@0.4.0

Choose a tag to compare

@primer primer released this 29 Jun 08:15
Immutable release. Only release title and notes can be modified.
0d3d8a2

Minor Changes

  • #8058 0a49d7d Thanks @mattobee! - MCP server: Add Copy, Delete, Filter and Search scenario patterns to the list_patterns and get_pattern tools. Scenario patterns take precedence over UI patterns when a name matches.

Patch Changes

@primer/react@38.29.0

Choose a tag to compare

@primer primer released this 18 Jun 20:04
Immutable release. Only release title and notes can be modified.
195cf4e

Minor Changes

  • #8009 2cf75b5 Thanks @joshblack! - Update CSS build options to compile down :is() selectors

  • #7994 8cb7f6d Thanks @TylerJDev! - ActionList: Adds tooltipDirection prop to ActionList.TrailingAction

  • #7867 4ec4248 Thanks @llastflowers! - Add data-component attributes and associated tests for ActionMenu, AnchoredOverlay, Autocomplete, and NavList

  • #7897 1f7b8af Thanks @liuliu-dev! - Add support for the as prop on TreeView.Item. This enables rendering the
    treeitem as a different element (e.g. as="a" for native anchors, or a custom
    router-link component) while preserving all existing keyboard, focus, and ARIA
    behavior.

    When as is omitted, the existing markup is unchanged: an <li> is rendered
    as the role="treeitem" element. When as is provided, the polymorphic
    element is rendered as the treeitem and is wrapped in an <li role="none">
    so the markup remains valid (a <ul role="tree"> may only directly contain
    <li> elements).

Patch Changes

  • #7976 1fac927 Thanks @copilot-swe-agent! - NavList: add a small gap between items for readability, including before expanded sub-navs, behind the primer_react_action_list_item_gap feature flag

  • #7999 eada357 Thanks @copilot-swe-agent! - Breadcrumbs: Improve rendering performance and refresh the overflow menu when breadcrumb content changes without changing the number of items.

  • #7929 48c34ca Thanks @joshblack! - FilteredActionList: Make body skeleton widths stable for server rendering

  • #7985 969c874 Thanks @joshblack! - AnchoredOverlay: Render the popover target attribute correctly for popover anchors

  • #7984 06fdad4 Thanks @joshblack! - CircleBadge, ActionList: Prevent internal props from rendering on DOM elements

  • #7978 e3f655c Thanks @copilot-swe-agent! - PageHeader.ParentLink: Forward unknown props (e.g. to) to the underlying element, enabling client-side routing with polymorphic as.

  • #7930 f32ac0f Thanks @copilot-swe-agent! - Blankslate: reduce size="small" padding to var(--base-size-16) for denser layouts

@primer/react@38.28.0

Choose a tag to compare

@primer primer released this 12 Jun 15:31
f590c21

Minor Changes

  • #7888 45be31b Thanks @TylerJDev! - AnchoredOverlay: Extend cssAnchorPositioningSettings with a fallbackStrategy ('default' | 'none' | 'opposite-side') to control CSS anchor positioning fallback behavior when native CSS anchor positioning is active.

  • #7923 6a7e130 Thanks @dylanatsmith! - Card: Add layout="compact" prop for a compact card layout with tighter spacing, no icon background, and smaller title

  • #7922 55b7b04 Thanks @dylanatsmith! - InlineMessage: Make variant prop optional, defaulting to the standard foreground color with an info icon

  • #7889 3af5edc Thanks @llastflowers! - Add data-component attributes and associated tests for PageHeader, PageLayout, Pagehead, Popover, Portal, and ProgressBar

  • #7964 0f0f79f Thanks @TylerJDev! - AnchoredOverlay: Add cssAnchorPositioningSettings prop to allow opting out of native CSS anchor positioning (via disable), and use it in SelectPanel so the modal variant stays manually centered instead of being repositioned by CSS anchor positioning.

Patch Changes

  • #7918 95986ce Thanks @jonrohan! - Autocomplete: Keep the typed text instead of restoring the full inline suggestion when the input loses focus, matching the behavior of pressing Escape

  • #7971 2087e87 Thanks @francinelucca! - ThemeProvider: Skip rendering the SSR handoff script when the primer_react_theme_provider_remove_ssr_handoff feature flag is enabled

  • #7910 0c38cfa Thanks @janmaarten-a11y! - Timeline: Add primer_react_timeline_list_semantics feature flag to opt into list semantics

    When the primer_react_timeline_list_semantics feature flag is enabled, Timeline renders as <ol role="list"> and Timeline.Item / Timeline.Break render as <li> so screen reader users get list navigation (total item count, position in sequence). The default behavior is unchanged — Timeline and its subcomponents still render as <div> until the flag is opted into.

    Enable the flag with the FeatureFlags provider:

    import {FeatureFlags} from '@primer/react/experimental'
    
    ;<FeatureFlags flags={{primer_react_timeline_list_semantics: true}}>
      <Timeline></Timeline>
    </FeatureFlags>

@primer/react@38.27.0

Choose a tag to compare

@primer primer released this 05 Jun 17:16
d829b12

Minor Changes

  • #7900 49a546f Thanks @mattcosta7! - PageLayout.Sidebar (and SplitPageLayout.Sidebar): add controlled-width support via currentWidth + onResizeEnd, matching the discriminated-union API already on PageLayout.Pane. The underlying usePaneWidth hook 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 or widthStorageKey-backed) behavior is preserved exactly.

  • #7906 adc5299 Thanks @jonrohan! - Text: Add whiteSpace prop to control the CSS white-space property

Patch Changes

  • #7915 f58e448 Thanks @jonrohan! - Dialog: Fix Escape key not closing the dialog on the first keypress when the close button is focused

  • #7908 e9a2254 Thanks @jonrohan! - KeybindingHint: display the Meta key correctly on platforms other than macOS and Windows. The Meta, Alt, and Mod keys are now resolved based on the detected platform: Apple platforms (macOS and iOS) show /, Windows shows Win, and all other platforms show Meta/Alt.

  • #7894 af4541d Thanks @mattcosta7! - ActionList: Replace :has(...) selectors on ActionList.Item, InactiveButtonWrap, and TrailingActionButton with 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 9659ce7 Thanks @mattcosta7! - TreeView: make rows safer to use with contain: paint / content-visibility: auto and 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: -8px of the row container) was being clipped when a consumer applied contain: paint to the <li> or when the documented containIntrinsicSize prop on TreeView.Item triggered content-visibility: auto on the row container — including for current items. Both .TreeViewItem and .TreeViewItemContainer now declare overflow-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. LoadingItem now communicates with the placeholder Item via a module-private context that emits a positive data-loading attribute 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-within descendant selector. Color is driven by an inherited --tree-line-color custom 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 .TreeViewItemLevelLine selectors against every level line in the tree.
    • Fixed a unitless outline-offset: -2 in 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's grid-template-columns now declares the trailingAction column explicitly (auto) so it matches the 5-area grid-template-areas declaration (previously the trailing column was implicit auto).

@primer/react@38.26.0

Choose a tag to compare

@primer primer released this 29 May 20:13
df9fd9b

Minor Changes

  • #7869 23fba52 Thanks @adierkens! - Slot system consistency improvements:

    • Remove orphan __SLOT__ markers from root components that no parent scans for: ActionMenu (root Menu), UnderlinePanels (root), Autocomplete is unchanged (still used as a FormControl child), PageLayout (root), SegmentedControl (root), RadioGroup (root), CheckboxGroup (root), and Dialog (root). Sub-component markers are intentionally retained so consumers can keep wrapping them.
    • Standardize Symbol(...) descriptions used as slot markers to the Parent.Slot convention: CheckboxOrRadioGroupLabelCheckboxOrRadioGroup.Label, CheckboxOrRadioGroupCaptionCheckboxOrRadioGroup.Caption, CheckboxOrRadioGroupValidationCheckboxOrRadioGroup.Validation, DEPRECATED_TooltipTooltip, and TableDataTable.Table.
    • Migrate PageHeader, NavList.Item, and the internal CheckboxOrRadioGroup to use the useSlots hook instead of hand-rolling React.Children traversal with isSlot. The CheckboxOrRadioGroup migration also removes duplicated work where useSlots was already called but slots were re-extracted by hand immediately after.
    • Export useSlots, isSlot, asSlot, and the WithSlotMarker/FCWithSlotMarker types publicly from @primer/react so 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 useSlots when a child's displayName matches a slot component's displayName but the child is missing the __SLOT__ marker — a common footgun when wrapping slot components.
  • #7898 da27739 Thanks @francinelucca! - ThemeProvider: Add contextOnly prop to opt out of rendering the wrapping <div> with data-* theme attributes

  • #7886 64dfbd3 Thanks @janmaarten-a11y! - Add Timeline.Actions sub-component for rendering action buttons, links, SHAs, status labels, and similar right-aligned content on a Timeline.Item. Renders as a horizontal flex row pushed to the right edge of the item with gap: 8px between children and min-height matching the badge so contents vertically center against it.

  • #7885 9d2cb53 Thanks @janmaarten-a11y! - Add Timeline.Avatar sub-component for rendering an actor avatar in the left gutter of a Timeline.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 the Timeline for the avatar to be visible.

Patch Changes

  • #7864 e7205ea Thanks @mattcosta7! - Eliminate nested-update cascades in useFocus, PageLayout.Pane, and
    AnchoredOverlay:

    • useFocus no 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 in startTransition so it runs in the transition lane rather
      than as part of the layout-effect commit.
    • AnchoredOverlay no longer keeps useAnchoredPosition's scroll
      listeners and ResizeObserver attached while it is closed. After an
      open→close cycle, the first scroll/resize event no longer fires a
      spurious setPosition(undefined) that re-renders the closed overlay.

    Also adds a profiler-based test harness at
    src/utils/testing/profiler.tsx so future regressions can be pinned with
    counter.updateCount and counter.nestedUpdateCount assertions.

  • #7892 4dd08af Thanks @TylerJDev! - AnchoredOverlay: Disable CSS anchor positioning if related CSS rules are not supported

  • #7878 8c468fd Thanks @mattcosta7! - FilteredActionList: Guard against undefined items in the virtualizer's getItemKey callback to prevent a crash when @tanstack/react-virtual invokes it with an index whose item was just removed (e.g. when filtering shrinks the items list).

  • #7893 0eef204 Thanks @mattcosta7! - Button: Replace the icon-only-with-counter :has(...):not(:has(...)) selector with a data-icon-only-counter attribute computed from props. Reduces style-recalculation cost on pages that render many Buttons. No visual or behavioral changes.

  • #7896 673514b Thanks @mattcosta7! - TextInput / TextInputWithTokens / Select / Autocomplete: Replace chained :not([data-leading-visual]), :not([data-trailing-visual]), and :not([data-trailing-action]) attribute negations in TextInputWrapper styles with positive data-no-leading-visual, data-no-trailing-visual, and data-no-trailing-action markers 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 980e94c Thanks @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 via useEffect), the list width is kept
    in a ref instead of state, and iconsVisible / loadingCounters flow to
    each tab via context — combined with React.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 8cc7e99 Thanks @mattcosta7! - Dev-only effects (the if (__DEV__) { useEffect(...) } pattern with an
    eslint-disable react-hooks/rules-of-hooks comment at every call site) are
    now expressed via a new internal useDevOnlyEffect hook. The lint
    suppression lives in the wrapper, the effect is dropped from production by
    the consumer's process.env.NODE_ENV replacement, and call sites get
    react-hooks/exhaustive-deps lint via additionalEffectHooks. No public
    API changes.

@primer/react@38.25.0

Choose a tag to compare

@primer primer released this 26 May 17:01
bb7a95a

Minor Changes

  • #7852 5504680 Thanks @liuliu-dev! - Card: Add data-component attributes to Card and its subcomponents (Icon, Image, Heading, Description, Metadata, Menu). Add an as prop ('div' | 'section') so standalone Cards can render as a labelled region landmark; as="section" requires aria-label or aria-labelledby. Card now requires children. Also improves docs and stories.

Patch Changes

@primer/react@38.24.0

Choose a tag to compare

@primer primer released this 20 May 15:52
509f46d

Minor Changes

  • #7829 228019c Thanks @adierkens! - ActionList: Add ActionList.GroupHeading.TrailingAction for header-level actions on grouped lists. Closes #2043.

    When the primer_react_action_list_group_heading_trailing_action feature flag is enabled, you can place an ActionList.GroupHeading.TrailingAction (a small invisible IconButton) inside ActionList.GroupHeading to render a uniform square action target next to the group's heading. Only supported inside an ActionList with the default list role — using it inside ActionMenu or with role="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 8ddf1b0 Thanks @llastflowers! - Add data-component attributes and associated tests for Hidden, InlineMessage, KeybindingHint, Label, and LabelGroup

  • #7776 d6f61c1 Thanks @llastflowers! - Add data-component attributes for Blankslate, BranchName, Breadcrumbs, ButtonGroup, Checkbox, CheckboxGroup, CircleBadge, ConfirmationDialog, CounterLabel, and Dialog to provide stable selectors.

  • #7816 aef8548 Thanks @iansan5653! - Replace ActionBar overflow calculations with CSS wrapping approach to improve performance and stability

  • #7831 0de97c2 Thanks @liuliu-dev! - Dialog: Support custom width values.

  • #7819 8ed6149 Thanks @llastflowers! - Add data-component attributes for Details, Flash, FormControl (+ update InputValidation to forward from FormControl.Validation), Header, and Heading.

Patch Changes