@workday/canvas-kit-react 10.0.0-alpha.538-next.0 → 10.0.0-alpha.540-next.0

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 (155) hide show
  1. package/button/index.ts +8 -11
  2. package/button/lib/BaseButton.tsx +274 -256
  3. package/button/lib/Button.tsx +67 -0
  4. package/button/lib/DeleteButton.tsx +42 -58
  5. package/button/lib/PrimaryButton.tsx +82 -149
  6. package/button/lib/SecondaryButton.tsx +87 -173
  7. package/button/lib/TertiaryButton.tsx +158 -223
  8. package/button/lib/ToolbarDropdownButton.tsx +11 -2
  9. package/button/lib/ToolbarIconButton.tsx +10 -2
  10. package/button/lib/parts/ButtonLabelIcon.tsx +1 -7
  11. package/button/lib/types.ts +6 -8
  12. package/checkbox/lib/Checkbox.tsx +24 -33
  13. package/common/lib/CanvasProvider.tsx +50 -24
  14. package/dist/commonjs/button/index.d.ts +8 -5
  15. package/dist/commonjs/button/index.d.ts.map +1 -1
  16. package/dist/commonjs/button/index.js +9 -13
  17. package/dist/commonjs/button/lib/BaseButton.d.ts +69 -5
  18. package/dist/commonjs/button/lib/BaseButton.d.ts.map +1 -1
  19. package/dist/commonjs/button/lib/BaseButton.js +199 -192
  20. package/dist/commonjs/button/lib/Button.d.ts +17 -0
  21. package/dist/commonjs/button/lib/Button.d.ts.map +1 -0
  22. package/dist/commonjs/button/lib/Button.js +42 -0
  23. package/dist/commonjs/button/lib/DeleteButton.d.ts +7 -9
  24. package/dist/commonjs/button/lib/DeleteButton.d.ts.map +1 -1
  25. package/dist/commonjs/button/lib/DeleteButton.js +29 -19
  26. package/dist/commonjs/button/lib/PrimaryButton.d.ts +15 -36
  27. package/dist/commonjs/button/lib/PrimaryButton.d.ts.map +1 -1
  28. package/dist/commonjs/button/lib/PrimaryButton.js +67 -79
  29. package/dist/commonjs/button/lib/SecondaryButton.d.ts +16 -43
  30. package/dist/commonjs/button/lib/SecondaryButton.d.ts.map +1 -1
  31. package/dist/commonjs/button/lib/SecondaryButton.js +71 -96
  32. package/dist/commonjs/button/lib/TertiaryButton.d.ts +35 -47
  33. package/dist/commonjs/button/lib/TertiaryButton.d.ts.map +1 -1
  34. package/dist/commonjs/button/lib/TertiaryButton.js +136 -134
  35. package/dist/commonjs/button/lib/ToolbarDropdownButton.d.ts.map +1 -1
  36. package/dist/commonjs/button/lib/ToolbarDropdownButton.js +11 -2
  37. package/dist/commonjs/button/lib/ToolbarIconButton.d.ts.map +1 -1
  38. package/dist/commonjs/button/lib/ToolbarIconButton.js +10 -2
  39. package/dist/commonjs/button/lib/parts/ButtonLabelIcon.d.ts +1 -7
  40. package/dist/commonjs/button/lib/parts/ButtonLabelIcon.d.ts.map +1 -1
  41. package/dist/commonjs/button/lib/types.d.ts +6 -7
  42. package/dist/commonjs/button/lib/types.d.ts.map +1 -1
  43. package/dist/commonjs/card/lib/Card.d.ts +1 -1
  44. package/dist/commonjs/card/lib/CardBody.d.ts +1 -1
  45. package/dist/commonjs/card/lib/CardBody.d.ts.map +1 -1
  46. package/dist/commonjs/checkbox/lib/Checkbox.d.ts.map +1 -1
  47. package/dist/commonjs/checkbox/lib/Checkbox.js +13 -17
  48. package/dist/commonjs/common/lib/CanvasProvider.d.ts +1 -8
  49. package/dist/commonjs/common/lib/CanvasProvider.d.ts.map +1 -1
  50. package/dist/commonjs/common/lib/CanvasProvider.js +31 -13
  51. package/dist/commonjs/dialog/lib/Dialog.d.ts +1 -1
  52. package/dist/commonjs/layout/lib/Box.d.ts +3 -2
  53. package/dist/commonjs/layout/lib/Box.d.ts.map +1 -1
  54. package/dist/commonjs/layout/lib/Box.js +2 -1
  55. package/dist/commonjs/layout/lib/Flex.d.ts +1 -1
  56. package/dist/commonjs/layout/lib/Grid.d.ts +1 -1
  57. package/dist/commonjs/menu/lib/MenuItem.d.ts +1 -1
  58. package/dist/commonjs/popup/lib/Popup.d.ts +1 -1
  59. package/dist/commonjs/popup/lib/PopupBody.d.ts +1 -1
  60. package/dist/commonjs/popup/lib/PopupCloseIcon.js +1 -1
  61. package/dist/commonjs/radio/lib/Radio.d.ts.map +1 -1
  62. package/dist/commonjs/radio/lib/Radio.js +17 -22
  63. package/dist/commonjs/segmented-control/lib/SegmentedControlButton.d.ts.map +1 -1
  64. package/dist/commonjs/segmented-control/lib/SegmentedControlButton.js +3 -1
  65. package/dist/commonjs/table/lib/Table.d.ts +1 -2
  66. package/dist/commonjs/table/lib/Table.d.ts.map +1 -1
  67. package/dist/commonjs/table/lib/Table.js +1 -2
  68. package/dist/commonjs/table/lib/TableRow.d.ts +3 -6
  69. package/dist/commonjs/table/lib/TableRow.d.ts.map +1 -1
  70. package/dist/commonjs/table/lib/TableRow.js +3 -5
  71. package/dist/commonjs/tabs/lib/TabsItem.d.ts +1 -1
  72. package/dist/commonjs/text-area/lib/TextArea.d.ts.map +1 -1
  73. package/dist/commonjs/text-area/lib/TextArea.js +1 -1
  74. package/dist/commonjs/text-input/lib/TextInput.js +1 -1
  75. package/dist/commonjs/tokens/lib/space.d.ts +44 -31
  76. package/dist/commonjs/tokens/lib/space.d.ts.map +1 -1
  77. package/dist/commonjs/tokens/lib/space.js +22 -29
  78. package/dist/commonjs/tooltip/lib/TooltipContainer.js +2 -2
  79. package/dist/es6/button/index.d.ts +8 -5
  80. package/dist/es6/button/index.d.ts.map +1 -1
  81. package/dist/es6/button/index.js +8 -5
  82. package/dist/es6/button/lib/BaseButton.d.ts +69 -5
  83. package/dist/es6/button/lib/BaseButton.d.ts.map +1 -1
  84. package/dist/es6/button/lib/BaseButton.js +199 -192
  85. package/dist/es6/button/lib/Button.d.ts +17 -0
  86. package/dist/es6/button/lib/Button.d.ts.map +1 -0
  87. package/dist/es6/button/lib/Button.js +20 -0
  88. package/dist/es6/button/lib/DeleteButton.d.ts +7 -9
  89. package/dist/es6/button/lib/DeleteButton.d.ts.map +1 -1
  90. package/dist/es6/button/lib/DeleteButton.js +31 -21
  91. package/dist/es6/button/lib/PrimaryButton.d.ts +15 -36
  92. package/dist/es6/button/lib/PrimaryButton.d.ts.map +1 -1
  93. package/dist/es6/button/lib/PrimaryButton.js +67 -79
  94. package/dist/es6/button/lib/SecondaryButton.d.ts +16 -43
  95. package/dist/es6/button/lib/SecondaryButton.d.ts.map +1 -1
  96. package/dist/es6/button/lib/SecondaryButton.js +71 -95
  97. package/dist/es6/button/lib/TertiaryButton.d.ts +35 -47
  98. package/dist/es6/button/lib/TertiaryButton.d.ts.map +1 -1
  99. package/dist/es6/button/lib/TertiaryButton.js +137 -135
  100. package/dist/es6/button/lib/ToolbarDropdownButton.d.ts.map +1 -1
  101. package/dist/es6/button/lib/ToolbarDropdownButton.js +11 -2
  102. package/dist/es6/button/lib/ToolbarIconButton.d.ts.map +1 -1
  103. package/dist/es6/button/lib/ToolbarIconButton.js +10 -2
  104. package/dist/es6/button/lib/parts/ButtonLabelIcon.d.ts +1 -7
  105. package/dist/es6/button/lib/parts/ButtonLabelIcon.d.ts.map +1 -1
  106. package/dist/es6/button/lib/types.d.ts +6 -7
  107. package/dist/es6/button/lib/types.d.ts.map +1 -1
  108. package/dist/es6/card/lib/Card.d.ts +1 -1
  109. package/dist/es6/card/lib/CardBody.d.ts +1 -1
  110. package/dist/es6/card/lib/CardBody.d.ts.map +1 -1
  111. package/dist/es6/checkbox/lib/Checkbox.d.ts.map +1 -1
  112. package/dist/es6/checkbox/lib/Checkbox.js +14 -18
  113. package/dist/es6/common/lib/CanvasProvider.d.ts +1 -8
  114. package/dist/es6/common/lib/CanvasProvider.d.ts.map +1 -1
  115. package/dist/es6/common/lib/CanvasProvider.js +31 -13
  116. package/dist/es6/dialog/lib/Dialog.d.ts +1 -1
  117. package/dist/es6/layout/lib/Box.d.ts +3 -2
  118. package/dist/es6/layout/lib/Box.d.ts.map +1 -1
  119. package/dist/es6/layout/lib/Box.js +2 -1
  120. package/dist/es6/layout/lib/Flex.d.ts +1 -1
  121. package/dist/es6/layout/lib/Grid.d.ts +1 -1
  122. package/dist/es6/menu/lib/MenuItem.d.ts +1 -1
  123. package/dist/es6/popup/lib/Popup.d.ts +1 -1
  124. package/dist/es6/popup/lib/PopupBody.d.ts +1 -1
  125. package/dist/es6/popup/lib/PopupCloseIcon.js +1 -1
  126. package/dist/es6/radio/lib/Radio.d.ts.map +1 -1
  127. package/dist/es6/radio/lib/Radio.js +18 -23
  128. package/dist/es6/segmented-control/lib/SegmentedControlButton.d.ts.map +1 -1
  129. package/dist/es6/segmented-control/lib/SegmentedControlButton.js +3 -1
  130. package/dist/es6/table/lib/Table.d.ts +1 -2
  131. package/dist/es6/table/lib/Table.d.ts.map +1 -1
  132. package/dist/es6/table/lib/Table.js +1 -2
  133. package/dist/es6/table/lib/TableRow.d.ts +3 -6
  134. package/dist/es6/table/lib/TableRow.d.ts.map +1 -1
  135. package/dist/es6/table/lib/TableRow.js +4 -6
  136. package/dist/es6/tabs/lib/TabsItem.d.ts +1 -1
  137. package/dist/es6/text-area/lib/TextArea.d.ts.map +1 -1
  138. package/dist/es6/text-area/lib/TextArea.js +2 -2
  139. package/dist/es6/text-input/lib/TextInput.js +2 -2
  140. package/dist/es6/tokens/lib/space.d.ts +44 -31
  141. package/dist/es6/tokens/lib/space.d.ts.map +1 -1
  142. package/dist/es6/tokens/lib/space.js +22 -29
  143. package/dist/es6/tooltip/lib/TooltipContainer.js +3 -3
  144. package/layout/lib/Box.tsx +6 -4
  145. package/package.json +5 -3
  146. package/popup/lib/PopupCloseIcon.tsx +1 -1
  147. package/radio/lib/Radio.tsx +18 -34
  148. package/segmented-control/lib/SegmentedControlButton.tsx +3 -1
  149. package/table/lib/Table.tsx +1 -2
  150. package/table/lib/TableRow.tsx +5 -8
  151. package/text-area/lib/TextArea.tsx +2 -8
  152. package/text-input/lib/TextInput.tsx +2 -2
  153. package/tokens/README.md +25 -28
  154. package/tokens/lib/space.ts +53 -40
  155. package/tooltip/lib/TooltipContainer.tsx +3 -3
