init with Skeleton

+preconfiguration
This commit is contained in:
matthieu42morin 2023-11-02 00:36:58 +01:00
parent 80ecda8d58
commit 66ba7d2378
24 changed files with 4094 additions and 0 deletions

3
.dockerignore Normal file
View File

@ -0,0 +1,3 @@
**/node_modules
**/.next
**/dist

14
.editorconfig Normal file
View File

@ -0,0 +1,14 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
indent_style = tab
indent_size = 4
charset = utf-8
trim_trailing_whitespace = false
quote_type = single
[*.{yml, md}]
indent_style = space
indent_size = 2

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

30
.eslintrc.cjs Normal file
View File

@ -0,0 +1,30 @@
module.exports = {
root: true,
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:svelte/recommended',
'prettier'
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
parserOptions: {
sourceType: 'module',
ecmaVersion: 2020,
extraFileExtensions: ['.svelte']
},
env: {
browser: true,
es2017: true,
node: true
},
overrides: [
{
files: ['*.svelte'],
parser: 'svelte-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser'
}
}
]
};

60
.gitignore vendored Normal file
View File

@ -0,0 +1,60 @@
+ .turbo
+ build/**
+ dist/**
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
.vercel
.output
.yarn
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
!.vscode/extensions.json
.vscode/*
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
*.flock
*.tmp
# php
public/api/vendor
/test-results/
/playwright-report/
/playwright/.cache/
/test-results/
/playwright-report/
/playwright/.cache/
/test-results/
/playwright-report/
/playwright/.cache/
/test-results/
/playwright-report/
/playwright/.cache/

2
.npmrc Normal file
View File

@ -0,0 +1,2 @@
engine-strict=true
resolution-mode=highest

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

9
.prettierrc Normal file
View File

@ -0,0 +1,9 @@
{
"useTabs": true,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
"plugins": ["prettier-plugin-svelte"],
"pluginSearchDirs": ["."],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
}

3
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"recommendations": ["svelte.svelte-vscode", "orta.vscode-twoslash-queries"]
}

111
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,111 @@
{
"editor.formatOnSave": true,
"svelte.plugin.typescript.format.enable": true, // enable Svelte formatter for TypeScript in Svelte files
"svelte.plugin.svelte.format.enable": true, // enable Svelte formatter for HTML and CSS in Svelte files
"[svelte]": {
"editor.defaultFormatter": "svelte.svelte-vscode" // enable Prettier formatter for JavaScript files
},
"[ts]": {
"editor.defaultFormatter": "esbenp.prettier-vscode" // enable Prettier formatter for JavaScript files
},
"editor.fontFamily": "Fira Code",
"editor.fontLigatures": true,
"prettier.documentSelectors": [
"**/*.svelte"
],
"tailwindCSS.classAttributes": [
"class",
"accent",
"active",
"aspectRatio",
"background",
"bgBackdrop",
"bgDark",
"bgDrawer",
"bgLight",
"blur",
"border",
"button",
"buttonClasses",
"buttonTextFirst",
"buttonTextLast",
"buttonTextNext",
"buttonTextPrevious",
"caretClosed",
"caretOpen",
"color",
"controlSeparator",
"controlVariant",
"cursor",
"display",
"element",
"fill",
"fillDark",
"fillLight",
"flex",
"gap",
"gridColumns",
"height",
"hover",
"inactive",
"indent",
"justify",
"meter",
"padding",
"regionAnchor",
"regionBackdrop",
"regionBody",
"regionCaption",
"regionCaret",
"regionCell",
"regionChildren",
"regionCone",
"regionContent",
"regionControl",
"regionDefault",
"regionDrawer",
"regionFoot",
"regionFootCell",
"regionHead",
"regionHeadCell",
"regionHeader",
"regionIcon",
"regionInterface",
"regionInterfaceText",
"regionLabel",
"regionLead",
"regionLegend",
"regionList",
"regionListItem",
"regionNavigation",
"regionPage",
"regionPanel",
"regionRowHeadline",
"regionRowMain",
"regionSummary",
"regionSymbol",
"regionTab",
"regionTrail",
"ring",
"rounded",
"select",
"shadow",
"slotDefault",
"slotFooter",
"slotHeader",
"slotLead",
"slotMessage",
"slotMeta",
"slotPageContent",
"slotPageFooter",
"slotPageHeader",
"slotSidebarLeft",
"slotSidebarRight",
"slotTrail",
"spacing",
"text",
"track",
"width",
"zIndex"
]
}

