Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/dashibase/lotion
An open-source Notion UI built with Vue 3
https://github.com/dashibase/lotion
editorjs hacktoberfest markdown notion vue
Last synced: 5 days ago
JSON representation
An open-source Notion UI built with Vue 3
- Host: GitHub
- URL: https://github.com/dashibase/lotion
- Owner: Dashibase
- License: gpl-3.0
- Created: 2022-07-25T04:47:59.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2023-06-11T05:37:29.000Z (over 1 year ago)
- Last Synced: 2025-01-03T22:08:21.763Z (5 days ago)
- Topics: editorjs, hacktoberfest, markdown, notion, vue
- Language: Vue
- Homepage:
- Size: 1.63 MB
- Stars: 2,809
- Watchers: 23
- Forks: 132
- Open Issues: 21
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
๐งด Lotion
An open-source Notion UI built with Vue 3.
> 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)!
## Features
- [x] Block-based editor
- [x] Drag to reorder blocks
- [x] Basic Markdown-parsing including bold, italic, headings and divider
- [x] Type '/' for command menu and shortcuts
- [x] Register your own blocks
- [x] Read-only mode## Getting Started
**1. Install package**
```bash
npm i @dashibase/lotion
```**2. Basic Lotion editor**
The following Vue component will initialize a basic Lotion editor.
```javascript
import { ref } from 'vue'
import { v4 as uuidv4 } from 'uuid'
import { Lotion, registerBlock } from '@dashibase/lotion'const page = ref({
name: '๐งด Lotion',
blocks:[{
id: uuidv4(),
type: 'TEXT',
details: {
value: 'Hello, World!'
},
}],
})```
**3. Create custom components**
See `examples/CustomBlock.vue` for an example of a custom block.
The custom block component can accept the following props:
- `block`: A `Block` object. See `src/utils/types.ts` for details.
- `readonly`: A boolean, which sets whether the block/editor is in read-only mode.The custom block component can also optionally expose the following methods (remember to call `defineExpose`):
- `onSet`: This is triggered when a user converts any block into this blocktype. It is called before the blocktype is changed.
- `onUnset`: This is triggered when a user converts this block into any blocktype. It is called before the blocktype is changed.```javascript
๐งด
import { PropType } from 'vue'
import { types } from '../src'const props = defineProps({
block: {
type: Object as PropType<types.Block>,
required: true,
},
readonly: {
type: Boolean,
default: false,
},
})function onSet () {
alert('Moisturizing...')
}function onUnset () {
alert('Moisturized!')
}defineExpose({
onSet,
onUnset,
})```
**4. Register custom components**
See `examples/Example.vue` for an example of registering a custom block.
After creating the custom component, register it as follows:
```javascript
import CustomBlock from './CustomBlock.vue'
import { addIcons } from "oh-vue-icons"
import { FaPumpSoap } from "oh-vue-icons/icons"
import { registerBlock } from '@dashibase/lotion'// Add the icon (from oh-vue-icons.js.org/)
addIcons(FaPumpSoap)
// Register the block
// registerBlock('', '', , 'BLOCK_ICON')
registerBlock('LOTION', 'Moisturize', CustomBlock, 'fa-pump-soap')```
After that, you should be able to see the custom block when the user opens the menu to switch to different blocks.
## Contributing
**1. Clone this repository, go to the root directory and install packages**
```bash
git clone https://github.com/dashibase/lotion
cd lotion
npm i
```**2. Run dev**
```bash
npm run dev
```If you head to http://localhost:5173 on your browser, you should see what looks like the screenshot above.
**3. Contribute!**
Lotion is quite limited for now but we hope it serves as a good starting point for other folks looking to build their own editors.
We would love to make Lotion more extensible and welcome any suggestions or contributions!
See CONTRIBUTING.md for details.
## Acknowledgements
This was made much easier with the following libraries and frameworks, thank you!
- [vue-draggable-next](https://github.com/anish2690/vue-draggable-next)
- [tiptap](https://tiptap.dev/) and [ProseMirror](https://prosemirror.net/)
- [Vue 3](https://vuejs.org/)
- [Vite](https://vitejs.dev/)
- [TypeScript](https://www.typescriptlang.org/)
- [Tailwind CSS](https://tailwindcss.com/)
- [Headless UI](https://headlessui.dev/)
- [Oh, Vue Icons!](https://oh-vue-icons.js.org/)
- [Vitest](https://vitest.dev/)
- [Playwright](https://playwright.dev/)