@luscii-healthtech/web-ui 2.0.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Accordion/Accordion.d.ts +10 -0
- package/dist/components/Accordion/AccordionItem.d.ts +9 -0
- package/dist/components/Form/Form.d.ts +9 -0
- package/dist/components/Form/FormFieldDecorator.d.ts +8 -0
- package/dist/components/Form/FormInput.d.ts +3 -0
- package/dist/components/Form/FormRadioGroup.d.ts +3 -0
- package/dist/components/Form/FormSelect.d.ts +3 -0
- package/dist/components/Form/form.transformer.d.ts +20 -0
- package/dist/components/Form/form.types.d.ts +54 -0
- package/dist/components/Input/Input.d.ts +8 -7
- package/dist/components/Input/SearchInput.d.ts +1 -1
- package/dist/components/List/List.d.ts +1 -1
- package/dist/components/List/List.types.d.ts +1 -0
- package/dist/components/List/ListItemSkeleton.d.ts +2 -0
- package/dist/components/List/ListSkeleton.d.ts +7 -0
- package/dist/components/Radio/Radio.d.ts +3 -0
- package/dist/components/Radio/RadioV2.d.ts +17 -0
- package/dist/components/RadioGroup/RadioGroup.d.ts +3 -0
- package/dist/components/RadioGroup/RadioGroupV2.d.ts +9 -0
- package/dist/components/Select/Select.d.ts +3 -0
- package/dist/components/Select/SelectV2.d.ts +31 -0
- package/dist/index.d.ts +2 -0
- package/dist/web-ui-tailwind.css +50 -0
- package/dist/web-ui.cjs.development.js +604 -40
- package/dist/web-ui.cjs.development.js.map +1 -1
- package/dist/web-ui.cjs.production.min.js +1 -1
- package/dist/web-ui.cjs.production.min.js.map +1 -1
- package/dist/web-ui.esm.js +604 -41
- package/dist/web-ui.esm.js.map +1 -1
- package/package.json +6 -3
- package/src/components/Accordion/Accordion.tsx +33 -0
- package/src/components/Accordion/AccordionItem.tsx +50 -0
- package/src/components/Form/Form.tsx +106 -0
- package/src/components/Form/FormFieldDecorator.tsx +66 -0
- package/src/components/Form/FormInput.tsx +47 -0
- package/src/components/Form/FormRadioGroup.tsx +23 -0
- package/src/components/Form/FormSelect.tsx +32 -0
- package/src/components/Form/form.transformer.ts +9 -0
- package/src/components/Form/form.types.ts +132 -0
- package/src/components/Input/Input.tsx +160 -165
- package/src/components/Input/SearchInput.tsx +13 -3
- package/src/components/List/List.tsx +13 -9
- package/src/components/List/List.types.ts +1 -0
- package/src/components/List/ListItemSkeleton.tsx +26 -0
- package/src/components/List/ListSkeleton.scss +5 -0
- package/src/components/List/ListSkeleton.tsx +30 -0
- package/src/components/Radio/Radio.js +3 -0
- package/src/components/Radio/RadioV2.css +15 -0
- package/src/components/Radio/RadioV2.tsx +87 -0
- package/src/components/RadioGroup/RadioGroup.js +3 -0
- package/src/components/RadioGroup/RadioGroupV2.tsx +35 -0
- package/src/components/Select/Select.tsx +38 -12
- package/src/components/Select/SelectV2.tsx +171 -0
- package/src/index.tsx +3 -0
- package/src/styles/_skeleton.scss +63 -0
- package/src/types/general.types.ts +1 -1
- package/src/components/Select/Select.examples.md +0 -161
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import classNames from "classnames";
|
|
3
|
+
|
|
4
|
+
import { RadioProps, RadioV2 } from "../Radio/RadioV2";
|
|
5
|
+
|
|
6
|
+
export interface RadioGroupProps
|
|
7
|
+
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "value"> {
|
|
8
|
+
name: string;
|
|
9
|
+
isError?: boolean;
|
|
10
|
+
options: Omit<RadioProps, "name">[];
|
|
11
|
+
innerRef?: React.Ref<HTMLInputElement>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function RadioGroupInner({
|
|
15
|
+
innerRef,
|
|
16
|
+
options,
|
|
17
|
+
...registerProps
|
|
18
|
+
}: RadioGroupProps): JSX.Element {
|
|
19
|
+
return (
|
|
20
|
+
<div className={classNames("flex flex-col space-y-2")}>
|
|
21
|
+
{options.map((option) => (
|
|
22
|
+
<RadioV2
|
|
23
|
+
key={option.value}
|
|
24
|
+
{...option}
|
|
25
|
+
{...registerProps}
|
|
26
|
+
ref={innerRef}
|
|
27
|
+
/>
|
|
28
|
+
))}
|
|
29
|
+
</div>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const RadioGroupV2 = React.forwardRef<HTMLInputElement, RadioGroupProps>(
|
|
34
|
+
(props, ref) => <RadioGroupInner {...props} innerRef={ref} />
|
|
35
|
+
);
|
|
@@ -13,10 +13,11 @@ import Select from "react-select/base";
|
|
|
13
13
|
*/
|
|
14
14
|
import "./Select.scss";
|
|
15
15
|
|
|
16
|
-
function generateCustomStyles<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
function generateCustomStyles<
|
|
17
|
+
Option,
|
|
18
|
+
IsMulti extends boolean,
|
|
19
|
+
Group extends GroupBase<Option>
|
|
20
|
+
>(hasError: boolean, isIE11: boolean): StylesConfig<Option, IsMulti, Group> {
|
|
20
21
|
return {
|
|
21
22
|
option: (baseStyles, state) => {
|
|
22
23
|
return {
|
|
@@ -47,8 +48,12 @@ function generateCustomStyles<Option, IsMulti extends boolean, Group extends Gro
|
|
|
47
48
|
const defaultBorderColor = state.isFocused ? "#045baa" : "#D1D5DB";
|
|
48
49
|
const validatedBorderColor = hasError ? "#c53030" : defaultBorderColor;
|
|
49
50
|
|
|
50
|
-
const defaultOutline = hasError
|
|
51
|
-
|
|
51
|
+
const defaultOutline = hasError
|
|
52
|
+
? "rgba(255, 98, 102, 0.3)"
|
|
53
|
+
: "rgba(0, 159, 227, 0.3)";
|
|
54
|
+
const validatedOutline = `4px solid ${
|
|
55
|
+
state.isFocused ? defaultOutline : "transparent"
|
|
56
|
+
}`;
|
|
52
57
|
|
|
53
58
|
return {
|
|
54
59
|
...baseStyles,
|
|
@@ -101,24 +106,45 @@ function generateCustomStyles<Option, IsMulti extends boolean, Group extends Gro
|
|
|
101
106
|
};
|
|
102
107
|
}
|
|
103
108
|
|
|
104
|
-
type CustomSelect = <
|
|
109
|
+
type CustomSelect = <
|
|
110
|
+
Option,
|
|
111
|
+
IsMulti extends boolean,
|
|
112
|
+
Group extends GroupBase<Option>
|
|
113
|
+
>(
|
|
105
114
|
props: Props<Option, IsMulti, Group>,
|
|
106
115
|
ref: React.RefAttributes<SelectInstance<Option, IsMulti, Group>>
|
|
107
116
|
) => React.ReactElement;
|
|
108
117
|
|
|
118
|
+
/**
|
|
119
|
+
* @deprecated: use SelectV2 instead
|
|
120
|
+
*/
|
|
109
121
|
const CustomSelect = React.forwardRef(
|
|
110
122
|
<Option, IsMulti extends boolean, Group extends GroupBase<Option>>(
|
|
111
123
|
props: Props<Option, IsMulti, Group>,
|
|
112
|
-
ref: Ref<Select<Option, IsMulti, Group
|
|
124
|
+
ref: Ref<Select<Option, IsMulti, Group>>
|
|
113
125
|
) => {
|
|
114
126
|
const { className, styles } = props;
|
|
115
127
|
|
|
116
128
|
const hasError = className?.includes("has-error") || false;
|
|
117
|
-
const isIE11 =
|
|
118
|
-
|
|
119
|
-
const
|
|
129
|
+
const isIE11 =
|
|
130
|
+
"MSInputMethodContext" in window && "documentMode" in document;
|
|
131
|
+
const customStyles = generateCustomStyles<Option, IsMulti, Group>(
|
|
132
|
+
hasError,
|
|
133
|
+
isIE11
|
|
134
|
+
);
|
|
135
|
+
const mergedStyles = mergeStyles<Option, IsMulti, Group>(
|
|
136
|
+
customStyles,
|
|
137
|
+
styles
|
|
138
|
+
);
|
|
120
139
|
|
|
121
|
-
return
|
|
140
|
+
return (
|
|
141
|
+
<ReactSelect<Option, IsMulti, Group>
|
|
142
|
+
{...props}
|
|
143
|
+
ref={ref}
|
|
144
|
+
className={classNames("customized-select", className)}
|
|
145
|
+
styles={mergedStyles}
|
|
146
|
+
/>
|
|
147
|
+
);
|
|
122
148
|
}
|
|
123
149
|
) as CustomSelect;
|
|
124
150
|
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
MultiValue,
|
|
3
|
+
OptionsOrGroups,
|
|
4
|
+
Props,
|
|
5
|
+
StylesConfig,
|
|
6
|
+
GroupBase, Options,
|
|
7
|
+
} from "react-select";
|
|
8
|
+
import ReactSelect, { mergeStyles } from "react-select";
|
|
9
|
+
import React from "react";
|
|
10
|
+
import classNames from "classnames";
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Exceptional case for this file:
|
|
16
|
+
* We use postcss-url to inline and base64 our image assets.
|
|
17
|
+
* But the library can only see as far as css files.
|
|
18
|
+
* When javascript gets in the way (react-select uses a package called `emotion` for styles), postcss-url cannot
|
|
19
|
+
* bundle the svg assets used here, and we end up with some broken style.
|
|
20
|
+
*/
|
|
21
|
+
import "./Select.scss";
|
|
22
|
+
|
|
23
|
+
function generateCustomStyles<Option, IsMulti extends boolean, Group extends GroupBase<Option>>(
|
|
24
|
+
hasError: boolean,
|
|
25
|
+
isIE11: boolean,
|
|
26
|
+
): StylesConfig<Option, IsMulti, Group> {
|
|
27
|
+
return {
|
|
28
|
+
option: (baseStyles, state) => {
|
|
29
|
+
return {
|
|
30
|
+
...baseStyles,
|
|
31
|
+
fontWeight: state.isSelected ? "bold" : "normal",
|
|
32
|
+
fontSize: "14px",
|
|
33
|
+
backgroundColor: "none",
|
|
34
|
+
color: "inherit",
|
|
35
|
+
position: "relative",
|
|
36
|
+
padding: "0.75rem",
|
|
37
|
+
opacity: state.isDisabled ? "0.5" : 1,
|
|
38
|
+
"&:after": {
|
|
39
|
+
visibility: state.isSelected ? "visible" : "hidden",
|
|
40
|
+
},
|
|
41
|
+
transition: "background-color 0.3s ease-in-out",
|
|
42
|
+
"&:hover": {
|
|
43
|
+
// tailwind blue-50
|
|
44
|
+
backgroundColor: state.isSelected ? "transparent" : "#F2FAFD",
|
|
45
|
+
},
|
|
46
|
+
pointerEvents: state.isDisabled ? "none" : "auto",
|
|
47
|
+
};
|
|
48
|
+
},
|
|
49
|
+
container: (baseStyles) => {
|
|
50
|
+
return { ...baseStyles, flexGrow: isIE11 ? 0.5 : "initial" };
|
|
51
|
+
},
|
|
52
|
+
control: (baseStyles, state) => {
|
|
53
|
+
const defaultBorderColor = state.isFocused ? "#045baa" : "#D1D5DB";
|
|
54
|
+
const validatedBorderColor = hasError ? "#c53030" : defaultBorderColor;
|
|
55
|
+
|
|
56
|
+
const defaultOutline = hasError ? "rgba(255, 98, 102, 0.3)" : "rgba(0, 159, 227, 0.3)";
|
|
57
|
+
const validatedOutline = `4px solid ${state.isFocused ? defaultOutline : "transparent"}`;
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
...baseStyles,
|
|
61
|
+
fontSize: "14px",
|
|
62
|
+
transition: "border 0.3s ease-in-out",
|
|
63
|
+
height: isIE11 ? "50px" : "2.75rem",
|
|
64
|
+
|
|
65
|
+
// primary outline
|
|
66
|
+
outline: validatedOutline,
|
|
67
|
+
|
|
68
|
+
borderColor: validatedBorderColor,
|
|
69
|
+
borderWidth: "1px !important",
|
|
70
|
+
borderStyle: "solid",
|
|
71
|
+
borderRadius: "4px",
|
|
72
|
+
|
|
73
|
+
boxShadow: "0px 1px 2px rgba(0, 0, 0, 0.05)",
|
|
74
|
+
|
|
75
|
+
"&:hover": {
|
|
76
|
+
borderColor: "#9CA3AF",
|
|
77
|
+
// selector for the chevron
|
|
78
|
+
"> [class*=\"IndicatorsContainer\"]": {
|
|
79
|
+
opacity: 1,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
},
|
|
84
|
+
// The placeholder has the following css prop: grid-area: 1/1/2/3;
|
|
85
|
+
// And grid-area doesn't work on IE11, so we need to style it slightly different.
|
|
86
|
+
placeholder: (baseStyles) => ({
|
|
87
|
+
...baseStyles,
|
|
88
|
+
fontWeight: 100,
|
|
89
|
+
color: "#6B7280",
|
|
90
|
+
paddingTop: isIE11 ? "1.2rem" : undefined,
|
|
91
|
+
}),
|
|
92
|
+
singleValue: (baseStyles) => {
|
|
93
|
+
return {
|
|
94
|
+
...baseStyles,
|
|
95
|
+
paddingTop: isIE11 ? "1.2rem" : undefined,
|
|
96
|
+
fontSize: "14px",
|
|
97
|
+
};
|
|
98
|
+
},
|
|
99
|
+
indicatorSeparator: () => ({
|
|
100
|
+
display: "none",
|
|
101
|
+
}),
|
|
102
|
+
menu: (baseStyles) => ({
|
|
103
|
+
...baseStyles,
|
|
104
|
+
zIndex: 20,
|
|
105
|
+
}),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// All the options require a value to work in the wrapper
|
|
110
|
+
interface OptionMinimal {
|
|
111
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
112
|
+
value: any;
|
|
113
|
+
label?: string;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
117
|
+
export interface SelectProps<Option extends OptionMinimal = OptionMinimal, IsMulti extends boolean = any, Group extends GroupBase<Option> = GroupBase<Option>> extends Props<Option, IsMulti, Group> {
|
|
118
|
+
isError?: boolean;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* A wrapper around react-select to style it according to our design specification.
|
|
123
|
+
*
|
|
124
|
+
* In addition, the value is taken out of the option, instead of returning the complete option.
|
|
125
|
+
*
|
|
126
|
+
* Care when using grouped options: the value of the options overspanning all groups need to be unique!
|
|
127
|
+
* For instance, if you have an option with value "chocolate" in both the groups "flavor" and "dip", then you get unforeseen errors.
|
|
128
|
+
* This is a problem within react-select itself, not our wrapper.
|
|
129
|
+
*
|
|
130
|
+
* Care when using defaultValue: this still requires the complete Option (instead of the value of the Option).
|
|
131
|
+
* So far there wasn't a use-case for this.
|
|
132
|
+
*/
|
|
133
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
134
|
+
export const Select = React.forwardRef(<Option extends OptionMinimal, IsMulti extends boolean, Group extends GroupBase<Option>>(
|
|
135
|
+
{ isError = false, styles, options, onChange, value, isMulti, className, ...otherProps }: SelectProps<Option, IsMulti, Group>,
|
|
136
|
+
innerRef,
|
|
137
|
+
) => {
|
|
138
|
+
const isIE11 = "MSInputMethodContext" in window && "documentMode" in document;
|
|
139
|
+
const customStyles = generateCustomStyles<Option, IsMulti, Group>(isError, isIE11);
|
|
140
|
+
const mergedStyles = mergeStyles<Option, IsMulti, Group>(customStyles, styles);
|
|
141
|
+
|
|
142
|
+
// the options can be either a list of options or a grouped list of options
|
|
143
|
+
// this is a typechecker to verify it is the case.
|
|
144
|
+
const isOptionsGrouped = !options ? false : (options as OptionsOrGroups<Option, Group>)
|
|
145
|
+
.reduce((acc, o) => acc || ("options" in o && !("values" in o)), false);
|
|
146
|
+
// we subsequently flatmap to ensure it's always a list of options
|
|
147
|
+
const flatmappedOptions = !options ? [] : isOptionsGrouped
|
|
148
|
+
? (options as Group[]).flatMap((g) => g.options)
|
|
149
|
+
: options as Options<Option>;
|
|
150
|
+
|
|
151
|
+
// based on: https://stackoverflow.com/a/70022957
|
|
152
|
+
const onChangeWrapped = !onChange ? undefined : isMulti
|
|
153
|
+
? (val, a) => onChange(val.map((v) => v.value), a)
|
|
154
|
+
: (val, a) => onChange(val?.value, a);
|
|
155
|
+
// TODO: how can we report the error if a value was given that is not within the options?
|
|
156
|
+
const valueWrapped = (!value || !options) ? value : isMulti
|
|
157
|
+
? flatmappedOptions.filter((o) => (value as MultiValue<Option>).includes(o.value))
|
|
158
|
+
: flatmappedOptions.find((o) => o.value === value);
|
|
159
|
+
|
|
160
|
+
return <ReactSelect
|
|
161
|
+
{...otherProps}
|
|
162
|
+
ref={innerRef}
|
|
163
|
+
styles={mergedStyles}
|
|
164
|
+
options={options}
|
|
165
|
+
onChange={onChangeWrapped}
|
|
166
|
+
value={valueWrapped}
|
|
167
|
+
isMulti={isMulti}
|
|
168
|
+
className={classNames("customized-select", className)}
|
|
169
|
+
/>;
|
|
170
|
+
},
|
|
171
|
+
);
|
package/src/index.tsx
CHANGED
|
@@ -113,6 +113,9 @@ export { default as Text } from "./components/Text/Text";
|
|
|
113
113
|
|
|
114
114
|
export { SearchInput, SearchInputProps } from "./components/Input/SearchInput";
|
|
115
115
|
|
|
116
|
+
export { Form } from "./components/Form/Form";
|
|
117
|
+
export { FormProps } from "./components/Form/form.types";
|
|
118
|
+
|
|
116
119
|
export { IconProps } from "./components/Icons/types/IconProps.type";
|
|
117
120
|
export { AddIcon } from "./components/Icons/AddIcon";
|
|
118
121
|
export { AlertsIcon } from "./components/Icons/AlertsIcon";
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
@mixin skeleton() {
|
|
2
|
+
.skeleton-box {
|
|
3
|
+
display: inline-block;
|
|
4
|
+
height: 1em;
|
|
5
|
+
position: relative;
|
|
6
|
+
overflow: hidden;
|
|
7
|
+
background-color: #cbd5e1; //slate 300
|
|
8
|
+
border-radius: 3px;
|
|
9
|
+
|
|
10
|
+
&::after {
|
|
11
|
+
position: absolute;
|
|
12
|
+
top: 0;
|
|
13
|
+
right: 0;
|
|
14
|
+
bottom: 0;
|
|
15
|
+
left: 0;
|
|
16
|
+
transform: translateX(-100%);
|
|
17
|
+
background-image: linear-gradient(
|
|
18
|
+
90deg,
|
|
19
|
+
rgba(#fff, 0) 0,
|
|
20
|
+
rgba(#fff, 0.2) 20%,
|
|
21
|
+
rgba(#fff, 0.5) 60%,
|
|
22
|
+
rgba(#fff, 0)
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
animation: shimmer 800ms infinite;
|
|
26
|
+
content: "";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&.is-circle {
|
|
30
|
+
border-radius: 50%;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
&.is-button {
|
|
34
|
+
background-color: #e2e8f0; //secondary button color
|
|
35
|
+
border-radius: 9999px;
|
|
36
|
+
|
|
37
|
+
&::after {
|
|
38
|
+
position: absolute;
|
|
39
|
+
top: 0;
|
|
40
|
+
right: 0;
|
|
41
|
+
bottom: 0;
|
|
42
|
+
left: 0;
|
|
43
|
+
transform: translateX(-100%);
|
|
44
|
+
background-image: linear-gradient(
|
|
45
|
+
90deg,
|
|
46
|
+
rgba(#ddd, 0) 0,
|
|
47
|
+
rgba(#ddd, 0.2) 20%,
|
|
48
|
+
rgba(#ddd, 0.5) 60%,
|
|
49
|
+
rgba(#ddd, 0)
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
animation: shimmer 800ms infinite;
|
|
53
|
+
content: "";
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@keyframes shimmer {
|
|
58
|
+
100% {
|
|
59
|
+
transform: translateX(100%);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// This type is used to allow for other props to be injected into the component
|
|
2
|
-
// For instance, for a data-
|
|
2
|
+
// For instance, for a data-test-id or key
|
|
3
3
|
export interface RestPropped {
|
|
4
4
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5
5
|
[key: string]: any;
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
```js
|
|
2
|
-
class SelectExample extends React.Component {
|
|
3
|
-
constructor(props) {
|
|
4
|
-
super(props);
|
|
5
|
-
|
|
6
|
-
this.state = {
|
|
7
|
-
value: null,
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
this.handleChange = this.handleChange.bind(this);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
handleChange(event) {
|
|
14
|
-
this.setState({
|
|
15
|
-
value: event.target.value,
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
render() {
|
|
20
|
-
return (
|
|
21
|
-
<div>
|
|
22
|
-
<Select
|
|
23
|
-
value={this.state.value}
|
|
24
|
-
name="value"
|
|
25
|
-
options={[
|
|
26
|
-
{
|
|
27
|
-
value: "option1",
|
|
28
|
-
text: "Option1",
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
value: "option2",
|
|
32
|
-
text: "Option2",
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
value: "option3",
|
|
36
|
-
text: "Option3",
|
|
37
|
-
},
|
|
38
|
-
]}
|
|
39
|
-
onChange={this.handleChange}
|
|
40
|
-
/>
|
|
41
|
-
</div>
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
<SelectExample />;
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
```js
|
|
49
|
-
class SelectExampleWithPlaceholder extends React.Component {
|
|
50
|
-
constructor(props) {
|
|
51
|
-
super(props);
|
|
52
|
-
|
|
53
|
-
this.state = {
|
|
54
|
-
value: null,
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
this.handleChange = this.handleChange.bind(this);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
handleChange(event) {
|
|
61
|
-
this.setState({
|
|
62
|
-
value: event.target.value,
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
render() {
|
|
67
|
-
return (
|
|
68
|
-
<div>
|
|
69
|
-
<Select
|
|
70
|
-
value={this.state.value}
|
|
71
|
-
name="value"
|
|
72
|
-
placeholder="Please select an option"
|
|
73
|
-
options={[
|
|
74
|
-
{
|
|
75
|
-
value: "option1",
|
|
76
|
-
text: "Option1",
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
value: "option2",
|
|
80
|
-
text: "Option2",
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
value: "option3",
|
|
84
|
-
text: "Option3",
|
|
85
|
-
},
|
|
86
|
-
]}
|
|
87
|
-
onChange={this.handleChange}
|
|
88
|
-
/>
|
|
89
|
-
</div>
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
<SelectExampleWithPlaceholder />;
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
```js
|
|
97
|
-
const inForm = require("../HOCs/form/helpers/inForm").default;
|
|
98
|
-
const SelectInForm = inForm(Select);
|
|
99
|
-
|
|
100
|
-
class SelectExampleInForm extends React.Component {
|
|
101
|
-
constructor(props) {
|
|
102
|
-
super(props);
|
|
103
|
-
|
|
104
|
-
this.state = {
|
|
105
|
-
value: null,
|
|
106
|
-
error: null,
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
this.handleChange = this.handleChange.bind(this);
|
|
110
|
-
this.handleError = this.handleError.bind(this);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
handleChange(event) {
|
|
114
|
-
this.setState({
|
|
115
|
-
value: event.target.value,
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
handleError() {
|
|
120
|
-
this.setState((prevState) => {
|
|
121
|
-
return {
|
|
122
|
-
error: prevState.error ? null : "This field is required",
|
|
123
|
-
};
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
render() {
|
|
128
|
-
return (
|
|
129
|
-
<div className="styleguide-in-form styleguide-component-block">
|
|
130
|
-
<Title type="tagline" text={"Example Select use in Form"} />
|
|
131
|
-
|
|
132
|
-
<SelectInForm
|
|
133
|
-
label="Field Label"
|
|
134
|
-
error={this.state.error}
|
|
135
|
-
value={this.state.value}
|
|
136
|
-
name="value"
|
|
137
|
-
placeholder="Please select an option"
|
|
138
|
-
options={[
|
|
139
|
-
{
|
|
140
|
-
value: "option1",
|
|
141
|
-
text: "Option1",
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
value: "option2",
|
|
145
|
-
text: "Option2",
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
value: "option3",
|
|
149
|
-
text: "Option3",
|
|
150
|
-
},
|
|
151
|
-
]}
|
|
152
|
-
onChange={this.handleChange}
|
|
153
|
-
/>
|
|
154
|
-
|
|
155
|
-
<Button text="Toggle ErrorWrapper" className="styleguide-margin-top-10" onClick={this.handleError} />
|
|
156
|
-
</div>
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
<SelectExampleInForm />;
|
|
161
|
-
```
|