@agility/plenum-ui 2.0.0-rc47 → 2.0.0-rc49
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/.eslintrc.json +6 -6
- package/.prettierrc +13 -13
- package/.storybook/Layout.jsx +12 -12
- package/.storybook/head.tsx +4 -4
- package/.storybook/main.ts +18 -18
- package/.storybook/manager-head.html +1 -1
- package/.storybook/manager.ts +25 -25
- package/.storybook/plenumTheme.ts +8 -8
- package/.storybook/preview-head.html +3 -3
- package/.storybook/preview.tsx +28 -28
- package/.vscode/settings.json +3 -3
- package/README.md +271 -271
- package/app/globals.css +99 -99
- package/app/head.tsx +59 -59
- package/app/layout.tsx +28 -28
- package/app/page.tsx +7 -7
- package/build.js +45 -45
- package/dist/index.d.ts +232 -230
- package/dist/index.js +1 -1
- package/dist/index.js.map +3 -3
- package/dist/types/stories/molecules/inputs/select/Select.d.ts +2 -0
- package/local.sh +100 -100
- package/next.config.js +8 -8
- package/package.json +82 -82
- package/pages/api/hello.ts +13 -13
- package/postcss.config.js +6 -6
- package/rollup.config.mjs +41 -41
- package/scripts/create-component.js +97 -97
- package/stories/Introduction.mdx +314 -314
- package/stories/assets/stackalt.svg +1 -1
- package/stories/atoms/Avatar/Avatar.stories.tsx +96 -96
- package/stories/atoms/Avatar/Avatar.tsx +123 -123
- package/stories/atoms/Avatar/index.ts +3 -3
- package/stories/atoms/badges/Badge.tsx +127 -127
- package/stories/atoms/badges/Pill/Pill.stories.tsx +75 -75
- package/stories/atoms/badges/Rounded/Rounded.stories.tsx +75 -75
- package/stories/atoms/badges/index.ts +3 -3
- package/stories/atoms/buttons/Button/Alternative/Alternative.stories.ts +86 -86
- package/stories/atoms/buttons/Button/Button.tsx +232 -232
- package/stories/atoms/buttons/Button/Danger/Danger.stories.ts +90 -90
- package/stories/atoms/buttons/Button/Primary/Primary.stories.ts +97 -97
- package/stories/atoms/buttons/Button/Secondary/Secondary.stories.ts +93 -93
- package/stories/atoms/buttons/Button/defaultArgs.ts +9 -9
- package/stories/atoms/buttons/Button/index.ts +3 -3
- package/stories/atoms/buttons/Capsule/Alternative/Alternative.stories.ts +27 -27
- package/stories/atoms/buttons/Capsule/Capsule.tsx +88 -88
- package/stories/atoms/buttons/Capsule/Danger/Danger.stories.ts +27 -27
- package/stories/atoms/buttons/Capsule/Primary/Primary.stories.ts +27 -27
- package/stories/atoms/buttons/Capsule/Secondary/Secondary.stories.ts +27 -27
- package/stories/atoms/buttons/Capsule/index.ts +3 -3
- package/stories/atoms/buttons/FloatingActionButton/FloatingActionButton.stories.tsx +15 -15
- package/stories/atoms/buttons/FloatingActionButton/FloatingActionButton.tsx +22 -22
- package/stories/atoms/buttons/FloatingActionButton/index.tsx +3 -3
- package/stories/atoms/buttons/index.ts +4 -4
- package/stories/atoms/crumb/Crumb.stories.tsx +18 -18
- package/stories/atoms/crumb/Crumb.tsx +22 -22
- package/stories/atoms/crumb/index.tsx +3 -3
- package/stories/atoms/icons/DynamicIcon.stories.ts +43 -43
- package/stories/atoms/icons/DynamicIcon.tsx +90 -90
- package/stories/atoms/icons/IconWithShadow.stories.ts +43 -43
- package/stories/atoms/icons/IconWithShadow.tsx +16 -16
- package/stories/atoms/icons/TablerIcon.tsx +22 -22
- package/stories/atoms/icons/index.tsx +14 -14
- package/stories/atoms/icons/tablerIconNames.ts +4336 -4336
- package/stories/atoms/index.ts +46 -46
- package/stories/atoms/loaders/Loader.stories.ts +15 -15
- package/stories/atoms/loaders/Loader.tsx +21 -21
- package/stories/atoms/loaders/NProgress/RadialProgress.stories.tsx +19 -19
- package/stories/atoms/loaders/NProgress/RadialProgress.tsx +74 -74
- package/stories/atoms/loaders/NProgress/index.ts +3 -3
- package/stories/atoms/loaders/index.ts +4 -4
- package/stories/index.ts +136 -136
- package/stories/molecules/index.ts +51 -51
- package/stories/molecules/inputs/InputCounter/InputCounter.stories.tsx +18 -18
- package/stories/molecules/inputs/InputCounter/InputCounter.tsx +24 -24
- package/stories/molecules/inputs/InputCounter/index.tsx +3 -3
- package/stories/molecules/inputs/InputField/InputField.stories.tsx +29 -29
- package/stories/molecules/inputs/InputField/InputField.tsx +96 -96
- package/stories/molecules/inputs/InputField/index.tsx +3 -3
- package/stories/molecules/inputs/InputLabel/InputLabel.stories.tsx +19 -19
- package/stories/molecules/inputs/InputLabel/InputLabel.tsx +45 -45
- package/stories/molecules/inputs/InputLabel/index.tsx +3 -3
- package/stories/molecules/inputs/NestedInputButton/NestedInputButton.stories.tsx +52 -52
- package/stories/molecules/inputs/NestedInputButton/NestedInputButton.tsx +64 -64
- package/stories/molecules/inputs/NestedInputButton/index.tsx +3 -3
- package/stories/molecules/inputs/TextInput/TextInput.stories.tsx +32 -32
- package/stories/molecules/inputs/TextInput/TextInput.tsx +165 -165
- package/stories/molecules/inputs/TextInput/index.tsx +5 -5
- package/stories/molecules/inputs/checkbox/Checkbox.stories.ts +23 -23
- package/stories/molecules/inputs/checkbox/Checkbox.tsx +98 -98
- package/stories/molecules/inputs/checkbox/index.ts +3 -3
- package/stories/molecules/inputs/combobox/ComboBox.stories.ts +41 -41
- package/stories/molecules/inputs/combobox/ComboBox.tsx +185 -185
- package/stories/molecules/inputs/combobox/index.ts +3 -3
- package/stories/molecules/inputs/index.ts +38 -38
- package/stories/molecules/inputs/radio/Radio.stories.ts +27 -27
- package/stories/molecules/inputs/radio/Radio.tsx +92 -92
- package/stories/molecules/inputs/radio/index.ts +3 -3
- package/stories/molecules/inputs/select/Select.stories.ts +23 -23
- package/stories/molecules/inputs/select/Select.tsx +108 -100
- package/stories/molecules/inputs/select/index.ts +3 -3
- package/stories/molecules/inputs/textArea/TextArea.stories.ts +22 -22
- package/stories/molecules/inputs/textArea/TextArea.tsx +158 -158
- package/stories/molecules/inputs/textArea/index.ts +3 -3
- package/stories/molecules/inputs/toggleSwitch/ToggleSwitch.stories.tsx +118 -118
- package/stories/molecules/inputs/toggleSwitch/ToggleSwitch.tsx +81 -81
- package/stories/molecules/inputs/toggleSwitch/index.ts +3 -3
- package/stories/molecules/tabs/Tabs.stories.tsx +18 -18
- package/stories/molecules/tabs/Tabs.tsx +22 -22
- package/stories/molecules/tabs/index.tsx +2 -2
- package/stories/organisms/AnimatedLabelInput/AnimatedLabelInput.stories.tsx +30 -30
- package/stories/organisms/AnimatedLabelInput/AnimatedLabelInput.tsx +66 -66
- package/stories/organisms/AnimatedLabelInput/index.tsx +3 -3
- package/stories/organisms/AnimatedLabelTextArea/AnimatedLabelTextArea.stories.tsx +26 -26
- package/stories/organisms/AnimatedLabelTextArea/AnimatedLabelTextArea.tsx +61 -61
- package/stories/organisms/AnimatedLabelTextArea/index.tsx +3 -3
- package/stories/organisms/ButtonDropdown/ButtonDropdown.stories.tsx +125 -125
- package/stories/organisms/ButtonDropdown/ButtonDropdown.tsx +86 -86
- package/stories/organisms/ButtonDropdown/index.tsx +3 -3
- package/stories/organisms/DropdownComponent/Dropdown.stories.tsx +73 -73
- package/stories/organisms/DropdownComponent/DropdownComponent.tsx +346 -346
- package/stories/organisms/DropdownComponent/dropdownItems.ts +122 -122
- package/stories/organisms/DropdownComponent/index.ts +4 -4
- package/stories/organisms/EmptySectionPlaceholder/EmptySectionPlaceholder.stories.tsx +76 -76
- package/stories/organisms/EmptySectionPlaceholder/EmptySectionPlaceholder.tsx +52 -52
- package/stories/organisms/EmptySectionPlaceholder/index.tsx +4 -4
- package/stories/organisms/FormInputWithAddons/FormInputWithAddons.stories.tsx +29 -29
- package/stories/organisms/FormInputWithAddons/FormInputWithAddons.tsx +145 -145
- package/stories/organisms/FormInputWithAddons/index.tsx +3 -3
- package/stories/organisms/TextInputSelect/InputSelect.tsx +59 -59
- package/stories/organisms/TextInputSelect/TextInputSelect.stories.tsx +33 -33
- package/stories/organisms/TextInputSelect/TextInputSelect.tsx +186 -186
- package/stories/organisms/TextInputSelect/index.tsx +3 -3
- package/stories/organisms/index.ts +27 -27
- package/tailwind.config.js +192 -192
- package/tsconfig.json +29 -29
- package/tsconfig.lib.json +25 -25
- package/utils/types.d.ts +2 -2
- package/utils/types.ts +3 -3
- package/utils/useId.d.ts +1 -1
- package/utils/useId.tsx +16 -16
|
@@ -1,185 +1,185 @@
|
|
|
1
|
-
import React, { useState, useEffect } from "react"
|
|
2
|
-
import { default as cn } from "classnames"
|
|
3
|
-
import { Combobox as HeadlessUICombobox } from "@headlessui/react"
|
|
4
|
-
import InputLabel from "@/stories/molecules/inputs/InputLabel"
|
|
5
|
-
import { DynamicIcon } from "@/stories/atoms/icons"
|
|
6
|
-
|
|
7
|
-
export interface IComboboxProps<T extends Record<string, unknown>> {
|
|
8
|
-
/** Label */
|
|
9
|
-
label?: string
|
|
10
|
-
/** ID */
|
|
11
|
-
id: string
|
|
12
|
-
/** Array of items to display */
|
|
13
|
-
items: T[]
|
|
14
|
-
/** the item property to use as the key */
|
|
15
|
-
keyProperty: string
|
|
16
|
-
|
|
17
|
-
/** the item property to use as the display */
|
|
18
|
-
displayProperty: string
|
|
19
|
-
/** Placeholder */
|
|
20
|
-
placeholder?: string
|
|
21
|
-
/** Callback to trigger on change */
|
|
22
|
-
onChange?(value: T | undefined): void
|
|
23
|
-
/** Select disabled state */
|
|
24
|
-
isDisabled?: boolean
|
|
25
|
-
/** Select error state */
|
|
26
|
-
isError?: boolean
|
|
27
|
-
/** Select required state */
|
|
28
|
-
isRequired?: boolean
|
|
29
|
-
/** Message shown under field */
|
|
30
|
-
message?: string
|
|
31
|
-
|
|
32
|
-
displayValue?: string
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Whether this item is nullable or not.
|
|
36
|
-
*
|
|
37
|
-
* @type {boolean}
|
|
38
|
-
* @memberof ComboboxProps
|
|
39
|
-
*/
|
|
40
|
-
nullable?: boolean
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function classNames(...classes: string[]) {
|
|
44
|
-
return classes.filter(Boolean).join(" ")
|
|
45
|
-
}
|
|
46
|
-
|
|
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
|
-
|
|
65
|
-
const onChangeValue = (value: T | undefined) => {
|
|
66
|
-
if (value && selectedItem && value[keyProperty] === selectedItem[keyProperty]) {
|
|
67
|
-
setSelectedItem(undefined)
|
|
68
|
-
} else {
|
|
69
|
-
setSelectedItem(value)
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
useEffect(() => {
|
|
74
|
-
if (displayValue) {
|
|
75
|
-
const dv = items.find((i) => i[displayProperty] === displayValue)
|
|
76
|
-
setSelectedItem(dv)
|
|
77
|
-
}
|
|
78
|
-
}, [displayValue])
|
|
79
|
-
|
|
80
|
-
useEffect(() => {
|
|
81
|
-
typeof onChange === "function" && onChange(selectedItem)
|
|
82
|
-
}, [selectedItem])
|
|
83
|
-
|
|
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">
|
|
117
|
-
<div className="relative">
|
|
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
|
-
}
|
|
151
|
-
>
|
|
152
|
-
{({ active, selected }) => (
|
|
153
|
-
<>
|
|
154
|
-
<span className={classNames("block truncate", selected ? "font-semibold" : "")}>
|
|
155
|
-
{`${item[displayProperty]}`}
|
|
156
|
-
</span>
|
|
157
|
-
|
|
158
|
-
{selected && (
|
|
159
|
-
<span
|
|
160
|
-
className={classNames(
|
|
161
|
-
"absolute inset-y-0 right-0 flex items-center pr-4",
|
|
162
|
-
active ? "text-white" : "text-purple-600"
|
|
163
|
-
)}
|
|
164
|
-
>
|
|
165
|
-
<DynamicIcon icon="IconCheck" className="h-5 w-5" aria-hidden="true" />
|
|
166
|
-
</span>
|
|
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
|
|
1
|
+
import React, { useState, useEffect } from "react"
|
|
2
|
+
import { default as cn } from "classnames"
|
|
3
|
+
import { Combobox as HeadlessUICombobox } from "@headlessui/react"
|
|
4
|
+
import InputLabel from "@/stories/molecules/inputs/InputLabel"
|
|
5
|
+
import { DynamicIcon } from "@/stories/atoms/icons"
|
|
6
|
+
|
|
7
|
+
export interface IComboboxProps<T extends Record<string, unknown>> {
|
|
8
|
+
/** Label */
|
|
9
|
+
label?: string
|
|
10
|
+
/** ID */
|
|
11
|
+
id: string
|
|
12
|
+
/** Array of items to display */
|
|
13
|
+
items: T[]
|
|
14
|
+
/** the item property to use as the key */
|
|
15
|
+
keyProperty: string
|
|
16
|
+
|
|
17
|
+
/** the item property to use as the display */
|
|
18
|
+
displayProperty: string
|
|
19
|
+
/** Placeholder */
|
|
20
|
+
placeholder?: string
|
|
21
|
+
/** Callback to trigger on change */
|
|
22
|
+
onChange?(value: T | undefined): void
|
|
23
|
+
/** Select disabled state */
|
|
24
|
+
isDisabled?: boolean
|
|
25
|
+
/** Select error state */
|
|
26
|
+
isError?: boolean
|
|
27
|
+
/** Select required state */
|
|
28
|
+
isRequired?: boolean
|
|
29
|
+
/** Message shown under field */
|
|
30
|
+
message?: string
|
|
31
|
+
|
|
32
|
+
displayValue?: string
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Whether this item is nullable or not.
|
|
36
|
+
*
|
|
37
|
+
* @type {boolean}
|
|
38
|
+
* @memberof ComboboxProps
|
|
39
|
+
*/
|
|
40
|
+
nullable?: boolean
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function classNames(...classes: string[]) {
|
|
44
|
+
return classes.filter(Boolean).join(" ")
|
|
45
|
+
}
|
|
46
|
+
|
|
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
|
+
|
|
65
|
+
const onChangeValue = (value: T | undefined) => {
|
|
66
|
+
if (value && selectedItem && value[keyProperty] === selectedItem[keyProperty]) {
|
|
67
|
+
setSelectedItem(undefined)
|
|
68
|
+
} else {
|
|
69
|
+
setSelectedItem(value)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
if (displayValue) {
|
|
75
|
+
const dv = items.find((i) => i[displayProperty] === displayValue)
|
|
76
|
+
setSelectedItem(dv)
|
|
77
|
+
}
|
|
78
|
+
}, [displayValue])
|
|
79
|
+
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
typeof onChange === "function" && onChange(selectedItem)
|
|
82
|
+
}, [selectedItem])
|
|
83
|
+
|
|
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">
|
|
117
|
+
<div className="relative">
|
|
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
|
+
}
|
|
151
|
+
>
|
|
152
|
+
{({ active, selected }) => (
|
|
153
|
+
<>
|
|
154
|
+
<span className={classNames("block truncate", selected ? "font-semibold" : "")}>
|
|
155
|
+
{`${item[displayProperty]}`}
|
|
156
|
+
</span>
|
|
157
|
+
|
|
158
|
+
{selected && (
|
|
159
|
+
<span
|
|
160
|
+
className={classNames(
|
|
161
|
+
"absolute inset-y-0 right-0 flex items-center pr-4",
|
|
162
|
+
active ? "text-white" : "text-purple-600"
|
|
163
|
+
)}
|
|
164
|
+
>
|
|
165
|
+
<DynamicIcon icon="IconCheck" className="h-5 w-5" aria-hidden="true" />
|
|
166
|
+
</span>
|
|
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
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import Combobox, { IComboboxProps } from "./ComboBox"
|
|
2
|
-
export type { IComboboxProps }
|
|
3
|
-
export default Combobox
|
|
1
|
+
import Combobox, { IComboboxProps } from "./ComboBox"
|
|
2
|
+
export type { IComboboxProps }
|
|
3
|
+
export default Combobox
|
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
import Checkbox, { ICheckboxProps } from "./checkbox"
|
|
2
|
-
import Combobox, { IComboboxProps } from "./combobox"
|
|
3
|
-
import InputField, { AcceptedInputTypes, IInputFieldProps } from "./InputField"
|
|
4
|
-
import InputLabel, { IInputLabelProps } from "./InputLabel"
|
|
5
|
-
import NestedInputButton, { INestedInputButtonProps } from "./NestedInputButton"
|
|
6
|
-
import Radio, { IRadioProps } from "./radio"
|
|
7
|
-
import Select, { ISelectProps, ISimpleSelectOptions } from "./select"
|
|
8
|
-
import Textarea, { ITextareaProps } from "./textArea"
|
|
9
|
-
import TextInput, { ITextInputProps } from "./TextInput"
|
|
10
|
-
import ToggleSwitch, { IToggleSwitchProps } from "./toggleSwitch"
|
|
11
|
-
|
|
12
|
-
export type {
|
|
13
|
-
ICheckboxProps,
|
|
14
|
-
IComboboxProps,
|
|
15
|
-
IInputFieldProps,
|
|
16
|
-
IInputLabelProps,
|
|
17
|
-
INestedInputButtonProps,
|
|
18
|
-
IRadioProps,
|
|
19
|
-
ISelectProps,
|
|
20
|
-
ISimpleSelectOptions,
|
|
21
|
-
ITextareaProps,
|
|
22
|
-
ITextInputProps,
|
|
23
|
-
IToggleSwitchProps,
|
|
24
|
-
AcceptedInputTypes
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export {
|
|
28
|
-
Checkbox,
|
|
29
|
-
Combobox,
|
|
30
|
-
InputField,
|
|
31
|
-
InputLabel,
|
|
32
|
-
NestedInputButton,
|
|
33
|
-
Radio,
|
|
34
|
-
Select,
|
|
35
|
-
Textarea,
|
|
36
|
-
ToggleSwitch,
|
|
37
|
-
TextInput
|
|
38
|
-
}
|
|
1
|
+
import Checkbox, { ICheckboxProps } from "./checkbox"
|
|
2
|
+
import Combobox, { IComboboxProps } from "./combobox"
|
|
3
|
+
import InputField, { AcceptedInputTypes, IInputFieldProps } from "./InputField"
|
|
4
|
+
import InputLabel, { IInputLabelProps } from "./InputLabel"
|
|
5
|
+
import NestedInputButton, { INestedInputButtonProps } from "./NestedInputButton"
|
|
6
|
+
import Radio, { IRadioProps } from "./radio"
|
|
7
|
+
import Select, { ISelectProps, ISimpleSelectOptions } from "./select"
|
|
8
|
+
import Textarea, { ITextareaProps } from "./textArea"
|
|
9
|
+
import TextInput, { ITextInputProps } from "./TextInput"
|
|
10
|
+
import ToggleSwitch, { IToggleSwitchProps } from "./toggleSwitch"
|
|
11
|
+
|
|
12
|
+
export type {
|
|
13
|
+
ICheckboxProps,
|
|
14
|
+
IComboboxProps,
|
|
15
|
+
IInputFieldProps,
|
|
16
|
+
IInputLabelProps,
|
|
17
|
+
INestedInputButtonProps,
|
|
18
|
+
IRadioProps,
|
|
19
|
+
ISelectProps,
|
|
20
|
+
ISimpleSelectOptions,
|
|
21
|
+
ITextareaProps,
|
|
22
|
+
ITextInputProps,
|
|
23
|
+
IToggleSwitchProps,
|
|
24
|
+
AcceptedInputTypes
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
Checkbox,
|
|
29
|
+
Combobox,
|
|
30
|
+
InputField,
|
|
31
|
+
InputLabel,
|
|
32
|
+
NestedInputButton,
|
|
33
|
+
Radio,
|
|
34
|
+
Select,
|
|
35
|
+
Textarea,
|
|
36
|
+
ToggleSwitch,
|
|
37
|
+
TextInput
|
|
38
|
+
}
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
-
import Radio from "./Radio"
|
|
3
|
-
const meta: Meta<typeof Radio> = {
|
|
4
|
-
title: "Design System/Molecules/Inputs/Radio",
|
|
5
|
-
component: Radio,
|
|
6
|
-
tags: []
|
|
7
|
-
}
|
|
8
|
-
type Story = StoryObj<typeof Radio>
|
|
9
|
-
export const DefaultRadio: Story = {
|
|
10
|
-
args: {
|
|
11
|
-
label: "Radio Label",
|
|
12
|
-
id: "radioId",
|
|
13
|
-
isDisabled: false,
|
|
14
|
-
isChecked: false,
|
|
15
|
-
isRequired: false,
|
|
16
|
-
isError: false,
|
|
17
|
-
message: "",
|
|
18
|
-
name: "radio-group",
|
|
19
|
-
onChange: (value: string, checked: boolean) => {
|
|
20
|
-
|
|
21
|
-
},
|
|
22
|
-
onClick: (value: string, checked: boolean) => {
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
export default meta
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
+
import Radio from "./Radio"
|
|
3
|
+
const meta: Meta<typeof Radio> = {
|
|
4
|
+
title: "Design System/Molecules/Inputs/Radio",
|
|
5
|
+
component: Radio,
|
|
6
|
+
tags: []
|
|
7
|
+
}
|
|
8
|
+
type Story = StoryObj<typeof Radio>
|
|
9
|
+
export const DefaultRadio: Story = {
|
|
10
|
+
args: {
|
|
11
|
+
label: "Radio Label",
|
|
12
|
+
id: "radioId",
|
|
13
|
+
isDisabled: false,
|
|
14
|
+
isChecked: false,
|
|
15
|
+
isRequired: false,
|
|
16
|
+
isError: false,
|
|
17
|
+
message: "",
|
|
18
|
+
name: "radio-group",
|
|
19
|
+
onChange: (value: string, checked: boolean) => {
|
|
20
|
+
|
|
21
|
+
},
|
|
22
|
+
onClick: (value: string, checked: boolean) => {
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export default meta
|