diff --git a/.changeset/thirty-wasps-sleep.md b/.changeset/thirty-wasps-sleep.md new file mode 100644 index 00000000000..582d351b8f8 --- /dev/null +++ b/.changeset/thirty-wasps-sleep.md @@ -0,0 +1,5 @@ +--- +"@primer/react": minor +--- + +Remove the CSS module feature flag from Skeleton diff --git a/packages/react/src/experimental/Skeleton/FeatureFlag.tsx b/packages/react/src/experimental/Skeleton/FeatureFlag.tsx deleted file mode 100644 index 267b7ef5906..00000000000 --- a/packages/react/src/experimental/Skeleton/FeatureFlag.tsx +++ /dev/null @@ -1 +0,0 @@ -export const CSS_MODULE_FLAG = 'primer_react_css_modules_ga' diff --git a/packages/react/src/experimental/Skeleton/SkeletonAvatar.tsx b/packages/react/src/experimental/Skeleton/SkeletonAvatar.tsx index 5221154a39c..635b5e4bf39 100644 --- a/packages/react/src/experimental/Skeleton/SkeletonAvatar.tsx +++ b/packages/react/src/experimental/Skeleton/SkeletonAvatar.tsx @@ -1,36 +1,17 @@ import React, {type CSSProperties} from 'react' -import {getBreakpointDeclarations} from '../../utils/getBreakpointDeclarations' -import {get} from '../../constants' import {isResponsiveValue} from '../../hooks/useResponsiveValue' import type {AvatarProps} from '../../Avatar' import {DEFAULT_AVATAR_SIZE} from '../../Avatar/Avatar' import {SkeletonBox} from './SkeletonBox' import classes from './SkeletonAvatar.module.css' import {clsx} from 'clsx' -import {useFeatureFlag} from '../../FeatureFlags' import {merge} from '../../sx' -import {CSS_MODULE_FLAG} from './FeatureFlag' export type SkeletonAvatarProps = Pick & { /** Class name for custom styling */ className?: string } & Omit, 'size'> -const avatarSkeletonStyles = { - '&[data-component="SkeletonAvatar"]': { - borderRadius: '50%', - boxShadow: `0 0 0 1px ${get('colors.avatar.border')}`, - display: 'inline-block', - lineHeight: get('lineHeights.condensedUltra'), - height: 'var(--avatar-size)', - width: 'var(--avatar-size)', - }, - - '&[data-square]': { - borderRadius: 'clamp(4px, var(--avatar-size) - 24px, 6px)', - }, -} - export const SkeletonAvatar: React.FC = ({ size = DEFAULT_AVATAR_SIZE, square, @@ -40,40 +21,23 @@ export const SkeletonAvatar: React.FC = ({ }) => { const responsive = isResponsiveValue(size) const cssSizeVars = {} as Record - const enabled = useFeatureFlag(CSS_MODULE_FLAG) - const avatarSx = responsive - ? { - ...getBreakpointDeclarations( - size, - '--avatar-size' as keyof React.CSSProperties, - value => `${value || DEFAULT_AVATAR_SIZE}px`, - ), - ...avatarSkeletonStyles, - } - : { - '--avatar-size': `${size}px`, - ...avatarSkeletonStyles, - } - if (enabled) { - if (responsive) { - for (const [key, value] of Object.entries(size)) { - cssSizeVars[`--avatarSize-${key}`] = `${value}px` - } - } else { - cssSizeVars['--avatarSize-regular'] = `${size}px` + if (responsive) { + for (const [key, value] of Object.entries(size)) { + cssSizeVars[`--avatarSize-${key}`] = `${value}px` } + } else { + cssSizeVars['--avatarSize-regular'] = `${size}px` } return ( ) } diff --git a/packages/react/src/experimental/Skeleton/SkeletonBox.tsx b/packages/react/src/experimental/Skeleton/SkeletonBox.tsx index 8a8bcaea7b1..861dd5d56e3 100644 --- a/packages/react/src/experimental/Skeleton/SkeletonBox.tsx +++ b/packages/react/src/experimental/Skeleton/SkeletonBox.tsx @@ -1,13 +1,10 @@ import React from 'react' -import styled, {keyframes} from 'styled-components' -import sx, {merge, type SxProp} from '../../sx' -import {get} from '../../constants' -import {type CSSProperties, type HTMLProps} from 'react' -import {toggleStyledComponent} from '../../internal/utils/toggleStyledComponent' +import {merge, type SxProp} from '../../sx' +import {type CSSProperties} from 'react' import {clsx} from 'clsx' import classes from './SkeletonBox.module.css' -import {useFeatureFlag} from '../../FeatureFlags' -import {CSS_MODULE_FLAG} from './FeatureFlag' +import {defaultSxProp} from '../../utils/defaultSxProp' +import Box from '../../Box' type SkeletonBoxProps = { /** Height of the skeleton "box". Accepts any valid CSS `height` value. */ @@ -17,62 +14,39 @@ type SkeletonBoxProps = { /** The className of the skeleton box */ className?: string } & SxProp & - HTMLProps - -const shimmer = keyframes` - from { mask-position: 200%; } - to { mask-position: 0%; } -` - -const StyledSkeletonBox = toggleStyledComponent( - CSS_MODULE_FLAG, - 'div', - styled.div` - animation: ${shimmer}; - display: block; - background-color: var(--bgColor-muted, ${get('colors.canvas.subtle')}); - border-radius: 3px; - height: ${props => props.height || '1rem'}; - width: ${props => props.width}; - - @media (prefers-reduced-motion: no-preference) { - mask-image: linear-gradient(75deg, #000 30%, rgba(0, 0, 0, 0.65) 80%); - mask-size: 200%; - animation: ${shimmer}; - animation-duration: 1s; - animation-iteration-count: infinite; - } - - @media (forced-colors: active) { - outline: 1px solid transparent; - outline-offset: -1px; - } - - ${sx}; - `, -) + React.ComponentPropsWithoutRef<'div'> export const SkeletonBox = React.forwardRef(function SkeletonBox( - {height, width, className, style, ...props}, + {height, width, className, sx: sxProp = defaultSxProp, style, ...props}, ref, ) { - const enabled = useFeatureFlag(CSS_MODULE_FLAG) + if (sxProp !== defaultSxProp) { + return ( + + ) + } + return ( - diff --git a/packages/react/src/experimental/Skeleton/SkeletonText.tsx b/packages/react/src/experimental/Skeleton/SkeletonText.tsx index 08c2680363f..5babb759611 100644 --- a/packages/react/src/experimental/Skeleton/SkeletonText.tsx +++ b/packages/react/src/experimental/Skeleton/SkeletonText.tsx @@ -1,11 +1,8 @@ import React, {type CSSProperties, type HTMLProps} from 'react' -import Box from '../../Box' import {SkeletonBox} from './SkeletonBox' import classes from './SkeletonText.module.css' -import {useFeatureFlag} from '../../FeatureFlags' import {clsx} from 'clsx' import {merge} from '../../sx' -import {CSS_MODULE_FLAG} from './FeatureFlag' type SkeletonTextProps = { /** Size of the text that the skeleton is replacing. */ @@ -18,61 +15,6 @@ type SkeletonTextProps = { className?: string } & Omit, 'size'> -const skeletonTextStyles = { - '&[data-component="SkeletonText"]': { - '--font-size': 'var(--text-body-size-medium, 0.875rem)', - '--line-height': 'var(--text-body-lineHeight-medium, 1.4285)', - '--leading': 'calc(var(--font-size) * var(--line-height) - var(--font-size))', - borderRadius: 'var(--borderRadius-small, 0.1875rem)', - height: 'var(--font-size)', - marginBlock: 'calc(var(--leading) / 2)', - }, - '&[data-in-multiline="true"]': { - marginBlockEnd: 'calc(var(--leading) * 2)', - }, - '&[data-in-multiline="true"]:last-child': { - maxWidth: '65%', - minWidth: '50px', - marginBottom: 0, - }, - '@supports (margin-block: mod(1px, 1px))': { - '&[data-component="SkeletonText"]': { - '--leading': 'mod(var(--font-size) * var(--line-height), var(--font-size))', - }, - }, - '&[data-text-skeleton-size="display"], &[data-text-skeleton-size="titleLarge"]': { - borderRadius: 'var(--borderRadius-medium, 0.375rem)', - }, - '&[data-text-skeleton-size="display"]': { - '--font-size': 'var(--text-display-size, 2.5rem)', - '--line-height': 'var(--text-display-lineHeight, 1.4)', - }, - '&[data-text-skeleton-size="titleLarge"]': { - '--font-size': 'var(--text-title-size-large, 2.5rem)', - '--line-height': 'var(--text-title-lineHeight-large, 1.5)', - }, - '&[data-text-skeleton-size="titleMedium"]': { - '--font-size': 'var(--text-title-size-medium, 1.25rem)', - '--line-height': 'var(--text-title-lineHeight-medium, 1.6)', - }, - '&[data-text-skeleton-size="titleSmall"]': { - '--font-size': 'var(--text-title-size-small, 1rem)', - '--line-height': 'var(--text-title-lineHeight-small, 1.5)', - }, - '&[data-text-skeleton-size="subtitle"]': { - '--font-size': 'var(--text-subtitle-size, 1.25rem)', - '--line-height': 'var(--text-subtitle-lineHeight, 1.6)', - }, - '&[data-text-skeleton-size="bodyLarge"]': { - '--font-size': 'var(--text-body-size-large, 1rem)', - '--line-height': 'var(--text-body-lineHeight-large, 1.5)', - }, - '&[data-text-skeleton-size="bodySmall"]': { - '--font-size': 'var(--text-body-size-small, 0.75rem)', - '--line-height': 'var(--text-body-lineHeight-small, 1.6666)', - }, -} - export const SkeletonText: React.FC = ({ lines = 1, maxWidth, @@ -81,39 +23,22 @@ export const SkeletonText: React.FC = ({ style, ...rest }) => { - const enabled = useFeatureFlag(CSS_MODULE_FLAG) - if (lines < 2) { return ( ) } else { return ( - {Array.from({length: lines}, (_, index) => ( = ({ data-component="SkeletonText" data-in-multiline="true" data-text-skeleton-size={size} - sx={enabled ? {} : skeletonTextStyles} - className={clsx(className, {[classes.SkeletonText]: enabled})} + className={clsx(className, classes.SkeletonText)} {...rest} /> ))} - + ) } }