view mrjunejune/src/public/composer-lab.html @ 273:e02e2036ef84 default tip

add Layer 2 JRPG component system Add reusable content and window modals, an isolated component sandbox, shared cyberpunk scroll areas, production-safe cache freshness, and server-rendered JRPG panel state. Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Sat, 08 Aug 2026 02:08:08 -0700
parents 41a49c29a28f
children
line wrap: on
line source

<!doctype html>
<html lang="en" data-zen-theme="cyberpunk">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Composer Lab | MrJuneJune</title>
    <link rel="stylesheet" href="/public/design-system/styles/tokens.css">
    <link rel="stylesheet" href="/public/design-system/styles/themes.css">
    <link rel="stylesheet" href="/public/design-system/styles/components.css">
    <script type="module" src="/public/design-system/components/index.js"></script>
    <script type="module">
      const version = Date.now();
      const link = document.createElement("link");
      link.rel = "stylesheet";
      link.href = `/public/mjj-composer.css?sandbox=${version}`;
      await new Promise((resolve, reject) => {
        link.addEventListener("load", resolve, { once: true });
        link.addEventListener("error", reject, { once: true });
        document.head.append(link);
      });
      await import(`/public/mjj-composer.js?sandbox=${version}`);
      void navigator.serviceWorker?.getRegistration()
        .then(registration => registration?.update());
    </script>
    <style>
      body {
        box-sizing: border-box;
        min-height: 100vh;
        margin: 0;
        padding: var(--zenbu-sys-padding-xl);
        background: var(--zenbu-sys-color-surface-page);
        color: var(--zenbu-sys-color-text-primary);
        font-family: var(--zenbu-sys-font-family-ui);
      }

      main {
        display: grid;
        gap: var(--zenbu-sys-space-container);
        width: min(100%, 48rem);
        margin-inline: auto;
      }

      section {
        display: grid;
        gap: var(--zenbu-sys-space-group);
      }

      h1,
      h2,
      p {
        margin: 0;
      }

      mjj-composer {
        min-height: 10rem;
      }

      mjj-composer[compact] {
        min-height: 7rem;
      }

      output {
        min-height: 1.5em;
        color: var(--zenbu-sys-color-text-secondary);
      }
    </style>
  </head>
  <body>
    <main>
      <header>
        <h1>Composer Lab</h1>
        <p>Edit the public composer module or stylesheet, then refresh this page.</p>
      </header>

      <section aria-labelledby="default-composer-title">
        <h2 id="default-composer-title">Default</h2>
        <mjj-composer>
          <form>
            <div data-composer-control>
              <zen-field size="lg">
                <label data-composer-label>Message</label>
                <textarea rows="4" placeholder="Write a message..." required></textarea>
              </zen-field>
              <div data-composer-actions>
                <zen-button size="sm">
                  <button type="submit">
                    Send
                    <zen-icon name="arrow-right"></zen-icon>
                  </button>
                </zen-button>
              </div>
            </div>
            <p data-composer-meta>Enter to send / Shift + Enter for a new line</p>
          </form>
        </mjj-composer>
        <output data-output>Ready.</output>
      </section>

      <section aria-labelledby="compact-composer-title">
        <h2 id="compact-composer-title">Compact</h2>
        <mjj-composer compact>
          <form>
            <div data-composer-control>
              <zen-field size="lg">
                <label data-composer-label>Message</label>
                <textarea rows="3" placeholder="Ask Epi..." required></textarea>
              </zen-field>
              <div data-composer-actions>
                <zen-button size="sm">
                  <button type="submit" aria-label="Send message">
                    <span data-composer-action-label>Send</span>
                    <zen-icon name="arrow-right"></zen-icon>
                  </button>
                </zen-button>
              </div>
            </div>
          </form>
        </mjj-composer>
        <output data-output>Ready.</output>
      </section>
    </main>
    <script type="module">
      for (const composer of document.querySelectorAll("mjj-composer")) {
        composer.addEventListener("mjj-composer-submit", event => {
          composer.nextElementSibling.textContent =
            `Submitted: ${event.detail.message}`;
        });
      }
    </script>
  </body>
</html>