@operato/input 0.2.47 → 0.2.51

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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Webcomponent property-editor following open-wc recommendations",
4
4
  "license": "MIT",
5
5
  "author": "heartyoh@hatiolab.com",
6
- "version": "0.2.47",
6
+ "version": "0.2.51",
7
7
  "main": "dist/src/index.js",
8
8
  "module": "dist/src/index.js",
9
9
  "publishConfig": {
@@ -32,8 +32,10 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "@material/mwc-icon": "^0.25.3",
35
- "@operato/popup": "^0.2.47",
35
+ "@operato/popup": "^0.2.51",
36
+ "@operato/styles": "^0.2.51",
36
37
  "@zxing/library": "^0.18.6",
38
+ "codemirror": "^5.64.0",
37
39
  "lit": "^2.0.2"
38
40
  },
39
41
  "devDependencies": {
@@ -41,6 +43,7 @@
41
43
  "@hatiolab/prettier-config": "^1.0.0",
42
44
  "@open-wc/eslint-config": "^4.3.0",
43
45
  "@open-wc/testing": "next",
46
+ "@types/codemirror": "^5.60.5",
44
47
  "@typescript-eslint/eslint-plugin": "^4.33.0",
45
48
  "@typescript-eslint/parser": "^4.33.0",
46
49
  "@web/dev-server": "^0.1.25",
@@ -68,5 +71,5 @@
68
71
  "prettier --write"
69
72
  ]
70
73
  },
71
- "gitHead": "4595e7f0f52d9fc0b97adc9cbbdb0a07f8c0ae00"
74
+ "gitHead": "420032cc01a0a3aa1a2e057d9c0a91451edd3f14"
72
75
  }
package/src/index.ts CHANGED
@@ -6,3 +6,4 @@ export * from './ox-input-barcode'
6
6
  export * from './ox-buttons-radio'
7
7
  export * from './ox-checkbox'
8
8
  export * from './ox-select'
