chore(demos): added svelte default demo

This commit is contained in:
Dominik Biedebach 2022-06-24 18:31:39 +02:00
parent 8e65c20815
commit e0b13a5125
9 changed files with 1719 additions and 671 deletions

1989
demos/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -11,15 +11,16 @@
"@hocuspocus/provider": "^1.0.0-alpha.29",
"d3": "^7.3.0",
"fast-glob": "^3.2.11",
"lowlight": "^1.20.0",
"remixicon": "^2.5.0",
"shiki": "^0.10.0",
"simplify-js": "^1.2.4",
"y-webrtc": "10.2.2",
"yjs": "13.5.26",
"y-prosemirror": "1.0.20",
"lowlight": "^1.20.0"
"y-webrtc": "10.2.2",
"yjs": "13.5.26"
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.49",
"@types/uuid": "^8.3.4",
"@vitejs/plugin-react": "^1.3.1",
"@vitejs/plugin-vue": "^1.10.2",
@ -29,6 +30,7 @@
"react": "^18.0.0",
"react-dom": "^18.0.0",
"sass": "^1.49.7",
"svelte": "^3.48.0",
"tailwindcss": "^2.2.19",
"typescript": "^4.5.5",
"uuid": "^8.3.2",

View File

@ -10,7 +10,7 @@
v-for="(language, index) in sortedTabs"
:key="index"
@click="setTab(language.name)"
class="px-4 py-2 rounded-t-lg text-xs uppercase font-bold tracking-wide"
class="px-4 py-2 text-xs font-bold tracking-wide uppercase rounded-t-lg"
:class="[currentTab === language.name
? 'bg-black text-white'
: 'text-black'
@ -21,7 +21,7 @@
</div>
<div class="overflow-hidden rounded-b-xl">
<div
class="bg-white border-3 border-black last:rounded-b-xl"
class="bg-white border-black border-3 last:rounded-b-xl"
:class="[
showTabs && firstTabSelected
? 'rounded-tr-xl'
@ -34,7 +34,7 @@
/>
</div>
<div class="bg-black text-white" v-if="!hideSource && currentFile">
<div class="text-white bg-black" v-if="!hideSource && currentFile">
<div class="flex overflow-x-auto">
<div class="flex flex-auto px-4 border-b-2 border-gray-800">
<button
@ -66,17 +66,17 @@
<div class="overflow-dark overflow-auto max-h-[500px] relative text-white">
<shiki
class="overflow-visible p-4"
class="p-4 overflow-visible"
:language="debugJSON && showDebug ? 'js' : getFileExtension(currentFile.name)"
:code="debugJSON && showDebug ? debugJSON : currentFile.content"
/>
</div>
<div class="flex justify-between px-4 py-2 text-md text-gray-400 border-t border-gray-800">
<a class="flex-shrink min-w-0 overflow-ellipsis overflow-hidden whitespace-nowrap" :href="currentIframeUrl">
<div class="flex justify-between px-4 py-2 text-gray-400 border-t border-gray-800 text-md">
<a class="flex-shrink min-w-0 overflow-hidden overflow-ellipsis whitespace-nowrap" :href="currentIframeUrl">
{{ name }}/{{ currentTab }}
</a>
<a class="whitespace-nowrap pl-4" :href="githubUrl" target="_blank">
<a class="pl-4 whitespace-nowrap" :href="githubUrl" target="_blank">
Edit on GitHub
</a>
</div>
@ -115,7 +115,7 @@ export default {
sources: {},
currentTab: null,
currentFile: null,
tabOrder: ['React', 'Vue', 'JS'],
tabOrder: ['React', 'Vue', 'Svelte', 'JS'],
debugJSON: null,
showDebug: false,
}

21
demos/setup/svelte.ts Normal file
View File

@ -0,0 +1,21 @@
import 'iframe-resizer/js/iframeResizer.contentWindow'
import './style.scss'
import { debug, splitName } from './helper'
export default function init(name: string, source: any) {
// @ts-ignore
window.source = source
document.title = name
const [demoCategory, demoName] = splitName(name)
import(`../src/${demoCategory}/${demoName}/Svelte/index.svelte`)
.then(Module => {
const Component = Module.default
new Component({ target: document.querySelector('#app') }) // eslint-disable-line
debug()
})
}

View File

