From 7a00da3e2f40d5aae569554adb2eafbf406da373 Mon Sep 17 00:00:00 2001 From: Marcelo Serpa Date: Fri, 24 May 2024 16:52:45 -0600 Subject: [PATCH] Allow `ProgressBar` to have unconstrained width, which is disabled by default It has a default `max-width` of 160px, but allows consumers to explicitely disable it so that it expands to fit the parent's width by default. Consumers can then optionally set another width the way they see fit via a custom `className`. --- packages/components/CHANGELOG.md | 1 + .../components/src/progress-bar/index.tsx | 12 ++++++++-- .../src/progress-bar/stories/index.story.tsx | 15 +++++++++++++ .../components/src/progress-bar/styles.ts | 5 +++-- .../src/progress-bar/test/index.tsx | 22 +++++++++++++++++++ packages/components/src/progress-bar/types.ts | 7 ++++++ 6 files changed, 58 insertions(+), 4 deletions(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 9905ad789d2c7f..fa13180e32e1af 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -12,6 +12,7 @@ - `Tabs`: Animate indicator ([#60560](https://github.com/WordPress/gutenberg/pull/60560)). - `ComboboxControl`: Introduce Combobox expandOnFocus prop ([#61705](https://github.com/WordPress/gutenberg/pull/61705)). - Components: Make the `ProgressBar` public ([#61062](https://github.com/WordPress/gutenberg/pull/61062)). +- Components: Improve `ProgressBar` width control ([#61976](https://github.com/WordPress/gutenberg/pull/61976). ### Bug Fixes diff --git a/packages/components/src/progress-bar/index.tsx b/packages/components/src/progress-bar/index.tsx index e9f4acd9161809..d21ccd504e0ba5 100644 --- a/packages/components/src/progress-bar/index.tsx +++ b/packages/components/src/progress-bar/index.tsx @@ -20,11 +20,19 @@ function UnforwardedProgressBar( props: WordPressComponentProps< ProgressBarProps, 'progress', false >, ref: ForwardedRef< HTMLProgressElement > ) { - const { className, value, ...progressProps } = props; + const { + className, + value, + hasUnconstrainedWidth = false, + ...progressProps + } = props; const isIndeterminate = ! Number.isFinite( value ); return ( - + = { title: 'Components/ProgressBar', argTypes: { value: { control: { type: 'number', min: 0, max: 100, step: 1 } }, + hasUnconstrainedWidth: { control: 'boolean' }, }, parameters: { controls: { @@ -21,6 +22,7 @@ const meta: Meta< typeof ProgressBar > = { docs: { canvas: { sourceState: 'shown' } }, }, }; + export default meta; const Template: StoryFn< typeof ProgressBar > = ( { ...args } ) => { @@ -29,3 +31,16 @@ const Template: StoryFn< typeof ProgressBar > = ( { ...args } ) => { export const Default: StoryFn< typeof ProgressBar > = Template.bind( {} ); Default.args = {}; + +/** + * A progress bar that expands to fill its container, ignoring the default `max-width`. + * + * You can also further customize the width behavior by passing your own CSS class in + * the `cssName` prop. + */ +export const UnconstrainedWidth: StoryFn< typeof ProgressBar > = Template.bind( + {} +); +UnconstrainedWidth.args = { + hasUnconstrainedWidth: true, +}; diff --git a/packages/components/src/progress-bar/styles.ts b/packages/components/src/progress-bar/styles.ts index f04002f458c0aa..95d88e28c28193 100644 --- a/packages/components/src/progress-bar/styles.ts +++ b/packages/components/src/progress-bar/styles.ts @@ -21,11 +21,12 @@ const animateProgressBar = keyframes( { // Width of the indicator for the indeterminate progress bar export const INDETERMINATE_TRACK_WIDTH = 50; -export const Track = styled.div` +export const Track = styled.div< { hasUnconstrainedWidth?: boolean } >` position: relative; overflow: hidden; width: 100%; - max-width: 160px; + ${ ( { hasUnconstrainedWidth } ) => + ! hasUnconstrainedWidth && 'max-width: 160px;' } height: ${ CONFIG.borderWidthFocus }; /* Text color at 10% opacity */ background-color: color-mix( diff --git a/packages/components/src/progress-bar/test/index.tsx b/packages/components/src/progress-bar/test/index.tsx index c3984318cc618a..cd3dccacef5f9c 100644 --- a/packages/components/src/progress-bar/test/index.tsx +++ b/packages/components/src/progress-bar/test/index.tsx @@ -79,4 +79,26 @@ describe( 'ProgressBar', () => { ); expect( screen.getByRole( 'progressbar' ) ).toHaveStyle( style ); } ); + + it( 'should expand to fit the parent when `hasUnconstrainedWidth` is `true`', () => { + const { container } = render( ); + + // eslint-disable-next-line testing-library/no-container, testing-library/no-node-access + const track = container.firstChild; + + expect( track ).not.toHaveStyle( { + 'max-width': '160px', + } ); + } ); + + it( 'should have a default `max-width` when `hasUnconstrainedWidth` is `false`', () => { + const { container } = render( ); + + // eslint-disable-next-line testing-library/no-container, testing-library/no-node-access + const track = container.firstChild; + + expect( track ).toHaveStyle( { + 'max-width': '160px', + } ); + } ); } ); diff --git a/packages/components/src/progress-bar/types.ts b/packages/components/src/progress-bar/types.ts index 9beb28317e58aa..118ce8371630f5 100644 --- a/packages/components/src/progress-bar/types.ts +++ b/packages/components/src/progress-bar/types.ts @@ -8,4 +8,11 @@ export type ProgressBarProps = { * A CSS class to apply to the progress bar wrapper (track) element. */ className?: string; + + /** + * If `true`, the progress bar will expand to fill its container, ignoring the default `max-width` of 160px. + * This allows the progress bar to adapt to different container sizes. + * @default false + */ + hasUnconstrainedWidth?: boolean; };