diff --git a/app.config.ts b/app.config.ts index 299ea96..56b652b 100644 --- a/app.config.ts +++ b/app.config.ts @@ -76,8 +76,8 @@ export default defineConfig({ }, server: { preset: 'bun', - prerender: { - crawlLinks: true, - }, + // prerender: { + // crawlLinks: true, + // }, }, }); diff --git a/bun.lockb b/bun.lockb index 6d0efbd..69c8aa6 100644 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 14a66e0..0aecb9a 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,9 @@ "name": "calque", "dependencies": { "@solidjs/meta": "^0.29.4", - "@solidjs/router": "^0.15.0", - "@solidjs/start": "^1.0.9", - "dexie": "^4.0.9", + "@solidjs/router": "^0.15.1", + "@solidjs/start": "^1.0.10", + "dexie": "^4.0.10", "iterator-helpers-polyfill": "^3.0.1", "solid-icons": "^1.1.0", "solid-js": "^1.9.3", @@ -22,16 +22,16 @@ }, "type": "module", "devDependencies": { - "@happy-dom/global-registrator": "^15.11.0", + "@happy-dom/global-registrator": "^15.11.7", "@sinonjs/fake-timers": "^13.0.5", "@solidjs/testing-library": "^0.8.10", "@testing-library/jest-dom": "^6.6.3", "@testing-library/user-event": "^14.5.2", "@types/sinonjs__fake-timers": "^8.1.5", "@types/wicg-file-system-access": "^2023.10.5", - "bun-types": "^1.1.34", + "bun-types": "^1.1.38", "jsdom": "^25.0.1", - "vite-plugin-pwa": "^0.21.0", + "vite-plugin-pwa": "^0.21.1", "vite-plugin-solid-svg": "^0.8.1", "workbox-window": "^7.3.0" } diff --git a/src/app.css b/src/app.css index 4ca227f..1354fbc 100644 --- a/src/app.css +++ b/src/app.css @@ -44,6 +44,42 @@ --padding-l: .75em; --padding-xl: 1em; --padding-xxl: 1.5em; + + --shadow-color: 220 3% 15%; + --shadow-strength: 1%; + + --shadow-1: 0 1px 2px -1px oklch(var(--shadow-color) / calc(var(--shadow-strength) + 9%)); + --shadow-2: + 0 3px 5px -2px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 3%)), + 0 7px 14px -5px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 5%)); + --shadow-3: + 0 -1px 3px 0 hsl(var(--shadow-color) / calc(var(--shadow-strength) + 2%)), + 0 1px 2px -5px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 2%)), + 0 2px 5px -5px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 4%)), + 0 4px 12px -5px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 5%)), + 0 12px 15px -5px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 7%)); + --shadow-4: + 0 -2px 5px 0 hsl(var(--shadow-color) / calc(var(--shadow-strength) + 2%)), + 0 1px 1px -2px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 3%)), + 0 2px 2px -2px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 3%)), + 0 5px 5px -2px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 4%)), + 0 9px 9px -2px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 5%)), + 0 16px 16px -2px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 6%)); + --shadow-5: + 0 -1px 2px 0 hsl(var(--shadow-color) / calc(var(--shadow-strength) + 2%)), + 0 2px 1px -2px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 3%)), + 0 5px 5px -2px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 3%)), + 0 10px 10px -2px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 4%)), + 0 20px 20px -2px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 5%)), + 0 40px 40px -2px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 7%)); + --shadow-6: + 0 -1px 2px 0 hsl(var(--shadow-color) / calc(var(--shadow-strength) + 2%)), + 0 3px 2px -2px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 3%)), + 0 7px 5px -2px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 3%)), + 0 12px 10px -2px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 4%)), + 0 22px 18px -2px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 5%)), + 0 41px 33px -2px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 6%)), + 0 100px 80px -2px hsl(var(--shadow-color) / calc(var(--shadow-strength) + 7%)); } html { diff --git a/src/components/colorschemepicker.module.css b/src/components/colorschemepicker.module.css index 9324005..b586f43 100644 --- a/src/components/colorschemepicker.module.css +++ b/src/components/colorschemepicker.module.css @@ -2,13 +2,14 @@ display: flex; flex-flow: row; align-items: center; + background-color: inherit; border: 1px solid transparent; border-radius: var(--radii-m); padding: var(--padding-s); & select { border: none; - background-color: transparent; + background-color: inherit; border-radius: var(--radii-m); &:focus { diff --git a/src/components/colorschemepicker.tsx b/src/components/colorschemepicker.tsx index 2ba96de..6b3fb66 100644 --- a/src/components/colorschemepicker.tsx +++ b/src/components/colorschemepicker.tsx @@ -1,9 +1,9 @@ -import { Accessor, Component, createContext, createEffect, createMemo, createResource, For, ParentComponent, Setter, Show, Suspense, useContext } from "solid-js"; +import { Component, createContext, createEffect, createResource, For, ParentComponent, Show, Suspense, useContext } from "solid-js"; import css from './colorschemepicker.module.css'; import { CgDarkMode } from "solid-icons/cg"; -import { action, createAsyncStore, query, useAction } from "@solidjs/router"; +import { action, query, useAction } from "@solidjs/router"; import { useSession } from "vinxi/http"; -import { createStore, reconcile, ReconcileOptions, SetStoreFunction } from "solid-js/store"; +import { createStore } from "solid-js/store"; export enum ColorScheme { Auto = 'light dark', @@ -38,7 +38,7 @@ const setState = action(async (state: State) => { 'use server'; const session = await getSession(); - await session.update(state); + await session.update(prev => ({ ...prev, ...state })); }, 'color-scheme'); interface ThemeContextType { @@ -62,7 +62,7 @@ export const useTheme = () => { }; export const ThemeProvider: ParentComponent = (props) => { - const [state, { mutate }] = createResource(() => getState(), { deferStream: true, initialValue: { colorScheme: ColorScheme.Auto, hue: 0 } }); + const [state, { mutate }] = createResource(() => getState(), { deferStream: true }); const updateState = useAction(setState); return @@ -75,8 +75,8 @@ export const ThemeProvider: ParentComponent = (props) => { return ({ ...prev, colorScheme }))) }, - setHue(hue: number) { updateState(mutate(prev => ({ ...prev, hue }))) }, + setColorScheme(colorScheme: ColorScheme) { updateState(mutate(prev => ({ colorScheme, hue: prev?.hue ?? 0 }))) }, + setHue(hue: number) { updateState(mutate(prev => ({ hue, colorScheme: prev?.colorScheme ?? ColorScheme.Auto }))) }, }}> {props.children} ; diff --git a/src/components/sidebar.module.css b/src/components/sidebar.module.css index 56c5bb3..cac1752 100644 --- a/src/components/sidebar.module.css +++ b/src/components/sidebar.module.css @@ -20,6 +20,7 @@ } &.open > .content { + min-inline-size: 10em; inline-size: max-content; } diff --git a/src/entry-server.tsx b/src/entry-server.tsx index da4e228..51b314e 100644 --- a/src/entry-server.tsx +++ b/src/entry-server.tsx @@ -26,9 +26,8 @@ export default createHandler(({ nonce }) => { ); }, event => { const nonce = crypto.randomUUID(); - const isDev = process.env.NODE_ENV === 'development'; - const base = `'self' 'nonce-${nonce}' ${isDev ? `'unsafe-eval'` : ''}`; + const base = `'self' 'nonce-${nonce}' 'unsafe-eval'`; const policies = { default: base, diff --git a/src/routes/(editor).tsx b/src/routes/(editor).tsx index ec19d5f..97fb291 100644 --- a/src/routes/(editor).tsx +++ b/src/routes/(editor).tsx @@ -1,28 +1,33 @@ -import { Link, Meta, Style, Title } from "@solidjs/meta"; -import { Component, createEffect, createMemo, createSignal, ErrorBoundary, ParentProps, Show, Suspense } from "solid-js"; +import { Link, Meta, Title } from "@solidjs/meta"; +import { Component, createMemo, createSignal, createUniqueId, ErrorBoundary, ParentProps, Show } from "solid-js"; import { FilesProvider } from "~/features/file"; import { CommandPalette, CommandPaletteApi, Menu, MenuProvider } from "~/features/menu"; import { A, RouteDefinition, useBeforeLeave } from "@solidjs/router"; import { createCommand, Modifier } from "~/features/command"; import { ColorScheme, ColorSchemePicker, getState, useTheme } from "~/components/colorschemepicker"; -import { getRequestEvent, isServer } from "solid-js/web"; +import { getRequestEvent } from "solid-js/web"; import { HttpHeader } from "@solidjs/start"; +import { FaSolidPalette } from "solid-icons/fa"; import css from "./editor.module.css"; const event = getRequestEvent(); export const route: RouteDefinition = { - preload: ({ params, location, intent }) => { - console.log(); - + preload: () => { return getState(); }, }; export default function Editor(props: ParentProps) { const theme = useTheme(); + const themeMenuId = createUniqueId(); const [commandPalette, setCommandPalette] = createSignal(); + const lightness = createMemo(() => { + const scheme = theme.colorScheme === ColorScheme.Auto ? event?.request.headers.get('Sec-CH-Prefers-Color-Scheme') : theme.colorScheme; + + return scheme === ColorScheme.Light ? .9 : .2; + }); const commands = [ createCommand('open command palette', () => { @@ -47,26 +52,14 @@ export default function Editor(props: ParentProps) { Calque - { - theme => { - const lightness = createMemo(() => { - const scheme = theme().colorScheme === ColorScheme.Auto ? event?.request.headers.get('Sec-CH-Prefers-Color-Scheme') : theme().colorScheme; + + - return scheme === ColorScheme.Light ? .9 : .2; - }); - - return <> - - - - - ; + @@ -85,8 +78,15 @@ export default function Editor(props: ParentProps) {
- +
+ + + + +
diff --git a/src/routes/editor.module.css b/src/routes/editor.module.css index c54a444..ceceb3f 100644 --- a/src/routes/editor.module.css +++ b/src/routes/editor.module.css @@ -6,6 +6,12 @@ overflow: clip; background-color: var(--surface-300); + @media (display-mode: window-controls-overlay) { + & { + row-gap: var(--padding-l); + } + } + .menu { view-transition-name: menu; display: grid; @@ -47,6 +53,47 @@ display: grid; grid-auto-flow: column; align-content: center; + + & .themeMenu { + display: contents; + + & > button { + display: flex; + justify-content: center; + padding: var(--padding-m); + border: none; + border-radius: var(--radii-m); + background-color: transparent; + + &:hover { + background-color: var(--surface-500); + } + + @media (display-mode: window-controls-overlay) { + & { + color: light-dark(#0008, #fff8); + } + } + } + + & > dialog { + inset-inline-end: anchor(right); + inset-block-start: anchor(bottom); + + padding: var(--padding-m); + border: none; + border-radius: var(--radii-m); + border-top-right-radius: 0; + background-color: var(--surface-600); + box-shadow: var(--shadow-3); + } + + &:has(:popover-open) > button { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + background-color: var(--surface-600); + } + } } }