@junyiacademy/ui-test 0.0.11 → 0.0.12
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 +1 -1
- package/declarations/libs/ui/src/interfaces/index.d.ts +18 -0
- 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 +1 -1
- package/dist/libs/ui/src/lib/select/OutlinedSelect.js +22 -5
- package/dist/libs/ui/src/lib/select/Select.js +16 -0
- package/dist/libs/ui/src/lib/select/StandardSelect.js +14 -0
- package/dist/libs/ui/src/lib/topic-filter/TopicFilter.js +120 -0
- package/package.json +1 -1
- package/src/index.ts +1 -1
- package/src/interfaces/index.tsx +25 -0
- package/src/lib/select/OutlinedSelect.tsx +24 -27
- package/src/lib/select/{OutlinedSelect.stories.tsx → Select.stories.tsx} +211 -28
- package/src/lib/select/Select.tsx +13 -0
- package/src/lib/select/StandardSelect.tsx +16 -18
- package/src/lib/{TopicFilter.stories.tsx → topic-filter/TopicFilter.stories.tsx} +1 -1
- package/src/lib/{TopicFilter.tsx → topic-filter/TopicFilter.tsx} +4 -4
- 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/StandardSelect.stories.tsx +0 -221
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { default as TopicFilter } from './lib/TopicFilter';
|
|
1
|
+
export { default as TopicFilter } from './lib/topic-filter/TopicFilter';
|
|
2
2
|
export { default as SelectMenuItem } from './lib/menu-item/SelectMenuItem';
|
|
3
3
|
export { default as OutlinedSelect } from './lib/select/OutlinedSelect';
|
|
4
4
|
export { default as Button } from './lib/button/Button';
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ChangeEvent } from 'react';
|
|
2
|
+
import { SelectProps as MuiSelectProp, InputProps as MuiInputProps, OutlinedInputProps } from '@material-ui/core';
|
|
1
3
|
export interface ITopicTreeNode {
|
|
2
4
|
childTopics: ITopicTreeNode[];
|
|
3
5
|
id: string;
|
|
@@ -6,3 +8,19 @@ export interface ITopicTreeNode {
|
|
|
6
8
|
tags: string[];
|
|
7
9
|
title: string;
|
|
8
10
|
}
|
|
11
|
+
export interface SelectProps extends MuiSelectProp {
|
|
12
|
+
placeholder: string;
|
|
13
|
+
helperText?: string;
|
|
14
|
+
InputProps?: (Partial<OutlinedInputProps> & {
|
|
15
|
+
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
16
|
+
}) | (object & Partial<MuiInputProps>);
|
|
17
|
+
SelectProps?: object | Partial<MuiSelectProp>;
|
|
18
|
+
color?: 'primary' | 'secondary';
|
|
19
|
+
size?: 'medium' | 'small';
|
|
20
|
+
width?: number | 'auto';
|
|
21
|
+
paperMaxHeight?: number | 'auto';
|
|
22
|
+
error?: boolean;
|
|
23
|
+
hasLabel?: boolean;
|
|
24
|
+
hasShrink?: boolean;
|
|
25
|
+
disabled?: boolean;
|
|
26
|
+
}
|
|
@@ -5,5 +5,5 @@ export interface SelectMenuItemProps extends MenuItemProps {
|
|
|
5
5
|
value?: any;
|
|
6
6
|
disabled?: boolean;
|
|
7
7
|
}
|
|
8
|
-
declare const SelectMenuItem: React.ForwardRefExoticComponent<Pick<React.PropsWithChildren<SelectMenuItemProps>, "
|
|
8
|
+
declare const SelectMenuItem: React.ForwardRefExoticComponent<Pick<React.PropsWithChildren<SelectMenuItemProps>, "classes" | "disabled" | "value" | "onChange" | "children" | "onKeyUp" | "onKeyDown" | "onBlur" | "onFocus" | "defaultValue" | "defaultChecked" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "id" | "lang" | "placeholder" | "slot" | "spellCheck" | "style" | "tabIndex" | "title" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "color" | "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" | "onFocusCapture" | "onBlurCapture" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "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" | "innerRef" | "button" | "width" | "alignItems" | "dense" | "key" | "selected" | "ContainerComponent" | "ContainerProps" | "disableGutters" | "divider" | "focusVisibleClassName"> & React.RefAttributes<HTMLLIElement>>;
|
|
9
9
|
export default SelectMenuItem;
|
|
@@ -1,20 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export interface OutlinedSelectProps extends SelectProps {
|
|
4
|
-
color?: 'primary' | 'secondary';
|
|
5
|
-
size?: 'medium' | 'small';
|
|
6
|
-
width?: number | 'auto';
|
|
7
|
-
paperMaxHeight?: number | 'auto';
|
|
8
|
-
error?: boolean;
|
|
9
|
-
hasLabel?: boolean;
|
|
10
|
-
hasShrink?: boolean;
|
|
11
|
-
placeholder: string;
|
|
12
|
-
helperText?: string;
|
|
13
|
-
disabled?: boolean;
|
|
14
|
-
SelectProps?: object | Partial<SelectProps>;
|
|
15
|
-
OutlinedInputProps?: Partial<OutlinedInputProps> & {
|
|
16
|
-
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
declare const OutlinedSelect: ({ placeholder, SelectProps, OutlinedInputProps, children, color, size, width, paperMaxHeight, error, hasLabel, hasShrink, helperText, value, disabled, }: OutlinedSelectProps) => JSX.Element;
|
|
1
|
+
import { SelectProps } from '../../interfaces';
|
|
2
|
+
export declare const OutlinedSelect: ({ placeholder, helperText, InputProps, SelectProps, children, color, size, width, paperMaxHeight, error, hasLabel, hasShrink, value, disabled, }: SelectProps) => JSX.Element;
|
|
20
3
|
export default OutlinedSelect;
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
import { SelectProps
|
|
2
|
-
export
|
|
3
|
-
color?: 'primary' | 'secondary';
|
|
4
|
-
size?: 'medium' | 'small';
|
|
5
|
-
width?: number | 'auto';
|
|
6
|
-
paperMaxHeight?: number | 'auto';
|
|
7
|
-
error?: boolean;
|
|
8
|
-
hasShrink?: boolean;
|
|
9
|
-
placeholder: string;
|
|
10
|
-
helperText?: string;
|
|
11
|
-
InputProps?: object & Partial<InputProps>;
|
|
12
|
-
disabled?: boolean;
|
|
13
|
-
SelectProps?: object | Partial<SelectProps>;
|
|
14
|
-
}
|
|
15
|
-
export declare function StandardSelect({ placeholder, helperText, InputProps, SelectProps, children, color, size, width, paperMaxHeight, error, hasShrink, value, disabled, }: StandardSelectProps): JSX.Element;
|
|
1
|
+
import { SelectProps } from '../../interfaces';
|
|
2
|
+
export declare function StandardSelect({ placeholder, helperText, InputProps, SelectProps, children, color, size, width, paperMaxHeight, error, hasShrink, value, disabled, }: SelectProps): JSX.Element;
|
|
16
3
|
export default StandardSelect;
|
|
@@ -0,0 +1,13 @@
|
|
|
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
|
+
export declare const TopicFilter: ({ topicTree, onTopicSelected, isLastLayer, hasArrow, initSelectedTopicIds, }: TopicFilterProps) => JSX.Element;
|
|
13
|
+
export default TopicFilter;
|
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
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");
|
|
7
|
+
var TopicFilter_1 = require("./lib/topic-filter/TopicFilter");
|
|
8
8
|
Object.defineProperty(exports, "TopicFilter", { enumerable: true, get: function () { return __importDefault(TopicFilter_1).default; } });
|
|
9
9
|
var SelectMenuItem_1 = require("./lib/menu-item/SelectMenuItem");
|
|
10
10
|
Object.defineProperty(exports, "SelectMenuItem", { enumerable: true, get: function () { return __importDefault(SelectMenuItem_1).default; } });
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OutlinedSelect = void 0;
|
|
3
4
|
const tslib_1 = require("tslib");
|
|
4
5
|
const react_1 = tslib_1.__importDefault(require("react"));
|
|
5
6
|
const styles_1 = require("@material-ui/core/styles");
|
|
@@ -14,10 +15,12 @@ const classes = {
|
|
|
14
15
|
inputLabelError: `${PREFIX}-inputLabelError`,
|
|
15
16
|
inputLabelDisabled: `${PREFIX}-inputLabelDisabled`,
|
|
16
17
|
outlineInputInput: `${PREFIX}-input`,
|
|
18
|
+
outlineInputRoot: `${PREFIX}-inputRoot`,
|
|
17
19
|
outlineInputInputMarginDense: `${PREFIX}-inputMarginDense`,
|
|
18
20
|
outlineInputNotchedOutline: `${PREFIX}-notchedOutline`,
|
|
19
21
|
outlineInputDisabled: `${PREFIX}-inputDisabled`,
|
|
20
22
|
outlineInputError: `${PREFIX}-outlinedInputError`,
|
|
23
|
+
outlineInputFocused: `${PREFIX}-focused`,
|
|
21
24
|
selectPaper: `${PREFIX}-menuPaper`,
|
|
22
25
|
};
|
|
23
26
|
const StyledFormControl = styles_1.styled((_a) => {
|
|
@@ -32,6 +35,9 @@ const StyledFormControl = styles_1.styled((_a) => {
|
|
|
32
35
|
borderColor: theme.palette[color].main,
|
|
33
36
|
},
|
|
34
37
|
},
|
|
38
|
+
[`& .${classes.outlineInputError}.${classes.outlineInputFocused} .${classes.outlineInputNotchedOutline}`]: {
|
|
39
|
+
borderColor: `${theme.palette.error.main}`,
|
|
40
|
+
},
|
|
35
41
|
}));
|
|
36
42
|
const StyledInputLabel = styles_1.styled((_a) => {
|
|
37
43
|
var { color: _color } = _a, props = tslib_1.__rest(_a, ["color"]);
|
|
@@ -62,14 +68,22 @@ const StyledInputLabel = styles_1.styled((_a) => {
|
|
|
62
68
|
},
|
|
63
69
|
}));
|
|
64
70
|
const StyledOutlinedInput = styles_1.styled((props) => (react_1.default.createElement(core_1.OutlinedInput, Object.assign({ classes: {
|
|
71
|
+
root: classes.outlineInputRoot,
|
|
72
|
+
focused: classes.outlineInputFocused,
|
|
65
73
|
input: classes.outlineInputInput,
|
|
66
74
|
inputMarginDense: classes.outlineInputInputMarginDense,
|
|
67
75
|
notchedOutline: classes.outlineInputNotchedOutline,
|
|
68
76
|
disabled: classes.outlineInputDisabled,
|
|
69
77
|
error: classes.outlineInputError,
|
|
70
78
|
} }, props))))(({ theme }) => ({
|
|
79
|
+
[`&.${classes.outlineInputRoot}.${classes.outlineInputFocused}`]: {
|
|
80
|
+
backgroundColor: theme.palette.action.selected,
|
|
81
|
+
},
|
|
71
82
|
[`& .${classes.outlineInputInput}`]: {
|
|
72
83
|
color: theme.palette.text.primary,
|
|
84
|
+
['&:focus']: {
|
|
85
|
+
background: 'rgba(0,0,0,0)',
|
|
86
|
+
},
|
|
73
87
|
},
|
|
74
88
|
[`& .${classes.outlineInputInputMarginDense}`]: {
|
|
75
89
|
padding: '14.5px 15px 14.5px 12px',
|
|
@@ -88,7 +102,9 @@ const StyledSelect = styles_1.styled((_a) => {
|
|
|
88
102
|
horizontal: 'left',
|
|
89
103
|
},
|
|
90
104
|
getContentAnchorEl: null,
|
|
91
|
-
classes: {
|
|
105
|
+
classes: {
|
|
106
|
+
paper: className,
|
|
107
|
+
},
|
|
92
108
|
} }, props)));
|
|
93
109
|
})(({ hasAdornment, paperMaxHeight }) => ({
|
|
94
110
|
'&': {
|
|
@@ -96,12 +112,13 @@ const StyledSelect = styles_1.styled((_a) => {
|
|
|
96
112
|
left: hasAdornment ? '24px !important' : '70px',
|
|
97
113
|
},
|
|
98
114
|
}));
|
|
99
|
-
const OutlinedSelect = ({ placeholder,
|
|
100
|
-
const hasAdornment = !!(
|
|
115
|
+
const OutlinedSelect = ({ placeholder, helperText, InputProps, SelectProps, children, color = 'primary', size = 'medium', width = 'auto', paperMaxHeight = 'auto', error = false, hasLabel = true, hasShrink = false, value = '', disabled = false, }) => {
|
|
116
|
+
const hasAdornment = !!(InputProps === null || InputProps === void 0 ? void 0 : InputProps.startAdornment);
|
|
101
117
|
const hasHelperText = !!helperText;
|
|
102
118
|
return (react_1.default.createElement(StyledFormControl, { size: size, width: width, disabled: disabled, error: error, color: color },
|
|
103
119
|
hasLabel && (react_1.default.createElement(StyledInputLabel, { color: color, variant: 'outlined', shrink: hasShrink ? true : undefined }, placeholder)),
|
|
104
|
-
react_1.default.createElement(StyledSelect, Object.assign({ value: value, paperMaxHeight: paperMaxHeight, hasAdornment: hasAdornment, input: react_1.default.createElement(StyledOutlinedInput, Object.assign({ color: color, label: hasLabel ? placeholder : undefined, disabled: disabled },
|
|
120
|
+
react_1.default.createElement(StyledSelect, Object.assign({ value: value, paperMaxHeight: paperMaxHeight, hasAdornment: hasAdornment, input: react_1.default.createElement(StyledOutlinedInput, Object.assign({ color: color, label: hasLabel ? placeholder : undefined, disabled: disabled }, InputProps)) }, SelectProps), children),
|
|
105
121
|
hasHelperText && react_1.default.createElement(core_1.FormHelperText, null, helperText)));
|
|
106
122
|
};
|
|
107
|
-
exports.
|
|
123
|
+
exports.OutlinedSelect = OutlinedSelect;
|
|
124
|
+
exports.default = exports.OutlinedSelect;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Select = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
|
+
const OutlinedSelect_1 = require("./OutlinedSelect");
|
|
7
|
+
const StandardSelect_1 = require("./StandardSelect");
|
|
8
|
+
function Select(_a) {
|
|
9
|
+
var { variant } = _a, props = tslib_1.__rest(_a, ["variant"]);
|
|
10
|
+
if (variant === 'outlined') {
|
|
11
|
+
return react_1.default.createElement(OutlinedSelect_1.OutlinedSelect, Object.assign({}, props));
|
|
12
|
+
}
|
|
13
|
+
return react_1.default.createElement(StandardSelect_1.StandardSelect, Object.assign({}, props));
|
|
14
|
+
}
|
|
15
|
+
exports.Select = Select;
|
|
16
|
+
exports.default = Select;
|
|
@@ -11,6 +11,9 @@ const classes = {
|
|
|
11
11
|
inputLabelFocused: `${PREFIX}-inputLabelFocused`,
|
|
12
12
|
inputLabelMarginDense: `${PREFIX}-inputLabelMarginDense`,
|
|
13
13
|
inputLabelError: `${PREFIX}-inputLabelError`,
|
|
14
|
+
inputRoot: `${PREFIX}-inputRoot`,
|
|
15
|
+
inputFocused: `${PREFIX}-inputFocused`,
|
|
16
|
+
inputInput: `${PREFIX}-input`,
|
|
14
17
|
inputUnderline: `${PREFIX}-inputUnderline`,
|
|
15
18
|
inputError: `${PREFIX}-inputError`,
|
|
16
19
|
inputDisabled: `${PREFIX}-inputDisabled`,
|
|
@@ -60,12 +63,23 @@ const StyledSelect = styles_1.styled((_a) => {
|
|
|
60
63
|
const StyledInput = styles_1.styled((_a) => {
|
|
61
64
|
var { color: _color } = _a, props = tslib_1.__rest(_a, ["color"]);
|
|
62
65
|
return (react_1.default.createElement(core_1.Input, Object.assign({ classes: {
|
|
66
|
+
root: classes.inputRoot,
|
|
67
|
+
focused: classes.inputFocused,
|
|
68
|
+
input: classes.inputInput,
|
|
63
69
|
disabled: classes.inputDisabled,
|
|
64
70
|
underline: classes.inputUnderline,
|
|
65
71
|
error: classes.inputError,
|
|
66
72
|
} }, props)));
|
|
67
73
|
})(({ color, theme }) => ({
|
|
68
74
|
color: theme.palette.text.primary,
|
|
75
|
+
[`&.${classes.inputRoot}.${classes.inputFocused}`]: {
|
|
76
|
+
backgroundColor: theme.palette.action.selected,
|
|
77
|
+
},
|
|
78
|
+
[`& .${classes.inputInput}`]: {
|
|
79
|
+
['&:focus']: {
|
|
80
|
+
background: 'rgba(0,0,0,0)',
|
|
81
|
+
},
|
|
82
|
+
},
|
|
69
83
|
[`&.${classes.inputUnderline}:not(.${classes.inputDisabled}):not(.${classes.inputError})`]: {
|
|
70
84
|
[`&:after,&:hover:before`]: {
|
|
71
85
|
borderBottomColor: theme.palette[color].main,
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TopicFilter = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const react_1 = tslib_1.__importStar(require("react"));
|
|
6
|
+
const styles_1 = require("@material-ui/core/styles");
|
|
7
|
+
const ArrowRightRounded_1 = tslib_1.__importDefault(require("@material-ui/icons/ArrowRightRounded"));
|
|
8
|
+
const OutlinedSelect_1 = tslib_1.__importDefault(require("../select/OutlinedSelect"));
|
|
9
|
+
const SelectMenuItem_1 = tslib_1.__importDefault(require("../menu-item/SelectMenuItem"));
|
|
10
|
+
// self-defined-configs
|
|
11
|
+
const PLACEHOLDER = '請選擇';
|
|
12
|
+
// self-defined-components
|
|
13
|
+
const PREFIX = 'JuiTopicFilter';
|
|
14
|
+
const FiltersWrapper = styles_1.styled('div')({
|
|
15
|
+
display: 'flex',
|
|
16
|
+
alignItems: 'center',
|
|
17
|
+
flexWrap: 'wrap',
|
|
18
|
+
});
|
|
19
|
+
const SelectWrapper = styles_1.styled('div')({
|
|
20
|
+
display: 'flex',
|
|
21
|
+
alignItems: 'center',
|
|
22
|
+
});
|
|
23
|
+
const StyledArrowRightRoundedIcon = styles_1.styled(ArrowRightRounded_1.default)(({ theme }) => ({
|
|
24
|
+
margin: theme.spacing(-1, -1.5),
|
|
25
|
+
fontSize: theme.spacing(7),
|
|
26
|
+
color: '#444',
|
|
27
|
+
}));
|
|
28
|
+
const TopicFilter = ({ topicTree, onTopicSelected, isLastLayer, hasArrow, initSelectedTopicIds, }) => {
|
|
29
|
+
const [selectedTopicIds, setSelectedTopicIds] = react_1.useState([]);
|
|
30
|
+
const [layeredTopicList, setLayeredTopicList] = react_1.useState([]);
|
|
31
|
+
const [isFocusedList, setIsFocusedList] = react_1.useState([]);
|
|
32
|
+
const initSelectedLayers = () => {
|
|
33
|
+
const newLayeredTopicList = initSelectedTopicIds.reduce((topicListAccumulator, topicId, index) => {
|
|
34
|
+
var _a, _b;
|
|
35
|
+
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);
|
|
36
|
+
if (!selectedTopic) {
|
|
37
|
+
return topicListAccumulator;
|
|
38
|
+
}
|
|
39
|
+
if (isLastLayer(selectedTopic)) {
|
|
40
|
+
return topicListAccumulator;
|
|
41
|
+
}
|
|
42
|
+
return [...topicListAccumulator, selectedTopic];
|
|
43
|
+
}, [topicTree]);
|
|
44
|
+
setLayeredTopicList(newLayeredTopicList);
|
|
45
|
+
setSelectedTopicIds(initSelectedTopicIds.slice(0, newLayeredTopicList.length));
|
|
46
|
+
setIsFocusedList(Array(newLayeredTopicList.length).fill(false));
|
|
47
|
+
};
|
|
48
|
+
const handleChange = (e, layerNumber, layeredTopic) => {
|
|
49
|
+
const selectedTopic = layeredTopic.childTopics.find((childTopic) => childTopic.id === e.target.value);
|
|
50
|
+
const newSelectedTopicIds = [
|
|
51
|
+
...selectedTopicIds.slice(0, layerNumber),
|
|
52
|
+
selectedTopic.id,
|
|
53
|
+
];
|
|
54
|
+
setSelectedTopicIds(newSelectedTopicIds);
|
|
55
|
+
onTopicSelected(selectedTopic, {
|
|
56
|
+
layerNumber,
|
|
57
|
+
selectedTopicIds: newSelectedTopicIds,
|
|
58
|
+
});
|
|
59
|
+
if (isLastLayer(selectedTopic)) {
|
|
60
|
+
setLayeredTopicList((prevTopicList) => prevTopicList.slice(0, layerNumber + 1));
|
|
61
|
+
setIsFocusedList((prevList) => prevList.slice(0, layerNumber + 1));
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
setLayeredTopicList((prevTopicList) => [
|
|
65
|
+
...prevTopicList.slice(0, layerNumber + 1),
|
|
66
|
+
selectedTopic,
|
|
67
|
+
]);
|
|
68
|
+
setIsFocusedList((prevList) => [
|
|
69
|
+
...prevList.slice(0, layerNumber + 1),
|
|
70
|
+
false,
|
|
71
|
+
]);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
react_1.useEffect(() => {
|
|
75
|
+
if (!topicTree || Object.keys(topicTree).length === 0) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (initSelectedTopicIds.length !== 0) {
|
|
79
|
+
initSelectedLayers();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
setLayeredTopicList([topicTree]);
|
|
83
|
+
}, [topicTree]);
|
|
84
|
+
if (layeredTopicList.length === 0) {
|
|
85
|
+
return (react_1.default.createElement(OutlinedSelect_1.default, { size: 'small', width: 220, placeholder: '\u8F09\u5165\u8CC7\u6599\u4E2D...', disabled: true }));
|
|
86
|
+
}
|
|
87
|
+
return (react_1.default.createElement(FiltersWrapper, null, layeredTopicList.map((layeredTopic, layerNumber) => {
|
|
88
|
+
const hasLabel = isFocusedList[layerNumber] || !selectedTopicIds[layerNumber];
|
|
89
|
+
return (react_1.default.createElement(SelectWrapper, { key: layeredTopic.id },
|
|
90
|
+
react_1.default.createElement(OutlinedSelect_1.default, { size: 'small', width: 220, paperMaxHeight: 412, hasLabel: hasLabel, placeholder: PLACEHOLDER, value: (selectedTopicIds === null || selectedTopicIds === void 0 ? void 0 : selectedTopicIds[layerNumber]) || '', SelectProps: {
|
|
91
|
+
'data-testid': `layered-topic-${layerNumber}`,
|
|
92
|
+
}, InputProps: {
|
|
93
|
+
inputProps: {
|
|
94
|
+
'aria-label': `layered-topic-${layerNumber}`,
|
|
95
|
+
},
|
|
96
|
+
onChange: (e) => {
|
|
97
|
+
handleChange(e, layerNumber, layeredTopic);
|
|
98
|
+
},
|
|
99
|
+
onFocus: () => {
|
|
100
|
+
setIsFocusedList((prevList) => {
|
|
101
|
+
const newList = [...prevList];
|
|
102
|
+
newList[layerNumber] = true;
|
|
103
|
+
return newList;
|
|
104
|
+
});
|
|
105
|
+
},
|
|
106
|
+
onBlur: () => {
|
|
107
|
+
setIsFocusedList((prevList) => {
|
|
108
|
+
const newList = [...prevList];
|
|
109
|
+
newList[layerNumber] = false;
|
|
110
|
+
return newList;
|
|
111
|
+
});
|
|
112
|
+
},
|
|
113
|
+
} },
|
|
114
|
+
react_1.default.createElement(SelectMenuItem_1.default, { width: 220, disabled: true }, PLACEHOLDER),
|
|
115
|
+
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)))),
|
|
116
|
+
hasArrow && layerNumber !== layeredTopicList.length - 1 && (react_1.default.createElement(StyledArrowRightRoundedIcon, { fontSize: 'large', "data-testid": 'topic-filter-arrow' }))));
|
|
117
|
+
})));
|
|
118
|
+
};
|
|
119
|
+
exports.TopicFilter = TopicFilter;
|
|
120
|
+
exports.default = exports.TopicFilter;
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { default as TopicFilter } from './lib/TopicFilter'
|
|
1
|
+
export { default as TopicFilter } from './lib/topic-filter/TopicFilter'
|
|
2
2
|
export { default as SelectMenuItem } from './lib/menu-item/SelectMenuItem'
|
|
3
3
|
export { default as OutlinedSelect } from './lib/select/OutlinedSelect'
|
|
4
4
|
export { default as Button } from './lib/button/Button'
|
package/src/interfaces/index.tsx
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import { ChangeEvent } from 'react'
|
|
2
|
+
import {
|
|
3
|
+
SelectProps as MuiSelectProp,
|
|
4
|
+
InputProps as MuiInputProps,
|
|
5
|
+
OutlinedInputProps,
|
|
6
|
+
} from '@material-ui/core'
|
|
7
|
+
|
|
1
8
|
export interface ITopicTreeNode {
|
|
2
9
|
childTopics: ITopicTreeNode[]
|
|
3
10
|
id: string
|
|
@@ -6,3 +13,21 @@ export interface ITopicTreeNode {
|
|
|
6
13
|
tags: string[]
|
|
7
14
|
title: string
|
|
8
15
|
}
|
|
16
|
+
export interface SelectProps extends MuiSelectProp {
|
|
17
|
+
placeholder: string
|
|
18
|
+
helperText?: string
|
|
19
|
+
InputProps?:
|
|
20
|
+
| (Partial<OutlinedInputProps> & {
|
|
21
|
+
onChange: (e: ChangeEvent<HTMLInputElement>) => void
|
|
22
|
+
})
|
|
23
|
+
| (object & Partial<MuiInputProps>)
|
|
24
|
+
SelectProps?: object | Partial<MuiSelectProp>
|
|
25
|
+
color?: 'primary' | 'secondary'
|
|
26
|
+
size?: 'medium' | 'small'
|
|
27
|
+
width?: number | 'auto'
|
|
28
|
+
paperMaxHeight?: number | 'auto'
|
|
29
|
+
error?: boolean
|
|
30
|
+
hasLabel?: boolean
|
|
31
|
+
hasShrink?: boolean
|
|
32
|
+
disabled?: boolean
|
|
33
|
+
}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react'
|
|
2
2
|
import { Theme, styled } from '@material-ui/core/styles'
|
|
3
3
|
import {
|
|
4
4
|
InputLabel,
|
|
5
5
|
FormControl,
|
|
6
6
|
Select,
|
|
7
7
|
OutlinedInput,
|
|
8
|
-
SelectProps,
|
|
9
|
-
OutlinedInputProps,
|
|
10
8
|
FormHelperText,
|
|
11
9
|
} from '@material-ui/core'
|
|
10
|
+
import { SelectProps } from '../../interfaces'
|
|
12
11
|
|
|
13
12
|
// self-defined-components
|
|
14
13
|
const PREFIX = 'JuiOutlinedSelect'
|
|
@@ -21,10 +20,12 @@ const classes = {
|
|
|
21
20
|
inputLabelError: `${PREFIX}-inputLabelError`,
|
|
22
21
|
inputLabelDisabled: `${PREFIX}-inputLabelDisabled`,
|
|
23
22
|
outlineInputInput: `${PREFIX}-input`,
|
|
23
|
+
outlineInputRoot: `${PREFIX}-inputRoot`,
|
|
24
24
|
outlineInputInputMarginDense: `${PREFIX}-inputMarginDense`,
|
|
25
25
|
outlineInputNotchedOutline: `${PREFIX}-notchedOutline`,
|
|
26
26
|
outlineInputDisabled: `${PREFIX}-inputDisabled`,
|
|
27
27
|
outlineInputError: `${PREFIX}-outlinedInputError`,
|
|
28
|
+
outlineInputFocused: `${PREFIX}-focused`,
|
|
28
29
|
selectPaper: `${PREFIX}-menuPaper`,
|
|
29
30
|
}
|
|
30
31
|
|
|
@@ -45,6 +46,9 @@ const StyledFormControl = styled(
|
|
|
45
46
|
borderColor: theme.palette[color].main,
|
|
46
47
|
},
|
|
47
48
|
},
|
|
49
|
+
[`& .${classes.outlineInputError}.${classes.outlineInputFocused} .${classes.outlineInputNotchedOutline}`]: {
|
|
50
|
+
borderColor: `${theme.palette.error.main}`,
|
|
51
|
+
},
|
|
48
52
|
}))
|
|
49
53
|
|
|
50
54
|
interface StyledInputLabelProps {
|
|
@@ -90,6 +94,8 @@ interface StyledOutlinedInputProps {
|
|
|
90
94
|
const StyledOutlinedInput = styled((props) => (
|
|
91
95
|
<OutlinedInput
|
|
92
96
|
classes={{
|
|
97
|
+
root: classes.outlineInputRoot,
|
|
98
|
+
focused: classes.outlineInputFocused,
|
|
93
99
|
input: classes.outlineInputInput,
|
|
94
100
|
inputMarginDense: classes.outlineInputInputMarginDense,
|
|
95
101
|
notchedOutline: classes.outlineInputNotchedOutline,
|
|
@@ -99,8 +105,14 @@ const StyledOutlinedInput = styled((props) => (
|
|
|
99
105
|
{...props}
|
|
100
106
|
/>
|
|
101
107
|
))(({ theme }: StyledOutlinedInputProps) => ({
|
|
108
|
+
[`&.${classes.outlineInputRoot}.${classes.outlineInputFocused}`]: {
|
|
109
|
+
backgroundColor: theme.palette.action.selected,
|
|
110
|
+
},
|
|
102
111
|
[`& .${classes.outlineInputInput}`]: {
|
|
103
112
|
color: theme.palette.text.primary,
|
|
113
|
+
['&:focus']: {
|
|
114
|
+
background: 'rgba(0,0,0,0)',
|
|
115
|
+
},
|
|
104
116
|
},
|
|
105
117
|
[`& .${classes.outlineInputInputMarginDense}`]: {
|
|
106
118
|
padding: '14.5px 15px 14.5px 12px',
|
|
@@ -131,7 +143,9 @@ const StyledSelect = styled(
|
|
|
131
143
|
horizontal: 'left',
|
|
132
144
|
},
|
|
133
145
|
getContentAnchorEl: null,
|
|
134
|
-
classes: {
|
|
146
|
+
classes: {
|
|
147
|
+
paper: className,
|
|
148
|
+
},
|
|
135
149
|
}}
|
|
136
150
|
{...props}
|
|
137
151
|
/>
|
|
@@ -143,27 +157,11 @@ const StyledSelect = styled(
|
|
|
143
157
|
},
|
|
144
158
|
}))
|
|
145
159
|
|
|
146
|
-
export
|
|
147
|
-
color?: 'primary' | 'secondary'
|
|
148
|
-
size?: 'medium' | 'small'
|
|
149
|
-
width?: number | 'auto'
|
|
150
|
-
paperMaxHeight?: number | 'auto'
|
|
151
|
-
error?: boolean
|
|
152
|
-
hasLabel?: boolean
|
|
153
|
-
hasShrink?: boolean
|
|
154
|
-
placeholder: string
|
|
155
|
-
helperText?: string
|
|
156
|
-
disabled?: boolean
|
|
157
|
-
SelectProps?: object | Partial<SelectProps>
|
|
158
|
-
OutlinedInputProps?: Partial<OutlinedInputProps> & {
|
|
159
|
-
onChange: (e: ChangeEvent<HTMLInputElement>) => void
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const OutlinedSelect = ({
|
|
160
|
+
export const OutlinedSelect = ({
|
|
164
161
|
placeholder,
|
|
162
|
+
helperText,
|
|
163
|
+
InputProps,
|
|
165
164
|
SelectProps,
|
|
166
|
-
OutlinedInputProps,
|
|
167
165
|
children,
|
|
168
166
|
color = 'primary',
|
|
169
167
|
size = 'medium',
|
|
@@ -172,11 +170,10 @@ const OutlinedSelect = ({
|
|
|
172
170
|
error = false,
|
|
173
171
|
hasLabel = true,
|
|
174
172
|
hasShrink = false,
|
|
175
|
-
helperText = '',
|
|
176
173
|
value = '',
|
|
177
174
|
disabled = false,
|
|
178
|
-
}:
|
|
179
|
-
const hasAdornment = !!
|
|
175
|
+
}: SelectProps) => {
|
|
176
|
+
const hasAdornment = !!InputProps?.startAdornment
|
|
180
177
|
const hasHelperText = !!helperText
|
|
181
178
|
return (
|
|
182
179
|
<StyledFormControl
|
|
@@ -204,7 +201,7 @@ const OutlinedSelect = ({
|
|
|
204
201
|
color={color}
|
|
205
202
|
label={hasLabel ? placeholder : undefined}
|
|
206
203
|
disabled={disabled}
|
|
207
|
-
{...
|
|
204
|
+
{...InputProps}
|
|
208
205
|
/>
|
|
209
206
|
}
|
|
210
207
|
{...SelectProps}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import React, { useState } from 'react'
|
|
2
2
|
import { Story, Meta } from '@storybook/react'
|
|
3
3
|
import { Theme, styled } from '@material-ui/core/styles'
|
|
4
|
-
import { InputAdornment
|
|
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 },
|
|
@@ -53,7 +52,8 @@ export default {
|
|
|
53
52
|
},
|
|
54
53
|
hasLabel: {
|
|
55
54
|
type: { name: 'boolean', required: false },
|
|
56
|
-
description:
|
|
55
|
+
description:
|
|
56
|
+
'If true, the label is displayed. Always true on StandardSelect.',
|
|
57
57
|
table: {
|
|
58
58
|
type: { summary: 'boolean' },
|
|
59
59
|
defaultValue: { summary: true },
|
|
@@ -121,9 +121,10 @@ export default {
|
|
|
121
121
|
type: { summary: 'any' },
|
|
122
122
|
},
|
|
123
123
|
},
|
|
124
|
-
|
|
124
|
+
CommonInputProps: {
|
|
125
125
|
type: { name: 'any', required: false },
|
|
126
|
-
description:
|
|
126
|
+
description:
|
|
127
|
+
'Attributes applied to to inner OutlinedInput element on OutlinedSelect or Input element on StandardSelect.',
|
|
127
128
|
table: {
|
|
128
129
|
type: { summary: 'any' },
|
|
129
130
|
},
|
|
@@ -131,10 +132,12 @@ export default {
|
|
|
131
132
|
},
|
|
132
133
|
} as Meta
|
|
133
134
|
|
|
134
|
-
const
|
|
135
|
+
const PLACEHOLDER = 'Please select an option'
|
|
136
|
+
const ERROR_PLACEHOLDER = 'Please select an option'
|
|
137
|
+
const PREFIX = 'JuiSelect'
|
|
135
138
|
|
|
136
139
|
const classes = {
|
|
137
|
-
|
|
140
|
+
inputAdornmentRoot: `${PREFIX}-inputAdornmentRoot`,
|
|
138
141
|
}
|
|
139
142
|
|
|
140
143
|
interface StyledInputAdornmentProps {
|
|
@@ -145,18 +148,20 @@ interface StyledInputAdornmentProps {
|
|
|
145
148
|
const StyledInputAdornment = styled(({ disabled: _disabled, ...props }) => (
|
|
146
149
|
<InputAdornment
|
|
147
150
|
classes={{
|
|
148
|
-
root: classes.
|
|
151
|
+
root: classes.inputAdornmentRoot,
|
|
149
152
|
}}
|
|
150
153
|
{...props}
|
|
151
154
|
/>
|
|
152
155
|
))(({ disabled, theme }: StyledInputAdornmentProps) => ({
|
|
153
|
-
|
|
156
|
+
height: '100%',
|
|
157
|
+
[`&.${classes.inputAdornmentRoot}`]: {
|
|
154
158
|
color: disabled
|
|
155
159
|
? theme.palette.action.disabled
|
|
156
160
|
: theme.palette.action.active,
|
|
157
161
|
},
|
|
158
162
|
}))
|
|
159
163
|
|
|
164
|
+
// Outlined Select start with here.
|
|
160
165
|
interface OutlinedSelectWithMenuProps {
|
|
161
166
|
startAdornment?: React.ReactNode
|
|
162
167
|
}
|
|
@@ -164,15 +169,16 @@ interface OutlinedSelectWithMenuProps {
|
|
|
164
169
|
const OutlinedSelectWithMenu = ({
|
|
165
170
|
startAdornment,
|
|
166
171
|
...props
|
|
167
|
-
}:
|
|
172
|
+
}: SelectProps & OutlinedSelectWithMenuProps) => {
|
|
168
173
|
const [item, setItem] = useState<string>('')
|
|
169
174
|
|
|
170
175
|
const handleChange = (event) => {
|
|
171
176
|
setItem(event.target.value)
|
|
172
177
|
}
|
|
173
178
|
return (
|
|
174
|
-
<
|
|
175
|
-
|
|
179
|
+
<Select
|
|
180
|
+
variant='outlined'
|
|
181
|
+
InputProps={{
|
|
176
182
|
onChange: (e) => {
|
|
177
183
|
handleChange(e)
|
|
178
184
|
},
|
|
@@ -181,38 +187,91 @@ const OutlinedSelectWithMenu = ({
|
|
|
181
187
|
value={item}
|
|
182
188
|
{...props}
|
|
183
189
|
>
|
|
184
|
-
<SelectMenuItem width={
|
|
190
|
+
<SelectMenuItem width={props.width} value='' disabled>
|
|
185
191
|
{PLACEHOLDER}
|
|
186
192
|
</SelectMenuItem>
|
|
187
|
-
<SelectMenuItem width={
|
|
193
|
+
<SelectMenuItem width={props.width} value='Test'>
|
|
188
194
|
This is a select menu item
|
|
189
195
|
</SelectMenuItem>
|
|
190
|
-
<SelectMenuItem width={
|
|
196
|
+
<SelectMenuItem width={props.width} value='Example'>
|
|
191
197
|
Example
|
|
192
198
|
</SelectMenuItem>
|
|
193
|
-
</
|
|
199
|
+
</Select>
|
|
194
200
|
)
|
|
195
201
|
}
|
|
196
202
|
|
|
197
|
-
const
|
|
203
|
+
const OutlinedValueOnlyStory: Story<SelectProps> = (args) => (
|
|
198
204
|
<OutlinedSelectWithMenu {...args} />
|
|
199
205
|
)
|
|
200
206
|
|
|
201
|
-
export const
|
|
207
|
+
export const OutlinedValueOnly = OutlinedValueOnlyStory.bind({})
|
|
202
208
|
|
|
203
|
-
|
|
209
|
+
OutlinedValueOnly.args = {
|
|
204
210
|
color: 'primary',
|
|
205
211
|
size: 'medium',
|
|
206
212
|
width: 220,
|
|
207
213
|
paperMaxHeight: 412,
|
|
208
214
|
hasLabel: true,
|
|
209
215
|
placeholder: PLACEHOLDER,
|
|
210
|
-
helperText: '
|
|
216
|
+
helperText: 'Pick your choice',
|
|
211
217
|
disabled: false,
|
|
212
218
|
SelectProps: {},
|
|
213
219
|
}
|
|
214
220
|
|
|
215
|
-
const
|
|
221
|
+
const OutlinedSelectWithError = ({
|
|
222
|
+
startAdornment,
|
|
223
|
+
...props
|
|
224
|
+
}: SelectProps & OutlinedSelectWithMenuProps) => {
|
|
225
|
+
const [item, setItem] = useState<string>('')
|
|
226
|
+
|
|
227
|
+
const handleChange = (event) => {
|
|
228
|
+
setItem(event.target.value)
|
|
229
|
+
}
|
|
230
|
+
return (
|
|
231
|
+
<Select
|
|
232
|
+
variant='outlined'
|
|
233
|
+
InputProps={{
|
|
234
|
+
onChange: (e) => {
|
|
235
|
+
handleChange(e)
|
|
236
|
+
},
|
|
237
|
+
startAdornment,
|
|
238
|
+
}}
|
|
239
|
+
value={item}
|
|
240
|
+
error={item === ''}
|
|
241
|
+
helperText={item === '' ? ERROR_PLACEHOLDER : ''}
|
|
242
|
+
{...props}
|
|
243
|
+
>
|
|
244
|
+
<SelectMenuItem width={props.width} value='' disabled>
|
|
245
|
+
{PLACEHOLDER}
|
|
246
|
+
</SelectMenuItem>
|
|
247
|
+
<SelectMenuItem width={props.width} value='Option1'>
|
|
248
|
+
This is a select menu item
|
|
249
|
+
</SelectMenuItem>
|
|
250
|
+
<SelectMenuItem width={props.width} value='Option2'>
|
|
251
|
+
This is option 2
|
|
252
|
+
</SelectMenuItem>
|
|
253
|
+
</Select>
|
|
254
|
+
)
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const OutlinedWithErrorStory: Story<SelectProps> = (args) => (
|
|
258
|
+
<OutlinedSelectWithError {...args} />
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
export const OutlinedWithError = OutlinedWithErrorStory.bind({})
|
|
262
|
+
|
|
263
|
+
OutlinedWithError.args = {
|
|
264
|
+
color: 'primary',
|
|
265
|
+
size: 'medium',
|
|
266
|
+
width: 220,
|
|
267
|
+
paperMaxHeight: 412,
|
|
268
|
+
hasLabel: true,
|
|
269
|
+
placeholder: PLACEHOLDER,
|
|
270
|
+
disabled: false,
|
|
271
|
+
SelectProps: {},
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const OutlinedWithPrefixStory: Story<SelectProps> = (args) => (
|
|
216
275
|
<OutlinedSelectWithMenu
|
|
217
276
|
startAdornment={
|
|
218
277
|
<StyledInputAdornment position='start' disabled={args.disabled}>
|
|
@@ -223,16 +282,140 @@ const WithPrefixStory: Story<OutlinedSelectProps> = (args) => (
|
|
|
223
282
|
/>
|
|
224
283
|
)
|
|
225
284
|
|
|
226
|
-
export const
|
|
285
|
+
export const OutlinedWithPrefix = OutlinedWithPrefixStory.bind({})
|
|
227
286
|
|
|
228
|
-
|
|
287
|
+
OutlinedWithPrefix.args = {
|
|
229
288
|
color: 'primary',
|
|
230
289
|
size: 'medium',
|
|
231
290
|
width: 220,
|
|
232
291
|
paperMaxHeight: 412,
|
|
233
292
|
hasLabel: true,
|
|
234
293
|
placeholder: PLACEHOLDER,
|
|
235
|
-
helperText: '
|
|
294
|
+
helperText: 'Pick your choice',
|
|
236
295
|
disabled: false,
|
|
237
296
|
SelectProps: {},
|
|
238
297
|
}
|
|
298
|
+
|
|
299
|
+
// Standard Select start with here.
|
|
300
|
+
const StandardSelectWithMenu = (props: SelectProps) => {
|
|
301
|
+
const [item, setItem] = useState<string>('')
|
|
302
|
+
|
|
303
|
+
const handleChange = (event) => {
|
|
304
|
+
setItem(event.target.value)
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return (
|
|
308
|
+
<Select
|
|
309
|
+
variant='standard'
|
|
310
|
+
value={item}
|
|
311
|
+
SelectProps={{
|
|
312
|
+
onChange: (e) => {
|
|
313
|
+
handleChange(e)
|
|
314
|
+
},
|
|
315
|
+
}}
|
|
316
|
+
{...props}
|
|
317
|
+
>
|
|
318
|
+
<SelectMenuItem width={props.width} value='' disabled>
|
|
319
|
+
{PLACEHOLDER}
|
|
320
|
+
</SelectMenuItem>
|
|
321
|
+
<SelectMenuItem width={props.width} value='Option1'>
|
|
322
|
+
This is a select menu item
|
|
323
|
+
</SelectMenuItem>
|
|
324
|
+
<SelectMenuItem width={props.width} value='Option2'>
|
|
325
|
+
This is option 2
|
|
326
|
+
</SelectMenuItem>
|
|
327
|
+
</Select>
|
|
328
|
+
)
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const StandardValueOnlyStory: Story<SelectProps> = (args) => (
|
|
332
|
+
<StandardSelectWithMenu {...args} />
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
export const StandardValueOnly = StandardValueOnlyStory.bind({})
|
|
336
|
+
|
|
337
|
+
StandardValueOnly.args = {
|
|
338
|
+
color: 'primary',
|
|
339
|
+
size: 'medium',
|
|
340
|
+
width: 300,
|
|
341
|
+
paperMaxHeight: 300,
|
|
342
|
+
hasShrink: false,
|
|
343
|
+
placeholder: PLACEHOLDER,
|
|
344
|
+
helperText: 'Pick your choice',
|
|
345
|
+
disabled: false,
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const StandardSelectWithError = (props: SelectProps) => {
|
|
349
|
+
const [item, setItem] = useState<string>('')
|
|
350
|
+
|
|
351
|
+
const handleChange = (event) => {
|
|
352
|
+
setItem(event.target.value)
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return (
|
|
356
|
+
<Select
|
|
357
|
+
variant='standard'
|
|
358
|
+
value={item}
|
|
359
|
+
SelectProps={{
|
|
360
|
+
onChange: (e) => {
|
|
361
|
+
handleChange(e)
|
|
362
|
+
},
|
|
363
|
+
}}
|
|
364
|
+
error={item === ''}
|
|
365
|
+
helperText={item === '' ? ERROR_PLACEHOLDER : ''}
|
|
366
|
+
{...props}
|
|
367
|
+
>
|
|
368
|
+
<SelectMenuItem width={props.width} value='' disabled>
|
|
369
|
+
{PLACEHOLDER}
|
|
370
|
+
</SelectMenuItem>
|
|
371
|
+
<SelectMenuItem width={props.width} value={'Test'}>
|
|
372
|
+
This is a select menu item, This is a select menu item
|
|
373
|
+
</SelectMenuItem>
|
|
374
|
+
<SelectMenuItem width={props.width} value={'Example'}>
|
|
375
|
+
Example
|
|
376
|
+
</SelectMenuItem>
|
|
377
|
+
</Select>
|
|
378
|
+
)
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const StandardWithErrorStory: Story<SelectProps> = (args) => (
|
|
382
|
+
<StandardSelectWithError {...args} />
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
export const StandardWithError = StandardWithErrorStory.bind({})
|
|
386
|
+
|
|
387
|
+
StandardWithError.args = {
|
|
388
|
+
color: 'primary',
|
|
389
|
+
size: 'medium',
|
|
390
|
+
width: 300,
|
|
391
|
+
paperMaxHeight: 300,
|
|
392
|
+
hasShrink: false,
|
|
393
|
+
placeholder: PLACEHOLDER,
|
|
394
|
+
disabled: false,
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
const StandardWithPrefixStory: Story<SelectProps> = (args) => (
|
|
398
|
+
<StandardSelectWithMenu
|
|
399
|
+
InputProps={{
|
|
400
|
+
startAdornment: (
|
|
401
|
+
<StyledInputAdornment position='start' disabled={args.disabled}>
|
|
402
|
+
<Visibility />
|
|
403
|
+
</StyledInputAdornment>
|
|
404
|
+
),
|
|
405
|
+
}}
|
|
406
|
+
{...args}
|
|
407
|
+
/>
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
export const StandardWithPrefix = StandardWithPrefixStory.bind({})
|
|
411
|
+
|
|
412
|
+
StandardWithPrefix.args = {
|
|
413
|
+
color: 'primary',
|
|
414
|
+
size: 'medium',
|
|
415
|
+
width: 300,
|
|
416
|
+
paperMaxHeight: 300,
|
|
417
|
+
hasShrink: false,
|
|
418
|
+
placeholder: PLACEHOLDER,
|
|
419
|
+
helperText: 'Pick your choice',
|
|
420
|
+
disabled: false,
|
|
421
|
+
}
|
|
@@ -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,9 @@ const classes = {
|
|
|
18
16
|
inputLabelFocused: `${PREFIX}-inputLabelFocused`,
|
|
19
17
|
inputLabelMarginDense: `${PREFIX}-inputLabelMarginDense`,
|
|
20
18
|
inputLabelError: `${PREFIX}-inputLabelError`,
|
|
19
|
+
inputRoot: `${PREFIX}-inputRoot`,
|
|
20
|
+
inputFocused: `${PREFIX}-inputFocused`,
|
|
21
|
+
inputInput: `${PREFIX}-input`,
|
|
21
22
|
inputUnderline: `${PREFIX}-inputUnderline`,
|
|
22
23
|
inputError: `${PREFIX}-inputError`,
|
|
23
24
|
inputDisabled: `${PREFIX}-inputDisabled`,
|
|
@@ -102,6 +103,9 @@ interface StyledInputProps {
|
|
|
102
103
|
const StyledInput = styled(({ color: _color, ...props }) => (
|
|
103
104
|
<Input
|
|
104
105
|
classes={{
|
|
106
|
+
root: classes.inputRoot,
|
|
107
|
+
focused: classes.inputFocused,
|
|
108
|
+
input: classes.inputInput,
|
|
105
109
|
disabled: classes.inputDisabled,
|
|
106
110
|
underline: classes.inputUnderline,
|
|
107
111
|
error: classes.inputError,
|
|
@@ -110,6 +114,14 @@ const StyledInput = styled(({ color: _color, ...props }) => (
|
|
|
110
114
|
/>
|
|
111
115
|
))(({ color, theme }: StyledInputProps) => ({
|
|
112
116
|
color: theme.palette.text.primary,
|
|
117
|
+
[`&.${classes.inputRoot}.${classes.inputFocused}`]: {
|
|
118
|
+
backgroundColor: theme.palette.action.selected,
|
|
119
|
+
},
|
|
120
|
+
[`& .${classes.inputInput}`]: {
|
|
121
|
+
['&:focus']: {
|
|
122
|
+
background: 'rgba(0,0,0,0)',
|
|
123
|
+
},
|
|
124
|
+
},
|
|
113
125
|
[`&.${classes.inputUnderline}:not(.${classes.inputDisabled}):not(.${classes.inputError})`]: {
|
|
114
126
|
[`&:after,&:hover:before`]: {
|
|
115
127
|
borderBottomColor: theme.palette[color].main,
|
|
@@ -122,20 +134,6 @@ const StyledInput = styled(({ color: _color, ...props }) => (
|
|
|
122
134
|
},
|
|
123
135
|
}))
|
|
124
136
|
|
|
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
137
|
export function StandardSelect({
|
|
140
138
|
placeholder,
|
|
141
139
|
helperText,
|
|
@@ -150,7 +148,7 @@ export function StandardSelect({
|
|
|
150
148
|
hasShrink = false,
|
|
151
149
|
value = '',
|
|
152
150
|
disabled = false,
|
|
153
|
-
}:
|
|
151
|
+
}: SelectProps) {
|
|
154
152
|
const hasAdornment = !!InputProps?.startAdornment
|
|
155
153
|
const hasHelperText = !!helperText
|
|
156
154
|
return (
|
|
@@ -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 = '請選擇'
|
|
@@ -150,7 +150,7 @@ export 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,221 +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 } from '@material-ui/core'
|
|
5
|
-
import { Visibility } from '@material-ui/icons'
|
|
6
|
-
import { StandardSelect, StandardSelectProps } from './StandardSelect'
|
|
7
|
-
import SelectMenuItem from '../menu-item/SelectMenuItem'
|
|
8
|
-
|
|
9
|
-
const PLACEHOLDER = '請選擇'
|
|
10
|
-
|
|
11
|
-
export default {
|
|
12
|
-
component: StandardSelect,
|
|
13
|
-
title: 'StandardSelect',
|
|
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
|
-
hasShrink: {
|
|
55
|
-
type: { name: 'boolean', required: false },
|
|
56
|
-
description: 'If true, the label is displayed and shrunk.',
|
|
57
|
-
table: {
|
|
58
|
-
type: { summary: 'boolean' },
|
|
59
|
-
defaultValue: { summary: true },
|
|
60
|
-
},
|
|
61
|
-
control: { type: 'boolean' },
|
|
62
|
-
},
|
|
63
|
-
placeholder: {
|
|
64
|
-
type: { name: 'string', required: true },
|
|
65
|
-
description: `The label title`,
|
|
66
|
-
table: {
|
|
67
|
-
type: { summary: 'string' },
|
|
68
|
-
defaultValue: { summary: '請選擇' },
|
|
69
|
-
},
|
|
70
|
-
control: { type: 'text' },
|
|
71
|
-
},
|
|
72
|
-
value: {
|
|
73
|
-
type: { name: 'any', required: false },
|
|
74
|
-
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.
|
|
75
|
-
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.`,
|
|
76
|
-
table: {
|
|
77
|
-
type: { summary: 'any' },
|
|
78
|
-
defaultValue: { summary: '' },
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
disabled: {
|
|
82
|
-
type: { name: 'boolean', required: false },
|
|
83
|
-
description: 'If true, the input element will be disabled.',
|
|
84
|
-
table: {
|
|
85
|
-
type: { summary: 'boolean' },
|
|
86
|
-
defaultValue: { summary: false },
|
|
87
|
-
},
|
|
88
|
-
control: { type: 'boolean' },
|
|
89
|
-
},
|
|
90
|
-
error: {
|
|
91
|
-
type: { name: 'boolean', required: false },
|
|
92
|
-
description: 'If true, the label will be displayed in an error state.',
|
|
93
|
-
table: {
|
|
94
|
-
type: { summary: 'boolean' },
|
|
95
|
-
defaultValue: { summary: false },
|
|
96
|
-
},
|
|
97
|
-
control: { type: 'boolean' },
|
|
98
|
-
},
|
|
99
|
-
helperText: {
|
|
100
|
-
type: { name: 'string', required: true },
|
|
101
|
-
description: `Display the helper text.`,
|
|
102
|
-
table: {
|
|
103
|
-
type: { summary: 'string' },
|
|
104
|
-
defaultValue: { summary: '' },
|
|
105
|
-
},
|
|
106
|
-
control: { type: 'text' },
|
|
107
|
-
},
|
|
108
|
-
InputProps: {
|
|
109
|
-
type: { name: 'any', required: false },
|
|
110
|
-
description: 'Attributes applied to inner Input element.',
|
|
111
|
-
table: {
|
|
112
|
-
type: { summary: 'any' },
|
|
113
|
-
},
|
|
114
|
-
},
|
|
115
|
-
SelectProps: {
|
|
116
|
-
type: { name: 'any', required: false },
|
|
117
|
-
description: 'Attributes applied to inner Select element.',
|
|
118
|
-
table: {
|
|
119
|
-
type: { summary: 'any' },
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
} as Meta
|
|
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
|
-
|
|
150
|
-
const StandardSelectWithMenu = (props: StandardSelectProps) => {
|
|
151
|
-
const [item, setItem] = useState<string>('')
|
|
152
|
-
|
|
153
|
-
const handleChange = (event) => {
|
|
154
|
-
setItem(event.target.value)
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return (
|
|
158
|
-
<StandardSelect
|
|
159
|
-
value={item}
|
|
160
|
-
SelectProps={{
|
|
161
|
-
onChange: (e) => {
|
|
162
|
-
handleChange(e)
|
|
163
|
-
},
|
|
164
|
-
}}
|
|
165
|
-
{...props}
|
|
166
|
-
>
|
|
167
|
-
<SelectMenuItem width={300} value='' disabled>
|
|
168
|
-
{PLACEHOLDER}
|
|
169
|
-
</SelectMenuItem>
|
|
170
|
-
<SelectMenuItem width={300} value={'Test'}>
|
|
171
|
-
This is a select menu item, This is a select menu item
|
|
172
|
-
</SelectMenuItem>
|
|
173
|
-
<SelectMenuItem width={300} value={'Example'}>
|
|
174
|
-
Example
|
|
175
|
-
</SelectMenuItem>
|
|
176
|
-
</StandardSelect>
|
|
177
|
-
)
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const ValueOnlyStory: Story<StandardSelectProps> = (args) => (
|
|
181
|
-
<StandardSelectWithMenu {...args} />
|
|
182
|
-
)
|
|
183
|
-
|
|
184
|
-
export const ValueOnly = ValueOnlyStory.bind({})
|
|
185
|
-
|
|
186
|
-
ValueOnly.args = {
|
|
187
|
-
color: 'primary',
|
|
188
|
-
size: 'medium',
|
|
189
|
-
width: 220,
|
|
190
|
-
paperMaxHeight: 300,
|
|
191
|
-
hasShrink: false,
|
|
192
|
-
placeholder: PLACEHOLDER,
|
|
193
|
-
helperText: 'test',
|
|
194
|
-
disabled: false,
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
const WithPrefixStory: Story<StandardSelectProps> = (args) => (
|
|
198
|
-
<StandardSelectWithMenu
|
|
199
|
-
InputProps={{
|
|
200
|
-
startAdornment: (
|
|
201
|
-
<StyledInputAdornment position='start' disabled={args.disabled}>
|
|
202
|
-
<Visibility />
|
|
203
|
-
</StyledInputAdornment>
|
|
204
|
-
),
|
|
205
|
-
}}
|
|
206
|
-
{...args}
|
|
207
|
-
/>
|
|
208
|
-
)
|
|
209
|
-
|
|
210
|
-
export const WithPrefix = WithPrefixStory.bind({})
|
|
211
|
-
|
|
212
|
-
WithPrefix.args = {
|
|
213
|
-
color: 'primary',
|
|
214
|
-
size: 'medium',
|
|
215
|
-
width: 300,
|
|
216
|
-
paperMaxHeight: 300,
|
|
217
|
-
hasShrink: false,
|
|
218
|
-
placeholder: PLACEHOLDER,
|
|
219
|
-
helperText: 'test',
|
|
220
|
-
disabled: false,
|
|
221
|
-
}
|