@agility/plenum-ui 2.0.0-rc8 → 2.0.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/README.md +104 -31
- package/build.js +30 -25
- package/dist/index.d.ts +105 -65
- package/dist/index.js +1 -6295
- package/dist/index.js.map +4 -4
- package/dist/{lib/tailwind.css → tailwind.css} +3729 -8120
- package/dist/types/stories/atoms/buttons/Button/Alternative/Alternative.stories.d.ts +1 -0
- package/dist/types/stories/atoms/buttons/Button/Button.d.ts +3 -7
- package/dist/types/stories/atoms/buttons/Button/Danger/Danger.stories.d.ts +1 -0
- package/dist/types/stories/atoms/buttons/Button/Primary/Primary.stories.d.ts +1 -0
- package/dist/types/stories/atoms/buttons/Button/Secondary/Secondary.stories.d.ts +1 -0
- package/dist/types/stories/atoms/buttons/Capsule/Capsule.d.ts +1 -1
- package/dist/types/stories/atoms/icons/DynamicIcon.d.ts +2 -2
- package/dist/types/stories/atoms/icons/TablerIcon.d.ts +1 -1
- package/dist/types/stories/index.d.ts +4 -4
- package/dist/types/stories/molecules/index.d.ts +2 -2
- package/dist/types/stories/molecules/inputs/InputField/InputField.d.ts +7 -7
- package/dist/types/stories/molecules/inputs/TextInput/TextInput.d.ts +1 -1
- package/dist/types/stories/molecules/inputs/index.d.ts +2 -2
- package/dist/types/stories/molecules/inputs/select/Select.d.ts +4 -2
- package/dist/types/stories/molecules/inputs/textArea/TextArea.d.ts +5 -1
- package/dist/types/stories/molecules/inputs/toggleSwitch/ToggleSwitch.d.ts +10 -7
- package/dist/types/stories/organisms/AnimatedLabelInput/AnimatedLabelInput.d.ts +5 -5
- package/dist/types/stories/organisms/AnimatedLabelInput/index.d.ts +1 -1
- package/dist/types/stories/organisms/AnimatedLabelTextArea/AnimatedLabelTextArea.d.ts +12 -0
- package/dist/types/stories/organisms/AnimatedLabelTextArea/index.d.ts +3 -0
- package/dist/types/stories/organisms/ButtonDropdown/ButtonDropdown.d.ts +1 -0
- package/dist/types/stories/organisms/DropdownComponent/DropdownComponent.d.ts +24 -13
- package/dist/types/stories/organisms/DropdownComponent/index.d.ts +2 -2
- package/dist/types/stories/organisms/EmptySectionPlaceholder/index.d.ts +1 -1
- package/dist/types/stories/organisms/index.d.ts +4 -3
- package/local.sh +100 -0
- package/package.json +36 -19
- package/rollup.config.mjs +42 -0
- package/stories/atoms/badges/Badge.tsx +1 -1
- package/stories/atoms/buttons/Button/Alternative/Alternative.stories.ts +10 -0
- package/stories/atoms/buttons/Button/Button.tsx +111 -25
- package/stories/atoms/buttons/Button/Danger/Danger.stories.ts +14 -2
- package/stories/atoms/buttons/Button/Primary/Primary.stories.ts +14 -2
- package/stories/atoms/buttons/Button/Secondary/Secondary.stories.ts +13 -1
- package/stories/atoms/buttons/Button/defaultArgs.ts +1 -1
- package/stories/atoms/buttons/Capsule/Capsule.tsx +2 -1
- package/stories/atoms/icons/DynamicIcon.stories.ts +1 -1
- package/stories/atoms/icons/DynamicIcon.tsx +7 -7
- package/stories/atoms/icons/IconWithShadow.stories.ts +3 -3
- package/stories/atoms/icons/TablerIcon.tsx +1 -1
- package/stories/atoms/loaders/Loader.tsx +12 -6
- package/stories/atoms/loaders/NProgress/RadialProgress.tsx +0 -2
- package/stories/index.ts +8 -4
- package/stories/molecules/index.ts +2 -0
- package/stories/molecules/inputs/InputCounter/InputCounter.tsx +2 -2
- package/stories/molecules/inputs/InputField/InputField.tsx +31 -29
- package/stories/molecules/inputs/InputLabel/InputLabel.tsx +1 -1
- package/stories/molecules/inputs/TextInput/TextInput.tsx +12 -6
- package/stories/molecules/inputs/checkbox/Checkbox.stories.ts +1 -1
- package/stories/molecules/inputs/checkbox/Checkbox.tsx +1 -2
- package/stories/molecules/inputs/combobox/ComboBox.tsx +126 -135
- package/stories/molecules/inputs/index.ts +2 -1
- package/stories/molecules/inputs/radio/Radio.stories.ts +2 -2
- package/stories/molecules/inputs/select/Select.tsx +10 -2
- package/stories/molecules/inputs/textArea/TextArea.stories.ts +1 -1
- package/stories/molecules/inputs/textArea/TextArea.tsx +57 -27
- package/stories/molecules/inputs/toggleSwitch/ToggleSwitch.stories.tsx +15 -16
- package/stories/molecules/inputs/toggleSwitch/ToggleSwitch.tsx +63 -57
- package/stories/molecules/tabs/index.tsx +2 -3
- package/stories/organisms/AnimatedLabelInput/AnimatedLabelInput.stories.tsx +10 -1
- package/stories/organisms/AnimatedLabelInput/AnimatedLabelInput.tsx +53 -37
- package/stories/organisms/AnimatedLabelInput/index.tsx +1 -1
- package/stories/organisms/AnimatedLabelTextArea/AnimatedLabelTextArea.stories.tsx +26 -0
- package/stories/organisms/AnimatedLabelTextArea/AnimatedLabelTextArea.tsx +61 -0
- package/stories/organisms/AnimatedLabelTextArea/index.tsx +3 -0
- package/stories/organisms/ButtonDropdown/ButtonDropdown.stories.tsx +59 -59
- package/stories/organisms/ButtonDropdown/ButtonDropdown.tsx +42 -30
- package/stories/organisms/DropdownComponent/Dropdown.stories.tsx +26 -2
- package/stories/organisms/DropdownComponent/DropdownComponent.tsx +232 -180
- package/stories/organisms/DropdownComponent/dropdownItems.ts +30 -9
- package/stories/organisms/DropdownComponent/index.ts +2 -2
- package/stories/organisms/EmptySectionPlaceholder/EmptySectionPlaceholder.stories.tsx +3 -3
- package/stories/organisms/EmptySectionPlaceholder/index.tsx +2 -1
- package/stories/organisms/FormInputWithAddons/FormInputWithAddons.stories.tsx +1 -1
- package/stories/organisms/FormInputWithAddons/FormInputWithAddons.tsx +7 -2
- package/stories/organisms/index.ts +12 -3
- package/tailwind.config.js +81 -37
- package/tsconfig.lib.json +13 -6
- package/watch.js +49 -0
- package/.yarnrc.yml +0 -1
- package/dist/types/stories/layouts/index.d.ts +0 -0
- package/stories/layouts/CardLayout/CardLayout.stories.tsx +0 -18
- package/stories/layouts/CardLayout/CardLayout.tsx +0 -22
- package/stories/layouts/CardLayout/index.tsx +0 -3
- package/stories/layouts/ModalLayout/ModalLayout.stories.tsx +0 -18
- package/stories/layouts/ModalLayout/ModalLayout.tsx +0 -22
- package/stories/layouts/ModalLayout/index.tsx +0 -3
- package/stories/layouts/index.ts +0 -0
- package/stories/organisms/DropdownComponent/Dropdown.test.tsx +0 -0
|
@@ -32,7 +32,7 @@ export interface ITextInputProps {
|
|
|
32
32
|
/** Max length of input character */
|
|
33
33
|
maxLength?: number
|
|
34
34
|
/** Callback on change */
|
|
35
|
-
|
|
35
|
+
handleChange(value: string): void
|
|
36
36
|
/** input value */
|
|
37
37
|
value: string
|
|
38
38
|
/**Placeholder input text*/
|
|
@@ -56,7 +56,7 @@ const TextInput = (
|
|
|
56
56
|
message,
|
|
57
57
|
isShowCounter,
|
|
58
58
|
maxLength,
|
|
59
|
-
|
|
59
|
+
handleChange,
|
|
60
60
|
placeholder,
|
|
61
61
|
value: externalValue,
|
|
62
62
|
className,
|
|
@@ -116,20 +116,26 @@ const TextInput = (
|
|
|
116
116
|
<InputField
|
|
117
117
|
onFocus={handleInputFocus}
|
|
118
118
|
onBlur={handleInputBlur}
|
|
119
|
-
handleChange={(v) =>
|
|
119
|
+
handleChange={(v: string) => {
|
|
120
|
+
setValue(v)
|
|
121
|
+
handleChange(v)
|
|
122
|
+
}}
|
|
120
123
|
ref={ref}
|
|
121
124
|
type={type}
|
|
122
125
|
name={name}
|
|
123
126
|
id={id}
|
|
124
127
|
className={cn(
|
|
125
128
|
"w-full rounded border py-2 px-3 text-sm font-normal leading-5",
|
|
126
|
-
{ "border-gray-300": !isFocus && !isError },
|
|
129
|
+
{ "border-gray-300": !isFocus && !isError && !isDisabled },
|
|
127
130
|
{
|
|
128
|
-
"!border-purple-500 shadow-none outline-purple-500 focus:!ring-purple-500": isFocus && !isError
|
|
131
|
+
"!border-purple-500 shadow-none outline-purple-500 focus:!ring-purple-500": isFocus && !isError && !isDisabled
|
|
129
132
|
},
|
|
130
133
|
{
|
|
131
134
|
"!border-red-500 shadow-none focus:ring-red-500": isError
|
|
132
135
|
},
|
|
136
|
+
{
|
|
137
|
+
"placeholder:text-gray-300 !border-gray-300 !outline-gray-300 focus:!ring-gray-300" : isDisabled
|
|
138
|
+
},
|
|
133
139
|
className
|
|
134
140
|
)}
|
|
135
141
|
isDisabled={isDisabled}
|
|
@@ -150,7 +156,7 @@ const TextInput = (
|
|
|
150
156
|
</div>
|
|
151
157
|
{isShowCounter && (
|
|
152
158
|
<div className="shrink-0">
|
|
153
|
-
<InputCounter current={Number(value?.length)} limit={maxLength} />
|
|
159
|
+
<InputCounter current={Number(value?.length)} limit={maxLength ?? 150} />
|
|
154
160
|
</div>
|
|
155
161
|
)}
|
|
156
162
|
</div>
|
|
@@ -53,13 +53,12 @@ const Checkbox: FC<ICheckboxProps> = ({
|
|
|
53
53
|
const wrapperStyles = cn(
|
|
54
54
|
"relative flex items-center min-h-[38px]",
|
|
55
55
|
{ "opacity-50": isDisabled },
|
|
56
|
-
{ "rounded-sm
|
|
56
|
+
{ "rounded-sm border border-1 px-3 border-gray-200": hasBorder },
|
|
57
57
|
{ "py-3": hasBorder && message },
|
|
58
58
|
className
|
|
59
59
|
)
|
|
60
60
|
|
|
61
61
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
62
|
-
console.log(e)
|
|
63
62
|
const targetValue = e.target.value
|
|
64
63
|
const targetChecked = e.target.checked
|
|
65
64
|
typeof onChange === "function" && onChange(targetValue, targetChecked)
|
|
@@ -44,151 +44,142 @@ function classNames(...classes: string[]) {
|
|
|
44
44
|
return classes.filter(Boolean).join(" ")
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
47
|
+
const Combobox = <T extends Record<string, unknown>>({
|
|
48
|
+
label,
|
|
49
|
+
items,
|
|
50
|
+
displayProperty,
|
|
51
|
+
displayValue,
|
|
52
|
+
keyProperty,
|
|
53
|
+
onChange,
|
|
54
|
+
placeholder,
|
|
55
|
+
message,
|
|
56
|
+
isDisabled,
|
|
57
|
+
isError,
|
|
58
|
+
isRequired,
|
|
59
|
+
id,
|
|
60
|
+
nullable
|
|
61
|
+
}: IComboboxProps<T>) => {
|
|
62
|
+
const [query, setQuery] = useState<string>("")
|
|
63
|
+
const [selectedItem, setSelectedItem] = useState<T | undefined>()
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
65
|
+
const onChangeValue = (value: T | undefined) => {
|
|
66
|
+
if (value && selectedItem && value[keyProperty] === selectedItem[keyProperty]) {
|
|
67
|
+
setSelectedItem(undefined)
|
|
68
|
+
} else {
|
|
69
|
+
setSelectedItem(value)
|
|
71
70
|
}
|
|
71
|
+
}
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
if (displayValue) {
|
|
75
|
+
const dv = items.find((i) => i[displayProperty] === displayValue)
|
|
76
|
+
setSelectedItem(dv)
|
|
77
|
+
}
|
|
78
|
+
}, [displayValue])
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
typeof onChange === "function" && onChange(selectedItem)
|
|
82
|
+
}, [selectedItem])
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
84
|
+
const filteredItems =
|
|
85
|
+
query === ""
|
|
86
|
+
? items
|
|
87
|
+
: items.filter((item) => {
|
|
88
|
+
return `${item[displayProperty]}`.toLowerCase().includes(query.toLowerCase())
|
|
89
|
+
})
|
|
90
|
+
const labelStyles = cn("block text-sm font-medium text-gray-700")
|
|
91
|
+
const buttonStyles = cn("absolute inset-y-0 right-0 flex items-center rounded-r px-2 focus:outline-none")
|
|
92
|
+
const optionStyles = cn(
|
|
93
|
+
"absolute z-30 mt-1 max-h-60 w-full overflow-auto rounded bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm"
|
|
94
|
+
)
|
|
95
|
+
return (
|
|
96
|
+
<HeadlessUICombobox
|
|
97
|
+
as="div"
|
|
98
|
+
value={selectedItem}
|
|
99
|
+
onChange={(e: T | undefined) => onChangeValue(e)}
|
|
100
|
+
disabled={isDisabled}
|
|
101
|
+
nullable={nullable ? undefined : false}
|
|
102
|
+
>
|
|
103
|
+
{label && (
|
|
104
|
+
<HeadlessUICombobox.Label className={labelStyles}>
|
|
105
|
+
<InputLabel
|
|
106
|
+
isPlaceholder
|
|
107
|
+
isActive
|
|
108
|
+
label={label}
|
|
109
|
+
isRequired={isRequired}
|
|
110
|
+
id={id}
|
|
111
|
+
isError={isError}
|
|
112
|
+
isDisabled={isDisabled}
|
|
113
|
+
/>
|
|
114
|
+
</HeadlessUICombobox.Label>
|
|
115
|
+
)}
|
|
116
|
+
<div className="relative">
|
|
116
117
|
<div className="relative">
|
|
117
|
-
<
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
118
|
+
<HeadlessUICombobox.Input
|
|
119
|
+
className={`w-full rounded border border-gray-300 focus:border-purple-500 focus:outline-none focus:ring-1 focus:ring-purple-500 sm:text-sm ${
|
|
120
|
+
isError ? "border-red-500" : ""
|
|
121
|
+
}`}
|
|
122
|
+
onChange={(event) => setQuery(event.target.value)}
|
|
123
|
+
displayValue={(item: Record<string, unknown>) => `${item ? item[displayProperty] : ""}`}
|
|
124
|
+
placeholder={placeholder}
|
|
125
|
+
/>
|
|
126
|
+
{selectedItem && nullable && (
|
|
127
|
+
<button
|
|
128
|
+
className="absolute right-8 top-[1px] h-9 w-5 text-gray-400 hover:text-gray-500"
|
|
129
|
+
onClick={() => setSelectedItem(undefined)}
|
|
130
|
+
>
|
|
131
|
+
<DynamicIcon icon="IconX" className="h-4 w-4 " aria-hidden="true" />
|
|
132
|
+
</button>
|
|
133
|
+
)}
|
|
134
|
+
</div>
|
|
135
|
+
<HeadlessUICombobox.Button className={buttonStyles}>
|
|
136
|
+
<DynamicIcon icon="IconSelector" className="h-5 w-5 text-gray-400" aria-hidden="true" />
|
|
137
|
+
</HeadlessUICombobox.Button>
|
|
138
|
+
|
|
139
|
+
{filteredItems.length > 0 && (
|
|
140
|
+
<HeadlessUICombobox.Options className={optionStyles}>
|
|
141
|
+
{filteredItems.map((item, index) => (
|
|
142
|
+
<HeadlessUICombobox.Option
|
|
143
|
+
key={`${item[keyProperty]}-${index}`}
|
|
144
|
+
value={item}
|
|
145
|
+
className={({ active }) =>
|
|
146
|
+
classNames(
|
|
147
|
+
"relative cursor-default select-none py-2 pl-3 pr-9",
|
|
148
|
+
active ? "bg-purple-600 text-white" : "text-gray-900"
|
|
149
|
+
)
|
|
150
|
+
}
|
|
130
151
|
>
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
<DynamicIcon icon="SelectorIcon" className="h-5 w-5 text-gray-400" aria-hidden="true" />
|
|
137
|
-
</HeadlessUICombobox.Button>
|
|
152
|
+
{({ active, selected }) => (
|
|
153
|
+
<>
|
|
154
|
+
<span className={classNames("block truncate", selected ? "font-semibold" : "")}>
|
|
155
|
+
{`${item[displayProperty]}`}
|
|
156
|
+
</span>
|
|
138
157
|
|
|
139
|
-
|
|
140
|
-
<HeadlessUICombobox.Options className={optionStyles}>
|
|
141
|
-
{filteredItems.map((item, index) => (
|
|
142
|
-
<HeadlessUICombobox.Option
|
|
143
|
-
key={`${item[keyProperty]}-${index}`}
|
|
144
|
-
value={item}
|
|
145
|
-
className={({ active }) =>
|
|
146
|
-
classNames(
|
|
147
|
-
"relative cursor-default select-none py-2 pl-3 pr-9",
|
|
148
|
-
active ? "bg-purple-600 text-white" : "text-gray-900"
|
|
149
|
-
)
|
|
150
|
-
}
|
|
151
|
-
>
|
|
152
|
-
{({ active, selected }) => (
|
|
153
|
-
<>
|
|
158
|
+
{selected && (
|
|
154
159
|
<span
|
|
155
160
|
className={classNames(
|
|
156
|
-
"
|
|
157
|
-
|
|
161
|
+
"absolute inset-y-0 right-0 flex items-center pr-4",
|
|
162
|
+
active ? "text-white" : "text-purple-600"
|
|
158
163
|
)}
|
|
159
164
|
>
|
|
160
|
-
|
|
165
|
+
<DynamicIcon icon="IconCheck" className="h-5 w-5" aria-hidden="true" />
|
|
161
166
|
</span>
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
</HeadlessUICombobox.Options>
|
|
182
|
-
)}
|
|
183
|
-
</div>
|
|
184
|
-
<div className="grow">
|
|
185
|
-
{message && (
|
|
186
|
-
<span className={`mt-1 block text-sm ${isError ? `text-red-500` : `text-gray-500`}`}>
|
|
187
|
-
{message}
|
|
188
|
-
</span>
|
|
189
|
-
)}
|
|
190
|
-
</div>
|
|
191
|
-
</HeadlessUICombobox>
|
|
192
|
-
)
|
|
193
|
-
}
|
|
194
|
-
export default Combobox
|
|
167
|
+
)}
|
|
168
|
+
</>
|
|
169
|
+
)}
|
|
170
|
+
</HeadlessUICombobox.Option>
|
|
171
|
+
))}
|
|
172
|
+
</HeadlessUICombobox.Options>
|
|
173
|
+
)}
|
|
174
|
+
</div>
|
|
175
|
+
<div className="grow">
|
|
176
|
+
{message && (
|
|
177
|
+
<span className={`mt-1 block text-sm ${isError ? `text-red-500` : `text-gray-500`}`}>
|
|
178
|
+
{message}
|
|
179
|
+
</span>
|
|
180
|
+
)}
|
|
181
|
+
</div>
|
|
182
|
+
</HeadlessUICombobox>
|
|
183
|
+
)
|
|
184
|
+
}
|
|
185
|
+
export default Combobox
|
|
@@ -4,7 +4,7 @@ import InputField, { AcceptedInputTypes, IInputFieldProps } from "./InputField"
|
|
|
4
4
|
import InputLabel, { IInputLabelProps } from "./InputLabel"
|
|
5
5
|
import NestedInputButton, { INestedInputButtonProps } from "./NestedInputButton"
|
|
6
6
|
import Radio, { IRadioProps } from "./radio"
|
|
7
|
-
import Select, { ISelectProps } from "./select"
|
|
7
|
+
import Select, { ISelectProps, ISimpleSelectOptions } from "./select"
|
|
8
8
|
import Textarea, { ITextareaProps } from "./textArea"
|
|
9
9
|
import TextInput, { ITextInputProps } from "./TextInput"
|
|
10
10
|
import ToggleSwitch, { IToggleSwitchProps } from "./toggleSwitch"
|
|
@@ -17,6 +17,7 @@ export type {
|
|
|
17
17
|
INestedInputButtonProps,
|
|
18
18
|
IRadioProps,
|
|
19
19
|
ISelectProps,
|
|
20
|
+
ISimpleSelectOptions,
|
|
20
21
|
ITextareaProps,
|
|
21
22
|
ITextInputProps,
|
|
22
23
|
IToggleSwitchProps,
|
|
@@ -17,10 +17,10 @@ export const DefaultRadio: Story = {
|
|
|
17
17
|
message: "",
|
|
18
18
|
name: "radio-group",
|
|
19
19
|
onChange: (value: string, checked: boolean) => {
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
},
|
|
22
22
|
onClick: (value: string, checked: boolean) => {
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
}
|
|
@@ -3,7 +3,7 @@ import InputLabel from "@/stories/molecules/inputs/InputLabel"
|
|
|
3
3
|
import { useId } from "@/utils/useId"
|
|
4
4
|
import { default as cn } from "classnames"
|
|
5
5
|
|
|
6
|
-
export
|
|
6
|
+
export interface ISimpleSelectOptions {
|
|
7
7
|
label: string
|
|
8
8
|
value: string
|
|
9
9
|
}
|
|
@@ -28,6 +28,10 @@ export interface ISelectProps {
|
|
|
28
28
|
value?: string
|
|
29
29
|
|
|
30
30
|
className?: string
|
|
31
|
+
|
|
32
|
+
onFocus?: () => void
|
|
33
|
+
|
|
34
|
+
onBlur?: () => void
|
|
31
35
|
}
|
|
32
36
|
const Select: React.FC<ISelectProps> = ({
|
|
33
37
|
label,
|
|
@@ -39,7 +43,9 @@ const Select: React.FC<ISelectProps> = ({
|
|
|
39
43
|
isError,
|
|
40
44
|
isRequired,
|
|
41
45
|
value,
|
|
42
|
-
className
|
|
46
|
+
className,
|
|
47
|
+
onFocus,
|
|
48
|
+
onBlur
|
|
43
49
|
}) => {
|
|
44
50
|
const [selectedOption, setSelectedOption] = useState<string>(value || options[0].value)
|
|
45
51
|
const uniqueID = useId()
|
|
@@ -84,6 +90,8 @@ const Select: React.FC<ISelectProps> = ({
|
|
|
84
90
|
onChange={handleChange}
|
|
85
91
|
disabled={isDisabled}
|
|
86
92
|
value={selectedOption}
|
|
93
|
+
onFocus={onFocus}
|
|
94
|
+
onBlur={onBlur}
|
|
87
95
|
>
|
|
88
96
|
{options.map(({ value, label }) => {
|
|
89
97
|
return (
|
|
@@ -2,13 +2,19 @@ import React, { forwardRef, useEffect, useId, useState } from "react"
|
|
|
2
2
|
import { default as cn } from "classnames"
|
|
3
3
|
import InputLabel from "../InputLabel"
|
|
4
4
|
import InputCounter from "../InputCounter"
|
|
5
|
+
|
|
6
|
+
interface ILabelProps extends React.DetailedHTMLProps<React.LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement> {
|
|
7
|
+
display: string
|
|
8
|
+
htmlFor?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
5
11
|
export interface ITextareaProps extends Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, "onChange"> {
|
|
6
12
|
/** Input ID */
|
|
7
13
|
id?: string
|
|
8
14
|
/** Input Name */
|
|
9
15
|
name?: string
|
|
10
16
|
/** Label for the input */
|
|
11
|
-
label?:
|
|
17
|
+
label?: ILabelProps
|
|
12
18
|
/** Error state */
|
|
13
19
|
isError?: boolean
|
|
14
20
|
/** If field is required */
|
|
@@ -51,49 +57,73 @@ const Textarea: React.FC<ITextareaProps> = ({
|
|
|
51
57
|
rows = 12,
|
|
52
58
|
cols = 48,
|
|
53
59
|
onChange,
|
|
54
|
-
value
|
|
60
|
+
value,
|
|
55
61
|
placeholder,
|
|
56
62
|
className,
|
|
57
63
|
ref,
|
|
58
64
|
...rest
|
|
59
65
|
}) => {
|
|
60
66
|
const uniqueID = useId()
|
|
61
|
-
const [value, setValue] = useState<string | undefined>(externalValue || defaultValue || "")
|
|
62
|
-
const handleOnchange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
|
63
|
-
const targetValue = e.currentTarget.value
|
|
64
|
-
typeof onChange === "function" && onChange(targetValue)
|
|
65
|
-
setValue(targetValue)
|
|
66
|
-
}
|
|
67
67
|
|
|
68
68
|
const discriptionStyles = cn("text-sm mt-1 block", { "text-gray-500": !isError }, { "text-red-500": isError })
|
|
69
69
|
|
|
70
|
-
useEffect(() => {
|
|
71
|
-
//if the external value is updated by the parent component, reset the value in here...
|
|
72
|
-
if (externalValue !== undefined && externalValue !== null) {
|
|
73
|
-
setValue(externalValue)
|
|
74
|
-
}
|
|
75
|
-
}, [externalValue])
|
|
76
|
-
|
|
77
70
|
if (!id) id = `ta-${uniqueID}`
|
|
78
71
|
|
|
72
|
+
if (!label) {
|
|
73
|
+
return (
|
|
74
|
+
<textarea
|
|
75
|
+
ref={ref}
|
|
76
|
+
maxLength={maxLength}
|
|
77
|
+
onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
|
78
|
+
const targetValue = e.target.value
|
|
79
|
+
if (onChange) {
|
|
80
|
+
onChange(targetValue)
|
|
81
|
+
}
|
|
82
|
+
}}
|
|
83
|
+
rows={rows}
|
|
84
|
+
name={name}
|
|
85
|
+
id={id}
|
|
86
|
+
cols={cols}
|
|
87
|
+
className={cn(
|
|
88
|
+
"peer block w-full rounded focus:border-purple-500 focus:ring-purple-500 sm:text-sm",
|
|
89
|
+
{ "border-gray-300 ": !isError },
|
|
90
|
+
{
|
|
91
|
+
"border-red-500 outline-red-500 focus:ring-red-500": isError
|
|
92
|
+
},
|
|
93
|
+
className
|
|
94
|
+
)}
|
|
95
|
+
disabled={isDisabled}
|
|
96
|
+
defaultValue={defaultValue}
|
|
97
|
+
value={value}
|
|
98
|
+
placeholder={placeholder}
|
|
99
|
+
{...rest}
|
|
100
|
+
/>
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
//with label
|
|
79
105
|
return (
|
|
80
106
|
<div>
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
)}
|
|
107
|
+
<InputLabel
|
|
108
|
+
isPlaceholder
|
|
109
|
+
isActive
|
|
110
|
+
label={label.display}
|
|
111
|
+
isRequired={isRequired}
|
|
112
|
+
id={id}
|
|
113
|
+
isError={isError}
|
|
114
|
+
isDisabled={isDisabled}
|
|
115
|
+
/>
|
|
116
|
+
|
|
92
117
|
<div>
|
|
93
118
|
<textarea
|
|
94
119
|
ref={ref}
|
|
95
120
|
maxLength={maxLength}
|
|
96
|
-
onChange={
|
|
121
|
+
onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
|
122
|
+
const targetValue = e.target.value
|
|
123
|
+
if (onChange) {
|
|
124
|
+
onChange(targetValue)
|
|
125
|
+
}
|
|
126
|
+
}}
|
|
97
127
|
rows={rows}
|
|
98
128
|
name={name}
|
|
99
129
|
id={id}
|
|
@@ -13,7 +13,7 @@ export const DefaultToggleSwitch: Story = {
|
|
|
13
13
|
args: {
|
|
14
14
|
isChecked: false,
|
|
15
15
|
onChange: (v: boolean) => {
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
},
|
|
18
18
|
label: {
|
|
19
19
|
text: "label me",
|
|
@@ -53,21 +53,20 @@ export const Checked: Story = {
|
|
|
53
53
|
},
|
|
54
54
|
}
|
|
55
55
|
export const WithIcon: Story = {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
},
|
|
56
|
+
args: {
|
|
57
|
+
...DefaultToggleSwitch.args,
|
|
58
|
+
label: {
|
|
59
|
+
text: "label me three",
|
|
60
|
+
className: "text-lg text-gray-400",
|
|
61
|
+
xPosition: "left"
|
|
62
|
+
},
|
|
63
|
+
withIcon: {
|
|
64
|
+
icon: "IconCheck"
|
|
65
|
+
},
|
|
66
|
+
variant: "base",
|
|
67
|
+
id: "toggle-switch-4",
|
|
68
|
+
name: "toggle four"
|
|
69
|
+
}
|
|
71
70
|
}
|
|
72
71
|
export const NoLabel: Story = {
|
|
73
72
|
args: {
|