@ -0,0 +1,117 @@
context('/src/Examples/Default/React/', () => {
before(() => {
cy.visit('/src/Examples/Default/React/')
})
beforeEach(() => {
cy.get('.ProseMirror').then(([{ editor }]) => {
editor.commands.setContent('<h1>Example Text</h1>')
cy.get('.ProseMirror').type('{selectall}')
})
})
it('should apply the paragraph style when the keyboard shortcut is pressed', () => {
cy.get('.ProseMirror h1').should('exist')
cy.get('.ProseMirror p').should('not.exist')
cy.get('.ProseMirror')
.trigger('keydown', { modKey: true, altKey: true, key: '0' })
.find('p')
.should('contain', 'Example Text')
})
const buttonMarks = [
{ label: 'bold', tag: 'strong' },
{ label: 'italic', tag: 'em' },
{ label: 'strike', tag: 's' },
]
buttonMarks.forEach(m => {
it(`should apply ${m.label} when the button is pressed`, () => {
cy.get('.ProseMirror').type('{selectall}Hello world')
cy.get('button').contains('paragraph').click()
cy.get('.ProseMirror').type('{selectall}')
cy.get('button').contains(m.label).click()
cy.get(`.ProseMirror ${m.tag}`).should('exist').should('have.text', 'Hello world')
})
})
it('should clear marks when the button is pressed', () => {
cy.get('.ProseMirror').type('{selectall}Hello world')
cy.get('button').contains('paragraph').click()
cy.get('.ProseMirror').type('{selectall}')
cy.get('button').contains('bold').click()
cy.get('.ProseMirror strong').should('exist').should('have.text', 'Hello world')
cy.get('button').contains('clear marks').click()
cy.get('.ProseMirror strong').should('not.exist')
})
it('should clear nodes when the button is pressed', () => {
cy.get('.ProseMirror').type('{selectall}Hello world')
cy.get('button').contains('bullet list').click()
cy.get('.ProseMirror ul').should('exist').should('have.text', 'Hello world')
cy.get('.ProseMirror').type('{enter}A second item{enter}A third item{selectall}')
cy.get('button').contains('clear nodes').click()
cy.get('.ProseMirror ul').should('not.exist')
cy.get('.ProseMirror p').should('have.length', 3)
})
const buttonNodes = [
{ label: 'h1', tag: 'h1' },
{ label: 'h2', tag: 'h2' },
{ label: 'h3', tag: 'h3' },
{ label: 'h4', tag: 'h4' },
{ label: 'h5', tag: 'h5' },
{ label: 'h6', tag: 'h6' },
{ label: 'bullet list', tag: 'ul' },
{ label: 'ordered list', tag: 'ol' },
{ label: 'code block', tag: 'pre code' },
{ label: 'blockquote', tag: 'blockquote' },
]
buttonNodes.forEach(n => {
it(`should set ${n.label} when the button is pressed`, () => {
cy.get('button').contains('paragraph').click()
cy.get('.ProseMirror').type('{selectall}Hello world{selectall}')
cy.get('button').contains(n.label).click()
cy.get(`.ProseMirror ${n.tag}`).should('exist').should('have.text', 'Hello world')
cy.get('button').contains(n.label).click()
cy.get(`.ProseMirror ${n.tag}`).should('not.exist')
})
})
it('should add a hr when on the same line as a node', () => {
cy.get('.ProseMirror').type('{rightArrow}')
cy.get('button').contains('horizontal rule').click()
cy.get('.ProseMirror hr').should('exist')
cy.get('.ProseMirror h1').should('exist')
})
it('should add a hr when on a new line', () => {
cy.get('.ProseMirror').type('{rightArrow}{enter}')
cy.get('button').contains('horizontal rule').click()
cy.get('.ProseMirror hr').should('exist')
cy.get('.ProseMirror h1').should('exist')
})
it('should add a br', () => {
cy.get('.ProseMirror').type('{rightArrow}')
cy.get('button').contains('hard break').click()
cy.get('.ProseMirror h1 br').should('exist')
})
it('should undo', () => {
cy.get('.ProseMirror').type('{selectall}{backspace}')
cy.get('button').contains('undo').click()
cy.get('.ProseMirror').should('contain', 'Hello world')
})
it('should redo', () => {
cy.get('.ProseMirror').type('{selectall}{backspace}')
cy.get('button').contains('undo').click()
cy.get('.ProseMirror').should('contain', 'Hello world')
cy.get('button').contains('redo').click()
cy.get('.ProseMirror').should('not.contain', 'Hello world')
})
})

View File

