too lazy to think of a message, so enjoy this pointless text. Good luck future me...
All checks were successful
Test action / Print hello world (push) Successful in 8m32s

This commit is contained in:
Chris Kruining 2025-10-08 10:49:59 +00:00
parent e7b0307690
commit 28fdba8b00
15 changed files with 3868 additions and 2785 deletions

View file

@ -1,471 +1,471 @@
@layer reset, base, tokens, recipes, utilities;
@import "open-props/style" layer(tokens);
@import "open-props/normalize" layer(reset);
@import "open-props/durations" layer(base);
@import "open-props/theme.light.switch.min.css" layer(tokens);
@import "open-props/theme.dark.switch.min.css" layer(tokens);
@layer base {
html {
display: grid;
grid: 100% / 100%;
inline-size: 100%;
block-size: 100%;
overflow: clip;
/* font-size: clamp(1rem, -0.875rem + 8.333vw, 3.5rem); */
& > body {
display: grid;
grid: 100% / 100%;
inline-size: 100%;
block-size: 100%;
contain: layout style paint;
margin: 0;
font-family: sans-serif;
overflow: clip;
background-color: var(--surface-3);
color: var(--text-2);
accent-color: var(--primary-500);
* {
box-sizing: border-box;
&:focus-visible {
outline: 1px solid var(--info);
}
}
}
}
}
@layer reset {
@property --sibling-index {
syntax: "<integer>";
inherits: false;
initial-value: 1;
}
@property --sibling-count {
syntax: "<integer>";
inherits: false;
initial-value: 0;
}
:nth-child(1) {
--sibling-index: 1;
}
:nth-child(2) {
--sibling-index: 2;
}
:nth-child(3) {
--sibling-index: 3;
}
:nth-child(4) {
--sibling-index: 4;
}
:nth-child(5) {
--sibling-index: 5;
}
:nth-child(6) {
--sibling-index: 6;
}
:nth-child(7) {
--sibling-index: 7;
}
:nth-child(8) {
--sibling-index: 8;
}
:nth-child(9) {
--sibling-index: 9;
}
:nth-child(10) {
--sibling-index: 10;
}
:nth-child(11) {
--sibling-index: 11;
}
:nth-child(12) {
--sibling-index: 12;
}
:nth-child(13) {
--sibling-index: 13;
}
:nth-child(14) {
--sibling-index: 14;
}
:nth-child(15) {
--sibling-index: 15;
}
:nth-child(16) {
--sibling-index: 16;
}
:nth-child(17) {
--sibling-index: 17;
}
:nth-child(18) {
--sibling-index: 18;
}
:nth-child(19) {
--sibling-index: 19;
}
:nth-child(20) {
--sibling-index: 20;
}
:nth-child(21) {
--sibling-index: 21;
}
:nth-child(22) {
--sibling-index: 22;
}
:nth-child(23) {
--sibling-index: 23;
}
:nth-child(24) {
--sibling-index: 24;
}
:nth-child(25) {
--sibling-index: 25;
}
:nth-child(26) {
--sibling-index: 26;
}
:nth-child(27) {
--sibling-index: 27;
}
:nth-child(28) {
--sibling-index: 28;
}
:nth-child(29) {
--sibling-index: 29;
}
:nth-child(30) {
--sibling-index: 30;
}
:nth-child(31) {
--sibling-index: 31;
}
:nth-child(32) {
--sibling-index: 32;
}
:nth-child(33) {
--sibling-index: 33;
}
:nth-child(34) {
--sibling-index: 34;
}
:nth-child(35) {
--sibling-index: 35;
}
:nth-child(36) {
--sibling-index: 36;
}
:nth-child(37) {
--sibling-index: 37;
}
:nth-child(38) {
--sibling-index: 38;
}
:nth-child(39) {
--sibling-index: 39;
}
:nth-child(40) {
--sibling-index: 40;
}
:nth-child(41) {
--sibling-index: 41;
}
:nth-child(42) {
--sibling-index: 42;
}
:nth-child(43) {
--sibling-index: 43;
}
:nth-child(44) {
--sibling-index: 44;
}
:nth-child(45) {
--sibling-index: 45;
}
:nth-child(46) {
--sibling-index: 46;
}
:nth-child(47) {
--sibling-index: 47;
}
:nth-child(48) {
--sibling-index: 48;
}
:nth-child(49) {
--sibling-index: 49;
}
:nth-child(50) {
--sibling-index: 50;
}
:nth-child(51) {
--sibling-index: 51;
}
:nth-child(52) {
--sibling-index: 52;
}
:nth-child(53) {
--sibling-index: 53;
}
:nth-child(54) {
--sibling-index: 54;
}
:nth-child(55) {
--sibling-index: 55;
}
:nth-child(56) {
--sibling-index: 56;
}
:nth-child(57) {
--sibling-index: 57;
}
:nth-child(58) {
--sibling-index: 58;
}
:nth-child(59) {
--sibling-index: 59;
}
:has(> :last-child:nth-child(1)) > * {
--sibling-count: 1;
}
:has(> :last-child:nth-child(2)) > * {
--sibling-count: 2;
}
:has(> :last-child:nth-child(3)) > * {
--sibling-count: 3;
}
:has(> :last-child:nth-child(4)) > * {
--sibling-count: 4;
}
:has(> :last-child:nth-child(5)) > * {
--sibling-count: 5;
}
:has(> :last-child:nth-child(6)) > * {
--sibling-count: 6;
}
:has(> :last-child:nth-child(7)) > * {
--sibling-count: 7;
}
:has(> :last-child:nth-child(8)) > * {
--sibling-count: 8;
}
:has(> :last-child:nth-child(9)) > * {
--sibling-count: 9;
}
:has(> :last-child:nth-child(10)) > * {
--sibling-count: 10;
}
:has(> :last-child:nth-child(11)) > * {
--sibling-count: 11;
}
:has(> :last-child:nth-child(12)) > * {
--sibling-count: 12;
}
:has(> :last-child:nth-child(13)) > * {
--sibling-count: 13;
}
:has(> :last-child:nth-child(14)) > * {
--sibling-count: 14;
}
:has(> :last-child:nth-child(15)) > * {
--sibling-count: 15;
}
:has(> :last-child:nth-child(16)) > * {
--sibling-count: 16;
}
:has(> :last-child:nth-child(17)) > * {
--sibling-count: 17;
}
:has(> :last-child:nth-child(18)) > * {
--sibling-count: 18;
}
:has(> :last-child:nth-child(19)) > * {
--sibling-count: 19;
}
:has(> :last-child:nth-child(20)) > * {
--sibling-count: 20;
}
:has(> :last-child:nth-child(21)) > * {
--sibling-count: 21;
}
:has(> :last-child:nth-child(22)) > * {
--sibling-count: 22;
}
:has(> :last-child:nth-child(23)) > * {
--sibling-count: 23;
}
:has(> :last-child:nth-child(24)) > * {
--sibling-count: 24;
}
:has(> :last-child:nth-child(25)) > * {
--sibling-count: 25;
}
:has(> :last-child:nth-child(26)) > * {
--sibling-count: 26;
}
:has(> :last-child:nth-child(27)) > * {
--sibling-count: 27;
}
:has(> :last-child:nth-child(28)) > * {
--sibling-count: 28;
}
:has(> :last-child:nth-child(29)) > * {
--sibling-count: 29;
}
:has(> :last-child:nth-child(30)) > * {
--sibling-count: 30;
}
:has(> :last-child:nth-child(31)) > * {
--sibling-count: 31;
}
:has(> :last-child:nth-child(32)) > * {
--sibling-count: 32;
}
:has(> :last-child:nth-child(33)) > * {
--sibling-count: 33;
}
:has(> :last-child:nth-child(34)) > * {
--sibling-count: 34;
}
:has(> :last-child:nth-child(35)) > * {
--sibling-count: 35;
}
:has(> :last-child:nth-child(36)) > * {
--sibling-count: 36;
}
:has(> :last-child:nth-child(37)) > * {
--sibling-count: 37;
}
:has(> :last-child:nth-child(38)) > * {
--sibling-count: 38;
}
:has(> :last-child:nth-child(39)) > * {
--sibling-count: 39;
}
:has(> :last-child:nth-child(40)) > * {
--sibling-count: 40;
}
:has(> :last-child:nth-child(41)) > * {
--sibling-count: 41;
}
:has(> :last-child:nth-child(42)) > * {
--sibling-count: 42;
}
:has(> :last-child:nth-child(43)) > * {
--sibling-count: 43;
}
:has(> :last-child:nth-child(44)) > * {
--sibling-count: 44;
}
:has(> :last-child:nth-child(45)) > * {
--sibling-count: 45;
}
:has(> :last-child:nth-child(46)) > * {
--sibling-count: 46;
}
:has(> :last-child:nth-child(47)) > * {
--sibling-count: 47;
}
:has(> :last-child:nth-child(48)) > * {
--sibling-count: 48;
}
:has(> :last-child:nth-child(49)) > * {
--sibling-count: 49;
}
:has(> :last-child:nth-child(50)) > * {
--sibling-count: 50;
}
:has(> :last-child:nth-child(51)) > * {
--sibling-count: 51;
}
:has(> :last-child:nth-child(52)) > * {
--sibling-count: 52;
}
:has(> :last-child:nth-child(53)) > * {
--sibling-count: 53;
}
:has(> :last-child:nth-child(54)) > * {
--sibling-count: 54;
}
:has(> :last-child:nth-child(55)) > * {
--sibling-count: 55;
}
:has(> :last-child:nth-child(56)) > * {
--sibling-count: 56;
}
:has(> :last-child:nth-child(57)) > * {
--sibling-count: 57;
}
:has(> :last-child:nth-child(58)) > * {
--sibling-count: 58;
}
:has(> :last-child:nth-child(59)) > * {
--sibling-count: 59;
}
:has(> :last-child:nth-child(60)) > * {
--sibling-count: 60;
}
:has(> :last-child:nth-child(61)) > * {
--sibling-count: 61;
}
:has(> :last-child:nth-child(62)) > * {
--sibling-count: 62;
}
:has(> :last-child:nth-child(63)) > * {
--sibling-count: 63;
}
:has(> :last-child:nth-child(64)) > * {
--sibling-count: 64;
}
:has(> :last-child:nth-child(65)) > * {
--sibling-count: 65;
}
:has(> :last-child:nth-child(66)) > * {
--sibling-count: 66;
}
:has(> :last-child:nth-child(67)) > * {
--sibling-count: 67;
}
:has(> :last-child:nth-child(68)) > * {
--sibling-count: 68;
}
:has(> :last-child:nth-child(69)) > * {
--sibling-count: 69;
}
}
@layer reset, base, tokens, recipes, utilities;
@import "open-props/style" layer(tokens);
@import "open-props/normalize" layer(reset);
@import "open-props/durations" layer(base);
@import "open-props/theme.light.switch.min.css" layer(tokens);
@import "open-props/theme.dark.switch.min.css" layer(tokens);
@layer base {
html {
display: grid;
grid: 100% / 100%;
inline-size: 100%;
block-size: 100%;
overflow: clip;
/* font-size: clamp(1rem, -0.875rem + 8.333vw, 3.5rem); */
& > body {
display: grid;
grid: 100% / 100%;
inline-size: 100%;
block-size: 100%;
contain: layout style paint;
margin: 0;
font-family: sans-serif;
overflow: clip;
background-color: var(--surface-3);
color: var(--text-2);
accent-color: var(--primary-500);
* {
box-sizing: border-box;
&:focus-visible {
outline: 1px solid var(--info);
}
}
}
}
}
@layer reset {
@property --sibling-index {
syntax: "<integer>";
inherits: false;
initial-value: 1;
}
@property --sibling-count {
syntax: "<integer>";
inherits: false;
initial-value: 0;
}
:nth-child(1) {
--sibling-index: 1;
}
:nth-child(2) {
--sibling-index: 2;
}
:nth-child(3) {
--sibling-index: 3;
}
:nth-child(4) {
--sibling-index: 4;
}
:nth-child(5) {
--sibling-index: 5;
}
:nth-child(6) {
--sibling-index: 6;
}
:nth-child(7) {
--sibling-index: 7;
}
:nth-child(8) {
--sibling-index: 8;
}
:nth-child(9) {
--sibling-index: 9;
}
:nth-child(10) {
--sibling-index: 10;
}
:nth-child(11) {
--sibling-index: 11;
}
:nth-child(12) {
--sibling-index: 12;
}
:nth-child(13) {
--sibling-index: 13;
}
:nth-child(14) {
--sibling-index: 14;
}
:nth-child(15) {
--sibling-index: 15;
}
:nth-child(16) {
--sibling-index: 16;
}
:nth-child(17) {
--sibling-index: 17;
}
:nth-child(18) {
--sibling-index: 18;
}
:nth-child(19) {
--sibling-index: 19;
}
:nth-child(20) {
--sibling-index: 20;
}
:nth-child(21) {
--sibling-index: 21;
}
:nth-child(22) {
--sibling-index: 22;
}
:nth-child(23) {
--sibling-index: 23;
}
:nth-child(24) {
--sibling-index: 24;
}
:nth-child(25) {
--sibling-index: 25;
}
:nth-child(26) {
--sibling-index: 26;
}
:nth-child(27) {
--sibling-index: 27;
}
:nth-child(28) {
--sibling-index: 28;
}
:nth-child(29) {
--sibling-index: 29;
}
:nth-child(30) {
--sibling-index: 30;
}
:nth-child(31) {
--sibling-index: 31;
}
:nth-child(32) {
--sibling-index: 32;
}
:nth-child(33) {
--sibling-index: 33;
}
:nth-child(34) {
--sibling-index: 34;
}
:nth-child(35) {
--sibling-index: 35;
}
:nth-child(36) {
--sibling-index: 36;
}
:nth-child(37) {
--sibling-index: 37;
}
:nth-child(38) {
--sibling-index: 38;
}
:nth-child(39) {
--sibling-index: 39;
}
:nth-child(40) {
--sibling-index: 40;
}
:nth-child(41) {
--sibling-index: 41;
}
:nth-child(42) {
--sibling-index: 42;
}
:nth-child(43) {
--sibling-index: 43;
}
:nth-child(44) {
--sibling-index: 44;
}
:nth-child(45) {
--sibling-index: 45;
}
:nth-child(46) {
--sibling-index: 46;
}
:nth-child(47) {
--sibling-index: 47;
}
:nth-child(48) {
--sibling-index: 48;
}
:nth-child(49) {
--sibling-index: 49;
}
:nth-child(50) {
--sibling-index: 50;
}
:nth-child(51) {
--sibling-index: 51;
}
:nth-child(52) {
--sibling-index: 52;
}
:nth-child(53) {
--sibling-index: 53;
}
:nth-child(54) {
--sibling-index: 54;
}
:nth-child(55) {
--sibling-index: 55;
}
:nth-child(56) {
--sibling-index: 56;
}
:nth-child(57) {
--sibling-index: 57;
}
:nth-child(58) {
--sibling-index: 58;
}
:nth-child(59) {
--sibling-index: 59;
}
:has(> :last-child:nth-child(1)) > * {
--sibling-count: 1;
}
:has(> :last-child:nth-child(2)) > * {
--sibling-count: 2;
}
:has(> :last-child:nth-child(3)) > * {
--sibling-count: 3;
}
:has(> :last-child:nth-child(4)) > * {
--sibling-count: 4;
}
:has(> :last-child:nth-child(5)) > * {
--sibling-count: 5;
}
:has(> :last-child:nth-child(6)) > * {
--sibling-count: 6;
}
:has(> :last-child:nth-child(7)) > * {
--sibling-count: 7;
}
:has(> :last-child:nth-child(8)) > * {
--sibling-count: 8;
}
:has(> :last-child:nth-child(9)) > * {
--sibling-count: 9;
}
:has(> :last-child:nth-child(10)) > * {
--sibling-count: 10;
}
:has(> :last-child:nth-child(11)) > * {
--sibling-count: 11;
}
:has(> :last-child:nth-child(12)) > * {
--sibling-count: 12;
}
:has(> :last-child:nth-child(13)) > * {
--sibling-count: 13;
}
:has(> :last-child:nth-child(14)) > * {
--sibling-count: 14;
}
:has(> :last-child:nth-child(15)) > * {
--sibling-count: 15;
}
:has(> :last-child:nth-child(16)) > * {
--sibling-count: 16;
}
:has(> :last-child:nth-child(17)) > * {
--sibling-count: 17;
}
:has(> :last-child:nth-child(18)) > * {
--sibling-count: 18;
}
:has(> :last-child:nth-child(19)) > * {
--sibling-count: 19;
}
:has(> :last-child:nth-child(20)) > * {
--sibling-count: 20;
}
:has(> :last-child:nth-child(21)) > * {
--sibling-count: 21;
}
:has(> :last-child:nth-child(22)) > * {
--sibling-count: 22;
}
:has(> :last-child:nth-child(23)) > * {
--sibling-count: 23;
}
:has(> :last-child:nth-child(24)) > * {
--sibling-count: 24;
}
:has(> :last-child:nth-child(25)) > * {
--sibling-count: 25;
}
:has(> :last-child:nth-child(26)) > * {
--sibling-count: 26;
}
:has(> :last-child:nth-child(27)) > * {
--sibling-count: 27;
}
:has(> :last-child:nth-child(28)) > * {
--sibling-count: 28;
}
:has(> :last-child:nth-child(29)) > * {
--sibling-count: 29;
}
:has(> :last-child:nth-child(30)) > * {
--sibling-count: 30;
}
:has(> :last-child:nth-child(31)) > * {
--sibling-count: 31;
}
:has(> :last-child:nth-child(32)) > * {
--sibling-count: 32;
}
:has(> :last-child:nth-child(33)) > * {
--sibling-count: 33;
}
:has(> :last-child:nth-child(34)) > * {
--sibling-count: 34;
}
:has(> :last-child:nth-child(35)) > * {
--sibling-count: 35;
}
:has(> :last-child:nth-child(36)) > * {
--sibling-count: 36;
}
:has(> :last-child:nth-child(37)) > * {
--sibling-count: 37;
}
:has(> :last-child:nth-child(38)) > * {
--sibling-count: 38;
}
:has(> :last-child:nth-child(39)) > * {
--sibling-count: 39;
}
:has(> :last-child:nth-child(40)) > * {
--sibling-count: 40;
}
:has(> :last-child:nth-child(41)) > * {
--sibling-count: 41;
}
:has(> :last-child:nth-child(42)) > * {
--sibling-count: 42;
}
:has(> :last-child:nth-child(43)) > * {
--sibling-count: 43;
}
:has(> :last-child:nth-child(44)) > * {
--sibling-count: 44;
}
:has(> :last-child:nth-child(45)) > * {
--sibling-count: 45;
}
:has(> :last-child:nth-child(46)) > * {
--sibling-count: 46;
}
:has(> :last-child:nth-child(47)) > * {
--sibling-count: 47;
}
:has(> :last-child:nth-child(48)) > * {
--sibling-count: 48;
}
:has(> :last-child:nth-child(49)) > * {
--sibling-count: 49;
}
:has(> :last-child:nth-child(50)) > * {
--sibling-count: 50;
}
:has(> :last-child:nth-child(51)) > * {
--sibling-count: 51;
}
:has(> :last-child:nth-child(52)) > * {
--sibling-count: 52;
}
:has(> :last-child:nth-child(53)) > * {
--sibling-count: 53;
}
:has(> :last-child:nth-child(54)) > * {
--sibling-count: 54;
}
:has(> :last-child:nth-child(55)) > * {
--sibling-count: 55;
}
:has(> :last-child:nth-child(56)) > * {
--sibling-count: 56;
}
:has(> :last-child:nth-child(57)) > * {
--sibling-count: 57;
}
:has(> :last-child:nth-child(58)) > * {
--sibling-count: 58;
}
:has(> :last-child:nth-child(59)) > * {
--sibling-count: 59;
}
:has(> :last-child:nth-child(60)) > * {
--sibling-count: 60;
}
:has(> :last-child:nth-child(61)) > * {
--sibling-count: 61;
}
:has(> :last-child:nth-child(62)) > * {
--sibling-count: 62;
}
:has(> :last-child:nth-child(63)) > * {
--sibling-count: 63;
}
:has(> :last-child:nth-child(64)) > * {
--sibling-count: 64;
}
:has(> :last-child:nth-child(65)) > * {
--sibling-count: 65;
}
:has(> :last-child:nth-child(66)) > * {
--sibling-count: 66;
}
:has(> :last-child:nth-child(67)) > * {
--sibling-count: 67;
}
:has(> :last-child:nth-child(68)) > * {
--sibling-count: 68;
}
:has(> :last-child:nth-child(69)) > * {
--sibling-count: 69;
}
}