package/button/index.ts CHANGED
@@ -1,7 +1,3 @@
1
- export {PrimaryButton, PrimaryButtonProps} from './lib/PrimaryButton';
2
- export {SecondaryButton, SecondaryButtonProps} from './lib/SecondaryButton';
3
- export {TertiaryButton, TertiaryButtonProps} from './lib/TertiaryButton';
4
- export {DeleteButton, DeleteButtonProps} from './lib/DeleteButton';
5
1
  export {
6
2
  DeprecatedButton as deprecated_Button,
7
3
  DeprecatedButtonProps,
@@ -9,12 +5,13 @@ export {
9
5
  export {ToolbarIconButton, ToolbarIconButtonProps} from './lib/ToolbarIconButton';
10
6
  export {ToolbarDropdownButton, ToolbarDropdownButtonProps} from './lib/ToolbarDropdownButton';
11
7
  export {Hyperlink, HyperlinkProps} from './lib/Hyperlink';
12
- export {
13
- BaseButton,
14
- ButtonContainerProps,
15
- BaseButtonProps,
16
- getMinWidthStyles,
17
- getPaddingStyles,
18
- } from './lib/BaseButton';
19
8
  export {ExternalHyperlink, ExternalHyperlinkProps} from './lib/ExternalHyperlink';
20
9
  export * from './lib/types';
10
+ export * from './lib/PrimaryButton';
11
+ export * from './lib/SecondaryButton';
12
+ export * from './lib/TertiaryButton';
13
+ export * from './lib/DeleteButton';
14
+ export * from './lib/BaseButton';
15
+ export * from './lib/ToolbarDropdownButton';
16
+ export * from './lib/ToolbarIconButton';
17
+ export * from './lib/types';
@@ -1,24 +1,15 @@
1
1
  import * as React from 'react';
2
2
 
3
- import {ButtonLabelIcon} from './parts/ButtonLabelIcon';
4
- import {ButtonLabel} from './parts/ButtonLabel';
3
+ import {ButtonLabelIcon} from '../lib/parts/ButtonLabelIcon';
4
+ import {ButtonLabel} from '../lib/parts/ButtonLabel';
5
5
 
6
- import {
7
- createComponent,
8
- GrowthBehavior,
9
- mouseFocusBehavior,
10
- focusRing,
11
- styled,
12
- EmotionCanvasTheme,
13
- StyledType,
14
- } from '@workday/canvas-kit-react/common';
6
+ import {createComponent, GrowthBehavior, focusRing} from '@workday/canvas-kit-react/common';
7
+ import {createStyles, createVars, cssVar, createModifiers} from '@workday/canvas-kit-styling';
15
8
  import {SystemIconProps} from '@workday/canvas-kit-react/icon';
16
- import {boxStyleFn} from '@workday/canvas-kit-react/layout';
17
- import {borderRadius, space, spaceNumbers, type} from '@workday/canvas-kit-react/tokens';
18
-
19
- import {ButtonColors, ButtonSizes, IconPositions, TertiaryButtonSizes} from './types';
20
-
21
- import {CSSObject} from '@emotion/styled';
9
+ import {Box} from '@workday/canvas-kit-react/layout';
10
+ import {space} from '@workday/canvas-kit-react/tokens';
11
+ import {base, brand, system} from '@workday/canvas-tokens-web';
12
+ import {ButtonColors, ButtonSizes, IconPositions} from './types';
22
13
  import {CanvasSystemIcon} from '@workday/design-assets-types';
23
14
 
24
15
  export interface ButtonContainerProps extends Partial<SystemIconProps>, GrowthBehavior {
@@ -29,13 +20,33 @@ export interface ButtonContainerProps extends Partial<SystemIconProps>, GrowthBe
29
20
  /**
30
21
  * There are four button sizes: `extraSmall`, `small`, `medium`, and `large`.
31
22
  * If no size is provided, it will default to `medium`.
23
+ *
24
+ * @default 'medium
32
25
  */
33
26
  size?: ButtonSizes;
27
+ /**
28
+ * The icon of the Button.
29
+ * Note: not displayed at `small` size
30
+ */
31
+ icon?: CanvasSystemIcon;
34
32
  /**
35
33
  * Whether the icon should received filled (colored background layer) or regular styles.
36
34
  * Corresponds to `toggled` in ToolbarIconButton
37
35
  */
38
36
  fillIcon?: boolean;
37
+ /**
38
+ * Button icon positions can either be `start` or `end`.
39
+ * If no value is provided, it defaults to `start`.
40
+ *
41
+ * @default 'start'
42
+ */
43
+ iconPosition?: IconPositions;
44
+ /**
45
+ * If set to `true`, transform the icon's x-axis to mirror the graphic
46
+ * @default false
47
+ */
48
+ shouldMirrorIcon?: boolean;
49
+ children?: React.ReactNode;
39
50
  }
40
51
 
41
52
  /**
@@ -45,260 +56,267 @@ export interface ButtonContainerProps extends Partial<SystemIconProps>, GrowthBe
45
56
  */
46
57
  export interface BaseButtonProps extends Omit<ButtonContainerProps, 'ref'> {}
47
58
 
48
- function getIconColorSelectors(
49
- {
50
- canvas: {
51
- palette: {primary: themePrimary},
52
- },
53
- }: EmotionCanvasTheme,
54
- color: string,
55
- fill?: boolean
56
- ): CSSObject {
57
- return {
58
- '&:focus span, &:hover span, & span': {
59
- '.wd-icon-fill, .wd-icon-accent, .wd-icon-accent2': {
60
- fill: color,
61
- },
62
- '.wd-icon-background': {
63
- fill: fill ? color : undefined,
64
- },
65
- '.wd-icon-background ~ .wd-icon-accent, .wd-icon-background ~ .wd-icon-accent2': {
66
- fill: fill
67
- ? color === themePrimary.contrast
68
- ? themePrimary.main
69
- : themePrimary.contrast
70
- : color,
71
- },
72
- },
73
- };
74
- }
59
+ /**
60
+ * Factory function for creating Button vars.
61
+ */
62
+ const createButtonVars = () =>
63
+ createVars(
64
+ 'background',
65
+ 'border',
66
+ 'boxShadowInner',
67
+ 'boxShadowOuter',
68
+ 'icon',
69
+ 'label',
70
+ 'opacity',
71
+ 'borderRadius'
72
+ );
75
73
 
76
- const ButtonContainer = styled('button')<StyledType & ButtonContainerProps>(
77
- {
78
- ...type.levels.subtext.large,
79
- cursor: 'pointer',
80
- display: 'inline-flex',
81
- alignItems: 'center',
82
- justifyContent: 'center',
83
- boxSizing: 'border-box',
74
+ /**
75
+ * Temporary css variables to be used across all Buttons.
76
+ */
77
+ export const buttonVars = {
78
+ default: createButtonVars(),
79
+ hover: createButtonVars(),
80
+ active: createButtonVars(),
81
+ focus: createButtonVars(),
82
+ disabled: createButtonVars(),
83
+ };
84
+
85
+ /**
86
+ * Base styles for Buttons.
87
+ */
88
+ const baseButtonStyles = createStyles({
89
+ fontFamily: '"Roboto", "Helvetica Neue", "Helvetica", Arial, sans-serif',
90
+ fontSize: '0.875rem',
91
+ lineHeight: 'normal',
92
+ letterSpacing: '0.015rem',
93
+ fontWeight: 'bold',
94
+ backgroundColor: cssVar(buttonVars.default.background, 'transparent'),
95
+ color: cssVar(buttonVars.default.label, cssVar(base.blackPepper400)),
96
+ borderWidth: '1px',
97
+ borderStyle: 'solid',
98
+ gap: cssVar(system.space.x2, space.xxs),
99
+ borderColor: cssVar(buttonVars.default.border, 'transparent'),
100
+ cursor: 'pointer',
101
+ display: 'inline-flex',
102
+ boxShadow: 'none',
103
+ alignItems: 'center',
104
+ justifyContent: 'center',
105
+ boxSizing: 'border-box',
106
+ outline: '2px transparent',
107
+ whiteSpace: 'nowrap',
108
+ WebkitFontSmoothing: 'antialiased',
109
+ MozOsxFontSmoothing: 'grayscale',
110
+ borderRadius: cssVar(buttonVars.default.borderRadius, system.shape.circle),
111
+ position: 'relative',
112
+ verticalAlign: 'middle',
113
+ overflow: 'hidden',
114
+ transition:
115
+ 'box-shadow 120ms linear, border 120ms linear, background-color 120ms linear, color 120ms linear',
116
+ '&:disabled, &:disabled:active': {
117
+ cursor: 'default',
84
118
  boxShadow: 'none',
85
- outline: 'none',
86
- fontWeight: type.properties.fontWeights.bold,
87
- lineHeight: 'normal',
88
- whiteSpace: 'nowrap',
89
- WebkitFontSmoothing: 'antialiased',
90
- MozOsxFontSmoothing: 'grayscale',
91
- borderRadius: borderRadius.circle,
92
- position: 'relative',
93
- verticalAlign: 'middle',
94
- overflow: 'hidden',
95
- border: '1px solid transparent',
96
- background: 'transparent',
97
- transition:
98
- 'box-shadow 120ms linear, border 120ms linear, background-color 120ms linear, color 120ms linear',
99
- '&:disabled, &:disabled:active': {
100
- cursor: 'default',
101
- boxShadow: 'none',
102
- opacity: 0.4,
119
+ opacity: cssVar(buttonVars.disabled.opacity, '1'),
120
+ },
121
+ '& span .wd-icon-fill': {
122
+ transitionDuration: '40ms',
123
+ fill: cssVar(buttonVars.default.icon, cssVar(base.blackPepper400)),
124
+ },
125
+ '.wd-icon-background ~ .wd-icon-accent, .wd-icon-background ~ .wd-icon-accent2': {
126
+ fill: cssVar(buttonVars.default.icon, cssVar(base.blackPepper400)),
127
+ },
128
+ '&:focus-visible, &.focus': {
129
+ backgroundColor: cssVar(buttonVars.focus.background, 'transparent'),
130
+ borderColor: cssVar(buttonVars.focus.border, 'transparent'),
131
+ color: cssVar(buttonVars.focus.label, cssVar(base.blackPepper400)),
132
+ '& span .wd-icon-fill': {
133
+ fill: cssVar(buttonVars.focus.icon, cssVar(base.blackPepper400)),
103
134
  },
104
-
105
- '&:hover:active': {transitionDuration: '40ms'},
106
-
107
- '& > *:first-of-type': {
108
- marginLeft: '0',
135
+ '.wd-icon-background ~ .wd-icon-accent, .wd-icon-background ~ .wd-icon-accent2': {
136
+ fill: cssVar(buttonVars.focus.icon, cssVar(base.blackPepper400)),
109
137
  },
110
-
111
- '& > *:last-of-type': {
112
- marginRight: 0,
138
+ ...focusRing({
139
+ width: 2,
140
+ separation: 2,
141
+ innerColor: cssVar(buttonVars.focus.boxShadowInner, cssVar(base.frenchVanilla100)),
142
+ outerColor: cssVar(buttonVars.focus.boxShadowOuter, cssVar(brand.primary.base)),
143
+ }),
144
+ },
145
+ '&:hover, &.hover': {
146
+ backgroundColor: cssVar(buttonVars.hover.background, cssVar(base.blackPepper500)),
147
+ borderColor: cssVar(buttonVars.hover.border, 'transparent'),
148
+ color: cssVar(buttonVars.hover.label, cssVar(base.blackPepper500)),
149
+ '& span .wd-icon-fill': {
150
+ fill: cssVar(buttonVars.hover.icon, cssVar(base.blackPepper500)),
151
+ },
152
+ '.wd-icon-background ~ .wd-icon-accent, .wd-icon-background ~ .wd-icon-accent2': {
153
+ fill: cssVar(buttonVars.hover.icon, cssVar(base.blackPepper500)),
113
154
  },
114
155
  },
115
- ({size}) => {
116
- switch (size) {
117
- case 'large':
118
- return {
119
- ...type.levels.body.small,
120
- fontWeight: type.properties.fontWeights.bold,
121
- height: '48px',
122
- '& > * ': {
123
- margin: `0 ${space.xxxs}`,
124
- },
125
- };
126
- case 'medium':
127
- default:
128
- return {
129
- height: space.xl,
130
- '& > * ': {
131
- margin: `0 ${space.xxxs}`,
132
- },
133
- };
134
- case 'small':
135
- return {
136
- height: space.l,
137
- '& > * ': {
138
- margin: `0 ${spaceNumbers.xxxs / 2}rem`,
139
- },
140
- };
141
- case 'extraSmall':
142
- return {
143
- ...type.levels.subtext.medium,
144
- fontWeight: type.properties.fontWeights.bold,
145
- height: space.m,
146
- '& > * ': {
147
- margin: `0 ${spaceNumbers.xxxs / 2}rem`,
148
- },
149
- };
150
- }
156
+ '&:hover:active': {transitionDuration: '40ms'},
157
+ '&:active, &.active': {
158
+ backgroundColor: cssVar(buttonVars.active.background, 'transparent'),
159
+ borderColor: cssVar(buttonVars.active.border, 'transparent'),
160
+ color: cssVar(buttonVars.active.label, cssVar(base.blackPepper400)),
161
+ '& span .wd-icon-fill': {
162
+ fill: cssVar(buttonVars.active.icon, cssVar(base.blackPepper400)),
163
+ },
164
+ '.wd-icon-background ~ .wd-icon-accent, .wd-icon-background ~ .wd-icon-accent2': {
165
+ fill: cssVar(buttonVars.active.icon),
166
+ },
151
167
  },
152
- ({grow}) => grow && {width: '100%', maxWidth: '100%'},
153
- ({colors, fillIcon, theme}) => {
154
- if (!colors) {
155
- return;
156
- }
157
-
158
- const baseStyles = {
159
- ...(colors.default.icon && {
160
- '.wd-icon-fill, .wd-icon-accent, .wd-icon-accent2, .wd-icon-background': {
161
- transition: 'fill 120ms ease-in',
162
- },
163
- ...getIconColorSelectors(theme, colors.default.icon, fillIcon),
164
- }),
165
- backgroundColor: colors.default.background,
166
- borderColor: colors.default.border,
167
- color: colors.default.label,
168
- };
169
-
170
- const hoverStyles = {
171
- '&:hover': {
172
- ...(colors.hover.icon && getIconColorSelectors(theme, colors.hover.icon, fillIcon)),
173
- backgroundColor: colors.hover.background,
174
- borderColor: colors.hover.border,
175
- color: colors.hover.label,
176
- },
177
- };
178
-
179
- const activeStyles = {
180
- '&:active, &:focus:active, &:hover:active': {
181
- ...(colors.active.icon && getIconColorSelectors(theme, colors.active.icon, fillIcon)),
182
- backgroundColor: colors.active.background,
183
- borderColor: colors.active.border,
184
- color: colors.active.label,
185
- },
186
- };
187
-
188
- return {
189
- ...baseStyles,
190
- '&:focus': {
191
- ...(colors.focus.focusRing || focusRing({separation: 2}, theme)),
192
- ...(colors.focus.icon && getIconColorSelectors(theme, colors.focus.icon, fillIcon)),
193
- backgroundColor: colors.focus.background,
194
- borderColor: colors.focus.border,
195
- color: colors.focus.label,
196
- },
197
-
198
- ...activeStyles,
199
- ...hoverStyles,
200
- '&:disabled, &:active:disabled, &:focus:disabled, &:hover:disabled': {
201
- ...(colors.disabled.icon && getIconColorSelectors(theme, colors.disabled.icon, fillIcon)),
202
- backgroundColor: colors.disabled.background,
203
- borderColor: colors.disabled.border,
204
- color: colors.disabled.label,
205
- opacity: colors.disabled.opacity,
206
- },
207
- ...mouseFocusBehavior({
208
- '&:focus': {
209
- ...baseStyles,
210
- ...hoverStyles,
211
- ...activeStyles,
212
- outline: 'none',
213
- boxShadow: 'none',
214
- animation: 'none',
215
- },
216
- }),
217
- };
168
+ '&:disabled': {
169
+ backgroundColor: cssVar(buttonVars.disabled.background, 'transparent'),
170
+ borderColor: cssVar(buttonVars.disabled.border, 'transparent'),
171
+ color: cssVar(buttonVars.disabled.label, cssVar(base.blackPepper400)),
172
+ '& span .wd-icon-fill': {
173
+ fill: cssVar(buttonVars.disabled.icon, cssVar(base.blackPepper400)),
174
+ },
175
+ '.wd-icon-background ~ .wd-icon-accent, .wd-icon-background ~ .wd-icon-accent2': {
176
+ fill: cssVar(buttonVars.disabled.icon, cssVar(base.blackPepper400)),
177
+ },
218
178
  },
219
- boxStyleFn
220
- );
221
-
222
- export const getMinWidthStyles = (
223
- children: React.ReactNode,
224
- size: ButtonSizes | TertiaryButtonSizes
225
- ) => {
226
- switch (size) {
227
- case 'large':
228
- return children ? '112px' : '48px';
229
- case 'medium':
230
- return children ? '96px' : space.xl;
231
- case 'small':
232
- return children ? space.xxxl : space.l;
233
- case 'extraSmall':
234
- return children ? 'auto' : space.m;
235
- default:
236
- return children ? '96px' : space.xl;
237
- }
238
- };
239
-
240
- export const getPaddingStyles = (
241
- children: React.ReactNode,
242
- size: ButtonSizes | TertiaryButtonSizes,
243
- icon: CanvasSystemIcon | undefined,
244
- iconPosition: IconPositions | undefined
245
- ) => {
246
- // In order to calculate the correct padding, we need to know its children
247
- // and what side the icon is on and if there's an icon provided
248
- if (!children) {
249
- // icon buttons do not have any padding
250
- return 0;
251
- }
252
- // If there are children AND an icon
253
- // 1. We check what side the icon is in
254
- // 2. Adjust padding to visually center the icon and text
255
- // If there is children (most likely just text)
256
- // 1. We keep the padding the same on both side
257
- switch (size) {
258
- case 'large':
259
- return icon
260
- ? iconPosition === 'start'
261
- ? `0 ${space.l} 0 ${space.m}`
262
- : `0 ${space.m} 0 ${space.l}`
263
- : `0 ${space.l}`;
264
-
265
- case 'medium':
266
- return icon
267
- ? iconPosition === 'start'
268
- ? `0 ${space.m} 0 20px`
269
- : `0 20px 0 ${space.m}`
270
- : `0 ${space.m}`;
179
+ });
271
180
 
272
- case 'small':
273
- return icon
274
- ? iconPosition === 'start'
275
- ? `0 ${space.s} 0 ${space.xs}`
276
- : `0 ${space.xs} 0 ${space.s}`
277
- : `0 ${space.s}`;
181
+ /**
182
+ * Button modifiers that will overwrite the base styles of Buttons.
183
+ * - `Size`: These modifiers will dictate a size of a Button and has a set of styles to associated with it.
184
+ * - `iconPosition`: These modifiers will override the existing `Size` styles. These are specific to icon locations
185
+ * within a button or if there is only an icon and no text.
186
+ */
187
+ export const buttonModifiers = createModifiers({
188
+ size: {
189
+ large: createStyles({
190
+ fontSize: cssVar(system.space.x4),
191
+ lineHeight: cssVar(system.space.x6),
192
+ letterSpacing: '0.01rem',
193
+ height: '48px',
194
+ paddingInline: cssVar(system.space.x8),
195
+ minWidth: '112px',
196
+ }),
197
+ medium: createStyles({
198
+ fontSize: '0.875rem',
199
+ letterSpacing: '0.015rem',
200
+ minWidth: '96px',
201
+ paddingInline: cssVar(system.space.x6),
202
+ height: cssVar(system.space.x10),
203
+ }),
204
+ small: createStyles({
205
+ fontSize: '0.875rem',
206
+ letterSpacing: '0.015rem',
207
+ height: cssVar(system.space.x8),
208
+ minWidth: cssVar(system.space.x20),
209
+ paddingInline: cssVar(system.space.x4),
210
+ gap: cssVar(system.space.x1),
211
+ }),
212
+ extraSmall: createStyles({
213
+ fontSize: '0.75rem',
214
+ lineHeight: cssVar(system.space.x4),
215
+ letterSpacing: '0.02rem',
216
+ height: cssVar(system.space.x6),
217
+ minWidth: 'auto',
218
+ paddingInline: cssVar(system.space.x3),
219
+ gap: cssVar(system.space.x1),
220
+ }),
221
+ },
222
+ iconPosition: {
223
+ largeOnly: createStyles({
224
+ padding: '0',
225
+ minWidth: cssVar(system.space.x12),
226
+ }),
227
+ largeStart: createStyles({
228
+ paddingInlineStart: cssVar(system.space.x6),
229
+ paddingInlineEnd: cssVar(system.space.x8),
230
+ }),
231
+ largeEnd: createStyles({
232
+ paddingInlineStart: cssVar(system.space.x8),
233
+ paddingInlineEnd: cssVar(system.space.x6),
234
+ }),
235
+ mediumOnly: createStyles({padding: '0', minWidth: cssVar(system.space.x10, space.xl)}),
236
+ mediumStart: createStyles({
237
+ paddingInlineStart: cssVar(system.space.x5),
238
+ paddingInlineEnd: cssVar(system.space.x6),
239
+ }),
240
+ mediumEnd: createStyles({
241
+ paddingInlineStart: cssVar(system.space.x6),
242
+ paddingInlineEnd: cssVar(system.space.x5),
243
+ }),
244
+ smallOnly: createStyles({padding: '0', minWidth: cssVar(system.space.x8, space.l)}),
245
+ smallStart: createStyles({
246
+ paddingInlineStart: cssVar(system.space.x3),
247
+ paddingInlineEnd: cssVar(system.space.x4),
248
+ }),
249
+ smallEnd: createStyles({
250
+ paddingInlineStart: cssVar(system.space.x4),
251
+ paddingInlineEnd: cssVar(system.space.x3),
252
+ }),
253
+ extraSmallOnly: createStyles({padding: '0', minWidth: cssVar(system.space.x6, space.m)}),
254
+ extraSmallStart: createStyles({
255
+ paddingInlineStart: cssVar(system.space.x2),
256
+ paddingInlineEnd: cssVar(system.space.x3),
257
+ }),
258
+ extraSmallEnd: createStyles({
259
+ paddingInlineStart: cssVar(system.space.x3),
260
+ paddingInlineEnd: cssVar(system.space.x2),
261
+ }),
262
+ },
263
+ });
278
264
 
279
- case 'extraSmall':
280
- return icon
281
- ? iconPosition === 'start'
282
- ? `0 ${space.xs} 0 ${space.xxs}`
283
- : `0 ${space.xxs} 0 ${space.xs}`
284
- : `0 ${space.xs}`;
265
+ export function capitalize(string: string = '') {
266
+ return string.charAt(0).toUpperCase() + string.substring(1);
267
+ }
285
268
 
286
- default:
287
- return icon
288
- ? iconPosition === 'start'
289
- ? `0 ${space.m} 0 20px`
290
- : `0 20px 0 ${space.m}`
291
- : `0 ${space.m}`;
292
- }
293
- };
269
+ export function getIconPosition(
270
+ size?: keyof typeof buttonModifiers.size,
271
+ iconPosition?: IconPositions,
272
+ children?: React.ReactNode
273
+ ): keyof typeof buttonModifiers.iconPosition {
274
+ return `${size}${capitalize(iconPosition)}` as keyof typeof buttonModifiers.iconPosition;
275
+ }
294
276
 
277
+ /**
278
+ * The base button which all other buttons are built.
279
+ */
295
280
  export const BaseButton = createComponent('button')({
296
- displayName: 'Button',
297
- Component: ({children, ...elemProps}: ButtonContainerProps, ref, Element) => {
281
+ displayName: 'BaseButton',
282
+ Component: (
283
+ {
284
+ children,
285
+ cs,
286
+ size,
287
+ fillIcon,
288
+ iconPosition,
289
+ icon,
290
+ colors,
291
+ shouldMirrorIcon = false,
292
+ ...elemProps
293
+ }: ButtonContainerProps,
294
+ ref,
295
+ Element
296
+ ) => {
297
+ // console.log('iconPosition', children, getIconPosition(size, iconPosition));
298
298
  return (
299
- <ButtonContainer as={Element} ref={ref} type="button" {...elemProps}>
299
+ <Box
300
+ as={Element}
301
+ ref={ref}
302
+ type="button"
303
+ cs={[
304
+ baseButtonStyles,
305
+ buttonModifiers({
306
+ size: size,
307
+ iconPosition: getIconPosition(size, iconPosition, children),
308
+ }),
309
+ buttonVars.default(colors?.default || {}),
310
+ buttonVars.focus(colors?.focus || {}),
311
+ buttonVars.hover(colors?.hover || {}),
312
+ buttonVars.active(colors?.active || {}),
313
+ buttonVars.disabled(colors?.disabled || {}),
314
+ cs,
315
+ ]}
316
+ {...elemProps}
317
+ >
300
318
  {children}
301
- </ButtonContainer>
319
+ </Box>
302
320
  );
303
321
  },
304
322
  subComponents: {
@@ -0,0 +1,67 @@
1
+ import * as React from 'react';
2
+
3
+ import {BaseButton, ButtonContainerProps} from './BaseButton';
4
+ import {createComponent} from '@workday/canvas-kit-react/common';
5
+
6
+ /**
7
+ * Extends all the style properties from Box to our buttons as well as props from ButtonContainerProps.
8
+ * We omit `ref` since all of our buttons use `createComponent` and already give access to `ref`.
9
+ * Use this type to extend and customize any one off buttons that you want full control over styling.
10
+ */
11
+ export interface ButtonProps extends Omit<ButtonContainerProps, 'ref'> {
12
+ /**
13
+ * Button icon positions can either be `start` or `end`.
14
+ * If no value is provided, it defaults to `start`.
15
+ *
16
+ * @default 'start'
17
+ */
18
+ iconPosition?: 'start' | 'end';
19
+ }
20
+
21
+ export const Button = createComponent('button')({
22
+ displayName: 'Button',
23
+ Component: (
24
+ {
25
+ children,
26
+ icon,
27
+ colors,
28
+ iconPosition,
29
+ shouldMirrorIcon,
30
+ size = 'medium',
31
+ ...elemProps
32
+ }: ButtonProps,
33
+ ref,
34
+ Element
35
+ ) => {
36
+ const baseIconPosition = iconPosition
37
+ ? iconPosition
38
+ : icon
39
+ ? children
40
+ ? 'start'
41
+ : 'only'
42
+ : undefined;
43
+
44
+ return (
45
+ <BaseButton
46
+ as={Element}
47
+ ref={ref}
48
+ size={size}
49
+ icon={icon}
50
+ iconPosition={baseIconPosition}
51
+ {...elemProps}
52
+ >
53
+ {icon && baseIconPosition === 'start' && (
54
+ <BaseButton.Icon size={size} icon={icon} shouldMirrorIcon={shouldMirrorIcon} />
55
+ )}
56
+ {children && <BaseButton.Label>{children}</BaseButton.Label>}
57
+
58
+ {icon && baseIconPosition === 'only' && (
59
+ <BaseButton.Icon size={size} icon={icon} shouldMirrorIcon={shouldMirrorIcon} />
60
+ )}
61
+ {icon && baseIconPosition === 'end' && (
62
+ <BaseButton.Icon size={size} icon={icon} shouldMirrorIcon={shouldMirrorIcon} />
63
+ )}
64
+ </BaseButton>
65
+ );
66
+ },
67
+ });