@operato/input 8.0.0-beta.0 → 8.0.0-beta.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.
Files changed (121) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/package.json +7 -7
  3. package/.editorconfig +0 -29
  4. package/.storybook/main.js +0 -3
  5. package/.storybook/preview.js +0 -52
  6. package/.storybook/server.mjs +0 -8
  7. package/demo/index-3dish.html +0 -38
  8. package/demo/index-angle.html +0 -36
  9. package/demo/index-barcode.html +0 -68
  10. package/demo/index-button-radio.html +0 -42
  11. package/demo/index-checkbox.html +0 -69
  12. package/demo/index-code.html +0 -61
  13. package/demo/index-color-gradient.html +0 -35
  14. package/demo/index-color-stops.html +0 -62
  15. package/demo/index-color.html +0 -35
  16. package/demo/index-crontab.html +0 -37
  17. package/demo/index-file.html +0 -41
  18. package/demo/index-image.html +0 -40
  19. package/demo/index-multiple-colors.html +0 -52
  20. package/demo/index-options.html +0 -43
  21. package/demo/index-partition-keys.html +0 -79
  22. package/demo/index-range.html +0 -40
  23. package/demo/index-select.html +0 -136
  24. package/demo/index-stack.html +0 -33
  25. package/demo/index-table.html +0 -50
  26. package/demo/index-value-map.html +0 -80
  27. package/demo/index-value-ranges.html +0 -80
  28. package/demo/index-work-shift.html +0 -59
  29. package/demo/index.html +0 -54
  30. package/src/index.ts +0 -35
  31. package/src/locale/locale-codes.ts +0 -18
  32. package/src/locale/locale-picker.ts +0 -43
  33. package/src/locale/localization.ts +0 -15
  34. package/src/locales/en.ts +0 -30
  35. package/src/locales/ko.ts +0 -30
  36. package/src/locales/ms.ts +0 -30
  37. package/src/locales/zh.ts +0 -30
  38. package/src/ox-buttons-radio.ts +0 -140
  39. package/src/ox-checkbox.ts +0 -181
  40. package/src/ox-form-field.ts +0 -53
  41. package/src/ox-input-3axis.ts +0 -77
  42. package/src/ox-input-3dish.ts +0 -211
  43. package/src/ox-input-angle.ts +0 -73
  44. package/src/ox-input-barcode.ts +0 -318
  45. package/src/ox-input-code.ts +0 -139
  46. package/src/ox-input-color-gradient.ts +0 -349
  47. package/src/ox-input-color-stops.ts +0 -525
  48. package/src/ox-input-color.ts +0 -338
  49. package/src/ox-input-container.ts +0 -32
  50. package/src/ox-input-crontab.ts +0 -595
  51. package/src/ox-input-data.ts +0 -219
  52. package/src/ox-input-direction.ts +0 -92
  53. package/src/ox-input-duration.ts +0 -175
  54. package/src/ox-input-file.ts +0 -209
  55. package/src/ox-input-hashtags.ts +0 -185
  56. package/src/ox-input-i18n-label.ts +0 -140
  57. package/src/ox-input-image.ts +0 -168
  58. package/src/ox-input-key-values.ts +0 -301
  59. package/src/ox-input-layout/ox-input-card-layout.ts +0 -58
  60. package/src/ox-input-layout/ox-input-grid-layout.ts +0 -64
  61. package/src/ox-input-layout/ox-input-layout.ts +0 -77
  62. package/src/ox-input-mass-fraction.ts +0 -437
  63. package/src/ox-input-multiple-colors.ts +0 -135
  64. package/src/ox-input-options.ts +0 -216
  65. package/src/ox-input-partition-keys.ts +0 -303
  66. package/src/ox-input-privilege.ts +0 -163
  67. package/src/ox-input-quantifier.ts +0 -62
  68. package/src/ox-input-range.ts +0 -146
  69. package/src/ox-input-scene-component-id.ts +0 -73
  70. package/src/ox-input-search.ts +0 -126
  71. package/src/ox-input-select-buttons.ts +0 -75
  72. package/src/ox-input-signature.ts +0 -208
  73. package/src/ox-input-stack.ts +0 -136
  74. package/src/ox-input-switch.ts +0 -117
  75. package/src/ox-input-table-column-config.ts +0 -211
  76. package/src/ox-input-table.ts +0 -404
  77. package/src/ox-input-textarea.ts +0 -86
  78. package/src/ox-input-unit-number.ts +0 -354
  79. package/src/ox-input-value-map.ts +0 -342
  80. package/src/ox-input-value-ranges.ts +0 -363
  81. package/src/ox-input-work-shift.ts +0 -290
  82. package/src/ox-select-floor.ts +0 -246
  83. package/src/ox-select.ts +0 -219
  84. package/stories/image-for-select-floor.ts +0 -2
  85. package/stories/ox-buttons-radio.stories.ts +0 -89
  86. package/stories/ox-checkbox.stories.ts +0 -111
  87. package/stories/ox-input-3axis.stories.ts +0 -77
  88. package/stories/ox-input-3dish.stories.ts +0 -106
  89. package/stories/ox-input-angle.stories.ts +0 -84
  90. package/stories/ox-input-barcode.stories.ts +0 -117
  91. package/stories/ox-input-code.stories.ts +0 -99
  92. package/stories/ox-input-crontab.stories.ts +0 -82
  93. package/stories/ox-input-data.stories.ts +0 -82
  94. package/stories/ox-input-direction.stories.ts +0 -91
  95. package/stories/ox-input-duration.stories.ts +0 -84
  96. package/stories/ox-input-file.stories.ts +0 -111
  97. package/stories/ox-input-hashtags.stories.ts +0 -82
  98. package/stories/ox-input-i18n-label.stories.ts +0 -103
  99. package/stories/ox-input-key-values.stories.ts +0 -97
  100. package/stories/ox-input-mass-fraction.stories.ts +0 -102
  101. package/stories/ox-input-multiple-colors.stories.ts +0 -72
  102. package/stories/ox-input-options.stories.ts +0 -80
  103. package/stories/ox-input-partition-keys.stories.ts +0 -84
  104. package/stories/ox-input-privilege.stories.ts +0 -108
  105. package/stories/ox-input-quantifier.stories.ts +0 -80
  106. package/stories/ox-input-range.stories.ts +0 -89
  107. package/stories/ox-input-search.stories.ts +0 -91
  108. package/stories/ox-input-select-buttons.stories.ts +0 -118
  109. package/stories/ox-input-signature.stories.ts +0 -75
  110. package/stories/ox-input-switch.stories.ts +0 -91
  111. package/stories/ox-input-table-column-config.stories.ts +0 -109
  112. package/stories/ox-input-unit.stories.ts +0 -151
  113. package/stories/ox-input-value-map.stories.ts +0 -92
  114. package/stories/ox-input-value-ranges.stories.ts +0 -92
  115. package/stories/ox-input-work-shift.stories.ts +0 -106
  116. package/stories/ox-select-floor.stories.ts +0 -197
  117. package/stories/ox-select-set-options.stories.ts +0 -208
  118. package/stories/ox-select.stories.ts +0 -181
  119. package/tsconfig.json +0 -25
  120. package/web-dev-server.config.mjs +0 -27
  121. package/web-test-runner.config.mjs +0 -41