View file

@ -1,35 +1,35 @@
import { Component, createSignal, onCleanup, onMount } from "solid-js";
import { Entry } from "~/features/content";
import css from "./details.module.css";
interface DetailsProps {
entry: Entry;
}
export const Details: Component<DetailsProps> = (props) => {
const [header, setHeader] = createSignal<HTMLElement>();
onMount(() => {
const observer = new ResizeObserver(([entry]) => {
const { inlineSize, blockSize } = entry.contentBoxSize[0];
(entry.target as HTMLElement).style.setProperty(
"--ratio",
String((blockSize * 0.2) / inlineSize)
);
});
observer.observe(header()!);
onCleanup(() => observer.disconnect());
});
return (
<div class={css.container}>
<header ref={setHeader} class={css.header}>
<img class={css.background} src={props.entry.image} />
<h1>{props.entry.title}</h1>
</header>
</div>
);
};
import { Component, createSignal, onCleanup, onMount } from "solid-js";
import { Entry } from "~/features/content";
import css from "./details.module.css";
interface DetailsProps {
entry: Entry;
}
export const Details: Component<DetailsProps> = (props) => {
const [header, setHeader] = createSignal<HTMLElement>();
onMount(() => {
const observer = new ResizeObserver(([entry]) => {
const { inlineSize, blockSize } = entry.contentBoxSize[0];
(entry.target as HTMLElement).style.setProperty(
"--ratio",
String((blockSize * 0.2) / inlineSize)
);
});
observer.observe(header()!);
onCleanup(() => observer.disconnect());
});
return (
<div class={css.container}>
<header ref={setHeader} class={css.header}>
<img class={css.background} src={props.entry.image} />
<h1>{props.entry.title}</h1>
</header>
</div>
);
};

