From 50ea1b63668f667bf7f30583c0a513ba49559613 Mon Sep 17 00:00:00 2001 From: TheoryOfNekomata Date: Sun, 27 Dec 2020 17:59:55 +0800 Subject: [PATCH] Make theme toggle smooth Add compatibility for a smoother transition of themes. --- packages/react-common-docs/public/theme.css | 145 ++++++++++++++++++ .../react-common-docs/public/theme/dark.css | 135 +--------------- .../react-common-docs/public/theme/light.css | 141 ----------------- .../components/ThemeToggle/ThemeToggle.tsx | 54 ++----- .../react-common-docs/src/pages/_document.tsx | 3 +- 5 files changed, 165 insertions(+), 313 deletions(-) create mode 100644 packages/react-common-docs/public/theme.css diff --git a/packages/react-common-docs/public/theme.css b/packages/react-common-docs/public/theme.css new file mode 100644 index 0000000..f34f5f7 --- /dev/null +++ b/packages/react-common-docs/public/theme.css @@ -0,0 +1,145 @@ +@font-face { + font-family: 'Encode Sans'; + font-stretch: semi-expanded; + font-weight: 400; + src: + local('Encode Sans Semi Expanded'), + local('Encode Sans'); +} + +@font-face { + font-family: 'Encode Sans'; + font-stretch: semi-expanded; + font-weight: 700; + src: + local('Encode Sans Semi Expanded Bold'), + local('Encode Sans Semi Expanded'), + local('Encode Sans'); +} + +@font-face { + font-family: 'Encode Sans'; + font-stretch: condensed; + font-weight: 100; + src: + local('Encode Sans Condensed Thin'), + local('Encode Sans Condensed'), + local('Encode Sans'); +} + +@font-face { + font-family: 'Encode Sans'; + font-stretch: condensed; + font-weight: 200; + src: + local('Encode Sans Condensed ExtraLight'), + local('Encode Sans Condensed Extra Light'), + local('Encode Sans Condensed'), + local('Encode Sans'); +} + +@font-face { + font-family: 'Encode Sans'; + font-stretch: condensed; + font-weight: 300; + src: + local('Encode Sans Condensed Light'), + local('Encode Sans Condensed'), + local('Encode Sans'); +} + +:root { + --font-family-base: 'Encode Sans Semi Expanded', 'Encode Sans', system-ui; + --font-stretch-base: semi-expanded; + --font-weight-base: 400; + --line-height-base: 2; + --font-family-headings:'Encode Sans Condensed', 'Encode Sans', system-ui; + --font-stretch-headings: condensed; + --font-weight-headings: 100; + --line-height-headings: 1.5; + --font-family-monospace: 'mononoki'; + --font-size-root: 16px; + --opacity-light: 0.25; + --opacity-lighter: 0.5; + --opacity-lightest: 0.75; +} + +:root { + --color-bg: var(--color-negative, white); + --color-fg: var(--color-positive, black); +} + +@media (prefers-color-scheme: dark) { + :root { + --color-bg: var(--color-negative, black); + --color-fg: var(--color-positive, white); + } +} + +:root { + + background-color: var(--color-bg); + color: var(--color-fg); + font-size: var(--font-size-root); + font-family: var(--font-family-base), sans-serif; + font-stretch: var(--font-stretch-base, normal); + font-weight: var(--font-weight-base, 400); + line-height: var(--line-height-base, 2); + transition-property: color, background-color; + transition-timing-function: ease; + transition-duration: 350ms; +} + +h1 { + font-family: var(--font-family-headings), sans-serif; + font-stretch: var(--font-stretch-headings, normal); + font-weight: var(--font-weight-headings, 400); + line-height: var(--line-height-headings, 1.5); +} + +h2 { + font-family: var(--font-family-headings), sans-serif; + font-stretch: var(--font-stretch-headings, normal); + font-weight: var(--font-weight-headings, 400); + line-height: var(--line-height-headings, 1.5); +} + +h3 { + font-family: var(--font-family-headings), sans-serif; + font-stretch: var(--font-stretch-headings, normal); + font-weight: var(--font-weight-headings, 400); + line-height: var(--line-height-headings, 1.5); +} + +h4 { + font-family: var(--font-family-headings), sans-serif; + font-stretch: var(--font-stretch-headings, normal); + font-weight: var(--font-weight-headings, 400); + line-height: var(--line-height-headings, 1.5); +} + +h5 { + font-family: var(--font-family-headings), sans-serif; + font-stretch: var(--font-stretch-headings, normal); + font-weight: var(--font-weight-headings, 400); + line-height: var(--line-height-headings, 1.5); +} + +h6 { + font-family: var(--font-family-headings), sans-serif; + font-stretch: var(--font-stretch-headings, normal); + font-weight: var(--font-weight-headings, 400); + line-height: var(--line-height-headings, 1.5); +} + +code { + font-family: var(--font-family-monospace), monospace; +} + +pre { + font-family: var(--font-family-monospace), monospace; +} + +a { + color: var(--color-accent); +} diff --git a/packages/react-common-docs/public/theme/dark.css b/packages/react-common-docs/public/theme/dark.css index 9e36de6..44e7b0a 100644 --- a/packages/react-common-docs/public/theme/dark.css +++ b/packages/react-common-docs/public/theme/dark.css @@ -1,73 +1,9 @@ -@font-face { - font-family: 'Encode Sans'; - font-stretch: semi-expanded; - font-weight: 400; - src: - local('Encode Sans Semi Expanded'), - local('Encode Sans'); -} - -@font-face { - font-family: 'Encode Sans'; - font-stretch: semi-expanded; - font-weight: 700; - src: - local('Encode Sans Semi Expanded Bold'), - local('Encode Sans Semi Expanded'), - local('Encode Sans'); -} - -@font-face { - font-family: 'Encode Sans'; - font-stretch: condensed; - font-weight: 100; - src: - local('Encode Sans Condensed Thin'), - local('Encode Sans Condensed'), - local('Encode Sans'); -} - -@font-face { - font-family: 'Encode Sans'; - font-stretch: condensed; - font-weight: 200; - src: - local('Encode Sans Condensed ExtraLight'), - local('Encode Sans Condensed Extra Light'), - local('Encode Sans Condensed'), - local('Encode Sans'); -} - -@font-face { - font-family: 'Encode Sans'; - font-stretch: condensed; - font-weight: 300; - src: - local('Encode Sans Condensed Light'), - local('Encode Sans Condensed'), - local('Encode Sans'); -} - :root { --color-shade: #000; - --color-active: #f90; - --font-family-base: 'Encode Sans Semi Expanded', 'Encode Sans', system-ui; - --font-stretch-base: semi-expanded; - --font-weight-base: 400; - --line-height-base: 2; - --font-family-headings:'Encode Sans Condensed', 'Encode Sans', system-ui; - --font-stretch-headings: condensed; - --font-weight-headings: 100; - --line-height-headings: 1.5; - --font-family-monospace: 'mononoki'; - --font-size-root: 16px; --color-negative: #222; --color-positive: #eee; --color-accent: #C78AB3; - --opacity-light: 0.25; - --opacity-lighter: 0.5; - --opacity-lightest: 0.75; - + --color-active: #f90; --color-code-number: #74f95e; --color-code-keyword: #ff4389; --color-code-type: #5097D2; @@ -81,72 +17,3 @@ --color-code-url: #0099CC; --color-code-global: #C28050; } - -:root { - --color-bg: var(--color-negative, white); - --color-fg: var(--color-positive, black); - background-color: var(--color-bg); - color: var(--color-fg); - font-size: var(--font-size-root); - font-family: var(--font-family-base), sans-serif; - font-stretch: var(--font-stretch-base, normal); - font-weight: var(--font-weight-base, 400); - line-height: var(--line-height-base, 2); - transition-property: color, background-color; - transition-timing-function: ease; - transition-duration: 350ms; -} - -h1 { - font-family: var(--font-family-headings), sans-serif; - font-stretch: var(--font-stretch-headings, normal); - font-weight: var(--font-weight-headings, 400); - line-height: var(--line-height-headings, 1.5); -} - -h2 { - font-family: var(--font-family-headings), sans-serif; - font-stretch: var(--font-stretch-headings, normal); - font-weight: var(--font-weight-headings, 400); - line-height: var(--line-height-headings, 1.5); -} - -h3 { - font-family: var(--font-family-headings), sans-serif; - font-stretch: var(--font-stretch-headings, normal); - font-weight: var(--font-weight-headings, 400); - line-height: var(--line-height-headings, 1.5); -} - -h4 { - font-family: var(--font-family-headings), sans-serif; - font-stretch: var(--font-stretch-headings, normal); - font-weight: var(--font-weight-headings, 400); - line-height: var(--line-height-headings, 1.5); -} - -h5 { - font-family: var(--font-family-headings), sans-serif; - font-stretch: var(--font-stretch-headings, normal); - font-weight: var(--font-weight-headings, 400); - line-height: var(--line-height-headings, 1.5); -} - -h6 { - font-family: var(--font-family-headings), sans-serif; - font-stretch: var(--font-stretch-headings, normal); - font-weight: var(--font-weight-headings, 400); - line-height: var(--line-height-headings, 1.5); -} - -a { - color: var(--color-accent); -} - -code { - font-family: var(--font-family-monospace), monospace; -} - -pre { - font-family: var(--font-family-monospace), monospace; -} diff --git a/packages/react-common-docs/public/theme/light.css b/packages/react-common-docs/public/theme/light.css index 6834721..ed6ae3a 100644 --- a/packages/react-common-docs/public/theme/light.css +++ b/packages/react-common-docs/public/theme/light.css @@ -1,73 +1,9 @@ -@font-face { - font-family: 'Encode Sans'; - font-stretch: semi-expanded; - font-weight: 400; - src: - local('Encode Sans Semi Expanded'), - local('Encode Sans'); -} - -@font-face { - font-family: 'Encode Sans'; - font-stretch: semi-expanded; - font-weight: 700; - src: - local('Encode Sans Semi Expanded Bold'), - local('Encode Sans Semi Expanded'), - local('Encode Sans'); -} - -@font-face { - font-family: 'Encode Sans'; - font-stretch: condensed; - font-weight: 100; - src: - local('Encode Sans Condensed Thin'), - local('Encode Sans Condensed'), - local('Encode Sans'); -} - -@font-face { - font-family: 'Encode Sans'; - font-stretch: condensed; - font-weight: 200; - src: - local('Encode Sans Condensed ExtraLight'), - local('Encode Sans Condensed Extra Light'), - local('Encode Sans Condensed'), - local('Encode Sans'); -} - -@font-face { - font-family: 'Encode Sans'; - font-stretch: condensed; - font-weight: 300; - src: - local('Encode Sans Condensed Light'), - local('Encode Sans Condensed'), - local('Encode Sans'); -} - :root { --color-shade: #fff; --color-negative: #f8f8f8; --color-positive: #333; --color-accent: #ba6a9c; --color-active: #f90; - --font-family-base: 'Encode Sans Semi Expanded', 'Encode Sans', system-ui; - --font-stretch-base: semi-expanded; - --font-weight-base: 400; - --line-height-base: 2; - --font-family-headings:'Encode Sans Condensed', 'Encode Sans', system-ui; - --font-stretch-headings: condensed; - --font-weight-headings: 100; - --line-height-headings: 1.5; - --font-family-monospace: 'mononoki'; - --font-size-root: 16px; - --opacity-light: 0.5; - --opacity-lighter: 0.75; - --opacity-lightest: 0.875; - --color-code-number: #72b507; --color-code-keyword: #ee5189; --color-code-type: #427fb1; @@ -81,80 +17,3 @@ --color-code-url: #0099CC; --color-code-global: #C28050; } - -/*@media (prefers-color-scheme: dark) {*/ -/* :root {*/ -/* --color-negative: #222;*/ -/* --color-positive: #eee;*/ -/* --color-accent: #C78AB3;*/ -/* --opacity-light: 0.25;*/ -/* --opacity-lighter: 0.5;*/ -/* --opacity-lightest: 0.75;*/ -/* }*/ -/*}*/ - -:root { - --color-bg: var(--color-negative, white); - --color-fg: var(--color-positive, black); - background-color: var(--color-bg); - color: var(--color-fg); - font-size: var(--font-size-root); - font-family: var(--font-family-base), sans-serif; - font-stretch: var(--font-stretch-base, normal); - font-weight: var(--font-weight-base, 400); - line-height: var(--line-height-base, 2); -} - -h1 { - font-family: var(--font-family-headings), sans-serif; - font-stretch: var(--font-stretch-headings, normal); - font-weight: var(--font-weight-headings, 400); - line-height: var(--line-height-headings, 1.5); -} - -h2 { - font-family: var(--font-family-headings), sans-serif; - font-stretch: var(--font-stretch-headings, normal); - font-weight: var(--font-weight-headings, 400); - line-height: var(--line-height-headings, 1.5); -} - -h3 { - font-family: var(--font-family-headings), sans-serif; - font-stretch: var(--font-stretch-headings, normal); - font-weight: var(--font-weight-headings, 400); - line-height: var(--line-height-headings, 1.5); -} - -h4 { - font-family: var(--font-family-headings), sans-serif; - font-stretch: var(--font-stretch-headings, normal); - font-weight: var(--font-weight-headings, 400); - line-height: var(--line-height-headings, 1.5); -} - -h5 { - font-family: var(--font-family-headings), sans-serif; - font-stretch: var(--font-stretch-headings, normal); - font-weight: var(--font-weight-headings, 400); - line-height: var(--line-height-headings, 1.5); -} - -h6 { - font-family: var(--font-family-headings), sans-serif; - font-stretch: var(--font-stretch-headings, normal); - font-weight: var(--font-weight-headings, 400); - line-height: var(--line-height-headings, 1.5); -} - -a { - color: var(--color-accent); -} - -code { - font-family: var(--font-family-monospace), monospace; -} - -pre { - font-family: var(--font-family-monospace), monospace; -} diff --git a/packages/react-common-docs/src/components/ThemeToggle/ThemeToggle.tsx b/packages/react-common-docs/src/components/ThemeToggle/ThemeToggle.tsx index 1932112..237917a 100644 --- a/packages/react-common-docs/src/components/ThemeToggle/ThemeToggle.tsx +++ b/packages/react-common-docs/src/components/ThemeToggle/ThemeToggle.tsx @@ -35,61 +35,41 @@ const applyStyles = (theme) => { }) } -const handleInitializeTheme = (initialTheme: string) => () => { - applyStyles(getTheme() || initialTheme) -} - const ThemeToggle = ({ initialTheme, }) => { - const [theme, setTheme] = React.useState(initialTheme!) + const [theme, setTheme] = React.useState(null) - const handleSetTheme = (t: string) => () => { - setTheme(t) + const handleSetTheme = (e) => { + setTheme(e.target.checked ? 'Light' : 'Dark') } React.useEffect(() => { - window.localStorage.setItem('tesseract-theme', theme as string) - }, [theme]) - - React.useEffect(() => { - applyStyles(theme) + if (theme as string) { + window.localStorage.setItem('tesseract-theme', theme) + return + } + setTheme(getTheme()) }, [theme]) React.useEffect(() => { - const handler = handleInitializeTheme(initialTheme) - window.addEventListener('load', handler) - return () => { - window.removeEventListener('load', handler) + if (theme as string) { + applyStyles(theme) } - }, [initialTheme]) + }, [theme]) return ( - { - theme === 'Dark' - && ( - - ) - } - { - theme === 'Light' - && ( - - ) - } + ) diff --git a/packages/react-common-docs/src/pages/_document.tsx b/packages/react-common-docs/src/pages/_document.tsx index 447a5ce..801ac72 100644 --- a/packages/react-common-docs/src/pages/_document.tsx +++ b/packages/react-common-docs/src/pages/_document.tsx @@ -24,7 +24,8 @@ export default class MyDocument extends Document { <> {initialProps.styles} - + + {sheet.getStyleElement()}