@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.
Files changed (95) hide show
  1. package/README.md +104 -31
  2. package/build.js +30 -25
  3. package/dist/index.d.ts +105 -65
  4. package/dist/index.js +1 -6295
  5. package/dist/index.js.map +4 -4
  6. package/dist/{lib/tailwind.css → tailwind.css} +3729 -8120
  7. package/dist/types/stories/atoms/buttons/Button/Alternative/Alternative.stories.d.ts +1 -0
  8. package/dist/types/stories/atoms/buttons/Button/Button.d.ts +3 -7
  9. package/dist/types/stories/atoms/buttons/Button/Danger/Danger.stories.d.ts +1 -0
  10. package/dist/types/stories/atoms/buttons/Button/Primary/Primary.stories.d.ts +1 -0
  11. package/dist/types/stories/atoms/buttons/Button/Secondary/Secondary.stories.d.ts +1 -0
  12. package/dist/types/stories/atoms/buttons/Capsule/Capsule.d.ts +1 -1
  13. package/dist/types/stories/atoms/icons/DynamicIcon.d.ts +2 -2
  14. package/dist/types/stories/atoms/icons/TablerIcon.d.ts +1 -1
  15. package/dist/types/stories/index.d.ts +4 -4
  16. package/dist/types/stories/molecules/index.d.ts +2 -2
  17. package/dist/types/stories/molecules/inputs/InputField/InputField.d.ts +7 -7
  18. package/dist/types/stories/molecules/inputs/TextInput/TextInput.d.ts +1 -1
  19. package/dist/types/stories/molecules/inputs/index.d.ts +2 -2
  20. package/dist/types/stories/molecules/inputs/select/Select.d.ts +4 -2
  21. package/dist/types/stories/molecules/inputs/textArea/TextArea.d.ts +5 -1
  22. package/dist/types/stories/molecules/inputs/toggleSwitch/ToggleSwitch.d.ts +10 -7
  23. package/dist/types/stories/organisms/AnimatedLabelInput/AnimatedLabelInput.d.ts +5 -5
  24. package/dist/types/stories/organisms/AnimatedLabelInput/index.d.ts +1 -1
  25. package/dist/types/stories/organisms/AnimatedLabelTextArea/AnimatedLabelTextArea.d.ts +12 -0
  26. package/dist/types/stories/organisms/AnimatedLabelTextArea/index.d.ts +3 -0
  27. package/dist/types/stories/organisms/ButtonDropdown/ButtonDropdown.d.ts +1 -0
  28. package/dist/types/stories/organisms/DropdownComponent/DropdownComponent.d.ts +24 -13
  29. package/dist/types/stories/organisms/DropdownComponent/index.d.ts +2 -2
  30. package/dist/types/stories/organisms/EmptySectionPlaceholder/index.d.ts +1 -1
  31. package/dist/types/stories/organisms/index.d.ts +4 -3
  32. package/local.sh +100 -0
  33. package/package.json +36 -19
  34. package/rollup.config.mjs +42 -0
  35. package/stories/atoms/badges/Badge.tsx +1 -1
  36. package/stories/atoms/buttons/Button/Alternative/Alternative.stories.ts +10 -0
  37. package/stories/atoms/buttons/Button/Button.tsx +111 -25
  38. package/stories/atoms/buttons/Button/Danger/Danger.stories.ts +14 -2
  39. package/stories/atoms/buttons/Button/Primary/Primary.stories.ts +14 -2
  40. package/stories/atoms/buttons/Button/Secondary/Secondary.stories.ts +13 -1
  41. package/stories/atoms/buttons/Button/defaultArgs.ts +1 -1
  42. package/stories/atoms/buttons/Capsule/Capsule.tsx +2 -1
  43. package/stories/atoms/icons/DynamicIcon.stories.ts +1 -1
  44. package/stories/atoms/icons/DynamicIcon.tsx +7 -7
  45. package/stories/atoms/icons/IconWithShadow.stories.ts +3 -3
  46. package/stories/atoms/icons/TablerIcon.tsx +1 -1
  47. package/stories/atoms/loaders/Loader.tsx +12 -6
  48. package/stories/atoms/loaders/NProgress/RadialProgress.tsx +0 -2
  49. package/stories/index.ts +8 -4
  50. package/stories/molecules/index.ts +2 -0
  51. package/stories/molecules/inputs/InputCounter/InputCounter.tsx +2 -2
  52. package/stories/molecules/inputs/InputField/InputField.tsx +31 -29
  53. package/stories/molecules/inputs/InputLabel/InputLabel.tsx +1 -1
  54. package/stories/molecules/inputs/TextInput/TextInput.tsx +12 -6
  55. package/stories/molecules/inputs/checkbox/Checkbox.stories.ts +1 -1
  56. package/stories/molecules/inputs/checkbox/Checkbox.tsx +1 -2
  57. package/stories/molecules/inputs/combobox/ComboBox.tsx +126 -135
  58. package/stories/molecules/inputs/index.ts +2 -1
  59. package/stories/molecules/inputs/radio/Radio.stories.ts +2 -2
  60. package/stories/molecules/inputs/select/Select.tsx +10 -2
  61. package/stories/molecules/inputs/textArea/TextArea.stories.ts +1 -1
  62. package/stories/molecules/inputs/textArea/TextArea.tsx +57 -27
  63. package/stories/molecules/inputs/toggleSwitch/ToggleSwitch.stories.tsx +15 -16
  64. package/stories/molecules/inputs/toggleSwitch/ToggleSwitch.tsx +63 -57
  65. package/stories/molecules/tabs/index.tsx +2 -3
  66. package/stories/organisms/AnimatedLabelInput/AnimatedLabelInput.stories.tsx +10 -1
  67. package/stories/organisms/AnimatedLabelInput/AnimatedLabelInput.tsx +53 -37
  68. package/stories/organisms/AnimatedLabelInput/index.tsx +1 -1
  69. package/stories/organisms/AnimatedLabelTextArea/AnimatedLabelTextArea.stories.tsx +26 -0
  70. package/stories/organisms/AnimatedLabelTextArea/AnimatedLabelTextArea.tsx +61 -0
  71. package/stories/organisms/AnimatedLabelTextArea/index.tsx +3 -0
  72. package/stories/organisms/ButtonDropdown/ButtonDropdown.stories.tsx +59 -59
  73. package/stories/organisms/ButtonDropdown/ButtonDropdown.tsx +42 -30
  74. package/stories/organisms/DropdownComponent/Dropdown.stories.tsx +26 -2
  75. package/stories/organisms/DropdownComponent/DropdownComponent.tsx +232 -180
  76. package/stories/organisms/DropdownComponent/dropdownItems.ts +30 -9
  77. package/stories/organisms/DropdownComponent/index.ts +2 -2
  78. package/stories/organisms/EmptySectionPlaceholder/EmptySectionPlaceholder.stories.tsx +3 -3
  79. package/stories/organisms/EmptySectionPlaceholder/index.tsx +2 -1
  80. package/stories/organisms/FormInputWithAddons/FormInputWithAddons.stories.tsx +1 -1
  81. package/stories/organisms/FormInputWithAddons/FormInputWithAddons.tsx +7 -2
  82. package/stories/organisms/index.ts +12 -3
  83. package/tailwind.config.js +81 -37
  84. package/tsconfig.lib.json +13 -6
  85. package/watch.js +49 -0
  86. package/.yarnrc.yml +0 -1
  87. package/dist/types/stories/layouts/index.d.ts +0 -0
  88. package/stories/layouts/CardLayout/CardLayout.stories.tsx +0 -18
  89. package/stories/layouts/CardLayout/CardLayout.tsx +0 -22
  90. package/stories/layouts/CardLayout/index.tsx +0 -3
  91. package/stories/layouts/ModalLayout/ModalLayout.stories.tsx +0 -18
  92. package/stories/layouts/ModalLayout/ModalLayout.tsx +0 -22
  93. package/stories/layouts/ModalLayout/index.tsx +0 -3
  94. package/stories/layouts/index.ts +0 -0
  95. 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
