@khanacademy/wonder-blocks-link 3.8.17 → 3.9.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.
@@ -33,6 +33,7 @@ export default class LinkCore extends React.Component<Props> {
33
33
  focused,
34
34
  hovered,
35
35
  href,
36
+ inline,
36
37
  kind,
37
38
  light,
38
39
  visitable,
@@ -43,14 +44,22 @@ export default class LinkCore extends React.Component<Props> {
43
44
  ...restProps
44
45
  } = this.props;
45
46
 
46
- const linkStyles = _generateStyles(kind, light, visitable);
47
+ const linkStyles = _generateStyles(inline, kind, light, visitable);
48
+ const restingStyles = inline
49
+ ? linkStyles.restingInline
50
+ : linkStyles.resting;
47
51
 
48
52
  const defaultStyles = [
49
53
  sharedStyles.shared,
50
- !(hovered || focused || pressed) && linkStyles.default,
51
- pressed
52
- ? linkStyles.active
53
- : (hovered || focused) && linkStyles.focus,
54
+ !(hovered || focused || pressed) && restingStyles,
55
+ pressed && linkStyles.active,
56
+ // A11y: The focus ring should always be present when the
57
+ // the link has focus, even the link is being hovered over.
58
+ // TODO(WB-1498): Udpate ClickableBehavior so that focus doesn't
59
+ // stop on mouseleave. We want the focus ring to remain on a
60
+ // focused link even after hovering and un-hovering on it.
61
+ !pressed && hovered && linkStyles.hover,
62
+ !pressed && focused && linkStyles.focus,
54
63
  ];
55
64
 
56
65
  const commonProps = {
@@ -86,11 +95,14 @@ const sharedStyles = StyleSheet.create({
86
95
  cursor: "pointer",
87
96
  textDecoration: "none",
88
97
  outline: "none",
98
+ display: "inline-flex",
99
+ fontSize: 16,
100
+ lineHeight: "22px",
89
101
  },
90
102
  });
91
103
 
92
- const _generateStyles = (kind, light, visitable) => {
93
- const buttonType = kind + light.toString() + visitable.toString();
104
+ const _generateStyles = (inline, kind, light, visitable) => {
105
+ const buttonType = `${kind}-${inline.toString()}-${light.toString()}-${visitable.toString()}`;
94
106
  if (styles[buttonType]) {
95
107
  return styles[buttonType];
96
108
  }
@@ -99,49 +111,77 @@ const _generateStyles = (kind, light, visitable) => {
99
111
  throw new Error("Secondary Light links are not supported");
100
112
  }
101
113
 
102
- if (visitable && (kind !== "primary" || (kind === "primary" && light))) {
103
- throw new Error("Only primary (not light) link is visitable");
114
+ if (visitable && kind !== "primary") {
115
+ throw new Error("Only primary link is visitable");
104
116
  }
105
117
 
106
- const {blue, purple, white, offBlack, offBlack32} = Color;
107
- const linkPurple = mix(fade(offBlack, 0.08), purple);
118
+ const {blue, pink, purple, white, offBlack, offBlack32, offBlack64} = Color;
108
119
 
120
+ // Standard purple
121
+ const linkPurple = mix(fade(offBlack, 0.08), purple);
122
+ // Light blue
123
+ const fadedBlue = mix(fade(blue, 0.32), white);
124
+ // Light pink
125
+ const activeLightVisited = mix(fade(white, 0.32), pink);
126
+ // Dark blue
127
+ const activeDefaultPrimary = mix(offBlack32, blue);
128
+
129
+ const primaryDefaultTextColor = light ? white : blue;
130
+ const secondaryDefaultTextColor = inline ? offBlack : offBlack64;
109
131
  const defaultTextColor =
110
- kind === "primary" ? (light ? white : blue) : offBlack;
132
+ kind === "primary"
133
+ ? primaryDefaultTextColor
134
+ : secondaryDefaultTextColor;
111
135
 
112
- const focusColor: string = light ? white : blue;
113
- const activeColor: string = light
114
- ? mix(fade(blue, 0.32), white)
115
- : mix(offBlack32, blue);
136
+ const primaryActiveColor = light ? fadedBlue : activeDefaultPrimary;
137
+ const secondaryActiveColor = inline ? activeDefaultPrimary : offBlack;
138
+ const activeColor =
139
+ kind === "primary" ? primaryActiveColor : secondaryActiveColor;
116
140
 
117
141
  const defaultVisited = visitable
118
142
  ? {
119
143
  ":visited": {
120
- color: linkPurple,
144
+ color: light ? pink : linkPurple,
121
145
  },
122
146
  }
123
147
  : Object.freeze({});
124
148
  const activeVisited = visitable
125
149
  ? {
126
150
  ":visited": {
127
- color: mix(offBlack32, linkPurple),
151
+ color: light
152
+ ? activeLightVisited
153
+ : mix(offBlack32, linkPurple),
128
154
  },
129
155
  }
130
156
  : Object.freeze({});
131
157
 
132
158
  const newStyles: StyleDeclaration = {
133
- default: {
159
+ resting: {
160
+ color: defaultTextColor,
161
+ ...defaultVisited,
162
+ },
163
+ restingInline: {
134
164
  color: defaultTextColor,
165
+ textDecoration: "underline currentcolor solid 1px",
166
+ textUnderlineOffset: 4,
167
+ ...defaultVisited,
168
+ },
169
+ hover: {
170
+ textDecoration: "underline currentcolor dashed 2px",
171
+ color: defaultTextColor,
172
+ textUnderlineOffset: 4,
135
173
  ...defaultVisited,
136
174
  },
137
175
  focus: {
138
- textDecoration: "underline currentcolor solid",
139
- color: focusColor,
176
+ color: defaultTextColor,
177
+ outline: `1px solid ${light ? white : blue}`,
178
+ borderRadius: 3,
140
179
  ...defaultVisited,
141
180
  },
142
181
  active: {
143
182
  color: activeColor,
144
- textDecoration: "underline currentcolor solid",
183
+ textDecoration: "underline currentcolor solid 1px",
184
+ textUnderlineOffset: 4,
145
185
  ...activeVisited,
146
186
  },
147
187
  };
@@ -25,6 +25,13 @@ type CommonProps = {|
25
25
  */
26
26
  id?: string,
27
27
 
28
+ /**
29
+ * Indicates that this link is used within a body of text.
30
+ * This styles the link with an underline to distinguish it
31
+ * from surrounding text.
32
+ */
33
+ inline: boolean,
34
+
28
35
  /**
29
36
  * Kind of Link. Note: Secondary light Links are not supported.
30
37
  */
@@ -159,6 +166,7 @@ export type SharedProps =
159
166
  |};
160
167
 
161
168
  type DefaultProps = {|
169
+ inline: $PropertyType<SharedProps, "inline">,
162
170
  kind: $PropertyType<SharedProps, "kind">,
163
171
  light: $PropertyType<SharedProps, "light">,
164
172
  visitable: $PropertyType<SharedProps, "visitable">,
@@ -184,6 +192,7 @@ type DefaultProps = {|
184
192
  */
185
193
  export default class Link extends React.Component<SharedProps> {
186
194
  static defaultProps: DefaultProps = {
195
+ inline: false,
187
196
  kind: "primary",
188
197
  light: false,
189
198
  visitable: false,