Skip to content

Commit

Permalink
Allow ProgressBar to have unconstrained width, which is disabled by…
Browse files Browse the repository at this point in the history
… 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`.
  • Loading branch information
fullofcaffeine committed May 28, 2024
1 parent 43e1a57 commit 7a00da3
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 4 deletions.
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
12 changes: 10 additions & 2 deletions packages/components/src/progress-bar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<ProgressBarStyled.Track className={ className }>
<ProgressBarStyled.Track
className={ className }
hasUnconstrainedWidth={ hasUnconstrainedWidth }
>
<ProgressBarStyled.Indicator
style={ {
'--indicator-width': ! isIndeterminate
Expand Down
15 changes: 15 additions & 0 deletions packages/components/src/progress-bar/stories/index.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const meta: Meta< typeof ProgressBar > = {
title: 'Components/ProgressBar',
argTypes: {
value: { control: { type: 'number', min: 0, max: 100, step: 1 } },
hasUnconstrainedWidth: { control: 'boolean' },
},
parameters: {
controls: {
Expand All @@ -21,6 +22,7 @@ const meta: Meta< typeof ProgressBar > = {
docs: { canvas: { sourceState: 'shown' } },
},
};

export default meta;

const Template: StoryFn< typeof ProgressBar > = ( { ...args } ) => {
Expand All @@ -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,
};
5 changes: 3 additions & 2 deletions packages/components/src/progress-bar/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
22 changes: 22 additions & 0 deletions packages/components/src/progress-bar/test/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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( <ProgressBar hasUnconstrainedWidth /> );

// 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( <ProgressBar /> );

// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
const track = container.firstChild;

expect( track ).toHaveStyle( {
'max-width': '160px',
} );
} );
} );
7 changes: 7 additions & 0 deletions packages/components/src/progress-bar/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

0 comments on commit 7a00da3

Please sign in to comment.