Add light theme

This commit is contained in:
2024-05-06 18:18:01 +01:00
parent e7b178279e
commit 0c264d8cc7
7 changed files with 100 additions and 7 deletions

View File

@@ -1,12 +1,13 @@
#root {
background-color: var(--color-neutral1);
background-color: var(--color-background1);
color: var(--color-text);
display: grid;
padding: 8px;
gap: 8px;
> div {
border-radius: 16px;
background-color: var(--color-neutral0);
background-color: var(--color-background0);
padding: 16px;
width: 100%;
height: max-content;

View File

@@ -22,7 +22,7 @@ export const CartesianGrid = () => (
key={index}
y1={Math.max(1, Math.min(height - 1, (height * index) / 4))}
y2={Math.max(1, Math.min(height - 1, (height * index) / 4))}
stroke='var(--color-neutral1)'
stroke='var(--color-background1)'
strokeWidth={1}
/>
))}

View File

@@ -1,5 +1,5 @@
.chart {
color: var(--color-neutral2);
color: var(--color-text-subdued);
display: grid;
font-size: 16px;
gap: 4px;

View File

@@ -1,6 +1,7 @@
import { useAnimationFrame } from '@/hooks/use-animation-frame';
import { useQuery } from '@tanstack/react-query';
import { useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import { Switch } from '../switch';
const formatUptime = (value: number) => {
const seconds = String(Math.floor(value % 60)).padStart(2, '0');
@@ -37,6 +38,12 @@ const Uptime = ({ boot_time }: Pick<StaticData, 'boot_time'>) => {
export const Static = () => {
const { data: staticData } = useQuery<StaticData>({ queryKey: ['static'] });
const root = useRef(document.getElementById('root')!);
const [dark, setDark] = useState(window.matchMedia('(prefers-color-scheme: dark)').matches);
useEffect(() => {
root.current.setAttribute('data-theme', dark ? 'dark' : 'light');
}, [dark]);
return (
staticData && (
@@ -51,6 +58,12 @@ export const Static = () => {
<small>Kernel</small>
<h3>{staticData.kernel_version}</h3>
{staticData.boot_time && <Uptime boot_time={staticData.boot_time} />}
<Switch
checked={dark}
label={`${dark ? 'Dark' : 'Light'} theme`}
onChange={({ target }) => setDark(target.checked)}
/>
</div>
)
);

View File

@@ -0,0 +1,46 @@
.switch-wrapper {
display: grid;
grid-template-columns: repeat(2, max-content);
align-items: center;
gap: 8px;
}
.switch {
position: relative;
width: 64px;
height: 32px;
}
.switch input {
visibility: hidden;
}
.slider {
position: absolute;
cursor: pointer;
inset: 0;
background-color: var(--color-background2);
transition: 200ms background-color;
border-radius: 32px;
}
.slider:before {
position: absolute;
content: "";
aspect-ratio: 1;
left: 4px;
top: 4px;
bottom: 4px;
background-color: var(--color-background0);
transition: 200ms transform;
border-radius: 50%;
}
input:checked + .slider {
background-color: var(--color-primary);
}
input:checked + .slider:before {
transform: translateX(32px);
}

View File

@@ -0,0 +1,18 @@
import type { ComponentPropsWithoutRef } from 'react';
import './index.css';
type Props = ComponentPropsWithoutRef<'input'> & {
label: string;
};
export const Switch = ({ label, ...rest }: Props) => {
return (
<label className='switch-wrapper'>
<span className={'switch'}>
<input {...rest} type='checkbox' />
<span className='slider' />
</span>
{label}
</label>
);
};

View File

@@ -7,19 +7,34 @@
--color-neutral5: #93a1a1;
--color-neutral6: #eee8d5;
--color-neutral7: #fdf6e3;
--color-primary: #2aa198;
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color: var(--color-neutral6);
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
[data-theme="light"] {
--color-background0: var(--color-neutral7);
--color-background1: var(--color-neutral6);
--color-background2: var(--color-neutral5);
--color-text: var(--color-neutral1);
--color-text-subdued: var(--color-neutral5);
}
[data-theme="dark"] {
--color-background0: var(--color-neutral0);
--color-background1: var(--color-neutral1);
--color-background2: var(--color-neutral2);
--color-text: var(--color-neutral6);
--color-text-subdued: var(--color-neutral2);
}
body {
margin: 0;
}