@khanacademy/wonder-blocks-clickable 3.1.2 → 4.0.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,29 @@
1
1
  # @khanacademy/wonder-blocks-clickable
2
2
 
3
+ ## 4.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 674a1e5c: Props are using discriminated union types to prevent invalid combinations of props
8
+
9
+ ### Minor Changes
10
+
11
+ - 8c77f29d: Create new Switch component and add 'switch' role to ClickableRole
12
+
13
+ ### Patch Changes
14
+
15
+ - 674a1e5c: We're no longer building flow types
16
+ - Updated dependencies [674a1e5c]
17
+ - Updated dependencies [674a1e5c]
18
+ - @khanacademy/wonder-blocks-core@6.0.0
19
+
20
+ ## 3.1.3
21
+
22
+ ### Patch Changes
23
+
24
+ - Updated dependencies [1344436f]
25
+ - @khanacademy/wonder-blocks-core@5.4.0
26
+
3
27
  ## 3.1.2
4
28
 
5
29
  ### Patch Changes
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
- export type ClickableRole = "button" | "link" | "checkbox" | "radio" | "listbox" | "option" | "menuitem" | "menu" | "tab";
3
- type Props = Readonly<{
2
+ export type ClickableRole = "button" | "checkbox" | "link" | "listbox" | "menu" | "menuitem" | "option" | "radio" | "switch" | "tab";
3
+ type CommonProps = Readonly<{
4
4
  /**
5
5
  * A function that returns the a React `Element`.
6
6
  *
@@ -74,11 +74,15 @@ type Props = Readonly<{
74
74
  * Respond to raw "keyup" event.
75
75
  */
76
76
  onKeyUp?: (e: React.KeyboardEvent) => unknown;
77
+ }>;
78
+ type Props = (CommonProps & Readonly<{
77
79
  /**
78
80
  * A target destination window for a link to open in. Should only be used
79
81
  * when `href` is specified.
80
82
  */
81
83
  target?: "_blank";
84
+ beforeNav?: never;
85
+ }>) | (CommonProps & Readonly<{
82
86
  /**
83
87
  * Run async code before navigating to the URL passed to `href`. If the
84
88
  * promise returned rejects then navigation will not occur.
@@ -93,7 +97,8 @@ type Props = Readonly<{
93
97
  * navigation.
94
98
  */
95
99
  beforeNav?: () => Promise<unknown>;
96
- }>;
100
+ target?: never;
101
+ }>);
97
102
  export type ClickableState = Readonly<{
98
103
  /**
99
104
  * Whether the component is hovered.
@@ -2,55 +2,28 @@ import * as React from "react";
2
2
  import { Link } from "react-router-dom";
3
3
  import type { AriaProps, StyleType } from "@khanacademy/wonder-blocks-core";
4
4
  import type { ClickableRole, ClickableState } from "./clickable-behavior";
5
+ type CommonProps =
5
6
  /**
6
- * A component to turn any custom component into a clickable one.
7
- *
8
- * Works by wrapping `ClickableBehavior` around the child element and styling
9
- * the child appropriately and encapsulates routing logic which can be
10
- * customized. Expects a function which returns an element as its child.
11
- *
12
- * Clickable allows your components to:
13
- *
14
- * - Handle mouse / touch / keyboard events
15
- * - Match the standard behavior of the given role
16
- * - Apply custom styles based on pressed / focused / hovered state
17
- * - Perform Client Side Navigation when href is passed and the component is a
18
- * descendent of a react-router Router.
19
- *
20
- * ### Usage
21
- *
22
- * ```jsx
23
- * <Clickable onClick={() => alert("You clicked me!")}>
24
- * {({hovered, focused, pressed}) =>
25
- * <div
26
- * style={[
27
- * hovered && styles.hovered,
28
- * focused && styles.focused,
29
- * pressed && styles.pressed,
30
- * ]}
31
- * >
32
- * Click Me!
33
- * </div>
34
- * }
35
- * </Clickable>
36
- * ```
7
+ * aria-label should be used when `spinner={true}` to let people using screen
8
+ * readers that the action taken by clicking the button will take some
9
+ * time to complete.
37
10
  */
38
- declare const Clickable: React.ForwardRefExoticComponent<Partial<Omit<AriaProps, "aria-disabled">> & {
11
+ Partial<Omit<AriaProps, "aria-disabled">> & {
39
12
  /**
40
13
  * The child of Clickable must be a function which returns the component
41
14
  * which should be made Clickable. The function is passed an object with
42
15
  * three boolean properties: hovered, focused, and pressed.
43
16
  */
44
- children: (arg1: ClickableState) => React.ReactNode;
17
+ children: (clickableState: ClickableState) => React.ReactNode;
45
18
  /**
46
19
  * An onClick function which Clickable can execute when clicked
47
20
  */
48
- onClick?: ((e: React.SyntheticEvent) => unknown) | undefined;
21
+ onClick?: (e: React.SyntheticEvent) => unknown;
49
22
  /**
50
23
  * Optional href which Clickable should direct to, uses client-side routing
51
24
  * by default if react-router is present
52
25
  */
53
- href?: string | undefined;
26
+ href?: string;
54
27
  /**
55
28
  * Styles to apply to the Clickable component
56
29
  */
@@ -58,63 +31,57 @@ declare const Clickable: React.ForwardRefExoticComponent<Partial<Omit<AriaProps,
58
31
  /**
59
32
  * Adds CSS classes to the Clickable.
60
33
  */
61
- className?: string | undefined;
34
+ className?: string;
62
35
  /**
63
36
  * Whether the Clickable is on a dark colored background.
64
37
  * Sets the default focus ring color to white, instead of blue.
65
38
  * Defaults to false.
66
39
  */
67
- light?: boolean | undefined;
40
+ light?: boolean;
68
41
  /**
69
42
  * Disables or enables the child; defaults to false
70
43
  */
71
- disabled?: boolean | undefined;
44
+ disabled?: boolean;
72
45
  /**
73
46
  * An optional id attribute.
74
47
  */
75
- id?: string | undefined;
48
+ id?: string;
76
49
  /**
77
50
  * Specifies the type of relationship between the current document and the
78
51
  * linked document. Should only be used when `href` is specified. This
79
52
  * defaults to "noopener noreferrer" when `target="_blank"`, but can be
80
53
  * overridden by setting this prop to something else.
81
54
  */
82
- rel?: string | undefined;
55
+ rel?: string;
83
56
  /**
84
57
  * The role of the component, can be a role of type ClickableRole
85
58
  */
86
- role?: ClickableRole | undefined;
59
+ role?: ClickableRole;
87
60
  /**
88
61
  * Avoids client-side routing in the presence of the href prop
89
62
  */
90
- skipClientNav?: boolean | undefined;
63
+ skipClientNav?: boolean;
91
64
  /**
92
65
  * Test ID used for e2e testing.
93
66
  */
94
- testId?: string | undefined;
67
+ testId?: string;
95
68
  /**
96
69
  * Respond to raw "keydown" event.
97
70
  */
98
- onKeyDown?: ((e: React.KeyboardEvent) => unknown) | undefined;
71
+ onKeyDown?: (e: React.KeyboardEvent) => unknown;
99
72
  /**
100
73
  * Respond to raw "keyup" event.
101
74
  */
102
- onKeyUp?: ((e: React.KeyboardEvent) => unknown) | undefined;
75
+ onKeyUp?: (e: React.KeyboardEvent) => unknown;
103
76
  /**
104
77
  * Don't show the default focus ring. This should be used when implementing
105
78
  * a custom focus ring within your own component that uses Clickable.
106
79
  */
107
- hideDefaultFocusRing?: boolean | undefined;
108
- /**
109
- * A target destination window for a link to open in.
110
- *
111
- * TODO(WB-1262): only allow this prop when `href` is also set.t
112
- */
113
- target?: "_blank" | undefined;
80
+ hideDefaultFocusRing?: boolean;
114
81
  /**
115
82
  * Set the tabindex attribute on the rendered element.
116
83
  */
117
- tabIndex?: number | undefined;
84
+ tabIndex?: number;
118
85
  /**
119
86
  * Run async code before navigating. If the promise returned rejects then
120
87
  * navigation will not occur.
@@ -125,13 +92,104 @@ declare const Clickable: React.ForwardRefExoticComponent<Partial<Omit<AriaProps,
125
92
  * WARNING: This prop must be used with `href` and should not be used with
126
93
  * `target="blank"`.
127
94
  */
128
- beforeNav?: (() => Promise<unknown>) | undefined;
95
+ beforeNav?: () => Promise<unknown>;
96
+ /**
97
+ * Run async code in the background while client-side navigating. If the
98
+ * browser does a full page load navigation, the callback promise must be
99
+ * settled before the navigation will occur. Errors are ignored so that
100
+ * navigation is guaranteed to succeed.
101
+ */
102
+ safeWithNav?: () => Promise<unknown>;
103
+ };
104
+ type Props = (CommonProps & {
105
+ target?: never;
106
+ beforeNav?: never;
107
+ safeWithNav?: never;
108
+ }) | (CommonProps & {
109
+ href: string;
110
+ /**
111
+ * A target destination window for a link to open in.
112
+ */
113
+ target?: "_blank";
114
+ beforeNav?: never;
115
+ safeWithNav?: never;
116
+ }) | (CommonProps & {
117
+ href: string;
118
+ /**
119
+ * Run async code before navigating. If the promise returned rejects then
120
+ * navigation will not occur.
121
+ *
122
+ * If both safeWithNav and beforeNav are provided, beforeNav will be run
123
+ * first and safeWithNav will only be run if beforeNav does not reject.
124
+ */
125
+ beforeNav: () => Promise<unknown>;
126
+ safeWithNav?: never;
127
+ target?: never;
128
+ }) | (CommonProps & {
129
+ href: string;
129
130
  /**
130
131
  * Run async code in the background while client-side navigating. If the
131
132
  * browser does a full page load navigation, the callback promise must be
132
133
  * settled before the navigation will occur. Errors are ignored so that
133
134
  * navigation is guaranteed to succeed.
134
135
  */
135
- safeWithNav?: (() => Promise<unknown>) | undefined;
136
- } & React.RefAttributes<HTMLAnchorElement | HTMLButtonElement | typeof Link>>;
136
+ safeWithNav: () => Promise<unknown>;
137
+ /**
138
+ * A target destination window for a link to open in.
139
+ */
140
+ target?: "_blank";
141
+ beforeNav?: never;
142
+ }) | (CommonProps & {
143
+ href: string;
144
+ /**
145
+ * Run async code before navigating. If the promise returned rejects then
146
+ * navigation will not occur.
147
+ *
148
+ * If both safeWithNav and beforeNav are provided, beforeNav will be run
149
+ * first and safeWithNav will only be run if beforeNav does not reject.
150
+ */
151
+ beforeNav: () => Promise<unknown>;
152
+ /**
153
+ * Run async code in the background while client-side navigating. If the
154
+ * browser does a full page load navigation, the callback promise must be
155
+ * settled before the navigation will occur. Errors are ignored so that
156
+ * navigation is guaranteed to succeed.
157
+ */
158
+ safeWithNav: () => Promise<unknown>;
159
+ target?: never;
160
+ });
161
+ /**
162
+ * A component to turn any custom component into a clickable one.
163
+ *
164
+ * Works by wrapping `ClickableBehavior` around the child element and styling
165
+ * the child appropriately and encapsulates routing logic which can be
166
+ * customized. Expects a function which returns an element as its child.
167
+ *
168
+ * Clickable allows your components to:
169
+ *
170
+ * - Handle mouse / touch / keyboard events
171
+ * - Match the standard behavior of the given role
172
+ * - Apply custom styles based on pressed / focused / hovered state
173
+ * - Perform Client Side Navigation when href is passed and the component is a
174
+ * descendent of a react-router Router.
175
+ *
176
+ * ### Usage
177
+ *
178
+ * ```jsx
179
+ * <Clickable onClick={() => alert("You clicked me!")}>
180
+ * {({hovered, focused, pressed}) =>
181
+ * <div
182
+ * style={[
183
+ * hovered && styles.hovered,
184
+ * focused && styles.focused,
185
+ * pressed && styles.pressed,
186
+ * ]}
187
+ * >
188
+ * Click Me!
189
+ * </div>
190
+ * }
191
+ * </Clickable>
192
+ * ```
193
+ */
194
+ declare const Clickable: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLAnchorElement | HTMLButtonElement | typeof Link>>;
137
195
  export default Clickable;
@@ -9,6 +9,7 @@
9
9
  * See https://reacttraining.com/react-router/web/guides/basic-components.
10
10
  */
11
11
  import * as React from "react";
12
+ import { PropsFor } from "@khanacademy/wonder-blocks-core";
12
13
  import ClickableBehavior from "../components/clickable-behavior";
13
14
  export default function getClickableBehavior(
14
15
  /**
@@ -22,4 +23,4 @@ skipClientNav?: boolean,
22
23
  /**
23
24
  * router object added to the React context object by react-router-dom.
24
25
  */
25
- router?: any): React.ComponentType<JSX.LibraryManagedAttributes<typeof ClickableBehavior, React.ComponentProps<typeof ClickableBehavior>>>;
26
+ router?: any): React.ComponentType<PropsFor<typeof ClickableBehavior>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khanacademy/wonder-blocks-clickable",
3
- "version": "3.1.2",
3
+ "version": "4.0.0",
4
4
  "design": "v1",
