Merge pull request #1796 from mermaid-js/release-promotion
Release live editor
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
docs/**
|
||||
.svelte-kit/**
|
||||
static/**
|
||||
build/**
|
||||
node_modules/**
|
||||
coverage/**
|
||||
__snapshots__/**
|
||||
snapshots.js
|
||||
-121
@@ -1,121 +0,0 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
parser: '@typescript-eslint/parser',
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
// 'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
||||
'plugin:@typescript-eslint/strict',
|
||||
'plugin:unicorn/recommended',
|
||||
'plugin:svelte/recommended',
|
||||
'plugin:svelte/prettier',
|
||||
'prettier'
|
||||
],
|
||||
plugins: [
|
||||
'tailwindcss',
|
||||
'@typescript-eslint',
|
||||
'es',
|
||||
'vitest',
|
||||
'no-only-tests',
|
||||
'sort-keys',
|
||||
'unicorn'
|
||||
],
|
||||
ignorePatterns: [
|
||||
'docs/*',
|
||||
'*.cjs',
|
||||
'*.js',
|
||||
'*.md',
|
||||
'snapshots.js',
|
||||
'svelte.config.js',
|
||||
'renovate.json',
|
||||
'package.json',
|
||||
'tsconfig.json'
|
||||
],
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.svelte'],
|
||||
parser: 'svelte-eslint-parser',
|
||||
parserOptions: {
|
||||
parser: '@typescript-eslint/parser'
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ['*.ts'],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
||||
'plugin:@typescript-eslint/strict',
|
||||
'prettier'
|
||||
]
|
||||
},
|
||||
{
|
||||
files: ['**/components/ui/**'],
|
||||
rules: {
|
||||
'unicorn/prefer-export-from': 'off',
|
||||
'unicorn/prevent-abbreviations': 'off',
|
||||
'unicorn/explicit-length-check': 'off',
|
||||
'sort-keys/sort-keys-fix': 'off'
|
||||
}
|
||||
}
|
||||
],
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
ecmaVersion: 2020,
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.json',
|
||||
extraFileExtensions: ['.svelte']
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
es2020: true
|
||||
},
|
||||
rules: {
|
||||
'sort-keys/sort-keys-fix': ['error', 'asc', { minKeys: 5 }],
|
||||
'@typescript-eslint/ban-ts-comment': [
|
||||
'error',
|
||||
{
|
||||
'ts-ignore': 'allow-with-description'
|
||||
}
|
||||
],
|
||||
'@typescript-eslint/no-unsafe-member-access': 'off',
|
||||
'@typescript-eslint/no-unsafe-assignment': 'off',
|
||||
'es/no-regexp-lookbehind-assertions': 'error',
|
||||
curly: ['error', 'all'],
|
||||
'no-only-tests/no-only-tests': 'error',
|
||||
'unicorn/no-null': 'off',
|
||||
'unicorn/filename-case': [
|
||||
'error',
|
||||
{
|
||||
case: 'camelCase'
|
||||
}
|
||||
],
|
||||
'unicorn/filename-case': 'off',
|
||||
'unicorn/prevent-abbreviations': [
|
||||
'error',
|
||||
{
|
||||
allowList: {
|
||||
args: true,
|
||||
ctx: true,
|
||||
db: true,
|
||||
doc: true,
|
||||
env: true,
|
||||
fn: true,
|
||||
i: true,
|
||||
j: true,
|
||||
k: true,
|
||||
param: true,
|
||||
Params: true,
|
||||
params: true,
|
||||
Props: true,
|
||||
props: true,
|
||||
req: true,
|
||||
res: true,
|
||||
str: true,
|
||||
temp: true,
|
||||
ImportMetaEnv: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
+2
-1
@@ -5,5 +5,6 @@
|
||||
"trailingComma": "none",
|
||||
"printWidth": 100,
|
||||
"tailwindConfig": "./tailwind.config.js",
|
||||
"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"]
|
||||
"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
|
||||
"tailwindStylesheet": "./src/app.css"
|
||||
}
|
||||
|
||||
+4
-5
@@ -1,17 +1,16 @@
|
||||
{
|
||||
"$schema": "https://next.shadcn-svelte.com/schema.json",
|
||||
"style": "new-york",
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.js",
|
||||
"css": "src/app.postcss",
|
||||
"css": "src/app.css",
|
||||
"baseColor": "slate"
|
||||
},
|
||||
"aliases": {
|
||||
"components": "$lib/components",
|
||||
"utils": "$lib/utils",
|
||||
"ui": "$lib/components/ui",
|
||||
"hooks": "$lib/hooks"
|
||||
"hooks": "$lib/hooks",
|
||||
"lib": "$lib"
|
||||
},
|
||||
"typescript": true,
|
||||
"registry": "https://next.shadcn-svelte.com/registry"
|
||||
"registry": "https://tw3.shadcn-svelte.com/registry/new-york"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
import { includeIgnoreFile } from '@eslint/compat';
|
||||
import js from '@eslint/js';
|
||||
import prettier from 'eslint-config-prettier';
|
||||
import sortKeysPlugin from 'eslint-plugin-sort-keys';
|
||||
import svelte from 'eslint-plugin-svelte';
|
||||
import eslintPluginUnicorn from 'eslint-plugin-unicorn';
|
||||
import { defineConfig } from 'eslint/config';
|
||||
import globals from 'globals';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import ts from 'typescript-eslint';
|
||||
import svelteConfig from './svelte.config.js';
|
||||
|
||||
const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url));
|
||||
|
||||
export default defineConfig(
|
||||
includeIgnoreFile(gitignorePath),
|
||||
js.configs.recommended,
|
||||
...ts.configs.strict,
|
||||
...ts.configs.stylistic,
|
||||
...svelte.configs.recommended,
|
||||
prettier,
|
||||
...svelte.configs.prettier,
|
||||
{
|
||||
languageOptions: {
|
||||
globals: { ...globals.browser, ...globals.node }
|
||||
},
|
||||
rules: {
|
||||
// typescript-eslint strongly recommend that you do not use the no-undef lint rule on TypeScript projects.
|
||||
// see: https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors
|
||||
'no-undef': 'off'
|
||||
}
|
||||
},
|
||||
{
|
||||
plugins: {
|
||||
unicorn: eslintPluginUnicorn
|
||||
},
|
||||
rules: {
|
||||
'unicorn/no-null': 'off',
|
||||
'unicorn/filename-case': 'off'
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ['src/**'],
|
||||
plugins: {
|
||||
'sort-keys': sortKeysPlugin
|
||||
},
|
||||
rules: {
|
||||
'sort-keys/sort-keys-fix': ['error', 'asc', { minKeys: 5 }]
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
projectService: true,
|
||||
extraFileExtensions: ['.svelte'],
|
||||
parser: ts.parser,
|
||||
svelteConfig
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
'svelte/no-unused-props': 'off'
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ['**/components/ui/**'],
|
||||
rules: {
|
||||
'unicorn/prefer-export-from': 'off',
|
||||
'unicorn/prevent-abbreviations': 'off',
|
||||
'unicorn/explicit-length-check': 'off',
|
||||
'sort-keys/sort-keys-fix': 'off'
|
||||
}
|
||||
}
|
||||
);
|
||||
+35
-33
@@ -9,8 +9,8 @@
|
||||
"dev:test": "pnpm dev",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"lint": "prettier --check --cache . && eslint --ignore-path .gitignore .",
|
||||
"lint:fix": "prettier --write --cache . && eslint --fix --ignore-path .gitignore .",
|
||||
"lint": "prettier --check --cache . && eslint .",
|
||||
"lint:fix": "prettier --write --cache . && eslint --fix .",
|
||||
"format": "prettier --write --cache .",
|
||||
"pre-commit": "lint-staged",
|
||||
"postinstall": "husky install && svelte-kit sync && (git config blame.ignoreRevsFile .git-blame-ignore-revs || true)",
|
||||
@@ -23,62 +23,64 @@
|
||||
"test:e2e:debug": "playwright test --debug"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/compat": "^1.2.5",
|
||||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@eslint/js": "^9.18.0",
|
||||
"@fortawesome/fontawesome-free": "^6.7.2",
|
||||
"@iconify-json/material-symbols": "^1.2.20",
|
||||
"@iconify-json/mdi": "^1.2.3",
|
||||
"@playwright/test": "^1.52.0",
|
||||
"@sveltejs/adapter-static": "3.0.8",
|
||||
"@sveltejs/kit": "2.20.8",
|
||||
"@sveltejs/vite-plugin-svelte": "^4.0.4",
|
||||
"@sveltejs/adapter-static": "^3.0.9",
|
||||
"@sveltejs/kit": "^2.37.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^6.1.3",
|
||||
"@tailwindcss/typography": "^0.5.15",
|
||||
"@tailwindcss/vite": "^4.0.0",
|
||||
"@types/hammerjs": "^2.0.46",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^22.15.10",
|
||||
"@types/pako": "2.0.3",
|
||||
"@types/uuid": "9.0.8",
|
||||
"@typescript-eslint/eslint-plugin": "6.21.0",
|
||||
"@typescript-eslint/parser": "6.21.0",
|
||||
"@vitest/coverage-v8": "2.1.9",
|
||||
"@vitest/ui": "^2.1.9",
|
||||
"@vitest/coverage-v8": "^3.2.4",
|
||||
"@vitest/ui": "^3.2.4",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"bits-ui": "^1.4.6",
|
||||
"bits-ui": "^2.9.6",
|
||||
"c8": "7.14.0",
|
||||
"chai": "^4.5.0",
|
||||
"clsx": "^2.1.1",
|
||||
"cssnano": "^6.1.2",
|
||||
"eslint": "8.57.1",
|
||||
"eslint-config-prettier": "9.1.0",
|
||||
"eslint": "^9.18.0",
|
||||
"eslint-config-prettier": "^10.0.1",
|
||||
"eslint-plugin-es": "^4.1.0",
|
||||
"eslint-plugin-no-only-tests": "^3.3.0",
|
||||
"eslint-plugin-postcss-modules": "^2.0.0",
|
||||
"eslint-plugin-sort-keys": "^2.3.5",
|
||||
"eslint-plugin-svelte": "^2.46.1",
|
||||
"eslint-plugin-tailwindcss": "^3.18.0",
|
||||
"eslint-plugin-unicorn": "^50.0.1",
|
||||
"eslint-plugin-vitest": "^0.5.4",
|
||||
"eslint-plugin-svelte": "^3.0.0",
|
||||
"eslint-plugin-tailwindcss": "^3.18.2",
|
||||
"eslint-plugin-unicorn": "^60.0.0",
|
||||
"esserializer": "^1.3.11",
|
||||
"globals": "^16.0.0",
|
||||
"husky": "^8.0.3",
|
||||
"jsdom": "^25.0.1",
|
||||
"lint-staged": "^15.5.1",
|
||||
"lucide-svelte": "^0.507.0",
|
||||
"node-html-parser": "^6.1.13",
|
||||
"paneforge": "^1.0.0-next.5",
|
||||
"postcss": "^8.5.3",
|
||||
"postcss-load-config": "5.1.0",
|
||||
"paneforge": "1.0.0-next.6",
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-svelte": "^3.3.3",
|
||||
"prettier-plugin-svelte": "^3.4.0",
|
||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
||||
"svelte": "^5.28.2",
|
||||
"svelte": "^5.38.6",
|
||||
"svelte-preprocess": "^6.0.3",
|
||||
"svelte-sonner": "^0.3.28",
|
||||
"tailwind-merge": "^3.2.0",
|
||||
"tailwind-variants": "^0.3.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"svelte-sonner": "^1.0.5",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
"tailwind-variants": "^3.1.0",
|
||||
"tailwindcss": "^4.0.0",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"unplugin-icons": "^22.1.0",
|
||||
"vite": "^5.4.19",
|
||||
"vitest": "^2.1.9",
|
||||
"tw-animate-css": "^1.3.8",
|
||||
"typescript": "^5.9.2",
|
||||
"typescript-eslint": "^8.42.0",
|
||||
"unplugin-icons": "^22.2.0",
|
||||
"vite": "^7.1.4",
|
||||
"vite-plugin-devtools-json": "^1.0.0",
|
||||
"vitest": "^3.2.4",
|
||||
"vitest-dom": "^0.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -99,7 +101,7 @@
|
||||
"hammerjs": "^2.0.8",
|
||||
"js-base64": "3.7.7",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mermaid": "^11.10.0",
|
||||
"mermaid": "^11.10.1",
|
||||
"mode-watcher": "^0.5.1",
|
||||
"monaco-editor": "0.52.2",
|
||||
"pako": "2.1.0",
|
||||
@@ -112,7 +114,7 @@
|
||||
"lint-staged": {
|
||||
"*.{ts,svelte,js,css,md,json}": [
|
||||
"prettier --plugin-search-dir=. --write",
|
||||
"eslint --ignore-path .gitignore "
|
||||
"eslint "
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
|
||||
Generated
+1600
-1389
File diff suppressed because it is too large
Load Diff
@@ -1,23 +0,0 @@
|
||||
const tailwindcss = require('tailwindcss');
|
||||
const autoprefixer = require('autoprefixer');
|
||||
const cssnano = require('cssnano');
|
||||
|
||||
const mode = process.env.NODE_ENV;
|
||||
const dev = mode === 'development';
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
// Some plugins, like postcss-nested, need to run before Tailwind
|
||||
|
||||
tailwindcss,
|
||||
|
||||
// But others, like autoprefixer, need to run after
|
||||
|
||||
autoprefixer,
|
||||
|
||||
!dev &&
|
||||
cssnano({
|
||||
preset: 'default'
|
||||
})
|
||||
]
|
||||
};
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
@import '@fontsource-variable/recursive/crsv.css';
|
||||
@import 'tailwindcss';
|
||||
@import 'tw-animate-css';
|
||||
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
@layer base {
|
||||
*,
|
||||
::after,
|
||||
::before,
|
||||
::backdrop,
|
||||
::file-selector-button {
|
||||
border-color: var(--color-gray-200, currentcolor);
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--background: hsl(0 0% 100%);
|
||||
--foreground: hsl(222.2 84% 4.9%);
|
||||
--card: hsl(0 0% 100%);
|
||||
--card-foreground: hsl(222.2 84% 4.9%);
|
||||
--popover: hsl(0 0% 100%);
|
||||
--popover-foreground: hsl(222.2 84% 4.9%);
|
||||
--primary: hsl(240 10% 91%);
|
||||
--primary-foreground: hsl(255 20% 15%);
|
||||
--secondary: hsl(210 40% 96.1%);
|
||||
--secondary-foreground: hsl(222.2 47.4% 11.2%);
|
||||
--muted: hsl(228 24% 96%);
|
||||
--muted-foreground: hsl(215.4 16.3% 46.9%);
|
||||
--accent: hsl(340 100% 44%);
|
||||
--accent-foreground: hsl(210 40% 98%);
|
||||
--destructive: hsl(0 72.22% 50.59%);
|
||||
--destructive-foreground: hsl(210 40% 98%);
|
||||
--border: hsl(214.3 31.8% 91.4%);
|
||||
--border-dark: hsl(214.3 31.8% 81.4%);
|
||||
--input: hsl(214.3 31.8% 91.4%);
|
||||
--ring: hsl(222.2 84% 4.9%);
|
||||
--radius: 0.75rem;
|
||||
}
|
||||
.dark {
|
||||
--background: hsl(222.2 84% 4.9%);
|
||||
--foreground: hsl(210 40% 98%);
|
||||
--card: hsl(222.2 84% 4.9%);
|
||||
--card-foreground: hsl(210 40% 98%);
|
||||
--popover: hsl(222.2 84% 4.9%);
|
||||
--popover-foreground: hsl(210 40% 98%);
|
||||
--primary: hsl(210 40% 30%);
|
||||
--primary-foreground: hsl(222.2 47.4% 90%);
|
||||
--secondary: hsl(217.2 32.6% 17.5%);
|
||||
--secondary-foreground: hsl(210 40% 98%);
|
||||
--muted: hsl(217.2 32.6% 17.5%);
|
||||
--muted-foreground: hsl(215 20.2% 65.1%);
|
||||
--accent: hsl(340 100% 44%);
|
||||
--accent-foreground: hsl(210 40% 98%);
|
||||
--destructive: hsl(0 62.8% 30.6%);
|
||||
--destructive-foreground: hsl(210 40% 98%);
|
||||
--border: hsl(217.2 32.6% 17.5%);
|
||||
--border-dark: hsl(217.2 32.6% 27.5%);
|
||||
--input: hsl(217.2 32.6% 17.5%);
|
||||
--ring: hsl(212.7 26.8% 83.9%);
|
||||
}
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
/* Radius (for rounded-*) */
|
||||
--radius-sm: calc(var(--radius) - 4px);
|
||||
--radius-md: calc(var(--radius) - 2px);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) + 4px);
|
||||
|
||||
/* Colors */
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
--color-popover: var(--popover);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-card: var(--card);
|
||||
--color-card-foreground: var(--card-foreground);
|
||||
--color-border: var(--border);
|
||||
--color-border-dark: var(--border-dark);
|
||||
--color-input: var(--input);
|
||||
--color-primary: var(--primary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-destructive-foreground: var(--destructive-foreground);
|
||||
--color-ring: var(--ring);
|
||||
--color-radius: var(--radius);
|
||||
--color-sidebar: var(--sidebar);
|
||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||
--color-sidebar-primary: var(--sidebar-primary);
|
||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||
--color-sidebar-accent: var(--sidebar-accent);
|
||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||
--color-sidebar-border: var(--sidebar-border);
|
||||
--color-sidebar-ring: var(--sidebar-ring);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
body {
|
||||
@apply h-screen w-screen overflow-hidden bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Recursive Variable', sans-serif;
|
||||
}
|
||||
|
||||
.d {
|
||||
@apply border border-red-500;
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
@import '@fontsource-variable/recursive/crsv.css';
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 222.2 84% 4.9%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 222.2 84% 4.9%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 222.2 84% 4.9%;
|
||||
--primary: 240 10% 91%;
|
||||
--primary-foreground: 255 20% 15%;
|
||||
--secondary: 210 40% 96.1%;
|
||||
--secondary-foreground: 222.2 47.4% 11.2%;
|
||||
--muted: 228 24% 96%;
|
||||
--muted-foreground: 215.4 16.3% 46.9%;
|
||||
--accent: 340 100% 44%;
|
||||
--accent-foreground: 210 40% 98%;
|
||||
--destructive: 0 72.22% 50.59%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
--border: 214.3 31.8% 91.4%;
|
||||
--input: 214.3 31.8% 91.4%;
|
||||
--ring: 222.2 84% 4.9%;
|
||||
--radius: 0.75rem;
|
||||
}
|
||||
.dark {
|
||||
--background: 222.2 84% 4.9%;
|
||||
--foreground: 210 40% 98%;
|
||||
--card: 222.2 84% 4.9%;
|
||||
--card-foreground: 210 40% 98%;
|
||||
--popover: 222.2 84% 4.9%;
|
||||
--popover-foreground: 210 40% 98%;
|
||||
--primary: 210 40% 30%;
|
||||
--primary-foreground: 222.2 47.4% 90%;
|
||||
--secondary: 217.2 32.6% 17.5%;
|
||||
--secondary-foreground: 210 40% 98%;
|
||||
--muted: 217.2 32.6% 17.5%;
|
||||
--muted-foreground: 215 20.2% 65.1%;
|
||||
--accent: 340 100% 44%;
|
||||
--accent-foreground: 210 40% 98%;
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
--border: 217.2 32.6% 17.5%;
|
||||
--input: 217.2 32.6% 17.5%;
|
||||
--ring: 212.7 26.8% 83.9%;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
body {
|
||||
@apply h-screen w-screen overflow-hidden bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Recursive Variable', sans-serif;
|
||||
}
|
||||
|
||||
.d {
|
||||
@apply border border-red-500;
|
||||
}
|
||||
@@ -38,13 +38,20 @@
|
||||
// Prevents the SVG size of the interface from being changed
|
||||
svg = svg.cloneNode(true) as HTMLElement;
|
||||
}
|
||||
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 (height) {
|
||||
svg?.setAttribute('height', `${height}px`);
|
||||
}
|
||||
if (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 = getSvgElement();
|
||||
}
|
||||
|
||||
svg.style.backgroundColor = `hsl(${window.getComputedStyle(document.body).getPropertyValue('--background')})`;
|
||||
|
||||
const svgString = svg.outerHTML
|
||||
.replaceAll('<br>', '<br/>')
|
||||
.replaceAll(/<img([^>]*)>/g, (m, g: string) => `<img ${g} />`);
|
||||
@@ -215,7 +222,7 @@ ${svgString}`);
|
||||
|
||||
<Card title="Actions" isStackable icon={{ component: DownloadIcon, class: 'rotate-180' }}>
|
||||
<div class="flex min-w-fit flex-col gap-2 p-2">
|
||||
<div class="flex w-full items-center gap-2 whitespace-nowrap py-2">
|
||||
<div class="flex w-full items-center gap-2 py-2 whitespace-nowrap">
|
||||
PNG size
|
||||
<ToggleGroup.Root type="single" variant="outline" bind:value={imageSizeMode}>
|
||||
<ToggleGroup.Item value="auto">Auto</ToggleGroup.Item>
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
role="toolbar"
|
||||
tabindex="0"
|
||||
class={[
|
||||
'flex h-11 flex-none cursor-pointer items-center justify-between whitespace-nowrap bg-muted p-2',
|
||||
'flex h-11 flex-none cursor-pointer items-center justify-between bg-muted p-2 whitespace-nowrap',
|
||||
isTabsShown && 'pb-1'
|
||||
]}
|
||||
onclick={toggleCardOpen}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
<div class="flex w-fit cursor-default items-center gap-2">
|
||||
<ul class="flex gap-2 align-middle" transition:fade>
|
||||
{#each tabs as tab, index}
|
||||
{#each tabs as tab, index (tab.id)}
|
||||
<Button
|
||||
role="tab"
|
||||
variant="ghost"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { Button } from '$/components/ui/button';
|
||||
import type { InputType } from '$/types';
|
||||
import { notify } from '$/util/notify';
|
||||
import { scale } from 'svelte/transition';
|
||||
import CheckIcon from '~icons/material-symbols/check-rounded';
|
||||
@@ -9,7 +8,7 @@
|
||||
let {
|
||||
onclick,
|
||||
label = 'Copy'
|
||||
}: { onclick: (event?: Event) => Promise<unknown>; label?: string; type?: InputType } = $props();
|
||||
}: { onclick: (event?: Event) => Promise<unknown>; label?: string } = $props();
|
||||
|
||||
let showCheckIcon = $state(false);
|
||||
</script>
|
||||
|
||||
@@ -93,7 +93,9 @@
|
||||
});
|
||||
|
||||
const unsubscribeMode = mode.subscribe((mode) => {
|
||||
editor && monaco.editor.setTheme(`mermaid${mode === 'dark' ? '-dark' : ''}`);
|
||||
if (editor) {
|
||||
monaco.editor.setTheme(`mermaid${mode === 'dark' ? '-dark' : ''}`);
|
||||
}
|
||||
});
|
||||
const resizeObserver = new ResizeObserver((entries) => {
|
||||
editor?.layout({
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<Popover.Content>
|
||||
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
||||
<ul tabindex="0" class="flex flex-col">
|
||||
{#each props.links as { href, title }}
|
||||
{#each props.links as { href, title } (title)}
|
||||
<li class="rounded-md p-2 hover:bg-muted">
|
||||
<a
|
||||
role="menuitem"
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
// Vite will automatically take care of adding this to our `<head>`
|
||||
let lazyLoadFontAwesomeCSS = import('./FontAwesomeCSS.svelte');
|
||||
|
||||
// eslint-disable-next-line unicorn/prefer-top-level-await
|
||||
let fontsLoaded = (async () => {
|
||||
await lazyLoadFontAwesomeCSS;
|
||||
|
||||
|
||||
@@ -175,13 +175,13 @@
|
||||
{:else}
|
||||
<span class="whitespace-nowrap">{name}</span>
|
||||
{/if}
|
||||
<span class="whitespace-nowrap text-xs text-primary-foreground/30">
|
||||
<span class="text-xs whitespace-nowrap text-primary-foreground/30">
|
||||
{new Date(time).toLocaleString()}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="whitespace-nowrap text-sm text-primary-foreground/50">
|
||||
<span class="text-sm whitespace-nowrap text-primary-foreground/50">
|
||||
{dayjs(time).fromNow()}
|
||||
</span>
|
||||
<Button size="icon" variant="ghost" onclick={() => restoreHistoryItem(state)}>
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
||||
import type { HistoryEntry } from '$lib/types';
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import {
|
||||
addHistoryEntry,
|
||||
injectHistoryIDs,
|
||||
clearHistoryData,
|
||||
historyModeStore,
|
||||
historyStore
|
||||
} from './history';
|
||||
import { defaultState } from '$lib/util/state';
|
||||
import { get } from 'svelte/store';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import {
|
||||
addHistoryEntry,
|
||||
clearHistoryData,
|
||||
historyModeStore,
|
||||
historyStore,
|
||||
injectHistoryIDs
|
||||
} from './history';
|
||||
|
||||
describe('history', () => {
|
||||
it('should handle saving individual history entry', () => {
|
||||
@@ -105,11 +104,11 @@ describe('history migration', () => {
|
||||
'[{"state":{"code":"graph TD\\n A[New Year] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","autoSync":true,"updateDiagram":false},"time":0,"type":"auto","name":"barking-dog"},{"state":{"code":"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","autoSync":true,"updateDiagram":true},"time":0,"type":"manual","name":"needy-mosquito"}]'
|
||||
);
|
||||
let manualHistoryStore = JSON.parse(
|
||||
window.localStorage.getItem('manualHistoryStore') ?? '[]'
|
||||
) as HistoryEntry[];
|
||||
let autoHistoryStore = JSON.parse(
|
||||
window.localStorage.getItem('autoHistoryStore') ?? '[]'
|
||||
) as HistoryEntry[];
|
||||
window.localStorage.getItem('manualHistoryStore') ?? '[]'
|
||||
) as HistoryEntry[],
|
||||
autoHistoryStore = JSON.parse(
|
||||
window.localStorage.getItem('autoHistoryStore') ?? '[]'
|
||||
) as HistoryEntry[];
|
||||
expect(manualHistoryStore.every(({ id }) => id !== undefined)).toBe(false);
|
||||
expect(autoHistoryStore.every(({ id }) => id !== undefined)).toBe(false);
|
||||
|
||||
|
||||
@@ -147,6 +147,5 @@ export const injectHistoryIDs = (): void => {
|
||||
const validateEntry = (entry: HistoryEntry): boolean => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
return entry.type && entry.state && entry.time && true;
|
||||
};
|
||||
|
||||
@@ -1,56 +1,95 @@
|
||||
<script lang="ts">
|
||||
import McWrapper from '$/components/McWrapper.svelte';
|
||||
import ThemeIcon from '$/components/ThemeIcon.svelte';
|
||||
import * as Popover from '$/components/ui/popover';
|
||||
import { Switch } from '$/components/ui/switch';
|
||||
import { urlsStore } from '$/util/state';
|
||||
import { cn } from '$/utils';
|
||||
import { mode, setMode } from 'mode-watcher';
|
||||
import type { Component } from 'svelte';
|
||||
import type { Component, Snippet } from 'svelte';
|
||||
import MermaidTailIcon from '~icons/custom/mermaid-tail';
|
||||
import AddIcon from '~icons/material-symbols/add-2-rounded';
|
||||
import BookIcon from '~icons/material-symbols/book-2-outline-rounded';
|
||||
import PluginIcon from '~icons/material-symbols/extension-outline';
|
||||
import HomeIcon from '~icons/material-symbols/house-outline-rounded';
|
||||
import DuplicateIcon from '~icons/material-symbols/content-copy-outline-rounded';
|
||||
import ContrastIcon from '~icons/material-symbols/contrast';
|
||||
import PluginIcon from '~icons/material-symbols/electrical-services-rounded';
|
||||
import MenuIcon from '~icons/material-symbols/menu-rounded';
|
||||
import CommunityIcon from '~icons/material-symbols/person-play-outline-rounded';
|
||||
import PlaygroundIcon from '~icons/material-symbols/shape-line-outline';
|
||||
import MermaidChartIcon from './MermaidChartIcon.svelte';
|
||||
|
||||
const menuItems = $derived([
|
||||
{ label: 'New Diagram', icon: AddIcon, href: $urlsStore.new },
|
||||
{ label: 'Home', icon: HomeIcon, href: 'https://mermaid.js.org/' },
|
||||
{ label: 'Documentation', icon: BookIcon, href: 'https://mermaid.js.org/intro/' },
|
||||
{ label: 'Community', icon: CommunityIcon, href: 'https://discord.gg/sKeNQX4Wtj' }
|
||||
]);
|
||||
interface MenuItem {
|
||||
label: string;
|
||||
icon: Component;
|
||||
href: string;
|
||||
class?: string;
|
||||
sharesData?: boolean;
|
||||
checkDiagramType?: boolean;
|
||||
isSectionEnd?: boolean;
|
||||
renderer: (item: Omit<MenuItem, 'renderer'>) => ReturnType<Snippet>;
|
||||
}
|
||||
|
||||
const mermaidChartMenuItems = $derived([
|
||||
const menuItems: MenuItem[] = $derived([
|
||||
{ label: 'New', icon: AddIcon, href: $urlsStore.new, renderer: menuItem },
|
||||
{ label: 'Duplicate', icon: DuplicateIcon, href: window.location.href, renderer: menuItem },
|
||||
{
|
||||
label: 'Edit in Playground',
|
||||
href: $urlsStore.mermaidChart({ medium: 'main_menu' }).playground,
|
||||
icon: PlaygroundIcon,
|
||||
href: $urlsStore.mermaidChart({ medium: 'main_menu' }).playground
|
||||
isSectionEnd: true,
|
||||
label: 'Edit in Playground',
|
||||
renderer: mcMenuItem
|
||||
},
|
||||
{
|
||||
label: 'Mermaid.js',
|
||||
icon: MermaidTailIcon,
|
||||
href: 'https://mermaid.js.org/',
|
||||
renderer: menuItem
|
||||
},
|
||||
{
|
||||
label: 'Documentation',
|
||||
icon: BookIcon,
|
||||
href: 'https://mermaid.js.org/intro/',
|
||||
renderer: menuItem
|
||||
},
|
||||
{
|
||||
label: 'Community',
|
||||
icon: CommunityIcon,
|
||||
href: 'https://discord.gg/sKeNQX4Wtj',
|
||||
renderer: menuItem
|
||||
},
|
||||
{
|
||||
checkDiagramType: false,
|
||||
href: $urlsStore.mermaidChart({ medium: 'main_menu' }).plugins,
|
||||
icon: PluginIcon,
|
||||
label: 'Plugins',
|
||||
renderer: mcMenuItem,
|
||||
sharesData: false
|
||||
},
|
||||
{
|
||||
href: '#',
|
||||
icon: ContrastIcon,
|
||||
isSectionEnd: true,
|
||||
label: 'Dark Mode',
|
||||
renderer: darkModeMenuItem
|
||||
},
|
||||
{
|
||||
checkDiagramType: false,
|
||||
class: 'text-accent border-b-0',
|
||||
href: $urlsStore.mermaidChart({ medium: 'main_menu' }).home,
|
||||
icon: MermaidChartIcon,
|
||||
label: 'MermaidChart',
|
||||
label: 'Mermaid',
|
||||
renderer: mcMenuItem,
|
||||
sharesData: false
|
||||
}
|
||||
]);
|
||||
</script>
|
||||
|
||||
{#snippet menuItem(options: { label: string; icon: Component; href: string; class?: string })}
|
||||
{#snippet menuItem(options: MenuItem)}
|
||||
<a
|
||||
href={options.href}
|
||||
target="_blank"
|
||||
class={cn(
|
||||
'flex items-center justify-start gap-2 border-b bg-muted p-2 px-3 hover:bg-background',
|
||||
'flex items-center justify-start gap-2 border-b-2 p-2 px-3 hover:bg-muted',
|
||||
options.isSectionEnd && 'border-border-dark',
|
||||
options.class
|
||||
)}>
|
||||
<options.icon class="size-5" />
|
||||
@@ -58,36 +97,40 @@
|
||||
</a>
|
||||
{/snippet}
|
||||
|
||||
{#snippet mcMenuItem(item: MenuItem)}
|
||||
<McWrapper
|
||||
side="right"
|
||||
labelPrefix={item.sharesData === false ? 'Opens a new tab in' : undefined}
|
||||
sharesData={item.sharesData}
|
||||
shouldCheckDiagramType={item.checkDiagramType}>
|
||||
{@render menuItem(item)}
|
||||
</McWrapper>
|
||||
{/snippet}
|
||||
|
||||
{#snippet darkModeMenuItem(options: MenuItem)}
|
||||
<div
|
||||
class={cn(
|
||||
'flex cursor-pointer items-center justify-between border-b-2 px-3 py-2 hover:bg-muted',
|
||||
options.isSectionEnd && 'border-border-dark',
|
||||
options.class
|
||||
)}>
|
||||
<span class="flex items-center gap-2">
|
||||
<ContrastIcon />
|
||||
Dark Mode
|
||||
</span>
|
||||
<Switch
|
||||
checked={$mode === 'dark'}
|
||||
onCheckedChange={(dark) => setMode(dark ? 'dark' : 'light')} />
|
||||
</div>
|
||||
{/snippet}
|
||||
|
||||
<Popover.Root>
|
||||
<Popover.Trigger class="shrink-0">
|
||||
<img class="size-6" src="/favicon.svg" alt="Mermaid Live Editor" />
|
||||
<MenuIcon class="size-6" />
|
||||
</Popover.Trigger>
|
||||
<Popover.Content align="start" class="flex flex-col overflow-hidden p-0" sideOffset={16}>
|
||||
{#each menuItems as item}
|
||||
{@render menuItem(item)}
|
||||
{/each}
|
||||
|
||||
<div class="flex items-center justify-between border-b bg-muted px-3 py-2 hover:bg-background">
|
||||
<span class="flex items-center gap-2">
|
||||
<ThemeIcon />
|
||||
Dark Mode
|
||||
</span>
|
||||
<Switch
|
||||
checked={$mode === 'dark'}
|
||||
onCheckedChange={(dark) => setMode(dark ? 'dark' : 'light')} />
|
||||
</div>
|
||||
|
||||
{#each mermaidChartMenuItems as item}
|
||||
<McWrapper
|
||||
side="right"
|
||||
labelPrefix={item.sharesData === false ? 'Opens a new tab in' : undefined}
|
||||
sharesData={item.sharesData}
|
||||
shouldCheckDiagramType={item.checkDiagramType}>
|
||||
{@render menuItem({
|
||||
...item,
|
||||
class: 'text-accent bg-background hover:bg-muted'
|
||||
})}
|
||||
</McWrapper>
|
||||
<Popover.Content align="start" class="flex flex-col overflow-hidden border-2 p-0" sideOffset={16}>
|
||||
{#each menuItems as { renderer, ...item } (item.label)}
|
||||
{@render renderer(item)}
|
||||
{/each}
|
||||
</Popover.Content>
|
||||
</Popover.Root>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import { urlsStore } from '$lib/util/state';
|
||||
import { MCBaseURL } from '$lib/util/util';
|
||||
import type { ComponentProps, Snippet } from 'svelte';
|
||||
import MermaidIcon from '~icons/custom/mermaid';
|
||||
import CloseIcon from '~icons/material-symbols/close-rounded';
|
||||
import GithubIcon from '~icons/mdi/github';
|
||||
import DropdownNavMenu from './DropdownNavMenu.svelte';
|
||||
@@ -83,8 +84,9 @@
|
||||
{/if}
|
||||
|
||||
<nav class="z-50 flex p-4 sm:p-6">
|
||||
<div class="flex flex-1 items-center gap-4">
|
||||
<div class="flex flex-1 items-center gap-2">
|
||||
<MainMenu />
|
||||
<MermaidIcon class="size-6" />
|
||||
<div
|
||||
id="switcher"
|
||||
class="flex items-center justify-center gap-4 font-medium"
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
|
||||
<Card title="Sample Diagrams" isOpen isStackable icon={{ component: ShapesIcon }}>
|
||||
<div class="flex h-fit max-h-52 flex-wrap gap-2 overflow-y-auto p-2">
|
||||
{#each diagramOrder as sample}
|
||||
{#each diagramOrder as sample (sample)}
|
||||
<Button
|
||||
size="sm"
|
||||
class="w-fit min-w-20 flex-grow normal-case"
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
} = await renderDiagram(JSON.parse(state.mermaid) as MermaidConfig, code, viewID);
|
||||
diagramType = detectedDiagramType;
|
||||
if (svg.length > 0) {
|
||||
// eslint-disable-next-line svelte/no-dom-manipulating
|
||||
container.innerHTML = svg;
|
||||
let graphDiv = document.querySelector<SVGSVGElement>(`#${viewID}`);
|
||||
if (!graphDiv) {
|
||||
@@ -138,6 +139,7 @@
|
||||
// Queue state changes to avoid race condition
|
||||
let pendingStateChange = Promise.resolve();
|
||||
stateStore.subscribe((state) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
pendingStateChange = pendingStateChange.then(() => handleStateChange(state).catch(() => {}));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" module>
|
||||
import type { WithElementRef } from 'bits-ui';
|
||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
||||
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
|
||||
import { type VariantProps, tv } from 'tailwind-variants';
|
||||
import { tv, type VariantProps } from 'tailwind-variants';
|
||||
|
||||
export const buttonVariants = tv({
|
||||
base: 'focus-visible:ring-ring inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-6 [&_svg]:shrink-0',
|
||||
@@ -40,8 +40,6 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils.js';
|
||||
|
||||
let {
|
||||
class: className,
|
||||
variant = 'default',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils.js';
|
||||
import { Dialog as DialogPrimitive, type WithoutChildrenOrChild } from 'bits-ui';
|
||||
import { cn, type WithoutChildrenOrChild } from '$lib/utils.js';
|
||||
import { Dialog as DialogPrimitive } from 'bits-ui';
|
||||
import X from 'lucide-svelte/icons/x';
|
||||
import type { Snippet } from 'svelte';
|
||||
import * as Dialog from './index.js';
|
||||
@@ -22,13 +22,13 @@
|
||||
<DialogPrimitive.Content
|
||||
bind:ref
|
||||
class={cn(
|
||||
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
|
||||
'fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
|
||||
className
|
||||
)}
|
||||
{...restProps}>
|
||||
{@render children?.()}
|
||||
<DialogPrimitive.Close
|
||||
class="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:text-muted-foreground">
|
||||
class="absolute top-4 right-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none disabled:pointer-events-none data-[state=open]:text-muted-foreground">
|
||||
<X class="size-4" />
|
||||
<span class="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { WithElementRef } from 'bits-ui';
|
||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
import { cn } from '$lib/utils.js';
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
import type { WithElementRef } from 'bits-ui';
|
||||
import { cn } from '$lib/utils.js';
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<DialogPrimitive.Overlay
|
||||
bind:ref
|
||||
class={cn(
|
||||
'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
||||
'fixed inset-0 z-50 bg-black/80 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0',
|
||||
className
|
||||
)}
|
||||
{...restProps} />
|
||||
|
||||
@@ -11,5 +11,5 @@
|
||||
|
||||
<DialogPrimitive.Title
|
||||
bind:ref
|
||||
class={cn('text-lg font-semibold leading-none tracking-tight', className)}
|
||||
class={cn('text-lg leading-none font-semibold tracking-tight', className)}
|
||||
{...restProps} />
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { InputType } from '$/types';
|
||||
import { cn } from '$lib/utils.js';
|
||||
import type { WithElementRef } from 'bits-ui';
|
||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
||||
import type { HTMLInputAttributes } from 'svelte/elements';
|
||||
|
||||
type Props = WithElementRef<
|
||||
@@ -23,7 +22,7 @@
|
||||
<input
|
||||
bind:this={ref}
|
||||
class={cn(
|
||||
'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
||||
'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
||||
className
|
||||
)}
|
||||
type="file"
|
||||
@@ -34,7 +33,7 @@
|
||||
<input
|
||||
bind:this={ref}
|
||||
class={cn(
|
||||
'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
||||
'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
||||
className
|
||||
)}
|
||||
{type}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
{align}
|
||||
{sideOffset}
|
||||
class={cn(
|
||||
'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
||||
'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95',
|
||||
className
|
||||
)}
|
||||
{...restProps} />
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { cn, type WithoutChildrenOrChild } from '$lib/utils.js';
|
||||
import GripVertical from 'lucide-svelte/icons/grip-vertical';
|
||||
import * as ResizablePrimitive from 'paneforge';
|
||||
import type { WithoutChildrenOrChild } from 'bits-ui';
|
||||
import { cn } from '$lib/utils.js';
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
@@ -17,7 +16,7 @@
|
||||
<ResizablePrimitive.PaneResizer
|
||||
bind:ref
|
||||
class={cn(
|
||||
'relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[direction=vertical]:h-px data-[direction=vertical]:w-full data-[direction=vertical]:after:left-0 data-[direction=vertical]:after:h-1 data-[direction=vertical]:after:w-full data-[direction=vertical]:after:-translate-y-1/2 data-[direction=vertical]:after:translate-x-0 [&[data-direction=vertical]>div]:rotate-90',
|
||||
'relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-none data-[direction=vertical]:h-px data-[direction=vertical]:w-full data-[direction=vertical]:after:left-0 data-[direction=vertical]:after:h-1 data-[direction=vertical]:after:w-full data-[direction=vertical]:after:translate-x-0 data-[direction=vertical]:after:-translate-y-1/2 [&[data-direction=vertical]>div]:rotate-90',
|
||||
className
|
||||
)}
|
||||
{...restProps}>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils.js';
|
||||
import { Switch as SwitchPrimitive, type WithoutChildrenOrChild } from 'bits-ui';
|
||||
import { cn, type WithoutChildrenOrChild } from '$lib/utils.js';
|
||||
import { Switch as SwitchPrimitive } from 'bits-ui';
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
@@ -14,7 +14,7 @@
|
||||
bind:ref
|
||||
bind:checked
|
||||
class={cn(
|
||||
'peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-accent data-[state=unchecked]:bg-slate-700',
|
||||
'peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-accent data-[state=unchecked]:bg-slate-700',
|
||||
className
|
||||
)}
|
||||
{...restProps}>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
bind:ref
|
||||
{sideOffset}
|
||||
class={cn(
|
||||
'z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
||||
'z-50 animate-in overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground fade-in-0 zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95',
|
||||
className
|
||||
)}
|
||||
{...restProps} />
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { addHistoryEntry } from '$lib/components/History/history';
|
||||
import type { State } from '$lib/types';
|
||||
@@ -49,7 +46,7 @@ const getGistData = async (gistURL: string): Promise<GistData> => {
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const [_, __, gistID, revisionID] = path.split('/');
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
|
||||
const { html_url, files, history }: GistResponse = await fetchJSON(
|
||||
`https://api.github.com/gists/${gistID}${revisionID ? '/' + revisionID : ''}`
|
||||
);
|
||||
@@ -65,7 +62,7 @@ const getGistData = async (gistURL: string): Promise<GistData> => {
|
||||
code,
|
||||
config,
|
||||
time: new Date(currentItem.committed_at).getTime(),
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
|
||||
url: `${html_url}/${currentItem.version}`,
|
||||
version: currentItem.version.slice(-7)
|
||||
};
|
||||
@@ -85,7 +82,9 @@ const getStateFromGist = (gist: GistData, gistURL: string = gist.url): State =>
|
||||
type: 'gist'
|
||||
}
|
||||
};
|
||||
gist.config && (state.mermaid = gist.config);
|
||||
if (gist.config) {
|
||||
state.mermaid = gist.config;
|
||||
}
|
||||
return state;
|
||||
};
|
||||
|
||||
@@ -96,7 +95,7 @@ export const loadGistData = async (gistURL: string): Promise<State> => {
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const [_, __, gistID, revisionID] = path.split('/');
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
|
||||
const { history }: GistResponse = await fetchJSON(
|
||||
`https://api.github.com/gists/${gistID}${revisionID ? '/' + revisionID : ''}`
|
||||
);
|
||||
|
||||
@@ -49,9 +49,10 @@ export const loadDataFromUrl = async (): Promise<void> => {
|
||||
}
|
||||
}
|
||||
}
|
||||
loaded &&
|
||||
if (loaded) {
|
||||
updateCodeStore({
|
||||
...state,
|
||||
updateDiagram: true
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import type * as Monaco from 'monaco-editor';
|
||||
|
||||
// eslint-disable-next-line es/no-regexp-lookbehind-assertions
|
||||
const commentRegex = /(?<!["'])%%(?![^"']*["']\)).*$/;
|
||||
|
||||
export const initEditor = (monacoEditor: typeof Monaco): void => {
|
||||
@@ -235,7 +234,6 @@ export const initEditor = (monacoEditor: typeof Monaco): void => {
|
||||
])
|
||||
)
|
||||
)
|
||||
// eslint-disable-next-line unicorn/no-array-reduce
|
||||
.reduce(
|
||||
(overallKeywords, nextKeyword) => ({
|
||||
...overallKeywords,
|
||||
|
||||
@@ -185,13 +185,11 @@ function getBrowserStorage(
|
||||
}
|
||||
};
|
||||
const connect = () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
if (listenExternalChanges && typeof window !== 'undefined' && window.addEventListener) {
|
||||
window.addEventListener('storage', listenerFunction);
|
||||
}
|
||||
};
|
||||
const disconnect = () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
if (listenExternalChanges && typeof window !== 'undefined' && window.removeEventListener) {
|
||||
window.removeEventListener('storage', listenerFunction);
|
||||
}
|
||||
@@ -231,7 +229,6 @@ function getBrowserStorage(
|
||||
* @param listenExternalChanges - Update the store if the localStorage is updated from another page
|
||||
*/
|
||||
export function localStorage<T>(listenExternalChanges = false): StorageInterface<T> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
if (typeof window !== 'undefined' && window.localStorage) {
|
||||
return getBrowserStorage(window.localStorage, listenExternalChanges);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { deflate, inflate } from 'pako';
|
||||
import { toUint8Array, fromUint8Array, toBase64, fromBase64 } from 'js-base64';
|
||||
import type { State } from '$lib/types';
|
||||
import { fromBase64, fromUint8Array, toBase64, toUint8Array } from 'js-base64';
|
||||
import { deflate, inflate } from 'pako';
|
||||
|
||||
interface Serde {
|
||||
serialize: (state: string) => string;
|
||||
@@ -30,7 +30,7 @@ export const pakoSerde: Serde = {
|
||||
|
||||
export type SerdeType = 'base64' | 'pako';
|
||||
|
||||
const serdes: { [key in SerdeType]: Serde } = {
|
||||
const serdes: Record<SerdeType, Serde> = {
|
||||
base64: base64Serde,
|
||||
pako: pakoSerde
|
||||
};
|
||||
|
||||
@@ -89,7 +89,6 @@ const processState = async (state: State) => {
|
||||
|
||||
let first_line: number, last_line: number, first_column: number, last_column: number;
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
({ first_line, last_line, first_column, last_column } = (error.hash as ErrorHash).loc);
|
||||
} catch {
|
||||
const lineNo = findMostRelevantLineNumber(errorString, state.code);
|
||||
|
||||
@@ -4,3 +4,10 @@ import { twMerge } from 'tailwind-merge';
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export type WithoutChild<T> = T extends { child?: any } ? Omit<T, 'child'> : T;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export type WithoutChildren<T> = T extends { children?: any } ? Omit<T, 'children'> : T;
|
||||
export type WithoutChildrenOrChild<T> = WithoutChildren<WithoutChild<T>>;
|
||||
export type WithElementRef<T, U extends HTMLElement = HTMLElement> = T & { ref?: U | null };
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { base } from '$app/paths';
|
||||
import { mode, ModeWatcher } from 'mode-watcher';
|
||||
import { onMount, type Snippet } from 'svelte';
|
||||
import '../app.postcss';
|
||||
import '../app.css';
|
||||
|
||||
interface Props {
|
||||
children: Snippet;
|
||||
@@ -20,11 +20,10 @@
|
||||
window.addEventListener('hashchange', () => {
|
||||
void initHandler();
|
||||
});
|
||||
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker
|
||||
.register(`${base}/service-worker.js`, {
|
||||
scope: `${base}/`
|
||||
})
|
||||
.register(`${base}/service-worker.js`, { scope: `${base}/` })
|
||||
.then(function (registration) {
|
||||
console.log('Registration successful, scope is:', registration.scope);
|
||||
})
|
||||
@@ -48,7 +47,7 @@
|
||||
|
||||
{#if $loadingStateStore.loading}
|
||||
<div
|
||||
class="absolute left-0 top-0 z-50 flex h-screen w-screen justify-center bg-gray-600 align-middle opacity-50">
|
||||
class="absolute top-0 left-0 z-50 flex h-screen w-screen justify-center bg-gray-600 align-middle opacity-50">
|
||||
<div class="my-auto text-4xl font-bold text-indigo-100">
|
||||
<div class="loader mx-auto"></div>
|
||||
<div>{$loadingStateStore.message}</div>
|
||||
|
||||
@@ -131,8 +131,8 @@
|
||||
<Resizable.Handle class="mr-1 hidden opacity-0 sm:block" />
|
||||
<Resizable.Pane minSize={15} class="relative flex h-full flex-1 flex-col overflow-hidden">
|
||||
<View {panZoomState} shouldShowGrid={$stateStore.grid} />
|
||||
<div class="absolute right-0 top-0"><PanZoomToolbar {panZoomState} /></div>
|
||||
<div class="absolute bottom-0 right-0"><VersionSecurityToolbar /></div>
|
||||
<div class="absolute top-0 right-0"><PanZoomToolbar {panZoomState} /></div>
|
||||
<div class="absolute right-0 bottom-0"><VersionSecurityToolbar /></div>
|
||||
<div class="absolute bottom-0 left-0 sm:left-5"><SyncRoughToolbar /></div>
|
||||
</Resizable.Pane>
|
||||
{#if isHistoryOpen}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg viewBox="40 40 410 410" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<path d="M407.48,111.18C335.587,108.103 269.573,152.338 245.08,220C220.587,152.338 154.573,108.103 82.68,111.18C80.285,168.229 107.577,222.632 154.74,254.82C178.908,271.419 193.35,298.951 193.27,328.27L193.27,379.13L296.9,379.13L296.9,328.27C296.816,298.953 311.255,271.42 335.42,254.82C382.596,222.644 409.892,168.233 407.48,111.18Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 689 B |
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg viewBox="0 0 490 490" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<path d="M490.16,84.61C490.16,37.912 452.248,0 405.55,0L84.61,0C37.912,0 0,37.912 0,84.61L0,405.55C0,452.248 37.912,490.16 84.61,490.16L405.55,490.16C452.248,490.16 490.16,452.248 490.16,405.55L490.16,84.61Z" style="fill:#ff3670;"/>
|
||||
<path d="M407.48,111.18C335.587,108.103 269.573,152.338 245.08,220C220.587,152.338 154.573,108.103 82.68,111.18C80.285,168.229 107.577,222.632 154.74,254.82C178.908,271.419 193.35,298.951 193.27,328.27L193.27,379.13L296.9,379.13L296.9,328.27C296.816,298.953 311.255,271.42 335.42,254.82C382.596,222.644 409.892,168.233 407.48,111.18Z" style="fill:white;fill-rule:nonzero;"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 942 B |
+1
-5
@@ -5,11 +5,7 @@ import { sveltePreprocess } from 'svelte-preprocess';
|
||||
const config = {
|
||||
// Consult https://github.com/sveltejs/svelte-preprocess
|
||||
// for more information about preprocessors
|
||||
preprocess: [
|
||||
sveltePreprocess({
|
||||
postcss: true
|
||||
})
|
||||
],
|
||||
preprocess: [sveltePreprocess({})],
|
||||
kit: {
|
||||
alias: {
|
||||
'$/*': './src/lib/*'
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
import tailwindcssAnimate from 'tailwindcss-animate';
|
||||
import { fontFamily } from 'tailwindcss/defaultTheme';
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
const config = {
|
||||
darkMode: ['class'],
|
||||
content: ['./src/**/*.{html,js,svelte,ts}'],
|
||||
safelist: ['dark'],
|
||||
theme: {
|
||||
container: {
|
||||
center: true,
|
||||
padding: '2rem',
|
||||
screens: {
|
||||
'2xl': '1400px'
|
||||
}
|
||||
},
|
||||
extend: {
|
||||
colors: {
|
||||
border: 'hsl(var(--border) / <alpha-value>)',
|
||||
input: 'hsl(var(--input) / <alpha-value>)',
|
||||
ring: 'hsl(var(--ring) / <alpha-value>)',
|
||||
background: 'hsl(var(--background) / <alpha-value>)',
|
||||
foreground: 'hsl(var(--foreground) / <alpha-value>)',
|
||||
primary: {
|
||||
DEFAULT: 'hsl(var(--primary) / <alpha-value>)',
|
||||
foreground: 'hsl(var(--primary-foreground) / <alpha-value>)'
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: 'hsl(var(--secondary) / <alpha-value>)',
|
||||
foreground: 'hsl(var(--secondary-foreground) / <alpha-value>)'
|
||||
},
|
||||
destructive: {
|
||||
DEFAULT: 'hsl(var(--destructive) / <alpha-value>)',
|
||||
foreground: 'hsl(var(--destructive-foreground) / <alpha-value>)'
|
||||
},
|
||||
muted: {
|
||||
DEFAULT: 'hsl(var(--muted) / <alpha-value>)',
|
||||
foreground: 'hsl(var(--muted-foreground) / <alpha-value>)'
|
||||
},
|
||||
accent: {
|
||||
DEFAULT: 'hsl(var(--accent) / <alpha-value>)',
|
||||
foreground: 'hsl(var(--accent-foreground) / <alpha-value>)'
|
||||
},
|
||||
popover: {
|
||||
DEFAULT: 'hsl(var(--popover) / <alpha-value>)',
|
||||
foreground: 'hsl(var(--popover-foreground) / <alpha-value>)'
|
||||
},
|
||||
card: {
|
||||
DEFAULT: 'hsl(var(--card) / <alpha-value>)',
|
||||
foreground: 'hsl(var(--card-foreground) / <alpha-value>)'
|
||||
},
|
||||
sidebar: {
|
||||
DEFAULT: 'hsl(var(--sidebar-background))',
|
||||
foreground: 'hsl(var(--sidebar-foreground))',
|
||||
primary: 'hsl(var(--sidebar-primary))',
|
||||
'primary-foreground': 'hsl(var(--sidebar-primary-foreground))',
|
||||
accent: 'hsl(var(--sidebar-accent))',
|
||||
'accent-foreground': 'hsl(var(--sidebar-accent-foreground))',
|
||||
border: 'hsl(var(--sidebar-border))',
|
||||
ring: 'hsl(var(--sidebar-ring))'
|
||||
}
|
||||
},
|
||||
borderRadius: {
|
||||
xl: 'calc(var(--radius) + 4px)',
|
||||
lg: 'var(--radius)',
|
||||
md: 'calc(var(--radius) - 2px)',
|
||||
sm: 'calc(var(--radius) - 4px)'
|
||||
},
|
||||
fontFamily: {
|
||||
sans: [...fontFamily.sans]
|
||||
},
|
||||
keyframes: {
|
||||
'accordion-down': {
|
||||
from: { height: '0' },
|
||||
to: { height: 'var(--bits-accordion-content-height)' }
|
||||
},
|
||||
'accordion-up': {
|
||||
from: { height: 'var(--bits-accordion-content-height)' },
|
||||
to: { height: '0' }
|
||||
},
|
||||
'caret-blink': {
|
||||
'0%,70%,100%': { opacity: '1' },
|
||||
'20%,50%': { opacity: '0' }
|
||||
}
|
||||
},
|
||||
animation: {
|
||||
'accordion-down': 'accordion-down 0.2s ease-out',
|
||||
'accordion-up': 'accordion-up 0.2s ease-out',
|
||||
'caret-blink': 'caret-blink 1.25s ease-out infinite'
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [tailwindcssAnimate]
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -17,6 +17,7 @@ export class EditorPage {
|
||||
await this.page.goto(url);
|
||||
await expect(this.page)
|
||||
.toHaveURL(/.*\/edit#pako/)
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
|
||||
+3
-5
@@ -8,12 +8,10 @@ export interface EditorOptions {
|
||||
newline?: boolean;
|
||||
}
|
||||
|
||||
interface WindowWithEditor {
|
||||
editorLoaded: boolean;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window extends WindowWithEditor {}
|
||||
interface Window {
|
||||
editorLoaded: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
export async function typeInEditor(
|
||||
|
||||
+12
-14
@@ -1,7 +1,9 @@
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import { FileSystemIconLoader } from 'unplugin-icons/loaders';
|
||||
import Icons from 'unplugin-icons/vite';
|
||||
import { defineConfig } from 'vitest/config';
|
||||
import { defineConfig } from 'vite';
|
||||
import devtoolsJson from 'vite-plugin-devtools-json';
|
||||
|
||||
/**
|
||||
* HMR creates state inconsistencies, so we always reload the page.
|
||||
@@ -17,6 +19,7 @@ const alwaysFullReload = {
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
tailwindcss(),
|
||||
sveltekit(),
|
||||
Icons({
|
||||
compiler: 'svelte',
|
||||
@@ -24,17 +27,12 @@ export default defineConfig({
|
||||
custom: FileSystemIconLoader('./static/icons')
|
||||
}
|
||||
}),
|
||||
alwaysFullReload
|
||||
alwaysFullReload,
|
||||
devtoolsJson()
|
||||
],
|
||||
envPrefix: 'MERMAID_',
|
||||
server: {
|
||||
port: 3000,
|
||||
host: true
|
||||
},
|
||||
preview: {
|
||||
port: 3000,
|
||||
host: true
|
||||
},
|
||||
server: { port: 3000, host: true },
|
||||
preview: { port: 3000, host: true },
|
||||
test: {
|
||||
environment: 'jsdom',
|
||||
// in-source testing
|
||||
@@ -42,10 +40,10 @@ export default defineConfig({
|
||||
// Ignore E2E tests
|
||||
exclude: [
|
||||
'tests/**/*',
|
||||
'**\/node_modules/**',
|
||||
'**\/dist/**',
|
||||
'**\/.{idea,git,cache,output,temp}/**',
|
||||
'**\/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*'
|
||||
'**/node_modules/**',
|
||||
'**/dist/**',
|
||||
'**/.{idea,git,cache,output,temp}/**',
|
||||
'**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*'
|
||||
],
|
||||
setupFiles: ['./src/tests/setup.ts'],
|
||||
coverage: {
|
||||
|
||||
Reference in New Issue
Block a user