@operato/input 1.5.49 → 1.5.50

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.
@@ -2,18 +2,18 @@
2
2
  * @license Copyright © HatioLab Inc. All rights reserved.
3
3
  */
4
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 FullScreenStyle from '!!text-loader!codemirror/addon/display/fullscreen.css'
11
- import CodeMirrorStyle from '!!text-loader!codemirror/lib/codemirror.css'
12
- import NightThemeStyle from '!!text-loader!codemirror/theme/night.css'
13
- import CodeMirror from 'codemirror'
14
- import { css, html, PropertyValues, unsafeCSS } from 'lit'
5
+ import { css, PropertyValues } from 'lit'
15
6
  import { customElement, property } from 'lit/decorators.js'
16
7
 
8
+ import { history, historyKeymap, indentWithTab } from '@codemirror/commands'
9
+ import { EditorView, highlightActiveLine, keymap } from '@codemirror/view'
10
+ import { EditorState } from '@codemirror/state'
11
+ import { autocompletion, closeBrackets } from '@codemirror/autocomplete'
12
+ import { bracketMatching, syntaxHighlighting } from '@codemirror/language'
13
+ import { oneDarkHighlightStyle, oneDark } from '@codemirror/theme-one-dark'
14
+
15
+ import { javascript } from '@codemirror/lang-javascript'
16
+
17
17
  import { ScrollbarStyles } from '@operato/styles'
18
18
  import { togglefullscreen } from '@operato/utils'
19
19
 
@@ -31,45 +31,17 @@ Example:
31
31
  export class OxInputCode extends OxFormField {
32
32
  static styles = [
33
33
  ScrollbarStyles,
34
- css`
35
- ${unsafeCSS(CodeMirrorStyle)}
36
- ${unsafeCSS(FullScreenStyle)}
37
- ${unsafeCSS(NightThemeStyle)}
38
- `,
39
34
  css`
40
35
  :host {
41
36
  display: flex;
42
37
  flex-direction: column;
43
38
  position: relative;
39
+ background: white;
44
40
  }
45
41
 
46
- .CodeMirror {
42
+ .cm-editor {
47
43
  flex: 1;
48
44
  }
49
-
50
- textarea {
51
- display: block;
52
- height: 100%;
53
- width: 100%;
54
- resize: none;
55
- font-size: 16px;
56
- line-height: 20px;
57
- border: 0px;
58
- padding: 0px;
59
- }
60
-
61
- #fs-toggle:not(:fullscreen) {
62
- background-color: #afa;
63
- }
64
-
65
- .CodeMirror-fullscreen {
66
- position: fixed;
67
- top: 0;
68
- left: 0;
69
- width: 100%;
70
- height: 100%;
71
- z-index: 9999;
72
- }
73
45
  `
74
46
  ]
75
47
 
@@ -82,84 +54,55 @@ export class OxInputCode extends OxFormField {
82
54
  @property({ type: Boolean, attribute: 'tab-as-space' }) tabAsSpace: boolean = true
83
55
 
84
56
  private _self_changing: boolean = false
85
- private _editor: CodeMirror.EditorFromTextArea | null | undefined = null
57
+ private _editor?: EditorView
86
58
  private _changed: boolean = false
87
59
 
88
- // private lint: any
89
- // private hintOptions: any
90
-
91
60
  updated(changes: PropertyValues<this>) {
92
61
  if (changes.has('value') && this.editor && !this._self_changing) {
93
- this.editor?.setValue(this.value === undefined ? '' : String(this.value))
94
- this.editor?.refresh()
62
+ const to = this.editor.state.doc.toString().length
63
+ this.editor.dispatch({
64
+ changes: { from: 0, to, insert: this.value === undefined ? '' : String(this.value) }
65
+ })
95
66
  }
96
67
  }
97
68
 
98
- render() {
99
- return html` <textarea></textarea> `
100
- }
101
-
102
69
  get editor() {
103
70
  if (!this._editor) {
104
- let textarea = this.renderRoot.querySelector('textarea')
105
- let mode = this.mode || 'javascript'
106
- let tabSize = Number(this.tabSize) || 2
107
- let indentUnit = tabSize
108
- // let lint = this.lint
109
- // let hintOptions = this.hintOptions
110
- let tabAsSpace = this.tabAsSpace
111
-
112
- if (textarea) {
113
- this._editor = CodeMirror.fromTextArea(textarea, {
114
- value: this.value,
115
- mode,
116
- // lint,
117
- // hintOptions,
118
- tabSize,
119
- indentUnit,
120
- lineNumbers: false,
121
- showCursorWhenSelecting: true,
122
- theme: 'night',
123
- extraKeys: {
124
- F11: function (cm) {
125
- cm.setOption('fullScreen', !cm.getOption('fullScreen'))
126
- },
127
- Esc: function (cm) {
128
- // cm.setOption('fullScreen', !cm.getOption('fullScreen'))
129
- togglefullscreen(cm.getWrapperElement())
130
- },
131
- // https://github.com/codemirror/CodeMirror/issues/988#issuecomment-37095621
132
- Tab: tabAsSpace
133
- ? function (cm: CodeMirror.Editor) {
134
- cm.replaceSelection(Array(cm.getOption('tabSize')).join(' '))
135
- }
136
- : false
137
- },
138
- autoRefresh: {
139
- delay: 500
140
- }
141
- })
142
-
143
- this._editor.on('blur', e => {
144
- if (!this._changed) return
145
-
146
- this.value = e.getValue()
147
- this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true, detail: this.value }))
148
- })
149
-
150
- this._editor.on('change', async e => {
151
- this._self_changing = true
152
-
153
- this._changed = true
154
-
155
- await this.updateComplete
156
- this._self_changing = false
157
- })
158
-
159
- this._editor.on('keydown', async (_: any, e: Event) => {
160
- e.stopPropagation()
161
- })
162
- }
71
+ this._editor = new EditorView({
72
+ doc: this.value,
73
+ extensions: [
74
+ bracketMatching(),
75
+ closeBrackets(),
76
+ history(),
77
+ autocompletion(),
78
+ oneDark,
79
+ syntaxHighlighting(oneDarkHighlightStyle),
80
+ highlightActiveLine(),
81
+ javascript(),
82
+ keymap.of([
83
+ ...historyKeymap,
84
+ indentWithTab,
85
+ {
86
+ key: 'Escape',
87
+ run: (view: EditorView) => {
88
+ togglefullscreen(this)
89
+ return true
90
+ }
91
+ }
92
+ ]),
93
+ EditorView.updateListener.of(v => {
94
+ if (v.docChanged) {
95
+ this._self_changing = true
96
+ this.value = v.state.doc.toString()
97
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true, detail: this.value }))
98
+ requestAnimationFrame(() => {
99
+ this._self_changing = false
100
+ })
101
+ }
102
+ })
103
+ ],
104
+ parent: this.renderRoot
105
+ })
163
106
  }
