diff --git a/.changeset/plenty-suns-juggle.md b/.changeset/plenty-suns-juggle.md new file mode 100644 index 0000000000..8e36f81fc1 --- /dev/null +++ b/.changeset/plenty-suns-juggle.md @@ -0,0 +1,6 @@ +--- +"@nextui-org/autocomplete": patch +"@nextui-org/popover": patch +--- + +add `disableDialogFocus` to free-solo-popover (#3225, #3124, #3203) diff --git a/packages/components/autocomplete/src/use-autocomplete.ts b/packages/components/autocomplete/src/use-autocomplete.ts index cf8482948e..b3c9890764 100644 --- a/packages/components/autocomplete/src/use-autocomplete.ts +++ b/packages/components/autocomplete/src/use-autocomplete.ts @@ -460,6 +460,9 @@ export function useAutocomplete(originalProps: UseAutocomplete shouldCloseOnInteractOutside: popoverProps?.shouldCloseOnInteractOutside ? popoverProps.shouldCloseOnInteractOutside : (element: Element) => ariaShouldCloseOnInteractOutside(element, inputWrapperRef, state), + // when the popover is open, the focus should be on input instead of dialog + // therefore, we skip dialog focus here + disableDialogFocus: true, } as unknown as PopoverProps; }; diff --git a/packages/components/popover/src/free-solo-popover.tsx b/packages/components/popover/src/free-solo-popover.tsx index 036a0ce348..149e9b53b6 100644 --- a/packages/components/popover/src/free-solo-popover.tsx +++ b/packages/components/popover/src/free-solo-popover.tsx @@ -24,6 +24,7 @@ export interface FreeSoloPopoverProps extends Omit originX?: number; originY?: number; }; + disableDialogFocus?: boolean; } type FreeSoloPopoverWrapperProps = { @@ -87,7 +88,7 @@ const FreeSoloPopoverWrapper = forwardRef<"div", FreeSoloPopoverWrapperProps>( FreeSoloPopoverWrapper.displayName = "NextUI.FreeSoloPopoverWrapper"; const FreeSoloPopover = forwardRef<"div", FreeSoloPopoverProps>( - ({children, transformOrigin, ...props}, ref) => { + ({children, transformOrigin, disableDialogFocus = false, ...props}, ref) => { const { Component, state, @@ -109,7 +110,10 @@ const FreeSoloPopover = forwardRef<"div", FreeSoloPopoverProps>( const dialogRef = React.useRef(null); const {dialogProps: ariaDialogProps, titleProps} = useDialog({}, dialogRef); const dialogProps = getDialogProps({ - ref: dialogRef, + // by default, focus is moved into the dialog on mount + // we can use `disableDialogFocus` to disable this behaviour + // e.g. in autocomplete, the focus should be moved to the input (handled in autocomplete hook) instead of the dialog first + ...(!disableDialogFocus && {ref: dialogRef}), ...ariaDialogProps, });