@agility/plenum-ui 2.0.0-rc2 → 2.0.0-rc3

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.
@@ -7,6 +7,7 @@ export declare const Alternative: Story;
7
7
  export declare const AlternativeTrailingIcon: Story;
8
8
  export declare const AlternativeLeadingIcon: Story;
9
9
  export declare const AlternativeExtraSmall: Story;
10
+ export declare const AlternativeSimpleIconName: Story;
10
11
  export declare const AlternativeSmall: Story;
11
12
  export declare const AlternativeMedium: Story;
12
13
  export declare const AlternativeLarge: Story;
@@ -1,15 +1,15 @@
1
1
  import { HTMLAttributeAnchorTarget } from "react";
2
- import { IDynamicIconProps } from "../../icons";
2
+ import { UnifiedIconName, IDynamicIconProps } from "../../icons";
3
3
  export type BTNActionType = "primary" | "secondary" | "alternative" | "danger";
4
4
  export interface IButtonProps extends React.ComponentPropsWithoutRef<"button"> {
5
5
  /** Is the button a Primary CTA, alternative or danger button? */
6
- actionType: BTNActionType;
6
+ actionType?: BTNActionType;
7
7
  /** How lg should the button be? - Defaults to 'base'. */
8
8
  size?: "xs" | "sm" | "md" | "lg" | "xl";
9
9
  /** The Button's text content. */
10
10
  label: string;
11
11
  /** The Icon to be displayed inside the button. */
12
- icon?: IDynamicIconProps;
12
+ icon?: IDynamicIconProps | UnifiedIconName;
13
13
  /** Does the button width grow to fill it's container? */
14
14
  fullWidth?: boolean;
15
15
  /** Optionally render as anchor tag */
@@ -25,9 +25,11 @@ export interface IButtonProps extends React.ComponentPropsWithoutRef<"button"> {
25
25
  /** Is the associated content loading? */
26
26
  isLoading?: boolean;
27
27
  className?: string;
28
+ iconObj?: React.ReactNode;
29
+ ref?: React.LegacyRef<HTMLButtonElement>;
28
30
  }
29
31
  /**
30
32
  * Primary UI component for user interaction
31
33
  */
32
- declare const Button: ({ actionType, size, label, icon, CustomSVGIcon, fullWidth, iconPosition, asLink, isLoading, className, ...props }: IButtonProps) => import("react/jsx-runtime").JSX.Element;
34
+ declare const Button: ({ actionType, size, label, icon, iconObj, CustomSVGIcon, fullWidth, iconPosition, asLink, isLoading, className, ref, ...props }: IButtonProps) => import("react/jsx-runtime").JSX.Element;
33
35
  export default Button;
@@ -6,6 +6,7 @@ type Story = StoryObj<typeof Button>;
6
6
  export declare const Danger: Story;
7
7
  export declare const DangerTrailingIcon: Story;
8
8
  export declare const DangerLeadingIcon: Story;
9
+ export declare const DangerSimpleIconName: Story;
9
10
  export declare const DangerExtraSmall: Story;
10
11
  export declare const DangerSmall: Story;
11
12
  export declare const DangerMedium: Story;
@@ -5,6 +5,7 @@ export default meta;
5
5
  type Story = StoryObj<typeof Button>;
6
6
  export declare const Primary: Story;
7
7
  export declare const PrimaryLeadingIcon: Story;
8
+ export declare const PrimarySimpleIconName: Story;
8
9
  export declare const PrimaryTrailingIcon: Story;
9
10
  export declare const PrimaryExtraSmall: Story;
10
11
  export declare const PrimarySmall: Story;
@@ -6,6 +6,7 @@ type Story = StoryObj<typeof Button>;
6
6
  export declare const Secondary: Story;
7
7
  export declare const SecondaryTrailingIcon: Story;
8
8
  export declare const SecondaryLeadingIcon: Story;
9
+ export declare const SecondarySimpleIconName: Story;
9
10
  export declare const SecondaryExtraSmall: Story;
10
11
  export declare const SecondarySmall: Story;
11
12
  export declare const SecondaryMedium: Story;
@@ -1,14 +1,10 @@
1
1
  import React, { HTMLAttributes } from "react";
2
2
  import { Placement } from "@floating-ui/react";
3
3
  import { ClassNameWithAutocomplete } from "utils/types";
4
- import { IDynamicIconProps } from "@/stories/atoms/icons";
4
+ import { IDynamicIconProps, UnifiedIconName } from "@/stories/atoms/icons";
5
5
  export interface IItemProp extends HTMLAttributes<HTMLButtonElement> {
6
- icon?: {
7
- name: IDynamicIconProps["icon"];
8
- className?: ClassNameWithAutocomplete;
9
- pos?: "trailing" | "leading";
10
- outline?: boolean;
11
- };
6
+ icon?: IDynamicIconProps | UnifiedIconName;
7
+ iconPosition?: "trailing" | "leading";
12
8
  label: string;
13
9
  onClick?(): void;
14
10
  isEmphasized?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agility/plenum-ui",
3
- "version": "2.0.0-rc2",
3
+ "version": "2.0.0-rc3",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -63,4 +63,4 @@
63
63
  "tailwindcss": "^3.2.4",
64
64
  "typescript": "^5.1.6"
65
65
  }
66
- }
66
+ }
@@ -41,6 +41,13 @@ export const AlternativeExtraSmall: Story = {
41
41
  size: "sm"
42
42
  }
