Skip to content

Restyle the theme rail and source its icons from config - #323

Open
sandesh-sp wants to merge 2 commits into
developmentfrom
fix/layer-filter-theme-styling
Open

Restyle the theme rail and source its icons from config#323
sandesh-sp wants to merge 2 commits into
developmentfrom
fix/layer-filter-theme-styling

Conversation

@sandesh-sp

Copy link
Copy Markdown
Collaborator

Styling

The rail painted itself from the primary ramp (--theme-color-primary-dark). It now uses the theme's darkest surface, --theme-color-ink — which matches the Disasters Portal design (Figma node 9564:23148 is a 66×940 rect filled --color/hds/carbon/90, #17171b, horizon's ink).

Categories and the collapse chevron sit in --theme-color-base-lighter (#e3e3e3) and lift to white on hover, so pointing at a category previews the selected treatment. The selected category keeps the inversion: white fill, ink text and icon.

Two values stayed literals rather than tokens: the label's 10px/1.6. Horizon's smallest type-scale step resolves to 12px and line-height-2 to 1.2, so tokenizing them would have changed the rendering on a 66px-wide rail. Noted in a comment.

Icons come from config, not the bundle

The three theme SVGs are gone from the plugin. Each category names its own icon in the mission config from one of three sources, chosen per row:

Source Field Notes
upload iconUpload File uploaded through the Configure page
link iconUrl Hosted elsewhere
mdi iconMdi Material Design Icons name

variables.themes becomes an objectarray, so each row carries its own upload field with a thumbnail. This reuses the existing type: "upload" component and POST /api/upload — the same path the Card tool uses — so there is no new component type and no backend change. Files land in Missions/<mission>/LayerFilterThemes/uploads/, and the stored mission-relative path resolves against app:getMissionPath at render time.

Configs written against the earlier flat icon string still resolve — path-like values as images, bare words as MDI names — so existing missions keep rendering while they migrate.

Uploaded images are drawn as CSS masks

Not <img>, and not inlined. This buys two things at once:

  1. The icon takes its color from the item, so one uploaded file covers both rail states rather than needing a light and a dark variant.
  2. An uploaded SVG is never parsed as a document, so script embedded in one cannot run. This matters: the upload path does not sanitize SVG, and the safety argument on record (API/Backend/Upload/validate.js:8) holds only for <img src>.

The tradeoff is that icons render as single-color silhouettes — fine for glyph-style icons, wrong for a multi-color logo.

Matches the existing repo idiom (AOIComponent.scss, layer-legend.scss).

Collapse chevron

A chevron above the categories opens and closes the neighbouring panel, rotating a half-turn between states (dropped under prefers-reduced-motion). It targets the panel named by the new togglePanelId var, or the sole other collapsible panel in the rail's region, and hides when neither resolves.

It drives the panel through panels:getAll / panels:toggleCollapsed, added in #322. This branch does not depend on that one to build or pass — the wrappers return null when the handlers are absent, so the chevron simply hides itself until #322 lands.

Testing

tests/unit/layerFilterThemesRail.spec.js extended to cover all three icon sources, the fallback when a chosen source is left empty, the warning when nothing falls back, and legacy flat-icon configs.

Full unit suite at this branch tip: 79 files, 1306 tests passing, tsc --noEmit clean, production build compiles.

Not verified

None of this has been checked in a running browser — no live confirmation of the rail's appearance, the chevron collapsing a panel, or an uploaded icon rendering at size. Worth a smoke test on the DisastersTool mission, which is the one configured with this plugin.

Paint the rail from the theme's darkest surface (--theme-color-ink) rather
than the primary ramp, and set the categories and the collapse chevron in
--theme-color-base-lighter, lifting to white on hover so pointing at a
category previews the selected treatment. The selected category keeps the
inversion: white fill, ink text and icon.

Theme icons are no longer bundled with the plugin. Each category names its
own icon in the mission config, from one of three sources: a file uploaded
through the Configure page, a link to one hosted elsewhere, or a Material
Design Icons name. The themes editor becomes an objectarray so each row
carries its own upload field, and configs written against the earlier flat
`icon` string still resolve.

Uploaded and linked images are painted as CSS masks filled with the item's
own color. One file therefore covers both rail states, and an uploaded SVG
is never parsed as a document, so script embedded in one cannot run -- the
upload path does not sanitize SVG.

A chevron above the categories opens and closes the neighbouring panel,
rotating a half-turn between the two states. It drives the panel named by
`togglePanelId`, or the sole other collapsible panel in the rail's region,
and stays hidden when neither resolves or when core registers no panel
handlers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant