@junyiacademy/ui-test 0.0.4 → 0.0.8

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 (31) hide show
  1. package/declarations/libs/ui/src/lib/selection-item/SelectionItem.d.ts +10 -0
  2. package/dist/libs/ui/src/lib/selection-item/SelectionItem.js +16 -0
  3. package/package.json +1 -1
  4. package/src/lib/TopicFilter.tsx +5 -14
  5. package/src/lib/menu-item/SelectMenuItem.tsx +5 -11
  6. package/src/lib/radio/Radio.stories.tsx +3 -2
  7. package/src/lib/select/OutlinedSelect.stories.tsx +79 -58
  8. package/src/lib/select/OutlinedSelect.tsx +34 -79
  9. package/src/lib/select/StandardSelect.stories.tsx +45 -29
  10. package/src/lib/select/StandardSelect.tsx +14 -50
  11. package/src/lib/text-field/TextField.stories.tsx +35 -1
  12. package/declarations/libs/ui/src/index.d.ts +0 -8
  13. package/declarations/libs/ui/src/interfaces/index.d.ts +0 -8
  14. package/declarations/libs/ui/src/lib/TopicFilter.d.ts +0 -13
  15. package/declarations/libs/ui/src/lib/button/Button.d.ts +0 -6
  16. package/declarations/libs/ui/src/lib/button-group/ButtonGroup.d.ts +0 -3
  17. package/declarations/libs/ui/src/lib/menu-item/SelectMenuItem.d.ts +0 -9
  18. package/declarations/libs/ui/src/lib/radio/Radio.d.ts +0 -10
  19. package/declarations/libs/ui/src/lib/select/OutlinedSelect.d.ts +0 -24
  20. package/declarations/libs/ui/src/lib/select/StandardSelect.d.ts +0 -20
  21. package/declarations/libs/ui/src/lib/text-field/TextField.d.ts +0 -3
  22. package/dist/libs/ui/src/index.js +0 -22
  23. package/dist/libs/ui/src/interfaces/index.js +0 -2
  24. package/dist/libs/ui/src/lib/TopicFilter.js +0 -123
  25. package/dist/libs/ui/src/lib/button/Button.js +0 -71
  26. package/dist/libs/ui/src/lib/button-group/ButtonGroup.js +0 -33
  27. package/dist/libs/ui/src/lib/menu-item/SelectMenuItem.js +0 -30
  28. package/dist/libs/ui/src/lib/radio/Radio.js +0 -43
  29. package/dist/libs/ui/src/lib/select/OutlinedSelect.js +0 -132
  30. package/dist/libs/ui/src/lib/select/StandardSelect.js +0 -105
  31. package/dist/libs/ui/src/lib/text-field/TextField.js +0 -75
@@ -1,5 +1,8 @@
1
1
  import React, { useState } from 'react'
2
2
  import { Story, Meta } from '@storybook/react'
3
+ import { Theme, styled } from '@material-ui/core/styles'
4
+ import { InputAdornment } from '@material-ui/core'
5
+ import { Visibility } from '@material-ui/icons'
3
6
  import { StandardSelect, StandardSelectProps } from './StandardSelect'
4
7
  import SelectMenuItem from '../menu-item/SelectMenuItem'
5
8
 
@@ -29,7 +32,6 @@ export default {
29
32
  },
30
33
  options: ['small', 'medium'],
31
34
  control: { type: 'radio' },
32
- defaultValue: 'medium',
33
35
  },
34
36
  width: {
35
37
  type: { name: 'number', required: false },
@@ -39,7 +41,6 @@ export default {
39
41
  defaultValue: { summary: 'auto' },
40
42
  },
41
43
  control: { type: 'number' },
42
- defaultValue: '220',
43
44
  },
44
45
  paperMaxHeight: {
45
46
  type: { name: 'number', required: false },
@@ -49,17 +50,15 @@ export default {
49
50
  defaultValue: { summary: 'auto' },
50
51
  },
51
52
  control: { type: 'number' },
52
- defaultValue: '412',
53
53
  },
