Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[initialfallback] Rename WithSSRPlaceholder to InitialFallback #2304

Merged
merged 3 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/wicked-carrots-hope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@khanacademy/wonder-blocks-core": major
"@khanacademy/wonder-blocks-layout": minor
---

Renamed `WithSSRPlaceholder` to `InitialFallback`. This includes changing the `placeholder` prop to `fallback` so it's closer to `Suspense` usage.
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ import * as React from "react";
import type {Meta, StoryObj} from "@storybook/react";
import {Body} from "@khanacademy/wonder-blocks-typography";

import {View, WithSSRPlaceholder} from "@khanacademy/wonder-blocks-core";
import {View, InitialFallback} from "@khanacademy/wonder-blocks-core";
import packageConfig from "../../packages/wonder-blocks-core/package.json";

import ComponentInfo from "../../.storybook/components/component-info";

type StoryComponentType = StoryObj<typeof WithSSRPlaceholder>;
type StoryComponentType = StoryObj<typeof InitialFallback>;

export default {
title: "Packages / Core / WithSSRPlaceholder",
component: WithSSRPlaceholder,
title: "Packages / Core / InitialFallback",
component: InitialFallback,
parameters: {
componentSubtitle: (
<ComponentInfo
Expand All @@ -33,7 +33,7 @@ export default {
},
},
args: {
placeholder: (): React.ReactElement => (
fallback: (): React.ReactElement => (
<View>
This gets rendered on server, and also on the client for the
very first render (the rehydration render)
Expand All @@ -46,19 +46,19 @@ export default {
</View>
),
},
} as Meta<typeof WithSSRPlaceholder>;
} as Meta<typeof InitialFallback>;

export const Default: StoryComponentType = {};

export const WithoutPlaceholder: StoryComponentType = () => (
<WithSSRPlaceholder placeholder={null}>
<InitialFallback fallback={null}>
{() => (
<View>
This is rendered only by the client, while nothing was rendered
on the server.
</View>
)}
</WithSSRPlaceholder>
</InitialFallback>
);

WithoutPlaceholder.parameters = {
Expand Down Expand Up @@ -104,24 +104,24 @@ export const NestedComponent: StoryComponentType = (): React.ReactElement => {
The list below should have three render entries; root
placeholder, root children render, and child children render. If
there are two child renders that means that the second forced
render is still occurring for nested WithSSRPlaceholder
components, which would be a bug.
render is still occurring for nested InitialFallback components,
which would be a bug.
</Body>
<ul id={resultsId} />
<Body>
And below this is the actual WithSSRPlaceholder nesting, which
And below this is the actual InitialFallback nesting, which
should just show the child render.
</Body>
<WithSSRPlaceholder
placeholder={() => (
<InitialFallback
fallback={() => (
<View>{trackAndRender("Root: placeholder")}</View>
)}
>
{() => {
addTrackedRender("Root: render");
return (
<WithSSRPlaceholder
placeholder={() => (
<InitialFallback
fallback={() => (
<View>
{trackAndRender(
"Child: placeholder (should never see me)",
Expand All @@ -132,18 +132,18 @@ export const NestedComponent: StoryComponentType = (): React.ReactElement => {
{() => (
<View>{trackAndRender("Child: render")}</View>
)}
</WithSSRPlaceholder>
</InitialFallback>
);
}}
</WithSSRPlaceholder>
</InitialFallback>
</View>
);
};

NestedComponent.parameters = {
docs: {
description: {
story: "Here, we nest two `WithSSRPlaceholder` components and use an array to track rendering, so that we can see how only the top level `WithSSRPlaceholder` component skips the initial render.",
story: "Here, we nest two `InitialFallback` components and use an array to track rendering, so that we can see how only the top level `InitialFallback` component skips the initial render.",
},
},
};
Expand Down Expand Up @@ -186,19 +186,19 @@ export const SideBySide: StoryComponentType = (): React.ReactElement => {
</Body>
<ul id={resultsId} />
<Body>
And below this are the WithSSRPlaceholder component trees, which
And below this are the InitialFallback component trees, which
should just show their child renders.
</Body>
<WithSSRPlaceholder
placeholder={() => (
<InitialFallback
fallback={() => (
<View>{trackAndRender("Root 1: placeholder")}</View>
)}
>
{() => {
addTrackedRender("Root 1: render");
return (
<WithSSRPlaceholder
placeholder={() => (
<InitialFallback
fallback={() => (
<View>
{trackAndRender(
"Child 1: placeholder (should never see me)",
Expand All @@ -209,20 +209,20 @@ export const SideBySide: StoryComponentType = (): React.ReactElement => {
{() => (
<View>{trackAndRender("Child 1: render")}</View>
)}
</WithSSRPlaceholder>
</InitialFallback>
);
}}
</WithSSRPlaceholder>
<WithSSRPlaceholder
placeholder={() => (
</InitialFallback>
<InitialFallback
fallback={() => (
<View>{trackAndRender("Root 2: placeholder")}</View>
)}
>
{() => {
addTrackedRender("Root 2: render");
return (
<WithSSRPlaceholder
placeholder={() => (
<InitialFallback
fallback={() => (
<View>
{trackAndRender(
"Child 2: placeholder (should never see me)",
Expand All @@ -233,18 +233,18 @@ export const SideBySide: StoryComponentType = (): React.ReactElement => {
{() => (
<View>{trackAndRender("Child 2: render")}</View>
)}
</WithSSRPlaceholder>
</InitialFallback>
);
}}
</WithSSRPlaceholder>
</InitialFallback>
</View>
);
};

SideBySide.parameters = {
docs: {
description: {
story: "In this example, we have side-by-side `WithSSRPlaceholder` components. This demonstrates how component non-nested `WithSSRPlaceholder` components independently track the first render.",
story: "In this example, we have side-by-side `InitialFallback` components. This demonstrates how component non-nested `InitialFallback` components independently track the first render.",
},
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@ import * as React from "react";
import * as ReactDOMServer from "react-dom/server";
import {render} from "@testing-library/react";

import WithSSRPlaceholder from "../with-ssr-placeholder";
import InitialFallback from "../initial-fallback";
import {RenderStateRoot} from "../render-state-root";

describe("WithSSRPlaceholder", () => {
describe("InitialFallback", () => {
describe("client-side rendering", () => {
test("calls placeholder render first, then the actual content render", async () => {
// Arrange
const mockPlaceholder = jest.fn(() => null);
await new Promise((resolve: any) => {
const nodes = (
<WithSSRPlaceholder placeholder={mockPlaceholder}>
<InitialFallback fallback={mockPlaceholder}>
{() => {
resolve();
return null;
}}
</WithSSRPlaceholder>
</InitialFallback>
);

// Act
Expand All @@ -43,15 +43,15 @@ describe("WithSSRPlaceholder", () => {
};

const placeholder = () => (
<WithSSRPlaceholder placeholder={nestedPlaceholder}>
<InitialFallback fallback={nestedPlaceholder}>
{mockChildrenNotCalled}
</WithSSRPlaceholder>
</InitialFallback>
);

const nodes = (
<WithSSRPlaceholder placeholder={placeholder}>
<InitialFallback fallback={placeholder}>
{() => null}
</WithSSRPlaceholder>
</InitialFallback>
);

// Act
Expand All @@ -60,7 +60,7 @@ describe("WithSSRPlaceholder", () => {

// Assert
// Our promise doesn't resolve until the placeholder of our nested
// WithSSRPlaceholder is rendered, therefore if we get here it means
// InitialFallback is rendered, therefore if we get here it means
// that the test is doing what we'd expect.
// In addition, if our code is working right, the children of the
// nested placeholder should have been skipped.
Expand All @@ -73,26 +73,26 @@ describe("WithSSRPlaceholder", () => {
const mockPlaceholderNotCalled = jest.fn(() => null);
await new Promise((resolve: any) => {
const nodes = (
<WithSSRPlaceholder placeholder={mockPlaceholder}>
<InitialFallback fallback={mockPlaceholder}>
{() => (
<WithSSRPlaceholder
placeholder={mockPlaceholderNotCalled}
<InitialFallback
fallback={mockPlaceholderNotCalled}
>
{() => {
resolve();
return null;
}}
</WithSSRPlaceholder>
</InitialFallback>
)}
</WithSSRPlaceholder>
</InitialFallback>
);

// Act
render(nodes);
});

// Assert
// Our promise doesn't resolve until the children of our nested WithSSRPlaceholder
// Our promise doesn't resolve until the children of our nested InitialFallback
// are rendered, therefore we don't get here until that and so if the
// parent placeholder has been called, it must have been called first.
// In addition, if our code is working right, the placeholder of the
Expand All @@ -110,9 +110,9 @@ describe("WithSSRPlaceholder", () => {
const mockPlaceholder = jest.fn(() => null);

const nodes = (
<WithSSRPlaceholder placeholder={mockPlaceholder}>
<InitialFallback fallback={mockPlaceholder}>
{mockChildren}
</WithSSRPlaceholder>
</InitialFallback>
);

// Act
Expand All @@ -128,9 +128,9 @@ describe("WithSSRPlaceholder", () => {
const mockChildren = jest.fn(() => null);

const nodes = (
<WithSSRPlaceholder placeholder={null}>
<InitialFallback fallback={null}>
{mockChildren}
</WithSSRPlaceholder>
</InitialFallback>
);

// Act
Expand All @@ -146,15 +146,15 @@ describe("WithSSRPlaceholder", () => {
// Arrange
const expectation = "CHILD PLACEHOLDER";
const placeholder = (
<WithSSRPlaceholder placeholder={() => expectation}>
<InitialFallback fallback={() => expectation}>
{() => "This won't render"}
</WithSSRPlaceholder>
</InitialFallback>
);

const nodes = (
<WithSSRPlaceholder placeholder={() => placeholder}>
<InitialFallback fallback={() => placeholder}>
{() => "This won't render"}
</WithSSRPlaceholder>
</InitialFallback>
);

// Act
Expand All @@ -167,16 +167,15 @@ describe("WithSSRPlaceholder", () => {
test("in parent children, renders as null", () => {
// Arrange
const placeholder = (
// @ts-expect-error [FEI-5019] - TS2769 - No overload matches this call.
<WithSSRPlaceholder placeholder={undefined}>
<InitialFallback fallback={null}>
{() => "This won't render"}
</WithSSRPlaceholder>
</InitialFallback>
);

const nodes = (
<WithSSRPlaceholder placeholder={() => placeholder}>
<InitialFallback fallback={() => placeholder}>
{() => "This won't render"}
</WithSSRPlaceholder>
</InitialFallback>
);

// Act
Expand All @@ -195,12 +194,12 @@ describe("WithSSRPlaceholder", () => {
await new Promise((resolve: any) => {
const nodes = (
<RenderStateRoot>
<WithSSRPlaceholder placeholder={mockPlaceholder}>
<InitialFallback fallback={mockPlaceholder}>
{() => {
resolve();
return null;
}}
</WithSSRPlaceholder>
</InitialFallback>
</RenderStateRoot>
);

Expand All @@ -222,9 +221,9 @@ describe("WithSSRPlaceholder", () => {

const nodes = (
<RenderStateRoot>
<WithSSRPlaceholder placeholder={mockPlaceholder}>
<InitialFallback fallback={mockPlaceholder}>
{mockChildren}
</WithSSRPlaceholder>
</InitialFallback>
</RenderStateRoot>
);

Expand All @@ -242,9 +241,9 @@ describe("WithSSRPlaceholder", () => {

const nodes = (
<RenderStateRoot>
<WithSSRPlaceholder placeholder={null}>
<InitialFallback fallback={null}>
{mockChildren}
</WithSSRPlaceholder>
</InitialFallback>
</RenderStateRoot>
);

Expand Down
Loading