@charcoal-ui/react 2.2.1 → 2.4.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 (39) hide show
  1. package/dist/components/Checkbox/index.d.ts.map +1 -1
  2. package/dist/components/Checkbox/index.story.d.ts.map +1 -1
  3. package/dist/components/DropdownSelector/DropdownPopover.d.ts +13 -0
  4. package/dist/components/DropdownSelector/DropdownPopover.d.ts.map +1 -0
  5. package/dist/components/DropdownSelector/index.d.ts.map +1 -1
  6. package/dist/components/DropdownSelector/index.story.d.ts +3 -0
  7. package/dist/components/DropdownSelector/index.story.d.ts.map +1 -1
  8. package/dist/components/Modal/index.d.ts +5 -1
  9. package/dist/components/Modal/index.d.ts.map +1 -1
  10. package/dist/core/CharcoalProvider.d.ts +12 -0
  11. package/dist/core/CharcoalProvider.d.ts.map +1 -0
  12. package/dist/core/ComponentAbstraction.d.ts +1 -1
  13. package/dist/core/ComponentAbstraction.d.ts.map +1 -1
  14. package/dist/index.cjs.js +2157 -0
  15. package/dist/index.cjs.js.map +1 -0
  16. package/dist/index.d.ts +1 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.esm.js +2118 -0
  19. package/dist/index.esm.js.map +1 -0
  20. package/dist/styled.d.ts +3 -3
  21. package/package.json +23 -22
  22. package/src/components/Checkbox/index.story.tsx +29 -11
  23. package/src/components/Checkbox/index.tsx +16 -6
  24. package/src/components/DropdownSelector/DropdownPopover.tsx +72 -0
  25. package/src/components/DropdownSelector/Listbox.tsx +15 -13
  26. package/src/components/DropdownSelector/index.story.tsx +123 -45
  27. package/src/components/DropdownSelector/index.tsx +8 -11
  28. package/src/components/Modal/index.tsx +6 -6
  29. package/src/components/Switch/index.tsx +7 -3
  30. package/src/core/CharcoalProvider.tsx +35 -0
  31. package/src/core/ComponentAbstraction.tsx +1 -1
  32. package/src/index.ts +4 -0
  33. package/dist/components/DropdownSelector/Popover.d.ts +0 -10
  34. package/dist/components/DropdownSelector/Popover.d.ts.map +0 -1
  35. package/dist/index.cjs +0 -4446
  36. package/dist/index.cjs.map +0 -1
  37. package/dist/index.js +0 -4409
  38. package/dist/index.js.map +0 -1
  39. package/src/components/DropdownSelector/Popover.tsx +0 -46
@@ -1,5 +1,5 @@
1
1
  import { action } from '@storybook/addon-actions'
