@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,92 +1,92 @@
|
|
|
1
|
-
import InputLabel from "@/stories/molecules/inputs/InputLabel"
|
|
2
|
-
import { useId } from "@/utils/useId"
|
|
3
|
-
import React from "react"
|
|
4
|
-
import { default as cn } from "classnames"
|
|
5
|
-
export interface IRadioProps {
|
|
6
|
-
/** group name */
|
|
7
|
-
name?: string
|
|
8
|
-
/** Radio label */
|
|
9
|
-
label: string
|
|
10
|
-
/** Radio ID */
|
|
11
|
-
id?: string
|
|
12
|
-
/** Disabled state */
|
|
13
|
-
isDisabled?: boolean
|
|
14
|
-
/** Check state */
|
|
15
|
-
isChecked?: boolean
|
|
16
|
-
/** If field is required */
|
|
17
|
-
isRequired?: boolean
|
|
18
|
-
/** Error state */
|
|
19
|
-
isError?: boolean
|
|
20
|
-
/** Message or description */
|
|
21
|
-
message?: string
|
|
22
|
-
/** value */
|
|
23
|
-
value?: string
|
|
24
|
-
/** Callback on input change */
|
|
25
|
-
onChange?(value: string, isChecked: boolean): void
|
|
26
|
-
/** Callback on click */
|
|
27
|
-
onClick?(value: string, isChecked: boolean): void
|
|
28
|
-
}
|
|
29
|
-
const Radio: React.FC<IRadioProps> = ({
|
|
30
|
-
label,
|
|
31
|
-
id,
|
|
32
|
-
name,
|
|
33
|
-
isDisabled = false,
|
|
34
|
-
isChecked = false,
|
|
35
|
-
isRequired = false,
|
|
36
|
-
isError = false,
|
|
37
|
-
message,
|
|
38
|
-
onChange,
|
|
39
|
-
onClick,
|
|
40
|
-
value
|
|
41
|
-
}) => {
|
|
42
|
-
const uniqueID = useId()
|
|
43
|
-
if (!id) id = `input-${uniqueID}`
|
|
44
|
-
if (!name) name = id
|
|
45
|
-
|
|
46
|
-
const checboxStyles = cn("focus:ring-purple-500 h-4 w-4 text-purple-600 border-gray-300", {
|
|
47
|
-
"border-red-500 shadow-none": isError
|
|
48
|
-
})
|
|
49
|
-
const wrapperStyles = cn("relative flex items-start", { "opacity-50": isDisabled })
|
|
50
|
-
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
51
|
-
const targetValue = e.currentTarget.value
|
|
52
|
-
const targetChecked = e.currentTarget.checked
|
|
53
|
-
typeof onChange === "function" && onChange(targetValue, targetChecked)
|
|
54
|
-
}
|
|
55
|
-
const handleClick = (e: React.MouseEvent<HTMLInputElement>) => {
|
|
56
|
-
const targetValue = e.currentTarget.value
|
|
57
|
-
const targetChecked = e.currentTarget.checked
|
|
58
|
-
typeof onClick === "function" && onClick(targetValue, targetChecked)
|
|
59
|
-
}
|
|
60
|
-
return (
|
|
61
|
-
<div className={wrapperStyles}>
|
|
62
|
-
<div className="flex items-center h-5">
|
|
63
|
-
<input
|
|
64
|
-
id={id}
|
|
65
|
-
aria-describedby={`${id}-description`}
|
|
66
|
-
name={name}
|
|
67
|
-
type="radio"
|
|
68
|
-
value={value}
|
|
69
|
-
className={checboxStyles}
|
|
70
|
-
disabled={isDisabled}
|
|
71
|
-
defaultChecked={isChecked}
|
|
72
|
-
onChange={(e) => {
|
|
73
|
-
handleChange(e)
|
|
74
|
-
}}
|
|
75
|
-
onClick={(e) => {
|
|
76
|
-
handleClick(e)
|
|
77
|
-
}}
|
|
78
|
-
/>
|
|
79
|
-
</div>
|
|
80
|
-
<div className="ml-3 text-sm">
|
|
81
|
-
<InputLabel label={label} isRequired={isRequired} id={id} />
|
|
82
|
-
{message && (
|
|
83
|
-
<p id={`${id}-description`} className="text-gray-500">
|
|
84
|
-
{message}
|
|
85
|
-
</p>
|
|
86
|
-
)}
|
|
87
|
-
</div>
|
|
88
|
-
</div>
|
|
89
|
-
)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export default Radio
|
|
1
|
+
import InputLabel from "@/stories/molecules/inputs/InputLabel"
|
|
2
|
+
import { useId } from "@/utils/useId"
|
|
3
|
+
import React from "react"
|
|
4
|
+
import { default as cn } from "classnames"
|
|
5
|
+
export interface IRadioProps {
|
|
6
|
+
/** group name */
|
|
7
|
+
name?: string
|
|
8
|
+
/** Radio label */
|
|
9
|
+
label: string
|
|
10
|
+
/** Radio ID */
|
|
11
|
+
id?: string
|
|
12
|
+
/** Disabled state */
|
|
13
|
+
isDisabled?: boolean
|
|
14
|
+
/** Check state */
|
|
15
|
+
isChecked?: boolean
|
|
16
|
+
/** If field is required */
|
|
17
|
+
isRequired?: boolean
|
|
18
|
+
/** Error state */
|
|
19
|
+
isError?: boolean
|
|
20
|
+
/** Message or description */
|
|
21
|
+
message?: string
|
|
22
|
+
/** value */
|
|
23
|
+
value?: string
|
|
24
|
+
/** Callback on input change */
|
|
25
|
+
onChange?(value: string, isChecked: boolean): void
|
|
26
|
+
/** Callback on click */
|
|
27
|
+
onClick?(value: string, isChecked: boolean): void
|
|
28
|
+
}
|
|
29
|
+
const Radio: React.FC<IRadioProps> = ({
|
|
30
|
+
label,
|
|
31
|
+
id,
|
|
32
|
+
name,
|
|
33
|
+
isDisabled = false,
|
|
34
|
+
isChecked = false,
|
|
35
|
+
isRequired = false,
|
|
36
|
+
isError = false,
|
|
37
|
+
message,
|
|
38
|
+
onChange,
|
|
39
|
+
onClick,
|
|
40
|
+
value
|
|
41
|
+
}) => {
|
|
42
|
+
const uniqueID = useId()
|
|
43
|
+
if (!id) id = `input-${uniqueID}`
|
|
44
|
+
if (!name) name = id
|
|
45
|
+
|
|
46
|
+
const checboxStyles = cn("focus:ring-purple-500 h-4 w-4 text-purple-600 border-gray-300", {
|
|
47
|
+
"border-red-500 shadow-none": isError
|
|
48
|
+
})
|
|
49
|
+
const wrapperStyles = cn("relative flex items-start", { "opacity-50": isDisabled })
|
|
50
|
+
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
51
|
+
const targetValue = e.currentTarget.value
|
|
52
|
+
const targetChecked = e.currentTarget.checked
|
|
53
|
+
typeof onChange === "function" && onChange(targetValue, targetChecked)
|
|
54
|
+
}
|
|
55
|
+
const handleClick = (e: React.MouseEvent<HTMLInputElement>) => {
|
|
56
|
+
const targetValue = e.currentTarget.value
|
|
57
|
+
const targetChecked = e.currentTarget.checked
|
|
58
|
+
typeof onClick === "function" && onClick(targetValue, targetChecked)
|
|
59
|
+
}
|
|
60
|
+
return (
|
|
61
|
+
<div className={wrapperStyles}>
|
|
62
|
+
<div className="flex items-center h-5">
|
|
63
|
+
<input
|
|
64
|
+
id={id}
|
|
65
|
+
aria-describedby={`${id}-description`}
|
|
66
|
+
name={name}
|
|
67
|
+
type="radio"
|
|
68
|
+
value={value}
|
|
69
|
+
className={checboxStyles}
|
|
70
|
+
disabled={isDisabled}
|
|
71
|
+
defaultChecked={isChecked}
|
|
72
|
+
onChange={(e) => {
|
|
73
|
+
handleChange(e)
|
|
74
|
+
}}
|
|
75
|
+
onClick={(e) => {
|
|
76
|
+
handleClick(e)
|
|
77
|
+
}}
|
|
78
|
+
/>
|
|
79
|
+
</div>
|
|
80
|
+
<div className="ml-3 text-sm">
|
|
81
|
+
<InputLabel label={label} isRequired={isRequired} id={id} />
|
|
82
|
+
{message && (
|
|
83
|
+
<p id={`${id}-description`} className="text-gray-500">
|
|
84
|
+
{message}
|
|
85
|
+
</p>
|
|
86
|
+
)}
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export default Radio
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import Radio, { IRadioProps } from "./Radio"
|
|
2
|
-
export type { IRadioProps }
|
|
3
|
-
export default Radio
|
|
1
|
+
import Radio, { IRadioProps } from "./Radio"
|
|
2
|
+
export type { IRadioProps }
|
|
3
|
+
export default Radio
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
-
import Select from "./Select"
|
|
3
|
-
const meta: Meta<typeof Select> = {
|
|
4
|
-
title: "Design System/Molecules/Inputs/Select",
|
|
5
|
-
component: Select,
|
|
6
|
-
tags: ["autodocs"]
|
|
7
|
-
}
|
|
8
|
-
type Story = StoryObj<typeof Select>
|
|
9
|
-
export const DefaultSelect: Story = {
|
|
10
|
-
args: {
|
|
11
|
-
label: "Label",
|
|
12
|
-
id: "select",
|
|
13
|
-
name: "select",
|
|
14
|
-
options: [
|
|
15
|
-
{ label: "Canada", value: "value1" },
|
|
16
|
-
{ label: "USA", value: "value2" }
|
|
17
|
-
],
|
|
18
|
-
isDisabled: false,
|
|
19
|
-
isError: false,
|
|
20
|
-
isRequired: false
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
export default meta
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
+
import Select from "./Select"
|
|
3
|
+
const meta: Meta<typeof Select> = {
|
|
4
|
+
title: "Design System/Molecules/Inputs/Select",
|
|
5
|
+
component: Select,
|
|
6
|
+
tags: ["autodocs"]
|
|
7
|
+
}
|
|
8
|
+
type Story = StoryObj<typeof Select>
|
|
9
|
+
export const DefaultSelect: Story = {
|
|
10
|
+
args: {
|
|
11
|
+
label: "Label",
|
|
12
|
+
id: "select",
|
|
13
|
+
name: "select",
|
|
14
|
+
options: [
|
|
15
|
+
{ label: "Canada", value: "value1" },
|
|
16
|
+
{ label: "USA", value: "value2" }
|
|
17
|
+
],
|
|
18
|
+
isDisabled: false,
|
|
19
|
+
isError: false,
|
|
20
|
+
isRequired: false
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export default meta
|
|
@@ -1,100 +1,108 @@
|
|
|
1
|
-
import React, { useEffect, useState } from "react"
|
|
2
|
-
import InputLabel from "@/stories/molecules/inputs/InputLabel"
|
|
3
|
-
import { useId } from "@/utils/useId"
|
|
4
|
-
import { default as cn } from "classnames"
|
|
5
|
-
|
|
6
|
-
export interface ISimpleSelectOptions {
|
|
7
|
-
label: string
|
|
8
|
-
value: string
|
|
9
|
-
}
|
|
10
|
-
export interface ISelectProps {
|
|
11
|
-
/** Label */
|
|
12
|
-
label?: string
|
|
13
|
-
/** Select ID prop */
|
|
14
|
-
id?: string
|
|
15
|
-
/** Select name prop */
|
|
16
|
-
name?: string
|
|
17
|
-
/** List of options to display in the select menu */
|
|
18
|
-
options: ISimpleSelectOptions[]
|
|
19
|
-
/** Select name prop */
|
|
20
|
-
onChange?(value: string): void
|
|
21
|
-
/** Select disabled state */
|
|
22
|
-
isDisabled?: boolean
|
|
23
|
-
/** Select error state */
|
|
24
|
-
isError?: boolean
|
|
25
|
-
/** Select required state */
|
|
26
|
-
isRequired?: boolean
|
|
27
|
-
|
|
28
|
-
value?: string
|
|
29
|
-
|
|
30
|
-
className?: string
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
1
|
+
import React, { useEffect, useState } from "react"
|
|
2
|
+
import InputLabel from "@/stories/molecules/inputs/InputLabel"
|
|
3
|
+
import { useId } from "@/utils/useId"
|
|
4
|
+
import { default as cn } from "classnames"
|
|
5
|
+
|
|
6
|
+
export interface ISimpleSelectOptions {
|
|
7
|
+
label: string
|
|
8
|
+
value: string
|
|
9
|
+
}
|
|
10
|
+
export interface ISelectProps {
|
|
11
|
+
/** Label */
|
|
12
|
+
label?: string
|
|
13
|
+
/** Select ID prop */
|
|
14
|
+
id?: string
|
|
15
|
+
/** Select name prop */
|
|
16
|
+
name?: string
|
|
17
|
+
/** List of options to display in the select menu */
|
|
18
|
+
options: ISimpleSelectOptions[]
|
|
19
|
+
/** Select name prop */
|
|
20
|
+
onChange?(value: string): void
|
|
21
|
+
/** Select disabled state */
|
|
22
|
+
isDisabled?: boolean
|
|
23
|
+
/** Select error state */
|
|
24
|
+
isError?: boolean
|
|
25
|
+
/** Select required state */
|
|
26
|
+
isRequired?: boolean
|
|
27
|
+
|
|
28
|
+
value?: string
|
|
29
|
+
|
|
30
|
+
className?: string
|
|
31
|
+
|
|
32
|
+
onFocus?: () => void
|
|
33
|
+
|
|
34
|
+
onBlur?: () => void
|
|
35
|
+
}
|
|
36
|
+
const Select: React.FC<ISelectProps> = ({
|
|
37
|
+
label,
|
|
38
|
+
id,
|
|
39
|
+
name,
|
|
40
|
+
options,
|
|
41
|
+
onChange,
|
|
42
|
+
isDisabled,
|
|
43
|
+
isError,
|
|
44
|
+
isRequired,
|
|
45
|
+
value,
|
|
46
|
+
className,
|
|
47
|
+
onFocus,
|
|
48
|
+
onBlur
|
|
49
|
+
}) => {
|
|
50
|
+
const [selectedOption, setSelectedOption] = useState<string>(value || options[0].value)
|
|
51
|
+
const uniqueID = useId()
|
|
52
|
+
if (!id) id = `select-${uniqueID}`
|
|
53
|
+
if (!name) name = id
|
|
54
|
+
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (value !== undefined && value !== null) {
|
|
57
|
+
setSelectedOption(value)
|
|
58
|
+
}
|
|
59
|
+
}, [value])
|
|
60
|
+
|
|
61
|
+
const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
|
62
|
+
const targetValue = e.target.value
|
|
63
|
+
typeof onChange == "function" && onChange(targetValue)
|
|
64
|
+
setSelectedOption(targetValue)
|
|
65
|
+
}
|
|
66
|
+
const wrapperStyle = cn({ "opacity-50": isDisabled })
|
|
67
|
+
return (
|
|
68
|
+
<div className={wrapperStyle}>
|
|
69
|
+
{label && (
|
|
70
|
+
<InputLabel
|
|
71
|
+
isPlaceholder
|
|
72
|
+
isActive
|
|
73
|
+
label={label}
|
|
74
|
+
isRequired={isRequired}
|
|
75
|
+
id={id}
|
|
76
|
+
isError={isError}
|
|
77
|
+
isDisabled={isDisabled}
|
|
78
|
+
/>
|
|
79
|
+
)}
|
|
80
|
+
<select
|
|
81
|
+
id={id}
|
|
82
|
+
name={name}
|
|
83
|
+
className={cn(
|
|
84
|
+
"block w-full border-gray-300 py-2 pl-3 pr-10 text-base focus:outline-none",
|
|
85
|
+
"rounded focus:border-purple-500 focus:ring-purple-500 sm:text-sm",
|
|
86
|
+
{ "border-red-500": isError },
|
|
87
|
+
{ "border-gray-300": !isError },
|
|
88
|
+
className
|
|
89
|
+
)}
|
|
90
|
+
onChange={handleChange}
|
|
91
|
+
disabled={isDisabled}
|
|
92
|
+
value={selectedOption}
|
|
93
|
+
onFocus={onFocus}
|
|
94
|
+
onBlur={onBlur}
|
|
95
|
+
>
|
|
96
|
+
{options.map(({ value, label }) => {
|
|
97
|
+
return (
|
|
98
|
+
<option key={value} value={value}>
|
|
99
|
+
{label}
|
|
100
|
+
</option>
|
|
101
|
+
)
|
|
102
|
+
})}
|
|
103
|
+
</select>
|
|
104
|
+
</div>
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export default Select
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import Select, { ISelectProps, ISimpleSelectOptions } from "./Select"
|
|
2
|
-
export type { ISelectProps, ISimpleSelectOptions }
|
|
3
|
-
export default Select
|
|
1
|
+
import Select, { ISelectProps, ISimpleSelectOptions } from "./Select"
|
|
2
|
+
export type { ISelectProps, ISimpleSelectOptions }
|
|
3
|
+
export default Select
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
-
import Textarea from "./TextArea"
|
|
3
|
-
const meta: Meta<typeof Textarea> = {
|
|
4
|
-
title: "Design System/Molecules/Inputs/TextArea",
|
|
5
|
-
component: Textarea,
|
|
6
|
-
tags: ["autodocs"]
|
|
7
|
-
}
|
|
8
|
-
const dummyText: string = `Checkmate... Life finds a way. Is this my espresso machine? Wh-what is-h-how did you get my espresso machine? You're a very talented young man, with your own clever thoughts and ideas. Do you need a manager? Is this my espresso machine? Wh-what is-h-how did you get my espresso machine?
|
|
9
|
-
|
|
10
|
-
I was part of something special. Just my luck, no ice. You really think you can fly that thing? Must go faster... go, go, go, go, go! God creates dinosaurs. God destroys dinosaurs. God creates Man. Man destroys God. Man creates Dinosaurs. Yeah, but your scientists were so preoccupied with whether or not they could, they didn't stop to think if they should.`
|
|
11
|
-
type Story = StoryObj<typeof Textarea>
|
|
12
|
-
export const DefaultTextarea: Story = {
|
|
13
|
-
args: {
|
|
14
|
-
id: "appDescription",
|
|
15
|
-
name: "description",
|
|
16
|
-
rows: 12,
|
|
17
|
-
cols: 18,
|
|
18
|
-
label: { display: "Description" },
|
|
19
|
-
placeholder: dummyText
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
export default meta
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
+
import Textarea from "./TextArea"
|
|
3
|
+
const meta: Meta<typeof Textarea> = {
|
|
4
|
+
title: "Design System/Molecules/Inputs/TextArea",
|
|
5
|
+
component: Textarea,
|
|
6
|
+
tags: ["autodocs"]
|
|
7
|
+
}
|
|
8
|
+
const dummyText: string = `Checkmate... Life finds a way. Is this my espresso machine? Wh-what is-h-how did you get my espresso machine? You're a very talented young man, with your own clever thoughts and ideas. Do you need a manager? Is this my espresso machine? Wh-what is-h-how did you get my espresso machine?
|
|
9
|
+
|
|
10
|
+
I was part of something special. Just my luck, no ice. You really think you can fly that thing? Must go faster... go, go, go, go, go! God creates dinosaurs. God destroys dinosaurs. God creates Man. Man destroys God. Man creates Dinosaurs. Yeah, but your scientists were so preoccupied with whether or not they could, they didn't stop to think if they should.`
|
|
11
|
+
type Story = StoryObj<typeof Textarea>
|
|
12
|
+
export const DefaultTextarea: Story = {
|
|
13
|
+
args: {
|
|
14
|
+
id: "appDescription",
|
|
15
|
+
name: "description",
|
|
16
|
+
rows: 12,
|
|
17
|
+
cols: 18,
|
|
18
|
+
label: { display: "Description" },
|
|
19
|
+
placeholder: dummyText
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export default meta
|