diff --git a/.changeset/modern-singers-watch.md b/.changeset/modern-singers-watch.md new file mode 100644 index 000000000..8eeaac8e0 --- /dev/null +++ b/.changeset/modern-singers-watch.md @@ -0,0 +1,5 @@ +--- +'@ryanatkn/fuz': patch +--- + +fix ssr diff --git a/.changeset/new-berries-sleep.md b/.changeset/new-berries-sleep.md new file mode 100644 index 000000000..7e5d70a2c --- /dev/null +++ b/.changeset/new-berries-sleep.md @@ -0,0 +1,9 @@ +--- +'@ryanatkn/fuz': minor +--- + +rework `Themed.svelte` + +- move some helpers from `Themed.svelte` to `theme.ts` +- replace `get_theme` and `get_color_scheme` with `get_themer` +- remove `Themed_Scope.svelte` for now because it's too broken diff --git a/package-lock.json b/package-lock.json index e41bad2fb..4819aba5a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,9 +14,9 @@ "@ryanatkn/eslint-config": "^0.4.0", "@ryanatkn/fuz_code": "^0.15.0", "@ryanatkn/gro": "^0.129.0", - "@ryanatkn/moss": "^0.6.3", + "@ryanatkn/moss": "^0.7.0", "@sveltejs/adapter-static": "^3.0.2", - "@sveltejs/kit": "^2.5.17", + "@sveltejs/kit": "^2.5.18", "@sveltejs/package": "^2.3.2", "@sveltejs/vite-plugin-svelte": "^3.1.1", "@types/node": "^20.14.8", @@ -28,7 +28,7 @@ "prettier-plugin-svelte": "^3.2.5", "prism-svelte": "^0.5.0", "prismjs": "^1.29.0", - "svelte": "^5.0.0-next.164", + "svelte": "^5.0.0-next.175", "svelte-check": "^3.8.2", "tslib": "^2.6.3", "typescript": "^5.5.2", @@ -485,9 +485,9 @@ } }, "node_modules/@ryanatkn/moss": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@ryanatkn/moss/-/moss-0.6.3.tgz", - "integrity": "sha512-HxnupZSj50gMY6kkojyaG5aqUsw9yHRHvFEzzxux99fGMGaXxMafq3WJ2ag0kHEdgyttKlGIeXtsLLrwfvM4wA==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@ryanatkn/moss/-/moss-0.7.0.tgz", + "integrity": "sha512-xE/eksGvf+lCIxyhfCQvFeh0qLgBZkDdqcNJuyFmpyu+fXNFAYzo09YcH5MTP8lLSBe879MJssk9ZBjTKbVsKQ==", "dev": true, "license": "MIT", "engines": { @@ -508,9 +508,9 @@ } }, "node_modules/@sveltejs/kit": { - "version": "2.5.17", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.17.tgz", - "integrity": "sha512-wiADwq7VreR3ctOyxilAZOfPz3Jiy2IIp2C8gfafhTdQaVuGIHllfqQm8dXZKADymKr3uShxzgLZFT+a+CM4kA==", + "version": "2.5.18", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.18.tgz", + "integrity": "sha512-+g06hvpVAnH7b4CDjhnTDgFWBKBiQJpuSmQeGYOuzbO3SC3tdYjRNlDCrafvDtKbGiT2uxY5Dn9qdEUGVZdWOQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -2826,9 +2826,9 @@ } }, "node_modules/svelte": { - "version": "5.0.0-next.164", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.164.tgz", - "integrity": "sha512-e+V1dSZLCCu0Ln7RKwSl/zP9ZZFbDGW7ABfGQYU/+6sWponizQocmyHyKHzctor0ruGgJKOF7QQB+M6lE2+UrA==", + "version": "5.0.0-next.175", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.175.tgz", + "integrity": "sha512-fWMI0O3PiKFWvTohAEJRkd6RymR3uo7PO8GrNfyx57KDvmmK1KYRzAdHjx+RsKl8oZhfWeJHiot6iebgY8lJng==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index e45e86476..f2d471f8a 100644 --- a/package.json +++ b/package.json @@ -45,9 +45,9 @@ "@ryanatkn/eslint-config": "^0.4.0", "@ryanatkn/fuz_code": "^0.15.0", "@ryanatkn/gro": "^0.129.0", - "@ryanatkn/moss": "^0.6.3", + "@ryanatkn/moss": "^0.7.0", "@sveltejs/adapter-static": "^3.0.2", - "@sveltejs/kit": "^2.5.17", + "@sveltejs/kit": "^2.5.18", "@sveltejs/package": "^2.3.2", "@sveltejs/vite-plugin-svelte": "^3.1.1", "@types/node": "^20.14.8", @@ -59,7 +59,7 @@ "prettier-plugin-svelte": "^3.2.5", "prism-svelte": "^0.5.0", "prismjs": "^1.29.0", - "svelte": "^5.0.0-next.164", + "svelte": "^5.0.0-next.175", "svelte-check": "^3.8.2", "tslib": "^2.6.3", "typescript": "^5.5.2", @@ -324,14 +324,9 @@ "svelte": "./dist/Theme_Input.svelte", "default": "./dist/Theme_Input.svelte" }, - "./theme.js": { - "types": "./dist/theme.d.ts", - "default": "./dist/theme.js" - }, - "./Themed_Scope.svelte": { - "types": "./dist/Themed_Scope.svelte.d.ts", - "svelte": "./dist/Themed_Scope.svelte", - "default": "./dist/Themed_Scope.svelte" + "./theme.svelte.js": { + "types": "./dist/theme.svelte.d.ts", + "default": "./dist/theme.svelte.js" }, "./Themed.svelte": { "types": "./dist/Themed.svelte.d.ts", diff --git a/src/app.html b/src/app.html index 94e54be2f..e8329aae4 100644 --- a/src/app.html +++ b/src/app.html @@ -8,7 +8,6 @@ %sveltekit.head% -
%sveltekit.body%
diff --git a/src/lib/Color_Scheme_Input.svelte b/src/lib/Color_Scheme_Input.svelte index 02b684b57..1af838509 100644 --- a/src/lib/Color_Scheme_Input.svelte +++ b/src/lib/Color_Scheme_Input.svelte @@ -1,22 +1,19 @@ @@ -24,7 +21,7 @@ https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/menubar_role --> {#each color_schemes as color_scheme (color_scheme)} - {@const selected = color_scheme === $selected_color_scheme} + {@const selected = color_scheme === value.color_scheme} @@ -192,10 +209,15 @@ {/each} {#each themes as theme (theme.name)} - + @multiple proper equality check, won't work when we allow editing, need an id or unique names and a deep equality check {@const selected = - $selected_color_scheme === 'dark' && theme.name === $selected_theme.name} - + themer.color_scheme === 'dark' && theme.name === themer.theme.name} + theme), + 'dark', + )} + >
@@ -216,8 +238,9 @@
+ -->
- +

Themes are plain CSS that can be sourced in a variety of ways.

To use Fuz's base theme:

`} />

- Themed can be customized with the nonreactive, bindable, writable store props - selected_theme - and selected_color_scheme: + Themed can be customized with the the nonreactive prop + themer:

+ content={`import {Themer} from '@ryanatkn/fuz/theme.svelte.js';\nconst themer = new Themer(...);`} + lang="ts" + /> + {@render children()} `} /> +

