trueshade
Reactive icon

TrueShade

Stable version 1.5.1 (Compatible with OutSystems 11)
Uploaded
 on 9 Jun (yesterday)
 by 
5.0
 (9 ratings)
trueshade

TrueShade

Compatible with:
Created on OutSystems 11

Version 1.5.1

Stable
Current
See documentation
Uploaded on 9 Jun (yesterday) by 
Compatible with:
Version 11
11.9.2 or higher
11.7.6 to 11.9.0
11.0.539 to 11.0.615
Database:
All
Release notes:

New

  • GetStorageKey() client action — returns the localStorage key TrueShade uses to persist the theme preference for the current module ($layout-theme, or the derived $OS_$layout-theme). Useful for debugging or for reading the stored value directly in an anti-FOUC script. Backed by a new TrueShade.Theme.GetStorageKey() function.


Improved

  • The theme-change callback now exposes both values. The block's OnChange_Theme handler signature changed from (Raw) to (Effective, Raw). Consumers now receive both the effective theme (resolved light/dark — e.g. after applying the system preference) and the raw user selection (which may be system-default). This is backed by the underlying OnChange now delivering both arguments.
  • Initialization is idempotent and self-syncing. On Ready now unsubscribes any pre-existing listener before re-subscribing (preventing duplicate listeners on re-render / re-initialization) and subscribes with { immediate: true }, so the handler runs once on load to sync the initial theme.
  • Safe load when matchMedia is unavailable. The script no longer throws at load in environments that lack window.matchMedia (old/stripped webviews, some test harnesses). It degrades gracefully to light, with OS reactivity disabled; persistence, manual selection, and cross-tab sync still work.
  • Immutable configuration. The script's internal config constants are now frozen, preventing accidental runtime mutation.


Migration / Breaking

  • OnChange_Theme is a breaking signature change ((Raw) → (Effective, Raw)). Any block or screen that binds or overrides this handler must be updated to the two-parameter form.
  • Argument order matters: the first parameter is now the effective theme (resolved light/dark), whereas the old single argument was the raw value. Logic that relied on that one argument as the user's selection should now read the second parameter (Raw). Review and rebind accordingly.
Application Objects:
TrueShade has 0 AOs.

Version 1.4.0

Stable
See documentation
Uploaded on 4 Jun (6 days ago) by 
Compatible with:
Version 11
11.9.2 or higher
11.7.6 to 11.9.0
11.0.539 to 11.0.615
Database:
All
Release notes:

Fixed

  • Listener skipped when a callback unsubscribes during dispatch. If an OnChange callback removed a listener (its own unsubscribe, Dispose(), or a re-entrant theme change) while listeners were being notified, the dispatch loop could skip the next one. emit() now iterates a snapshot of the listener list, so subscribing or unsubscribing mid-dispatch can't skip or double-invoke anyone.
  • OnChange(cb, { immediate: true }) before Initialize() no longer double-fires. The immediate fire is skipped until the module is initialized; Initialize()'s first emit delivers the current theme, so the callback runs exactly once regardless of subscription timing. (Refines the immediate option added in 1.3.0.)
  • appName with a trailing $ no longer produces a doubled separator. Initialize('myapp$') (or 'shop$$$') now yields the same clean key as Initialize('myapp').


Improved

  • getModuleName() caching now covers the empty case. A degenerate derivation (no usable path or hostname) is cached instead of recomputed on every call. (1.3.0 rewrote this function for readability; 1.4.0 completes the caching.)
  • Resilient BroadcastChannel wiring. The message handler is attached via addEventListener('message', …) — and removed on Dispose() — instead of the single, clobberable onmessage slot. (Distinct from the 1.3.0 MediaQueryList.addListener fallback, which concerns OS-scheme listening.)
  • Less cross-tab chatter. Changes are broadcast only when they originate from a local SetLayoutColorScheme call; page loads and OS-scheme flips no longer broadcast, since every tab observes OS changes via its own matchMedia and already shares the persisted value. (This is the sender side — separate from the 1.3.0 change where the receiver stopped re-writing localStorage.) Behavior is unchanged; there's simply less redundant traffic.
  • Listener errors are now visible. A throwing OnChange callback is reported via console.error (and still doesn't abort dispatch to the other listeners) instead of being silently swallowed.
  • 'use strict' is now applied to the module.
Application Objects:
TrueShade has 0 AOs.

Version 1.3.0

Stable
See documentation
Uploaded on 2 Jun (8 days ago) by 
Compatible with:
Version 11
11.9.2 or higher
11.7.6 to 11.9.0
11.0.539 to 11.0.615
Database:
All
Release notes:

API conveniences plus broader browser support and an internal cleanup.


New

  • Theme.GetStorageKey() — returns the resolved localStorage key for the active module (e.g. myapp$layout-theme or $OS_example$layout-theme). Handy for debugging and for the anti-FOUC snippet below.
  • Theme.OnChange(cb, { immediate: true }) — optional second argument; when set, the callback also fires once synchronously with the current (effective, raw) theme, so initial render needs no separate Get* call. Default behavior (future changes only) is unchanged.
  • Legacy Safari support for OS changes — OS color-scheme listening now falls back to MediaQueryList.addListener on Safari < 14, which lacks addEventListener on media queries.
  • Documented FOUC-prevention snippet — the file header now includes a copy-paste synchronous script that sets data-theme before first paint.


Fixed

  • Corrected an incorrect @param name in applyTheme's JSDoc.


Changed (internal — no observable behavior change)

  • Cross-tab messages now require v: 1; unknown protocol versions are ignored. (This module has always sent v: 1, so mixed-version tabs still sync in both directions.)
  • Extracted isMode() and resolve() helpers, removing duplicated validation/resolution logic across several call sites.
  • Rewrote getModuleName() from hand-rolled charCode scanning to readable split-based logic (output is identical; cached after first call).
  • The channel receiver no longer redundantly re-writes localStorage — the sending tab already persisted to the shared store. Not observable in a real browser; persistence is intact.
  • Unified internal "unset" sentinels and simplified onColorSchemeChange.
Application Objects:
TrueShade has 0 AOs.