diff --git a/.changeset/little-ears-give.md b/.changeset/little-ears-give.md deleted file mode 100644 index 3039173..0000000 --- a/.changeset/little-ears-give.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@nextlint/svelte': major ---- - -rename gpt plugin to ask diff --git a/README.md b/README.md index 1ac5aae..6036e08 100644 --- a/README.md +++ b/README.md @@ -1,99 +1,331 @@ # Nextlint -Nextlint is a WYSIWYG (What You See Is What You Get) editor built using the "@tiptap" library and developed with Svelte. It provides a user-friendly interface for editing and formatting text, allowing users to create rich content effortlessly. +Rich text editor (WYSIWYG) written in Svelte, using [MeltUI](https://melt-ui.com/) headless UI and [tailwindcss](https://tailwindcss.com/) CSS framework. -- 💻 **Easy-to-use:** The editor provides a simple and intuitive interface, making it easy for users to create and edit content without any technical knowledge. -- ✍️ **Rich Text Editing:** Users can format text using various styles such as bold, italic, underline, headings, lists, and more. -- 🧱 **Extensible:** You can extend the editor's functionality by adding or creating custom extensions, allowing you to integrate additional features or customize the behavior of the editor. -- 🧠 **Integrate openAI,GPT functionality:** Unlocking the Power of Creative and Swift Writing with OpenAI and GPT Support. +Built on top of [tiptap](https://tiptap.dev/) editor(headless editor) and [prosemirror](https://prosemirror.net/). Easy to use, develop and maintain. A prompt engine that helps to integrate with any AI API, and enhance the writing experience. + +Dark/Light theme is supported and customizable. + +## Getting started + +### Install + +```sh +//npm +npm install @nextlint/svelte + +//yarn +yarn add @nextlint/svelte + +//pnmp +npm add @nextlint/svelte +``` + +### Setup +Nexltint editor uses headless svelte components from MeltUI and styles it with tailwindcss. The theme tokens are inherited from [Svelte Shadcn](https://www.shadcn-svelte.com/docs/theming). + +If you already have shadcn setup in your project then you can skip this part. + + +#### 1. Install tailwindcss and postcss: + +```sh +pnpm add -D tailwindcss postcss autoprefixer sass +npx tailwindcss init -p +``` +Now `tailwind.config.js` and `postcss.config.js` are created + +#### 2. Configure tailwind.config.js: + +```js + +// more detail at https://www.shadcn-svelte.com/docs/installation/manual + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + "./src/**/*.{svelte,js}", + "./node_modules/@nextlint/svelte/dist/**/*.{svelte,ts}" + ], + theme: { + extend: { + colors: { + border: "hsl(var(--border) / )", + input: "hsl(var(--input) / )", + ring: "hsl(var(--ring) / )", + background: "hsl(var(--background) / )", + foreground: "hsl(var(--foreground) / )", + primary: { + DEFAULT: "hsl(var(--primary) / )", + foreground: "hsl(var(--primary-foreground) / )", + }, + secondary: { + DEFAULT: "hsl(var(--secondary) / )", + foreground: "hsl(var(--secondary-foreground) / )", + }, + destructive: { + DEFAULT: "hsl(var(--destructive) / )", + foreground: "hsl(var(--destructive-foreground) / )", + }, + muted: { + DEFAULT: "hsl(var(--muted) / )", + foreground: "hsl(var(--muted-foreground) / )", + }, + accent: { + DEFAULT: "hsl(var(--accent) / )", + foreground: "hsl(var(--accent-foreground) / )", + }, + popover: { + DEFAULT: "hsl(var(--popover) / )", + foreground: "hsl(var(--popover-foreground) / )", + }, + card: { + DEFAULT: "hsl(var(--card) / )", + foreground: "hsl(var(--card-foreground) / )", + }, + }, + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", + }, + fontFamily: { + sans: ["Inter"], + }, + }, + }, + plugins: [], +} +``` +Theme can customize via css tokens. The default token is located at [EditorTheme.scss](https://github.com/sveltor/nextlint/blob/main/packages/svelte/src/lib/EditorTheme.scss). + +### Usage: +To use the default theme, you need to wrap your `SvelteEditor` component with `ThemeTheme`: +```svelte + + +
+ + + +
+``` + +The `EditorTheme` basicaly just import the default theme we define in `EditorTheme.scss`: + +```svelte + +//EditorTheme.svelte + + + + +``` + +Nexltint editor uses `nextlint/core`, which is a headless editor with [existing](https://github.com/sveltor/nextlint/blob/main/packages/core/src/editor/starterKit.ts#L57) plugins installed, can be used in any UI framework, compatible with tiptap and prosemirror plugins system. + +Nextlint Svelte itself has some [plugins](https://github.com/sveltor/nextlint/tree/main/packages/svelte/src/lib/plugins) completely written in Svelte and [configurable](https://github.com/sveltor/nextlint/blob/main/packages/svelte/src/lib/Editor.svelte#L2) ## Features -#### Bubble Menu +### Bubble Menu ![Bubble Menu](/source/bubble_menu.png) -#### Slash Menu +### Slash Menu ![Slash Menu](/source/slash_menu.png) -#### Image +### Image Support upload/embed/unsplash api ![Image](/source/image.png) -#### GPT prompt +### AI prompt ![GPT prompt](/source/gpt_prompt.png) -... and many more. +## Options + +| Name | Type | Description | +| :--------------------------------: | :---------------------: | :------------------------------------------------------ | +| **[`content`](#content)** | `Content` | Initialize editor content | +| **[`onChange`](#onChange)** | `(editor:Editor)=>void` | A callback will call when the editor change | +| **[`placeholder?`](#placeholder)** | `String` | The placeholder will be displayed when the editor empty | +| **[`onCreated?`](#onCreated)** | `(editor:Editor)=>void` | A callback will trigger once when the editor is created | +| **[`plugins?`](#plugins)** | `PluginsOptions` | Customize plugins options | +| **[`extensions?`](#extensions)** | `Extensions` | Customize editor extension | + + +### content + +Type: `HTMLContent | JSONContent | JSONContent[] | null` + +Initialize content, can be a JSONContent or a html markup. + +```tsx +// Can be string + + +// which is equal + +``` -## Demo: -https://nextlint-editor.vercel.app/ +### placeholder -*You can find the implementation of the demo in the repostiory at: - https://github.com/sveltor/nextlint/blob/main/packages/svelte/src/routes/%2Bpage.svelte* +Type: `String | undefined` +Default: `undefined` -## Quick start +Placeholder will display when editor content is empty -Install the package: +```svelte + +``` -```sh -//npm -npm install @nextlint/svelte +### onChange -//yarn -yarn add @nextlint/svelte +Type: `(editor: Editor)=>void` -//pnmp -npm add @nextlint/svelte +The callback will fire when the editor changes ( update state or selection ) + +```svelte + +{ + editor=_editor + }} +/> ``` -## Setup +### onCreated + +Type: `(editor: Editor)=>void | undefined` +Default: `undefined` + +The callback will fire once the editor finishes initialize ```svelte - +Type: `PluginOptions | undefined` +Default: `undefined` - - { editor = createdEditor }} - onChange={nextEditor => { editor = nextEditor }} - - - plugins={{ - selectImage: { - handleUpload, - unsplash: { - accessKey: 'UNPLASH_API_KEY' - } - }, - gpt: {query: submitPromt} - }} +```ts +type PluginOptions = { + image?: ImagePluginOptions; + gpt?: AskOptions; + dropCursor?: DropcursorOptions; +}; + +``` + +### plugins.image + +Type: `ImagePluginOptions|undefined` +Default: `undefined` + +Config the handleUpload function and setup API key to fetch images from unsplash + +```svelte +{ + // handle upload here + const blob = new Blob([file]); + const previewUrl = URL.createObjectURL(blob); + return previewUrl; + }, + unsplash: { + accessKey: 'UNPLASH_API_KEY' + } + }, + } +/> +``` + +### plugins.ask - /> - +Type:`AskOptions|undefined` +Default: `undefined` +Trigger prompt in an empty line, get the question from the editor, call the handle function via this config and append the result to the editor. +Allow to integrate with any AI out side the editor. + +```svelte +{ + // config any AI tool to get the result and return + // the result to the editor + return 'result from any AI Backend' + } + } +/> +``` + + +### plugins.dropCursor + +Type: `DropcursorOptions|undefined` +Default: `undefined` + +Config dropCursor color/width/class. + +```svelte + ``` ## Contributing diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index 7fd3f0c..4430f9e 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,11 @@ # @nextlint/editor +## 3.0.0 + +### Major Changes + +- [`83dbe8e`](https://github.com/sveltor/nextlint/commit/83dbe8e070d8bd505dec193ea08b3dbe50b6c7d8) Thanks [@lynhan318](https://github.com/lynhan318)! - rename gpt plugin to ask + ## 2.3.2 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 3595056..698c48d 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@nextlint/svelte", - "version": "2.3.2", + "version": "3.0.0", "scripts": { "playground": "vite dev", "dev": "pnpm dev:package",