@khanacademy/wonder-blocks-link 4.4.0 → 5.0.1
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 +24 -0
- package/dist/components/link-core.d.ts +5 -866
- package/dist/components/link.d.ts +22 -165
- package/package.json +6 -6
- package/src/components/__tests__/link.typestest.tsx +9 -4
- package/src/components/link.tsx +32 -23
- package/tsconfig-build.tsbuildinfo +1 -1
- package/dist/components/link-core.js.flow +0 -2842
- package/dist/components/link.js.flow +0 -376
- package/dist/index.js.flow +0 -8
|
@@ -3,7 +3,7 @@ import { Link as ReactRouterLink } from "react-router-dom";
|
|
|
3
3
|
import type { AriaProps, StyleType } from "@khanacademy/wonder-blocks-core";
|
|
4
4
|
import Icon from "@khanacademy/wonder-blocks-icon";
|
|
5
5
|
import type { Typography } from "@khanacademy/wonder-blocks-typography";
|
|
6
|
-
|
|
6
|
+
type CommonProps = AriaProps & {
|
|
7
7
|
/**
|
|
8
8
|
* Text to appear on the link. It can be a plain text or a Typography element.
|
|
9
9
|
*/
|
|
@@ -96,6 +96,22 @@ export type SharedProps = AriaProps & {
|
|
|
96
96
|
* Respond to raw "keyup" event.
|
|
97
97
|
*/
|
|
98
98
|
onKeyUp?: (e: React.KeyboardEvent) => unknown;
|
|
99
|
+
/**
|
|
100
|
+
* An optional title attribute.
|
|
101
|
+
*/
|
|
102
|
+
title?: string;
|
|
103
|
+
/**
|
|
104
|
+
* An optional icon displayed before the link label.
|
|
105
|
+
*/
|
|
106
|
+
startIcon?: React.ReactElement<typeof Icon>;
|
|
107
|
+
/**
|
|
108
|
+
* An optional icon displayed after the link label.
|
|
109
|
+
* If `target="_blank"` and `endIcon` is passed in, `endIcon` will override
|
|
110
|
+
* the default `externalIcon`.
|
|
111
|
+
*/
|
|
112
|
+
endIcon?: React.ReactElement<typeof Icon>;
|
|
113
|
+
};
|
|
114
|
+
export type SharedProps = (CommonProps & {
|
|
99
115
|
/**
|
|
100
116
|
* A target destination window for a link to open in. We only support
|
|
101
117
|
* "_blank" which opens the URL in a new tab.
|
|
@@ -103,6 +119,8 @@ export type SharedProps = AriaProps & {
|
|
|
103
119
|
* TODO(WB-1262): only allow this prop when `href` is also set.t
|
|
104
120
|
*/
|
|
105
121
|
target?: "_blank";
|
|
122
|
+
beforeNav?: never;
|
|
123
|
+
}) | (CommonProps & {
|
|
106
124
|
/**
|
|
107
125
|
* Run async code before navigating to the URL passed to `href`. If the
|
|
108
126
|
* promise returned rejects then navigation will not occur.
|
|
@@ -117,21 +135,8 @@ export type SharedProps = AriaProps & {
|
|
|
117
135
|
* navigation.
|
|
118
136
|
*/
|
|
119
137
|
beforeNav?: () => Promise<unknown>;
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
*/
|
|
123
|
-
title?: string;
|
|
124
|
-
/**
|
|
125
|
-
* An optional icon displayed before the link label.
|
|
126
|
-
*/
|
|
127
|
-
startIcon?: React.ReactElement<typeof Icon>;
|
|
128
|
-
/**
|
|
129
|
-
* An optional icon displayed after the link label.
|
|
130
|
-
* If `target="_blank"` and `endIcon` is passed in, `endIcon` will override
|
|
131
|
-
* the default `externalIcon`.
|
|
132
|
-
*/
|
|
133
|
-
endIcon?: React.ReactElement<typeof Icon>;
|
|
134
|
-
};
|
|
138
|
+
target?: never;
|
|
139
|
+
});
|
|
135
140
|
/**
|
|
136
141
|
* Reusable link component.
|
|
137
142
|
*
|
|
@@ -150,153 +155,5 @@ export type SharedProps = AriaProps & {
|
|
|
150
155
|
* </Link>
|
|
151
156
|
* ```
|
|
152
157
|
*/
|
|
153
|
-
declare const Link: React.ForwardRefExoticComponent<
|
|
154
|
-
role?: import("../../../wonder-blocks-core/src/util/aria-types").AriaRole | undefined;
|
|
155
|
-
}> & {
|
|
156
|
-
/**
|
|
157
|
-
* Text to appear on the link. It can be a plain text or a Typography element.
|
|
158
|
-
*/
|
|
159
|
-
children: string | React.ReactElement<React.ComponentProps<Typography>>;
|
|
160
|
-
/**
|
|
161
|
-
* URL to navigate to.
|
|
162
|
-
*/
|
|
163
|
-
href: string;
|
|
164
|
-
/**
|
|
165
|
-
* An optional id attribute.
|
|
166
|
-
*/
|
|
167
|
-
id?: string | undefined;
|
|
168
|
-
/**
|
|
169
|
-
* Indicates that this link is used within a body of text.
|
|
170
|
-
* This styles the link with an underline to distinguish it
|
|
171
|
-
* from surrounding text.
|
|
172
|
-
*/
|
|
173
|
-
inline?: boolean | undefined;
|
|
174
|
-
/**
|
|
175
|
-
* Kind of Link. Note: Secondary light Links are not supported.
|
|
176
|
-
*/
|
|
177
|
-
kind?: "primary" | "secondary" | undefined;
|
|
178
|
-
/**
|
|
179
|
-
* Whether the button is on a dark/colored background.
|
|
180
|
-
*/
|
|
181
|
-
light?: boolean | undefined;
|
|
182
|
-
/**
|
|
183
|
-
* Whether the link should change color once it's visited.
|
|
184
|
-
* secondary or primary (light) links are not allowed to be visitable.
|
|
185
|
-
*/
|
|
186
|
-
visitable?: boolean | undefined;
|
|
187
|
-
/**
|
|
188
|
-
* Specifies the type of relationship between the current document and the
|
|
189
|
-
* linked document. Should only be used when `href` is specified. This
|
|
190
|
-
* defaults to "noopener noreferrer" when `target="_blank"`, but can be
|
|
191
|
-
* overridden by setting this prop to something else.
|
|
192
|
-
*/
|
|
193
|
-
rel?: string | undefined;
|
|
194
|
-
/**
|
|
195
|
-
* Set the tabindex attribute on the rendered element.
|
|
196
|
-
*/
|
|
197
|
-
tabIndex?: number | undefined;
|
|
198
|
-
/**
|
|
199
|
-
* Test ID used for e2e testing.
|
|
200
|
-
*/
|
|
201
|
-
testId?: string | undefined;
|
|
202
|
-
/**
|
|
203
|
-
* Whether to avoid using client-side navigation.
|
|
204
|
-
*
|
|
205
|
-
* If the URL passed to href is local to the client-side, e.g.
|
|
206
|
-
* /math/algebra/eval-exprs, then it tries to use react-router-dom's Link
|
|
207
|
-
* component which handles the client-side navigation. You can set
|
|
208
|
-
* `skipClientNav` to true avoid using client-side nav entirely.
|
|
209
|
-
*
|
|
210
|
-
* NOTE: All URLs containing a protocol are considered external, e.g.
|
|
211
|
-
* https://khanacademy.org/math/algebra/eval-exprs will trigger a full
|
|
212
|
-
* page reload.
|
|
213
|
-
*/
|
|
214
|
-
skipClientNav?: boolean | undefined;
|
|
215
|
-
/**
|
|
216
|
-
* Custom styles.
|
|
217
|
-
*/
|
|
218
|
-
style?: StyleType;
|
|
219
|
-
/**
|
|
220
|
-
* Adds CSS classes to the Link.
|
|
221
|
-
*/
|
|
222
|
-
className?: string | undefined;
|
|
223
|
-
/**
|
|
224
|
-
* Function to call when button is clicked.
|
|
225
|
-
*
|
|
226
|
-
* This callback should be used for things like marking BigBingo
|
|
227
|
-
* conversions. It should NOT be used to redirect to a different URL or to
|
|
228
|
-
* prevent navigation via e.preventDefault(). The event passed to this
|
|
229
|
-
* handler will have its preventDefault() and stopPropagation() methods
|
|
230
|
-
* stubbed out.
|
|
231
|
-
*/
|
|
232
|
-
onClick?: ((e: React.SyntheticEvent) => unknown) | undefined;
|
|
233
|
-
/**
|
|
234
|
-
* Run async code in the background while client-side navigating. If the
|
|
235
|
-
* browser does a full page load navigation, the callback promise must be
|
|
236
|
-
* settled before the navigation will occur. Errors are ignored so that
|
|
237
|
-
* navigation is guaranteed to succeed.
|
|
238
|
-
*/
|
|
239
|
-
safeWithNav?: (() => Promise<unknown>) | undefined;
|
|
240
|
-
/**
|
|
241
|
-
* Respond to raw "keydown" event.
|
|
242
|
-
*/
|
|
243
|
-
onKeyDown?: ((e: React.KeyboardEvent) => unknown) | undefined;
|
|
244
|
-
/**
|
|
245
|
-
* Respond to raw "keyup" event.
|
|
246
|
-
*/
|
|
247
|
-
onKeyUp?: ((e: React.KeyboardEvent) => unknown) | undefined;
|
|
248
|
-
/**
|
|
249
|
-
* A target destination window for a link to open in. We only support
|
|
250
|
-
* "_blank" which opens the URL in a new tab.
|
|
251
|
-
*
|
|
252
|
-
* TODO(WB-1262): only allow this prop when `href` is also set.t
|
|
253
|
-
*/
|
|
254
|
-
target?: "_blank" | undefined;
|
|
255
|
-
/**
|
|
256
|
-
* Run async code before navigating to the URL passed to `href`. If the
|
|
257
|
-
* promise returned rejects then navigation will not occur.
|
|
258
|
-
*
|
|
259
|
-
* If both safeWithNav and beforeNav are provided, beforeNav will be run
|
|
260
|
-
* first and safeWithNav will only be run if beforeNav does not reject.
|
|
261
|
-
*
|
|
262
|
-
* WARNING: Using this with `target="_blank"` will trigger built-in popup
|
|
263
|
-
* blockers in Firefox and Safari. This is because we do navigation
|
|
264
|
-
* programmatically and `beforeNav` causes a delay which means that the
|
|
265
|
-
* browser can't make a directly link between a user action and the
|
|
266
|
-
* navigation.
|
|
267
|
-
*/
|
|
268
|
-
beforeNav?: (() => Promise<unknown>) | undefined;
|
|
269
|
-
/**
|
|
270
|
-
* An optional title attribute.
|
|
271
|
-
*/
|
|
272
|
-
title?: string | undefined;
|
|
273
|
-
/**
|
|
274
|
-
* An optional icon displayed before the link label.
|
|
275
|
-
*/
|
|
276
|
-
startIcon?: React.ReactElement<React.ForwardRefExoticComponent<Readonly<import("../../../wonder-blocks-core/src/util/aria-types").AriaAttributes> & Readonly<{
|
|
277
|
-
role?: import("../../../wonder-blocks-core/src/util/aria-types").AriaRole | undefined;
|
|
278
|
-
}> & {
|
|
279
|
-
color?: string | undefined;
|
|
280
|
-
icon: import("@khanacademy/wonder-blocks-icon").IconAsset;
|
|
281
|
-
size?: keyof import("@khanacademy/wonder-blocks-icon").IconAsset | undefined;
|
|
282
|
-
style?: StyleType;
|
|
283
|
-
className?: string | undefined;
|
|
284
|
-
testId?: string | undefined;
|
|
285
|
-
} & React.RefAttributes<SVGSVGElement>>, string | React.JSXElementConstructor<any>> | undefined;
|
|
286
|
-
/**
|
|
287
|
-
* An optional icon displayed after the link label.
|
|
288
|
-
* If `target="_blank"` and `endIcon` is passed in, `endIcon` will override
|
|
289
|
-
* the default `externalIcon`.
|
|
290
|
-
*/
|
|
291
|
-
endIcon?: React.ReactElement<React.ForwardRefExoticComponent<Readonly<import("../../../wonder-blocks-core/src/util/aria-types").AriaAttributes> & Readonly<{
|
|
292
|
-
role?: import("../../../wonder-blocks-core/src/util/aria-types").AriaRole | undefined;
|
|
293
|
-
}> & {
|
|
294
|
-
color?: string | undefined;
|
|
295
|
-
icon: import("@khanacademy/wonder-blocks-icon").IconAsset;
|
|
296
|
-
size?: keyof import("@khanacademy/wonder-blocks-icon").IconAsset | undefined;
|
|
297
|
-
style?: StyleType;
|
|
298
|
-
className?: string | undefined;
|
|
299
|
-
testId?: string | undefined;
|
|
300
|
-
} & React.RefAttributes<SVGSVGElement>>, string | React.JSXElementConstructor<any>> | undefined;
|
|
301
|
-
} & React.RefAttributes<HTMLAnchorElement | typeof ReactRouterLink>>;
|
|
158
|
+
declare const Link: React.ForwardRefExoticComponent<SharedProps & React.RefAttributes<HTMLAnchorElement | typeof ReactRouterLink>>;
|
|
302
159
|
export default Link;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@khanacademy/wonder-blocks-link",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.1",
|
|
4
4
|
"design": "v1",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
"license": "MIT",
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@babel/runtime": "^7.18.6",
|
|
19
|
-
"@khanacademy/wonder-blocks-clickable": "^
|
|
19
|
+
"@khanacademy/wonder-blocks-clickable": "^4.0.1",
|
|
20
20
|
"@khanacademy/wonder-blocks-color": "^2.0.1",
|
|
21
|
-
"@khanacademy/wonder-blocks-core": "^
|
|
22
|
-
"@khanacademy/wonder-blocks-icon": "^2.1.
|
|
21
|
+
"@khanacademy/wonder-blocks-core": "^6.0.0",
|
|
22
|
+
"@khanacademy/wonder-blocks-icon": "^2.1.1",
|
|
23
23
|
"@khanacademy/wonder-blocks-spacing": "^4.0.1"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
@@ -29,6 +29,6 @@
|
|
|
29
29
|
"react-router-dom": "5.3.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"wb-dev-build-settings": "^0.
|
|
32
|
+
"@khanacademy/wb-dev-build-settings": "^1.0.0"
|
|
33
33
|
}
|
|
34
|
-
}
|
|
34
|
+
}
|
|
@@ -2,11 +2,11 @@ import * as React from "react";
|
|
|
2
2
|
|
|
3
3
|
import Link from "../link";
|
|
4
4
|
|
|
5
|
-
//
|
|
6
|
-
|
|
5
|
+
// @ts-expect-error - href must be used with safeWithNav
|
|
6
|
+
<Link beforeNav={() => Promise.resolve()}>Hello, world!</Link>;
|
|
7
7
|
|
|
8
|
-
//
|
|
9
|
-
|
|
8
|
+
// @ts-expect-error - href must be used with safeWithNav
|
|
9
|
+
<Link safeWithNav={() => Promise.resolve()}>Hello, world!</Link>;
|
|
10
10
|
|
|
11
11
|
// It's okay to use onClick with href
|
|
12
12
|
<Link href="/foo" onClick={() => {}}>
|
|
@@ -21,6 +21,11 @@ import Link from "../link";
|
|
|
21
21
|
Hello, world!
|
|
22
22
|
</Link>;
|
|
23
23
|
|
|
24
|
+
// @ts-expect-error - `target="_blank"` cannot beused with `beforeNav`
|
|
25
|
+
<Link href="/foo" target="_blank" beforeNav={() => Promise.resolve()}>
|
|
26
|
+
Hello, world!
|
|
27
|
+
</Link>;
|
|
28
|
+
|
|
24
29
|
// All three of these props can be used together
|
|
25
30
|
<Link
|
|
26
31
|
href="/foo"
|
package/src/components/link.tsx
CHANGED
|
@@ -8,8 +8,7 @@ import Icon from "@khanacademy/wonder-blocks-icon";
|
|
|
8
8
|
import type {Typography} from "@khanacademy/wonder-blocks-typography";
|
|
9
9
|
import LinkCore from "./link-core";
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
export type SharedProps = AriaProps & {
|
|
11
|
+
type CommonProps = AriaProps & {
|
|
13
12
|
/**
|
|
14
13
|
* Text to appear on the link. It can be a plain text or a Typography element.
|
|
15
14
|
*/
|
|
@@ -117,27 +116,6 @@ export type SharedProps = AriaProps & {
|
|
|
117
116
|
* Respond to raw "keyup" event.
|
|
118
117
|
*/
|
|
119
118
|
onKeyUp?: (e: React.KeyboardEvent) => unknown;
|
|
120
|
-
/**
|
|
121
|
-
* A target destination window for a link to open in. We only support
|
|
122
|
-
* "_blank" which opens the URL in a new tab.
|
|
123
|
-
*
|
|
124
|
-
* TODO(WB-1262): only allow this prop when `href` is also set.t
|
|
125
|
-
*/
|
|
126
|
-
target?: "_blank";
|
|
127
|
-
/**
|
|
128
|
-
* Run async code before navigating to the URL passed to `href`. If the
|
|
129
|
-
* promise returned rejects then navigation will not occur.
|
|
130
|
-
*
|
|
131
|
-
* If both safeWithNav and beforeNav are provided, beforeNav will be run
|
|
132
|
-
* first and safeWithNav will only be run if beforeNav does not reject.
|
|
133
|
-
*
|
|
134
|
-
* WARNING: Using this with `target="_blank"` will trigger built-in popup
|
|
135
|
-
* blockers in Firefox and Safari. This is because we do navigation
|
|
136
|
-
* programmatically and `beforeNav` causes a delay which means that the
|
|
137
|
-
* browser can't make a directly link between a user action and the
|
|
138
|
-
* navigation.
|
|
139
|
-
*/
|
|
140
|
-
beforeNav?: () => Promise<unknown>;
|
|
141
119
|
/**
|
|
142
120
|
* An optional title attribute.
|
|
143
121
|
*/
|
|
@@ -154,6 +132,37 @@ export type SharedProps = AriaProps & {
|
|
|
154
132
|
endIcon?: React.ReactElement<typeof Icon>;
|
|
155
133
|
};
|
|
156
134
|
|
|
135
|
+
export type SharedProps =
|
|
136
|
+
| (CommonProps & {
|
|
137
|
+
/**
|
|
138
|
+
* A target destination window for a link to open in. We only support
|
|
139
|
+
* "_blank" which opens the URL in a new tab.
|
|
140
|
+
*
|
|
141
|
+
* TODO(WB-1262): only allow this prop when `href` is also set.t
|
|
142
|
+
*/
|
|
143
|
+
target?: "_blank";
|
|
144
|
+
|
|
145
|
+
beforeNav?: never; // disallow beforeNav when target="_blank"
|
|
146
|
+
})
|
|
147
|
+
| (CommonProps & {
|
|
148
|
+
/**
|
|
149
|
+
* Run async code before navigating to the URL passed to `href`. If the
|
|
150
|
+
* promise returned rejects then navigation will not occur.
|
|
151
|
+
*
|
|
152
|
+
* If both safeWithNav and beforeNav are provided, beforeNav will be run
|
|
153
|
+
* first and safeWithNav will only be run if beforeNav does not reject.
|
|
154
|
+
*
|
|
155
|
+
* WARNING: Using this with `target="_blank"` will trigger built-in popup
|
|
156
|
+
* blockers in Firefox and Safari. This is because we do navigation
|
|
157
|
+
* programmatically and `beforeNav` causes a delay which means that the
|
|
158
|
+
* browser can't make a directly link between a user action and the
|
|
159
|
+
* navigation.
|
|
160
|
+
*/
|
|
161
|
+
beforeNav?: () => Promise<unknown>;
|
|
162
|
+
|
|
163
|
+
target?: never; // disallow target="_blank" when using beforeNav
|
|
164
|
+
});
|
|
165
|
+
|
|
157
166
|
/**
|
|
158
167
|
* Reusable link component.
|
|
159
168
|
*
|