{"_id":"@bwly999/lotion","_rev":"1-57f45cc7855e9c0bf0d5659365b0e87f","name":"@bwly999/lotion","dist-tags":{"latest":"0.1.6"},"versions":{"0.1.5":{"name":"@bwly999/lotion","version":"0.1.5","type":"module","main":"lib/lolo.js","types":"types/src/index.d.ts","keywords":["vue","notion","editor","markdown"],"scripts":{"dev":"vite","build":"vue-tsc --noEmit && vite build","preview":"vite preview","test:unit":"vitest","test:e2e":"playwright test","coverage":"vitest run --coverage","build-bundle":"tsc && vite build --mode library && npx tailwind -c ./tailwind.config.cjs -i ./src/index.css -o lib/style.css"},"dependencies":{"@tiptap/extension-link":"^2.0.0-beta.195","@tiptap/extension-placeholder":"^2.0.0-beta.53","@tiptap/starter-kit":"^2.0.0-beta.191","@tiptap/vue-3":"^2.0.0-beta.96","fuse.js":"^6.6.2","oh-vue-icons":"^1.0.0-rc3","uuid":"^8.3.2","vue":"^3.2.37","vue-draggable-next":"^2.1.1"},"devDependencies":{"@babel/types":"^7.18.9","@playwright/test":"^1.25.1","@types/node":"^18.0.6","@types/sortablejs":"^1.13.0","@types/uuid":"^8.3.4","@vitejs/plugin-vue":"^3.0.0","@vitest/coverage-c8":"^0.22.1","@vue/test-utils":"^2.0.2","autoprefixer":"^10.4.7","happy-dom":"^6.0.4","postcss":"^8.4.14","tailwindcss":"^3.1.6","typescript":"^4.6.4","vite":"^3.0.0","vitest":"^0.22.1","vue-tsc":"^0.38.4"},"gitHead":"3ea19c0ed257a6ef5a502a4b324c7f34d7342499","description":"<h1 align=\"center\"><b>🧴 Lotion</b></h1>\r <p align=\"center\">\r   An open-source Notion UI built with Vue 3.\r </p>\r <p align=\"center\">\r   <a href=\"https://lotion.dashibase.com\" target=\"_blank\">Try demo</a>\r </p>\r <p align=\"center\">\r   <a href=\"https://twitt","_id":"@bwly999/lotion@0.1.5","_nodeVersion":"16.13.2","_npmVersion":"8.1.2","dist":{"integrity":"sha512-VHHmK57vi1tMoPnIu9ngTL9uvnNXJ+LGzkPUKVW2pIk+OhuKVGKvO9rJ9IfavnniPY2mKDlhaA0Oll3Phb68mg==","shasum":"2bb61e38a354c642b316519ce15660b3c1287124","tarball":"https://registry.npmjs.org/@bwly999/lotion/-/lotion-0.1.5.tgz","fileCount":3,"unpackedSize":42540,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBU9JnL8F3lvn1qHQbCSBz9SbyvSiDx4HNt0GPyQzZ0LAiB/aRKsrQiNxA76VA6DmeIKrK26ui/AGD19SfXwT2U1MQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjftNdACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoBZhAAilsP64aa+7WwYMZmaI7J2K2NtjAMiUK1xsnLtWVqIjpcyca2\r\n9AKkBdSVI2ws+rQMVIRo3BDE5ArwWbHd7rVDbbrQ3OkeoFdb3Xt9YBoypkg2\r\nTSFdf6fp4pG++HYP+2vJeWFId3Fa/0omwjZ2qwWyz/4V7NW84q6es1UE0tCJ\r\nz+04tpQiWlhk3bg250fd/zHUMJNGD+GB50ltj9eCGlMoF9pZM3Phouqpqbz/\r\n5T7s22za2LSWswOQONg0uGR+uGpxjgxFKNHQ/aLcp9XS7OlafvDyx6dqQJD6\r\nKnKEjmMj5cEPE2giJyqVNynn058v7ykCLQcMNfz41yHMrkNAMpsu35lTMuyT\r\njFRignBlP4+A5MuOREhTgxbMI1jV5qH402iJSg2hKpc76O+Q3aqkozQn98Ll\r\njMZuvKQGl2bgIcqitQpKg8i79A3NH2z56GclwNX7L1CpUmuehrs11uobxclj\r\nEQghZu87BNkK7+QQZ39Mq5ocpXKUjElvWrGroxfZkDgRYEFdrgFtfraIoaMf\r\nEdAvR5cK/75klpVm6MjK0WJlJ4mgBnNmwaTAiUp8zh5tzoWTzGpOS3F3qYPu\r\nyIwU4mMvFmlY3Tyxl5G1ajLm8ssWCnzC+52P17Gw7c6KXVtcPeZCyYwoTRaH\r\nChDizwJ1wvMIhDqyqMD+sYRDojtYjggu82A=\r\n=tJGJ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"bwly999","email":"438225686@qq.com"},"directories":{},"maintainers":[{"name":"bwly999","email":"438225686@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/lotion_0.1.5_1669256029770_0.15733712054401017"},"_hasShrinkwrap":false},"0.1.6":{"name":"@bwly999/lotion","version":"0.1.6","type":"module","main":"lib/lolo.js","types":"types/src/index.d.ts","keywords":["vue","notion","editor","markdown"],"scripts":{"dev":"vite","build":"vue-tsc --noEmit && vite build","preview":"vite preview","test:unit":"vitest","test:e2e":"playwright test","coverage":"vitest run --coverage","build-bundle":"tsc && vite build --mode library && npx tailwind -c ./tailwind.config.cjs -i ./src/index.css -o lib/style.css"},"dependencies":{"@tiptap/extension-link":"^2.0.0-beta.195","@tiptap/extension-placeholder":"^2.0.0-beta.53","@tiptap/starter-kit":"^2.0.0-beta.191","@tiptap/vue-3":"^2.0.0-beta.96","fuse.js":"^6.6.2","oh-vue-icons":"^1.0.0-rc3","uuid":"^8.3.2","vue":"^3.2.37","vue-draggable-next":"^2.1.1"},"devDependencies":{"@babel/types":"^7.18.9","@playwright/test":"^1.25.1","@types/node":"^18.0.6","@types/sortablejs":"^1.13.0","@types/uuid":"^8.3.4","@vitejs/plugin-vue":"^3.0.0","@vitest/coverage-c8":"^0.22.1","@vue/test-utils":"^2.0.2","autoprefixer":"^10.4.7","happy-dom":"^6.0.4","postcss":"^8.4.14","tailwindcss":"^3.1.6","typescript":"^4.6.4","vite":"^3.0.0","vitest":"^0.22.1","vue-tsc":"^0.38.4"},"gitHead":"3ea19c0ed257a6ef5a502a4b324c7f34d7342499","description":"<h1 align=\"center\"><b>🧴 Lotion</b></h1>\r <p align=\"center\">\r   An open-source Notion UI built with Vue 3.\r </p>\r <p align=\"center\">\r   <a href=\"https://lotion.dashibase.com\" target=\"_blank\">Try demo</a>\r </p>\r <p align=\"center\">\r   <a href=\"https://twitt","_id":"@bwly999/lotion@0.1.6","_nodeVersion":"16.13.2","_npmVersion":"8.1.2","dist":{"integrity":"sha512-As/f6ycFMFegrYJkvp6knSpyM4uoiJnW8mJwsdrcaJOb7cDdHXbXa7WUgijMLy7O/pt1CE7KZv6Oc8eRFhIUqA==","shasum":"9eff05b1f1ce902d664e3af38383dd95491e3b84","tarball":"https://registry.npmjs.org/@bwly999/lotion/-/lotion-0.1.6.tgz","fileCount":10,"unpackedSize":1015668,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBg89IHjrzDQBSe1EDAb3tSkZUY3dEXer6O6NLM6aqA/AiEA29nsV60ohpXEF3BolAB/iJhWUHSJii09SfaGOo3xfVs="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfuRiACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmow9g//WiOcG4iJT+K0FxClZobzLH9NnRDXkwuSIGEarBn/RYchJEsH\r\nl143jULwLVjUwhX0we8hHjAMZPCC7BAh6AifWzdmlaC41hZJ6rV5BVD0E/fF\r\nJ7rXpDE9mFPOUDlFlpb01CRIDVcLjDdL0vTWtdYMz/Rr1tSiC97uSv/OVAVg\r\nDDeMhEBFK92NjDroEclTL7QWte3ZTMRx165fEcNFrK6jIeFmfvm89TvLojiv\r\njd3MwTc7H//aBgnsXZSeF04kPS08l+UAAmXGhKuLTQHNgQ2PaBzCEVsN0XiF\r\nWhZRzWtNvvmHMwRpjpkgfLWxX1fbae12B9iEeWLHnZGB8HKKPy42zxQc3L3O\r\nRdEzsLC5yYkIwsXuLyrPKjcvl7fLtjAx0gMUnfsT/Vu1YD9tmr7MMgpszuGr\r\niobne2a6o3RZVA/mLZmn/w2zKuQAI32ezlHQrRRCC6twxdXjt4WqidXovAoJ\r\nIWO3zDKka0elDs9z8qVsmDvo82IxrUKgtLx0yANwjaJAwfFdr/UwsUK1CZwd\r\n73fzXGQysUiBMcgU8HQH1fMJSdor9vLyB4smR35BA0AQtCpHFJpc5y5BZ+4D\r\ngl3oQWbyMXj1+4V5L4S2/8jZC9SHQrWLWfIE0t6OhzZwrtYLLbgIJgr/lIpF\r\n5+rBRx1jUAS5OKBc4gX/jF8w1zC4RlqFR5k=\r\n=J1hx\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"bwly999","email":"438225686@qq.com"},"directories":{},"maintainers":[{"name":"bwly999","email":"438225686@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/lotion_0.1.6_1669260386412_0.01080117138168446"},"_hasShrinkwrap":false}},"time":{"created":"2022-11-24T02:13:49.700Z","0.1.5":"2022-11-24T02:13:49.947Z","modified":"2022-11-24T03:26:26.678Z","0.1.6":"2022-11-24T03:26:26.595Z"},"maintainers":[{"name":"bwly999","email":"438225686@qq.com"}],"description":"<h1 align=\"center\"><b>🧴 Lotion</b></h1>\r <p align=\"center\">\r   An open-source Notion UI built with Vue 3.\r </p>\r <p align=\"center\">\r   <a href=\"https://lotion.dashibase.com\" target=\"_blank\">Try demo</a>\r </p>\r <p align=\"center\">\r   <a href=\"https://twitt","keywords":["vue","notion","editor","markdown"],"readme":"<h1 align=\"center\"><b>🧴 Lotion</b></h1>\r\n<p align=\"center\">\r\n  An open-source Notion UI built with Vue 3.\r\n</p>\r\n<p align=\"center\">\r\n  <a href=\"https://lotion.dashibase.com\" target=\"_blank\">Try demo</a>\r\n</p>\r\n<p align=\"center\">\r\n  <a href=\"https://twitter.com/intent/follow?screen_name=dashibase\">\r\n    <img src=\"https://img.shields.io/twitter/follow/dashibase?style=social&logo=twitter\" alt=\"follow on Twitter\">\r\n  </a>\r\n  <a href=\"https://discord.gg/HjJCwm5\">\r\n    <img src=\"https://img.shields.io/discord/995844576013201449?logo=discord&logoColor=b0b7ff&color=5865f2\" alt=\"chat on Discord\">\r\n  </a>\r\n  <img src=\"https://img.shields.io/github/license/dashibase/lotion?color=green\" />\r\n  <a href=\"https://www.npmjs.com/package/@dashibase/lotion\">\r\n    <img src=\"https://img.shields.io/npm/v/@dashibase/lotion\" />\r\n  </a>\r\n  <br />\r\n</p>\r\n\r\n> We shared about Lotion and recreating the Notion UI during [CityJS Singapore's pre-conference meetup on 27th July](https://twitter.com/dashibase/status/1554070309224861696?s=20&t=f9pkIgoxYUCgAL5tRTxK4Q)!\r\n\r\n<p align=\"center\">\r\n  <img src=\"https://github.com/Dashibase/lotion/blob/main/assets/lotion.png\" style=\"border-radius: 10px;\" />\r\n</p>\r\n\r\n## Features\r\n\r\n- [x] Block-based editor\r\n- [x] Drag to reorder blocks\r\n- [x] Basic Markdown-parsing including bold, italic, headings and divider\r\n- [x] Type '/' for command menu and shortcuts\r\n- [x] Register your own blocks\r\n- [x] Read-only mode\r\n\r\n## Getting Started\r\n\r\n**1. Install package**\r\n\r\n```bash\r\nnpm i @dashibase/lotion\r\n```\r\n\r\n**2. Basic Lotion editor**\r\n\r\nThe following Vue component will initialize a basic Lotion editor.\r\n\r\n```javascript\r\n<template>\r\n  <Lotion :page=\"page\" />\r\n</template>\r\n<script setup lang=\"ts\">\r\nimport { ref } from 'vue'\r\nimport { v4 as uuidv4 } from 'uuid'\r\nimport { Lotion, registerBlock } from '@dashibase/lotion'\r\n\r\nconst page = ref({\r\n  name: '🧴 Lotion',\r\n  blocks:[{\r\n    id: uuidv4(),\r\n    type: 'TEXT',\r\n    details: {\r\n      value: 'Hello, World!'\r\n    },\r\n  }],\r\n})\r\n</script>\r\n```\r\n\r\n**3. Create custom components**\r\n\r\nSee `examples/CustomBlock.vue` for an example of a custom block.\r\n\r\nThe custom block component can accept the following props:\r\n- `block`: A `Block` object. See `src/utils/types.ts` for details.\r\n- `readonly`: A boolean, which sets whether the block/editor is in read-only mode.\r\n\r\nThe custom block component can also optionally expose the following methods (remember to call `defineExpose`):\r\n- `onSet`: This is triggered when a user converts any block into this blocktype. It is called before the blocktype is changed.\r\n- `onUnset`: This is triggered when a user converts this block into any blocktype. It is called before the blocktype is changed.\r\n\r\n```javascript\r\n<template>\r\n  <div>\r\n    🧴\r\n  </div>\r\n</template>\r\n<script setup lang=\"ts\">\r\nimport { PropType } from 'vue'\r\nimport { types } from '../src'\r\n\r\nconst props = defineProps({\r\n  block: {\r\n    type: Object as PropType<types.Block>,\r\n    required: true,\r\n  },\r\n  readonly: {\r\n    type: Boolean,\r\n    default: false,\r\n  },\r\n})\r\n\r\nfunction onSet () {\r\n  alert('Moisturizing...')\r\n}\r\n\r\nfunction onUnset () {\r\n  alert('Moisturized!')\r\n}\r\n\r\ndefineExpose({\r\n  onSet,\r\n  onUnset,\r\n})\r\n</script>\r\n\r\n```\r\n\r\n**4. Register custom components**\r\n\r\nSee `examples/Example.vue` for an example of registering a custom block.\r\n\r\nAfter creating the custom component, register it as follows:\r\n\r\n```javascript\r\nimport CustomBlock from './CustomBlock.vue'\r\nimport { addIcons } from \"oh-vue-icons\"\r\nimport { FaPumpSoap } from \"oh-vue-icons/icons\"\r\nimport { registerBlock } from '@dashibase/lotion'\r\n\r\n// Add the icon (from oh-vue-icons.js.org/)\r\naddIcons(FaPumpSoap)\r\n// Register the block\r\n// registerBlock('<BLOCK_TYPE_ID>', '<BLOCK_TYPE_LABEL>', <BLOCK_COMPONENT>, 'BLOCK_ICON')\r\nregisterBlock('LOTION', 'Moisturize', CustomBlock, 'fa-pump-soap')\r\n</script>\r\n```\r\n\r\nAfter that, you should be able to see the custom block when the user opens the menu to switch to different blocks.\r\n\r\n## Contributing\r\n\r\n**1. Clone this repository, go to the root directory and install packages**\r\n\r\n```bash\r\ngit clone https://github.com/dashibase/lotion\r\ncd lotion\r\nnpm i\r\n```\r\n\r\n**2. Run dev**\r\n\r\n```bash\r\nnpm run dev\r\n```\r\n\r\nIf you head to http://localhost:5173 on your browser, you should see what looks like the screenshot above.\r\n\r\n**3. Contribute!**\r\n\r\nLotion is quite limited for now but we hope it serves as a good starting point for other folks looking to build their own editors.\r\n\r\nWe would love to make Lotion more extensible and welcome any suggestions or contributions!\r\n\r\nSee CONTRIBUTING.md for details.\r\n\r\n## Acknowledgements\r\n\r\nThis was made much easier with the following libraries and frameworks, thank you!\r\n\r\n- [vue-draggable-next](https://github.com/anish2690/vue-draggable-next)\r\n- [tiptap](https://tiptap.dev/) and [ProseMirror](https://prosemirror.net/)\r\n- [Vue 3](https://vuejs.org/)\r\n- [Vite](https://vitejs.dev/)\r\n- [TypeScript](https://www.typescriptlang.org/)\r\n- [Tailwind CSS](https://tailwindcss.com/)\r\n- [Headless UI](https://headlessui.dev/)\r\n- [Oh, Vue Icons!](https://oh-vue-icons.js.org/)\r\n- [Vitest](https://vitest.dev/)\r\n- [Playwright](https://playwright.dev/)\r\n","readmeFilename":"README.md"}