wsb-daemon 0.275.7622

wsb's daemon: the workbench, the GitHub mirror's schedule and peer continuity, for every workspace on the machine
<script lang="ts">
  import MonacoEditor from "../layout/MonacoEditor.svelte";
  import AppIcon from "../layout/AppIcon.svelte";
  import MarkdownPreview from "./MarkdownPreview.svelte";

  interface Props {
    content: string;
    onchange?: (value: string) => void;
  }

  let { content, onchange }: Props = $props();

  let mode: "preview" | "source" = $state("preview");
</script>

<div class="md-viewer">
  <div class="md-toolbar">
    <div class="md-toolbar-left">
      <AppIcon name="file-text" size={13} />
      <span class="md-toolbar-label">Markdown</span>
    </div>
    <div class="md-toolbar-right">
      <button
        class="mode-btn"
        class:active={mode === "preview"}
        onclick={() => (mode = "preview")}
      >
        <AppIcon name="eye" size={12} />
        Preview
      </button>
      <button
        class="mode-btn"
        class:active={mode === "source"}
        onclick={() => (mode = "source")}
      >
        <AppIcon name="code" size={12} />
        Source
      </button>
    </div>
  </div>

  {#if mode === "preview"}
    <MarkdownPreview content={content} />
  {:else}
    <MonacoEditor
      value={content}
      language="markdown"
      readOnly={!onchange}
      onchange={onchange ?? (() => {})}
      height="100%"
    />
  {/if}
</div>

<style>
  .md-viewer {
    height: 100%;
    display: flex;
    flex-direction: column;
    min-height: 0;
    background: var(--vscode-tab-activeBackground);
  }

  .md-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 var(--wb-spacing-14);
    height: var(--wb-control-size-36);
    flex-shrink: 0;
    border-bottom: 1px solid var(--vscode-panel-border);
    background: var(--vscode-sideBar-background);
    gap: var(--wb-spacing-12);
  }

  .md-toolbar-left {
    display: flex;
    align-items: center;
    gap: var(--wb-spacing-6);
    color: var(--vscode-disabledForeground);
    font-size: var(--wb-font-size-12);
  }

  .md-toolbar-label {
    font-weight: 500;
    color: var(--vscode-foreground);
  }

  .md-toolbar-right {
    display: flex;
    align-items: center;
    gap: var(--wb-spacing-2);
  }

  .mode-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--wb-spacing-5);
    height: var(--wb-control-size-26);
    padding: 0 var(--wb-spacing-10);
    border-radius: var(--wsb-radius-sm);
    font-size: var(--wb-font-size-12);
    color: var(--vscode-foreground);
    border: 1px solid transparent;
  }

  .mode-btn:hover {
    background: var(--vscode-list-hoverBackground);
    color: var(--vscode-editor-foreground);
  }

  .mode-btn.active {
    background: var(--vscode-input-background);
    border-color: var(--vscode-widget-border);
    color: var(--vscode-editor-foreground);
  }

  /* Monaco source view fills remaining height */
  .md-viewer :global(.monaco-shell) {
    flex: 1;
    min-height: 0;
    border: none;
    border-radius: 0;
    height: 100% !important;
  }
</style>