# lotion **Repository Path**: mirrors_trending/lotion ## Basic Information - **Project Name**: lotion - **Description**: An open-source Notion UI built with Vue 3. - **Primary Language**: Unknown - **License**: GPL-3.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 2 - **Created**: 2022-07-30 - **Last Updated**: 2026-05-02 ## Categories & Tags **Categories**: webui **Tags**: None ## README

🧴 Lotion

An open-source Notion UI built with Vue 3.

Try demo

follow on Twitter chat on Discord

> 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 ``` **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 ``` **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/)