@charcoal-ui/react 6.1.0 → 6.1.1-beta.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/components/DropdownSelector/Popover/index.d.ts.map +1 -1
- package/dist/components/DropdownSelector/Popover/index2.cjs +32 -1
- package/dist/components/DropdownSelector/Popover/index2.cjs.map +1 -1
- package/dist/components/DropdownSelector/Popover/index2.js +32 -1
- package/dist/components/DropdownSelector/Popover/index2.js.map +1 -1
- package/dist/index.css +1519 -1519
- package/dist/layered.css +1519 -1519
- package/dist/layered.css.map +1 -1
- package/package.json +3 -3
- package/src/components/DropdownSelector/Popover/index.tsx +60 -2
- package/src/components/DropdownSelector/index.browser.test.tsx +78 -3
- package/src/components/DropdownSelector/index.story.tsx +37 -0
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* iOS Safari は非インタラクティブな要素へのペン入力で click を合成しないため、
|
|
12
12
|
* click に依存する react-aria の外側判定では overlay を閉じられない。
|
|
13
13
|
*/
|
|
14
|
-
import { fireEvent, render, screen } from '@testing-library/react'
|
|
14
|
+
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
|
|
15
15
|
import { vi } from 'vitest'
|
|
16
16
|
import DropdownSelector from '.'
|
|
17
17
|
import DropdownMenuItem from './DropdownMenuItem'
|
|
@@ -60,7 +60,7 @@ describe.each([
|
|
|
60
60
|
['inertWorkaround が無効', false],
|
|
61
61
|
['inertWorkaround が有効', true],
|
|
62
62
|
])('%s なとき', (_, inertWorkaround) => {
|
|
63
|
-
it('Apple Pencil で overlay の外側をタップすると閉じる', () => {
|
|
63
|
+
it('Apple Pencil で overlay の外側をタップすると閉じる', async () => {
|
|
64
64
|
renderSelector(inertWorkaround)
|
|
65
65
|
|
|
66
66
|
penTap(screen.getByRole('button'))
|
|
@@ -68,7 +68,9 @@ describe.each([
|
|
|
68
68
|
|
|
69
69
|
penTap(hitTestOutsidePopover())
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
await waitFor(() => {
|
|
72
|
+
expect(popover()).toBeNull()
|
|
73
|
+
})
|
|
72
74
|
})
|
|
73
75
|
|
|
74
76
|
// 選択肢のタップは onChange 経由で閉じるのが仕様なので、余白部分を叩く
|
|
@@ -85,6 +87,79 @@ describe.each([
|
|
|
85
87
|
})
|
|
86
88
|
})
|
|
87
89
|
|
|
90
|
+
it('inertWorkaround が有効なとき、開いた直後に underlay へ送られる互換 click では閉じない', () => {
|
|
91
|
+
renderSelector(true)
|
|
92
|
+
|
|
93
|
+
penTap(screen.getByRole('button'))
|
|
94
|
+
expect(popover()).not.toBeNull()
|
|
95
|
+
|
|
96
|
+
// Android Chrome はペンの pointerup 後、underlay 上の pointerdown を伴わない
|
|
97
|
+
// mouse / click イベントを新しく追加された underlay に送る。
|
|
98
|
+
const underlay = getUnderlay()
|
|
99
|
+
fireEvent.mouseDown(underlay)
|
|
100
|
+
fireEvent.mouseUp(underlay)
|
|
101
|
+
fireEvent.click(underlay)
|
|
102
|
+
|
|
103
|
+
expect(popover()).not.toBeNull()
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it('ペンで外側をタップしたとき、下にあるクリック可能な要素をクリックせずに閉じる', async () => {
|
|
107
|
+
const handleBackgroundClick = vi.fn()
|
|
108
|
+
render(
|
|
109
|
+
<>
|
|
110
|
+
<DropdownSelector
|
|
111
|
+
label="Label"
|
|
112
|
+
value="1"
|
|
113
|
+
onChange={vi.fn()}
|
|
114
|
+
inertWorkaround
|
|
115
|
+
>
|
|
116
|
+
<DropdownMenuItem value="1">Option 1</DropdownMenuItem>
|
|
117
|
+
<DropdownMenuItem value="2">Option 2</DropdownMenuItem>
|
|
118
|
+
</DropdownSelector>
|
|
119
|
+
<button
|
|
120
|
+
type="button"
|
|
121
|
+
onClick={handleBackgroundClick}
|
|
122
|
+
style={{ position: 'fixed', right: 16, bottom: 16 }}
|
|
123
|
+
>
|
|
124
|
+
Background button
|
|
125
|
+
</button>
|
|
126
|
+
</>,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
penTap(screen.getByRole('button', { name: 'Label' }))
|
|
130
|
+
expect(popover()).not.toBeNull()
|
|
131
|
+
|
|
132
|
+
const backgroundButton = screen.getByRole('button', {
|
|
133
|
+
name: 'Background button',
|
|
134
|
+
})
|
|
135
|
+
const rect = backgroundButton.getBoundingClientRect()
|
|
136
|
+
const point = {
|
|
137
|
+
x: Math.round(rect.left + rect.width / 2),
|
|
138
|
+
y: Math.round(rect.top + rect.height / 2),
|
|
139
|
+
}
|
|
140
|
+
const pointerTarget = document.elementFromPoint(point.x, point.y)
|
|
141
|
+
if (pointerTarget === null) throw new Error('pointer target not found')
|
|
142
|
+
|
|
143
|
+
fireEvent.pointerDown(pointerTarget, {
|
|
144
|
+
pointerType: 'pen',
|
|
145
|
+
button: 0,
|
|
146
|
+
composed: true,
|
|
147
|
+
})
|
|
148
|
+
// Android Chrome はこの touchstart がキャンセルされた場合、後続の互換
|
|
149
|
+
// mouse / click イベントを生成しない。
|
|
150
|
+
expect(fireEvent.touchStart(pointerTarget)).toBe(false)
|
|
151
|
+
fireEvent.pointerUp(pointerTarget, {
|
|
152
|
+
pointerType: 'pen',
|
|
153
|
+
button: 0,
|
|
154
|
+
composed: true,
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
await waitFor(() => {
|
|
158
|
+
expect(popover()).toBeNull()
|
|
159
|
+
})
|
|
160
|
+
expect(handleBackgroundClick).not.toHaveBeenCalled()
|
|
161
|
+
})
|
|
162
|
+
|
|
88
163
|
it('underlay は inertWorkaround が無効なとき inert になる', () => {
|
|
89
164
|
renderSelector(false)
|
|
90
165
|
penTap(screen.getByRole('button'))
|
|
@@ -543,3 +543,40 @@ export const WithRef: StoryObj<typeof DropdownSelector> = {
|
|
|
543
543
|
)
|
|
544
544
|
},
|
|
545
545
|
}
|
|
546
|
+
|
|
547
|
+
export const InertWorkaroundPenOutside: StoryObj<typeof DropdownSelector> = {
|
|
548
|
+
render: function Render() {
|
|
549
|
+
const [selected, setSelected] = useState('1')
|
|
550
|
+
const [backgroundClickCount, setBackgroundClickCount] = useState(0)
|
|
551
|
+
|
|
552
|
+
return (
|
|
553
|
+
<div style={{ display: 'flex', alignItems: 'flex-start', gap: 64 }}>
|
|
554
|
+
<div style={{ width: 288 }}>
|
|
555
|
+
<DropdownSelector
|
|
556
|
+
value={selected}
|
|
557
|
+
onChange={setSelected}
|
|
558
|
+
label="DropdownSelector"
|
|
559
|
+
inertWorkaround
|
|
560
|
+
>
|
|
561
|
+
<DropdownMenuItem value="1">Option 1</DropdownMenuItem>
|
|
562
|
+
<DropdownMenuItem value="2">Option 2</DropdownMenuItem>
|
|
563
|
+
<DropdownMenuItem value="3">Option 3</DropdownMenuItem>
|
|
564
|
+
</DropdownSelector>
|
|
565
|
+
</div>
|
|
566
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
|
567
|
+
<Button
|
|
568
|
+
data-testid="background-button"
|
|
569
|
+
onClick={() => {
|
|
570
|
+
setBackgroundClickCount((count) => count + 1)
|
|
571
|
+
}}
|
|
572
|
+
>
|
|
573
|
+
Background button
|
|
574
|
+
</Button>
|
|
575
|
+
<div data-testid="background-click-count">
|
|
576
|
+
Background click count: {backgroundClickCount}
|
|
577
|
+
</div>
|
|
578
|
+
</div>
|
|
579
|
+
</div>
|
|
580
|
+
)
|
|
581
|
+
},
|
|
582
|
+
}
|