164
107
 
165
108
  return this._editor
@@ -0,0 +1,99 @@
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 { history, historyKeymap, indentWithTab } from '@codemirror/commands'
9
+ import { EditorView, highlightActiveLine, keymap } from '@codemirror/view'
10
+ import { javascript } from '@codemirror/lang-javascript'
11
+ import { ScrollbarStyles } from '@operato/styles'
12
+ import { togglefullscreen } from '@operato/utils'
13
+
14
+ import { OxFormField } from './ox-form-field'
15
+
16
+ /**
17
+ WEB Component for code-mirror code editor.
18
+
19
+ Example:
20
+
21
+ <ox-input-code .value=${text} mode=${mode} tab-size="4" tab-as-space="true">
22
+ </ox-input-code>
23
+ */
24
+ @customElement('ox-input-code')
25
+ export class OxInputCode extends OxFormField {
26
+ static styles = [
27
+ ScrollbarStyles,
28
+ css`
29
+ :host {
30
+ display: flex;
31
+ flex-direction: column;
32
+ position: relative;
33
+ background: white;
34
+ }
35
+
36
+ .cm-editor {
37
+ flex: 1;
38
+ }
39
+ `
40
+ ]
41
+
42
+ /**
43
+ * `value`는 에디터에서 작성중인 contents이다.
44
+ */
45
+ @property({ type: String }) value: string = ''
46
+ @property({ type: String }) mode?: string
47
+ @property({ type: Number, attribute: 'tab-size' }) tabSize: number = 2
48
+ @property({ type: Boolean, attribute: 'tab-as-space' }) tabAsSpace: boolean = true
49
+
50
+ private _self_changing: boolean = false
51
+ private _editor?: EditorView
52
+ private _changed: boolean = false
53
+
54
+ updated(changes: PropertyValues<this>) {
55
+ if (changes.has('value') && this.editor && !this._self_changing) {
56
+ const to = this.editor.state.doc.toString().length
57
+ this.editor.dispatch({
58
+ changes: { from: 0, to, insert: this.value === undefined ? '' : String(this.value) }
59
+ })
60
+ }
61
+ }
62
+
63
+ get editor() {
64
+ if (!this._editor) {
65
+ this._editor = new EditorView({
66
+ doc: this.value,
67
+ extensions: [
68
+ highlightActiveLine(),
69
+ history(),
70
+ javascript(),
71
+ keymap.of([
72
+ ...historyKeymap,
73
+ indentWithTab,
74
+ {
75
+ key: 'Escape',
76
+ run: (view: EditorView) => {
77
+ togglefullscreen(this)
78
+ return true
79
+ }
80
+ }
81
+ ]),
82
+ EditorView.updateListener.of(v => {
83
+ if (v.docChanged) {
84
+ this._self_changing = true
85
+ this.value = v.state.doc.toString()
86
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true, detail: this.value }))
87
+ requestAnimationFrame(() => {
88
+ this._self_changing = false
89
+ })
90
+ }
91
+ })
92
+ ],
93
+ parent: this.renderRoot
94
+ })
95
+ }
96
+
97
+ return this._editor
98
+ }
99
+ }
@@ -6,7 +6,7 @@ export default {
6
6
  title: 'ox-input-code',
7
7
  component: 'ox-input-code',
8
8
  argTypes: {
9
- value: { control: 'object' },
9
+ value: { control: 'text' },
10
10
  name: { control: 'text' }
11
11
  }
12
12
  }
