@khanacademy/wonder-blocks-link 3.9.1 → 3.9.2

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,30 @@
1
1
  # @khanacademy/wonder-blocks-link
2
2
 
3
+ ## 3.9.2
4
+
5
+ ### Patch Changes
6
+
7
+ - d816af08: Update build and test configs use TypeScript
8
+ - 3891f544: Update babel config to include plugins that Storybook needed
9
+ - 0d28bb1c: Configured TypeScript
10
+ - 3d05f764: Fix HOCs and other type errors
11
+ - c2ec4902: Update eslint configuration, fix lint
12
+ - 2983c05b: Include 'types' field in package.json
13
+ - 77ff6a66: Generate Flow types from TypeScript types
14
+ - ec8d4b7f: Fix miscellaneous TypeScript errors
15
+ - Updated dependencies [d816af08]
16
+ - Updated dependencies [3891f544]
17
+ - Updated dependencies [0d28bb1c]
18
+ - Updated dependencies [873f4a14]
19
+ - Updated dependencies [3d05f764]
20
+ - Updated dependencies [c2ec4902]
21
+ - Updated dependencies [2983c05b]
22
+ - Updated dependencies [77ff6a66]
23
+ - Updated dependencies [ec8d4b7f]
24
+ - @khanacademy/wonder-blocks-clickable@2.4.6
25
+ - @khanacademy/wonder-blocks-color@1.2.2
26
+ - @khanacademy/wonder-blocks-core@4.8.0
27
+
3
28
  ## 3.9.1
4
29
 
5
30
  ### Patch Changes
