Skip to content

v2.9.0

Latest

Choose a tag to compare

@ndlabdev ndlabdev released this 13 Oct 07:41
89f03a5

Added

  • ThemeMode — createInitialModeExpression for apps that inject the dark mode script themselves with disableHeadScriptInjection, plus the ColorMode, ResolvedColorMode, ThemeColors and InitialModeConfig types. (#224)

Changed

  • ThemeMode — dark mode is handled by sv5ui itself instead of wrapping mode-watcher. Props, exports and the localStorage keys (mode-watcher-mode, mode-watcher-theme) are unchanged, so stored preferences carry over. mode-watcher stays in dependencies until the next major so apps that import it directly keep building, but importing from sv5ui is the supported path. An app that still mounts its own <ModeWatcher /> stays in sync with sv5ui and gets a one time console warning. Each mode change is also dispatched as a storage event on window in the same tab, so a storage listener that does not filter by key will see it. (#224)
  • Checkbox, CheckboxGroup, RadioGroup, Switch, Slider — aria-* props now land on the control instead of the wrapper (aria-hidden, class, style and data-* stay on the wrapper). Selectors such as [aria-label="…"] [role="slider"] become [role="slider"][aria-label="…"]. (#236)

Fixed

  • ThemeMode — the script injected by ThemeMode quotes the nonce and drops one outside the CSP nonce character set, and config values are escaped, so neither can break out of the script tag. (#224)
  • ThemeMode — an invalid stored mode no longer applies dark before mount on a light system. Like the other script fixes, this applies to <ThemeMode />; an app that still mounts <ModeWatcher /> keeps that package's script. (#224)
  • ThemeMode — with themeColors, the theme-color meta on first paint follows the resolved mode instead of the stored one, so system on a light system gets the light color. (#224)
  • ThemeMode — importing sv5ui no longer throws when localStorage is unavailable, such as in a sandboxed iframe or with storage blocked. The mode is kept in memory instead. (#224)
  • ThemeModeButton — loading shows the spinner again instead of the mode icon. It was hidden since 2.8.0, when the button started rendering both mode icons through a slot that took precedence over the spinner.
  • ThemeModeButton — an onclick handler no longer replaces the toggle. It runs first, and calling preventDefault() in it cancels the toggle. (#224)
  • ThemeModeButton — toggles the dark class even when ThemeMode is not mounted. The class applied on page load still comes from ThemeMode. (#224)
  • Form controls — a user aria-describedby or aria-invalid is no longer overwritten, and inside a FormField it merges with the field ids. User event handlers no longer get replaced. (#236)
  • FormField — the label names every control, slot content and the description stay announced next to an error, required sets aria-required on text inputs, and a user id keeps the label and Form errors linked. (#236)
  • Textarea, InputTags — leadingSlot and trailingSlot reserve room so they no longer cover the text, and a control inside them can be clicked, matching Input. (#237)
  • Textarea, Select, SelectMenu, Button — loading shows the spinner instead of a slot on the same side. (#237)
  • Breadcrumb — two items with the same label render side by side instead of crashing the page with a duplicate key error. (#241)

Upgrading

Nothing was removed from the public API, but these behaviours changed.

  • Checkbox, CheckboxGroup, RadioGroup, Switch and Slider put aria-* props on the control instead of the wrapper. Selectors such as [aria-label="…"] [role="slider"] become [role="slider"][aria-label="…"]. This is the one I expect people to hit.
  • Dark mode no longer goes through mode-watcher. Props, exports and the localStorage keys are unchanged, and mode-watcher stays in dependencies until the next major. An app that still mounts its own <ModeWatcher /> stays in sync and gets a one time console warning.
  • Each mode change is dispatched as a storage event on window in the same tab, so a storage listener that does not filter by key will see it.
  • A ThemeModeButton onclick handler now runs before the toggle instead of replacing it. Call preventDefault() in it to cancel the toggle.
  • With loading, Textarea, Select, SelectMenu and Button show the spinner instead of a slot on the same side.
  • Textarea and InputTags slots reserve padding and accept pointer events, as Input does since 2.8.0.