@khanacademy/wonder-blocks-clickable 2.2.5 → 2.2.6
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 +6 -0
- package/dist/es/index.js +14 -206
- package/package.json +3 -3
- package/src/components/clickable-behavior.js +1 -0
- package/src/components/clickable.js +4 -0
package/CHANGELOG.md
CHANGED
package/dist/es/index.js
CHANGED
|
@@ -9,13 +9,11 @@ import Color from '@khanacademy/wonder-blocks-color';
|
|
|
9
9
|
|
|
10
10
|
const getAppropriateTriggersForRole = role => {
|
|
11
11
|
switch (role) {
|
|
12
|
-
// Triggers on ENTER, but not SPACE
|
|
13
12
|
case "link":
|
|
14
13
|
return {
|
|
15
14
|
triggerOnEnter: true,
|
|
16
15
|
triggerOnSpace: false
|
|
17
16
|
};
|
|
18
|
-
// Triggers on SPACE, but not ENTER
|
|
19
17
|
|
|
20
18
|
case "checkbox":
|
|
21
19
|
case "radio":
|
|
@@ -25,7 +23,6 @@ const getAppropriateTriggersForRole = role => {
|
|
|
25
23
|
triggerOnEnter: false,
|
|
26
24
|
triggerOnSpace: true
|
|
27
25
|
};
|
|
28
|
-
// Triggers on both ENTER and SPACE
|
|
29
26
|
|
|
30
27
|
case "button":
|
|
31
28
|
case "menuitem":
|
|
@@ -50,8 +47,6 @@ const disabledHandlers = {
|
|
|
50
47
|
onTouchCancel: () => void 0,
|
|
51
48
|
onKeyDown: () => void 0,
|
|
52
49
|
onKeyUp: () => void 0,
|
|
53
|
-
// Clickable components should still be tabbable so they can
|
|
54
|
-
// be used as anchors.
|
|
55
50
|
tabIndex: 0
|
|
56
51
|
};
|
|
57
52
|
const keyCodes = {
|
|
@@ -64,95 +59,13 @@ const startState = {
|
|
|
64
59
|
pressed: false,
|
|
65
60
|
waiting: false
|
|
66
61
|
};
|
|
67
|
-
/**
|
|
68
|
-
* Add hover, focus, and active status updates to a clickable component.
|
|
69
|
-
*
|
|
70
|
-
* Via mouse:
|
|
71
|
-
*
|
|
72
|
-
* 1. Hover over button -> hover state
|
|
73
|
-
* 2. Mouse down -> active state
|
|
74
|
-
* 3. Mouse up -> default state
|
|
75
|
-
* 4. Press tab -> focus state
|
|
76
|
-
*
|
|
77
|
-
* Via touch:
|
|
78
|
-
*
|
|
79
|
-
* 1. Touch down -> press state
|
|
80
|
-
* 2. Touch up -> default state
|
|
81
|
-
*
|
|
82
|
-
* Via keyboard:
|
|
83
|
-
*
|
|
84
|
-
* 1. Tab to focus -> focus state
|
|
85
|
-
* 2. Keydown (spacebar/enter) -> active state
|
|
86
|
-
* 3. Keyup (spacebar/enter) -> focus state
|
|
87
|
-
*
|
|
88
|
-
* Warning: The event handlers returned (onClick, onMouseEnter, onMouseLeave,
|
|
89
|
-
* onMouseDown, onMouseUp, onDragStart, onTouchStart, onTouchEnd, onTouchCancel, onKeyDown,
|
|
90
|
-
* onKeyUp, onFocus, onBlur, tabIndex) should be passed on to the component
|
|
91
|
-
* that has the ClickableBehavior. You cannot override these handlers without
|
|
92
|
-
* potentially breaking the functionality of ClickableBehavior.
|
|
93
|
-
*
|
|
94
|
-
* There are internal props triggerOnEnter and triggerOnSpace that can be set
|
|
95
|
-
* to false if one of those keys shouldn't count as a click on this component.
|
|
96
|
-
* Be careful about setting those to false -- make certain that the component
|
|
97
|
-
* shouldn't process that key.
|
|
98
|
-
*
|
|
99
|
-
* See [this document](https://docs.google.com/document/d/1DG5Rg2f0cawIL5R8UqnPQpd7pbdObk8OyjO5ryYQmBM/edit#)
|
|
100
|
-
* for a more thorough explanation of expected behaviors and potential cavaets.
|
|
101
|
-
*
|
|
102
|
-
* `ClickableBehavior` accepts a function as `children` which is passed state
|
|
103
|
-
* and an object containing event handlers and some other props. The `children`
|
|
104
|
-
* function should return a clickable React Element of some sort.
|
|
105
|
-
*
|
|
106
|
-
* Example:
|
|
107
|
-
*
|
|
108
|
-
* ```js
|
|
109
|
-
* class MyClickableComponent extends React.Component<Props> {
|
|
110
|
-
* render(): React.Node {
|
|
111
|
-
* const ClickableBehavior = getClickableBehavior();
|
|
112
|
-
* return <ClickableBehavior
|
|
113
|
-
* disabled={this.props.disabled}
|
|
114
|
-
* onClick={this.props.onClick}
|
|
115
|
-
* >
|
|
116
|
-
* {({hovered}, childrenProps) =>
|
|
117
|
-
* <RoundRect
|
|
118
|
-
* textcolor='white'
|
|
119
|
-
* backgroundColor={hovered ? 'red' : 'blue'}}
|
|
120
|
-
* {...childrenProps}
|
|
121
|
-
* >
|
|
122
|
-
* {this.props.children}
|
|
123
|
-
* </RoundRect>
|
|
124
|
-
* }
|
|
125
|
-
* </ClickableBehavior>
|
|
126
|
-
* }
|
|
127
|
-
* }
|
|
128
|
-
* ```
|
|
129
|
-
*
|
|
130
|
-
* This follows a pattern called [Function as Child Components]
|
|
131
|
-
* (https://medium.com/merrickchristensen/function-as-child-components-5f3920a9ace9).
|
|
132
|
-
*
|
|
133
|
-
* WARNING: Do not use this component directly, use getClickableBehavior
|
|
134
|
-
* instead. getClickableBehavior takes three arguments (href, directtNav, and
|
|
135
|
-
* router) and returns either the default ClickableBehavior or a react-router
|
|
136
|
-
* aware version.
|
|
137
|
-
*
|
|
138
|
-
* The react-router aware version is returned if `router` is a react-router-dom
|
|
139
|
-
* router, `skipClientNav` is not `true`, and `href` is an internal URL.
|
|
140
|
-
*
|
|
141
|
-
* The `router` can be accessed via __RouterContext (imported from 'react-router')
|
|
142
|
-
* from a component rendered as a descendant of a BrowserRouter.
|
|
143
|
-
* See https://reacttraining.com/react-router/web/guides/basic-components.
|
|
144
|
-
*/
|
|
145
|
-
|
|
146
62
|
class ClickableBehavior extends React.Component {
|
|
147
63
|
static getDerivedStateFromProps(props, state) {
|
|
148
|
-
// If new props are disabled, reset the hovered/pressed states
|
|
149
64
|
if (props.disabled) {
|
|
150
|
-
// Keep the focused state for enabling keyboard navigation.
|
|
151
65
|
return _extends({}, startState, {
|
|
152
66
|
focused: state.focused
|
|
153
67
|
});
|
|
154
68
|
} else {
|
|
155
|
-
// Cannot return undefined
|
|
156
69
|
return null;
|
|
157
70
|
}
|
|
158
71
|
}
|
|
@@ -179,7 +92,6 @@ class ClickableBehavior extends React.Component {
|
|
|
179
92
|
};
|
|
180
93
|
|
|
181
94
|
this.handleMouseEnter = e => {
|
|
182
|
-
// When the left button is pressed already, we want it to be pressed
|
|
183
95
|
if (e.buttons === 1) {
|
|
184
96
|
this.dragging = true;
|
|
185
97
|
this.setState({
|
|
@@ -263,17 +175,11 @@ class ClickableBehavior extends React.Component {
|
|
|
263
175
|
} = getAppropriateTriggersForRole(role);
|
|
264
176
|
|
|
265
177
|
if (triggerOnEnter && keyCode === keyCodes.enter || triggerOnSpace && keyCode === keyCodes.space) {
|
|
266
|
-
// This prevents space from scrolling down. It also prevents the
|
|
267
|
-
// space and enter keys from triggering click events. We manually
|
|
268
|
-
// call the supplied onClick and handle potential navigation in
|
|
269
|
-
// handleKeyUp instead.
|
|
270
178
|
e.preventDefault();
|
|
271
179
|
this.setState({
|
|
272
180
|
pressed: true
|
|
273
181
|
});
|
|
274
182
|
} else if (!triggerOnEnter && keyCode === keyCodes.enter) {
|
|
275
|
-
// If the component isn't supposed to trigger on enter, we have to
|
|
276
|
-
// keep track of the enter keydown to negate the onClick callback
|
|
277
183
|
this.enterClick = true;
|
|
278
184
|
}
|
|
279
185
|
};
|
|
@@ -345,8 +251,7 @@ class ClickableBehavior extends React.Component {
|
|
|
345
251
|
waiting: false
|
|
346
252
|
});
|
|
347
253
|
} else {
|
|
348
|
-
window.location.assign(href);
|
|
349
|
-
// load navigation will do that for us by loading a new page.
|
|
254
|
+
window.location.assign(href);
|
|
350
255
|
}
|
|
351
256
|
}
|
|
352
257
|
} else {
|
|
@@ -363,15 +268,11 @@ class ClickableBehavior extends React.Component {
|
|
|
363
268
|
} = this.props;
|
|
364
269
|
|
|
365
270
|
if (history && !skipClientNav || this.props.target === "_blank") {
|
|
366
|
-
// client-side nav
|
|
367
271
|
safeWithNav();
|
|
368
272
|
this.navigateOrReset(shouldNavigate);
|
|
369
273
|
return Promise.resolve();
|
|
370
274
|
} else {
|
|
371
275
|
if (!this.state.waiting) {
|
|
372
|
-
// We only show the spinner for safeWithNav when doing
|
|
373
|
-
// a full page load navigation since since the spinner is
|
|
374
|
-
// indicating that we're waiting for navigation to occur.
|
|
375
276
|
this.setState({
|
|
376
277
|
waiting: true
|
|
377
278
|
});
|
|
@@ -379,19 +280,13 @@ class ClickableBehavior extends React.Component {
|
|
|
379
280
|
|
|
380
281
|
return safeWithNav().then(() => {
|
|
381
282
|
if (!this.state.waiting) {
|
|
382
|
-
// We only show the spinner for safeWithNav when doing
|
|
383
|
-
// a full page load navigation since since the spinner is
|
|
384
|
-
// indicating that we're waiting for navigation to occur.
|
|
385
283
|
this.setState({
|
|
386
284
|
waiting: true
|
|
387
285
|
});
|
|
388
286
|
}
|
|
389
287
|
|
|
390
288
|
return;
|
|
391
|
-
}).catch(error => {
|
|
392
|
-
// navigate when using safeWithNav regardless of
|
|
393
|
-
// whether we're doing a client-side nav or not.
|
|
394
|
-
}).finally(() => {
|
|
289
|
+
}).catch(error => {}).finally(() => {
|
|
395
290
|
this.navigateOrReset(shouldNavigate);
|
|
396
291
|
});
|
|
397
292
|
}
|
|
@@ -410,9 +305,7 @@ class ClickableBehavior extends React.Component {
|
|
|
410
305
|
|
|
411
306
|
if (onClick) {
|
|
412
307
|
onClick(e);
|
|
413
|
-
}
|
|
414
|
-
// navigate.
|
|
415
|
-
|
|
308
|
+
}
|
|
416
309
|
|
|
417
310
|
if (e.defaultPrevented) {
|
|
418
311
|
shouldNavigate = false;
|
|
@@ -426,20 +319,12 @@ class ClickableBehavior extends React.Component {
|
|
|
426
319
|
|
|
427
320
|
while (target) {
|
|
428
321
|
if (target instanceof window.HTMLFormElement) {
|
|
429
|
-
// This event must be marked as cancelable otherwise calling
|
|
430
|
-
// e.preventDefault() on it won't do anything in Firefox.
|
|
431
|
-
// Chrome and Safari allow calling e.preventDefault() on
|
|
432
|
-
// non-cancelable events, but really they shouldn't.
|
|
433
322
|
const event = new window.Event("submit", {
|
|
434
323
|
cancelable: true
|
|
435
324
|
});
|
|
436
325
|
target.dispatchEvent(event);
|
|
437
326
|
break;
|
|
438
|
-
}
|
|
439
|
-
// Updating all of the places will take some time so I'll do
|
|
440
|
-
// this later
|
|
441
|
-
// $FlowFixMe[prop-missing]
|
|
442
|
-
|
|
327
|
+
}
|
|
443
328
|
|
|
444
329
|
target = target.parentElement;
|
|
445
330
|
}
|
|
@@ -465,7 +350,6 @@ class ClickableBehavior extends React.Component {
|
|
|
465
350
|
|
|
466
351
|
render() {
|
|
467
352
|
const childrenProps = this.props.disabled ? _extends({}, disabledHandlers, {
|
|
468
|
-
// Keep these handlers for keyboard accessibility.
|
|
469
353
|
onFocus: this.handleFocus,
|
|
470
354
|
onBlur: this.handleBlur
|
|
471
355
|
}) : {
|
|
@@ -482,15 +366,8 @@ class ClickableBehavior extends React.Component {
|
|
|
482
366
|
onKeyUp: this.handleKeyUp,
|
|
483
367
|
onFocus: this.handleFocus,
|
|
484
368
|
onBlur: this.handleBlur,
|
|
485
|
-
// We set tabIndex to 0 so that users can tab to clickable
|
|
486
|
-
// things that aren't buttons or anchors.
|
|
487
369
|
tabIndex: 0
|
|
488
|
-
};
|
|
489
|
-
// `rel` attributes. This is to ensure that the links we're sending folks
|
|
490
|
-
// to can't hijack the existing page. These defaults can be overriden
|
|
491
|
-
// by passing in a different value for the `rel` prop.
|
|
492
|
-
// More info: https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/
|
|
493
|
-
|
|
370
|
+
};
|
|
494
371
|
childrenProps.rel = this.props.rel || (this.props.target === "_blank" ? "noopener noreferrer" : undefined);
|
|
495
372
|
const {
|
|
496
373
|
children
|
|
@@ -503,12 +380,6 @@ ClickableBehavior.defaultProps = {
|
|
|
503
380
|
disabled: false
|
|
504
381
|
};
|
|
505
382
|
|
|
506
|
-
/**
|
|
507
|
-
* Returns:
|
|
508
|
-
* - false for hrefs staring with http://, https://, //.
|
|
509
|
-
* - false for '#', 'javascript:...', 'mailto:...', 'tel:...', etc.
|
|
510
|
-
* - true for all other values, e.g. /foo/bar
|
|
511
|
-
*/
|
|
512
383
|
const isClientSideUrl = href => {
|
|
513
384
|
if (typeof href !== "string") {
|
|
514
385
|
return false;
|
|
@@ -517,35 +388,9 @@ const isClientSideUrl = href => {
|
|
|
517
388
|
return !/^(https?:)?\/\//i.test(href) && !/^([^#]*#[\w-]*|[\w\-.]+:)/.test(href);
|
|
518
389
|
};
|
|
519
390
|
|
|
520
|
-
/**
|
|
521
|
-
* Returns either the default ClickableBehavior or a react-router aware version.
|
|
522
|
-
*
|
|
523
|
-
* The react-router aware version is returned if `router` is a react-router-dom
|
|
524
|
-
* router, `skipClientNav` is not `true`, and `href` is an internal URL.
|
|
525
|
-
*
|
|
526
|
-
* The `router` can be accessed via __RouterContext (imported from 'react-router')
|
|
527
|
-
* from a component rendered as a descendant of a BrowserRouter.
|
|
528
|
-
* See https://reacttraining.com/react-router/web/guides/basic-components.
|
|
529
|
-
*/
|
|
530
391
|
const ClickableBehaviorWithRouter = withRouter(ClickableBehavior);
|
|
531
|
-
function getClickableBehavior(
|
|
532
|
-
/**
|
|
533
|
-
* The URL to navigate to.
|
|
534
|
-
*/
|
|
535
|
-
href,
|
|
536
|
-
/**
|
|
537
|
-
* Should we skip using the react router and go to the page directly.
|
|
538
|
-
*/
|
|
539
|
-
skipClientNav,
|
|
540
|
-
/**
|
|
541
|
-
* router object added to the React context object by react-router-dom.
|
|
542
|
-
*/
|
|
543
|
-
router) {
|
|
392
|
+
function getClickableBehavior(href, skipClientNav, router) {
|
|
544
393
|
if (router && skipClientNav !== true && href && isClientSideUrl(href)) {
|
|
545
|
-
// We cast to `any` here since the type of ClickableBehaviorWithRouter
|
|
546
|
-
// is slightly different from the return type of this function.
|
|
547
|
-
// TODO(WB-1037): Always return the wrapped version once all routes have
|
|
548
|
-
// been ported to the app-shell in webapp.
|
|
549
394
|
return ClickableBehaviorWithRouter;
|
|
550
395
|
}
|
|
551
396
|
|
|
@@ -556,56 +401,30 @@ const _excluded = ["href", "onClick", "skipClientNav", "beforeNav", "safeWithNav
|
|
|
556
401
|
const StyledAnchor = addStyle("a");
|
|
557
402
|
const StyledButton = addStyle("button");
|
|
558
403
|
const StyledLink = addStyle(Link);
|
|
559
|
-
/**
|
|
560
|
-
* A component to turn any custom component into a clickable one.
|
|
561
|
-
*
|
|
562
|
-
* Works by wrapping ClickableBehavior around the child element and styling the
|
|
563
|
-
* child appropriately and encapsulates routing logic which can be customized.
|
|
564
|
-
* Expects a function which returns an element as it's child.
|
|
565
|
-
*
|
|
566
|
-
* Example usage:
|
|
567
|
-
* ```jsx
|
|
568
|
-
* <Clickable onClick={() => alert("You clicked me!")}>
|
|
569
|
-
* {({hovered, focused, pressed}) =>
|
|
570
|
-
* <div
|
|
571
|
-
* style={[
|
|
572
|
-
* hovered && styles.hovered,
|
|
573
|
-
* focused && styles.focused,
|
|
574
|
-
* pressed && styles.pressed,
|
|
575
|
-
* ]}
|
|
576
|
-
* >
|
|
577
|
-
* Click Me!
|
|
578
|
-
* </div>
|
|
579
|
-
* }
|
|
580
|
-
* </Clickable>
|
|
581
|
-
* ```
|
|
582
|
-
*/
|
|
583
|
-
|
|
584
404
|
class Clickable extends React.Component {
|
|
585
405
|
constructor(...args) {
|
|
586
406
|
super(...args);
|
|
587
407
|
|
|
588
408
|
this.getCorrectTag = (clickableState, router, commonProps) => {
|
|
589
409
|
const activeHref = this.props.href && !this.props.disabled;
|
|
590
|
-
const useClient = router && !this.props.skipClientNav && isClientSideUrl(this.props.href || "");
|
|
591
|
-
// needs it to refine this.props.href to a string.
|
|
410
|
+
const useClient = router && !this.props.skipClientNav && isClientSideUrl(this.props.href || "");
|
|
592
411
|
|
|
593
412
|
if (activeHref && useClient && this.props.href) {
|
|
594
|
-
return
|
|
413
|
+
return React.createElement(StyledLink, _extends({}, commonProps, {
|
|
595
414
|
to: this.props.href,
|
|
596
415
|
role: this.props.role,
|
|
597
416
|
target: this.props.target || undefined,
|
|
598
417
|
"aria-disabled": this.props.disabled ? "true" : undefined
|
|
599
418
|
}), this.props.children(clickableState));
|
|
600
419
|
} else if (activeHref && !useClient) {
|
|
601
|
-
return
|
|
420
|
+
return React.createElement(StyledAnchor, _extends({}, commonProps, {
|
|
602
421
|
href: this.props.href,
|
|
603
422
|
role: this.props.role,
|
|
604
423
|
target: this.props.target || undefined,
|
|
605
424
|
"aria-disabled": this.props.disabled ? "true" : undefined
|
|
606
425
|
}), this.props.children(clickableState));
|
|
607
426
|
} else {
|
|
608
|
-
return
|
|
427
|
+
return React.createElement(StyledButton, _extends({}, commonProps, {
|
|
609
428
|
type: "button",
|
|
610
429
|
"aria-disabled": this.props.disabled
|
|
611
430
|
}), this.props.children(clickableState));
|
|
@@ -637,7 +456,7 @@ class Clickable extends React.Component {
|
|
|
637
456
|
const getStyle = state => [styles.reset, styles.link, !hideDefaultFocusRing && state.focused && (light ? styles.focusedLight : styles.focused), style];
|
|
638
457
|
|
|
639
458
|
if (beforeNav) {
|
|
640
|
-
return
|
|
459
|
+
return React.createElement(ClickableBehavior, {
|
|
641
460
|
href: href,
|
|
642
461
|
onClick: onClick,
|
|
643
462
|
beforeNav: beforeNav,
|
|
@@ -650,7 +469,7 @@ class Clickable extends React.Component {
|
|
|
650
469
|
style: getStyle(state)
|
|
651
470
|
}, childrenProps)));
|
|
652
471
|
} else {
|
|
653
|
-
return
|
|
472
|
+
return React.createElement(ClickableBehavior, {
|
|
654
473
|
href: href,
|
|
655
474
|
onClick: onClick,
|
|
656
475
|
safeWithNav: safeWithNav,
|
|
@@ -666,11 +485,10 @@ class Clickable extends React.Component {
|
|
|
666
485
|
}
|
|
667
486
|
|
|
668
487
|
render() {
|
|
669
|
-
return
|
|
488
|
+
return React.createElement(__RouterContext.Consumer, null, router => this.renderClickableBehavior(router));
|
|
670
489
|
}
|
|
671
490
|
|
|
672
|
-
}
|
|
673
|
-
|
|
491
|
+
}
|
|
674
492
|
Clickable.defaultProps = {
|
|
675
493
|
light: false,
|
|
676
494
|
disabled: false,
|
|
@@ -685,23 +503,13 @@ const styles = StyleSheet.create({
|
|
|
685
503
|
overflow: "visible",
|
|
686
504
|
background: "transparent",
|
|
687
505
|
textDecoration: "none",
|
|
688
|
-
|
|
689
|
-
/* inherit font & color from ancestor */
|
|
690
506
|
color: "inherit",
|
|
691
507
|
font: "inherit",
|
|
692
508
|
boxSizing: "border-box",
|
|
693
|
-
// This removes the 300ms click delay on mobile browsers by indicating that
|
|
694
|
-
// "double-tap to zoom" shouldn't be used on this element.
|
|
695
509
|
touchAction: "manipulation",
|
|
696
510
|
userSelect: "none",
|
|
697
|
-
// This is usual frowned upon b/c of accessibility. We expect users of Clickable
|
|
698
|
-
// to define their own focus styles.
|
|
699
511
|
outline: "none",
|
|
700
|
-
|
|
701
|
-
/* Normalize `line-height`. Cannot be changed from `normal` in Firefox 4+. */
|
|
702
512
|
lineHeight: "normal",
|
|
703
|
-
|
|
704
|
-
/* Corrects font smoothing for webkit */
|
|
705
513
|
WebkitFontSmoothing: "inherit",
|
|
706
514
|
MozOsxFontSmoothing: "inherit"
|
|
707
515
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@khanacademy/wonder-blocks-clickable",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.6",
|
|
4
4
|
"design": "v1",
|
|
5
5
|
"description": "Clickable component for Wonder-Blocks.",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@babel/runtime": "^7.16.3",
|
|
19
|
-
"@khanacademy/wonder-blocks-core": "^4.3.
|
|
19
|
+
"@khanacademy/wonder-blocks-core": "^4.3.1"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
22
|
"aphrodite": "^1.2.5",
|
|
@@ -26,6 +26,6 @@
|
|
|
26
26
|
"react-router-dom": "5.3.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"wb-dev-build-settings": "^0.
|
|
29
|
+
"wb-dev-build-settings": "^0.4.0"
|
|
30
30
|
}
|
|
31
31
|
}
|
|
@@ -111,6 +111,8 @@ type Props =
|
|
|
111
111
|
|
|
112
112
|
/**
|
|
113
113
|
* A target destination window for a link to open in.
|
|
114
|
+
*
|
|
115
|
+
* TODO(WB-1262): only allow this prop when `href` is also set.t
|
|
114
116
|
*/
|
|
115
117
|
target?: "_blank",
|
|
116
118
|
|}
|
|
@@ -143,6 +145,8 @@ type Props =
|
|
|
143
145
|
|
|
144
146
|
/**
|
|
145
147
|
* A target destination window for a link to open in.
|
|
148
|
+
*
|
|
149
|
+
* TODO(WB-1262): only allow this prop when `href` is also set.t
|
|
146
150
|
*/
|
|
147
151
|
target?: "_blank",
|
|
148
152
|
|}
|