diff --git a/.gitignore b/.gitignore
index 294b385..3b462cb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,7 +7,6 @@ node_modules
.wrangler
/.svelte-kit
/build
-/dist
# OS
.DS_Store
diff --git a/README.md b/README.md
index 0849f2b..714f640 100644
--- a/README.md
+++ b/README.md
@@ -48,6 +48,38 @@ This will install svelte-trix as well as the base Trix dependency.
Both of the above examples will produce a simple rich text editor with buttons on the top that looks like this:

+### Using Multiple Editors on the Same Page
+
+When using multiple Trix editors on the same page, you should provide custom IDs to avoid conflicts:
+
+```svelte
+
+
+
+
+
Editor 1
+
+
+
+
+
Editor 2
+
+
+
+```
+
## Props
svelte-trix has typesafe support for all customizations and event listeners that the original Trix library supports, as well as a bindable `value` prop for svelte-ishness.
@@ -59,6 +91,9 @@ svelte-trix has typesafe support for all customizations and event listeners that
| `editor` | `Element` | Bindable prop that exposes the instance of the TrixEditor directly, should you want to perform any customizations or actions that aren't available through props. | Yes |
| `label` | `string` | Optional label for the form. | No |
| `disabled` | `boolean` | Disabled editors are not editable and cannot receive focus. | No |
+| `wrapperId` | `string` | Custom ID for the main wrapper element. Defaults to 'svelte-trix-editor-wrapper'. | No |
+| `hiddenInputId` | `string` | Custom ID for the hidden input element. Defaults to 'svelte-trix-hidden-input'. | No |
+| `editorId` | `string` | Custom ID for the Trix editor element. Defaults to 'svelte-trix-editor'. | No |
| `config` | `ITrixConfig` | Learn more about [Config](#config) | No |
### Event Listeners
diff --git a/dist/Editor.svelte b/dist/Editor.svelte
new file mode 100644
index 0000000..e8a557b
--- /dev/null
+++ b/dist/Editor.svelte
@@ -0,0 +1,411 @@
+
+
+{#if BROWSER}
+
+ {#if label}
+ {label}
+ {/if}
+
+
+
+{/if}
+
+
diff --git a/dist/Editor.svelte.d.ts b/dist/Editor.svelte.d.ts
new file mode 100644
index 0000000..c14c2c8
--- /dev/null
+++ b/dist/Editor.svelte.d.ts
@@ -0,0 +1,26 @@
+import 'trix/dist/trix.css';
+import type { ITrixConfig } from './types.js';
+interface IProps {
+ value?: string;
+ editor?: any;
+ config?: ITrixConfig;
+ onChange?: (value: string) => void;
+ onFileAccept?: (event: Event) => void;
+ onAttachmentAdd?: (event: Event) => void;
+ onAttachmentRemove?: (event: Event) => void;
+ onSelectionChange?: (event: Event) => void;
+ onFocus?: (event: Event) => void;
+ onBlur?: (event: Event) => void;
+ onPaste?: (event: Event) => void;
+ onActionInvoke?: (event: Event) => void;
+ label?: string;
+ disabled?: boolean;
+ required?: boolean;
+ hideAttachmentButton?: boolean;
+ wrapperId?: string;
+ hiddenInputId?: string;
+ editorId?: string;
+}
+declare const Editor: import("svelte").Component;
+type Editor = ReturnType;
+export default Editor;
diff --git a/dist/index.d.ts b/dist/index.d.ts
new file mode 100644
index 0000000..1d8cc7c
--- /dev/null
+++ b/dist/index.d.ts
@@ -0,0 +1 @@
+export { default as TrixEditor } from './Editor.svelte';
diff --git a/dist/index.js b/dist/index.js
new file mode 100644
index 0000000..c0dd8e0
--- /dev/null
+++ b/dist/index.js
@@ -0,0 +1,2 @@
+// Reexport your entry components here
+export { default as TrixEditor } from './Editor.svelte';
diff --git a/dist/types.d.ts b/dist/types.d.ts
new file mode 100644
index 0000000..e5d3cb4
--- /dev/null
+++ b/dist/types.d.ts
@@ -0,0 +1,184 @@
+export interface ITrixConfig {
+ attachments?: Attachments;
+ blockAttributes?: BlockAttributes;
+ browser?: Browser;
+ css?: Css;
+ dompurify?: Dompurify;
+ fileSize?: FileSize;
+ input?: Input;
+ keyNames?: KeyNames;
+ lang?: Lang;
+ parser?: Parser;
+ textAttributes?: TextAttributes;
+ toolbar?: Toolbar;
+ undo?: Undo;
+}
+interface Undo {
+ interval?: number;
+}
+interface Toolbar {
+ getDefaultHTML?: () => any;
+}
+interface TextAttributes {
+ bold?: Bold;
+ italic?: Bold;
+ href?: Href;
+ strike?: Bold;
+ frozen?: Frozen;
+}
+interface Frozen {
+ style?: Style;
+}
+interface Style {
+ backgroundColor?: string;
+}
+interface Href {
+ groupTagName?: string;
+}
+interface Bold {
+ tagName?: string;
+ inheritable?: boolean;
+}
+interface Parser {
+ removeBlankTableCells?: boolean;
+ tableCellSeparator?: string;
+ tableRowSeparator?: string;
+}
+interface Lang {
+ attachFiles?: string;
+ bold?: string;
+ bullets?: string;
+ byte?: string;
+ bytes?: string;
+ captionPlaceholder?: string;
+ code?: string;
+ heading1?: string;
+ indent?: string;
+ italic?: string;
+ link?: string;
+ numbers?: string;
+ outdent?: string;
+ quote?: string;
+ redo?: string;
+ remove?: string;
+ strike?: string;
+ undo?: string;
+ unlink?: string;
+ url?: string;
+ urlPlaceholder?: string;
+ GB?: string;
+ KB?: string;
+ MB?: string;
+ PB?: string;
+ TB?: string;
+}
+interface KeyNames {
+ '8'?: string;
+ '9'?: string;
+ '13'?: string;
+ '27'?: string;
+ '37'?: string;
+ '39'?: string;
+ '46'?: string;
+ '68'?: string;
+ '72'?: string;
+ '79'?: string;
+}
+interface Input {
+ level2Enabled?: boolean;
+}
+interface FileSize {
+ prefix?: string;
+ precision?: number;
+ formatter?: (t3: string) => string;
+}
+interface Dompurify {
+ ADD_ATTR?: string[];
+ SAFE_FOR_XML?: boolean;
+ RETURN_DOM?: boolean;
+}
+interface Css {
+ attachment?: string;
+ attachmentCaption?: string;
+ attachmentCaptionEditor?: string;
+ attachmentMetadata?: string;
+ attachmentMetadataContainer?: string;
+ attachmentName?: string;
+ attachmentProgress?: string;
+ attachmentSize?: string;
+ attachmentToolbar?: string;
+ attachmentGallery?: string;
+}
+interface Browser {
+ composesExistingText?: boolean;
+ recentAndroid?: boolean;
+ samsungAndroid?: boolean;
+ forcesObjectResizing?: boolean;
+ supportsInputEvents?: boolean;
+}
+interface BlockAttributes {
+ default?: Default;
+ quote?: Quote;
+ heading1?: Heading1;
+ code?: Code;
+ bulletList?: Default;
+ bullet?: Bullet;
+ numberList?: Default;
+ number?: Bullet;
+ attachmentGallery?: AttachmentGallery;
+}
+interface AttachmentGallery {
+ tagName?: string;
+ exclusive?: boolean;
+ terminal?: boolean;
+ parse?: boolean;
+ group?: boolean;
+}
+interface Bullet {
+ tagName?: string;
+ listAttribute?: string;
+ group?: boolean;
+ nestable?: boolean;
+}
+interface Code {
+ tagName?: string;
+ terminal?: boolean;
+ htmlAttributes?: string[];
+ text?: Text;
+}
+interface Text {
+ plaintext?: boolean;
+}
+interface Heading1 {
+ tagName?: string;
+ terminal?: boolean;
+ breakOnReturn?: boolean;
+ group?: boolean;
+}
+interface Quote {
+ tagName?: string;
+ nestable?: boolean;
+}
+interface Default {
+ tagName?: string;
+ parse?: boolean;
+}
+interface Attachments {
+ preview?: Preview;
+ file?: File;
+}
+interface File {
+ caption?: Caption2;
+}
+interface Caption2 {
+ size?: boolean;
+}
+interface Preview {
+ presentation?: string;
+ caption?: Caption;
+}
+interface Caption {
+ name?: boolean;
+ size?: boolean;
+}
+export {};
diff --git a/dist/types.js b/dist/types.js
new file mode 100644
index 0000000..cb0ff5c
--- /dev/null
+++ b/dist/types.js
@@ -0,0 +1 @@
+export {};
diff --git a/package-lock.json b/package-lock.json
index 01e3a55..f6ef764 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,16 @@
{
"name": "svelte-trix",
- "version": "0.0.1",
+ "version": "0.0.6",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "svelte-trix",
- "version": "0.0.1",
+ "version": "0.0.6",
+ "license": "MIT",
+ "dependencies": {
+ "trix": "^2.1.15"
+ },
"devDependencies": {
"@eslint/compat": "^1.2.5",
"@eslint/js": "^9.18.0",
diff --git a/src/lib/Editor.svelte b/src/lib/Editor.svelte
index c53d092..e8a557b 100644
--- a/src/lib/Editor.svelte
+++ b/src/lib/Editor.svelte
@@ -4,43 +4,49 @@
import { onMount } from 'svelte';
import type { ITrixConfig } from './types.js';
- interface IProps {
- value?: string;
- editor?: any;
- config?: ITrixConfig;
- onChange?: (value: string) => void;
- onFileAccept?: (event: Event) => void;
- onAttachmentAdd?: (event: Event) => void;
- onAttachmentRemove?: (event: Event) => void;
- onSelectionChange?: (event: Event) => void;
- onFocus?: (event: Event) => void;
- onBlur?: (event: Event) => void;
- onPaste?: (event: Event) => void;
- onActionInvoke?: (event: Event) => void;
- label?: string;
- disabled?: boolean;
- required?: boolean;
- hideAttachmentButton?: boolean;
- }
-
- let {
- value = $bindable(),
- editor = $bindable(),
- onChange = undefined,
- onFileAccept = undefined,
- onAttachmentAdd = undefined,
- onAttachmentRemove = undefined,
- onSelectionChange = undefined,
- onFocus = undefined,
- onBlur = undefined,
- onPaste = undefined,
- onActionInvoke = undefined,
- label = '',
- disabled = false,
- required = false,
- hideAttachmentButton = false,
- config
- }: IProps = $props();
+ interface IProps {
+ value?: string;
+ editor?: any;
+ config?: ITrixConfig;
+ onChange?: (value: string) => void;
+ onFileAccept?: (event: Event) => void;
+ onAttachmentAdd?: (event: Event) => void;
+ onAttachmentRemove?: (event: Event) => void;
+ onSelectionChange?: (event: Event) => void;
+ onFocus?: (event: Event) => void;
+ onBlur?: (event: Event) => void;
+ onPaste?: (event: Event) => void;
+ onActionInvoke?: (event: Event) => void;
+ label?: string;
+ disabled?: boolean;
+ required?: boolean;
+ hideAttachmentButton?: boolean;
+ wrapperId?: string;
+ hiddenInputId?: string;
+ editorId?: string;
+ }
+
+ let {
+ value = $bindable(),
+ editor = $bindable(),
+ onChange = undefined,
+ onFileAccept = undefined,
+ onAttachmentAdd = undefined,
+ onAttachmentRemove = undefined,
+ onSelectionChange = undefined,
+ onFocus = undefined,
+ onBlur = undefined,
+ onPaste = undefined,
+ onActionInvoke = undefined,
+ label = '',
+ disabled = false,
+ required = false,
+ hideAttachmentButton = false,
+ wrapperId = 'svelte-trix-editor-wrapper',
+ hiddenInputId = 'svelte-trix-hidden-input',
+ editorId = 'svelte-trix-editor',
+ config
+ }: IProps = $props();
let Trix: any;
let el = $state();
@@ -289,56 +295,58 @@
};
const _onChange = (e: Event) => {
- value = e?.target?.value;
- if (onChange) {
- onChange(e?.target?.value);
+ if (e.target === el) {
+ value = e?.target?.value;
+ if (onChange) {
+ onChange(e?.target?.value);
+ }
}
};
const _onPaste = (e: Event) => {
- if (onPaste) {
+ if (e.target === el && onPaste) {
onPaste(e);
}
};
const _onAttachmentAdd = (e: Event) => {
- if (onAttachmentAdd) {
+ if (e.target === el && onAttachmentAdd) {
onAttachmentAdd(e);
}
};
const _onAttachmentRemove = (e: Event) => {
- if (onAttachmentRemove) {
+ if (e.target === el && onAttachmentRemove) {
onAttachmentRemove(e);
}
};
const _onFileAccept = (e: Event) => {
- if (onFileAccept) {
+ if (e.target === el && onFileAccept) {
onFileAccept(e);
}
};
const _onSelectionChange = (e: Event) => {
- if (onSelectionChange) {
+ if (e.target === el && onSelectionChange) {
onSelectionChange(e);
}
};
const _onFocus = (e: Event) => {
- if (onFocus) {
+ if (e.target === el && onFocus) {
onFocus(e);
}
};
const _onBlur = (e: Event) => {
- if (onBlur) {
+ if (e.target === el && onBlur) {
onBlur(e);
}
};
const _onActionInvoke = (e: Event) => {
- if (onActionInvoke) {
+ if (e.target === el && onActionInvoke) {
onActionInvoke(e);
}
};
@@ -355,8 +363,8 @@
document.addEventListener('trix-selection-change', _onSelectionChange);
document.addEventListener('trix-action-invoke', _onActionInvoke);
- _editor = document.querySelector('trix-editor');
- editor = document.querySelector('trix-editor');
+ _editor = document.querySelector(`trix-editor#${editorId}`);
+ editor = document.querySelector(`trix-editor#${editorId}`);
};
$effect(() => {
@@ -378,24 +386,24 @@
{#if BROWSER}
-
+
{#if label}
- {label}
+ {label}
{/if}
-
+
{/if}
\ No newline at end of file