@agility/plenum-ui 2.0.0-rc4 → 2.0.0-rc41

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 (102) hide show
  1. package/README.md +104 -31
  2. package/build.js +30 -25
  3. package/dist/index.d.ts +278 -89
  4. package/dist/index.js +1 -5980
  5. package/dist/index.js.map +4 -4
  6. package/dist/tailwind.css +63599 -0
  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 +3 -3
  17. package/dist/types/stories/molecules/inputs/InputCounter/InputCounter.d.ts +10 -0
  18. package/dist/types/stories/molecules/inputs/InputCounter/index.d.ts +2 -0
  19. package/dist/types/stories/molecules/inputs/InputField/InputField.d.ts +6 -4
  20. package/dist/types/stories/molecules/inputs/TextInput/TextInput.d.ts +39 -0
  21. package/dist/types/stories/molecules/inputs/TextInput/index.d.ts +4 -0
  22. package/dist/types/stories/molecules/inputs/index.d.ts +5 -4
  23. package/dist/types/stories/molecules/inputs/select/Select.d.ts +2 -2
  24. package/dist/types/stories/molecules/inputs/textArea/TextArea.d.ts +34 -21
  25. package/dist/types/stories/molecules/inputs/textArea/TextArea.stories.d.ts +4 -4
  26. package/dist/types/stories/molecules/inputs/textArea/index.d.ts +3 -3
  27. package/dist/types/stories/molecules/inputs/toggleSwitch/ToggleSwitch.d.ts +10 -7
  28. package/dist/types/stories/organisms/AnimatedLabelInput/AnimatedLabelInput.d.ts +3 -5
  29. package/dist/types/stories/organisms/AnimatedLabelInput/index.d.ts +1 -1
  30. package/dist/types/stories/organisms/AnimatedLabelTextArea/AnimatedLabelTextArea.d.ts +12 -0
  31. package/dist/types/stories/organisms/AnimatedLabelTextArea/index.d.ts +3 -0
  32. package/dist/types/stories/organisms/DropdownComponent/DropdownComponent.d.ts +21 -12
  33. package/dist/types/stories/organisms/DropdownComponent/index.d.ts +2 -2
  34. package/dist/types/stories/organisms/EmptySectionPlaceholder/index.d.ts +1 -1
  35. package/dist/types/stories/organisms/TextInputSelect/InputSelect.d.ts +16 -0
  36. package/dist/types/stories/organisms/TextInputSelect/TextInputSelect.d.ts +48 -0
  37. package/dist/types/stories/organisms/TextInputSelect/index.d.ts +3 -0
  38. package/dist/types/stories/organisms/index.d.ts +5 -3
  39. package/local.sh +100 -0
  40. package/package.json +36 -19
  41. package/rollup.config.mjs +42 -0
  42. package/stories/Introduction.mdx +1 -1
  43. package/stories/atoms/badges/Badge.tsx +1 -1
  44. package/stories/atoms/buttons/Button/Alternative/Alternative.stories.ts +10 -0
  45. package/stories/atoms/buttons/Button/Button.tsx +108 -24
  46. package/stories/atoms/buttons/Button/Danger/Danger.stories.ts +14 -2
  47. package/stories/atoms/buttons/Button/Primary/Primary.stories.ts +14 -2
  48. package/stories/atoms/buttons/Button/Secondary/Secondary.stories.ts +13 -1
  49. package/stories/atoms/buttons/Button/defaultArgs.ts +1 -1
  50. package/stories/atoms/buttons/Capsule/Capsule.tsx +2 -1
  51. package/stories/atoms/icons/DynamicIcon.stories.ts +1 -1
  52. package/stories/atoms/icons/DynamicIcon.tsx +7 -7
  53. package/stories/atoms/icons/IconWithShadow.stories.ts +3 -3
  54. package/stories/atoms/icons/TablerIcon.tsx +1 -1
  55. package/stories/atoms/loaders/Loader.tsx +12 -6
  56. package/stories/index.ts +22 -10
  57. package/stories/molecules/index.ts +22 -6
  58. package/stories/molecules/inputs/InputField/InputField.tsx +10 -9
  59. package/stories/molecules/inputs/TextInput/TextInput.tsx +6 -3
  60. package/stories/molecules/inputs/TextInput/index.tsx +4 -2
  61. package/stories/molecules/inputs/checkbox/Checkbox.tsx +1 -2
  62. package/stories/molecules/inputs/combobox/ComboBox.tsx +126 -135
  63. package/stories/molecules/inputs/index.ts +18 -4
  64. package/stories/molecules/inputs/select/Select.tsx +1 -1
  65. package/stories/molecules/inputs/textArea/TextArea.stories.ts +7 -5
  66. package/stories/molecules/inputs/textArea/TextArea.tsx +139 -48
  67. package/stories/molecules/inputs/textArea/index.ts +3 -3
  68. package/stories/molecules/inputs/toggleSwitch/ToggleSwitch.tsx +63 -57
  69. package/stories/molecules/tabs/index.tsx +2 -3
  70. package/stories/organisms/AnimatedLabelInput/AnimatedLabelInput.stories.tsx +10 -1
  71. package/stories/organisms/AnimatedLabelInput/AnimatedLabelInput.tsx +43 -37
  72. package/stories/organisms/AnimatedLabelInput/index.tsx +1 -1
  73. package/stories/organisms/AnimatedLabelTextArea/AnimatedLabelTextArea.stories.tsx +26 -0
  74. package/stories/organisms/AnimatedLabelTextArea/AnimatedLabelTextArea.tsx +61 -0
  75. package/stories/organisms/AnimatedLabelTextArea/index.tsx +3 -0
  76. package/stories/organisms/ButtonDropdown/ButtonDropdown.stories.tsx +65 -58
  77. package/stories/organisms/ButtonDropdown/ButtonDropdown.tsx +26 -21
  78. package/stories/organisms/DropdownComponent/Dropdown.stories.tsx +2 -2
  79. package/stories/organisms/DropdownComponent/DropdownComponent.tsx +213 -178
  80. package/stories/organisms/DropdownComponent/dropdownItems.ts +30 -9
  81. package/stories/organisms/DropdownComponent/index.ts +2 -2
  82. package/stories/organisms/EmptySectionPlaceholder/EmptySectionPlaceholder.stories.tsx +3 -3
  83. package/stories/organisms/EmptySectionPlaceholder/index.tsx +2 -1
  84. package/stories/organisms/FormInputWithAddons/FormInputWithAddons.stories.tsx +1 -1
  85. package/stories/organisms/FormInputWithAddons/FormInputWithAddons.tsx +7 -2
  86. package/stories/organisms/TextInputSelect/InputSelect.tsx +59 -0
  87. package/stories/organisms/TextInputSelect/TextInputSelect.stories.tsx +33 -0
  88. package/stories/organisms/TextInputSelect/TextInputSelect.tsx +186 -0
  89. package/stories/organisms/TextInputSelect/index.tsx +3 -0
  90. package/stories/organisms/index.ts +15 -4
  91. package/tsconfig.lib.json +13 -6
  92. package/watch.js +49 -0
  93. package/.yarnrc.yml +0 -1
  94. package/dist/types/stories/layouts/index.d.ts +0 -0
  95. package/stories/layouts/CardLayout/CardLayout.stories.tsx +0 -18
  96. package/stories/layouts/CardLayout/CardLayout.tsx +0 -22
  97. package/stories/layouts/CardLayout/index.tsx +0 -3
  98. package/stories/layouts/ModalLayout/ModalLayout.stories.tsx +0 -18
  99. package/stories/layouts/ModalLayout/ModalLayout.tsx +0 -22
  100. package/stories/layouts/ModalLayout/index.tsx +0 -3
  101. package/stories/layouts/index.ts +0 -0
  102. package/stories/organisms/DropdownComponent/Dropdown.test.tsx +0 -0
