1
0

add transition to nav tree

user-agent detection is employed to ensure that the SSR renders the nav items by default for desktop (opposite for mobile). CSS media queries take over after the content loads on the device.

TODO: fix preview pane jump on desktop
This commit is contained in:
Nicola Clark 2024-10-12 14:37:07 -05:00
parent 890f8c6c17
commit 8ac0f6b931
Signed by: nicola
GPG Key ID: 3E1710E7FF08956C
6 changed files with 99 additions and 13 deletions

63
package-lock.json generated
View File

@ -7,11 +7,16 @@
"": {
"name": "resumarkdown",
"version": "0.0.1",
"dependencies": {
"ua-parser-js": "^1.0.39"
},
"devDependencies": {
"@playwright/test": "^1.28.1",
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@types/ua-parser-js": "^0.7.39",
"@types/user-agents": "^1.0.4",
"less": "^4.2.0",
"prettier": "^3.1.1",
"prettier-plugin-svelte": "^3.1.2",
@ -19,6 +24,7 @@
"svelte-check": "^4.0.0",
"svelte-preprocess": "^6.0.3",
"typescript": "^5.0.0",
"user-agents": "^1.1.325",
"vite": "^5.0.3",
"vitest": "^2.0.0"
}
@ -829,6 +835,20 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/ua-parser-js": {
"version": "0.7.39",
"resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.39.tgz",
"integrity": "sha512-P/oDfpofrdtF5xw433SPALpdSchtJmY7nsJItf8h3KXqOslkbySh8zq4dSWXH2oTjRvJ5PczVEoCZPow6GicLg==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/user-agents": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@types/user-agents/-/user-agents-1.0.4.tgz",
"integrity": "sha512-AjeFc4oX5WPPflgKfRWWJfkEk7Wu82fnj1rROPsiqFt6yElpdGFg8Srtm/4PU4rA9UiDUZlruGPgcwTMQlwq4w==",
"dev": true,
"license": "MIT"
},
"node_modules/@vitest/expect": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.2.tgz",
@ -1357,6 +1377,13 @@
"dev": true,
"license": "MIT"
},
"node_modules/lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
"integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
"dev": true,
"license": "MIT"
},
"node_modules/loupe": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz",
@ -1986,6 +2013,42 @@
"node": ">=14.17"
}
},
"node_modules/ua-parser-js": {
"version": "1.0.39",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.39.tgz",
"integrity": "sha512-k24RCVWlEcjkdOxYmVJgeD/0a1TiSpqLg+ZalVGV9lsnr4yqu0w7tX/x2xX6G4zpkgQnRf89lxuZ1wsbjXM8lw==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/ua-parser-js"
},
{
"type": "paypal",
"url": "https://paypal.me/faisalman"
},
{
"type": "github",
"url": "https://github.com/sponsors/faisalman"
}
],
"license": "MIT",
"bin": {
"ua-parser-js": "script/cli.js"
},
"engines": {
"node": "*"
}
},
"node_modules/user-agents": {
"version": "1.1.325",
"resolved": "https://registry.npmjs.org/user-agents/-/user-agents-1.1.325.tgz",
"integrity": "sha512-BmVDscJOZsBBztMPHg+wf65QwbT+N3C46YEsuW8BmcxRxwKh2AbdSaKEjzoC7rDlyuECXEUXO+C2eW3QAhbl2A==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"lodash.clonedeep": "^4.5.0"
}
},
"node_modules/vite": {
"version": "5.4.8",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz",

View File

@ -14,11 +14,16 @@
"lint": "prettier --check .",
"format": "prettier --write ."
},
"dependencies": {
"ua-parser-js": "^1.0.39"
},
"devDependencies": {
"@playwright/test": "^1.28.1",
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@types/ua-parser-js": "^0.7.39",
"@types/user-agents": "^1.0.4",
"less": "^4.2.0",
"prettier": "^3.1.1",
"prettier-plugin-svelte": "^3.1.2",
@ -26,6 +31,7 @@
"svelte-check": "^4.0.0",
"svelte-preprocess": "^6.0.3",
"typescript": "^5.0.0",
"user-agents": "^1.1.325",
"vite": "^5.0.3",
"vitest": "^2.0.0"
},

View File

@ -1,14 +1,14 @@
<script lang="ts">
import { onMount } from 'svelte';
import { slide } from 'svelte/transition';
import { navHeight } from '$lib/stores/layout';
import NavToggle from './nav-toggle.svelte';
let open: boolean = false;
export let mobile: boolean = true;
let hidden: boolean;
$: hidden = !open;
let open: boolean = false;
// magic to offset preview pane on desktop
let navRef: HTMLElement;
@ -20,9 +20,11 @@
<nav bind:this={navRef}>
<NavToggle bind:navOpen={open} />
<ul class:hidden role="tablist">
{#if open || !mobile}
<ul role="tablist" transition:slide={{ duration: 300 }}>
<slot />
</ul>
{/if}
</nav>
<style lang="less">
@ -35,14 +37,10 @@
margin: 0;
padding: 0;
&.hidden {
display: none;
}
@media screen and (min-width: @sizes[lg]) {
align-items: center;
border-right: @border;
display: flex !important;
display: flex;
flex-direction: row;
justify-content: space-evenly;
width: 50%;

View File

@ -0,0 +1,12 @@
import { UAParser } from 'ua-parser-js';
export async function load({ request }) {
const ua = request.headers.get('user-agent');
if (!ua) {
return { mobile: true };
}
const { device } = UAParser(ua);
return { mobile: device.type === 'mobile' };
}

View File

@ -5,6 +5,8 @@
import NavItem from '$lib/components/nav-item.svelte';
import NavTree from '$lib/components/nav-tree.svelte';
export let data;
let markdown: string = '';
let stylesheet: string = '';
</script>
@ -15,7 +17,7 @@
<div>
<header>
<Headline>resumarkdown</Headline>
<NavTree>
<NavTree mobile={data.mobile}>
<NavItem destination="content">content</NavItem>
<NavItem destination="style">style</NavItem>
<NavItem destination="preview">preview</NavItem>

View File

@ -1,6 +1,11 @@
import { expect, test } from '@playwright/test';
test.use({ viewport: { height: 2556, width: 1179 } });
import UserAgent from 'user-agents';
test.use({
viewport: { height: 2556, width: 1179 },
userAgent: new UserAgent({ deviceCategory: 'mobile' }).toString(),
});
test('mobile page has nav tree hidden by default', async ({ page }) => {
await page.goto('/');