38
README.md Normal file
View File

@ -0,0 +1,38 @@
# create-svelte
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte).
## Creating a project
If you're seeing this, you've probably already done this step. Congrats!
```bash
# create a new project in the current directory
npm create svelte@latest
# create a new project in my-app
npm create svelte@latest my-app
```
## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
```bash
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
```
## Building
To create a production version of your app:
```bash
npm run build
```
You can preview the production build with `npm run preview`.
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.

75
package.json Normal file
View File

@ -0,0 +1,75 @@
{
"name": "portfolio",
"description": "Uses pnpm, svelte, mdsvex",
"version": "1.0.0",
"main": "index.js",
"private": true,
"homepage": "mattmor.in",
"author": "Matthieu Morin",
"license": "AGPLv3",
"repository": {
"type": "git",
"url": "https://github.com/matthieu42morin/Portfolio/"
},
"packageManager": "pnpm@8.6.6",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"test": "vitest",
"lint": "prettier --plugin-search-dir . --check . && eslint .",
"format": "prettier --plugin-search-dir . --write ."
},
"devDependencies": {
"@skeletonlabs/skeleton": "2.0.0",
"@skeletonlabs/tw-plugin": "0.1.0",
"@sveltejs/adapter-auto": "^2.0.0",
"@sveltejs/kit": "^1.20.4",
"@tailwindcss/forms": "0.5.6",
"@tailwindcss/typography": "0.5.9",
"@types/js-cookie": "^3.0.5",
"@types/node": "20.5.7",
"@typescript-eslint/eslint-plugin": "^5.45.0",
"@typescript-eslint/parser": "^5.45.0",
"autoprefixer": "10.4.15",
"eslint": "^8.28.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-svelte": "^2.30.0",
"js-cookie": "^3.0.5",
"postcss": "8.4.29",
"prettier": "^2.8.0",
"prettier-plugin-svelte": "^2.10.1",
"sass": "^1.66.1",
"svelte": "^4.0.5",
"svelte-check": "^3.4.3",
"tailwindcss": "3.3.3",
"tslib": "^2.4.1",
"typescript": "^5.2.2",
"vite": "^4.4.2",
"vite-plugin-tailwind-purgecss": "0.1.3",
"vitest": "^0.34.0"
},
"type": "module",
"dependencies": {
"@floating-ui/dom": "1.5.1",
"@threlte/core": "^6.0.10",
"@threlte/extras": "^7.0.0",
"@yushijinhun/three-minifier-rollup": "^0.4.0",
"hastscript": "^8.0.0",
"highlight.js": "11.8.0",
"linkedom": "^0.15.3",
"mdast-util-to-string": "^4.0.0",
"mdsvex": "^0.11.0",
"prismjs": "^1.29.0",
"rehype-img-size": "^1.0.1",
"rehype-wrap-all": "^1.1.0",
"remark-autolink-headings": "^7.0.1",
"remark-external-links": "^9.0.1",
"remark-slug": "^7.0.1",
"rss": "^1.2.2",
"svelte-preprocess": "^5.0.4",
"unist-util-visit": "^5.0.0"
}
}

3390
pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load Diff

6
postcss.config.cjs Normal file
View File

@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

9
src/app.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
// and what to do when importing types
declare namespace App {
// interface Locals {}
// interface PageData {}
// interface Error {}
// interface Platform {}
}

15
src/app.html Normal file
View File

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en" class="dark">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 18 16'><text x='0' y='14'>🚀</text></svg>" />
<link rel="preload" href="/fonts/MagilioRegular.ttf" as="font" type="font/ttf" crossorigin />
<link rel="preload" href="/fonts/satoshi/Satoshi-Variable.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/fonts/satoshi/Satoshi-VariableItalic.woff2" as="font" type="font/woff2" crossorigin>
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover" data-theme="wintry">
<div style="display: contents" class="h-full overflow-hidden">%sveltekit.body%</div>
</body>
</html>