54
54
  hasShrink: {
55
55
  type: { name: 'boolean', required: false },
56
- description: 'Control the label display state.',
56
+ description: 'If true, the label is displayed and shrunk.',
57
57
  table: {
58
58
  type: { summary: 'boolean' },
59
59
  defaultValue: { summary: true },
60
60
  },
61
61
  control: { type: 'boolean' },
62
- defaultValue: true,
63
62
  },
64
63
  placeholder: {
65
64
  type: { name: 'string', required: true },
@@ -69,7 +68,6 @@ export default {
69
68
  defaultValue: { summary: '請選擇' },
70
69
  },
71
70
  control: { type: 'text' },
72
- defaultValue: '請選擇',
73
71
  },
74
72
  value: {
75
73
  type: { name: 'any', required: false },
@@ -98,33 +96,21 @@ export default {
98
96
  },
99
97
  control: { type: 'boolean' },
100
98
  },
101
- hasHelperText: {
102
- type: { name: 'boolean', required: false },
103
- description: 'If true, the helper text will be displayed.',
104
- table: {
105
- type: { summary: 'boolean' },
106
- defaultValue: { summary: false },
107
- },
108
- control: { type: 'boolean' },
109
- },
110
99
  helperText: {
111
100
  type: { name: 'string', required: true },
112
- description: `The helper text.`,
101
+ description: `Display the helper text.`,
113
102
  table: {
114
103
  type: { summary: 'string' },
115
- defaultValue: { summary: 'Helper text.' },
104
+ defaultValue: { summary: '' },
116
105
  },
117
106
  control: { type: 'text' },
118
- defaultValue: 'Helper text.',
119
107
  },
