@khanacademy/wonder-blocks-link 7.1.1 → 8.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,31 @@
1
1
  # @khanacademy/wonder-blocks-link
2
2
 
3
+ ## 8.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 762f749: Remove `kind` prop as the `secondary` variant is now dropped.
8
+ - b6d77dc: Removes the `visitable` prop as it is not used. Also, removed as per design recommendation for privacy purposes.
9
+
10
+ ### Patch Changes
11
+
12
+ - 5655b9f: Switch to use `focus.outer` semanticColor token
13
+ - beb09cd: Update Link to use CSS pseudo-classes (:hover, :focus-visible, :active) instead of JS driven states (hovered, focused, pressed).
14
+ - 5bd2a95: Internal `Link` refactor to use `semanticColor` tokens intead of `color`. Also moved the link colors to an object to prepare this for an upcoming theme integration"
15
+ - 8f53293: Rename action tokens: `filled` -> `primary`, `outlined` -> `secondary`.
16
+ - Updated dependencies [ed26d66]
17
+ - Updated dependencies [5655b9f]
18
+ - Updated dependencies [5655b9f]
19
+ - Updated dependencies [8f53293]
20
+ - Updated dependencies [051f0f8]
21
+ - Updated dependencies [8fc65a9]
22
+ - Updated dependencies [e1b78db]
23
+ - Updated dependencies [051f0f8]
24
+ - @khanacademy/wonder-blocks-core@12.2.0
25
+ - @khanacademy/wonder-blocks-tokens@5.0.0
26
+ - @khanacademy/wonder-blocks-clickable@6.1.2
27
+ - @khanacademy/wonder-blocks-icon@5.1.2
28
+
3
29
  ## 7.1.1
4
30
 
5
31
  ### Patch Changes
