From 1fd62032998c091ced8e18064e3157584f44a2cb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 7 Feb 2026 18:04:14 +0000 Subject: [PATCH 1/2] chore(deps): update dependency nuxt to ^4.3.1 --- .templates/template-nuxt/package.json | 2 +- nuxt-full/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.templates/template-nuxt/package.json b/.templates/template-nuxt/package.json index 85434baa0..44524469a 100644 --- a/.templates/template-nuxt/package.json +++ b/.templates/template-nuxt/package.json @@ -10,7 +10,7 @@ "preview": "nuxt preview" }, "dependencies": { - "nuxt": "^4.3.0", + "nuxt": "^4.3.1", "vue": "^3.5.27" }, "devDependencies": { diff --git a/nuxt-full/package.json b/nuxt-full/package.json index 77e9cdf1a..aac2aada7 100644 --- a/nuxt-full/package.json +++ b/nuxt-full/package.json @@ -10,7 +10,7 @@ "preview": "nuxt preview" }, "dependencies": { - "nuxt": "^4.3.0", + "nuxt": "^4.3.1", "prosekit": "^0.17.1", "vue": "^3.5.27" }, From 0f2cfef6aa542064b4680713effe9c1c39fd265f Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Sat, 7 Feb 2026 18:05:04 +0000 Subject: [PATCH 2/2] [autofix.ci] apply automated fixes --- .../editor/examples/minimal/editor.ts | 5 + .../editor/examples/slash-menu/editor.ts | 5 + lit-toolbar/.gitignore | 4 + lit-toolbar/README.md | 15 + lit-toolbar/index.html | 13 + lit-toolbar/package.json | 25 + lit-toolbar/src/app.css | 13 + lit-toolbar/src/app.ts | 18 + .../editor/examples/toolbar/editor.ts | 82 ++++ .../editor/examples/toolbar/extension.ts | 8 + .../editor/examples/toolbar/index.ts | 1 + .../editor/sample/sample-uploader.ts | 54 +++ .../src/components/editor/ui/button/button.ts | 76 +++ .../src/components/editor/ui/button/index.ts | 1 + .../image-upload-popover.ts | 179 +++++++ .../editor/ui/image-upload-popover/index.ts | 1 + .../src/components/editor/ui/toolbar/index.ts | 1 + .../components/editor/ui/toolbar/toolbar.ts | 456 ++++++++++++++++++ lit-toolbar/src/editor.ts | 18 + lit-toolbar/tsconfig.json | 24 + lit-toolbar/vite.config.ts | 6 + 21 files changed, 1005 insertions(+) create mode 100644 lit-toolbar/.gitignore create mode 100644 lit-toolbar/README.md create mode 100644 lit-toolbar/index.html create mode 100644 lit-toolbar/package.json create mode 100644 lit-toolbar/src/app.css create mode 100644 lit-toolbar/src/app.ts create mode 100644 lit-toolbar/src/components/editor/examples/toolbar/editor.ts create mode 100644 lit-toolbar/src/components/editor/examples/toolbar/extension.ts create mode 100644 lit-toolbar/src/components/editor/examples/toolbar/index.ts create mode 100644 lit-toolbar/src/components/editor/sample/sample-uploader.ts create mode 100644 lit-toolbar/src/components/editor/ui/button/button.ts create mode 100644 lit-toolbar/src/components/editor/ui/button/index.ts create mode 100644 lit-toolbar/src/components/editor/ui/image-upload-popover/image-upload-popover.ts create mode 100644 lit-toolbar/src/components/editor/ui/image-upload-popover/index.ts create mode 100644 lit-toolbar/src/components/editor/ui/toolbar/index.ts create mode 100644 lit-toolbar/src/components/editor/ui/toolbar/toolbar.ts create mode 100644 lit-toolbar/src/editor.ts create mode 100644 lit-toolbar/tsconfig.json create mode 100644 lit-toolbar/vite.config.ts diff --git a/lit-minimal/src/components/editor/examples/minimal/editor.ts b/lit-minimal/src/components/editor/examples/minimal/editor.ts index 122b4ad8f..5603677c4 100644 --- a/lit-minimal/src/components/editor/examples/minimal/editor.ts +++ b/lit-minimal/src/components/editor/examples/minimal/editor.ts @@ -35,6 +35,11 @@ export class LitEditor extends LitElement { return this } + override disconnectedCallback() { + this.editor.unmount() + super.disconnectedCallback() + } + override updated(changedProperties: PropertyValues) { super.updated(changedProperties) this.editor.mount(this.ref.value) diff --git a/lit-slash-menu/src/components/editor/examples/slash-menu/editor.ts b/lit-slash-menu/src/components/editor/examples/slash-menu/editor.ts index 2dd8cc1dc..eed4cda64 100644 --- a/lit-slash-menu/src/components/editor/examples/slash-menu/editor.ts +++ b/lit-slash-menu/src/components/editor/examples/slash-menu/editor.ts @@ -38,6 +38,11 @@ export class LitEditor extends LitElement { return this } + override disconnectedCallback() { + this.editor.unmount() + super.disconnectedCallback() + } + override updated(changedProperties: PropertyValues) { super.updated(changedProperties) this.editor.mount(this.ref.value) diff --git a/lit-toolbar/.gitignore b/lit-toolbar/.gitignore new file mode 100644 index 000000000..5d6225c6d --- /dev/null +++ b/lit-toolbar/.gitignore @@ -0,0 +1,4 @@ +node_modules +dist +.next +.svelte-kit diff --git a/lit-toolbar/README.md b/lit-toolbar/README.md new file mode 100644 index 000000000..6f77188cb --- /dev/null +++ b/lit-toolbar/README.md @@ -0,0 +1,15 @@ +# lit-toolbar + +A [ProseKit](https://prosekit.dev) example. + +[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/prosekit/examples/tree/master/lit-toolbar) +[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/prosekit/examples/tree/master/lit-toolbar) + +Run the example locally with: + +```bash +npx degit prosekit/examples/lit-toolbar lit-toolbar +cd lit-toolbar +npm install +npm run dev +``` diff --git a/lit-toolbar/index.html b/lit-toolbar/index.html new file mode 100644 index 000000000..9637b1626 --- /dev/null +++ b/lit-toolbar/index.html @@ -0,0 +1,13 @@ + + + + + + ProseKit + Lit + + + + + + + diff --git a/lit-toolbar/package.json b/lit-toolbar/package.json new file mode 100644 index 000000000..5634ad8db --- /dev/null +++ b/lit-toolbar/package.json @@ -0,0 +1,25 @@ +{ + "name": "example-lit-toolbar", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "build": "tsc && vite build", + "dev": "vite", + "preview": "vite preview" + }, + "dependencies": { + "lit": "^3.3.2", + "prosekit": "^0.17.1" + }, + "devDependencies": { + "@egoist/tailwindcss-icons": "^1.9.2", + "@iconify-json/lucide": "^1.2.89", + "@tailwindcss/vite": "^4.1.18", + "postcss": "^8.5.6", + "tailwindcss": "^4.1.18", + "tw-animate-css": "^1.4.0", + "typescript": "5.9.3", + "vite": "7.3.1" + } +} diff --git a/lit-toolbar/src/app.css b/lit-toolbar/src/app.css new file mode 100644 index 000000000..5d0567ecf --- /dev/null +++ b/lit-toolbar/src/app.css @@ -0,0 +1,13 @@ +@import 'tailwindcss'; +@import 'tw-animate-css'; + +@plugin "@egoist/tailwindcss-icons"; + +body { + height: 100svh; + display: grid; + max-width: 900px; + padding: 16px; + margin-left: auto; + margin-right: auto; +} diff --git a/lit-toolbar/src/app.ts b/lit-toolbar/src/app.ts new file mode 100644 index 000000000..3cbf14f94 --- /dev/null +++ b/lit-toolbar/src/app.ts @@ -0,0 +1,18 @@ +import './app.css' +import './editor' + +import { LitElement, html } from 'lit' +import { customElement } from 'lit/decorators.js' + +@customElement('my-app') +export class MyApp extends LitElement { + createRenderRoot() { + return this + } + + render() { + return html` + + ` + } +} diff --git a/lit-toolbar/src/components/editor/examples/toolbar/editor.ts b/lit-toolbar/src/components/editor/examples/toolbar/editor.ts new file mode 100644 index 000000000..64f4418ac --- /dev/null +++ b/lit-toolbar/src/components/editor/examples/toolbar/editor.ts @@ -0,0 +1,82 @@ +import 'prosekit/basic/style.css' +import 'prosekit/basic/typography.css' + +import '../../ui/toolbar/index' + +import { + html, + LitElement, + type PropertyDeclaration, + type PropertyValues, +} from 'lit' +import { createRef, ref, type Ref } from 'lit/directives/ref.js' +import type { Editor } from 'prosekit/core' +import { createEditor } from 'prosekit/core' + +import { sampleUploader } from '../../sample/sample-uploader' + +import { defineExtension } from './extension' + +export class LitEditor extends LitElement { + static override properties = { + editor: { + state: true, + attribute: false, + } satisfies PropertyDeclaration, + } + + private editor: Editor + private ref: Ref + + constructor() { + super() + + const extension = defineExtension() + this.editor = createEditor({ extension }) + this.ref = createRef() + } + + override createRenderRoot() { + return this + } + + override disconnectedCallback() { + this.editor.unmount() + super.disconnectedCallback() + } + + override updated(changedProperties: PropertyValues) { + super.updated(changedProperties) + this.editor.mount(this.ref.value) + } + + override render() { + return html` +
+ +
+
+
+
+ ` + } +} + +export function registerLitEditor() { + if (customElements.get('lit-editor-example-toolbar')) return + customElements.define('lit-editor-example-toolbar', LitEditor) +} + +declare global { + interface HTMLElementTagNameMap { + 'lit-editor-example-toolbar': LitEditor + } +} diff --git a/lit-toolbar/src/components/editor/examples/toolbar/extension.ts b/lit-toolbar/src/components/editor/examples/toolbar/extension.ts new file mode 100644 index 000000000..1c2b5cbd7 --- /dev/null +++ b/lit-toolbar/src/components/editor/examples/toolbar/extension.ts @@ -0,0 +1,8 @@ +import { defineBasicExtension } from 'prosekit/basic' +import { union } from 'prosekit/core' + +export function defineExtension() { + return union(defineBasicExtension()) +} + +export type EditorExtension = ReturnType diff --git a/lit-toolbar/src/components/editor/examples/toolbar/index.ts b/lit-toolbar/src/components/editor/examples/toolbar/index.ts new file mode 100644 index 000000000..9eeecbbc5 --- /dev/null +++ b/lit-toolbar/src/components/editor/examples/toolbar/index.ts @@ -0,0 +1 @@ +export { LitEditor as ExampleEditor, registerLitEditor } from './editor' diff --git a/lit-toolbar/src/components/editor/sample/sample-uploader.ts b/lit-toolbar/src/components/editor/sample/sample-uploader.ts new file mode 100644 index 000000000..8e86d9210 --- /dev/null +++ b/lit-toolbar/src/components/editor/sample/sample-uploader.ts @@ -0,0 +1,54 @@ +import type { Uploader } from 'prosekit/extensions/file' + +/** + * Uploads the given file to https://tmpfiles.org/ and returns the URL of the + * uploaded file. + * + * This function is only for demonstration purposes. All uploaded files will be + * deleted by the server after 1 hour. + */ +export const sampleUploader: Uploader = ({ + file, + onProgress, +}): Promise => { + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest() + const formData = new FormData() + formData.append('file', file) + + xhr.upload.addEventListener('progress', (event) => { + if (event.lengthComputable) { + onProgress({ + loaded: event.loaded, + total: event.total, + }) + } + }) + + xhr.addEventListener('load', () => { + if (xhr.status === 200) { + try { + const json = JSON.parse(xhr.responseText) as { data: { url: string } } + const url: string = json.data.url.replace( + 'tmpfiles.org/', + 'tmpfiles.org/dl/', + ) + + // Simulate a larger delay + setTimeout(() => resolve(url), 1000) + } catch (error) { + reject(new Error('Failed to parse response', { cause: error })) + } + } else { + reject(new Error(`Upload failed with status ${xhr.status}`)) + } + }) + + xhr.addEventListener('error', () => { + reject(new Error('Upload failed')) + }) + + xhr.open('POST', 'https://tmpfiles.org/api/v1/upload', true) + xhr.send(formData) + }) +} diff --git a/lit-toolbar/src/components/editor/ui/button/button.ts b/lit-toolbar/src/components/editor/ui/button/button.ts new file mode 100644 index 000000000..29d27bccf --- /dev/null +++ b/lit-toolbar/src/components/editor/ui/button/button.ts @@ -0,0 +1,76 @@ +import 'prosekit/lit/tooltip' + +import { html, LitElement, nothing, type PropertyDeclaration } from 'lit' + +class LitButton extends LitElement { + static override properties = { + pressed: { type: Boolean }, + disabled: { type: Boolean }, + tooltip: { type: String }, + icon: { type: String }, + } satisfies Record + + pressed = false + disabled = false + tooltip = '' + icon = '' + + override createRenderRoot() { + return this + } + + override connectedCallback() { + super.connectedCallback() + this.classList.add('contents') + } + + private handleMouseDown = (event: MouseEvent) => { + // Prevent the editor from being blurred when the button is clicked + event.preventDefault() + } + + override render() { + const tooltip = this.tooltip + + return html` + + + + + ${tooltip + ? html` + + ${tooltip} + + ` + : nothing} + + ` + } +} + +customElements.define('lit-editor-button', LitButton) + +declare global { + interface HTMLElementTagNameMap { + 'lit-editor-button': LitButton + } +} diff --git a/lit-toolbar/src/components/editor/ui/button/index.ts b/lit-toolbar/src/components/editor/ui/button/index.ts new file mode 100644 index 000000000..ef28ef97f --- /dev/null +++ b/lit-toolbar/src/components/editor/ui/button/index.ts @@ -0,0 +1 @@ +import './button' diff --git a/lit-toolbar/src/components/editor/ui/image-upload-popover/image-upload-popover.ts b/lit-toolbar/src/components/editor/ui/image-upload-popover/image-upload-popover.ts new file mode 100644 index 000000000..57c1f68f0 --- /dev/null +++ b/lit-toolbar/src/components/editor/ui/image-upload-popover/image-upload-popover.ts @@ -0,0 +1,179 @@ +import 'prosekit/lit/popover' +import '../button/index' + +import { html, LitElement, nothing, type PropertyDeclaration } from 'lit' +import type { Editor } from 'prosekit/core' +import type { Uploader } from 'prosekit/extensions/file' +import type { ImageExtension } from 'prosekit/extensions/image' + +let imageUploadId = 0 + +class LitImageUploadPopover extends LitElement { + static override properties = { + editor: { attribute: false } satisfies PropertyDeclaration, + uploader: { attribute: false } satisfies PropertyDeclaration< + Uploader + >, + tooltip: { type: String }, + disabled: { type: Boolean }, + icon: { type: String }, + } + + editor?: Editor + uploader?: Uploader + tooltip = '' + disabled = false + icon = '' + + private open = false + private url = '' + private file: File | null = null + private ariaId = `lit-image-upload-${imageUploadId++}` + + override createRenderRoot() { + return this + } + + override connectedCallback() { + super.connectedCallback() + this.classList.add('contents') + } + + private handleOpenChange = (event: CustomEvent) => { + const isOpen = event.detail + + if (!isOpen) { + this.deferResetState() + } + + this.open = isOpen + this.requestUpdate() + } + + private handleFileChange = (event: Event) => { + const target = event.target as HTMLInputElement + const selectedFile = target.files?.[0] + + if (selectedFile) { + this.file = selectedFile + this.url = '' + } else { + this.file = null + } + + this.requestUpdate() + } + + private handleUrlChange = (event: Event) => { + const target = event.target as HTMLInputElement + const inputUrl = target.value + + if (inputUrl) { + this.url = inputUrl + this.file = null + } else { + this.url = '' + } + + this.requestUpdate() + } + + private deferResetState() { + setTimeout(() => { + this.url = '' + this.file = null + this.requestUpdate() + }, 300) + } + + private handleSubmit = () => { + const editor = this.editor + if (!editor) return + + if (this.url) { + editor.commands.insertImage({ src: this.url }) + } else if (this.file && this.uploader) { + editor.commands.uploadImage({ file: this.file, uploader: this.uploader }) + } + + this.open = false + this.deferResetState() + this.requestUpdate() + } + + override render() { + return html` + + + + + + + ${!this.file + ? html` + + + ` + : nothing} + ${!this.url + ? html` + + + ` + : nothing} + ${this.url + ? html` + + ` + : nothing} + ${this.file + ? html` + + ` + : nothing} + + + ` + } +} + +customElements.define('lit-editor-image-upload-popover', LitImageUploadPopover) + +declare global { + interface HTMLElementTagNameMap { + 'lit-editor-image-upload-popover': LitImageUploadPopover + } +} diff --git a/lit-toolbar/src/components/editor/ui/image-upload-popover/index.ts b/lit-toolbar/src/components/editor/ui/image-upload-popover/index.ts new file mode 100644 index 000000000..cf1b5dfb3 --- /dev/null +++ b/lit-toolbar/src/components/editor/ui/image-upload-popover/index.ts @@ -0,0 +1 @@ +import './image-upload-popover' diff --git a/lit-toolbar/src/components/editor/ui/toolbar/index.ts b/lit-toolbar/src/components/editor/ui/toolbar/index.ts new file mode 100644 index 000000000..743d96b73 --- /dev/null +++ b/lit-toolbar/src/components/editor/ui/toolbar/index.ts @@ -0,0 +1 @@ +import './toolbar' diff --git a/lit-toolbar/src/components/editor/ui/toolbar/toolbar.ts b/lit-toolbar/src/components/editor/ui/toolbar/toolbar.ts new file mode 100644 index 000000000..ed2034dad --- /dev/null +++ b/lit-toolbar/src/components/editor/ui/toolbar/toolbar.ts @@ -0,0 +1,456 @@ +import '../button/index' +import '../image-upload-popover/index' + +import { + html, + LitElement, + nothing, + type PropertyDeclaration, + type PropertyValues, +} from 'lit' +import type { BasicExtension } from 'prosekit/basic' +import { defineUpdateHandler, type Editor } from 'prosekit/core' +import type { Uploader } from 'prosekit/extensions/file' + +function getToolbarItems(editor: Editor) { + return { + undo: editor.commands.undo + ? { + isActive: false, + canExec: editor.commands.undo.canExec(), + command: () => editor.commands.undo(), + } + : undefined, + redo: editor.commands.redo + ? { + isActive: false, + canExec: editor.commands.redo.canExec(), + command: () => editor.commands.redo(), + } + : undefined, + bold: editor.commands.toggleBold + ? { + isActive: editor.marks.bold.isActive(), + canExec: editor.commands.toggleBold.canExec(), + command: () => editor.commands.toggleBold(), + } + : undefined, + italic: editor.commands.toggleItalic + ? { + isActive: editor.marks.italic.isActive(), + canExec: editor.commands.toggleItalic.canExec(), + command: () => editor.commands.toggleItalic(), + } + : undefined, + underline: editor.commands.toggleUnderline + ? { + isActive: editor.marks.underline.isActive(), + canExec: editor.commands.toggleUnderline.canExec(), + command: () => editor.commands.toggleUnderline(), + } + : undefined, + strike: editor.commands.toggleStrike + ? { + isActive: editor.marks.strike.isActive(), + canExec: editor.commands.toggleStrike.canExec(), + command: () => editor.commands.toggleStrike(), + } + : undefined, + code: editor.commands.toggleCode + ? { + isActive: editor.marks.code.isActive(), + canExec: editor.commands.toggleCode.canExec(), + command: () => editor.commands.toggleCode(), + } + : undefined, + codeBlock: editor.commands.insertCodeBlock + ? { + isActive: editor.nodes.codeBlock.isActive(), + canExec: editor.commands.insertCodeBlock.canExec({ + language: 'javascript', + }), + command: () => + editor.commands.insertCodeBlock({ language: 'javascript' }), + } + : undefined, + heading1: editor.commands.toggleHeading + ? { + isActive: editor.nodes.heading.isActive({ level: 1 }), + canExec: editor.commands.toggleHeading.canExec({ level: 1 }), + command: () => editor.commands.toggleHeading({ level: 1 }), + } + : undefined, + heading2: editor.commands.toggleHeading + ? { + isActive: editor.nodes.heading.isActive({ level: 2 }), + canExec: editor.commands.toggleHeading.canExec({ level: 2 }), + command: () => editor.commands.toggleHeading({ level: 2 }), + } + : undefined, + heading3: editor.commands.toggleHeading + ? { + isActive: editor.nodes.heading.isActive({ level: 3 }), + canExec: editor.commands.toggleHeading.canExec({ level: 3 }), + command: () => editor.commands.toggleHeading({ level: 3 }), + } + : undefined, + horizontalRule: editor.commands.insertHorizontalRule + ? { + isActive: editor.nodes.horizontalRule.isActive(), + canExec: editor.commands.insertHorizontalRule.canExec(), + command: () => editor.commands.insertHorizontalRule(), + } + : undefined, + blockquote: editor.commands.toggleBlockquote + ? { + isActive: editor.nodes.blockquote.isActive(), + canExec: editor.commands.toggleBlockquote.canExec(), + command: () => editor.commands.toggleBlockquote(), + } + : undefined, + bulletList: editor.commands.toggleList + ? { + isActive: editor.nodes.list.isActive({ kind: 'bullet' }), + canExec: editor.commands.toggleList.canExec({ kind: 'bullet' }), + command: () => editor.commands.toggleList({ kind: 'bullet' }), + } + : undefined, + orderedList: editor.commands.toggleList + ? { + isActive: editor.nodes.list.isActive({ kind: 'ordered' }), + canExec: editor.commands.toggleList.canExec({ kind: 'ordered' }), + command: () => editor.commands.toggleList({ kind: 'ordered' }), + } + : undefined, + taskList: editor.commands.toggleList + ? { + isActive: editor.nodes.list.isActive({ kind: 'task' }), + canExec: editor.commands.toggleList.canExec({ kind: 'task' }), + command: () => editor.commands.toggleList({ kind: 'task' }), + } + : undefined, + toggleList: editor.commands.toggleList + ? { + isActive: editor.nodes.list.isActive({ kind: 'toggle' }), + canExec: editor.commands.toggleList.canExec({ kind: 'toggle' }), + command: () => editor.commands.toggleList({ kind: 'toggle' }), + } + : undefined, + indentList: editor.commands.indentList + ? { + isActive: false, + canExec: editor.commands.indentList.canExec(), + command: () => editor.commands.indentList(), + } + : undefined, + dedentList: editor.commands.dedentList + ? { + isActive: false, + canExec: editor.commands.dedentList.canExec(), + command: () => editor.commands.dedentList(), + } + : undefined, + insertImage: editor.commands.insertImage + ? { + isActive: false, + canExec: editor.commands.insertImage.canExec(), + } + : undefined, + } +} + +class LitToolbar extends LitElement { + static override properties = { + editor: { attribute: false } satisfies PropertyDeclaration, + uploader: { attribute: false } satisfies PropertyDeclaration< + Uploader + >, + } + + editor?: Editor + uploader?: Uploader + + private removeUpdateExtension?: VoidFunction + + override createRenderRoot() { + return this + } + + override connectedCallback() { + super.connectedCallback() + this.classList.add('contents') + this.attachEditorListener() + } + + override disconnectedCallback() { + this.detachEditorListener() + super.disconnectedCallback() + } + + override updated(changedProperties: PropertyValues) { + super.updated(changedProperties) + + if (changedProperties.has('editor')) { + this.attachEditorListener() + } + } + + private attachEditorListener() { + this.detachEditorListener() + + if (!this.editor) return + + this.removeUpdateExtension = this.editor.use( + defineUpdateHandler(() => this.requestUpdate()), + ) + } + + private detachEditorListener() { + this.removeUpdateExtension?.() + this.removeUpdateExtension = undefined + } + + override render() { + const editor = this.editor + if (!editor) { + return nothing + } + + const items = getToolbarItems(editor) + + return html` +
+ ${items.undo + ? html` + + ` + : nothing} + ${items.redo + ? html` + + ` + : nothing} + ${items.bold + ? html` + + ` + : nothing} + ${items.italic + ? html` + + ` + : nothing} + ${items.underline + ? html` + + ` + : nothing} + ${items.strike + ? html` + + ` + : nothing} + ${items.code + ? html` + + ` + : nothing} + ${items.codeBlock + ? html` + + ` + : nothing} + ${items.heading1 + ? html` + + ` + : nothing} + ${items.heading2 + ? html` + + ` + : nothing} + ${items.heading3 + ? html` + + ` + : nothing} + ${items.horizontalRule + ? html` + + ` + : nothing} + ${items.blockquote + ? html` + + ` + : nothing} + ${items.bulletList + ? html` + + ` + : nothing} + ${items.orderedList + ? html` + + ` + : nothing} + ${items.taskList + ? html` + + ` + : nothing} + ${items.toggleList + ? html` + + ` + : nothing} + ${items.indentList + ? html` + + ` + : nothing} + ${items.dedentList + ? html` + + ` + : nothing} + ${this.uploader && items.insertImage + ? html` + + ` + : nothing} +
+ ` + } +} + +customElements.define('lit-editor-toolbar', LitToolbar) + +declare global { + interface HTMLElementTagNameMap { + 'lit-editor-toolbar': LitToolbar + } +} diff --git a/lit-toolbar/src/editor.ts b/lit-toolbar/src/editor.ts new file mode 100644 index 000000000..6eed3b264 --- /dev/null +++ b/lit-toolbar/src/editor.ts @@ -0,0 +1,18 @@ +import { registerLitEditor } from './components/editor/examples/toolbar' +import { LitElement, html } from 'lit' +import { customElement } from 'lit/decorators.js' + +registerLitEditor() + +@customElement('my-editor') +export class MyEditor extends LitElement { + createRenderRoot() { + return this + } + + render() { + return html` + + ` + } +} diff --git a/lit-toolbar/tsconfig.json b/lit-toolbar/tsconfig.json new file mode 100644 index 000000000..1de5d357a --- /dev/null +++ b/lit-toolbar/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ES2022", + "experimentalDecorators": true, + "useDefineForClassFields": false, + "module": "ESNext", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"] +} diff --git a/lit-toolbar/vite.config.ts b/lit-toolbar/vite.config.ts new file mode 100644 index 000000000..fb0cdf00b --- /dev/null +++ b/lit-toolbar/vite.config.ts @@ -0,0 +1,6 @@ +import { defineConfig } from 'vite' +import tailwindcss from '@tailwindcss/vite' + +export default defineConfig({ + plugins: [tailwindcss()], +})