diff --git a/packages/react-core/src/components/Dropdown/Dropdown.tsx b/packages/react-core/src/components/Dropdown/Dropdown.tsx index 2257392775a..fc496addf2c 100644 --- a/packages/react-core/src/components/Dropdown/Dropdown.tsx +++ b/packages/react-core/src/components/Dropdown/Dropdown.tsx @@ -31,6 +31,8 @@ export interface DropdownProps extends React.HTMLProps, OUIAProp }; /** Display menu above or below dropdown toggle */ direction?: DropdownDirection | 'up' | 'down'; + /** Minimum width of the dropdown menu. If set to "trigger", the minimum width will be set to the toggle width. */ + minWidth?: string | 'trigger'; /** The container to append the menu to. Defaults to 'inline'. * If your menu is being cut off you can append it to an element higher up the DOM tree. * Some examples: @@ -72,6 +74,7 @@ export const Dropdown: React.FunctionComponent = ({ ouiaSafe, alignments, contextProps, + minWidth, menuAppendTo = 'inline', isFlipEnabled = true, zIndex = 9999, @@ -79,7 +82,7 @@ export const Dropdown: React.FunctionComponent = ({ }: DropdownProps) => ( onSelect && onSelect(event), + onSelect: (event) => onSelect && onSelect(event), toggleTextClass: styles.dropdownToggleText, toggleIconClass: styles.dropdownToggleImage, toggleIndicatorClass: styles.dropdownToggleIcon, @@ -104,6 +107,7 @@ export const Dropdown: React.FunctionComponent = ({ menuAppendTo={menuAppendTo} isFlipEnabled={isFlipEnabled} zIndex={zIndex} + minWidth={minWidth} {...props} /> diff --git a/packages/react-core/src/components/Dropdown/DropdownWithContext.tsx b/packages/react-core/src/components/Dropdown/DropdownWithContext.tsx index 65aa43dafe8..a3a149d7042 100644 --- a/packages/react-core/src/components/Dropdown/DropdownWithContext.tsx +++ b/packages/react-core/src/components/Dropdown/DropdownWithContext.tsx @@ -75,6 +75,7 @@ export class DropdownWithContext extends React.Component ); }} diff --git a/packages/react-core/src/components/LabelGroup/examples/LabelGroupEditableAddDropdown.tsx b/packages/react-core/src/components/LabelGroup/examples/LabelGroupEditableAddDropdown.tsx index e5d65f6c195..fe51f0fac60 100644 --- a/packages/react-core/src/components/LabelGroup/examples/LabelGroupEditableAddDropdown.tsx +++ b/packages/react-core/src/components/LabelGroup/examples/LabelGroupEditableAddDropdown.tsx @@ -115,14 +115,7 @@ export const LabelGroupEditableAddDropdown: React.FunctionComponent = () => { numLabels={5} isEditable addLabelControl={ - + } > {labels.map((label, index) => ( diff --git a/packages/react-core/src/components/LabelGroup/examples/LabelGroupEditableAddModal.tsx b/packages/react-core/src/components/LabelGroup/examples/LabelGroupEditableAddModal.tsx index 3d40557e0e0..c3a594adac4 100644 --- a/packages/react-core/src/components/LabelGroup/examples/LabelGroupEditableAddModal.tsx +++ b/packages/react-core/src/components/LabelGroup/examples/LabelGroupEditableAddModal.tsx @@ -289,7 +289,6 @@ export const LabelGroupEditableAddModal: React.FunctionComponent = () => { popperRef={colorMenuRef} appendTo={colorContainerRef.current as HTMLElement} isVisible={isColorOpen} - popperMatchesTriggerWidth={false} /> @@ -302,7 +301,6 @@ export const LabelGroupEditableAddModal: React.FunctionComponent = () => { popperRef={iconMenuRef} appendTo={iconContainerRef.current as HTMLElement} isVisible={isIconOpen} - popperMatchesTriggerWidth={false} /> diff --git a/packages/react-core/src/components/Nav/__tests__/__snapshots__/Nav.test.tsx.snap b/packages/react-core/src/components/Nav/__tests__/__snapshots__/Nav.test.tsx.snap index c7be5b9533d..ea860ce0f09 100644 --- a/packages/react-core/src/components/Nav/__tests__/__snapshots__/Nav.test.tsx.snap +++ b/packages/react-core/src/components/Nav/__tests__/__snapshots__/Nav.test.tsx.snap @@ -1096,7 +1096,7 @@ exports[`Nav Nav List with flyout 1`] = ` data-popper-escaped="true" data-popper-placement="right-start" data-popper-reference-hidden="true" - style="position: absolute; left: 0px; top: 0px; z-index: 9999; width: 0px; transform: translate(0px, 0px);" + style="position: absolute; left: 0px; top: 0px; z-index: 9999; min-width: 0px; transform: translate(0px, 0px);" >
Flyout test diff --git a/packages/react-core/src/components/Pagination/PaginationOptionsMenu.tsx b/packages/react-core/src/components/Pagination/PaginationOptionsMenu.tsx index 3b86bbedd0b..6cdaa624279 100644 --- a/packages/react-core/src/components/Pagination/PaginationOptionsMenu.tsx +++ b/packages/react-core/src/components/Pagination/PaginationOptionsMenu.tsx @@ -16,6 +16,8 @@ export interface PaginationOptionsMenuProps extends React.HTMLProps
); diff --git a/packages/react-core/src/components/Popover/Popover.tsx b/packages/react-core/src/components/Popover/Popover.tsx index b29c218273d..668d4b4e31e 100644 --- a/packages/react-core/src/components/Popover/Popover.tsx +++ b/packages/react-core/src/components/Popover/Popover.tsx @@ -464,7 +464,7 @@ export const Popover: React.FunctionComponent = ({ triggerRef={triggerRef} popper={content} popperRef={popoverRef} - popperMatchesTriggerWidth={false} + minWidth="revert" appendTo={appendTo} isVisible={visible} positionModifiers={positionModifiers} diff --git a/packages/react-core/src/components/SearchInput/__tests__/__snapshots__/SearchInput.test.tsx.snap b/packages/react-core/src/components/SearchInput/__tests__/__snapshots__/SearchInput.test.tsx.snap index e6dbf02bc21..f316079ce1b 100644 --- a/packages/react-core/src/components/SearchInput/__tests__/__snapshots__/SearchInput.test.tsx.snap +++ b/packages/react-core/src/components/SearchInput/__tests__/__snapshots__/SearchInput.test.tsx.snap @@ -246,7 +246,7 @@ exports[`SearchInput advanced search with custom attributes 1`] = ` data-popper-escaped="true" data-popper-placement="bottom-start" data-popper-reference-hidden="true" - style="position: absolute; top: 0px; left: 0px; transform: translate(0px, 0px); width: 0px; z-index: 9999;" + style="position: absolute; top: 0px; left: 0px; transform: translate(0px, 0px); min-width: 0px; z-index: 9999;" >
= ({ popper={overflowMenu} popperRef={menuRef} isVisible={isExpanded} - popperMatchesTriggerWidth={false} + minWidth="revert" appendTo={overflowLIRef.current} zIndex={zIndex} /> diff --git a/packages/react-core/src/components/Tabs/__tests__/OverflowTab.test.tsx b/packages/react-core/src/components/Tabs/__tests__/OverflowTab.test.tsx index 5b3f748cb68..da4c39bcf47 100644 --- a/packages/react-core/src/components/Tabs/__tests__/OverflowTab.test.tsx +++ b/packages/react-core/src/components/Tabs/__tests__/OverflowTab.test.tsx @@ -6,11 +6,10 @@ import { OverflowTab } from '../OverflowTab'; import { TabsContext } from '../TabsContext'; jest.mock('../../../helpers', () => ({ - Popper: ({ trigger, popper, isVisible, popperMatchesTriggerWidth, appendTo }) => ( + Popper: ({ trigger, popper, isVisible, appendTo }) => (
{trigger}
{isVisible && popper}
-

Popper matches trigger width: {`${popperMatchesTriggerWidth}`}

Append to class name: {appendTo && `${appendTo.className}`}

) @@ -206,8 +205,8 @@ test('Closes the overflowing tabs menu when a tab is selected', async () => { }, - { title: 'Tab two', eventKey: 2, tabContentRef: ('fakeRef' as unknown) as React.RefObject } + { title: 'Tab one', eventKey: 1, tabContentRef: 'fakeRef' as unknown as React.RefObject }, + { title: 'Tab two', eventKey: 2, tabContentRef: 'fakeRef' as unknown as React.RefObject } ]} /> @@ -228,8 +227,8 @@ test('Closes the overflowing tabs menu when the user clicks outside of the menu' }, - { title: 'Tab two', eventKey: 2, tabContentRef: ('fakeRef' as unknown) as React.RefObject } + { title: 'Tab one', eventKey: 1, tabContentRef: 'fakeRef' as unknown as React.RefObject }, + { title: 'Tab two', eventKey: 2, tabContentRef: 'fakeRef' as unknown as React.RefObject } ]} /> @@ -250,7 +249,7 @@ test('Calls the onTabClick callback provided via context when a tab is clicked', } + { title: 'Tab one', eventKey: 1, tabContentRef: 'fakeRef' as unknown as React.RefObject } ]} /> @@ -303,7 +302,7 @@ test('Uses the selected tab title as the overflow tab title rather than the defa } + { title: 'Tab one', eventKey: 1, tabContentRef: 'fakeRef' as unknown as React.RefObject } ]} /> @@ -323,7 +322,7 @@ test('Uses the selected tab title as the overflow tab title rather than the defa } + { title: 'Tab one', eventKey: 1, tabContentRef: 'fakeRef' as unknown as React.RefObject } ]} defaultTitleText="Test" /> @@ -369,13 +368,6 @@ test('Renders the tab with aria-expanded set to true when the menu is opened', a expect(overflowTab).toHaveAttribute('aria-expanded', 'true'); }); -test('Passes Popper popperMatchesTriggerWidth set to false', () => { - render(); - - // This assertion relies on the structure of the Popper mock to verify the correct props are being sent to Popper - expect(screen.getByText('Popper matches trigger width: false')).toBeVisible(); -}); - test('Passes Popper an appendTo value of the presentation element', async () => { const user = userEvent.setup(); @@ -394,7 +386,7 @@ test('Does not render an overflowing tab as a selected menu item by default', as } + { title: 'Tab one', eventKey: 1, tabContentRef: 'fakeRef' as unknown as React.RefObject } ]} /> @@ -413,7 +405,7 @@ test('Renders an overflowing tab as a selected menu item when its key matches th } + { title: 'Tab one', eventKey: 1, tabContentRef: 'fakeRef' as unknown as React.RefObject } ]} /> @@ -432,8 +424,8 @@ test('Matches snapshot when expanded', async () => { }, - { title: 'Tab two', eventKey: 2, tabContentRef: ('fakeRef' as unknown) as React.RefObject } + { title: 'Tab one', eventKey: 1, tabContentRef: 'fakeRef' as unknown as React.RefObject }, + { title: 'Tab two', eventKey: 2, tabContentRef: 'fakeRef' as unknown as React.RefObject } ]} /> diff --git a/packages/react-core/src/components/Tabs/__tests__/__snapshots__/OverflowTab.test.tsx.snap b/packages/react-core/src/components/Tabs/__tests__/__snapshots__/OverflowTab.test.tsx.snap index c5c13b9e85e..33f4d7e26cb 100644 --- a/packages/react-core/src/components/Tabs/__tests__/__snapshots__/OverflowTab.test.tsx.snap +++ b/packages/react-core/src/components/Tabs/__tests__/__snapshots__/OverflowTab.test.tsx.snap @@ -78,9 +78,6 @@ exports[`Matches snapshot when expanded 1`] = `
-

- Popper matches trigger width: false -

Append to class name: pf-c-tabs__item pf-m-overflow pf-m-current

@@ -166,9 +163,6 @@ exports[`Renders tabs passed via overflowingTabs when expanded in strict mode 1` -

- Popper matches trigger width: false -

Append to class name: pf-c-tabs__item pf-m-overflow

diff --git a/packages/react-core/src/components/Tooltip/Tooltip.tsx b/packages/react-core/src/components/Tooltip/Tooltip.tsx index 2761f3f9aaf..a41a1764286 100644 --- a/packages/react-core/src/components/Tooltip/Tooltip.tsx +++ b/packages/react-core/src/components/Tooltip/Tooltip.tsx @@ -93,6 +93,8 @@ export interface TooltipProps extends Omit, 'con | 'right-start' | 'right-end' )[]; + /** Minimum width of the tooltip. If set to "trigger", the minimum width will be set to the reference element width. */ + minWidth?: string | 'trigger'; /** Maximum width of the tooltip (default 18.75rem) */ maxWidth?: string; /** Callback when tooltip's hide transition has finished executing */ @@ -151,6 +153,7 @@ export const Tooltip: React.FunctionComponent = ({ exitDelay = 300, appendTo = () => document.body, zIndex = 9999, + minWidth, maxWidth = tooltipMaxWidth.value, distance = 15, aria = 'describedby', @@ -321,7 +324,7 @@ export const Tooltip: React.FunctionComponent = ({ triggerRef={triggerRef} popper={content} popperRef={popperRef} - popperMatchesTriggerWidth={false} + minWidth={minWidth !== undefined ? minWidth : 'revert'} appendTo={appendTo} isVisible={visible} positionModifiers={positionModifiers} diff --git a/packages/react-core/src/demos/ComposableMenu/examples/ComposableActionsMenu.tsx b/packages/react-core/src/demos/ComposableMenu/examples/ComposableActionsMenu.tsx index 2a1baa45aa8..f942fc467f1 100644 --- a/packages/react-core/src/demos/ComposableMenu/examples/ComposableActionsMenu.tsx +++ b/packages/react-core/src/demos/ComposableMenu/examples/ComposableActionsMenu.tsx @@ -69,11 +69,6 @@ export const ComposableActionsMenu: React.FunctionComponent = () => { // eslint-disable-next-line no-console onActionClick={(event, itemId, actionId) => console.log(`clicked on ${itemId} - ${actionId}`)} onSelect={onSelect} - style={ - { - '--pf-c-menu--Width': '300px' - } as React.CSSProperties - } > @@ -122,14 +117,5 @@ export const ComposableActionsMenu: React.FunctionComponent = () => { ); - return ( - - ); + return ; }; diff --git a/packages/react-core/src/demos/ComposableMenu/examples/ComposableApplicationLauncher.tsx b/packages/react-core/src/demos/ComposableMenu/examples/ComposableApplicationLauncher.tsx index a02e18c6d9c..763a69a6b37 100644 --- a/packages/react-core/src/demos/ComposableMenu/examples/ComposableApplicationLauncher.tsx +++ b/packages/react-core/src/demos/ComposableMenu/examples/ComposableApplicationLauncher.tsx @@ -265,14 +265,5 @@ export const ComposableApplicationLauncher: React.FunctionComponent = () => { ); - return ( - - ); + return ; }; diff --git a/packages/react-core/src/demos/ComposableMenu/examples/ComposableContextSelector.tsx b/packages/react-core/src/demos/ComposableMenu/examples/ComposableContextSelector.tsx index b7cd8809d8d..89cc49ad08c 100644 --- a/packages/react-core/src/demos/ComposableMenu/examples/ComposableContextSelector.tsx +++ b/packages/react-core/src/demos/ComposableMenu/examples/ComposableContextSelector.tsx @@ -146,17 +146,7 @@ export const ComposableContextSelector: React.FunctionComponent = () => { }; const menu = ( - + { ); - return ( - - ); + return ; }; diff --git a/packages/react-core/src/demos/ComposableMenu/examples/ComposableDateSelect.tsx b/packages/react-core/src/demos/ComposableMenu/examples/ComposableDateSelect.tsx index 8aca5f971d5..0030932fd75 100644 --- a/packages/react-core/src/demos/ComposableMenu/examples/ComposableDateSelect.tsx +++ b/packages/react-core/src/demos/ComposableMenu/examples/ComposableDateSelect.tsx @@ -109,14 +109,5 @@ export const ComposableSimpleDropdown: React.FunctionComponent = () => { ); - return ( - - ); + return ; }; diff --git a/packages/react-core/src/demos/ComposableMenu/examples/ComposableDrilldownMenu.tsx b/packages/react-core/src/demos/ComposableMenu/examples/ComposableDrilldownMenu.tsx index 95c85398881..f25da999673 100644 --- a/packages/react-core/src/demos/ComposableMenu/examples/ComposableDrilldownMenu.tsx +++ b/packages/react-core/src/demos/ComposableMenu/examples/ComposableDrilldownMenu.tsx @@ -107,11 +107,6 @@ export const ComposableDrilldownMenu: React.FunctionComponent = () => { onDrillOut={drillOut} onGetMenuHeight={setHeight} ref={menuRef} - style={ - { - '--pf-c-menu--Width': '300px' - } as React.CSSProperties - } > @@ -247,14 +242,5 @@ export const ComposableDrilldownMenu: React.FunctionComponent = () => { ); - return ( - - ); + return ; }; diff --git a/packages/react-core/src/demos/ComposableMenu/examples/ComposableDropdwnVariants.tsx b/packages/react-core/src/demos/ComposableMenu/examples/ComposableDropdwnVariants.tsx index 5e5e02e519d..e69d20f3a31 100644 --- a/packages/react-core/src/demos/ComposableMenu/examples/ComposableDropdwnVariants.tsx +++ b/packages/react-core/src/demos/ComposableMenu/examples/ComposableDropdwnVariants.tsx @@ -226,14 +226,7 @@ export const ComposableDropdwnVariants: React.FunctionComponent = () => { />
- + ); }; diff --git a/packages/react-core/src/demos/ComposableMenu/examples/ComposableFlyout.tsx b/packages/react-core/src/demos/ComposableMenu/examples/ComposableFlyout.tsx index 81ef42a0d58..0043decf203 100644 --- a/packages/react-core/src/demos/ComposableMenu/examples/ComposableFlyout.tsx +++ b/packages/react-core/src/demos/ComposableMenu/examples/ComposableFlyout.tsx @@ -100,14 +100,5 @@ export const ComposableFlyout: React.FunctionComponent = () => { ); - return ( - - ); + return ; }; diff --git a/packages/react-core/src/demos/ComposableMenu/examples/ComposableTreeViewMenu.tsx b/packages/react-core/src/demos/ComposableMenu/examples/ComposableTreeViewMenu.tsx index f5338300e18..b3380281eab 100644 --- a/packages/react-core/src/demos/ComposableMenu/examples/ComposableTreeViewMenu.tsx +++ b/packages/react-core/src/demos/ComposableMenu/examples/ComposableTreeViewMenu.tsx @@ -267,14 +267,5 @@ export const ComposableTreeViewMenu: React.FunctionComponent = () => { ); - return ( - - ); + return ; }; diff --git a/packages/react-core/src/demos/Filters/examples/FilterAttributeSearch.tsx b/packages/react-core/src/demos/Filters/examples/FilterAttributeSearch.tsx index f3ccdb16026..5f47580d166 100644 --- a/packages/react-core/src/demos/Filters/examples/FilterAttributeSearch.tsx +++ b/packages/react-core/src/demos/Filters/examples/FilterAttributeSearch.tsx @@ -256,7 +256,6 @@ export const FilterAttributeSearch: React.FunctionComponent = () => { popperRef={bulkSelectMenuRef} appendTo={bulkSelectContainerRef.current || undefined} isVisible={isBulkSelectOpen} - popperMatchesTriggerWidth={false} /> ); diff --git a/packages/react-core/src/demos/Filters/examples/FilterCheckboxSelect.tsx b/packages/react-core/src/demos/Filters/examples/FilterCheckboxSelect.tsx index 16558d5a564..4f343b18505 100644 --- a/packages/react-core/src/demos/Filters/examples/FilterCheckboxSelect.tsx +++ b/packages/react-core/src/demos/Filters/examples/FilterCheckboxSelect.tsx @@ -231,7 +231,6 @@ export const FilterCheckboxSelect: React.FunctionComponent = () => { popperRef={bulkSelectMenuRef} appendTo={bulkSelectContainerRef.current || undefined} isVisible={isBulkSelectOpen} - popperMatchesTriggerWidth={false} /> ); diff --git a/packages/react-core/src/demos/Filters/examples/FilterFaceted.tsx b/packages/react-core/src/demos/Filters/examples/FilterFaceted.tsx index 5c58b9a83cd..9b4da81e200 100644 --- a/packages/react-core/src/demos/Filters/examples/FilterFaceted.tsx +++ b/packages/react-core/src/demos/Filters/examples/FilterFaceted.tsx @@ -239,7 +239,6 @@ export const FilterFaceted: React.FunctionComponent = () => { popperRef={bulkSelectMenuRef} appendTo={bulkSelectContainerRef.current || undefined} isVisible={isBulkSelectOpen} - popperMatchesTriggerWidth={false} /> ); diff --git a/packages/react-core/src/demos/Filters/examples/FilterMixedSelectGroup.tsx b/packages/react-core/src/demos/Filters/examples/FilterMixedSelectGroup.tsx index ecfc1098b5b..565a17023d0 100644 --- a/packages/react-core/src/demos/Filters/examples/FilterMixedSelectGroup.tsx +++ b/packages/react-core/src/demos/Filters/examples/FilterMixedSelectGroup.tsx @@ -236,7 +236,6 @@ export const FilterMixedSelectGroup: React.FunctionComponent = () => { popperRef={bulkSelectMenuRef} appendTo={bulkSelectContainerRef.current || undefined} isVisible={isBulkSelectOpen} - popperMatchesTriggerWidth={false} /> ); diff --git a/packages/react-core/src/demos/Filters/examples/FilterSameSelectGroup.tsx b/packages/react-core/src/demos/Filters/examples/FilterSameSelectGroup.tsx index 9fe3fc11035..5da3371cc37 100644 --- a/packages/react-core/src/demos/Filters/examples/FilterSameSelectGroup.tsx +++ b/packages/react-core/src/demos/Filters/examples/FilterSameSelectGroup.tsx @@ -237,7 +237,6 @@ export const FilterSameSelectGroup: React.FunctionComponent = () => { popperRef={bulkSelectMenuRef} appendTo={bulkSelectContainerRef.current || undefined} isVisible={isBulkSelectOpen} - popperMatchesTriggerWidth={false} /> ); diff --git a/packages/react-core/src/demos/Filters/examples/FilterSearchInput.tsx b/packages/react-core/src/demos/Filters/examples/FilterSearchInput.tsx index 56ec8d6ed2b..076d7082944 100644 --- a/packages/react-core/src/demos/Filters/examples/FilterSearchInput.tsx +++ b/packages/react-core/src/demos/Filters/examples/FilterSearchInput.tsx @@ -240,7 +240,6 @@ export const FilterSearchInput: React.FunctionComponent = () => { popperRef={bulkSelectMenuRef} appendTo={bulkSelectContainerRef.current || undefined} isVisible={isBulkSelectOpen} - popperMatchesTriggerWidth={false} /> ); diff --git a/packages/react-core/src/demos/Filters/examples/FilterSingleSelect.tsx b/packages/react-core/src/demos/Filters/examples/FilterSingleSelect.tsx index 41427758fea..132d63747e4 100644 --- a/packages/react-core/src/demos/Filters/examples/FilterSingleSelect.tsx +++ b/packages/react-core/src/demos/Filters/examples/FilterSingleSelect.tsx @@ -226,7 +226,6 @@ export const FilterSingleSelect: React.FunctionComponent = () => { popperRef={bulkSelectMenuRef} appendTo={bulkSelectContainerRef.current || undefined} isVisible={isBulkSelectOpen} - popperMatchesTriggerWidth={false} /> ); diff --git a/packages/react-core/src/helpers/Popper/Popper.tsx b/packages/react-core/src/helpers/Popper/Popper.tsx index e1b5677bf80..e949076cca0 100644 --- a/packages/react-core/src/helpers/Popper/Popper.tsx +++ b/packages/react-core/src/helpers/Popper/Popper.tsx @@ -62,14 +62,18 @@ export interface PopperProps { * Passing this prop will remove the wrapper div element from the popper. */ popperRef?: HTMLElement | (() => HTMLElement) | React.RefObject; - /** True to set the width of the popper element to the trigger element's width */ - popperMatchesTriggerWidth?: boolean; /** popper direction */ direction?: 'up' | 'down'; /** popper position */ position?: 'right' | 'left' | 'center'; /** Instead of direction and position can set the placement of the popper */ placement?: Placement; + /** Custsom width of the popper. If the value is "trigger", it will set the width to the trigger element's width */ + width?: string | 'trigger'; + /** Minimum width of the popper. If the value is "trigger", it will set the min width to the trigger element's width */ + minWidth?: string | 'trigger'; + /** Maximum width of the popper. If the value is "trigger", it will set the max width to the trigger element's width */ + maxWidth?: string | 'trigger'; /** The container to append the popper to. Defaults to 'inline'. */ appendTo?: HTMLElement | (() => HTMLElement) | 'inline'; /** z-index of the popper element */ @@ -147,10 +151,12 @@ export interface PopperProps { export const Popper: React.FunctionComponent = ({ trigger, popper, - popperMatchesTriggerWidth = true, direction = 'down', position = 'left', placement, + width, + minWidth = 'trigger', + maxWidth, appendTo = 'inline', zIndex = 9999, isVisible = true, @@ -279,21 +285,44 @@ export const Popper: React.FunctionComponent = ({ () => getOppositePlacement(getPlacement()), [direction, position, placement] ); - const sameWidthMod: Modifier<'sameWidth', {}> = React.useMemo( + + const widthMods: Modifier<'widthMods', {}> = React.useMemo( () => ({ - name: 'sameWidth', - enabled: popperMatchesTriggerWidth, + name: 'widthMods', + enabled: width !== undefined || minWidth !== undefined || maxWidth !== undefined, phase: 'beforeWrite', requires: ['computeStyles'], fn: ({ state }) => { - state.styles.popper.width = `${state.rects.reference.width}px`; + const triggerWidth = state.rects.reference.width; + if (width) { + state.styles.popper.width = width === 'trigger' ? `${triggerWidth}px` : width; + } + + if (minWidth) { + state.styles.popper.minWidth = minWidth === 'trigger' ? `${triggerWidth}px` : minWidth; + } + + if (maxWidth) { + state.styles.popper.maxWidth = maxWidth === 'trigger' ? `${triggerWidth}px` : maxWidth; + } }, effect: ({ state }) => { - state.elements.popper.style.width = `${(state.elements.reference as HTMLElement).offsetWidth}px`; + const triggerWidth = (state.elements.reference as HTMLElement).offsetWidth; + if (width) { + state.elements.popper.style.width = width === 'trigger' ? `${triggerWidth}px` : width; + } + + if (minWidth) { + state.elements.popper.style.minWidth = minWidth === 'trigger' ? `${triggerWidth}px` : minWidth; + } + + if (maxWidth) { + state.elements.popper.style.maxWidth = maxWidth === 'trigger' ? `${triggerWidth}px` : maxWidth; + } return () => {}; } }), - [popperMatchesTriggerWidth] + [width, minWidth, maxWidth] ); const { @@ -326,7 +355,7 @@ export const Popper: React.FunctionComponent = ({ fallbackPlacements: flipBehavior === 'flip' ? [getOppositePlacementMemo] : flipBehavior } }, - sameWidthMod + widthMods ] }); diff --git a/packages/react-core/src/next/components/Dropdown/Dropdown.tsx b/packages/react-core/src/next/components/Dropdown/Dropdown.tsx index 89f11a496a4..6b5813feb46 100644 --- a/packages/react-core/src/next/components/Dropdown/Dropdown.tsx +++ b/packages/react-core/src/next/components/Dropdown/Dropdown.tsx @@ -22,8 +22,6 @@ export interface DropdownProps extends MenuProps, OUIAProps { isPlain?: boolean; /** Indicates if the menu should be scrollable. */ isScrollable?: boolean; - /** Min width of the menu. */ - minWidth?: string; /** @hide Forwarded ref */ innerRef?: React.Ref; /** Value to overwrite the randomly generated data-ouia-component-id.*/ @@ -33,7 +31,7 @@ export interface DropdownProps extends MenuProps, OUIAProps { /** z-index of the dropdown menu */ zIndex?: number; /** Additional properties to pass to the Popper */ - popperProps?: PopperProps; + popperProps?: Partial; } const DropdownBase: React.FunctionComponent = ({ @@ -45,7 +43,6 @@ const DropdownBase: React.FunctionComponent = ({ onOpenChange, isPlain, isScrollable, - minWidth, innerRef, ouiaId, ouiaSafe = true, @@ -106,11 +103,6 @@ const DropdownBase: React.FunctionComponent = ({ onSelect={(event, itemId) => onSelect && onSelect(event, itemId)} isPlain={isPlain} isScrollable={isScrollable} - {...(minWidth && { - style: { - '--pf-c-menu--MinWidth': minWidth - } as React.CSSProperties - })} {...props} > {children} diff --git a/packages/react-core/src/next/components/Dropdown/__tests__/Dropdown.test.tsx b/packages/react-core/src/next/components/Dropdown/__tests__/Dropdown.test.tsx index e1ff2ffe2bc..cc4e236638b 100644 --- a/packages/react-core/src/next/components/Dropdown/__tests__/Dropdown.test.tsx +++ b/packages/react-core/src/next/components/Dropdown/__tests__/Dropdown.test.tsx @@ -14,7 +14,7 @@ const dropdownChildren =
Dropdown children
; test('renders dropdown', () => { render(
- toggle(toggleRef)}>{dropdownChildren} + toggle(toggleRef)}>{dropdownChildren}
); @@ -22,20 +22,20 @@ test('renders dropdown', () => { }); test('passes children', () => { - render( toggle(toggleRef)}>{dropdownChildren}); + render( toggle(toggleRef)}>{dropdownChildren}); expect(screen.getByText('Dropdown children')).toBeVisible(); }); test('renders passed toggle element', () => { - render( toggle(toggleRef)}>{dropdownChildren}); + render( toggle(toggleRef)}>{dropdownChildren}); expect(screen.getByRole('button', { name: 'Dropdown' })).toBeVisible(); }); test('passes no class name by default', () => { render( - toggle(toggleRef)}> + toggle(toggleRef)}> {dropdownChildren} ); @@ -45,7 +45,7 @@ test('passes no class name by default', () => { test('passes custom class name', () => { render( - toggle(toggleRef)}> + toggle(toggleRef)}> {dropdownChildren} ); @@ -55,7 +55,7 @@ test('passes custom class name', () => { test('does not pass isPlain to Menu by default', () => { render( - toggle(toggleRef)}> + toggle(toggleRef)}> {dropdownChildren} ); @@ -65,7 +65,7 @@ test('does not pass isPlain to Menu by default', () => { test('passes isPlain to Menu', () => { render( - toggle(toggleRef)}> + toggle(toggleRef)}> {dropdownChildren} ); @@ -75,7 +75,7 @@ test('passes isPlain to Menu', () => { test('does not pass isScrollable to Menu by default', () => { render( - toggle(toggleRef)}> + toggle(toggleRef)}> {dropdownChildren} ); @@ -85,7 +85,7 @@ test('does not pass isScrollable to Menu by default', () => { test('passes isScrollable to Menu', () => { render( - toggle(toggleRef)}> + toggle(toggleRef)}> {dropdownChildren} ); @@ -93,35 +93,15 @@ test('passes isScrollable to Menu', () => { expect(screen.getByText('isScrollable: true')).toBeVisible(); }); -test('does not pass minWidth to Menu by default', () => { - render( - toggle(toggleRef)}> - {dropdownChildren} - - ); - - expect(screen.getByText('minWidth: undefined')).toBeVisible(); -}); - -test('passes minWidth to Menu', () => { - render( - toggle(toggleRef)}> - {dropdownChildren} - - ); - - expect(screen.getByText('minWidth: 100px')).toBeVisible(); -}); - test('passes default zIndex to popper', () => { - render( toggle(toggleRef)}>{dropdownChildren}); + render( toggle(toggleRef)}>{dropdownChildren}); expect(screen.getByText('zIndex: 9999')).toBeVisible(); }); test('passes zIndex to popper', () => { render( - toggle(toggleRef)}> + toggle(toggleRef)}> {dropdownChildren} ); @@ -130,14 +110,14 @@ test('passes zIndex to popper', () => { }); test('does not pass isOpen to popper by default', () => { - render( toggle(toggleRef)}>{dropdownChildren}); + render( toggle(toggleRef)}>{dropdownChildren}); expect(screen.getByText('isOpen: undefined')).toBeVisible(); }); test('passes isOpen to popper', () => { render( - toggle(toggleRef)}> + toggle(toggleRef)}> {dropdownChildren} ); @@ -154,7 +134,7 @@ test('passes onSelect callback', async () => { const onSelect = jest.fn(); render( - toggle(toggleRef)}> + toggle(toggleRef)}> {dropdownChildren} ); @@ -170,7 +150,7 @@ test('onOpenChange is called when passed and user clicks outside of dropdown', a const onOpenChange = jest.fn(); render( - toggle(toggleRef)}> + toggle(toggleRef)}> {dropdownChildren} ); @@ -187,7 +167,7 @@ test('onOpenChange is called when passed and user presses tab key', async () => const onOpenChange = jest.fn(); render( - toggle(toggleRef)}> + toggle(toggleRef)}> {dropdownChildren} ); @@ -205,7 +185,7 @@ test('onOpenChange is called when passed and user presses esc key', async () => const onOpenChange = jest.fn(); render( - toggle(toggleRef)}> + toggle(toggleRef)}> {dropdownChildren} ); @@ -226,7 +206,7 @@ test('match snapshot', () => { isScrollable isPlain className={'customClass'} - toggle={toggleRef => toggle(toggleRef)} + toggle={(toggleRef) => toggle(toggleRef)} > {dropdownChildren} diff --git a/packages/react-core/src/next/components/Dropdown/examples/DropdownWithDescriptions.tsx b/packages/react-core/src/next/components/Dropdown/examples/DropdownWithDescriptions.tsx index 801381081eb..7ed93c5604c 100644 --- a/packages/react-core/src/next/components/Dropdown/examples/DropdownWithDescriptions.tsx +++ b/packages/react-core/src/next/components/Dropdown/examples/DropdownWithDescriptions.tsx @@ -19,9 +19,8 @@ export const DropdownWithDescriptions: React.FunctionComponent = () => { setIsOpen(isOpen)} - toggle={toggleRef => ( + onOpenChange={(isOpen) => setIsOpen(isOpen)} + toggle={(toggleRef) => ( Dropdown @@ -36,7 +35,7 @@ export const DropdownWithDescriptions: React.FunctionComponent = () => { key="action" description="This is a very long description that describes the menu item" to="#default-link2" - onClick={ev => ev.preventDefault()} + onClick={(ev) => ev.preventDefault()} > Action diff --git a/packages/react-core/src/next/components/Dropdown/examples/DropdownWithKebabToggle.tsx b/packages/react-core/src/next/components/Dropdown/examples/DropdownWithKebabToggle.tsx index 153b3e706ec..fb966f268c7 100644 --- a/packages/react-core/src/next/components/Dropdown/examples/DropdownWithKebabToggle.tsx +++ b/packages/react-core/src/next/components/Dropdown/examples/DropdownWithKebabToggle.tsx @@ -20,9 +20,8 @@ export const DropdownWithKebab: React.FunctionComponent = () => { setIsOpen(isOpen)} - toggle={toggleRef => ( + onOpenChange={(isOpen) => setIsOpen(isOpen)} + toggle={(toggleRef) => ( { Link - ev.preventDefault()}> + ev.preventDefault()}> Action diff --git a/packages/react-core/src/next/components/Select/Select.tsx b/packages/react-core/src/next/components/Select/Select.tsx index 516d4919e66..7b9ccafa950 100644 --- a/packages/react-core/src/next/components/Select/Select.tsx +++ b/packages/react-core/src/next/components/Select/Select.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { css } from '@patternfly/react-styles'; import { Menu, MenuContent, MenuProps } from '../../../components/Menu'; -import { Popper } from '../../../helpers/Popper/Popper'; +import { Popper, PopperProps } from '../../../helpers/Popper/Popper'; import { getOUIAProps, OUIAProps, getDefaultOUIAId } from '../../../helpers'; export interface SelectProps extends MenuProps, OUIAProps { @@ -22,14 +22,14 @@ export interface SelectProps extends MenuProps, OUIAProps { onOpenChange?: (isOpen: boolean) => void; /** Indicates if the select should be without the outer box-shadow */ isPlain?: boolean; - /** Minimum width of the select menu */ - minWidth?: string; /** @hide Forwarded ref */ innerRef?: React.Ref; /** z-index of the select menu */ zIndex?: number; /** @beta Determines the accessible role of the select. For a checkbox select pass in "menu". */ role?: string; + /** Additional properties to pass to the popper */ + popperProps?: Partial; } const SelectBase: React.FunctionComponent = ({ @@ -41,10 +41,10 @@ const SelectBase: React.FunctionComponent = ({ toggle, onOpenChange, isPlain, - minWidth, innerRef, zIndex = 9999, role = 'listbox', + popperProps, ...props }: SelectProps & OUIAProps) => { const localMenuRef = React.useRef(); @@ -100,11 +100,6 @@ const SelectBase: React.FunctionComponent = ({ onSelect={(event, itemId) => onSelect && onSelect(event, itemId)} isPlain={isPlain} selected={selected} - {...(minWidth && { - style: { - '--pf-c-menu--MinWidth': minWidth - } as React.CSSProperties - })} {...getOUIAProps( Select.displayName, props.ouiaId !== undefined ? props.ouiaId : getDefaultOUIAId(Select.displayName), @@ -125,6 +120,7 @@ const SelectBase: React.FunctionComponent = ({ appendTo={containerRef.current || undefined} isVisible={isOpen} zIndex={zIndex} + {...popperProps} /> ); diff --git a/packages/react-table/src/components/Table/ActionsColumn.tsx b/packages/react-table/src/components/Table/ActionsColumn.tsx index b8a2bdfab04..460f20d7d6b 100644 --- a/packages/react-table/src/components/Table/ActionsColumn.tsx +++ b/packages/react-table/src/components/Table/ActionsColumn.tsx @@ -37,8 +37,7 @@ const ActionsColumnBase: React.FunctionComponent = ({ actionsToggle, popperProps = { position: 'right', - direction: 'down', - popperMatchesTriggerWidth: false + direction: 'down' }, ...props }: ActionsColumnProps) => { @@ -65,12 +64,12 @@ const ActionsColumnBase: React.FunctionComponent = ({ return ( {items - .filter(item => item.isOutsideDropdown) + .filter((item) => item.isOutsideDropdown) // eslint-disable-next-line @typescript-eslint/no-unused-vars .map(({ title, itemKey, onClick, isOutsideDropdown, ...props }, key) => typeof title === 'string' ? (