53
src/app.postcss Normal file
View File

@ -0,0 +1,53 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@tailwind variants;
html,
body {
@apply h-full overflow-hidden;
}
:root [data-theme='wintry'] {
}
.gradient-heading {
@apply bg-clip-text text-transparent box-decoration-clone;
/* Direction */
@apply bg-gradient-to-br;
/* Color Stops */
@apply from-primary-500 via-tertiary-500 to-secondary-500;
}
/* gold-nouveau theme */
@font-face {
font-family: 'Quicksand';
src: url('/fonts/Quicksand.ttf');
font-display: swap;
}
/*
@font-face {
font-family: 'Magilio';
src: url('/fonts/MagilioRegular.ttf') format('truetype');
font-weight: 900;
font-display: swap;
}
@font-face {
font-family: 'Satoshi-Variable';
src: url('/fonts/satoshi/Satoshi-Variable.woff2') format('woff2'),
url('/fonts/satoshi/Satoshi-Variable.woff') format('woff'),
url('/fonts/satoshi/Satoshi-Variable.ttf') format('truetype');
font-weight: 300 900;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Satoshi-VariableItalic';
src: url('/fonts/satoshi/Satoshi-VariableItalic.woff2') format('woff2'),
url('/fonts/satoshi/Satoshi-VariableItalic.woff') format('woff'),
url('/fonts/satoshi/Satoshi-VariableItalic.ttf') format('truetype');
font-weight: 300 900;
font-display: swap;
font-style: italic;
} */

16
src/hooks.ts Normal file
View File

@ -0,0 +1,16 @@
// import type { Handle } from "@sveltejs/kit";
// import * as cookie from "cookie";
import { sequence } from "@sveltejs/kit/hooks";
import { basename } from "path";
const handleHeaders = async ({ event, resolve }:{event:any, resolve:any}) => {
const response = await resolve(event);
// Avoid clickjacking attacks, see https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html
response.headers.set(
"Content-Security-Policy",
"frame-ancestors *.mattmor.in *;"
);
return response;
};
export const handle = sequence(handleHeaders);

7
src/index.test.ts Normal file
View File

@ -0,0 +1,7 @@
import { describe, it, expect } from 'vitest';
describe('sum test', () => {
it('adds 1 + 2 to equal 3', () => {
expect(1 + 2).toBe(3);
});
});

6
src/service-worker.ts Normal file
View File

@ -0,0 +1,6 @@
/// <reference types="@sveltejs/kit" />
/// <reference no-default-lib="true"/>
/// <reference lib="esnext" />
/// <reference lib="webworker" />
const sw = self as unknown as ServiceWorkerGlobalScope;

132
svelte.config.js Normal file
View File