- onChange(value: string): void
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
- onChange,
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) => setValue(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>
@@ -16,7 +16,7 @@ export const DefaultCheckbox: Story = {
16
16
  isError: false,
17
17
  message: "",
18
18
  onChange: (value: string) => {
19
- console.log(`onChange ${value}`)
19
+
20
20
  }
21
21
  }
22
22
  }
@@ -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 ring-1 px-3 ring-gray-300": hasBorder },
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
- 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>()
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
- const onChangeValue = (value: T | undefined) => {
66
- if (value && selectedItem && value[keyProperty] === selectedItem[keyProperty]) {
67
- setSelectedItem(undefined)
68
- } else {
69
- setSelectedItem(value)
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
- useEffect(() => {
74
- if (displayValue) {
75
- const dv = items.find((i) => i[displayProperty] === displayValue)
76
- setSelectedItem(dv)
77
- }
78
- }, [displayValue])
73
+ useEffect(() => {
74
+ if (displayValue) {
75
+ const dv = items.find((i) => i[displayProperty] === displayValue)
76
+ setSelectedItem(dv)
77
+ }
78
+ }, [displayValue])
79
79
 
80
- useEffect(() => {
81
- typeof onChange === "function" && onChange(selectedItem)
82
- }, [selectedItem])
80
+ useEffect(() => {
81
+ typeof onChange === "function" && onChange(selectedItem)
82
+ }, [selectedItem])
83
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
- )}
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
- <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)}
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
- <DynamicIcon icon="XIcon" className="h-4 w-4 " aria-hidden="true" />
132
- </button>
133
- )}
134
- </div>
135
- <HeadlessUICombobox.Button className={buttonStyles}>
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
- {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
- <>
158
+ {selected && (
154
159
  <span
155
160
  className={classNames(
156
- "block truncate",
157
- selected ? "font-semibold" : ""
161
+ "absolute inset-y-0 right-0 flex items-center pr-4",
162
+ active ? "text-white" : "text-purple-600"
158
163
  )}
159
164
  >
160
- {`${item[displayProperty]}`}
165
+ <DynamicIcon icon="IconCheck" className="h-5 w-5" aria-hidden="true" />
161
166
  </span>
162
-
163
- {selected && (
164
- <span
165
- className={classNames(
166
- "absolute inset-y-0 right-0 flex items-center pr-4",
167
- active ? "text-white" : "text-purple-600"
168
- )}
169
- >
170
- <DynamicIcon
171
- icon="CheckIcon"
172
- className="h-5 w-5"
173
- aria-hidden="true"
174
- />
175
- </span>
176
- )}
177
- </>
178
- )}
179
- </HeadlessUICombobox.Option>
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
- console.log(`onChange ${value} ${checked}`)
20
+
21
21
  },
22
22
  onClick: (value: string, checked: boolean) => {
23
- console.log(`onClick ${value} ${checked}`)
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 type ISimpleSelectOptions = {
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 (
@@ -15,7 +15,7 @@ export const DefaultTextarea: Story = {
15
15
  name: "description",
16
16
  rows: 12,
17
17
  cols: 18,
18
- label: "Description",
18
+ label: { display: "Description" },
19
19
  placeholder: dummyText
20
20
  }
21
21
  }
@@ -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?: string
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: externalValue,
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
- {label && (
82
- <InputLabel
83
- isPlaceholder
84
- isActive
85
- label={label}
86
- isRequired={isRequired}
87
- id={id}
88
- isError={isError}
89
- isDisabled={isDisabled}
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={handleOnchange}
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
- console.log(v, "v")
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
- 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
- name: "IconCheck",
65
- type: "solid",
66
- },
67
- variant: "base",
68
- id: "toggle-switch-4",
69
- name: "toggle four",
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: {