5
5
  "description": "Clickable component for Wonder-Blocks.",
6
6
  "main": "dist/index.js",
@@ -17,7 +17,7 @@
17
17
  "dependencies": {
18
18
  "@babel/runtime": "^7.18.6",
19
19
  "@khanacademy/wonder-blocks-color": "^2.0.1",
20
- "@khanacademy/wonder-blocks-core": "^5.3.1"
20
+ "@khanacademy/wonder-blocks-core": "^6.0.0"
21
21
  },
22
22
  "peerDependencies": {
23
23
  "aphrodite": "^1.2.5",
@@ -27,6 +27,6 @@
27
27
  "react-router-dom": "5.3.0"
28
28
  },
29
29
  "devDependencies": {
30
- "wb-dev-build-settings": "^0.9.7"
30
+ "@khanacademy/wb-dev-build-settings": "^1.0.0"
31
31
  }
32
32
  }
@@ -0,0 +1,20 @@
1
+ import * as React from "react";
2
+
3
+ import ClickableBehavior from "../clickable-behavior";
4
+
5
+ <ClickableBehavior>
6
+ {(_, childrenProps) => <div {...childrenProps} />}
7
+ </ClickableBehavior>;
8
+
9
+ <ClickableBehavior target="_blank">
10
+ {(_, childrenProps) => <div {...childrenProps} />}
11
+ </ClickableBehavior>;
12
+
13
+ <ClickableBehavior beforeNav={() => Promise.resolve()}>
14
+ {(_, childrenProps) => <div {...childrenProps} />}
15
+ </ClickableBehavior>;
16
+
17
+ // @ts-expect-error `target` and `beforeNav` can't be used together.
18
+ <ClickableBehavior target="_blank" beforeNav={() => Promise.resolve()}>
19
+ {(_, childrenProps) => <div {...childrenProps} />}
20
+ </ClickableBehavior>;
@@ -0,0 +1,45 @@
1
+ import * as React from "react";
2
+
3
+ import Clickable from "../clickable";
4
+
5
+ <Clickable>{(_) => "Hello, world!"}</Clickable>;
6
+
7
+ <Clickable href="/foo">{(_) => "Hello, world!"}</Clickable>;
8
+
9
+ <Clickable href="/foo" target="_blank">
10
+ {(_) => "Hello, world!"}
11
+ </Clickable>;
12
+
13
+ // @ts-expect-error - `href` must be set when using `target="_blank"`.
14
+ <Clickable target="_blank">{(_) => "Hello, world!"}</Clickable>;
15
+
16
+ <Clickable href="/foo" beforeNav={() => Promise.resolve()}>
17
+ {(_) => "Hello, world!"}
18
+ </Clickable>;
19
+
20
+ <Clickable href="/foo" target="_blank" safeWithNav={() => Promise.resolve()}>
21
+ {(_) => "Hello, world!"}
22
+ </Clickable>;
23
+
24
+ // @ts-expect-error - `target="_blank"` cannot be used with `beforeNav`.
25
+ <Clickable href="/foo" target="_blank" beforeNav={() => Promise.resolve()}>
26
+ {(_) => "Hello, world!"}
27
+ </Clickable>;
28
+
29
+ // @ts-expect-error - `target="_blank"` cannot be used with `beforeNav`.
30
+ <Clickable
31
+ href="/foo"
32
+ target="_blank"
33
+ beforeNav={() => Promise.resolve()}
34
+ safeWithNav={() => Promise.resolve()}
35
+ >
36
+ {(_) => "Hello, world!"}
37
+ </Clickable>;
38
+
39
+ <Clickable
40
+ href="/foo"
41
+ beforeNav={() => Promise.resolve()}
42
+ safeWithNav={() => Promise.resolve()}
43
+ >
44
+ {(_) => "Hello, world!"}
45
+ </Clickable>;
@@ -3,13 +3,14 @@ import * as React from "react";
3
3
  // NOTE: Potentially add to this as more cases come up.