@ -0,0 +1,132 @@
import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/kit/vite';
import preprocess from 'svelte-preprocess';
import path from 'path';
import { mdsvex } from 'mdsvex';
import headings from 'remark-autolink-headings';
import remarkExternalLinks from 'remark-external-links';
import slug from 'remark-slug';
import remarkSetImagePath from './src/lib/utils/remark-set-image-path.js';
import remarkEmbedVideo from './src/lib/utils/remark-embed-video.js';
import remarkLinkWithImageAsOnlyChild from './src/lib/utils/remark-link-with-image-as-only-child.js';
import remarkHeadingsPermaLinks from './src/lib/utils/remark-headings-permalinks.js';
import { toString } from 'mdast-util-to-string';
import rehypeWrap from 'rehype-wrap-all';
import rehypeImgSize from 'rehype-img-size';
import { highlightCode } from './src/lib/utils/highlight.js';
import { mdsvexGlobalComponents } from './src/lib/utils/mdsvex-global-components.js';
import { h } from 'hastscript';
import { visit } from 'unist-util-visit';
import getHeadings from './src/lib/utils/get-headings.js';
const mdsvexOptions = {
extensions: ['.md'],
highlight: {
highlighter: highlightCode,
},
rehypePlugins: [
[
rehypeWrap,
{ selector: 'table', wrapper: 'div.overflow-auto' },
],
[rehypeImgSize, { dir: './static' }],
[
/** Custom rehype plugin to add loading="lazy" to all images */
() => {
return (tree) => {
visit(tree, 'element', (node) => {
if (node.tagName === 'img') {
node.properties.loading = 'lazy';
}
});
};
},
],
],
remarkPlugins: [
[
remarkExternalLinks,
{
target: '_blank',
},
],
slug,
[
headings,
{
behavior: 'append',
linkProperties: {},
content: function (node) {
return [
h('span.icon.icon-link header-anchor', {
ariaLabel: toString(node) + ' permalink',
}),
];
},
},
],
remarkSetImagePath,
remarkLinkWithImageAsOnlyChild,
remarkHeadingsPermaLinks,
getHeadings,
[
remarkEmbedVideo,
{
width: 800,
height: 400,
noIframeBorder: true,
},
],
],
};
/** @type {import('@sveltejs/kit').Config} */
const config = {
extensions: ['.svelte', '.md'],
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
// for more information about preprocessors
preprocess: [
vitePreprocess(),
preprocess({
postcss: true
}),
mdsvexGlobalComponents({
dir: `$lib/components`,
list: [['CodeFence', 'code-fence.svelte']],
extensions: ['.md'],
}),
mdsvex(mdsvexOptions)
],
vitePlugin: {
inspector: true,
},
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter({
runtime: 'nodejs18.x'
}),
alias: {
$lib: path.resolve('src', 'lib'),
$root: path.resolve('/'),
$src: path.resolve('src'),
$routes: path.resolve('src', 'routes'),
$content: path.resolve('src', 'content')
},
prerender: {
handleHttpError: ({ path, referrer, message }) => {
// ignore deliberate link to shiny 404 page
if (path === '/not-found' && referrer === '/404') {
return;
}
// otherwise fail the build
throw new Error(message);
}
}
}
};
export default config;

30
tailwind.config.ts Normal file
View File

@ -0,0 +1,30 @@
import { join } from 'path';
import type { Config } from 'tailwindcss';
import forms from '@tailwindcss/forms';
import typography from '@tailwindcss/typography';
import { skeleton } from '@skeletonlabs/tw-plugin';
export default {
darkMode: 'class',
content: [
'./src/**/*.{html,js,svelte,ts}',
join(require.resolve('@skeletonlabs/skeleton'), '../**/*.{html,js,svelte,ts}')
],
theme: {
extend: {}
},
plugins: [
forms,
typography,
skeleton({
themes: {
preset: [
{
name: 'wintry',
enhancements: true
}
]
}
})
]
} satisfies Config;

18
tsconfig.json Normal file
View File

@ -0,0 +1,18 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"outDir": ".svelte-kit",
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true
}
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
}

41
vite.config.ts Normal file
View File

@ -0,0 +1,41 @@
import { purgeCss } from 'vite-plugin-tailwind-purgecss';
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vitest/config';
import { threeMinifier } from '@yushijinhun/three-minifier-rollup';
import path from 'path';
export default defineConfig({
server: {
host: 'localhost',
port: 5174
},
build: {
// to resolve https://github.com/vitejs/vite/issues/6985
target: 'esnext',
},
plugins: [
sveltekit(),
purgeCss({
safelist: {
// any selectors that begin with "hljs-" will not be purged
greedy: [/^hljs-/]
}
}),
{ ...threeMinifier(), enforce: 'pre' }
],
test: {
include: ['src/**/*.{test,spec}.{js,ts}']
},
ssr: {
noExternal: ['three']
},
resolve: {
alias: {
$lib: path.resolve(__dirname, 'src', 'lib'),
$root: path.resolve(__dirname),
$src: path.resolve(__dirname, 'src'),
$routes: path.resolve(__dirname, 'src', 'routes'),
$content: path.resolve(__dirname, 'src', 'content')
}
}
});