Differentiate color picker icons by type (text / fill / background / stroke / border) #158
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_whiteboard#158
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The selection toolbar exposes several color pickers — Text color, Fill color, Stroke color, Background color, Border color — but every picker renders as the same circular swatch (
wb-pt-color-swatch). Only the hover tooltip distinguishes them. Users have to hover each swatch to know what it controls.Expected
Each color picker should be visually distinguishable at a glance by a small type indicator overlaid on (or next to) the swatch:
Aglyph (orbi-typeicon) on top of the swatch.bi-square-fill).bi-square).The tooltip stays as a fallback.
Actual
All color pickers render as identical circular swatches, only differentiated by tooltip text on hover.
Notes
The current helper is
_colorTriggerWithTitle(value, onChange, palette, title, hasNoFill)incrates/hero_whiteboard_ui/static/web/js/whiteboard/selection_toolbar.js. Adding akindparameter (text/fill/stroke) and rendering a small icon overlay inside the swatch would give every call site a distinct visual without breaking the existing API.Sweep all call sites and pass the right
kind:Text color→textFill color,Background color→fillStroke color,Border color→strokeImplementation Spec
Audit (selection_toolbar.js)
_buildColorTrigger(initial, onPick, palette, allowTransparent)~L554 — creates the toolbar trigger button (wb-pt-color-trigger) with an inner<span class="swatch">. The swatch we want to decorate._colorTriggerWithTitle(initial, onPick, palette, tooltip, allowTransparent)~L732 — wraps_buildColorTriggerwith title + aria-label. Addkindhere._applySwatchVisual(swatchEl, value)~L462 — togglesis-no-filland setsstyle.background. The new overlay icon is a sibling of thestyle.background, so this repaint path doesn't wipe it.Call sites and their semantic kind
filltextstrokefilltextstroketextfillstroke_buildColorTrigger)fillfillstrokeVisual choice: Bootstrap Icon overlay
Bootstrap Icons (
bi-type,bi-square-fill,bi-square) are already loaded by bothbase.htmlandweb/base_web.htmland the rest of the toolbar uses the same icon vocabulary. The overlay sits inside the 18×18 swatch withmix-blend-mode: differenceso it stays legible against any color, and falls back tovar(--wb-text)on theis-no-fillchecker state. No theme branching needed.Not chosen: CSS pseudo-glyphs (loses icon-vocabulary alignment) or different swatch shapes (muddles the "this is a color chip" affordance).
Files to Modify
crates/hero_whiteboard_ui/static/web/js/whiteboard/selection_toolbar.js— extend helpers, sweep call sites.crates/hero_whiteboard_ui/static/web/css/selection_toolbar.css— add overlay rules (the swatch styles live in this file, notwhiteboard.css).No template changes (Bootstrap Icons already loaded).
Implementation Plan
Step 1 — Extend the helpers
Files:
selection_toolbar.js_buildColorTrigger(initial, onPick, palette, allowTransparent, kind).kindoptional, one of'text' | 'fill' | 'stroke'. Default'fill'. Unknown values fall back to'fill'._buildColorTrigger, after creating the inner.swatch, append: whereiconClassFor:'text'→'bi-type','fill'→'bi-square-fill','stroke'→'bi-square'._colorTriggerWithTitleto takekindas a 6th arg and forward it.kindplaced last in both signatures so existing callers that don't pass it keep working (default'fill').Step 2 — Sweep call sites
Update each call to pass the right
kindfrom the audit table above.Step 3 — CSS in
selection_toolbar.cssAdd next to existing
.wb-pt-color-trigger .swatchrules:The popover grid swatches (
.wb-pt-color-swatchinside_buildColorPopover) are NOT decorated — those represent specific color choices, not the picker's purpose.Acceptance Criteria
A(bi-type).var(--wb-text)).kindgetbi-square-filland otherwise identical DOM/behavior.What NOT to break
_colorTriggerWithTitleand_buildColorTrigger: backwards compatible (new arg appended at the end)._applySwatchVisualrepaint path: only mutatesstyle.backgroundand theis-no-fillclass on the swatch; the overlay is a sibling and survives.pointer-events: none.aria-hidden="true"._buildColorPopover) DOM and its grid: untouched.Validation
cargo check --workspacecargo test --workspace --libImplementation summary
Changes
crates/hero_whiteboard_ui/static/web/js/whiteboard/selection_toolbar.js_buildColorTriggernow takes a 5thkindparameter ('text' | 'fill' | 'stroke', default'fill') and appends a Bootstrap-icon<i>overlay (bi-type/bi-square-fill/bi-square) inside the swatch span._colorTriggerWithTitletakes the samekindas a 6th parameter and forwards it._colorTriggerWithTitle+ 1 direct_buildColorTriggerfor kanban columns) now pass an explicitkind: text inputs use'text'; sticky / shape fill / document background / mindmap tree / kanban column use'fill'; shape stroke / drawing stroke / document border / connector all use'stroke'.crates/hero_whiteboard_ui/static/web/css/selection_toolbar.css.wb-pt-color-trigger .swatch { position: relative; }plus.wb-pt-color-kindrules (absolute-positioned overlay,mix-blend-mode: differenceso the glyph stays legible against any swatch color, with a fallback path for theis-no-fillchecker pattern that switches tovar(--wb-text)).No template changes (Bootstrap Icons already loaded). The popover grid swatches are intentionally left undecorated — those represent specific color choices, not the picker's purpose.
API is backwards-compatible: any caller that doesn't pass
kindkeeps working and gets thebi-square-filldefault.Validation
cargo check --workspace: passcargo test --workspace --lib: passNotes
UI-only change. Verify visually: select a sticky → background swatch shows a filled square. Select text → swatch shows
A. Select a shape → fill swatch is filled square, stroke swatch is hollow square. Switch theme — icons stay legible thanks to mix-blend-mode.