docs(editor): replace static demo with editor

This commit is contained in:
Rafael Bardini 2023-09-15 03:40:25 +02:00
parent e9aba0d654
commit 5575556d76
9 changed files with 345 additions and 21 deletions

View File

@ -4,7 +4,7 @@
"node": true "node": true
}, },
"extends": "eslint:recommended", "extends": "eslint:recommended",
"ignorePatterns": ["test", "vite.config.js"], "ignorePatterns": ["editor.js", "test", "vite.config.js"],
"parserOptions": { "parserOptions": {
"sourceType": "module" "sourceType": "module"
} }

View File

@ -1,5 +1,6 @@
{ {
"arrowParens": "avoid", "arrowParens": "avoid",
"printWidth": 120,
"semi": false, "semi": false,
"singleQuote": true "singleQuote": true
} }

55
editor.css Normal file
View File

@ -0,0 +1,55 @@
html,
body {
height: 100%;
}
html {
color-scheme: light dark;
}
body {
display: grid;
grid-template: 50% 50% / 100%;
margin: 0;
}
button {
cursor: pointer;
}
iframe {
border: 0;
order: 1;
width: 100%;
height: 100%;
}
nav {
display: flex;
flex-direction: column;
gap: 0.5rem;
position: absolute;
inset-block-end: 1rem;
inset-inline-end: 1rem;
}
nav > * {
background: ButtonFace;
border: 1px solid ButtonBorder;
border-radius: 50%;
color: ButtonText;
padding: 0.5rem;
display: grid;
place-items: center;
}
nav > :hover,
nav > :focus {
background: Canvas;
}
@media (min-width: 720px) {
body {
grid-template: 100% / 50% 50%;
}
}

33
editor.js Normal file
View File

@ -0,0 +1,33 @@
import { indentWithTab } from '@codemirror/commands'
import { json } from '@codemirror/lang-json'
import { EditorView, keymap } from '@codemirror/view'
import { oneDark } from '@codemirror/theme-one-dark'
import { basicSetup } from 'codemirror'
import { debounce } from 'debounce'
import resume from 'resume-schema/sample.resume.json' assert { type: 'json' }
import { render } from './index.js'
import './editor.css'
const preview = document.querySelector('iframe')
const printButton = document.querySelector('button[name=print]')
printButton.addEventListener('click', () => preview.contentWindow.print())
const renderPreview = debounce(resume => (preview.srcdoc = render(resume)), 200)
renderPreview(resume)
new EditorView({
doc: JSON.stringify(resume, null, ' '),
extensions: [
basicSetup,
oneDark,
EditorView.lineWrapping,
EditorView.updateListener.of(
({ docChanged, state }) => docChanged && renderPreview(JSON.parse(state.doc.toString())),
),
keymap.of([indentWithTab]),
json(),
],
parent: document.body,
})

34
index.html Normal file
View File

@ -0,0 +1,34 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>jsonresume-theme-even</title>
<meta name="description" content="A flat JSON Resume theme, compatible with the latest resume schema." />
<meta name="viewport" content="width=device-width" />
<script src="/editor.js" type="module"></script>
</head>
<body>
<iframe src="about:blank"></iframe>
<nav>
<button name="print" aria-label="Print resume" title="Print resume">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<polyline points="6 9 6 2 18 2 18 9"></polyline>
<path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path>
<rect x="6" y="14" width="12" height="8"></rect>
</svg>
</button>
<a
href="https://github.com/rbardini/jsonresume-theme-even"
aria-label="Star on GitHub"
title="Star on GitHub"
target="_blank"
>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path
d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"
></path>
</svg>
</a>
</nav>
</body>
</html>

View File

@ -1,3 +1,3 @@
[build] [build]
command = "npm run build:demo" command = "npm run build -- --mode development"
publish = "public" publish = "public"

184
package-lock.json generated
View File

