diff --git a/ReadMe.md b/ReadMe.md
index a65a52e..433b6e4 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -7,6 +7,13 @@
[![NPM](https://nodei.co/npm/file-cell.png?downloads=true&downloadRank=true&stars=true)][6]
+## Versions
+
+| SemVer | status | ES decorator | MobX | Quill |
+| :-----: | :----------: | :----------: | :---------: | :---: |
+| `>=0.2` | ✅developing | stage-3 | `>=6.11` | v2 |
+| `<0.2` | ❌deprecated | stage-2 | `>=4 <6.11` | v1 |
+
## Usage
```tsx
diff --git a/package.json b/package.json
index 21d1200..b1e86e5 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "quill-cell",
- "version": "0.1.0",
+ "version": "0.2.0",
"license": "LGPL-3.0",
"author": "shiy2008@gmail.com",
"description": "HTML Rich-text editor element based on Web Components, WebCell v2 & Quill.",
diff --git a/source/Editor.tsx b/source/Editor.tsx
deleted file mode 100644
index 9b73620..0000000
--- a/source/Editor.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { observable } from 'mobx';
-import Quill from 'quill';
-import { WebCell, attribute, component, observer } from 'web-cell';
-
-export interface QuillCell extends WebCell {}
-
-@component({
- tagName: 'quill-cell',
- mode: 'open'
-})
-@observer
-export class QuillCell extends HTMLElement implements WebCell {
- core: Quill;
-
- @attribute
- @observable
- accessor theme: 'bubble' | 'snow' = 'snow';
-
- mountedCallback() {
- const { theme } = this;
-
- this.core = new Quill(
- this.shadowRoot.lastElementChild as HTMLDivElement,
- { theme }
- );
- }
-
- render() {
- const { theme } = this;
-
- return (
- <>
-
-
- >
- );
- }
-}
diff --git a/source/index.tsx b/source/index.tsx
index c501f2e..e0c8ef2 100644
--- a/source/index.tsx
+++ b/source/index.tsx
@@ -3,25 +3,30 @@ import {
component,
WebField,
observer,
- attribute
+ attribute,
+ formField
} from 'web-cell';
import { observable } from 'mobx';
-import { TextFieldProps, importCSS } from 'web-utility';
+import { TextFieldProps } from 'web-utility';
import Quill, { QuillOptions } from 'quill';
-import './index.less';
+// import './index.less';
export interface QuillCellProps
- extends Omit,
+ extends QuillOptions,
+ Omit,
WebCellProps {
- theme: 'bubble' | 'snow';
- options?: QuillOptions;
upload?: (file: File) => Promise;
+ onChange?: (event: CustomEvent) => any;
}
export interface QuillCell extends WebField {}
-@component({ tagName: 'quill-cell' })
+@component({
+ tagName: 'quill-cell'
+ // mode: 'open'
+})
+@formField
@observer
export class QuillCell extends HTMLElement implements WebField {
get type() {
@@ -30,71 +35,42 @@ export class QuillCell extends HTMLElement implements WebField {
@attribute
@observable
- accessor theme: QuillCellProps['theme'];
+ accessor theme: QuillCellProps['theme'] = 'snow';
@attribute
@observable
- accessor readOnly?: boolean;
+ accessor readOnly = false;
@attribute
@observable
- accessor placeholder?: string;
-
- @observable
- accessor options?: QuillOptions;
+ accessor placeholder = '';
@observable.shallow
- accessor upload?: QuillCellProps['upload'];
+ accessor upload: QuillCellProps['upload'] | undefined;
protected box?: Quill;
- @observable
- // @ts-ignore
- set defaultValue(defaultValue: string) {
- this.setProps({ defaultValue }).then(
- () => (this.box.root.innerHTML = defaultValue)
- );
+ mountedCallback() {
+ this.boot();
}
- // @ts-ignore
- set value(value: string) {
- const { box } = this;
-
- this.setProps({ value });
- if (!box) return;
-
- this.internals.setFormValue(value);
- box.root.innerHTML = value;
- }
-
- get value() {
- return this.box?.root.innerHTML || this.props.value;
- }
-
- async connectedCallback() {
- await importCSS(
- `https://unpkg.com/quill@2.0.0/dist/quill.${this.theme}.css`
- );
+ disconnectedCallback() {
+ this.box.root.removeEventListener('input', this.updateValue);
}
/**
- * @see https://quilljs.com/docs/modules/toolbar/#container
+ * @see https://quilljs.com/docs/modules/toolbar#container
*/
- protected boot = async (node: HTMLElement) => {
- const { theme, readOnly, placeholder, upload, options, value } = this;
-
- const SizeStyle = Quill.import('attributors/style/size');
- SizeStyle.whitelist = ['12px', '14px', '16px', '18px', '20px'];
-
- Quill.register(SizeStyle, true);
+ protected boot = async () => {
+ const { theme, readOnly, placeholder, upload, defaultValue } = this;
- if (theme === 'snow')
- Quill.register(
- 'modules/imageUploader',
- (await import('quill-image-uploader')).default
- );
+ // if (theme === 'snow')
+ // Quill.register(
+ // 'modules/imageUploader',
+ // (await import('quill-image-uploader')).default
+ // );
- this.box = new Quill(node, {
+ this.box = new Quill(this.root.lastElementChild as HTMLDivElement, {
theme,
readOnly,
placeholder,
@@ -102,53 +78,58 @@ export class QuillCell extends HTMLElement implements WebField {
toolbar: [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
+ ['link', 'image', 'video', 'formula'],
[{ header: 1 }, { header: 2 }], // custom button values
- [{ list: 'ordered' }, { list: 'bullet' }],
+ [
+ { list: 'ordered' },
+ { list: 'bullet' },
+ { list: 'check' }
+ ],
[{ script: 'sub' }, { script: 'super' }], // superscript/subscript
[{ indent: '-1' }, { indent: '+1' }], // outdent/indent
[{ direction: 'rtl' }], // text direction
- [{ size: SizeStyle.whitelist }], // custom dropdown
+ [{ size: ['small', false, 'large', 'huge'] }], // custom dropdown
[{ header: [1, 2, 3, 4, 5, 6, false] }],
[{ color: [] }, { background: [] }], // dropdown with defaults from theme
[{ font: [] }],
[{ align: [] }],
- ...(theme === 'snow' ? [['image']] : []),
-
['clean'] // remove formatting button
- ],
- ...(upload && { imageUploader: { upload } })
- },
- ...options
+ ]
+ // ...(upload && { imageUploader: { upload } })
+ }
});
- this.box.root.innerHTML = value;
+ this.box.root.innerHTML = defaultValue;
- node.addEventListener('input', () =>
- this.internals.setFormValue(this.value)
- );
+ this.box.root.addEventListener('input', this.updateValue);
+ this.box.on('text-change', this.updateValue);
};
- updatedCallback() {
- const { defaultValue } = this.props;
+ updateValue = () => {
+ this.value = this.box.root.innerHTML.trim();
- if (!(defaultValue != null) && this.box)
- return this.setProps({ defaultValue: this.box.root.innerHTML });
- }
+ this.emit('change', this.value);
+ };
render() {
- const { theme, defaultSlot } = this;
+ const { theme } = this;
return (
-
- {defaultSlot}
-
+ <>
+
+
+ >
);
}
}
diff --git a/test/index.tsx b/test/index.tsx
index 16f32fa..accfbeb 100644
--- a/test/index.tsx
+++ b/test/index.tsx
@@ -1,16 +1,16 @@
import { configure } from 'mobx';
import { DOMRenderer } from 'dom-renderer';
-import { QuillCell } from '../source/Editor';
+import { QuillCell } from '../source';
configure({ enforceActions: 'never' });
new DOMRenderer().render(
// @ts-ignore
,
diff --git a/tsconfig.json b/tsconfig.json
index d49f90c..22f9177 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -7,7 +7,8 @@
"useDefineForClassFields": true,
"jsx": "react-jsx",
"jsxImportSource": "dom-renderer",
- "lib": ["ES2023", "DOM"]
+ "lib": ["ES2023", "DOM"],
+ "skipLibCheck": true
},
"include": ["source/*"],
"typedocOptions": {