2
- import React from 'react'
2
+ import React, { useState } from 'react'
3
3
  import DropdownSelector, {
4
4
  DropdownSelectorItem,
5
5
  DropdownSelectorProps,
@@ -18,16 +18,18 @@ type Props = Omit<
18
18
  >
19
19
  export const Default: Story<Props> = (props) => {
20
20
  return (
21
- <DropdownSelector
22
- {...props}
23
- placeholder={props.placeholder ?? 'Drop Down menu'}
24
- onChange={action('change')}
25
- onOpenChange={action('open')}
26
- >
27
- <DropdownSelectorItem key="k:1">選択肢1</DropdownSelectorItem>
28
- <DropdownSelectorItem key="k:2">選択肢2</DropdownSelectorItem>
29
- <DropdownSelectorItem key="k:3">選択肢3</DropdownSelectorItem>
30
- </DropdownSelector>
21
+ <div style={{ width: 288 }}>
22
+ <DropdownSelector
23
+ {...props}
24
+ placeholder={props.placeholder ?? 'Drop Down menu'}
25
+ onChange={action('change')}
26
+ onOpenChange={action('open')}
27
+ >
28
+ <DropdownSelectorItem key="k:1">選択肢1</DropdownSelectorItem>
29
+ <DropdownSelectorItem key="k:2">選択肢2</DropdownSelectorItem>
30
+ <DropdownSelectorItem key="k:3">選択肢3</DropdownSelectorItem>
31
+ </DropdownSelector>
32
+ </div>
31
33
  )
32
34
  }
33
35
  Default.args = {
@@ -39,6 +41,76 @@ Default.args = {
39
41
  disabled: false,
40
42
  }
41
43
 
44
+ export const Multiple: Story<DropdownSelectorProps> = (props) => {
45
+ return (
46
+ <div>
47
+ <DropdownSelector
48
+ {...props}
49
+ placeholder={'Drop Down menu'}
50
+ onChange={action('change')}
51
+ onOpenChange={action('open')}
52
+ >
53
+ <DropdownSelectorItem key="1">選択肢1</DropdownSelectorItem>
54
+ <DropdownSelectorItem key="2">選択肢2</DropdownSelectorItem>
55
+ <DropdownSelectorItem key="3">選択肢3</DropdownSelectorItem>
56
+ </DropdownSelector>
57
+ <DropdownSelector
58
+ {...props}
59
+ placeholder={'Drop Down menu'}
60
+ onChange={action('change')}
61
+ onOpenChange={action('open')}
62
+ >
63
+ <DropdownSelectorItem key="1">選択肢1</DropdownSelectorItem>
64
+ <DropdownSelectorItem key="2">選択肢2</DropdownSelectorItem>
65
+ <DropdownSelectorItem key="3">選択肢3</DropdownSelectorItem>
66
+ </DropdownSelector>
67
+ </div>
68
+ )
69
+ }
70
+
71
+ export const Bottom: Story<DropdownSelectorProps> = (props) => {
72
+ return (
73
+ <div style={{ marginTop: '1000px' }}>
74
+ <DropdownSelector
75
+ {...props}
76
+ placeholder={'Drop Down menu'}
77
+ onChange={action('change')}
78
+ onOpenChange={action('open')}
79
+ >
80
+ <DropdownSelectorItem key="1">選択肢1</DropdownSelectorItem>
81
+ <DropdownSelectorItem key="2">選択肢2</DropdownSelectorItem>
82
+ <DropdownSelectorItem key="3">選択肢3</DropdownSelectorItem>
83
+ </DropdownSelector>
84
+ </div>
85
+ )
86
+ }
87
+
88
+ export const Many: Story<DropdownSelectorProps> = (props) => {
89
+ const [value, setValue] = useState('50')
90
+ return (
91
+ <div style={{ padding: '300px 100px' }}>
92
+ <DropdownSelector
93
+ {...props}
94
+ placeholder={'Drop Down menu'}
95
+ onChange={(v) => {
96
+ setValue(v.toString())
97
+ action('change')
98
+ }}
99
+ onOpenChange={action('open')}
100
+ value={value}
101
+ >
102
+ {[...(Array(100) as undefined[])].map((_, i) => {
103
+ return (
104
+ <DropdownSelectorItem textValue={i.toString()} key={i}>
105
+ 選択肢{i}
106
+ </DropdownSelectorItem>
107
+ )
108
+ })}
109
+ </DropdownSelector>
110
+ </div>
111
+ )
112
+ }
113
+
42
114
  type HasLabelProps = {
43
115
  disabled?: boolean
44
116
  }
@@ -52,17 +124,19 @@ export const HasLabel: Story<HasLabelProps> = ({ disabled }) => {
52
124
  assertiveText: 'Hint',
53
125
  }
54
126
  return (
55
- <DropdownSelector
56
- {...defaultProps}
57
- disabled={disabled}
58
- placeholder={'Drop Down menu'}
59
- onChange={action('change')}
60
- onOpenChange={action('open')}
61
- >
62
- <DropdownSelectorItem key="1">選択肢1</DropdownSelectorItem>
63
- <DropdownSelectorItem key="2">選択肢2</DropdownSelectorItem>
64
- <DropdownSelectorItem key="3">選択肢3</DropdownSelectorItem>
65
- </DropdownSelector>
127
+ <div style={{ width: 288 }}>
128
+ <DropdownSelector
129
+ {...defaultProps}
130
+ disabled={disabled}
131
+ placeholder={'Drop Down menu'}
132
+ onChange={action('change')}
133
+ onOpenChange={action('open')}
134
+ >
135
+ <DropdownSelectorItem key="1">選択肢1</DropdownSelectorItem>
136
+ <DropdownSelectorItem key="2">選択肢2</DropdownSelectorItem>
137
+ <DropdownSelectorItem key="3">選択肢3</DropdownSelectorItem>
138
+ </DropdownSelector>
139
+ </div>
66
140
  )
67
141
  }
68
142
 
@@ -86,18 +160,20 @@ export const WithSeparator: Story<WithSeparatorProps> = ({
86
160
  assertiveText: 'Hint',
87
161
  }
88
162
  return (
89
- <DropdownSelector
90
- {...defaultProps}
91
- mode={mode}
92
- placeholder={'Drop Down menu'}
93
- onChange={action('change')}
94
- onOpenChange={action('open')}
95
- {...props}
96
- >
97
- <DropdownSelectorItem key="1">選択肢1</DropdownSelectorItem>
98
- <DropdownSelectorItem key="2">選択肢2</DropdownSelectorItem>
99
- <DropdownSelectorItem key="3">選択肢3</DropdownSelectorItem>
100
- </DropdownSelector>
163
+ <div style={{ width: 288 }}>
164
+ <DropdownSelector
165
+ {...defaultProps}
166
+ mode={mode}
167
+ placeholder={'Drop Down menu'}
168
+ onChange={action('change')}
169
+ onOpenChange={action('open')}
170
+ {...props}
171
+ >
172
+ <DropdownSelectorItem key="1">選択肢1</DropdownSelectorItem>
173
+ <DropdownSelectorItem key="2">選択肢2</DropdownSelectorItem>
174
+ <DropdownSelectorItem key="3">選択肢3</DropdownSelectorItem>
175
+ </DropdownSelector>
176
+ </div>
101
177
  )
102
178
  }
103
179
 
@@ -115,17 +191,19 @@ export const Invalid: Story<InvalidProps> = ({ disabled }) => {
115
191
  invalid: true,
116
192
  }
117
193
  return (
118
- <DropdownSelector
119
- {...props}
120
- disabled={disabled}
121
- placeholder={'Drop Down menu'}
122
- onChange={action('change')}
123
- onOpenChange={action('open')}
124
- >
125
- <DropdownSelectorItem key="1">選択肢1</DropdownSelectorItem>
126
- <DropdownSelectorItem key="2">選択肢2</DropdownSelectorItem>
127
- <DropdownSelectorItem key="3">選択肢3</DropdownSelectorItem>
128
- </DropdownSelector>
194
+ <div style={{ width: 288 }}>
195
+ <DropdownSelector
196
+ {...props}
197
+ disabled={disabled}
198
+ placeholder={'Drop Down menu'}
199
+ onChange={action('change')}
200
+ onOpenChange={action('open')}
201
+ >
202
+ <DropdownSelectorItem key="1">選択肢1</DropdownSelectorItem>
203
+ <DropdownSelectorItem key="2">選択肢2</DropdownSelectorItem>
204
+ <DropdownSelectorItem key="3">選択肢3</DropdownSelectorItem>
205
+ </DropdownSelector>
206
+ </div>
129
207
  )
130
208
  }
