From 730f6f290b6d20a7b473d3b9c4f5c6759b41b49c Mon Sep 17 00:00:00 2001 From: atomiks Date: Tue, 15 Oct 2024 15:13:23 +1100 Subject: [PATCH] Adjust positioning --- docs/data/components/select/select.mdx | 6 ++++-- .../src/Select/OptionText/SelectOptionText.tsx | 13 +++++++++++-- .../src/Select/Positioner/useSelectPositioner.tsx | 2 -- packages/mui-base/src/utils/useAnchorPositioning.ts | 10 ++-------- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/docs/data/components/select/select.mdx b/docs/data/components/select/select.mdx index 34fffe199..3fb2aa882 100644 --- a/docs/data/components/select/select.mdx +++ b/docs/data/components/select/select.mdx @@ -144,14 +144,16 @@ By default, the selected option inside the popup is aligned to the trigger eleme ``` -- **`alignOptionToTrigger`**: aligns the popup such that the selected option inside of it appears centered over the trigger. If there's not enough space, it falls back to standard anchoring. This method is useful as it allows the user to select the an option in a single click or "pointer cycle" (pointer down, pointer move, pointer up). This is the native behavior on macOS; the scroll arrow components must be used to ensure a single pointer cycle can be used. +- **`alignOptionToTrigger={true}`**: aligns the popup such that the selected option inside of it appears centered over the trigger. If there's not enough space, it falls back to standard anchoring. This method is useful as it allows the user to select an option in a single click or "pointer cycle" (pointer down, pointer move, pointer up). This is the native behavior on macOS; the scroll arrow components must be used to ensure a single pointer cycle can be used. - **`alignOptionToTrigger={false}`**: aligns the popup to the trigger itself on its top or bottom side, which is the standard form of anchor positioning used in Tooltip, Popover, Menu, etc. +This option is always `false` on touch devices or touch input. + ### Scrollable popup -When disabling `alignOptionToTrigger`, the select's height needs to be manually limited by its available space using CSS. +The select's height needs to be manually limited by its available space using CSS. This can be achieved by using the `--available-height` CSS variable: diff --git a/packages/mui-base/src/Select/OptionText/SelectOptionText.tsx b/packages/mui-base/src/Select/OptionText/SelectOptionText.tsx index 534741ebb..48d4c6a38 100644 --- a/packages/mui-base/src/Select/OptionText/SelectOptionText.tsx +++ b/packages/mui-base/src/Select/OptionText/SelectOptionText.tsx @@ -25,8 +25,15 @@ const SelectOptionText = React.forwardRef(function SelectOptionText( ) { const { className, render, ...otherProps } = props; - const { open, triggerElement, valueRef, popupRef, innerFallback, alignOptionToTrigger } = - useSelectRootContext(); + const { + open, + triggerElement, + valueRef, + popupRef, + innerFallback, + touchModality, + alignOptionToTrigger, + } = useSelectRootContext(); const { isPositioned, setOptionTextOffset } = useSelectPositionerContext(); const { selected } = useSelectOptionContext(); @@ -38,6 +45,7 @@ const SelectOptionText = React.forwardRef(function SelectOptionText( useEnhancedEffect(() => { if ( !alignOptionToTrigger || + touchModality || innerFallback || !open || !isPositioned || @@ -69,6 +77,7 @@ const SelectOptionText = React.forwardRef(function SelectOptionText( setOptionTextOffset, triggerElement, valueRef, + touchModality, ]); const { renderElement } = useComponentRenderer({ diff --git a/packages/mui-base/src/Select/Positioner/useSelectPositioner.tsx b/packages/mui-base/src/Select/Positioner/useSelectPositioner.tsx index 6362eba3c..8f661d902 100644 --- a/packages/mui-base/src/Select/Positioner/useSelectPositioner.tsx +++ b/packages/mui-base/src/Select/Positioner/useSelectPositioner.tsx @@ -52,8 +52,6 @@ export function useSelectPositioner( touchModality, }, trackAnchor: !itemAligned, - collisionPadding: - touchModality && params.collisionPadding == null ? 20 : params.collisionPadding, }); const getPositionerProps: useSelectPositioner.ReturnValue['getPositionerProps'] = diff --git a/packages/mui-base/src/utils/useAnchorPositioning.ts b/packages/mui-base/src/utils/useAnchorPositioning.ts index 3b9abbcea..918dddffe 100644 --- a/packages/mui-base/src/utils/useAnchorPositioning.ts +++ b/packages/mui-base/src/utils/useAnchorPositioning.ts @@ -102,7 +102,7 @@ export function useAnchorPositioning( innerOptions = {}, } = params; - const standardMode = !(!innerOptions.fallback && innerMiddleware); + const standardMode = innerOptions.touchModality || !(!innerOptions.fallback && innerMiddleware); const placement = alignment === 'center' ? side : (`${side}-${alignment}` as Placement); const commonCollisionProps = { @@ -153,13 +153,7 @@ export function useAnchorPositioning( } middleware.push( - ...(!standardMode - ? [innerMiddleware, shiftMiddleware] - : [ - innerOptions.touchModality - ? shift({ crossAxis: true, ...commonCollisionProps }) - : (false as const), - ]), + ...(!standardMode ? [innerMiddleware, shiftMiddleware] : []), size({ ...commonCollisionProps, apply({ elements: { floating }, rects: { reference }, availableWidth, availableHeight }) {