@khanacademy/wonder-blocks-core 7.0.0 → 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 +12 -0
- package/dist/components/text.d.ts +2 -2
- package/dist/es/index.js +4 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -3
- package/dist/util/add-style.d.ts +1 -1
- package/package.json +7 -7
- package/src/components/__tests__/__snapshots__/view.test.tsx.snap +0 -55
- package/src/components/__tests__/id-provider.test.tsx +0 -48
- package/src/components/__tests__/initial-fallback.test.tsx +0 -258
- package/src/components/__tests__/render-state-root.test.tsx +0 -86
- package/src/components/__tests__/text.test.tsx +0 -44
- package/src/components/__tests__/unique-id-provider.test.tsx +0 -188
- package/src/components/__tests__/view.test.tsx +0 -60
- package/src/components/id-provider.tsx +0 -87
- package/src/components/initial-fallback.tsx +0 -170
- package/src/components/render-state-context.ts +0 -29
- package/src/components/render-state-root.tsx +0 -47
- package/src/components/text.tsx +0 -73
- package/src/components/unique-id-provider.tsx +0 -111
- package/src/components/view.tsx +0 -102
- package/src/hooks/__tests__/use-force-update.test.tsx +0 -121
- package/src/hooks/__tests__/use-is-mounted.test.tsx +0 -87
- package/src/hooks/__tests__/use-latest-ref.test.ts +0 -40
- package/src/hooks/__tests__/use-latest-ref.typestest.ts +0 -21
- package/src/hooks/__tests__/use-on-mount-effect.test.ts +0 -30
- package/src/hooks/__tests__/use-online.test.tsx +0 -69
- package/src/hooks/__tests__/use-pre-hydration-effect.test.tsx +0 -88
- package/src/hooks/__tests__/use-render-state.test.tsx +0 -56
- package/src/hooks/__tests__/use-unique-id.test.tsx +0 -256
- package/src/hooks/use-force-update.ts +0 -28
- package/src/hooks/use-is-mounted.ts +0 -32
- package/src/hooks/use-latest-ref.ts +0 -17
- package/src/hooks/use-on-mount-effect.ts +0 -34
- package/src/hooks/use-online.ts +0 -28
- package/src/hooks/use-pre-hydration-effect.ts +0 -47
- package/src/hooks/use-render-state.ts +0 -10
- package/src/hooks/use-unique-id.ts +0 -68
- package/src/index.ts +0 -29
- package/src/util/__tests__/__snapshots__/unique-id-factory.test.ts.snap +0 -7
- package/src/util/__tests__/add-style.test.tsx +0 -111
- package/src/util/__tests__/server.test.ts +0 -36
- package/src/util/__tests__/ssr-id-factory.test.ts +0 -13
- package/src/util/__tests__/unique-id-factory.test.ts +0 -164
- package/src/util/add-style.js.flow +0 -13
- package/src/util/add-style.tsx +0 -254
- package/src/util/add-styles.typestest.tsx +0 -21
- package/src/util/aria-types.ts +0 -304
- package/src/util/server.md +0 -24
- package/src/util/server.ts +0 -18
- package/src/util/ssr-id-factory.ts +0 -21
- package/src/util/types.propsfor.js.flow +0 -9
- package/src/util/types.propsfor.ts +0 -14
- package/src/util/types.ts +0 -112
- package/src/util/unique-id-factory.ts +0 -61
- package/src/util/util.ts +0 -91
- package/tsconfig-build.json +0 -11
- package/tsconfig-build.tsbuildinfo +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @khanacademy/wonder-blocks-core
|
|
2
2
|
|
|
3
|
+
## 8.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- e6abdd17: Upgrade to React 18
|
|
8
|
+
|
|
9
|
+
## 7.0.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 02a1b298: Make sure we don't package tsconfig and tsbuildinfo files
|
|
14
|
+
|
|
3
15
|
## 7.0.0
|
|
4
16
|
|
|
5
17
|
### Major Changes
|
|
@@ -23,8 +23,8 @@ declare const Text: React.ForwardRefExoticComponent<{
|
|
|
23
23
|
title?: string | undefined;
|
|
24
24
|
"data-modal-launcher-portal"?: boolean | undefined;
|
|
25
25
|
"data-placement"?: string | undefined;
|
|
26
|
-
} & Readonly<import("
|
|
27
|
-
role?: import("
|
|
26
|
+
} & Readonly<import("..").AriaAttributes> & Readonly<{
|
|
27
|
+
role?: import("..").AriaRole | undefined;
|
|
28
28
|
}> & {
|
|
29
29
|
onMouseDown?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
|
|
30
30
|
onMouseUp?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
|
package/dist/es/index.js
CHANGED
|
@@ -90,11 +90,12 @@ const Text = React.forwardRef(function Text(_ref, ref) {
|
|
|
90
90
|
const _excluded$1 = ["className", "style"];
|
|
91
91
|
function addStyle(Component, defaultStyle) {
|
|
92
92
|
return React.forwardRef((props, ref) => {
|
|
93
|
-
const
|
|
93
|
+
const _ref = props,
|
|
94
|
+
{
|
|
94
95
|
className,
|
|
95
96
|
style
|
|
96
|
-
} =
|
|
97
|
-
otherProps = _objectWithoutPropertiesLoose(
|
|
97
|
+
} = _ref,
|
|
98
|
+
otherProps = _objectWithoutPropertiesLoose(_ref, _excluded$1);
|
|
98
99
|
const reset = typeof Component === "string" ? overrides[Component] : null;
|
|
99
100
|
const {
|
|
100
101
|
className: aphroditeClassName,
|
package/dist/index.d.ts
CHANGED
|
@@ -16,4 +16,5 @@ export { usePreHydrationEffect } from "./hooks/use-pre-hydration-effect";
|
|
|
16
16
|
export { useRenderState } from "./hooks/use-render-state";
|
|
17
17
|
export { RenderStateRoot } from "./components/render-state-root";
|
|
18
18
|
export { RenderState } from "./components/render-state-context";
|
|
19
|
+
export type { AriaRole, AriaAttributes } from "./util/aria-types";
|
|
19
20
|
export type { AriaProps, IIdentifierFactory, StyleType, PropsFor };
|
package/dist/index.js
CHANGED
|
@@ -117,11 +117,12 @@ const Text = React__namespace.forwardRef(function Text(_ref, ref) {
|
|
|
117
117
|
const _excluded$1 = ["className", "style"];
|
|
118
118
|
function addStyle(Component, defaultStyle) {
|
|
119
119
|
return React__namespace.forwardRef((props, ref) => {
|
|
120
|
-
const
|
|
120
|
+
const _ref = props,
|
|
121
|
+
{
|
|
121
122
|
className,
|
|
122
123
|
style
|
|
123
|
-
} =
|
|
124
|
-
otherProps = _objectWithoutPropertiesLoose__default["default"](
|
|
124
|
+
} = _ref,
|
|
125
|
+
otherProps = _objectWithoutPropertiesLoose__default["default"](_ref, _excluded$1);
|
|
125
126
|
const reset = typeof Component === "string" ? overrides[Component] : null;
|
|
126
127
|
const {
|
|
127
128
|
className: aphroditeClassName,
|
package/dist/util/add-style.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export default function addStyle<T extends React.ComponentType<any> | keyof JSX.
|
|
|
4
4
|
className?: string;
|
|
5
5
|
style?: StyleType;
|
|
6
6
|
children?: React.ReactNode;
|
|
7
|
-
} & Omit<React.ComponentProps<T>, "style">>(Component: T, defaultStyle?: StyleType): React.ForwardRefExoticComponent<React.PropsWithoutRef<Props> & React.RefAttributes<T extends keyof
|
|
7
|
+
} & Omit<React.ComponentProps<T>, "style">>(Component: T, defaultStyle?: StyleType): React.ForwardRefExoticComponent<React.PropsWithoutRef<Props> & React.RefAttributes<T extends keyof IntrinsicElementsMap ? IntrinsicElementsMap[T] : T>>;
|
|
8
8
|
type IntrinsicElementsMap = {
|
|
9
9
|
a: HTMLAnchorElement;
|
|
10
10
|
abbr: HTMLElement;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@khanacademy/wonder-blocks-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0",
|
|
4
4
|
"design": "v1",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
},
|
|
18
18
|
"peerDependencies": {
|
|
19
19
|
"aphrodite": "^1.2.5",
|
|
20
|
-
"react": "
|
|
21
|
-
"react-dom": "
|
|
22
|
-
"react-router": "5.
|
|
23
|
-
"react-router-dom": "5.3.
|
|
20
|
+
"react": "18.2.0",
|
|
21
|
+
"react-dom": "18.2.0",
|
|
22
|
+
"react-router": "5.3.4",
|
|
23
|
+
"react-router-dom": "5.3.4"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@khanacademy/wb-dev-build-settings": "^
|
|
27
|
-
"@khanacademy/wonder-blocks-testing-core": "^
|
|
26
|
+
"@khanacademy/wb-dev-build-settings": "^2.0.0",
|
|
27
|
+
"@khanacademy/wonder-blocks-testing-core": "^2.0.0"
|
|
28
28
|
},
|
|
29
29
|
"author": "",
|
|
30
30
|
"license": "MIT"
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
-
|
|
3
|
-
exports[`View Should set the tag to be article 1`] = `
|
|
4
|
-
<div>
|
|
5
|
-
<article
|
|
6
|
-
class=""
|
|
7
|
-
style="align-items: stretch; border-width: 0px; border-style: solid; box-sizing: border-box; display: flex; flex-direction: column; margin: 0px; padding: 0px; position: relative; z-index: 0; min-height: 0; min-width: 0;"
|
|
8
|
-
/>
|
|
9
|
-
</div>
|
|
10
|
-
`;
|
|
11
|
-
|
|
12
|
-
exports[`View Should set the tag to be aside 1`] = `
|
|
13
|
-
<div>
|
|
14
|
-
<aside
|
|
15
|
-
class=""
|
|
16
|
-
style="align-items: stretch; border-width: 0px; border-style: solid; box-sizing: border-box; display: flex; flex-direction: column; margin: 0px; padding: 0px; position: relative; z-index: 0; min-height: 0; min-width: 0;"
|
|
17
|
-
/>
|
|
18
|
-
</div>
|
|
19
|
-
`;
|
|
20
|
-
|
|
21
|
-
exports[`View Should set the tag to be div 1`] = `
|
|
22
|
-
<div>
|
|
23
|
-
<div
|
|
24
|
-
class=""
|
|
25
|
-
style="align-items: stretch; border-width: 0px; border-style: solid; box-sizing: border-box; display: flex; flex-direction: column; margin: 0px; padding: 0px; position: relative; z-index: 0; min-height: 0; min-width: 0;"
|
|
26
|
-
/>
|
|
27
|
-
</div>
|
|
28
|
-
`;
|
|
29
|
-
|
|
30
|
-
exports[`View Should set the tag to be nav 1`] = `
|
|
31
|
-
<div>
|
|
32
|
-
<nav
|
|
33
|
-
class=""
|
|
34
|
-
style="align-items: stretch; border-width: 0px; border-style: solid; box-sizing: border-box; display: flex; flex-direction: column; margin: 0px; padding: 0px; position: relative; z-index: 0; min-height: 0; min-width: 0;"
|
|
35
|
-
/>
|
|
36
|
-
</div>
|
|
37
|
-
`;
|
|
38
|
-
|
|
39
|
-
exports[`View Should set the tag to be section 1`] = `
|
|
40
|
-
<div>
|
|
41
|
-
<section
|
|
42
|
-
class=""
|
|
43
|
-
style="align-items: stretch; border-width: 0px; border-style: solid; box-sizing: border-box; display: flex; flex-direction: column; margin: 0px; padding: 0px; position: relative; z-index: 0; min-height: 0; min-width: 0;"
|
|
44
|
-
/>
|
|
45
|
-
</div>
|
|
46
|
-
`;
|
|
47
|
-
|
|
48
|
-
exports[`View Should set the tag to be section 2`] = `
|
|
49
|
-
<div>
|
|
50
|
-
<section
|
|
51
|
-
class=""
|
|
52
|
-
style="align-items: stretch; border-width: 0px; border-style: solid; box-sizing: border-box; display: flex; flex-direction: column; margin: 0px; padding: 0px; position: relative; z-index: 0; min-height: 0; min-width: 0;"
|
|
53
|
-
/>
|
|
54
|
-
</div>
|
|
55
|
-
`;
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import {render} from "@testing-library/react";
|
|
3
|
-
|
|
4
|
-
import IDProvider from "../id-provider";
|
|
5
|
-
|
|
6
|
-
const mockIDENTIFIER = `uid-component-0-${IDProvider.defaultId}`;
|
|
7
|
-
|
|
8
|
-
jest.mock("@khanacademy/wonder-blocks-core", () => {
|
|
9
|
-
const Core = jest.requireActual("@khanacademy/wonder-blocks-core");
|
|
10
|
-
// We want all of Core to be the regular thing except for UniqueIDProvider
|
|
11
|
-
return {
|
|
12
|
-
...Core,
|
|
13
|
-
UniqueIDProvider: (props: any) =>
|
|
14
|
-
// eslint-disable-next-line testing-library/no-node-access
|
|
15
|
-
props.children({
|
|
16
|
-
get: () => mockIDENTIFIER,
|
|
17
|
-
}),
|
|
18
|
-
};
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
describe("UniqueDialog", () => {
|
|
22
|
-
test("renders children if ID is provided", () => {
|
|
23
|
-
// Arrange
|
|
24
|
-
const renderDialogFn = jest.fn(() => <div />);
|
|
25
|
-
const titleId = "custom-title";
|
|
26
|
-
|
|
27
|
-
// Act
|
|
28
|
-
render(
|
|
29
|
-
<IDProvider id={titleId} scope="component">
|
|
30
|
-
{renderDialogFn}
|
|
31
|
-
</IDProvider>,
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
// Assert
|
|
35
|
-
expect(renderDialogFn).toHaveBeenCalledWith(titleId);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
test("if ID is not provided, then generates a unique ID and renders children", () => {
|
|
39
|
-
// Arrange
|
|
40
|
-
const renderDialogFn = jest.fn(() => <div />);
|
|
41
|
-
|
|
42
|
-
// Act
|
|
43
|
-
render(<IDProvider scope="component">{renderDialogFn}</IDProvider>);
|
|
44
|
-
|
|
45
|
-
// Assert
|
|
46
|
-
expect(renderDialogFn).toHaveBeenCalledWith(mockIDENTIFIER);
|
|
47
|
-
});
|
|
48
|
-
});
|
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import * as ReactDOMServer from "react-dom/server";
|
|
3
|
-
import {render} from "@testing-library/react";
|
|
4
|
-
|
|
5
|
-
import InitialFallback from "../initial-fallback";
|
|
6
|
-
import {RenderStateRoot} from "../render-state-root";
|
|
7
|
-
|
|
8
|
-
describe("InitialFallback", () => {
|
|
9
|
-
describe("client-side rendering", () => {
|
|
10
|
-
test("calls placeholder render first, then the actual content render", async () => {
|
|
11
|
-
// Arrange
|
|
12
|
-
const mockPlaceholder = jest.fn(() => null);
|
|
13
|
-
await new Promise((resolve: any) => {
|
|
14
|
-
const nodes = (
|
|
15
|
-
<InitialFallback fallback={mockPlaceholder}>
|
|
16
|
-
{() => {
|
|
17
|
-
resolve();
|
|
18
|
-
return null;
|
|
19
|
-
}}
|
|
20
|
-
</InitialFallback>
|
|
21
|
-
);
|
|
22
|
-
|
|
23
|
-
// Act
|
|
24
|
-
render(nodes);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
// Assert
|
|
28
|
-
// Our promise doesn't resolve until the children render, therefore
|
|
29
|
-
// we don't get here until that and so if the placeholder has been
|
|
30
|
-
// called, it must have been called first.
|
|
31
|
-
expect(mockPlaceholder).toHaveBeenCalledTimes(1);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
describe("nested", () => {
|
|
35
|
-
test("in parent placeholder, calls placeholder", async () => {
|
|
36
|
-
// Arrange
|
|
37
|
-
const mockChildrenNotCalled = jest.fn(() => null);
|
|
38
|
-
|
|
39
|
-
await new Promise((resolve: any) => {
|
|
40
|
-
const nestedPlaceholder = () => {
|
|
41
|
-
resolve();
|
|
42
|
-
return null;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const placeholder = () => (
|
|
46
|
-
<InitialFallback fallback={nestedPlaceholder}>
|
|
47
|
-
{mockChildrenNotCalled}
|
|
48
|
-
</InitialFallback>
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
const nodes = (
|
|
52
|
-
<InitialFallback fallback={placeholder}>
|
|
53
|
-
{() => null}
|
|
54
|
-
</InitialFallback>
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
// Act
|
|
58
|
-
render(nodes);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
// Assert
|
|
62
|
-
// Our promise doesn't resolve until the placeholder of our nested
|
|
63
|
-
// InitialFallback is rendered, therefore if we get here it means
|
|
64
|
-
// that the test is doing what we'd expect.
|
|
65
|
-
// In addition, if our code is working right, the children of the
|
|
66
|
-
// nested placeholder should have been skipped.
|
|
67
|
-
expect(mockChildrenNotCalled).not.toHaveBeenCalled();
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
test("in parent children, calls children render, skipping placeholder", async () => {
|
|
71
|
-
// Arrange
|
|
72
|
-
const mockPlaceholder = jest.fn(() => null);
|
|
73
|
-
const mockPlaceholderNotCalled = jest.fn(() => null);
|
|
74
|
-
await new Promise((resolve: any) => {
|
|
75
|
-
const nodes = (
|
|
76
|
-
<InitialFallback fallback={mockPlaceholder}>
|
|
77
|
-
{() => (
|
|
78
|
-
<InitialFallback
|
|
79
|
-
fallback={mockPlaceholderNotCalled}
|
|
80
|
-
>
|
|
81
|
-
{() => {
|
|
82
|
-
resolve();
|
|
83
|
-
return null;
|
|
84
|
-
}}
|
|
85
|
-
</InitialFallback>
|
|
86
|
-
)}
|
|
87
|
-
</InitialFallback>
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
// Act
|
|
91
|
-
render(nodes);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
// Assert
|
|
95
|
-
// Our promise doesn't resolve until the children of our nested InitialFallback
|
|
96
|
-
// are rendered, therefore we don't get here until that and so if the
|
|
97
|
-
// parent placeholder has been called, it must have been called first.
|
|
98
|
-
// In addition, if our code is working right, the placeholder of the
|
|
99
|
-
// nested component should have been skipped.
|
|
100
|
-
expect(mockPlaceholder).toHaveBeenCalledTimes(1);
|
|
101
|
-
expect(mockPlaceholderNotCalled).not.toHaveBeenCalled();
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
describe("server-side rendering", () => {
|
|
107
|
-
test("server-side rendering, calls placeholder render only", () => {
|
|
108
|
-
// Arrange
|
|
109
|
-
const mockChildren = jest.fn(() => null);
|
|
110
|
-
const mockPlaceholder = jest.fn(() => null);
|
|
111
|
-
|
|
112
|
-
const nodes = (
|
|
113
|
-
<InitialFallback fallback={mockPlaceholder}>
|
|
114
|
-
{mockChildren}
|
|
115
|
-
</InitialFallback>
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
// Act
|
|
119
|
-
ReactDOMServer.renderToStaticMarkup(nodes);
|
|
120
|
-
|
|
121
|
-
// Assert
|
|
122
|
-
expect(mockPlaceholder).toHaveBeenCalledTimes(1);
|
|
123
|
-
expect(mockChildren).toHaveBeenCalledTimes(0);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
test("null placeholder returns null", () => {
|
|
127
|
-
// Arrange
|
|
128
|
-
const mockChildren = jest.fn(() => null);
|
|
129
|
-
|
|
130
|
-
const nodes = (
|
|
131
|
-
<InitialFallback fallback={null}>
|
|
132
|
-
{mockChildren}
|
|
133
|
-
</InitialFallback>
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
// Act
|
|
137
|
-
const result = ReactDOMServer.renderToStaticMarkup(nodes);
|
|
138
|
-
|
|
139
|
-
// Assert
|
|
140
|
-
expect(result).toBe("");
|
|
141
|
-
expect(mockChildren).toHaveBeenCalledTimes(0);
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
describe("nested", () => {
|
|
145
|
-
test("in parent placeholder, renders as placeholder", () => {
|
|
146
|
-
// Arrange
|
|
147
|
-
const expectation = "CHILD PLACEHOLDER";
|
|
148
|
-
const placeholder = (
|
|
149
|
-
<InitialFallback fallback={() => expectation}>
|
|
150
|
-
{() => "This won't render"}
|
|
151
|
-
</InitialFallback>
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
const nodes = (
|
|
155
|
-
<InitialFallback fallback={() => placeholder}>
|
|
156
|
-
{() => "This won't render"}
|
|
157
|
-
</InitialFallback>
|
|
158
|
-
);
|
|
159
|
-
|
|
160
|
-
// Act
|
|
161
|
-
const result = ReactDOMServer.renderToStaticMarkup(nodes);
|
|
162
|
-
|
|
163
|
-
// Assert
|
|
164
|
-
expect(result).toBe(expectation);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
test("in parent children, renders as null", () => {
|
|
168
|
-
// Arrange
|
|
169
|
-
const placeholder = (
|
|
170
|
-
<InitialFallback fallback={null}>
|
|
171
|
-
{() => "This won't render"}
|
|
172
|
-
</InitialFallback>
|
|
173
|
-
);
|
|
174
|
-
|
|
175
|
-
const nodes = (
|
|
176
|
-
<InitialFallback fallback={() => placeholder}>
|
|
177
|
-
{() => "This won't render"}
|
|
178
|
-
</InitialFallback>
|
|
179
|
-
);
|
|
180
|
-
|
|
181
|
-
// Act
|
|
182
|
-
const result = ReactDOMServer.renderToStaticMarkup(nodes);
|
|
183
|
-
|
|
184
|
-
// Assert
|
|
185
|
-
expect(result).toBe("");
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
describe("inside a RenderStateRoot", () => {
|
|
191
|
-
test("calls placeholder render first, then the actual content render", async () => {
|
|
192
|
-
// Arrange
|
|
193
|
-
const mockPlaceholder = jest.fn(() => null);
|
|
194
|
-
await new Promise((resolve: any) => {
|
|
195
|
-
const nodes = (
|
|
196
|
-
<RenderStateRoot>
|
|
197
|
-
<InitialFallback fallback={mockPlaceholder}>
|
|
198
|
-
{() => {
|
|
199
|
-
resolve();
|
|
200
|
-
return null;
|
|
201
|
-
}}
|
|
202
|
-
</InitialFallback>
|
|
203
|
-
</RenderStateRoot>
|
|
204
|
-
);
|
|
205
|
-
|
|
206
|
-
// Act
|
|
207
|
-
render(nodes);
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
// Assert
|
|
211
|
-
// Our promise doesn't resolve until the children render, therefore
|
|
212
|
-
// we don't get here until that and so if the placeholder has been
|
|
213
|
-
// called, it must have been called first.
|
|
214
|
-
expect(mockPlaceholder).toHaveBeenCalledTimes(1);
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
test("server-side rendering, calls placeholder render only", () => {
|
|
218
|
-
// Arrange
|
|
219
|
-
const mockChildren = jest.fn(() => null);
|
|
220
|
-
const mockPlaceholder = jest.fn(() => null);
|
|
221
|
-
|
|
222
|
-
const nodes = (
|
|
223
|
-
<RenderStateRoot>
|
|
224
|
-
<InitialFallback fallback={mockPlaceholder}>
|
|
225
|
-
{mockChildren}
|
|
226
|
-
</InitialFallback>
|
|
227
|
-
</RenderStateRoot>
|
|
228
|
-
);
|
|
229
|
-
|
|
230
|
-
// Act
|
|
231
|
-
ReactDOMServer.renderToStaticMarkup(nodes);
|
|
232
|
-
|
|
233
|
-
// Assert
|
|
234
|
-
expect(mockPlaceholder).toHaveBeenCalledTimes(1);
|
|
235
|
-
expect(mockChildren).toHaveBeenCalledTimes(0);
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
test("null placeholder returns null", () => {
|
|
239
|
-
// Arrange
|
|
240
|
-
const mockChildren = jest.fn(() => null);
|
|
241
|
-
|
|
242
|
-
const nodes = (
|
|
243
|
-
<RenderStateRoot>
|
|
244
|
-
<InitialFallback fallback={null}>
|
|
245
|
-
{mockChildren}
|
|
246
|
-
</InitialFallback>
|
|
247
|
-
</RenderStateRoot>
|
|
248
|
-
);
|
|
249
|
-
|
|
250
|
-
// Act
|
|
251
|
-
const result = ReactDOMServer.renderToStaticMarkup(nodes);
|
|
252
|
-
|
|
253
|
-
// Assert
|
|
254
|
-
expect(result).toBe("");
|
|
255
|
-
expect(mockChildren).toHaveBeenCalledTimes(0);
|
|
256
|
-
});
|
|
257
|
-
});
|
|
258
|
-
});
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import {render} from "@testing-library/react";
|
|
3
|
-
|
|
4
|
-
import {RenderStateRoot} from "../render-state-root";
|
|
5
|
-
import {RenderState, RenderStateContext} from "../render-state-context";
|
|
6
|
-
|
|
7
|
-
const {useContext} = React;
|
|
8
|
-
|
|
9
|
-
describe("RenderStateRoot", () => {
|
|
10
|
-
test("the first render should set context's value to RenderState.Initial", () => {
|
|
11
|
-
// Arrange
|
|
12
|
-
const values: Array<any> = [];
|
|
13
|
-
const TestComponent = () => {
|
|
14
|
-
const value = useContext(RenderStateContext);
|
|
15
|
-
|
|
16
|
-
values.push(value);
|
|
17
|
-
|
|
18
|
-
return null;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
// Act
|
|
22
|
-
render(
|
|
23
|
-
<RenderStateRoot>
|
|
24
|
-
<TestComponent />
|
|
25
|
-
</RenderStateRoot>,
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
// Assert
|
|
29
|
-
expect(values[0]).toEqual(RenderState.Initial);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
test("the second render should set context's value to RenderState.Standard", () => {
|
|
33
|
-
// Arrange
|
|
34
|
-
const values: Array<any> = [];
|
|
35
|
-
const TestComponent = () => {
|
|
36
|
-
const value = useContext(RenderStateContext);
|
|
37
|
-
|
|
38
|
-
values.push(value);
|
|
39
|
-
|
|
40
|
-
return null;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// Act
|
|
44
|
-
render(
|
|
45
|
-
<RenderStateRoot>
|
|
46
|
-
<TestComponent />
|
|
47
|
-
</RenderStateRoot>,
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
// Assert
|
|
51
|
-
expect(values[1]).toEqual(RenderState.Standard);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it("should not allow nesting of <RenderStateRoot> when", () => {
|
|
55
|
-
// Act
|
|
56
|
-
const underTest = () =>
|
|
57
|
-
render(
|
|
58
|
-
<RenderStateRoot>
|
|
59
|
-
<RenderStateRoot>Hello, world!</RenderStateRoot>
|
|
60
|
-
</RenderStateRoot>,
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
expect(underTest).toThrowErrorMatchingInlineSnapshot(
|
|
64
|
-
`"There's already a <RenderStateRoot> above this instance in the render tree. This instance should be removed."`,
|
|
65
|
-
);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it("should allow nesting of <RenderStateRoot> when throwIfNested={false}", () => {
|
|
69
|
-
// Act
|
|
70
|
-
const underTest = () =>
|
|
71
|
-
render(
|
|
72
|
-
<RenderStateRoot throwIfNested={false}>
|
|
73
|
-
<RenderStateRoot throwIfNested={false}>
|
|
74
|
-
Hello, world!
|
|
75
|
-
</RenderStateRoot>
|
|
76
|
-
</RenderStateRoot>,
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
expect(underTest).not.toThrowError();
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
// This test can be written once ADR #526 has been implemented. I've left
|
|
83
|
-
// a comment in the ADR about this kind of test case being something we
|
|
84
|
-
// should support.
|
|
85
|
-
it.todo("should only render a single context provider when nesting");
|
|
86
|
-
});
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import {render, screen} from "@testing-library/react";
|
|
3
|
-
import Text from "../text";
|
|
4
|
-
|
|
5
|
-
describe("Text", () => {
|
|
6
|
-
test("forwards the ref to the heading element", () => {
|
|
7
|
-
// Arrange
|
|
8
|
-
const ref: React.RefObject<HTMLSpanElement> = React.createRef();
|
|
9
|
-
|
|
10
|
-
// Act
|
|
11
|
-
render(<Text ref={ref}>Some text</Text>);
|
|
12
|
-
|
|
13
|
-
// Assert
|
|
14
|
-
expect(ref.current).toBeInstanceOf(HTMLSpanElement);
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
test("applies style to the text wrapper", () => {
|
|
18
|
-
// Arrange
|
|
19
|
-
render(<Text style={{color: "red"}}>Text</Text>);
|
|
20
|
-
|
|
21
|
-
// Act
|
|
22
|
-
const wrapper = screen.getByText("Text");
|
|
23
|
-
|
|
24
|
-
// Assert
|
|
25
|
-
expect(wrapper).toHaveStyle({color: "red"});
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
test("appends the className prop to the element's class list", () => {
|
|
29
|
-
// Arrange
|
|
30
|
-
const className = "some-class";
|
|
31
|
-
|
|
32
|
-
// Act
|
|
33
|
-
render(
|
|
34
|
-
<Text style={{color: "red"}} className={className}>
|
|
35
|
-
Text
|
|
36
|
-
</Text>,
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
const wrapper = screen.getByText("Text");
|
|
40
|
-
|
|
41
|
-
// Assert
|
|
42
|
-
expect(wrapper).toHaveClass(className);
|
|
43
|
-
});
|
|
44
|
-
});
|