@@ -0,0 +1,11 @@
1
+ import * as React from "react";
2
+ import type { ChildrenProps, ClickableState } from "@khanacademy/wonder-blocks-clickable";
3
+ import type { SharedProps } from "./link";
4
+ type Props = SharedProps & ChildrenProps & ClickableState & {
5
+ href: string;
6
+ };
7
+ export default class LinkCore extends React.Component<Props> {
8
+ renderInner(router: any): React.ReactNode;
9
+ render(): React.ReactElement;
10
+ }
11
+ export {};
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Flowtype definitions for link-core
3
+ * Generated by Flowgen from a Typescript Definition
4
+ * Flowgen v1.21.0
5
+ * @flow
6
+ */
7
+
8
+ import * as React from "react";
9
+ import type {
10
+ ChildrenProps,
11
+ ClickableState,
12
+ } from "@khanacademy/wonder-blocks-clickable";
13
+ import type { SharedProps } from "./link";
14
+ declare type Props = {
15
+ ...SharedProps,
16
+ ...ChildrenProps,
17
+ ...ClickableState,
18
+ ...{
19
+ href: string,
20
+ ...
21
+ },
22
+ };
23
+ declare export default class LinkCore mixins React.Component<Props> {
24
+ renderInner(router: any): React.Node;
25
+ render(): React.Element<>;
26
+ }
@@ -0,0 +1,148 @@
1
+ import * as React from "react";
2
+ import type { AriaProps, StyleType } from "@khanacademy/wonder-blocks-core";
3
+ import type { Typography } from "@khanacademy/wonder-blocks-typography";
4
+ export type SharedProps = AriaProps & {
5
+ /**
6
+ * Text to appear on the link. It can be a plain text or a Typography element.
7
+ */
8
+ children: string | React.ReactElement<React.ComponentProps<Typography>>;
9
+ /**
10
+ * URL to navigate to.
11
+ */
12
+ href: string;
13
+ /**
14
+ * An optional id attribute.
15
+ */
16
+ id?: string;
17
+ /**
18
+ * Indicates that this link is used within a body of text.
19
+ * This styles the link with an underline to distinguish it
20
+ * from surrounding text.
21
+ */
22
+ inline: boolean;
23
+ /**
24
+ * Kind of Link. Note: Secondary light Links are not supported.
25
+ */
26
+ kind: "primary" | "secondary";
27
+ /**
28
+ * Whether the button is on a dark/colored background.
29
+ */
30
+ light: boolean;
31
+ /**
32
+ * Whether the link should change color once it's visited.
33
+ * secondary or primary (light) links are not allowed to be visitable.
34
+ */
35
+ visitable: boolean;
36
+ /**
37
+ * Specifies the type of relationship between the current document and the
38
+ * linked document. Should only be used when `href` is specified. This
39
+ * defaults to "noopener noreferrer" when `target="_blank"`, but can be
40
+ * overridden by setting this prop to something else.
41
+ */
42
+ rel?: string;
43
+ /**
44
+ * Set the tabindex attribute on the rendered element.
45
+ */
46
+ tabIndex?: number;
47
+ /**
48
+ * Test ID used for e2e testing.
49
+ */
50
+ testId?: string;
51
+ /**
52
+ * Whether to avoid using client-side navigation.
53
+ *
54
+ * If the URL passed to href is local to the client-side, e.g.
55
+ * /math/algebra/eval-exprs, then it tries to use react-router-dom's Link
56
+ * component which handles the client-side navigation. You can set
57
+ * `skipClientNav` to true avoid using client-side nav entirely.
58
+ *
59
+ * NOTE: All URLs containing a protocol are considered external, e.g.
60
+ * https://khanacademy.org/math/algebra/eval-exprs will trigger a full
61
+ * page reload.
62
+ */
63
+ skipClientNav?: boolean;
64
+ /**
65
+ * Custom styles.
66
+ */
67
+ style?: StyleType;
68
+ /**
69
+ * Adds CSS classes to the Link.
70
+ */
71
+ className?: string;
72
+ /**
73
+ * Function to call when button is clicked.
74
+ *
75
+ * This callback should be used for things like marking BigBingo
76
+ * conversions. It should NOT be used to redirect to a different URL or to
77
+ * prevent navigation via e.preventDefault(). The event passed to this
78
+ * handler will have its preventDefault() and stopPropagation() methods
79
+ * stubbed out.
80
+ */
81
+ onClick?: (e: React.SyntheticEvent) => unknown;
82
+ /**
83
+ * Run async code in the background while client-side navigating. If the
84
+ * browser does a full page load navigation, the callback promise must be
85
+ * settled before the navigation will occur. Errors are ignored so that
86
+ * navigation is guaranteed to succeed.
87
+ */
88
+ safeWithNav?: () => Promise<unknown>;
89
+ /**
90
+ * Respond to raw "keydown" event.
91
+ */
92
+ onKeyDown?: (e: React.KeyboardEvent) => unknown;
93
+ /**
94
+ * Respond to raw "keyup" event.
95
+ */
96
+ onKeyUp?: (e: React.KeyboardEvent) => unknown;
97
+ /**
98
+ * A target destination window for a link to open in. We only support
99
+ * "_blank" which opens the URL in a new tab.
100
+ *
101
+ * TODO(WB-1262): only allow this prop when `href` is also set.t
102
+ */
103
+ target?: "_blank";
104
+ /**
105
+ * Run async code before navigating to the URL passed to `href`. If the
106
+ * promise returned rejects then navigation will not occur.
107
+ *
108
+ * If both safeWithNav and beforeNav are provided, beforeNav will be run
109
+ * first and safeWithNav will only be run if beforeNav does not reject.
110
+ *
111
+ * WARNING: Using this with `target="_blank"` will trigger built-in popup
112
+ * blockers in Firefox and Safari. This is because we do navigation
113
+ * programmatically and `beforeNav` causes a delay which means that the
114
+ * browser can't make a directly link between a user action and the
115
+ * navigation.
116
+ */
117
+ beforeNav?: () => Promise<unknown>;
118
+ };
119
+ type DefaultProps = {
120
+ inline: SharedProps["inline"];
121
+ kind: SharedProps["kind"];
122
+ light: SharedProps["light"];
123
+ visitable: SharedProps["visitable"];
124
+ };
125
+ /**
126
+ * Reusable link component.
127
+ *
128
+ * Consisting of a [`ClickableBehavior`](#clickablebehavior) surrounding a
129
+ * `LinkCore`. `ClickableBehavior` handles interactions and state changes.
130
+ * `LinkCore` is a stateless component which displays the different states
131
+ * the `Link` can take.
132
+ *
133
+ * ### Usage
134
+ *
135
+ * ```jsx
136
+ * <Link
137
+ * href="https://khanacademy.org/"
138
+ * >
139
+ * Label
140
+ * </Link>
141
+ * ```
142
+ */
143
+ export default class Link extends React.Component<SharedProps> {
144
+ static defaultProps: DefaultProps;
145
+ renderClickableBehavior(router: any): React.ReactNode;
146
+ render(): React.ReactElement;
147
+ }
148
+ export {};
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Flowtype definitions for link
3
+ * Generated by Flowgen from a Typescript Definition
4
+ * Flowgen v1.21.0
5
+ * @flow
6
+ */
7
+
8
+ import * as React from "react";
9
+ import type { AriaProps, StyleType } from "@khanacademy/wonder-blocks-core";
10
+ import type { Typography } from "@khanacademy/wonder-blocks-typography";
11
+ export type SharedProps = {
12
+ ...AriaProps,
13
+ ...{
14
+ /**
15
+ * Text to appear on the link. It can be a plain text or a Typography element.
16
+ */
17
+ children: string | React.Element<React.ComponentProps<Typography>>,
18
+
19
+ /**
20
+ * URL to navigate to.
21
+ */
22
+ href: string,
23
+
24
+ /**
25
+ * An optional id attribute.
26
+ */
27
+ id?: string,
28
+
29
+ /**
30
+ * Indicates that this link is used within a body of text.
31
+ * This styles the link with an underline to distinguish it
32
+ * from surrounding text.
33
+ */
34
+ inline: boolean,
35
+
36
+ /**
37
+ * Kind of Link. Note: Secondary light Links are not supported.
38
+ */
39
+ kind: "primary" | "secondary",
40
+
41
+ /**
42
+ * Whether the button is on a dark/colored background.
43
+ */
44
+ light: boolean,
45
+
46
+ /**
47
+ * Whether the link should change color once it's visited.
48
+ * secondary or primary (light) links are not allowed to be visitable.
49
+ */
50
+ visitable: boolean,
51
+
52
+ /**
53
+ * Specifies the type of relationship between the current document and the
54
+ * linked document. Should only be used when `href` is specified. This
55
+ * defaults to "noopener noreferrer" when `target="_blank"`, but can be
56
+ * overridden by setting this prop to something else.
57
+ */
58
+ rel?: string,
59
+
60
+ /**
61
+ * Set the tabindex attribute on the rendered element.
62
+ */
63
+ tabIndex?: number,
64
+
65
+ /**
66
+ * Test ID used for e2e testing.
67
+ */
68
+ testId?: string,
69
+
70
+ /**
71
+ * Whether to avoid using client-side navigation.
72
+ *
73
+ * If the URL passed to href is local to the client-side, e.g.
74
+ * /math/algebra/eval-exprs, then it tries to use react-router-dom's Link
75
+ * component which handles the client-side navigation. You can set
76
+ * `skipClientNav` to true avoid using client-side nav entirely.
77
+ *
78
+ * NOTE: All URLs containing a protocol are considered external, e.g.
79
+ * https://khanacademy.org/math/algebra/eval-exprs will trigger a full
80
+ * page reload.
81
+ */
82
+ skipClientNav?: boolean,
83
+
84
+ /**
85
+ * Custom styles.
86
+ */
87
+ style?: StyleType,
88
+
89
+ /**
90
+ * Adds CSS classes to the Link.
91
+ */
92
+ className?: string,
93
+
94
+ /**
95
+ * Function to call when button is clicked.
96
+ *
97
+ * This callback should be used for things like marking BigBingo
98
+ * conversions. It should NOT be used to redirect to a different URL or to
99
+ * prevent navigation via e.preventDefault(). The event passed to this
100
+ * handler will have its preventDefault() and stopPropagation() methods
101
+ * stubbed out.
102
+ */
103
+ onClick?: (e: React.SyntheticEvent<>) => mixed,
104
+
105
+ /**
106
+ * Run async code in the background while client-side navigating. If the
107
+ * browser does a full page load navigation, the callback promise must be
108
+ * settled before the navigation will occur. Errors are ignored so that
109
+ * navigation is guaranteed to succeed.
110
+ */
111
+ safeWithNav?: () => Promise<mixed>,
112
+
113
+ /**
114
+ * Respond to raw "keydown" event.
115
+ */
116
+ onKeyDown?: (e: React.KeyboardEvent<>) => mixed,
117
+
118
+ /**
119
+ * Respond to raw "keyup" event.
120
+ */
121
+ onKeyUp?: (e: React.KeyboardEvent<>) => mixed,
122
+
123
+ /**
124
+ * A target destination window for a link to open in. We only support
125
+ * "_blank" which opens the URL in a new tab.
126
+ *
127
+ * TODO(WB-1262): only allow this prop when `href` is also set.t
128
+ */
129
+ target?: "_blank",
130
+
131
+ /**
132
+ * Run async code before navigating to the URL passed to `href`. If the
133
+ * promise returned rejects then navigation will not occur.
134
+ *
135
+ * If both safeWithNav and beforeNav are provided, beforeNav will be run
136
+ * first and safeWithNav will only be run if beforeNav does not reject.
137
+ *
138
+ * WARNING: Using this with `target="_blank"` will trigger built-in popup
139
+ * blockers in Firefox and Safari. This is because we do navigation
140
+ * programmatically and `beforeNav` causes a delay which means that the
141
+ * browser can't make a directly link between a user action and the
142
+ * navigation.
143
+ */
144
+ beforeNav?: () => Promise<mixed>,
145
+ ...
146
+ },
147
+ };
148
+ declare type DefaultProps = {
149
+ inline: $PropertyType<SharedProps, "inline">,
150
+ kind: $PropertyType<SharedProps, "kind">,
151
+ light: $PropertyType<SharedProps, "light">,
152
+ visitable: $PropertyType<SharedProps, "visitable">,
153
+ ...
154
+ };
155
+ /**
156
+ * Reusable link component.
157
+ *
158
+ * Consisting of a [`ClickableBehavior`](#clickablebehavior) surrounding a
159
+ * `LinkCore`. `ClickableBehavior` handles interactions and state changes.
160
+ * `LinkCore` is a stateless component which displays the different states
161
+ * the `Link` can take.
162
+ *
163
+ * ### Usage
164
+ *
165
+ * ```jsx
166
+ * <Link
167
+ * href="https://khanacademy.org/"
168
+ * >
169
+ * Label
170
+ * </Link>
171
+ * ```
172
+ */
173
+ declare export default class Link mixins React.Component<SharedProps> {
174
+ static defaultProps: DefaultProps;
175
+ renderClickableBehavior(router: any): React.Node;
176
+ render(): React.Element<>;
177
+ }
package/dist/es/index.js CHANGED
@@ -1,5 +1,3 @@
1
- import _extends from '@babel/runtime/helpers/extends';
2
- import _objectWithoutPropertiesLoose from '@babel/runtime/helpers/objectWithoutPropertiesLoose';
3
1
  import * as React from 'react';