@@ -22,19 +22,10 @@ type CommonProps = AriaProps & {
22
22
  * from surrounding text.
23
23
  */
24
24
  inline?: boolean;
25
- /**
26
- * Kind of Link. Note: Secondary light Links are not supported.
27
- */
28
- kind?: "primary" | "secondary";
29
25
  /**
30
26
  * Whether the button is on a dark/colored background.
31
27
  */
32
28
  light?: boolean;
33
- /**
34
- * Whether the link should change color once it's visited.
35
- * secondary or primary (light) links are not allowed to be visitable.
36
- */
37
- visitable?: boolean;
38
29
  /**
39
30
  * Specifies the type of relationship between the current document and the
40
31
  * linked document. Should only be used when `href` is specified. This
package/dist/es/index.js CHANGED
@@ -7,11 +7,11 @@ import { isClientSideUrl, getClickableBehavior } from '@khanacademy/wonder-block
7
7
  import { StyleSheet } from 'aphrodite';
8
8
  import { Link as Link$1 } from 'react-router-dom';
9
9
  import { addStyle } from '@khanacademy/wonder-blocks-core';
10
- import { spacing, mix, fade, color } from '@khanacademy/wonder-blocks-tokens';
10
+ import { spacing, semanticColor, color, border } from '@khanacademy/wonder-blocks-tokens';
11
11
  import { PhosphorIcon } from '@khanacademy/wonder-blocks-icon';
12
12
  import externalLinkIcon from '@phosphor-icons/core/bold/arrow-square-out-bold.svg';
13
13
 
14
- const _excluded$1 = ["children", "skipClientNav", "focused", "hovered", "href", "inline", "kind", "light", "visitable", "pressed", "style", "testId", "waiting", "target", "startIcon", "endIcon"];
14
+ const _excluded$1 = ["children", "skipClientNav", "focused", "hovered", "href", "inline", "light", "pressed", "style", "testId", "waiting", "target", "startIcon", "endIcon"];
15
15
  const StyledA = addStyle("a");
16
16
  const StyledLink = addStyle(Link$1);
17
17
  const LinkCore = React.forwardRef(function LinkCore(props, ref) {
@@ -20,12 +20,9 @@ const LinkCore = React.forwardRef(function LinkCore(props, ref) {
20
20
  children,
21
21
  skipClientNav,
22
22
  focused,
23
- hovered,
24
23
  href,
25
24
  inline = false,
26
- kind = "primary",
27
25
  light = false,
28
- visitable = false,
29
26
  pressed,
30
27
  style,
31
28
  testId,
@@ -34,9 +31,8 @@ const LinkCore = React.forwardRef(function LinkCore(props, ref) {
34
31
  endIcon
35
32
  } = props,
36
33
  restProps = _objectWithoutPropertiesLoose(props, _excluded$1);
37
- const linkStyles = _generateStyles(inline, kind, light, visitable);
38
- const restingStyles = inline ? linkStyles.restingInline : linkStyles.resting;
39
- const defaultStyles = [sharedStyles.shared, restingStyles, pressed && linkStyles.active, !pressed && hovered && linkStyles.hover, !pressed && focused && linkStyles.focus];
34
+ const linkStyles = _generateStyles(inline, light);
35
+ const defaultStyles = [sharedStyles.shared, linkStyles.rest, inline && linkStyles.restInline, !pressed && focused && linkStyles.focus];
40
36
  const commonProps = _extends({
41
37
  "data-testid": testId,
42
38
  style: [defaultStyles, style],
@@ -97,76 +93,78 @@ const sharedStyles = StyleSheet.create({
97
93
  alignItems: "center"
98
94
  }
99
95
  });
100
- const _generateStyles = (inline, kind, light, visitable) => {
101
- const buttonType = `${kind}-${inline.toString()}-${light.toString()}-${visitable.toString()}`;
96
+ const action = semanticColor.action.secondary.progressive;
97
+ const theme = {
98
+ color: {
99
+ default: {
100
+ rest: {
101
+ foreground: action.default.foreground
102
+ },
103
+ hover: {
104
+ foreground: action.hover.foreground
105
+ },
106
+ focus: {
107
+ border: semanticColor.focus.outer,
108
+ foreground: action.hover.foreground
109
+ },
110
+ press: {
111
+ foreground: action.press.foreground
112
+ }
113
+ },
114
+ inverse: {
115
+ rest: {
116
+ foreground: semanticColor.text.inverse
117
+ },
118
+ hover: {
119
+ foreground: semanticColor.text.inverse
120
+ },
121
+ focus: {
122
+ border: semanticColor.border.inverse,
123
+ foreground: semanticColor.text.inverse
124
+ },
125
+ press: {
126
+ foreground: color.fadedBlue
127
+ }
128
+ }
129
+ }
130
+ };
131
+ const _generateStyles = (inline, light) => {
132
+ const buttonType = `${inline.toString()}-${light.toString()}`;
102
133
  if (styles[buttonType]) {
103
134
  return styles[buttonType];
104
135
  }
105
- if (kind === "secondary" && light) {
106
- throw new Error("Secondary Light links are not supported");
107
- }
108
- if (visitable && kind !== "primary") {
109
- throw new Error("Only primary link is visitable");
110
- }
111
- const {
112
- blue,
113
- purple,
114
- white,
115
- offBlack,
116
- offBlack32,
117
- offBlack64
118
- } = color;
119
- const pink = "#fa50ae";
120
- const linkPurple = mix(fade(offBlack, 0.08), purple);
121
- const fadedBlue = color.fadedBlue;
122
- const activeLightVisited = mix(fade(white, 0.32), pink);
123
- const activeDefaultPrimary = color.activeBlue;
124
- const primaryDefaultTextColor = light ? white : blue;
125
- const secondaryDefaultTextColor = inline ? offBlack : offBlack64;
126
- const defaultTextColor = kind === "primary" ? primaryDefaultTextColor : secondaryDefaultTextColor;
127
- const primaryActiveColor = light ? fadedBlue : activeDefaultPrimary;
128
- const secondaryActiveColor = inline ? activeDefaultPrimary : offBlack;
129
- const activeColor = kind === "primary" ? primaryActiveColor : secondaryActiveColor;
130
- const defaultVisited = visitable ? {
131
- ":visited": {
132
- color: light ? pink : linkPurple
133
- }
134
- } : Object.freeze({});
135
- const activeVisited = visitable ? {
136
- ":visited": {
137
- color: light ? activeLightVisited : mix(offBlack32, linkPurple)
138
- }
139
- } : Object.freeze({});
136
+ const variant = light ? theme.color.inverse : theme.color.default;
137
+ const focusStyling = {
138
+ color: variant.focus.foreground,
139
+ outline: `${border.width.hairline}px solid ${variant.focus.border}`,
140
+ borderRadius: border.radius.small_3
141
+ };
142
+ const pressStyling = {
143
+ color: variant.press.foreground,
144
+ textDecoration: "underline currentcolor solid"
145
+ };
140
146
  const newStyles = {
141
- resting: _extends({
142
- color: defaultTextColor
143
- }, defaultVisited),
144
- restingInline: _extends({
145
- color: defaultTextColor,
147
+ rest: {
148
+ color: variant.rest.foreground,
149
+ ":hover": {
150
+ textDecoration: "underline currentcolor solid",
151
+ color: variant.hover.foreground
152
+ },
153
+ ":focus-visible": focusStyling,
154
+ ":active": pressStyling
155
+ },
156
+ restInline: {
146
157
  textDecoration: "underline currentcolor solid",
147
158
  textUnderlineOffset: 2
148
- }, defaultVisited),
149
- hover: _extends({
150
- textDecoration: "underline currentcolor solid",
151
- color: defaultTextColor
152
- }, defaultVisited),
153
- focus: {
154
- ":focus-visible": _extends({
155
- color: defaultTextColor,
156
- outline: `1px solid ${light ? white : blue}`,
157
- borderRadius: 3
158
- }, defaultVisited)
159
159
  },
160
- active: _extends({
161
- color: activeColor,
162
- textDecoration: "underline currentcolor solid"
163
- }, activeVisited)
160
+ focus: focusStyling,
161
+ press: pressStyling
164
162
  };
165
163
  styles[buttonType] = StyleSheet.create(newStyles);
166
164
  return styles[buttonType];
167
165
  };
168
166
 
169
- const _excluded = ["onClick", "beforeNav", "safeWithNav", "href", "skipClientNav", "children", "tabIndex", "onKeyDown", "onKeyUp", "target", "inline", "kind", "light", "visitable"];
167
+ const _excluded = ["onClick", "beforeNav", "safeWithNav", "href", "skipClientNav", "children", "tabIndex", "onKeyDown", "onKeyUp", "target", "inline", "light"];
170
168
  const Link = React.forwardRef(function Link(props, ref) {
171
169
  const {
172
170
  onClick,
@@ -180,9 +178,7 @@ const Link = React.forwardRef(function Link(props, ref) {
180
178
  onKeyUp,
181
179
  target = undefined,
182
180
  inline = false,
183
- kind = "primary",
184
- light = false,
185
- visitable = false
181
+ light = false
186
182
  } = props,
187
183
  sharedProps = _objectWithoutPropertiesLoose(props, _excluded);
188
184
  const renderClickableBehavior = router => {
@@ -205,9 +201,7 @@ const Link = React.forwardRef(function Link(props, ref) {
205
201
  target: target,
206
202
  tabIndex: tabIndex,
207
203
  inline: inline,
208
- kind: kind,
209
204
  light: light,
210
- visitable: visitable,
211
205
  ref: ref
212
206
  }), children);
213
207
  });
@@ -229,9 +223,7 @@ const Link = React.forwardRef(function Link(props, ref) {
229
223
  target: target,
230
224
  tabIndex: tabIndex,
231
225
  inline: inline,
232
- kind: kind,
233
226
  light: light,
234
- visitable: visitable,
235
227
  ref: ref
236
228
  }), children);
237
229
  });
package/dist/index.js CHANGED
@@ -39,7 +39,7 @@ var _objectWithoutPropertiesLoose__default = /*#__PURE__*/_interopDefaultLegacy(
39
39
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
40
40
  var externalLinkIcon__default = /*#__PURE__*/_interopDefaultLegacy(externalLinkIcon);
41
41
 
42
- const _excluded$1 = ["children", "skipClientNav", "focused", "hovered", "href", "inline", "kind", "light", "visitable", "pressed", "style", "testId", "waiting", "target", "startIcon", "endIcon"];
42
+ const _excluded$1 = ["children", "skipClientNav", "focused", "hovered", "href", "inline", "light", "pressed", "style", "testId", "waiting", "target", "startIcon", "endIcon"];
43
43
  const StyledA = wonderBlocksCore.addStyle("a");
44
44
  const StyledLink = wonderBlocksCore.addStyle(reactRouterDom.Link);
45
45
  const LinkCore = React__namespace.forwardRef(function LinkCore(props, ref) {
@@ -48,12 +48,9 @@ const LinkCore = React__namespace.forwardRef(function LinkCore(props, ref) {
48
48
  children,
49
49
  skipClientNav,
50
50
  focused,
51
- hovered,
52
51
  href,
53
52
  inline = false,
54
- kind = "primary",
55
53
  light = false,
56
- visitable = false,
57
54
  pressed,
58
55
  style,
59
56
  testId,
@@ -62,9 +59,8 @@ const LinkCore = React__namespace.forwardRef(function LinkCore(props, ref) {
62
59
  endIcon
63
60
  } = props,
64
61
  restProps = _objectWithoutPropertiesLoose__default["default"](props, _excluded$1);
65
- const linkStyles = _generateStyles(inline, kind, light, visitable);
66
- const restingStyles = inline ? linkStyles.restingInline : linkStyles.resting;
67
- const defaultStyles = [sharedStyles.shared, restingStyles, pressed && linkStyles.active, !pressed && hovered && linkStyles.hover, !pressed && focused && linkStyles.focus];
62
+ const linkStyles = _generateStyles(inline, light);
63
+ const defaultStyles = [sharedStyles.shared, linkStyles.rest, inline && linkStyles.restInline, !pressed && focused && linkStyles.focus];
68
64
  const commonProps = _extends__default["default"]({
69
65
  "data-testid": testId,
70
66
  style: [defaultStyles, style],
@@ -125,76 +121,78 @@ const sharedStyles = aphrodite.StyleSheet.create({
125
121
  alignItems: "center"
126
122
  }
127
123
  });
128
- const _generateStyles = (inline, kind, light, visitable) => {
129
- const buttonType = `${kind}-${inline.toString()}-${light.toString()}-${visitable.toString()}`;
124
+ const action = wonderBlocksTokens.semanticColor.action.secondary.progressive;
125
+ const theme = {
126
+ color: {
127
+ default: {
128
+ rest: {
129
+ foreground: action.default.foreground
130
+ },
131
+ hover: {
132
+ foreground: action.hover.foreground
133
+ },
134
+ focus: {
135
+ border: wonderBlocksTokens.semanticColor.focus.outer,
136
+ foreground: action.hover.foreground
137
+ },
138
+ press: {
139
+ foreground: action.press.foreground
140
+ }
141
+ },
142
+ inverse: {
143
+ rest: {
144
+ foreground: wonderBlocksTokens.semanticColor.text.inverse
145
+ },
146
+ hover: {
147
+ foreground: wonderBlocksTokens.semanticColor.text.inverse
148
+ },
149
+ focus: {
150
+ border: wonderBlocksTokens.semanticColor.border.inverse,
151
+ foreground: wonderBlocksTokens.semanticColor.text.inverse
152
+ },
153
+ press: {
154
+ foreground: wonderBlocksTokens.color.fadedBlue
155
+ }
156
+ }
157
+ }
158
+ };
159
+ const _generateStyles = (inline, light) => {
160
+ const buttonType = `${inline.toString()}-${light.toString()}`;
130
161
  if (styles[buttonType]) {
131
162
  return styles[buttonType];
132
163
  }
133
- if (kind === "secondary" && light) {
134
- throw new Error("Secondary Light links are not supported");
135
- }
136
- if (visitable && kind !== "primary") {
137
- throw new Error("Only primary link is visitable");
138
- }
139
- const {
140
- blue,
141
- purple,
142
- white,
143
- offBlack,
144
- offBlack32,
145
- offBlack64
146
- } = wonderBlocksTokens.color;
147
- const pink = "#fa50ae";
148
- const linkPurple = wonderBlocksTokens.mix(wonderBlocksTokens.fade(offBlack, 0.08), purple);
149
- const fadedBlue = wonderBlocksTokens.color.fadedBlue;
150
- const activeLightVisited = wonderBlocksTokens.mix(wonderBlocksTokens.fade(white, 0.32), pink);
151
- const activeDefaultPrimary = wonderBlocksTokens.color.activeBlue;
152
- const primaryDefaultTextColor = light ? white : blue;
153
- const secondaryDefaultTextColor = inline ? offBlack : offBlack64;
154
- const defaultTextColor = kind === "primary" ? primaryDefaultTextColor : secondaryDefaultTextColor;
155
- const primaryActiveColor = light ? fadedBlue : activeDefaultPrimary;
156
- const secondaryActiveColor = inline ? activeDefaultPrimary : offBlack;
157
- const activeColor = kind === "primary" ? primaryActiveColor : secondaryActiveColor;
158
- const defaultVisited = visitable ? {
159
- ":visited": {
160
- color: light ? pink : linkPurple
161
- }
162
- } : Object.freeze({});
163
- const activeVisited = visitable ? {
164
- ":visited": {
165
- color: light ? activeLightVisited : wonderBlocksTokens.mix(offBlack32, linkPurple)
166
- }
167
- } : Object.freeze({});
164
+ const variant = light ? theme.color.inverse : theme.color.default;
165
+ const focusStyling = {
166
+ color: variant.focus.foreground,
167
+ outline: `${wonderBlocksTokens.border.width.hairline}px solid ${variant.focus.border}`,
168
+ borderRadius: wonderBlocksTokens.border.radius.small_3
169
+ };
170
+ const pressStyling = {
171
+ color: variant.press.foreground,
172
+ textDecoration: "underline currentcolor solid"
173
+ };
168
174
  const newStyles = {
169
- resting: _extends__default["default"]({
170
- color: defaultTextColor
171
- }, defaultVisited),
172
- restingInline: _extends__default["default"]({
173
- color: defaultTextColor,
175
+ rest: {
176
+ color: variant.rest.foreground,
177
+ ":hover": {
178
+ textDecoration: "underline currentcolor solid",
179
+ color: variant.hover.foreground
180
+ },
181
+ ":focus-visible": focusStyling,
182
+ ":active": pressStyling
183
+ },
184
+ restInline: {
174
185
  textDecoration: "underline currentcolor solid",
175
186
  textUnderlineOffset: 2
176
- }, defaultVisited),
177
- hover: _extends__default["default"]({
178
- textDecoration: "underline currentcolor solid",
179
- color: defaultTextColor
180
- }, defaultVisited),
181
- focus: {
182
- ":focus-visible": _extends__default["default"]({
183
- color: defaultTextColor,
184
- outline: `1px solid ${light ? white : blue}`,
185
- borderRadius: 3
186
- }, defaultVisited)
187
187
  },
188
- active: _extends__default["default"]({
189
- color: activeColor,
190
- textDecoration: "underline currentcolor solid"
191
- }, activeVisited)
188
+ focus: focusStyling,
189
+ press: pressStyling
192
190
  };
193
191
  styles[buttonType] = aphrodite.StyleSheet.create(newStyles);
194
192
  return styles[buttonType];
195
193
  };
196
194
 
197
- const _excluded = ["onClick", "beforeNav", "safeWithNav", "href", "skipClientNav", "children", "tabIndex", "onKeyDown", "onKeyUp", "target", "inline", "kind", "light", "visitable"];
195
+ const _excluded = ["onClick", "beforeNav", "safeWithNav", "href", "skipClientNav", "children", "tabIndex", "onKeyDown", "onKeyUp", "target", "inline", "light"];
198
196
  const Link = React__namespace.forwardRef(function Link(props, ref) {
199
197
  const {
200
198
  onClick,
@@ -208,9 +206,7 @@ const Link = React__namespace.forwardRef(function Link(props, ref) {
208
206
  onKeyUp,
209
207
  target = undefined,
210
208
  inline = false,
211
- kind = "primary",
212
- light = false,
213
- visitable = false
209
+ light = false
214
210
  } = props,
215
211
  sharedProps = _objectWithoutPropertiesLoose__default["default"](props, _excluded);
216
212
  const renderClickableBehavior = router => {
@@ -233,9 +229,7 @@ const Link = React__namespace.forwardRef(function Link(props, ref) {
233
229
  target: target,
234
230
  tabIndex: tabIndex,
235
231
  inline: inline,
236
- kind: kind,
237
232
  light: light,
238
- visitable: visitable,
239
233
  ref: ref
240
234
  }), children);
241
235
  });
@@ -257,9 +251,7 @@ const Link = React__namespace.forwardRef(function Link(props, ref) {
257
251
  target: target,
258
252
  tabIndex: tabIndex,
259
253
  inline: inline,
260
- kind: kind,
261
254
  light: light,
262
- visitable: visitable,
263
255
  ref: ref
264
256
  }), children);
265
257
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khanacademy/wonder-blocks-link",
3
- "version": "7.1.1",
3
+ "version": "8.0.0",
4
4
  "design": "v1",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -13,10 +13,10 @@
13
13
  "license": "MIT",
14
14
  "dependencies": {
15
15
  "@babel/runtime": "^7.24.5",
16
- "@khanacademy/wonder-blocks-clickable": "6.1.1",
17
- "@khanacademy/wonder-blocks-core": "12.1.1",
18
- "@khanacademy/wonder-blocks-icon": "5.1.1",
19
- "@khanacademy/wonder-blocks-tokens": "4.2.1"
16
+ "@khanacademy/wonder-blocks-clickable": "6.1.2",
17
+ "@khanacademy/wonder-blocks-core": "12.2.0",
18
+ "@khanacademy/wonder-blocks-icon": "5.1.2",
19
+ "@khanacademy/wonder-blocks-tokens": "5.0.0"
20
20
  },
21
21
  "peerDependencies": {
22
22
  "@phosphor-icons/core": "^2.0.2",