View file

@ -1,88 +1,88 @@
import {
ContextProviderProps,
createContextProvider,
} from "@solid-primitives/context";
import { action, createAsyncStore, query, useAction } from "@solidjs/router";
import { createStore } from "solid-js/store";
import { useSession } from "vinxi/http";
export enum ColorScheme {
Auto = "light dark",
Light = "light",
Dark = "dark",
}
export interface State {
colorScheme: ColorScheme;
hue: number;
}
const getSession = async () => {
"use server";
return useSession<State>({
password: process.env.SESSION_SECRET!,
});
};
export const getState = query(async () => {
"use server";
const session = await getSession();
if (Object.getOwnPropertyNames(session.data).length === 0) {
await session.update({
colorScheme: ColorScheme.Auto,
hue: 0,
});
}
return session.data;
}, "color-scheme");
const setState = action(async (state: State) => {
"use server";
const session = await getSession();
await session.update((prev) => ({ ...prev, ...state }));
}, "color-scheme");
interface ThemeContextType {
readonly theme: State;
setColorScheme(colorScheme: ColorScheme): void;
setHue(colorScheme: number): void;
}
const [ThemeContextProvider, useTheme] = createContextProvider<
ThemeContextType,
ContextProviderProps
>(
(props) => {
const updateState = useAction(setState);
const state = createAsyncStore(() => getState());
return {
get theme() {
return state.latest ?? { colorScheme: null };
},
setColorScheme(colorScheme) {
// updateState({ colorScheme, hue: state.latest!.hue });
},
setHue(hue) {
// updateState({ hue, colorScheme: state.latest!.colorScheme });
},
};
},
{
theme: {
colorScheme: ColorScheme.Auto,
hue: 180,
},
setColorScheme(colorScheme) {},
setHue(hue) {},
},
);
export { ThemeContextProvider, useTheme };
import {
ContextProviderProps,
createContextProvider,
} from "@solid-primitives/context";
import { action, createAsyncStore, query, useAction } from "@solidjs/router";
import { createStore } from "solid-js/store";
import { useSession } from "vinxi/http";
export enum ColorScheme {
Auto = "light dark",
Light = "light",
Dark = "dark",
}
export interface State {
colorScheme: ColorScheme;
hue: number;
}
const getSession = async () => {
"use server";
return useSession<State>({
password: process.env.SESSION_SECRET!,
});
};
export const getState = query(async () => {
"use server";
const session = await getSession();
if (Object.getOwnPropertyNames(session.data).length === 0) {
await session.update({
colorScheme: ColorScheme.Auto,
hue: 0,
});
}
return session.data;
}, "color-scheme");
const setState = action(async (state: State) => {
"use server";
const session = await getSession();
await session.update((prev) => ({ ...prev, ...state }));
}, "color-scheme");
interface ThemeContextType {
readonly theme: State;
setColorScheme(colorScheme: ColorScheme): void;
setHue(colorScheme: number): void;
}
const [ThemeContextProvider, useTheme] = createContextProvider<
ThemeContextType,
ContextProviderProps
>(
(props) => {
const updateState = useAction(setState);
const state = createAsyncStore(() => getState());
return {
get theme() {
return state.latest ?? { colorScheme: null };
},
setColorScheme(colorScheme) {
// updateState({ colorScheme, hue: state.latest!.hue });
},
setHue(hue) {
// updateState({ hue, colorScheme: state.latest!.colorScheme });
},
};
},
{
theme: {
colorScheme: ColorScheme.Auto,
hue: 180,
},
setColorScheme(colorScheme) {},
setHue(hue) {},
},
);
export { ThemeContextProvider, useTheme };

