You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ModelSelect gains renderHeader + filterResetKey — renderHeader renders a caller-owned
toolbar pinned to the TOP of the open panel, always visible even when the result list is empty
(unlike renderFooter, which hides on an empty set) — the place for a domain control that must
stay reachable, e.g. a browse-mode switch above the picker. filterResetKey imperatively clears
the internal search + provider/capability filters when its value changes, WITHOUT remounting, so
the panel keeps its open state/scroll/focus and never flashes a stale-filter "no results" after the
option set is swapped out from under the filters (again: a browse-mode switch). Both are optional
and fully backward-compatible.
Fixed
MermaidDiagram restores its documented .mermaid-container DOM contract. The content
stylesheet already scoped responsive SVG rules to that class, but the rendered diagram omitted
it, leaving host styling and stable diagram selection disconnected from the actual output.
CodeBlock no longer pulls Shiki's full language catalogue into host builds. The content
renderer now uses Shiki core with explicit lazy grammar/theme loaders and the JavaScript regex
engine. Common application and LLM-output languages retain VS Code-grade highlighting; unknown
fence labels fall back to escaped plaintext. This keeps MarkdownRenderer on demand in practice,
instead of making Next/Vite discover and compile hundreds of unused language modules.
Overlays are no longer see-through — dropdown menus, selects, comboboxes, popovers, the
language & theme switchers, the mobile navbar sheet and the notification panel were painted with a
60%-opaque bg-background/60 frosted panel, so content behind them showed through and read as if
it were still clickable. They now use bg-popover/85 (still frosted via backdrop-blur, but
opaque enough to occlude what's underneath) and the correct --popover surface token.
Button labels never wrap — the .btn base now sets white-space: nowrap, so a button
label can no longer break onto multiple lines in a narrow container. A CJK label like 使用
in a cramped table action column used to split vertically into 使/用; it now stays on one
line (the column widens / the table scrolls instead). Matches the standard button convention.
Added
Sortable TableHead — TableHead gains optional, backward-compatible sort props: onSort makes the header a sort control (renders its content as a <button> with an
asc/desc/unsorted chevron and sets aria-sort on the <th>), sortDirection
("asc" | "desc" | false) is the column's current state, and align
("left" | "right" | "center") aligns both the content and the control (use "right"
for numeric columns). Omit onSort and it behaves exactly as before. Fills the
data-table column-sorting gap without a separate component. TableHead is also now whitespace-nowrap so short header labels never wrap — CJK labels in particular no
longer break mid-word (能力 → 能/力) in narrow columns / WebKit.
AgentTimeline (@yuhuanowo/yunui/ai) — an agent turn rendered as an
ordered, INLINE sequence of typed blocks (reasoning / tool call+result /
assistant text / approval), in the neutral .card language. Unlike the AgentSteps panel, the answer is a text block among the tool/reasoning
blocks in conversation order (no result-on-top / steps-below split); tool
rows expand into $-prefixed monospace output, failures use semantic red-500/5 tints, and an approval block renders an amber allow/deny gate.
Prop-driven and copy-free — the consumer maps records onto AgentTimelineBlock,
localizes every label, and supplies a markdown renderer. Verified on Chrome +
Safari/WebKit, desktop + mobile.
AgentRunStatus (@yuhuanowo/yunui/ai) — a layout-stable live surface for the
single activity an agent is doing now (a shimmering label + pulsing dot trio,
announced via role="status"/aria-live). Complements AgentTimeline: the status
stays put for the whole run while timeline rows become durable history. phase
(thinking/acting/observing/reflecting/responding/waiting) is a semantic hint.
TextShimmer (@yuhuanowo/yunui) — a restrained animated text sweep for transient
work states ("Thinking…"); the label is exposed to assistive tech exactly once while the
duplicated paint layers stay aria-hidden. active pauses the sweep without a layout shift.
ChatAttachment (@yuhuanowo/yunui/chat) — a compact attachment surface shared by
the composer and sent messages: name/meta, an optional preview or icon, a determinate
upload progress bar, status (idle/loading/error) affordances and an actions slot.
InlineCitation (@yuhuanowo/yunui/content) — a claim-adjacent evidence marker for
grounded AI output. A compact inline pill previews the concrete source (title, location, a
bounded excerpt) on hover/focus and delegates opening to the host via onOpen.
ReadingProgress (@yuhuanowo/yunui/patterns) — reading position + back-to-top as one
floating control: a circular ring fills with scroll progress around an up-arrow button (no
full-width hairline). bar/backToTop toggle each half; threshold and labels.backToTop
are configurable. One rAF-coalesced scroll listener; the ring animates via stroke-dashoffset.
SettingsShell (@yuhuanowo/yunui/patterns) — the canonical settings layout: grouped
desktop sidebar navigation, a compact mobile Select, and one scroll-safe content lane; works
in a dialog or full page. Controlled via value/onValueChange, sections from groups
(SettingsNavGroup/SettingsNavItem). The host owns the active panel; YunUI owns navigation.
NavStateIndicator (@yuhuanowo/yunui/patterns) — the shared active/running marker that
sits beside a selected item in Sidebar/SettingsShell; a presentational <span> driven by active/running data-states. Extracted so bespoke navigation surfaces can match the system.
CustomSelect server-backed search + infinite scroll — onSearch (debounced by searchDebounceMs, default 250) drives results from a backend, paired with loading; onLoadMore + hasMore append pages as the list nears its end. Both optional and independent
of the existing client-side searchable filtering.
Combobox gains clearable (default true) — a clear (×) action for the current value;
set clearable={false} when the field must always hold a value.
useAnchoredPosition flips above the trigger when there isn't room below, and remeasures
open panels as layout changes — hand-rolled floating panels now match the collision behavior of
the Radix-based overlays.
getModelDeveloperId (@yuhuanowo/yunui/ai) — model-family icon resolution is centralized,
so a model id resolves to its developer/family icon through one shared helper.
Fixed
Untrusted Mermaid/KaTeX is sanitized — MermaidDiagram renders with a strict securityLevel and KaTeX with trust: false, so diagram/math content coming from model
or user input can't inject scripts or navigate via crafted labels (XSS hardening).
Tooltip content escapes clipping ancestors — tooltips now portal out, so they're no
longer cut off by an overflow: hidden/clip parent.
Removed
AgentSteps (@yuhuanowo/yunui/ai) — the earlier Codex-style execution
panel (result-on-top / steps-below split) is removed, superseded by AgentTimeline, which renders the same agent-turn data as an inline ordered
sequence of typed blocks. No consumer shipped against AgentSteps.
Changed
ModelSelect selection bar inset refined to 5px (from left-1.5/6px),
set as an inline style since Tailwind's 1.25 step isn't core and could be
dropped by a consumer's JIT scan.
AgentTimeline now speaks YunUI's semantic status vocabulary — the error /
success / warning affordances moved off raw Tailwind red-*/emerald-*/amber-*
onto the --error / --success / --warning tokens, so they track the active
theme (light / dark / brand) instead of drifting from the system's palette.
./package.json is now an export so tooling and consumers can read the
package version at runtime (the docs site uses it for its version badge).
Dependencies refreshed to latest — React 19.2.8, the Radix primitives,
Tailwind 4.3.3, shiki 4, framer-motion 12.43, lucide-react 1.28 and more.
No API changes; typescript intentionally held at 6.x (7.x isn't yet compatible
with the tsup/rollup-plugin-dts build toolchain).