@charcoal-ui/react 3.9.0 → 3.10.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.
Files changed (35) hide show
  1. package/dist/components/DropdownSelector/MenuItem/internals/useMenuItemHandleKeyDown.d.ts.map +1 -1
  2. package/dist/components/DropdownSelector/MenuList/MenuListContext.d.ts +2 -1
  3. package/dist/components/DropdownSelector/MenuList/MenuListContext.d.ts.map +1 -1
  4. package/dist/components/DropdownSelector/MenuList/index.d.ts.map +1 -1
  5. package/dist/components/DropdownSelector/MenuList/internals/getValuesRecursive.d.ts +2 -1
  6. package/dist/components/DropdownSelector/MenuList/internals/getValuesRecursive.d.ts.map +1 -1
  7. package/dist/components/DropdownSelector/index.d.ts +4 -0
  8. package/dist/components/DropdownSelector/index.d.ts.map +1 -1
  9. package/dist/components/DropdownSelector/index.story.d.ts +12 -5
  10. package/dist/components/DropdownSelector/index.story.d.ts.map +1 -1
  11. package/dist/components/LoadingSpinner/LoadingSpinnerIcon.story.d.ts.map +1 -1
  12. package/dist/components/LoadingSpinner/index.story.d.ts.map +1 -1
  13. package/dist/components/Modal/index.story.d.ts +1 -0
  14. package/dist/components/Modal/index.story.d.ts.map +1 -1
  15. package/dist/components/Modal/useCustomModalOverlay.d.ts.map +1 -1
  16. package/dist/index.cjs.js +49 -25
  17. package/dist/index.cjs.js.map +1 -1
  18. package/dist/index.esm.js +60 -36
  19. package/dist/index.esm.js.map +1 -1
  20. package/package.json +9 -7
  21. package/src/components/DropdownSelector/ListItem/__snapshots__/index.story.storyshot +5 -3
  22. package/src/components/DropdownSelector/ListItem/index.tsx +5 -1
  23. package/src/components/DropdownSelector/MenuItem/internals/useMenuItemHandleKeyDown.tsx +29 -18
  24. package/src/components/DropdownSelector/MenuList/MenuListContext.ts +3 -2
  25. package/src/components/DropdownSelector/MenuList/__snapshots__/index.story.storyshot +15 -9
  26. package/src/components/DropdownSelector/MenuList/index.tsx +6 -4
  27. package/src/components/DropdownSelector/MenuList/internals/getValuesRecursive.tsx +11 -8
  28. package/src/components/DropdownSelector/__snapshots__/index.story.storyshot +2666 -396
  29. package/src/components/DropdownSelector/index.story.tsx +264 -103
  30. package/src/components/DropdownSelector/index.tsx +35 -7
  31. package/src/components/LoadingSpinner/LoadingSpinnerIcon.story.tsx +1 -0
  32. package/src/components/LoadingSpinner/index.story.tsx +1 -0
  33. package/src/components/Modal/__snapshots__/index.story.storyshot +990 -0
  34. package/src/components/Modal/index.story.tsx +23 -0
  35. package/src/components/Modal/useCustomModalOverlay.tsx +5 -0
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "@charcoal-ui/react",
3
- "version": "3.9.0",
3
+ "version": "3.10.0",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index.cjs.js",
6
6
  "module": "./dist/index.esm.js",
7
7
  "exports": {
8
+ "types": "./dist/index.d.ts",
8
9
  "require": "./dist/index.cjs.js",
10
+ "import": "./dist/index.esm.js",
9
11
  "default": "./dist/index.esm.js"
10
12
  },
11
13
  "types": "./dist/index.d.ts",
@@ -18,7 +20,7 @@
18
20
  "clean": "rimraf dist .tsbuildinfo"
19
21
  },
20
22
  "devDependencies": {
21
- "@charcoal-ui/esbuild-plugin-styled-components": "^3.9.0",
23
+ "@charcoal-ui/esbuild-plugin-styled-components": "^3.10.0",
22
24
  "@react-types/switch": "^3.1.2",
23
25
  "@storybook/addon-actions": "^7.4.1",
24
26
  "@storybook/addon-knobs": "^7.0.2",
@@ -52,10 +54,10 @@
52
54
  "typescript": "^4.9.5"
53
55
  },
