APP

tcmts.cli.test.e2e.react.APP · #3xcehcmj · term · runs anywhere

export const APP = `// tcm: namespace ui
import { Suspense, createContext, lazy, useContext } from "react";
import * as React from "react";
import { setCookie } from "#codebase/lib/server";

export const Theme = createContext("light");

export async function Slow({ ms }: { ms: number }) {
  await new Promise((r) => setTimeout(r, ms));
  // set after the page's headers have gone out
  setCookie("late", "yes", { httpOnly: false });
  return <p id="slow">slow part, {ms}ms</p>;
}

export function Themed() {
  const theme = useContext(Theme);
  return <b id="theme">{theme}</b>;
}

export function Unthemed() {
  return <i id="default">{useContext(Theme)}</i>;
}

export function Counter() {
  const [n, setN] = React.useState(0);
  return <button id="count" onClick={() => setN(n + 1)}>{n}</button>;
}

// code split: loads in the browser
export const LazyCounter = lazy(async () => ({ default: Counter }));

export class Clock extends React.Component<{ label: string }, { ticks: number }> {
  state = { ticks: 0 };
  render() {
    return <span id="clock" onClick={() => this.setState({ ticks: this.state.ticks + 1 })}>{this.props.label} {this.state.ticks}</span>;
  }
}

export async function Page() {
  setCookie("early", "yes", { httpOnly: false });
  return (
    <Theme value="dark">
      <title>streaming page</title>
      <LazyCounter />
      <h1 id="title">streaming</h1>
      <Themed />
      <Counter />
      <Clock label="ticks" />
      <Suspense fallback={<p id="slow">loading</p>}>
        <Slow ms={1200} />
      </Suspense>
    </Theme>
  );
}

export async function Outside() {
  return <Unthemed />;
}

export function App() {
  return <main><Page /><Outside /></main>;
}
`

used by