@ -17,7 +17,13 @@
"jsonresume-theme-even": "bin/cli.js" "jsonresume-theme-even": "bin/cli.js"
}, },
"devDependencies": { "devDependencies": {
"@codemirror/commands": "6.2.5",
"@codemirror/lang-json": "6.0.1",
"@codemirror/theme-one-dark": "6.1.2",
"@codemirror/view": "6.19.0",
"@vitest/coverage-v8": "0.34.3", "@vitest/coverage-v8": "0.34.3",
"codemirror": "6.0.1",
"debounce": "1.2.1",
"eslint": "8.48.0", "eslint": "8.48.0",
"html-validate": "8.3.0", "html-validate": "8.3.0",
"husky": "8.0.3", "husky": "8.0.3",
@ -235,6 +241,111 @@
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
"dev": true "dev": true
}, },
"node_modules/@codemirror/autocomplete": {
"version": "6.9.0",
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.9.0.tgz",
"integrity": "sha512-Fbwm0V/Wn3BkEJZRhr0hi5BhCo5a7eBL6LYaliPjOSwCyfOpnjXY59HruSxOUNV+1OYer0Tgx1zRNQttjXyDog==",
"dev": true,
"dependencies": {
"@codemirror/language": "^6.0.0",
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.6.0",
"@lezer/common": "^1.0.0"
},
"peerDependencies": {
"@codemirror/language": "^6.0.0",
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0",
"@lezer/common": "^1.0.0"
}
},
"node_modules/@codemirror/commands": {
"version": "6.2.5",
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.2.5.tgz",
"integrity": "sha512-dSi7ow2P2YgPBZflR9AJoaTHvqmeGIgkhignYMd5zK5y6DANTvxKxp6eMEpIDUJkRAaOY/TFZ4jP1ADIO/GLVA==",
"dev": true,
"dependencies": {
"@codemirror/language": "^6.0.0",
"@codemirror/state": "^6.2.0",
"@codemirror/view": "^6.0.0",
"@lezer/common": "^1.0.0"
}
},
"node_modules/@codemirror/lang-json": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.1.tgz",
"integrity": "sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==",
"dev": true,
"dependencies": {
"@codemirror/language": "^6.0.0",
"@lezer/json": "^1.0.0"
}
},
"node_modules/@codemirror/language": {
"version": "6.9.0",
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.9.0.tgz",
"integrity": "sha512-nFu311/0ne/qGuGCL3oKuktBgzVOaxCHZPZv1tLSZkNjPYxxvkjSbzno3MlErG2tgw1Yw1yF8BxMCegeMXqpiw==",
"dev": true,
"dependencies": {
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0",
"@lezer/common": "^1.0.0",
"@lezer/highlight": "^1.0.0",
"@lezer/lr": "^1.0.0",
"style-mod": "^4.0.0"
}
},
"node_modules/@codemirror/lint": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.4.1.tgz",
"integrity": "sha512-2Hx945qKX7FBan5/gUdTM8fsMYrNG9clIgEcPXestbLVFAUyQYFAuju/5BMNf/PwgpVaX5pvRm4+ovjbp9D9gQ==",
"dev": true,
"dependencies": {
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0",
"crelt": "^1.0.5"
}
},
"node_modules/@codemirror/search": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.2.tgz",
"integrity": "sha512-WRihpqd0l9cEh9J3IZe45Yi+Z5MfTsEXnyc3V7qXHP4ZYtIYpGOn+EJ7fyLIkyAm/8S6QIr7/mMISfAadf8zCg==",
"dev": true,
"dependencies": {
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0",
"crelt": "^1.0.5"
}
},
"node_modules/@codemirror/state": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.2.1.tgz",
"integrity": "sha512-RupHSZ8+OjNT38zU9fKH2sv+Dnlr8Eb8sl4NOnnqz95mCFTZUaiRP8Xv5MeeaG0px2b8Bnfe7YGwCV3nsBhbuw==",
"dev": true
},
"node_modules/@codemirror/theme-one-dark": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz",
"integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==",
"dev": true,
"dependencies": {
"@codemirror/language": "^6.0.0",
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0",
"@lezer/highlight": "^1.0.0"
}
},
"node_modules/@codemirror/view": {
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.19.0.tgz",
"integrity": "sha512-XqNIfW/3GaaF+T7Q1jBcRLCPm1NbrR2DBxrXacSt1FG+rNsdsNn3/azAfgpUoJ7yy4xgd8xTPa3AlL+y0lMizQ==",
"dev": true,
"dependencies": {
"@codemirror/state": "^6.1.4",
"style-mod": "^4.1.0",
"w3c-keyname": "^2.2.4"
}
},
"node_modules/@esbuild/android-arm": { "node_modules/@esbuild/android-arm": {
"version": "0.18.20", "version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
@ -801,6 +912,40 @@
"@jridgewell/sourcemap-codec": "^1.4.14" "@jridgewell/sourcemap-codec": "^1.4.14"
} }
}, },
"node_modules/@lezer/common": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.4.tgz",
"integrity": "sha512-lZHlk8p67x4aIDtJl6UQrXSOP6oi7dQR3W/geFVrENdA1JDaAJWldnVqVjPMJupbTKbzDfFcePfKttqVidS/dg==",
"dev": true
},
"node_modules/@lezer/highlight": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.1.6.tgz",
"integrity": "sha512-cmSJYa2us+r3SePpRCjN5ymCqCPv+zyXmDl0ciWtVaNiORT/MxM7ZgOMQZADD0o51qOaOg24qc/zBViOIwAjJg==",
"dev": true,
"dependencies": {
"@lezer/common": "^1.0.0"
}
},
"node_modules/@lezer/json": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.1.tgz",
"integrity": "sha512-nkVC27qiEZEjySbi6gQRuMwa2sDu2PtfjSgz0A4QF81QyRGm3kb2YRzLcOPcTEtmcwvrX/cej7mlhbwViA4WJw==",
"dev": true,
"dependencies": {
"@lezer/highlight": "^1.0.0",
"@lezer/lr": "^1.0.0"
}
},
"node_modules/@lezer/lr": {
"version": "1.3.10",
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.3.10.tgz",
"integrity": "sha512-BZfVvf7Re5BIwJHlZXbJn9L8lus5EonxQghyn+ih8Wl36XMFBPTXC0KM0IdUtj9w/diPHsKlXVgL+AlX2jYJ0Q==",
"dev": true,
"dependencies": {
"@lezer/common": "^1.0.0"
}
},
"node_modules/@nodelib/fs.scandir": { "node_modules/@nodelib/fs.scandir": {
"version": "2.1.5", "version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -1335,6 +1480,21 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/codemirror": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz",
"integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==",
"dev": true,
"dependencies": {
"@codemirror/autocomplete": "^6.0.0",
"@codemirror/commands": "^6.0.0",
"@codemirror/language": "^6.0.0",
"@codemirror/lint": "^6.0.0",
"@codemirror/search": "^6.0.0",
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0"
}
},
"node_modules/color-convert": { "node_modules/color-convert": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@ -1390,6 +1550,12 @@
"url": "https://opencollective.com/core-js" "url": "https://opencollective.com/core-js"
} }
}, },
"node_modules/crelt": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
"integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
"dev": true
},
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@ -1404,6 +1570,12 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/debounce": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
"integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==",
"dev": true
},
"node_modules/debug": { "node_modules/debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -3894,6 +4066,12 @@
"resolved": "https://registry.npmjs.org/striptags/-/striptags-3.2.0.tgz", "resolved": "https://registry.npmjs.org/striptags/-/striptags-3.2.0.tgz",
"integrity": "sha512-g45ZOGzHDMe2bdYMdIvdAfCQkCTDMGBazSw1ypMowwGIee7ZQ5dU0rBJ8Jqgl+jAKIv4dbeE1jscZq9wid1Tkw==" "integrity": "sha512-g45ZOGzHDMe2bdYMdIvdAfCQkCTDMGBazSw1ypMowwGIee7ZQ5dU0rBJ8Jqgl+jAKIv4dbeE1jscZq9wid1Tkw=="
}, },
"node_modules/style-mod": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.0.tgz",
"integrity": "sha512-Ca5ib8HrFn+f+0n4N4ScTIA9iTOQ7MaGS1ylHcoVqW9J7w2w8PzN6g9gKmTYgGEBH8e120+RCmhpje6jC5uGWA==",
"dev": true
},
"node_modules/supports-color": { "node_modules/supports-color": {
"version": "7.2.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@ -4251,6 +4429,12 @@
} }
} }
}, },
"node_modules/w3c-keyname": {
"version": "2.2.8",
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
"dev": true
},
"node_modules/which": { "node_modules/which": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",

View File

@ -1,7 +1,7 @@
{ {
"name": "jsonresume-theme-even", "name": "jsonresume-theme-even",
"version": "0.21.0", "version": "0.21.0",
"description": "A flat theme for JSON Resume, compatible with the bleeding edge resume schema", "description": "A flat JSON Resume theme, compatible with the latest resume schema",
"keywords": [ "keywords": [
"resume", "resume",
"json", "json",
@ -38,8 +38,7 @@
], ],
"scripts": { "scripts": {
"build": "vite build", "build": "vite build",
"prebuild:demo": "npm run build", "dev": "vite",
"build:demo": "mkdir -p public && ./bin/cli.js < node_modules/resume-schema/sample.resume.json > public/index.html",
"format": "prettier .", "format": "prettier .",
"lint": "eslint --ignore-path .gitignore .", "lint": "eslint --ignore-path .gitignore .",
"prepare": "husky install", "prepare": "husky install",
@ -52,7 +51,13 @@
"striptags": "^3.2.0" "striptags": "^3.2.0"
}, },
"devDependencies": { "devDependencies": {
"@codemirror/commands": "6.2.5",
"@codemirror/lang-json": "6.0.1",
"@codemirror/theme-one-dark": "6.1.2",
"@codemirror/view": "6.19.0",
"@vitest/coverage-v8": "0.34.3", "@vitest/coverage-v8": "0.34.3",
"codemirror": "6.0.1",
"debounce": "1.2.1",
"eslint": "8.48.0", "eslint": "8.48.0",
"html-validate": "8.3.0", "html-validate": "8.3.0",
"husky": "8.0.3", "husky": "8.0.3",

View File

@ -1,21 +1,33 @@
import { defineConfig } from 'vite' import { defineConfig } from 'vite'
import pkg from './package.json' assert { type: 'json' } import pkg from './package.json' assert { type: 'json' }
export default defineConfig({ export default defineConfig(({ mode }) => {
build: { if (mode === 'development') {
copyPublicDir: false, return {
lib: { build: {
entry: './index.js', outDir: './public',
fileName: 'index', target: 'esnext',
formats: ['es', 'cjs', 'umd'], },
name: 'jsonresumeThemeEven', publicDir: false,
}
}
return {
build: {
copyPublicDir: false,
lib: {
entry: './index.js',
fileName: 'index',
formats: ['es', 'cjs', 'umd'],
name: 'jsonresumeThemeEven',
},
rollupOptions: {
external: [...Object.keys(pkg.dependencies), /^node:.*/],
},
target: 'esnext',
test: {
clearMocks: true,
},
}, },
rollupOptions: { }
external: [...Object.keys(pkg.dependencies), /^node:.*/],
},
target: 'esnext',
test: {
clearMocks: true,
},
},
}) })