4
2
  import { __RouterContext } from 'react-router';
5
3
  import { isClientSideUrl, getClickableBehavior } from '@khanacademy/wonder-blocks-clickable';
@@ -8,50 +6,96 @@ import { Link as Link$1 } from 'react-router-dom';
8
6
  import { addStyle } from '@khanacademy/wonder-blocks-core';
9
7
  import Color, { mix, fade } from '@khanacademy/wonder-blocks-color';
10
8
 
9
+ function _objectDestructuringEmpty(obj) {
10
+ if (obj == null) throw new TypeError("Cannot destructure " + obj);
11
+ }
12
+
13
+ function _extends() {
14
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
15
+ for (var i = 1; i < arguments.length; i++) {
16
+ var source = arguments[i];
17
+ for (var key in source) {
18
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
19
+ target[key] = source[key];
20
+ }
21
+ }
22
+ }
23
+ return target;
24
+ };
25
+ return _extends.apply(this, arguments);
26
+ }
27
+
28
+ function _objectWithoutPropertiesLoose(source, excluded) {
29
+ if (source == null) return {};
30
+ var target = {};
31
+ var sourceKeys = Object.keys(source);
32
+ var key, i;
33
+ for (i = 0; i < sourceKeys.length; i++) {
34
+ key = sourceKeys[i];
35
+ if (excluded.indexOf(key) >= 0) continue;
36
+ target[key] = source[key];
37
+ }
38
+ return target;
39
+ }
40
+
41
+ function _setPrototypeOf(o, p) {
42
+ _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
43
+ o.__proto__ = p;
44
+ return o;
45
+ };
46
+ return _setPrototypeOf(o, p);
47
+ }
48
+
49
+ function _inheritsLoose(subClass, superClass) {
50
+ subClass.prototype = Object.create(superClass.prototype);
51
+ subClass.prototype.constructor = subClass;
52
+ _setPrototypeOf(subClass, superClass);
53
+ }
54
+
11
55
  const _excluded$1 = ["children", "skipClientNav", "focused", "hovered", "href", "inline", "kind", "light", "visitable", "pressed", "style", "testId", "waiting"];