120
- hasAdornment: {
121
- type: { name: 'boolean', required: false },
122
- description: 'If true, the prefix adornment will be displayed.',
108
+ InputProps: {
109
+ type: { name: 'any', required: false },
110
+ description: 'Attributes applied to inner Input element.',
123
111
  table: {
124
- type: { summary: 'boolean' },
125
- defaultValue: { summary: false },
112
+ type: { summary: 'any' },
126
113
  },
127
- control: { type: 'boolean' },
128
114
  },
129
115
  SelectProps: {
130
116
  type: { name: 'any', required: false },
@@ -136,6 +122,31 @@ export default {
136
122
  },
137
123
  } as Meta
138
124
 
125
+ const PREFIX = 'JuiStandardSelect'
126
+
127
+ const classes = {
128
+ inputAdornmentRoot: `${PREFIX}-inputAdornmentRoot`,
129
+ }
130
+ interface StyledInputAdornmentProps {
131
+ theme: Theme
132
+ disabled: boolean
133
+ }
134
+
135
+ const StyledInputAdornment = styled(({ disabled: _disabled, ...props }) => (
136
+ <InputAdornment
137
+ classes={{
138
+ root: classes.inputAdornmentRoot,
139
+ }}
140
+ {...props}
141
+ />
142
+ ))(({ disabled, theme }: StyledInputAdornmentProps) => ({
143
+ [`&.${classes.inputAdornmentRoot}`]: {
144
+ color: disabled
145
+ ? theme.palette.action.disabled
146
+ : theme.palette.action.active,
147
+ },
148
+ }))
149
+
139
150
  const StandardSelectWithMenu = (props: StandardSelectProps) => {
140
151
  const [item, setItem] = useState<string>('')
141
152
 
@@ -179,14 +190,21 @@ ValueOnly.args = {
179
190
  paperMaxHeight: 300,
180
191
  hasShrink: false,
181
192
  placeholder: PLACEHOLDER,
182
- hasHelperText: false,
183
193
  helperText: 'test',
184
- hasAdornment: false,
185
194
  disabled: false,
186
195
  }
187
196
 
188
197
  const WithPrefixStory: Story<StandardSelectProps> = (args) => (
189
- <StandardSelectWithMenu {...args} />
198
+ <StandardSelectWithMenu
199
+ InputProps={{
200
+ startAdornment: (
201
+ <StyledInputAdornment position='start' disabled={args.disabled}>
202
+ <Visibility />
203
+ </StyledInputAdornment>
204
+ ),
205
+ }}
206
+ {...args}
207
+ />
190
208
  )
191
209
 
192
210
  export const WithPrefix = WithPrefixStory.bind({})
@@ -198,8 +216,6 @@ WithPrefix.args = {
198
216
  paperMaxHeight: 300,
199
217
  hasShrink: false,
200
218
  placeholder: PLACEHOLDER,
201
- hasHelperText: false,
202
219
  helperText: 'test',
203
- hasAdornment: true,
204
220
  disabled: false,
205
221
  }
@@ -6,20 +6,18 @@ import {
6
6
  Select,
7
7
  SelectProps,
8
8
  Input,
9
+ InputProps,
9
10
  FormHelperText,
10
11
  InputAdornment,
11
12
  } from '@material-ui/core'
12
- import VisibilityIcon from '@material-ui/icons/Visibility'
13
13
 
14
14
  // self-defined-components
15
15
  const PREFIX = 'JuiStandardSelect'
16
16
 
17
17
  const classes = {
18
- inputLabelRoot: `${PREFIX}-inputLabel`,
19
18
  inputLabelFocused: `${PREFIX}-inputLabelFocused`,
20
19
  inputLabelMarginDense: `${PREFIX}-inputLabelMarginDense`,
21
20
  inputLabelError: `${PREFIX}-inputLabelError`,
22
- inputRoot: `${PREFIX}-inputRoot`,
23
21
  inputUnderline: `${PREFIX}-inputUnderline`,
24
22
  inputError: `${PREFIX}-inputError`,
25
23
  inputDisabled: `${PREFIX}-inputDisabled`,
@@ -49,22 +47,19 @@ interface StyledInputLabelProps {
49
47
  const StyledInputLabel = styled(({ color: _color, ...props }) => (
50
48
  <InputLabel
51
49
  classes={{
52
- root: classes.inputLabelRoot,
53
50
  focused: classes.inputLabelFocused,
54
51
  error: classes.inputLabelError,
55
52
  }}
56
53
  {...props}
57
54
  />
58
55
  ))(({ color, theme }: StyledInputLabelProps) => ({
59
- [`&.${classes.inputLabelRoot}`]: {
60
- color: theme.palette.text.disabled,
61
- margin: theme.spacing(0, 10, 1.5, 0),
62
- [`&.${classes.inputLabelFocused}`]: {
63
- color: theme.palette[color].main,
64
- },
65
- [`&.${classes.inputLabelError}`]: {
66
- color: theme.palette.error.main,
67
- },
56
+ color: theme.palette.text.disabled,
57
+ margin: theme.spacing(0, 10, 1.5, 0),
58
+ [`&.${classes.inputLabelFocused}`]: {
59
+ color: theme.palette[color].main,
60
+ },
61
+ [`&.${classes.inputLabelError}`]: {
62
+ color: theme.palette.error.main,
68
63
  },
69
64
  }))
70
65
 
@@ -109,16 +104,13 @@ const StyledInput = styled(({ color: _color, ...props }) => (
109
104
  <Input
110
105
  classes={{
111
106
  disabled: classes.inputDisabled,
112
- root: classes.inputRoot,
113
107
  underline: classes.inputUnderline,
114
108
  error: classes.inputError,
115
109
  }}
116
110
  {...props}
117
111
  />
118
112
  ))(({ color, theme }: StyledInputProps) => ({
119
- [`&.${classes.inputRoot}`]: {
120
- color: theme.palette.text.primary,
121
- },
113
+ color: theme.palette.text.primary,
122
114
  [`&.${classes.inputUnderline}:not(.${classes.inputDisabled}):not(.${classes.inputError})`]: {
123
115
  [`&:after,&:hover:before`]: {
124
116
  borderBottomColor: theme.palette[color].main,
@@ -131,23 +123,6 @@ const StyledInput = styled(({ color: _color, ...props }) => (
131
123
  },
132
124
  }))
133
125
 
134
- interface StyledInputAdornmentProps {
135
- theme: Theme
136
- }
137
-
138
- const StyledInputAdornment = styled((props) => (
139
- <InputAdornment
140
- classes={{
141
- root: classes.inputAdornmentRoot,
142
- }}
143
- {...props}
144
- />
145
- ))(({ theme }: StyledInputAdornmentProps) => ({
146
- [`&.${classes.inputAdornmentRoot}`]: {
147
- color: theme.palette.action.active,
148
- },
149
- }))
150
-
151
126
  export interface StandardSelectProps {
152
127
  color?: 'primary' | 'secondary'
153
128
  size?: 'medium' | 'small'
@@ -156,9 +131,8 @@ export interface StandardSelectProps {
156
131
  error?: boolean
157
132
  hasShrink?: boolean
158
133
  placeholder: string
159
- hasHelperText?: boolean
160
134
  helperText?: string
161
- hasAdornment?: boolean
135
+ InputProps?: object & Partial<InputProps>
162
136
  value?: unknown
163
137
  disabled?: boolean
164
138
  SelectProps?: object | Partial<SelectProps>
@@ -173,14 +147,15 @@ export function StandardSelect({
173
147
  error = false,
174
148
  hasShrink = false,
175
149
  placeholder,
176
- hasHelperText = false,
177
150
  helperText,
178
- hasAdornment = false,
151
+ InputProps,
179
152
  value = '',
180
153
  SelectProps,
181
154
  disabled = false,
182
155
  children,
183
156
  }: StandardSelectProps) {
157
+ const hasAdornment = !!InputProps?.startAdornment
158
+ const hasHelperText = !!helperText
184
159
  return (
185
160
  <StyledFormControl
186
161
  color={color}
@@ -200,18 +175,7 @@ export function StandardSelect({
200
175
  value={value}
201
176
  paperMaxHeight={paperMaxHeight}
202
177
  hasAdornment={hasAdornment}
203
- input={
204
- <StyledInput
205
- color={color}
206
- startAdornment={
207
- hasAdornment && (
208
- <StyledInputAdornment position='start'>
209
- <VisibilityIcon />
210
- </StyledInputAdornment>
211
- )
212
- }
213
- />
214
- }
178
+ input={<StyledInput color={color} {...InputProps} />}
215
179
  {...SelectProps}
216
180
  >
217
181
  {children}
@@ -1,4 +1,4 @@
1
- import React from 'react'
1
+ import React, { useEffect } from 'react'
2
2
  import { Story, Meta } from '@storybook/react'
3
3
  import { InputAdornment, TextFieldProps } from '@material-ui/core'
4
4
  import { Visibility } from '@material-ui/icons'
@@ -77,6 +77,40 @@ ValueOnly.args = {
77
77
  label: 'Which UI?',
78
78
  }
79
79
 
80
+ const TextFieldWithError = (props: TextFieldProps) => {
81
+ const [value, setValue] = React.useState('')
82
+ const [isError, setIsError] = React.useState(false)
83
+
84
+ const handleChange = (event) => {
85
+ setValue(event.target.value)
86
+ }
87
+
88
+ useEffect(() => {
89
+ if (value.length > 3) {
90
+ setIsError(true)
91
+ return
92
+ }
93
+ setIsError(false)
94
+ return
95
+ }, [value])
96
+
97
+ return <TextField error={isError} onChange={handleChange} {...props} />
98
+ }
99
+
100
+ const WithErrorStory: Story<TextFieldProps> = (args) => (
101
+ <TextFieldWithError {...args} />
102
+ )
103
+
104
+ export const WithError = WithErrorStory.bind({})
105
+
106
+ WithError.args = {
107
+ variant: 'standard',
108
+ color: 'primary',
109
+ disabled: false,
110
+ size: 'small',
111
+ label: 'No more than 3 words',
112
+ }
113
+
80
114
  const WithSuffixStory: Story<TextFieldProps> = (args) => (
81
115
  <TextField
82
116
  {...args}
@@ -1,8 +0,0 @@
1
- export { default as TopicFilter } from './lib/TopicFilter';
2
- export { default as SelectMenuItem } from './lib/menu-item/SelectMenuItem';
3
- export { default as OutlinedSelect } from './lib/select/OutlinedSelect';
4
- export { default as Button } from './lib/button/Button';
5
- export { default as ButtonGroup } from './lib/button-group/ButtonGroup';
6
- export { default as Radio } from './lib/radio/Radio';
7
- export { default as TextField } from './lib/text-field/TextField';
8
- export { default as StandardSelect } from './lib/select/StandardSelect';
@@ -1,8 +0,0 @@
1
- export interface ITopicTreeNode {
2
- childTopics: ITopicTreeNode[];
3
- id: string;
4
- isContentTopic: boolean;
5
- key: string;
6
- tags: string[];
7
- title: string;
8
- }
@@ -1,13 +0,0 @@
1
- import type { ITopicTreeNode } from '../interfaces';
2
- export interface TopicFilterProps {
3
- topicTree: ITopicTreeNode;
4
- onTopicSelected: (topic: ITopicTreeNode, selectedInfo: {
5
- layerNumber: number;
6
- selectedTopicIds: string[];
7
- }) => void;
8
- isLastLayer: (topic: ITopicTreeNode) => boolean;
9
- hasArrow: boolean;
10
- initSelectedTopicIds: string[];
11
- }
12
- declare const TopicFilter: ({ topicTree, onTopicSelected, isLastLayer, hasArrow, initSelectedTopicIds, }: TopicFilterProps) => JSX.Element;
13
- export default TopicFilter;
@@ -1,6 +0,0 @@
1
- import { ButtonProps as MuiButtonProps } from '@material-ui/core';
2
- export interface ButtonProps extends MuiButtonProps {
3
- active?: boolean;
4
- }
5
- export declare const Button: ({ active, children, ...otherProps }: ButtonProps) => JSX.Element;
6
- export default Button;
@@ -1,3 +0,0 @@
1
- import { ButtonGroupProps as MuiButtonGroupProps } from '@material-ui/core';
2
- export declare const ButtonGroup: ({ children, ...otherProps }: MuiButtonGroupProps) => JSX.Element;
3
- export default ButtonGroup;
@@ -1,9 +0,0 @@
1
- import React from 'react';
2
- import { MenuItemProps } from '@material-ui/core';
3
- export interface SelectMenuItemProps extends MenuItemProps {
4
- width: number | 'auto';
5
- value?: any;
6
- disabled?: boolean;
7
- }
8
- declare const SelectMenuItem: React.ForwardRefExoticComponent<Pick<React.PropsWithChildren<SelectMenuItemProps>, "button" | "slot" | "style" | "title" | "color" | "width" | "alignItems" | "translate" | "hidden" | "dense" | "disabled" | "classes" | "className" | "children" | "placeholder" | "value" | "innerRef" | "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "id" | "lang" | "spellCheck" | "tabIndex" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "autoFocus" | "selected" | "ContainerComponent" | "ContainerProps" | "disableGutters" | "divider" | "focusVisibleClassName"> & React.RefAttributes<HTMLLIElement>>;
9
- export default SelectMenuItem;
@@ -1,10 +0,0 @@
1
- import { RadioProps as MuiRadioProps, FormControlLabelProps } from '@material-ui/core';
2
- export interface RadioProps extends FormControlLabelProps {
3
- color?: 'primary' | 'secondary' | 'default';
4
- size?: 'medium' | 'small';
5
- caption?: string;
6
- formControlLabelProps?: Partial<FormControlLabelProps>;
7
- radioProps?: Partial<MuiRadioProps>;
8
- }
9
- export declare const Radio: ({ checked, disabled, label, labelPlacement, value, formControlLabelProps, radioProps, color, size, caption, }: RadioProps) => JSX.Element;
10
- export default Radio;
@@ -1,24 +0,0 @@
1
- import React, { ChangeEvent } from 'react';
2
- import { SelectProps, OutlinedInputProps } from '@material-ui/core';
3
- export interface OutlinedSelectProps {
4
- color?: 'primary' | 'secondary';
5
- size?: 'medium' | 'small';
6
- width?: number | 'auto';
7
- selectPaperMaxHeight?: number | 'auto';
8
- error?: boolean;
9
- hasLabel?: boolean;
10
- hasShrink?: boolean;
11
- placeholder: string;
12
- hasHelperText?: boolean;
13
- helperText?: string;
14
- hasAdornment?: boolean;
15
- value?: unknown;
16
- disabled?: boolean;
17
- SelectProps?: object | Partial<SelectProps>;
18
- OutlinedInputProps?: Partial<OutlinedInputProps> & {
19
- onChange: (e: ChangeEvent<HTMLInputElement>) => void;
20
- };
21
- children?: React.ReactNode;
22
- }
23
- declare const OutlinedSelect: ({ color, size, width, selectPaperMaxHeight, error, hasLabel, hasShrink, placeholder, hasHelperText, helperText, hasAdornment, value, disabled, SelectProps, OutlinedInputProps, children, }: OutlinedSelectProps) => JSX.Element;
24
- export default OutlinedSelect;
@@ -1,20 +0,0 @@
1
- import React from 'react';
2
- import { SelectProps } from '@material-ui/core';
3
- export interface StandardSelectProps {
4
- color?: 'primary' | 'secondary';
5
- size?: 'medium' | 'small';
6
- width?: number | 'auto';
7
- paperMaxHeight?: number | 'auto';
8
- error?: boolean;
9
- hasShrink?: boolean;
10
- placeholder: string;
11
- hasHelperText?: boolean;
12
- helperText?: string;
13
- hasAdornment?: boolean;
14
- value?: unknown;
15
- disabled?: boolean;
16
- SelectProps?: object | Partial<SelectProps>;
17
- children?: React.ReactNode;
18
- }
19
- export declare function StandardSelect({ color, size, width, paperMaxHeight, error, hasShrink, placeholder, hasHelperText, helperText, hasAdornment, value, SelectProps, disabled, children, }: StandardSelectProps): JSX.Element;
20
- export default StandardSelect;
@@ -1,3 +0,0 @@
1
- import { TextFieldProps } from '@material-ui/core';
2
- export declare const TextField: (props: TextFieldProps) => JSX.Element;
3
- export default TextField;
@@ -1,22 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.StandardSelect = exports.TextField = exports.Radio = exports.ButtonGroup = exports.Button = exports.OutlinedSelect = exports.SelectMenuItem = exports.TopicFilter = void 0;
7
- var TopicFilter_1 = require("./lib/TopicFilter");
8
- Object.defineProperty(exports, "TopicFilter", { enumerable: true, get: function () { return __importDefault(TopicFilter_1).default; } });
9
- var SelectMenuItem_1 = require("./lib/menu-item/SelectMenuItem");
10
- Object.defineProperty(exports, "SelectMenuItem", { enumerable: true, get: function () { return __importDefault(SelectMenuItem_1).default; } });
11
- var OutlinedSelect_1 = require("./lib/select/OutlinedSelect");
12
- Object.defineProperty(exports, "OutlinedSelect", { enumerable: true, get: function () { return __importDefault(OutlinedSelect_1).default; } });
13
- var Button_1 = require("./lib/button/Button");
14
- Object.defineProperty(exports, "Button", { enumerable: true, get: function () { return __importDefault(Button_1).default; } });
15
- var ButtonGroup_1 = require("./lib/button-group/ButtonGroup");
16
- Object.defineProperty(exports, "ButtonGroup", { enumerable: true, get: function () { return __importDefault(ButtonGroup_1).default; } });
17
- var Radio_1 = require("./lib/radio/Radio");
18
- Object.defineProperty(exports, "Radio", { enumerable: true, get: function () { return __importDefault(Radio_1).default; } });
19
- var TextField_1 = require("./lib/text-field/TextField");
20
- Object.defineProperty(exports, "TextField", { enumerable: true, get: function () { return __importDefault(TextField_1).default; } });
21
- var StandardSelect_1 = require("./lib/select/StandardSelect");
22
- Object.defineProperty(exports, "StandardSelect", { enumerable: true, get: function () { return __importDefault(StandardSelect_1).default; } });
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,123 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- const react_1 = tslib_1.__importStar(require("react"));
5
- const styles_1 = require("@material-ui/core/styles");
6
- const ArrowRightRounded_1 = tslib_1.__importDefault(require("@material-ui/icons/ArrowRightRounded"));
7
- const OutlinedSelect_1 = tslib_1.__importDefault(require("./select/OutlinedSelect"));
8
- const SelectMenuItem_1 = tslib_1.__importDefault(require("./menu-item/SelectMenuItem"));
9
- // self-defined-configs
10
- const PLACEHOLDER = '請選擇';
11
- // self-defined-components
12
- const PREFIX = 'JuiTopicFilter';
13
- const classes = {
14
- root: `${PREFIX}-arrowIcon`,
15
- };
16
- const FiltersWrapper = styles_1.styled('div')({
17
- display: 'flex',
18
- alignItems: 'center',
19
- flexWrap: 'wrap',
20
- });
21
- const SelectWrapper = styles_1.styled('div')({
22
- display: 'flex',
23
- alignItems: 'center',
24
- });
25
- const StyledArrowRightRoundedIcon = styles_1.styled((props) => (react_1.default.createElement(ArrowRightRounded_1.default, Object.assign({ classes: classes }, props))))(({ theme }) => ({
26
- [`&.${classes.root}`]: {
27
- margin: theme.spacing(-1, -1.5),
28
- fontSize: theme.spacing(7),
29
- color: '#444',
30
- },
31
- }));
32
- const TopicFilter = ({ topicTree, onTopicSelected, isLastLayer, hasArrow, initSelectedTopicIds, }) => {
33
- const [selectedTopicIds, setSelectedTopicIds] = react_1.useState([]);
34
- const [layeredTopicList, setLayeredTopicList] = react_1.useState([]);
35
- const [isFocusedList, setIsFocusedList] = react_1.useState([]);
36
- const initSelectedLayers = () => {
37
- const newLayeredTopicList = initSelectedTopicIds.reduce((topicListAccumulator, topicId, index) => {
38
- var _a, _b;
39
- const selectedTopic = (_b = (_a = topicListAccumulator[index]) === null || _a === void 0 ? void 0 : _a.childTopics) === null || _b === void 0 ? void 0 : _b.find((childTopic) => childTopic.id === topicId);
40
- if (!selectedTopic) {
41
- return topicListAccumulator;
42
- }
43
- if (isLastLayer(selectedTopic)) {
44
- return topicListAccumulator;
45
- }
46
- return [...topicListAccumulator, selectedTopic];
47
- }, [topicTree]);
48
- setLayeredTopicList(newLayeredTopicList);
49
- setSelectedTopicIds(initSelectedTopicIds.slice(0, newLayeredTopicList.length));
50
- setIsFocusedList(Array(newLayeredTopicList.length).fill(false));
51
- };
52
- const handleChange = (e, layerNumber, layeredTopic) => {
53
- const selectedTopic = layeredTopic.childTopics.find((childTopic) => childTopic.id === e.target.value);
54
- const newSelectedTopicIds = [
55
- ...selectedTopicIds.slice(0, layerNumber),
56
- selectedTopic.id,
57
- ];
58
- setSelectedTopicIds(newSelectedTopicIds);
59
- onTopicSelected(selectedTopic, {
60
- layerNumber,
61
- selectedTopicIds: newSelectedTopicIds,
62
- });
63
- if (isLastLayer(selectedTopic)) {
64
- setLayeredTopicList((prevTopicList) => prevTopicList.slice(0, layerNumber + 1));
65
- setIsFocusedList((prevList) => prevList.slice(0, layerNumber + 1));
66
- }
67
- else {
68
- setLayeredTopicList((prevTopicList) => [
69
- ...prevTopicList.slice(0, layerNumber + 1),
70
- selectedTopic,
71
- ]);
72
- setIsFocusedList((prevList) => [
73
- ...prevList.slice(0, layerNumber + 1),
74
- false,
75
- ]);
76
- }
77
- };
78
- react_1.useEffect(() => {
79
- if (!topicTree || Object.keys(topicTree).length === 0) {
80
- return;
81
- }
82
- if (initSelectedTopicIds.length !== 0) {
83
- initSelectedLayers();
84
- return;
85
- }
86
- setLayeredTopicList([topicTree]);
87
- }, [topicTree]);
88
- if (layeredTopicList.length === 0) {
89
- return (react_1.default.createElement(OutlinedSelect_1.default, { size: 'small', width: 220, placeholder: '\u8F09\u5165\u8CC7\u6599\u4E2D...', disabled: true }));
90
- }
91
- return (react_1.default.createElement(FiltersWrapper, null, layeredTopicList.map((layeredTopic, layerNumber) => {
92
- const hasLabel = isFocusedList[layerNumber] || !selectedTopicIds[layerNumber];
93
- return (react_1.default.createElement(SelectWrapper, { key: layeredTopic.id },
94
- react_1.default.createElement(OutlinedSelect_1.default, { size: 'small', width: 220, selectPaperMaxHeight: 412, error: false, hasLabel: hasLabel, hasShrink: false, placeholder: PLACEHOLDER, hasAdornment: false, value: (selectedTopicIds === null || selectedTopicIds === void 0 ? void 0 : selectedTopicIds[layerNumber]) || '', SelectProps: {
95
- 'data-testid': `layered-topic-${layerNumber}`,
96
- }, OutlinedInputProps: {
97
- inputProps: {
98
- 'aria-label': `layered-topic-${layerNumber}`,
99
- },
100
- onChange: (e) => {
101
- handleChange(e, layerNumber, layeredTopic);
102
- },
103
- onFocus: () => {
104
- setIsFocusedList((prevList) => {
105
- const newList = [...prevList];
106
- newList[layerNumber] = true;
107
- return newList;
108
- });
109
- },
110
- onBlur: () => {
111
- setIsFocusedList((prevList) => {
112
- const newList = [...prevList];
113
- newList[layerNumber] = false;
114
- return newList;
115
- });
116
- },
117
- } },
118
- react_1.default.createElement(SelectMenuItem_1.default, { width: 220, disabled: true }, PLACEHOLDER),
119
- layeredTopic.childTopics.map((childTopic) => (react_1.default.createElement(SelectMenuItem_1.default, { width: 220, key: childTopic.id, value: childTopic.id, "data-testid": `layered-menuitem-${layerNumber}`, "data-is-content-topic": childTopic.isContentTopic }, childTopic.title)))),
120
- hasArrow && layerNumber !== layeredTopicList.length - 1 && (react_1.default.createElement(StyledArrowRightRoundedIcon, { fontSize: 'large', "data-testid": 'topic-filter-arrow' }))));
121
- })));
122
- };
123
- exports.default = TopicFilter;