diff --git a/.eslintrc.cjs b/.eslintrc.cjs index af91af2d..65ff1269 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -7,17 +7,11 @@ module.exports = { // 'plugin:@typescript-eslint/recommended-requiring-type-checking', 'plugin:@typescript-eslint/strict', 'plugin:unicorn/recommended', + 'plugin:svelte/recommended', + 'plugin:svelte/prettier', 'prettier' ], - plugins: [ - 'svelte3', - 'tailwindcss', - '@typescript-eslint', - 'es', - 'vitest', - 'no-only-tests', - 'unicorn' - ], + plugins: ['tailwindcss', '@typescript-eslint', 'es', 'vitest', 'no-only-tests', 'unicorn'], ignorePatterns: [ 'docs/*', '*.cjs', @@ -30,7 +24,13 @@ module.exports = { 'tsconfig.json' ], overrides: [ - { files: ['*.svelte'], processor: 'svelte3/svelte3' }, + { + files: ['*.svelte'], + parser: 'svelte-eslint-parser', + parserOptions: { + parser: '@typescript-eslint/parser' + } + }, { files: ['*.ts'], extends: [ @@ -42,16 +42,12 @@ module.exports = { ] } ], - settings: { - 'svelte3/typescript': () => require('typescript') - }, parserOptions: { sourceType: 'module', ecmaVersion: 2020, tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - extraFileExtensions: ['.svelte'], - allowAutomaticSingleRunInference: true + project: './tsconfig.json', + extraFileExtensions: ['.svelte'] }, env: { browser: true, @@ -76,6 +72,7 @@ module.exports = { case: 'camelCase' } ], + 'unicorn/filename-case': 'off', 'unicorn/prevent-abbreviations': [ 'error', { diff --git a/.node-version b/.node-version new file mode 100644 index 00000000..25bf17fc --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +18 \ No newline at end of file diff --git a/.prettierrc b/.prettierrc index ab65daf2..e0366fc9 100644 --- a/.prettierrc +++ b/.prettierrc @@ -3,5 +3,7 @@ "svelteSortOrder": "options-scripts-markup-styles", "bracketSameLine": true, "trailingComma": "none", - "printWidth": 100 + "printWidth": 100, + "tailwindConfig": "./tailwind.config.cjs", + "plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"] } diff --git a/.vscode/settings.json b/.vscode/settings.json index e1731904..5d2cb867 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,12 +10,15 @@ "daisyui", "esserializer", "gantt", + "gitgraph", "KROKI", "localstorage", "mermaidchart", "mindmap", "Pageview", "pako", + "panzoom", + "pzoom", "Serde", "serdes", "tailwindcss", diff --git a/cypress/e2e/util.ts b/cypress/e2e/util.ts index 57a9f54b..456ae585 100644 --- a/cypress/e2e/util.ts +++ b/cypress/e2e/util.ts @@ -11,7 +11,7 @@ export const typeInEditor = ( ) => { cy.window().should('have.property', 'editorLoaded', true); cy.get('#editor').click(); - cy.get('#editor').within(($editor) => { + cy.get('#editor').within(() => { if (bottom) { cy.get('textarea').type('{pageDown}', { force: true }); } diff --git a/package.json b/package.json index 37592fa9..044f27a3 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,9 @@ "dev:test": "yarn dev", "build": "vite build", "preview": "vite preview", - "lint": "prettier --check --cache --plugin-search-dir=. .;eslint --ignore-path .gitignore .", - "lint:fix": "prettier --write --cache --plugin-search-dir=. .;eslint --fix --ignore-path .gitignore .", - "format": "prettier --write --cache --plugin-search-dir=. .", + "lint": "prettier --check --cache . && eslint --ignore-path .gitignore .", + "lint:fix": "prettier --write --cache . && eslint --fix --ignore-path .gitignore .", + "format": "prettier --write --cache .", "pre-commit": "lint-staged", "postinstall": "husky install && svelte-kit sync && (git config blame.ignoreRevsFile .git-blame-ignore-revs || true)", "test:unit": "vitest", @@ -23,15 +23,15 @@ }, "devDependencies": { "@cypress/snapshot": "2.1.7", - "@sveltejs/adapter-static": "2.0.3", - "@sveltejs/kit": "1.28.0", - "@testing-library/jest-dom": "5.17.0", - "@testing-library/svelte": "3.2.2", + "@sveltejs/adapter-static": "3.0.1", + "@sveltejs/kit": "2.3.0", + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "@testing-library/svelte": "4.0.5", "@types/pako": "2.0.3", "@types/uuid": "9.0.7", - "@typescript-eslint/eslint-plugin": "5.62.0", - "@typescript-eslint/parser": "5.62.0", - "@vitest/ui": "^0.34.0", + "@typescript-eslint/eslint-plugin": "6.18.1", + "@typescript-eslint/parser": "6.18.1", + "@vitest/ui": "^1.1.3", "autoprefixer": "^10.4.14", "c8": "7.14.0", "chai": "^4.3.7", @@ -39,33 +39,35 @@ "cy-verify-downloads": "0.2.2", "cypress": "12.17.4", "cypress-localstorage-commands": "2.2.5", - "eslint": "8.55.0", - "eslint-config-prettier": "8.10.0", + "eslint": "8.56.0", + "eslint-config-prettier": "9.1.0", "eslint-plugin-cypress": "2.15.1", - "eslint-plugin-es": "4.1.0", + "eslint-plugin-es": "^4.1.0", "eslint-plugin-no-only-tests": "^3.1.0", - "eslint-plugin-postcss-modules": "2.0.0", - "eslint-plugin-svelte3": "4.0.0", - "eslint-plugin-tailwindcss": "3.13.0", - "eslint-plugin-unicorn": "^46.0.0", - "eslint-plugin-vitest": "^0.3.0", - "esserializer": "1.3.11", + "eslint-plugin-postcss-modules": "^2.0.0", + "eslint-plugin-svelte": "^2.35.1", + "eslint-plugin-tailwindcss": "^3.13.1", + "eslint-plugin-unicorn": "^50.0.1", + "eslint-plugin-vitest": "^0.3.20", + "esserializer": "^1.3.11", "font-awesome": "^4.7.0", "husky": "^8.0.3", - "jsdom": "21.1.2", - "lint-staged": "13.3.0", + "jsdom": "^21.1.2", + "lint-staged": "^15.2.0", "node-html-parser": "^6.1.5", - "postcss": "^8.4.21", - "postcss-load-config": "4.0.2", - "prettier": "2.8.8", - "prettier-plugin-svelte": "^2.10.0", - "svelte": "3.59.2", - "svelte-preprocess": "5.1.1", - "tailwindcss": "^3.3.1", - "tslib": "^2.5.0", - "typescript": "5.3.2", - "vite": "^4.5.1", - "vitest": "^0.34.0" + "postcss": "^8.4.33", + "postcss-load-config": "5.0.2", + "prettier": "^3.1.0", + "prettier-plugin-svelte": "^3.1.2", + "prettier-plugin-tailwindcss": "^0.5.11", + "svelte": "^4.2.8", + "svelte-preprocess": "^5.1.3", + "tailwindcss": "^3.4.1", + "tslib": "^2.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.11", + "vitest": "^1.1.3", + "vitest-dom": "^0.1.1" }, "dependencies": { "daisyui": "2.52.0", diff --git a/src/app.html b/src/app.html index e2469685..9b8d5a11 100644 --- a/src/app.html +++ b/src/app.html @@ -1,4 +1,4 @@ - + diff --git a/src/app.postcss b/src/app.postcss index 888c737e..73ce33f0 100644 --- a/src/app.postcss +++ b/src/app.postcss @@ -3,7 +3,7 @@ @tailwind utilities; .input { - @apply flex-1 border-primary border-solid border-2 rounded; + @apply flex-1 rounded border-2 border-solid border-primary; } .action-btn { @apply btn btn-primary; diff --git a/src/global.d.ts b/src/global.d.ts index 95ecd6a0..63908c66 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -1,16 +1 @@ -/* eslint-disable @typescript-eslint/no-empty-interface */ -/* eslint-disable @typescript-eslint/ban-types */ -/* eslint-disable @typescript-eslint/no-unused-vars */ - /// -import type { TestingLibraryMatchers } from '@testing-library/jest-dom/matchers'; - -declare global { - namespace jest { - interface Matchers - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error - // eslint-disable-next-line no-undef - extends TestingLibraryMatchers {} - } -} diff --git a/src/lib/components/Actions.svelte b/src/lib/components/Actions.svelte index 7b1b9578..9b1fd242 100644 --- a/src/lib/components/Actions.svelte +++ b/src/lib/components/Actions.svelte @@ -7,12 +7,12 @@ import { logEvent } from '$lib/util/stats'; import { toBase64 } from 'js-base64'; import dayjs from 'dayjs'; - const { krokiRendererUrl, rendererUrl } = env; + const { krokiRendererUrl, rendererUrl } = env; type Exporter = (context: CanvasRenderingContext2D, image: HTMLImageElement) => () => void; - const getFileName = (ext: string) => - `mermaid-diagram-${dayjs().format('YYYY-MM-DD-HHmmss')}.${ext}`; + const getFileName = (extension: string) => + `mermaid-diagram-${dayjs().format('YYYY-MM-DD-HHmmss')}.${extension}`; const getBase64SVG = (svg?: HTMLElement, width?: number, height?: number): string => { if (svg) { @@ -22,7 +22,7 @@ height && svg?.setAttribute('height', `${height}px`); width && svg?.setAttribute('width', `${width}px`); // Workaround https://stackoverflow.com/questions/28690643/firefox-error-rendering-an-svg-image-to-html5-canvas-with-drawimage if (!svg) { - svg = getSvgEl(); + svg = getSvgElement(); } const svgString = svg.outerHTML .replaceAll('
', '
') @@ -32,7 +32,7 @@ const exportImage = (event: Event, exporter: Exporter) => { const canvas: HTMLCanvasElement = document.createElement('canvas'); - const svg: HTMLElement | null = document.querySelector('#container svg'); + const svg = document.querySelector('#container svg'); if (!svg) { throw new Error('svg not found'); } @@ -57,28 +57,26 @@ context.fillRect(0, 0, canvas.width, canvas.height); const image = new Image(); - image.onload = exporter(context, image); + image.addEventListener('load', exporter(context, image)); image.src = `data:image/svg+xml;base64,${getBase64SVG(svg, canvas.width, canvas.height)}`; event.stopPropagation(); event.preventDefault(); }; - const getSvgEl = () => { - const svgEl: HTMLElement = document - .querySelector('#container svg')! - .cloneNode(true) as HTMLElement; - svgEl.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); - const fontAwesomeCdnUrl = Array.from(document.head.getElementsByTagName('link')) - .map((l) => l.href) - .find((h) => h.includes('font-awesome')); + const getSvgElement = () => { + const svgElement = document.querySelector('#container svg')?.cloneNode(true) as HTMLElement; + svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); + const fontAwesomeCdnUrl = [...document.head.querySelectorAll('link')] + .map((link) => link.href) + .find((url) => url.includes('font-awesome')); if (fontAwesomeCdnUrl == null) { - return svgEl; + return svgElement; } - const styleEl = document.createElement('style'); - styleEl.innerText = `@import url("${fontAwesomeCdnUrl}");'`; - svgEl.prepend(styleEl); - return svgEl; + const styleElement = document.createElement('style'); + styleElement.textContent = `@import url("${fontAwesomeCdnUrl}");'`; + svgElement.prepend(styleElement); + return svgElement; }; const simulateDownload = (download: string, href: string): void => { @@ -144,7 +142,7 @@ }; const onCopyMarkdown = () => { - (document.getElementById('markdown') as HTMLInputElement).select(); + document.querySelector('#markdown')?.select(); document.execCommand('Copy'); logEvent('copyMarkdown'); }; @@ -185,7 +183,7 @@ -
+
{#if isClipboardAvailable()} -
+
PNG size
-
+
-
+
{#if isNetlify} -
- + diff --git a/src/lib/components/Card/Card.svelte b/src/lib/components/Card/Card.svelte index 38098eb6..3e107487 100644 --- a/src/lib/components/Card/Card.svelte +++ b/src/lib/components/Card/Card.svelte @@ -11,20 +11,22 @@ $: isTabsShown = isOpen && tabs.length > 0; -
+