@iyulab/editor-components 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -4
- package/LICENSE +20 -20
- package/README.md +103 -116
- package/dist/_virtual/{_@oxc-project_runtime@0.130.0/helpers → _@oxc-project_runtime@0.139.0/helpers/esm}/decorate.js +2 -2
- package/dist/_virtual/{_@oxc-project_runtime@0.130.0/helpers → _@oxc-project_runtime@0.139.0/helpers/esm}/decorateMetadata.js +2 -2
- package/dist/components/code-editor/UCodeEditor.d.ts +5 -0
- package/dist/components/code-editor/UCodeEditor.js +9 -3
- package/dist/components/text-editor/UTextEditor.d.ts +14 -3
- package/dist/components/text-editor/UTextEditor.js +28 -11
- package/dist/react/UCodeEditor.d.ts +1 -0
- package/dist/react/UCodeEditor.js +5 -3
- package/dist/react/UTextEditor.d.ts +1 -0
- package/dist/react/UTextEditor.js +5 -3
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
## [
|
|
4
|
-
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.0.2] - 2026-07-17
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- `u-code-editor`: 프로그램적 `value` 세팅 시 Monaco `onDidChangeModelContent`가 그대로 `change` 이벤트로 노출되어, controlled 래퍼(React 등)에서 에코 루프·state 오염을 유발하던 문제 수정. 이제 `change`는 사용자 편집에서만 발화한다.
|
|
7
|
+
- `u-text-editor`: 프로그램적 `value` 세팅·초기 콘텐츠 주입이 `quill.root.innerHTML` 직접 변이로 이뤄져 Quill MutationObserver가 이를 사용자 편집(`source='user'`)으로 오인해 `change`가 발화되던 문제 수정. 콘텐츠 주입을 `clipboard.convert()` + `setContents(delta, 'silent')`로 전환하고, `text-change` 리스너는 `source='user'`만 `change`로 노출한다. 사용자 편집 시 `value` 프로퍼티도 동기화된다.
|
|
8
|
+
- `u-text-editor`: 명령형 API도 동일 규약으로 정리 — `setHTML()`이 innerHTML 직접 변이로 change를 위장 발화하던 문제 수정(이제 `value` 프로퍼티 경로 위임), `setDelta()`/`clear()`는 silent source 전환 + `value` 프로퍼티 동기화.
|
|
9
|
+
- README를 실제 구현에 맞게 재작성 — 잘못된 태그명(`<code-editor>`/`<rich-text-editor>` → `u-code-editor`/`u-text-editor`), 잘못된 prop(`noHeader` → `headless`), 존재하지 않는 `copy` 이벤트·`demo.html` 서술 제거, change 의미론·`/react` 서브패스 문서화.
|
|
10
|
+
- 위 수정은 `@iyulab/components` 1.7.0의 "change = 사용자 상호작용 전용" 규약 정합 작업의 일환.
|
|
11
|
+
|
|
12
|
+
## [Unreleased]
|
|
13
|
+
- Initial library version release
|
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Iyulab, Inc.
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Iyulab, Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,116 +1,103 @@
|
|
|
1
|
-
# @iyulab/editor-components
|
|
2
|
-
|
|
3
|
-
다양한 에디터 컴포넌트를 제공하는 라이브러리입니다.
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
##
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
- `copy`: 복사 버튼 클릭 시 발생 (detail: string)
|
|
105
|
-
|
|
106
|
-
## 데모
|
|
107
|
-
|
|
108
|
-
프로젝트에 포함된 `demo.html` 파일을 통해 컴포넌트들을 실제로 테스트해볼 수 있습니다.
|
|
109
|
-
|
|
110
|
-
```bash
|
|
111
|
-
npm run start
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
## 라이선스
|
|
115
|
-
|
|
116
|
-
MIT
|
|
1
|
+
# @iyulab/editor-components
|
|
2
|
+
|
|
3
|
+
다양한 에디터 컴포넌트를 제공하는 라이브러리입니다.
|
|
4
|
+
|
|
5
|
+
## 설치
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @iyulab/editor-components
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
import '@iyulab/editor-components';
|
|
13
|
+
|
|
14
|
+
// 또는 개별 컴포넌트만 import
|
|
15
|
+
import { UCodeEditor, UTextEditor } from '@iyulab/editor-components';
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
React 래퍼는 `/react` 서브패스로 제공됩니다:
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
import { UCodeEditor, UTextEditor } from '@iyulab/editor-components/react';
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 포함된 컴포넌트
|
|
25
|
+
|
|
26
|
+
### `u-code-editor` (UCodeEditor)
|
|
27
|
+
|
|
28
|
+
Monaco Editor 기반 코드 에디터 컴포넌트입니다.
|
|
29
|
+
|
|
30
|
+
**특징:** 구문 강조 · 자동완성/IntelliSense · 다크/라이트 테마 자동 추적 · 읽기 전용 모드
|
|
31
|
+
|
|
32
|
+
```html
|
|
33
|
+
<u-code-editor
|
|
34
|
+
label="My Code Editor"
|
|
35
|
+
language="javascript"
|
|
36
|
+
font-size="14"
|
|
37
|
+
value="console.log('Hello World!');">
|
|
38
|
+
</u-code-editor>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Properties:**
|
|
42
|
+
|
|
43
|
+
| Property | Type | Default | 설명 |
|
|
44
|
+
|----------|------|---------|------|
|
|
45
|
+
| `headless` | `boolean` | `false` | 헤더(라벨 영역) 숨김 |
|
|
46
|
+
| `label` | `string` | `"Editor"` | 헤더 라벨 텍스트 |
|
|
47
|
+
| `theme` | `"light" \| "dark"` | 시스템 테마 추적 | 에디터 테마 |
|
|
48
|
+
| `readOnly` | `boolean` | `false` | 읽기 전용 모드 |
|
|
49
|
+
| `language` | `string` | `"json"` | 구문 강조 언어 |
|
|
50
|
+
| `fontSize` | `number` | `14` | 폰트 크기(px) |
|
|
51
|
+
| `value` | `string` | `""` | 에디터 내용 |
|
|
52
|
+
|
|
53
|
+
### `u-text-editor` (UTextEditor)
|
|
54
|
+
|
|
55
|
+
Quill.js 기반 리치 텍스트(WYSIWYG) 에디터 컴포넌트입니다.
|
|
56
|
+
|
|
57
|
+
**특징:** 텍스트 포맷팅 · 목록/헤더/인용구 · 링크/이미지 · 커스텀 툴바 · 다크/라이트 테마 자동 추적
|
|
58
|
+
|
|
59
|
+
```html
|
|
60
|
+
<u-text-editor
|
|
61
|
+
label="My Rich Text Editor"
|
|
62
|
+
height="300"
|
|
63
|
+
placeholder="Start writing..."
|
|
64
|
+
value="<h2>Hello World!</h2><p>This is <strong>rich text</strong>.</p>">
|
|
65
|
+
</u-text-editor>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Properties:**
|
|
69
|
+
|
|
70
|
+
| Property | Type | Default | 설명 |
|
|
71
|
+
|----------|------|---------|------|
|
|
72
|
+
| `headless` | `boolean` | `false` | 헤더(라벨 영역) 숨김 |
|
|
73
|
+
| `label` | `string` | `"Rich Text Editor"` | 헤더 라벨 텍스트 |
|
|
74
|
+
| `theme` | `"light" \| "dark" \| "system"` | 시스템 테마 추적 | 에디터 테마 |
|
|
75
|
+
| `readOnly` | `boolean` | `false` | 읽기 전용 모드 |
|
|
76
|
+
| `placeholder` | `string` | `"Start writing..."` | 플레이스홀더 텍스트 |
|
|
77
|
+
| `value` | `string` | `""` | 에디터 HTML 내용 |
|
|
78
|
+
| `height` | `number` | `300` | 에디터 높이(px) |
|
|
79
|
+
| `toolbar` | `string[][]` | 기본 툴바 | 커스텀 툴바 설정 |
|
|
80
|
+
|
|
81
|
+
**Methods:**
|
|
82
|
+
|
|
83
|
+
- `getHTML()` / `getText()` / `getDelta()`: HTML / 플레인 텍스트 / Quill Delta 형식으로 내용 반환
|
|
84
|
+
- `setHTML(html)` / `setDelta(delta)`: 내용 설정 (프로그램적 — `change` 미발화)
|
|
85
|
+
- `clear()`: 모든 내용 삭제 (프로그램적 — `change` 미발화)
|
|
86
|
+
- `focus()`: 에디터에 포커스
|
|
87
|
+
|
|
88
|
+
## 이벤트
|
|
89
|
+
|
|
90
|
+
`change`는 네이티브 폼 컨트롤 규약을 따라 **사용자 편집에서만** 발화합니다. 프로그램적 `value` 세팅·`setHTML()`/`setDelta()`/`clear()`는 발화하지 않으므로, React 등 controlled 래퍼에서 에코 루프 없이 안전하게 바인딩할 수 있습니다.
|
|
91
|
+
|
|
92
|
+
### `u-code-editor`
|
|
93
|
+
- `change`: 사용자 편집으로 내용이 변경될 때 발생. 현재 값은 `event.target.value`로 읽습니다.
|
|
94
|
+
|
|
95
|
+
### `u-text-editor`
|
|
96
|
+
- `change`: 사용자 편집으로 내용이 변경될 때 발생 (`detail: { html, text, delta }`)
|
|
97
|
+
|
|
98
|
+
## 개발
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npm test # Vite 개발 서버 (컴포넌트 프리뷰)
|
|
102
|
+
npm run build # 프로덕션 빌드 (eslint + vite)
|
|
103
|
+
```
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region \0@oxc-project+runtime@0.
|
|
1
|
+
//#region \0@oxc-project+runtime@0.139.0/helpers/esm/decorate.js
|
|
2
2
|
function __decorate(decorators, target, key, desc) {
|
|
3
3
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
4
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -6,4 +6,4 @@ function __decorate(decorators, target, key, desc) {
|
|
|
6
6
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
7
|
}
|
|
8
8
|
//#endregion
|
|
9
|
-
export { __decorate };
|
|
9
|
+
export { __decorate as default };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
//#region \0@oxc-project+runtime@0.
|
|
1
|
+
//#region \0@oxc-project+runtime@0.139.0/helpers/esm/decorateMetadata.js
|
|
2
2
|
function __decorateMetadata(k, v) {
|
|
3
3
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4
4
|
}
|
|
5
5
|
//#endregion
|
|
6
|
-
export { __decorateMetadata };
|
|
6
|
+
export { __decorateMetadata as default };
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { UElement } from '@iyulab/components/dist/components/UElement.js';
|
|
2
2
|
/**
|
|
3
3
|
* code editor component used by monaco-editor
|
|
4
|
+
*
|
|
5
|
+
* @event change - Fired when the content of the editor changes. The event detail contains the current HTML, text, and delta representation of the content.
|
|
4
6
|
*/
|
|
5
7
|
export declare class UCodeEditor extends UElement {
|
|
6
8
|
static styles: import('lit').CSSResultGroup[];
|
|
@@ -20,6 +22,9 @@ export declare class UCodeEditor extends UElement {
|
|
|
20
22
|
value: string;
|
|
21
23
|
private container;
|
|
22
24
|
private editor?;
|
|
25
|
+
/** 프로그램적 value 동기화 중 여부 — Monaco onDidChangeModelContent는 setValue에서도
|
|
26
|
+
* 발화하므로, 이 플래그로 프로그램적 변경이 change 이벤트로 위장되는 것을 막는다. */
|
|
27
|
+
private syncingValue;
|
|
23
28
|
private observer;
|
|
24
29
|
connectedCallback(): void;
|
|
25
30
|
disconnectedCallback(): void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "./UCodeEditor.worker.js";
|
|
2
2
|
import { styles } from "./UCodeEditor.styles.js";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.139.0/helpers/esm/decorateMetadata.js";
|
|
4
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.139.0/helpers/esm/decorate.js";
|
|
5
5
|
import { html, unsafeCSS } from "lit";
|
|
6
6
|
import { customElement, property } from "lit/decorators.js";
|
|
7
7
|
import { createRef, ref } from "lit/directives/ref.js";
|
|
@@ -21,6 +21,7 @@ var UCodeEditor = class UCodeEditor extends UElement {
|
|
|
21
21
|
this.fontSize = 14;
|
|
22
22
|
this.value = "";
|
|
23
23
|
this.container = createRef();
|
|
24
|
+
this.syncingValue = false;
|
|
24
25
|
this.observer = new MutationObserver(() => {
|
|
25
26
|
const theme = Theme.get() === "dark" ? "dark" : "light";
|
|
26
27
|
if (this.theme !== theme) this.theme = theme;
|
|
@@ -62,6 +63,7 @@ var UCodeEditor = class UCodeEditor extends UElement {
|
|
|
62
63
|
scrollbar: { alwaysConsumeMouseWheel: false }
|
|
63
64
|
});
|
|
64
65
|
this.editor.onDidChangeModelContent(() => {
|
|
66
|
+
if (this.syncingValue) return;
|
|
65
67
|
this.value = this.editor.getValue();
|
|
66
68
|
this.dispatchEvent(new Event("change", {
|
|
67
69
|
bubbles: true,
|
|
@@ -71,7 +73,11 @@ var UCodeEditor = class UCodeEditor extends UElement {
|
|
|
71
73
|
}
|
|
72
74
|
async updated(changedProperties) {
|
|
73
75
|
super.updated(changedProperties);
|
|
74
|
-
if (changedProperties.has("value") && this.value !== this.editor?.getValue() && !this.editor?.hasWidgetFocus())
|
|
76
|
+
if (changedProperties.has("value") && this.value !== this.editor?.getValue() && !this.editor?.hasWidgetFocus()) {
|
|
77
|
+
this.syncingValue = true;
|
|
78
|
+
this.editor?.setValue(this.value);
|
|
79
|
+
this.syncingValue = false;
|
|
80
|
+
}
|
|
75
81
|
if (changedProperties.has("theme") && this.editor) this.editor.updateOptions({ theme: this.theme === "light" ? "vs-light" : "vs-dark" });
|
|
76
82
|
if (changedProperties.has("language") && this.editor) monaco.editor.setModelLanguage(this.editor.getModel(), this.language);
|
|
77
83
|
}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { UElement } from '@iyulab/components/dist/components/UElement.js';
|
|
2
|
+
/**
|
|
3
|
+
* A rich text editor component built using Quill.js, providing a customizable and user-friendly interface for text editing. It supports various formatting options, themes, and can be configured to be read-only or editable.
|
|
4
|
+
*
|
|
5
|
+
* @event change - Fired when the content of the editor changes. The event detail includes the current HTML, plain text, and Quill Delta representation of the content.
|
|
6
|
+
*/
|
|
2
7
|
export declare class UTextEditor extends UElement {
|
|
3
8
|
static styles: import('lit').CSSResultGroup[];
|
|
4
9
|
/** Specifies whether the header should be displayed or not. @default false */
|
|
@@ -24,6 +29,9 @@ export declare class UTextEditor extends UElement {
|
|
|
24
29
|
disconnectedCallback(): void;
|
|
25
30
|
protected firstUpdated(changedProperties: any): Promise<void>;
|
|
26
31
|
protected updated(changedProperties: any): Promise<void>;
|
|
32
|
+
/** HTML을 Quill Delta로 변환해 silent source로 주입한다 — 프로그램적 콘텐츠 세팅이
|
|
33
|
+
* text-change(→ change 이벤트)로 위장되지 않도록 하기 위함. */
|
|
34
|
+
private setQuillContents;
|
|
27
35
|
render(): import('lit-html').TemplateResult<1>;
|
|
28
36
|
private updateEditorHeight;
|
|
29
37
|
/**
|
|
@@ -39,15 +47,18 @@ export declare class UTextEditor extends UElement {
|
|
|
39
47
|
*/
|
|
40
48
|
getDelta(): any;
|
|
41
49
|
/**
|
|
42
|
-
* Set content from HTML
|
|
50
|
+
* Set content from HTML.
|
|
51
|
+
* 프로그램적 세팅이므로 change 이벤트는 발화하지 않는다 (value 프로퍼티 경로와 동일).
|
|
43
52
|
*/
|
|
44
53
|
setHTML(html: string): void;
|
|
45
54
|
/**
|
|
46
|
-
* Set content from Quill Delta
|
|
55
|
+
* Set content from Quill Delta.
|
|
56
|
+
* 프로그램적 세팅이므로 change 이벤트는 발화하지 않는다.
|
|
47
57
|
*/
|
|
48
58
|
setDelta(delta: any): void;
|
|
49
59
|
/**
|
|
50
|
-
* Clear all content
|
|
60
|
+
* Clear all content.
|
|
61
|
+
* 프로그램적 세팅이므로 change 이벤트는 발화하지 않는다.
|
|
51
62
|
*/
|
|
52
63
|
clear(): void;
|
|
53
64
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.139.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.139.0/helpers/esm/decorate.js";
|
|
3
3
|
import { styles } from "./UTextEditor.styles.js";
|
|
4
4
|
import { html, unsafeCSS } from "lit";
|
|
5
5
|
import { customElement, property } from "lit/decorators.js";
|
|
@@ -88,9 +88,11 @@ var UTextEditor = class UTextEditor extends UElement {
|
|
|
88
88
|
placeholder: this.placeholder,
|
|
89
89
|
modules: { toolbar: this.toolbar || defaultToolbar }
|
|
90
90
|
});
|
|
91
|
-
if (this.value) this.
|
|
92
|
-
this.quill.on("text-change", () => {
|
|
91
|
+
if (this.value) this.setQuillContents(this.value);
|
|
92
|
+
this.quill.on("text-change", (_delta, _oldDelta, source) => {
|
|
93
|
+
if (source !== "user") return;
|
|
93
94
|
const html = this.quill.root.innerHTML;
|
|
95
|
+
this.value = html;
|
|
94
96
|
this.dispatchEvent(new CustomEvent("change", { detail: {
|
|
95
97
|
html,
|
|
96
98
|
text: this.quill.getText(),
|
|
@@ -103,12 +105,18 @@ var UTextEditor = class UTextEditor extends UElement {
|
|
|
103
105
|
super.updated(changedProperties);
|
|
104
106
|
await this.updateComplete;
|
|
105
107
|
if (this.quill) {
|
|
106
|
-
if (changedProperties.has("value") && this.value !== this.quill.root.innerHTML) this.
|
|
108
|
+
if (changedProperties.has("value") && this.value !== this.quill.root.innerHTML) this.setQuillContents(this.value);
|
|
107
109
|
if (changedProperties.has("readOnly")) this.quill.enable(!this.readOnly);
|
|
108
110
|
if (changedProperties.has("placeholder")) this.quill.root.dataset.placeholder = this.placeholder;
|
|
109
111
|
if (changedProperties.has("height")) this.updateEditorHeight();
|
|
110
112
|
}
|
|
111
113
|
}
|
|
114
|
+
/** HTML을 Quill Delta로 변환해 silent source로 주입한다 — 프로그램적 콘텐츠 세팅이
|
|
115
|
+
* text-change(→ change 이벤트)로 위장되지 않도록 하기 위함. */
|
|
116
|
+
setQuillContents(htmlValue) {
|
|
117
|
+
const delta = this.quill.clipboard.convert({ html: htmlValue });
|
|
118
|
+
this.quill.setContents(delta, Quill.sources.SILENT);
|
|
119
|
+
}
|
|
112
120
|
render() {
|
|
113
121
|
return html`
|
|
114
122
|
<div class="header" ?hidden=${this.headless}>
|
|
@@ -146,22 +154,31 @@ var UTextEditor = class UTextEditor extends UElement {
|
|
|
146
154
|
return this.quill ? this.quill.getContents() : null;
|
|
147
155
|
}
|
|
148
156
|
/**
|
|
149
|
-
* Set content from HTML
|
|
157
|
+
* Set content from HTML.
|
|
158
|
+
* 프로그램적 세팅이므로 change 이벤트는 발화하지 않는다 (value 프로퍼티 경로와 동일).
|
|
150
159
|
*/
|
|
151
160
|
setHTML(html) {
|
|
152
|
-
|
|
161
|
+
this.value = html;
|
|
153
162
|
}
|
|
154
163
|
/**
|
|
155
|
-
* Set content from Quill Delta
|
|
164
|
+
* Set content from Quill Delta.
|
|
165
|
+
* 프로그램적 세팅이므로 change 이벤트는 발화하지 않는다.
|
|
156
166
|
*/
|
|
157
167
|
setDelta(delta) {
|
|
158
|
-
if (this.quill)
|
|
168
|
+
if (this.quill) {
|
|
169
|
+
this.quill.setContents(delta, Quill.sources.SILENT);
|
|
170
|
+
this.value = this.quill.root.innerHTML;
|
|
171
|
+
}
|
|
159
172
|
}
|
|
160
173
|
/**
|
|
161
|
-
* Clear all content
|
|
174
|
+
* Clear all content.
|
|
175
|
+
* 프로그램적 세팅이므로 change 이벤트는 발화하지 않는다.
|
|
162
176
|
*/
|
|
163
177
|
clear() {
|
|
164
|
-
if (this.quill)
|
|
178
|
+
if (this.quill) {
|
|
179
|
+
this.quill.setText("", Quill.sources.SILENT);
|
|
180
|
+
this.value = this.quill.root.innerHTML;
|
|
181
|
+
}
|
|
165
182
|
}
|
|
166
183
|
/**
|
|
167
184
|
* Focus the editor
|
|
@@ -3,6 +3,7 @@ import { UCodeEditor as UCodeEditorElement } from '../components/code-editor/UCo
|
|
|
3
3
|
|
|
4
4
|
export declare const UCodeEditor: React.ForwardRefExoticComponent<
|
|
5
5
|
Partial<UCodeEditorElement> & React.HTMLAttributes<UCodeEditorElement> & {
|
|
6
|
+
onChange?: (event: CustomEvent) => void;
|
|
6
7
|
}
|
|
7
8
|
>;
|
|
8
9
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { createComponent } from '@lit/react';
|
|
3
|
-
import { UCodeEditor } from '../components/code-editor/UCodeEditor.js';
|
|
3
|
+
import { UCodeEditor as UCodeEditorElement } from '../components/code-editor/UCodeEditor.js';
|
|
4
4
|
|
|
5
5
|
export const UCodeEditor = createComponent({
|
|
6
6
|
react: React,
|
|
7
7
|
tagName: 'u-code-editor',
|
|
8
|
-
elementClass:
|
|
9
|
-
events: {
|
|
8
|
+
elementClass: UCodeEditorElement,
|
|
9
|
+
events: {
|
|
10
|
+
onChange: 'change',
|
|
11
|
+
},
|
|
10
12
|
});
|
|
@@ -3,6 +3,7 @@ import { UTextEditor as UTextEditorElement } from '../components/text-editor/UTe
|
|
|
3
3
|
|
|
4
4
|
export declare const UTextEditor: React.ForwardRefExoticComponent<
|
|
5
5
|
Partial<UTextEditorElement> & React.HTMLAttributes<UTextEditorElement> & {
|
|
6
|
+
onChange?: (event: CustomEvent) => void;
|
|
6
7
|
}
|
|
7
8
|
>;
|
|
8
9
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { createComponent } from '@lit/react';
|
|
3
|
-
import { UTextEditor } from '../components/text-editor/UTextEditor.js';
|
|
3
|
+
import { UTextEditor as UTextEditorElement } from '../components/text-editor/UTextEditor.js';
|
|
4
4
|
|
|
5
5
|
export const UTextEditor = createComponent({
|
|
6
6
|
react: React,
|
|
7
7
|
tagName: 'u-text-editor',
|
|
8
|
-
elementClass:
|
|
9
|
-
events: {
|
|
8
|
+
elementClass: UTextEditorElement,
|
|
9
|
+
events: {
|
|
10
|
+
onChange: 'change',
|
|
11
|
+
},
|
|
10
12
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iyulab/editor-components",
|
|
3
3
|
"description": "various editor components by iyulab",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.2",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"iyulab",
|
|
7
7
|
"web-components",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"build": "eslint && vite build"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@iyulab/components": "^1.
|
|
43
|
+
"@iyulab/components": "^1.5.1",
|
|
44
44
|
"lit": "^3.3.3",
|
|
45
45
|
"monaco-editor": "^0.55.1",
|
|
46
46
|
"quill": "^2.0.3"
|
|
@@ -59,13 +59,13 @@
|
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@eslint/js": "^9.39.4",
|
|
62
|
-
"@types/node": "^
|
|
62
|
+
"@types/node": "^26.1.1",
|
|
63
63
|
"eslint": "^9.39.4",
|
|
64
64
|
"glob": "^13.0.6",
|
|
65
|
-
"globals": "^17.
|
|
65
|
+
"globals": "^17.7.0",
|
|
66
66
|
"typescript": "^5.9.3",
|
|
67
|
-
"typescript-eslint": "^8.
|
|
68
|
-
"vite": "^8.
|
|
69
|
-
"vite-plugin-dts": "^5.0.
|
|
67
|
+
"typescript-eslint": "^8.64.0",
|
|
68
|
+
"vite": "^8.1.4",
|
|
69
|
+
"vite-plugin-dts": "^5.0.3"
|
|
70
70
|
}
|
|
71
71
|
}
|