- Themed sets the writable stores selected_theme - and selected_color_scheme in the Svelte context: + Themed sets the themer in the Svelte context:

+ -
- {#snippet summary()}More about Themed{/snippet} - -
+

+ For a more complete example, see fuz_template. +

+
+
+ +

+ Themed initializes the system's theme support. Without it, the page will not + reflect the user's system + color-scheme. By default, Themed applies the base theme to the root + of the page via create_theme_setup_script. It uses JS to add the + .dark CSS class to the :root element. +

+

+ This strategy enables color scheme and theme support with minimal CSS and optimal performance + for most use cases. The system supports plain CSS usage that can be static or dynamic, or + imported at buildtime or runtime. It also allows runtime access to the underlying data like + the style variables if you want to pay + the performance costs. Scoped theming to one part of the page is planned. +

+

+ The theme setup script interacts with sync_color_scheme to save the user's + preference to localStorage. See also Color_Scheme_Input. +

+

+ The setup script avoids flash-on-load due to color scheme, but currently themes flash in after + loading. We'll try to fix this when the system stabilizes. +

diff --git a/src/routes/library/Themed/Themed_Scope.svelte b/src/routes/library/Themed/Themed_Scope.svelte new file mode 100644 index 000000000..7cd4210e8 --- /dev/null +++ b/src/routes/library/Themed/Themed_Scope.svelte @@ -0,0 +1,71 @@ + + + + + + + {#if theme_style_html}{@html theme_style_html}{/if} + + +{@render children(id, style, theme_style_html, themer)} diff --git a/src/routes/package.ts b/src/routes/package.ts index 3b979a9d4..9fe473111 100644 --- a/src/routes/package.ts +++ b/src/routes/package.ts @@ -41,9 +41,9 @@ export const package_json = { '@ryanatkn/eslint-config': '^0.4.0', '@ryanatkn/fuz_code': '^0.15.0', '@ryanatkn/gro': '^0.129.0', - '@ryanatkn/moss': '^0.6.3', + '@ryanatkn/moss': '^0.7.0', '@sveltejs/adapter-static': '^3.0.2', - '@sveltejs/kit': '^2.5.17', + '@sveltejs/kit': '^2.5.18', '@sveltejs/package': '^2.3.2', '@sveltejs/vite-plugin-svelte': '^3.1.1', '@types/node': '^20.14.8', @@ -55,7 +55,7 @@ export const package_json = { 'prettier-plugin-svelte': '^3.2.5', 'prism-svelte': '^0.5.0', prismjs: '^1.29.0', - svelte: '^5.0.0-next.164', + svelte: '^5.0.0-next.175', 'svelte-check': '^3.8.2', tslib: '^2.6.3', typescript: '^5.5.2', @@ -298,12 +298,7 @@ export const package_json = { svelte: './dist/Theme_Input.svelte', default: './dist/Theme_Input.svelte', }, - './theme.js': {types: './dist/theme.d.ts', default: './dist/theme.js'}, - './Themed_Scope.svelte': { - types: './dist/Themed_Scope.svelte.d.ts', - svelte: './dist/Themed_Scope.svelte', - default: './dist/Themed_Scope.svelte', - }, + './theme.svelte.js': {types: './dist/theme.svelte.d.ts', default: './dist/theme.svelte.js'}, './Themed.svelte': { types: './dist/Themed.svelte.d.ts', svelte: './dist/Themed.svelte', @@ -454,9 +449,13 @@ export const src_json = { './Spiderspace_Logo.svelte': {path: 'Spiderspace_Logo.svelte', declarations: []}, './Teleport.svelte': {path: 'Teleport.svelte', declarations: []}, './Theme_Input.svelte': {path: 'Theme_Input.svelte', declarations: []}, - './theme.js': { - path: 'theme.ts', + './theme.svelte.js': { + path: 'theme.svelte.ts', declarations: [ + {name: 'Themer', kind: 'class'}, + {name: 'Themer_Json', kind: 'type'}, + {name: 'get_themer', kind: 'function'}, + {name: 'set_themer', kind: 'function'}, {name: 'sync_color_scheme', kind: 'function'}, {name: 'COLOR_SCHEME_STORAGE_KEY', kind: 'variable'}, {name: 'save_color_scheme', kind: 'function'}, @@ -465,9 +464,9 @@ export const src_json = { {name: 'save_theme', kind: 'function'}, {name: 'load_theme', kind: 'function'}, {name: 'create_theme_setup_script', kind: 'function'}, + {name: 'create_theme_style_html', kind: 'function'}, ], }, - './Themed_Scope.svelte': {path: 'Themed_Scope.svelte', declarations: []}, './Themed.svelte': {path: 'Themed.svelte', declarations: []}, './Tome_Detail.svelte': {path: 'Tome_Detail.svelte', declarations: []}, './Tome_Link.svelte': {path: 'Tome_Link.svelte', declarations: []},