mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-13 16:02:59 +00:00
fix: the badge solves its lightness against the colour the browser paints
Three nits from the review round. The contrast bisection measured the hue at full float precision, but a browser paints 8-bit channels: rounding them moved the result up to 0.025 off the target, which took #993388 to 4.478 against white — under the AA floor the comment claims. Quantizing the channels inside `paintedLuminance` puts the worst case across 2880 hue and saturation combinations at 4.500, and your own fork's badge measures 4.53 as painted. An agent nobody can write still offered the rename behind its path segment: an editor with two read-only fields, in place of the click that copies the path. It is gated on `readOnly` now, the way a detail page is gated on `onSaved`. The script and flow editors take the same gate from the `customUi` flags that already decide whether their summary offers one — unreachable today, since the editors own the band only on routes that pass no `customUi`, but the four editors now answer the question the same way. And the registry's doc named an `onEditName` field that has never existed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
028d7527ff
commit
ece9e67b67
@@ -1582,7 +1582,13 @@
|
||||
kind: 'flow',
|
||||
path: pathSnapshot ?? $pathStore,
|
||||
summaryContent: flowSummary,
|
||||
pathTrigger: flowPathTrigger
|
||||
// Gated like the summary's own editor: a host that allows neither field keeps the
|
||||
// band's segment, which copies the path.
|
||||
pathTrigger:
|
||||
customUi?.topBar?.editablePath != false ||
|
||||
customUi?.topBar?.editableSummary != false
|
||||
? flowPathTrigger
|
||||
: undefined
|
||||
}}
|
||||
actions={flowHeaderActions}
|
||||
contexts={headerContexts}
|
||||
|
||||
@@ -2299,7 +2299,12 @@
|
||||
// invalidates the band before this component is torn down.
|
||||
path: pathSnapshot ?? script?.path,
|
||||
summaryContent: scriptSummary,
|
||||
pathTrigger: scriptPathTrigger
|
||||
// Gated like the summary's own editor: a host that allows neither field keeps the
|
||||
// band's segment, which copies the path.
|
||||
pathTrigger:
|
||||
customUi?.topBar?.editablePath != false || customUi?.topBar?.editableSummary != false
|
||||
? scriptPathTrigger
|
||||
: undefined
|
||||
}}
|
||||
afterName={scriptMarks}
|
||||
actions={scriptHeaderActions}
|
||||
|
||||
@@ -319,7 +319,9 @@
|
||||
item={{
|
||||
path: pathSnapshot ?? shownPath,
|
||||
summaryContent: agentSummary,
|
||||
pathTrigger: agentPathTrigger
|
||||
// Only where the rename behind it can be saved: a reader who cannot write this agent
|
||||
// keeps the segment that copies the path, rather than an editor with nothing to edit.
|
||||
pathTrigger: readOnly ? undefined : agentPathTrigger
|
||||
}}
|
||||
afterName={agentHint}
|
||||
actions={settings}
|
||||
|
||||
@@ -6,7 +6,8 @@ export type PageHeaderItem = {
|
||||
/** Absent for an item the picker does not file under a kind — an agent's detail page. The
|
||||
* breadcrumb then names the item without claiming it is one of the three. */
|
||||
kind?: WorkspaceItemKind
|
||||
/** Shown whole. Clicking it opens `onEditName` where a page offers one, and copies otherwise. */
|
||||
/** Shown whole. Clicking it opens whatever the page hangs off it with `pathTrigger`, and copies
|
||||
* the path where there is none. */
|
||||
path: string | undefined
|
||||
/** Wraps the band's own path segment in whatever the page wants behind it — its rename
|
||||
* popover, anchored there rather than beside the summary, so the editor opens under the half
|
||||
|
||||
@@ -78,11 +78,14 @@ function contrast(a: number, b: number): number {
|
||||
return (Math.max(a, b) + 0.05) / (Math.min(a, b) + 0.05)
|
||||
}
|
||||
|
||||
/** Luminance of what `hslFloorL` paints, not of the exact numbers: a percent of lightness is
|
||||
* worth more than the margin being solved for. */
|
||||
/** Luminance of what the browser paints, which is neither the exact numbers nor the `hsl()` string
|
||||
* alone: the string carries whole percents, and the channels it resolves to are 8-bit. Solving
|
||||
* against the unrounded channels leaves the chosen lightness up to 0.025 short of the target once
|
||||
* painted, which is enough to miss AA on a hue like #993388. */
|
||||
function paintedLuminance(h: number, s: number, l: number): number {
|
||||
const [r, g, b] = hslToRgb(Math.round(h), Math.round(s * 100) / 100, Math.floor(l * 100) / 100)
|
||||
return relativeLuminance(r, g, b)
|
||||
const q = (x: number) => Math.round(x * 255) / 255
|
||||
return relativeLuminance(q(r), q(g), q(b))
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user