view mrjunejune/src/public/composer-lab.html @ 272:41a49c29a28f

polish JRPG conversation experience Integrate desktop conversations into the utility panel, simplify the mobile frame, add modal destinations and a reusable Zenbu composer lab, and preserve explicit conversation resume behavior. Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Fri, 07 Aug 2026 16:05:29 -0700
parents
children e02e2036ef84
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">
    <link rel="stylesheet" href="/public/mjj-composer.css">
    <script type="module" src="/public/design-system/components/index.js"></script>
    <script type="module" src="/public/mjj-composer.js"></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>