Skip to content

Commit

Permalink
fix!: DropdownScrollArea と DropdownContent の scrollable を削除 (#5000)
Browse files Browse the repository at this point in the history
  • Loading branch information
uknmr authored Oct 15, 2024
1 parent 8025cc3 commit b6f6548
Show file tree
Hide file tree
Showing 14 changed files with 156 additions and 221 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { tv } from 'tailwind-variants'

import { AnchorButton, Button, UnstyledButton } from '../Button'
import { RemoteDialogTrigger } from '../Dialog'
import { Dropdown, DropdownContent, DropdownScrollArea, DropdownTrigger } from '../Dropdown'
import { Dropdown, DropdownContent, DropdownTrigger } from '../Dropdown'
import { dropdownMenuButton } from '../Dropdown/DropdownMenuButton/DropdownMenuButton'
import { FaCaretDownIcon } from '../Icon'

Expand Down Expand Up @@ -69,9 +69,7 @@ export const AppNaviDropdownMenuButton: FC<AppNaviDropdownMenuButtonProps> = ({
</UnstyledButton>
</DropdownTrigger>
<DropdownContent>
<DropdownScrollArea as="ul" className={actionListStyle()}>
{actualChildren}
</DropdownScrollArea>
<ul className={actionListStyle()}>{actualChildren}</ul>
</DropdownContent>
</Dropdown>
)
Expand Down
150 changes: 70 additions & 80 deletions packages/smarthr-ui/src/components/Dropdown/Dropdown.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { Dropdown } from './Dropdown'
import { DropdownCloser } from './DropdownCloser'
import { DropdownContent } from './DropdownContent'
import { DropdownMenuButton } from './DropdownMenuButton'
import { DropdownScrollArea } from './DropdownScrollArea'
import { DropdownTrigger } from './DropdownTrigger'
import { FilterDropdown } from './FilterDropdown'
import { SortDropdown } from './SortDropdown'
Expand All @@ -32,7 +31,6 @@ export default {
DropdownTrigger,
DropdownContent,
DropdownCloser,
DropdownScrollArea,
},
parameters: {
withTheming: true,
Expand Down Expand Up @@ -72,65 +70,61 @@ export const ControllableDropdown = () => {
<TriggerButton data-test="controlled-dropdown-trigger">制御された Dropdown</TriggerButton>
</DropdownTrigger>
<DropdownContent controllable>
<DropdownScrollArea>
<ControllableBoxDiv>
<Fieldset title="Dropdown内部">
<Text as="p">
`DropdownControllableContent` を使うとドロップダウン制御できます。
</Text>
<Text as="p">
制御されたドロップダウン内のコンテンツをクリックしても、ドロップダウンは閉じません。
<br />
ドロップダウンを閉じたいときは、`DropdownCloser` を使います。
</Text>
<Stack align="flex-start">
<RadioButtonList>
<li>
<RadioButton name="hoge" checked={value === 'hoge'} onChange={onChangeValue}>
hoge
</RadioButton>
</li>
<li>
<RadioButton name="fuga" checked={value === 'fuga'} onChange={onChangeValue}>
fuga
</RadioButton>
</li>
<li>
<RadioButton name="piyo" checked={value === 'piyo'} onChange={onChangeValue}>
piyo
</RadioButton>
</li>
</RadioButtonList>
<Input name="test" value={text} onChange={onChangeText} title="test" />
<DropdownCloser>
<Button
onClick={() => setIsDialogOpen(true)}
aria-controls="dropdown-dialog"
aria-haspopup="dialog"
data-test="dropdown-dialog-trigger"
>
ダイアログを開く
</Button>
</DropdownCloser>
</Stack>
</Fieldset>
</ControllableBoxDiv>
<ControllableBoxBottom>
<Cluster justify="flex-end">
<DropdownCloser>
<Button>Close only</Button>
</DropdownCloser>
<ControllableBoxDiv>
<Fieldset title="Dropdown内部">
<Text as="p">`DropdownControllableContent` を使うとドロップダウン制御できます。</Text>
<Text as="p">
制御されたドロップダウン内のコンテンツをクリックしても、ドロップダウンは閉じません。
<br />
ドロップダウンを閉じたいときは、`DropdownCloser` を使います。
</Text>
<Stack align="flex-start">
<RadioButtonList>
<li>
<RadioButton name="hoge" checked={value === 'hoge'} onChange={onChangeValue}>
hoge
</RadioButton>
</li>
<li>
<RadioButton name="fuga" checked={value === 'fuga'} onChange={onChangeValue}>
fuga
</RadioButton>
</li>
<li>
<RadioButton name="piyo" checked={value === 'piyo'} onChange={onChangeValue}>
piyo
</RadioButton>
</li>
</RadioButtonList>
<Input name="test" value={text} onChange={onChangeText} title="test" />
<DropdownCloser>
<Button variant="primary" onClick={action('clicked button 1')}>
Action and close
<Button
onClick={() => setIsDialogOpen(true)}
aria-controls="dropdown-dialog"
aria-haspopup="dialog"
data-test="dropdown-dialog-trigger"
>
ダイアログを開く
</Button>
</DropdownCloser>
<Button variant="primary" onClick={action('clicked button 2')}>
Action only
</Stack>
</Fieldset>
</ControllableBoxDiv>
<ControllableBoxBottom>
<Cluster justify="flex-end">
<DropdownCloser>
<Button>Close only</Button>
</DropdownCloser>
<DropdownCloser>
<Button variant="primary" onClick={action('clicked button 1')}>
Action and close
</Button>
</Cluster>
</ControllableBoxBottom>
</DropdownScrollArea>
</DropdownCloser>
<Button variant="primary" onClick={action('clicked button 2')}>
Action only
</Button>
</Cluster>
</ControllableBoxBottom>
</DropdownContent>
</Dropdown>
<Dialog isOpen={isDialogOpen} id="dropdown-dialog">
Expand Down Expand Up @@ -173,29 +167,25 @@ const Template: StoryFn = () => (
<Button>入れ子にできる Dropdown</Button>
</DropdownTrigger>
<DropdownContent controllable>
<DropdownScrollArea>
<ControllableBoxDiv>
<Dropdown>
<DropdownTrigger>
<Button>さらに入れ子にできる Dropdown</Button>
</DropdownTrigger>
<DropdownContent controllable>
<DropdownScrollArea>
<ControllableBoxDiv>
<Dropdown>
<DropdownTrigger>
<TriggerButton>いくらでも入れ子にできる Dropdown</TriggerButton>
</DropdownTrigger>
<DropdownContent>
<ListMenu />
</DropdownContent>
</Dropdown>
</ControllableBoxDiv>
</DropdownScrollArea>
</DropdownContent>
</Dropdown>
</ControllableBoxDiv>
</DropdownScrollArea>
<ControllableBoxDiv>
<Dropdown>
<DropdownTrigger>
<Button>さらに入れ子にできる Dropdown</Button>
</DropdownTrigger>
<DropdownContent controllable>
<ControllableBoxDiv>
<Dropdown>
<DropdownTrigger>
<TriggerButton>いくらでも入れ子にできる Dropdown</TriggerButton>
</DropdownTrigger>
<DropdownContent>
<ListMenu />
</DropdownContent>
</Dropdown>
</ControllableBoxDiv>
</DropdownContent>
</Dropdown>
</ControllableBoxDiv>
</DropdownContent>
</Dropdown>
</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ const closer = tv({
type Props = PropsWithChildren<ComponentProps<'div'>>

export const DropdownCloser: React.FC<Props> = ({ children, className }) => {
const { onClickCloser, controllable, scrollable } = useContext(DropdownContentContext)
const { onClickCloser, controllable } = useContext(DropdownContentContext)
const { maxHeight } = useContext(DropdownContentInnerContext)

const styleProps = useMemo(() => {
const maxHeightStyle = !controllable && scrollable ? maxHeight : undefined
const maxHeightStyle = controllable ? undefined : maxHeight
return {
className: closer({ controllable, className }),
style: {
maxHeight: maxHeightStyle,
},
}
}, [className, controllable, maxHeight, scrollable])
}, [className, controllable, maxHeight])

return (
// eslint-disable-next-line smarthr/a11y-delegate-element-has-role-presentation
Expand Down
14 changes: 2 additions & 12 deletions packages/smarthr-ui/src/components/Dropdown/DropdownContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ import { DropdownContentInner, ElementProps as InnerElementProps } from './Dropd
export const DropdownContentContext = React.createContext<{
onClickCloser: () => void
controllable: boolean
scrollable: boolean
}>({
onClickCloser: () => {
/* noop */
},
controllable: false,
scrollable: true,
})

type Props = PropsWithChildren<{
Expand All @@ -21,28 +19,20 @@ type Props = PropsWithChildren<{
* この場合は、 `DropdownCloser` を用いてドロップダウンを閉じることができる。
*/
controllable?: boolean
/** `true` のとき、ウィンドウサイズに応じてドロップダウン内が自動的にスクロール可能になる */
scrollable?: boolean
}>

type ElementProps = Omit<InnerElementProps, keyof Props>

export const DropdownContent: React.FC<Props & ElementProps> = ({
controllable = false,
scrollable = true,
...props
}) => {
const { DropdownContentRoot, triggerRect, onClickCloser } = useContext(DropdownContext)

return (
<DropdownContentRoot>
<DropdownContentContext.Provider value={{ onClickCloser, controllable, scrollable }}>
<DropdownContentInner
{...props}
triggerRect={triggerRect}
scrollable={scrollable}
controllable={controllable}
/>
<DropdownContentContext.Provider value={{ onClickCloser, controllable }}>
<DropdownContentInner {...props} triggerRect={triggerRect} controllable={controllable} />
</DropdownContentContext.Provider>
</DropdownContentRoot>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,17 @@ import { ContentBoxStyle, Rect, getContentBoxStyle } from './dropdownHelper'
import { useKeyboardNavigation } from './useKeyboardNavigation'

const contentInner = tv({
slots: {
wrapper:
'smarthr-ui-Dropdown-content shr-absolute shr-z-overlap-base shr-flex shr-break-words shr-rounded-m shr-bg-white shr-shadow-layer-3',
controllableWrapper: 'shr-flex shr-flex-col',
},
base: 'smarthr-ui-Dropdown-content shr-absolute shr-z-overlap-base shr-break-words shr-rounded-m shr-bg-white shr-shadow-layer-3 shr-overflow-y-auto',
variants: {
isActive: {
true: {
wrapper: 'shr-visible',
},
false: {
wrapper: 'shr-invisible',
},
true: 'shr-visible',
false: 'shr-invisible',
},
},
})

type Props = PropsWithChildren<{
triggerRect: Rect
scrollable: boolean
controllable: boolean
}>

Expand All @@ -52,7 +43,6 @@ export const DropdownContentInnerContext = createContext<DropdownContentInnerCon

export const DropdownContentInner: FC<Props & ElementProps> = ({
triggerRect,
scrollable,
children,
className,
controllable,
Expand All @@ -66,32 +56,29 @@ export const DropdownContentInner: FC<Props & ElementProps> = ({
const wrapperRef = useRef<HTMLDivElement>(null)
const focusTargetRef = useRef<HTMLDivElement>(null)

const { wrapper, controllableWrapper } = useMemo(() => contentInner(), [])

const wrapperStyleProps = useMemo(() => {
const leftMargin = contentBox.left === undefined ? spacing[0.5] : `max(${contentBox.left}, 0px)`
const rightMargin =
contentBox.right === undefined ? spacing[0.5] : `max(${contentBox.right}, 0px)`
const maxWidthStyle = `calc(100% - ${leftMargin} - ${rightMargin})`

return {
className: `${wrapper({ isActive, className })}`,
className: contentInner({ isActive, className }),
style: {
insetBlockStart: contentBox.top,
insetInlineStart: contentBox.left || undefined,
insetInlineEnd: contentBox.right || undefined,
maxWidth: maxWidthStyle,
},
}
}, [className, contentBox.left, contentBox.right, contentBox.top, isActive, spacing, wrapper])
}, [className, contentBox.left, contentBox.right, contentBox.top, isActive])
const controllableWrapperStyleProps = useMemo(
() => ({
className: controllableWrapper(),
style: {
maxHeight: contentBox.maxHeight && scrollable ? contentBox.maxHeight : 'initial',
maxHeight: contentBox.maxHeight || undefined,
},
}),
[contentBox.maxHeight, scrollable, controllableWrapper],
[contentBox.maxHeight],
)

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import React, {
import innerText from 'react-innertext'
import { tv } from 'tailwind-variants'

import { Dropdown, DropdownContent, DropdownScrollArea, DropdownTrigger } from '..'
import { Dropdown, DropdownContent, DropdownTrigger } from '..'
import { AnchorButton, Button, BaseProps as ButtonProps } from '../../Button'
import { RemoteDialogTrigger } from '../../Dialog'
import { FaCaretDownIcon, FaEllipsisIcon } from '../../Icon'
Expand Down Expand Up @@ -74,7 +74,7 @@ export const DropdownMenuButton: FC<Props & ElementProps> = ({
className,
...props
}) => {
const containerRef = React.useRef<HTMLDivElement>(null)
const containerRef = React.useRef<HTMLUListElement>(null)

const triggerLabel = useMemo(() => {
const Icon = TriggerIcon || FaEllipsisIcon
Expand Down Expand Up @@ -114,13 +114,13 @@ export const DropdownMenuButton: FC<Props & ElementProps> = ({
</Button>
</DropdownTrigger>
<DropdownContent>
<DropdownScrollArea as="ul" ref={containerRef} className={actionListStyle}>
<ul ref={containerRef} className={actionListStyle}>
{React.Children.map(children, (item, i) =>
// MEMO: {flag && <Button/>}のような書き方に対応させる為、型を変換する
// itemの存在チェックでfalsyな値は弾かれている想定
item ? <li key={i}>{actionItem(item as ActionItemTruthyType)}</li> : null,
)}
</DropdownScrollArea>
</ul>
</DropdownContent>
</Dropdown>
)
Expand Down
18 changes: 0 additions & 18 deletions packages/smarthr-ui/src/components/Dropdown/DropdownScrollArea.tsx

This file was deleted.

Loading

0 comments on commit b6f6548

Please sign in to comment.