@khanacademy/wonder-blocks-link 3.8.16 → 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.
- package/CHANGELOG.md +18 -0
- package/dist/es/index.js +44 -18
- package/dist/index.js +242 -0
- package/package.json +4 -4
- package/src/__tests__/__snapshots__/custom-snapshot.test.js.snap +1445 -62
- package/src/__tests__/custom-snapshot.test.js +30 -27
- package/src/components/__docs__/link.argtypes.js +8 -0
- package/src/components/__docs__/link.stories.js +326 -36
- package/src/components/__tests__/link.test.js +102 -0
- package/src/components/link-core.js +62 -22
- package/src/components/link.js +9 -0
|
@@ -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) &&
|
|
51
|
-
pressed
|
|
52
|
-
|
|
53
|
-
|
|
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
|
|
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 &&
|
|
103
|
-
throw new Error("Only primary
|
|
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"
|
|
132
|
+
kind === "primary"
|
|
133
|
+
? primaryDefaultTextColor
|
|
134
|
+
: secondaryDefaultTextColor;
|
|
111
135
|
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
:
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
139
|
-
|
|
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
|
};
|
package/src/components/link.js
CHANGED
|
@@ -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,
|