Merge pull request #1 from BradNut/headless-ui

Headless UI
This commit is contained in:
Bradley Shellnut 2022-07-07 19:38:01 +00:00 committed by GitHub
commit eda90dbeb7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 2637 additions and 8728 deletions

13
.eslintignore Normal file
View file

@ -0,0 +1,13 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

13
.prettierignore Normal file
View file

@ -0,0 +1,13 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

View file

@ -1,6 +1,3 @@
{ {
"cSpell.words": [ "cSpell.words": ["kickstarter", "msrp"]
"kickstarter",
"msrp"
]
} }

View file

@ -1,24 +1,14 @@
# create-svelte # Bored Game
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte); Feeling bored?
## Creating a project How about a board game?
If you're seeing this, you've probably already done this step. Congrats! Use this app to search for a board game to play because you are bored apparently.
```bash
# create a new project in the current directory
npm init svelte@next
# create a new project in my-app
npm init svelte@next my-app
```
> Note: the `@next` is temporary
## Developing ## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: Once you've checked out the project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
```bash ```bash
npm run dev npm run dev
@ -29,10 +19,12 @@ npm run dev -- --open
## Building ## Building
Before creating a production version of your app, install an [adapter](https://kit.svelte.dev/docs#adapters) for your target environment. Then: Building for production?
Great! Run:
```bash ```bash
npm run build npm run build
``` ```
> You can preview the built app with `npm run preview`, regardless of whether you installed an adapter. This should _not_ be used to serve your app in production. > You can preview the built app with `npm run preview`. This should _not_ be used to serve your app in production.

6184
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -2,43 +2,46 @@
"name": "boredgame", "name": "boredgame",
"version": "0.0.1", "version": "0.0.1",
"scripts": { "scripts": {
"dev": "svelte-kit dev --host", "dev": "vite dev --host",
"build": "svelte-kit build", "build": "vite build",
"package": "svelte-kit package", "package": "svelte-kit package",
"preview": "svelte-kit preview", "preview": "vite preview",
"prepare": "svelte-kit sync",
"test": "playwright test",
"check": "svelte-check --tsconfig ./tsconfig.json", "check": "svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-check --tsconfig ./tsconfig.json --watch", "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. . && eslint --ignore-path .gitignore .", "lint": "prettier --check --plugin-search-dir=. . && eslint .",
"format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ." "format": "prettier --write --plugin-search-dir=. ."
}, },
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.21.1", "@playwright/test": "^1.23.2",
"@rgossiaux/svelte-headlessui": "1.0.0-beta.12", "@rgossiaux/svelte-headlessui": "1.0.2",
"@sveltejs/adapter-auto": "next", "@sveltejs/adapter-auto": "next",
"@sveltejs/kit": "1.0.0-next.326", "@sveltejs/kit": "next",
"@types/cookie": "^0.5.1", "@types/cookie": "^0.5.1",
"@types/node": "^17.0.31", "@types/node": "^17.0.45",
"@typescript-eslint/eslint-plugin": "^5.22.0", "@typescript-eslint/eslint-plugin": "^5.30.5",
"@typescript-eslint/parser": "^5.22.0", "@typescript-eslint/parser": "^5.30.5",
"carbon-components-svelte": "^0.63.8", "carbon-components-svelte": "^0.63.8",
"carbon-icons-svelte": "^11.0.1", "carbon-icons-svelte": "^11.1.0",
"eslint": "^8.15.0", "eslint": "^8.19.0",
"eslint-config-prettier": "^8.5.0", "eslint-config-prettier": "^8.5.0",
"eslint-plugin-svelte3": "^3.4.1", "eslint-plugin-svelte3": "^3.4.1",
"prettier": "^2.6.2", "prettier": "^2.7.1",
"prettier-plugin-svelte": "^2.7.0", "prettier-plugin-svelte": "^2.7.0",
"svelte": "^3.48.0", "sass": "^1.53.0",
"svelte-check": "^2.7.0", "svelte": "^3.49.0",
"svelte-preprocess": "^4.10.6", "svelte-check": "^2.8.0",
"svelte-preprocess": "^4.10.7",
"tslib": "^2.4.0", "tslib": "^2.4.0",
"typescript": "^4.6.4" "typescript": "^4.7.4",
"vite": "^2.9.13"
}, },
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@fontsource/fira-mono": "^4.5.8", "@fontsource/fira-mono": "^4.5.8",
"@lukeed/uuid": "^2.0.0", "@lukeed/uuid": "^2.0.0",
"cookie": "^0.5.0", "cookie": "^0.5.0",
"node-sass": "^7.0.1", "zod": "^3.17.3"
"zod": "^3.15.1"
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -20,10 +20,12 @@ body {
min-height: 100vh; min-height: 100vh;
margin: 0; margin: 0;
background-color: var(--primary-color); background-color: var(--primary-color);
background: linear-gradient(180deg, background: linear-gradient(
180deg,
var(--primary-color) 0%, var(--primary-color) 0%,
var(--secondary-color) 10.45%, var(--secondary-color) 10.45%,
var(--tertiary-color) 41.35%); var(--tertiary-color) 41.35%
);
} }
body::before { body::before {
@ -34,9 +36,11 @@ body::before {
top: 0; top: 0;
left: 10vw; left: 10vw;
z-index: -1; z-index: -1;
background: radial-gradient(50% 50% at 50% 50%, background: radial-gradient(
50% 50% at 50% 50%,
var(--pure-white) 0%, var(--pure-white) 0%,
rgba(255, 255, 255, 0) 100%); rgba(255, 255, 255, 0) 100%
);
opacity: 0.05; opacity: 0.05;
} }

8
src/app.d.ts vendored
View file

@ -2,14 +2,10 @@
// See https://kit.svelte.dev/docs/types#app // See https://kit.svelte.dev/docs/types#app
// for information about these interfaces // for information about these interfaces
// and what to do when importing types
declare namespace App { declare namespace App {
interface Locals { // interface Locals {}
userid: string;
}
// interface Platform {} // interface Platform {}
// interface Session {} // interface Session {}
// interface Stuff {} // interface Stuff {}
} }

View file

@ -2,12 +2,40 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="description" content="Svelte demo app" /> <meta name="description" content="Bored? Find a game! Bored Game!" />
<link rel="icon" href="%svelte.assets%/favicon.png" /> <link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
%svelte.head% <script>
const htmlElement = document.documentElement;
const userTheme = localStorage.theme;
const userFont = localStorage.font;
// check if the user set a theme
if (userTheme) {
htmlElement.dataset.theme = userTheme;
}
// otherwise check for user preference
if (!userTheme && prefersDarkMode) {
htmlElement.dataset.theme = '🌛 Night';
localStorage.theme = '🌛 Night';
}
if (!userTheme && prefersLightMode) {
htmlElement.dataset.theme = '☀️ Daylight';
localStorage.theme = '☀️ Daylight';
}
// if nothing is set default to dark mode
if (!userTheme && !prefersDarkMode && !prefersLightMode) {
htmlElement.dataset.theme = '🌛 Night';
localStorage.theme = '🌛 Night';
}
</script>
%sveltekit.head%
</head> </head>
<body> <body>
<div id="svelte">%svelte.body%</div> <div id="svelte">%sveltekit.body%</div>
</body> </body>
</html> </html>

View file

@ -24,7 +24,7 @@
</div> </div>
</article> </article>
<style> <style lang="scss">
.thumbnail { .thumbnail {
align-self: start; align-self: start;
} }
@ -33,8 +33,11 @@
border-radius: 10px; border-radius: 10px;
} }
.game-container:hover { .game-container {
background-color: var(--primary); background-color: var(--primary);
&:hover {
background-color: hsla(222, 9%, 65%, 1);
}
} }
.game-container { .game-container {

View file

@ -0,0 +1,146 @@
<script lang="ts">
import { fade } from 'svelte/transition';
import { browser } from '$app/env';
import {
Listbox,
ListboxButton,
ListboxOption,
ListboxOptions
} from '@rgossiaux/svelte-headlessui';
const themes = {
'🌛 Night': { name: '🌛 Night' },
'☀️ Daylight': { name: '☀️ Daylight' },
'🐺 Night Howl': { name: '🐺 Night Howl' },
'🧠 Night Mind': { name: '🧠 Night Mind' }
};
let selectedTheme = getTheme() ?? themes['🌛 Night'];
function getTheme() {
if (!browser) return;
const htmlElement = document.documentElement;
const userTheme = localStorage.theme;
const prefersDarkMode = window.matchMedia('prefers-color-scheme: dark').matches;
const prefersLightMode = window.matchMedia('prefers-color-scheme: light').matches;
// check if the user set a theme
if (userTheme) {
htmlElement.dataset.theme = userTheme;
return themes[userTheme];
}
// otherwise check for user preference
if (!userTheme && prefersDarkMode) {
htmlElement.dataset.theme = '🌛 Night';
localStorage.theme = '🌛 Night';
}
if (!userTheme && prefersLightMode) {
htmlElement.dataset.theme = '☀️ Daylight';
localStorage.theme = '☀️ Daylight';
}
// if nothing is set default to dark mode
if (!userTheme && !prefersDarkMode && !prefersLightMode) {
htmlElement.dataset.theme = '🌛 Night';
localStorage.theme = '🌛 Night';
}
return themes[userTheme];
}
function handleChange(event: CustomEvent) {
selectedTheme = themes[event.detail.name];
const htmlElement = document.documentElement;
htmlElement.dataset.theme = selectedTheme.name;
localStorage.theme = selectedTheme.name;
}
</script>
<div class="theme">
<div class="listbox">
<Listbox value={selectedTheme} on:change={handleChange} let:open>
<ListboxButton class="button">
<span>{selectedTheme.name}</span>
<span>
<svg
width="20"
height="20"
class="arrows"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fill-rule="evenodd"
d="M10 3a1 1 0 01.707.293l3 3a1 1 0 01-1.414 1.414L10 5.414 7.707 7.707a1 1 0 01-1.414-1.414l3-3A1 1 0 0110 3zm-3.707 9.293a1 1 0 011.414 0L10 14.586l2.293-2.293a1 1 0 011.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z"
clip-rule="evenodd"
/>
</svg>
</span>
</ListboxButton>
{#if open}
<div transition:fade={{ duration: 100 }}>
<ListboxOptions class="options" static>
{#each Object.entries(themes) as [key, theme] (key)}
<ListboxOption value={theme} let:active let:selected>
<span class="option" class:active class:selected>
{theme.name}
</span>
</ListboxOption>
{/each}
</ListboxOptions>
</div>
{/if}
</Listbox>
</div>
</div>
<style>
.listbox {
--width: 184px;
}
.listbox :global(.button) {
width: var(--width);
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
padding: var(--spacing-16) var(--spacing-24);
font-weight: 700;
background-color: var(--clr-primary);
color: var(--clr-theme-txt);
border-radius: var(--rounded-20);
box-shadow: var(--shadow-sm);
}
.listbox :global(.arrows) {
width: 20px;
height: 20px;
display: block;
}
.listbox :global(.options) {
width: var(--width);
position: absolute;
margin-top: 0.4rem;
font-weight: 700;
color: var(--clr-theme-txt);
background-color: var(--clr-primary);
border-radius: var(--rounded-20);
box-shadow: var(--shadow-sm);
list-style: none;
}
.listbox :global(.option) {
display: block;
padding: var(--spacing-16) var(--spacing-24);
border-radius: var(--rounded-20);
cursor: pointer;
}
.listbox :global(.active) {
background-color: var(--clr-theme-active);
}
</style>

View file

@ -6,7 +6,8 @@
// } from "carbon-components-svelte"; // } from "carbon-components-svelte";
// import type { CarbonTheme } from "carbon-components-svelte/types/Theme/Theme.svelte"; // import type { CarbonTheme } from "carbon-components-svelte/types/Theme/Theme.svelte";
import { page } from '$app/stores'; import { page } from '$app/stores';
import Toggle from '$root/components/toggle.svelte'; import Themes from '$lib/components/preferences/themes.svelte';
import Toggle from '$lib/components/toggle.svelte';
import logo from './svelte-logo.svg'; import logo from './svelte-logo.svg';
// let theme: CarbonTheme = "white"; // let theme: CarbonTheme = "white";
@ -34,12 +35,13 @@
<div> <div>
<Toggle /> <Toggle />
</div> </div>
<ul> <div><Themes /></div>
<!-- <ul>
<li class:active={$page.url.pathname === '/'}><a sveltekit:prefetch href="/">Home</a></li> <li class:active={$page.url.pathname === '/'}><a sveltekit:prefetch href="/">Home</a></li>
<li class:active={$page.url.pathname === '/about'}> <li class:active={$page.url.pathname === '/about'}>
<a sveltekit:prefetch href="/about">About</a> <a sveltekit:prefetch href="/about">About</a>
</li> </li>
</ul> </ul> -->
</nav> </nav>
</header> </header>

View file

@ -9,7 +9,7 @@ export type ToastData = {
duration: number; duration: number;
type: ToastType; type: ToastType;
message: string; message: string;
} };
export type GameType = { export type GameType = {
id: string; id: string;
@ -18,7 +18,7 @@ export type GameType = {
url: string; url: string;
edit_url: string; edit_url: string;
thumb_url: string; thumb_url: string;
image_url: string, image_url: string;
price: number; price: number;
price_ca: number; price_ca: number;
price_uk: number; price_uk: number;
@ -33,7 +33,7 @@ export type GameType = {
description: string; description: string;
players: string; players: string;
playtime: string; playtime: string;
} };
export type SearchQuery = { export type SearchQuery = {
client_id: string; client_id: string;
@ -84,4 +84,4 @@ export type SearchQuery = {
lt_reddit_week_count?: number; lt_reddit_week_count?: number;
lt_reddit_day_count?: number; lt_reddit_day_count?: number;
fields?: string; fields?: string;
} };

View file

@ -1,10 +1,10 @@
import { z } from "zod"; import { z } from 'zod';
export const BoardGameSearch = z.object({ export const BoardGameSearch = z.object({
minAge: z.number(), minAge: z.number(),
maxAge: z.number(), maxAge: z.number(),
minPlayers: z.number(), minPlayers: z.number(),
maxPlayers: z.number(), maxPlayers: z.number()
}); });
export const Game = z.object({ export const Game = z.object({
@ -26,5 +26,5 @@ export const Game = z.object({
min_age: z.number(), min_age: z.number(),
description: z.string(), description: z.string(),
players: z.string(), players: z.string(),
playtime: z.string(), playtime: z.string()
}); });

View file

@ -1,21 +1,32 @@
<script lang="ts"> <script lang="ts">
import Header from '$lib/header/Header.svelte'; import Header from '$lib/header/Header.svelte';
import '$root/styles/global.css'; // import 'carbon-components-svelte/css/all.css';
import 'carbon-components-svelte/css/all.css'; import '$root/styles/styles.scss';
import '../app.css';
</script> </script>
<div class="fade" style:animation-duration="250ms" style:animation-delay="250ms">
<Header /> <Header />
<main> <main>
<slot /> <slot />
</main> </main>
<footer> <footer>
<p>Built by <a target="__blank" href="https://bradleyshellnut.com">Bradley Shellnut</a></p> <p>Built by <a target="__blank" href="https://bradleyshellnut.com">Bradley Shellnut</a></p>
</footer> </footer>
</div>
<style> <style>
.fade {
animation-name: fadeIn;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
main { main {
flex: 1; flex: 1;
display: flex; display: flex;

View file

@ -9,14 +9,19 @@
guarantees are made. Don't use it to organize your life.) guarantees are made. Don't use it to organize your life.)
*/ */
import { URLSearchParams } from "url"; import { URLSearchParams } from 'url';
const base = 'https://api.boardgameatlas.com/api'; const base = 'https://api.boardgameatlas.com/api';
export function boardGameApi(method: string, resource: string, queryParams: Record<string, string>, data?: Record<string, unknown>) { export function boardGameApi(
method: string,
resource: string,
queryParams: Record<string, string>,
data?: Record<string, unknown>
) {
queryParams.client_id = import.meta.env.VITE_PUBLIC_CLIENT_ID; queryParams.client_id = import.meta.env.VITE_PUBLIC_CLIENT_ID;
const urlQueryParams = new URLSearchParams(queryParams) const urlQueryParams = new URLSearchParams(queryParams);
const url = `${base}/${resource}${urlQueryParams ? `?${urlQueryParams}` : ''}` const url = `${base}/${resource}${urlQueryParams ? `?${urlQueryParams}` : ''}`;
return fetch(url, { return fetch(url, {
method, method,
headers: { headers: {

View file

@ -1,5 +1,5 @@
import type { RequestHandler } from "@sveltejs/kit"; import type { RequestHandler } from '@sveltejs/kit';
import type { SearchQuery } from "$lib/types"; import type { SearchQuery } from '$lib/types';
export const post: RequestHandler = async ({ request }) => { export const post: RequestHandler = async ({ request }) => {
const form = await request.formData(); const form = await request.formData();
@ -8,8 +8,8 @@ export const post: RequestHandler = async ({ request }) => {
order_by: 'rank', order_by: 'rank',
ascending: false, ascending: false,
limit: 20, limit: 20,
client_id: import.meta.env.VITE_PUBLIC_CLIENT_ID, client_id: import.meta.env.VITE_PUBLIC_CLIENT_ID
} };
const minAge = form.get('minAge'); const minAge = form.get('minAge');
const minPlayers = form.get('minPlayers'); const minPlayers = form.get('minPlayers');
@ -47,7 +47,7 @@ export const post: RequestHandler = async ({ request }) => {
if (exactMinPlayers) { if (exactMinPlayers) {
queryParams.min_players = +minPlayers; queryParams.min_players = +minPlayers;
} else { } else {
queryParams.gt_min_players = (+minPlayers === 1 ? 0 : (+minPlayers - 1)); queryParams.gt_min_players = +minPlayers === 1 ? 0 : +minPlayers - 1;
} }
} }
@ -70,12 +70,14 @@ export const post: RequestHandler = async ({ request }) => {
const urlQueryParams = new URLSearchParams(newQueryParams); const urlQueryParams = new URLSearchParams(newQueryParams);
const url = `https://api.boardgameatlas.com/api/search${urlQueryParams ? `?${urlQueryParams}` : ''}` const url = `https://api.boardgameatlas.com/api/search${
urlQueryParams ? `?${urlQueryParams}` : ''
}`;
const response = await fetch(url, { const response = await fetch(url, {
method: 'get', method: 'get',
headers: { headers: {
'content-type': 'application/json' 'content-type': 'application/json'
}, }
}); });
console.log('response', response); console.log('response', response);
if (response.status === 404) { if (response.status === 404) {
@ -94,7 +96,7 @@ export const post: RequestHandler = async ({ request }) => {
console.log('games', games); console.log('games', games);
return { return {
body: { body: {
games: gameResponse?.games, games: gameResponse?.games
} }
}; };
} }
@ -102,4 +104,4 @@ export const post: RequestHandler = async ({ request }) => {
return { return {
status: response.status status: response.status
}; };
} };

View file

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import type { Game } from "$lib/types"; import type { Game } from '$lib/types';
import { Checkbox, NumberInput } from "carbon-components-svelte"; import { Checkbox, NumberInput } from 'carbon-components-svelte';
// import { enhance } from "$lib/form"; // import { enhance } from "$lib/form";
let games: Game[] = []; let games: Game[] = [];
@ -28,7 +28,6 @@ import { Checkbox, NumberInput } from "carbon-components-svelte";
let exactMaxPlayers = false; let exactMaxPlayers = false;
</script> </script>
<svelte:head> <svelte:head>
<title>Games</title> <title>Games</title>
</svelte:head> </svelte:head>
@ -50,7 +49,12 @@ import { Checkbox, NumberInput } from "carbon-components-svelte";
invalidText="Number must be between 0 and 120" invalidText="Number must be between 0 and 120"
label="Min Age" label="Min Age"
/> />
<Checkbox name="exactMinAge" bind:value={exactMinAge} labelText="Search exact?" bind:checked={exactMinAge} /> <Checkbox
name="exactMinAge"
bind:value={exactMinAge}
labelText="Search exact?"
bind:checked={exactMinAge}
/>
</div> </div>
<div> <div>
<NumberInput <NumberInput
@ -61,7 +65,12 @@ import { Checkbox, NumberInput } from "carbon-components-svelte";
invalidText="Number must be between 1 and 50" invalidText="Number must be between 1 and 50"
label="Min Players" label="Min Players"
/> />
<Checkbox name="exactMinPlayers" labelText="Search exact?" bind:value={exactMinPlayers} bind:checked={exactMinPlayers} /> <Checkbox
name="exactMinPlayers"
labelText="Search exact?"
bind:value={exactMinPlayers}
bind:checked={exactMinPlayers}
/>
</div> </div>
<div> <div>
<NumberInput <NumberInput
@ -72,7 +81,12 @@ import { Checkbox, NumberInput } from "carbon-components-svelte";
invalidText="Number must be between 1 and 50" invalidText="Number must be between 1 and 50"
label="Max Players" label="Max Players"
/> />
<Checkbox name="exactMaxPlayers" labelText="Search exact?" bind:value={exactMaxPlayers} bind:checked={exactMaxPlayers} /> <Checkbox
name="exactMaxPlayers"
labelText="Search exact?"
bind:value={exactMaxPlayers}
bind:checked={exactMaxPlayers}
/>
</div> </div>
</fieldset> </fieldset>
<button type="submit" disabled={submitting}>Submit</button> <button type="submit" disabled={submitting}>Submit</button>
@ -117,7 +131,7 @@ import { Checkbox, NumberInput } from "carbon-components-svelte";
border-radius: 4px; border-radius: 4px;
margin: 0; margin: 0;
padding: 0.2rem; padding: 0.2rem;
background-color: palegreen; background-color: var(--color-btn-primary-active);
} }
.games { .games {

View file

@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import Listbox from '$root/components/listbox.svelte'; import Listbox from '$lib/components/listbox.svelte';
</script> </script>
<Listbox /> <Listbox />

View file

@ -1,12 +1,8 @@
<script context="module" lang="ts">
export const prerender = true;
</script>
<script lang="ts"> <script lang="ts">
import { Checkbox, NumberInput } from 'carbon-components-svelte'; // import { Checkbox, NumberInput } from 'carbon-components-svelte';
import Game from '$root/components/game.svelte'; import Game from '$lib/components/game.svelte';
import type { GameType } from '$lib/types'; import type { GameType } from '$lib/types';
import Listbox from '$root/components/listbox.svelte'; import Listbox from '$lib/components/listbox.svelte';
// import { enhance } from "$lib/form"; // import { enhance } from "$lib/form";
let games: GameType[] = []; let games: GameType[] = [];
@ -35,7 +31,7 @@
</script> </script>
<svelte:head> <svelte:head>
<title>Home</title> <title>Bored Game</title>
</svelte:head> </svelte:head>
<h1>Search Boardgames!</h1> <h1>Search Boardgames!</h1>
@ -44,23 +40,38 @@
<form on:submit|preventDefault={handleSubmit} method="post"> <form on:submit|preventDefault={handleSubmit} method="post">
<fieldset aria-busy={submitting} disabled={submitting}> <fieldset aria-busy={submitting} disabled={submitting}>
<div> <div>
<NumberInput <label htmlfor="minAge">
<input id="minAge" name="minAge" bind:value={minAge} type="number" min={0} max={120} />
Min Age
</label>
<!-- <NumberInput
name="minAge" name="minAge"
min={0} min={0}
max={120} max={120}
bind:value={minAge} bind:value={minAge}
invalidText="Number must be between 0 and 120" invalidText="Number must be between 0 and 120"
label="Min Age" label="Min Age"
/> /> -->
<Checkbox <!-- <Checkbox
name="exactMinAge" name="exactMinAge"
bind:checked={exactMinAge} bind:checked={exactMinAge}
bind:value={exactMinAge} bind:value={exactMinAge}
labelText="Search exact?" labelText="Search exact?"
/> /> -->
</div> </div>
<div> <div>
<NumberInput <label htmlfor="maxPlayers">
<input
id="maxPlayers"
name="maxPlayers"
bind:value={maxPlayers}
type="number"
min={0}
max={50}
/>
Min Players
</label>
<!-- <NumberInput
name="minPlayers" name="minPlayers"
min={1} min={1}
max={50} max={50}
@ -68,10 +79,21 @@
invalidText="Number must be between 1 and 50" invalidText="Number must be between 1 and 50"
label="Min Players" label="Min Players"
/> />
<Checkbox name="exactMinPlayers" labelText="Search exact?" bind:checked={exactMinPlayers} /> <Checkbox name="exactMinPlayers" labelText="Search exact?" bind:checked={exactMinPlayers} /> -->
</div> </div>
<div> <div>
<NumberInput <label htmlfor="maxPlayers">
<input
id="maxPlayers"
name="maxPlayers"
bind:value={maxPlayers}
type="number"
min={0}
max={50}
/>
Max Players
</label>
<!-- <NumberInput
name="maxPlayers" name="maxPlayers"
min={1} min={1}
max={50} max={50}
@ -79,7 +101,7 @@
invalidText="Number must be between 1 and 50" invalidText="Number must be between 1 and 50"
label="Max Players" label="Max Players"
/> />
<Checkbox name="exactMaxPlayers" labelText="Search exact?" bind:checked={exactMaxPlayers} /> <Checkbox name="exactMaxPlayers" labelText="Search exact?" bind:checked={exactMaxPlayers} /> -->
</div> </div>
</fieldset> </fieldset>
<button type="submit" disabled={submitting}>Submit</button> <button type="submit" disabled={submitting}>Submit</button>
@ -111,10 +133,11 @@
} }
button { button {
border-radius: 4px; border-radius: 10px;
margin: 0; margin: 0.5rem;
padding: 0.2rem; padding: 1rem;
background-color: palegreen; color: var(--clr-input-txt);
background-color: var(--color-btn-primary-active);
} }
.games { .games {
@ -127,8 +150,8 @@
} }
.game-form { .game-form {
display: flex; /* display: flex; */
place-items: center; /* place-items: center; */
} }
.game-form fieldset { .game-form fieldset {

View file

@ -19,8 +19,8 @@ export const post: RequestHandler = async ({ request, locals }) => {
gt_min_players: String(+minPlayers === 1 ? 0 : +minPlayers - 1), gt_min_players: String(+minPlayers === 1 ? 0 : +minPlayers - 1),
lt_max_players: String(+maxPlayers + 1), lt_max_players: String(+maxPlayers + 1),
gt_min_age: String(+minAge === 1 ? 0 : +minAge - 1), gt_min_age: String(+minAge === 1 ? 0 : +minAge - 1),
lt_max_age: String(+maxAge + 1), lt_max_age: String(+maxAge + 1)
} };
const response = await boardGameApi('get', `search`, queryParams); const response = await boardGameApi('get', `search`, queryParams);
console.log('response', response); console.log('response', response);
if (response.status === 404) { if (response.status === 404) {
@ -39,7 +39,7 @@ export const post: RequestHandler = async ({ request, locals }) => {
console.log('games', games); console.log('games', games);
return { return {
body: { body: {
games: gameResponse?.games, games: gameResponse?.games
} }
}; };
} }

View file

@ -1,214 +0,0 @@
/* Setup */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap');
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: inherit;
}
:root {
--color-brand: hsl(204 88% 53%);
--color-text-primary: hsl(0 0% 98%);
--color-text-muted: hsl(210 34% 80%);
--color-bg-primary: hsl(210 34% 13%);
--color-bg-secondary: hsl(209, 35%, 15%);
--color-btn-primary-active: var(--color-brand);
--color-btn-primary-active-hover: hsl(204 88% 60%);
--color-btn-primary-inactive: hsl(205 70% 33%);
--color-btn-secondary: hsl(192 19% 95%);
--color-border-primary: hsl(0, 0%, 34%);
--color-link-hover: hsl(209 22% 19%);
--color-placeholder: hsl(210 34% 80%);
--red: #990000;
--redBrown: #633539;
--blue: #336699;
--black: #1f273a;
--white: #fff;
--grey: #efefef;
--greyBlue: #888e9c;
--lighterGreyBlue: #6a707e;
--yellow: #ffc600;
--light: #ffffff;
--dark: #000000;
--lightGrey: #C5C5C5;
--lightGray: var(--lightGrey);
--imGoingToFaint: #fbfbfb;
--redBrown: #633539;
--maxWidth: 1200px;
/* Define Colors intentions */
--primary: var(--greyBlue);
--secondary: var(--redBrown);
--background: var(--white);
--textColor: var(--lighterGreyBlue);
--buttonTextColor: var(--black);
--lineColor: var(--grey);
--cardBg: var(--darkGrey);
--headerBackground: var(--greyBlue);
--footerBackground: var(--darkGrey);
--linkHover: var(--white);
--lightHairLine: #C5C5C5;
--radius-base: 2.4rem;
/* Type */
--headingFont: 'Merriweather Sans', sans-serif;
--bodyFont: 'Work Sans', sans-serif;
--baseFontSize: 100%;
--h1: 3.052rem;
--h2: 2.441rem;
--h3: 1.953rem;
--h4: 1.563rem;
--h5: 1.25rem;
--h6: 1.8rem;
--bodyTextSize: 1.8rem;
--smallText: 1.44rem;
--lineHeight: 2.25rem;
--font-serif: 'Inter', sans-serif;
--font-16: 1.6rem;
--font-18: 1.8rem;
--font-24: 2.4rem;
--font-32: 3.2rem;
--font-80: 8rem;
--spacing-4: 0.4rem;
--spacing-8: 0.5rem;
--spacing-16: 1.6rem;
--spacing-20: 2rem;
--spacing-24: 2.4rem;
--spacing-32: 3.2rem;
/* Elevation */
--level-0: none;
--level-1: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
--level-2: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
0 2px 4px -1px rgba(0, 0, 0, 0.06);
--level-3: 0 10px 15px -3px rgba(0, 0, 0, 0.1),
0 4px 6px -2px rgba(0, 0, 0, 0.05);
--level-4: 0 20px 25px -5px rgba(0, 0, 0, 0.1),
0 10px 10px -5px rgba(0, 0, 0, 0.04);
/* Z Indexes */
--zBase: 1;
/* Positioning */
--containerPadding: 2.5%;
--headerHeight: 8rem;
--borderRadius: 4px;
--borderRadiusLarge: 10px;
--maxWidth: 1200px;
/* Media Queryies - Not yet supported in CSS */
/*
--xsmall: 340px;
--small: 500px;
--large: 960px;
--wide: 1200px;
*/
}
html {
/* background-image: url(${floatingCogs}); */
/* background-color: var(--background); */
/* background-size: 450px; */
/* background-attachment: fixed; */
font-size: 62.5%;
box-sizing: border-box;
scrollbar-width: thin;
}
html,
body {
height: 100%;
}
::-webkit-scrollbar {
width: 4px;
height: 4px;
}
::-webkit-scrollbar-track {
background-color: transparent;
}
::-webkit-scrollbar-thumb {
background-color: var(--color-brand);
border-radius: var(--radius-base);
}
::selection {
background: var(--primary);
color: var(--white);
}
body {
font-family: var(--font-serif);
font-size: var(--font-18);
color: var(--color-text-primary);
background-color: var(--color-bg-primary);
}
a {
text-decoration: none;
color: var(--color-text-primary);
}
label {
display: block;
margin: var(--spacing-8) 0;
font-size: var(--font-24);
color: var(--color-text-muted);
}
input {
padding: var(--spacing-16);
font-size: var(--font-24);
border-radius: var(--radius-base);
border: none;
}
.btn {
padding: var(--spacing-16) var(--spacing-32);
font-size: var(--font-18);
font-weight: bold;
color: var(--color-text-primary);
background-color: var(--color-btn-primary-active);
border-radius: var(--radius-base);
border: none;
cursor: pointer;
}
.btn:hover {
background-color: var(--color-btn-primary-active-hover);
}
.btn:disabled {
color: var(--color-text-muted);
background-color: var(--color-btn-primary-inactive);
cursor: not-allowed;
}
ul,
ol {
list-style: none;
}
/* Utils */
.responsive {
resize: both;
overflow: scroll;
border: 1px solid hsl(0 0% 0%);
}
.placeholder {
padding: var(--spacing-20) 0;
background-color: var(--color-placeholder);
border-radius: var(--radius-base);
}

237
src/styles/global.scss Normal file
View file

@ -0,0 +1,237 @@
/* Setup */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap');
:root {
--color-brand: hsl(204 88% 53%);
--color-text-primary: hsl(0 0% 98%);
--color-text-muted: hsl(210 34% 80%);
--color-bg-primary: hsl(210 34% 13%);
--color-bg-secondary: hsl(209, 35%, 15%);
--color-btn-primary-active: var(--color-brand);
--color-btn-primary-active-hover: hsl(204 88% 60%);
--color-btn-primary-inactive: hsl(205 70% 33%);
--color-btn-secondary: hsl(192 19% 95%);
--color-border-primary: hsl(0, 0%, 34%);
--color-link-hover: hsl(209 22% 19%);
--color-placeholder: hsl(210 34% 80%);
--clr-input-txt: hsl(177 100% 15%);
--red: #990000;
--redBrown: #633539;
--blue: #336699;
--black: #1f273a;
--white: #fff;
--grey: #efefef;
--greyBlue: hsla(222, 9%, 57%, 1);
--lighterGreyBlue: #6a707e;
--yellow: #ffc600;
--light: #ffffff;
--dark: #000000;
--lightGrey: #c5c5c5;
--lightGray: var(--lightGrey);
--imGoingToFaint: #fbfbfb;
--redBrown: #633539;
--maxWidth: 1200px;
/* Define Colors intentions */
--primary: var(--greyBlue);
--secondary: var(--redBrown);
--background: var(--white);
--textColor: var(--lighterGreyBlue);
--buttonTextColor: var(--white);
--lineColor: var(--grey);
--cardBg: var(--darkGrey);
--headerBackground: var(--greyBlue);
--footerBackground: var(--darkGrey);
--linkHover: var(--white);
--lightHairLine: #c5c5c5;
--radius-base: 1rem;
/* Type */
--headingFont: 'Merriweather Sans', sans-serif;
--bodyFont: 'Work Sans', sans-serif;
--baseFontSize: 100%;
--h1: 3.052rem;
--h2: 2.441rem;
--h3: 1.953rem;
--h4: 1.563rem;
--h5: 1.25rem;
--h6: 1.8rem;
--bodyTextSize: 1.8rem;
--smallText: 1.44rem;
--lineHeight: 2.25rem;
--font-serif: 'Inter', sans-serif;
--font-16: 1.6rem;
--font-18: 1.8rem;
--font-24: 2.4rem;
--font-32: 3.2rem;
--font-80: 8rem;
--spacing-4: 0.4rem;
--spacing-8: 0.5rem;
--spacing-16: 1.6rem;
--spacing-20: 2rem;
--spacing-24: 2.4rem;
--spacing-32: 3.2rem;
/* Elevation */
--level-0: none;
--level-1: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
--level-2: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
--level-3: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
--level-4: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
/* Z Indexes */
--zBase: 1;
/* Positioning */
--containerPadding: 2.5%;
--headerHeight: 8rem;
--borderRadius: 4px;
--borderRadiusLarge: 10px;
--maxWidth: 1200px;
/* Font */
--font-sans: 'Poppins', sans-serif;
--font-serif: 'Arsenica', serif;
--font-mono: Source Code Pro, monospace;
--font-dyslexic: OpenDyslexic, sans-serif;
--font-dyslexic-mono: OpenDyslexic Mono, monospace;
--font-16: 1.6rem;
--font-24: 2.4rem;
--font-32: 3.2rem;
--font-48: 4.8rem;
--font-96: 9.6rem;
/* Spacing */
--spacing-4: 0.4rem;
--spacing-8: 0.8rem;
--spacing-16: 1.6rem;
--spacing-24: 2.4rem;
--spacing-32: 3.2rem;
--spacing-64: 6.4rem;
--spacing-128: 12.8rem;
/* Scrollbar */
--clr-scrollbar-thumb: hsl(173 10% 20%);
/* Shadows */
--shadow-sm: 0px 0px 4px 4px hsl(0 0% 0% / 4%);
--shadow-md: 0px 0px 10px 4px hsl(0 0% 0% / 10%);
--shadow-lg: 0px 0px 20px 8px hsl(0 0% 0% / 20%);
/* Border radius */
--rounded-4: 4px;
--rounded-20: 20px;
/* Media Queryies - Not yet supported in CSS */
/*
--xsmall: 340px;
--small: 500px;
--large: 960px;
--wide: 1200px;
*/
}
html {
font-size: 62.5%;
box-sizing: border-box;
scrollbar-width: thin;
}
html,
body {
height: 100%;
}
::-webkit-scrollbar {
width: 4px;
height: 4px;
}
::-webkit-scrollbar-track {
background-color: transparent;
}
::-webkit-scrollbar-thumb {
background-color: var(--color-brand);
border-radius: var(--radius-base);
}
::selection {
background: var(--primary);
color: var(--white);
}
body {
font-family: var(--font-serif);
font-size: var(--font-18);
color: var(--color-text-primary);
// background-color: var(--color-bg-primary);
background-color: #2d3a3a;
// background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25' viewBox='0 0 100 60'%3E%3Cg %3E%3Crect fill='%23555555' width='11' height='11'/%3E%3Crect fill='%23565656' x='10' width='11' height='11'/%3E%3Crect fill='%23575757' y='10' width='11' height='11'/%3E%3Crect fill='%23575757' x='20' width='11' height='11'/%3E%3Crect fill='%23585858' x='10' y='10' width='11' height='11'/%3E%3Crect fill='%23595959' y='20' width='11' height='11'/%3E%3Crect fill='%235a5a5a' x='30' width='11' height='11'/%3E%3Crect fill='%235b5b5b' x='20' y='10' width='11' height='11'/%3E%3Crect fill='%235c5c5c' x='10' y='20' width='11' height='11'/%3E%3Crect fill='%235c5c5c' y='30' width='11' height='11'/%3E%3Crect fill='%235d5d5d' x='40' width='11' height='11'/%3E%3Crect fill='%235e5e5e' x='30' y='10' width='11' height='11'/%3E%3Crect fill='%235f5f5f' x='20' y='20' width='11' height='11'/%3E%3Crect fill='%23606060' x='10' y='30' width='11' height='11'/%3E%3Crect fill='%23616161' y='40' width='11' height='11'/%3E%3Crect fill='%23626262' x='50' width='11' height='11'/%3E%3Crect fill='%23626262' x='40' y='10' width='11' height='11'/%3E%3Crect fill='%23636363' x='30' y='20' width='11' height='11'/%3E%3Crect fill='%23646464' x='20' y='30' width='11' height='11'/%3E%3Crect fill='%23656565' x='10' y='40' width='11' height='11'/%3E%3Crect fill='%23666666' y='50' width='11' height='11'/%3E%3Crect fill='%23676767' x='60' width='11' height='11'/%3E%3Crect fill='%23686868' x='50' y='10' width='11' height='11'/%3E%3Crect fill='%23686868' x='40' y='20' width='11' height='11'/%3E%3Crect fill='%23696969' x='30' y='30' width='11' height='11'/%3E%3Crect fill='%236a6a6a' x='20' y='40' width='11' height='11'/%3E%3Crect fill='%236b6b6b' x='10' y='50' width='11' height='11'/%3E%3Crect fill='%236c6c6c' x='70' width='11' height='11'/%3E%3Crect fill='%236d6d6d' x='60' y='10' width='11' height='11'/%3E%3Crect fill='%236e6e6e' x='50' y='20' width='11' height='11'/%3E%3Crect fill='%236e6e6e' x='40' y='30' width='11' height='11'/%3E%3Crect fill='%236f6f6f' x='30' y='40' width='11' height='11'/%3E%3Crect fill='%23707070' x='20' y='50' width='11' height='11'/%3E%3Crect fill='%23717171' x='80' width='11' height='11'/%3E%3Crect fill='%23727272' x='70' y='10' width='11' height='11'/%3E%3Crect fill='%23737373' x='60' y='20' width='11' height='11'/%3E%3Crect fill='%23747474' x='50' y='30' width='11' height='11'/%3E%3Crect fill='%23747474' x='40' y='40' width='11' height='11'/%3E%3Crect fill='%23757575' x='30' y='50' width='11' height='11'/%3E%3Crect fill='%23767676' x='90' width='11' height='11'/%3E%3Crect fill='%23777777' x='80' y='10' width='11' height='11'/%3E%3Crect fill='%23787878' x='70' y='20' width='11' height='11'/%3E%3Crect fill='%23797979' x='60' y='30' width='11' height='11'/%3E%3Crect fill='%237a7a7a' x='50' y='40' width='11' height='11'/%3E%3Crect fill='%237b7b7b' x='40' y='50' width='11' height='11'/%3E%3Crect fill='%237c7c7c' x='90' y='10' width='11' height='11'/%3E%3Crect fill='%237c7c7c' x='80' y='20' width='11' height='11'/%3E%3Crect fill='%237d7d7d' x='70' y='30' width='11' height='11'/%3E%3Crect fill='%237e7e7e' x='60' y='40' width='11' height='11'/%3E%3Crect fill='%237f7f7f' x='50' y='50' width='11' height='11'/%3E%3Crect fill='%23808080' x='90' y='20' width='11' height='11'/%3E%3Crect fill='%23818181' x='80' y='30' width='11' height='11'/%3E%3Crect fill='%23828282' x='70' y='40' width='11' height='11'/%3E%3Crect fill='%23838383' x='60' y='50' width='11' height='11'/%3E%3Crect fill='%23848484' x='90' y='30' width='11' height='11'/%3E%3Crect fill='%23848484' x='80' y='40' width='11' height='11'/%3E%3Crect fill='%23858585' x='70' y='50' width='11' height='11'/%3E%3Crect fill='%23868686' x='90' y='40' width='11' height='11'/%3E%3Crect fill='%23878787' x='80' y='50' width='11' height='11'/%3E%3Crect fill='%23888888' x='90' y='50' width='11' height='11'/%3E%3C/g%3E%3C/svg%3E");
background-attachment: fixed;
background-size: cover;
}
a {
text-decoration: none;
color: var(--color-text-primary);
}
label {
display: block;
margin: var(--spacing-8) 0;
font-size: var(--font-24);
color: var(--color-text-muted);
}
input {
padding: var(--spacing-8);
font-size: var(--font-16);
border-radius: var(--radius-base);
border: none;
}
.btn {
padding: var(--spacing-16) var(--spacing-32);
font-size: var(--font-18);
font-weight: bold;
color: var(--color-text-primary);
background-color: var(--color-btn-primary-active);
border-radius: var(--radius-base);
border: none;
cursor: pointer;
}
.btn:hover {
background-color: var(--color-btn-primary-active-hover);
}
.btn:disabled {
color: var(--color-text-muted);
background-color: var(--color-btn-primary-inactive);
cursor: not-allowed;
}
ul,
ol {
list-style: none;
}
/* Utils */
.responsive {
resize: both;
overflow: scroll;
border: 1px solid hsl(0 0% 0%);
}
.placeholder {
padding: var(--spacing-20) 0;
background-color: var(--color-placeholder);
border-radius: var(--radius-base);
}

58
src/styles/reset.scss Normal file
View file

@ -0,0 +1,58 @@
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
img,
picture,
video,
canvas,
svg {
display: block;
max-width: 100%;
}
iframe,
video {
width: 100%;
border: none;
aspect-ratio: 16 / 9;
}
input,
button,
textarea,
select {
font: inherit;
}
p,
h1,
h2,
h3,
h4,
h5,
h6 {
overflow-wrap: break-word;
}
button,
input {
font: inherit;
color: inherit;
border: none;
}
button {
font: inherit;
background: none;
cursor: pointer;
}
ul,
ol {
list-style: none;
}

3
src/styles/styles.scss Normal file
View file

@ -0,0 +1,3 @@
@use 'reset.scss';
@use 'global.scss';
@use 'theme.scss';

247
src/styles/theme.scss Normal file
View file

@ -0,0 +1,247 @@
html[data-theme='🌛 Night'] {
/* Global */
--clr-primary: hsl(173 100% 66%);
--clr-txt: hsl(0 0% 98%);
--clr-bg: hsl(210 7% 11%);
--bg: radial-gradient(hsl(173 100% 4%), var(--clr-bg));
--bg-opacity: 0.7;
/* Menu */
--clr-menu-text: hsl(0 0% 78%);
--clr-menu-bg: linear-gradient(180deg, hsl(180 7% 14%) 0%, hsl(216 7% 14%) 100%);
--clr-menu-arrow-bg: hsl(180 7% 14%);
--clr-menu-border: hsl(0 0% 19%);
--clr-theme-txt: hsl(177 100% 15%);
--clr-theme-active: hsl(177 100% 80%);
--clr-switch-on-bg: hsl(0 0% 24%);
--clr-switch-off-bg: hsl(0 0% 10%);
/* Hero */
--clr-hero-txt: hsl(174 27% 73%);
--clr-hero-bg: linear-gradient(270deg, hsl(210 15% 13%) 43%, hsl(176 19% 15%) 66%);
--clr-hero-divider-bg: hsl(0 0% 21%);
--clr-input-txt: hsl(177 100% 15%);
--clr-input-bg: hsl(210 13% 24%);
--clr-input-placeholder-txt: hsl(210 13% 50%);
--clr-input-border: hsl(0 0% 21%);
/* Card */
--clr-card-bg: linear-gradient(180deg, hsl(180 7% 14%) 0%, hsl(216 7% 14%) 100%);
--clr-card-txt: hsl(0 0% 78%);
/* Link */
--clr-link-txt: hsl(0 100% 98%);
--clr-link-background: hsl(0 0% 4%);
/* Footer */
--clr-footer-txt: hsl(0 0% 78%);
--clr-footer-bg: hsl(210 5% 7%);
/* Post */
--post-overlay-bg: radial-gradient(hsl(173 100% 4% / 80%), var(--clr-bg));
--post-blockquote-txt: hsl(173 100% 94%);
--post-blockquote-bg: hsl(173 60% 4%);
--post-blockquote-border: hsl(173 10% 10%);
--clr-code-bg: hsl(173 60% 4%);
--clr-code-title: hsl(173 100% 94%);
--clr-code-border: hsl(173 10% 10%);
--clr-code-line-number: hsl(173 20% 20%);
--clr-code-line-highlight: hsl(173 40% 8%);
--clr-code-inline-txt: hsl(173 100% 94%);
--clr-code-inline-bg: hsl(173 60% 4%);
--clr-token-1: hsl(173 100% 66%);
--clr-token-2: hsl(180 60% 80%);
--clr-token-3: hsl(173 100% 66%);
--clr-token-4: hsl(0 0% 98%);
--clr-token-5: hsl(173 10% 60%);
}
html[data-theme='☀️ Daylight'] {
/* Global */
--clr-primary: hsl(220 100% 50%);
--clr-txt: hsl(220 10% 10%);
--clr-bg: hsl(0 0% 98%);
--bg: radial-gradient(hsl(0 0% 98%), var(--clr-bg));
--bg-opacity: 0.7;
/* Menu */
--clr-menu-text: hsl(220 10% 10%);
--clr-menu-bg: linear-gradient(180deg, hsl(0 0% 98%) 0%, hsl(0 0% 94%) 100%);
--clr-menu-arrow-bg: hsl(0 0% 98%);
--clr-menu-border: hsl(0 0% 80%);
--clr-theme-txt: hsl(0 0% 98%);
--clr-theme-active: hsl(220 100% 60%);
--clr-switch-on-bg: hsl(220 40% 90%);
--clr-switch-off-bg: hsl(220 40% 80%);
/* Hero */
--clr-hero-txt: hsl(220 10% 40%);
--clr-hero-bg: linear-gradient(270deg, hsl(0 0% 94%) 43%, hsl(0 0% 98%) 66%);
--clr-hero-divider-bg: hsl(0 0% 80%);
--clr-input-txt: hsl(220 10% 98%);
--clr-input-bg: hsl(0 0% 98%);
--clr-input-placeholder-txt: hsl(220 10% 60%);
--clr-input-border: hsl(0 0% 80%);
/* Card */
--clr-card-bg: linear-gradient(180deg, hsl(0 0% 98%) 0%, hsl(0 0% 94%) 100%);
--clr-card-txt: hsl(220 10% 40%);
/* Link */
--clr-link-txt: hsl(220 10% 10%);
--clr-link-background: hsl(0 0% 100%);
/* Footer */
--clr-footer-txt: hsl(220 10% 10%);
--clr-footer-bg: hsl(0 0% 98%);
/* Post */
--post-overlay-bg: radial-gradient(hsl(0 0% 100% / 60%), var(--clr-bg));
--post-blockquote-txt: hsl(0 0% 40%);
--post-blockquote-bg: hsl(0 0% 98%);
--post-blockquote-border: hsl(0 0% 84%);
--clr-code-bg: hsl(0 0% 98%);
--clr-code-title: hsl(0 0% 40%);
--clr-code-border: hsl(0 0% 84%);
--clr-code-line-number: hsl(0 0% 60%);
--clr-code-line-highlight: hsl(0 0% 94%);
--clr-code-inline-txt: hsl(0 0% 98%);
--clr-code-inline-bg: hsl(0 0% 20%);
--clr-token-1: hsl(220 100% 50%);
--clr-token-2: hsl(220 60% 50%);
--clr-token-3: hsl(220 100% 50%);
--clr-token-4: hsl(0 0% 20%);
--clr-token-5: hsl(0 0% 60%);
}
html[data-theme='🐺 Night Howl'] {
/* Global */
--clr-primary: hsl(207 100% 94%);
--clr-txt: hsl(210 40% 80%);
--clr-bg: hsl(210 47% 12%);
--bg: radial-gradient(hsl(206 50% 11%), var(--clr-bg));
--bg-opacity: 0.7;
/* Menu */
--clr-menu-text: hsl(210 40% 80%);
--clr-menu-bg: linear-gradient(180deg, hsl(210 47% 14%) 0%, hsl(210 47% 12%) 100%);
--clr-menu-arrow-bg: hsl(210 47% 14%);
--clr-menu-border: hsl(210 40% 20%);
--clr-theme-txt: hsl(210 40% 20%);
--clr-theme-active: hsl(210 40% 80%);
--clr-switch-on-bg: hsl(210 40% 60%);
--clr-switch-off-bg: hsl(210 40% 20%);
/* Hero */
--clr-hero-txt: hsl(210 40% 60%);
--clr-hero-bg: linear-gradient(270deg, hsl(210 47% 12%) 43%, hsl(210 47% 14%) 66%);
--clr-hero-divider-bg: hsl(210 40% 20%);
--clr-input-txt: hsl(210 40% 20%);
--clr-input-bg: hsl(210 40% 16%);
--clr-input-placeholder-txt: hsl(210 40% 60%);
--clr-input-border: hsl(210 40% 20%);
/* Card */
--clr-card-bg: linear-gradient(180deg, hsl(210 47% 14%) 0%, hsl(210 47% 12%) 100%);
--clr-card-txt: hsl(210 40% 60%);
/* Link */
--clr-link-txt: hsl(210 40% 80%);
--clr-link-background: hsl(210 40% 4%);
/* Footer */
--clr-footer-txt: hsl(210 40% 80%);
--clr-footer-bg: hsl(210 47% 12%);
/* Post */
--post-overlay-bg: radial-gradient(hsl(206 50% 11% / 60%), var(--clr-bg));
--post-blockquote-txt: hsl(210 47% 80%);
--post-blockquote-bg: hsl(210 47% 14%);
--post-blockquote-border: hsl(210 40% 20%);
--clr-code-bg: hsl(210 47% 14%);
--clr-code-title: hsl(210 40% 60%);
--clr-code-border: hsl(210 40% 20%);
--clr-code-line-number: hsl(210 40% 40%);
--clr-code-line-highlight: hsl(210 40% 16%);
--clr-code-inline-txt: hsl(210 47% 98%);
--clr-code-inline-bg: hsl(210 47% 10%);
--clr-token-1: hsl(180 100% 43%);
--clr-token-2: hsl(197 100% 49%);
--clr-token-3: hsl(180 100% 43%);
--clr-token-4: hsl(206 50% 98%);
--clr-token-5: hsl(217 10% 64%);
}
html[data-theme='🧠 Night Mind'] {
/* Global */
--clr-primary: hsl(9 100% 84%);
--clr-txt: hsl(265 28% 98%);
--clr-bg: hsl(265 28% 10%);
--bg: radial-gradient(hsl(265 28% 20%), var(--clr-bg));
--bg-opacity: 0.7;
/* Menu */
--clr-menu-text: hsl(265 28% 98%);
--clr-menu-bg: linear-gradient(180deg, hsl(265 28% 20%) 0%, hsl(265 28% 18%) 100%);
--clr-menu-arrow-bg: hsl(265 28% 20%);
--clr-menu-border: hsl(265 28% 24%);
--clr-theme-txt: hsl(265 28% 20%);
--clr-theme-active: hsl(9 100% 90%);
--clr-switch-on-bg: hsl(265 28% 30%);
--clr-switch-off-bg: hsl(265 28% 24%);
/* Hero */
--clr-hero-txt: hsl(265 28% 80%);
--clr-hero-bg: linear-gradient(270deg, hsl(265 28% 20%) 43%, hsl(265 28% 24%) 66%);
--clr-hero-divider-bg: hsl(265 28% 24%);
--clr-input-txt: hsl(265 28% 20%);
--clr-input-bg: hsl(265 28% 24%);
--clr-input-placeholder-txt: hsl(265 28% 80%);
--clr-input-border: hsl(265 28% 26%);
/* Card */
--clr-card-bg: linear-gradient(180deg, hsl(265 28% 22%) 0%, hsl(265 28% 20%) 100%);
--clr-card-txt: hsl(265 28% 80%);
/* Link */
--clr-link-txt: hsl(265 28% 98%);
--clr-link-background: hsl(210 40% 4%);
/* Footer */
--clr-footer-txt: hsl(265 28% 98%);
--clr-footer-bg: hsl(265 28% 10%);
/* Post */
--post-overlay-bg: radial-gradient(hsl(265 28% 20% / 60%), var(--clr-bg));
--post-blockquote-txt: hsl(265 28% 90%);
--post-blockquote-bg: hsl(265 28% 10%);
--post-blockquote-border: hsl(265 28% 18%);
--clr-code-bg: hsl(265 28% 10%);
--clr-code-title: hsl(265 28% 80%);
--clr-code-border: hsl(265 28% 18%);
--clr-code-line-number: hsl(265 20% 34%);
--clr-code-line-highlight: hsl(265 28% 14%);
--clr-code-inline-txt: hsl(265 28% 98%);
--clr-code-inline-bg: hsl(265 28% 10%);
--clr-token-1: hsl(238 80% 80%);
--clr-token-2: hsl(205 80% 80%);
--clr-token-3: hsl(358 80% 80%);
--clr-token-4: hsl(256 80% 98%);
--clr-token-5: hsl(265 10% 60%);
}

View file

@ -1,23 +1,16 @@
import adapter from '@sveltejs/adapter-auto'; import adapter from '@sveltejs/adapter-auto';
import preprocess from 'svelte-preprocess'; import preprocess from 'svelte-preprocess';
import path from 'path';
/** @type {import('@sveltejs/kit').Config} */ /** @type {import('@sveltejs/kit').Config} */
const config = { const config = {
// Consult https://github.com/sveltejs/svelte-preprocess // Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors // for more information about preprocessors
preprocess: preprocess({ preprocess: preprocess(),
scss: {},
}),
kit: { kit: {
adapter: adapter(), adapter: adapter(),
vite: {
resolve: {
alias: { alias: {
$root: path.resolve('./src') $components: 'src/components',
} $root: './src'
}
}, },
// Override http methods in the Todo forms // Override http methods in the Todo forms
methodOverride: { methodOverride: {

View file

@ -5,16 +5,9 @@
"checkJs": true, "checkJs": true,
"esModuleInterop": true, "esModuleInterop": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"lib": [
"es2020",
"DOM"
],
"moduleResolution": "node",
"module": "es2020",
"resolveJsonModule": true, "resolveJsonModule": true,
"skipLibCheck": true, "skipLibCheck": true,
"sourceMap": true, "sourceMap": true,
"strict": true, "strict": true
"target": "es2020",
} }
} }

8
vite.config.js Normal file
View file

@ -0,0 +1,8 @@
import { sveltekit } from '@sveltejs/kit/vite';
/** @type {import('vite').UserConfig} */
const config = {
plugins: [sveltekit()]
};
export default config;