diff --git a/.changeset/replace-usetheme-with-theme.md b/.changeset/replace-usetheme-with-theme.md
new file mode 100644
index 00000000000..7ca53d2be74
--- /dev/null
+++ b/.changeset/replace-usetheme-with-theme.md
@@ -0,0 +1,5 @@
+---
+"@primer/react": major
+---
+
+Replaces `useTheme` usage with `theme`. If an application uses a custom theme that modifies one of the following 5 tokens, they will be reset to the default theme values. (`space.2, colors.success.fg, colors.border.default, colors.border.muted, animation.easeOutCubic`)
diff --git a/packages/react/src/ConfirmationDialog/ConfirmationDialog.features.stories.tsx b/packages/react/src/ConfirmationDialog/ConfirmationDialog.features.stories.tsx
index 4fa7a953b3f..f7e643e5413 100644
--- a/packages/react/src/ConfirmationDialog/ConfirmationDialog.features.stories.tsx
+++ b/packages/react/src/ConfirmationDialog/ConfirmationDialog.features.stories.tsx
@@ -1,7 +1,6 @@
import type React from 'react'
import {useState, useCallback} from 'react'
import type {Meta} from '@storybook/react-vite'
-import {useTheme} from '..'
import {Button} from '../Button'
import {ActionMenu} from '../ActionMenu'
import {ActionList} from '../ActionList'
@@ -15,18 +14,17 @@ export default {
export const ShorthandHook = () => {
const confirm = useConfirm()
- const {theme} = useTheme()
const onButtonClick = useCallback(
async (event: React.MouseEvent) => {
if (
(await confirm({title: 'Are you sure?', content: 'Do you really want to turn this button green?'})) &&
event.target instanceof HTMLElement
) {
- event.target.style.color = theme?.colors.success.fg ?? 'green'
+ event.target.style.color = 'var(--fgColor-success)'
event.target.textContent = "I'm green!"
}
},
- [confirm, theme],
+ [confirm],
)
return (
diff --git a/packages/react/src/LabelGroup/LabelGroup.tsx b/packages/react/src/LabelGroup/LabelGroup.tsx
index a5babffb2e4..fd7001d9758 100644
--- a/packages/react/src/LabelGroup/LabelGroup.tsx
+++ b/packages/react/src/LabelGroup/LabelGroup.tsx
@@ -6,7 +6,7 @@ import {get} from '../constants'
import VisuallyHidden from '../_VisuallyHidden'
import {AnchoredOverlay} from '../AnchoredOverlay'
import {Button, IconButton} from '../Button'
-import {useTheme} from '../ThemeProvider'
+import theme from '../theme'
import classes from './LabelGroup.module.css'
export type LabelGroupProps = {
@@ -171,9 +171,7 @@ const LabelGroup: React.FC
> = ({
toJSON: () => undefined,
})
- const {theme} = useTheme()
-
- const overlayPaddingPx = parseInt(get('space.2')(theme), 10)
+ const overlayPaddingPx = parseInt(theme.space[2], 10)
const hiddenItemIds = Object.keys(visibilityMap).filter(key => !visibilityMap[key])
diff --git a/packages/react/src/Overlay/Overlay.tsx b/packages/react/src/Overlay/Overlay.tsx
index ca84e09c668..89557b79c29 100644
--- a/packages/react/src/Overlay/Overlay.tsx
+++ b/packages/react/src/Overlay/Overlay.tsx
@@ -1,18 +1,17 @@
import type {ComponentPropsWithRef, ReactElement} from 'react'
import React, {useEffect, useRef} from 'react'
import useLayoutEffect from '../utils/useIsomorphicLayoutEffect'
-import {get} from '../constants'
import type {AriaRole, Merge} from '../utils/types'
import type {TouchOrMouseEvent} from '../hooks'
import {useOverlay} from '../hooks'
import Portal from '../Portal'
import {useRefObjectAsForwardedRef} from '../hooks/useRefObjectAsForwardedRef'
import type {AnchorSide} from '@primer/behaviors'
-import {useTheme} from '../ThemeProvider'
import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../utils/polymorphic'
import {useFeatureFlag} from '../FeatureFlags'
import classes from './Overlay.module.css'
import {clsx} from 'clsx'
+import theme from '../theme'
type StyledOverlayProps = {
width?: keyof typeof widthMap
@@ -192,9 +191,8 @@ const Overlay = React.forwardRef(
): ReactElement => {
const overlayRef = useRef(null)
useRefObjectAsForwardedRef(forwardedRef, overlayRef)
- const {theme} = useTheme()
- const slideAnimationDistance = parseInt(get('space.2')(theme).replace('px', ''))
- const slideAnimationEasing = get('animation.easeOutCubic')(theme)
+ const slideAnimationDistance = parseInt(theme.space[2], 10)
+ const slideAnimationEasing = theme.animation.easeOutCubic
useOverlay({
overlayRef,
diff --git a/packages/react/src/SegmentedControl/SegmentedControl.tsx b/packages/react/src/SegmentedControl/SegmentedControl.tsx
index a706f41a0ef..b7cb8760152 100644
--- a/packages/react/src/SegmentedControl/SegmentedControl.tsx
+++ b/packages/react/src/SegmentedControl/SegmentedControl.tsx
@@ -5,7 +5,6 @@ import type {SegmentedControlIconButtonProps} from './SegmentedControlIconButton
import SegmentedControlIconButton from './SegmentedControlIconButton'
import {ActionList} from '../ActionList'
import {ActionMenu} from '../ActionMenu'
-import {useTheme} from '../ThemeProvider'
import type {ResponsiveValue} from '../hooks/useResponsiveValue'
import {useResponsiveValue} from '../hooks/useResponsiveValue'
import type {WidthOnlyViewportRangeKeys} from '../utils/types/ViewportRangeKeys'
@@ -40,7 +39,6 @@ const Root: React.FC> = ({
...rest
}) => {
const segmentedControlContainerRef = useRef(null)
- const {theme} = useTheme()
const isUncontrolled =
onChange === undefined ||
React.Children.toArray(children).some(
@@ -176,7 +174,7 @@ const Root: React.FC> = ({
selected: index === selectedIndex,
style: {
'--separator-color':
- index === selectedIndex || index === selectedIndex - 1 ? 'transparent' : theme?.colors.border.default,
+ index === selectedIndex || index === selectedIndex - 1 ? 'transparent' : 'var(--borderColor-default)',
...child.props.style,
},
}
diff --git a/packages/react/src/UnderlineNav/UnderlineNav.tsx b/packages/react/src/UnderlineNav/UnderlineNav.tsx
index 0c8a417773d..24df16d225b 100644
--- a/packages/react/src/UnderlineNav/UnderlineNav.tsx
+++ b/packages/react/src/UnderlineNav/UnderlineNav.tsx
@@ -3,10 +3,9 @@ import React, {useRef, forwardRef, useCallback, useState, useEffect} from 'react
import {UnderlineNavContext} from './UnderlineNavContext'
import type {ResizeObserverEntry} from '../hooks/useResizeObserver'
import {useResizeObserver} from '../hooks/useResizeObserver'
-import {useTheme} from '../ThemeProvider'
import type {ChildWidthArray, ResponsiveProps, ChildSize} from './types'
import VisuallyHidden from '../_VisuallyHidden'
-import {moreBtnStyles, getDividerStyle, menuStyles, menuItemStyles, baseMenuStyles, baseMenuMinWidth} from './styles'
+import {moreBtnStyles, dividerStyles, menuStyles, menuItemStyles, baseMenuStyles, baseMenuMinWidth} from './styles'
import {UnderlineItemList, UnderlineWrapper, LoadingCounter, GAP} from '../internal/components/UnderlineTabbedInterface'
import styled from 'styled-components'
import {Button} from '../Button'
@@ -151,7 +150,6 @@ export const UnderlineNav = forwardRef(
const containerRef = React.useRef(null)
const disclosureWidgetId = useId()
- const {theme} = useTheme()
const [isWidgetOpen, setIsWidgetOpen] = useState(false)
const [iconsVisible, setIconsVisible] = useState(true)
const [childWidthArray, setChildWidthArray] = useState([])
@@ -298,7 +296,6 @@ export const UnderlineNav = forwardRef(
return (
0 && (
- {!onlyMenuVisible && }
+ {!onlyMenuVisible && }