-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathButton.tsx
More file actions
154 lines (142 loc) · 4.9 KB
/
Button.tsx
File metadata and controls
154 lines (142 loc) · 4.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import React from "react";
import {
AnchorButton as BlueprintAnchorButton,
AnchorButtonProps as BlueprintAnchorButtonProps,
Button as BlueprintButton,
ButtonProps as BlueprintButtonProps,
Intent as BlueprintIntent,
} from "@blueprintjs/core";
import { CLASSPREFIX as eccgui } from "../../configuration/constants";
import { ValidIconName } from "../Icon/canonicalIconNames";
import Icon from "../Icon/Icon";
import Badge, { BadgeProps } from "./../Badge/Badge";
import Tooltip, { TooltipProps } from "./../Tooltip/Tooltip";
interface AdditionalButtonProps {
/**
* Always use this when the button triggers an affirmative action, e.g. confirm a process.
* The button is displayed with accent color intent.
*/
affirmative?: boolean;
/**
* Always use this when the button triggers an disruptive action, e.g. delete or remove.
* The button is displayed with danger color intent.
*/
disruptive?: boolean;
/**
* Use this when a button is important enough to highlight it in a set of other buttons.
* The button is displayed with accent color intent.
*/
elevated?: boolean;
/**
* Intent state visualized by color.
*/
intent?: BlueprintIntent | "accent";
/**
* Content displayed in a badge that is attached to the button.
* By default it is displayed `{ size: "small", position: "top-right", maxLength: 2 }` and with the same intent state of the button.
* Use `badgeProps` to change that default behaviour.
*/
badge?: BadgeProps["children"];
/**
* Object with additional properties for the badge.
*/
badgeProps?: Partial<Omit<BadgeProps, "children">>;
/**
* takes in either a string of text or a react element to display as a tooltip when the button is hovered.
*/
tooltip?: string | React.JSX.Element | null;
/**
* Object with additional properties for the tooltip.
*/
tooltipProps?: Partial<Omit<TooltipProps, "content" | "children">>;
/**
* Icon displayed on button start.
*/
icon?: ValidIconName | React.JSX.Element;
/**
* Icon displayed on button end.
*/
rightIcon?: ValidIconName | React.JSX.Element;
}
interface ExtendedButtonProps
extends AdditionalButtonProps,
Omit<BlueprintButtonProps, "intent" | "icon" | "rightIcon"> {}
interface ExtendedAnchorButtonProps
extends AdditionalButtonProps,
Omit<BlueprintAnchorButtonProps, "intent" | "icon" | "rightIcon"> {}
export type ButtonProps = ExtendedButtonProps & ExtendedAnchorButtonProps;
/**
* Display a button element to enable user interaction.
* It normally should trigger action when clicked.
*/
export const Button = ({
children,
className = "",
affirmative = false,
disruptive = false,
elevated = false,
icon,
rightIcon,
tooltip = null,
tooltipProps,
badge,
badgeProps = { size: "small", position: "top-right", maxLength: 2 },
intent,
...restProps
}: ButtonProps) => {
let intentByFunction;
switch (true) {
case affirmative || elevated:
intentByFunction = "accent";
break;
case disruptive:
intentByFunction = BlueprintIntent.DANGER;
break;
default:
break;
}
const ButtonType = restProps.href ? BlueprintAnchorButton : BlueprintButton;
const button = (
<ButtonType
{...restProps}
className={`${eccgui}-button ` + className}
intent={(intent || intentByFunction) as BlueprintIntent}
icon={typeof icon === "string" ? <Icon name={icon} /> : icon}
rightIcon={typeof rightIcon === "string" ? <Icon name={rightIcon} /> : rightIcon}
>
{children}
{badge && (
<Badge
children={badge}
{...constructBadgeProperties({
intent,
minimal: restProps.minimal,
outlined: restProps.outlined,
badgeProps,
})}
/>
)}
</ButtonType>
);
return tooltip && !restProps.loading ? (
<Tooltip content={tooltip} {...tooltipProps}>
<span>{button}</span>
</Tooltip>
) : (
button
);
};
interface constructBadgePropertiesProps
extends Pick<ButtonProps, "intent" | "badgeProps">,
Pick<BlueprintButtonProps, "minimal" | "outlined"> {}
const constructBadgeProperties = ({ intent, minimal, outlined, badgeProps = {} }: constructBadgePropertiesProps) => {
if (badgeProps.intent) return badgeProps;
if (intent) badgeProps["intent"] = intent;
if (!badgeProps.tagProps || typeof badgeProps.tagProps.minimal === "undefined") {
if (!minimal && !outlined) {
badgeProps["tagProps"] = { ...badgeProps.tagProps, minimal: true };
}
}
return badgeProps;
};
export default Button;