12
56
  const StyledAnchor = addStyle("a");
13
57
  const StyledLink = addStyle(Link$1);
14
- class LinkCore extends React.Component {
15
- renderInner(router) {
58
+ let LinkCore = function (_React$Component) {
59
+ _inheritsLoose(LinkCore, _React$Component);
60
+ function LinkCore() {
61
+ return _React$Component.apply(this, arguments) || this;
62
+ }
63
+ var _proto = LinkCore.prototype;
64
+ _proto.renderInner = function renderInner(router) {
16
65
  const _this$props = this.props,
17
- {
18
- children,
19
- skipClientNav,
20
- focused,
21
- hovered,
22
- href,
23
- inline,
24
- kind,
25
- light,
26
- visitable,
27
- pressed,
28
- style,
29
- testId
30
- } = _this$props,
31
- restProps = _objectWithoutPropertiesLoose(_this$props, _excluded$1);
32
-
66
+ {
67
+ children,
68
+ skipClientNav,
69
+ focused,
70
+ hovered,
71
+ href,
72
+ inline,
73
+ kind,
74
+ light,
75
+ visitable,
76
+ pressed,
77
+ style,
78
+ testId
79
+ } = _this$props,
80
+ restProps = _objectWithoutPropertiesLoose(_this$props, _excluded$1);
33
81
  const linkStyles = _generateStyles(inline, kind, light, visitable);
34
-
35
82
  const restingStyles = inline ? linkStyles.restingInline : linkStyles.resting;
36
83
  const defaultStyles = [sharedStyles.shared, !(hovered || focused || pressed) && restingStyles, pressed && linkStyles.active, !pressed && hovered && linkStyles.hover, !pressed && focused && linkStyles.focus];
37
-
38
84
  const commonProps = _extends({
39
85
  "data-test-id": testId,
40
86
  style: [defaultStyles, style]
41
87
  }, restProps);
42
-
43
88
  return router && !skipClientNav && isClientSideUrl(href) ? React.createElement(StyledLink, _extends({}, commonProps, {
44
89
  to: href
45
90
  }), children) : React.createElement(StyledAnchor, _extends({}, commonProps, {
46
91
  href: href
47
92
  }), children);
48
- }
49
-
50
- render() {
93
+ };
94
+ _proto.render = function render() {
51
95
  return React.createElement(__RouterContext.Consumer, null, router => this.renderInner(router));
52
- }
53
-
54
- }
96
+ };
97
+ return LinkCore;
98
+ }(React.Component);
55
99
  const styles = {};