@@ -19,10 +19,10 @@ interface Story<T> {
19
19
 
20
20
  interface ArgTypes {
21
21
  name?: string
22
- value?: object
22
+ value?: string
23
23
  }
24
24
 
25
- const Template: Story<ArgTypes> = ({ name = 'code', value = {} }: ArgTypes) => html`
25
+ const Template: Story<ArgTypes> = ({ name = 'code', value = '' }: ArgTypes) => html`
26
26
  <link href="/themes/app-theme.css" rel="stylesheet" />
27
27
  <link href="https://fonts.googleapis.com/css?family=Material+Icons&display=block" rel="stylesheet" />
28
28
  <style>
@@ -43,9 +43,5 @@ const Template: Story<ArgTypes> = ({ name = 'code', value = {} }: ArgTypes) => h
43
43
  export const Regular = Template.bind({})
44
44
  Regular.args = {
45
45
  name: 'code',
46
- value: {
47
- A: 'A',
48
- B: 'B',
49
- C: 'C'
50
- }
46
+ value: ''
51
47
  }
@@ -0,0 +1,58 @@
1
+ import '../src/ox-input-graphql.js'
2
+
3
+ import { html, TemplateResult } from 'lit'
4
+
5
+ export default {
6
+ title: 'ox-input-graphql',
7
+ component: 'ox-input-graphql',
8
+ argTypes: {
9
+ value: { control: 'text' },
10
+ name: { control: 'text' }
11
+ }
12
+ }
13
+
14
+ interface Story<T> {
15
+ (args: T): TemplateResult
16
+ args?: Partial<T>
17
+ argTypes?: Record<string, unknown>
18
+ }
19
+
20
+ interface ArgTypes {
21
+ name?: string
22
+ value?: string
23
+ }
24
+
25
+ const Template: Story<ArgTypes> = ({ name = 'code', value = '' }: ArgTypes) => html`
26
+ <link href="/themes/app-theme.css" rel="stylesheet" />
27
+ <link href="https://fonts.googleapis.com/css?family=Material+Icons&display=block" rel="stylesheet" />
28
+ <style>
29
+ body {
30
+ }
31
+ </style>
32
+
33
+ <ox-input-graphql
34
+ @change=${(e: Event) => {
35
+ console.log((e.target as HTMLInputElement).value)
36
+ }}
37
+ name=${name}
38
+ .value=${value}
39
+ >
40
+ </ox-input-graphql>
41
+ `
42
+
43
+ export const Regular = Template.bind({})
44
+ Regular.args = {
45
+ name: 'code',
46
+ value: `
47
+ query privileges {
48
+ privileges {
49
+ items {
50
+ privilege
51
+ category
52
+ description
53
+ }
54
+ total
55
+ }
56
+ }
57
+ `
58
+ }