mirror of
https://github.com/ueberdosis/tiptap.git
synced 2025-08-06 13:38:49 +08:00
chore(demos): added svelte default demo
This commit is contained in:
parent
8e65c20815
commit
e0b13a5125
1989
demos/package-lock.json
generated
1989
demos/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -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",
|
||||
|
@ -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
21
demos/setup/svelte.ts
Normal 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()
|
||||
})
|
||||
}
|
0
demos/src/Examples/Default/Svelte/index.html
Normal file
0
demos/src/Examples/Default/Svelte/index.html
Normal file
117
demos/src/Examples/Default/Svelte/index.spec.js
Normal file
117
demos/src/Examples/Default/Svelte/index.spec.js
Normal 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')
|
||||
})
|
||||
})
|
158
demos/src/Examples/Default/Svelte/index.svelte
Normal file
158
demos/src/Examples/Default/Svelte/index.svelte
Normal 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 you’d probably expect from a text editor. But wait until you see the lists:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
That’s a bullet list with one …
|
||||
</li>
|
||||
<li>
|
||||
… or two list items.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Isn’t that great? And all of that is editable. But wait, there’s more. Let’s try a code block:
|
||||
</p>
|
||||
<pre><code class="language-css">body {
|
||||
display: none;
|
||||
}</code></pre>
|
||||
<p>
|
||||
I know, I know, this is impressive. It’s only the tip of the iceberg though. Give it a try and click a little bit around. Don’t forget to check the other examples too.
|
||||
</p>
|
||||
<blockquote>
|
||||
Wow, that’s 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} />
|
56
demos/src/Examples/Default/Svelte/styles.scss
Normal file
56
demos/src/Examples/Default/Svelte/styles.scss
Normal 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;
|
||||
}
|
||||
}
|
@ -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: `
|
||||
|
Loading…
Reference in New Issue
Block a user