Skip to content

Commit

Permalink
[optimize] update Original Source Code
Browse files Browse the repository at this point in the history
  • Loading branch information
TechQuery committed Apr 25, 2024
1 parent 8bf3c6d commit 095cc90
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 123 deletions.
7 changes: 7 additions & 0 deletions ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "quill-cell",
"version": "0.1.0",
"version": "0.2.0",
"license": "LGPL-3.0",
"author": "[email protected]",
"description": "HTML Rich-text editor element based on Web Components, WebCell v2 & Quill.",
Expand Down
41 changes: 0 additions & 41 deletions source/Editor.tsx

This file was deleted.

139 changes: 62 additions & 77 deletions source/index.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
import {
WebField,
WebCellProps,
component,
WebField,
formField,
observer,
attribute
} 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<TextFieldProps, 'list'>,
extends QuillOptions,
Omit<TextFieldProps, 'list'>,
WebCellProps {
theme: 'bubble' | 'snow';
options?: QuillOptions;
upload?: (file: File) => Promise<string>;
onChange?: (event: CustomEvent<string>) => any;
}

export interface QuillCell extends WebField<QuillCellProps> {}

@component({ tagName: 'quill-cell' })
@component({
tagName: 'quill-cell'
// mode: 'open'
})
@formField
@observer
export class QuillCell extends HTMLElement implements WebField<QuillCellProps> {
get type() {
Expand All @@ -30,125 +35,105 @@ export class QuillCell extends HTMLElement implements WebField<QuillCellProps> {

@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)
);
}
// @ts-ignore
set value(value: string) {
const { box } = this;

this.setProps({ value });

if (!box) return;

this.internals.setFormValue(value);
box.root.innerHTML = value;
mountedCallback() {
this.boot();
}

get value() {
return this.box?.root.innerHTML || this.props.value;
}

async connectedCallback() {
await importCSS(
`https://unpkg.com/[email protected]/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,
modules: {
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 (
<div
className={theme === 'bubble' ? 'form-control p-0' : undefined}
ref={this.boot}
>
{defaultSlot}
</div>
<>
<link
rel="stylesheet"
href="https://unpkg.com/[email protected]/dist/css/bootstrap.min.css"
/>
<link
rel="stylesheet"
href={`https://unpkg.com/quill@2/dist/quill.${theme}.css`}
/>
<div
className={
theme === 'bubble' ? 'form-control p-0' : undefined
}
/>
</>
);
}
}
6 changes: 3 additions & 3 deletions test/index.tsx
Original file line number Diff line number Diff line change
@@ -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
<form className="container">
<legend>Quill Cell editor</legend>
<legend className="float-none">Quill Cell editor</legend>

<QuillCell />
<QuillCell placeholder="type something..." onChange={console.log} />

<button className="btn btn-primary my-2"></button>
</form>,
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"useDefineForClassFields": true,
"jsx": "react-jsx",
"jsxImportSource": "dom-renderer",
"lib": ["ES2023", "DOM"]
"lib": ["ES2023", "DOM"],
"skipLibCheck": true
},
"include": ["source/*"],
"typedocOptions": {
Expand Down

0 comments on commit 095cc90

Please sign in to comment.