@@ -1,5 +1,4 @@
1
- import React, { Fragment, HTMLAttributes, useState } from "react"
2
- import { Transition } from "@headlessui/react"
1
+ import React, { HTMLAttributes, useEffect, useMemo, useRef, useState } from "react"
3
2
  import { default as cn } from "classnames"
4
3
  import {
5
4
  useFloating,
@@ -13,50 +12,58 @@ import {
13
12
  autoPlacement,
14
13
  shift,
15
14
  FloatingPortal,
15
+ FloatingList,
16
16
  useTransitionStyles,
17
- Placement
17
+ Placement,
18
+ useListNavigation
18
19
  } from "@floating-ui/react"
19
20
 
20
21
  import { ClassNameWithAutocomplete } from "utils/types"
21
22
  import { DynamicIcon, IDynamicIconProps, UnifiedIconName } from "@/stories/atoms/icons"
23
+ import { list } from "postcss"
22
24
 
23
- export interface IItemProp extends HTMLAttributes<HTMLButtonElement> {
24
- icon?: IDynamicIconProps | UnifiedIconName
25
+ export interface IItemProp {
26
+ //Don't think this needs to extend HtmlButton... extends HTMLAttributes<HTMLButtonElement> {
27
+ icon?: IDynamicIconProps
25
28
  iconPosition?: "trailing" | "leading"
26
29
  label: string
27
30
  onClick?(): void
28
31
  isEmphasized?: boolean
29
32
  key: React.Key
33
+ iconObj?: JSX.Element
30
34
  }
31
- export interface IDropdownClassnames {
32
- groupClassname?: ClassNameWithAutocomplete
33
- itemsClassname?: ClassNameWithAutocomplete
34
- itemClassname?: ClassNameWithAutocomplete
35
- activeItemClassname?: ClassNameWithAutocomplete
36
- buttonClassname?: ClassNameWithAutocomplete
37
- }
35
+
38
36
  export interface IDropdownProps extends HTMLAttributes<HTMLDivElement> {
39
37
  items: IItemProp[][]
40
38
  label: string
41
39
  CustomDropdownTrigger?: React.ReactNode
42
40
  id: string
43
- classNames?: IDropdownClassnames
41
+ groupClassname?: ClassNameWithAutocomplete
42
+ itemsClassname?: ClassNameWithAutocomplete
43
+ itemClassname?: ClassNameWithAutocomplete
44
+ activeItemClassname?: ClassNameWithAutocomplete
45
+ buttonClassname?: ClassNameWithAutocomplete
46
+ iconClassname?: ClassNameWithAutocomplete
47
+ iconSpacingClassname?: ClassNameWithAutocomplete
44
48
  placement?: Placement
45
49
  offsetOptions?: Partial<{
46
50
  mainAxis: number
47
51
  crossAxis: number
48
52
  alignmentAxis: number | null
49
53
  }>
54
+ disabled?: boolean
50
55
  }
51
- export const defaultClassNames: IDropdownClassnames = {
56
+ export const defaultClassNames = {
52
57
  groupClassname: "flex inline-block text-left",
53
58
  itemsClassname:
54
- "mt-2 origin-bottom-right rounded bg-white shadow-lg z-20 divide-y divide-gray-100 border border-gray-300 ",
59
+ "mt-2 origin-bottom-right rounded bg-white shadow-lg z-[99999] divide-y divide-gray-100 border border-gray-300 ",
55
60
  itemClassname:
56
61
  "group flex font-muli cursor-pointer items-center px-4 py-2 text-sm transition-all hover:bg-gray-100 hover:text-gray-900 justify-between gap-4 ",
57
62
  activeItemClassname: "block px-4 py-2 text-sm text-gray-700 bg-gray-100 hover:bg-gray-200 hover:text-gray-900",
58
63
  buttonClassname:
59
- "py-[2px] z-20 flex items-center rounded outline-purple-500 transition-all text-gray-400 hover:text-gray-600 "
64
+ "py-[2px] flex items-center rounded outline-purple-500 transition-all text-gray-400 hover:text-gray-600 ",
65
+ iconClassname: "ml-1 h-5 w-6",
66
+ iconSpacingClassname: "flex items-center gap-x-4"
60
67
  }
61
68
 
62
69
  /** Comment */
@@ -64,19 +71,34 @@ const Dropdown: React.FC<IDropdownProps> = ({
64
71
  items,
65
72
  id,
66
73
  label,
67
- classNames = defaultClassNames,
74
+ groupClassname,
75
+ itemsClassname,
76
+ itemClassname,
77
+ activeItemClassname,
78
+ buttonClassname,
79
+ iconClassname,
80
+ iconSpacingClassname,
68
81
  CustomDropdownTrigger,
69
82
  placement = "bottom-start",
70
83
  offsetOptions,
84
+ disabled,
71
85
  ...props
72
86
  }: IDropdownProps): JSX.Element | null => {
73
87
  const [isOpen, setIsOpen] = useState(false)
74
88
  const [activeItem, setActiveItem] = useState<React.Key | null>(null)
89
+ const [activeIndex, setActiveIndex] = useState<number | null>(null)
90
+
91
+ const listRef = useRef<(HTMLButtonElement | null)[]>([])
75
92
 
76
93
  // Floating UI logic
77
94
  const { refs, floatingStyles, context } = useFloating({
78
95
  open: isOpen,
79
- onOpenChange: setIsOpen,
96
+ onOpenChange: (bool) => {
97
+ console.log("onOpenChange", bool)
98
+ listRef.current = []
99
+ setActiveIndex(null)
100
+ setIsOpen(bool)
101
+ },
80
102
  placement,
81
103
  middleware: [
82
104
  offset(offsetOptions ?? 10),
@@ -90,26 +112,161 @@ const Dropdown: React.FC<IDropdownProps> = ({
90
112
  const click = useClick(context)
91
113
  const dismiss = useDismiss(context)
92
114
  const role = useRole(context)
93
- const { getReferenceProps, getFloatingProps } = useInteractions([click, dismiss, role])
115
+ const listNavigation = useListNavigation(context, {
116
+ listRef,
117
+ activeIndex,
118
+ onNavigate: (index) => {
119
+ if (index !== null && listRef.current[index]) {
120
+ setActiveIndex(index)
121
+ listRef.current[index]?.focus()
122
+ }
123
+ }
124
+ })
125
+
126
+ const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions([
127
+ click,
128
+ dismiss,
129
+ role,
130
+ listNavigation
131
+ ])
132
+
133
+ const ItemComponents = useMemo(
134
+ () =>
135
+ items.map((itemStack, stackIndex) => {
136
+ return itemStack.map((item, itemIndex) => {
137
+ const { key, label, icon, iconObj, iconPosition, isEmphasized, onClick, ...rest } = item
138
+ const active = activeItem && activeItem === key
139
+ const itemClass = cn(
140
+ defaultClassNames.itemClassname,
141
+ itemClassname,
142
+ "group flex cursor-pointer items-center px-4 py-2 text-sm transition-all",
143
+ {
144
+ "text-red-500": isEmphasized
145
+ },
146
+ {
147
+ "text-gray-900": !isEmphasized
148
+ },
149
+ {
150
+ "bg-gray-100 text-gray-900": active
151
+ },
152
+ active ? cn(defaultClassNames.activeItemClassname, activeItemClassname) : "",
153
+ {
154
+ "bg-gray-100 text-red-500 hover:text-red-500": active && isEmphasized
155
+ }
156
+ )
157
+ return (
158
+ <button
159
+ {...{
160
+ key: key,
161
+ id: key.toString(),
162
+ className: cn(itemClass, "w-full"),
163
+ ...rest,
164
+ ...getItemProps(),
165
+ onClick: () => {
166
+ onClick && onClick()
167
+ setTimeout(() => {
168
+ //hide the dropdown after click
169
+ setIsOpen(false)
170
+ }, 150)
171
+ }
172
+ }}
173
+ ref={(node) => {
174
+ //If the list ref already contains a node with the same id do nothing, otherwise add it
175
+ if (listRef.current.some((item) => item?.id === key)) {
176
+ return
177
+ }
178
+ listRef.current.push(node)
179
+ }}
180
+ key={key}
181
+ >
182
+ <div className={cn(defaultClassNames.iconSpacingClassname, iconSpacingClassname)}>
183
+ {iconObj && (iconPosition === "leading" || iconPosition === undefined) && (
184
+ <>{iconObj}</>
185
+ )}
186
+ {icon &&
187
+ (iconPosition === "leading" || iconPosition === undefined) &&
188
+ (typeof icon === "string" ? (
189
+ <DynamicIcon
190
+ {...{
191
+ icon: icon,
192
+ className: cn(
193
+ {
194
+ "text-red-500": isEmphasized
195
+ },
196
+ "opacity-60 group"
197
+ )
198
+ }}
199
+ />
200
+ ) : (
201
+ <DynamicIcon
202
+ {...{
203
+ ...icon,
204
+ className: cn(
205
+ icon.className,
206
+ {
207
+ "text-red-500": isEmphasized
208
+ },
209
+ "opacity-60 group"
210
+ )
211
+ }}
212
+ />
213
+ ))}
214
+ <div className="whitespace-nowrap">{label}</div>
215
+ {iconObj && iconPosition === "trailing" && <>{iconObj}</>}
216
+ {icon &&
217
+ iconPosition === "trailing" &&
218
+ (typeof icon === "string" ? (
219
+ <DynamicIcon
220
+ {...{
221
+ icon: icon,
222
+ className: cn(
223
+ {
224
+ "text-red-500": isEmphasized
225
+ },
226
+ "opacity-60 group"
227
+ )
228
+ }}
229
+ />
230
+ ) : (
231
+ <DynamicIcon
232
+ {...{
233
+ ...icon,
234
+ className: cn(
235
+ icon.className,
236
+ {
237
+ "text-red-500": isEmphasized
238
+ },
239
+ "opacity-60 group"
240
+ )
241
+ }}
242
+ />
243
+ ))}
244
+ </div>
245
+ </button>
246
+ )
247
+ })
248
+ }),
249
+ [activeItem, activeItemClassname, getItemProps, iconSpacingClassname, itemClassname, items]
250
+ )
251
+
94
252
  const { isMounted, styles: transitionStyles } = useTransitionStyles(context, {
95
253
  duration: {
96
254
  open: 200,
97
255
  close: 200
98
256
  },
99
257
  initial: {
100
- opacity: 0
258
+ opacity: 0,
259
+ scale: 95
101
260
  },
102
261
  open: {
103
- opacity: 1
262
+ opacity: 1,
263
+ scale: 100
104
264
  }
105
265
  })
106
-
107
- const { groupClassname, buttonClassname, itemsClassname, itemClassname, activeItemClassname } = classNames
108
-
109
266
  return (
110
267
  <div
111
268
  {...{
112
- className: groupClassname,
269
+ className: cn(defaultClassNames.groupClassname, groupClassname),
113
270
  role: "combobox",
114
271
  "aria-owns": `${id}-list`,
115
272
  "aria-expanded": isOpen,
@@ -120,10 +277,12 @@ const Dropdown: React.FC<IDropdownProps> = ({
120
277
  <button
121
278
  {...{
122
279
  ref: refs.setReference,
123
- className: buttonClassname,
280
+ className: cn(defaultClassNames.buttonClassname, buttonClassname),
124
281
  onClick: () => {
125
282
  setIsOpen(!isOpen)
126
283
  },
284
+ type: "button",
285
+ disabled: disabled,
127
286
  ...getReferenceProps()
128
287
  }}
129
288
  >
@@ -132,166 +291,42 @@ const Dropdown: React.FC<IDropdownProps> = ({
132
291
  ) : (
133
292
  <>
134
293
  <span className="pl-1">{label}</span>
135
- <DynamicIcon icon="ChevronDownIcon" className="ml-1 h-5 w-6 " />
294
+ <DynamicIcon
295
+ icon="IconChevronDown"
296
+ className={cn(defaultClassNames.iconClassname, iconClassname)}
297
+ />
136
298
  </>
137
299
  )}
138
300
  </button>
139
301
 
140
302
  {isMounted && items.length > 0 && isOpen && (
141
- <FloatingPortal>
142
- <FloatingFocusManager context={context} modal={true}>
143
- <Transition
144
- as={Fragment}
145
- show={isOpen}
146
- enter="transition ease-out duration-100"
147
- enterFrom="transform opacity-0 scale-95"
148
- enterTo="transform opacity-100 scale-100"
149
- leave="transition ease-in duration-75"
150
- leaveFrom="transform opacity-100 scale-100"
151
- leaveTo="transform opacity-0 scale-95"
152
- >
153
- <ul
154
- {...{
155
- ...getFloatingProps(),
156
- className: itemsClassname,
157
- ref: refs.setFloating,
158
- // style: floatingStyles,
159
- "aria-labelledby": label,
160
- id: `${id}-list`,
161
- role: "listbox",
162
- style: {
163
- position: context.strategy,
164
- top: Math.round(context.y ?? 0),
165
- left: Math.round(context.x ?? 0),
166
- width: "max-content",
167
- maxWidth: "min(calc(100vw - 10px), 25rem)",
168
- ...floatingStyles
169
- }
170
- }}
171
- className={itemsClassname}
303
+ <FloatingList
304
+ {...{
305
+ elementsRef: listRef
306
+ }}
307
+ >
308
+ <FloatingPortal>
309
+ <FloatingFocusManager context={context} modal={true}>
310
+ <div
311
+ {...getFloatingProps()}
312
+ className={cn(defaultClassNames.itemsClassname, itemsClassname)}
172
313
  ref={refs.setFloating}
173
314
  aria-labelledby={label}
174
- {...getFloatingProps()}
315
+ style={{
316
+ position: context.strategy,
317
+ top: Math.round(context.y ?? 0),
318
+ left: Math.round(context.x ?? 0),
319
+ width: "max-content",
320
+ maxWidth: "min(calc(100vw - 10px), 25rem)",
321
+ ...floatingStyles,
322
+ ...transitionStyles
323
+ }}
175
324
  >
176
- {items.map((itemStack, idx) => {
177
- return (
178
- <React.Fragment key={`${idx}-list-${id}`}>
179
- {itemStack.map(
180
- ({
181
- onClick,
182
- label,
183
- key,
184
- isEmphasized,
185
- icon,
186
- iconPosition,
187
- ...rest
188
- }) => {
189
- const active = activeItem && activeItem === key
190
- const itemClass = cn(
191
- itemClassname,
192
- "group flex cursor-pointer items-center px-4 py-2 text-sm transition-all",
193
- {
194
- "text-red-500": isEmphasized
195
- },
196
- {
197
- "text-gray-900": !isEmphasized
198
- },
199
- {
200
- "bg-gray-100 text-gray-900": active
201
- },
202
- active ? activeItemClassname : "",
203
- {
204
- "bg-gray-100 text-red-500 hover:text-red-500":
205
- active && isEmphasized
206
- },
207
- itemClassname
208
- )
209
-
210
- return (
211
- <li key={key}>
212
- <button
213
- {...{
214
- onClick: () => {
215
- setActiveItem(key)
216
- onClick && onClick()
217
- },
218
- key,
219
- className: cn(itemClass, "w-full"),
220
- ...rest
221
- }}
222
- >
223
- <div className="flex items-center gap-x-4">
224
- {icon &&
225
- (iconPosition === "leading" ||
226
- iconPosition === undefined) &&
227
- (typeof icon === "string" ? (
228
- <DynamicIcon
229
- {...{
230
- icon: icon,
231
- className: cn(
232
- {
233
- "text-red-500": isEmphasized
234
- },
235
- "opacity-60 group"
236
- )
237
- }}
238
- />
239
- ) : (
240
- <DynamicIcon
241
- {...{
242
- ...icon,
243
- className: cn(
244
- icon.className,
245
- {
246
- "text-red-500": isEmphasized
247
- },
248
- "opacity-60 group"
249
- )
250
- }}
251
- />
252
- ))}
253
- <div className="whitespace-nowrap">{label}</div>
254
- {icon &&
255
- iconPosition === "trailing" &&
256
- (typeof icon === "string" ? (
257
- <DynamicIcon
258
- {...{
259
- icon: icon,
260
- className: cn(
261
- {
262
- "text-red-500": isEmphasized
263
- },
264
- "opacity-60 group"
265
- )
266
- }}
267
- />
268
- ) : (
269
- <DynamicIcon
270
- {...{
271
- ...icon,
272
- className: cn(
273
- icon.className,
274
- {
275
- "text-red-500": isEmphasized
276
- },
277
- "opacity-60 group"
278
- )
279
- }}
280
- />
281
- ))}
282
- </div>
283
- </button>
284
- </li>
285
- )
286
- }
287
- )}
288
- </React.Fragment>
289
- )
290
- })}
291
- </ul>
292
- </Transition>
293
- </FloatingFocusManager>
294
- </FloatingPortal>
325
+ {ItemComponents}
326
+ </div>
327
+ </FloatingFocusManager>
328
+ </FloatingPortal>
329
+ </FloatingList>
295
330
  )}
296
331
  </div>
297
332
  )
@@ -3,15 +3,26 @@ import { IItemProp } from "./DropdownComponent"
3
3
  export const dropdownDataBase: IItemProp[][] = [
4
4
  [
5
5
  {
6
+ icon: {
7
+ icon: "IconCopy"
8
+ // pos: "leading",
9
+ // className: "h-5 w-5",
10
+ // outline: false
11
+ },
6
12
  key: "Copy",
7
- label: "Copy",
13
+ label: "Copy to Clipboard",
8
14
  onClick: () => {
9
15
  console.log("Copy action")
10
16
  }
11
- }
12
- ],
13
- [
17
+ },
18
+
14
19
  {
20
+ icon: {
21
+ icon: "IconPlus"
22
+ // pos: "leading",
23
+ // className: "h-5 w-5",
24
+ // outline: false
25
+ },
15
26
  key: "Add to Batch",
16
27
  label: "Add to Batch",
17
28
  onClick: () => {
@@ -19,15 +30,25 @@ export const dropdownDataBase: IItemProp[][] = [
19
30
  }
20
31
  },
21
32
  {
33
+ icon: {
34
+ icon: "IconEye"
35
+ // pos: "leading",
36
+ // className: "h-5 w-5",
37
+ // outline: false
38
+ },
22
39
  key: "View Batch",
23
40
  label: "View Batch",
24
41
  onClick: () => {
25
42
  console.log("View Batch action")
26
43
  }
27
- }
28
- ],
29
- [
44
+ },
30
45
  {
46
+ icon: {
47
+ icon: "IconTrash"
48
+ // pos: "leading",
49
+ // className: "h-5 w-5",
50
+ // outline: false
51
+ },
31
52
  label: "Delete",
32
53
  onClick: () => {
33
54
  console.log("Delete action")
@@ -42,13 +63,13 @@ export const dropdownDataWithIcons: IItemProp[][] = [
42
63
  [
43
64
  {
44
65
  icon: {
45
- icon: "IconClipboardCopy",
66
+ icon: "IconCopy",
46
67
  className: "h-5 w-5",
47
68
  outline: false
48
69
  },
49
70
  iconPosition: "leading",
50
71
  key: "Copy",
51
- label: "Copy",
72
+ label: "Copy Item",
52
73
  onClick: () => {
53
74
  console.log("Copy action")
54
75
  }
@@ -1,4 +1,4 @@
1
- import Dropdown, { IItemProp, IDropdownClassnames, IDropdownProps, defaultClassNames } from "./DropdownComponent"
2
- export type { IItemProp, IDropdownClassnames, IDropdownProps }
1
+ import Dropdown, { IItemProp, IDropdownProps, defaultClassNames } from "./DropdownComponent"
2
+ export type { IItemProp, IDropdownProps }
3
3
  export { defaultClassNames }
4
4
  export default Dropdown
@@ -39,7 +39,7 @@ export const CallsToAction: Story = {
39
39
  {
40
40
  actionType: "alternative",
41
41
  icon: {
42
- icon: "UploadIcon",
42
+ icon: "IconUpload",
43
43
  outline: true
44
44
  },
45
45
  iconPosition: "leading",
@@ -49,7 +49,7 @@ export const CallsToAction: Story = {
49
49
  {
50
50
  actionType: "alternative",
51
51
  icon: {
52
- icon: "ViewGridIcon",
52
+ icon: "IconGridDots",
53
53
  outline: true
54
54
  },
55
55
  size: "lg",
@@ -64,7 +64,7 @@ export const CallsToAction: Story = {
64
64
  export const NoActions: Story = {
65
65
  args: {
66
66
  icon: {
67
- icon: "PencilAltIcon",
67
+ icon: "IconPencil",
68
68
  className: "h-5 w-5 text-gray-400 ",
69
69
  outline: true
70
70
  },
@@ -1,3 +1,4 @@
1
1
  import EmptySectionPlaceholder, { IEmptySectionPlaceholderProps } from "./EmptySectionPlaceholder"
2
- export default EmptySectionPlaceholder
2
+
3
3
  export type { IEmptySectionPlaceholderProps }
4
+ export default EmptySectionPlaceholder
@@ -24,6 +24,6 @@ export const DefaultFormInputWithAddons: Story = {
24
24
  leadLabel: "Search",
25
25
  addonOffset: 60,
26
26
  labelClass: "text-gray-900",
27
- trailIcon: { icon: "SearchIcon" }
27
+ trailIcon: { icon: "IconSearch" }
28
28
  }
29
29
  }
@@ -79,7 +79,12 @@ const FormInputWithAddons: React.FC<IFormInputWithAddonsProps> = ({
79
79
  <DynamicIcon
80
80
  {...{
81
81
  ...leadIcon,
82
- className: cn("h-5 w-5 text-gray-400", leadIconClassNames, customIconClass),
82
+ className: cn(
83
+ "h-5 w-5 text-gray-400",
84
+ leadIconClassNames,
85
+ customIconClass,
86
+ leadIcon.className
87
+ ),
83
88
  outline: iconOutlined
84
89
  }}
85
90
  />
@@ -123,7 +128,7 @@ const FormInputWithAddons: React.FC<IFormInputWithAddonsProps> = ({
123
128
  <DynamicIcon
124
129
  {...{
125
130
  ...trailIcon,
126
- className: cn("h-5 w-5 text-gray-400", customIconClass),
131
+ className: cn("h-5 w-5 text-gray-400", customIconClass, trailIcon.className),
127
132
  outline: iconOutlined
128
133
  }}
129
134
  />
@@ -0,0 +1,59 @@
1
+ import React, { FC, useState } from "react"
2
+ import { default as cn } from "classnames"
3
+
4
+ export type SelectOptions = {
5
+ label: string
6
+ value: string
7
+ }
8
+ export interface InputSelectProps {
9
+ align: "left" | "right"
10
+ /** Show the CTA without Background color and a border seperator */
11
+ inputOptions: SelectOptions[]
12
+ /** Onclick callback */
13
+ onSelectOption?(value: string): void
14
+ className?: string
15
+ isDisabled?: boolean
16
+ }
17
+
18
+ /** Comment */
19
+ export const InputSelect: FC<InputSelectProps> = ({
20
+ inputOptions,
21
+ onSelectOption,
22
+ align = "right",
23
+ className,
24
+ isDisabled
25
+ }: InputSelectProps): JSX.Element | null => {
26
+ const [selectedOption, setSelectedOption] = useState<string>(inputOptions[0].value)
27
+
28
+ const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
29
+ const targetValue = e.target.value
30
+ onSelectOption && onSelectOption(targetValue)
31
+ setSelectedOption(targetValue)
32
+ }
33
+
34
+ if (!inputOptions?.length) return null
35
+ return (
36
+ <select
37
+ className={cn(
38
+ "relative z-10 inline-flex items-center space-x-2 border border-gray-300 bg-white px-4 py-2 pr-7 text-sm font-medium",
39
+ "focus:border-purple-500 focus:outline-none focus:ring-1 focus:ring-purple-500",
40
+ align === "right"
41
+ ? "-ml-px rounded-r border-l-white text-gray-700"
42
+ : align === "left"
43
+ ? "-mr-px rounded-l border-r-white text-gray-500 focus-within:z-10"
44
+ : "",
45
+ !onSelectOption ? "cursor-default" : "",
46
+ className
47
+ )}
48
+ onChange={handleChange}
49
+ value={selectedOption}
50
+ disabled={isDisabled}
51
+ >
52
+ {inputOptions.map((option) => (
53
+ <option key={option.value} value={option.value}>
54
+ {option.label}
55
+ </option>
56
+ ))}
57
+ </select>
58
+ )
59
+ }