diff --git a/packages/react-core/src/components/Toolbar/ToolbarContent.tsx b/packages/react-core/src/components/Toolbar/ToolbarContent.tsx index 2f4839219fd..ec722df5a42 100644 --- a/packages/react-core/src/components/Toolbar/ToolbarContent.tsx +++ b/packages/react-core/src/components/Toolbar/ToolbarContent.tsx @@ -16,6 +16,15 @@ export interface ToolbarContentProps extends React.HTMLProps { xl?: 'hidden' | 'visible'; '2xl'?: 'hidden' | 'visible'; }; + /** Value to set for content wrapping at various breakpoints */ + rowWrap?: { + default?: 'wrap' | 'nowrap'; + sm?: 'wrap' | 'nowrap'; + md?: 'wrap' | 'nowrap'; + lg?: 'wrap' | 'nowrap'; + xl?: 'wrap' | 'nowrap'; + '2xl'?: 'wrap' | 'nowrap'; + }; /** Vertical alignment of children */ alignItems?: 'start' | 'center' | 'baseline' | 'default'; /** Content to be rendered as children of the content row */ @@ -50,6 +59,7 @@ class ToolbarContent extends Component { isExpanded, toolbarId, visibility, + rowWrap, alignItems, clearAllFilters, showClearFiltersButton, @@ -95,6 +105,7 @@ class ToolbarContent extends Component {
, | 'rowGap_3xl' | 'rowGap_4xl'; }; + /** Value to set for row wrapping at various breakpoints */ + rowWrap?: { + default?: 'wrap' | 'nowrap'; + sm?: 'wrap' | 'nowrap'; + md?: 'wrap' | 'nowrap'; + lg?: 'wrap' | 'nowrap'; + xl?: 'wrap' | 'nowrap'; + '2xl'?: 'wrap' | 'nowrap'; + }; /** Content to be rendered inside the data toolbar group */ children?: React.ReactNode; /** Flag that modifies the toolbar group to hide overflow and respond to available space. Used for horizontal navigation. */ @@ -175,6 +184,7 @@ class ToolbarGroupWithRef extends Component { gap, columnGap, rowGap, + rowWrap, className, variant, children, @@ -203,6 +213,7 @@ class ToolbarGroupWithRef extends Component { formatBreakpointMods(gap, styles, '', getBreakpoint(width)), formatBreakpointMods(columnGap, styles, '', getBreakpoint(width)), formatBreakpointMods(rowGap, styles, '', getBreakpoint(width)), + formatBreakpointMods(rowWrap, styles, '', getBreakpoint(width)), alignItems === 'start' && styles.modifiers.alignItemsStart, alignItems === 'center' && styles.modifiers.alignItemsCenter, alignItems === 'baseline' && styles.modifiers.alignItemsBaseline, diff --git a/packages/react-core/src/components/Toolbar/ToolbarItem.tsx b/packages/react-core/src/components/Toolbar/ToolbarItem.tsx index 315df000323..028e899d645 100644 --- a/packages/react-core/src/components/Toolbar/ToolbarItem.tsx +++ b/packages/react-core/src/components/Toolbar/ToolbarItem.tsx @@ -151,6 +151,15 @@ export interface ToolbarItemProps extends React.HTMLProps { | 'rowGap_3xl' | 'rowGap_4xl'; }; + /** Value to set for row wrapping at various breakpoints */ + rowWrap?: { + default?: 'wrap' | 'nowrap'; + sm?: 'wrap' | 'nowrap'; + md?: 'wrap' | 'nowrap'; + lg?: 'wrap' | 'nowrap'; + xl?: 'wrap' | 'nowrap'; + '2xl'?: 'wrap' | 'nowrap'; + }; /** id for this data toolbar item */ id?: string; /** Flag indicating if the expand-all variant is expanded or not */ @@ -168,6 +177,7 @@ export const ToolbarItem: React.FunctionComponent = ({ gap, columnGap, rowGap, + rowWrap, align, alignSelf, alignItems, @@ -196,6 +206,7 @@ export const ToolbarItem: React.FunctionComponent = ({ formatBreakpointMods(gap, styles, '', getBreakpoint(width)), formatBreakpointMods(columnGap, styles, '', getBreakpoint(width)), formatBreakpointMods(rowGap, styles, '', getBreakpoint(width)), + formatBreakpointMods(rowWrap, styles, '', getBreakpoint(width)), alignItems === 'start' && styles.modifiers.alignItemsStart, alignItems === 'center' && styles.modifiers.alignItemsCenter, alignItems === 'baseline' && styles.modifiers.alignItemsBaseline, diff --git a/packages/react-core/src/components/Toolbar/__tests__/Toolbar.test.tsx b/packages/react-core/src/components/Toolbar/__tests__/Toolbar.test.tsx index 9d5f3ca2cfa..0b23a45fe36 100644 --- a/packages/react-core/src/components/Toolbar/__tests__/Toolbar.test.tsx +++ b/packages/react-core/src/components/Toolbar/__tests__/Toolbar.test.tsx @@ -147,4 +147,33 @@ describe('Toolbar', () => { expect(screen.getByTestId('Toolbar-test-secondary-id')).toHaveClass(styles.modifiers.secondary); }); + + describe('ToobarContent rowWrap', () => { + const bps = ['default', 'sm', 'md', 'lg', 'xl', '2xl']; + + describe.each(bps)(`rowWrap at various breakpoints`, (bp) => { + it(`should render with pf-m-wrap when rowWrap is set to wrap at ${bp}`, () => { + render( + + + Test + + + ); + const bpWrapClass = bp === 'default' ? 'pf-m-wrap' : `pf-m-wrap-on-${bp}`; + + expect(screen.getByTestId('toolbarconent').querySelector('div')).toHaveClass(bpWrapClass); + }); + + it(`should render with pf-m-nowrap when rowWrap is set to nowrap at ${bp}`, () => { + render( + + Test + + ); + const bpNoWrapClass = bp === 'default' ? 'pf-m-nowrap' : `pf-m-nowrap-on-${bp}`; + expect(screen.getByTestId('toolbarconent').querySelector('div')).toHaveClass(bpNoWrapClass); + }); + }); + }); }); diff --git a/packages/react-core/src/components/Toolbar/__tests__/ToolbarGroup.test.tsx b/packages/react-core/src/components/Toolbar/__tests__/ToolbarGroup.test.tsx index f278800d97a..935a5480ee1 100644 --- a/packages/react-core/src/components/Toolbar/__tests__/ToolbarGroup.test.tsx +++ b/packages/react-core/src/components/Toolbar/__tests__/ToolbarGroup.test.tsx @@ -1,7 +1,7 @@ import { render, screen } from '@testing-library/react'; import { ToolbarGroup } from '../ToolbarGroup'; -describe('ToolbarItem', () => { +describe('ToolbarGroup', () => { it('should render with pf-m-overflow-container when isOverflowContainer is set', () => { render( @@ -10,4 +10,31 @@ describe('ToolbarItem', () => { ); expect(screen.getByTestId('toolbargroup')).toHaveClass('pf-m-overflow-container'); }); + + describe('ToobarGroup rowWrap', () => { + const bps = ['default', 'sm', 'md', 'lg', 'xl', '2xl']; + + describe.each(bps)(`rowWrap at various breakpoints`, (bp) => { + it(`should render with pf-m-wrap when rowWrap is set to wrap at ${bp}`, () => { + render( + + Test + + ); + const bpWrapClass = bp === 'default' ? 'pf-m-wrap' : `pf-m-wrap-on-${bp}`; + + expect(screen.getByTestId('toolbargroup')).toHaveClass(bpWrapClass); + }); + + it(`should render with pf-m-nowrap when rowWrap is set to nowrap at ${bp}`, () => { + render( + + Test + + ); + const bpNoWrapClass = bp === 'default' ? 'pf-m-nowrap' : `pf-m-nowrap-on-${bp}`; + expect(screen.getByTestId('toolbargroup')).toHaveClass(bpNoWrapClass); + }); + }); + }); }); diff --git a/packages/react-core/src/components/Toolbar/__tests__/ToolbarItem.test.tsx b/packages/react-core/src/components/Toolbar/__tests__/ToolbarItem.test.tsx index 707ba5920c8..5fbd364a87a 100644 --- a/packages/react-core/src/components/Toolbar/__tests__/ToolbarItem.test.tsx +++ b/packages/react-core/src/components/Toolbar/__tests__/ToolbarItem.test.tsx @@ -10,4 +10,31 @@ describe('ToolbarItem', () => { ); expect(screen.getByTestId('toolbaritem')).toHaveClass('pf-m-overflow-container'); }); + + describe('ToobarItem rowWrap', () => { + const bps = ['default', 'sm', 'md', 'lg', 'xl', '2xl']; + + describe.each(bps)(`rowWrap at various breakpoints`, (bp) => { + it(`should render with pf-m-wrap when rowWrap is set to wrap at ${bp}`, () => { + render( + + Test + + ); + const bpWrapClass = bp === 'default' ? 'pf-m-wrap' : `pf-m-wrap-on-${bp}`; + + expect(screen.getByTestId('toolbaritem')).toHaveClass(bpWrapClass); + }); + + it(`should render with pf-m-nowrap when rowWrap is set to nowrap at ${bp}`, () => { + render( + + Test + + ); + const bpNoWrapClass = bp === 'default' ? 'pf-m-nowrap' : `pf-m-nowrap-on-${bp}`; + expect(screen.getByTestId('toolbaritem')).toHaveClass(bpNoWrapClass); + }); + }); + }); }); diff --git a/packages/react-core/src/components/Toolbar/examples/Toolbar.md b/packages/react-core/src/components/Toolbar/examples/Toolbar.md index 9e1840ed83d..2a0f85e197e 100644 --- a/packages/react-core/src/components/Toolbar/examples/Toolbar.md +++ b/packages/react-core/src/components/Toolbar/examples/Toolbar.md @@ -113,11 +113,18 @@ When all of a toolbar's required elements cannot fit in a single line, you can s ``` -## Examples with toolbar spacers +## Examples with spacers and wrapping You may adjust the space between toolbar items to arrange them into groups. Read our spacers documentation to learn more about using spacers. Items are spaced “16px” apart by default and can be modified by changing their or their parents' `gap`, `columnGap`, and `rowGap` properties. You can set the property values at multiple breakpoints, including "default", "md", "lg", "xl", and "2xl". +### Toolbar content wrapping +The toolbar content section will wrap by default, but you can set the `rowRap` property to `noWrap` to make it not wrap. + +```ts file="./ToolbarContentWrap.tsx" + +``` + ### Toolbar group spacers ```ts file="./ToolbarGroupSpacers.tsx" diff --git a/packages/react-core/src/components/Toolbar/examples/ToolbarContentWrap.tsx b/packages/react-core/src/components/Toolbar/examples/ToolbarContentWrap.tsx new file mode 100644 index 00000000000..466de5c1cdb --- /dev/null +++ b/packages/react-core/src/components/Toolbar/examples/ToolbarContentWrap.tsx @@ -0,0 +1,35 @@ +import { Fragment } from 'react'; +import { Toolbar, ToolbarItem, ToolbarContent } from '@patternfly/react-core'; +import { Button, SearchInput } from '@patternfly/react-core'; + +export const ToolbarItems: React.FunctionComponent = () => { + const items = ( + + + + + + + + + + + + + + + + + + + + + + ); + + return ( + + {items} + + ); +}; diff --git a/packages/react-core/src/components/Toolbar/examples/ToolbarGroupSpacers.tsx b/packages/react-core/src/components/Toolbar/examples/ToolbarGroupSpacers.tsx index dc413856b0f..9096a55d21c 100644 --- a/packages/react-core/src/components/Toolbar/examples/ToolbarGroupSpacers.tsx +++ b/packages/react-core/src/components/Toolbar/examples/ToolbarGroupSpacers.tsx @@ -76,7 +76,7 @@ export const ToolbarGroupSpacers: React.FunctionComponent = () => { const groupRowGapItems = ( - + @@ -103,7 +103,7 @@ export const ToolbarGroupSpacers: React.FunctionComponent = () => { - + @@ -130,7 +130,7 @@ export const ToolbarGroupSpacers: React.FunctionComponent = () => { - + diff --git a/packages/react-core/src/components/Toolbar/examples/ToolbarItemSpacers.tsx b/packages/react-core/src/components/Toolbar/examples/ToolbarItemSpacers.tsx index 8ac72d23389..3f051a8972a 100644 --- a/packages/react-core/src/components/Toolbar/examples/ToolbarItemSpacers.tsx +++ b/packages/react-core/src/components/Toolbar/examples/ToolbarItemSpacers.tsx @@ -5,7 +5,7 @@ import { Button } from '@patternfly/react-core'; export const ToolbarItemSpacers: React.FunctionComponent = () => { const itemGapItems = ( - + @@ -26,7 +26,7 @@ export const ToolbarItemSpacers: React.FunctionComponent = () => { const itemColumnGapItems = ( - + @@ -48,17 +48,17 @@ export const ToolbarItemSpacers: React.FunctionComponent = () => { const itemRowGapItems = ( - + - + - +