@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.
Files changed (141) hide show
  1. package/.eslintrc.json +6 -6
  2. package/.prettierrc +13 -13
  3. package/.storybook/Layout.jsx +12 -12
  4. package/.storybook/head.tsx +4 -4
  5. package/.storybook/main.ts +18 -18
  6. package/.storybook/manager-head.html +1 -1
  7. package/.storybook/manager.ts +25 -25
  8. package/.storybook/plenumTheme.ts +8 -8
  9. package/.storybook/preview-head.html +3 -3
  10. package/.storybook/preview.tsx +28 -28
  11. package/.vscode/settings.json +3 -3
  12. package/README.md +271 -271
  13. package/app/globals.css +99 -99
  14. package/app/head.tsx +59 -59
  15. package/app/layout.tsx +28 -28
  16. package/app/page.tsx +7 -7
  17. package/build.js +45 -45
  18. package/dist/index.d.ts +232 -230
  19. package/dist/index.js +1 -1
  20. package/dist/index.js.map +3 -3
  21. package/dist/types/stories/molecules/inputs/select/Select.d.ts +2 -0
  22. package/local.sh +100 -100
  23. package/next.config.js +8 -8
  24. package/package.json +82 -82
  25. package/pages/api/hello.ts +13 -13
  26. package/postcss.config.js +6 -6
  27. package/rollup.config.mjs +41 -41
  28. package/scripts/create-component.js +97 -97
  29. package/stories/Introduction.mdx +314 -314
  30. package/stories/assets/stackalt.svg +1 -1
  31. package/stories/atoms/Avatar/Avatar.stories.tsx +96 -96
  32. package/stories/atoms/Avatar/Avatar.tsx +123 -123
  33. package/stories/atoms/Avatar/index.ts +3 -3
  34. package/stories/atoms/badges/Badge.tsx +127 -127
  35. package/stories/atoms/badges/Pill/Pill.stories.tsx +75 -75
  36. package/stories/atoms/badges/Rounded/Rounded.stories.tsx +75 -75
  37. package/stories/atoms/badges/index.ts +3 -3
  38. package/stories/atoms/buttons/Button/Alternative/Alternative.stories.ts +86 -86
  39. package/stories/atoms/buttons/Button/Button.tsx +232 -232
  40. package/stories/atoms/buttons/Button/Danger/Danger.stories.ts +90 -90
  41. package/stories/atoms/buttons/Button/Primary/Primary.stories.ts +97 -97
  42. package/stories/atoms/buttons/Button/Secondary/Secondary.stories.ts +93 -93
  43. package/stories/atoms/buttons/Button/defaultArgs.ts +9 -9
  44. package/stories/atoms/buttons/Button/index.ts +3 -3
  45. package/stories/atoms/buttons/Capsule/Alternative/Alternative.stories.ts +27 -27
  46. package/stories/atoms/buttons/Capsule/Capsule.tsx +88 -88
  47. package/stories/atoms/buttons/Capsule/Danger/Danger.stories.ts +27 -27
  48. package/stories/atoms/buttons/Capsule/Primary/Primary.stories.ts +27 -27
  49. package/stories/atoms/buttons/Capsule/Secondary/Secondary.stories.ts +27 -27
  50. package/stories/atoms/buttons/Capsule/index.ts +3 -3
  51. package/stories/atoms/buttons/FloatingActionButton/FloatingActionButton.stories.tsx +15 -15
  52. package/stories/atoms/buttons/FloatingActionButton/FloatingActionButton.tsx +22 -22
  53. package/stories/atoms/buttons/FloatingActionButton/index.tsx +3 -3
  54. package/stories/atoms/buttons/index.ts +4 -4
  55. package/stories/atoms/crumb/Crumb.stories.tsx +18 -18
  56. package/stories/atoms/crumb/Crumb.tsx +22 -22
  57. package/stories/atoms/crumb/index.tsx +3 -3
  58. package/stories/atoms/icons/DynamicIcon.stories.ts +43 -43
  59. package/stories/atoms/icons/DynamicIcon.tsx +90 -90
  60. package/stories/atoms/icons/IconWithShadow.stories.ts +43 -43
  61. package/stories/atoms/icons/IconWithShadow.tsx +16 -16
  62. package/stories/atoms/icons/TablerIcon.tsx +22 -22
  63. package/stories/atoms/icons/index.tsx +14 -14
  64. package/stories/atoms/icons/tablerIconNames.ts +4336 -4336
  65. package/stories/atoms/index.ts +46 -46
  66. package/stories/atoms/loaders/Loader.stories.ts +15 -15
  67. package/stories/atoms/loaders/Loader.tsx +21 -21
  68. package/stories/atoms/loaders/NProgress/RadialProgress.stories.tsx +19 -19
  69. package/stories/atoms/loaders/NProgress/RadialProgress.tsx +74 -74
  70. package/stories/atoms/loaders/NProgress/index.ts +3 -3
  71. package/stories/atoms/loaders/index.ts +4 -4
  72. package/stories/index.ts +136 -136
  73. package/stories/molecules/index.ts +51 -51
  74. package/stories/molecules/inputs/InputCounter/InputCounter.stories.tsx +18 -18
  75. package/stories/molecules/inputs/InputCounter/InputCounter.tsx +24 -24
  76. package/stories/molecules/inputs/InputCounter/index.tsx +3 -3
  77. package/stories/molecules/inputs/InputField/InputField.stories.tsx +29 -29
  78. package/stories/molecules/inputs/InputField/InputField.tsx +96 -96
  79. package/stories/molecules/inputs/InputField/index.tsx +3 -3
  80. package/stories/molecules/inputs/InputLabel/InputLabel.stories.tsx +19 -19
  81. package/stories/molecules/inputs/InputLabel/InputLabel.tsx +45 -45
  82. package/stories/molecules/inputs/InputLabel/index.tsx +3 -3
  83. package/stories/molecules/inputs/NestedInputButton/NestedInputButton.stories.tsx +52 -52
  84. package/stories/molecules/inputs/NestedInputButton/NestedInputButton.tsx +64 -64
  85. package/stories/molecules/inputs/NestedInputButton/index.tsx +3 -3
  86. package/stories/molecules/inputs/TextInput/TextInput.stories.tsx +32 -32
  87. package/stories/molecules/inputs/TextInput/TextInput.tsx +165 -165
  88. package/stories/molecules/inputs/TextInput/index.tsx +5 -5
  89. package/stories/molecules/inputs/checkbox/Checkbox.stories.ts +23 -23
  90. package/stories/molecules/inputs/checkbox/Checkbox.tsx +98 -98
  91. package/stories/molecules/inputs/checkbox/index.ts +3 -3
  92. package/stories/molecules/inputs/combobox/ComboBox.stories.ts +41 -41
  93. package/stories/molecules/inputs/combobox/ComboBox.tsx +185 -185
  94. package/stories/molecules/inputs/combobox/index.ts +3 -3
  95. package/stories/molecules/inputs/index.ts +38 -38
  96. package/stories/molecules/inputs/radio/Radio.stories.ts +27 -27
  97. package/stories/molecules/inputs/radio/Radio.tsx +92 -92
  98. package/stories/molecules/inputs/radio/index.ts +3 -3
  99. package/stories/molecules/inputs/select/Select.stories.ts +23 -23
  100. package/stories/molecules/inputs/select/Select.tsx +108 -100
  101. package/stories/molecules/inputs/select/index.ts +3 -3
  102. package/stories/molecules/inputs/textArea/TextArea.stories.ts +22 -22
  103. package/stories/molecules/inputs/textArea/TextArea.tsx +158 -158
  104. package/stories/molecules/inputs/textArea/index.ts +3 -3
  105. package/stories/molecules/inputs/toggleSwitch/ToggleSwitch.stories.tsx +118 -118
  106. package/stories/molecules/inputs/toggleSwitch/ToggleSwitch.tsx +81 -81
  107. package/stories/molecules/inputs/toggleSwitch/index.ts +3 -3
  108. package/stories/molecules/tabs/Tabs.stories.tsx +18 -18
  109. package/stories/molecules/tabs/Tabs.tsx +22 -22
  110. package/stories/molecules/tabs/index.tsx +2 -2
  111. package/stories/organisms/AnimatedLabelInput/AnimatedLabelInput.stories.tsx +30 -30
  112. package/stories/organisms/AnimatedLabelInput/AnimatedLabelInput.tsx +66 -66
  113. package/stories/organisms/AnimatedLabelInput/index.tsx +3 -3
  114. package/stories/organisms/AnimatedLabelTextArea/AnimatedLabelTextArea.stories.tsx +26 -26
  115. package/stories/organisms/AnimatedLabelTextArea/AnimatedLabelTextArea.tsx +61 -61
  116. package/stories/organisms/AnimatedLabelTextArea/index.tsx +3 -3
  117. package/stories/organisms/ButtonDropdown/ButtonDropdown.stories.tsx +125 -125
  118. package/stories/organisms/ButtonDropdown/ButtonDropdown.tsx +86 -86
  119. package/stories/organisms/ButtonDropdown/index.tsx +3 -3
  120. package/stories/organisms/DropdownComponent/Dropdown.stories.tsx +73 -73
  121. package/stories/organisms/DropdownComponent/DropdownComponent.tsx +346 -346
  122. package/stories/organisms/DropdownComponent/dropdownItems.ts +122 -122
  123. package/stories/organisms/DropdownComponent/index.ts +4 -4
  124. package/stories/organisms/EmptySectionPlaceholder/EmptySectionPlaceholder.stories.tsx +76 -76
  125. package/stories/organisms/EmptySectionPlaceholder/EmptySectionPlaceholder.tsx +52 -52
  126. package/stories/organisms/EmptySectionPlaceholder/index.tsx +4 -4
  127. package/stories/organisms/FormInputWithAddons/FormInputWithAddons.stories.tsx +29 -29
  128. package/stories/organisms/FormInputWithAddons/FormInputWithAddons.tsx +145 -145
  129. package/stories/organisms/FormInputWithAddons/index.tsx +3 -3
  130. package/stories/organisms/TextInputSelect/InputSelect.tsx +59 -59
  131. package/stories/organisms/TextInputSelect/TextInputSelect.stories.tsx +33 -33
  132. package/stories/organisms/TextInputSelect/TextInputSelect.tsx +186 -186
  133. package/stories/organisms/TextInputSelect/index.tsx +3 -3
  134. package/stories/organisms/index.ts +27 -27
  135. package/tailwind.config.js +192 -192
  136. package/tsconfig.json +29 -29
  137. package/tsconfig.lib.json +25 -25
  138. package/utils/types.d.ts +2 -2
  139. package/utils/types.ts +3 -3
  140. package/utils/useId.d.ts +1 -1
  141. package/utils/useId.tsx +16 -16