4
4
  export type ClickableRole =
5
5
  | "button"
6
- | "link"
7
6
  | "checkbox"
8
- | "radio"
7
+ | "link"
9
8
  | "listbox"
10
- | "option"
11
- | "menuitem"
12
9
  | "menu"
10
+ | "menuitem"
11
+ | "option"
12
+ | "radio"
13
+ | "switch"
13
14
  | "tab";
14
15
 
15
16
  const getAppropriateTriggersForRole = (role?: ClickableRole | null) => {
@@ -41,8 +42,7 @@ const getAppropriateTriggersForRole = (role?: ClickableRole | null) => {
41
42
  }
42
43
  };
43
44
 
44
- // TODO(FEI-5000): Convert back to conditional props after TS migration is complete.
45
- type Props = Readonly<{
45
+ type CommonProps = Readonly<{
46
46
  /**
47
47
  * A function that returns the a React `Element`.
48
48
  *
@@ -119,28 +119,40 @@ type Props = Readonly<{
119
119
  * Respond to raw "keyup" event.
120
120
  */
121
121
  onKeyUp?: (e: React.KeyboardEvent) => unknown;
122
- /**
123
- * A target destination window for a link to open in. Should only be used
124
- * when `href` is specified.
125
- */
126
- // TODO(WB-1262): only allow this prop when `href` is also set.
127
- target?: "_blank";
128
- /**
129
- * Run async code before navigating to the URL passed to `href`. If the
130
- * promise returned rejects then navigation will not occur.
131
- *
132
- * If both safeWithNav and beforeNav are provided, beforeNav will be run
133
- * first and safeWithNav will only be run if beforeNav does not reject.
134
- *
135
- * WARNING: Using this with `target="_blank"` will trigger built-in popup
136
- * blockers in Firefox and Safari. This is because we do navigation
137
- * programmatically and `beforeNav` causes a delay which means that the
138
- * browser can't make a directly link between a user action and the
139
- * navigation.
140
- */
141
- beforeNav?: () => Promise<unknown>;
142
122
  }>;
143
123
 
124
+ type Props =
125
+ | (CommonProps &
126
+ Readonly<{
127
+ /**
128
+ * A target destination window for a link to open in. Should only be used
129
+ * when `href` is specified.
130
+ */
131
+ // TODO(WB-1262): only allow this prop when `href` is also set.
132
+ target?: "_blank";
133
+
134
+ beforeNav?: never; // disallow beforeNav when target="_blank"
135
+ }>)
136
+ | (CommonProps &
137
+ Readonly<{
138
+ /**
139
+ * Run async code before navigating to the URL passed to `href`. If the
140
+ * promise returned rejects then navigation will not occur.
141
+ *
142
+ * If both safeWithNav and beforeNav are provided, beforeNav will be run
143
+ * first and safeWithNav will only be run if beforeNav does not reject.
144
+ *
145
+ * WARNING: Using this with `target="_blank"` will trigger built-in popup
146
+ * blockers in Firefox and Safari. This is because we do navigation
147
+ * programmatically and `beforeNav` causes a delay which means that the
148
+ * browser can't make a directly link between a user action and the
149
+ * navigation.
150
+ */
151
+ beforeNav?: () => Promise<unknown>;
152
+
153
+ target?: never; // disallow target="_blank" when beforeNav is set
154
+ }>);
155
+
144
156
  export type ClickableState = Readonly<{
145
157
  /**
146
158
  * Whether the component is hovered.
@@ -11,8 +11,7 @@ import getClickableBehavior from "../util/get-clickable-behavior";
11
11
  import type {ClickableRole, ClickableState} from "./clickable-behavior";
12
12
  import {isClientSideUrl} from "../util/is-client-side-url";
13
13
 
14
- // TODO(FEI-5000): Convert back to conditional props after TS migration is complete.
15
- type Props =
14
+ type CommonProps =
16
15
  /**
17
16
  * aria-label should be used when `spinner={true}` to let people using screen
18
17
  * readers that the action taken by clicking the button will take some
@@ -24,7 +23,7 @@ type Props =
24
23
  * which should be made Clickable. The function is passed an object with
25
24
  * three boolean properties: hovered, focused, and pressed.
26
25
  */
27
- children: (arg1: ClickableState) => React.ReactNode;
26
+ children: (clickableState: ClickableState) => React.ReactNode;
28
27
  /**
29
28
  * An onClick function which Clickable can execute when clicked
30
29
  */
@@ -88,12 +87,6 @@ type Props =
88
87
  * a custom focus ring within your own component that uses Clickable.
89
88
  */
90
89
  hideDefaultFocusRing?: boolean;
91
- /**
92
- * A target destination window for a link to open in.
93
- *
94
- * TODO(WB-1262): only allow this prop when `href` is also set.t
95
- */
96
- target?: "_blank";
97
90
  /**
98
91
  * Set the tabindex attribute on the rendered element.
99
92
  */
@@ -118,6 +111,79 @@ type Props =
118
111
  safeWithNav?: () => Promise<unknown>;
119
112
  };
120
113
 
114
+ type Props =
115
+ | (CommonProps & {
116
+ target?: never;
117
+ beforeNav?: never;
118
+ safeWithNav?: never;
119
+ })
120
+ | (CommonProps & {
121
+ href: string;
122
+
123
+ /**
124
+ * A target destination window for a link to open in.
125
+ */
126
+ target?: "_blank";
127
+
128
+ beforeNav?: never;
129
+ safeWithNav?: never;
130
+ })
131
+ | (CommonProps & {
132
+ href: string;
133
+
134
+ /**
135
+ * Run async code before navigating. If the promise returned rejects then
136
+ * navigation will not occur.
137
+ *
138
+ * If both safeWithNav and beforeNav are provided, beforeNav will be run
139
+ * first and safeWithNav will only be run if beforeNav does not reject.
140
+ */
141
+ beforeNav: () => Promise<unknown>;
142
+
143
+ safeWithNav?: never;
144
+ target?: never;
145
+ })
146
+ | (CommonProps & {
147
+ href: string;
148
+
149
+ /**
150
+ * Run async code in the background while client-side navigating. If the
151
+ * browser does a full page load navigation, the callback promise must be
152
+ * settled before the navigation will occur. Errors are ignored so that
153
+ * navigation is guaranteed to succeed.
154
+ */
155
+ safeWithNav: () => Promise<unknown>;
156
+
157
+ /**
158
+ * A target destination window for a link to open in.
159
+ */
160
+ target?: "_blank";
161
+
162
+ beforeNav?: never;
163
+ })
164
+ | (CommonProps & {
165
+ href: string;
166
+
167
+ /**
168
+ * Run async code before navigating. If the promise returned rejects then
169
+ * navigation will not occur.
170
+ *
171
+ * If both safeWithNav and beforeNav are provided, beforeNav will be run
172
+ * first and safeWithNav will only be run if beforeNav does not reject.
173
+ */
174
+ beforeNav: () => Promise<unknown>;
175
+
176
+ /**
177
+ * Run async code in the background while client-side navigating. If the
178
+ * browser does a full page load navigation, the callback promise must be
179
+ * settled before the navigation will occur. Errors are ignored so that
180
+ * navigation is guaranteed to succeed.
181
+ */
182
+ safeWithNav: () => Promise<unknown>;
183
+
184
+ target?: never;
185
+ });
186
+
121
187
  const StyledAnchor = addStyle("a");
122
188
  const StyledButton = addStyle("button");
123
189
  const StyledLink = addStyle(Link);
@@ -11,6 +11,8 @@
11
11
  import * as React from "react";
12
12
  import {withRouter} from "react-router-dom";
13
13
 
14
+ import {PropsFor} from "@khanacademy/wonder-blocks-core";
15
+
14
16
  import ClickableBehavior from "../components/clickable-behavior";
15
17
  import {isClientSideUrl} from "./is-client-side-url";
16
18
 
@@ -30,12 +32,7 @@ export default function getClickableBehavior(
30
32
  * router object added to the React context object by react-router-dom.
31
33
  */
32
34
  router?: any,
33
- ): React.ComponentType<
34
- JSX.LibraryManagedAttributes<
35
- typeof ClickableBehavior,
36
- React.ComponentProps<typeof ClickableBehavior>
37
- >
38
- > {
35
+ ): React.ComponentType<PropsFor<typeof ClickableBehavior>> {
39
36
  if (router && skipClientNav !== true && href && isClientSideUrl(href)) {
40
37
  // We cast to `any` here since the type of ClickableBehaviorWithRouter
41
38
  // is slightly different from the return type of this function.