43
43
  }
44
+ export const AlternativeSimpleIconName: Story = {
45
+ args: {
46
+ ...Alternative.args,
47
+ icon: defaultIcon.icon,
48
+ iconPosition: "leading"
49
+ }
50
+ }
44
51
  export const AlternativeSmall: Story = {
45
52
  args: {
46
53
  ...Alternative.args,
@@ -8,13 +8,13 @@ import { DynamicIcon, UnifiedIconName, IDynamicIconProps } from "../../icons"
8
8
  export type BTNActionType = "primary" | "secondary" | "alternative" | "danger"
9
9
  export interface IButtonProps extends React.ComponentPropsWithoutRef<"button"> {
10
10
  /** Is the button a Primary CTA, alternative or danger button? */
11
- actionType: BTNActionType
11
+ actionType?: BTNActionType
12
12
  /** How lg should the button be? - Defaults to 'base'. */
13
13
  size?: "xs" | "sm" | "md" | "lg" | "xl"
14
14
  /** The Button's text content. */
15
15
  label: string
16
16
  /** The Icon to be displayed inside the button. */
17
- icon?: IDynamicIconProps
17
+ icon?: IDynamicIconProps | UnifiedIconName
18
18
  /** Does the button width grow to fill it's container? */
19
19
  fullWidth?: boolean
20
20
  /** Optionally render as anchor tag */
@@ -30,6 +30,8 @@ export interface IButtonProps extends React.ComponentPropsWithoutRef<"button"> {
30
30
  /** Is the associated content loading? */
31
31
  isLoading?: boolean
32
32
  className?: string
33
+ iconObj?: React.ReactNode
34
+ ref?: React.LegacyRef<HTMLButtonElement>
33
35
  }
34
36
  /**
35
37
  * Primary UI component for user interaction
@@ -39,12 +41,14 @@ const Button = ({
39
41
  size = "sm",
40
42
  label,
41
43
  icon,
44
+ iconObj,
42
45
  CustomSVGIcon,
43
46
  fullWidth = false,
44
47
  iconPosition = "trailing",
45
48
  asLink,
46
49
  isLoading = false,
47
50
  className,
51
+ ref,
48
52
  ...props
49
53
  }: IButtonProps) => {
50
54
  const iconStyles = cn(
@@ -88,6 +92,7 @@ const Button = ({
88
92
  },
89
93
  className ? className : ""
90
94
  )}
95
+ ref={ref}
91
96
  {...props}
92
97
  >
93
98
  {CustomSVGIcon &&
@@ -96,11 +101,20 @@ const Button = ({
96
101
  ) : (
97
102
  <i>{CustomSVGIcon}</i>
98
103
  ))}
104
+ {iconObj &&
105
+ iconPosition === "leading" &&
106
+ (!isLoading ? (
107
+ <>{iconObj}</>
108
+ ) : (
109
+ <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
110
+ ))}
99
111
 
100
112
  {icon &&
101
113
  iconPosition === "leading" &&
102
114
  (isLoading ? (
103
115
  <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
116
+ ) : typeof icon === "string" ? (
117
+ <DynamicIcon {...{ icon: icon, className: iconStyles }} />
104
118
  ) : (
105
119
  <DynamicIcon {...{ ...icon, className: iconStyles }} />
106
120
  ))}
@@ -113,9 +127,18 @@ const Button = ({
113
127
  iconPosition === "trailing" &&
114
128
  (isLoading ? (
115
129
  <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
130
+ ) : typeof icon === "string" ? (
131
+ <DynamicIcon {...{ icon: icon, className: iconStyles }} />
116
132
  ) : (
117
133
  <DynamicIcon {...{ ...icon, className: iconStyles }} />
118
134
  ))}
135
+ {iconObj &&
136
+ iconPosition === "trailing" &&
137
+ (!isLoading ? (
138
+ <>{iconObj}</>
139
+ ) : (
140
+ <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
141
+ ))}
119
142
  </button>
120
143
  )
121
144
  }
@@ -38,6 +38,13 @@ export const DangerLeadingIcon: Story = {
38
38
  iconPosition: "leading"
39
39
  }
40
40
  }
41
+ export const DangerSimpleIconName: Story = {
42
+ args: {
43
+ ...Danger.args,
44
+ icon: "TrashIcon",
45
+ iconPosition: "leading"
46
+ }
47
+ }
41
48
  export const DangerExtraSmall: Story = {
42
49
  args: {
43
50
  ...Danger.args,
@@ -39,6 +39,13 @@ export const PrimaryLeadingIcon: Story = {
39
39
  iconPosition: "leading"
40
40
  }
41
41
  }
42
+ export const PrimarySimpleIconName: Story = {
43
+ args: {
44
+ ...Primary.args,
45
+ icon: "CheckIcon",
46
+ iconPosition: "leading"
47
+ }
48
+ }
42
49
  export const PrimaryTrailingIcon: Story = {
43
50
  args: {
44
51
  ...PrimaryLeadingIcon.args,
@@ -41,6 +41,13 @@ export const SecondaryLeadingIcon: Story = {
41
41
  iconPosition: "leading"
42
42
  }
43
43
  }
44
+ export const SecondarySimpleIconName: Story = {
45
+ args: {
46
+ ...Secondary.args,
47
+ icon: "BellIcon",
48
+ iconPosition: "leading"
49
+ }
50
+ }
44
51
  export const SecondaryExtraSmall: Story = {
45
52
  args: {
46
53
  ...Secondary.args,
@@ -18,15 +18,11 @@ import {
18
18
  } from "@floating-ui/react"
19
19
 
20
20
  import { ClassNameWithAutocomplete } from "utils/types"
21
- import { DynamicIcon, IDynamicIconProps } from "@/stories/atoms/icons"
21
+ import { DynamicIcon, IDynamicIconProps, UnifiedIconName } from "@/stories/atoms/icons"
22
22
 
23
23
  export interface IItemProp extends HTMLAttributes<HTMLButtonElement> {
24
- icon?: {
25
- name: IDynamicIconProps["icon"]
26
- className?: ClassNameWithAutocomplete
27
- pos?: "trailing" | "leading"
28
- outline?: boolean
29
- }
24
+ icon?: IDynamicIconProps | UnifiedIconName
25
+ iconPosition?: "trailing" | "leading"
30
26
  label: string
31
27
  onClick?(): void
32
28
  isEmphasized?: boolean
@@ -180,80 +176,115 @@ const Dropdown: React.FC<IDropdownProps> = ({
180
176
  {items.map((itemStack, idx) => {
181
177
  return (
182
178
  <React.Fragment key={`${idx}-list-${id}`}>
183
- {itemStack.map(({ onClick, label, key, isEmphasized, icon, ...rest }) => {
184
- const active = activeItem && activeItem === key
185
- const itemClass = cn(
186
- itemClassname,
187
- "group flex cursor-pointer items-center px-4 py-2 text-sm transition-all",
188
- {
189
- "text-red-500": isEmphasized
190
- },
191
- {
192
- "text-gray-900": !isEmphasized
193
- },
194
- {
195
- "bg-gray-100 text-gray-900": active
196
- },
197
- active ? activeItemClassname : "",
198
- {
199
- "bg-gray-100 text-red-500 hover:text-red-500":
200
- active && isEmphasized
201
- },
202
- itemClassname
203
- )
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
+ )
204
209
 
205
- return (
206
- <li key={key}>
207
- <button
208
- {...{
209
- onClick: () => {
210
- setActiveItem(key)
211
- onClick && onClick()
212
- },
213
- key,
214
- className: cn(itemClass, "w-full"),
215
- ...rest
216
- }}
217
- >
218
- <div className="flex items-center gap-x-4">
219
- {icon &&
220
- (icon.pos === "leading" ||
221
- icon?.pos === undefined) && (
222
- <DynamicIcon
223
- {...{
224
- icon: icon.name,
225
- className: cn(
226
- icon.className,
227
- {
228
- "text-red-500": isEmphasized
229
- },
230
- "opacity-60 group-hover:opacity-100"
231
- ),
232
- outline: icon.outline
233
- }}
234
- />
235
- )}
236
- <div className="whitespace-nowrap">{label}</div>
237
- {icon && icon.pos === "trailing" && (
238
- <DynamicIcon
239
- {...{
240
- icon: icon.name,
241
- className: cn(
242
- icon.className,
243
- {
244
- "text-red-500": isEmphasized
245
- },
246
- "opacity-60 group-"
247
- ),
248
- outline: icon.outline
249
- }}
250
- />
251
- )}
252
- </div>
253
- </button>
254
- </li>
255
- )
256
- })}
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
+ )}
257
288
  </React.Fragment>
258
289
  )
259
290
  })}
@@ -42,11 +42,11 @@ export const dropdownDataWithIcons: IItemProp[][] = [
42
42
  [
43
43
  {
44
44
  icon: {
45
- name: "IconClipboardCopy",
46
- pos: "leading",
45
+ icon: "IconClipboardCopy",
47
46
  className: "h-5 w-5",
48
47
  outline: false
49
48
  },
49
+ iconPosition: "leading",
50
50
  key: "Copy",
51
51
  label: "Copy",
52
52
  onClick: () => {
@@ -57,11 +57,11 @@ export const dropdownDataWithIcons: IItemProp[][] = [
57
57
  [
58
58
  {
59
59
  icon: {
60
- name: "IconFolderPlus",
61
- pos: "leading",
60
+ icon: "IconFolderPlus",
62
61
  className: "h-5 w-5",
63
62
  outline: false
64
63
  },
64
+ iconPosition: "leading",
65
65
  key: "Add to Batch",
66
66
  label: "Add to Batch",
67
67
  onClick: () => {
@@ -70,11 +70,11 @@ export const dropdownDataWithIcons: IItemProp[][] = [
70
70
  },
71
71
  {
72
72
  icon: {
73
- name: "IconEye",
74
- pos: "leading",
73
+ icon: "IconEye",
75
74
  className: "h-5 w-5",
76
75
  outline: false
77
76
  },
77
+ iconPosition: "leading",
78
78
  key: "View Batch",
79
79
  label: "View Batch",
80
80
  onClick: () => {
@@ -85,11 +85,11 @@ export const dropdownDataWithIcons: IItemProp[][] = [
85
85
  [
86
86
  {
87
87
  icon: {
88
- name: "IconTrash",
89
- pos: "leading",
88
+ icon: "IconTrash",
90
89
  className: "h-5 w-5",
91
90
  outline: false
92
91
  },
92
+ iconPosition: "leading",
93
93
  key: "Delete",
94
94
  label: "Delete",
95
95
  onClick: () => {