Files
windmill/frontend/src/lib/components/GfmMarkdown.svelte
T
Diego ImbertandClaude Opus 5 a0295b20c4 fix(frontend): render ordered lists in markdown descriptions (#10973)
* fix(frontend): render ordered lists in markdown descriptions

`GfmMarkdown` defaulted to `prose-xs`, which Tailwind Typography does not
define — the class only ever matched four hand-rolled rules in app.css, all
scoped to `ul`. Every surface on that default (script and flow descriptions,
flow-graph notes, markdown job results) therefore rendered `<ol>` with
Preflight's `list-style: none` and no typography at all: no numbers, no
heading or paragraph rhythm.

Route the default through the shared `markdownProse` stacks instead, and cut
the app.css list rules down to the dash glyph so ordered and unordered lists
share Tailwind Typography's indentation and rhythm.

Fixes #10971

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6G5gDXJnm6uqch4uCPkPE

* fix(frontend): address review nits on the markdown prose fix

- default `GfmMarkdown` to the `sm` stack rather than `xs`: the AI-agent tool
  Message pane takes the default and has no ancestor font size, so `xs` left it
  smaller than its own label. The group note, whose wrapper is `text-2xs`, opts
  down explicitly.
- regenerate `static/tailwind_full.css`, which raw apps are served and which
  still carried the deleted list rules.
- correct the marker-color rationale: the typography config already maps markers
  to tertiary, so the rule steps them up rather than rescuing them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6G5gDXJnm6uqch4uCPkPE

* fix(frontend): make the note color override an arbitrary value

`text-inherit` is not generated: this config replaces the Tailwind color palette
outright and defines no `inherit` key, so `[&_*]:!text-inherit` compiled to
nothing and notes still rendered in the prose stack's `text-primary`. Verified in
the browser: a yellow note's list items now compute to `text-yellow-900`, matching
the wrapper and the edit-mode textarea, in both themes.

Also drop the `static/tailwind_full.css` regeneration. That file was generated with
tailwind 3.4.1 against a config predating the typography theme overrides; rebuilding
it today sweeps in 250KB of unrelated churn and would flip every raw app's `.prose`
palette from stock gray to Windmill tokens. Its staleness predates this PR and is
its own change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6G5gDXJnm6uqch4uCPkPE

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-05 10:39:44 +00:00

121 lines
3.1 KiB
Svelte

<script lang="ts">
import { Markdown } from 'svelte-exmarkdown'
import { markdownPlugins as plugins } from './markdownPlugins'
import { markdownProse, type MarkdownProseSize } from './markdownProse'
import { isOfflineReplay } from './recording/offlineReplay.svelte'
interface Props {
md: string
noPadding?: boolean
/** Shared prose stack to render with. */
prose?: MarkdownProseSize
}
let { md, noPadding, prose = 'sm' }: Props = $props()
// Rendering markdown turns `![](url)` into a real `<img>`, i.e. a request. On the
// public replay page the source is a recording from an arbitrary origin and the
// page promises to issue none, so show the text instead. Gated here rather than
// at each call site because every recorded annotation (flow notes, group notes,
// step descriptions) reaches markdown through this one component.
let asPlainText = $derived(isOfflineReplay())
</script>
<div class="{markdownProse[prose]} {noPadding ? '' : 'pgap'}">
{#if asPlainText}
<p class="whitespace-pre-wrap">{md}</p>
{:else}
<Markdown {md} {plugins} />
{/if}
</div>
<style global>
.pgap > p {
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
:root {
--github-alert-default-color: rgb(208, 215, 222);
--github-alert-note-color: rgb(9, 105, 218);
--github-alert-tip-color: rgb(26, 127, 55);
--github-alert-important-color: rgb(130, 80, 223);
--github-alert-warning-color: rgb(191, 135, 0);
--github-alert-caution-color: rgb(207, 34, 46);
}
@media (prefers-color-scheme: dark) {
:root {
--github-alert-default-color: rgb(48, 54, 61);
--github-alert-note-color: rgb(31, 111, 235);
--github-alert-tip-color: rgb(35, 134, 54);
--github-alert-important-color: rgb(137, 87, 229);
--github-alert-warning-color: rgb(158, 106, 3);
--github-alert-caution-color: rgb(248, 81, 73);
}
}
.markdown-alert {
padding: 0.5rem 1rem;
margin-bottom: 16px;
border-left: 0.25em solid var(--github-alert-default-color);
}
.markdown-alert > :first-child {
margin-top: 0;
}
.markdown-alert > :last-child {
margin-bottom: 0;
}
.markdown-alert-note {
border-left-color: var(--github-alert-note-color);
}
.markdown-alert-tip {
border-left-color: var(--github-alert-tip-color);
}
.markdown-alert-important {
border-left-color: var(--github-alert-important-color);
}
.markdown-alert-warning {
border-left-color: var(--github-alert-warning-color);
}
.markdown-alert-caution {
border-left-color: var(--github-alert-caution-color);
}
.markdown-alert-title {
display: flex;
margin-bottom: 4px;
align-items: center;
}
.markdown-alert-title > svg {
margin-right: 8px;
}
.markdown-alert-note .markdown-alert-title {
color: var(--github-alert-note-color);
}
.markdown-alert-tip .markdown-alert-title {
color: var(--github-alert-tip-color);
}
.markdown-alert-important .markdown-alert-title {
color: var(--github-alert-important-color);
}
.markdown-alert-warning .markdown-alert-title {
color: var(--github-alert-warning-color);
}
.markdown-alert-caution .markdown-alert-title {
color: var(--github-alert-caution-color);
}
</style>