@dataloop-ai/components 0.18.25 → 0.18.27
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 +1 -1
- package/src/assets/globals.scss +1 -0
- package/src/components/compound/DlCodeEditor/DlCodeEditor.vue +3 -0
- package/src/components/compound/DlCodeEditor/components/CodeEditor.vue +34 -20
- package/src/components/compound/DlInput/DlInput.vue +18 -3
- package/src/components/compound/DlJsonEditor/DlJsonEditor.vue +111 -50
- package/src/demos/DlJsonEditorDemo.vue +27 -4
package/package.json
CHANGED
package/src/assets/globals.scss
CHANGED
|
@@ -128,6 +128,7 @@ import { DlSelect } from '../../DlSelect'
|
|
|
128
128
|
import { DlToast } from '../../DlToast'
|
|
129
129
|
import '../styles/themes.css'
|
|
130
130
|
import '../styles/themes-base16.css'
|
|
131
|
+
import { debounce } from 'lodash'
|
|
131
132
|
|
|
132
133
|
export default defineComponent({
|
|
133
134
|
name: 'CodeEditor',
|
|
@@ -369,32 +370,27 @@ export default defineComponent({
|
|
|
369
370
|
lineNumsResizer.value = null as any
|
|
370
371
|
}
|
|
371
372
|
|
|
372
|
-
const
|
|
373
|
+
const getLinesCount = () => {
|
|
373
374
|
if (!lineNumsEl.value) return
|
|
374
375
|
|
|
375
376
|
// lineNum
|
|
376
377
|
const str = textarea.value.value
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
//
|
|
384
|
-
const
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
const heightNum =
|
|
388
|
-
Math.round(textareaHeight.value / singleLineHeight) - 1
|
|
378
|
+
const matches = str.match(/(\r\n|\r|\n)/gim)
|
|
379
|
+
const localLineNum = matches.length
|
|
380
|
+
|
|
381
|
+
// // disabling the current behavior of highlighting entire dock
|
|
382
|
+
// const singleLineHeight = (
|
|
383
|
+
// lineNumsEl.value.firstChild as HTMLElement
|
|
384
|
+
// ).offsetHeight
|
|
385
|
+
// const heightNum =
|
|
386
|
+
// Math.round(textareaHeight.value / singleLineHeight) - 1
|
|
387
|
+
|
|
389
388
|
// displayed lineNum
|
|
390
|
-
lineNum.value =
|
|
391
|
-
height.value == 'auto'
|
|
392
|
-
? localLineNum
|
|
393
|
-
: localLineNum > heightNum
|
|
394
|
-
? localLineNum
|
|
395
|
-
: heightNum
|
|
389
|
+
lineNum.value = localLineNum
|
|
396
390
|
}
|
|
397
391
|
|
|
392
|
+
const debouncedGetLinesCount = debounce(getLinesCount, 100)
|
|
393
|
+
|
|
398
394
|
onMounted(() => {
|
|
399
395
|
emit('lang', props.languages[0][0])
|
|
400
396
|
emit('content', props.content)
|
|
@@ -404,6 +400,13 @@ export default defineComponent({
|
|
|
404
400
|
setupLineNumsResizer()
|
|
405
401
|
}
|
|
406
402
|
code.value.textContent = contentValue.value
|
|
403
|
+
if (lineNums.value) {
|
|
404
|
+
if (scrolling.value) {
|
|
405
|
+
scrolling.value = false
|
|
406
|
+
} else {
|
|
407
|
+
debouncedGetLinesCount()
|
|
408
|
+
}
|
|
409
|
+
}
|
|
407
410
|
hljs.highlightElement(code.value)
|
|
408
411
|
})
|
|
409
412
|
|
|
@@ -429,16 +432,27 @@ export default defineComponent({
|
|
|
429
432
|
} else {
|
|
430
433
|
disposeLineNumsResizer()
|
|
431
434
|
}
|
|
435
|
+
|
|
432
436
|
if (lineNums.value) {
|
|
433
437
|
if (scrolling.value) {
|
|
434
438
|
scrolling.value = false
|
|
435
439
|
} else {
|
|
436
|
-
|
|
440
|
+
debouncedGetLinesCount()
|
|
437
441
|
}
|
|
438
442
|
}
|
|
439
443
|
})
|
|
440
444
|
})
|
|
441
445
|
|
|
446
|
+
watch(modelValue, () => {
|
|
447
|
+
if (lineNums.value) {
|
|
448
|
+
if (scrolling.value) {
|
|
449
|
+
scrolling.value = false
|
|
450
|
+
} else {
|
|
451
|
+
debouncedGetLinesCount()
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
})
|
|
455
|
+
|
|
442
456
|
const copy = async () => {
|
|
443
457
|
try {
|
|
444
458
|
await navigator.clipboard.writeText(textarea.value.value)
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
:type="showPass ? 'text' : type"
|
|
79
79
|
:disabled="disabled"
|
|
80
80
|
:readonly="readonly"
|
|
81
|
-
@input="
|
|
81
|
+
@input="debouncedInput"
|
|
82
82
|
@focus="onFocus"
|
|
83
83
|
@blur="debouncedBlur"
|
|
84
84
|
@keyup.enter="onKeyPress"
|
|
@@ -100,7 +100,12 @@
|
|
|
100
100
|
]"
|
|
101
101
|
>
|
|
102
102
|
<slot name="append" />
|
|
103
|
-
<span
|
|
103
|
+
<span
|
|
104
|
+
v-if="showClearButton"
|
|
105
|
+
v-show="focused || mouseOverClear"
|
|
106
|
+
@mouseenter="mouseOverClear = true"
|
|
107
|
+
@mouseleave="mouseOverClear = false"
|
|
108
|
+
>
|
|
104
109
|
<dl-button
|
|
105
110
|
ref="input-clear-button"
|
|
106
111
|
icon="icon-dl-close"
|
|
@@ -374,10 +379,15 @@ export default defineComponent({
|
|
|
374
379
|
margin: {
|
|
375
380
|
type: String,
|
|
376
381
|
default: null
|
|
382
|
+
},
|
|
383
|
+
debounce: {
|
|
384
|
+
type: Number,
|
|
385
|
+
default: 100
|
|
377
386
|
}
|
|
378
387
|
},
|
|
379
388
|
emits: ['input', 'focus', 'blur', 'clear', 'enter', 'update:model-value'],
|
|
380
389
|
setup(props, { emit }) {
|
|
390
|
+
const mouseOverClear = ref(false)
|
|
381
391
|
const highlightedIndex = ref(-1)
|
|
382
392
|
const isMenuOpen = ref(false)
|
|
383
393
|
const suggestItems = computed<string[]>(() => {
|
|
@@ -408,7 +418,8 @@ export default defineComponent({
|
|
|
408
418
|
onAutoSuggestClick,
|
|
409
419
|
isMenuOpen,
|
|
410
420
|
setHighlightedIndex,
|
|
411
|
-
handleSelectedItem
|
|
421
|
+
handleSelectedItem,
|
|
422
|
+
mouseOverClear
|
|
412
423
|
}
|
|
413
424
|
},
|
|
414
425
|
data() {
|
|
@@ -559,6 +570,10 @@ export default defineComponent({
|
|
|
559
570
|
}
|
|
560
571
|
|
|
561
572
|
return classes
|
|
573
|
+
},
|
|
574
|
+
debouncedInput(): any {
|
|
575
|
+
const debounced = debounce(this.onChange.bind(this), this.debounce)
|
|
576
|
+
return debounced
|
|
562
577
|
}
|
|
563
578
|
},
|
|
564
579
|
methods: {
|
|
@@ -6,8 +6,16 @@
|
|
|
6
6
|
</template>
|
|
7
7
|
|
|
8
8
|
<script lang="ts">
|
|
9
|
-
import { defineComponent } from 'vue-demi'
|
|
10
|
-
import {
|
|
9
|
+
import { defineComponent, onMounted, ref, toRefs, watch } from 'vue-demi'
|
|
10
|
+
import {
|
|
11
|
+
Content,
|
|
12
|
+
ContentParseError,
|
|
13
|
+
JSONEditor,
|
|
14
|
+
JSONEditorPropsOptional,
|
|
15
|
+
Mode,
|
|
16
|
+
OnChangeStatus,
|
|
17
|
+
TextContent
|
|
18
|
+
} from 'vanilla-jsoneditor'
|
|
11
19
|
import { debounce } from 'lodash'
|
|
12
20
|
|
|
13
21
|
export default defineComponent({
|
|
@@ -20,55 +28,74 @@ export default defineComponent({
|
|
|
20
28
|
* The string to display and modify as JSON
|
|
21
29
|
*/
|
|
22
30
|
modelValue: {
|
|
31
|
+
required: false,
|
|
23
32
|
type: String,
|
|
24
33
|
default: '{}'
|
|
25
34
|
},
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
indentation: {
|
|
36
|
+
required: false,
|
|
37
|
+
type: Number,
|
|
38
|
+
default: 2
|
|
39
|
+
},
|
|
40
|
+
readonly: {
|
|
41
|
+
required: false,
|
|
31
42
|
type: Boolean,
|
|
32
|
-
default:
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
emits: ['update:model-value', 'update-prevent', 'align-text'],
|
|
36
|
-
data() {
|
|
37
|
-
return {
|
|
38
|
-
jsonEditor: {} as JSONEditor,
|
|
39
|
-
preventOnChange: false
|
|
43
|
+
default: false
|
|
40
44
|
}
|
|
41
45
|
},
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
emits: ['update:model-value', 'align-text', 'change'],
|
|
47
|
+
setup(props, { emit }) {
|
|
48
|
+
const { modelValue, indentation, readonly } = toRefs(props)
|
|
49
|
+
|
|
50
|
+
const jsonEditorRef = ref(null)
|
|
51
|
+
const jsonEditor = ref<JSONEditor>(null as any)
|
|
52
|
+
const innerUpdate = ref(false)
|
|
53
|
+
|
|
54
|
+
watch(modelValue, (val) => {
|
|
55
|
+
if (innerUpdate.value) {
|
|
56
|
+
innerUpdate.value = false
|
|
57
|
+
return
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
jsonEditor.value?.set({
|
|
61
|
+
text: val
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
const handleJSONChange = (
|
|
66
|
+
content: Content,
|
|
67
|
+
previousContent: Content,
|
|
68
|
+
status: OnChangeStatus
|
|
69
|
+
) => {
|
|
70
|
+
if (
|
|
71
|
+
status.contentErrors &&
|
|
72
|
+
(status.contentErrors as ContentParseError).isRepairable !==
|
|
73
|
+
undefined
|
|
74
|
+
) {
|
|
75
|
+
if (!(status.contentErrors as ContentParseError).isRepairable) {
|
|
76
|
+
console.warn('[DlJsonEditor] Failed to parse JSON')
|
|
77
|
+
return
|
|
47
78
|
}
|
|
48
79
|
}
|
|
80
|
+
|
|
81
|
+
if (
|
|
82
|
+
(content as TextContent).text ===
|
|
83
|
+
(previousContent as TextContent).text
|
|
84
|
+
) {
|
|
85
|
+
return
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
innerUpdate.value = true
|
|
89
|
+
emit('update:model-value', (content as TextContent).text)
|
|
90
|
+
emit('change', (content as TextContent).text)
|
|
49
91
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
initJsonEditor() {
|
|
58
|
-
const initialAttrs: any = {
|
|
59
|
-
onChange: debounce(
|
|
60
|
-
(updatedContent: { text: string; json: any }) => {
|
|
61
|
-
if (this.preventOnChange) {
|
|
62
|
-
this.preventOnChange = false
|
|
63
|
-
return
|
|
64
|
-
}
|
|
65
|
-
this.$emit('update:model-value', updatedContent.text)
|
|
66
|
-
if (this.preventUpdate !== null) {
|
|
67
|
-
this.$emit('update-prevent', true)
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
100
|
|
71
|
-
),
|
|
92
|
+
|
|
93
|
+
const debouncedHandleJSONChange = debounce(handleJSONChange, 100)
|
|
94
|
+
|
|
95
|
+
const initJsonEditor = () => {
|
|
96
|
+
const initialAttrs: JSONEditorPropsOptional = {
|
|
97
|
+
onChange: debouncedHandleJSONChange,
|
|
98
|
+
indentation: indentation.value,
|
|
72
99
|
mode: Mode.text,
|
|
73
100
|
mainMenuBar: false,
|
|
74
101
|
navigationBar: false,
|
|
@@ -78,17 +105,49 @@ export default defineComponent({
|
|
|
78
105
|
// There is type instantiation issue with JSONEditor,
|
|
79
106
|
// it gives excessively deep and possibly infinite error
|
|
80
107
|
// @ts-ignore
|
|
81
|
-
|
|
82
|
-
target:
|
|
83
|
-
? (
|
|
108
|
+
jsonEditor.value = new JSONEditor({
|
|
109
|
+
target: jsonEditorRef.value
|
|
110
|
+
? (jsonEditorRef.value as Element)
|
|
84
111
|
: document.createElement('div'),
|
|
85
112
|
props: initialAttrs
|
|
86
113
|
})
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
114
|
+
|
|
115
|
+
jsonEditor.value?.set({
|
|
116
|
+
text: modelValue.value
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
watch(readonly, (val) => {
|
|
121
|
+
jsonEditor.value?.updateProps({
|
|
122
|
+
readOnly: val
|
|
91
123
|
})
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
const format = () => {
|
|
127
|
+
try {
|
|
128
|
+
const parsed = JSON.parse(modelValue.value)
|
|
129
|
+
const formatted = JSON.stringify(
|
|
130
|
+
parsed,
|
|
131
|
+
null,
|
|
132
|
+
indentation.value
|
|
133
|
+
)
|
|
134
|
+
jsonEditor.value?.set({
|
|
135
|
+
text: formatted
|
|
136
|
+
})
|
|
137
|
+
} catch (e) {
|
|
138
|
+
console.warn('[DlJsonEditor] Failed to format document', e)
|
|
139
|
+
return
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
onMounted(() => {
|
|
144
|
+
initJsonEditor()
|
|
145
|
+
emit('align-text')
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
jsonEditorRef,
|
|
150
|
+
format
|
|
92
151
|
}
|
|
93
152
|
}
|
|
94
153
|
})
|
|
@@ -99,11 +158,13 @@ export default defineComponent({
|
|
|
99
158
|
--jse-text-color: var(--dl-color-tooltip-background);
|
|
100
159
|
--jse-delimiter-color: var(--dl-color-tooltip-background);
|
|
101
160
|
--jse-key-color: var(--dl-color-negative);
|
|
102
|
-
--jse-background-color: var(--dl-color-
|
|
161
|
+
--jse-background-color: var(--dl-color-secondary-opaque);
|
|
103
162
|
--jse-value-color-boolean: #ae6307;
|
|
104
163
|
--jse-value-color-string: #337433;
|
|
105
164
|
--jse-panel-background: var(--dl-color-fill);
|
|
106
165
|
--jse-panel-border: var(--dl-color-separator);
|
|
166
|
+
--jse-main-border: 1px solid var(--dl-color-separator);
|
|
167
|
+
|
|
107
168
|
height: 100%;
|
|
108
169
|
.jse-error {
|
|
109
170
|
display: none !important;
|
|
@@ -6,8 +6,20 @@
|
|
|
6
6
|
justify-content: space-between;
|
|
7
7
|
"
|
|
8
8
|
>
|
|
9
|
+
<dl-button
|
|
10
|
+
label="Align Text"
|
|
11
|
+
@click="jsonEditorEl.format()"
|
|
12
|
+
/>
|
|
13
|
+
<dl-switch
|
|
14
|
+
v-model="readonly"
|
|
15
|
+
left-label="read only"
|
|
16
|
+
/>
|
|
9
17
|
<div style="height: 200px; width: 500px">
|
|
10
|
-
<dl-json-editor
|
|
18
|
+
<dl-json-editor
|
|
19
|
+
ref="jsonEditorEl"
|
|
20
|
+
v-model="jsonModel"
|
|
21
|
+
:readonly="readonly"
|
|
22
|
+
/>
|
|
11
23
|
</div>
|
|
12
24
|
<span>JSON: {{ jsonModel }}</span>
|
|
13
25
|
|
|
@@ -41,18 +53,29 @@ import {
|
|
|
41
53
|
DlJsonEditor,
|
|
42
54
|
DlDialogBox,
|
|
43
55
|
DlDialogBoxHeader,
|
|
44
|
-
DlButton
|
|
56
|
+
DlButton,
|
|
57
|
+
DlSwitch
|
|
45
58
|
} from '../components'
|
|
46
59
|
export default defineComponent({
|
|
47
|
-
components: {
|
|
60
|
+
components: {
|
|
61
|
+
DlJsonEditor,
|
|
62
|
+
DlDialogBox,
|
|
63
|
+
DlDialogBoxHeader,
|
|
64
|
+
DlButton,
|
|
65
|
+
DlSwitch
|
|
66
|
+
},
|
|
48
67
|
setup() {
|
|
49
68
|
const jsonModel = ref('')
|
|
50
69
|
const dialogJsonModel = ref('')
|
|
51
70
|
const dialogState = ref(false)
|
|
71
|
+
const jsonEditorEl = ref(null)
|
|
72
|
+
const readonly = ref(false)
|
|
52
73
|
return {
|
|
53
74
|
jsonModel,
|
|
54
75
|
dialogState,
|
|
55
|
-
dialogJsonModel
|
|
76
|
+
dialogJsonModel,
|
|
77
|
+
jsonEditorEl,
|
|
78
|
+
readonly
|
|
56
79
|
}
|
|
57
80
|
}
|
|
58
81
|
})
|