54
56
  "dependencies": {
55
- "@charcoal-ui/icons": "^3.9.0",
56
- "@charcoal-ui/styled": "^3.9.0",
57
- "@charcoal-ui/theme": "^3.9.0",
58
- "@charcoal-ui/utils": "^3.9.0",
57
+ "@charcoal-ui/icons": "^3.10.0",
58
+ "@charcoal-ui/styled": "^3.10.0",
59
+ "@charcoal-ui/theme": "^3.10.0",
60
+ "@charcoal-ui/utils": "^3.10.0",
59
61
  "@react-aria/button": "^3.9.1",
60
62
  "@react-aria/checkbox": "^3.13.0",
61
63
  "@react-aria/dialog": "^3.5.10",
@@ -88,5 +90,5 @@
88
90
  "url": "https://github.com/pixiv/charcoal.git",
89
91
  "directory": "packages/react"
90
92
  },
91
- "gitHead": "fe760d136886d2227013d73067544c5a42ff075b"
93
+ "gitHead": "f4cb1eec09bb1dc9982cb123d513c970e0184c96"
92
94
  }
@@ -19,6 +19,8 @@ exports[`Storybook Tests DropdownSelector/ListItem Basic 1`] = `
19
19
  outline: none;
20
20
  padding-right: 16px;
21
21
  padding-left: 16px;
22
+ -webkit-transition: background-color 0.2s;
23
+ transition: background-color 0.2s;
22
24
  }
23
25
 
24
26
  .c1:disabled,
@@ -27,9 +29,9 @@ exports[`Storybook Tests DropdownSelector/ListItem Basic 1`] = `
27
29
  cursor: default;
28
30
  }
29
31
 
