@agility/plenum-ui 2.0.0-rc47 → 2.0.0-rc49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +6 -6
- package/.prettierrc +13 -13
- package/.storybook/Layout.jsx +12 -12
- package/.storybook/head.tsx +4 -4
- package/.storybook/main.ts +18 -18
- package/.storybook/manager-head.html +1 -1
- package/.storybook/manager.ts +25 -25
- package/.storybook/plenumTheme.ts +8 -8
- package/.storybook/preview-head.html +3 -3
- package/.storybook/preview.tsx +28 -28
- package/.vscode/settings.json +3 -3
- package/README.md +271 -271
- package/app/globals.css +99 -99
- package/app/head.tsx +59 -59
- package/app/layout.tsx +28 -28
- package/app/page.tsx +7 -7
- package/build.js +45 -45
- package/dist/index.d.ts +232 -230
- package/dist/index.js +1 -1
- package/dist/index.js.map +3 -3
- package/dist/types/stories/molecules/inputs/select/Select.d.ts +2 -0
- package/local.sh +100 -100
- package/next.config.js +8 -8
- package/package.json +82 -82
- package/pages/api/hello.ts +13 -13
- package/postcss.config.js +6 -6
- package/rollup.config.mjs +41 -41
- package/scripts/create-component.js +97 -97
- package/stories/Introduction.mdx +314 -314
- package/stories/assets/stackalt.svg +1 -1
- package/stories/atoms/Avatar/Avatar.stories.tsx +96 -96
- package/stories/atoms/Avatar/Avatar.tsx +123 -123
- package/stories/atoms/Avatar/index.ts +3 -3
- package/stories/atoms/badges/Badge.tsx +127 -127
- package/stories/atoms/badges/Pill/Pill.stories.tsx +75 -75
- package/stories/atoms/badges/Rounded/Rounded.stories.tsx +75 -75
- package/stories/atoms/badges/index.ts +3 -3
- package/stories/atoms/buttons/Button/Alternative/Alternative.stories.ts +86 -86
- package/stories/atoms/buttons/Button/Button.tsx +232 -232
- package/stories/atoms/buttons/Button/Danger/Danger.stories.ts +90 -90
- package/stories/atoms/buttons/Button/Primary/Primary.stories.ts +97 -97
- package/stories/atoms/buttons/Button/Secondary/Secondary.stories.ts +93 -93
- package/stories/atoms/buttons/Button/defaultArgs.ts +9 -9
- package/stories/atoms/buttons/Button/index.ts +3 -3
- package/stories/atoms/buttons/Capsule/Alternative/Alternative.stories.ts +27 -27
- package/stories/atoms/buttons/Capsule/Capsule.tsx +88 -88
- package/stories/atoms/buttons/Capsule/Danger/Danger.stories.ts +27 -27
- package/stories/atoms/buttons/Capsule/Primary/Primary.stories.ts +27 -27
- package/stories/atoms/buttons/Capsule/Secondary/Secondary.stories.ts +27 -27
- package/stories/atoms/buttons/Capsule/index.ts +3 -3
- package/stories/atoms/buttons/FloatingActionButton/FloatingActionButton.stories.tsx +15 -15
- package/stories/atoms/buttons/FloatingActionButton/FloatingActionButton.tsx +22 -22
- package/stories/atoms/buttons/FloatingActionButton/index.tsx +3 -3
- package/stories/atoms/buttons/index.ts +4 -4
- package/stories/atoms/crumb/Crumb.stories.tsx +18 -18
- package/stories/atoms/crumb/Crumb.tsx +22 -22
- package/stories/atoms/crumb/index.tsx +3 -3
- package/stories/atoms/icons/DynamicIcon.stories.ts +43 -43
- package/stories/atoms/icons/DynamicIcon.tsx +90 -90
- package/stories/atoms/icons/IconWithShadow.stories.ts +43 -43
- package/stories/atoms/icons/IconWithShadow.tsx +16 -16
- package/stories/atoms/icons/TablerIcon.tsx +22 -22
- package/stories/atoms/icons/index.tsx +14 -14
- package/stories/atoms/icons/tablerIconNames.ts +4336 -4336
- package/stories/atoms/index.ts +46 -46
- package/stories/atoms/loaders/Loader.stories.ts +15 -15
- package/stories/atoms/loaders/Loader.tsx +21 -21
- package/stories/atoms/loaders/NProgress/RadialProgress.stories.tsx +19 -19
- package/stories/atoms/loaders/NProgress/RadialProgress.tsx +74 -74
- package/stories/atoms/loaders/NProgress/index.ts +3 -3
- package/stories/atoms/loaders/index.ts +4 -4
- package/stories/index.ts +136 -136
- package/stories/molecules/index.ts +51 -51
- package/stories/molecules/inputs/InputCounter/InputCounter.stories.tsx +18 -18
- package/stories/molecules/inputs/InputCounter/InputCounter.tsx +24 -24
- package/stories/molecules/inputs/InputCounter/index.tsx +3 -3
- package/stories/molecules/inputs/InputField/InputField.stories.tsx +29 -29
- package/stories/molecules/inputs/InputField/InputField.tsx +96 -96
- package/stories/molecules/inputs/InputField/index.tsx +3 -3
- package/stories/molecules/inputs/InputLabel/InputLabel.stories.tsx +19 -19
- package/stories/molecules/inputs/InputLabel/InputLabel.tsx +45 -45
- package/stories/molecules/inputs/InputLabel/index.tsx +3 -3
- package/stories/molecules/inputs/NestedInputButton/NestedInputButton.stories.tsx +52 -52
- package/stories/molecules/inputs/NestedInputButton/NestedInputButton.tsx +64 -64
- package/stories/molecules/inputs/NestedInputButton/index.tsx +3 -3
- package/stories/molecules/inputs/TextInput/TextInput.stories.tsx +32 -32
- package/stories/molecules/inputs/TextInput/TextInput.tsx +165 -165
- package/stories/molecules/inputs/TextInput/index.tsx +5 -5
- package/stories/molecules/inputs/checkbox/Checkbox.stories.ts +23 -23
- package/stories/molecules/inputs/checkbox/Checkbox.tsx +98 -98
- package/stories/molecules/inputs/checkbox/index.ts +3 -3
- package/stories/molecules/inputs/combobox/ComboBox.stories.ts +41 -41
- package/stories/molecules/inputs/combobox/ComboBox.tsx +185 -185
- package/stories/molecules/inputs/combobox/index.ts +3 -3
- package/stories/molecules/inputs/index.ts +38 -38
- package/stories/molecules/inputs/radio/Radio.stories.ts +27 -27
- package/stories/molecules/inputs/radio/Radio.tsx +92 -92
- package/stories/molecules/inputs/radio/index.ts +3 -3
- package/stories/molecules/inputs/select/Select.stories.ts +23 -23
- package/stories/molecules/inputs/select/Select.tsx +108 -100
- package/stories/molecules/inputs/select/index.ts +3 -3
- package/stories/molecules/inputs/textArea/TextArea.stories.ts +22 -22
- package/stories/molecules/inputs/textArea/TextArea.tsx +158 -158
- package/stories/molecules/inputs/textArea/index.ts +3 -3
- package/stories/molecules/inputs/toggleSwitch/ToggleSwitch.stories.tsx +118 -118
- package/stories/molecules/inputs/toggleSwitch/ToggleSwitch.tsx +81 -81
- package/stories/molecules/inputs/toggleSwitch/index.ts +3 -3
- package/stories/molecules/tabs/Tabs.stories.tsx +18 -18
- package/stories/molecules/tabs/Tabs.tsx +22 -22
- package/stories/molecules/tabs/index.tsx +2 -2
- package/stories/organisms/AnimatedLabelInput/AnimatedLabelInput.stories.tsx +30 -30
- package/stories/organisms/AnimatedLabelInput/AnimatedLabelInput.tsx +66 -66
- package/stories/organisms/AnimatedLabelInput/index.tsx +3 -3
- package/stories/organisms/AnimatedLabelTextArea/AnimatedLabelTextArea.stories.tsx +26 -26
- package/stories/organisms/AnimatedLabelTextArea/AnimatedLabelTextArea.tsx +61 -61
- package/stories/organisms/AnimatedLabelTextArea/index.tsx +3 -3
- package/stories/organisms/ButtonDropdown/ButtonDropdown.stories.tsx +125 -125
- package/stories/organisms/ButtonDropdown/ButtonDropdown.tsx +86 -86
- package/stories/organisms/ButtonDropdown/index.tsx +3 -3
- package/stories/organisms/DropdownComponent/Dropdown.stories.tsx +73 -73
- package/stories/organisms/DropdownComponent/DropdownComponent.tsx +346 -346
- package/stories/organisms/DropdownComponent/dropdownItems.ts +122 -122
- package/stories/organisms/DropdownComponent/index.ts +4 -4
- package/stories/organisms/EmptySectionPlaceholder/EmptySectionPlaceholder.stories.tsx +76 -76
- package/stories/organisms/EmptySectionPlaceholder/EmptySectionPlaceholder.tsx +52 -52
- package/stories/organisms/EmptySectionPlaceholder/index.tsx +4 -4
- package/stories/organisms/FormInputWithAddons/FormInputWithAddons.stories.tsx +29 -29
- package/stories/organisms/FormInputWithAddons/FormInputWithAddons.tsx +145 -145
- package/stories/organisms/FormInputWithAddons/index.tsx +3 -3
- package/stories/organisms/TextInputSelect/InputSelect.tsx +59 -59
- package/stories/organisms/TextInputSelect/TextInputSelect.stories.tsx +33 -33
- package/stories/organisms/TextInputSelect/TextInputSelect.tsx +186 -186
- package/stories/organisms/TextInputSelect/index.tsx +3 -3
- package/stories/organisms/index.ts +27 -27
- package/tailwind.config.js +192 -192
- package/tsconfig.json +29 -29
- package/tsconfig.lib.json +25 -25
- package/utils/types.d.ts +2 -2
- package/utils/types.ts +3 -3
- package/utils/useId.d.ts +1 -1
- package/utils/useId.tsx +16 -16
|
@@ -1,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
|