View file

@ -1,4 +1,4 @@
export { ThemeContextProvider, useTheme } from './context';
export { ThemeContextProvider, useTheme } from './context';
export { ColorSchemePicker } from './picker';

View file

@ -1,9 +1,9 @@
.picker {
grid-template-columns: auto 1fr;
}
.hue {
display: flex;
flex-flow: row;
align-items: center;
.picker {
grid-template-columns: auto 1fr;
}
.hue {
display: flex;
flex-flow: row;
align-items: center;
}

View file

@ -1,69 +1,69 @@
import {
WiMoonAltFirstQuarter,
WiMoonAltFull,
WiMoonAltNew,
} from "solid-icons/wi";
import {
Component,
createEffect,
For,
Match,
on,
Setter,
Switch,
} from "solid-js";
import { ColorScheme, useTheme } from "./context";
import css from "./picker.module.css";
import { Select } from "~/components/select";
const colorSchemes: Record<ColorScheme, keyof typeof ColorScheme> =
Object.fromEntries(
Object.entries(ColorScheme).map(([k, v]) => [v, k])
) as any;
export const ColorSchemePicker: Component = (props) => {
const themeContext = useTheme();
const setScheme: Setter<ColorScheme> = (next) => {
if (typeof next === "function") {
next = next();
}
themeContext.setColorScheme(next);
};
return (
<>
<label aria-label="Color scheme picker">
<Select
id="color-scheme-picker"
class={css.picker}
value={themeContext.theme.colorScheme}
setValue={setScheme}
values={colorSchemes}
>
{(k, v) => (
<>
<Switch>
<Match when={k === ColorScheme.Auto}>
<WiMoonAltFirstQuarter />
</Match>
<Match when={k === ColorScheme.Light}>
<WiMoonAltNew />
</Match>
<Match when={k === ColorScheme.Dark}>
<WiMoonAltFull />
</Match>
</Switch>
{v}
</>
)}
</Select>
</label>
{/* <label class={css.hue} aria-label="Hue slider">
<input type="range" min="0" max="360" value={theme.hue} onInput={e => setHue(e.target.valueAsNumber)} />
</label> */}
</>
);
};
import {
WiMoonAltFirstQuarter,
WiMoonAltFull,
WiMoonAltNew,
} from "solid-icons/wi";
import {
Component,
createEffect,
For,
Match,
on,
Setter,
Switch,
} from "solid-js";
import { ColorScheme, useTheme } from "./context";
import css from "./picker.module.css";
import { Select } from "~/components/select";
const colorSchemes: Record<ColorScheme, keyof typeof ColorScheme> =
Object.fromEntries(
Object.entries(ColorScheme).map(([k, v]) => [v, k])
) as any;
export const ColorSchemePicker: Component = (props) => {
const themeContext = useTheme();
const setScheme: Setter<ColorScheme> = (next) => {
if (typeof next === "function") {
next = next();
}
themeContext.setColorScheme(next);
};
return (
<>
<label aria-label="Color scheme picker">
<Select
id="color-scheme-picker"
class={css.picker}
value={themeContext.theme.colorScheme}
setValue={setScheme}
values={colorSchemes}
>
{(k, v) => (
<>
<Switch>
<Match when={k === ColorScheme.Auto}>
<WiMoonAltFirstQuarter />
</Match>
<Match when={k === ColorScheme.Light}>
<WiMoonAltNew />
</Match>
<Match when={k === ColorScheme.Dark}>
<WiMoonAltFull />
</Match>
</Switch>
{v}
</>
)}
</Select>
</label>
{/* <label class={css.hue} aria-label="Hue slider">
<input type="range" min="0" max="360" value={theme.hue} onInput={e => setHue(e.target.valueAsNumber)} />
</label> */}
</>
);
};

View file

@ -1,41 +1,41 @@
import { Meta } from "@solidjs/meta";
import { query, createAsync } from "@solidjs/router";
import { ParentProps } from "solid-js";
import { getRequestEvent } from "solid-js/web";
import { auth } from "~/auth.server";
import { Shell } from "~/features/shell";
import { useTheme } from "~/features/theme";
import { User } from "~/features/user";
const load = query(async (): Promise<User | undefined> => {
"use server";
const session = await auth.api.getSession(getRequestEvent()!.request);
if (session === null) {
return undefined;
}
const { username, name, email, image = null } = session.user;
return { username, name, email, image };
}, "session");
export const route = {
async preload() {
return load();
},
};
export default function ShellPage(props: ParentProps) {
const user = createAsync(() => load());
const themeContext = useTheme();
return (
<Shell user={user()}>
<Meta name="color-scheme" content={themeContext.theme.colorScheme} />
{props.children}
</Shell>
);
}
import { Meta } from "@solidjs/meta";
import { query, createAsync } from "@solidjs/router";
import { ParentProps } from "solid-js";
import { getRequestEvent } from "solid-js/web";
import { auth } from "~/auth.server";
import { Shell } from "~/features/shell";
import { useTheme } from "~/features/theme";
import { User } from "~/features/user";
const load = query(async (): Promise<User | undefined> => {
"use server";
const session = await auth.api.getSession(getRequestEvent()!.request);
if (session === null) {
return undefined;
}
const { username, name, email, image = null } = session.user;
return { username, name, email, image };
}, "session");
export const route = {
async preload() {
return load();
},
};
export default function ShellPage(props: ParentProps) {
const user = createAsync(() => load());
const themeContext = useTheme();
return (
<Shell user={user()}>
<Meta name="color-scheme" content={themeContext.theme.colorScheme} />
{props.children}
</Shell>
);
}