@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
|
@@ -1,8 +1,7 @@
|
|
|
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
|
-
export { default as OutlinedSelect } from './lib/select/OutlinedSelect';
|
|
4
3
|
export { default as Button } from './lib/button/Button';
|
|
5
4
|
export { default as ButtonGroup } from './lib/button-group/ButtonGroup';
|
|
6
5
|
export { default as Radio } from './lib/radio/Radio';
|
|
7
6
|
export { default as TextField } from './lib/text-field/TextField';
|
|
8
|
-
export { default as
|
|
7
|
+
export { default as Select } from './lib/select/Select';
|
|
@@ -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
|
+
}
|
|
@@ -9,5 +9,5 @@ export interface TopicFilterProps {
|
|
|
9
9
|
hasArrow: boolean;
|
|
10
10
|
initSelectedTopicIds: string[];
|
|
11
11
|
}
|
|
12
|
-
declare const TopicFilter: ({ topicTree, onTopicSelected, isLastLayer, hasArrow, initSelectedTopicIds, }: TopicFilterProps) => JSX.Element;
|
|
12
|
+
export declare const TopicFilter: ({ topicTree, onTopicSelected, isLastLayer, hasArrow, initSelectedTopicIds, }: TopicFilterProps) => JSX.Element;
|
|
13
13
|
export default TopicFilter;
|
|
@@ -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;
|
|
@@ -3,13 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
var TopicFilter_1 = require("./lib/TopicFilter");
|
|
6
|
+
exports.Select = exports.TextField = exports.Radio = exports.ButtonGroup = exports.Button = exports.SelectMenuItem = exports.TopicFilter = void 0;
|
|
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; } });
|
|
11
|
-
var OutlinedSelect_1 = require("./lib/select/OutlinedSelect");
|
|
12
|
-
Object.defineProperty(exports, "OutlinedSelect", { enumerable: true, get: function () { return __importDefault(OutlinedSelect_1).default; } });
|
|
13
11
|
var Button_1 = require("./lib/button/Button");
|
|
14
12
|
Object.defineProperty(exports, "Button", { enumerable: true, get: function () { return __importDefault(Button_1).default; } });
|
|
15
13
|
var ButtonGroup_1 = require("./lib/button-group/ButtonGroup");
|
|
@@ -18,5 +16,5 @@ var Radio_1 = require("./lib/radio/Radio");
|
|
|
18
16
|
Object.defineProperty(exports, "Radio", { enumerable: true, get: function () { return __importDefault(Radio_1).default; } });
|
|
19
17
|
var TextField_1 = require("./lib/text-field/TextField");
|
|
20
18
|
Object.defineProperty(exports, "TextField", { enumerable: true, get: function () { return __importDefault(TextField_1).default; } });
|
|
21
|
-
var
|
|
22
|
-
Object.defineProperty(exports, "
|
|
19
|
+
var Select_1 = require("./lib/select/Select");
|
|
20
|
+
Object.defineProperty(exports, "Select", { enumerable: true, get: function () { return __importDefault(Select_1).default; } });
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TopicFilter = void 0;
|
|
3
4
|
const tslib_1 = require("tslib");
|
|
4
5
|
const react_1 = tslib_1.__importStar(require("react"));
|
|
5
6
|
const styles_1 = require("@material-ui/core/styles");
|
|
@@ -115,4 +116,5 @@ const TopicFilter = ({ topicTree, onTopicSelected, isLastLayer, hasArrow, initSe
|
|
|
115
116
|
hasArrow && layerNumber !== layeredTopicList.length - 1 && (react_1.default.createElement(StyledArrowRightRoundedIcon, { fontSize: 'large', "data-testid": 'topic-filter-arrow' }))));
|
|
116
117
|
})));
|
|
117
118
|
};
|
|
118
|
-
exports.
|
|
119
|
+
exports.TopicFilter = TopicFilter;
|
|
120
|
+
exports.default = exports.TopicFilter;
|
|
@@ -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) => {
|
|
@@ -62,17 +65,27 @@ const StyledInputLabel = styles_1.styled((_a) => {
|
|
|
62
65
|
},
|
|
63
66
|
}));
|
|
64
67
|
const StyledOutlinedInput = styles_1.styled((props) => (react_1.default.createElement(core_1.OutlinedInput, Object.assign({ classes: {
|
|
68
|
+
root: classes.outlineInputRoot,
|
|
65
69
|
input: classes.outlineInputInput,
|
|
70
|
+
focused: classes.outlineInputFocused,
|
|
66
71
|
inputMarginDense: classes.outlineInputInputMarginDense,
|
|
67
72
|
notchedOutline: classes.outlineInputNotchedOutline,
|
|
68
73
|
disabled: classes.outlineInputDisabled,
|
|
69
74
|
error: classes.outlineInputError,
|
|
70
75
|
} }, props))))(({ theme }) => ({
|
|
76
|
+
[`&.${classes.outlineInputRoot}`]: {
|
|
77
|
+
[`&.${classes.outlineInputError}.${classes.outlineInputFocused} .${classes.outlineInputNotchedOutline}`]: {
|
|
78
|
+
borderColor: `${theme.palette.error.main}`,
|
|
79
|
+
},
|
|
80
|
+
[`& .${classes.outlineInputInputMarginDense}`]: {
|
|
81
|
+
padding: '14.5px 15px 14.5px 12px',
|
|
82
|
+
},
|
|
83
|
+
},
|
|
71
84
|
[`& .${classes.outlineInputInput}`]: {
|
|
72
85
|
color: theme.palette.text.primary,
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
86
|
+
['&:focus']: {
|
|
87
|
+
background: 'rgba(0,0,0,0)',
|
|
88
|
+
},
|
|
76
89
|
},
|
|
77
90
|
}));
|
|
78
91
|
const StyledSelect = styles_1.styled((_a) => {
|
|
@@ -88,7 +101,9 @@ const StyledSelect = styles_1.styled((_a) => {
|
|
|
88
101
|
horizontal: 'left',
|
|
89
102
|
},
|
|
90
103
|
getContentAnchorEl: null,
|
|
91
|
-
classes: {
|
|
104
|
+
classes: {
|
|
105
|
+
paper: className,
|
|
106
|
+
},
|
|
92
107
|
} }, props)));
|
|
93
108
|
})(({ hasAdornment, paperMaxHeight }) => ({
|
|
94
109
|
'&': {
|
|
@@ -96,12 +111,13 @@ const StyledSelect = styles_1.styled((_a) => {
|
|
|
96
111
|
left: hasAdornment ? '24px !important' : '70px',
|
|
97
112
|
},
|
|
98
113
|
}));
|
|
99
|
-
const OutlinedSelect = ({ placeholder,
|
|
100
|
-
const hasAdornment = !!(
|
|
114
|
+
const OutlinedSelect = ({ placeholder, helperText, InputProps, SelectProps, children, color = 'primary', size = 'small', width = 'auto', paperMaxHeight = 'auto', error = false, hasLabel = true, hasShrink = false, value = '', disabled = false, }) => {
|
|
115
|
+
const hasAdornment = !!(InputProps === null || InputProps === void 0 ? void 0 : InputProps.startAdornment);
|
|
101
116
|
const hasHelperText = !!helperText;
|
|
102
117
|
return (react_1.default.createElement(StyledFormControl, { size: size, width: width, disabled: disabled, error: error, color: color },
|
|
103
118
|
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 },
|
|
119
|
+
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
120
|
hasHelperText && react_1.default.createElement(core_1.FormHelperText, null, helperText)));
|
|
106
121
|
};
|
|
107
|
-
exports.
|
|
122
|
+
exports.OutlinedSelect = OutlinedSelect;
|
|
123
|
+
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,8 @@ const classes = {
|
|
|
11
11
|
inputLabelFocused: `${PREFIX}-inputLabelFocused`,
|
|
12
12
|
inputLabelMarginDense: `${PREFIX}-inputLabelMarginDense`,
|
|
13
13
|
inputLabelError: `${PREFIX}-inputLabelError`,
|
|
14
|
+
inputFocused: `${PREFIX}-inputFocused`,
|
|
15
|
+
inputInput: `${PREFIX}-input`,
|
|
14
16
|
inputUnderline: `${PREFIX}-inputUnderline`,
|
|
15
17
|
inputError: `${PREFIX}-inputError`,
|
|
16
18
|
inputDisabled: `${PREFIX}-inputDisabled`,
|
|
@@ -60,12 +62,18 @@ const StyledSelect = styles_1.styled((_a) => {
|
|
|
60
62
|
const StyledInput = styles_1.styled((_a) => {
|
|
61
63
|
var { color: _color } = _a, props = tslib_1.__rest(_a, ["color"]);
|
|
62
64
|
return (react_1.default.createElement(core_1.Input, Object.assign({ classes: {
|
|
65
|
+
input: classes.inputInput,
|
|
63
66
|
disabled: classes.inputDisabled,
|
|
64
67
|
underline: classes.inputUnderline,
|
|
65
68
|
error: classes.inputError,
|
|
66
69
|
} }, props)));
|
|
67
70
|
})(({ color, theme }) => ({
|
|
68
71
|
color: theme.palette.text.primary,
|
|
72
|
+
[`& .${classes.inputInput}`]: {
|
|
73
|
+
['&:focus']: {
|
|
74
|
+
background: 'rgba(0,0,0,0)',
|
|
75
|
+
},
|
|
76
|
+
},
|
|
69
77
|
[`&.${classes.inputUnderline}:not(.${classes.inputDisabled}):not(.${classes.inputError})`]: {
|
|
70
78
|
[`&:after,&:hover:before`]: {
|
|
71
79
|
borderBottomColor: theme.palette[color].main,
|
|
@@ -77,7 +85,7 @@ const StyledInput = styles_1.styled((_a) => {
|
|
|
77
85
|
},
|
|
78
86
|
},
|
|
79
87
|
}));
|
|
80
|
-
function StandardSelect({ placeholder, helperText, InputProps, SelectProps, children, color = 'primary', size = '
|
|
88
|
+
function StandardSelect({ placeholder, helperText, InputProps, SelectProps, children, color = 'primary', size = 'small', width = 'auto', paperMaxHeight = 'auto', error = false, hasShrink = false, value = '', disabled = false, }) {
|
|
81
89
|
const hasAdornment = !!(InputProps === null || InputProps === void 0 ? void 0 : InputProps.startAdornment);
|
|
82
90
|
const hasHelperText = !!helperText;
|
|
83
91
|
return (react_1.default.createElement(StyledFormControl, { color: color, size: size, width: width, disabled: disabled, error: error },
|
|
@@ -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,8 +1,7 @@
|
|
|
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
|
-
export { default as OutlinedSelect } from './lib/select/OutlinedSelect'
|
|
4
3
|
export { default as Button } from './lib/button/Button'
|
|
5
4
|
export { default as ButtonGroup } from './lib/button-group/ButtonGroup'
|
|
6
5
|
export { default as Radio } from './lib/radio/Radio'
|
|
7
6
|
export { default as TextField } from './lib/text-field/TextField'
|
|
8
|
-
export { default as
|
|
7
|
+
export { default as Select } from './lib/select/Select'
|
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
|
|
|
@@ -90,7 +91,9 @@ interface StyledOutlinedInputProps {
|
|
|
90
91
|
const StyledOutlinedInput = styled((props) => (
|
|
91
92
|
<OutlinedInput
|
|
92
93
|
classes={{
|
|
94
|
+
root: classes.outlineInputRoot,
|
|
93
95
|
input: classes.outlineInputInput,
|
|
96
|
+
focused: classes.outlineInputFocused,
|
|
94
97
|
inputMarginDense: classes.outlineInputInputMarginDense,
|
|
95
98
|
notchedOutline: classes.outlineInputNotchedOutline,
|
|
96
99
|
disabled: classes.outlineInputDisabled,
|
|
@@ -99,11 +102,19 @@ const StyledOutlinedInput = styled((props) => (
|
|
|
99
102
|
{...props}
|
|
100
103
|
/>
|
|
101
104
|
))(({ theme }: StyledOutlinedInputProps) => ({
|
|
105
|
+
[`&.${classes.outlineInputRoot}`]: {
|
|
106
|
+
[`&.${classes.outlineInputError}.${classes.outlineInputFocused} .${classes.outlineInputNotchedOutline}`]: {
|
|
107
|
+
borderColor: `${theme.palette.error.main}`,
|
|
108
|
+
},
|
|
109
|
+
[`& .${classes.outlineInputInputMarginDense}`]: {
|
|
110
|
+
padding: '14.5px 15px 14.5px 12px',
|
|
111
|
+
},
|
|
112
|
+
},
|
|
102
113
|
[`& .${classes.outlineInputInput}`]: {
|
|
103
114
|
color: theme.palette.text.primary,
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
115
|
+
['&:focus']: {
|
|
116
|
+
background: 'rgba(0,0,0,0)',
|
|
117
|
+
},
|
|
107
118
|
},
|
|
108
119
|
}))
|
|
109
120
|
|
|
@@ -131,7 +142,9 @@ const StyledSelect = styled(
|
|
|
131
142
|
horizontal: 'left',
|
|
132
143
|
},
|
|
133
144
|
getContentAnchorEl: null,
|
|
134
|
-
classes: {
|
|
145
|
+
classes: {
|
|
146
|
+
paper: className,
|
|
147
|
+
},
|
|
135
148
|
}}
|
|
136
149
|
{...props}
|
|
137
150
|
/>
|
|
@@ -143,40 +156,23 @@ const StyledSelect = styled(
|
|
|
143
156
|
},
|
|
144
157
|
}))
|
|
145
158
|
|
|
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 = ({
|
|
159
|
+
export const OutlinedSelect = ({
|
|
164
160
|
placeholder,
|
|
161
|
+
helperText,
|
|
162
|
+
InputProps,
|
|
165
163
|
SelectProps,
|
|
166
|
-
OutlinedInputProps,
|
|
167
164
|
children,
|
|
168
165
|
color = 'primary',
|
|
169
|
-
size = '
|
|
166
|
+
size = 'small',
|
|
170
167
|
width = 'auto',
|
|
171
168
|
paperMaxHeight = 'auto',
|
|
172
169
|
error = false,
|
|
173
170
|
hasLabel = true,
|
|
174
171
|
hasShrink = false,
|
|
175
|
-
helperText = '',
|
|
176
172
|
value = '',
|
|
177
173
|
disabled = false,
|
|
178
|
-
}:
|
|
179
|
-
const hasAdornment = !!
|
|
174
|
+
}: SelectProps) => {
|
|
175
|
+
const hasAdornment = !!InputProps?.startAdornment
|
|
180
176
|
const hasHelperText = !!helperText
|
|
181
177
|
return (
|
|
182
178
|
<StyledFormControl
|
|
@@ -204,7 +200,7 @@ const OutlinedSelect = ({
|
|
|
204
200
|
color={color}
|
|
205
201
|
label={hasLabel ? placeholder : undefined}
|
|
206
202
|
disabled={disabled}
|
|
207
|
-
{...
|
|
203
|
+
{...InputProps}
|
|
208
204
|
/>
|
|
209
205
|
}
|
|
210
206
|
{...SelectProps}
|