@ -0,0 +1,158 @@
<script>
import "./styles.scss";
import StarterKit from "@tiptap/starter-kit";
import { Editor } from "@tiptap/core";
import { onMount } from "svelte";
let element;
let editor;
onMount(() => {
console.log({ element });
editor = new Editor({
element: element,
extensions: [StarterKit],
content: `
<h2>
Hi there,
</h2>
<p>
this is a <em>basic</em> example of <strong>tiptap</strong>. Sure, there are all kind of basic text styles youd probably expect from a text editor. But wait until you see the lists:
</p>
<ul>
<li>
Thats a bullet list with one …
</li>
<li>
… or two list items.
</li>
</ul>
<p>
Isnt that great? And all of that is editable. But wait, theres more. Lets try a code block:
</p>
<pre><code class="language-css">body {
display: none;
}</code></pre>
<p>
I know, I know, this is impressive. Its only the tip of the iceberg though. Give it a try and click a little bit around. Dont forget to check the other examples too.
</p>
<blockquote>
Wow, thats amazing. Good work, boy! 👏
<br />
— Mom
</blockquote>
`,
onTransaction: () => {
// force re-render so `editor.isActive` works as expected
editor = editor;
},
});
});
</script>
{#if editor}
<div>
<div>
<button
on:click={() => console.log && editor.chain().focus().toggleBold().run()}
class={editor.isActive("bold") ? "is-active" : ""}
>
bold
</button>
<button
on:click={() => editor.chain().focus().toggleItalic().run()}
class={editor.isActive("italic") ? "is-active" : ""}
>
italic
</button>
<button
on:click={() => editor.chain().focus().toggleStrike().run()}
class={editor.isActive("strike") ? "is-active" : ""}
>
strike
</button>
<button
on:click={() => editor.chain().focus().toggleCode().run()}
class={editor.isActive("code") ? "is-active" : ""}
>
code
</button>
<button on:click={() => editor.chain().focus().unsetAllMarks().run()}> clear marks </button>
<button on:click={() => editor.chain().focus().clearNodes().run()}> clear nodes </button>
<button
on:click={() => editor.chain().focus().setParagraph().run()}
class={editor.isActive("paragraph") ? "is-active" : ""}
>
paragraph
</button>
<button
on:click={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}
class={editor.isActive("heading", { level: 1 }) ? "is-active" : ""}
>
h1
</button>
<button
on:click={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}
class={editor.isActive("heading", { level: 2 }) ? "is-active" : ""}
>
h2
</button>
<button
on:click={() => editor.chain().focus().toggleHeading({ level: 3 }).run()}
class={editor.isActive("heading", { level: 3 }) ? "is-active" : ""}
>
h3
</button>
<button
on:click={() => editor.chain().focus().toggleHeading({ level: 4 }).run()}
class={editor.isActive("heading", { level: 4 }) ? "is-active" : ""}
>
h4
</button>
<button
on:click={() => editor.chain().focus().toggleHeading({ level: 5 }).run()}
class={editor.isActive("heading", { level: 5 }) ? "is-active" : ""}
>
h5
</button>
<button
on:click={() => editor.chain().focus().toggleHeading({ level: 6 }).run()}
class={editor.isActive("heading", { level: 6 }) ? "is-active" : ""}
>
h6
</button>
<button
on:click={() => editor.chain().focus().toggleBulletList().run()}
class={editor.isActive("bulletList") ? "is-active" : ""}
>
bullet list
</button>
<button
on:click={() => editor.chain().focus().toggleOrderedList().run()}
class={editor.isActive("orderedList") ? "is-active" : ""}
>
ordered list
</button>
<button
on:click={() => editor.chain().focus().toggleCodeBlock().run()}
class={editor.isActive("codeBlock") ? "is-active" : ""}
>
code block
</button>
<button
on:click={() => editor.chain().focus().toggleBlockquote().run()}
class={editor.isActive("blockquote") ? "is-active" : ""}
>
blockquote
</button>
<button on:click={() => editor.chain().focus().setHorizontalRule().run()}>
horizontal rule
</button>
<button on:click={() => editor.chain().focus().setHardBreak().run()}> hard break </button>
<button on:click={() => editor.chain().focus().undo().run()}> undo </button>
<button on:click={() => editor.chain().focus().redo().run()}> redo </button>
</div>
</div>
{/if}
<div bind:this={element} />

View File

@ -0,0 +1,56 @@
/* Basic editor styles */
.ProseMirror {
> * + * {
margin-top: 0.75em;
}
ul,
ol {
padding: 0 1rem;
}
h1,
h2,
h3,
h4,
h5,
h6 {
line-height: 1.1;
}
code {
background-color: rgba(#616161, 0.1);
color: #616161;
}
pre {
background: #0D0D0D;
color: #FFF;
font-family: 'JetBrainsMono', monospace;
padding: 0.75rem 1rem;
border-radius: 0.5rem;
code {
color: inherit;
padding: 0;
background: none;
font-size: 0.8rem;
}
}
img {
max-width: 100%;
height: auto;
}
blockquote {
padding-left: 1rem;
border-left: 2px solid rgba(#0D0D0D, 0.1);
}
hr {
border: none;
border-top: 2px solid rgba(#0D0D0D, 0.1);
margin: 2rem 0;
}
}

View File

@ -1,3 +1,4 @@
import { svelte } from '@sveltejs/vite-plugin-svelte'
import react from '@vitejs/plugin-react'
import vue from '@vitejs/plugin-vue'
import fg from 'fast-glob'
@ -38,6 +39,7 @@ export default defineConfig({
// checker({ typescript: { tsconfigPath: './tsconfig.vue-3.json' } }),
vue(),
react(),
svelte(),
{
name: 'html-transform',
@ -95,6 +97,29 @@ export default defineConfig({
}
}
if (dir.endsWith('/Svelte')) {
return {
html: `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<div id="app"></div>
<script type="module">
import setup from '../../../../setup/svelte.ts'
import source from '@source'
setup('${demoCategory}/${demoName}', source)
</script>
</body>
</html>
`,
tags: [],
}
}
if (dir.endsWith('/React')) {
return {
html: `