From 9bd2f79070a2cd30fa99c0641e7acc0ed34c166b Mon Sep 17 00:00:00 2001 From: Jon Rohan Date: Thu, 19 Dec 2024 14:49:52 -0800 Subject: [PATCH 01/39] chore(Skeleton): Remove the CSS module feature flag from Skeleton (#5461) * Remove the CSS module feature flag from Skeleton * Create thirty-wasps-sleep.md --- .changeset/thirty-wasps-sleep.md | 5 ++ .../src/experimental/Skeleton/FeatureFlag.tsx | 1 - .../experimental/Skeleton/SkeletonAvatar.tsx | 50 ++--------- .../src/experimental/Skeleton/SkeletonBox.tsx | 90 +++++++------------ .../experimental/Skeleton/SkeletonText.tsx | 88 ++---------------- 5 files changed, 50 insertions(+), 184 deletions(-) create mode 100644 .changeset/thirty-wasps-sleep.md delete mode 100644 packages/react/src/experimental/Skeleton/FeatureFlag.tsx 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} /> ))} - + ) } } From 6d70d1bed593c73cb92c1185dd9709ae5da5d602 Mon Sep 17 00:00:00 2001 From: Jon Rohan Date: Thu, 19 Dec 2024 14:52:20 -0800 Subject: [PATCH 02/39] chore(Header): Remove CSS modules feature flag from Header (#5460) * Remove CSS modules feature flag from Header * Adjust Header for as prop * Create shaggy-comics-whisper.md --- .changeset/shaggy-comics-whisper.md | 5 + packages/react/src/Header/Header.tsx | 150 ++++++------------- packages/react/src/__tests__/Header.test.tsx | 2 +- 3 files changed, 52 insertions(+), 105 deletions(-) create mode 100644 .changeset/shaggy-comics-whisper.md diff --git a/.changeset/shaggy-comics-whisper.md b/.changeset/shaggy-comics-whisper.md new file mode 100644 index 00000000000..a665f985634 --- /dev/null +++ b/.changeset/shaggy-comics-whisper.md @@ -0,0 +1,5 @@ +--- +"@primer/react": minor +--- + +Remove CSS modules feature flag from Header diff --git a/packages/react/src/Header/Header.tsx b/packages/react/src/Header/Header.tsx index 33c7a6b7b0d..0d5c2c6efc8 100644 --- a/packages/react/src/Header/Header.tsx +++ b/packages/react/src/Header/Header.tsx @@ -1,139 +1,81 @@ import type {Location, Pathname} from 'history' -import styled, {css} from 'styled-components' -import {get} from '../constants' import type {SxProp} from '../sx' -import sx from '../sx' -import type {ComponentProps} from '../utils/types' -import {toggleStyledComponent} from '../internal/utils/toggleStyledComponent' -import {useFeatureFlag} from '../FeatureFlags' import React from 'react' import {clsx} from 'clsx' import classes from './Header.module.css' import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../utils/polymorphic' +import {defaultSxProp} from '../utils/defaultSxProp' +import Box from '../Box' -type StyledHeaderProps = React.ComponentProps<'header'> & SxProp -type StyledHeaderItemProps = React.ComponentProps<'div'> & SxProp & {full?: boolean} -type StyledHeaderLinkProps = React.ComponentProps<'a'> & SxProp & {to?: Location | Pathname} +export type HeaderProps = React.ComponentProps<'header'> & SxProp & {as?: React.ElementType} +export type HeaderItemProps = React.ComponentProps<'div'> & SxProp & {full?: boolean} +export type HeaderLinkProps = React.ComponentProps<'a'> & SxProp & {to?: Location | Pathname; as?: React.ElementType} -const CSS_MODULES_FEATURE_FLAG = 'primer_react_css_modules_ga' - -const StyledHeader = toggleStyledComponent( - CSS_MODULES_FEATURE_FLAG, - 'header', - styled.header` - z-index: 32; - display: flex; - padding: ${get('space.3')}; - font-size: ${get('fontSizes.1')}; - line-height: ${get('lineHeights.default')}; - color: ${get('colors.header.text')}; - background-color: ${get('colors.header.bg')}; - align-items: center; - flex-wrap: nowrap; - overflow: auto; - - ${sx}; - `, -) - -const Header = React.forwardRef(function Header( - {children, className, ...rest}, +const Header = React.forwardRef(function Header( + {children, className, sx: sxProp = defaultSxProp, as = 'header', ...rest}, forwardRef, ) { - const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG) + if (sxProp !== defaultSxProp || as !== 'header') { + return ( + + {children} + + ) + } return ( - +
{children} - +
) -}) as PolymorphicForwardRefComponent<'header', StyledHeaderProps> +}) as PolymorphicForwardRefComponent<'header', HeaderProps> Header.displayName = 'Header' -const StyledHeaderItem = toggleStyledComponent( - CSS_MODULES_FEATURE_FLAG, - 'div', - styled.div` - display: flex; - margin-right: ${get('space.3')}; - align-self: stretch; - align-items: center; - flex-wrap: nowrap; - - ${({full}) => - full && - css` - flex: auto; - `}; - - ${sx}; - `, -) - -const HeaderItem = React.forwardRef(function HeaderItem( - {children, className, ...rest}, +const HeaderItem = React.forwardRef(function HeaderItem( + {children, className, sx: sxProp = defaultSxProp, full, ...rest}, forwardRef, ) { - const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG) + if (sxProp !== defaultSxProp) { + return ( + + {children} + + ) + } return ( - +
{children} - +
) }) HeaderItem.displayName = 'Header.Item' -const StyledHeaderLink = toggleStyledComponent( - CSS_MODULES_FEATURE_FLAG, - 'a', - styled.a.attrs(({to}) => { - const isReactRouter = typeof to === 'string' - if (isReactRouter) { - // according to their docs, NavLink supports aria-current: - // https://reacttraining.com/react-router/web/api/NavLink/aria-current-string - return {'aria-current': 'page'} - } else { - return {} - } - })` - font-weight: ${get('fontWeights.bold')}; - color: ${get('colors.header.logo')}; - white-space: nowrap; - cursor: pointer; - text-decoration: none; - display: flex; - align-items: center; - - &:hover, - &:focus { - color: ${get('colors.header.text')}; - } - - ${sx}; - `, -) - -const HeaderLink = React.forwardRef(function HeaderLink( - {children, className, ...rest}, +const HeaderLink = React.forwardRef(function HeaderLink( + {children, className, sx: sxProp = defaultSxProp, as = 'a', ...rest}, forwardRef, ) { - const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG) + if (sxProp !== defaultSxProp || as !== 'a') { + return ( + + {children} + + ) + } return ( - + {children} - + ) }) HeaderLink.displayName = 'Header.Link' -export type HeaderProps = ComponentProps -export type HeaderLinkProps = ComponentProps -export type HeaderItemProps = ComponentProps export default Object.assign(Header, {Link: HeaderLink, Item: HeaderItem}) diff --git a/packages/react/src/__tests__/Header.test.tsx b/packages/react/src/__tests__/Header.test.tsx index e084cc9e8c6..02673ed76da 100644 --- a/packages/react/src/__tests__/Header.test.tsx +++ b/packages/react/src/__tests__/Header.test.tsx @@ -13,7 +13,7 @@ describe('Header', () => { }) describe('Header.Item', () => { - behavesAsComponent({Component: Header.Item}) + behavesAsComponent({Component: Header.Item, options: {skipAs: true}}) it('accepts and applies className', () => { expect(render().props.className).toContain('primer') From 87cf3b29c1704e16fc3129153b2996796a7f9a1c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Dec 2024 14:26:22 -0500 Subject: [PATCH 03/39] chore(deps): bump next from 14.2.10 to 14.2.15 (#5455) Bumps [next](https://github.com/vercel/next.js) from 14.2.10 to 14.2.15. - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v14.2.10...v14.2.15) --- updated-dependencies: - dependency-name: next dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Marie Lucca <40550942+francinelucca@users.noreply.github.com> --- examples/app-router/package.json | 2 +- examples/theming/package.json | 2 +- package-lock.json | 93 ++++++++++++++++---------------- 3 files changed, 50 insertions(+), 47 deletions(-) diff --git a/examples/app-router/package.json b/examples/app-router/package.json index c3310b09376..a8e07cdb878 100644 --- a/examples/app-router/package.json +++ b/examples/app-router/package.json @@ -11,7 +11,7 @@ }, "dependencies": { "@primer/react": "37.8.0", - "next": "^14.2.10", + "next": "^14.2.15", "react": "^18.3.1", "react-dom": "^18.3.1", "styled-components": "5.x", diff --git a/examples/theming/package.json b/examples/theming/package.json index 26cdc3f2ff2..f66a0058fe8 100644 --- a/examples/theming/package.json +++ b/examples/theming/package.json @@ -13,7 +13,7 @@ "@primer/octicons-react": "^19.9.0", "@primer/react": "37.8.0", "clsx": "^1.2.1", - "next": "^14.2.10", + "next": "^14.2.15", "react": "^18.3.1", "react-dom": "^18.3.1", "styled-components": "5.x", diff --git a/package-lock.json b/package-lock.json index 4da8ecd093f..2749806fe1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,7 +63,7 @@ "version": "0.0.0", "dependencies": { "@primer/react": "37.8.0", - "next": "^14.2.10", + "next": "^14.2.15", "react": "^18.3.1", "react-dom": "^18.3.1", "styled-components": "5.x", @@ -117,7 +117,7 @@ "@primer/octicons-react": "^19.9.0", "@primer/react": "37.8.0", "clsx": "^1.2.1", - "next": "^14.2.10", + "next": "^14.2.15", "react": "^18.3.1", "react-dom": "^18.3.1", "styled-components": "5.x", @@ -5179,9 +5179,10 @@ } }, "node_modules/@next/env": { - "version": "14.2.10", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.10.tgz", - "integrity": "sha512-dZIu93Bf5LUtluBXIv4woQw2cZVZ2DJTjax5/5DOs3lzEOeKLy7GxRSr4caK9/SCPdaW6bCgpye6+n4Dh9oJPw==" + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.15.tgz", + "integrity": "sha512-S1qaj25Wru2dUpcIZMjxeMVSwkt8BK4dmWHHiBuRstcIyOsMapqT4A4jSB6onvqeygkSSmOkyny9VVx8JIGamQ==", + "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { "version": "14.1.0", @@ -5235,12 +5236,13 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.2.10", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.10.tgz", - "integrity": "sha512-V3z10NV+cvMAfxQUMhKgfQnPbjw+Ew3cnr64b0lr8MDiBJs3eLnM6RpGC46nhfMZsiXgQngCJKWGTC/yDcgrDQ==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.15.tgz", + "integrity": "sha512-Rvh7KU9hOUBnZ9TJ28n2Oa7dD9cvDBKua9IKx7cfQQ0GoYUwg9ig31O2oMwH3wm+pE3IkAQ67ZobPfEgurPZIA==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -5250,9 +5252,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.2.10", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.10.tgz", - "integrity": "sha512-Y0TC+FXbFUQ2MQgimJ/7Ina2mXIKhE7F+GUe1SgnzRmwFY3hX2z8nyVCxE82I2RicspdkZnSWMn4oTjIKz4uzA==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.15.tgz", + "integrity": "sha512-5TGyjFcf8ampZP3e+FyCax5zFVHi+Oe7sZyaKOngsqyaNEpOgkKB3sqmymkZfowy3ufGA/tUgDPPxpQx931lHg==", "cpu": [ "x64" ], @@ -5266,9 +5268,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.2.10", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.10.tgz", - "integrity": "sha512-ZfQ7yOy5zyskSj9rFpa0Yd7gkrBnJTkYVSya95hX3zeBG9E55Z6OTNPn1j2BTFWvOVVj65C3T+qsjOyVI9DQpA==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.15.tgz", + "integrity": "sha512-3Bwv4oc08ONiQ3FiOLKT72Q+ndEMyLNsc/D3qnLMbtUYTQAmkx9E/JRu0DBpHxNddBmNT5hxz1mYBphJ3mfrrw==", "cpu": [ "arm64" ], @@ -5282,9 +5284,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.2.10", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.10.tgz", - "integrity": "sha512-n2i5o3y2jpBfXFRxDREr342BGIQCJbdAUi/K4q6Env3aSx8erM9VuKXHw5KNROK9ejFSPf0LhoSkU/ZiNdacpQ==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.15.tgz", + "integrity": "sha512-k5xf/tg1FBv/M4CMd8S+JL3uV9BnnRmoe7F+GWC3DxkTCD9aewFRH1s5rJ1zkzDa+Do4zyN8qD0N8c84Hu96FQ==", "cpu": [ "arm64" ], @@ -5298,9 +5300,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.2.10", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.10.tgz", - "integrity": "sha512-GXvajAWh2woTT0GKEDlkVhFNxhJS/XdDmrVHrPOA83pLzlGPQnixqxD8u3bBB9oATBKB//5e4vpACnx5Vaxdqg==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.15.tgz", + "integrity": "sha512-kE6q38hbrRbKEkkVn62reLXhThLRh6/TvgSP56GkFNhU22TbIrQDEMrO7j0IcQHcew2wfykq8lZyHFabz0oBrA==", "cpu": [ "x64" ], @@ -5314,9 +5316,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.2.10", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.10.tgz", - "integrity": "sha512-opFFN5B0SnO+HTz4Wq4HaylXGFV+iHrVxd3YvREUX9K+xfc4ePbRrxqOuPOFjtSuiVouwe6uLeDtabjEIbkmDA==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.15.tgz", + "integrity": "sha512-PZ5YE9ouy/IdO7QVJeIcyLn/Rc4ml9M2G4y3kCM9MNf1YKvFY4heg3pVa/jQbMro+tP6yc4G2o9LjAz1zxD7tQ==", "cpu": [ "x64" ], @@ -5330,9 +5332,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.10", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.10.tgz", - "integrity": "sha512-9NUzZuR8WiXTvv+EiU/MXdcQ1XUvFixbLIMNQiVHuzs7ZIFrJDLJDaOF1KaqttoTujpcxljM/RNAOmw1GhPPQQ==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.15.tgz", + "integrity": "sha512-2raR16703kBvYEQD9HNLyb0/394yfqzmIeyp2nDzcPV4yPjqNUG3ohX6jX00WryXz6s1FXpVhsCo3i+g4RUX+g==", "cpu": [ "arm64" ], @@ -5346,9 +5348,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.10", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.10.tgz", - "integrity": "sha512-fr3aEbSd1GeW3YUMBkWAu4hcdjZ6g4NBl1uku4gAn661tcxd1bHs1THWYzdsbTRLcCKLjrDZlNp6j2HTfrw+Bg==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.15.tgz", + "integrity": "sha512-fyTE8cklgkyR1p03kJa5zXEaZ9El+kDNM5A+66+8evQS5e/6v0Gk28LqA0Jet8gKSOyP+OTm/tJHzMlGdQerdQ==", "cpu": [ "ia32" ], @@ -5362,9 +5364,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.10", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.10.tgz", - "integrity": "sha512-UjeVoRGKNL2zfbcQ6fscmgjBAS/inHBh63mjIlfPg/NG8Yn2ztqylXt5qilYb6hoHIwaU2ogHknHWWmahJjgZQ==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.15.tgz", + "integrity": "sha512-SzqGbsLsP9OwKNUG9nekShTwhj6JSB9ZLMWQ8g1gG6hdE5gQLncbnbymrwy2yVmH9nikSLYRYxYMFu78Ggp7/g==", "cpu": [ "x64" ], @@ -21681,11 +21683,12 @@ } }, "node_modules/next": { - "version": "14.2.10", - "resolved": "https://registry.npmjs.org/next/-/next-14.2.10.tgz", - "integrity": "sha512-sDDExXnh33cY3RkS9JuFEKaS4HmlWmDKP1VJioucCG6z5KuA008DPsDZOzi8UfqEk3Ii+2NCQSJrfbEWtZZfww==", + "version": "14.2.15", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.15.tgz", + "integrity": "sha512-h9ctmOokpoDphRvMGnwOJAedT6zKhwqyZML9mDtspgf4Rh3Pn7UTYKqePNoDvhsWBAO5GoPNYshnAUGIazVGmw==", + "license": "MIT", "dependencies": { - "@next/env": "14.2.10", + "@next/env": "14.2.15", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -21700,15 +21703,15 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.2.10", - "@next/swc-darwin-x64": "14.2.10", - "@next/swc-linux-arm64-gnu": "14.2.10", - "@next/swc-linux-arm64-musl": "14.2.10", - "@next/swc-linux-x64-gnu": "14.2.10", - "@next/swc-linux-x64-musl": "14.2.10", - "@next/swc-win32-arm64-msvc": "14.2.10", - "@next/swc-win32-ia32-msvc": "14.2.10", - "@next/swc-win32-x64-msvc": "14.2.10" + "@next/swc-darwin-arm64": "14.2.15", + "@next/swc-darwin-x64": "14.2.15", + "@next/swc-linux-arm64-gnu": "14.2.15", + "@next/swc-linux-arm64-musl": "14.2.15", + "@next/swc-linux-x64-gnu": "14.2.15", + "@next/swc-linux-x64-musl": "14.2.15", + "@next/swc-win32-arm64-msvc": "14.2.15", + "@next/swc-win32-ia32-msvc": "14.2.15", + "@next/swc-win32-x64-msvc": "14.2.15" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", From 578a33d77e68695edd285cd03435d3190d025dfc Mon Sep 17 00:00:00 2001 From: Tyler Jones Date: Mon, 30 Dec 2024 10:18:56 -0500 Subject: [PATCH 04/39] ActionBar: Ensure overflow menu only exists if there is no space (#5476) * Ensure items in menu leave menu if there is space * Fixes initial check for if menu items should have overflow menu or not; adds new story * Add changeset * Fix stories file structure * Fix ID * Remove redundant check --- .changeset/thirty-apples-wave.md | 5 + e2e/components/drafts/ActionBar.test.ts | 6 +- .../ActionBar/ActionBar.examples.stories.tsx | 287 ++++++++++++++++++ .../react/src/ActionBar/ActionBar.stories.tsx | 268 ---------------- packages/react/src/ActionBar/ActionBar.tsx | 10 +- 5 files changed, 303 insertions(+), 273 deletions(-) create mode 100644 .changeset/thirty-apples-wave.md create mode 100644 packages/react/src/ActionBar/ActionBar.examples.stories.tsx diff --git a/.changeset/thirty-apples-wave.md b/.changeset/thirty-apples-wave.md new file mode 100644 index 00000000000..fc0f37d1810 --- /dev/null +++ b/.changeset/thirty-apples-wave.md @@ -0,0 +1,5 @@ +--- +"@primer/react": patch +--- + +ActionBar: Fixes issue where `ActionBar` overflow menu would persist even if it was no longer needed; allows overflow menu to appear on initial render if there is no space for all items. diff --git a/e2e/components/drafts/ActionBar.test.ts b/e2e/components/drafts/ActionBar.test.ts index 71d20bd6aa9..d8a183d0392 100644 --- a/e2e/components/drafts/ActionBar.test.ts +++ b/e2e/components/drafts/ActionBar.test.ts @@ -9,7 +9,7 @@ test.describe('ActionBar', () => { test.describe(theme, () => { test('default @vrt', async ({page}) => { await visit(page, { - id: 'experimental-components-actionbar--comment-box', + id: 'experimental-components-actionbar-examples--comment-box', globals: { colorScheme: theme, }, @@ -19,7 +19,7 @@ test.describe('ActionBar', () => { test('axe @aat', async ({page}) => { await visit(page, { - id: 'experimental-components-actionbar--comment-box', + id: 'experimental-components-actionbar-examples--comment-box', globals: { colorScheme: theme, }, @@ -35,7 +35,7 @@ test.describe('ActionBar', () => { test.describe(theme, () => { test('Overflow interaction @vrt', async ({page}) => { await visit(page, { - id: 'experimental-components-actionbar--comment-box', + id: 'experimental-components-actionbar-examples--comment-box', globals: { colorScheme: theme, }, diff --git a/packages/react/src/ActionBar/ActionBar.examples.stories.tsx b/packages/react/src/ActionBar/ActionBar.examples.stories.tsx new file mode 100644 index 00000000000..d80446b9d41 --- /dev/null +++ b/packages/react/src/ActionBar/ActionBar.examples.stories.tsx @@ -0,0 +1,287 @@ +import React from 'react' +import type {Meta} from '@storybook/react' +import ActionBar from '.' +import Text from '../Text' +import { + PencilIcon, + BoldIcon, + CodeIcon, + ItalicIcon, + SearchIcon, + LinkIcon, + FileAddedIcon, + HeadingIcon, + QuoteIcon, + ListUnorderedIcon, + ListOrderedIcon, + TasklistIcon, + ReplyIcon, + ThreeBarsIcon, +} from '@primer/octicons-react' +import {Box, Button, Avatar, ActionMenu, IconButton, ActionList, Textarea} from '..' +import {Dialog} from '../DialogV1' +import {Divider} from '../deprecated/ActionList/Divider' +import mockData from '../experimental/SelectPanel2/mock-story-data' + +export default { + title: 'Experimental/Components/ActionBar/Examples', +} as Meta + +export const TextLabels = () => ( + + + + + +) + +export const SmallActionBar = () => ( + + + + + + + + + +) + +type CommentBoxProps = {'aria-label': string} + +export const CommentBox = (props: CommentBoxProps) => { + const {'aria-label': ariaLabel} = props + const [value, setValue] = React.useState('') + const [isOpen, setIsOpen] = React.useState(false) + const buttonRef = React.useRef(null) + const toolBarLabel = `${ariaLabel ? ariaLabel : 'Comment box'} toolbar` + return ( + + + + + + + + + + + + + + + setIsOpen(true)} + icon={ReplyIcon} + aria-label="Saved Replies" + > + + + +