@@ -1,318 +0,0 @@
1
- /**
2
- * @license Copyright © HatioLab Inc. All rights reserved.
3
- */
4
-
5
- import '@operato/popup/ox-popup.js'
6
-
7
- import { css, html } from 'lit'
8
- import { customElement, property, query, state } from 'lit/decorators.js'
9
- import { scanImageData } from '@undecaf/zbar-wasm'
10
-
11
- import { OxPopup } from '@operato/popup'
12
-
13
- import { OxFormField } from './ox-form-field.js'
14
-
15
- const barcodeIcon = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAYBAMAAAAfR1CMAAADKGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpFNjM4RURDQkQ1OUExMUU5QkExMkQ4NUY3NkMxNzBFOSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpFNjM4RURDQ0Q1OUExMUU5QkExMkQ4NUY3NkMxNzBFOSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkU2MzhFREM5RDU5QTExRTlCQTEyRDg1Rjc2QzE3MEU5IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkU2MzhFRENBRDU5QTExRTlCQTEyRDg1Rjc2QzE3MEU5Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+55pr/QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAkUExURQAAAEdwTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEus/7UCWQwAAAALdFJOU9YAg3wKBFBDSz9PnvQNDgAAAE9JREFUGNNjEEQFDKLJSnCOklkgg9QUJFn3RgZhRyS+iCGDEIp2RSBfQICRkRGIgTSQL4jCF6ScvxsZYOFT2T50/6D7Fz080MMLPTzRwhsAHVspfelur08AAAAASUVORK5CYII=`
16
-
17
- /**
18
- * Custom input component for barcode scanning.
19
- *
20
- * This component provides a text input field and a barcode scanning button. Users can input text
21
- * manually or scan barcodes using the device camera. Supported barcode formats include:
22
- *
23
- * - Code-39
24
- * - Code-93
25
- * - Code-128
26
- * - Codabar
27
- * - Databar/Expanded
28
- * - EAN/GTIN-5/8/13
29
- * - ISBN-10/13
30
- * - ISBN-13+2
31
- * - ISBN-13+5
32
- * - ITF (Interleaved 2 of 5)
33
- * - QR Code
34
- * - UPC-A/E
35
- *
36
- * @fires CustomEvent#change - Dispatched when the input value changes.
37
- * @fires KeyboardEvent#keydown - Dispatched when the Enter key is pressed (if not withoutEnter).
38
- *
39
- * @cssprop {String} --barcodescan-input-button-icon - Icon for the barcode scanning button.
40
- *
41
- * @customElement
42
- */
43
- @customElement('ox-input-barcode')
44
- export class OxInputBarcode extends OxFormField {
45
- static styles = [
46
- css`
47
- :host {
48
- display: flex;
49
- align-items: center;
50
- border: none;
51
- background-color: transparent;
52
- height: var(--ox-input-height, var(--form-element-height-medium));
53
- }
54
-
55
- * {
56
- align-self: stretch;
57
- }
58
-
59
- *:focus {
60
- outline: none;
61
- }
62
-
63
- input {
64
- flex: 1;
65
- width: 10px; /* intentionally width set */
66
- border: var(--ox-input-border, 1px solid var(--md-sys-color-outline));
67
- border-radius: var(--ox-input-radius, var(--md-sys-shape-corner-small));
68
- background-color: var(--ox-input-background-color, var(--md-sys-color-on-primary));
69
- color: var(--ox-input-color, var(--md-sys-color-on-primary-container));
70
- font-size: var(--md-sys-typescale-label-large-size, 0.875rem);
71
-
72
- box-sizing: border-box;
73
- padding-right: 35px;
74
- }
75
-
76
- input:focus {
77
- outline: none;
78
- border-color: var(--md-sys-color-secondary-fixed-dim);
79
- }
80
-
81
- #scan-button {
82
- display: block;
83
- position: relative;
84
- margin-left: -35px;
85
- width: 35px;
86
- border: none;
87
- background: var(--barcodescan-input-button-icon) no-repeat center center;
88
- }
89
-
90
- #scan-button[hidden] {
91
- display: none;
92
- }
93
- `
94
- ]
95
-
96
- /**
97
- * Indicates whether barcode scanning is enabled.
98
- * @property {Boolean} scannable
99
- */
100
- @property({ type: Boolean, attribute: true }) scannable?: boolean
101
-
102
- /**
103
- * If true, the "Enter" key press event is not fired after scanning a barcode.
104
- * @property {Boolean} withoutEnter
105
- */
106
- @property({ attribute: 'without-enter', type: Boolean }) withoutEnter?: boolean
107
-
108
- /**
109
- * The value of the input field.
110
- * @property {String} declare value
111
- */
112
- @property({ type: String }) declare value?: string
113
-
114
- /**
115
- * If true, only English characters are allowed in the input field.
116
- * @property {Boolean} englishOnly
117
- */
118
- @property({ attribute: 'english-only', type: Boolean }) englishOnly?: boolean
119
-
120
- /**
121
- * If true, the input field is automatically selected after a change event.
122
- * @property {Boolean} selectAfterChange
123
- */
124
- @property({ attribute: 'select-after-change', type: Boolean }) selectAfterChange?: boolean
125
-
126
- @state() stream?: MediaStream
127
-
128
- @query('input') input!: HTMLInputElement
129
-
130
- private popup: OxPopup | null = null
131
- private video: HTMLVideoElement | null = null
132
-
133
- connectedCallback() {
134
- super.connectedCallback()
135
-
136
- if (navigator.mediaDevices) {
137
- ;(async () => {
138
- try {
139
- var stream = await navigator.mediaDevices.getUserMedia({ audio: false, video: { facingMode: 'environment' } })
140
- if (stream) {
141
- stream.getTracks().forEach(track => track.stop())
142
- this.scannable = true
143
- }
144
- } catch (e) {
145
- this.scannable = false
146
- console.warn('this device not support camera for barcode scan', e)
147
- }
148
- })()
149
- } else {
150
- this.scannable = false
151
- }
152
- }
153
-
154
- disconnectedCallback() {
155
- this.stopScan()
156
- }
157
-
158
- render() {
159
- this.style.setProperty('--barcodescan-input-button-icon', `url(${barcodeIcon})`)
160
-
161
- return html`
162
- <input
163
- type="text"
164
- .value=${this.value || ''}
165
- @change=${(e: Event) => this.onInputChange(e)}
166
- @keydown=${(e: KeyboardEvent) => this.onInputKeyDown(e)}
167
- ?disabled=${this.disabled}
168
- />
169
- <button
170
- ?hidden=${!this.scannable}
171
- id="scan-button"
172
- @click=${(e: MouseEvent) => {
173
- this.scan(e)
174
- }}
175
- ?disabled=${this.disabled}
176
- ></button>
177
- `
178
- }
179
-
180
- onInputChange(e: Event) {
181
- e.stopPropagation()
182
-
183
- if (this.englishOnly) {
184
- /* englishOnly 인 경우에는 멀티바이트 문자들을 모두 제거한다. */
185
- this.value = this.input.value = this.input.value?.replace(/[^\x00-\x7F]/g, '')
186
- } else {
187
- this.value = this.input.value
188
- }
189
-
190
- if (this.selectAfterChange) {
191
- requestAnimationFrame(() => {
192
- this.input.select()
193
- })
194
- }
195
-
196
- this.dispatchEvent(
197
- new CustomEvent('change', {
198
- detail: this.value
199
- })
200
- )
201
- }
202
-
203
- onInputKeyDown(e: KeyboardEvent) {
204
- if (e.key === 'Enter' && !e.isComposing) {
205
- /* Even if the value has not changed, the enter key triggers a change event. */
206
- e.preventDefault() /* Prevent change event from occurring twice. */
207
-
208
- this.input.dispatchEvent(new CustomEvent('change'))
209
- } else if (this.englishOnly && !e.metaKey && !e.ctrlKey && !e.altKey && /^Key/.test(e.code)) {
210
- e.stopPropagation()
211
- e.preventDefault()
212
-
213
- /* englishOnly 인 경우에 문자들은 여기에서 처리한다. 멀티바이트 문자들이 대부분 알파벳의 자모음을 조합하므로, ... */
214
- const key = e.shiftKey ? e.code.charAt(3) : e.code.charAt(3).toLowerCase()
215
- const value = this.input.value
216
-
217
- const start = this.input.selectionStart || 0
218
- const end = this.input.selectionEnd || start
219
-
220
- this.input.value = [value.substring(0, start), key, value.substring(end)].join('')
221
- this.input.setSelectionRange(start + 1, start + 1)
222
- }
223
- }
224
-
225
- async scan(e: MouseEvent) {
226
- try {
227
- if (this.popup) {
228
- this.stopScan()
229
- }
230
-
231
- this.popup = OxPopup.open({
232
- template: html`
233
- <video></video>
234
- <md-icon
235
- style="position: fixed; right: 0; top: 0; color: red; tabindex: 0"
236
- @click=${() => {
237
- this.stopScan()
238
- }}
239
- >close</md-icon
240
- >
241
- `,
242
- width: '100vw',
243
- height: '100dvh'
244
- })
245
-
246
- this.video! = this.popup.querySelector('video') as HTMLVideoElement
247
-
248
- var constraints = { audio: false, video: { facingMode: 'environment' } } /* backside camera first */
249
- this.stream = await navigator.mediaDevices.getUserMedia(constraints)
250
-
251
- this.video.srcObject = this.stream
252
- this.video.play()
253
-
254
- this.video.onloadedmetadata = async e => {
255
- var canvas = new OffscreenCanvas(
256
- this.video!.videoWidth || this.video!.width,
257
- this.video!.videoHeight || this.video!.height
258
- )
259
-
260
- var context = canvas.getContext('2d', {
261
- willReadFrequently: true
262
- })
263
-
264
- const detect = async () => {
265
- try {
266
- if (!this.stream?.active) {
267
- return
268
- }
269
-
270
- context!.drawImage(this.video!, 0, 0, canvas.width, canvas.height)
271
- const imageData = context!.getImageData(0, 0, canvas.width, canvas.height)
272
- const symbols = await scanImageData(imageData)
273
- const result = symbols[0]?.decode()
274
-
275
- if (result) {
276
- this.stopScan()
277
-
278
- var input = this.input
279
- input.focus()
280
- this.value = input.value = String(result)
281
-
282
- if (!this.withoutEnter) {
283
- input.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }))
284
- }
285
- } else {
286
- requestAnimationFrame(async () => await detect())
287
- }
288
- } catch (e) {
289
- console.warn(e)
290
- this.stopScan()
291
- }
292
- }
293
-
294
- await detect()
295
- }
296
- } catch (err) {
297
- /*
298
- * 1. stream device 문제로 예외 발생한 경우.
299
- * 2. 뒤로가기 등으로 popup이 종료된 경우에도 NotFoundException: Video stream has ended before any code could be detected. 이 발생한다.
300
- */
301
- console.warn(err)
302
- }
303
- }
304
-
305
- stopScan() {
306
- if (this.video) {
307
- this.video.pause()
308
- this.video.srcObject = null
309
- }
310
-
311
- if (this.popup) {
312
- this.popup.close()
313
- this.popup = null
314
- }
315
-
316
- this.stream?.getTracks().forEach(track => track.stop())
317
- }
318
- }
@@ -1,139 +0,0 @@
1
- /**
2
- * @license Copyright © HatioLab Inc. All rights reserved.
3
- */
4
-
5
- import { css, PropertyValues } from 'lit'
6
- import { customElement, property } from 'lit/decorators.js'
7
-
8
- import { minimalSetup } from 'codemirror'
9
- import { history, historyKeymap, indentWithTab } from '@codemirror/commands'
10
- import { EditorView, highlightActiveLine, keymap, lineNumbers } from '@codemirror/view'
11
- import { autocompletion, closeBrackets } from '@codemirror/autocomplete'
12
- import { bracketMatching, LanguageSupport, syntaxHighlighting } from '@codemirror/language'
13
- import { oneDarkHighlightStyle, oneDark } from '@codemirror/theme-one-dark'
14
-
15
- import { javascript } from '@codemirror/lang-javascript'
16
- import { sql } from '@codemirror/lang-sql'
17
- import { json } from '@codemirror/lang-json'
18
-
19
- import { ScrollbarStyles } from '@operato/styles'
20
- import { togglefullscreen } from '@operato/utils'
21
-
22
- import { OxFormField } from './ox-form-field'
23
-
24
- /**
25
- WEB Component for code-mirror code editor.
26
-
27
- Example:
28
-
29
- <ox-input-code .value=${text} language="javascript" show-line-numbers>
30
- </ox-input-code>
31
- */
32
- @customElement('ox-input-code')
33
- export class OxInputCode extends OxFormField {
34
- static styles = [
35
- ScrollbarStyles,
36
- css`
37
- :host {
38
- display: flex;
39
- flex-direction: column;
40
- position: relative;
41
- background: white;
42
- overflow: auto;
43
- border:1px solid var(--md-sys-color-outline);
44
- border-radius:var(--md-sys-shape-corner-small);
45
- }
46
-
47
- .cm-editor {
48
- flex: 1;
49
-
50
- }
51
- `
52
- ]
53
-
54
- /**
55
- * `value`는 에디터에서 작성중인 contents이다.
56
- */
57
- @property({ type: String }) value: string = ''
58
- @property({ type: Boolean, attribute: 'show-line-numbers' }) showLineNumbers: boolean = false
59
- @property({ type: String }) language?: string = 'javascript'
60
-
61
- private _self_changing: boolean = false
62
- private _editor?: EditorView
63
- private _changed: boolean = false
64
-
65
- updated(changes: PropertyValues<this>) {
66
- if (changes.has('value') && this.editor && !this._self_changing) {
67
- const to = this.editor.state.doc.toString().length
68
- this.editor.dispatch({
69
- changes: { from: 0, to, insert: this.value === undefined ? '' : String(this.value) }
70
- })
71
- }
72
- }
73
-
74
- get editor() {
75
- if (!this._editor) {
76
- let language: LanguageSupport[] = []
77
- switch (this.language) {
78
- case 'sql':
79
- language = [sql()]
80
- break
81
- case 'json':
82
- language = [json()]
83
- break
84
- case 'javascript':
85
- language = [javascript()]
86
- break
87
- default:
88
- break
89
- }
90
-
91
- this._editor = new EditorView({
92
- doc: this.value,
93
- extensions: [
94
- minimalSetup,
95
- ...language,
96
- ...(this.showLineNumbers ? [lineNumbers()] : []),
97
- bracketMatching(),
98
- closeBrackets(),
99
- history(),
100
- autocompletion(),
101
- oneDark,
102
- syntaxHighlighting(oneDarkHighlightStyle),
103
- highlightActiveLine(),
104
- keymap.of([...historyKeymap, indentWithTab]),
105
- EditorView.updateListener.of(async v => {
106
- if (v.docChanged) {
107
- this._self_changing = true
108
- this._changed = true
109
-
110
- await this.updateComplete
111
-
112
- this._self_changing = false
113
- }
114
- })
115
- ],
116
- parent: this.renderRoot
117
- })
118
- }
119
-
120
- this._editor.contentDOM.addEventListener('keydown', event => {
121
- event.stopPropagation()
122
-
123
- if (event.key === 'Escape') {
124
- togglefullscreen(this._editor!.contentDOM)
125
- }
126
- })
127
-
128
- this._editor.contentDOM.addEventListener('blur', e => {
129
- if (!this._changed) {
130
- return
131
- }
132
-
133
- this.value = this._editor!.state.doc.toString()
134
- this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true, detail: this.value }))
135
- })
136
-
137
- return this._editor
138
- }
139
- }