56
100
  const sharedStyles = StyleSheet.create({
57
101
  shared: {
@@ -63,22 +107,17 @@ const sharedStyles = StyleSheet.create({
63
107
  lineHeight: "22px"
64
108
  }
65
109
  });
66
-
67
110
  const _generateStyles = (inline, kind, light, visitable) => {
68
111
  const buttonType = `${kind}-${inline.toString()}-${light.toString()}-${visitable.toString()}`;
69
-
70
112
  if (styles[buttonType]) {
71
113
  return styles[buttonType];
72
114
  }
73
-
74
115
  if (kind === "secondary" && light) {
75
116
  throw new Error("Secondary Light links are not supported");
76
117
  }
77
-
78
118
  if (visitable && kind !== "primary") {
79
119
  throw new Error("Only primary link is visitable");
80
120
  }
81
-
82
121
  const {
83
122
  blue,
84
123
  pink,
@@ -138,25 +177,28 @@ const _generateStyles = (inline, kind, light, visitable) => {
138
177
  };
139
178
 
140
179
  const _excluded = ["onClick", "beforeNav", "safeWithNav", "href", "skipClientNav", "children", "tabIndex", "onKeyDown", "onKeyUp", "target"];
141
- class Link extends React.Component {
142
- renderClickableBehavior(router) {
180
+ let Link = function (_React$Component) {
181
+ _inheritsLoose(Link, _React$Component);
182
+ function Link() {
183
+ return _React$Component.apply(this, arguments) || this;
184
+ }
185
+ var _proto = Link.prototype;
186
+ _proto.renderClickableBehavior = function renderClickableBehavior(router) {
143
187
  const _this$props = this.props,
144
- {
145
- onClick,
146
- beforeNav = undefined,
147
- safeWithNav,
148
- href,
149
- skipClientNav,
150
- children,
151
- tabIndex,
152
- onKeyDown,
153
- onKeyUp,
154
- target = undefined
155
- } = _this$props,
156
- sharedProps = _objectWithoutPropertiesLoose(_this$props, _excluded);
157
-
188
+ {
189
+ onClick,
190
+ beforeNav = undefined,
191
+ safeWithNav,
192
+ href,
193
+ skipClientNav,
194
+ children,
195
+ tabIndex,
196
+ onKeyDown,
197
+ onKeyUp,
198
+ target = undefined
199
+ } = _this$props,
200
+ sharedProps = _objectWithoutPropertiesLoose(_this$props, _excluded);
158
201
  const ClickableBehavior = getClickableBehavior(href, skipClientNav, router);
159
-
160
202
  if (beforeNav) {
161
203
  return React.createElement(ClickableBehavior, {
162
204
  disabled: false,
@@ -168,8 +210,7 @@ class Link extends React.Component {
168
210
  onKeyDown: onKeyDown,
169
211
  onKeyUp: onKeyUp
170
212
  }, (state, _ref) => {
171
- let childrenProps = _extends({}, _ref);
172
-
213
+ let childrenProps = _extends({}, (_objectDestructuringEmpty(_ref), _ref));
173
214
  return React.createElement(LinkCore, _extends({}, sharedProps, state, childrenProps, {
174
215
  skipClientNav: skipClientNav,
175
216
  href: href,
@@ -188,8 +229,7 @@ class Link extends React.Component {
188
229
  onKeyDown: onKeyDown,
189
230
  onKeyUp: onKeyUp
190
231
  }, (state, _ref2) => {
191
- let childrenProps = _extends({}, _ref2);
192
-
232
+ let childrenProps = _extends({}, (_objectDestructuringEmpty(_ref2), _ref2));
193
233
  return React.createElement(LinkCore, _extends({}, sharedProps, state, childrenProps, {
194
234
  skipClientNav: skipClientNav,
195
235
  href: href,
@@ -198,13 +238,12 @@ class Link extends React.Component {
198
238
  }), children);
199
239
  });
200
240
  }
201
- }
202
-
203
- render() {
241
+ };
242
+ _proto.render = function render() {
204
243
  return React.createElement(__RouterContext.Consumer, null, router => this.renderClickableBehavior(router));
205
- }
206
-
207
- }
244
+ };
245
+ return Link;
246
+ }(React.Component);
208
247
  Link.defaultProps = {
209
248
  inline: false,
210
249
  kind: "primary",
@@ -0,0 +1,2 @@
1
+ import Link from "./components/link";
2
+ export { Link as default };