<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Edge Apps library 1.5.0 | Screenly</title><description>What has shipped across Screenly, newest first.</description><link>https://www.screenly.io/releases/edge-apps/1.5.0/</link><language>en</language><atom:link href="https://www.screenly.io/releases/edge-apps/1.5.0/rss.xml" rel="self" type="application/rss+xml"/><lastBuildDate>Wed, 19 Aug 2026 00:00:00 +0000</lastBuildDate><item><title>Edge Apps library 1.5.0: A new isLightColor helper picks readable text for any brand color</title><link>https://www.screenly.io/releases/edge-apps/1.5.0/is-light-color/</link><guid isPermaLink="true">https://www.screenly.io/releases/edge-apps/1.5.0/is-light-color/</guid><pubDate>Wed, 19 Aug 2026 00:00:00 +0000</pubDate><category>release</category><category>developers</category><description>&lt;p&gt;Your app doesn&amp;rsquo;t choose the accent color. Each customer sets their own in &lt;code&gt;screenly_color_accent&lt;/code&gt;,
and the same app has to put readable text on a pale yellow brand and on a navy one.
&lt;code&gt;isLightColor()&lt;/code&gt; tells you which you&amp;rsquo;re dealing with:&lt;/p&gt;
&lt;div class="code-block"&gt;
&lt;button type="button" class="code-copy" aria-label="Copy code" data-copy-code&gt;
&lt;svg data-copy viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;rect x="9" y="9" width="11" height="11" rx="2"&gt;&lt;/rect&gt;
&lt;path d="M5 15V5a2 2 0 0 1 2-2h10"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;svg data-check viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;/button&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6ab825;font-weight:bold"&gt;import&lt;/span&gt; { isLightColor, setupTheme } &lt;span style="color:#6ab825;font-weight:bold"&gt;from&lt;/span&gt; &lt;span style="color:#ed9d13"&gt;&amp;#39;@screenly/edge-apps&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6ab825;font-weight:bold"&gt;const&lt;/span&gt; { primary } = setupTheme()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#24909d"&gt;document&lt;/span&gt;.body.classList.toggle(&lt;span style="color:#ed9d13"&gt;&amp;#39;on-light-brand&amp;#39;&lt;/span&gt;, isLightColor(primary))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;It returns &lt;code&gt;true&lt;/code&gt; when a color needs dark text and &lt;code&gt;false&lt;/code&gt; when it needs light text. The answer
comes from the WCAG relative luminance formula rather than an average of the red, green, and blue
values, so it ranks colors the way people see them. Pure yellow and pure blue have similar channel
totals and land on opposite sides.&lt;/p&gt;
&lt;p&gt;It accepts hex (&lt;code&gt;#abc&lt;/code&gt;, &lt;code&gt;#aabbcc&lt;/code&gt;, &lt;code&gt;#aabbccdd&lt;/code&gt;) and numeric &lt;code&gt;rgb()&lt;/code&gt; or &lt;code&gt;rgba()&lt;/code&gt; strings, and
ignores alpha. Named colors and percentage channels aren&amp;rsquo;t supported. Anything it can&amp;rsquo;t read
returns &lt;code&gt;false&lt;/code&gt; instead of throwing, so a malformed setting can&amp;rsquo;t stop a screen from rendering.&lt;/p&gt;</description></item></channel></rss>