diff --git a/packages/react/src/components/DropdownSelector/DropdownPopover.tsx b/packages/react/src/components/DropdownSelector/DropdownPopover.tsx index 5dbffcda5..5a19a903e 100644 --- a/packages/react/src/components/DropdownSelector/DropdownPopover.tsx +++ b/packages/react/src/components/DropdownSelector/DropdownPopover.tsx @@ -26,7 +26,6 @@ export function DropdownPopover({ children, ...props }: DropdownPopoverProps) { const selectedElement = document.querySelector( `[data-key="${props.value.toString()}"]` ) as HTMLElement | undefined - selectedElement?.scrollIntoView({ block: 'center' }) selectedElement?.focus() window.scrollTo(windowScrollX, windowScrollY) } diff --git a/packages/react/src/components/DropdownSelector/Popover/index.tsx b/packages/react/src/components/DropdownSelector/Popover/index.tsx index 1fa36c8f3..1a3780ef7 100644 --- a/packages/react/src/components/DropdownSelector/Popover/index.tsx +++ b/packages/react/src/components/DropdownSelector/Popover/index.tsx @@ -1,8 +1,10 @@ -import { RefObject, useRef } from 'react' +import { RefObject, useContext, useRef } from 'react' import { ReactNode } from 'react' import { DismissButton, Overlay, usePopover } from '@react-aria/overlays' import styled from 'styled-components' import { theme } from '../../../styled' +import { ModalBackgroundContext } from '../../Modal/ModalBackgroundContext' +import { usePreventScroll } from './usePreventScroll' export type PopoverProps = { isOpen: boolean @@ -40,11 +42,24 @@ export default function Popover(props: PopoverProps) { } ) + const modalBackground = useContext(ModalBackgroundContext) + usePreventScroll(modalBackground, props.isOpen) + if (!props.isOpen) return null return ( -
+
props.onClose()} /> {props.children} diff --git a/packages/react/src/components/DropdownSelector/Popover/usePreventScroll.tsx b/packages/react/src/components/DropdownSelector/Popover/usePreventScroll.tsx new file mode 100644 index 000000000..1c3cb9891 --- /dev/null +++ b/packages/react/src/components/DropdownSelector/Popover/usePreventScroll.tsx @@ -0,0 +1,18 @@ +import { useEffect } from 'react' + +export function usePreventScroll(element: HTMLElement | null, isOpen: boolean) { + useEffect(() => { + if (isOpen && element) { + const defaultPaddingRight = element.style.paddingRight + const defaultOverflow = element.style.overflow + element.style.paddingRight = `${ + window.innerWidth - element.clientWidth + }px` + element.style.overflow = 'hidden' + return () => { + element.style.paddingRight = defaultPaddingRight + element.style.overflow = defaultOverflow + } + } + }, [element, isOpen]) +} diff --git a/packages/react/src/components/DropdownSelector/index.story.tsx b/packages/react/src/components/DropdownSelector/index.story.tsx index 415898351..2931ed778 100644 --- a/packages/react/src/components/DropdownSelector/index.story.tsx +++ b/packages/react/src/components/DropdownSelector/index.story.tsx @@ -4,6 +4,10 @@ import { Story } from '../../_lib/compat' import { Divider } from './Divider' import MenuItemGroup from './MenuItemGroup' import DropdownMenuItem from './DropdownMenuItem' +import Modal from '../Modal' +import { ModalBody, ModalHeader } from '../Modal/ModalPlumbing' +import styled from 'styled-components' +import Button from '../Button' export default { title: 'DropdownSelector', @@ -26,6 +30,7 @@ export const Playground: Story = ( const [selected, setSelected] = useState('50') return (
+ { @@ -51,27 +56,78 @@ Playground.args = { ...baseProps } export const Basic: Story = ( props: DropdownSelectorProps ) => { - const [selected, setSelected] = useState('') return (
- { - setSelected(value) - }} - value={selected} - label="label" - > - Apple - Banana - Orange - +
) } Basic.args = { ...baseProps } +function PlaygroundDropdownSelector(props: Partial) { + const [selected, setSelected] = useState('10') + return ( + { + setSelected(value) + }} + value={selected} + label="label" + > + Apple + Banana + Orange + + ) +} + +const DummyBox = styled.div` + border: solid 1px ${({ theme }) => theme.border.default.color}; + display: flex; + justify-content: center; + align-items: center; + height: 256px; +` + +export const InModal: Story = () => { + const [open, setOpen] = useState(true) + return ( +
+ + { + setOpen(false) + }} + > + + +
+ 256px + + 256px + + 256px +
+
+
+
+ ) +} + export const InFormTag: Story = ( props: DropdownSelectorProps ) => { diff --git a/packages/react/src/components/Modal/ModalBackgroundContext.tsx b/packages/react/src/components/Modal/ModalBackgroundContext.tsx new file mode 100644 index 000000000..3a8f0a752 --- /dev/null +++ b/packages/react/src/components/Modal/ModalBackgroundContext.tsx @@ -0,0 +1,8 @@ +import * as React from 'react' + +/** + * ModalBackgroundのElementが入ったコンテキスト + */ +export const ModalBackgroundContext = React.createContext( + null +) diff --git a/packages/react/src/components/Modal/index.story.tsx b/packages/react/src/components/Modal/index.story.tsx index 947fefb57..31fe9b9d8 100644 --- a/packages/react/src/components/Modal/index.story.tsx +++ b/packages/react/src/components/Modal/index.story.tsx @@ -12,6 +12,8 @@ import { import styled from 'styled-components' import { theme } from '../../styled' import TextField from '../TextField' +import DropdownSelector from '../DropdownSelector' +import DropdownMenuItem from '../DropdownSelector/DropdownMenuItem' export default { title: 'Modal', @@ -75,6 +77,19 @@ const M = (props: ModalProps) => { placeholder="Tokyo" > + + null} + value="10" + showLabel + label="Fruits" + placeholder="Apple" + > + Apple + Banana + Orange + +