From ce5c5dbd46afbe738b03600758bf5c35113de522 Mon Sep 17 00:00:00 2001 From: Happydev <81974850+MoustaphaDev@users.noreply.github.com> Date: Wed, 18 Jan 2023 23:35:41 +0100 Subject: [PATCH] feat: add theme toggle button to error overlay (#5884) * feat: add theme toggle button for error overlay * add changeset * simplify toggling logic Co-authored-by: Chris Swithinbank * redesign toggle * code figma design * style: remove code indent * add `aria-hidden` to svgs Co-authored-by: Yan Thomas <61414485+Yan-Thomas@users.noreply.github.com> * apply Yan a11y suggestions Co-authored-by: Chris Swithinbank Co-authored-by: Yan Thomas <61414485+Yan-Thomas@users.noreply.github.com> --- .changeset/few-rice-report.md | 5 + packages/astro/src/core/errors/overlay.ts | 242 +++++++++++++++++----- 2 files changed, 198 insertions(+), 49 deletions(-) create mode 100644 .changeset/few-rice-report.md diff --git a/.changeset/few-rice-report.md b/.changeset/few-rice-report.md new file mode 100644 index 000000000000..c92b909b82ff --- /dev/null +++ b/.changeset/few-rice-report.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Add a theme toggle button to the error overlay diff --git a/packages/astro/src/core/errors/overlay.ts b/packages/astro/src/core/errors/overlay.ts index 378e05f83463..e208017a9037 100644 --- a/packages/astro/src/core/errors/overlay.ts +++ b/packages/astro/src/core/errors/overlay.ts @@ -59,7 +59,14 @@ const style = /* css */ ` rgba(255, 255, 255, 0.96449) 78.38%, rgba(255, 255, 255, 0.991353) 84.11%, #ffffff 89.84% - ); + ); + + /* Theme toggle */ + --toggle-ball-color: var(--accent); + --toggle-tabel-background: var(--background); + --sun-icon-color: #ffffff; + --moon-icon-color: #a3acc8; + --toggle-border-color: #C3CADB; /* Syntax Highlighting */ --shiki-color-text: #000000; @@ -74,54 +81,145 @@ const style = /* css */ ` --shiki-token-link: #ee0000; } -@media (prefers-color-scheme: dark) { - :host { - --background: #090b11; - --error-text: #f49090; - --error-text-hover: #ffaaaa; - --title-text: #ffffff; - --box-background: #141925; - --box-background-hover: #2e333f; - --hint-text: #a3acc8; - --hint-text-hover: #bdc6e2; - --border: #283044; - --accent: #c490f4; - --accent-hover: #deaaff; - --stack-text: #c3cadb; - --misc-text: #8490b5; - - --houston-overlay: linear-gradient( - 180deg, - rgba(9, 11, 17, 0) 3.95%, - rgba(9, 11, 17, 0.0086472) 9.68%, - rgba(9, 11, 17, 0.03551) 15.4%, - rgba(9, 11, 17, 0.0816599) 21.13%, - rgba(9, 11, 17, 0.147411) 26.86%, - rgba(9, 11, 17, 0.231775) 32.58%, - rgba(9, 11, 17, 0.331884) 38.31%, - rgba(9, 11, 17, 0.442691) 44.03%, - rgba(9, 11, 17, 0.557309) 49.76%, - rgba(9, 11, 17, 0.668116) 55.48%, - rgba(9, 11, 17, 0.768225) 61.21%, - rgba(9, 11, 17, 0.852589) 66.93%, - rgba(9, 11, 17, 0.91834) 72.66%, - rgba(9, 11, 17, 0.96449) 78.38%, - rgba(9, 11, 17, 0.991353) 84.11%, - #090b11 89.84% - ); +:host(.astro-dark) { + --background: #090b11; + --error-text: #f49090; + --error-text-hover: #ffaaaa; + --title-text: #ffffff; + --box-background: #141925; + --box-background-hover: #2e333f; + --hint-text: #a3acc8; + --hint-text-hover: #bdc6e2; + --border: #283044; + --accent: #c490f4; + --accent-hover: #deaaff; + --stack-text: #c3cadb; + --misc-text: #8490b5; - /* Syntax Highlighting */ - --shiki-color-text: #ffffff; - --shiki-token-constant: #90f4e3; - --shiki-token-string: #f4cf90; - --shiki-token-comment: #8490b5; - --shiki-token-keyword: var(--accent); - --shiki-token-parameter: #aa0000; - --shiki-token-function: #90f4e3; - --shiki-token-string-expression: #f4cf90; - --shiki-token-punctuation: #ffffff; - --shiki-token-link: #ee0000; - } + --houston-overlay: linear-gradient( + 180deg, + rgba(9, 11, 17, 0) 3.95%, + rgba(9, 11, 17, 0.0086472) 9.68%, + rgba(9, 11, 17, 0.03551) 15.4%, + rgba(9, 11, 17, 0.0816599) 21.13%, + rgba(9, 11, 17, 0.147411) 26.86%, + rgba(9, 11, 17, 0.231775) 32.58%, + rgba(9, 11, 17, 0.331884) 38.31%, + rgba(9, 11, 17, 0.442691) 44.03%, + rgba(9, 11, 17, 0.557309) 49.76%, + rgba(9, 11, 17, 0.668116) 55.48%, + rgba(9, 11, 17, 0.768225) 61.21%, + rgba(9, 11, 17, 0.852589) 66.93%, + rgba(9, 11, 17, 0.91834) 72.66%, + rgba(9, 11, 17, 0.96449) 78.38%, + rgba(9, 11, 17, 0.991353) 84.11%, + #090b11 89.84% + ); + + /* Theme toggle */ + --sun-icon-color: #505D84; + --moon-icon-color: #090B11; + --toggle-border-color: #3D4663; + + /* Syntax Highlighting */ + --shiki-color-text: #ffffff; + --shiki-token-constant: #90f4e3; + --shiki-token-string: #f4cf90; + --shiki-token-comment: #8490b5; + --shiki-token-keyword: var(--accent); + --shiki-token-parameter: #aa0000; + --shiki-token-function: #90f4e3; + --shiki-token-string-expression: #f4cf90; + --shiki-token-punctuation: #ffffff; + --shiki-token-link: #ee0000; +} + +#theme-toggle-wrapper{ + position: relative; + display: inline-block +} + +#theme-toggle-wrapper > div{ + position: absolute; + right: 3px; + margin-top: 3px; +} + +.theme-toggle-checkbox { + opacity: 0; + position: absolute; +} + +#theme-toggle-label { + background-color: var(--toggle-tabel-background); + border-radius: 50px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: space-between; + padding: 7.5px; + position: relative; + width: 66px; + height: 30px; + transform: scale(1.2); + box-shadow: 0 0 0 1px var(--toggle-border-color); + outline: 1px solid transparent; +} + +.theme-toggle-checkbox:focus ~ #theme-toggle-label { + outline: 2px solid var(--toggle-border-color); + outline-offset: 4px; +} + +#theme-toggle-label #theme-toggle-ball { + background-color: var(--accent); + border-radius: 50%; + position: absolute; + height: 30px; + width: 30px; + transform: translateX(-7.5px); + transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1) 0ms; +} + +@media (forced-colors: active) { + #theme-toggle-label { + --moon-icon-color: CanvasText; + --sun-icon-color: CanvasText; + } + #theme-toggle-label #theme-toggle-ball { + background-color: SelectedItem; + } +} + +.theme-toggle-checkbox:checked + #theme-toggle-label #theme-toggle-ball { + transform: translateX(28.5px); +} + +.sr-only { + border: 0 !important; + clip: rect(1px, 1px, 1px, 1px) !important; + -webkit-clip-path: inset(50%) !important; + clip-path: inset(50%) !important; + height: 1px !important; + margin: -1px !important; + overflow: hidden !important; + padding: 0 !important; + position: absolute !important; + width: 1px !important; + white-space: nowrap !important; +} + +.icon-tabler{ + transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1) 0ms; + z-index: 10; +} + +.icon-tabler-moon { + color: var(--moon-icon-color); +} + +.icon-tabler-sun { + color: var(--sun-icon-color); } #backdrop { @@ -138,6 +236,7 @@ const style = /* css */ ` #layout { max-width: min(100%, 1280px); + position: relative; width: 1280px; margin: 0 auto; padding: 40px; @@ -151,6 +250,12 @@ const style = /* css */ ` padding: 12px; margin-top: 12px; } + + #theme-toggle-wrapper > div{ + position: absolute; + right: 22px; + margin-top: 47px; + } #layout { padding: 0; @@ -172,6 +277,7 @@ const style = /* css */ ` #header-left { min-height: 63px; display: flex; + align-items: flex-start; flex-direction: column; justify-content: end; } @@ -390,6 +496,25 @@ ${style.trim()}
+
+
+ + +
+
@@ -445,6 +570,25 @@ class ErrorOverlay extends HTMLElement { this.root = this.attachShadow({ mode: 'open' }); this.root.innerHTML = overlayTemplate; + // theme toggle logic + const themeToggle = this.root.querySelector('.theme-toggle-checkbox'); + if ( + localStorage.astroErrorOverlayTheme === 'dark' || + (!('astroErrorOverlayTheme' in localStorage) && + window.matchMedia('(prefers-color-scheme: dark)').matches) + ) { + this?.classList.add('astro-dark'); + themeToggle!.checked = true; + } else { + this?.classList.remove('astro-dark'); + themeToggle!.checked = false; + } + themeToggle?.addEventListener('click', () => { + const isDark = localStorage.astroErrorOverlayTheme === 'dark'; + this?.classList.toggle('astro-dark', !isDark); + localStorage.astroErrorOverlayTheme = isDark ? 'light' : 'dark'; + }); + this.text('#name', err.name); this.text('#title', err.title); this.text('#message-content', err.message, true);