9
+ export * from './ox-input-code'
@@ -0,0 +1,145 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import 'codemirror/mode/javascript/javascript'
6
+ import 'codemirror/mode/python/python'
7
+ import 'codemirror/addon/display/fullscreen'
8
+ import 'codemirror/addon/display/autorefresh'
9
+
10
+ import { PropertyValues, css, html, unsafeCSS } from 'lit'
11
+ import { customElement, property } from 'lit/decorators'
12
+
13
+ import CodeMirror from 'codemirror'
14
+ import CodeMirrorStyle from '!!text-loader!codemirror/lib/codemirror.css'
15
+ import FullScreenStyle from '!!text-loader!codemirror/addon/display/fullscreen.css'
16
+ import NightThemeStyle from '!!text-loader!codemirror/theme/night.css'
17
+ import { OxFormField } from './ox-formfield'
18
+ import { ScrollbarStyles } from '@operato/styles'
19
+
20
+ /**
21
+ WEB Component for code-mirror code editor.
22
+
23
+ Example:
24
+
25
+ <things-editor-code .value=${text} mode=${mode} tab-size="4" tab-as-space="true">
26
+ </things-editor-code>
27
+ */
28
+ @customElement('ox-input-code')
29
+ export default class OxInputCode extends OxFormField {
30
+ static styles = [
31
+ ScrollbarStyles,
32
+ css`
33
+ ${unsafeCSS(CodeMirrorStyle)}
34
+ ${unsafeCSS(FullScreenStyle)}
35
+ ${unsafeCSS(NightThemeStyle)}
36
+ `,
37
+ css`
38
+ :host {
39
+ display: block;
40
+ position: relative;
41
+ }
42
+
43
+ textarea {
44
+ display: block;
45
+ height: 100%;
46
+ width: 100%;
47
+ resize: none;
48
+ font-size: 16px;
49
+ line-height: 20px;
50
+ border: 0px;
51
+ padding: 0px;
52
+ }
53
+ `
54
+ ]
55
+
56
+ /**
57
+ * `value`는 에디터에서 작성중인 contents이다.
58
+ */
59
+ @property({ type: String }) value: string = ''
60
+ @property({ type: String }) mode?: string
61
+ @property({ type: Number, attribute: 'tab-size' }) tabSize: number = 2
62
+ @property({ type: Boolean, attribute: 'tab-as-space' }) tabAsSpace: boolean = true
63
+
64
+ private _outside_changing: boolean = false
65
+ private _self_changing: boolean = false
66
+ private _editor: CodeMirror.EditorFromTextArea | null | undefined = null
67
+ private _changed: boolean = false
68
+
69
+ // private lint: any
70
+ // private hintOptions: any
71
+
72
+ updated(changes: PropertyValues<this>) {
73
+ this._outside_changing = true
74
+ if (changes.has('value') && this.editor && !this._self_changing) {
75
+ this.editor?.setValue(this.value === undefined ? '' : String(this.value))
76
+ this.editor?.refresh()
77
+ }
78
+ this._outside_changing = false
79
+ }
80
+
81
+ render() {
82
+ return html` <textarea></textarea> `
83
+ }
84
+
85
+ get editor() {
86
+ if (!this._editor) {
87
+ let textarea = this.renderRoot.querySelector('textarea')
88
+ let mode = this.mode || 'javascript'
89
+ let tabSize = Number(this.tabSize) || 2
90
+ let indentUnit = tabSize
91
+ // let lint = this.lint
92
+ // let hintOptions = this.hintOptions
93
+ let tabAsSpace = this.tabAsSpace
94
+
95
+ if (textarea) {
96
+ this._editor = CodeMirror.fromTextArea(textarea, {
97
+ value: this.value,
98
+ mode,
99
+ // lint,
100
+ // hintOptions,
101
+ tabSize,
102
+ indentUnit,
103
+ lineNumbers: false,
104
+ showCursorWhenSelecting: true,
105
+ theme: 'night',
106
+ extraKeys: {
107
+ F11: function (cm) {
108
+ cm.setOption('fullScreen', !cm.getOption('fullScreen'))
109
+ },
110
+ Esc: function (cm) {
111
+ cm.setOption('fullScreen', !cm.getOption('fullScreen'))
112
+ },
113
+ // https://github.com/codemirror/CodeMirror/issues/988#issuecomment-37095621
114
+ Tab: tabAsSpace
115
+ ? function (cm: CodeMirror.Editor) {
116
+ cm.replaceSelection(Array(cm.getOption('tabSize')).join(' '))
117
+ }
118
+ : false
119
+ },
120
+ autoRefresh: {
121
+ delay: 500
122
+ }
123
+ })
124
+
125
+ this._editor.on('blur', e => {
126
+ if (!this._changed) return
127
+
128
+ this.value = e.getValue()
129
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
130
+ })
131
+
132
+ this._editor.on('change', async e => {
133
+ this._self_changing = true
134
+
135
+ this._changed = true
136
+
137
+ await this.updateComplete
138
+ this._self_changing = false
139
+ })
140
+ }
141
+ }
142
+
143
+ return this._editor
144
+ }
145
+ }
@@ -0,0 +1,151 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import './ox-input-code'
6
+
7
+ import { PropertyValues, css, html } from 'lit'
8
+ import { customElement, property } from 'lit/decorators'
9
+
10
+ import { OxFormField } from './ox-formfield'
11
+ import OxInputCode from './ox-input-code'
12
+
13
+ /**
14
+ WEB Component for code-mirror based data editor.
15
+
16
+ Example:
17
+
18
+ <ox-input-data value=${text}>
19
+ </ox-input-data>
20
+ */
21
+ @customElement('ox-input-data')
22
+ export default class OxInputData extends OxFormField {
23
+ static styles = [
24
+ css`
25
+ :host {
26
+ display: flex;
27
+ flex-direction: column;
28
+ position: relative;
29
+ }
30
+
31
+ div[datatype] {
32
+ display: flex;
33
+ align-items: center;
34
+ padding: 2px;
35
+ background-color: rgba(0, 0, 0, 0.08);
36
+ font-size: small;
37
+ }
38
+
39
+ div[datatype] mwc-icon {
40
+ margin-left: auto;
41
+ }
42
+
43
+ ox-input-code {
44
+ flex: 1;
45
+ max-width: 260px;
46
+ overflow: auto;
47
+ }
48
+ `
49
+ ]
50
+
51
+ /**
52
+ * `value`는 에디터에서 작성중인 contents이다.
53
+ */
54
+ @property({ type: Object }) value: any
55
+
56
+ render() {
57
+ return html`
58
+ <div datatype>
59
+ <input
60
+ type="radio"
61
+ name="data-type"
62
+ data-value="string"
63
+ .checked=${typeof this.value == 'string'}
64
+ @click=${() => this._setDataType('string')}
65
+ />string
66
+
67
+ <input
68
+ type="radio"
69
+ name="data-type"
70
+ data-value="number"
71
+ .checked=${typeof this.value == 'number'}
72
+ @click=${() => this._setDataType('number')}
73
+ />number
74
+
75
+ <input
76
+ type="radio"
77
+ name="data-type"
78
+ data-value="object"
79
+ .checked=${typeof this.value == 'object'}
80
+ @click=${() => this._setDataType('object')}
81
+ />object
82
+ <mwc-icon @click=${() => this._clearData()} title="delete">delete_forever</mwc-icon>
83
+ </div>
84
+
85
+ <ox-input-code .value=${this._getData(this.value)} editor> </ox-input-code>
86
+ `
87
+ }
88
+
89
+ firstUpdated() {
90
+ this.renderRoot.addEventListener('change', e => {
91
+ e.stopPropagation()
92
+ const target = e.target as OxInputCode
93
+ if (target.hasAttribute('editor')) {
94
+ this.value = target.value
95
+ }
96
+
97
+ const type = this.renderRoot.querySelector('input[name=data-type]:checked')?.getAttribute('data-value')
98
+ this._setDataType(type)
99
+ })
100
+ }
101
+
102
+ udpated(changes: PropertyValues<this>) {
103
+ if (changes.has('value')) {
104
+ this.value = this._getData(this.value)
105
+ }
106
+ }
107
+
108
+ _setDataType(type: string | undefined | null) {
109
+ if (typeof this.value !== type) {
110
+ var value = this.value
111
+
112
+ try {
113
+ switch (type) {
114
+ case 'string':
115
+ this.value = String(value || '')
116
+ break
117
+ case 'number':
118
+ if (!isNaN(value)) {
119
+ this.value = Number(value)
120
+ }
121
+ break
122
+ case 'object':
123
+ this.value = eval('(' + value + ')')
124
+ break
125
+ }
126
+ } catch (e) {
127
+ console.log(e)
128
+ }
129
+ }
130
+
131
+ this._onAfterValueChange()
132
+ }
133
+
134
+ _clearData() {
135
+ this.value = undefined
136
+ this._onAfterValueChange()
137
+ }
138
+
139
+ _getData(data: any) {
140
+ return typeof data !== 'object' ? data || '' : JSON.stringify(data, null, 1)
141
+ }
142
+
143
+ _onAfterValueChange() {
144
+ this.dispatchEvent(
145
+ new CustomEvent('change', {
146
+ bubbles: true,
147
+ composed: true
148
+ })
149
+ )
150
+ }
151
+ }
package/tsconfig.json CHANGED
@@ -16,7 +16,7 @@
16
16
  "rootDir": "./",
17
17
  "declaration": true,
18
18
  "incremental": true,
19
- "types": ["node", "mocha", "three"]
19
+ "types": ["node", "mocha"]
20
20
  },
21
21
  "include": ["**/*.ts"]
22
22
  }