@junyiacademy/ui-test 0.0.10 → 0.0.14
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/declarations/libs/ui/src/index.d.ts +2 -3
- package/declarations/libs/ui/src/interfaces/index.d.ts +18 -0
- package/declarations/libs/ui/src/lib/TopicFilter.d.ts +1 -1
- package/declarations/libs/ui/src/lib/menu-item/SelectMenuItem.d.ts +1 -1
- package/declarations/libs/ui/src/lib/select/OutlinedSelect.d.ts +2 -19
- package/declarations/libs/ui/src/lib/select/Select.d.ts +3 -0
- package/declarations/libs/ui/src/lib/select/StandardSelect.d.ts +2 -15
- package/declarations/libs/ui/src/lib/topic-filter/TopicFilter.d.ts +13 -0
- package/dist/libs/ui/src/index.js +4 -6
- package/dist/libs/ui/src/lib/TopicFilter.js +3 -1
- package/dist/libs/ui/src/lib/select/OutlinedSelect.js +24 -8
- package/dist/libs/ui/src/lib/select/Select.js +16 -0
- package/dist/libs/ui/src/lib/select/StandardSelect.js +9 -1
- package/dist/libs/ui/src/lib/topic-filter/TopicFilter.js +120 -0
- package/package.json +1 -1
- package/src/index.ts +2 -3
- package/src/interfaces/index.tsx +25 -0
- package/src/lib/select/OutlinedSelect.tsx +27 -31
- package/src/lib/select/{StandardSelect.stories.tsx → Select.stories.tsx} +106 -30
- package/src/lib/select/Select.tsx +13 -0
- package/src/lib/select/StandardSelect.tsx +11 -19
- package/src/lib/{TopicFilter.stories.tsx → topic-filter/TopicFilter.stories.tsx} +10 -9
- package/src/lib/{TopicFilter.tsx → topic-filter/TopicFilter.tsx} +5 -5
- package/src/lib/TopicFilter.spec.tsx +0 -10
- package/src/lib/menu-item/SelectMenuItem.spec.tsx +0 -10
- package/src/lib/select/OutlinedSelect.spec.tsx +0 -10
- package/src/lib/select/OutlinedSelect.stories.tsx +0 -238
|
@@ -3,14 +3,13 @@ import { Story, Meta } from '@storybook/react'
|
|
|
3
3
|
import { Theme, styled } from '@material-ui/core/styles'
|
|
4
4
|
import { InputAdornment } from '@material-ui/core'
|
|
5
5
|
import { Visibility } from '@material-ui/icons'
|
|
6
|
-
import {
|
|
6
|
+
import { Select } from './Select'
|
|
7
7
|
import SelectMenuItem from '../menu-item/SelectMenuItem'
|
|
8
|
-
|
|
9
|
-
const PLACEHOLDER = '請選擇'
|
|
8
|
+
import { SelectProps } from '../../interfaces'
|
|
10
9
|
|
|
11
10
|
export default {
|
|
12
|
-
component:
|
|
13
|
-
title: '
|
|
11
|
+
component: Select,
|
|
12
|
+
title: 'Select',
|
|
14
13
|
argTypes: {
|
|
15
14
|
color: {
|
|
16
15
|
type: { name: 'string', required: false },
|
|
@@ -23,12 +22,22 @@ export default {
|
|
|
23
22
|
options: ['primary', 'secondary'],
|
|
24
23
|
control: { type: 'radio' },
|
|
25
24
|
},
|
|
25
|
+
variant: {
|
|
26
|
+
type: { name: 'string', required: false },
|
|
27
|
+
description: 'The variant to use.',
|
|
28
|
+
table: {
|
|
29
|
+
type: { summary: 'standard | outlined' },
|
|
30
|
+
defaultValue: { summary: 'standard' },
|
|
31
|
+
},
|
|
32
|
+
options: ['standard', 'outlined'],
|
|
33
|
+
control: { type: 'radio' },
|
|
34
|
+
},
|
|
26
35
|
size: {
|
|
27
36
|
type: { name: 'string', required: false },
|
|
28
37
|
description: `Adjust size`,
|
|
29
38
|
table: {
|
|
30
39
|
type: { summary: 'medium | small' },
|
|
31
|
-
defaultValue: { summary: '
|
|
40
|
+
defaultValue: { summary: 'small' },
|
|
32
41
|
},
|
|
33
42
|
options: ['small', 'medium'],
|
|
34
43
|
control: { type: 'radio' },
|
|
@@ -51,12 +60,22 @@ export default {
|
|
|
51
60
|
},
|
|
52
61
|
control: { type: 'number' },
|
|
53
62
|
},
|
|
63
|
+
hasLabel: {
|
|
64
|
+
type: { name: 'boolean', required: false },
|
|
65
|
+
description:
|
|
66
|
+
'If true, the label is displayed. Always true on StandardSelect.',
|
|
67
|
+
table: {
|
|
68
|
+
type: { summary: 'boolean' },
|
|
69
|
+
defaultValue: { summary: true },
|
|
70
|
+
},
|
|
71
|
+
control: { type: 'boolean' },
|
|
72
|
+
},
|
|
54
73
|
hasShrink: {
|
|
55
74
|
type: { name: 'boolean', required: false },
|
|
56
75
|
description: 'If true, the label is displayed and shrunk.',
|
|
57
76
|
table: {
|
|
58
77
|
type: { summary: 'boolean' },
|
|
59
|
-
defaultValue: { summary:
|
|
78
|
+
defaultValue: { summary: false },
|
|
60
79
|
},
|
|
61
80
|
control: { type: 'boolean' },
|
|
62
81
|
},
|
|
@@ -105,16 +124,17 @@ export default {
|
|
|
105
124
|
},
|
|
106
125
|
control: { type: 'text' },
|
|
107
126
|
},
|
|
108
|
-
|
|
127
|
+
SelectProps: {
|
|
109
128
|
type: { name: 'any', required: false },
|
|
110
|
-
description: 'Attributes applied to inner
|
|
129
|
+
description: 'Attributes applied to inner Select element.',
|
|
111
130
|
table: {
|
|
112
131
|
type: { summary: 'any' },
|
|
113
132
|
},
|
|
114
133
|
},
|
|
115
|
-
|
|
134
|
+
CommonInputProps: {
|
|
116
135
|
type: { name: 'any', required: false },
|
|
117
|
-
description:
|
|
136
|
+
description:
|
|
137
|
+
'Attributes applied to to inner OutlinedInput element on OutlinedSelect or Input element on StandardSelect.',
|
|
118
138
|
table: {
|
|
119
139
|
type: { summary: 'any' },
|
|
120
140
|
},
|
|
@@ -122,14 +142,17 @@ export default {
|
|
|
122
142
|
},
|
|
123
143
|
} as Meta
|
|
124
144
|
|
|
125
|
-
const
|
|
145
|
+
const PLACEHOLDER = 'Please select an option'
|
|
146
|
+
const ERROR_PLACEHOLDER = 'Please select an option'
|
|
147
|
+
const PREFIX = 'JuiSelect'
|
|
126
148
|
|
|
127
149
|
const classes = {
|
|
128
150
|
inputAdornmentRoot: `${PREFIX}-inputAdornmentRoot`,
|
|
129
151
|
}
|
|
152
|
+
|
|
130
153
|
interface StyledInputAdornmentProps {
|
|
131
|
-
theme: Theme
|
|
132
154
|
disabled: boolean
|
|
155
|
+
theme?: Theme
|
|
133
156
|
}
|
|
134
157
|
|
|
135
158
|
const StyledInputAdornment = styled(({ disabled: _disabled, ...props }) => (
|
|
@@ -140,6 +163,7 @@ const StyledInputAdornment = styled(({ disabled: _disabled, ...props }) => (
|
|
|
140
163
|
{...props}
|
|
141
164
|
/>
|
|
142
165
|
))(({ disabled, theme }: StyledInputAdornmentProps) => ({
|
|
166
|
+
height: '100%',
|
|
143
167
|
[`&.${classes.inputAdornmentRoot}`]: {
|
|
144
168
|
color: disabled
|
|
145
169
|
? theme.palette.action.disabled
|
|
@@ -147,7 +171,8 @@ const StyledInputAdornment = styled(({ disabled: _disabled, ...props }) => (
|
|
|
147
171
|
},
|
|
148
172
|
}))
|
|
149
173
|
|
|
150
|
-
|
|
174
|
+
// Standard Select start with here.
|
|
175
|
+
const SelectWithMenu = (props: SelectProps) => {
|
|
151
176
|
const [item, setItem] = useState<string>('')
|
|
152
177
|
|
|
153
178
|
const handleChange = (event) => {
|
|
@@ -155,7 +180,7 @@ const StandardSelectWithMenu = (props: StandardSelectProps) => {
|
|
|
155
180
|
}
|
|
156
181
|
|
|
157
182
|
return (
|
|
158
|
-
<
|
|
183
|
+
<Select
|
|
159
184
|
value={item}
|
|
160
185
|
SelectProps={{
|
|
161
186
|
onChange: (e) => {
|
|
@@ -164,38 +189,88 @@ const StandardSelectWithMenu = (props: StandardSelectProps) => {
|
|
|
164
189
|
}}
|
|
165
190
|
{...props}
|
|
166
191
|
>
|
|
167
|
-
<SelectMenuItem width={
|
|
192
|
+
<SelectMenuItem width={props.width} value='' disabled>
|
|
168
193
|
{PLACEHOLDER}
|
|
169
194
|
</SelectMenuItem>
|
|
170
|
-
<SelectMenuItem width={
|
|
171
|
-
This is a select menu item
|
|
195
|
+
<SelectMenuItem width={props.width} value='Option1'>
|
|
196
|
+
This is a select menu item
|
|
172
197
|
</SelectMenuItem>
|
|
173
|
-
<SelectMenuItem width={
|
|
174
|
-
|
|
198
|
+
<SelectMenuItem width={props.width} value='Option2'>
|
|
199
|
+
This is option 2
|
|
175
200
|
</SelectMenuItem>
|
|
176
|
-
</
|
|
201
|
+
</Select>
|
|
177
202
|
)
|
|
178
203
|
}
|
|
179
204
|
|
|
180
|
-
const ValueOnlyStory: Story<
|
|
181
|
-
<
|
|
205
|
+
const ValueOnlyStory: Story<SelectProps> = (args) => (
|
|
206
|
+
<SelectWithMenu {...args} />
|
|
182
207
|
)
|
|
183
208
|
|
|
184
209
|
export const ValueOnly = ValueOnlyStory.bind({})
|
|
185
210
|
|
|
186
211
|
ValueOnly.args = {
|
|
187
212
|
color: 'primary',
|
|
188
|
-
|
|
189
|
-
|
|
213
|
+
variant: 'standard',
|
|
214
|
+
size: 'small',
|
|
215
|
+
width: 300,
|
|
216
|
+
paperMaxHeight: 300,
|
|
217
|
+
hasShrink: false,
|
|
218
|
+
placeholder: PLACEHOLDER,
|
|
219
|
+
helperText: 'Pick your choice',
|
|
220
|
+
disabled: false,
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const SelectWithError = (props: SelectProps) => {
|
|
224
|
+
const [item, setItem] = useState<string>('')
|
|
225
|
+
|
|
226
|
+
const handleChange = (event) => {
|
|
227
|
+
setItem(event.target.value)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return (
|
|
231
|
+
<Select
|
|
232
|
+
value={item}
|
|
233
|
+
SelectProps={{
|
|
234
|
+
onChange: (e) => {
|
|
235
|
+
handleChange(e)
|
|
236
|
+
},
|
|
237
|
+
}}
|
|
238
|
+
error={item === ''}
|
|
239
|
+
helperText={item === '' ? ERROR_PLACEHOLDER : ''}
|
|
240
|
+
{...props}
|
|
241
|
+
>
|
|
242
|
+
<SelectMenuItem width={props.width} value='' disabled>
|
|
243
|
+
{PLACEHOLDER}
|
|
244
|
+
</SelectMenuItem>
|
|
245
|
+
<SelectMenuItem width={props.width} value={'Test'}>
|
|
246
|
+
This is a select menu item, This is a select menu item
|
|
247
|
+
</SelectMenuItem>
|
|
248
|
+
<SelectMenuItem width={props.width} value={'Example'}>
|
|
249
|
+
Example
|
|
250
|
+
</SelectMenuItem>
|
|
251
|
+
</Select>
|
|
252
|
+
)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const WithErrorStory: Story<SelectProps> = (args) => (
|
|
256
|
+
<SelectWithError {...args} />
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
export const WithError = WithErrorStory.bind({})
|
|
260
|
+
|
|
261
|
+
WithError.args = {
|
|
262
|
+
color: 'primary',
|
|
263
|
+
variant: 'standard',
|
|
264
|
+
size: 'small',
|
|
265
|
+
width: 300,
|
|
190
266
|
paperMaxHeight: 300,
|
|
191
267
|
hasShrink: false,
|
|
192
268
|
placeholder: PLACEHOLDER,
|
|
193
|
-
helperText: 'test',
|
|
194
269
|
disabled: false,
|
|
195
270
|
}
|
|
196
271
|
|
|
197
|
-
const WithPrefixStory: Story<
|
|
198
|
-
<
|
|
272
|
+
const WithPrefixStory: Story<SelectProps> = (args) => (
|
|
273
|
+
<SelectWithMenu
|
|
199
274
|
InputProps={{
|
|
200
275
|
startAdornment: (
|
|
201
276
|
<StyledInputAdornment position='start' disabled={args.disabled}>
|
|
@@ -211,11 +286,12 @@ export const WithPrefix = WithPrefixStory.bind({})
|
|
|
211
286
|
|
|
212
287
|
WithPrefix.args = {
|
|
213
288
|
color: 'primary',
|
|
214
|
-
|
|
289
|
+
variant: 'standard',
|
|
290
|
+
size: 'small',
|
|
215
291
|
width: 300,
|
|
216
292
|
paperMaxHeight: 300,
|
|
217
293
|
hasShrink: false,
|
|
218
294
|
placeholder: PLACEHOLDER,
|
|
219
|
-
helperText: '
|
|
295
|
+
helperText: 'Pick your choice',
|
|
220
296
|
disabled: false,
|
|
221
297
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { OutlinedSelect } from './OutlinedSelect'
|
|
3
|
+
import { StandardSelect } from './StandardSelect'
|
|
4
|
+
import { SelectProps } from '../../interfaces'
|
|
5
|
+
|
|
6
|
+
export function Select({ variant, ...props }: SelectProps) {
|
|
7
|
+
if (variant === 'outlined') {
|
|
8
|
+
return <OutlinedSelect {...props} />
|
|
9
|
+
}
|
|
10
|
+
return <StandardSelect {...props} />
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default Select
|
|
@@ -4,12 +4,10 @@ import {
|
|
|
4
4
|
InputLabel,
|
|
5
5
|
FormControl,
|
|
6
6
|
Select,
|
|
7
|
-
SelectProps,
|
|
8
7
|
Input,
|
|
9
|
-
InputProps,
|
|
10
8
|
FormHelperText,
|
|
11
|
-
InputAdornment,
|
|
12
9
|
} from '@material-ui/core'
|
|
10
|
+
import { SelectProps } from '../../interfaces'
|
|
13
11
|
|
|
14
12
|
// self-defined-components
|
|
15
13
|
const PREFIX = 'JuiStandardSelect'
|
|
@@ -18,6 +16,8 @@ const classes = {
|
|
|
18
16
|
inputLabelFocused: `${PREFIX}-inputLabelFocused`,
|
|
19
17
|
inputLabelMarginDense: `${PREFIX}-inputLabelMarginDense`,
|
|
20
18
|
inputLabelError: `${PREFIX}-inputLabelError`,
|
|
19
|
+
inputFocused: `${PREFIX}-inputFocused`,
|
|
20
|
+
inputInput: `${PREFIX}-input`,
|
|
21
21
|
inputUnderline: `${PREFIX}-inputUnderline`,
|
|
22
22
|
inputError: `${PREFIX}-inputError`,
|
|
23
23
|
inputDisabled: `${PREFIX}-inputDisabled`,
|
|
@@ -102,6 +102,7 @@ interface StyledInputProps {
|
|
|
102
102
|
const StyledInput = styled(({ color: _color, ...props }) => (
|
|
103
103
|
<Input
|
|
104
104
|
classes={{
|
|
105
|
+
input: classes.inputInput,
|
|
105
106
|
disabled: classes.inputDisabled,
|
|
106
107
|
underline: classes.inputUnderline,
|
|
107
108
|
error: classes.inputError,
|
|
@@ -110,6 +111,11 @@ const StyledInput = styled(({ color: _color, ...props }) => (
|
|
|
110
111
|
/>
|
|
111
112
|
))(({ color, theme }: StyledInputProps) => ({
|
|
112
113
|
color: theme.palette.text.primary,
|
|
114
|
+
[`& .${classes.inputInput}`]: {
|
|
115
|
+
['&:focus']: {
|
|
116
|
+
background: 'rgba(0,0,0,0)',
|
|
117
|
+
},
|
|
118
|
+
},
|
|
113
119
|
[`&.${classes.inputUnderline}:not(.${classes.inputDisabled}):not(.${classes.inputError})`]: {
|
|
114
120
|
[`&:after,&:hover:before`]: {
|
|
115
121
|
borderBottomColor: theme.palette[color].main,
|
|
@@ -122,20 +128,6 @@ const StyledInput = styled(({ color: _color, ...props }) => (
|
|
|
122
128
|
},
|
|
123
129
|
}))
|
|
124
130
|
|
|
125
|
-
export interface StandardSelectProps extends SelectProps {
|
|
126
|
-
color?: 'primary' | 'secondary'
|
|
127
|
-
size?: 'medium' | 'small'
|
|
128
|
-
width?: number | 'auto'
|
|
129
|
-
paperMaxHeight?: number | 'auto'
|
|
130
|
-
error?: boolean
|
|
131
|
-
hasShrink?: boolean
|
|
132
|
-
placeholder: string
|
|
133
|
-
helperText?: string
|
|
134
|
-
InputProps?: object & Partial<InputProps>
|
|
135
|
-
disabled?: boolean
|
|
136
|
-
SelectProps?: object | Partial<SelectProps>
|
|
137
|
-
}
|
|
138
|
-
|
|
139
131
|
export function StandardSelect({
|
|
140
132
|
placeholder,
|
|
141
133
|
helperText,
|
|
@@ -143,14 +135,14 @@ export function StandardSelect({
|
|
|
143
135
|
SelectProps,
|
|
144
136
|
children,
|
|
145
137
|
color = 'primary',
|
|
146
|
-
size = '
|
|
138
|
+
size = 'small',
|
|
147
139
|
width = 'auto',
|
|
148
140
|
paperMaxHeight = 'auto',
|
|
149
141
|
error = false,
|
|
150
142
|
hasShrink = false,
|
|
151
143
|
value = '',
|
|
152
144
|
disabled = false,
|
|
153
|
-
}:
|
|
145
|
+
}: SelectProps) {
|
|
154
146
|
const hasAdornment = !!InputProps?.startAdornment
|
|
155
147
|
const hasHelperText = !!helperText
|
|
156
148
|
return (
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { Story, Meta } from '@storybook/react'
|
|
3
|
-
import
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
TopicFilter as JuiTopicFilter,
|
|
5
|
+
TopicFilterProps as JuiTopicFilterProps,
|
|
6
|
+
} from './TopicFilter'
|
|
7
|
+
import { topicTree } from '../../utils/topicTree'
|
|
5
8
|
|
|
6
9
|
export default {
|
|
7
|
-
component:
|
|
10
|
+
component: JuiTopicFilter,
|
|
8
11
|
title: 'TopicFilter',
|
|
9
12
|
argTypes: {
|
|
10
13
|
topicTree: {
|
|
@@ -63,15 +66,13 @@ export default {
|
|
|
63
66
|
},
|
|
64
67
|
} as Meta
|
|
65
68
|
|
|
66
|
-
const
|
|
67
|
-
<
|
|
69
|
+
const TopicFilterStory: Story<JuiTopicFilterProps> = (args) => (
|
|
70
|
+
<JuiTopicFilter {...args} />
|
|
68
71
|
)
|
|
69
72
|
|
|
70
|
-
export const
|
|
71
|
-
{}
|
|
72
|
-
)
|
|
73
|
+
export const TopicFilter = TopicFilterStory.bind({})
|
|
73
74
|
|
|
74
|
-
|
|
75
|
+
TopicFilter.args = {
|
|
75
76
|
topicTree: topicTree,
|
|
76
77
|
onTopicSelected: () => {},
|
|
77
78
|
isLastLayer: (selectedTopic) => {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React, { useState, useEffect } from 'react'
|
|
2
2
|
import { Theme, styled } from '@material-ui/core/styles'
|
|
3
3
|
import ArrowRightRoundedIcon from '@material-ui/icons/ArrowRightRounded'
|
|
4
|
-
import type { ITopicTreeNode } from '
|
|
5
|
-
import OutlinedSelect from '
|
|
6
|
-
import SelectMenuItem from '
|
|
4
|
+
import type { ITopicTreeNode } from '../../interfaces'
|
|
5
|
+
import OutlinedSelect from '../select/OutlinedSelect'
|
|
6
|
+
import SelectMenuItem from '../menu-item/SelectMenuItem'
|
|
7
7
|
|
|
8
8
|
// self-defined-configs
|
|
9
9
|
const PLACEHOLDER = '請選擇'
|
|
@@ -45,7 +45,7 @@ export interface TopicFilterProps {
|
|
|
45
45
|
initSelectedTopicIds: string[]
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
const TopicFilter = ({
|
|
48
|
+
export const TopicFilter = ({
|
|
49
49
|
topicTree,
|
|
50
50
|
onTopicSelected,
|
|
51
51
|
isLastLayer,
|
|
@@ -150,7 +150,7 @@ const TopicFilter = ({
|
|
|
150
150
|
SelectProps={{
|
|
151
151
|
'data-testid': `layered-topic-${layerNumber}`,
|
|
152
152
|
}}
|
|
153
|
-
|
|
153
|
+
InputProps={{
|
|
154
154
|
inputProps: {
|
|
155
155
|
'aria-label': `layered-topic-${layerNumber}`,
|
|
156
156
|
},
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { render } from '@testing-library/react'
|
|
2
|
-
|
|
3
|
-
import TopicFilter from './TopicFilter'
|
|
4
|
-
|
|
5
|
-
describe('TopicFilter', () => {
|
|
6
|
-
it('should render successfully', () => {
|
|
7
|
-
const { baseElement } = render(<TopicFilter />)
|
|
8
|
-
expect(baseElement).toBeTruthy()
|
|
9
|
-
})
|
|
10
|
-
})
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { render } from '@testing-library/react'
|
|
2
|
-
|
|
3
|
-
import SelectMenuItem from './SelectMenuItem'
|
|
4
|
-
|
|
5
|
-
describe('SelectMenuItem', () => {
|
|
6
|
-
it('should render successfully', () => {
|
|
7
|
-
const { baseElement } = render(<SelectMenuItem />)
|
|
8
|
-
expect(baseElement).toBeTruthy()
|
|
9
|
-
})
|
|
10
|
-
})
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { render } from '@testing-library/react'
|
|
2
|
-
|
|
3
|
-
import OutlinedSelect from './OutlinedSelect'
|
|
4
|
-
|
|
5
|
-
describe('OutlinedSelect', () => {
|
|
6
|
-
it('should render successfully', () => {
|
|
7
|
-
const { baseElement } = render(<OutlinedSelect />)
|
|
8
|
-
expect(baseElement).toBeTruthy()
|
|
9
|
-
})
|
|
10
|
-
})
|
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react'
|
|
2
|
-
import { Story, Meta } from '@storybook/react'
|
|
3
|
-
import { Theme, styled } from '@material-ui/core/styles'
|
|
4
|
-
import { InputAdornment, OutlinedInputProps } from '@material-ui/core'
|
|
5
|
-
import { Visibility } from '@material-ui/icons'
|
|
6
|
-
import OutlinedSelect, { OutlinedSelectProps } from './OutlinedSelect'
|
|
7
|
-
import SelectMenuItem from '../menu-item/SelectMenuItem'
|
|
8
|
-
|
|
9
|
-
const PLACEHOLDER = '請選擇'
|
|
10
|
-
|
|
11
|
-
export default {
|
|
12
|
-
component: OutlinedSelect,
|
|
13
|
-
title: 'OutlinedSelect',
|
|
14
|
-
argTypes: {
|
|
15
|
-
color: {
|
|
16
|
-
type: { name: 'string', required: false },
|
|
17
|
-
description:
|
|
18
|
-
'The color of the component. It supports those theme colors that make sense for this component.',
|
|
19
|
-
table: {
|
|
20
|
-
type: { summary: 'primary | secondary' },
|
|
21
|
-
defaultValue: { summary: 'primary' },
|
|
22
|
-
},
|
|
23
|
-
options: ['primary', 'secondary'],
|
|
24
|
-
control: { type: 'radio' },
|
|
25
|
-
},
|
|
26
|
-
size: {
|
|
27
|
-
type: { name: 'string', required: false },
|
|
28
|
-
description: `Adjust size`,
|
|
29
|
-
table: {
|
|
30
|
-
type: { summary: 'medium | small' },
|
|
31
|
-
defaultValue: { summary: 'medium' },
|
|
32
|
-
},
|
|
33
|
-
options: ['small', 'medium'],
|
|
34
|
-
control: { type: 'radio' },
|
|
35
|
-
},
|
|
36
|
-
width: {
|
|
37
|
-
type: { name: 'number', required: false },
|
|
38
|
-
description: `Adjust width`,
|
|
39
|
-
table: {
|
|
40
|
-
type: { summary: 'number' },
|
|
41
|
-
defaultValue: { summary: 'auto' },
|
|
42
|
-
},
|
|
43
|
-
control: { type: 'number' },
|
|
44
|
-
},
|
|
45
|
-
paperMaxHeight: {
|
|
46
|
-
type: { name: 'number', required: false },
|
|
47
|
-
description: `Adjust select menu paper max height.`,
|
|
48
|
-
table: {
|
|
49
|
-
type: { summary: 'number' },
|
|
50
|
-
defaultValue: { summary: 'auto' },
|
|
51
|
-
},
|
|
52
|
-
control: { type: 'number' },
|
|
53
|
-
},
|
|
54
|
-
hasLabel: {
|
|
55
|
-
type: { name: 'boolean', required: false },
|
|
56
|
-
description: 'If true, the label is displayed.',
|
|
57
|
-
table: {
|
|
58
|
-
type: { summary: 'boolean' },
|
|
59
|
-
defaultValue: { summary: true },
|
|
60
|
-
},
|
|
61
|
-
control: { type: 'boolean' },
|
|
62
|
-
},
|
|
63
|
-
hasShrink: {
|
|
64
|
-
type: { name: 'boolean', required: false },
|
|
65
|
-
description: 'If true, the label is displayed and shrunk.',
|
|
66
|
-
table: {
|
|
67
|
-
type: { summary: 'boolean' },
|
|
68
|
-
defaultValue: { summary: false },
|
|
69
|
-
},
|
|
70
|
-
control: { type: 'boolean' },
|
|
71
|
-
},
|
|
72
|
-
placeholder: {
|
|
73
|
-
type: { name: 'string', required: true },
|
|
74
|
-
description: `The label title`,
|
|
75
|
-
table: {
|
|
76
|
-
type: { summary: 'string' },
|
|
77
|
-
defaultValue: { summary: '請選擇' },
|
|
78
|
-
},
|
|
79
|
-
control: { type: 'text' },
|
|
80
|
-
},
|
|
81
|
-
value: {
|
|
82
|
-
type: { name: 'any', required: false },
|
|
83
|
-
description: `The input value. Providing an empty string will select no options. This prop is required when the native prop is false (default). Set to an empty string '' if you don't want any of the available options to be selected.
|
|
84
|
-
If the value is an object it must have reference equality with the option in order to be selected. If the value is not an object, the string representation must match with the string representation of the option in order to be selected.`,
|
|
85
|
-
table: {
|
|
86
|
-
type: { summary: 'any' },
|
|
87
|
-
defaultValue: { summary: '' },
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
disabled: {
|
|
91
|
-
type: { name: 'boolean', required: false },
|
|
92
|
-
description: 'If true, the input element will be disabled.',
|
|
93
|
-
table: {
|
|
94
|
-
type: { summary: 'boolean' },
|
|
95
|
-
defaultValue: { summary: false },
|
|
96
|
-
},
|
|
97
|
-
control: { type: 'boolean' },
|
|
98
|
-
},
|
|
99
|
-
error: {
|
|
100
|
-
type: { name: 'boolean', required: false },
|
|
101
|
-
description: 'If true, the label will be displayed in an error state.',
|
|
102
|
-
table: {
|
|
103
|
-
type: { summary: 'boolean' },
|
|
104
|
-
defaultValue: { summary: false },
|
|
105
|
-
},
|
|
106
|
-
control: { type: 'boolean' },
|
|
107
|
-
},
|
|
108
|
-
helperText: {
|
|
109
|
-
type: { name: 'string', required: true },
|
|
110
|
-
description: `Display the helper text.`,
|
|
111
|
-
table: {
|
|
112
|
-
type: { summary: 'string' },
|
|
113
|
-
defaultValue: { summary: '' },
|
|
114
|
-
},
|
|
115
|
-
control: { type: 'text' },
|
|
116
|
-
},
|
|
117
|
-
SelectProps: {
|
|
118
|
-
type: { name: 'any', required: false },
|
|
119
|
-
description: 'Attributes applied to inner Select element.',
|
|
120
|
-
table: {
|
|
121
|
-
type: { summary: 'any' },
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
OutlinedInputProps: {
|
|
125
|
-
type: { name: 'any', required: false },
|
|
126
|
-
description: 'Attributes applied to to inner OutlinedInput element.',
|
|
127
|
-
table: {
|
|
128
|
-
type: { summary: 'any' },
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
} as Meta
|
|
133
|
-
|
|
134
|
-
const PREFIX = 'JuiOutlinedSelect'
|
|
135
|
-
|
|
136
|
-
const classes = {
|
|
137
|
-
outlineInputAdornmentRoot: `${PREFIX}-outlineInputAdornmentRoot`,
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
interface StyledInputAdornmentProps {
|
|
141
|
-
disabled: boolean
|
|
142
|
-
theme?: Theme
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const StyledInputAdornment = styled(({ disabled: _disabled, ...props }) => (
|
|
146
|
-
<InputAdornment
|
|
147
|
-
classes={{
|
|
148
|
-
root: classes.outlineInputAdornmentRoot,
|
|
149
|
-
}}
|
|
150
|
-
{...props}
|
|
151
|
-
/>
|
|
152
|
-
))(({ disabled, theme }: StyledInputAdornmentProps) => ({
|
|
153
|
-
[`&.${classes.outlineInputAdornmentRoot}`]: {
|
|
154
|
-
color: disabled
|
|
155
|
-
? theme.palette.action.disabled
|
|
156
|
-
: theme.palette.action.active,
|
|
157
|
-
},
|
|
158
|
-
}))
|
|
159
|
-
|
|
160
|
-
interface OutlinedSelectWithMenuProps {
|
|
161
|
-
startAdornment?: React.ReactNode
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const OutlinedSelectWithMenu = ({
|
|
165
|
-
startAdornment,
|
|
166
|
-
...props
|
|
167
|
-
}: OutlinedSelectProps & OutlinedSelectWithMenuProps) => {
|
|
168
|
-
const [item, setItem] = useState<string>('')
|
|
169
|
-
|
|
170
|
-
const handleChange = (event) => {
|
|
171
|
-
setItem(event.target.value)
|
|
172
|
-
}
|
|
173
|
-
return (
|
|
174
|
-
<OutlinedSelect
|
|
175
|
-
OutlinedInputProps={{
|
|
176
|
-
onChange: (e) => {
|
|
177
|
-
handleChange(e)
|
|
178
|
-
},
|
|
179
|
-
startAdornment,
|
|
180
|
-
}}
|
|
181
|
-
value={item}
|
|
182
|
-
{...props}
|
|
183
|
-
>
|
|
184
|
-
<SelectMenuItem width={220} value='' disabled>
|
|
185
|
-
{PLACEHOLDER}
|
|
186
|
-
</SelectMenuItem>
|
|
187
|
-
<SelectMenuItem width={220} value='Test'>
|
|
188
|
-
This is a select menu item
|
|
189
|
-
</SelectMenuItem>
|
|
190
|
-
<SelectMenuItem width={220} value='Example'>
|
|
191
|
-
Example
|
|
192
|
-
</SelectMenuItem>
|
|
193
|
-
</OutlinedSelect>
|
|
194
|
-
)
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
const ValueOnlyStory: Story<OutlinedSelectProps> = (args) => (
|
|
198
|
-
<OutlinedSelectWithMenu {...args} />
|
|
199
|
-
)
|
|
200
|
-
|
|
201
|
-
export const ValueOnly = ValueOnlyStory.bind({})
|
|
202
|
-
|
|
203
|
-
ValueOnly.args = {
|
|
204
|
-
color: 'primary',
|
|
205
|
-
size: 'medium',
|
|
206
|
-
width: 220,
|
|
207
|
-
paperMaxHeight: 412,
|
|
208
|
-
hasLabel: true,
|
|
209
|
-
placeholder: PLACEHOLDER,
|
|
210
|
-
helperText: 'test',
|
|
211
|
-
disabled: false,
|
|
212
|
-
SelectProps: {},
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
const WithPrefixStory: Story<OutlinedSelectProps> = (args) => (
|
|
216
|
-
<OutlinedSelectWithMenu
|
|
217
|
-
startAdornment={
|
|
218
|
-
<StyledInputAdornment position='start' disabled={args.disabled}>
|
|
219
|
-
<Visibility />
|
|
220
|
-
</StyledInputAdornment>
|
|
221
|
-
}
|
|
222
|
-
{...args}
|
|
223
|
-
/>
|
|
224
|
-
)
|
|
225
|
-
|
|
226
|
-
export const WithPrefix = WithPrefixStory.bind({})
|
|
227
|
-
|
|
228
|
-
WithPrefix.args = {
|
|
229
|
-
color: 'primary',
|
|
230
|
-
size: 'medium',
|
|
231
|
-
width: 220,
|
|
232
|
-
paperMaxHeight: 412,
|
|
233
|
-
hasLabel: true,
|
|
234
|
-
placeholder: PLACEHOLDER,
|
|
235
|
-
helperText: 'test',
|
|
236
|
-
disabled: false,
|
|
237
|
-
SelectProps: {},
|
|
238
|
-
}
|