30
- .c1:hover,
31
- .c1:focus,
32
- .c1:focus-within {
32
+ .c1:hover:not(disabled):not([aria-disabled='true']),
33
+ .c1:focus:not(disabled):not([aria-disabled='true']),
34
+ .c1:focus-within:not(disabled):not([aria-disabled='true']) {
33
35
  background-color: var(--charcoal-surface3);
34
36
  }
35
37
 
@@ -46,6 +46,8 @@ const ItemDiv = styled.div`
46
46
  padding-right: 16px;
47
47
  padding-left: 16px;
48
48
 
49
+ transition: background-color 0.2s;
50
+
49
51
  &:disabled,
50
52
  &[aria-disabled]:not([aria-disabled='false']) {
51
53
  opacity: 0.32;
@@ -55,6 +57,8 @@ const ItemDiv = styled.div`
55
57
  :hover,
56
58
  :focus,
57
59
  :focus-within {
58
- background-color: var(--charcoal-surface3);
60
+ &:not(disabled):not([aria-disabled='true']) {
61
+ background-color: var(--charcoal-surface3);
62
+ }
59
63
  }
60
64
  `
@@ -12,7 +12,7 @@ import { MenuListContext } from '../../MenuList/MenuListContext'
12
12
  export function useMenuItemHandleKeyDown(
13
13
  value?: string
14
14
  ): [(e: React.KeyboardEvent<HTMLDivElement>) => void, () => void] {
15
- const { setValue, root, values } = useContext(MenuListContext)
15
+ const { setValue, root, propsArray } = useContext(MenuListContext)
16
16
  const setContextValue = useCallback(() => {
17
17
  if (value !== undefined) setValue(value)
18
18
  }, [value, setValue])
@@ -22,34 +22,45 @@ export function useMenuItemHandleKeyDown(
22
22
  if (e.key === 'Enter') {
23
23
  setContextValue()
24
24
  } else if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
25
+ const isForward = e.key === 'ArrowDown'
25
26
  // prevent scroll
26
27
  e.preventDefault()
27
- if (!values || value === undefined) return
28
- const index = values.indexOf(value)
28
+ if (!propsArray || value === undefined) return
29
+ const values = propsArray
30
+ .map((props) => props.value)
31
+ .filter((v) => v) as string[]
32
+ let index = values.indexOf(value)
29
33
  if (index === -1) return
30
34
 
31
- const focusValue =
32
- e.key === 'ArrowUp'
35
+ for (let n = 0; n < values.length; n++) {
36
+ const focusValue = isForward
33
37
  ? // prev or last
34
- index - 1 < 0
35
- ? values[values.length - 1]
36
- : values[index - 1]
38
+ index + 1 >= values.length
39
+ ? values[0]
40
+ : values[index + 1]
37
41
  : // next or first
38
- index + 1 >= values.length
39
- ? values[0]
40
- : values[index + 1]
42
+ index - 1 < 0
43
+ ? values[values.length - 1]
44
+ : values[index - 1]
45
+ const next = root?.current?.querySelector(
46
+ `[data-key='${focusValue}']`
47
+ )
41
48
 
42
- const next = root?.current?.querySelector(`[data-key='${focusValue}']`)
43
-
44
- if (next instanceof HTMLElement) {
45
- next.focus({ preventScroll: true })
46
- if (root?.current?.parentElement) {
47
- handleFocusByKeyBoard(next, root.current.parentElement)
49
+ if (next instanceof HTMLElement) {
50
+ if (next.ariaDisabled === 'true') {
51
+ index += isForward ? 1 : -1
52
+ continue
53
+ }
54
+ next.focus({ preventScroll: true })
55
+ if (root?.current?.parentElement) {
56
+ handleFocusByKeyBoard(next, root.current.parentElement)
57
+ }
58
+ break
48
59
  }
49
60
  }
50
61
  }
51
62
  },
52
- [setContextValue, value, root, values]
63
+ [setContextValue, propsArray, value, root]
53
64
  )
54
65
  return [handleKeyDown, setContextValue]
55
66
  }
@@ -1,16 +1,17 @@
1
1
  import { RefObject, createContext } from 'react'
2
+ import { DropdownMenuItemProps } from '../DropdownMenuItem'
2
3
 
3
4
  type MenuListContextType = {
4
5
  root?: RefObject<HTMLUListElement>
5
6
  value?: string
6
- values?: string[]
7
+ propsArray?: DropdownMenuItemProps[]
7
8
  setValue: (v: string) => void
8
9
  }
9
10
 
10
11
  export const MenuListContext = createContext<MenuListContextType>({
11
12
  root: undefined,
12
13
  value: '',
13
- values: [],
14
+ propsArray: [],
14
15
  setValue: (_v: string) => {
15
16
  // empty
16
17
  },
@@ -24,6 +24,8 @@ exports[`Storybook Tests DropdownSelector/MenuList Basic 1`] = `
24
24
  outline: none;
25
25
  padding-right: 16px;
26
26
  padding-left: 16px;
27
+ -webkit-transition: background-color 0.2s;
28
+ transition: background-color 0.2s;
27
29
  }
28
30
 
29
31
  .c2:disabled,
@@ -32,9 +34,9 @@ exports[`Storybook Tests DropdownSelector/MenuList Basic 1`] = `
32
34
  cursor: default;
33
35
  }
34
36
 
35
- .c2:hover,
36
- .c2:focus,
37
- .c2:focus-within {
37
+ .c2:hover:not(disabled):not([aria-disabled='true']),
38
+ .c2:focus:not(disabled):not([aria-disabled='true']),
39
+ .c2:focus-within:not(disabled):not([aria-disabled='true']) {
38
40
  background-color: var(--charcoal-surface3);
39
41
  }
40
42
 
@@ -232,6 +234,8 @@ exports[`Storybook Tests DropdownSelector/MenuList Disabled 1`] = `
232
234
  outline: none;
233
235
  padding-right: 16px;
234
236
  padding-left: 16px;
237
+ -webkit-transition: background-color 0.2s;
238
+ transition: background-color 0.2s;
235
239
  }
236
240
 
237
241
  .c2:disabled,
