@workday/canvas-kit-react 6.0.0-alpha.0-next.27 → 6.0.0-alpha.0-next.31
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/button/lib/PrimaryButton.tsx +110 -32
- package/button/lib/SecondaryButton.tsx +31 -16
- package/button/lib/TertiaryButton.tsx +45 -36
- package/button/lib/parts/ButtonContainer.tsx +18 -5
- package/button/lib/parts/ButtonLabelIcon.tsx +34 -14
- package/button/lib/types.ts +11 -0
- package/dist/commonjs/button/lib/PrimaryButton.d.ts +80 -6
- package/dist/commonjs/button/lib/PrimaryButton.d.ts.map +1 -1
- package/dist/commonjs/button/lib/PrimaryButton.js +80 -26
- package/dist/commonjs/button/lib/SecondaryButton.d.ts +8 -5
- package/dist/commonjs/button/lib/SecondaryButton.d.ts.map +1 -1
- package/dist/commonjs/button/lib/SecondaryButton.js +22 -12
- package/dist/commonjs/button/lib/TertiaryButton.d.ts +8 -4
- package/dist/commonjs/button/lib/TertiaryButton.d.ts.map +1 -1
- package/dist/commonjs/button/lib/TertiaryButton.js +24 -20
- package/dist/commonjs/button/lib/parts/ButtonContainer.d.ts +5 -3
- package/dist/commonjs/button/lib/parts/ButtonContainer.d.ts.map +1 -1
- package/dist/commonjs/button/lib/parts/ButtonContainer.js +7 -9
- package/dist/commonjs/button/lib/parts/ButtonLabelIcon.d.ts +7 -4
- package/dist/commonjs/button/lib/parts/ButtonLabelIcon.d.ts.map +1 -1
- package/dist/commonjs/button/lib/parts/ButtonLabelIcon.js +28 -13
- package/dist/commonjs/button/lib/types.d.ts +9 -0
- package/dist/commonjs/button/lib/types.d.ts.map +1 -1
- package/dist/es6/button/lib/PrimaryButton.d.ts +80 -6
- package/dist/es6/button/lib/PrimaryButton.d.ts.map +1 -1
- package/dist/es6/button/lib/PrimaryButton.js +81 -27
- package/dist/es6/button/lib/SecondaryButton.d.ts +8 -5
- package/dist/es6/button/lib/SecondaryButton.d.ts.map +1 -1
- package/dist/es6/button/lib/SecondaryButton.js +22 -12
- package/dist/es6/button/lib/TertiaryButton.d.ts +8 -4
- package/dist/es6/button/lib/TertiaryButton.d.ts.map +1 -1
- package/dist/es6/button/lib/TertiaryButton.js +25 -21
- package/dist/es6/button/lib/parts/ButtonContainer.d.ts +5 -3
- package/dist/es6/button/lib/parts/ButtonContainer.d.ts.map +1 -1
- package/dist/es6/button/lib/parts/ButtonContainer.js +7 -9
- package/dist/es6/button/lib/parts/ButtonLabelIcon.d.ts +7 -4
- package/dist/es6/button/lib/parts/ButtonLabelIcon.d.ts.map +1 -1
- package/dist/es6/button/lib/parts/ButtonLabelIcon.js +28 -13
- package/dist/es6/button/lib/types.d.ts +9 -0
- package/dist/es6/button/lib/types.d.ts.map +1 -1
- package/package.json +5 -5
- package/ts3.5/dist/commonjs/button/lib/PrimaryButton.d.ts +80 -6
- package/ts3.5/dist/commonjs/button/lib/SecondaryButton.d.ts +8 -5
- package/ts3.5/dist/commonjs/button/lib/TertiaryButton.d.ts +8 -4
- package/ts3.5/dist/commonjs/button/lib/parts/ButtonContainer.d.ts +5 -3
- package/ts3.5/dist/commonjs/button/lib/parts/ButtonLabelIcon.d.ts +7 -4
- package/ts3.5/dist/commonjs/button/lib/types.d.ts +9 -0
- package/ts3.5/dist/es6/button/lib/PrimaryButton.d.ts +80 -6
- package/ts3.5/dist/es6/button/lib/SecondaryButton.d.ts +8 -5
- package/ts3.5/dist/es6/button/lib/TertiaryButton.d.ts +8 -4
- package/ts3.5/dist/es6/button/lib/parts/ButtonContainer.d.ts +5 -3
- package/ts3.5/dist/es6/button/lib/parts/ButtonLabelIcon.d.ts +7 -4
- package/ts3.5/dist/es6/button/lib/types.d.ts +9 -0
|
@@ -6,17 +6,27 @@ import {
|
|
|
6
6
|
Themeable,
|
|
7
7
|
EmotionCanvasTheme,
|
|
8
8
|
createComponent,
|
|
9
|
+
focusRing,
|
|
9
10
|
} from '@workday/canvas-kit-react/common';
|
|
11
|
+
import {colors} from '@workday/canvas-kit-react/tokens';
|
|
10
12
|
import {CanvasSystemIcon} from '@workday/design-assets-types';
|
|
11
|
-
|
|
13
|
+
|
|
12
14
|
import {ButtonContainer, ButtonLabel, ButtonLabelData, ButtonLabelIcon} from './parts';
|
|
15
|
+
import {ButtonSizes, IconPositions} from './types';
|
|
13
16
|
|
|
14
17
|
export interface PrimaryButtonProps extends Themeable, GrowthBehavior {
|
|
15
18
|
/**
|
|
16
|
-
* The
|
|
19
|
+
* The variant of the PrimaryButton.
|
|
20
|
+
* @default undefined
|
|
21
|
+
*/
|
|
22
|
+
variant?: 'inverse';
|
|
23
|
+
/**
|
|
24
|
+
* There are four button sizes: `extraSmall`, `small`, `medium`, and `large`.
|
|
25
|
+
* If no size is provided, it will default to `medium`.
|
|
26
|
+
*
|
|
17
27
|
* @default 'medium'
|
|
18
28
|
*/
|
|
19
|
-
size?:
|
|
29
|
+
size?: ButtonSizes;
|
|
20
30
|
/**
|
|
21
31
|
* The data label of the Button.
|
|
22
32
|
* Note: not displayed at `small` size
|
|
@@ -28,10 +38,11 @@ export interface PrimaryButtonProps extends Themeable, GrowthBehavior {
|
|
|
28
38
|
*/
|
|
29
39
|
icon?: CanvasSystemIcon;
|
|
30
40
|
/**
|
|
31
|
-
*
|
|
41
|
+
* Button icon positions can either be `left` or `right`.
|
|
42
|
+
* If no value is provided, it defaults to `left`.
|
|
32
43
|
* @default 'left'
|
|
33
44
|
*/
|
|
34
|
-
iconPosition?:
|
|
45
|
+
iconPosition?: IconPositions;
|
|
35
46
|
/**
|
|
36
47
|
* If set to `true`, transform the icon's x-axis to mirror the graphic
|
|
37
48
|
* @default false
|
|
@@ -40,6 +51,16 @@ export interface PrimaryButtonProps extends Themeable, GrowthBehavior {
|
|
|
40
51
|
children?: React.ReactNode;
|
|
41
52
|
}
|
|
42
53
|
|
|
54
|
+
// Button sizes where data labels are enabled
|
|
55
|
+
const dataLabelSizes = ['medium', 'large'];
|
|
56
|
+
// All disabled buttons are set to 40% opacity.
|
|
57
|
+
// This will eventually live in the ButtonContainer styles, but for now we're scoping it to Primary, Secondary, and Tertiary buttons.
|
|
58
|
+
const disabledButtonOpacity = {
|
|
59
|
+
'&:disabled, &:disabled:active': {
|
|
60
|
+
opacity: 0.4,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
|
|
43
64
|
export const PrimaryButton = createComponent('button')({
|
|
44
65
|
displayName: 'PrimaryButton',
|
|
45
66
|
Component: (
|
|
@@ -49,6 +70,7 @@ export const PrimaryButton = createComponent('button')({
|
|
|
49
70
|
theme = useTheme(),
|
|
50
71
|
size = 'medium',
|
|
51
72
|
iconPosition = 'left',
|
|
73
|
+
variant,
|
|
52
74
|
dataLabel,
|
|
53
75
|
icon,
|
|
54
76
|
shouldMirrorIcon = false,
|
|
@@ -61,11 +83,12 @@ export const PrimaryButton = createComponent('button')({
|
|
|
61
83
|
<ButtonContainer
|
|
62
84
|
ref={ref}
|
|
63
85
|
as={Element}
|
|
64
|
-
colors={getPrimaryButtonColors(theme)}
|
|
86
|
+
colors={getPrimaryButtonColors(variant, theme)}
|
|
65
87
|
size={size}
|
|
88
|
+
extraStyles={disabledButtonOpacity}
|
|
66
89
|
{...elemProps}
|
|
67
90
|
>
|
|
68
|
-
{icon &&
|
|
91
|
+
{icon && iconPosition === 'left' && (
|
|
69
92
|
<ButtonLabelIcon
|
|
70
93
|
size={size}
|
|
71
94
|
iconPosition={iconPosition}
|
|
@@ -74,8 +97,8 @@ export const PrimaryButton = createComponent('button')({
|
|
|
74
97
|
/>
|
|
75
98
|
)}
|
|
76
99
|
<ButtonLabel>{children}</ButtonLabel>
|
|
77
|
-
{dataLabel && size
|
|
78
|
-
{icon &&
|
|
100
|
+
{dataLabel && dataLabelSizes.includes(size) && <ButtonLabelData>{dataLabel}</ButtonLabelData>}
|
|
101
|
+
{icon && iconPosition === 'right' && (
|
|
79
102
|
<ButtonLabelIcon
|
|
80
103
|
size={size}
|
|
81
104
|
iconPosition={iconPosition}
|
|
@@ -87,26 +110,81 @@ export const PrimaryButton = createComponent('button')({
|
|
|
87
110
|
),
|
|
88
111
|
});
|
|
89
112
|
|
|
90
|
-
export const getPrimaryButtonColors = (
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
+
export const getPrimaryButtonColors = (
|
|
114
|
+
variant: 'inverse' | undefined,
|
|
115
|
+
theme: EmotionCanvasTheme
|
|
116
|
+
) => {
|
|
117
|
+
const {
|
|
118
|
+
canvas: {
|
|
119
|
+
palette: {primary: themePrimary},
|
|
120
|
+
},
|
|
121
|
+
} = theme;
|
|
122
|
+
|
|
123
|
+
switch (variant) {
|
|
124
|
+
case undefined:
|
|
125
|
+
default:
|
|
126
|
+
return {
|
|
127
|
+
default: {
|
|
128
|
+
background: themePrimary.main,
|
|
129
|
+
icon: themePrimary.contrast,
|
|
130
|
+
label: themePrimary.contrast,
|
|
131
|
+
},
|
|
132
|
+
hover: {
|
|
133
|
+
background: themePrimary.dark,
|
|
134
|
+
},
|
|
135
|
+
active: {
|
|
136
|
+
background: themePrimary.darkest,
|
|
137
|
+
},
|
|
138
|
+
focus: {
|
|
139
|
+
background: themePrimary.main,
|
|
140
|
+
},
|
|
141
|
+
disabled: {
|
|
142
|
+
background: themePrimary.main,
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
case 'inverse':
|
|
147
|
+
return {
|
|
148
|
+
default: {
|
|
149
|
+
background: colors.frenchVanilla100,
|
|
150
|
+
icon: colors.blackPepper400,
|
|
151
|
+
label: colors.blackPepper400,
|
|
152
|
+
labelData: colors.blackPepper400,
|
|
153
|
+
},
|
|
154
|
+
hover: {
|
|
155
|
+
background: colors.soap300,
|
|
156
|
+
icon: colors.blackPepper500,
|
|
157
|
+
label: colors.blackPepper500,
|
|
158
|
+
labelData: colors.blackPepper500,
|
|
159
|
+
},
|
|
160
|
+
active: {
|
|
161
|
+
background: colors.soap300,
|
|
162
|
+
icon: colors.blackPepper500,
|
|
163
|
+
label: colors.blackPepper500,
|
|
164
|
+
labelData: colors.blackPepper500,
|
|
165
|
+
},
|
|
166
|
+
focus: {
|
|
167
|
+
background: colors.frenchVanilla100,
|
|
168
|
+
border: colors.blackPepper400,
|
|
169
|
+
icon: colors.blackPepper400,
|
|
170
|
+
label: colors.blackPepper400,
|
|
171
|
+
labelData: colors.blackPepper400,
|
|
172
|
+
focusRing: focusRing(
|
|
173
|
+
{
|
|
174
|
+
separation: 1,
|
|
175
|
+
innerColor: colors.blackPepper500,
|
|
176
|
+
outerColor: colors.frenchVanilla100,
|
|
177
|
+
},
|
|
178
|
+
theme
|
|
179
|
+
),
|
|
180
|
+
},
|
|
181
|
+
// Identical to inverse 'default' styles. ButtonContainer will set opacity to 40%
|
|
182
|
+
disabled: {
|
|
183
|
+
background: colors.frenchVanilla100,
|
|
184
|
+
icon: colors.blackPepper400,
|
|
185
|
+
label: colors.blackPepper400,
|
|
186
|
+
labelData: colors.blackPepper400,
|
|
187
|
+
},
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
};
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
focusRing,
|
|
11
11
|
} from '@workday/canvas-kit-react/common';
|
|
12
12
|
import {CanvasSystemIcon} from '@workday/design-assets-types';
|
|
13
|
-
import {ButtonColors} from './types';
|
|
13
|
+
import {ButtonColors, ButtonSizes, IconPositions} from './types';
|
|
14
14
|
import {ButtonContainer, ButtonLabel, ButtonLabelData, ButtonLabelIcon} from './parts';
|
|
15
15
|
|
|
16
16
|
export interface SecondaryButtonProps extends Themeable, GrowthBehavior {
|
|
@@ -20,10 +20,12 @@ export interface SecondaryButtonProps extends Themeable, GrowthBehavior {
|
|
|
20
20
|
*/
|
|
21
21
|
variant?: 'inverse' | undefined;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* There are four button sizes: `extraSmall`, `small`, `medium`, and `large`.
|
|
24
|
+
* If no size is provided, it will default to `medium`.
|
|
25
|
+
*
|
|
24
26
|
* @default 'medium'
|
|
25
27
|
*/
|
|
26
|
-
size?:
|
|
28
|
+
size?: ButtonSizes;
|
|
27
29
|
/**
|
|
28
30
|
* The data label of the Button.
|
|
29
31
|
* Note: not displayed at `small` size
|
|
@@ -35,10 +37,11 @@ export interface SecondaryButtonProps extends Themeable, GrowthBehavior {
|
|
|
35
37
|
*/
|
|
36
38
|
icon?: CanvasSystemIcon;
|
|
37
39
|
/**
|
|
38
|
-
*
|
|
40
|
+
* Button icon positions can either be `left` or `right`.
|
|
41
|
+
* If no value is provided, it defaults to `left`.
|
|
39
42
|
* @default 'left'
|
|
40
43
|
*/
|
|
41
|
-
iconPosition?:
|
|
44
|
+
iconPosition?: IconPositions;
|
|
42
45
|
/**
|
|
43
46
|
* If set to `true`, transform the icon's x-axis to mirror the graphic
|
|
44
47
|
* @default false
|
|
@@ -47,6 +50,16 @@ export interface SecondaryButtonProps extends Themeable, GrowthBehavior {
|
|
|
47
50
|
children?: React.ReactNode;
|
|
48
51
|
}
|
|
49
52
|
|
|
53
|
+
// Button sizes where data labels are enabled
|
|
54
|
+
const dataLabelSizes = ['medium', 'large'];
|
|
55
|
+
// All disabled buttons are set to 40% opacity.
|
|
56
|
+
// This will eventually live in the ButtonContainer styles, but for now we're scoping it to Primary, Secondary, and Tertiary buttons.
|
|
57
|
+
const disabledButtonOpacity = {
|
|
58
|
+
'&:disabled, &:disabled:active': {
|
|
59
|
+
opacity: 0.4,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
50
63
|
export const SecondaryButton = createComponent('button')({
|
|
51
64
|
displayName: 'SecondaryButton',
|
|
52
65
|
Component: (
|
|
@@ -71,9 +84,10 @@ export const SecondaryButton = createComponent('button')({
|
|
|
71
84
|
as={Element}
|
|
72
85
|
colors={getSecondaryButtonColors(variant, theme)}
|
|
73
86
|
size={size}
|
|
87
|
+
extraStyles={disabledButtonOpacity}
|
|
74
88
|
{...elemProps}
|
|
75
89
|
>
|
|
76
|
-
{icon &&
|
|
90
|
+
{icon && iconPosition === 'left' && (
|
|
77
91
|
<ButtonLabelIcon
|
|
78
92
|
size={size}
|
|
79
93
|
iconPosition={iconPosition}
|
|
@@ -82,8 +96,8 @@ export const SecondaryButton = createComponent('button')({
|
|
|
82
96
|
/>
|
|
83
97
|
)}
|
|
84
98
|
<ButtonLabel>{children}</ButtonLabel>
|
|
85
|
-
{dataLabel && size
|
|
86
|
-
{icon &&
|
|
99
|
+
{dataLabel && dataLabelSizes.includes(size) && <ButtonLabelData>{dataLabel}</ButtonLabelData>}
|
|
100
|
+
{icon && iconPosition === 'right' && (
|
|
87
101
|
<ButtonLabelIcon
|
|
88
102
|
size={size}
|
|
89
103
|
iconPosition={iconPosition}
|
|
@@ -136,12 +150,13 @@ export const getSecondaryButtonColors = (
|
|
|
136
150
|
label: colors.blackPepper400,
|
|
137
151
|
labelData: colors.blackPepper400,
|
|
138
152
|
},
|
|
153
|
+
// Identical to 'default' styles. ButtonContainer will set opacity to 40%
|
|
139
154
|
disabled: {
|
|
140
155
|
background: 'transparent',
|
|
141
|
-
border:
|
|
142
|
-
icon:
|
|
143
|
-
label:
|
|
144
|
-
labelData:
|
|
156
|
+
border: colors.blackPepper400,
|
|
157
|
+
icon: colors.blackPepper400,
|
|
158
|
+
label: colors.blackPepper400,
|
|
159
|
+
labelData: colors.blackPepper400,
|
|
145
160
|
},
|
|
146
161
|
};
|
|
147
162
|
case 'inverse':
|
|
@@ -180,12 +195,12 @@ export const getSecondaryButtonColors = (
|
|
|
180
195
|
theme
|
|
181
196
|
),
|
|
182
197
|
},
|
|
198
|
+
// Identical to inverse 'default' styles. ButtonContainer will set opacity to 40%
|
|
183
199
|
disabled: {
|
|
184
200
|
background: 'transparent',
|
|
185
|
-
border:
|
|
186
|
-
icon:
|
|
187
|
-
label:
|
|
188
|
-
labelData: 'rgba(255, 255, 255, 0.4)', // French Vanilla 400 @ 40%
|
|
201
|
+
border: colors.frenchVanilla100,
|
|
202
|
+
icon: colors.frenchVanilla100,
|
|
203
|
+
label: colors.frenchVanilla100,
|
|
189
204
|
},
|
|
190
205
|
};
|
|
191
206
|
}
|
|
@@ -7,9 +7,9 @@ import {
|
|
|
7
7
|
EmotionCanvasTheme,
|
|
8
8
|
createComponent,
|
|
9
9
|
} from '@workday/canvas-kit-react/common';
|
|
10
|
-
import {colors, space,
|
|
10
|
+
import {colors, space, borderRadius} from '@workday/canvas-kit-react/tokens';
|
|
11
11
|
import {CanvasSystemIcon} from '@workday/design-assets-types';
|
|
12
|
-
import {ButtonColors} from './types';
|
|
12
|
+
import {ButtonColors, TertiaryButtonSizes, IconPositions} from './types';
|
|
13
13
|
import {ButtonContainer, ButtonLabelIcon, ButtonLabel} from './parts';
|
|
14
14
|
|
|
15
15
|
export interface TertiaryButtonProps extends Themeable {
|
|
@@ -19,15 +19,18 @@ export interface TertiaryButtonProps extends Themeable {
|
|
|
19
19
|
*/
|
|
20
20
|
variant?: 'inverse' | undefined;
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
22
|
+
* There are three button sizes: `extraSmall`, `small`, and `medium`.
|
|
23
|
+
* If no size is provided, it will default to `medium`.
|
|
24
|
+
*
|
|
23
25
|
* @default 'medium'
|
|
24
26
|
*/
|
|
25
|
-
size?:
|
|
27
|
+
size?: TertiaryButtonSizes;
|
|
26
28
|
/**
|
|
27
|
-
*
|
|
29
|
+
* Button icon positions can either be `left` or `right`.
|
|
30
|
+
* If no value is provided, it defaults to `left`.
|
|
28
31
|
* @default 'left'
|
|
29
32
|
*/
|
|
30
|
-
iconPosition?:
|
|
33
|
+
iconPosition?: IconPositions;
|
|
31
34
|
/**
|
|
32
35
|
* The icon of the TertiaryButton.
|
|
33
36
|
*/
|
|
@@ -87,8 +90,8 @@ const getTertiaryButtonColors = (
|
|
|
87
90
|
},
|
|
88
91
|
disabled: {
|
|
89
92
|
background: 'transparent',
|
|
90
|
-
icon:
|
|
91
|
-
label:
|
|
93
|
+
icon: colors.frenchVanilla100,
|
|
94
|
+
label: colors.frenchVanilla100,
|
|
92
95
|
},
|
|
93
96
|
};
|
|
94
97
|
} else {
|
|
@@ -113,26 +116,34 @@ const getTertiaryButtonColors = (
|
|
|
113
116
|
focusRing: focusRing({}, theme),
|
|
114
117
|
},
|
|
115
118
|
disabled: {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
label: themePrimary.light,
|
|
119
|
+
icon: themePrimary.main,
|
|
120
|
+
label: themePrimary.main,
|
|
119
121
|
},
|
|
120
122
|
};
|
|
121
123
|
}
|
|
122
124
|
};
|
|
123
125
|
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
'
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
126
|
+
const getPaddingStyles = (
|
|
127
|
+
icon: CanvasSystemIcon | undefined,
|
|
128
|
+
iconPosition: 'left' | 'right'
|
|
129
|
+
): string => {
|
|
130
|
+
// if there is an icon on the left, add 4px extra padding to the right for visual balance
|
|
131
|
+
if (icon && iconPosition === 'left') {
|
|
132
|
+
return `0 ${space.xs} 0 ${space.xxs}`;
|
|
133
|
+
}
|
|
134
|
+
// if there is an icon on the right, add 4px extra padding to the left for visual balance
|
|
135
|
+
if (icon && iconPosition === 'right') {
|
|
136
|
+
return `0 ${space.xxs} 0 ${space.xs}`;
|
|
137
|
+
}
|
|
138
|
+
// if there is no icon, return the default padding
|
|
139
|
+
return `0 ${space.xxs}`;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// All disabled buttons are set to 40% opacity.
|
|
143
|
+
// This will eventually live in the ButtonContainer styles, but for now we're scoping it to Primary, Secondary, and Tertiary buttons.
|
|
144
|
+
const disabledButtonOpacity = {
|
|
145
|
+
'&:disabled, &:disabled:active': {
|
|
146
|
+
opacity: 0.4,
|
|
136
147
|
},
|
|
137
148
|
};
|
|
138
149
|
|
|
@@ -155,19 +166,17 @@ export const TertiaryButton = createComponent('button')({
|
|
|
155
166
|
ref,
|
|
156
167
|
Element
|
|
157
168
|
) => {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
fontSize: size === 'medium' ? type.properties.fontSizes[14] : undefined,
|
|
170
|
-
};
|
|
169
|
+
const allContainerStyles: CSSObject = {
|
|
170
|
+
borderRadius: borderRadius.m,
|
|
171
|
+
border: '0',
|
|
172
|
+
padding: getPaddingStyles(icon, iconPosition),
|
|
173
|
+
minWidth: 'auto',
|
|
174
|
+
textTransform: allCaps ? 'uppercase' : undefined,
|
|
175
|
+
'.wdc-text-button-label': {
|
|
176
|
+
textDecoration: 'underline',
|
|
177
|
+
},
|
|
178
|
+
...disabledButtonOpacity,
|
|
179
|
+
};
|
|
171
180
|
|
|
172
181
|
return (
|
|
173
182
|
<ButtonContainer
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
EmotionCanvasTheme,
|
|
11
11
|
StyledType,
|
|
12
12
|
} from '@workday/canvas-kit-react/common';
|
|
13
|
-
import {ButtonColors} from '../types';
|
|
13
|
+
import {ButtonColors, ButtonSizes} from '../types';
|
|
14
14
|
import {buttonLabelDataClassName} from './ButtonLabelData';
|
|
15
15
|
|
|
16
16
|
export interface ButtonContainerProps
|
|
@@ -18,10 +18,12 @@ export interface ButtonContainerProps
|
|
|
18
18
|
GrowthBehavior {
|
|
19
19
|
colors?: ButtonColors;
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
21
|
+
* There are four button sizes: `extraSmall`, `small`, `medium`, and `large`.
|
|
22
|
+
* If no size is provided, it will default to `medium`.
|
|
23
|
+
*
|
|
22
24
|
* @default 'medium'
|
|
23
25
|
*/
|
|
24
|
-
size?:
|
|
26
|
+
size?: ButtonSizes;
|
|
25
27
|
/**
|
|
26
28
|
* The ref to the button that the styled component renders.
|
|
27
29
|
*/
|
|
@@ -110,12 +112,13 @@ export const ButtonContainer = styled('button', {
|
|
|
110
112
|
switch (size) {
|
|
111
113
|
case 'large':
|
|
112
114
|
return {
|
|
113
|
-
|
|
115
|
+
...type.levels.body.small,
|
|
116
|
+
fontWeight: type.properties.fontWeights.bold,
|
|
114
117
|
minWidth: '112px',
|
|
115
118
|
height: '48px',
|
|
116
119
|
padding: `0 ${space.l}`,
|
|
117
120
|
'& > * ': {
|
|
118
|
-
margin: `0 ${spaceNumbers.
|
|
121
|
+
margin: `0 ${spaceNumbers.xxs / 2}px`,
|
|
119
122
|
},
|
|
120
123
|
};
|
|
121
124
|
case 'medium':
|
|
@@ -137,6 +140,16 @@ export const ButtonContainer = styled('button', {
|
|
|
137
140
|
margin: `0 ${spaceNumbers.xxxs / 2}px`,
|
|
138
141
|
},
|
|
139
142
|
};
|
|
143
|
+
case 'extraSmall':
|
|
144
|
+
return {
|
|
145
|
+
...type.levels.subtext.medium,
|
|
146
|
+
fontWeight: type.properties.fontWeights.bold,
|
|
147
|
+
height: space.m,
|
|
148
|
+
padding: `0 ${space.xs}`,
|
|
149
|
+
'& > * ': {
|
|
150
|
+
margin: `0 ${spaceNumbers.xxxs / 2}px`,
|
|
151
|
+
},
|
|
152
|
+
};
|
|
140
153
|
}
|
|
141
154
|
},
|
|
142
155
|
({grow}) => grow && {width: '100%', maxWidth: '100%'},
|
|
@@ -5,22 +5,25 @@ import isPropValid from '@emotion/is-prop-valid';
|
|
|
5
5
|
import {SystemIcon} from '@workday/canvas-kit-react/icon';
|
|
6
6
|
import {styled} from '@workday/canvas-kit-react/common';
|
|
7
7
|
|
|
8
|
+
import {ButtonSizes, IconPositions} from '../types';
|
|
8
9
|
export interface ButtonLabelIconProps {
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
+
* There are four button sizes: `extraSmall`, `small`, `medium`, and `large`.
|
|
12
|
+
*
|
|
11
13
|
* @default 'medium'
|
|
12
14
|
*/
|
|
13
|
-
size?:
|
|
15
|
+
size?: ButtonSizes;
|
|
14
16
|
/**
|
|
15
17
|
* The icon of the Button.
|
|
16
18
|
* Note: not displayed at `small` size
|
|
17
19
|
*/
|
|
18
20
|
icon?: CanvasSystemIcon;
|
|
19
21
|
/**
|
|
20
|
-
*
|
|
22
|
+
* Button icon positions can either be `left` or `right`.
|
|
23
|
+
* If no value is provided, it defaults to `left`.
|
|
21
24
|
* @default 'left'
|
|
22
25
|
*/
|
|
23
|
-
iconPosition?:
|
|
26
|
+
iconPosition?: IconPositions;
|
|
24
27
|
/**
|
|
25
28
|
* If set to `true`, transform the icon's x-axis to mirror the graphic
|
|
26
29
|
* @default false
|
|
@@ -28,8 +31,29 @@ export interface ButtonLabelIconProps {
|
|
|
28
31
|
shouldMirrorIcon?: boolean;
|
|
29
32
|
}
|
|
30
33
|
|
|
31
|
-
const
|
|
32
|
-
|
|
34
|
+
const iconSizes: Record<ButtonSizes, number> = {
|
|
35
|
+
extraSmall: 18,
|
|
36
|
+
small: 20,
|
|
37
|
+
medium: 20,
|
|
38
|
+
large: 24,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const getIconPositionStyles = ({iconPosition, size}: ButtonLabelIconProps) => {
|
|
42
|
+
// Adjust margin values for visual balance, large buttons require 8px
|
|
43
|
+
const balancingMargin = size === 'large' ? space.xxs : space.xxxs;
|
|
44
|
+
// iconPosition can only be "right", "left", or undefined (defaults to "left")
|
|
45
|
+
if (iconPosition === 'right') {
|
|
46
|
+
return {
|
|
47
|
+
marginLeft: undefined,
|
|
48
|
+
marginRight: `-${balancingMargin} !important`,
|
|
49
|
+
};
|
|
50
|
+
} else {
|
|
51
|
+
return {
|
|
52
|
+
marginLeft: `-${balancingMargin} !important`,
|
|
53
|
+
marginRight: undefined,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
};
|
|
33
57
|
|
|
34
58
|
const ButtonLabelIconStyled = styled('span', {
|
|
35
59
|
shouldForwardProp: prop => isPropValid(prop) && prop !== 'size',
|
|
@@ -38,13 +62,10 @@ const ButtonLabelIconStyled = styled('span', {
|
|
|
38
62
|
display: 'inline-block',
|
|
39
63
|
},
|
|
40
64
|
({size}) => ({
|
|
41
|
-
width: size
|
|
42
|
-
height: size
|
|
65
|
+
width: size ? iconSizes[size] : iconSizes.medium,
|
|
66
|
+
height: size ? iconSizes[size] : iconSizes.medium,
|
|
43
67
|
}),
|
|
44
|
-
|
|
45
|
-
marginLeft: iconPosition === 'right' ? undefined : `-${space.xxxs} !important`,
|
|
46
|
-
marginRight: iconPosition === 'right' ? `-${space.xxxs} !important` : undefined,
|
|
47
|
-
})
|
|
68
|
+
getIconPositionStyles
|
|
48
69
|
);
|
|
49
70
|
|
|
50
71
|
export const ButtonLabelIcon = ({
|
|
@@ -54,12 +75,11 @@ export const ButtonLabelIcon = ({
|
|
|
54
75
|
shouldMirrorIcon = false,
|
|
55
76
|
...elemProps
|
|
56
77
|
}: ButtonLabelIconProps) => {
|
|
57
|
-
/* istanbul ignore next line for coverage */
|
|
58
78
|
if (icon === undefined) {
|
|
59
79
|
return null;
|
|
60
80
|
}
|
|
61
81
|
|
|
62
|
-
const iconSize = size
|
|
82
|
+
const iconSize = size ? iconSizes[size] : undefined;
|
|
63
83
|
|
|
64
84
|
return (
|
|
65
85
|
<ButtonLabelIconStyled iconPosition={iconPosition} size={size} {...elemProps}>
|
package/button/lib/types.ts
CHANGED
|
@@ -20,3 +20,14 @@ export interface ButtonColors {
|
|
|
20
20
|
};
|
|
21
21
|
disabled: ButtonStateColors;
|
|
22
22
|
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* There are four button sizes: `extraSmall`, `small`, `medium`, and `large`.
|
|
26
|
+
* If no size is provided, it will default to `medium`.
|
|
27
|
+
*
|
|
28
|
+
* @default 'medium'
|
|
29
|
+
*/
|
|
30
|
+
export type ButtonSizes = 'extraSmall' | 'small' | 'medium' | 'large';
|
|
31
|
+
// TODO: Remove TertiaryButtonSizes in favor of button sizes when we add Tertiary large
|
|
32
|
+
export type TertiaryButtonSizes = 'extraSmall' | 'small' | 'medium';
|
|
33
|
+
export type IconPositions = 'left' | 'right';
|