Merge branch 'main' of github.com:ueberdosis/tiptap-next into main

This commit is contained in:
Hans Pagel 2021-02-04 11:37:22 +01:00
commit c64977add9
91 changed files with 2209 additions and 2247 deletions

View File

@ -44,7 +44,6 @@ module.exports = {
typeName: 'DocPage',
baseDir: './src/docPages',
template: './src/templates/DocPage/index.vue',
index: './introduction',
plugins: [
'@gridsome/remark-prismjs',
'remark-container',
@ -61,18 +60,6 @@ module.exports = {
},
},
},
{
use: 'gridsome-plugin-simple-analytics',
options: {
domain: 'data.next.tiptap.dev',
},
},
{
use: 'gridsome-plugin-plausible-analytics',
options: {
dataDomain: 'next.tiptap.dev',
},
},
],
runtimeCompiler: true,
configureWebpack: {

View File

@ -40,69 +40,19 @@ const calculateReadingTime = function (text) {
}
}
// const TypeDoc = require('typedoc')
// const packages = globby.sync('../packages/*', { onlyDirectories: true })
// .map(name => name.replace('../packages/', ''))
// .filter(name => name.startsWith('core'))
// .map(name => {
// const app = new TypeDoc.Application()
// app.options.addReader(new TypeDoc.TSConfigReader())
// app.options.addReader(new TypeDoc.TypeDocReader())
// app.bootstrap({
// mode: 'file',
// ignoreCompilerErrors: true,
// experimentalDecorators: true,
// excludeExternals: true,
// excludeNotExported: true,
// excludeProtected: true,
// excludePrivate: true,
// // excludeNotDocumented: true,
// exclude: [
// '**/*.test.ts',
// '**/__tests__/*',
// '**/__mocks__/*',
// ],
// })
// const project = app.convert(app.expandInputFiles([`../packages/${name}`]))
// if (project) {
// // app.generateDocs(project, `api/${name}`)
// // app.generateJson(project, `api/${name}.json`)
// const json = app.serializer.projectToObject(project)
// return json
// }
// return null
// })
// .filter(package => !!package)
// const packages = globby.sync('../packages/*', { onlyDirectories: true })
// .map(name => name.replace('../packages/', ''))
// .map(name => {
// // config.resolve.alias
// // .set(`@tiptap/${name}`, path.resolve(`../packages/${name}/index.ts`))
// return {
// name: `@tiptap/${name}`,
// module: require(`../packages/${name}/index.ts`),
// }
// })
module.exports = function (api) {
api.setClientOptions({
cwd: process.cwd(),
})
api.loadSource(({ addCollection }) => {
api.loadSource(() => {
/**
* Generate pages for all demo components for testing purposes
*/
globby.sync('./src/demos/**/index.vue').forEach(file => {
globby.sync('./src/demos/**/index.(vue|jsx)').forEach(file => {
const match = file.match(
new RegExp(/\.\/src\/demos\/([\S]+)\/index.vue/i),
new RegExp(/\.\/src\/demos\/([\S]+)\/index.(vue|jsx)/i),
)
if (!match) {
@ -121,42 +71,8 @@ module.exports = function (api) {
})
})
})
/**
* Read out all packages?
*/
const appCollection = addCollection({ typeName: 'Package' })
// packages.forEach(package => {
// appCollection.addNode(package)
// })
globby.sync('../packages/*', { onlyDirectories: true })
.map(name => name.replace('../packages/', ''))
.forEach(name => {
appCollection.addNode({ name })
// config.resolve.alias
// .set(`@tiptap/${name}`, path.resolve(`../packages/${name}/index.ts`))
// appCollection.addNode({
// name: `@tiptap/${name}`,
// module: require(`../packages/${name}/index.ts`),
// })
})
})
// api.createPages(({ createPage }) => {
// packages.forEach(package => {
// createPage({
// path: `/api/${package.name}`,
// component: './src/templates/ApiPage/index.vue',
// context: {
// package,
// },
// })
// })
// })
api.chainWebpack(config => {
config.resolve.extensions
.add('.ts')

View File

@ -17,8 +17,7 @@
"d3": "^6.5.0",
"globby": "^11.0.0",
"gridsome": "0.7.23",
"gridsome-plugin-plausible-analytics": "^1.0.0",
"gridsome-plugin-simple-analytics": "^1.1.0",
"iframe-resizer": "^4.3.1",
"portal-vue": "^2.1.7",
"raw-loader": "^4.0.2",
"react": "^17.0.1",
@ -29,7 +28,6 @@
"simplify-js": "^1.2.4",
"tippy.js": "^6.2.7",
"vue-github-button": "^1.1.2",
"vue-live": "^1.16.0",
"y-indexeddb": "^9.0.6",
"y-prosemirror": "^1.0.5",
"y-webrtc": "^10.1.7",

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,17 @@
<svg width="102" height="28" viewBox="0 0 102 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M41.1627 9.44277H38.8001V6.43427H35.3174V9.44277H33.6006V12.0589H35.3174V18.5991C35.3011 21.0598 36.977 22.278 39.5032 22.1717C40.4024 22.139 41.0401 21.9591 41.3917 21.8447L40.8439 19.2531C40.6722 19.2858 40.3043 19.3676 39.9773 19.3676C39.2824 19.3676 38.8001 19.106 38.8001 18.1413V12.0589H41.1627V9.44277ZM43.4314 22H46.9141V9.44277H43.4314V22ZM45.1809 7.82407C46.2192 7.82407 47.0694 7.03107 47.0694 6.05821C47.0694 5.09352 46.2192 4.30052 45.1809 4.30052C44.1508 4.30052 43.3006 5.09352 43.3006 6.05821C43.3006 7.03107 44.1508 7.82407 45.1809 7.82407ZM49.7039 26.709H53.1865V19.9889H53.2928C53.7752 21.0353 54.8298 22.2044 56.8572 22.2044C59.7186 22.2044 61.9504 19.9398 61.9504 15.7377C61.9504 11.4212 59.6205 9.27927 56.8654 9.27927C54.7644 9.27927 53.7588 10.5301 53.2928 11.552H53.1375V9.44277H49.7039V26.709ZM53.113 15.7214C53.113 13.4814 54.0613 12.0507 55.7536 12.0507C57.4786 12.0507 58.3942 13.5468 58.3942 15.7214C58.3942 17.9124 57.4622 19.433 55.7536 19.433C54.0776 19.433 53.113 17.9614 53.113 15.7214ZM70.9514 9.44277H68.5888V6.43427H65.1061V9.44277H63.3893V12.0589H65.1061V18.5991C65.0897 21.0598 66.7657 22.278 69.2918 22.1717C70.1911 22.139 70.8288 21.9591 71.1803 21.8447L70.6326 19.2531C70.4609 19.2858 70.093 19.3676 69.766 19.3676C69.0711 19.3676 68.5888 19.106 68.5888 18.1413V12.0589H70.9514V9.44277ZM77.7124 22.2044C79.7398 22.2044 80.7945 21.0353 81.2768 19.9889H81.424V22H84.8576V9.44277H81.3831V11.552H81.2768C80.8108 10.5301 79.8052 9.27927 77.7042 9.27927C74.9491 9.27927 72.6192 11.4212 72.6192 15.7377C72.6192 19.9398 74.851 22.2044 77.7124 22.2044ZM78.816 19.433C77.1074 19.433 76.1754 17.9124 76.1754 15.7214C76.1754 13.5468 77.0911 12.0507 78.816 12.0507C80.5083 12.0507 81.4567 13.4814 81.4567 15.7214C81.4567 17.9614 80.492 19.433 78.816 19.433ZM87.721 26.709H91.2036V19.9889H91.3099C91.7922 21.0353 92.8469 22.2044 94.8743 22.2044C97.7357 22.2044 99.9675 19.9398 99.9675 15.7377C99.9675 11.4212 97.6376 9.27927 94.8825 9.27927C92.7815 9.27927 91.7759 10.5301 91.3099 11.552H91.1546V9.44277H87.721V26.709ZM91.1301 15.7214C91.1301 13.4814 92.0784 12.0507 93.7707 12.0507C95.4956 12.0507 96.4113 13.5468 96.4113 15.7214C96.4113 17.9124 95.4793 19.433 93.7707 19.433C92.0947 19.433 91.1301 17.9614 91.1301 15.7214Z" fill="black"/>
<mask id="mask0" mask-type="alpha" maskUnits="userSpaceOnUse" x="0" y="2" width="25" height="25">
<circle cx="12.2302" cy="14.3884" r="12.2302" fill="#C4C4C4"/>
</mask>
<g mask="url(#mask0)">
<line x1="-8.63232" y1="2.87774" x2="34.5331" y2="2.87774" stroke="black" stroke-width="1.43885"/>
<line x1="-8.63281" y1="5.75543" x2="34.5327" y2="5.75543" stroke="black" stroke-width="1.43885"/>
<line x1="-8.63281" y1="8.63311" x2="34.5327" y2="8.63311" stroke="black" stroke-width="1.43885"/>
<line x1="-8.63281" y1="11.5108" x2="34.5327" y2="11.5108" stroke="black" stroke-width="1.43885"/>
<line x1="-8.63281" y1="14.3885" x2="34.5327" y2="14.3885" stroke="black" stroke-width="1.43885"/>
<line x1="-8.63281" y1="17.2662" x2="34.5327" y2="17.2662" stroke="black" stroke-width="1.43885"/>
<line x1="-8.63281" y1="20.1439" x2="34.5327" y2="20.1439" stroke="black" stroke-width="1.43885"/>
<line x1="-8.63281" y1="23.0215" x2="34.5327" y2="23.0215" stroke="black" stroke-width="1.43885"/>
<line x1="-8.63281" y1="25.8992" x2="34.5327" y2="25.8992" stroke="black" stroke-width="1.43885"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1,6 @@
<svg width="51" height="51" viewBox="0 0 51 51" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.269 47.8341C18.3776 48.8014 16.0914 48.4496 13.7172 47.6582C11.3791 46.8655 9.34912 45.3584 7.9138 43.3496L7.65 43.0858C6.33104 41.2393 5.3638 39.1289 4.48449 33.6772L3.07759 24.5324C2.11035 18.5531 2.37414 16.2669 3.25345 13.8927C4.0737 11.5687 5.53744 9.52554 7.47414 8.00135L7.82587 7.73755C9.67242 6.41859 11.7828 5.45135 17.1466 4.57204L26.1155 3.16514C32.0069 2.1979 34.2931 2.54962 36.6672 3.341C39.0053 4.13374 41.0354 5.64089 42.4707 7.64962L42.7345 8.00135C44.0534 9.8479 45.0207 11.9582 45.9 17.41L47.3069 26.4669C48.2741 32.4462 48.0103 34.7324 47.131 37.1065C46.3394 39.4454 44.8703 41.4961 42.9103 42.9979L42.5586 43.2617C40.7121 44.5807 38.6017 45.5479 33.2379 46.4272L24.269 47.8341Z" fill="#0D0D0D"/>
<path d="M34.3019 31.5676C37.3613 31.5676 39.8415 29.0874 39.8415 26.0279C39.8415 22.9685 37.3613 20.4883 34.3019 20.4883C31.2424 20.4883 28.7622 22.9685 28.7622 26.0279C28.7622 29.0874 31.2424 31.5676 34.3019 31.5676Z" stroke="white" stroke-width="2.42" stroke-linejoin="round"/>
<path d="M22.1093 12.1554L12.1875 13.7588L13.7909 23.6806L23.7127 22.0772L22.1093 12.1554Z" stroke="white" stroke-width="2.43" stroke-linejoin="round"/>
<path d="M21.1035 28.665L28.9294 38.6892L16.8828 40.6237L21.1035 28.665Z" stroke="white" stroke-width="2.42" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,3 @@
<svg width="66" height="41" viewBox="0 0 66 41" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M52.7002 25.2398C52.3902 25.1698 52.1402 25.0898 51.9002 24.9898C51.7402 24.9098 51.6002 24.8298 51.4802 24.7198C51.4403 24.6857 51.4095 24.6423 51.3903 24.5935C51.3711 24.5447 51.3642 24.4919 51.3702 24.4398C51.4902 23.1698 51.3602 22.0398 51.4702 20.7898C51.9802 15.6698 55.2002 17.2898 58.0902 16.4598C59.7402 15.9898 61.4002 15.0698 62.0102 13.2598C62.1102 12.9598 62.0202 12.6398 61.8102 12.4098C59.947 10.2839 57.8467 8.37815 55.5502 6.72976C47.795 1.33175 38.2879 -0.939673 28.9302 0.36976C28.8512 0.379221 28.7759 0.408588 28.7113 0.455108C28.6468 0.501628 28.5951 0.563778 28.5611 0.635733C28.5271 0.707688 28.512 0.787093 28.5171 0.866504C28.5222 0.945916 28.5473 1.02273 28.5902 1.08976C29.7187 2.8468 31.2254 4.32957 33.0002 5.42976C33.3202 5.62976 33.1902 6.05976 32.8202 5.96976C31.7516 5.73488 30.7393 5.29325 29.8402 4.66976C29.7905 4.63702 29.7333 4.61714 29.674 4.6119C29.6147 4.60667 29.555 4.61624 29.5002 4.63976L27.8102 5.31976C27.7366 5.34977 27.6721 5.39834 27.6228 5.46073C27.5736 5.52312 27.5413 5.59721 27.5293 5.67576C27.5172 5.75432 27.5257 5.83467 27.5539 5.90898C27.5821 5.98329 27.6291 6.04902 27.6902 6.09976C29.9294 8.04028 32.7264 9.22035 35.6789 9.47013C38.6313 9.71992 41.5869 9.02653 44.1202 7.48976C44.4402 7.28976 44.9502 7.68976 44.8502 8.04976C44.6802 8.61976 44.4902 9.40976 44.2902 10.4798C42.9902 17.0098 39.2702 16.5098 34.6602 14.8598C25.4602 11.5198 20.2302 14.3698 15.5902 8.72976C15.2602 8.32976 14.6902 8.19976 14.3102 8.52976C13.7939 8.96913 13.3871 9.52287 13.1223 10.147C12.8574 10.7711 12.7417 11.4483 12.7844 12.125C12.8272 12.8016 13.0271 13.4589 13.3683 14.0448C13.7096 14.6306 14.1827 15.1288 14.7502 15.4998C14.9002 15.5998 15.0902 15.5598 15.2002 15.4298C15.4902 15.0598 15.7202 14.8298 16.0202 14.6698C16.3302 14.5098 16.4902 14.9698 16.2202 15.1998C15.2302 16.0698 14.9502 17.1098 14.3102 19.1698C13.2902 22.3798 13.7202 25.6698 8.99023 26.5298C6.49023 26.6598 6.53023 28.3598 5.62023 30.8898C4.56023 33.9498 3.18023 35.2898 0.62023 37.9698C0.26023 38.3298 0.23023 38.9198 0.62023 39.2498C1.64023 40.1198 2.70023 40.1698 3.77023 39.7298C6.43023 38.6098 8.48023 35.1698 10.4102 32.9398C12.5602 30.4598 17.7202 31.5198 21.6202 29.0898C23.7202 27.7998 24.9902 26.1498 24.5902 23.6898C24.5202 23.2898 24.9802 23.0498 25.1402 23.4198C25.4502 24.1198 25.6602 24.8598 25.7402 25.6198C25.7702 25.8298 25.9402 25.9798 26.1502 25.9698C30.3702 25.7298 35.8202 30.3798 40.9202 31.6398C41.2302 31.7198 41.4502 31.3598 41.2802 31.0898C40.6538 30.145 40.2032 29.0948 39.9502 27.9898C39.8502 27.5998 40.4302 27.4898 40.6302 27.8498C41.3882 29.2218 42.4765 30.383 43.7966 31.2282C45.1168 32.0733 46.6269 32.5757 48.1902 32.6898C49.4302 32.7898 50.7902 32.6398 52.2102 32.2098C53.9102 31.6998 55.4802 31.0398 57.3502 31.3998C58.0473 31.5072 58.716 31.7527 59.317 32.1219C59.918 32.4911 60.4392 32.9765 60.8502 33.5498C61.9802 35.2098 64.3802 35.6498 65.6602 33.9098C65.7438 33.7919 65.7951 33.6542 65.8092 33.5104C65.8232 33.3666 65.7994 33.2216 65.7402 33.0898C62.9202 26.4898 55.7702 26.0398 52.6902 25.2398H52.7002Z" fill="#0D0D0D"/>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1,7 @@
<svg width="99" height="30" viewBox="0 0 99 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M26.5921 22.7484C30.1536 26.5926 36.1675 26.8321 40.0254 23.2834C43.8834 19.7346 44.1251 13.741 40.5653 9.89516C37.0055 6.0493 30.9918 5.80705 27.1322 9.35402C23.2789 12.9074 23.0374 18.8983 26.5921 22.7484ZM36.985 22.2023L36.3202 21.4817C33.9708 22.6873 31.1026 22.1793 29.314 20.2406C27.5253 18.3019 27.2573 15.4109 28.6593 13.1785L29.1823 13.7453C28.0945 15.6778 28.3766 18.0883 29.8815 19.7193C31.3864 21.3504 33.7729 21.8323 35.7961 20.9137L35.1313 20.1931C35.182 20.0969 35.2887 20.0437 35.3963 20.061L36.8465 20.1239C36.9427 20.1139 37.038 20.1499 37.1035 20.2208C37.1689 20.2918 37.1969 20.3894 37.1789 20.4842L37.1186 21.918C37.119 22.0279 37.07 22.1322 36.985 22.2023ZM30.2484 10.4056L30.8822 11.0925C33.2399 9.88873 36.1139 10.4009 37.907 12.3443C39.7001 14.2878 39.9717 17.1849 38.5708 19.4258L38.0167 18.8253C39.1045 16.8928 38.8224 14.4824 37.3175 12.8513C35.8127 11.2202 33.4262 10.7383 31.403 11.657L32.0922 12.4039C32.0055 12.4877 31.8899 12.5349 31.7692 12.5359L30.357 12.4515C30.2608 12.4615 30.1655 12.4256 30.1 12.3546C30.0346 12.2836 30.0066 12.186 30.0246 12.0913L30.0584 10.6817C30.0654 10.5598 30.1401 10.452 30.252 10.4023L30.2484 10.4056Z" fill="#0D0D0D"/>
<path d="M20.444 7.97054C19.9586 6.4746 19.1734 5.09252 18.1359 3.90816C17.0367 2.74479 15.7118 1.81618 14.2416 1.17869C12.5357 0.490414 10.7092 0.148196 8.86906 0.172066H0V3.04673H8.86906C10.1941 3.02554 11.5088 3.28292 12.7274 3.80211C13.7988 4.28215 14.7662 4.96538 15.5757 5.81372C16.3885 6.7154 16.9945 7.78263 17.3518 8.94127C17.7619 10.2184 17.9685 11.5518 17.964 12.8927C17.9712 14.2344 17.7645 15.5687 17.3518 16.8458C16.9948 17.9952 16.4054 19.0596 15.6199 19.9733C14.8569 20.8921 13.8771 21.608 12.7683 22.0567C11.5368 22.5751 10.2106 22.8324 8.87397 22.8121H3.24446V6.46142H0V25.6868H8.86906C10.745 25.6868 12.4393 25.398 13.9535 24.7878C15.4305 24.2092 16.769 23.3277 17.8822 22.2003C18.9895 21.0504 19.8378 19.6782 20.3703 18.1754C20.966 16.4784 21.2586 14.6904 21.2347 12.8927C21.2321 11.2207 20.9647 9.55948 20.4424 7.97054H20.444Z" fill="#0D0D0D"/>
<path d="M45.7076 16.2722C45.6943 17.5619 45.9265 18.8423 46.3918 20.0458C46.8323 21.2011 47.5078 22.2532 48.3758 23.1358C49.2204 24.0517 50.2534 24.7751 51.4042 25.2567C52.6274 25.8049 53.9576 26.0751 55.2985 26.048C56.2006 26.057 57.0993 25.9361 57.9668 25.6891C58.7925 25.4821 59.5823 25.1521 60.3093 24.7102C60.9853 24.3212 61.5935 23.8253 62.1099 23.2419C62.624 22.6815 63.0381 22.0375 63.3344 21.3379L60.2405 20.4047C60.0828 20.8312 59.8375 21.2202 59.5202 21.5468C59.164 21.8957 58.764 22.1973 58.3302 22.4441C57.878 22.7401 57.3804 22.9606 56.8569 23.0967C56.3279 23.2386 55.7825 23.311 55.2347 23.312C54.3861 23.3179 53.547 23.134 52.7792 22.7736C52.0242 22.4244 51.349 21.9246 50.7952 21.3053C50.214 20.6397 49.7617 19.8724 49.4611 19.0424C49.1068 18.1614 48.9353 17.2179 48.9569 16.2689C48.9412 15.3236 49.0999 14.3835 49.4251 13.4954C49.7348 12.6909 50.1866 11.9483 50.7592 11.3027C51.3093 10.6872 51.986 10.1969 52.7432 9.86537C54.4533 9.07789 56.4391 9.15803 58.0797 10.0807C58.9219 10.5773 59.6167 11.2878 60.0932 12.1397L63.1936 11.1608C62.4876 9.79594 61.414 8.65417 60.0932 7.86354C58.723 7.03638 57.1368 6.60567 55.2625 6.60567C53.9124 6.59697 52.575 6.86577 51.3338 7.39531C50.2075 7.8865 49.1899 8.59514 48.3398 9.48034C47.4783 10.3474 46.8139 11.389 46.3918 12.5345C45.9297 13.7263 45.6975 14.9945 45.7076 16.2722V16.2722Z" fill="#0D0D0D"/>
<path d="M67.3232 25.6866H70.5677V0.171875H67.3232V25.6866Z" fill="#0D0D0D"/>
<path d="M98.0639 17.8882C99.2879 14.8002 99.3136 11.3684 98.1359 8.26249C97.5611 6.74401 96.7307 5.33433 95.6805 4.09406C94.6136 2.88603 93.3316 1.88537 91.8991 1.14271C90.3771 0.376664 88.6932 -0.0149377 86.9882 0.000677509C85.3158 -0.0180362 83.6621 0.351159 82.1575 1.07909C80.7152 1.76922 79.4197 2.7297 78.3417 3.90807C77.253 5.12616 76.3865 6.52477 75.7815 8.04061C75.1768 9.60163 74.8709 11.2617 74.8796 12.935C74.8773 14.5674 75.1706 16.1868 75.7455 17.7153C76.2817 19.2411 77.1163 20.6458 78.201 21.8478C79.2466 23.0696 80.536 24.0608 81.9873 24.7584C83.4605 25.5138 85.0877 25.8727 86.926 25.8727C88.1791 25.8924 89.4254 25.6851 90.6042 25.2609C90.7152 25.2307 90.8244 25.1947 90.9316 25.1532L88.8412 22.7468C88.2268 22.8932 87.597 22.9656 86.9653 22.9621C85.6311 22.9621 84.4411 22.7092 83.364 22.135C82.2857 21.6011 81.3364 20.8408 80.5811 19.9064C79.7874 18.9608 79.1768 17.8765 78.7805 16.7087C78.3588 15.4956 78.1517 14.2187 78.1682 12.935C78.1607 11.6877 78.3677 10.4483 78.7805 9.27074C79.161 8.10994 79.747 7.02641 80.5107 6.07141C81.2744 5.12704 82.2208 4.34531 83.2936 3.77266C84.4286 3.18469 85.6928 2.88806 86.9718 2.90961C88.1986 2.90562 89.4092 3.18895 90.506 3.73677C91.5694 4.29279 92.5144 5.04907 93.2889 5.96374C94.0828 6.92315 94.6931 8.01975 95.0895 9.19896C95.522 10.3974 95.7435 11.6614 95.7443 12.935C95.7339 14.1435 95.5391 15.3433 95.1664 16.4933C94.7869 17.6108 94.24 18.6647 93.5442 19.6192L91.5979 17.3564H88.396L91.8336 21.3388L93.7799 23.6017L95.5806 25.6867H98.7547L95.5397 21.9849C96.6126 20.7752 97.4666 19.389 98.0639 17.8882V17.8882Z" fill="#0D0D0D"/>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -0,0 +1,9 @@
<svg width="52" height="48" viewBox="0 0 52 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.0153 47.914L35.5833 18.4902H16.4473L26.0153 47.914Z" fill="#0D0D0D"/>
<path opacity="0.75" fill-rule="evenodd" clip-rule="evenodd" d="M26.0149 47.914L16.4469 18.4902H3.0376L26.0149 47.914Z" fill="#0D0D0D"/>
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M3.03785 18.4902L0.130303 27.4318C-0.134897 28.2473 0.155561 29.1408 0.849884 29.6448L26.0152 47.914L3.03785 18.4902Z" fill="#0D0D0D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.0376 18.4905H16.4469L10.6841 0.768868C10.3877 -0.143132 9.09659 -0.142884 8.80019 0.768868L3.0376 18.4905Z" fill="#0D0D0D"/>
<path opacity="0.75" fill-rule="evenodd" clip-rule="evenodd" d="M26.0151 47.914L35.5831 18.4902H48.9925L26.0151 47.914Z" fill="#0D0D0D"/>
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M48.9924 18.4902L51.9 27.4318C52.1652 28.2473 51.8747 29.1408 51.1804 29.6448L26.0151 47.914L48.9924 18.4902Z" fill="#0D0D0D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M48.9923 18.4905H35.583L41.3458 0.768868C41.6422 -0.143132 42.9333 -0.142884 43.2297 0.768868L48.9923 18.4905Z" fill="#0D0D0D"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,3 @@
<svg width="87" height="40" viewBox="0 0 87 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M43.5663 0C34.5485 0 26.9051 6.17423 24.5362 14.5396C22.4774 10.1025 18.0158 6.9939 12.8768 6.9939C5.80951 6.9939 0 12.8611 0 19.9987C0 27.1362 5.80951 33.0061 12.8768 33.0061C18.0158 33.0061 22.4774 29.8956 24.5362 25.4577C26.9051 33.8237 34.5485 40 43.5663 40C52.5174 40 60.1218 33.9169 62.5513 25.6452C64.6482 29.9824 69.0546 33.0061 74.1205 33.0061C81.1878 33.0061 87 27.1362 87 19.9987C87 12.8611 81.1878 6.9939 74.1205 6.9939C69.0546 6.9939 64.6482 10.0157 62.5513 14.3521C60.1218 6.08109 52.5174 0 43.5663 0ZM43.5663 7.6341C50.3737 7.6341 55.8119 13.1236 55.8119 19.9987C55.8119 26.8737 50.3737 32.3659 43.5663 32.3659C36.7589 32.3659 31.3234 26.8737 31.3234 19.9987C31.3234 13.1236 36.7589 7.6341 43.5663 7.6341ZM12.8768 14.628C15.8593 14.628 18.1973 16.9865 18.1973 19.9987C18.1973 23.0108 15.8593 25.372 12.8768 25.372C9.89432 25.372 7.55899 23.0108 7.55899 19.9987C7.55899 16.9865 9.89432 14.628 12.8768 14.628ZM74.1205 14.628C77.103 14.628 79.441 16.9865 79.441 19.9987C79.441 23.0108 77.103 25.372 74.1205 25.372C71.1381 25.372 68.8027 23.0108 68.8027 19.9987C68.8027 16.9865 71.1381 14.628 74.1205 14.628Z" fill="#0D0D0D"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -0,0 +1,3 @@
<svg width="54" height="43" viewBox="0 0 54 43" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M44.2992 43C48.2272 43 49.6688 41.3116 49.6688 37.1805V29.1337C49.6688 25.2899 51.5427 23.0986 53.3446 22.0568C53.8851 21.7335 53.8851 20.9791 53.3446 20.6199C51.4706 19.4344 49.6688 16.9557 49.6688 13.6508V5.7477C49.6688 1.29323 48.4435 0 44.5154 0H9.23462C5.30653 0 4.08125 1.29323 4.08125 5.7477V13.6508C4.08125 16.9557 2.27937 19.4344 0.405422 20.6199C-0.135141 20.9432 -0.135141 21.7335 0.405422 22.0568C2.2073 23.0627 4.08125 25.254 4.08125 29.1337V37.1805C4.08125 41.3116 5.52275 43 9.45085 43H44.2992ZM27.4727 34.6774C23.1941 34.6774 20.0857 33.4468 17.1967 31.0207C16.7213 30.5988 16.5385 30.0713 16.5385 29.5439C16.5385 29.122 16.6482 28.6649 16.9773 28.3133L17.855 27.2233C18.2938 26.6959 18.7692 26.4498 19.3177 26.4498C19.9394 26.4498 20.5245 26.6959 21.1462 27.0827C23.1209 28.3133 25.3151 29.0165 27.9481 29.0165C29.9594 29.0165 31.5684 28.2078 31.5684 26.5553C31.5684 22.2656 16.7213 24.6214 16.7213 14.9873C16.7213 9.81868 21.1096 6.93548 26.8144 6.93548C30.8371 6.93548 33.7992 8.06063 35.9933 9.39675C36.5419 9.74835 36.9076 10.4516 36.9076 11.1548C36.9076 11.5767 36.7979 11.9635 36.5419 12.3151L35.8836 13.2644C35.4082 13.8973 34.8597 14.2138 34.1649 14.2138C33.6895 14.2138 33.1775 14.038 32.629 13.7919C30.9833 12.9832 29.2646 12.5612 27.1801 12.5612C25.0225 12.5612 23.7426 13.6864 23.7426 14.8467C23.7426 19.2418 38.5897 16.8509 38.5897 26.2036C38.5897 31.4426 34.2014 34.6774 27.4727 34.6774Z" fill="#0D0D0D"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,12 @@
<svg width="79" height="32" viewBox="0 0 79 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M60.6313 0.841797H68.2103V31.9997H60.6313V0.841797ZM70.7366 0.841797H78.3156V31.9997H70.7366V0.841797Z" fill="#0D0D0D"/>
<path d="M54.3157 8.92639C56.6877 8.92639 58.6105 7.00357 58.6105 4.63165C58.6105 2.25973 56.6877 0.336914 54.3157 0.336914C51.9438 0.336914 50.021 2.25973 50.021 4.63165C50.021 7.00357 51.9438 8.92639 54.3157 8.92639Z" fill="#0D0D0D"/>
<path d="M38.6728 22.3563L33.4198 10.9475H28.7411L23.4888 22.0279L18.4404 10.9475H10.1053V5.05273H2.52632V10.9475H0V16.8422H2.52632V32.0001H10.1053V16.8422H13.0754L20.944 32.0001H25.9916L30.9987 20.4683L36.2518 32.0001H41.2168L49.2303 16.8422H50.5263V32.0001H58.1053V10.9475H43.9663L38.6728 22.3563Z" fill="#0D0D0D"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="78.3158" height="32" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 919 B

View File

@ -0,0 +1,3 @@
<svg width="42" height="46" viewBox="0 0 42 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19.8427 0V11.1097L9.60158 17.0257L22.1019 24.247L41.8816 12.8016V23.9217L4.61767 45.4828L4.57067 45.51L4.51911 45.4772L0 42.6113V31.7843L4.55892 34.3967L12.357 29.8838L0 22.5825V11.4794L19.8427 0ZM38.8439 18.0688L4.56625 37.902L3.03773 37.0261V40.9407L4.64292 41.9586L38.8439 22.1698V18.0688ZM3.03773 16.7423V20.849L15.3751 28.137L18.993 26.0442L18.9954 25.9601L3.03773 16.7423ZM16.8049 5.26685L3.03773 13.2315L5.14041 14.4485L6.56936 15.2738L16.8049 9.35714V5.26685Z" fill="#0D0D0D"/>
</svg>

After

Width:  |  Height:  |  Size: 599 B

View File

@ -0,0 +1,9 @@
<template>
<section class="app-section">
<div class="app-section__inner">
<slot />
</div>
</section>
</template>
<style lang="scss" src="./style.scss"></style>

View File

@ -0,0 +1,19 @@
.app-section {
position: relative;
&__inner {
position: relative;
z-index: 2;
padding: 5rem 1rem;
margin: 0 auto;
max-width: 50rem;
@media (min-width: 600px) {
padding: 7rem 2rem;
}
}
& + & &__inner {
padding-top: 0;
}
}

View File

@ -1,14 +1,8 @@
<template>
<div v-if="inline && mainFile">
<component :is="mainFile" v-if="mode === 'vue'" />
<react-renderer :component="mainFile" v-if="mode === 'react'" />
</div>
<demo-frame v-if="inline && mainFile" v-bind="props" />
<div class="demo" v-else>
<template v-if="mainFile">
<div class="demo__preview">
<component :is="mainFile" v-if="mode === 'vue'" />
<react-renderer :component="mainFile" v-if="mode === 'react'" />
</div>
<demo-frame class="demo__preview" v-bind="props" />
<div class="demo__source" v-if="showSource">
<div class="demo__tabs" v-if="showFileNames">
<button
@ -22,7 +16,8 @@
</button>
</div>
<div class="demo__code" v-if="activeFile" :key="activeFile.path">
<prism :code="activeFile.content" :language="activeFile.highlight" :highlight="highlight" />
<!-- eslint-disable-next-line -->
<prism :language="activeFile.highlight" :highlight="highlight">{{ activeFile.content }}</prism>
</div>
</div>
<div class="demo__meta">
@ -44,66 +39,25 @@
</template>
<script>
import collect from 'collect.js'
import Prism from '~/components/Prism'
import DemoFrame from '~/components/DemoFrame'
import DemoMixin from '~/components/DemoMixin'
export default {
mixins: [DemoMixin],
components: {
ReactRenderer: () => import(/* webpackChunkName: "react-renderer" */ '~/components/ReactRenderer'),
DemoFrame,
Prism,
},
props: {
name: {
type: String,
required: true,
},
mode: {
type: String,
default: 'vue',
},
inline: {
type: Boolean,
default: false,
},
highlight: {
type: String,
default: null,
},
showSource: {
type: Boolean,
default: true,
},
},
data() {
return {
loading: true,
files: [],
content: null,
currentIndex: 0,
syntax: {
vue: 'html',
},
}
},
computed: {
mainFile() {
const file = this.files
.find(item => item.path.endsWith('index.vue') || item.path.endsWith('index.jsx'))
if (!file) {
return false
}
return require(`~/demos/${file.path}`).default
},
showFileNames() {
return this.files.length > 1
},
@ -120,29 +74,6 @@ export default {
return `https://github.com/ueberdosis/tiptap-next/tree/main/docs/src/demos/${this.name}`
},
},
mounted() {
this.files = collect(require.context('~/demos/', true, /.+\..+$/).keys())
.filter(path => path.startsWith(`./${this.name}/`))
.filter(path => !path.endsWith('.spec.js') && !path.endsWith('.spec.ts'))
.map(path => path.replace('./', ''))
.map(path => {
const extension = path.split('.').pop()
return {
path,
name: path.replace(`${this.name}/`, ''),
content: require(`!!raw-loader!~/demos/${path}`).default,
extension,
highlight: this.syntax[extension] || extension,
}
})
.filter(item => {
return ['vue', 'ts', 'js', 'jsx', 'scss'].includes(item.extension)
})
.sortBy(item => item.path.split('/').length && !item.path.endsWith('index.vue'))
.toArray()
},
}
</script>

View File

@ -1,26 +1,25 @@
.demo {
overflow: hidden;
border-radius: 0.5rem;
border-radius: 0.75rem;
&__preview {
padding: 1.25rem;
border-top-left-radius: inherit;
border-top-right-radius: inherit;
border-bottom-width: 0;
color: $colorBlack;
background-color: $colorWhite;
max-height: 50rem;
max-height: unquote("max(300px, 60vh)");
overflow: auto;
scroll-behavior: smooth;
border: 3px solid $colorBlack;
}
&__source {
border: 1px solid rgba($colorWhite, 0.1);
background-color: $colorBlack;
}
&__tabs {
padding: 1rem 1.25rem 0 1.25rem;
padding: 0.5rem 1.25rem 0 1.25rem;
background-color: rgba($colorBlack, 0.9);
white-space: nowrap;
overflow-x: auto;
@ -62,12 +61,12 @@
width: 100%;
padding: 0.5rem 1.25rem;
font-size: 0.85rem;
border: 1px solid rgba($colorWhite, 0.1);
border-top: 1px solid rgba($colorWhite, 0.1);
border-bottom-left-radius: inherit;
border-bottom-right-radius: inherit;
border-top-width: 0;
background-color: $colorBlack;
white-space: nowrap;
color: rgba($colorWhite, 0.5);
}
&__name {
@ -83,6 +82,10 @@
&__link {
margin-left: auto;
&:hover {
color: $colorWhite;
}
}
&__error {

View File

@ -0,0 +1,18 @@
<template>
<div v-if="mainFile">
<component :is="mainFile" v-if="mode === 'vue'" />
<react-renderer :component="mainFile" v-if="mode === 'react'" />
</div>
</template>
<script>
import DemoMixin from '~/components/DemoMixin'
export default {
mixins: [DemoMixin],
components: {
ReactRenderer: () => import(/* webpackChunkName: "react-renderer" */ '~/components/ReactRenderer'),
},
}
</script>

View File

@ -0,0 +1,128 @@
<template>
<div class="demo-frame" :class="{ 'is-inline': inline, 'is-loading': isLoading }">
<div class="demo-frame__loader-wrapper" v-if="isLoading">
<div class="demo-frame__loader" />
</div>
<iframe
class="demo-frame__iframe"
v-resize.quiet="{ scrolling: 'omit' }"
:src="`/demos/${name}?${query}`"
width="100%"
height="0"
frameborder="0"
@load="onLoad"
/>
</div>
</template>
<script>
export default {
props: {
name: {
type: String,
required: true,
},
mode: {
type: String,
default: 'vue',
},
inline: {
type: Boolean,
default: false,
},
highlight: {
type: String,
default: null,
},
showSource: {
type: Boolean,
default: true,
},
},
data() {
return {
isLoading: true,
}
},
computed: {
query() {
return `mode=${this.mode}&inline=${this.inline}&highlight=${this.highlight}&showSource=${this.showSource}`
},
},
methods: {
onLoad() {
this.isLoading = false
},
},
}
</script>
<style lang="scss" scoped>
.demo-frame {
display: flex;
flex-direction: column;
position: relative;
min-height: 5rem;
&__iframe {
background-color: transparent;
max-height: 100%;
}
&.is-inline {
border-radius: 0.75rem;
background-color: rgba($colorBlack, 0.03);
margin: -1.25rem;
}
&__loader-wrapper {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
}
&__loader {
font-size: 10px;
position: relative;
text-indent: -9999rem;
border-top: 2px solid rgba($colorBlack, 0.2);
border-right: 2px solid rgba($colorBlack, 0.2);
border-bottom: 2px solid rgba($colorBlack, 0.2);
border-left: 2px solid $colorBlack;
transform: translateZ(0);
animation: load8 1.1s infinite linear;
&,
&::after {
border-radius: 50%;
width: 1.25rem;
height: 1.25rem;
}
}
@keyframes load8 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
}
</style>

View File

@ -0,0 +1,85 @@
import collect from 'collect.js'
export default {
props: {
name: {
type: String,
required: true,
},
mode: {
type: String,
default: 'vue',
},
inline: {
type: Boolean,
default: false,
},
highlight: {
type: String,
default: null,
},
showSource: {
type: Boolean,
default: true,
},
},
data() {
return {
files: [],
syntax: {
vue: 'html',
},
}
},
computed: {
props() {
return {
name: this.name,
mode: this.mode,
inline: this.inline,
highlight: this.highlight,
showSource: this.showSource,
}
},
mainFile() {
const file = this.files
.find(item => item.path.endsWith('index.vue') || item.path.endsWith('index.jsx'))
if (!file) {
return false
}
return require(`~/demos/${file.path}`).default
},
},
mounted() {
this.files = collect(require.context('~/demos/', true, /.+\..+$/).keys())
.filter(path => path.startsWith(`./${this.name}/`))
.filter(path => !path.endsWith('.spec.js') && !path.endsWith('.spec.ts'))
.map(path => path.replace('./', ''))
.map(path => {
const extension = path.split('.').pop()
return {
path,
name: path.replace(`${this.name}/`, ''),
content: require(`!!raw-loader!~/demos/${path}`).default,
extension,
highlight: this.syntax[extension] || extension,
}
})
.filter(item => {
return ['vue', 'ts', 'js', 'jsx', 'scss'].includes(item.extension)
})
.sortBy(item => item.path.split('/').length && !item.path.endsWith('index.vue'))
.toArray()
},
}

View File

@ -0,0 +1,22 @@
<template>
<div class="feature-item text">
<slot />
</div>
</template>
<script>
export default {
props: {
},
}
</script>
<style lang="scss" scoped>
.feature-item {
break-inside: avoid-column;
background-color: rgba($colorBlack, 0.03);
border-radius: 0.75rem;
padding: 1.5rem;
margin-bottom: 1rem;
}
</style>

View File

@ -0,0 +1,22 @@
<template>
<div class="feature-list">
<slot />
</div>
</template>
<script>
export default {
props: {
},
}
</script>
<style lang="scss" scoped>
.feature-list {
@media (min-width: 700px) {
column-count: 2;
column-gap: 1rem;
}
}
</style>

View File

@ -1,86 +0,0 @@
<template>
<div class="live-demo-template">
<div class="live-demo-template__preview">
<slot name="preview" />
</div>
<div class="live-demo-template__editor">
<slot name="editor" />
</div>
</div>
</template>
<script>
export default {
mounted() {
let firstLoad = true
const pre = this.$el.getElementsByClassName('prism-editor__editor')[0]
const textarea = this.$el.getElementsByClassName('prism-editor__textarea')[0]
const resizeObserver = new ResizeObserver(() => {
const width = pre.scrollWidth
const height = pre.scrollHeight
textarea.style.width = `${width}px`
textarea.style.height = `${height}px`
if (!firstLoad) {
textarea.blur()
textarea.focus()
}
firstLoad = false
})
resizeObserver.observe(pre)
this.$once('hook:beforeDestroy', () => {
resizeObserver.unobserve(pre)
})
},
}
</script>
<style lang="scss" scoped>
.live-demo-template {
background-color: $colorWhite;
overflow: hidden;
border-radius: 0.5rem 0.5rem 0 0;
&__preview {
padding: 1.25rem;
border-top-left-radius: inherit;
border-top-right-radius: inherit;
border-bottom-width: 0;
color: $colorBlack;
}
&__editor {
border: 1px solid rgba($colorWhite, 0.1);
background-color: $colorBlack;
}
&__editor ::v-deep {
.prism-editor-wrapper {
overflow: auto;
max-height: unquote("max(300px, 60vh)");
padding: 1.25rem;
}
.prism-editor__container {
position: relative;
}
.prism-editor__textarea {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
z-index: 1;
resize: none;
-webkit-text-fill-color: transparent;
overflow: hidden;
}
}
}
</style>

View File

@ -1,110 +0,0 @@
<template>
<div class="live-demo">
<template v-if="file">
<div class="live-demo__preview">
<vue-live
:code="file.content"
:layout="CustomLayout"
:requires="requires"
/>
</div>
<div class="live-demo__meta">
<div class="live-demo__name">
Demo/{{ name }}
</div>
<a class="live-demo__link" :href="githubUrl" target="_blank">
Edit on GitHub
</a>
</div>
</template>
<div v-else class="live-demo__error">
Could not find a demo called {{ name }}.
</div>
</div>
</template>
<script>
/*
<static-query>
query {
packages: allPackage {
edges {
node {
name
}
}
}
}
</static-query>
*/
// import collect from 'collect.js'
import { VueLive } from 'vue-live'
import CustomLayout from './CustomLayout'
export default {
components: {
VueLive,
},
props: {
name: {
type: String,
required: true,
},
},
data() {
return {
files: [],
content: null,
currentIndex: 0,
CustomLayout,
syntax: {
vue: 'html',
},
}
},
computed: {
requires() {
// const names = this.$static.packages.edges
// .map(item => item.node.name)
// .filter(name => name !== 'html')
// const packages = Object.fromEntries(names.map(name => {
// const module = require(`~/../../packages/${name}/index.ts`)
// const onlyDefault = module.default && Object.keys(module).length === 1
// return [`@tiptap/${name}`, onlyDefault ? module.default : module]
// }))
// return packages
return {}
},
file() {
return this.files[0]
},
githubUrl() {
return `https://github.com/ueberdosis/tiptap-next/tree/main/docs/src/demos/${this.name}`
},
},
mounted() {
// this.files = collect(require.context('~/demos/', true, /.+\..+$/).keys())
// .filter(path => path.startsWith(`./${this.name}/index.vue`))
// .map(path => path.replace('./', ''))
// .map(path => {
// return {
// path,
// name: path.replace(`${this.name}/`, ''),
// content: require(`!!raw-loader!~/demos/${path}`).default,
// }
// })
// .toArray()
},
}
</script>
<style lang="scss" src="./style.scss" scoped />

View File

@ -1,58 +0,0 @@
.live-demo {
background-color: $colorWhite;
overflow: hidden;
border-radius: 0.5rem;
&__preview {
border-top-left-radius: inherit;
border-top-right-radius: inherit;
border-bottom-width: 0;
}
&__tab {
display: inline-flex;
position: relative;
background-color: transparent;
color: rgba($colorWhite, 0.7);
padding: 0.1rem 0.5rem;
border-radius: 5px;
font-weight: 500;
border: none;
margin-right: 0.5rem;
&:first-child {
margin-left: -0.5rem;
}
&.is-active,
&:hover {
color: $colorWhite;
background-color: rgba($colorWhite, 0.1);
}
}
&__code {
pre {
margin: 0;
border-radius: 0;
}
}
&__meta {
display: flex;
justify-content: space-between;
width: 100%;
padding: 0.5rem 1.25rem;
border: 1px solid rgba($colorWhite, 0.1);
border-bottom-left-radius: inherit;
border-bottom-right-radius: inherit;
border-top-width: 0;
background-color: $colorBlack;
}
&__error {
padding: 1.25rem;
color: $colorRed;
background-color: rgba($colorRed, 0.1);
}
}

View File

@ -0,0 +1,61 @@
<template>
<g-link class="logo-item" :to="to">
<div class="logo-item__image" v-html="svg" v-if="svg" />
<div class="logo-item__title">
{{ title }}
</div>
</g-link>
</template>
<script>
export default {
props: {
title: {
type: String,
default: null,
},
image: {
type: String,
default: null,
},
to: {
type: String,
default: null,
},
},
data() {
return {
svg: null,
}
},
created() {
this.svg = require(`!html-loader!@/assets/logos/${this.image}.svg`)
},
}
</script>
<style lang="scss" scoped>
.logo-item {
display: flex;
flex-direction: column;
align-items: center;
background-color: rgba($colorBlack, 0.03);
border-radius: 0.75rem;
padding: 1.5rem;
margin-bottom: 1rem;
&__image ::v-deep svg {
width: 100%;
height: 3rem;
}
&__title {
white-space: nowrap;
font-size: 0.85rem;
}
}
</style>

View File

@ -0,0 +1,23 @@
<template>
<div class="logo-list">
<slot />
</div>
</template>
<script>
export default {
props: {
},
}
</script>
<style lang="scss" scoped>
.logo-list {
column-count: 2;
column-gap: 1rem;
@media (min-width: 700px) {
column-count: 4;
}
}
</style>

View File

@ -4,13 +4,13 @@
padding: 1.5rem 0;
&__link {
color: rgba($colorWhite, 0.6);
color: rgba($colorBlack, 0.6);
padding: 0.25rem 0.5rem;
border-radius: 5px;
&:hover {
color: $colorWhite;
background-color: rgba($colorWhite, 0.05);
color: $colorBlack;
background-color: rgba($colorBlack, 0.05);
}
}
}

View File

@ -1,5 +1,5 @@
<template>
<pre :class="`language-${language}`" :data-line="highlight"><code :class="`language-${language}`">{{ code }}</code></pre>
<pre :class="`language-${language}`" :data-line="highlight"><code :class="`language-${language}`"><slot /></code></pre>
</template>
<script>
@ -14,11 +14,6 @@ export default {
type: String,
},
code: {
default: null,
type: String,
},
highlight: {
type: String,
default: null,

View File

@ -145,7 +145,6 @@ export default {
background-color: white;
border: 1px solid rgba(black, 0.1);
border-radius: 0.5rem;
margin-bottom: 1rem;
&__menu {
display: flex;
@ -157,7 +156,9 @@ export default {
&__content {
padding: 1rem;
max-height: 30rem;
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
&::-webkit-scrollbar-thumb {
background-color: rgba(black, 0.1);
@ -183,7 +184,6 @@ export default {
display: flex;
align-items: center;
border-radius: 5px;
margin-top: 1rem;
&::before {
content: ' ';

View File

@ -87,7 +87,9 @@ export default {
mounted() {
this.editor = new Editor({
extensions: defaultExtensions(),
extensions: [
...defaultExtensions(),
],
content: `
<h2>
Hi there,

View File

@ -13,7 +13,7 @@ context('/demos/Extensions/History', () => {
cy.get('.ProseMirror')
.should('contain', 'Mistake')
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')
@ -30,13 +30,13 @@ context('/demos/Extensions/History', () => {
cy.get('.ProseMirror')
.should('contain', 'Mistake')
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')
.should('not.contain', 'Mistake')
cy.get('.demo__preview button:nth-child(2)')
cy.get('button:nth-child(2)')
.click()
cy.get('.ProseMirror')

View File

@ -38,7 +38,7 @@ context('/demos/Extensions/TextAlign', () => {
})
it('aligns the text left on the 1st button', () => {
cy.get('.demo__preview button:nth-child(1)')
cy.get('button:nth-child(1)')
.click()
cy.get('.ProseMirror')
@ -47,7 +47,7 @@ context('/demos/Extensions/TextAlign', () => {
})
it('aligns the text center on the 2nd button', () => {
cy.get('.demo__preview button:nth-child(2)')
cy.get('button:nth-child(2)')
.click()
cy.get('.ProseMirror')
@ -56,7 +56,7 @@ context('/demos/Extensions/TextAlign', () => {
})
it('aligns the text right on the 3rd button', () => {
cy.get('.demo__preview button:nth-child(3)')
cy.get('button:nth-child(3)')
.click()
cy.get('.ProseMirror')
@ -65,7 +65,7 @@ context('/demos/Extensions/TextAlign', () => {
})
it('aligns the text justified on the 4th button', () => {
cy.get('.demo__preview button:nth-child(4)')
cy.get('button:nth-child(4)')
.click()
cy.get('.ProseMirror')
@ -74,7 +74,7 @@ context('/demos/Extensions/TextAlign', () => {
})
it('aligns the text default on the 5th button', () => {
cy.get('.demo__preview button:nth-child(5)')
cy.get('button:nth-child(5)')
.click()
cy.get('.ProseMirror')

View File

@ -41,7 +41,7 @@ context('/demos/Marks/Bold', () => {
})
it('the button should make the selected text bold', () => {
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')
@ -50,9 +50,9 @@ context('/demos/Marks/Bold', () => {
})
it('the button should toggle the selected text bold', () => {
cy.get('.demo__preview button:first').click()
cy.get('button:first').click()
cy.get('.ProseMirror').type('{selectall}')
cy.get('.demo__preview button:first').click()
cy.get('button:first').click()
cy.get('.ProseMirror strong').should('not.exist')
})

View File

@ -21,7 +21,7 @@ context('/demos/Marks/Code', () => {
})
it('should mark the selected text as inline code', () => {
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')
@ -30,13 +30,13 @@ context('/demos/Marks/Code', () => {
})
it('should toggle the selected text as inline code', () => {
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')
.type('{selectall}')
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror code')

View File

@ -14,7 +14,7 @@ context('/demos/Marks/Highlight', () => {
})
it('the button should highlight the selected text', () => {
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')
@ -108,13 +108,13 @@ context('/demos/Marks/Highlight', () => {
})
it('the button should toggle the selected text highlighted', () => {
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')
.type('{selectall}')
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')

View File

@ -32,7 +32,7 @@ context('/demos/Marks/Italic', () => {
})
it('the button should make the selected text italic', () => {
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')
@ -41,13 +41,13 @@ context('/demos/Marks/Italic', () => {
})
it('the button should toggle the selected text italic', () => {
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')
.type('{selectall}')
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror em')

View File

@ -35,7 +35,7 @@ context('/demos/Marks/Link', () => {
cy.window().then(win => {
cy.stub(win, 'prompt').returns('https://tiptap.dev')
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.window().its('prompt').should('be.called')

View File

@ -39,7 +39,7 @@ context('/demos/Marks/Strike', () => {
})
it('the button should strike the selected text', () => {
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')
@ -48,13 +48,13 @@ context('/demos/Marks/Strike', () => {
})
it('the button should toggle the selected text striked', () => {
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')
.type('{selectall}')
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')

View File

@ -25,7 +25,7 @@ context('/demos/Marks/Underline', () => {
})
it('the button should underline the selected text', () => {
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')
@ -34,13 +34,13 @@ context('/demos/Marks/Underline', () => {
})
it('the button should toggle the selected text underline', () => {
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')
.type('{selectall}')
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')

View File

@ -28,7 +28,7 @@ context('/demos/Nodes/Blockquote', () => {
cy.get('.ProseMirror blockquote')
.should('not.exist')
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')
@ -42,7 +42,7 @@ context('/demos/Nodes/Blockquote', () => {
cy.get('.ProseMirror').type('{selectall}')
})
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')
@ -54,7 +54,7 @@ context('/demos/Nodes/Blockquote', () => {
cy.get('.ProseMirror blockquote')
.should('not.exist')
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')
@ -64,7 +64,7 @@ context('/demos/Nodes/Blockquote', () => {
cy.get('.ProseMirror')
.type('{selectall}')
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror blockquote')

View File

@ -31,7 +31,7 @@ context('/demos/Nodes/BulletList', () => {
cy.get('.ProseMirror ul li')
.should('not.exist')
cy.get('.demo__preview button:nth-child(1)')
cy.get('button:nth-child(1)')
.click()
cy.get('.ProseMirror')
@ -47,14 +47,14 @@ context('/demos/Nodes/BulletList', () => {
cy.get('.ProseMirror ul')
.should('not.exist')
cy.get('.demo__preview button:nth-child(1)')
cy.get('button:nth-child(1)')
.click()
cy.get('.ProseMirror')
.find('ul')
.should('contain', 'Example Text')
cy.get('.demo__preview button:nth-child(1)')
cy.get('button:nth-child(1)')
.click()
cy.get('.ProseMirror ul')

View File

@ -25,7 +25,7 @@ context('/demos/Nodes/CodeBlock', () => {
})
it('the button should make the selected line a code block', () => {
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')
@ -34,7 +34,7 @@ context('/demos/Nodes/CodeBlock', () => {
})
it('the button should toggle the code block', () => {
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror')
@ -44,7 +44,7 @@ context('/demos/Nodes/CodeBlock', () => {
cy.get('.ProseMirror')
.type('{selectall}')
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror pre')

View File

@ -27,7 +27,7 @@ context('/demos/Nodes/HardBreak', () => {
cy.get('.ProseMirror br')
.should('not.exist')
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror br')

View File

@ -36,7 +36,7 @@ context('/demos/Nodes/Heading', () => {
cy.get('.ProseMirror h1')
.should('not.exist')
cy.get('.demo__preview button:nth-child(1)')
cy.get('button:nth-child(1)')
.click()
cy.get('.ProseMirror')
@ -48,7 +48,7 @@ context('/demos/Nodes/Heading', () => {
cy.get('.ProseMirror h2')
.should('not.exist')
cy.get('.demo__preview button:nth-child(2)')
cy.get('button:nth-child(2)')
.click()
cy.get('.ProseMirror')
@ -60,7 +60,7 @@ context('/demos/Nodes/Heading', () => {
cy.get('.ProseMirror h3')
.should('not.exist')
cy.get('.demo__preview button:nth-child(3)')
cy.get('button:nth-child(3)')
.click()
cy.get('.ProseMirror')
@ -72,14 +72,14 @@ context('/demos/Nodes/Heading', () => {
cy.get('.ProseMirror h1')
.should('not.exist')
cy.get('.demo__preview button:nth-child(1)')
cy.get('button:nth-child(1)')
.click()
cy.get('.ProseMirror')
.find('h1')
.should('contain', 'Example Text')
cy.get('.demo__preview button:nth-child(1)')
cy.get('button:nth-child(1)')
.click()
cy.get('.ProseMirror h1')

View File

@ -27,7 +27,7 @@ context('/demos/Nodes/HorizontalRule', () => {
cy.get('.ProseMirror hr')
.should('not.exist')
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.get('.ProseMirror hr')

View File

@ -14,7 +14,7 @@ context('/demos/Nodes/Image', () => {
cy.window().then(win => {
cy.stub(win, 'prompt').returns('foobar.png')
cy.get('.demo__preview button:first')
cy.get('button:first')
.click()
cy.window().its('prompt').should('be.called')

View File

@ -31,7 +31,7 @@ context('/demos/Nodes/OrderedList', () => {
cy.get('.ProseMirror ol li')
.should('not.exist')
cy.get('.demo__preview button:nth-child(1)')
cy.get('button:nth-child(1)')
.click()
cy.get('.ProseMirror')
@ -47,14 +47,14 @@ context('/demos/Nodes/OrderedList', () => {
cy.get('.ProseMirror ol')
.should('not.exist')
cy.get('.demo__preview button:nth-child(1)')
cy.get('button:nth-child(1)')
.click()
cy.get('.ProseMirror')
.find('ol')
.should('contain', 'Example Text')
cy.get('.demo__preview button:nth-child(1)')
cy.get('button:nth-child(1)')
.click()
cy.get('.ProseMirror ol')

View File

@ -31,7 +31,7 @@ context('/demos/Nodes/TaskList', () => {
cy.get('.ProseMirror ul li')
.should('not.exist')
cy.get('.demo__preview button:nth-child(1)')
cy.get('button:nth-child(1)')
.click()
cy.get('.ProseMirror')
@ -47,14 +47,14 @@ context('/demos/Nodes/TaskList', () => {
cy.get('.ProseMirror ul')
.should('not.exist')
cy.get('.demo__preview button:nth-child(1)')
cy.get('button:nth-child(1)')
.click()
cy.get('.ProseMirror')
.find('ul[data-type="taskList"]')
.should('contain', 'Example Text')
cy.get('.demo__preview button:nth-child(1)')
cy.get('button:nth-child(1)')
.click()
cy.get('.ProseMirror ul')

View File

@ -157,7 +157,7 @@ new Editor({
| `element` | `Element` | `false` | Focus the editor on init. |
| `extensions` | `Array` | `[]` | A list of extensions you would like to use. Can be [`Nodes`](/api/nodes), [`Marks`](/api/marks) or [`Extensions`](/api/extensions). |
| `injectCSS` | `Boolean` | `true` | When set to `false` tiptap wont load [the default ProseMirror CSS](https://github.com/ueberdosis/tiptap-next/tree/main/packages/core/src/style.ts). |
| ~~`parseOptions`~~ | ~~`Object`~~ | ~~`{}`~~ | ~~A list of [Prosemirror parseOptions](https://prosemirror.net/docs/ref/#model.ParseOptions).~~ | --> |
| ~~`parseOptions`~~ | ~~`Object`~~ | ~~`{}`~~ | ~~A list of [Prosemirror parseOptions](https://prosemirror.net/docs/ref/#model.ParseOptions).~~ | -->
## List of available methods
An editor instance will provide the following public methods. Theyll help you to work with the editor.

View File

@ -94,6 +94,6 @@ new Editor({
extensions: [
CustomBulletList(),
// …
]
],
})
```

View File

@ -1,6 +1,6 @@
# Emoji
:::pro Fund the development 💖
:::pro Fund the development ♥️
We need your support to maintain, update, support and develop tiptap 2. If youre waiting for this extension, [become a sponsor and fund open source](/sponsor).
:::

View File

@ -1,6 +1,6 @@
# Hashtag
:::pro Fund the development 💖
:::pro Fund the development ♥️
We need your support to maintain, update, support and develop tiptap 2. If youre waiting for this extension, [become a sponsor and fund open source](/sponsor).
:::

View File

@ -1,6 +1,6 @@
# Accessibility
:::pro Fund the development 💖
:::pro Fund the development ♥️
We need your support to maintain, update, support and develop tiptap 2. If youre waiting for progress here, [become a sponsor and fund open source](/sponsor).
:::

View File

@ -28,7 +28,7 @@ new Editor({
extensions: [
CustomBulletList(),
// …
]
],
})
```

View File

@ -99,9 +99,9 @@ const CustomBold = Bold.extend({
new Editor({
extensions: [
// …
CustomBold(),
]
// …
CustomBold(),
],
})
```

View File

@ -69,4 +69,4 @@ Most editor toolbars use icons for their buttons. In some of our demos, we use t
* [Font Awesome](https://fontawesome.com/icons?c=editors)
* [UI icons](https://www.ibm.com/design/language/iconography/ui-icons/library/)
Also, were working on providing a configurable interface for tiptap. If you think thats a great idea, [become a sponsor](/sponsor) to show us your support. 💖
Also, were working on providing a configurable interface for tiptap. If you think thats a great idea, [become a sponsor](/sponsor) to show us your support. ♥️

View File

@ -172,4 +172,4 @@ Read more about [the new collaborative editing experience](/guide/collaborative-
### Become a sponsor
tiptap wouldnt exist without the funding of its community. If you fell in love with tiptap, dont forget to [become a sponsor](/sponsor) and make the maintenance, development and support sustainable.
In exchange, well take you into our hearts, invite you to private repositories, add a `sponsor 💖` label to your issues and pull requests and more.
In exchange, well take you into our hearts, invite you to private repositories, add a `sponsor ♥️` label to your issues and pull requests and more.

View File

@ -1,13 +1,13 @@
# Become a sponsor
To deliver a top-notch developer experience and user experience, we put ~~hundreds~~ thousands of hours of unpaid work into tiptap. Your funding helps us to make this work more and more financially sustainable. This enables us to provide helpful support, maintain all our packages, keep everything up to date, and develop new features and extensions for tiptap.
Give back to the open source community and [sponsor us on GitHub](https://github.com/sponsors/ueberdosis)! 💖
Give back to the open source community and [sponsor us on GitHub](https://github.com/sponsors/ueberdosis)! ♥️
## Your benefits as a sponsor
* Give back to the open source community
* Get early access to private repositories
* Ensure the further maintenace and development of tiptap
* Your issues and pull requests get a `sponsor 💖` label
* Your issues and pull requests get a `sponsor ♥️` label
* Get a sponsor badge in all your comments on GitHub
* Show support in your GitHub profile
* Receive monthly reports about our open source work

View File

@ -2,11 +2,16 @@
<html ${htmlAttrs}>
<head>
${head}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docsearch/css@alpha" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docsearch/css" />
</head>
<body ${bodyAttrs}>
${app}
${scripts}
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@docsearch/js@alpha"></script>
${process.env.NODE_ENV === 'production'
? '<script async defer data-exclude="/demos/**" data-domain="next.tiptap.dev" src="https://plausible.io/js/plausible.exclusions.js"></script>'
: ''
}
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@docsearch/js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.2.11/iframeResizer.contentWindow.min.js" integrity="sha512-FOf4suFgz7OrWmBiyyWW48u/+6GaaAFSDHagh2EBu/GH/1+OQSYc0NFGeGeZK0gZ3vuU1ovmzVzD6bxmT4vayg==" crossorigin="anonymous"></script>
</body>
</html>

View File

@ -28,11 +28,15 @@
border: 4px solid rgba(0, 0, 0, 0);
background-clip: padding-box;
border-radius: 8px;
background-color: rgba($colorWhite, 0);
background-color: rgba($colorBlack, 0);
}
:hover::-webkit-scrollbar-thumb {
background-color: rgba($colorWhite, 0.1);
background-color: rgba($colorBlack, 0.1);
}
::-webkit-scrollbar-thumb:hover {
background-color: rgba($colorBlack, 0.15);
}
::-webkit-scrollbar-button {
@ -45,8 +49,8 @@
background-color: transparent;
}
html {
scroll-behavior: smooth;
::selection {
background: rgba($colorBlue, 0.5);
}
body {
@ -55,13 +59,13 @@ body {
-moz-osx-font-smoothing: grayscale;
line-height: 1.7;
font-feature-settings: 'cv05' 1;
background-color: $colorBlack;
background-color: $colorWhite;
color: $colorText;
}
*[id] {
scroll-margin-top: 6rem;
scroll-snap-margin-top: 6rem;
scroll-margin-top: 2rem;
scroll-snap-margin-top: 2rem;
}
button {
@ -75,14 +79,14 @@ a {
text-decoration: none;
&:hover {
color: $colorWhite;
color: $colorBlack;
}
}
code {
font-family: 'JetBrainsMono', monospace;
padding: 0.1rem 0.3rem;
border-radius: 0.25rem;
border-radius: 0.4rem;
font-size: 0.9rem;
}
@ -91,47 +95,319 @@ code {
color: white;
}
// TODO: Move to examples
// .ProseMirror {
// > * + * {
// margin-top: 0.75em;
// }
// ul,
// ol {
// padding: 0 1rem;
// }
// pre {
// background: $colorBlack;
// color: $colorWhite;
// font-family: 'JetBrainsMono', monospace;
// padding: 0.75rem 1rem;
// border-radius: 0.5rem;
// code {
// color: inherit;
// background: none;
// font-size: 0.8rem;
// }
// }
// img {
// max-width: 100%;
// height: auto;
// }
// hr {
// margin: 1rem 0;
// }
// blockquote {
// padding-left: 1rem;
// border-left: 2px solid rgba($colorBlack, 0.1);
// }
// }
.DocSearch,
.DocSearch-Container {
filter: saturate(0);
}
.DocSearch-Container {
position: fixed !important;
height: 100vh !important;
}
.text {
$spacing: 0.75em;
> p {
&.is-large {
font-size: 1.2rem;
}
}
> div,
> p,
> ul,
> ol,
> blockquote {
margin-top: 2 * $spacing;
margin-bottom: 2 * $spacing;
}
> ul li,
> ol li,
> ul ul,
> ul ol,
> ol ol,
> ol ul {
margin-top: 0.5 * $spacing;
margin-bottom: 0.5 * $spacing;
}
> h1,
> h2,
> h3,
> h4,
> h5,
> h6 {
color: $colorBlack;
margin-top: 3 * $spacing;
margin-bottom: $spacing;
& + * {
margin-top: 0;
}
}
> h1,
> h4,
> h5,
> h6 {
a {
display: none;
}
}
> h1,
> .is-h1 {
font-size: 2rem;
line-height: 1.15;
@media (min-width: 600px) {
font-size: 2.75rem;
}
&.is-large {
font-size: 3rem;
@media (min-width: 600px) {
font-size: 3.75rem;
}
}
}
> h2,
> .is-h2 {
font-size: 1.5rem;
line-height: 1.2;
}
> h2,
> h3 {
position: relative;
a {
position: absolute;
top: 0;
right: 100%;
color: rgba($colorBlack, 0.4);
text-decoration: none;
font-weight: 400;
padding-right: 0.5rem;
opacity: 0;
transition: opacity 0.1s $ease;
}
&:hover a {
opacity: 1;
}
}
> p > img {
max-width: 100%;
border-radius: 0.75rem;
}
:first-child {
margin-top: 0;
}
:last-child {
margin-bottom: 0;
}
> p code,
> ul code,
> ol code,
> .table-wrapper code,
> .remark-container code {
background-color: $colorYellow;
box-decoration-break: clone;
font-weight: 700;
}
> p a,
> ul a,
> ol a,
> .table-wrapper a,
> .remark-container a {
text-decoration: underline;
code {
text-decoration: underline;
}
}
#toc {
display: none;
& + ul {
list-style: none;
border: 3px solid $colorBlack;
padding: 1.25rem !important;
border-radius: 0.75rem;
&::before {
display: block;
content: 'On this page';
font-weight: 700;
letter-spacing: 0.025rem;
font-size: 0.75rem;
text-transform: uppercase;
margin-bottom: 0.5rem;
}
li {
padding-left: 0;
&::before {
display: none;
}
ul {
list-style: none;
margin-left: 1rem;
}
}
}
}
p a img[src^="https://img.shields.io"] {
margin-right: 0.5rem;
}
> ul {
list-style: none;
li {
position: relative;
padding-left: 1.25rem;
&::before {
position: absolute;
left: 0;
display: inline-block;
margin-right: 0.75rem;
content: "\2022";
color: $colorBlack;
}
}
}
> ol {
list-style: none;
counter-reset: item;
li {
position: relative;
padding-left: 2.5rem;
&::before {
position: absolute;
top: 0;
left: 0;
margin-top: 1px;
display: flex;
align-items: center;
justify-content: center;
height: 1.5rem;
width: 1.5rem;
background-color: $colorBlack;
border-radius: 9999px;
color: $colorWhite;
font-size: 0.75rem;
font-weight: 700;
content: counter(item);
counter-increment: item;
}
}
}
> .table-wrapper {
display: block;
width: 100%;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
> table {
width: 100%;
border-collapse: collapse;
font-size: 0.85rem;
text-align: left;
th,
td {
padding: 0.5rem;
min-width: 8rem;
&:first-child {
padding-left: 0;
}
&:last-child {
padding-right: 0;
}
}
th {
white-space: nowrap;
color: $colorBlack;
font-size: 0.9rem;
font-weight: 700;
border-bottom: 3px solid $colorBlack;
}
td {
border-bottom: 1px solid $colorBlack;
}
tr:last-child td {
border-bottom: 0;
}
tbody tr {
&:last-child td {
border-bottom: 0;
}
&:hover {
background: $colorYellow;
}
}
}
}
> .remark-container {
padding: 1rem 1.25rem;
border-radius: 0.75rem;
border: 3px solid $colorBlack;
&.warning {
background-color: $colorYellow;
}
&.info {
background-color: $colorBlue;
}
&.error {
background-color: $colorRed;
}
&.pro {
background-color: $colorBlack;
color: $colorWhite;
}
.remark-container-title {
font-size: 1.1rem;
font-weight: 700;
margin-bottom: 0.25rem;
}
}
> blockquote {
border-left: 1px solid rgba($colorGrey, 0.5);
padding-left: 2 * $spacing;
}
}

View File

@ -112,24 +112,24 @@
;
}
// @font-face {
// font-family: 'Inter';
// font-style: normal;
// font-weight: 700;
// src:
// url("~@/assets/fonts/Inter-Bold.woff2") format("woff2"),
// url("~@/assets/fonts/Inter-Bold.woff") format("woff"),
// ;
// }
// @font-face {
// font-family: 'Inter';
// font-style: italic;
// font-weight: 700;
// src:
// url("~@/assets/fonts/Inter-BoldItalic.woff2") format("woff2"),
// url("~@/assets/fonts/Inter-BoldItalic.woff") format("woff"),
// ;
// }
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 700;
src:
url("~@/assets/fonts/Inter-Bold.woff2") format("woff2"),
url("~@/assets/fonts/Inter-Bold.woff") format("woff"),
;
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 700;
src:
url("~@/assets/fonts/Inter-BoldItalic.woff2") format("woff2"),
url("~@/assets/fonts/Inter-BoldItalic.woff") format("woff"),
;
}
// @font-face {
// font-family: 'Inter';
@ -172,9 +172,19 @@
@font-face {
font-family: 'JetBrainsMono';
font-style: normal;
font-weight: 500;
font-weight: 400;
src:
url("~@/assets/fonts/JetBrainsMono-Regular.woff2") format("woff2"),
url("~@/assets/fonts/JetBrainsMono-Regular.woff") format("woff"),
;
}
@font-face {
font-family: 'JetBrainsMono';
font-style: normal;
font-weight: 700;
src:
url("~@/assets/fonts/JetBrainsMono-Bold.woff2") format("woff2"),
// url("~@/assets/fonts/JetBrainsMono-Bold.woff") format("woff"),
;
}

View File

@ -1,117 +1,110 @@
<template>
<div class="app">
<div class="app__sidebar">
<div class="app__title">
<g-link class="app__name" to="/">
{{ $static.metadata.siteName }}
<div class="app__navigation">
<div class="app__top-bar">
<g-link class="app__logo" to="/">
<img src="~@/assets/images/logo.svg">
</g-link>
<g-link to="https://github.com/ueberdosis/tiptap-next">
<svg
class="app__github"
width="15"
height="15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 15 15"
><path
d="M7.49936 0.849976C3.82767 0.849976 0.849976 3.82727 0.849976 7.5002C0.849976 10.4379 2.75523 12.9306 5.39775 13.8103C5.73047 13.8712 5.85171 13.6658 5.85171 13.4895C5.85171 13.3315 5.846 12.9134 5.84273 12.3586C3.99301 12.7603 3.60273 11.467 3.60273 11.467C3.30022 10.6987 2.86423 10.4942 2.86423 10.4942C2.26044 10.0819 2.90995 10.0901 2.90995 10.0901C3.57742 10.137 3.9285 10.7755 3.9285 10.7755C4.52167 11.7916 5.48512 11.4981 5.86396 11.3278C5.92438 10.8984 6.09625 10.6052 6.28608 10.4391C4.80948 10.2709 3.25695 9.7006 3.25695 7.15238C3.25695 6.42612 3.51618 5.83295 3.94157 5.36797C3.87299 5.19977 3.64478 4.52372 4.00689 3.60804C4.00689 3.60804 4.56494 3.42923 5.83538 4.28938C6.36568 4.14201 6.93477 4.06853 7.50018 4.06567C8.06518 4.06853 8.63386 4.14201 9.16498 4.28938C10.4346 3.42923 10.9918 3.60804 10.9918 3.60804C11.3548 4.52372 11.1266 5.19977 11.0584 5.36797C11.4846 5.83295 11.7418 6.42612 11.7418 7.15238C11.7418 9.70713 10.1868 10.2693 8.70571 10.4338C8.94412 10.6391 9.15681 11.0449 9.15681 11.6654C9.15681 12.5542 9.14865 13.2715 9.14865 13.4895C9.14865 13.6675 9.26867 13.8744 9.60588 13.8095C12.2464 12.9281 14.15 10.4375 14.15 7.5002C14.15 3.82727 11.1723 0.849976 7.49936 0.849976Z"
fill="currentColor"
fill-rule="evenodd"
clip-rule="evenodd"
/></svg>
</g-link>
</div>
<portal-target name="desktop-nav" />
<div class="app__menu">
<span class="app__menu-item">
Search
<div class="app__search-docsearch" />
</span>
<portal-target name="desktop-menu" />
</div>
<button
class="app__menu-icon"
@click="menuIsVisible = true"
v-if="!menuIsVisible"
>
<icon name="menu" />
</button>
<button
class="app__close-icon"
@click="menuIsVisible = false"
v-if="menuIsVisible"
>
<icon name="close" />
</button>
</div>
<div class="app__mobile-menu" v-if="menuIsVisible">
<portal-target name="mobile-menu" />
<portal-target name="mobile-sidebar" />
</div>
</div>
<div class="app__content">
<div class="app__top-bar">
<div class="app__inner app__top-bar-inner">
<div class="app__search">
<div class="app__search-button" />
<div class="app__search-docsearch" />
</div>
<button
class="app__menu-icon"
@click="menuIsVisible = true"
v-if="!menuIsVisible"
>
<icon name="menu" />
</button>
<button
class="app__close-icon"
@click="menuIsVisible = false"
v-if="menuIsVisible"
>
<icon name="close" />
</button>
</div>
<div class="app__mobile-nav" v-if="menuIsVisible">
<portal-target name="mobile-nav" />
</div>
<div class="app__sidebar" v-if="showSidebar">
<portal-target name="desktop-sidebar" />
</div>
<main class="app__main">
<div class="app__inner">
<slot />
</div>
<slot />
</main>
<div class="app__page-navigation">
<div class="app__inner">
<page-navigation />
</div>
</div>
<div class="app__page-footer">
<div class="app__inner">
<a :href="editLink" target="_blank">Edit this page on GitHub</a>
&middot;
Made with 🖤 by <a href="https://twitter.com/_ueberdosis">überdosis</a>
</div>
</div>
<portal :to="menuPortal">
<g-link class="app__menu-item" to="/overview/installation">
Documentation
</g-link>
<g-link class="app__menu-item" to="https://github.com/ueberdosis/tiptap-next">
GitHub
</g-link>
</portal>
<portal :to="sidebarPortal" v-if="showSidebar">
<nav class="app__sidebar-menu">
<div class="app__link-group" v-for="(linkGroup, i) in linkGroups" :key="i">
<div class="app__link-group-title">
{{ linkGroup.title }}
</div>
<ul class="app__link-list">
<li v-for="(item, j) in linkGroup.items" :key="j">
<g-link
:class="{
'app__link': true,
'app__link--exact': $router.currentRoute.path === item.link,
'app__link--active': $router.currentRoute.path.startsWith(item.link),
[`app__link--${item.type}`]: item.type !== null,
'app__link--with-children': !!item.items
}"
:to="item.redirect || item.link"
>
{{ item.title }}
</g-link>
<ul v-if="item.items" class="app__link-list">
<li v-for="(item, k) in item.items" :key="k">
<g-link
:class="{
'app__link': true,
'app__link--exact': $router.currentRoute.path === item.link,
'app__link--active': $router.currentRoute.path.startsWith(item.link),
[`app__link--${item.type}`]: item.type !== null,
}"
:to="item.link"
exact
>
{{ item.title }}
</g-link>
</li>
</ul>
</li>
</ul>
</div>
</nav>
</portal>
</div>
<portal :to="portal">
<nav class="app__navigation">
<div class="app__link-group" v-for="(linkGroup, i) in linkGroups" :key="i">
<div class="app__link-group-title">
{{ linkGroup.title }}
</div>
<ul class="app__link-list">
<li v-for="(item, j) in linkGroup.items" :key="j">
<g-link
:class="{
'app__link': true,
'app__link--exact': $router.currentRoute.path === item.link,
'app__link--active': $router.currentRoute.path.startsWith(item.link),
[`app__link--${item.type}`]: item.type !== null,
'app__link--with-children': !!item.items
}"
:to="item.redirect || item.link"
>
{{ item.title }}
</g-link>
<ul v-if="item.items" class="app__link-list">
<li v-for="(item, k) in item.items" :key="k">
<g-link
:class="{
'app__link': true,
'app__link--exact': $router.currentRoute.path === item.link,
'app__link--active': $router.currentRoute.path.startsWith(item.link),
[`app__link--${item.type}`]: item.type !== null,
}"
:to="item.link"
exact
>
{{ item.title }}
</g-link>
</li>
</ul>
</li>
</ul>
</div>
</nav>
</portal>
<footer class="app__footer">
<a :href="editLink" target="_blank">Edit this page on GitHub</a>
&middot;
Made with 🖤 by <a href="https://twitter.com/_ueberdosis">überdosis</a>
&middot;
Based on <a href="https://prosemirror.net/">ProseMirror by Marijn Haverbeke</a>
</footer>
</div>
</template>
@ -126,13 +119,18 @@ query {
<script>
import linkGroups from '@/links.yaml'
import Icon from '@/components/Icon'
import PageNavigation from '@/components/PageNavigation'
// import GithubButton from 'vue-github-button'
export default {
props: {
showSidebar: {
type: Boolean,
default: true,
},
},
components: {
Icon,
PageNavigation,
// GithubButton,
},
@ -145,12 +143,28 @@ export default {
},
computed: {
portal() {
if (this.windowWidth && this.windowWidth < 800) {
return 'mobile-nav'
menuPortal() {
if (!this.windowWidth) {
return
}
return 'desktop-nav'
if (this.windowWidth < 800) {
return 'mobile-menu'
}
return 'desktop-menu'
},
sidebarPortal() {
if (!this.windowWidth) {
return
}
if (this.windowWidth < 800) {
return 'mobile-sidebar'
}
return 'desktop-sidebar'
},
currentPath() {
@ -159,13 +173,20 @@ export default {
editLink() {
const { currentPath } = this
const filePath = currentPath === '' ? '/introduction' : currentPath
if (process.env.NODE_ENV === 'development') {
return `vscode://file${this.cwd}/src/docPages${filePath}.md`
if (currentPath === '') {
return `vscode://file${this.cwd}/src/pages/index.vue`
}
return `vscode://file${this.cwd}/src/docPages${currentPath}.md`
}
return `https://github.com/ueberdosis/tiptap-next/blob/main/docs/src/docPages${filePath}.md`
if (currentPath === '') {
return 'https://github.com/ueberdosis/tiptap-next/blob/main/docs/src/pages/index.vue'
}
return `https://github.com/ueberdosis/tiptap-next/blob/main/docs/src/docPages${currentPath}.md`
},
},
@ -173,6 +194,10 @@ export default {
$route() {
this.menuIsVisible = false
},
windowWidth() {
this.menuIsVisible = false
},
},
methods: {
@ -192,8 +217,11 @@ export default {
},
mounted() {
this.initSearch()
this.handleResize()
// what the hell is wrong with iOS safari
setTimeout(() => {
this.handleResize()
this.initSearch()
}, 10)
window.addEventListener('resize', this.handleResize)
},

View File

@ -45,8 +45,12 @@ pre[class*="language-"] {
color: $colorWhite;
background: $codeBackground;
padding: 1.25rem !important;
border-radius: 0.5rem;
border-radius: 0.75rem;
max-height: unquote("max(300px, 60vh)");
&::-webkit-scrollbar-thumb {
background-color: rgba($colorWhite, 0.2);
}
}
pre[class*="language-"].language-css > code,

View File

@ -3,32 +3,91 @@ $mobileBreakPoint: 600px;
$menuBreakPoint: 800px;
.app {
display: flex;
&__title {
&__navigation {
position: fixed;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 2rem;
flex-direction: column;
z-index: 2;
top: 0;
width: 100%;
max-height: 100vh;
backdrop-filter: blur(10px);
&::after {
content: '';
z-index: -1;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: $colorWhite;
opacity: 0.8;
transform: translate3d(0,0,0);
pointer-events: none;
}
}
&__name {
&__top-bar {
display: flex;
align-items: center;
flex: 0 0 auto;
height: $navHeight;
padding: 0 1rem;
@media (min-width: $mobileBreakPoint) {
padding: 0 2rem;
}
}
&__menu {
display: flex;
align-items: center;
}
&__menu-item {
display: block;
overflow: hidden;
position: relative;
font-weight: 500;
@media (min-width: $menuBreakPoint) {
display: inline-flex;
margin-right: 1.5rem;
&:last-child {
margin-right: 0;
}
}
}
&__content {
display: flex;
position: relative;
z-index: 1;
}
&__logo {
display: inline-flex;
align-items: center;
font-weight: 600;
color: $colorWhite;
color: $colorBlack;
font-size: 1.5rem;
margin-right: auto;
&::after {
content: '2.0 alpha';
display: block;
margin-left: 0.5rem;
font-size: 0.7rem;
letter-spacing: 0.05rem;
text-transform: uppercase;
border-radius: 5px;
border: 1px solid $colorWhite;
padding: 0 0.4em;
@media (min-width: 500px) {
&::after {
content: '2.0 alpha';
display: block;
margin-left: 0.5rem;
font-size: 0.7rem;
font-weight: 700;
letter-spacing: 0.05rem;
text-transform: uppercase;
border-radius: 0.4rem;
border: 2px solid $colorBlack;
padding: 0 0.4em;
}
}
}
@ -45,20 +104,6 @@ $menuBreakPoint: 800px;
&__search {
position: relative;
display: flex;
align-items: center;
width: 100%;
height: 3rem;
overflow: hidden;
background-color: transparent;
border: 1px solid rgba($colorWhite, 0.1);
border-radius: 0.5rem;
padding: 0.5rem 0.75rem;
&::after {
content: 'Search';
color: rgba($colorWhite, 0.5);
}
}
&__search-docsearch {
@ -85,68 +130,44 @@ $menuBreakPoint: 800px;
top: 0;
align-self: flex-start;
padding: 2rem;
padding-top: $navHeight + 2rem;
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
overscroll-behavior: contain;
border-right: 1px solid rgba($colorWhite, 0.1);
}
}
&__content {
flex: 1 1 auto;
min-width: 0;
}
&__top-bar {
display: flex;
flex-direction: column;
padding: 1rem 0;
position: sticky;
z-index: 2;
top: 0;
backdrop-filter: blur(10px);
max-height: 100vh;
&__sidebar-menu {
margin-top: 1.5rem;
@media (min-width: $menuBreakPoint) {
padding: 1.5rem 0;
}
&::after {
content: '';
z-index: -1;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: $colorBlack;
opacity: 0.8;
transform: translate3d(0,0,0);
pointer-events: none;
margin-top: 0;
}
}
&__top-bar-inner {
width: 100%;
display: flex;
align-items: center;
flex: 0 0 auto;
&__main {
flex: 1 1 auto;
min-width: 0;
padding-top: $navHeight;
overflow: hidden;
}
&__menu-icon,
&__close-icon {
display: flex;
flex: 0 0 auto;
padding: 0.5rem;
background: transparent;
border: 0;
color: $colorText;
margin-left: 1rem;
margin-left: 1.5rem;
margin-right: -0.5rem;
transition: color 0.2s $ease;
&:hover {
color: $colorWhite;
color: $colorBlack;
}
@media (min-width: $menuBreakPoint) {
@ -154,20 +175,10 @@ $menuBreakPoint: 800px;
}
}
&__inner {
margin: 0 auto;
max-width: 50rem;
padding: 0 1rem;
@media (min-width: $mobileBreakPoint) {
padding: 0 2rem;
}
}
&__link-group {
margin-bottom: 1rem;
margin-bottom: 1.5rem;
@media (min-width: $mobileBreakPoint) {
@media (min-width: $menuBreakPoint) {
margin-bottom: 2rem;
}
}
@ -177,7 +188,6 @@ $menuBreakPoint: 800px;
letter-spacing: 0.025rem;
font-size: 0.75rem;
text-transform: uppercase;
color: rgba($colorWhite, 0.3);
margin-bottom: 0.5rem;
}
@ -191,7 +201,7 @@ $menuBreakPoint: 800px;
margin: 0.5rem 0;
}
&__mobile-nav &__link-list &__link-list {
&__mobile-menu &__link-list &__link-list {
display: block;
}
@ -199,110 +209,105 @@ $menuBreakPoint: 800px;
display: block;
}
&__mobile-menu &__menu-item {
margin-bottom: 1.5rem;
&:last-child {
margin-bottom: 0;
}
}
&__link {
display: flex;
justify-content: space-between;
padding: 0.25rem 0.5rem;
border-radius: 5px;
border-radius: 0.4rem;
font-size: 0.85rem;
margin-left: -0.5rem;
white-space: nowrap;
&:hover {
color: $colorWhite;
color: $colorBlack;
}
&--exact {
color: $colorWhite;
background-color: rgba($colorWhite, 0.05);
font-weight: 700;
color: $colorBlack;
background-color: rgba($colorBlack, 0.05);
}
&--draft {
color: rgba($colorWhite, 0.4);
color: rgba($colorBlack, 0.4);
&::after {
content: 'draft';
font-family: 'JetBrainsMono', monospace;
content: 'DRAFT';
display: inline-flex;
align-items: center;
font-family: "JetBrainsMono", monospace;
font-weight: 700;
text-transform: uppercase;
color: $colorGrey;
background-color: rgba($colorGrey, 0.1);
padding: 0 0.5em;
border-radius: 5px;
background-color: rgba($colorBlack, 0.05);
font-size: 0.75rem;
padding: 0 0.4rem;
border-radius: 0.4rem;
}
}
&--pro {
&::after {
content: 'PRO';
font-family: 'JetBrainsMono', monospace;
content: "PRO";
display: inline-flex;
align-items: center;
font-family: "JetBrainsMono", monospace;
font-weight: 700;
text-transform: uppercase;
color: $colorOrange;
background-color: rgba($colorOrange, 0.1);
padding: 0 0.5em;
border-radius: 5px;
color: $colorWhite;
background-color: $colorBlack;
font-size: 0.75rem;
padding: 0 0.4rem;
border-radius: 0.4rem;
}
}
&--new {
&::after {
content: 'NEW';
font-family: 'JetBrainsMono', monospace;
display: inline-flex;
align-items: center;
font-family: "JetBrainsMono", monospace;
font-weight: 700;
text-transform: uppercase;
color: $colorGreen;
background-color: rgba($colorGreen, 0.1);
padding: 0 0.5em;
border-radius: 5px;
color: $colorBlack;
background-color: $colorGreen;
font-size: 0.75rem;
padding: 0 0.4rem;
border-radius: 0.4rem;
}
}
&--sponsor {
&::after {
content: '💖';
font-family: 'JetBrainsMono', monospace;
text-transform: uppercase;
content: '♥️';
padding: 0 0.5em;
border-radius: 5px;
}
}
&--with-children::after {
content: '';
font-weight: bold;
color: rgba($colorWhite, 0.2);
color: rgba($colorBlack, 0.2);
position: absolute;
margin-left: -1.5em;
margin-left: -1rem;
}
}
&__mobile-nav &__link--with-children::after {
&__mobile-menu &__link--with-children::after {
display: none;
}
&__main {
padding: 1rem 0;
@media (min-width: $mobileBreakPoint) {
padding: 2rem 0;
}
}
&__page-navigation {
border-top: 1px solid rgba($colorWhite, 0.1);
}
&__page-footer {
font-size: 0.85rem;
padding: 1.5rem 0;
text-align: center;
border-top: 1px solid rgba($colorWhite, 0.1);
a {
text-decoration: underline;
}
}
&__mobile-nav {
padding: 1rem;
&__mobile-menu {
padding: 1rem 0 1rem 1rem;
flex: 1 1 auto;
overflow-x: hidden;
overflow-y: auto;
@ -310,7 +315,16 @@ $menuBreakPoint: 800px;
overscroll-behavior: contain;
@media (min-width: $mobileBreakPoint) {
padding: 2rem;
padding: 1rem 1rem 1rem 2rem;
}
@media (min-width: $menuBreakPoint) {
padding: 2rem 0;
}
}
&__footer {
border-top: 1px solid rgba($colorBlack, 0.1);
padding: 2rem;
}
}

View File

@ -1,7 +1,5 @@
- title: Overview
items:
- title: Introduction
link: /
- title: Installation
link: /overview/installation
- title: Upgrade Guide

View File

@ -3,13 +3,12 @@ import 'prismjs/components/prism-jsx.js'
import 'prismjs/components/prism-typescript.js'
import 'prismjs/components/prism-scss.js'
import PortalVue from 'portal-vue'
import iframeResize from 'iframe-resizer/js/iframeResizer'
import App from '~/layouts/App'
Prism.manual = true
export default function (Vue, { head }) {
head.htmlAttrs = { 'data-theme': 'dark' }
export default function (Vue) {
// fix docsearch
if (typeof window === 'object' && !window.process) {
window.process = {
@ -20,7 +19,36 @@ export default function (Vue, { head }) {
}
Vue.use(PortalVue)
Vue.directive('resize', {
bind: (el, { value = {} }) => {
el.addEventListener('load', () => {
iframeResize({
...value,
messageCallback(messageData) {
if (messageData.message.type !== 'resize') {
return
}
const style = window.getComputedStyle(el.parentElement)
const maxHeight = parseInt(style.getPropertyValue('max-height'), 10)
if (messageData.message.height > maxHeight) {
el.setAttribute('scrolling', 'auto')
} else {
el.setAttribute('scrolling', 'no')
}
el.iFrameResizer.resize()
},
}, el)
})
},
unbind(el) {
el.iFrameResizer.removeListeners()
},
})
Vue.component('Layout', App)
Vue.component('Demo', () => import(/* webpackChunkName: "demo" */ '~/components/Demo'))
Vue.component('LiveDemo', () => import(/* webpackChunkName: "live-demo" */ '~/components/LiveDemo'))
}

266
docs/src/pages/index.vue Normal file
View File

@ -0,0 +1,266 @@
<template>
<Layout :show-sidebar="false">
<app-section>
<div class="text">
<h1 class="is-large">
The headless editor framework for web artisans.
</h1>
<p class="is-large">
tiptap gives you full control about every single aspect of your text editor experience. Its customizable, comes with a ton of extensions, is open-source, has an extensive documentation, and is simply a joy to use. Join our welcoming community and start building cool things! Its free.
</p>
<p>
<g-link to="/overview/installation">
Get Started
</g-link>
<g-link to="https://github.com/ueberdosis/tiptap-next">
View on GitHub
</g-link>
</p>
</div>
</app-section>
<app-section>
<demo name="Examples/CollaborativeEditing" inline />
</app-section>
<app-section>
<feature-list>
<feature-item>
<h3 class="is-h2">
Headless
</h3>
<p>
We dont tell you what a menu should look like or where it should be rendered in the DOM. Thats why tiptap is headless and comes without any CSS. You are in full control over markup, styling and behaviour.
</p>
<p>
<g-link to="/guide/styling">
Styling
</g-link>
</p>
</feature-item>
<feature-item>
<h3 class="is-h2">
Framework-agnostic
</h3>
<p>
No matter what framework you use, youll enjoy tiptap. Out of the box, it works with plain JavaScript and Vue.js, but its also possible to use it in <g-link to="/guide/getting-started/react">
React
</g-link>, Svelte and others.
</p>
<p>
<g-link to="/overview/installation">
Installation
</g-link>
</p>
</feature-item>
<feature-item>
<h3 class="is-h2">
TypeScript
</h3>
<p>
tiptap 2 is written in TypeScript. That helps us to find bugs early and gives you a nice autocomplete for the API (if your IDE supports that) on top of the extensive human written documentation.
</p>
<p>
<g-link to="/guide/typescript">
TypeScript
</g-link>
</p>
</feature-item>
<feature-item>
<h3 class="is-h2">
Collaborative
</h3>
<p>
Real-time collaboration, syncing between different devices and working offline used to be hard. We provide everything you need to keep everything in sync, conflict-free with the power of <g-link to="https://github.com/yjs/yjs">
Y.js
</g-link>. Our production-grade setup requires less than 20 lines of code.
</p>
<p>
<g-link to="/guide/collaborative-editing">
Collaborative editing
</g-link>
</p>
</feature-item>
<feature-item>
<h3 class="is-h2">
Community
</h3>
<p>
Over the years, a lovely community has grown around tiptap. Theres so much content shared, so many people helping out in issues and a ton of community extensions, youll be surprised how much that can help.
</p>
</feature-item>
</feature-list>
</app-section>
<app-section>
<div class="text">
<h2 class="is-h1">
Quickstart
</h2>
<p>
For quick demos or to give it just a spin, grab the latest build from a CDN. Here is a quick example to get you started with tiptap:
</p>
<!-- eslint-disable -->
<prism language="html">&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
&lt;meta charset="UTF-8"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class="element"&gt;&lt;/div&gt;
&lt;script type="module"&gt;
import { Editor } from 'https://cdn.skypack.dev/@tiptap/core?min'
import { defaultExtensions } from 'https://cdn.skypack.dev/@tiptap/starter-kit?min'
const editor = new Editor({
element: document.querySelector('.element'),
extensions: defaultExtensions(),
content: '&lt;p&gt;Hello World :-)&lt;/p&gt;',
})
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</prism>
<!-- eslint-enable -->
<p>
<g-link to="/overview/installation">
Learn More
</g-link>
</p>
</div>
</app-section>
<app-section>
<div class="text">
<h2 class="is-h1">
Who uses tiptap?
</h2>
<logo-list>
<logo-item
title="GitLab"
image="gitlab"
to="https://gitlab.com"
/>
<logo-item
title="Statamic CMS"
image="statamic"
to="https://statamic.com"
/>
<logo-item
title="Twill CMS"
image="twill"
to="https://twill.io"
/>
<logo-item
title="ApostropheCMS"
image="apostrophe"
to="https://apostrophecms.com"
/>
<logo-item
title="Directus CMS"
image="directus"
to="https://directus.io"
/>
<logo-item
title="Nextcloud"
image="nextcloud"
to="https://apps.nextcloud.com/apps/text"
/>
<logo-item
title="ycode"
image="ycode"
to="https://www.ycode.com/"
/>
<logo-item
title="DocIQ"
image="dociq"
to="https://www.dociq.io/"
/>
<!-- <logo-item
title="Scrumpy"
image="scrumpy"
to="https://www.scrumpy.io"
/> -->
</logo-list>
<p>
<g-link to="https://github.com/ueberdosis/tiptap/network/dependents?package_id=UGFja2FnZS0xMzE5OTg0ODc%3D">
And Many More
</g-link>
</p>
</div>
</app-section>
<app-section>
<div class="text">
<h2 class="is-h1">
License
</h2>
<p>
tiptap is licensed under <a href="https://github.com/ueberdosis/tiptap-next/blob/main/LICENSE.md">MIT</a>, so you are free to do whatever you want. If you are using it commercially, do the right thing and <g-link to="/sponsor">
become one of our wonderful sponsors
</g-link> to fund the maintenance, support and development of tiptap now and in the future. Thats all we ask for.
</p>
</div>
</app-section>
</Layout>
</template>
<script>
import AppSection from '@/components/AppSection'
import FeatureList from '@/components/FeatureList'
import FeatureItem from '@/components/FeatureItem'
import LogoList from '@/components/LogoList'
import LogoItem from '@/components/LogoItem'
import Prism from '~/components/Prism'
export default {
components: {
AppSection,
FeatureList,
FeatureItem,
LogoList,
LogoItem,
Prism,
},
metaInfo() {
const title = 'Headless WYSIWYG Text Editor'
return {
title,
meta: [
/* OpenGraph */
{
property: 'og:title',
content: title,
},
{
property: 'og:image',
content: 'https://next.tiptap.dev/og-image.png',
},
/* Twitter */
{
name: 'twitter:title',
content: title,
},
{
name: 'twitter:card',
content: 'summary_large_image',
},
{
name: 'twitter:image',
content: 'https://next.tiptap.dev/og-image.png',
},
{
name: 'twitter:site',
content: '@_ueberdosis',
},
],
}
},
}
</script>

View File

@ -1,38 +0,0 @@
<template>
<Layout>
<div>
<div v-for="(file, i) in this.package.children" :key="i">
<h2>
{{ file.name }}
</h2>
<div v-for="(bla, j) in file.children" :key="j">
<template v-if="['Class', 'Method', 'Module'].includes(bla.kindString)">
<h3>
{{ bla.name }}
</h3>
</template>
</div>
</div>
</div>
</Layout>
</template>
<script>
export default {
// props: {
// package: {
// default: null,
// type: Object
// }
// },
computed: {
package() {
console.log(this.$context.package)
return this.$context.package
},
},
}
</script>
<style lang="scss" src="./style.scss" scoped></style>

View File

@ -1,11 +1,17 @@
<template>
<div class="demo-page">
<demo :name="$context.name" :show-source="false" />
<demo-content :name="$context.name" v-bind="props" />
</div>
</template>
<script>
import DemoContent from '~/components/DemoContent'
export default {
components: {
DemoContent,
},
metaInfo() {
return {
title: this.$context.name,
@ -17,6 +23,63 @@ export default {
],
}
},
data() {
return {
resizeObserver: null,
}
},
methods: {
fromString(value) {
if (typeof value !== 'string') {
return value
}
if (value.match(/^\d*(\.\d+)?$/)) {
return Number(value)
}
if (value === 'true') {
return true
}
if (value === 'false') {
return false
}
if (value === 'null') {
return null
}
return value
},
},
computed: {
props() {
return Object.fromEntries(Object
.entries(this.$route.query)
.map(([key, value]) => [key, this.fromString(value)]))
},
},
mounted() {
this.resizeObserver = new window.ResizeObserver(items => {
if (window.parentIFrame) {
window.parentIFrame.sendMessage({
type: 'resize',
height: items[0].contentRect.height,
})
}
})
this.resizeObserver.observe(document.body)
},
beforeDestroy() {
this.resizeObserver.unobserve(document.body)
},
}
</script>

View File

@ -1,4 +1,3 @@
.demo-page {
max-width: 40rem;
margin: 2rem auto;
padding: 1.25rem;
}

View File

@ -1,8 +1,11 @@
<template>
<Layout>
<div class="doc-page">
<VueRemarkContent class="doc-page__markdown" />
</div>
<app-section>
<VueRemarkContent class="text" />
</app-section>
<app-section>
<page-navigation />
</app-section>
</Layout>
</template>
@ -19,7 +22,15 @@ query($path: String!) {
</page-query>
<script>
import AppSection from '@/components/AppSection'
import PageNavigation from '@/components/PageNavigation'
export default {
components: {
AppSection,
PageNavigation,
},
metaInfo() {
return {
title: this.$page?.docPage?.title,
@ -64,5 +75,3 @@ export default {
},
}
</script>
<style lang="scss" src="./style.scss" scoped></style>

View File

@ -1,287 +0,0 @@
.doc-page {
&__markdown ::v-deep {
$spacing: 0.75em;
> div,
> p,
> ul,
> ol,
> blockquote {
margin-top: 2 * $spacing;
margin-bottom: 2 * $spacing;
}
> ul li,
> ol li,
> ul ul,
> ul ol,
> ol ol,
> ol ul {
margin-top: 0.5 * $spacing;
margin-bottom: 0.5 * $spacing;
}
> h1,
> h2,
> h3,
> h4,
> h5,
> h6 {
font-weight: 500;
color: $colorWhite;
margin-top: 3 * $spacing;
margin-bottom: $spacing;
& + * {
margin-top: 0;
}
}
> h1,
> h4,
> h5,
> h6 {
a {
display: none;
}
}
> h2,
> h3 {
position: relative;
a {
position: absolute;
top: 0;
right: 100%;
color: rgba($colorWhite, 0.4);
text-decoration: none;
font-weight: 400;
padding-right: 0.5rem;
opacity: 0;
transition: opacity 0.1s $ease;
}
&:hover a {
opacity: 1;
}
}
> p > img {
max-width: 100%;
}
:first-child {
margin-top: 0;
}
:last-child {
margin-bottom: 0;
}
> pre {
border: 1px solid rgba($colorWhite, 0.1);
}
> p code,
> ul code,
> ol code,
> .table-wrapper code,
> .remark-container code {
color: $colorYellow;
background-color: rgba($colorYellow, 0.1);
box-decoration-break: clone;
}
> p a,
> ul a,
> ol a,
> .table-wrapper a,
> .remark-container a {
text-decoration: underline;
code {
text-decoration: underline;
}
}
#toc {
display: none;
& + ul {
list-style: none;
border: 1px solid rgba($colorWhite, 0.1);
padding: 1.25rem !important;
border-radius: 0.5rem;
&::before {
display: block;
content: 'On this page';
font-weight: 700;
letter-spacing: 0.025rem;
font-size: 0.75rem;
text-transform: uppercase;
color: rgba($colorWhite, 0.3);
margin-bottom: 0.5rem;
}
li {
padding-left: 0;
&::before {
display: none;
}
ul {
list-style: none;
margin-left: 1rem;
}
}
}
}
p a img[src^="https://img.shields.io"] {
margin-right: 0.5rem;
}
> ul {
list-style: none;
li {
position: relative;
padding-left: 1.25rem;
&::before {
position: absolute;
left: 0;
display: inline-block;
margin-right: 0.75rem;
content: "\2022";
color: $colorYellow;
}
}
}
> ol {
list-style: none;
counter-reset: item;
li {
position: relative;
padding-left: 2.5rem;
&::before {
position: absolute;
top: 0;
left: 0;
margin-top: 1px;
display: flex;
align-items: center;
justify-content: center;
height: 1.5rem;
width: 1.5rem;
background-color: rgba($colorYellow, 0.1);
border-radius: 9999px;
color: $colorYellow;
font-size: 0.75rem;
font-weight: 700;
content: counter(item);
counter-increment: item;
}
}
}
> .table-wrapper {
display: block;
width: 100%;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
> table {
width: 100%;
border-collapse: collapse;
font-size: 0.85rem;
text-align: left;
th,
td {
padding: 0.5rem;
min-width: 8rem;
&:first-child {
padding-left: 0;
}
&:last-child {
padding-right: 0;
}
}
th {
white-space: nowrap;
color: $colorWhite;
font-weight: 500;
border-bottom: 1px solid rgba($colorWhite, 0.2);
}
td {
border-bottom: 1px solid rgba($colorWhite, 0.1);
}
tr:last-child td {
border-bottom: 0;
}
tbody tr {
&:last-child td {
border-bottom: 0;
}
&:hover {
background: rgba($colorWhite, 0.02);
}
}
}
}
> .remark-container {
padding: 1.25rem;
border: 1px solid rgba($colorWhite, 0.1);
border-radius: 0.5rem;
&.warning {
border-color: rgba($colorYellow, 0.1);
background-color: rgba($colorYellow, 0.1);
color: $colorYellow;
}
&.info {
border-color: rgba($colorBlue, 0.1);
background-color: rgba($colorBlue, 0.1);
color: $colorBlue;
}
&.error {
border-color: rgba($colorRed, 0.1);
background-color: rgba($colorRed, 0.1);
color: $colorRed;
}
&.pro {
border-color: rgba($colorOrange, 0.1);
background-color: rgba($colorOrange, 0.1);
color: $colorOrange;
}
.remark-container-title {
font-weight: 600;
}
}
> blockquote {
border-left: 1px solid rgba($colorGrey, 0.5);
padding-left: 2*$spacing;
}
}
}

View File

@ -1,14 +1,14 @@
$colorWhite: #FFF;
$colorBlack: #0D0D0D;
$colorText: rgba($colorWhite, 0.75);
$colorText: rgba($colorBlack, 1);
$colorGrey: #616161;
$colorPurple: #A975FF;
$colorRed: #FB5151;
$colorOrange: #FD9170;
$colorYellow: #FFCB6B;
$colorBlue: #68CEF8;
$colorTeal: #80cbc4;
$colorGreen: #9DEF8F;
$colorPurple: #958DF1;
$colorRed: #F98181;
$colorOrange: #FBBC88;
$colorYellow: #FAF594;
$colorBlue: #70CFF8;
$colorTeal: #94FADB;
$colorGreen: #B9F18D;
/* Default Equations */
$linear: cubic-bezier(0.250, 0.250, 0.750, 0.750);

View File

@ -52,7 +52,6 @@
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript2": "^0.29.0",
"rollup-plugin-vue": "5",
"typedoc": "^0.20.19",
"typescript": "^4.1.3",
"vue": "^2.6.12"
}

1675
yarn.lock

File diff suppressed because it is too large Load Diff