@cloudflare/component-button 5.1.0 → 5.2.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Change Log
2
2
 
3
+ ## 5.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 8dfd2c3a82: Add plain and plainMono button types
8
+ - 658c7bd8b6: Update colors and states, added buttonState prop to lock appearance to a particular state (e.g. hover)
9
+
3
10
  ## 5.1.0
4
11
 
5
12
  ### Minor Changes
package/dist/Button.d.ts CHANGED
@@ -2,58 +2,10 @@ import React from 'react';
2
2
  import { ThemeProp } from '@cloudflare/style-container';
3
3
  import { IconType } from '@cloudflare/component-icon';
4
4
  export declare const buttonStyles: (props: PropsWithTheme) => {
5
- readonly '&:hover': {
6
- backgroundColor: string | undefined;
7
- color: string | undefined;
8
- } | undefined;
9
- readonly '&:active': {
10
- backgroundColor: string | undefined;
11
- color: string | undefined;
12
- } | undefined;
13
- readonly '&:focus': {
14
- backgroundColor: string | undefined;
15
- color: string | undefined;
16
- } | undefined;
17
- readonly '&:focus-visible': {
18
- readonly outlineOffset: 3;
19
- readonly outlineStyle: "auto";
20
- readonly outlineColor: string;
21
- };
22
- readonly '&:focus-within:hover': {
23
- backgroundColor: string | undefined;
24
- color: string | undefined;
25
- } | undefined;
26
- readonly '&:active:hover': {
27
- backgroundColor: string | undefined;
28
- color: string | undefined;
29
- } | undefined;
30
- readonly '&[title]': {
31
- readonly pointerEvents: "none" | "auto";
32
- };
33
- readonly backgroundColor: string | undefined;
34
- readonly color: string | undefined;
35
- readonly cursor: "default" | "pointer";
36
- readonly display: "inline-flex";
37
- readonly flexGrow: 1 | undefined;
38
- readonly alignItems: "center";
39
- readonly justifyContent: "center";
40
- readonly fontFamily: "-apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen, Ubuntu, \"Helvetica Neue\", Arial, sans-serif";
41
- readonly fontSize: 2;
42
- readonly fontWeight: 400;
43
- readonly lineHeight: 1.2;
44
- readonly borderBottomWidth: 0 | "1px";
45
- readonly borderLeftWidth: 0 | "1px";
46
- readonly borderRightWidth: 0 | "1px";
47
- readonly borderTopWidth: 0 | "1px";
48
- readonly borderBottomStyle: "solid";
49
- readonly borderTopStyle: "solid";
50
- readonly borderLeftStyle: "solid";
51
- readonly borderRightStyle: "solid";
52
- readonly borderColor: string | undefined;
53
- readonly borderTopRightRadius: 0 | 5;
54
- readonly borderTopLeftRadius: 0 | 5;
55
- readonly borderBottomLeftRadius: 0 | 5;
56
- readonly borderBottomRightRadius: 0 | 5;
5
+ readonly borderTopRightRadius: 0 | "4px";
6
+ readonly borderTopLeftRadius: 0 | "4px";
7
+ readonly borderBottomLeftRadius: 0 | "4px";
8
+ readonly borderBottomRightRadius: 0 | "4px";
57
9
  readonly '&::before': {
58
10
  content: string;
59
11
  color: string | undefined;
@@ -84,7 +36,7 @@ export declare const buttonStyles: (props: PropsWithTheme) => {
84
36
  readonly pointerEvents: "none" | "auto";
85
37
  readonly position: "relative";
86
38
  readonly textAlign: "center";
87
- readonly transitionProperty: "background-color,border-color" | "background-color,border-color,color";
39
+ readonly transitionProperty: "all";
88
40
  readonly transitionDuration: "200ms";
89
41
  readonly transitionTimingFunction: "ease";
90
42
  readonly userSelect: "none";
@@ -92,14 +44,56 @@ export declare const buttonStyles: (props: PropsWithTheme) => {
92
44
  readonly float: "none";
93
45
  readonly whiteSpace: "normal" | "nowrap";
94
46
  readonly width: "auto" | "100%";
47
+ readonly boxShadow?: string | undefined;
48
+ readonly '&:focus-visible': {
49
+ readonly outlineOffset: 3;
50
+ readonly outlineStyle: "auto";
51
+ readonly outlineColor: string;
52
+ };
53
+ readonly '&[title]': {
54
+ readonly pointerEvents: "none" | "auto";
55
+ };
56
+ readonly backgroundColor: string | undefined;
57
+ readonly color: string | undefined;
58
+ readonly cursor: "default" | "pointer";
59
+ readonly display: "inline-flex";
60
+ readonly flexGrow: 1 | undefined;
61
+ readonly alignItems: "center";
62
+ readonly justifyContent: "center";
63
+ readonly fontFamily: "-apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen, Ubuntu, \"Helvetica Neue\", Arial, sans-serif";
64
+ readonly fontSize: 2;
65
+ readonly fontWeight: 400;
66
+ readonly lineHeight: 1.2;
67
+ readonly border: "none";
68
+ readonly '&:focus'?: {
69
+ backgroundColor: string | undefined;
70
+ color: string | undefined;
71
+ boxShadow: string | undefined;
72
+ } | undefined;
73
+ readonly '&:hover'?: {
74
+ backgroundColor: string | undefined;
75
+ color: string | undefined;
76
+ boxShadow: string | undefined;
77
+ } | undefined;
78
+ readonly '&:active'?: {
79
+ backgroundColor: string | undefined;
80
+ color: string | undefined;
81
+ boxShadow: string | undefined;
82
+ } | undefined;
83
+ readonly '&:focus:active'?: {
84
+ backgroundColor: string | undefined;
85
+ color: string | undefined;
86
+ boxShadow: string | undefined;
87
+ } | undefined;
95
88
  };
96
89
  declare type Props = {
90
+ id?: string;
97
91
  submit?: boolean;
98
92
  spaced?: boolean;
99
93
  space?: number;
100
94
  direction?: 'column' | 'row';
101
95
  group?: 'first' | 'inbetween' | 'last';
102
- type?: 'default' | 'primary' | 'success' | 'warning' | 'danger';
96
+ type?: 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'plain' | 'plainMono';
103
97
  testId?: string;
104
98
  loading?: boolean;
105
99
  inverted?: boolean;
@@ -110,21 +104,23 @@ declare type Props = {
110
104
  ariaLabel?: string;
111
105
  stretch?: boolean;
112
106
  noWrapText?: boolean;
107
+ buttonState?: 'hover' | 'active' | 'focus';
113
108
  } & Pick<JSX.IntrinsicElements['button'], 'onClick' | 'disabled' | 'form' | 'tabIndex' | 'className'>;
114
109
  declare type PropsWithTheme = Props & ThemeProp;
115
110
  declare const _default: React.ComponentType<{
116
111
  space?: number | undefined;
117
112
  disabled?: boolean | undefined;
118
- submit?: boolean | undefined;
119
113
  form?: string | undefined;
120
114
  className?: string | undefined;
115
+ id?: string | undefined;
121
116
  tabIndex?: number | undefined;
122
- type?: "default" | "primary" | "success" | "warning" | "danger" | undefined;
117
+ type?: "default" | "primary" | "success" | "warning" | "danger" | "plain" | "plainMono" | undefined;
123
118
  direction?: "column" | "row" | undefined;
124
119
  key?: React.Key | null | undefined;
125
120
  onClick?: React.MouseEventHandler<HTMLButtonElement> | undefined;
126
121
  loading?: boolean | undefined;
127
122
  stretch?: boolean | undefined;
123
+ submit?: boolean | undefined;
128
124
  inverted?: boolean | undefined;
129
125
  spaced?: boolean | undefined;
130
126
  group?: "first" | "last" | "inbetween" | undefined;
@@ -135,6 +131,7 @@ declare const _default: React.ComponentType<{
135
131
  iconPosition?: "right" | "left" | undefined;
136
132
  ariaLabel?: string | undefined;
137
133
  noWrapText?: boolean | undefined;
134
+ buttonState?: "focus" | "active" | "hover" | undefined;
138
135
  color?: string | [string | undefined, string | undefined] | [string | undefined, string | undefined, string | undefined] | undefined;
139
136
  borderColor?: string | [string | undefined, string | undefined] | [string | undefined, string | undefined, string | undefined] | undefined;
140
137
  p?: import("csstype").PaddingProperty<string | number> | [import("csstype").PaddingProperty<string | number> | undefined, import("csstype").PaddingProperty<string | number> | undefined] | [import("csstype").PaddingProperty<string | number> | undefined, import("csstype").PaddingProperty<string | number> | undefined, import("csstype").PaddingProperty<string | number> | undefined] | undefined;
@@ -4,11 +4,11 @@ declare const TextButton: import("react").ComponentType<{
4
4
  name?: string | undefined;
5
5
  disabled?: boolean | undefined;
6
6
  color?: (string & (string | [string | undefined, string | undefined] | [string | undefined, string | undefined, string | undefined])) | undefined;
7
- children?: import("react").ReactNode;
8
7
  form?: string | undefined;
9
8
  slot?: string | undefined;
10
9
  style?: import("react").CSSProperties | undefined;
11
10
  title?: string | undefined;
11
+ children?: import("react").ReactNode;
12
12
  value?: string | number | readonly string[] | undefined;
13
13
  defaultChecked?: boolean | undefined;
14
14
  defaultValue?: string | number | readonly string[] | undefined;
@@ -52,7 +52,7 @@ declare const TextButton: import("react").ComponentType<{
52
52
  unselectable?: "on" | "off" | undefined;
53
53
  'aria-activedescendant'?: string | undefined;
54
54
  'aria-atomic'?: boolean | "true" | "false" | undefined;
55
- 'aria-autocomplete'?: "none" | "list" | "both" | "inline" | undefined;
55
+ 'aria-autocomplete'?: "inline" | "none" | "list" | "both" | undefined;
56
56
  'aria-busy'?: boolean | "true" | "false" | undefined;
57
57
  'aria-checked'?: boolean | "true" | "false" | "mixed" | undefined;
58
58
  'aria-colcount'?: number | undefined;
@@ -98,7 +98,7 @@ declare const TextButton: import("react").ComponentType<{
98
98
  'aria-valuemin'?: number | undefined;
99
99
  'aria-valuenow'?: number | undefined;
100
100
  'aria-valuetext'?: string | undefined;
101
- type?: "reset" | "submit" | "button" | undefined;
101
+ type?: "button" | "reset" | "submit" | undefined;
102
102
  autoFocus?: boolean | undefined;
103
103
  formAction?: string | undefined;
104
104
  formEncType?: string | undefined;
@@ -4,11 +4,11 @@ declare const UnstyledButton: import("react").ComponentType<{
4
4
  name?: string | undefined;
5
5
  disabled?: boolean | undefined;
6
6
  color?: (string & (string | [string | undefined, string | undefined] | [string | undefined, string | undefined, string | undefined])) | undefined;
7
- children?: import("react").ReactNode;
8
7
  form?: string | undefined;
9
8
  slot?: string | undefined;
10
9
  style?: import("react").CSSProperties | undefined;
11
10
  title?: string | undefined;
11
+ children?: import("react").ReactNode;
12
12
  value?: string | number | readonly string[] | undefined;
13
13
  defaultChecked?: boolean | undefined;
14
14
  defaultValue?: string | number | readonly string[] | undefined;
@@ -52,7 +52,7 @@ declare const UnstyledButton: import("react").ComponentType<{
52
52
  unselectable?: "on" | "off" | undefined;
53
53
  'aria-activedescendant'?: string | undefined;
54
54
  'aria-atomic'?: boolean | "true" | "false" | undefined;
55
- 'aria-autocomplete'?: "none" | "list" | "both" | "inline" | undefined;
55
+ 'aria-autocomplete'?: "inline" | "none" | "list" | "both" | undefined;
56
56
  'aria-busy'?: boolean | "true" | "false" | undefined;
57
57
  'aria-checked'?: boolean | "true" | "false" | "mixed" | undefined;
58
58
  'aria-colcount'?: number | undefined;
@@ -98,7 +98,7 @@ declare const UnstyledButton: import("react").ComponentType<{
98
98
  'aria-valuemin'?: number | undefined;
99
99
  'aria-valuenow'?: number | undefined;
100
100
  'aria-valuetext'?: string | undefined;
101
- type?: "reset" | "submit" | "button" | undefined;
101
+ type?: "button" | "reset" | "submit" | undefined;
102
102
  autoFocus?: boolean | undefined;
103
103
  formAction?: string | undefined;
104
104
  formEncType?: string | undefined;
package/es/Button.js CHANGED
@@ -11,19 +11,24 @@ import PropTypes from 'prop-types';
11
11
  import { isDarkMode } from '@cloudflare/style-const';
12
12
  import { ariaAttributes, createStyledComponent } from '@cloudflare/style-container';
13
13
  import { Icon } from '@cloudflare/component-icon';
14
+ var borderRadius = '4px';
15
+
16
+ var standardColors = (theme, state) => {
17
+ var _theme$colors$button$, _theme$colors$button$2, _theme$colors$button$3, _theme$colors$button$4, _theme$colors$button$5, _theme$colors$button$6;
14
18
 
15
- var standardColors = theme => {
16
19
  var color = theme.colors.gray[9];
17
20
  return {
18
21
  default: isDarkMode() ? color : theme.colors.gray[1],
19
- primary: color,
20
22
  success: color,
21
23
  warning: color,
22
- danger: color,
23
24
  inverted: {
24
- danger: theme.colors.red[3],
25
- primary: theme.colors.blue[3]
26
- }
25
+ danger: (_theme$colors$button$ = theme.colors.button.danger[state]) === null || _theme$colors$button$ === void 0 ? void 0 : _theme$colors$button$[state === 'active' ? 'text' : 'background'],
26
+ primary: (_theme$colors$button$2 = theme.colors.button.primary[state]) === null || _theme$colors$button$2 === void 0 ? void 0 : _theme$colors$button$2[state === 'active' ? 'text' : 'background']
27
+ },
28
+ primary: ((_theme$colors$button$3 = theme.colors.button.primary[state]) === null || _theme$colors$button$3 === void 0 ? void 0 : _theme$colors$button$3.text) || color,
29
+ danger: ((_theme$colors$button$4 = theme.colors.button.danger[state]) === null || _theme$colors$button$4 === void 0 ? void 0 : _theme$colors$button$4.text) || color,
30
+ plain: ((_theme$colors$button$5 = theme.colors.button.plain[state]) === null || _theme$colors$button$5 === void 0 ? void 0 : _theme$colors$button$5.text) || color,
31
+ plainMono: ((_theme$colors$button$6 = theme.colors.button.plainMono[state]) === null || _theme$colors$button$6 === void 0 ? void 0 : _theme$colors$button$6.text) || color
27
32
  };
28
33
  };
29
34
 
@@ -35,95 +40,73 @@ var buttonColors = theme => {
35
40
  normal: {
36
41
  backgroundColor: {
37
42
  default: isDarkMode() ? theme.colors.gray[standardIndex] : theme.colors.gray[8],
38
- primary: theme.colors.blue[standardIndex],
43
+ primary: theme.colors.button.primary.normal.background,
39
44
  success: theme.colors.green[standardIndex],
40
45
  warning: theme.colors.orange[standardIndex],
41
- danger: theme.colors.red[standardIndex],
46
+ danger: theme.colors.button.danger.normal.background,
42
47
  inverted: {
43
48
  danger: 'transparent',
44
49
  primary: 'transparent'
45
- }
50
+ },
51
+ plain: theme.colors.button.plain.normal.background,
52
+ plainMono: theme.colors.button.plainMono.normal.background
46
53
  },
47
- color: standardColors(theme)
54
+ color: standardColors(theme, 'normal')
48
55
  },
49
56
  // Hover
50
57
  hover: {
51
58
  backgroundColor: {
52
59
  default: theme.colors.gray[isDarkMode() ? 2 : 7],
53
- primary: theme.colors.blue[hoverIndex],
60
+ primary: theme.colors.button.primary.hover.background,
54
61
  success: theme.colors.green[hoverIndex],
55
62
  warning: theme.colors.orange[hoverIndex],
56
- danger: theme.colors.red[hoverIndex],
57
- inverted: {
58
- danger: theme.colors.red[hoverIndex],
59
- primary: theme.colors.blue[hoverIndex]
60
- }
61
- },
62
- color: _objectSpread(_objectSpread({}, standardColors(theme)), {}, {
63
+ danger: theme.colors.button.danger.hover.background,
63
64
  inverted: {
64
65
  danger: theme.colors.white,
65
66
  primary: theme.colors.white
66
- }
67
- })
67
+ },
68
+ plain: theme.colors.button.plain.hover.background,
69
+ plainMono: theme.colors.button.plainMono.hover.background
70
+ },
71
+ color: standardColors(theme, 'hover')
68
72
  },
69
73
  // Active
70
74
  active: {
71
75
  backgroundColor: {
72
- default: theme.colors.gray[isDarkMode() ? 3 : 8],
73
- primary: theme.colors.blue[standardIndex],
76
+ default: theme.colors.gray[isDarkMode() ? 3 : 6],
77
+ primary: theme.colors.button.primary.active.background,
74
78
  success: theme.colors.green[standardIndex],
75
79
  warning: theme.colors.orange[standardIndex],
76
- danger: theme.colors.red[standardIndex],
80
+ danger: theme.colors.button.danger.active.background,
77
81
  inverted: {
78
- danger: theme.colors.red[standardIndex],
79
- primary: theme.colors.blue[standardIndex]
80
- }
82
+ danger: theme.colors.red[hoverIndex],
83
+ primary: theme.colors.blue[hoverIndex]
84
+ },
85
+ plain: theme.colors.button.plain.active.background,
86
+ plainMono: theme.colors.button.plainMono.active.background
81
87
  },
82
- color: _objectSpread(_objectSpread({}, standardColors(theme)), {}, {
83
- inverted: {
84
- danger: theme.colors.gray[9],
85
- primary: theme.colors.gray[9]
86
- }
87
- })
88
+ color: standardColors(theme, 'active')
88
89
  },
89
90
  // Focus
90
91
  focus: {
91
92
  backgroundColor: {
92
93
  default: theme.colors.gray[isDarkMode() ? 3 : 8],
93
- primary: theme.colors.blue[standardIndex],
94
+ primary: theme.colors.button.primary.focus.background,
94
95
  success: theme.colors.green[standardIndex],
95
96
  warning: theme.colors.orange[standardIndex],
96
- danger: theme.colors.red[standardIndex],
97
+ danger: theme.colors.button.danger.focus.background,
97
98
  inverted: {
98
99
  danger: 'transparent',
99
100
  primary: 'transparent'
100
- }
101
+ },
102
+ plain: theme.colors.button.plain.focus.background,
103
+ plainMono: theme.colors.button.plainMono.focus.background
101
104
  },
102
- color: standardColors(theme)
105
+ color: standardColors(theme, 'focus')
103
106
  }
104
107
  };
105
108
  };
106
109
 
107
- var getFocusOutlineColor = (theme, type, inverted) => {
108
- var _invertedOutlines$typ;
109
-
110
- var standardIndex = isDarkMode() ? 3 : 4;
111
- var FOCUS_OFFSET_INDEX = 2;
112
- var focusIndex = standardIndex - FOCUS_OFFSET_INDEX;
113
- var outlines = {
114
- default: isDarkMode() ? theme.colors.gray[focusIndex] : theme.colors.gray[8 - FOCUS_OFFSET_INDEX],
115
- primary: theme.colors.blue[focusIndex],
116
- success: theme.colors.green[focusIndex],
117
- warning: theme.colors.orange[focusIndex],
118
- danger: theme.colors.red[focusIndex]
119
- };
120
- var invertedOutlines = {
121
- danger: theme.colors.red[focusIndex],
122
- primary: theme.colors.blue[focusIndex]
123
- };
124
- return inverted ? (_invertedOutlines$typ = invertedOutlines[type]) !== null && _invertedOutlines$typ !== void 0 ? _invertedOutlines$typ : outlines[type] : outlines[type];
125
- };
126
-
127
110
  var colorAccessor = (property, _ref) => {
128
111
  var {
129
112
  inverted = false,
@@ -140,13 +123,18 @@ var interactionStyleAccessor = (interactionState, props) => {
140
123
  } = props;
141
124
  var isInteractive = !(loading || disabled);
142
125
  var stateStyles = buttonColors(theme)[interactionState];
126
+ var color = colorAccessor(stateStyles.color, props);
127
+ var backgroundColor = colorAccessor(stateStyles.backgroundColor, props);
143
128
  return isInteractive ? {
144
- backgroundColor: colorAccessor(stateStyles.backgroundColor, props),
145
- color: colorAccessor(stateStyles.color, props)
129
+ backgroundColor,
130
+ color,
131
+ boxShadow: props.inverted ? "inset 0px 0px 0px 1px ".concat(interactionState === 'active' ? backgroundColor : color) : undefined
146
132
  } : undefined;
147
133
  };
148
134
 
149
135
  export var buttonStyles = props => {
136
+ var _styles$buttonState, _styles$buttonState2;
137
+
150
138
  var {
151
139
  theme,
152
140
  loading = false,
@@ -158,28 +146,33 @@ export var buttonStyles = props => {
158
146
  space = 2,
159
147
  type = 'default',
160
148
  stretch,
161
- noWrapText
149
+ noWrapText,
150
+ buttonState
162
151
  } = props;
163
- var normalStyles = buttonColors(theme).normal;
164
- var hoverStyles = interactionStyleAccessor('hover', props);
165
- var activeStyles = interactionStyleAccessor('active', props);
166
- var focusStyles = interactionStyleAccessor('focus', props);
167
- return {
168
- '&:hover': hoverStyles,
169
- '&:active': activeStyles,
170
- '&:focus': focusStyles,
152
+ var styles = {
153
+ normal: buttonColors(theme).normal,
154
+ hover: interactionStyleAccessor('hover', props),
155
+ active: interactionStyleAccessor('active', props),
156
+ focus: interactionStyleAccessor('focus', props)
157
+ };
158
+ var color = buttonState && styles[buttonState] ? (_styles$buttonState = styles[buttonState]) === null || _styles$buttonState === void 0 ? void 0 : _styles$buttonState.color : colorAccessor(styles.normal.color, props);
159
+ var backgroundColor = buttonState && styles[buttonState] ? (_styles$buttonState2 = styles[buttonState]) === null || _styles$buttonState2 === void 0 ? void 0 : _styles$buttonState2.backgroundColor : colorAccessor(styles.normal.backgroundColor, props);
160
+ return _objectSpread(_objectSpread(_objectSpread({}, buttonState ? {} : {
161
+ '&:focus': styles.focus,
162
+ '&:hover': styles.hover,
163
+ '&:active': styles.active,
164
+ '&:focus:active': styles.active
165
+ }), {}, {
171
166
  '&:focus-visible': {
172
167
  outlineOffset: 3,
173
168
  outlineStyle: 'auto',
174
- outlineColor: getFocusOutlineColor(theme, type, inverted)
169
+ outlineColor: type === 'danger' ? theme.colors.red[isDarkMode() ? 3 : 4] : theme.colors.focus
175
170
  },
176
- '&:focus-within:hover': focusStyles,
177
- '&:active:hover': activeStyles,
178
171
  '&[title]': {
179
172
  pointerEvents: disabled ? 'auto' : 'none'
180
173
  },
181
- backgroundColor: colorAccessor(normalStyles.backgroundColor, props),
182
- color: loading ? 'transparent' : colorAccessor(normalStyles.color, props),
174
+ backgroundColor,
175
+ color: loading ? 'transparent' : color,
183
176
  cursor: disabled || loading ? 'default' : 'pointer',
184
177
  display: 'inline-flex',
185
178
  flexGrow: stretch ? 1 : undefined,
@@ -189,22 +182,17 @@ export var buttonStyles = props => {
189
182
  fontSize: 2,
190
183
  fontWeight: 400,
191
184
  lineHeight: 1.2,
192
- borderBottomWidth: inverted ? '1px' : 0,
193
- borderLeftWidth: inverted ? '1px' : 0,
194
- borderRightWidth: inverted ? '1px' : 0,
195
- borderTopWidth: inverted ? '1px' : 0,
196
- borderBottomStyle: 'solid',
197
- borderTopStyle: 'solid',
198
- borderLeftStyle: 'solid',
199
- borderRightStyle: 'solid',
200
- borderColor: inverted ? colorAccessor(normalStyles.color, props) : 'currentColor',
201
- borderTopRightRadius: (group === 'first' || group === 'inbetween') && !spaced ? 0 : theme.radii[2],
202
- borderTopLeftRadius: (group === 'last' || group === 'inbetween') && !spaced ? 0 : theme.radii[2],
203
- borderBottomLeftRadius: (group === 'last' || group === 'inbetween') && !spaced ? 0 : theme.radii[2],
204
- borderBottomRightRadius: (group === 'first' || group === 'inbetween') && !spaced ? 0 : theme.radii[2],
185
+ border: 'none'
186
+ }, inverted ? {
187
+ boxShadow: "inset 0px 0px 0px 1px ".concat(buttonState === 'active' ? backgroundColor : color)
188
+ } : {}), {}, {
189
+ borderTopRightRadius: (group === 'first' || group === 'inbetween') && !spaced ? 0 : borderRadius,
190
+ borderTopLeftRadius: (group === 'last' || group === 'inbetween') && !spaced ? 0 : borderRadius,
191
+ borderBottomLeftRadius: (group === 'last' || group === 'inbetween') && !spaced ? 0 : borderRadius,
192
+ borderBottomRightRadius: (group === 'first' || group === 'inbetween') && !spaced ? 0 : borderRadius,
205
193
  '&::before': loading ? {
206
194
  content: '"•••"',
207
- color: colorAccessor(normalStyles.color, props),
195
+ color,
208
196
  display: 'flex',
209
197
  alignItems: 'center',
210
198
  justifyContent: 'center',
@@ -232,7 +220,7 @@ export var buttonStyles = props => {
232
220
  pointerEvents: disabled ? 'none' : 'auto',
233
221
  position: 'relative',
234
222
  textAlign: 'center',
235
- transitionProperty: loading ? 'background-color,border-color' : 'background-color,border-color,color',
223
+ transitionProperty: 'all',
236
224
  transitionDuration: '200ms',
237
225
  transitionTimingFunction: 'ease',
238
226
  userSelect: 'none',
@@ -240,10 +228,11 @@ export var buttonStyles = props => {
240
228
  float: 'none',
241
229
  whiteSpace: noWrapText ? 'nowrap' : 'normal',
242
230
  width: direction === 'column' ? '100%' : 'auto'
243
- };
231
+ });
244
232
  };
245
233
  var Button = /*#__PURE__*/React.forwardRef((props, ref) => {
246
234
  var {
235
+ id,
247
236
  submit = false,
248
237
  className,
249
238
  disabled,
@@ -263,6 +252,7 @@ var Button = /*#__PURE__*/React.forwardRef((props, ref) => {
263
252
  [propName]: props[propName]
264
253
  }), {});
265
254
  return /*#__PURE__*/React.createElement("button", _extends({}, ariaAndDataProps, {
255
+ id: id,
266
256
  type: submit ? 'submit' : 'button',
267
257
  "data-testid": testId,
268
258
  disabled: disabled || loading,
@@ -285,6 +275,7 @@ var Button = /*#__PURE__*/React.forwardRef((props, ref) => {
285
275
  }));
286
276
  });
287
277
  Button.propTypes = {
278
+ id: PropTypes.string,
288
279
  onClick: PropTypes.func,
289
280
  submit: PropTypes.bool,
290
281
  spaced: PropTypes.bool,
@@ -292,7 +283,7 @@ Button.propTypes = {
292
283
  direction: PropTypes.oneOf(['column', 'row']),
293
284
  className: PropTypes.string,
294
285
  group: PropTypes.oneOf(['first', 'inbetween', 'last']),
295
- type: PropTypes.oneOf(['default', 'primary', 'success', 'warning', 'danger']),
286
+ type: PropTypes.oneOf(['default', 'primary', 'success', 'warning', 'danger', 'plain', 'plainMono']),
296
287
  testId: PropTypes.string,
297
288
  disabled: PropTypes.bool,
298
289
  loading: PropTypes.bool,
@@ -304,7 +295,8 @@ Button.propTypes = {
304
295
  tabIndex: PropTypes.number,
305
296
  ariaLabel: PropTypes.string,
306
297
  stretch: PropTypes.bool,
307
- noWrapText: PropTypes.bool
298
+ noWrapText: PropTypes.bool,
299
+ buttonState: PropTypes.oneOf(['hover', 'active', 'focus'])
308
300
  };
309
301
  Button.displayName = 'Button';
310
302
  export default createStyledComponent(buttonStyles, Button);
@@ -8,13 +8,15 @@ import { createStyledComponent } from '@cloudflare/style-container';
8
8
  var UnstyledButton = createStyledComponent(_ref => {
9
9
  var {
10
10
  theme,
11
- focus
11
+ focus,
12
+ disabled
12
13
  } = _ref;
13
14
  return _objectSpread({
14
15
  background: 'none',
15
16
  color: 'inherit',
16
17
  border: 'none',
17
18
  padding: 0,
19
+ opacity: disabled ? 0.5 : undefined,
18
20
  font: 'inherit',
19
21
  cursor: 'pointer',
20
22
  outline: 'inherit'
package/lib/Button.js CHANGED
@@ -25,18 +25,24 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
25
25
 
26
26
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
27
27
 
28
- var standardColors = function standardColors(theme) {
28
+ var borderRadius = '4px';
29
+
30
+ var standardColors = function standardColors(theme, state) {
31
+ var _theme$colors$button$, _theme$colors$button$2, _theme$colors$button$3, _theme$colors$button$4, _theme$colors$button$5, _theme$colors$button$6;
32
+
29
33
  var color = theme.colors.gray[9];
30
34
  return {
31
35
  default: (0, _styleConst.isDarkMode)() ? color : theme.colors.gray[1],
32
- primary: color,
33
36
  success: color,
34
37
  warning: color,
35
- danger: color,
36
38
  inverted: {
37
- danger: theme.colors.red[3],
38
- primary: theme.colors.blue[3]
39
- }
39
+ danger: (_theme$colors$button$ = theme.colors.button.danger[state]) === null || _theme$colors$button$ === void 0 ? void 0 : _theme$colors$button$[state === 'active' ? 'text' : 'background'],
40
+ primary: (_theme$colors$button$2 = theme.colors.button.primary[state]) === null || _theme$colors$button$2 === void 0 ? void 0 : _theme$colors$button$2[state === 'active' ? 'text' : 'background']
41
+ },
42
+ primary: ((_theme$colors$button$3 = theme.colors.button.primary[state]) === null || _theme$colors$button$3 === void 0 ? void 0 : _theme$colors$button$3.text) || color,
43
+ danger: ((_theme$colors$button$4 = theme.colors.button.danger[state]) === null || _theme$colors$button$4 === void 0 ? void 0 : _theme$colors$button$4.text) || color,
44
+ plain: ((_theme$colors$button$5 = theme.colors.button.plain[state]) === null || _theme$colors$button$5 === void 0 ? void 0 : _theme$colors$button$5.text) || color,
45
+ plainMono: ((_theme$colors$button$6 = theme.colors.button.plainMono[state]) === null || _theme$colors$button$6 === void 0 ? void 0 : _theme$colors$button$6.text) || color
40
46
  };
41
47
  };
42
48
 
@@ -48,95 +54,73 @@ var buttonColors = function buttonColors(theme) {
48
54
  normal: {
49
55
  backgroundColor: {
50
56
  default: (0, _styleConst.isDarkMode)() ? theme.colors.gray[standardIndex] : theme.colors.gray[8],
51
- primary: theme.colors.blue[standardIndex],
57
+ primary: theme.colors.button.primary.normal.background,
52
58
  success: theme.colors.green[standardIndex],
53
59
  warning: theme.colors.orange[standardIndex],
54
- danger: theme.colors.red[standardIndex],
60
+ danger: theme.colors.button.danger.normal.background,
55
61
  inverted: {
56
62
  danger: 'transparent',
57
63
  primary: 'transparent'
58
- }
64
+ },
65
+ plain: theme.colors.button.plain.normal.background,
66
+ plainMono: theme.colors.button.plainMono.normal.background
59
67
  },
60
- color: standardColors(theme)
68
+ color: standardColors(theme, 'normal')
61
69
  },
62
70
  // Hover
63
71
  hover: {
64
72
  backgroundColor: {
65
73
  default: theme.colors.gray[(0, _styleConst.isDarkMode)() ? 2 : 7],
66
- primary: theme.colors.blue[hoverIndex],
74
+ primary: theme.colors.button.primary.hover.background,
67
75
  success: theme.colors.green[hoverIndex],
68
76
  warning: theme.colors.orange[hoverIndex],
69
- danger: theme.colors.red[hoverIndex],
70
- inverted: {
71
- danger: theme.colors.red[hoverIndex],
72
- primary: theme.colors.blue[hoverIndex]
73
- }
74
- },
75
- color: _objectSpread(_objectSpread({}, standardColors(theme)), {}, {
77
+ danger: theme.colors.button.danger.hover.background,
76
78
  inverted: {
77
79
  danger: theme.colors.white,
78
80
  primary: theme.colors.white
79
- }
80
- })
81
+ },
82
+ plain: theme.colors.button.plain.hover.background,
83
+ plainMono: theme.colors.button.plainMono.hover.background
84
+ },
85
+ color: standardColors(theme, 'hover')
81
86
  },
82
87
  // Active
83
88
  active: {
84
89
  backgroundColor: {
85
- default: theme.colors.gray[(0, _styleConst.isDarkMode)() ? 3 : 8],
86
- primary: theme.colors.blue[standardIndex],
90
+ default: theme.colors.gray[(0, _styleConst.isDarkMode)() ? 3 : 6],
91
+ primary: theme.colors.button.primary.active.background,
87
92
  success: theme.colors.green[standardIndex],
88
93
  warning: theme.colors.orange[standardIndex],
89
- danger: theme.colors.red[standardIndex],
94
+ danger: theme.colors.button.danger.active.background,
90
95
  inverted: {
91
- danger: theme.colors.red[standardIndex],
92
- primary: theme.colors.blue[standardIndex]
93
- }
96
+ danger: theme.colors.red[hoverIndex],
97
+ primary: theme.colors.blue[hoverIndex]
98
+ },
99
+ plain: theme.colors.button.plain.active.background,
100
+ plainMono: theme.colors.button.plainMono.active.background
94
101
  },
95
- color: _objectSpread(_objectSpread({}, standardColors(theme)), {}, {
96
- inverted: {
97
- danger: theme.colors.gray[9],
98
- primary: theme.colors.gray[9]
99
- }
100
- })
102
+ color: standardColors(theme, 'active')
101
103
  },
102
104
  // Focus
103
105
  focus: {
104
106
  backgroundColor: {
105
107
  default: theme.colors.gray[(0, _styleConst.isDarkMode)() ? 3 : 8],
106
- primary: theme.colors.blue[standardIndex],
108
+ primary: theme.colors.button.primary.focus.background,
107
109
  success: theme.colors.green[standardIndex],
108
110
  warning: theme.colors.orange[standardIndex],
109
- danger: theme.colors.red[standardIndex],
111
+ danger: theme.colors.button.danger.focus.background,
110
112
  inverted: {
111
113
  danger: 'transparent',
112
114
  primary: 'transparent'
113
- }
115
+ },
116
+ plain: theme.colors.button.plain.focus.background,
117
+ plainMono: theme.colors.button.plainMono.focus.background
114
118
  },
115
- color: standardColors(theme)
119
+ color: standardColors(theme, 'focus')
116
120
  }
117
121
  };
118
122
  };
119
123
 
120
- var getFocusOutlineColor = function getFocusOutlineColor(theme, type, inverted) {
121
- var _invertedOutlines$typ;
122
-
123
- var standardIndex = (0, _styleConst.isDarkMode)() ? 3 : 4;
124
- var FOCUS_OFFSET_INDEX = 2;
125
- var focusIndex = standardIndex - FOCUS_OFFSET_INDEX;
126
- var outlines = {
127
- default: (0, _styleConst.isDarkMode)() ? theme.colors.gray[focusIndex] : theme.colors.gray[8 - FOCUS_OFFSET_INDEX],
128
- primary: theme.colors.blue[focusIndex],
129
- success: theme.colors.green[focusIndex],
130
- warning: theme.colors.orange[focusIndex],
131
- danger: theme.colors.red[focusIndex]
132
- };
133
- var invertedOutlines = {
134
- danger: theme.colors.red[focusIndex],
135
- primary: theme.colors.blue[focusIndex]
136
- };
137
- return inverted ? (_invertedOutlines$typ = invertedOutlines[type]) !== null && _invertedOutlines$typ !== void 0 ? _invertedOutlines$typ : outlines[type] : outlines[type];
138
- };
139
-
140
124
  var colorAccessor = function colorAccessor(property, _ref) {
141
125
  var _ref$inverted = _ref.inverted,
142
126
  inverted = _ref$inverted === void 0 ? false : _ref$inverted,
@@ -151,13 +135,18 @@ var interactionStyleAccessor = function interactionStyleAccessor(interactionStat
151
135
  disabled = props.disabled;
152
136
  var isInteractive = !(loading || disabled);
153
137
  var stateStyles = buttonColors(theme)[interactionState];
138
+ var color = colorAccessor(stateStyles.color, props);
139
+ var backgroundColor = colorAccessor(stateStyles.backgroundColor, props);
154
140
  return isInteractive ? {
155
- backgroundColor: colorAccessor(stateStyles.backgroundColor, props),
156
- color: colorAccessor(stateStyles.color, props)
141
+ backgroundColor: backgroundColor,
142
+ color: color,
143
+ boxShadow: props.inverted ? "inset 0px 0px 0px 1px ".concat(interactionState === 'active' ? backgroundColor : color) : undefined
157
144
  } : undefined;
158
145
  };
159
146
 
160
147
  var buttonStyles = function buttonStyles(props) {
148
+ var _styles$buttonState, _styles$buttonState2;
149
+
161
150
  var theme = props.theme,
162
151
  _props$loading = props.loading,
163
152
  loading = _props$loading === void 0 ? false : _props$loading,
@@ -172,27 +161,32 @@ var buttonStyles = function buttonStyles(props) {
172
161
  _props$type = props.type,
173
162
  type = _props$type === void 0 ? 'default' : _props$type,
174
163
  stretch = props.stretch,
175
- noWrapText = props.noWrapText;
176
- var normalStyles = buttonColors(theme).normal;
177
- var hoverStyles = interactionStyleAccessor('hover', props);
178
- var activeStyles = interactionStyleAccessor('active', props);
179
- var focusStyles = interactionStyleAccessor('focus', props);
180
- return {
181
- '&:hover': hoverStyles,
182
- '&:active': activeStyles,
183
- '&:focus': focusStyles,
164
+ noWrapText = props.noWrapText,
165
+ buttonState = props.buttonState;
166
+ var styles = {
167
+ normal: buttonColors(theme).normal,
168
+ hover: interactionStyleAccessor('hover', props),
169
+ active: interactionStyleAccessor('active', props),
170
+ focus: interactionStyleAccessor('focus', props)
171
+ };
172
+ var color = buttonState && styles[buttonState] ? (_styles$buttonState = styles[buttonState]) === null || _styles$buttonState === void 0 ? void 0 : _styles$buttonState.color : colorAccessor(styles.normal.color, props);
173
+ var backgroundColor = buttonState && styles[buttonState] ? (_styles$buttonState2 = styles[buttonState]) === null || _styles$buttonState2 === void 0 ? void 0 : _styles$buttonState2.backgroundColor : colorAccessor(styles.normal.backgroundColor, props);
174
+ return _objectSpread(_objectSpread(_objectSpread({}, buttonState ? {} : {
175
+ '&:focus': styles.focus,
176
+ '&:hover': styles.hover,
177
+ '&:active': styles.active,
178
+ '&:focus:active': styles.active
179
+ }), {}, {
184
180
  '&:focus-visible': {
185
181
  outlineOffset: 3,
186
182
  outlineStyle: 'auto',
187
- outlineColor: getFocusOutlineColor(theme, type, inverted)
183
+ outlineColor: type === 'danger' ? theme.colors.red[(0, _styleConst.isDarkMode)() ? 3 : 4] : theme.colors.focus
188
184
  },
189
- '&:focus-within:hover': focusStyles,
190
- '&:active:hover': activeStyles,
191
185
  '&[title]': {
192
186
  pointerEvents: disabled ? 'auto' : 'none'
193
187
  },
194
- backgroundColor: colorAccessor(normalStyles.backgroundColor, props),
195
- color: loading ? 'transparent' : colorAccessor(normalStyles.color, props),
188
+ backgroundColor: backgroundColor,
189
+ color: loading ? 'transparent' : color,
196
190
  cursor: disabled || loading ? 'default' : 'pointer',
197
191
  display: 'inline-flex',
198
192
  flexGrow: stretch ? 1 : undefined,
@@ -202,22 +196,17 @@ var buttonStyles = function buttonStyles(props) {
202
196
  fontSize: 2,
203
197
  fontWeight: 400,
204
198
  lineHeight: 1.2,
205
- borderBottomWidth: inverted ? '1px' : 0,
206
- borderLeftWidth: inverted ? '1px' : 0,
207
- borderRightWidth: inverted ? '1px' : 0,
208
- borderTopWidth: inverted ? '1px' : 0,
209
- borderBottomStyle: 'solid',
210
- borderTopStyle: 'solid',
211
- borderLeftStyle: 'solid',
212
- borderRightStyle: 'solid',
213
- borderColor: inverted ? colorAccessor(normalStyles.color, props) : 'currentColor',
214
- borderTopRightRadius: (group === 'first' || group === 'inbetween') && !spaced ? 0 : theme.radii[2],
215
- borderTopLeftRadius: (group === 'last' || group === 'inbetween') && !spaced ? 0 : theme.radii[2],
216
- borderBottomLeftRadius: (group === 'last' || group === 'inbetween') && !spaced ? 0 : theme.radii[2],
217
- borderBottomRightRadius: (group === 'first' || group === 'inbetween') && !spaced ? 0 : theme.radii[2],
199
+ border: 'none'
200
+ }, inverted ? {
201
+ boxShadow: "inset 0px 0px 0px 1px ".concat(buttonState === 'active' ? backgroundColor : color)
202
+ } : {}), {}, {
203
+ borderTopRightRadius: (group === 'first' || group === 'inbetween') && !spaced ? 0 : borderRadius,
204
+ borderTopLeftRadius: (group === 'last' || group === 'inbetween') && !spaced ? 0 : borderRadius,
205
+ borderBottomLeftRadius: (group === 'last' || group === 'inbetween') && !spaced ? 0 : borderRadius,
206
+ borderBottomRightRadius: (group === 'first' || group === 'inbetween') && !spaced ? 0 : borderRadius,
218
207
  '&::before': loading ? {
219
208
  content: '"•••"',
220
- color: colorAccessor(normalStyles.color, props),
209
+ color: color,
221
210
  display: 'flex',
222
211
  alignItems: 'center',
223
212
  justifyContent: 'center',
@@ -245,7 +234,7 @@ var buttonStyles = function buttonStyles(props) {
245
234
  pointerEvents: disabled ? 'none' : 'auto',
246
235
  position: 'relative',
247
236
  textAlign: 'center',
248
- transitionProperty: loading ? 'background-color,border-color' : 'background-color,border-color,color',
237
+ transitionProperty: 'all',
249
238
  transitionDuration: '200ms',
250
239
  transitionTimingFunction: 'ease',
251
240
  userSelect: 'none',
@@ -253,13 +242,14 @@ var buttonStyles = function buttonStyles(props) {
253
242
  float: 'none',
254
243
  whiteSpace: noWrapText ? 'nowrap' : 'normal',
255
244
  width: direction === 'column' ? '100%' : 'auto'
256
- };
245
+ });
257
246
  };
258
247
 
259
248
  exports.buttonStyles = buttonStyles;
260
249
 
261
250
  var Button = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
262
- var _props$submit = props.submit,
251
+ var id = props.id,
252
+ _props$submit = props.submit,
263
253
  submit = _props$submit === void 0 ? false : _props$submit,
264
254
  className = props.className,
265
255
  disabled = props.disabled,
@@ -282,6 +272,7 @@ var Button = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
282
272
  return _objectSpread(_objectSpread({}, memo), {}, _defineProperty({}, propName, props[propName]));
283
273
  }, {});
284
274
  return /*#__PURE__*/_react.default.createElement("button", _extends({}, ariaAndDataProps, {
275
+ id: id,
285
276
  type: submit ? 'submit' : 'button',
286
277
  "data-testid": testId,
287
278
  disabled: disabled || loading,
@@ -305,6 +296,7 @@ var Button = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
305
296
  });
306
297
 
307
298
  Button.propTypes = {
299
+ id: _propTypes.default.string,
308
300
  onClick: _propTypes.default.func,
309
301
  submit: _propTypes.default.bool,
310
302
  spaced: _propTypes.default.bool,
@@ -312,7 +304,7 @@ Button.propTypes = {
312
304
  direction: _propTypes.default.oneOf(['column', 'row']),
313
305
  className: _propTypes.default.string,
314
306
  group: _propTypes.default.oneOf(['first', 'inbetween', 'last']),
315
- type: _propTypes.default.oneOf(['default', 'primary', 'success', 'warning', 'danger']),
307
+ type: _propTypes.default.oneOf(['default', 'primary', 'success', 'warning', 'danger', 'plain', 'plainMono']),
316
308
  testId: _propTypes.default.string,
317
309
  disabled: _propTypes.default.bool,
318
310
  loading: _propTypes.default.bool,
@@ -324,7 +316,8 @@ Button.propTypes = {
324
316
  tabIndex: _propTypes.default.number,
325
317
  ariaLabel: _propTypes.default.string,
326
318
  stretch: _propTypes.default.bool,
327
- noWrapText: _propTypes.default.bool
319
+ noWrapText: _propTypes.default.bool,
320
+ buttonState: _propTypes.default.oneOf(['hover', 'active', 'focus'])
328
321
  };
329
322
  Button.displayName = 'Button';
330
323
 
@@ -15,12 +15,14 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
15
15
 
16
16
  var UnstyledButton = (0, _styleContainer.createStyledComponent)(function (_ref) {
17
17
  var theme = _ref.theme,
18
- focus = _ref.focus;
18
+ focus = _ref.focus,
19
+ disabled = _ref.disabled;
19
20
  return _objectSpread({
20
21
  background: 'none',
21
22
  color: 'inherit',
22
23
  border: 'none',
23
24
  padding: 0,
25
+ opacity: disabled ? 0.5 : undefined,
24
26
  font: 'inherit',
25
27
  cursor: 'pointer',
26
28
  outline: 'inherit'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudflare/component-button",
3
3
  "description": "Cloudflare Button Component",
4
- "version": "5.1.0",
4
+ "version": "5.2.0",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",
7
7
  "author": "James Kyle <jkyle@cloudflare.com>",