@charcoal-ui/react 6.0.0-rc.8 → 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 +907 -901
- package/dist/layered.css +907 -901
- package/dist/layered.css.map +1 -1
- package/package.json +10 -10
- package/src/__tests__/css-shorthand-safety.test.ts +150 -0
- package/src/_lib/compat.ts +1 -7
- package/src/components/Button/__snapshots__/index.css.snap +8 -3
- package/src/components/Button/index.css +8 -3
- 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/LoadingSpinner/__snapshots__/index.css.snap +1 -2
- package/src/components/LoadingSpinner/index.css +1 -2
- package/src/components/Modal/__snapshots__/index.css.snap +1 -0
- package/src/components/Pagination/__snapshots__/index.css.snap +3 -1
- package/src/components/Pagination/index.css +3 -1
- package/src/components/TextEllipsis/TextEllipsis.story.tsx +1 -1
- package/src/css.d.ts +1 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
.charcoal-button {
|
|
2
2
|
appearance: none;
|
|
3
|
-
background:
|
|
3
|
+
background-image: none;
|
|
4
4
|
box-sizing: border-box;
|
|
5
5
|
padding: 0 24px;
|
|
6
6
|
border-style: none;
|
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
letter-spacing: inherit;
|
|
10
10
|
word-spacing: inherit;
|
|
11
11
|
text-decoration: none;
|
|
12
|
-
font: inherit;
|
|
12
|
+
font-family: inherit;
|
|
13
|
+
font-style: inherit;
|
|
14
|
+
font-variant: inherit;
|
|
13
15
|
margin: 0;
|
|
14
16
|
overflow: visible;
|
|
15
17
|
text-transform: none;
|
|
@@ -25,7 +27,10 @@
|
|
|
25
27
|
line-height: 22px;
|
|
26
28
|
font-weight: bold;
|
|
27
29
|
color: var(--charcoal-color-text-default);
|
|
28
|
-
background-color: var(
|
|
30
|
+
background-color: var(
|
|
31
|
+
--charcoal-color-container-secondary-default-a,
|
|
32
|
+
transparent
|
|
33
|
+
);
|
|
29
34
|
transition:
|
|
30
35
|
0.2s color,
|
|
31
36
|
0.2s background-color,
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* document.elementFromPoint のヒットテストで検証する。
|
|
9
9
|
* (pointer-events / 擬似要素のヒットテストは jsdom では再現できない)
|
|
10
10
|
*/
|
|
11
|
-
import { userEvent } from '
|
|
11
|
+
import { userEvent } from 'vitest/browser'
|
|
12
12
|
import { render } from '@testing-library/react'
|
|
13
13
|
import Carousel from '.'
|
|
14
14
|
|
|
@@ -23,18 +23,18 @@ describe('observeCenter', () => {
|
|
|
23
23
|
|
|
24
24
|
it('同一 root の el は observer を共有し、中央交差で対象の onEnter だけ呼ぶ', () => {
|
|
25
25
|
const instances: MockIO[] = []
|
|
26
|
-
globalThis.IntersectionObserver = vi.fn(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
) as unknown as typeof globalThis.IntersectionObserver
|
|
26
|
+
globalThis.IntersectionObserver = vi.fn(function (
|
|
27
|
+
cb: IntersectionObserverCallback,
|
|
28
|
+
) {
|
|
29
|
+
const inst: MockIO = {
|
|
30
|
+
cb,
|
|
31
|
+
observe: vi.fn(),
|
|
32
|
+
unobserve: vi.fn(),
|
|
33
|
+
disconnect: vi.fn(),
|
|
34
|
+
}
|
|
35
|
+
instances.push(inst)
|
|
36
|
+
return inst
|
|
37
|
+
}) as unknown as typeof globalThis.IntersectionObserver
|
|
38
38
|
|
|
39
39
|
const root = document.createElement('div')
|
|
40
40
|
const a = document.createElement('div')
|
|
@@ -23,7 +23,7 @@ describe('observeResize', () => {
|
|
|
23
23
|
|
|
24
24
|
it('単一の observer を共有し、対象のサイズ変化で cb を呼ぶ', () => {
|
|
25
25
|
const instances: MockRO[] = []
|
|
26
|
-
globalThis.ResizeObserver = vi.fn((cb: ResizeObserverCallback)
|
|
26
|
+
globalThis.ResizeObserver = vi.fn(function (cb: ResizeObserverCallback) {
|
|
27
27
|
const inst: MockRO = {
|
|
28
28
|
cb,
|
|
29
29
|
observe: vi.fn(),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ForwardedRef, forwardRef } from 'react'
|
|
1
|
+
import { ForwardedRef, forwardRef, useCallback, useRef } from 'react'
|
|
2
2
|
import ListItem, { ListItemProps } from '../ListItem'
|
|
3
3
|
import { useMenuItemHandleKeyDown } from './internals/useMenuItemHandleKeyDown'
|
|
4
4
|
|
|
@@ -18,6 +18,42 @@ const MenuItem = forwardRef(function MenuItem<
|
|
|
18
18
|
ref: ForwardedRef<HTMLLIElement>,
|
|
19
19
|
) {
|
|
20
20
|
const [handleKeyDown, setContextValue] = useMenuItemHandleKeyDown(value)
|
|
21
|
+
const penHandledRef = useRef(false)
|
|
22
|
+
const pointerStartRef = useRef<{ x: number; y: number } | null>(null)
|
|
23
|
+
|
|
24
|
+
const handlePointerDown = useCallback(
|
|
25
|
+
(e: React.PointerEvent<HTMLLIElement>) => {
|
|
26
|
+
if (e.pointerType === 'pen') {
|
|
27
|
+
pointerStartRef.current = { x: e.clientX, y: e.clientY }
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
[],
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
const handlePointerUp = useCallback(
|
|
34
|
+
(e: React.PointerEvent<HTMLLIElement>) => {
|
|
35
|
+
if (e.pointerType !== 'pen' || disabled === true) return
|
|
36
|
+
const start = pointerStartRef.current
|
|
37
|
+
if (!start) return
|
|
38
|
+
const dx = Math.abs(e.clientX - start.x)
|
|
39
|
+
const dy = Math.abs(e.clientY - start.y)
|
|
40
|
+
// タップとドラッグを区別するための許容量
|
|
41
|
+
if (dx > 8 || dy > 8) return
|
|
42
|
+
penHandledRef.current = true
|
|
43
|
+
setContextValue()
|
|
44
|
+
},
|
|
45
|
+
[disabled, setContextValue],
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
const handleClick = useCallback(() => {
|
|
49
|
+
if (penHandledRef.current) {
|
|
50
|
+
penHandledRef.current = false
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
if (disabled === true) return
|
|
54
|
+
setContextValue()
|
|
55
|
+
}, [disabled, setContextValue])
|
|
56
|
+
|
|
21
57
|
return (
|
|
22
58
|
// @ts-expect-error TODO: fix mismatch between MenuItemProps and ListItemProps
|
|
23
59
|
<ListItem
|
|
@@ -25,7 +61,9 @@ const MenuItem = forwardRef(function MenuItem<
|
|
|
25
61
|
ref={ref}
|
|
26
62
|
data-key={value}
|
|
27
63
|
onKeyDown={handleKeyDown}
|
|
28
|
-
|
|
64
|
+
onPointerDown={handlePointerDown}
|
|
65
|
+
onPointerUp={handlePointerUp}
|
|
66
|
+
onClick={handleClick}
|
|
29
67
|
tabIndex={-1}
|
|
30
68
|
aria-disabled={disabled}
|
|
31
69
|
role="option"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import './index.css'
|
|
2
2
|
|
|
3
|
-
import { RefObject, useContext, useRef, ReactNode } from 'react'
|
|
3
|
+
import { RefObject, useContext, useEffect, useRef, ReactNode } from 'react'
|
|
4
4
|
import { ModalBackgroundContext } from '../../Modal/ModalBackgroundContext'
|
|
5
5
|
import { usePreventScroll } from './usePreventScroll'
|
|
6
6
|
import { DismissButton, Overlay } from 'react-aria/Overlay'
|
|
@@ -54,6 +54,25 @@ export default function Popover(props: PopoverProps) {
|
|
|
54
54
|
const modalBackground = useContext(ModalBackgroundContext)
|
|
55
55
|
usePreventScroll(modalBackground, props.isOpen)
|
|
56
56
|
|
|
57
|
+
// iOS Safari は非インタラクティブな要素へのペン入力で click を合成しないため、
|
|
58
|
+
// click に依存する react-aria の外側判定ではペンで閉じられない。
|
|
59
|
+
// underlay 側では拾えない: react-aria が modal 時に外側を inert にするので
|
|
60
|
+
// underlay 自身がイベントを受け取らなくなる。
|
|
61
|
+
const { isOpen, onClose } = props
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (!isOpen) return
|
|
64
|
+
const handlePointerUp = (e: PointerEvent) => {
|
|
65
|
+
if (e.pointerType !== 'pen') return
|
|
66
|
+
const popover = finalPopoverRef.current
|
|
67
|
+
if (popover !== null && e.composedPath().includes(popover)) return
|
|
68
|
+
onClose()
|
|
69
|
+
}
|
|
70
|
+
document.addEventListener('pointerup', handlePointerUp, true)
|
|
71
|
+
return () => {
|
|
72
|
+
document.removeEventListener('pointerup', handlePointerUp, true)
|
|
73
|
+
}
|
|
74
|
+
}, [isOpen, onClose, finalPopoverRef])
|
|
75
|
+
|
|
57
76
|
if (!props.isOpen) return null
|
|
58
77
|
|
|
59
78
|
return (
|
|
@@ -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
|
|
@@ -33,8 +33,7 @@ to {
|
|
|
33
33
|
height: 1em;
|
|
34
34
|
border-radius: 1em;
|
|
35
35
|
background-color: currentColor;
|
|
36
|
-
animation: charcoal-loading-spinner-icon-scale-out 1s both ease-out;
|
|
37
|
-
animation-iteration-count: infinite;
|
|
36
|
+
animation: charcoal-loading-spinner-icon-scale-out 1s infinite both ease-out;
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
.charcoal-loading-spinner-icon[data-reset-animation] {
|
|
@@ -31,8 +31,7 @@
|
|
|
31
31
|
height: 1em;
|
|
32
32
|
border-radius: 1em;
|
|
33
33
|
background-color: currentColor;
|
|
34
|
-
animation: charcoal-loading-spinner-icon-scale-out 1s both ease-out;
|
|
35
|
-
animation-iteration-count: infinite;
|
|
34
|
+
animation: charcoal-loading-spinner-icon-scale-out 1s infinite both ease-out;
|
|
36
35
|
|
|
37
36
|
&[data-reset-animation] {
|
|
38
37
|
animation: none;
|
package/src/css.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module '*.css'
|