@@ -1,86 +1,86 @@
1
- import type { Meta, StoryObj } from "@storybook/react"
2
- import Button from "../Button"
3
- import { defaultIcon } from "../defaultArgs"
4
-
5
- // More on how to set up stories at: https://storybook.js.org/docs/7.0/react/writing-stories/introduction
6
- const meta: Meta<typeof Button> = {
7
- title: "Design System/atoms/Buttons/Button/Alternative",
8
- component: Button,
9
- tags: ["autodocs"],
10
- argTypes: {}
11
- }
12
-
13
- export default meta
14
- type Story = StoryObj<typeof Button>
15
- // #region Alternative Button Stories
16
- export const Alternative: Story = {
17
- args: {
18
- actionType: "alternative",
19
- label: "Button",
20
- onClick: () => {
21
- window.alert("Button clicked!")
22
- }
23
- }
24
- }
25
- export const AlternativeDisabled: Story = {
26
- args: {
27
- actionType: "alternative",
28
- label: "Button",
29
- disabled: true,
30
- onClick: () => {
31
- window.alert("Button clicked!")
32
- }
33
- }
34
- }
35
- export const AlternativeTrailingIcon: Story = {
36
- args: {
37
- ...Alternative.args,
38
- icon: defaultIcon,
39
- iconPosition: "trailing"
40
- }
41
- }
42
- export const AlternativeLeadingIcon: Story = {
43
- args: {
44
- ...AlternativeTrailingIcon.args,
45
- iconPosition: "leading"
46
- }
47
- }
48
- export const AlternativeExtraSmall: Story = {
49
- args: {
50
- ...Alternative.args,
51
- size: "sm"
52
- }
53
- }
54
- export const AlternativeSimpleIconName: Story = {
55
- args: {
56
- ...Alternative.args,
57
- icon: defaultIcon.icon,
58
- iconPosition: "leading"
59
- }
60
- }
61
- export const AlternativeSmall: Story = {
62
- args: {
63
- ...Alternative.args,
64
- size: "sm"
65
- }
66
- }
67
- export const AlternativeMedium: Story = {
68
- args: {
69
- ...Alternative.args,
70
- size: "md"
71
- }
72
- }
73
-
74
- export const AlternativeLarge: Story = {
75
- args: {
76
- ...Alternative.args,
77
- size: "lg"
78
- }
79
- }
80
- export const AlternativeExtraLarge: Story = {
81
- args: {
82
- ...Alternative.args,
83
- size: "xl"
84
- }
85
- }
86
- // #endregion
1
+ import type { Meta, StoryObj } from "@storybook/react"
2
+ import Button from "../Button"
3
+ import { defaultIcon } from "../defaultArgs"
4
+
5
+ // More on how to set up stories at: https://storybook.js.org/docs/7.0/react/writing-stories/introduction
6
+ const meta: Meta<typeof Button> = {
7
+ title: "Design System/atoms/Buttons/Button/Alternative",
8
+ component: Button,
9
+ tags: ["autodocs"],
10
+ argTypes: {}
11
+ }
12
+
13
+ export default meta
14
+ type Story = StoryObj<typeof Button>
15
+ // #region Alternative Button Stories
16
+ export const Alternative: Story = {
17
+ args: {
18
+ actionType: "alternative",
19
+ label: "Button",
20
+ onClick: () => {
21
+ window.alert("Button clicked!")
22
+ }
23
+ }
24
+ }
25
+ export const AlternativeDisabled: Story = {
26
+ args: {
27
+ actionType: "alternative",
28
+ label: "Button",
29
+ disabled: true,
30
+ onClick: () => {
31
+ window.alert("Button clicked!")
32
+ }
33
+ }
34
+ }
35
+ export const AlternativeTrailingIcon: Story = {
36
+ args: {
37
+ ...Alternative.args,
38
+ icon: defaultIcon,
39
+ iconPosition: "trailing"
40
+ }
41
+ }
42
+ export const AlternativeLeadingIcon: Story = {
43
+ args: {
44
+ ...AlternativeTrailingIcon.args,
45
+ iconPosition: "leading"
46
+ }
47
+ }
48
+ export const AlternativeExtraSmall: Story = {
49
+ args: {
50
+ ...Alternative.args,
51
+ size: "sm"
52
+ }
53
+ }
54
+ export const AlternativeSimpleIconName: Story = {
55
+ args: {
56
+ ...Alternative.args,
57
+ icon: defaultIcon.icon,
58
+ iconPosition: "leading"
59
+ }
60
+ }
61
+ export const AlternativeSmall: Story = {
62
+ args: {
63
+ ...Alternative.args,
64
+ size: "sm"
65
+ }
66
+ }
67
+ export const AlternativeMedium: Story = {
68
+ args: {
69
+ ...Alternative.args,
70
+ size: "md"
71
+ }
72
+ }
73
+
74
+ export const AlternativeLarge: Story = {
75
+ args: {
76
+ ...Alternative.args,
77
+ size: "lg"
78
+ }
79
+ }
80
+ export const AlternativeExtraLarge: Story = {
81
+ args: {
82
+ ...Alternative.args,
83
+ size: "xl"
84
+ }
85
+ }
86
+ // #endregion
@@ -1,232 +1,232 @@
1
- import Loader from "stories/atoms/loaders/Loader"
2
- import { default as cn } from "classnames"
3
- import React, { HTMLAttributeAnchorTarget, forwardRef } from "react"
4
- import { DynamicIcon, UnifiedIconName, IDynamicIconProps } from "../../icons"
5
-
6
- // import Loader from "../loaders/loader/Loader"
7
-
8
- export type BTNActionType = "primary" | "secondary" | "alternative" | "danger"
9
-
10
- export interface IButtonProps
11
- extends Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> {
12
- /** Is the button a Primary CTA, alternative or danger button? */
13
- actionType?: BTNActionType
14
- /** How lg should the button be? - Defaults to 'base'. */
15
- size?: "xs" | "sm" | "md" | "lg" | "xl"
16
- /** The Button's text content. */
17
- label: string
18
- /** The Icon to be displayed inside the button. */
19
- icon?: IDynamicIconProps | UnifiedIconName
20
- /** Does the button width grow to fill it's container? */
21
- fullWidth?: boolean
22
- /** Optionally render as anchor tag */
23
- asLink?: {
24
- href: string
25
- target: HTMLAttributeAnchorTarget
26
- title?: string
27
- }
28
- /** The placement of the icon relative to the text content. */
29
- iconPosition?: "trailing" | "leading"
30
- /** Use an custom svg element */
31
- CustomSVGIcon?: JSX.Element
32
- /** Is the associated content loading? */
33
- isLoading?: boolean
34
- className?: string
35
- iconObj?: React.ReactNode
36
- }
37
- /**
38
- * Primary UI component for user interaction
39
- */
40
- const _Button = (
41
- {
42
- actionType = "primary",
43
- size = "sm",
44
- label,
45
- icon,
46
- iconObj,
47
- CustomSVGIcon,
48
- fullWidth = false,
49
- iconPosition = "leading",
50
- asLink,
51
- isLoading = false,
52
- className,
53
- ...props
54
- }: IButtonProps,
55
- ref: React.LegacyRef<HTMLButtonElement>
56
- ) => {
57
- const iconStyles = cn(
58
- { "text-white h-5 w-5": actionType === "primary" || actionType === "danger" },
59
- { "text-purple-700 h-5 w-5 ": actionType === "secondary" },
60
- { "text-gray-700 h-5 w-5": actionType === "alternative" }
61
- )
62
- const loaderColors = cn(
63
- { "border-r-white": actionType === "primary" },
64
- { "border-purple-200 border-r-purple-700": actionType === "secondary" },
65
- { "border-gray-200 border-r-gray-700": actionType === "alternative" },
66
- { "border-red-800 border-r-white": actionType === "danger" }
67
- )
68
- const loaderSize = cn({ "h-4 w-4": size === "sm" }, { "h-5 w-5": size === "md" }, { "h-6 w-6 ": size === "lg" })
69
-
70
- return asLink ? (
71
- //@ts-ignore
72
- <a
73
- {...{
74
- href: asLink.href,
75
- target: asLink.target,
76
- title: asLink.title,
77
- className: cn(
78
- "inline-flex items-center justify-center gap-x-2 font-medium rounded-[3px] !ring-offset-white outline-none focus-visible:ring-2 focus-visible:ring-purple-600 focus-visible:ring-offset-2 focus-within:ring-2 focus-within:ring-purple-600 focus-within:ring-offset-2 focus:ring-2 focus:ring-purple-600 focus:ring-offset-2 active:ring-2 active:ring-purple-600 active:ring-offset-2 transition-all",
79
- { "w-full": fullWidth },
80
- { "px-[11px] py-[7px] text-xs": size === "xs" },
81
- { "px-[13px] py-[9px] text-sm": size === "sm" },
82
- { "px-[17px] py-[9px] text-sm": size === "md" },
83
- { "px-[17px] py-[9px] text-base": size === "lg" },
84
- { "px-[25px] py-[13px] text-base": size === "xl" },
85
- {
86
- "bg-purple-600 text-white hover:border-purple-700 hover:bg-purple-700 disabled:bg-purple-400 disabled:focus-visible:ring-0":
87
- actionType === "primary"
88
- },
89
- {
90
- " bg-purple-50 text-purple-700 hover:bg-purple-200 focus-within:bg-purple-100 focus-visible:bg-purple-100 focus:bg-purple-100 active:bg-purple-100 disabled:bg-purple-50 disabled:text-purple-300 disabled:focus-visible:ring-0":
91
- actionType === "secondary"
92
- },
93
- {
94
- "border-gray-300 bg-white border text-gray-700 hover:bg-gray-50 focus-visible:!border-gray-300 focus-within:!border-gray-300 focus:!border-gray-300 active:!border-gray-300 disabled:bg-gray-50 disabled:text-gray-300 disabled:focus-visible:ring-0":
95
- actionType === "alternative"
96
- },
97
- {
98
- " bg-red-600 text-white hover:bg-red-700 <focus-visible:!></focus-visible:!>ring-red-500 focus:!ring-red-500 active:!ring-red-500 focus-within:!ring-red-500 disabled:bg-red-400 disabled:text-gray-50 disabled:focus-visible:ring-0":
99
- actionType === "danger"
100
- },
101
- className ? className : ""
102
- ),
103
- onClick: props.onClick
104
- }}
105
- >
106
- {" "}
107
- {CustomSVGIcon &&
108
- (isLoading ? (
109
- <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
110
- ) : (
111
- <i>{CustomSVGIcon}</i>
112
- ))}
113
- {iconObj &&
114
- iconPosition === "leading" &&
115
- (!isLoading ? (
116
- <>{iconObj}</>
117
- ) : (
118
- <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
119
- ))}
120
- {icon &&
121
- iconPosition === "leading" &&
122
- (isLoading ? (
123
- <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
124
- ) : typeof icon === "string" ? (
125
- <DynamicIcon {...{ icon: icon, className: iconStyles }} />
126
- ) : (
127
- <DynamicIcon {...{ ...icon, className: iconStyles }} />
128
- ))}
129
- {!icon && !CustomSVGIcon && isLoading && (
130
- <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
131
- )}
132
- {label}
133
- {icon &&
134
- iconPosition === "trailing" &&
135
- (isLoading ? (
136
- <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
137
- ) : typeof icon === "string" ? (
138
- <DynamicIcon {...{ icon: icon, className: iconStyles }} />
139
- ) : (
140
- <DynamicIcon {...{ ...icon, className: iconStyles }} />
141
- ))}
142
- {iconObj &&
143
- iconPosition === "trailing" &&
144
- (!isLoading ? (
145
- <>{iconObj}</>
146
- ) : (
147
- <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
148
- ))}
149
- </a>
150
- ) : (
151
- <button
152
- type="button"
153
- className={cn(
154
- "inline-flex items-center justify-center gap-x-2 font-medium rounded-[3px] !ring-offset-white outline-none focus-visible:ring-2 focus-visible:ring-purple-600 focus-visible:ring-offset-2 focus-within:ring-2 focus-within:ring-purple-600 focus-within:ring-offset-2 focus:ring-2 focus:ring-purple-600 focus:ring-offset-2 active:ring-2 active:ring-purple-600 active:ring-offset-2 transition-all",
155
- { "w-full": fullWidth },
156
- { "px-[11px] py-[7px] text-xs": size === "xs" },
157
- { "px-[13px] py-[9px] text-sm": size === "sm" },
158
- { "px-[17px] py-[9px] text-sm": size === "md" },
159
- { "px-[17px] py-[9px] text-base": size === "lg" },
160
- { "px-[25px] py-[13px] text-base": size === "xl" },
161
- {
162
- "bg-purple-600 text-white hover:border-purple-700 hover:bg-purple-700 disabled:bg-purple-400 disabled:focus-visible:ring-0":
163
- actionType === "primary"
164
- },
165
- {
166
- " bg-purple-50 text-purple-700 hover:bg-purple-200 focus-within:bg-purple-100 focus-visible:bg-purple-100 focus:bg-purple-100 active:bg-purple-100 disabled:bg-purple-50 disabled:text-purple-300 disabled:focus-visible:ring-0":
167
- actionType === "secondary"
168
- },
169
- {
170
- "border-gray-300 bg-white border text-gray-700 hover:bg-gray-50 focus-visible:!border-gray-300 focus-within:!border-gray-300 focus:!border-gray-300 active:!border-gray-300 disabled:bg-gray-50 disabled:text-gray-300 disabled:focus-visible:ring-0":
171
- actionType === "alternative"
172
- },
173
- {
174
- " bg-red-600 text-white hover:bg-red-700 <focus-visible:!></focus-visible:!>ring-red-500 focus:!ring-red-500 active:!ring-red-500 focus-within:!ring-red-500 disabled:bg-red-400 disabled:text-gray-50 disabled:focus-visible:ring-0":
175
- actionType === "danger"
176
- },
177
- className ? className : ""
178
- )}
179
- ref={ref}
180
- {...props}
181
- >
182
- {CustomSVGIcon &&
183
- (isLoading ? (
184
- <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
185
- ) : (
186
- <i>{CustomSVGIcon}</i>
187
- ))}
188
- {iconObj &&
189
- iconPosition === "leading" &&
190
- (!isLoading ? (
191
- <>{iconObj}</>
192
- ) : (
193
- <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
194
- ))}
195
-
196
- {icon &&
197
- iconPosition === "leading" &&
198
- (isLoading ? (
199
- <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
200
- ) : typeof icon === "string" ? (
201
- <DynamicIcon {...{ icon: icon, className: iconStyles }} />
202
- ) : (
203
- <DynamicIcon {...{ ...icon, className: iconStyles }} />
204
- ))}
205
-
206
- {!icon && !CustomSVGIcon && isLoading && (
207
- <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
208
- )}
209
- {label}
210
- {icon &&
211
- iconPosition === "trailing" &&
212
- (isLoading ? (
213
- <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
214
- ) : typeof icon === "string" ? (
215
- <DynamicIcon {...{ icon: icon, className: iconStyles }} />
216
- ) : (
217
- <DynamicIcon {...{ ...icon, className: iconStyles }} />
218
- ))}
219
- {iconObj &&
220
- iconPosition === "trailing" &&
221
- (!isLoading ? (
222
- <>{iconObj}</>
223
- ) : (
224
- <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
225
- ))}
226
- </button>
227
- )
228
- }
229
-
230
- const Button = forwardRef<HTMLButtonElement, IButtonProps>(_Button)
231
-
232
- export default Button
1
+ import Loader from "stories/atoms/loaders/Loader"
2
+ import { default as cn } from "classnames"
3
+ import React, { HTMLAttributeAnchorTarget, forwardRef } from "react"
4
+ import { DynamicIcon, UnifiedIconName, IDynamicIconProps } from "../../icons"
5
+
6
+ // import Loader from "../loaders/loader/Loader"
7
+
8
+ export type BTNActionType = "primary" | "secondary" | "alternative" | "danger"
9
+
10
+ export interface IButtonProps
11
+ extends Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> {
12
+ /** Is the button a Primary CTA, alternative or danger button? */
13
+ actionType?: BTNActionType
14
+ /** How lg should the button be? - Defaults to 'base'. */
15
+ size?: "xs" | "sm" | "md" | "lg" | "xl"
16
+ /** The Button's text content. */
17
+ label: string
18
+ /** The Icon to be displayed inside the button. */
19
+ icon?: IDynamicIconProps | UnifiedIconName
20
+ /** Does the button width grow to fill it's container? */
21
+ fullWidth?: boolean
22
+ /** Optionally render as anchor tag */
23
+ asLink?: {
24
+ href: string
25
+ target: HTMLAttributeAnchorTarget
26
+ title?: string
27
+ }
28
+ /** The placement of the icon relative to the text content. */
29
+ iconPosition?: "trailing" | "leading"
30
+ /** Use an custom svg element */
31
+ CustomSVGIcon?: JSX.Element
32
+ /** Is the associated content loading? */
33
+ isLoading?: boolean
34
+ className?: string
35
+ iconObj?: React.ReactNode
36
+ }
37
+ /**
38
+ * Primary UI component for user interaction
39
+ */
40
+ const _Button = (
41
+ {
42
+ actionType = "primary",
43
+ size = "sm",
44
+ label,
45
+ icon,
46
+ iconObj,
47
+ CustomSVGIcon,
48
+ fullWidth = false,
49
+ iconPosition = "leading",
50
+ asLink,
51
+ isLoading = false,
52
+ className,
53
+ ...props
54
+ }: IButtonProps,
55
+ ref: React.LegacyRef<HTMLButtonElement>
56
+ ) => {
57
+ const iconStyles = cn(
58
+ { "text-white h-5 w-5": actionType === "primary" || actionType === "danger" },
59
+ { "text-purple-700 h-5 w-5 ": actionType === "secondary" },
60
+ { "text-gray-700 h-5 w-5": actionType === "alternative" }
61
+ )
62
+ const loaderColors = cn(
63
+ { "border-r-white": actionType === "primary" },
64
+ { "border-purple-200 border-r-purple-700": actionType === "secondary" },
65
+ { "border-gray-200 border-r-gray-700": actionType === "alternative" },
66
+ { "border-red-800 border-r-white": actionType === "danger" }
67
+ )
68
+ const loaderSize = cn({ "h-4 w-4": size === "sm" }, { "h-5 w-5": size === "md" }, { "h-6 w-6 ": size === "lg" })
69
+
70
+ return asLink ? (
71
+ //@ts-ignore
72
+ <a
73
+ {...{
74
+ href: asLink.href,
75
+ target: asLink.target,
76
+ title: asLink.title,
77
+ className: cn(
78
+ "inline-flex items-center justify-center gap-x-2 font-medium rounded-[3px] !ring-offset-white outline-none focus-visible:ring-2 focus-visible:ring-purple-600 focus-visible:ring-offset-2 focus-within:ring-2 focus-within:ring-purple-600 focus-within:ring-offset-2 focus:ring-2 focus:ring-purple-600 focus:ring-offset-2 active:ring-2 active:ring-purple-600 active:ring-offset-2 transition-all",
79
+ { "w-full": fullWidth },
80
+ { "px-[11px] py-[7px] text-xs": size === "xs" },
81
+ { "px-[13px] py-[9px] text-sm": size === "sm" },
82
+ { "px-[17px] py-[9px] text-sm": size === "md" },
83
+ { "px-[17px] py-[9px] text-base": size === "lg" },
84
+ { "px-[25px] py-[13px] text-base": size === "xl" },
85
+ {
86
+ "bg-purple-600 text-white hover:border-purple-700 hover:bg-purple-700 disabled:bg-purple-400 disabled:focus-visible:ring-0":
87
+ actionType === "primary"
88
+ },
89
+ {
90
+ " bg-purple-50 text-purple-700 hover:bg-purple-200 focus-within:bg-purple-100 focus-visible:bg-purple-100 focus:bg-purple-100 active:bg-purple-100 disabled:bg-purple-50 disabled:text-purple-300 disabled:focus-visible:ring-0":
91
+ actionType === "secondary"
92
+ },
93
+ {
94
+ "border-gray-300 bg-white border text-gray-700 hover:bg-gray-50 focus-visible:!border-gray-300 focus-within:!border-gray-300 focus:!border-gray-300 active:!border-gray-300 disabled:bg-gray-50 disabled:text-gray-300 disabled:focus-visible:ring-0":
95
+ actionType === "alternative"
96
+ },
97
+ {
98
+ " bg-red-600 text-white hover:bg-red-700 <focus-visible:!></focus-visible:!>ring-red-500 focus:!ring-red-500 active:!ring-red-500 focus-within:!ring-red-500 disabled:bg-red-400 disabled:text-gray-50 disabled:focus-visible:ring-0":
99
+ actionType === "danger"
100
+ },
101
+ className ? className : ""
102
+ ),
103
+ onClick: props.onClick
104
+ }}
105
+ >
106
+ {" "}
107
+ {CustomSVGIcon &&
108
+ (isLoading ? (
109
+ <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
110
+ ) : (
111
+ <i>{CustomSVGIcon}</i>
112
+ ))}
113
+ {iconObj &&
114
+ iconPosition === "leading" &&
115
+ (!isLoading ? (
116
+ <>{iconObj}</>
117
+ ) : (
118
+ <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
119
+ ))}
120
+ {icon &&
121
+ iconPosition === "leading" &&
122
+ (isLoading ? (
123
+ <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
124
+ ) : typeof icon === "string" ? (
125
+ <DynamicIcon {...{ icon: icon, className: iconStyles }} />
126
+ ) : (
127
+ <DynamicIcon {...{ ...icon, className: iconStyles }} />
128
+ ))}
129
+ {!icon && !CustomSVGIcon && isLoading && (
130
+ <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
131
+ )}
132
+ {label}
133
+ {icon &&
134
+ iconPosition === "trailing" &&
135
+ (isLoading ? (
136
+ <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
137
+ ) : typeof icon === "string" ? (
138
+ <DynamicIcon {...{ icon: icon, className: iconStyles }} />
139
+ ) : (
140
+ <DynamicIcon {...{ ...icon, className: iconStyles }} />
141
+ ))}
142
+ {iconObj &&
143
+ iconPosition === "trailing" &&
144
+ (!isLoading ? (
145
+ <>{iconObj}</>
146
+ ) : (
147
+ <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
148
+ ))}
149
+ </a>
150
+ ) : (
151
+ <button
152
+ type="button"
153
+ className={cn(
154
+ "inline-flex items-center justify-center gap-x-2 font-medium rounded-[3px] !ring-offset-white outline-none focus-visible:ring-2 focus-visible:ring-purple-600 focus-visible:ring-offset-2 focus-within:ring-2 focus-within:ring-purple-600 focus-within:ring-offset-2 focus:ring-2 focus:ring-purple-600 focus:ring-offset-2 active:ring-2 active:ring-purple-600 active:ring-offset-2 transition-all",
155
+ { "w-full": fullWidth },
156
+ { "px-[11px] py-[7px] text-xs": size === "xs" },
157
+ { "px-[13px] py-[9px] text-sm": size === "sm" },
158
+ { "px-[17px] py-[9px] text-sm": size === "md" },
159
+ { "px-[17px] py-[9px] text-base": size === "lg" },
160
+ { "px-[25px] py-[13px] text-base": size === "xl" },
161
+ {
162
+ "bg-purple-600 text-white hover:border-purple-700 hover:bg-purple-700 disabled:bg-purple-400 disabled:focus-visible:ring-0":
163
+ actionType === "primary"
164
+ },
165
+ {
166
+ " bg-purple-50 text-purple-700 hover:bg-purple-200 focus-within:bg-purple-100 focus-visible:bg-purple-100 focus:bg-purple-100 active:bg-purple-100 disabled:bg-purple-50 disabled:text-purple-300 disabled:focus-visible:ring-0":
167
+ actionType === "secondary"
168
+ },
169
+ {
170
+ "border-gray-300 bg-white border text-gray-700 hover:bg-gray-50 focus-visible:!border-gray-300 focus-within:!border-gray-300 focus:!border-gray-300 active:!border-gray-300 disabled:bg-gray-50 disabled:text-gray-300 disabled:focus-visible:ring-0":
171
+ actionType === "alternative"
172
+ },
173
+ {
174
+ " bg-red-600 text-white hover:bg-red-700 <focus-visible:!></focus-visible:!>ring-red-500 focus:!ring-red-500 active:!ring-red-500 focus-within:!ring-red-500 disabled:bg-red-400 disabled:text-gray-50 disabled:focus-visible:ring-0":
175
+ actionType === "danger"
176
+ },
177
+ className ? className : ""
178
+ )}
179
+ ref={ref}
180
+ {...props}
181
+ >
182
+ {CustomSVGIcon &&
183
+ (isLoading ? (
184
+ <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
185
+ ) : (
186
+ <i>{CustomSVGIcon}</i>
187
+ ))}
188
+ {iconObj &&
189
+ iconPosition === "leading" &&
190
+ (!isLoading ? (
191
+ <>{iconObj}</>
192
+ ) : (
193
+ <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
194
+ ))}
195
+
196
+ {icon &&
197
+ iconPosition === "leading" &&
198
+ (isLoading ? (
199
+ <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
200
+ ) : typeof icon === "string" ? (
201
+ <DynamicIcon {...{ icon: icon, className: iconStyles }} />
202
+ ) : (
203
+ <DynamicIcon {...{ ...icon, className: iconStyles }} />
204
+ ))}
205
+
206
+ {!icon && !CustomSVGIcon && isLoading && (
207
+ <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
208
+ )}
209
+ {label}
210
+ {icon &&
211
+ iconPosition === "trailing" &&
212
+ (isLoading ? (
213
+ <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
214
+ ) : typeof icon === "string" ? (
215
+ <DynamicIcon {...{ icon: icon, className: iconStyles }} />
216
+ ) : (
217
+ <DynamicIcon {...{ ...icon, className: iconStyles }} />
218
+ ))}
219
+ {iconObj &&
220
+ iconPosition === "trailing" &&
221
+ (!isLoading ? (
222
+ <>{iconObj}</>
223
+ ) : (
224
+ <div className={cn("h-4 rounded-full w-4 border-2 m-0 animate-spin", loaderColors, loaderSize)} />
225
+ ))}
226
+ </button>
227
+ )
228
+ }
229
+
230
+ const Button = forwardRef<HTMLButtonElement, IButtonProps>(_Button)
231
+
232
+ export default Button