131
209
 
@@ -7,13 +7,13 @@ import { useSelect, HiddenSelect } from '@react-aria/select'
7
7
  import { useButton } from '@react-aria/button'
8
8
  import { SelectProps } from '@react-types/select'
9
9
  import Listbox, { ListboxProps } from './Listbox'
10
- import Popover from './Popover'
11
10
  import Icon from '../Icon'
12
11
  import FieldLabel from '../FieldLabel'
13
12
  import { theme } from '../../styled'
14
13
 
15
14
  import type { CollectionBase } from '@react-types/shared'
16
15
  import type { ReactNode } from 'react'
16
+ import { DropdownPopover } from './DropdownPopover'
17
17
 
18
18
  type LabelProps = {
19
19
  readonly showLabel?: boolean
@@ -124,7 +124,11 @@ const DropdownSelector = <T extends Record<string, unknown>>({
124
124
  <DropdownButtonIcon name="16/Menu" />
125
125
  </DropdownButton>
126
126
  {state.isOpen && (
127
- <DropdownPopover open={state.isOpen} onClose={() => state.close()}>
127
+ <DropdownPopover
128
+ state={state}
129
+ triggerRef={triggerRef}
130
+ value={props.value ?? props.defaultValue}
131
+ >
128
132
  <Listbox {...menuProps} state={state} mode={mode} />
129
133
  </DropdownPopover>
130
134
  )}
@@ -148,6 +152,7 @@ export const DropdownSelectorItem = Item
148
152
  const DropdownSelectorRoot = styled.div`
149
153
  position: relative;
150
154
  display: inline-block;
155
+ width: 100%;
151
156
 
152
157
  ${disabledSelector} {
153
158
  cursor: default;
@@ -171,7 +176,7 @@ const DropdownButton = styled.button<{ invalid: boolean }>`
171
176
  align-items: center;
172
177
 
173
178
  height: 40px;
174
- width: 288px;
179
+ width: 100%;
175
180
  box-sizing: border-box;
176
181
  cursor: pointer;
177
182
 
@@ -208,11 +213,3 @@ const AssertiveText = styled.div<{ invalid: boolean }>`
208
213
  invalid ? o.font.assertive : o.font.text2,
209
214
  ])}
210
215
  `
211
-
212
- const DropdownPopover = styled(Popover)`
213
- position: absolute;
214
- width: 100%;
215
-
216
- top: 100%;
217
- margin-top: 2px;
218
- `
@@ -4,7 +4,6 @@ import {
4
4
  Overlay,
5
5
  useModalOverlay,
6
6
  useOverlay,
7
- usePreventScroll,
8
7
  } from '@react-aria/overlays'
9
8
  import styled, { css, useTheme } from 'styled-components'
10
9
  import { theme } from '../../styled'
@@ -29,8 +28,10 @@ export type ModalProps = AriaModalOverlayProps &
29
28
  isOpen: boolean
30
29
  onClose: () => void
31
30
 
32
- // NOTICE: デフォルト値を与えてはならない
33
- // (たとえば document.body をデフォルト値にすると SSR できなくなる)
31
+ /**
32
+ * https://github.com/adobe/react-spectrum/issues/3787
33
+ * Next.jsで使用する際に発生するエラーの一時的な回避策でdocument.bodyを指定する必要がある
34
+ */
34
35
  portalContainer?: HTMLElement
35
36
  }
36
37
 
@@ -39,7 +40,7 @@ const DEFAULT_Z_INDEX = 10
39
40
  /**
40
41
  * モーダルコンポーネント。
41
42
  *
42
- * @example アプリケーションルートで `<OverlayProvider>` で囲った上で利用する
43
+ * @example アプリケーションルートで `<OverlayProvider>` ないし `<CharcoalProvider>` で囲った上で利用する
43
44
  * ```tsx
44
45
  * import {
45
46
  * OverlayProvider,
@@ -78,7 +79,6 @@ export default function Modal({
78
79
  const ref = useRef<HTMLDivElement>(null)
79
80
  const { overlayProps, underlayProps } = useOverlay(props, ref)
80
81
 
81
- usePreventScroll()
82
82
  const { modalProps } = useModalOverlay(
83
83
  props,
84
84
  {
@@ -126,7 +126,7 @@ export default function Modal({
126
126
  return transition(
127
127
  ({ backgroundColor, transform }, item) =>
128
128
  item && (
129
- <Overlay>
129
+ <Overlay portalContainer={portalContainer}>
130
130
  <ModalBackground
131
131
  zIndex={zIndex}
132
132
  {...underlayProps}
@@ -4,7 +4,7 @@ import React, { useRef, useMemo } from 'react'
4
4
  import { useToggleState } from 'react-stately'
5
5
  import styled from 'styled-components'
6
6
  import { theme } from '../../styled'
7
- import { disabledSelector, px } from '@charcoal-ui/utils'
7
+ import { disabledSelector } from '@charcoal-ui/utils'
8
8
 
9
9
  export type SwitchProps = {
10
10
  name: string
@@ -59,7 +59,6 @@ const Label = styled.label`
59
59
  display: inline-grid;
60
60
  grid-template-columns: auto 1fr;
61
61
  align-items: center;
62
- gap: ${({ theme }) => px(theme.spacing[4])};
63
62
  cursor: pointer;
64
63
  outline: 0;
65
64
 
@@ -71,7 +70,11 @@ const Label = styled.label`
71
70
  `
72
71
 
73
72
  const LabelInner = styled.div`
74
- ${theme((o) => [o.typography(14), o.font.text2])}
73
+ ${theme((o) => [
74
+ o.typography(14).preserveHalfLeading,
75
+ o.font.text2,
76
+ o.margin.left(4),
77
+ ])}
75
78
  `
76
79
 
77
80
  const SwitchInput = styled.input.attrs({
@@ -91,6 +94,7 @@ const SwitchInput = styled.input.attrs({
91
94
  o.height.px(16),
92
95
  o.bg.text4.hover.press,
93
96
  o.outline.default.focus,
97
+ o.margin.all(0),
94
98
  ])}
95
99
 
96
100
  &::after {
@@ -0,0 +1,35 @@
1
+ import React from 'react'
2
+ import { ThemeProvider } from 'styled-components'
3
+ import ComponentAbstraction, { Components } from './ComponentAbstraction'
4
+ import { TokenInjector } from '@charcoal-ui/styled'
5
+ import { ThemeMap } from '@charcoal-ui/styled/src/TokenInjector'
6
+ import { CharcoalTheme } from '@charcoal-ui/theme'
7
+
8
+ import { OverlayProvider } from './OverlayProvider'
9
+ import { SSRProvider } from './SSRProvider'
10
+
11
+ export type CharcoalProviderProps = React.PropsWithChildren<{
12
+ themeMap: ThemeMap<CharcoalTheme>
13
+ defaultTheme?: CharcoalTheme
14
+ injectTokens?: boolean
15
+ components?: Partial<Components>
16
+ }>
17
+
18
+ export function CharcoalProvider({
19
+ themeMap,
20
+ defaultTheme = themeMap[':root'],
21
+ components = {},
22
+ injectTokens = true,
23
+ children,
24
+ }: CharcoalProviderProps) {
25
+ return (
26
+ <SSRProvider>
27
+ <ThemeProvider theme={defaultTheme}>
28
+ {injectTokens && <TokenInjector theme={themeMap} />}
29
+ <ComponentAbstraction components={components}>
30
+ <OverlayProvider>{children}</OverlayProvider>
31
+ </ComponentAbstraction>
32
+ </ThemeProvider>
33
+ </SSRProvider>
34
+ )
35
+ }
@@ -17,7 +17,7 @@ export const DefaultLink = React.forwardRef<HTMLAnchorElement, LinkProps>(
17
17
  }
18
18
  )
19
19
 
20
- interface Components {
20
+ export interface Components {
21
21
  Link: React.ComponentType<React.ComponentPropsWithRef<typeof DefaultLink>>
22
22
  }
23
23
 
package/src/index.ts CHANGED
@@ -5,6 +5,10 @@ export {
5
5
  } from './core/ComponentAbstraction'
6
6
  export { SSRProvider } from './core/SSRProvider'
7
7
  export { OverlayProvider } from './core/OverlayProvider'
8
+ export {
9
+ CharcoalProvider,
10
+ type CharcoalProviderProps,
11
+ } from './core/CharcoalProvider'
8
12
  export { default as Button, type ButtonProps } from './components/Button'
9
13
  export {
10
14
  default as Clickable,
@@ -1,10 +0,0 @@
1
- import React, { PropsWithChildren, CSSProperties } from 'react';
2
- declare type Props = PropsWithChildren<{
3
- open?: boolean;
4
- onClose?: () => void;
5
- style?: CSSProperties;
6
- className?: string;
7
- }>;
8
- declare const _default: React.NamedExoticComponent<Props>;
9
- export default _default;
10
- //# sourceMappingURL=Popover.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Popover.d.ts","sourceRoot":"","sources":["../../../src/components/DropdownSelector/Popover.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAIZ,iBAAiB,EAEjB,aAAa,EACd,MAAM,OAAO,CAAA;AAGd,aAAK,KAAK,GAAG,iBAAiB,CAAC;IAC7B,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAC,CAAA;;AA4BF,wBAA4B"}