@khanacademy/wonder-blocks-button 6.3.9 → 6.3.11

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.
@@ -1,309 +0,0 @@
1
- import * as React from "react";
2
- import {__RouterContext} from "react-router";
3
-
4
- import {getClickableBehavior} from "@khanacademy/wonder-blocks-clickable";
5
- import type {
6
- ClickableState,
7
- ChildrenProps,
8
- } from "@khanacademy/wonder-blocks-clickable";
9
- import type {AriaProps, StyleType} from "@khanacademy/wonder-blocks-core";
10
- import type {PhosphorIconAsset} from "@khanacademy/wonder-blocks-icon";
11
- import {Link} from "react-router-dom";
12
- import ButtonCore from "./button-core";
13
- import ThemedButton from "../themes/themed-button";
14
-
15
- export type SharedProps =
16
- /**
17
- * aria-label should be used when `spinner={true}` to let people using screen
18
- * readers that the action taken by clicking the button will take some
19
- * time to complete.
20
- */
21
- Partial<Omit<AriaProps, "aria-disabled">> & {
22
- /**
23
- * Text to appear on the button.
24
- */
25
- children: string;
26
- /**
27
- * A Phosphor icon asset (imported as a static SVG file) that
28
- * will appear at the start of the button (left for LTR, right for RTL).
29
- */
30
- startIcon?: PhosphorIconAsset;
31
- /**
32
- * A Phosphor icon asset (imported as a static SVG file) that
33
- * will appear at the end of the button (right for LTR, left for RTL).
34
- */
35
- endIcon?: PhosphorIconAsset;
36
- /**
37
- * If true, replaces the contents with a spinner.
38
- *
39
- * Note: setting this prop to `true` will disable the button.
40
- *
41
- * TODO(kevinb): support spinner + light once we have designs
42
- */
43
- spinner?: boolean;
44
- /**
45
- * The color of the button, either blue or red.
46
- */
47
- color?: "default" | "destructive";
48
- /**
49
- * The kind of the button, either primary, secondary, or tertiary.
50
- *
51
- * In default state:
52
- *
53
- * - Primary buttons have background colors
54
- * - Secondary buttons have a border and no background color
55
- * - Tertiary buttons have no background or border
56
- */
57
- kind?: "primary" | "secondary" | "tertiary";
58
- /**
59
- * Whether the button is on a dark/colored background.
60
- *
61
- * Sets primary button background color to white, and secondary and
62
- * tertiary button title to color.
63
- */
64
- light?: boolean;
65
- /**
66
- * The size of the button. "medium" = height: 40; "small" = height: 32;
67
- * "large" = height: 56;
68
- */
69
- size?: "medium" | "small" | "large";
70
- /**
71
- * Whether the button is disabled.
72
- */
73
- disabled?: boolean;
74
- /**
75
- * An optional id attribute.
76
- */
77
- id?: string;
78
- /**
79
- * Test ID used for e2e testing.
80
- */
81
- testId?: string;
82
- /**
83
- * Specifies the type of relationship between the current document and the
84
- * linked document. Should only be used when `href` is specified. This
85
- * defaults to "noopener noreferrer" when `target="_blank"`, but can be
86
- * overridden by setting this prop to something else.
87
- */
88
- rel?: string;
89
- /**
90
- * A target destination window for a link to open in. Should only be used
91
- * when `href` is specified.
92
- *
93
- * TODO(WB-1262): only allow this prop when `href` is also set.t
94
- */
95
- target?: "_blank";
96
- /**
97
- * Set the tabindex attribute on the rendered element.
98
- */
99
- tabIndex?: number;
100
- /**
101
- * Whether to avoid using client-side navigation.
102
- *
103
- * If the URL passed to href is local to the client-side, e.g.
104
- * /math/algebra/eval-exprs, then it tries to use react-router-dom's Link
105
- * component which handles the client-side navigation. You can set
106
- * `skipClientNav` to true avoid using client-side nav entirely.
107
- *
108
- * NOTE: All URLs containing a protocol are considered external, e.g.
109
- * https://khanacademy.org/math/algebra/eval-exprs will trigger a full
110
- * page reload.
111
- */
112
- skipClientNav?: boolean;
113
- /**
114
- * Optional custom styles for the inner label.
115
- */
116
- labelStyle?: StyleType;
117
- /**
118
- * Optional custom styles.
119
- */
120
- style?: StyleType;
121
- // TODO(yejia): use this if ADR #47 has been implemented
122
- /*
123
- style?: Style<Exact<{
124
- width?: number | string
125
- position: Position,
126
- ...MarginStyles,
127
- ...FlexItemStyles,
128
- }>>,
129
- */
130
- /**
131
- * URL to navigate to.
132
- */
133
- href?: string;
134
-
135
- /**
136
- * Used for buttons within <form>s.
137
- */
138
- type?: "submit";
139
-
140
- /**
141
- * Adds CSS classes to the Button.
142
- */
143
- className?: string;
144
- // NOTE(jeresig): Currently React Docgen (used by Styleguidist) doesn't
145
- // support ... inside of an exact object type. Thus we had to move the
146
- // following propers into this SharedProps, even though they should be
147
- // external. Once that's fixed we can split them back apart.
148
-
149
- /**
150
- * Function to call when button is clicked.
151
- *
152
- * This callback should be used for running synchronous code, like
153
- * dispatching a Redux action. For asynchronous code see the
154
- * beforeNav and safeWithNav props. It should NOT be used to redirect
155
- * to a different URL.
156
- *
157
- * Note: onClick is optional if href is present, but must be defined if
158
- * href is not
159
- */
160
- onClick?: (e: React.SyntheticEvent) => unknown;
161
-
162
- /**
163
- * Run async code before navigating. If the promise returned rejects then
164
- * navigation will not occur.
165
- *
166
- * If both safeWithNav and beforeNav are provided, beforeNav will be run
167
- * first and safeWithNav will only be run if beforeNav does not reject.
168
- *
169
- * WARNING: Do not use with `type="submit"`.
170
- */
171
- beforeNav?: () => Promise<unknown>;
172
-
173
- /**
174
- * Run async code in the background while client-side navigating. If the
175
- * browser does a full page load navigation, the callback promise must be
176
- * settled before the navigation will occur. Errors are ignored so that
177
- * navigation is guaranteed to succeed.
178
- *
179
- * WARNING: Do not use with `type="submit"`.
180
- */
181
- safeWithNav?: () => Promise<unknown>;
182
- };
183
-
184
- type Props = SharedProps;
185
-
186
- /**
187
- * Reusable button component.
188
- *
189
- * Consisting of a [`ClickableBehavior`](#clickablebehavior) surrounding a
190
- * `ButtonCore`. `ClickableBehavior` handles interactions and state changes.
191
- * `ButtonCore` is a stateless component which displays the different states
192
- * the `Button` can take.
193
- *
194
- * ### Usage
195
- *
196
- * ```jsx
197
- * import Button from "@khanacademy/wonder-blocks-button";
198
- *
199
- * <Button
200
- * onClick={(e) => console.log("Hello, world!")}
201
- * >
202
- * Hello, world!
203
- * </Button>
204
- * ```
205
- */
206
- const Button: React.ForwardRefExoticComponent<
207
- Props &
208
- React.RefAttributes<typeof Link | HTMLButtonElement | HTMLAnchorElement>
209
- > = React.forwardRef<
210
- typeof Link | HTMLButtonElement | HTMLAnchorElement,
211
- Props
212
- >(function Button(props: Props, ref) {
213
- const {
214
- href = undefined,
215
- type = undefined,
216
- children,
217
- skipClientNav,
218
- onClick,
219
- beforeNav = undefined,
220
- safeWithNav = undefined,
221
- tabIndex,
222
- target,
223
- rel,
224
- color = "default",
225
- kind = "primary",
226
- light = false,
227
- size = "medium",
228
- disabled = false,
229
- spinner = false,
230
- ...sharedButtonCoreProps
231
- } = props;
232
-
233
- const renderClickableBehavior = (router: any): React.ReactNode => {
234
- const ClickableBehavior = getClickableBehavior(
235
- href,
236
- skipClientNav,
237
- router,
238
- );
239
-
240
- const renderProp = (
241
- state: ClickableState,
242
- restChildProps: ChildrenProps,
243
- ) => {
244
- return (
245
- <ButtonCore
246
- {...sharedButtonCoreProps}
247
- {...state}
248
- {...restChildProps}
249
- disabled={disabled}
250
- spinner={spinner || state.waiting}
251
- color={color}
252
- kind={kind}
253
- light={light}
254
- size={size}
255
- skipClientNav={skipClientNav}
256
- href={href}
257
- target={target}
258
- type={type}
259
- tabIndex={tabIndex}
260
- ref={ref}
261
- >
262
- {children}
263
- </ButtonCore>
264
- );
265
- };
266
-
267
- if (beforeNav) {
268
- return (
269
- <ClickableBehavior
270
- disabled={spinner || disabled}
271
- href={href}
272
- role="button"
273
- type={type}
274
- onClick={onClick}
275
- beforeNav={beforeNav}
276
- safeWithNav={safeWithNav}
277
- rel={rel}
278
- >
279
- {renderProp}
280
- </ClickableBehavior>
281
- );
282
- } else {
283
- return (
284
- <ClickableBehavior
285
- disabled={spinner || disabled}
286
- href={href}
287
- role="button"
288
- type={type}
289
- onClick={onClick}
290
- safeWithNav={safeWithNav}
291
- target={target}
292
- rel={rel}
293
- >
294
- {renderProp}
295
- </ClickableBehavior>
296
- );
297
- }
298
- };
299
-
300
- return (
301
- <ThemedButton>
302
- <__RouterContext.Consumer>
303
- {(router) => renderClickableBehavior(router)}
304
- </__RouterContext.Consumer>
305
- </ThemedButton>
306
- );
307
- });
308
-
309
- export default Button;
package/src/index.ts DELETED
@@ -1,5 +0,0 @@
1
- import Button from "./components/button";
2
- import type {SharedProps} from "./components/button";
3
-
4
- export type {SharedProps as ButtonProps};
5
- export {Button as default};
@@ -1,163 +0,0 @@
1
- import * as tokens from "@khanacademy/wonder-blocks-tokens";
2
-
3
- const theme = {
4
- color: {
5
- bg: {
6
- /**
7
- * Color
8
- */
9
- // color="default"
10
- action: {
11
- default: tokens.color.blue,
12
- active: tokens.color.activeBlue,
13
- inverse: tokens.color.fadedBlue,
14
- },
15
- // color="destructive"
16
- critical: {
17
- default: tokens.color.red,
18
- active: tokens.color.activeRed,
19
- inverse: tokens.color.fadedRed,
20
- },
21
-
22
- /**
23
- * Kind
24
- */
25
- primary: {
26
- default: tokens.color.white,
27
- disabled: tokens.color.offBlack32,
28
- // used in boxShadow
29
- inverse: tokens.color.darkBlue,
30
- },
31
-
32
- secondary: {
33
- default: "none",
34
- inverse: "none",
35
- focus: tokens.color.white,
36
- active: {
37
- action: tokens.color.fadedBlue,
38
- critical: tokens.color.fadedRed,
39
- },
40
- },
41
-
42
- tertiary: {
43
- hover: tokens.color.white,
44
- },
45
-
46
- /**
47
- * Icons
48
- */
49
- icon: {
50
- secondaryHover: "transparent",
51
- },
52
- },
53
- text: {
54
- /**
55
- * Default
56
- */
57
- // kind="secondary, tertiary", disabled=true, light=false
58
- disabled: tokens.color.offBlack32,
59
- // kind="primary", light=false | kind="secondary, tertiary", light=true
60
- inverse: tokens.color.white,
61
-
62
- /**
63
- * Kind
64
- */
65
- primary: {
66
- disabled: tokens.color.white64,
67
- },
68
- secondary: {
69
- inverse: tokens.color.white50,
70
- },
71
-
72
- /**
73
- * Icons
74
- */
75
- icon: {
76
- // Allows the icon to be visible on hover in both light and dark
77
- // backgrounds.
78
- secondaryHover: "inherit",
79
- },
80
- },
81
- border: {
82
- /**
83
- * Default
84
- */
85
- // kind="secondary", light=false | kind="tertiary", light=false
86
- disabled: tokens.color.offBlack32,
87
- /**
88
- * Kind
89
- */
90
- primary: {
91
- inverse: tokens.color.white,
92
- },
93
- secondary: {
94
- action: tokens.color.offBlack50,
95
- critical: tokens.color.offBlack50,
96
- inverse: tokens.color.white50,
97
- },
98
- tertiary: {
99
- inverse: tokens.color.white,
100
- },
101
- },
102
- },
103
- border: {
104
- width: {
105
- // secondary (resting)
106
- secondary: tokens.border.width.hairline,
107
- // secondary (resting, focus, active), tertiary (focus)
108
- focused: tokens.border.width.thin,
109
- // secondary (disabled)
110
- disabled: tokens.border.width.thin,
111
- },
112
- radius: {
113
- // default
114
- default: tokens.border.radius.medium_4,
115
- // tertiary
116
- tertiary: tokens.border.radius.xSmall_2,
117
- // small button
118
- small: tokens.border.radius.medium_4,
119
- // large button
120
- large: tokens.border.radius.large_6,
121
-
122
- /**
123
- * Icons
124
- */
125
- icon: tokens.border.radius.full,
126
- },
127
- },
128
- size: {
129
- height: {
130
- tertiaryHover: tokens.spacing.xxxxSmall_2,
131
- small: tokens.spacing.xLarge_32,
132
- // NOTE: These height tokens are specific to this component.
133
- medium: 40,
134
- large: 56,
135
- },
136
- },
137
- margin: {
138
- icon: {
139
- offset: -tokens.spacing.xxxxSmall_2,
140
- },
141
- },
142
- padding: {
143
- xsmall: tokens.spacing.xxxxSmall_2,
144
- small: tokens.spacing.xxSmall_6,
145
- medium: tokens.spacing.small_12,
146
- large: tokens.spacing.medium_16,
147
- xLarge: tokens.spacing.xLarge_32,
148
- },
149
- font: {
150
- size: {
151
- // NOTE: This token is specific to this button size.
152
- large: 18,
153
- },
154
- lineHeight: {
155
- large: tokens.font.lineHeight.medium,
156
- },
157
- weight: {
158
- default: tokens.font.weight.bold,
159
- },
160
- },
161
- };
162
-
163
- export default theme;
@@ -1,58 +0,0 @@
1
- import {mergeTheme} from "@khanacademy/wonder-blocks-theming";
2
- import * as tokens from "@khanacademy/wonder-blocks-tokens";
3
- import defaultTheme from "./default";
4
-
5
- /**
6
- * The overrides for the Khanmigo theme.
7
- */
8
- const theme = mergeTheme(defaultTheme, {
9
- color: {
10
- bg: {
11
- secondary: {
12
- default: tokens.color.offWhite,
13
- active: {
14
- action: tokens.color.fadedBlue8,
15
- critical: tokens.color.fadedRed8,
16
- },
17
- focus: tokens.color.offWhite,
18
- },
19
- icon: {
20
- secondaryHover: tokens.color.fadedBlue16,
21
- },
22
- },
23
- border: {
24
- secondary: {
25
- action: tokens.color.fadedBlue,
26
- critical: tokens.color.fadedRed,
27
- },
28
- },
29
- text: {
30
- icon: {
31
- secondaryHover: tokens.color.blue,
32
- },
33
- },
34
- },
35
- border: {
36
- radius: {
37
- default: tokens.border.radius.xLarge_12,
38
- small: tokens.border.radius.large_6,
39
- large: tokens.border.radius.xLarge_12,
40
- },
41
- width: {
42
- focused: tokens.border.width.hairline,
43
- },
44
- },
45
- margin: {
46
- icon: {
47
- // Bring the icons closer to the edges of the button.
48
- offset: -tokens.spacing.xSmall_8,
49
- },
50
- },
51
- font: {
52
- weight: {
53
- default: tokens.font.weight.regular,
54
- },
55
- },
56
- });
57
-
58
- export default theme;
@@ -1,43 +0,0 @@
1
- import * as React from "react";
2
- import {
3
- createThemeContext,
4
- Themes,
5
- ThemeSwitcherContext,
6
- } from "@khanacademy/wonder-blocks-theming";
7
-
8
- import defaultTheme from "./default";
9
- import khanmigoTheme from "./khanmigo";
10
-
11
- type Props = {
12
- children: React.ReactNode;
13
- };
14
-
15
- export type ButtonThemeContract = typeof defaultTheme;
16
-
17
- /**
18
- * The themes available to the Button component.
19
- */
20
- const themes: Themes<ButtonThemeContract> = {
21
- default: defaultTheme,
22
- khanmigo: khanmigoTheme,
23
- };
24
-
25
- /**
26
- * The context that provides the theme to the Button component.
27
- * This is generally consumed via the `useScopedTheme` hook.
28
- */
29
- export const ButtonThemeContext = createThemeContext(defaultTheme);
30
-
31
- /**
32
- * ThemedButton is a component that provides a theme to the <Button/> component.
33
- */
34
- export default function ThemedButton(props: Props) {
35
- const currentTheme = React.useContext(ThemeSwitcherContext);
36
-
37
- const theme = themes[currentTheme] || defaultTheme;
38
- return (
39
- <ButtonThemeContext.Provider value={theme}>
40
- {props.children}
41
- </ButtonThemeContext.Provider>
42
- );
43
- }
@@ -1,17 +0,0 @@
1
- {
2
- "exclude": ["dist"],
3
- "extends": "../tsconfig-shared.json",
4
- "compilerOptions": {
5
- "outDir": "./dist",
6
- "rootDir": "src",
7
- },
8
- "references": [
9
- {"path": "../wonder-blocks-clickable/tsconfig-build.json"},
10
- {"path": "../wonder-blocks-core/tsconfig-build.json"},
11
- {"path": "../wonder-blocks-icon/tsconfig-build.json"},
12
- {"path": "../wonder-blocks-progress-spinner/tsconfig-build.json"},
13
- {"path": "../wonder-blocks-theming/tsconfig-build.json"},
14
- {"path": "../wonder-blocks-tokens/tsconfig-build.json"},
15
- {"path": "../wonder-blocks-typography/tsconfig-build.json"},
16
- ]
17
- }