@khanacademy/wonder-blocks-cell 2.0.0 → 2.1.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-cell
2
2
 
3
+ ## 2.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 9819c13f: Add href prop for client-side navigation
8
+
9
+ ## 2.0.2
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies [246a921d]
14
+ - @khanacademy/wonder-blocks-core@4.3.0
15
+ - @khanacademy/wonder-blocks-clickable@2.2.5
16
+ - @khanacademy/wonder-blocks-layout@1.4.8
17
+ - @khanacademy/wonder-blocks-typography@1.1.30
18
+
19
+ ## 2.0.1
20
+
21
+ ### Patch Changes
22
+
23
+ - 166ecc97: Use `aria-disabled` instead of disabled, fix focused + disabled styles.
24
+ - Updated dependencies [166ecc97]
25
+ - @khanacademy/wonder-blocks-clickable@2.2.4
26
+
3
27
  ## 2.0.0
4
28
 
5
29
  ### Major Changes
package/dist/es/index.js CHANGED
@@ -134,6 +134,7 @@ const CellCore = props => {
134
134
  active,
135
135
  children,
136
136
  disabled,
137
+ href,
137
138
  horizontalRule = "inset",
138
139
  leftAccessory = undefined,
139
140
  leftAccessoryStyle = undefined,
@@ -176,10 +177,11 @@ const CellCore = props => {
176
177
  }; // Pressable cell.
177
178
 
178
179
 
179
- if (onClick) {
180
+ if (onClick || href) {
180
181
  return /*#__PURE__*/React.createElement(Clickable, {
181
182
  disabled: disabled,
182
183
  onClick: onClick,
184
+ href: href,
183
185
  hideDefaultFocusRing: true,
184
186
  "aria-label": ariaLabel ? ariaLabel : undefined
185
187
  }, eventState => renderCell(eventState));
@@ -255,7 +257,10 @@ const styles$1 = StyleSheet.create({
255
257
  background: fade(Color.blue, 0.24)
256
258
  },
257
259
  disabled: {
258
- color: Color.offBlack32
260
+ color: Color.offBlack32,
261
+ ":hover": {
262
+ cursor: "not-allowed"
263
+ }
259
264
  },
260
265
  accessoryActive: {
261
266
  color: Color.blue
package/dist/index.js CHANGED
@@ -299,6 +299,7 @@ const CellCore = props => {
299
299
  active,
300
300
  children,
301
301
  disabled,
302
+ href,
302
303
  horizontalRule = "inset",
303
304
  leftAccessory = undefined,
304
305
  leftAccessoryStyle = undefined,
@@ -341,10 +342,11 @@ const CellCore = props => {
341
342
  }; // Pressable cell.
342
343
 
343
344
 
344
- if (onClick) {
345
+ if (onClick || href) {
345
346
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_clickable__WEBPACK_IMPORTED_MODULE_2___default.a, {
346
347
  disabled: disabled,
347
348
  onClick: onClick,
349
+ href: href,
348
350
  hideDefaultFocusRing: true,
349
351
  "aria-label": ariaLabel ? ariaLabel : undefined
350
352
  }, eventState => renderCell(eventState));
@@ -420,7 +422,10 @@ const styles = aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
420
422
  background: Object(_khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_4__["fade"])(_khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_4___default.a.blue, 0.24)
421
423
  },
422
424
  disabled: {
423
- color: _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_4___default.a.offBlack32
425
+ color: _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_4___default.a.offBlack32,
426
+ ":hover": {
427
+ cursor: "not-allowed"
428
+ }
424
429
  },
425
430
  accessoryActive: {
426
431
  color: _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_4___default.a.blue
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khanacademy/wonder-blocks-cell",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "design": "v1",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -14,12 +14,12 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "@babel/runtime": "^7.16.3",
17
- "@khanacademy/wonder-blocks-clickable": "^2.2.3",
17
+ "@khanacademy/wonder-blocks-clickable": "^2.2.5",
18
18
  "@khanacademy/wonder-blocks-color": "^1.1.20",
19
- "@khanacademy/wonder-blocks-core": "^4.2.1",
20
- "@khanacademy/wonder-blocks-layout": "^1.4.7",
19
+ "@khanacademy/wonder-blocks-core": "^4.3.0",
20
+ "@khanacademy/wonder-blocks-layout": "^1.4.8",
21
21
  "@khanacademy/wonder-blocks-spacing": "^3.0.5",
22
- "@khanacademy/wonder-blocks-typography": "^1.1.29"
22
+ "@khanacademy/wonder-blocks-typography": "^1.1.30"
23
23
  },
24
24
  "peerDependencies": {
25
25
  "aphrodite": "^1.2.5",
@@ -27,7 +27,7 @@ export const AccessoryMappings = {
27
27
  </View>
28
28
  ): React.Element<typeof View>),
29
29
  withImage: ((
30
- <img src="/avatar.png" alt="ItemAvatar" width={48} height={48} />
30
+ <img src="./avatar.png" alt="ItemAvatar" width={48} height={48} />
31
31
  ): React$Element<"img">),
32
32
  };
33
33
 
@@ -121,6 +121,17 @@ export default {
121
121
  },
122
122
  },
123
123
  },
124
+ href: {
125
+ description:
126
+ "Optional href which Cell should direct to, uses client-side routing by default if react-router is present.",
127
+ control: {type: "text"},
128
+ table: {
129
+ category: "Navigation",
130
+ type: {
131
+ summary: "string",
132
+ },
133
+ },
134
+ },
124
135
  onClick: {
125
136
  action: "clicked",
126
137
  description: `Called when the cell is clicked.
@@ -1,6 +1,7 @@
1
1
  // @flow
2
2
  import * as React from "react";
3
3
  import {StyleSheet} from "aphrodite";
4
+ import {MemoryRouter, Route, Switch} from "react-router-dom";
4
5
 
5
6
  import {View} from "@khanacademy/wonder-blocks-core";
6
7
  import Color from "@khanacademy/wonder-blocks-color";
@@ -145,10 +146,61 @@ ClickableDetailCell.parameters = {
145
146
  },
146
147
  };
147
148
 
149
+ export const DetailCellNavigation: StoryComponentType = () => (
150
+ <MemoryRouter>
151
+ <View>
152
+ <DetailCell
153
+ title="Data"
154
+ subtitle2="Subtitle for article item"
155
+ leftAccessory={<Icon icon={icons.contentVideo} size="medium" />}
156
+ rightAccessory={<Icon icon={icons.caretRight} />}
157
+ href="/math/algebra"
158
+ aria-label="Press to navigate to the article"
159
+ />
160
+ <DetailCell
161
+ title="Geometry"
162
+ subtitle2="Subtitle for article item"
163
+ leftAccessory={<Icon icon={icons.contentVideo} size="medium" />}
164
+ rightAccessory={<Icon icon={icons.caretRight} />}
165
+ href="/math/geometry"
166
+ aria-label="Press to navigate to the article"
167
+ horizontalRule="none"
168
+ />
169
+ </View>
170
+
171
+ <View style={styles.navigation}>
172
+ <Switch>
173
+ <Route path="/math/algebra">Navigates to /math/algebra</Route>
174
+ <Route path="/math/geometry">Navigates to /math/geometry</Route>
175
+ <Route path="*">See navigation changes here</Route>
176
+ </Switch>
177
+ </View>
178
+ </MemoryRouter>
179
+ );
180
+
181
+ DetailCellNavigation.storyName = "Client-side navigation with DetailCell";
182
+
183
+ DetailCellNavigation.parameters = {
184
+ chromatic: {
185
+ // This only includes interactions with the clickable cell, so no need
186
+ // to capture screenshots.
187
+ disableSnapshot: true,
188
+ },
189
+ docs: {
190
+ storyDescription:
191
+ "Cells accept an `href` prop to be able to navigate to a different URL. Note that this will use client-side navigation if the Cell component is within a React-Router environment.",
192
+ },
193
+ };
194
+
148
195
  const styles = StyleSheet.create({
149
196
  example: {
150
197
  backgroundColor: Color.offWhite,
151
198
  padding: Spacing.large_24,
152
199
  width: 376,
153
200
  },
201
+ navigation: {
202
+ border: `1px dashed ${Color.lightBlue}`,
203
+ marginTop: Spacing.large_24,
204
+ padding: Spacing.large_24,
205
+ },
154
206
  });
@@ -47,6 +47,20 @@ describe("CellCore", () => {
47
47
  expect(screen.getByRole("button")).toBeInTheDocument();
48
48
  });
49
49
 
50
+ it("should add an anchor if href is set", () => {
51
+ // Arrange
52
+
53
+ // Act
54
+ render(
55
+ <CellCore href="/math">
56
+ <div>cell core content</div>
57
+ </CellCore>,
58
+ );
59
+
60
+ // Assert
61
+ expect(screen.getByRole("link")).toHaveAttribute("href", "/math");
62
+ });
63
+
50
64
  it("should add aria-label to the button", () => {
51
65
  // Arrange
52
66
 
@@ -74,7 +88,10 @@ describe("CellCore", () => {
74
88
  );
75
89
 
76
90
  // Assert
77
- expect(screen.getByRole("button")).toBeDisabled();
91
+ expect(screen.getByRole("button")).toHaveAttribute(
92
+ "aria-disabled",
93
+ "true",
94
+ );
78
95
  });
79
96
 
80
97
  it("should add aria-current if active is set", () => {
@@ -119,6 +119,7 @@ const CellCore = (props: CellCoreProps): React.Node => {
119
119
  active,
120
120
  children,
121
121
  disabled,
122
+ href,
122
123
  horizontalRule = "inset",
123
124
  leftAccessory = undefined,
124
125
  leftAccessoryStyle = undefined,
@@ -191,11 +192,12 @@ const CellCore = (props: CellCoreProps): React.Node => {
191
192
  };
192
193
 
193
194
  // Pressable cell.
194
- if (onClick) {
195
+ if (onClick || href) {
195
196
  return (
196
197
  <Clickable
197
198
  disabled={disabled}
198
199
  onClick={onClick}
200
+ href={href}
199
201
  hideDefaultFocusRing={true}
200
202
  aria-label={ariaLabel ? ariaLabel : undefined}
201
203
  >
@@ -285,6 +287,9 @@ const styles = StyleSheet.create({
285
287
 
286
288
  disabled: {
287
289
  color: Color.offBlack32,
290
+ ":hover": {
291
+ cursor: "not-allowed",
292
+ },
288
293
  },
289
294
 
290
295
  accessoryActive: {
package/src/util/types.js CHANGED
@@ -126,4 +126,10 @@ export type CellProps = {|
126
126
  * Used to announce the cell's content to screen readers.
127
127
  */
128
128
  "aria-label"?: string,
129
+
130
+ /**
131
+ * Optinal href which Cell should direct to, uses client-side routing
132
+ * by default if react-router is present.
133
+ */
134
+ href?: string,
129
135
  |};