@@ -240,9 +244,9 @@ exports[`Storybook Tests DropdownSelector/MenuList Disabled 1`] = `
240
244
  cursor: default;
241
245
  }
242
246
 
243
- .c2:hover,
244
- .c2:focus,
245
- .c2:focus-within {
247
+ .c2:hover:not(disabled):not([aria-disabled='true']),
248
+ .c2:focus:not(disabled):not([aria-disabled='true']),
249
+ .c2:focus-within:not(disabled):not([aria-disabled='true']) {
246
250
  background-color: var(--charcoal-surface3);
247
251
  }
248
252
 
@@ -331,6 +335,8 @@ exports[`Storybook Tests DropdownSelector/MenuList Group 1`] = `
331
335
  outline: none;
332
336
  padding-right: 16px;
333
337
  padding-left: 16px;
338
+ -webkit-transition: background-color 0.2s;
339
+ transition: background-color 0.2s;
334
340
  }
335
341
 
336
342
  .c5:disabled,
@@ -339,9 +345,9 @@ exports[`Storybook Tests DropdownSelector/MenuList Group 1`] = `
339
345
  cursor: default;
340
346
  }
341
347
 
342
- .c5:hover,
343
- .c5:focus,
344
- .c5:focus-within {
348
+ .c5:hover:not(disabled):not([aria-disabled='true']),
349
+ .c5:focus:not(disabled):not([aria-disabled='true']),
350
+ .c5:focus-within:not(disabled):not([aria-disabled='true']) {
345
351
  background-color: var(--charcoal-surface3);
346
352
  }
347
353
 
@@ -1,4 +1,4 @@
1
- import { useRef } from 'react'
1
+ import { useMemo, useRef } from 'react'
2
2
  import styled from 'styled-components'
3
3
  import { MenuListContext } from './MenuListContext'
4
4
  import { getValuesRecursive } from './internals/getValuesRecursive'
@@ -24,8 +24,10 @@ export type MenuListProps = {
24
24
  */
25
25
  export default function MenuList(props: MenuListProps) {
26
26
  const root = useRef(null)
27
- const values: string[] = []
28
- getValuesRecursive(props.children, values)
27
+ const propsArray = useMemo(
28
+ () => getValuesRecursive(props.children),
29
+ [props.children]
30
+ )
29
31
 
30
32
  return (
31
33
  <StyledUl ref={root}>
@@ -33,7 +35,7 @@ export default function MenuList(props: MenuListProps) {
33
35
  value={{
34
36
  value: props.value ?? '',
35
37
  root,
36
- values,
38
+ propsArray,
37
39
  setValue: (v) => {
38
40
  props.onChange?.(v)
39
41
  },
@@ -2,6 +2,7 @@ import * as React from 'react'
2
2
  import MenuItem from '../../MenuItem'
3
3
  import { MenuListChildren } from '..'
4
4
  import MenuItemGroup from '../../MenuItemGroup'
5
+ import { DropdownMenuItemProps } from '../../DropdownMenuItem'
5
6
 
6
7
  /**
7
8
  * valueというpropsを持つ子要素の値を再起的に探索して配列にする
@@ -11,25 +12,27 @@ import MenuItemGroup from '../../MenuItemGroup'
11
12
  * @param values
12
13
  * @returns
13
14
  */
14
- export function getValuesRecursive(
15
- children: MenuListChildren,
16
- values: string[] = []
17
- ) {
15
+ export function getValuesRecursive(children: MenuListChildren) {
18
16
  const childArray = React.Children.toArray(children)
17
+ const propsArray: DropdownMenuItemProps[] = []
19
18
  for (let i = 0; i < childArray.length; i++) {
20
19
  const child = childArray[i]
21
20
  if (React.isValidElement(child)) {
22
21
  const props = child.props as {
23
- value?: never
22
+ value?: string
23
+ disabled?: boolean
24
24
  children?: React.ReactElement<typeof MenuItem | typeof MenuItemGroup>[]
25
25
  }
26
26
  if ('value' in props && typeof props.value === 'string') {
27
- const childValue = props.value
28
- values.push(childValue)
27
+ propsArray.push({
28
+ disabled: props.disabled,
29
+ value: props.value,
30
+ })
29
31
  }
30
32
  if ('children' in props && props.children) {
31
- getValuesRecursive(props.children, values)
33
+ propsArray.push(...getValuesRecursive(props.children))
32
34
  }
33
35
  }
34
36
  }
37
+ return propsArray
35
38
  }