@charcoal-ui/react 6.0.0-rc.9 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_lib/compat.d.ts.map +1 -1
- package/dist/_lib/createDivComponent.cjs +0 -1
- package/dist/_lib/createDivComponent.cjs.map +1 -1
- package/dist/_lib/createDivComponent.d.ts +1 -1
- package/dist/_lib/createDivComponent.js.map +1 -1
- package/dist/_lib/index.cjs.map +1 -1
- package/dist/_lib/index.js.map +1 -1
- package/dist/_lib/useClassNames.cjs +0 -1
- package/dist/_lib/useClassNames.cjs.map +1 -1
- package/dist/_lib/useClassNames.js.map +1 -1
- package/dist/_lib/useForwardedRef.cjs +1 -1
- package/dist/_lib/useForwardedRef.cjs.map +1 -1
- package/dist/_lib/useForwardedRef.js.map +1 -1
- package/dist/_lib/useIsomorphicLayoutEffect.cjs +0 -1
- package/dist/_lib/useIsomorphicLayoutEffect.cjs.map +1 -1
- package/dist/_lib/useIsomorphicLayoutEffect.d.ts +2 -2
- package/dist/_lib/useIsomorphicLayoutEffect.d.ts.map +1 -1
- package/dist/_lib/useIsomorphicLayoutEffect.js.map +1 -1
- package/dist/components/Button/index.d.ts +1 -1
- package/dist/components/Button/index.d.ts.map +1 -1
- package/dist/components/Button/index2.cjs +1 -1
- package/dist/components/Button/index2.cjs.map +1 -1
- package/dist/components/Button/index2.js.map +1 -1
- package/dist/components/Carousel/CarouselItem.cjs +0 -1
- package/dist/components/Carousel/CarouselItem.cjs.map +1 -1
- package/dist/components/Carousel/CarouselItem.d.ts.map +1 -1
- package/dist/components/Carousel/CarouselItem.js.map +1 -1
- package/dist/components/Carousel/carouselStore.cjs.map +1 -1
- package/dist/components/Carousel/carouselStore.js.map +1 -1
- package/dist/components/Carousel/index.d.ts +1 -1
- package/dist/components/Carousel/index.d.ts.map +1 -1
- package/dist/components/Carousel/index2.cjs +0 -1
- package/dist/components/Carousel/index2.cjs.map +1 -1
- package/dist/components/Carousel/index2.js.map +1 -1
- package/dist/components/Carousel/intersectionObserver.cjs.map +1 -1
- package/dist/components/Carousel/intersectionObserver.js.map +1 -1
- package/dist/components/Carousel/resizeObserver.cjs.map +1 -1
- package/dist/components/Carousel/resizeObserver.js.map +1 -1
- package/dist/components/Carousel/store.cjs.map +1 -1
- package/dist/components/Carousel/store.js.map +1 -1
- package/dist/components/Carousel/useCarouselScroller.cjs +0 -1
- package/dist/components/Carousel/useCarouselScroller.cjs.map +1 -1
- package/dist/components/Carousel/useCarouselScroller.js.map +1 -1
- package/dist/components/Checkbox/CheckboxInput/index.d.ts.map +1 -1
- package/dist/components/Checkbox/CheckboxInput/index2.cjs +0 -1
- package/dist/components/Checkbox/CheckboxInput/index2.cjs.map +1 -1
- package/dist/components/Checkbox/CheckboxInput/index2.js.map +1 -1
- package/dist/components/Checkbox/CheckboxWithLabel.cjs +1 -1
- package/dist/components/Checkbox/CheckboxWithLabel.cjs.map +1 -1
- package/dist/components/Checkbox/CheckboxWithLabel.d.ts +2 -2
- package/dist/components/Checkbox/CheckboxWithLabel.d.ts.map +1 -1
- package/dist/components/Checkbox/CheckboxWithLabel.js.map +1 -1
- package/dist/components/Checkbox/index.d.ts.map +1 -1
- package/dist/components/Checkbox/index2.cjs +0 -1
- package/dist/components/Checkbox/index2.cjs.map +1 -1
- package/dist/components/Checkbox/index2.js.map +1 -1
- package/dist/components/Clickable/index.d.ts +1 -1
- package/dist/components/Clickable/index.d.ts.map +1 -1
- package/dist/components/Clickable/index2.cjs +1 -1
- package/dist/components/Clickable/index2.cjs.map +1 -1
- package/dist/components/Clickable/index2.js.map +1 -1
- package/dist/components/DropdownSelector/DropdownMenuItem/index2.cjs +0 -1
- package/dist/components/DropdownSelector/DropdownMenuItem/index2.cjs.map +1 -1
- package/dist/components/DropdownSelector/DropdownMenuItem/index2.js.map +1 -1
- package/dist/components/DropdownSelector/DropdownPopover.cjs +0 -1
- package/dist/components/DropdownSelector/DropdownPopover.cjs.map +1 -1
- package/dist/components/DropdownSelector/DropdownPopover.js.map +1 -1
- package/dist/components/DropdownSelector/ListItem/index.d.ts +1 -1
- package/dist/components/DropdownSelector/ListItem/index.d.ts.map +1 -1
- package/dist/components/DropdownSelector/ListItem/index2.cjs +0 -1
- package/dist/components/DropdownSelector/ListItem/index2.cjs.map +1 -1
- package/dist/components/DropdownSelector/ListItem/index2.js.map +1 -1
- package/dist/components/DropdownSelector/MenuItem/index.cjs +29 -2
- package/dist/components/DropdownSelector/MenuItem/index.cjs.map +1 -1
- package/dist/components/DropdownSelector/MenuItem/index.d.ts.map +1 -1
- package/dist/components/DropdownSelector/MenuItem/index.js +30 -2
- package/dist/components/DropdownSelector/MenuItem/index.js.map +1 -1
- package/dist/components/DropdownSelector/MenuItem/internals/handleFocusByKeyBoard.cjs.map +1 -1
- package/dist/components/DropdownSelector/MenuItem/internals/handleFocusByKeyBoard.js.map +1 -1
- package/dist/components/DropdownSelector/MenuItem/internals/useMenuItemHandleKeyDown.cjs +0 -1
- package/dist/components/DropdownSelector/MenuItem/internals/useMenuItemHandleKeyDown.cjs.map +1 -1
- package/dist/components/DropdownSelector/MenuItem/internals/useMenuItemHandleKeyDown.js.map +1 -1
- package/dist/components/DropdownSelector/MenuItemGroup/index2.cjs +0 -1
- package/dist/components/DropdownSelector/MenuItemGroup/index2.cjs.map +1 -1
- package/dist/components/DropdownSelector/MenuItemGroup/index2.js.map +1 -1
- package/dist/components/DropdownSelector/MenuList/MenuListContext.cjs +0 -1
- package/dist/components/DropdownSelector/MenuList/MenuListContext.cjs.map +1 -1
- package/dist/components/DropdownSelector/MenuList/MenuListContext.js.map +1 -1
- package/dist/components/DropdownSelector/MenuList/index2.cjs +0 -1
- package/dist/components/DropdownSelector/MenuList/index2.cjs.map +1 -1
- package/dist/components/DropdownSelector/MenuList/index2.js.map +1 -1
- package/dist/components/DropdownSelector/MenuList/internals/getValuesRecursive.cjs +1 -1
- package/dist/components/DropdownSelector/MenuList/internals/getValuesRecursive.cjs.map +1 -1
- package/dist/components/DropdownSelector/MenuList/internals/getValuesRecursive.js.map +1 -1
- package/dist/components/DropdownSelector/Popover/index.d.ts.map +1 -1
- package/dist/components/DropdownSelector/Popover/index2.cjs +18 -1
- package/dist/components/DropdownSelector/Popover/index2.cjs.map +1 -1
- package/dist/components/DropdownSelector/Popover/index2.js +19 -1
- package/dist/components/DropdownSelector/Popover/index2.js.map +1 -1
- package/dist/components/DropdownSelector/Popover/usePreventScroll.cjs +0 -1
- package/dist/components/DropdownSelector/Popover/usePreventScroll.cjs.map +1 -1
- package/dist/components/DropdownSelector/Popover/usePreventScroll.js.map +1 -1
- package/dist/components/DropdownSelector/index.d.ts.map +1 -1
- package/dist/components/DropdownSelector/index2.cjs +27 -10
- package/dist/components/DropdownSelector/index2.cjs.map +1 -1
- package/dist/components/DropdownSelector/index2.js +26 -9
- package/dist/components/DropdownSelector/index2.js.map +1 -1
- package/dist/components/DropdownSelector/utils/findPreviewRecursive.cjs +1 -1
- package/dist/components/DropdownSelector/utils/findPreviewRecursive.cjs.map +1 -1
- package/dist/components/DropdownSelector/utils/findPreviewRecursive.js.map +1 -1
- package/dist/components/FieldLabel/index.d.ts.map +1 -1
- package/dist/components/FieldLabel/index2.cjs +1 -1
- package/dist/components/FieldLabel/index2.cjs.map +1 -1
- package/dist/components/FieldLabel/index2.js.map +1 -1
- package/dist/components/HintText/index2.cjs +0 -1
- package/dist/components/HintText/index2.cjs.map +1 -1
- package/dist/components/HintText/index2.js.map +1 -1
- package/dist/components/Icon/index.cjs +1 -1
- package/dist/components/Icon/index.cjs.map +1 -1
- package/dist/components/Icon/index.d.ts.map +1 -1
- package/dist/components/Icon/index.js.map +1 -1
- package/dist/components/IconButton/index.d.ts +1 -1
- package/dist/components/IconButton/index.d.ts.map +1 -1
- package/dist/components/IconButton/index2.cjs +1 -1
- package/dist/components/IconButton/index2.cjs.map +1 -1
- package/dist/components/IconButton/index2.js.map +1 -1
- package/dist/components/LoadingSpinner/index.d.ts.map +1 -1
- package/dist/components/LoadingSpinner/index2.cjs +0 -1
- package/dist/components/LoadingSpinner/index2.cjs.map +1 -1
- package/dist/components/LoadingSpinner/index2.js.map +1 -1
- package/dist/components/Modal/Dialog/index2.cjs +1 -1
- package/dist/components/Modal/Dialog/index2.cjs.map +1 -1
- package/dist/components/Modal/Dialog/index2.js.map +1 -1
- package/dist/components/Modal/ModalBackgroundContext.cjs +1 -1
- package/dist/components/Modal/ModalBackgroundContext.cjs.map +1 -1
- package/dist/components/Modal/ModalBackgroundContext.js.map +1 -1
- package/dist/components/Modal/ModalPlumbing.d.ts +3 -3
- package/dist/components/Modal/ModalPlumbing2.cjs +0 -1
- package/dist/components/Modal/ModalPlumbing2.cjs.map +1 -1
- package/dist/components/Modal/ModalPlumbing2.js.map +1 -1
- package/dist/components/Modal/index.d.ts.map +1 -1
- package/dist/components/Modal/index2.cjs +1 -1
- package/dist/components/Modal/index2.cjs.map +1 -1
- package/dist/components/Modal/index2.js.map +1 -1
- package/dist/components/Modal/useCustomModalOverlay.cjs +1 -1
- package/dist/components/Modal/useCustomModalOverlay.cjs.map +1 -1
- package/dist/components/Modal/useCustomModalOverlay.js.map +1 -1
- package/dist/components/Modal/useTransitionPresence.cjs +1 -3
- package/dist/components/Modal/useTransitionPresence.cjs.map +1 -1
- package/dist/components/Modal/useTransitionPresence.js +1 -2
- package/dist/components/Modal/useTransitionPresence.js.map +1 -1
- package/dist/components/MultiSelect/context.cjs +0 -1
- package/dist/components/MultiSelect/context.cjs.map +1 -1
- package/dist/components/MultiSelect/context.js.map +1 -1
- package/dist/components/MultiSelect/index.d.ts +1 -1
- package/dist/components/MultiSelect/index.d.ts.map +1 -1
- package/dist/components/MultiSelect/index2.cjs +2 -2
- package/dist/components/MultiSelect/index2.cjs.map +1 -1
- package/dist/components/MultiSelect/index2.js.map +1 -1
- package/dist/components/Pagination/PaginationContext.cjs +0 -1
- package/dist/components/Pagination/PaginationContext.cjs.map +1 -1
- package/dist/components/Pagination/PaginationContext.js.map +1 -1
- package/dist/components/Pagination/helper.cjs.map +1 -1
- package/dist/components/Pagination/helper.js.map +1 -1
- package/dist/components/Pagination/index2.cjs +26 -135
- package/dist/components/Pagination/index2.cjs.map +1 -1
- package/dist/components/Pagination/index2.js +86 -182
- package/dist/components/Pagination/index2.js.map +1 -1
- package/dist/components/Radio/RadioGroup/index2.cjs +1 -1
- package/dist/components/Radio/RadioGroup/index2.cjs.map +1 -1
- package/dist/components/Radio/RadioGroup/index2.js.map +1 -1
- package/dist/components/Radio/RadioGroupContext.cjs.map +1 -1
- package/dist/components/Radio/RadioGroupContext.js.map +1 -1
- package/dist/components/Radio/RadioInput/index.d.ts.map +1 -1
- package/dist/components/Radio/RadioInput/index2.cjs +0 -1
- package/dist/components/Radio/RadioInput/index2.cjs.map +1 -1
- package/dist/components/Radio/RadioInput/index2.js.map +1 -1
- package/dist/components/Radio/index.d.ts.map +1 -1
- package/dist/components/Radio/index2.cjs +2 -2
- package/dist/components/Radio/index2.cjs.map +1 -1
- package/dist/components/Radio/index2.js.map +1 -1
- package/dist/components/SegmentedControl/RadioGroupContext.cjs +1 -1
- package/dist/components/SegmentedControl/RadioGroupContext.cjs.map +1 -1
- package/dist/components/SegmentedControl/RadioGroupContext.js.map +1 -1
- package/dist/components/SegmentedControl/index.d.ts.map +1 -1
- package/dist/components/SegmentedControl/index2.cjs +1 -1
- package/dist/components/SegmentedControl/index2.cjs.map +1 -1
- package/dist/components/SegmentedControl/index2.js.map +1 -1
- package/dist/components/Switch/SwitchInput/index.d.ts.map +1 -1
- package/dist/components/Switch/SwitchInput/index2.cjs +0 -1
- package/dist/components/Switch/SwitchInput/index2.cjs.map +1 -1
- package/dist/components/Switch/SwitchInput/index2.js.map +1 -1
- package/dist/components/Switch/SwitchWithLabel.cjs +1 -1
- package/dist/components/Switch/SwitchWithLabel.cjs.map +1 -1
- package/dist/components/Switch/SwitchWithLabel.d.ts +2 -2
- package/dist/components/Switch/SwitchWithLabel.d.ts.map +1 -1
- package/dist/components/Switch/SwitchWithLabel.js.map +1 -1
- package/dist/components/Switch/index.d.ts +1 -1
- package/dist/components/Switch/index.d.ts.map +1 -1
- package/dist/components/Switch/index2.cjs +0 -1
- package/dist/components/Switch/index2.cjs.map +1 -1
- package/dist/components/Switch/index2.js.map +1 -1
- package/dist/components/TagItem/index.d.ts +1 -1
- package/dist/components/TagItem/index.d.ts.map +1 -1
- package/dist/components/TagItem/index2.cjs +1 -1
- package/dist/components/TagItem/index2.cjs.map +1 -1
- package/dist/components/TagItem/index2.js.map +1 -1
- package/dist/components/TextArea/index.d.ts.map +1 -1
- package/dist/components/TextArea/index2.cjs +0 -1
- package/dist/components/TextArea/index2.cjs.map +1 -1
- package/dist/components/TextArea/index2.js.map +1 -1
- package/dist/components/TextEllipsis/helper.cjs +2 -1
- package/dist/components/TextEllipsis/helper.cjs.map +1 -1
- package/dist/components/TextEllipsis/helper.d.ts.map +1 -1
- package/dist/components/TextEllipsis/helper.js +1 -1
- package/dist/components/TextEllipsis/helper.js.map +1 -1
- package/dist/components/TextEllipsis/index2.cjs +14 -98
- package/dist/components/TextEllipsis/index2.cjs.map +1 -1
- package/dist/components/TextEllipsis/index2.js +14 -93
- package/dist/components/TextEllipsis/index2.js.map +1 -1
- package/dist/components/TextField/AssistiveText/index.d.ts +1 -1
- package/dist/components/TextField/AssistiveText/index2.cjs.map +1 -1
- package/dist/components/TextField/AssistiveText/index2.js.map +1 -1
- package/dist/components/TextField/index.d.ts +1 -1
- package/dist/components/TextField/index.d.ts.map +1 -1
- package/dist/components/TextField/index2.cjs +1 -1
- package/dist/components/TextField/index2.cjs.map +1 -1
- package/dist/components/TextField/index2.js.map +1 -1
- package/dist/components/TextField/useFocusWithClick.cjs +0 -1
- package/dist/components/TextField/useFocusWithClick.cjs.map +1 -1
- package/dist/components/TextField/useFocusWithClick.js.map +1 -1
- package/dist/core/CharcoalProvider.cjs +1 -1
- package/dist/core/CharcoalProvider.cjs.map +1 -1
- package/dist/core/CharcoalProvider.js.map +1 -1
- package/dist/core/SSRProvider.cjs +1 -1
- package/dist/core/SSRProvider.cjs.map +1 -1
- package/dist/core/SSRProvider.js +1 -1
- package/dist/core/SSRProvider.js.map +1 -1
- package/dist/core/SetThemeScript.cjs +0 -1
- package/dist/core/SetThemeScript.cjs.map +1 -1
- package/dist/core/SetThemeScript.js.map +1 -1
- package/dist/core/themeHelper.cjs +0 -1
- package/dist/core/themeHelper.cjs.map +1 -1
- package/dist/core/themeHelper.d.ts +2 -2
- package/dist/core/themeHelper.d.ts.map +1 -1
- package/dist/core/themeHelper.js.map +1 -1
- package/dist/index.cjs +22 -23
- package/dist/index.css +1000 -1000
- package/dist/layered.css +1000 -1000
- package/dist/layered.css.map +1 -1
- package/package.json +10 -10
- package/src/_lib/compat.ts +1 -7
- package/src/components/Carousel/index.browser.test.tsx +1 -1
- package/src/components/Carousel/intersectionObserver.test.ts +12 -12
- package/src/components/Carousel/resizeObserver.test.ts +1 -1
- package/src/components/DropdownSelector/MenuItem/index.tsx +40 -2
- package/src/components/DropdownSelector/Popover/index.tsx +20 -1
- package/src/components/DropdownSelector/index.browser.test.tsx +94 -0
- package/src/components/DropdownSelector/index.test.tsx +57 -2
- package/src/components/DropdownSelector/index.tsx +37 -12
- package/src/components/FieldLabel/index.tsx +1 -2
- package/src/components/Icon/index.tsx +2 -1
- package/src/components/Modal/__snapshots__/index.css.snap +1 -0
- package/src/components/TextEllipsis/TextEllipsis.story.tsx +1 -1
- package/src/css.d.ts +1 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Apple Pencil (pointerType: 'pen') での overlay 解除テスト
|
|
3
|
+
*
|
|
4
|
+
* jsdom では検証できないため実ブラウザで実行する:
|
|
5
|
+
*
|
|
6
|
+
* 1. jsdom は inert を実装していない (`'inert' in HTMLElement.prototype` が false)。
|
|
7
|
+
* そのため react-aria の ariaHideOutside は aria-hidden にフォールバックし、
|
|
8
|
+
* 「inert 要素はポインタイベントを受け取らない」という本番の挙動が再現されない。
|
|
9
|
+
* 2. jsdom は PointerEvent を実装しておらず pointerType が落ちる。
|
|
10
|
+
*
|
|
11
|
+
* iOS Safari は非インタラクティブな要素へのペン入力で click を合成しないため、
|
|
12
|
+
* click に依存する react-aria の外側判定では overlay を閉じられない。
|
|
13
|
+
*/
|
|
14
|
+
import { fireEvent, render, screen } from '@testing-library/react'
|
|
15
|
+
import { vi } from 'vitest'
|
|
16
|
+
import DropdownSelector from '.'
|
|
17
|
+
import DropdownMenuItem from './DropdownMenuItem'
|
|
18
|
+
|
|
19
|
+
/** Apple Pencil のタップは iOS Safari で click を伴わない */
|
|
20
|
+
const penTap = (element: Element) => {
|
|
21
|
+
const init = { pointerType: 'pen', button: 0, composed: true }
|
|
22
|
+
fireEvent.pointerDown(element, init)
|
|
23
|
+
fireEvent.pointerUp(element, init)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const popover = () => document.querySelector('.charcoal-popover')
|
|
27
|
+
|
|
28
|
+
const getUnderlay = () => {
|
|
29
|
+
const underlay = popover()?.previousElementSibling
|
|
30
|
+
if (!(underlay instanceof HTMLElement)) throw new Error('underlay not found')
|
|
31
|
+
return underlay
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** ブラウザが実際にヒットテストする要素。inert / pointer-events を反映する */
|
|
35
|
+
const hitTestOutsidePopover = () => {
|
|
36
|
+
const rect = popover()?.getBoundingClientRect()
|
|
37
|
+
if (!rect) throw new Error('popover not found')
|
|
38
|
+
const target = document.elementFromPoint(
|
|
39
|
+
Math.round(rect.left + rect.width / 2),
|
|
40
|
+
Math.round(rect.bottom + 40),
|
|
41
|
+
)
|
|
42
|
+
if (target === null) throw new Error('no element at point')
|
|
43
|
+
return target
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const renderSelector = (inertWorkaround: boolean) =>
|
|
47
|
+
render(
|
|
48
|
+
<DropdownSelector
|
|
49
|
+
label="Label"
|
|
50
|
+
value="1"
|
|
51
|
+
onChange={vi.fn()}
|
|
52
|
+
inertWorkaround={inertWorkaround}
|
|
53
|
+
>
|
|
54
|
+
<DropdownMenuItem value="1">Option 1</DropdownMenuItem>
|
|
55
|
+
<DropdownMenuItem value="2">Option 2</DropdownMenuItem>
|
|
56
|
+
</DropdownSelector>,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
describe.each([
|
|
60
|
+
['inertWorkaround が無効', false],
|
|
61
|
+
['inertWorkaround が有効', true],
|
|
62
|
+
])('%s なとき', (_, inertWorkaround) => {
|
|
63
|
+
it('Apple Pencil で overlay の外側をタップすると閉じる', () => {
|
|
64
|
+
renderSelector(inertWorkaround)
|
|
65
|
+
|
|
66
|
+
penTap(screen.getByRole('button'))
|
|
67
|
+
expect(popover()).not.toBeNull()
|
|
68
|
+
|
|
69
|
+
penTap(hitTestOutsidePopover())
|
|
70
|
+
|
|
71
|
+
expect(popover()).toBeNull()
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
// 選択肢のタップは onChange 経由で閉じるのが仕様なので、余白部分を叩く
|
|
75
|
+
it('Apple Pencil で popover の余白をタップしても閉じない', () => {
|
|
76
|
+
renderSelector(inertWorkaround)
|
|
77
|
+
|
|
78
|
+
penTap(screen.getByRole('button'))
|
|
79
|
+
const inside = popover()
|
|
80
|
+
if (inside === null) throw new Error('popover not found')
|
|
81
|
+
|
|
82
|
+
penTap(inside)
|
|
83
|
+
|
|
84
|
+
expect(popover()).not.toBeNull()
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it('underlay は inertWorkaround が無効なとき inert になる', () => {
|
|
89
|
+
renderSelector(false)
|
|
90
|
+
penTap(screen.getByRole('button'))
|
|
91
|
+
|
|
92
|
+
expect('inert' in HTMLElement.prototype).toBe(true)
|
|
93
|
+
expect(getUnderlay().inert).toBe(true)
|
|
94
|
+
})
|
|
@@ -1,8 +1,34 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/react'
|
|
2
|
-
import { vi } from 'vitest'
|
|
1
|
+
import { fireEvent, render, screen } from '@testing-library/react'
|
|
2
|
+
import { beforeAll, vi } from 'vitest'
|
|
3
3
|
import DropdownSelector from '.'
|
|
4
4
|
import DropdownMenuItem from './DropdownMenuItem'
|
|
5
5
|
|
|
6
|
+
// Apple Pencil (pointerType: 'pen') の解除は index.browser.test.tsx で検証する。
|
|
7
|
+
// jsdom は inert を実装しておらず、react-aria が外側を inert にする本番の挙動を
|
|
8
|
+
// 再現できないため、ここでペンを扱うと通ってしまい実機の退行を見逃す。
|
|
9
|
+
|
|
10
|
+
// jsdom は PointerEvent を実装しておらず pointerType が落ちるため補う
|
|
11
|
+
class PointerEventPolyfill extends MouseEvent {
|
|
12
|
+
readonly pointerType: string
|
|
13
|
+
constructor(type: string, init: PointerEventInit = {}) {
|
|
14
|
+
super(type, init)
|
|
15
|
+
this.pointerType = init.pointerType ?? ''
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
beforeAll(() => {
|
|
20
|
+
vi.stubGlobal('PointerEvent', PointerEventPolyfill)
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const getUnderlay = () => {
|
|
24
|
+
const popover = document.querySelector('.charcoal-popover')
|
|
25
|
+
const underlay = popover?.previousElementSibling
|
|
26
|
+
if (!(underlay instanceof HTMLElement)) {
|
|
27
|
+
throw new Error('underlay not found')
|
|
28
|
+
}
|
|
29
|
+
return underlay
|
|
30
|
+
}
|
|
31
|
+
|
|
6
32
|
describe('DropdownSelector', () => {
|
|
7
33
|
describe('when `value` does not match any child `DropdownMenuItem`', () => {
|
|
8
34
|
it('keeps the DOM `<select>.value` aligned with props `value` without breaking placeholder display', () => {
|
|
@@ -27,4 +53,33 @@ describe('DropdownSelector', () => {
|
|
|
27
53
|
expect(button.textContent).toContain('Select an option')
|
|
28
54
|
})
|
|
29
55
|
})
|
|
56
|
+
|
|
57
|
+
describe.each([
|
|
58
|
+
['inertWorkaround が無効', false],
|
|
59
|
+
['inertWorkaround が有効', true],
|
|
60
|
+
])('%s なとき', (_, inertWorkaround) => {
|
|
61
|
+
it('マウスで overlay をクリックすると閉じる', () => {
|
|
62
|
+
render(
|
|
63
|
+
<DropdownSelector
|
|
64
|
+
label="Label"
|
|
65
|
+
value="1"
|
|
66
|
+
onChange={vi.fn()}
|
|
67
|
+
inertWorkaround={inertWorkaround}
|
|
68
|
+
>
|
|
69
|
+
<DropdownMenuItem value="1">Option 1</DropdownMenuItem>
|
|
70
|
+
<DropdownMenuItem value="2">Option 2</DropdownMenuItem>
|
|
71
|
+
</DropdownSelector>,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
fireEvent.click(screen.getByRole('button'))
|
|
75
|
+
expect(document.querySelector('.charcoal-popover')).not.toBeNull()
|
|
76
|
+
|
|
77
|
+
const underlay = getUnderlay()
|
|
78
|
+
fireEvent.pointerDown(underlay, { pointerType: 'mouse', button: 0 })
|
|
79
|
+
fireEvent.pointerUp(underlay, { pointerType: 'mouse', button: 0 })
|
|
80
|
+
fireEvent.click(underlay, { button: 0 })
|
|
81
|
+
|
|
82
|
+
expect(document.querySelector('.charcoal-popover')).toBeNull()
|
|
83
|
+
})
|
|
84
|
+
})
|
|
30
85
|
})
|
|
@@ -42,6 +42,7 @@ export default function DropdownSelector({
|
|
|
42
42
|
...props
|
|
43
43
|
}: DropdownSelectorProps) {
|
|
44
44
|
const triggerRef = useRef<HTMLButtonElement>(null)
|
|
45
|
+
const penHandledRef = useRef(false)
|
|
45
46
|
const [isOpen, setIsOpen] = useState(false)
|
|
46
47
|
const preview = findPreviewRecursive(props.children, props.value)
|
|
47
48
|
|
|
@@ -65,6 +66,38 @@ export default function DropdownSelector({
|
|
|
65
66
|
[onChange],
|
|
66
67
|
)
|
|
67
68
|
|
|
69
|
+
// Popover が document listener の登録に使うため、識別子を安定させる
|
|
70
|
+
const handleClose = useCallback(() => {
|
|
71
|
+
setIsOpen(false)
|
|
72
|
+
}, [])
|
|
73
|
+
|
|
74
|
+
const handleSelect = useCallback(
|
|
75
|
+
(v: string) => {
|
|
76
|
+
onChange(v)
|
|
77
|
+
setIsOpen(false)
|
|
78
|
+
},
|
|
79
|
+
[onChange],
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
const handleTriggerPointerUp = useCallback(
|
|
83
|
+
(e: React.PointerEvent<HTMLButtonElement>) => {
|
|
84
|
+
if (e.pointerType !== 'pen') return
|
|
85
|
+
if (props.disabled === true) return
|
|
86
|
+
penHandledRef.current = true
|
|
87
|
+
setIsOpen(true)
|
|
88
|
+
},
|
|
89
|
+
[props.disabled],
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
const handleTriggerClick = useCallback(() => {
|
|
93
|
+
if (penHandledRef.current) {
|
|
94
|
+
penHandledRef.current = false
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
if (props.disabled === true) return
|
|
98
|
+
setIsOpen(true)
|
|
99
|
+
}, [props.disabled])
|
|
100
|
+
|
|
68
101
|
const labelId = useId()
|
|
69
102
|
const describedbyId = useId()
|
|
70
103
|
|
|
@@ -116,10 +149,8 @@ export default function DropdownSelector({
|
|
|
116
149
|
props.assistiveText !== undefined ? describedbyId : undefined
|
|
117
150
|
}
|
|
118
151
|
disabled={props.disabled}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
setIsOpen(true)
|
|
122
|
-
}}
|
|
152
|
+
onPointerUp={handleTriggerPointerUp}
|
|
153
|
+
onClick={handleTriggerClick}
|
|
123
154
|
ref={triggerRef}
|
|
124
155
|
type="button"
|
|
125
156
|
data-active={isOpen}
|
|
@@ -135,18 +166,12 @@ export default function DropdownSelector({
|
|
|
135
166
|
{isOpen && (
|
|
136
167
|
<DropdownPopover
|
|
137
168
|
isOpen={isOpen}
|
|
138
|
-
onClose={
|
|
169
|
+
onClose={handleClose}
|
|
139
170
|
triggerRef={triggerRef}
|
|
140
171
|
value={props.value}
|
|
141
172
|
inertWorkaround={props.inertWorkaround}
|
|
142
173
|
>
|
|
143
|
-
<MenuList
|
|
144
|
-
value={props.value}
|
|
145
|
-
onChange={(v) => {
|
|
146
|
-
onChange(v)
|
|
147
|
-
setIsOpen(false)
|
|
148
|
-
}}
|
|
149
|
-
>
|
|
174
|
+
<MenuList value={props.value} onChange={handleSelect}>
|
|
150
175
|
{props.children}
|
|
151
176
|
</MenuList>
|
|
152
177
|
</DropdownPopover>
|
|
@@ -3,8 +3,7 @@ import { useClassNames } from '../../_lib/useClassNames'
|
|
|
3
3
|
|
|
4
4
|
import './index.css'
|
|
5
5
|
|
|
6
|
-
export interface FieldLabelProps
|
|
7
|
-
extends React.LabelHTMLAttributes<HTMLLabelElement> {
|
|
6
|
+
export interface FieldLabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {
|
|
8
7
|
readonly className?: string
|
|
9
8
|
readonly label: string
|
|
10
9
|
readonly subLabel?: React.ReactNode
|
package/src/css.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module '*.css'
|