mirror of
https://github.com/lana-k/sqliteviz.git
synced 2025-12-06 18:18:53 +08:00
add DelimiterSelector component
This commit is contained in:
130
src/ascii.js
Normal file
130
src/ascii.js
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
export default {
|
||||||
|
0: { name: 'null character' },
|
||||||
|
1: { name: 'start of header' },
|
||||||
|
2: { name: 'start of text' },
|
||||||
|
3: { name: 'end of text' },
|
||||||
|
4: { name: 'end of transmission' },
|
||||||
|
5: { name: 'enquiry' },
|
||||||
|
6: { name: 'acknowledge' },
|
||||||
|
7: { name: 'bell (ring)' },
|
||||||
|
8: { name: 'backspace' },
|
||||||
|
9: { name: 'horizontal tab' },
|
||||||
|
10: { name: 'line feed' },
|
||||||
|
11: { name: 'vertical tab' },
|
||||||
|
12: { name: 'form feed' },
|
||||||
|
13: { name: 'carriage return' },
|
||||||
|
14: { name: 'shift out' },
|
||||||
|
15: { name: 'shift in' },
|
||||||
|
16: { name: 'data link escape' },
|
||||||
|
17: { name: 'device control 1' },
|
||||||
|
18: { name: 'device control 2' },
|
||||||
|
19: { name: 'device control 3' },
|
||||||
|
20: { name: 'device control 4' },
|
||||||
|
21: { name: 'negative acknowledge' },
|
||||||
|
22: { name: 'synchronize' },
|
||||||
|
23: { name: 'end transmission block' },
|
||||||
|
24: { name: 'cancel' },
|
||||||
|
25: { name: 'end of medium' },
|
||||||
|
26: { name: 'substitute' },
|
||||||
|
27: { name: 'escape' },
|
||||||
|
28: { name: 'file separator' },
|
||||||
|
29: { name: 'group separator' },
|
||||||
|
30: { name: 'record separator' },
|
||||||
|
31: { name: 'unit separator' },
|
||||||
|
32: { name: 'space' },
|
||||||
|
33: { name: 'exclamation mark' },
|
||||||
|
34: { name: 'quotation mark' },
|
||||||
|
35: { name: 'number sign' },
|
||||||
|
36: { name: 'dollar sign' },
|
||||||
|
37: { name: 'percent sign' },
|
||||||
|
38: { name: 'ampersand' },
|
||||||
|
39: { name: 'apostrophe' },
|
||||||
|
40: { name: 'left parenthesis' },
|
||||||
|
41: { name: 'right parenthesis' },
|
||||||
|
42: { name: 'asterisk' },
|
||||||
|
43: { name: 'plus sign' },
|
||||||
|
44: { name: 'comma' },
|
||||||
|
45: { name: 'hyphen' },
|
||||||
|
46: { name: 'period' },
|
||||||
|
47: { name: 'slash' },
|
||||||
|
48: { name: 'digit 0' },
|
||||||
|
49: { name: 'digit 1' },
|
||||||
|
50: { name: 'digit 2' },
|
||||||
|
51: { name: 'digit 3' },
|
||||||
|
52: { name: 'digit 4' },
|
||||||
|
53: { name: 'digit 5' },
|
||||||
|
54: { name: 'digit 6' },
|
||||||
|
55: { name: 'digit 7' },
|
||||||
|
56: { name: 'digit 8' },
|
||||||
|
57: { name: 'digit 9' },
|
||||||
|
58: { name: 'colon' },
|
||||||
|
59: { name: 'semicolon' },
|
||||||
|
60: { name: 'less-than' },
|
||||||
|
61: { name: 'equals-to' },
|
||||||
|
62: { name: 'greater-than' },
|
||||||
|
63: { name: 'question mark' },
|
||||||
|
64: { name: 'at sign' },
|
||||||
|
65: { name: 'uppercase A' },
|
||||||
|
66: { name: 'uppercase B' },
|
||||||
|
67: { name: 'uppercase C' },
|
||||||
|
68: { name: 'uppercase D' },
|
||||||
|
69: { name: 'uppercase E' },
|
||||||
|
70: { name: 'uppercase F' },
|
||||||
|
71: { name: 'uppercase G' },
|
||||||
|
72: { name: 'uppercase H' },
|
||||||
|
73: { name: 'uppercase I' },
|
||||||
|
74: { name: 'uppercase J' },
|
||||||
|
75: { name: 'uppercase K' },
|
||||||
|
76: { name: 'uppercase L' },
|
||||||
|
77: { name: 'uppercase M' },
|
||||||
|
78: { name: 'uppercase N' },
|
||||||
|
79: { name: 'uppercase O' },
|
||||||
|
80: { name: 'uppercase P' },
|
||||||
|
81: { name: 'uppercase Q' },
|
||||||
|
82: { name: 'uppercase R' },
|
||||||
|
83: { name: 'uppercase S' },
|
||||||
|
84: { name: 'uppercase T' },
|
||||||
|
85: { name: 'uppercase U' },
|
||||||
|
86: { name: 'uppercase V' },
|
||||||
|
87: { name: 'uppercase W' },
|
||||||
|
88: { name: 'uppercase X' },
|
||||||
|
89: { name: 'uppercase Y' },
|
||||||
|
90: { name: 'uppercase Z' },
|
||||||
|
91: { name: 'left square bracket' },
|
||||||
|
92: { name: 'backslash' },
|
||||||
|
93: { name: 'right square bracket' },
|
||||||
|
94: { name: 'caret' },
|
||||||
|
95: { name: 'underscore' },
|
||||||
|
96: { name: 'grave accent' },
|
||||||
|
97: { name: 'lowercase a' },
|
||||||
|
98: { name: 'lowercase b' },
|
||||||
|
99: { name: 'lowercase c' },
|
||||||
|
100: { name: 'lowercase d' },
|
||||||
|
101: { name: 'lowercase e' },
|
||||||
|
102: { name: 'lowercase f' },
|
||||||
|
103: { name: 'lowercase g' },
|
||||||
|
104: { name: 'lowercase h' },
|
||||||
|
105: { name: 'lowercase i' },
|
||||||
|
106: { name: 'lowercase j' },
|
||||||
|
107: { name: 'lowercase k' },
|
||||||
|
108: { name: 'lowercase l' },
|
||||||
|
109: { name: 'lowercase m' },
|
||||||
|
110: { name: 'lowercase n' },
|
||||||
|
111: { name: 'lowercase o' },
|
||||||
|
112: { name: 'lowercase p' },
|
||||||
|
113: { name: 'lowercase q' },
|
||||||
|
114: { name: 'lowercase r' },
|
||||||
|
115: { name: 'lowercase s' },
|
||||||
|
116: { name: 'lowercase t' },
|
||||||
|
117: { name: 'lowercase u' },
|
||||||
|
118: { name: 'lowercase v' },
|
||||||
|
119: { name: 'lowercase w' },
|
||||||
|
120: { name: 'lowercase x' },
|
||||||
|
121: { name: 'lowercase y' },
|
||||||
|
122: { name: 'lowercase z' },
|
||||||
|
123: { name: 'left curly brace' },
|
||||||
|
124: { name: 'vertical bar' },
|
||||||
|
125: { name: 'right curly brace' },
|
||||||
|
126: { name: 'tilde' },
|
||||||
|
127: { name: 'delete (rubout)' }
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
--color-bg-light-3: var(--color-gray-light-5);
|
--color-bg-light-3: var(--color-gray-light-5);
|
||||||
--color-bg-dark: var(--color-gray-dark);
|
--color-bg-dark: var(--color-gray-dark);
|
||||||
--color-bg-warning: var(--color-yellow);
|
--color-bg-warning: var(--color-yellow);
|
||||||
|
--color-danger: var(--color-red);
|
||||||
--color-accent: var(--color-blue-medium);
|
--color-accent: var(--color-blue-medium);
|
||||||
--color-accent-shade: var(--color-blue-dark);
|
--color-accent-shade: var(--color-blue-dark);
|
||||||
--color-border-light: var(--color-gray-light-2);
|
--color-border-light: var(--color-gray-light-2);
|
||||||
|
|||||||
171
src/components/DelimiterSelector.vue
Normal file
171
src/components/DelimiterSelector.vue
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="text-field-label">Delimiter</div>
|
||||||
|
<div
|
||||||
|
class="delimiter-selector-container"
|
||||||
|
:style="{ width: width }"
|
||||||
|
@click="onContainerClick"
|
||||||
|
>
|
||||||
|
<div class="value">
|
||||||
|
<input
|
||||||
|
ref="delimiterInput"
|
||||||
|
type="text"
|
||||||
|
:value="value"
|
||||||
|
@click.stop
|
||||||
|
@keypress="onKeyPress"
|
||||||
|
@input.prevent="onInput($event)"
|
||||||
|
/>
|
||||||
|
<div class="name">{{ getSymbolName(value) }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="controls" @click.stop>
|
||||||
|
<clear-icon @click.native="$emit('input', '')"/>
|
||||||
|
<drop-down-chevron @click.native="showOptions = !showOptions"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-show="showOptions" class="options" :style="{ width: width }">
|
||||||
|
<div
|
||||||
|
v-for="(option, index) in options"
|
||||||
|
:key="index"
|
||||||
|
@click="chooseOption(option)"
|
||||||
|
class="option"
|
||||||
|
>
|
||||||
|
<span>{{option}}</span><div>{{ getSymbolName(option) }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ascii from '@/ascii'
|
||||||
|
import DropDownChevron from '@/components/svg/dropDownChevron'
|
||||||
|
import ClearIcon from '@/components/svg/clear'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'DelimiterSelector',
|
||||||
|
props: ['label', 'value', 'width'],
|
||||||
|
components: { DropDownChevron, ClearIcon },
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
showOptions: false,
|
||||||
|
options: [',', '\t', '|', ';', '\u001F', '\u001E']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getSymbolName (str) {
|
||||||
|
if (!str) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
return ascii[str.charCodeAt(0).toString()].name
|
||||||
|
},
|
||||||
|
onKeyPress (event) {
|
||||||
|
if (event.target.value.length >= 1) {
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onInput (event) {
|
||||||
|
const value = event.target.value
|
||||||
|
if (value.length > 1) {
|
||||||
|
event.target.value = value[0]
|
||||||
|
}
|
||||||
|
this.$emit('input', event.target.value)
|
||||||
|
},
|
||||||
|
chooseOption (option) {
|
||||||
|
this.$emit('input', option)
|
||||||
|
this.showOptions = false
|
||||||
|
},
|
||||||
|
onContainerClick (event) {
|
||||||
|
this.$refs.delimiterInput.focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.delimiter-selector-container {
|
||||||
|
background: var(--color-white);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
color: var(--color-text-light-2);
|
||||||
|
border-radius: var(--border-radius-medium-2);
|
||||||
|
height: 36px;
|
||||||
|
padding: 0 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value .name {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options {
|
||||||
|
background: var(--color-white);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-width: 0 1px 1px 1px;
|
||||||
|
color: var(--color-text-base);
|
||||||
|
border-radius: var(--border-radius-medium-2);
|
||||||
|
font-size: 12px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
white-space: pre;
|
||||||
|
height: 24px;
|
||||||
|
padding: 0 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option:hover {
|
||||||
|
background-color: var(--color-bg-light);
|
||||||
|
color: var(--color-text-active);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option span {
|
||||||
|
background-color: var(--color-bg-warning);
|
||||||
|
line-height: 16px;
|
||||||
|
letter-spacing: 6px;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
background: var(--color-white);
|
||||||
|
border: none;
|
||||||
|
color: var(--color-text-base);
|
||||||
|
height: 34px;
|
||||||
|
font-size: 12px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 20px;
|
||||||
|
letter-spacing: 6px;
|
||||||
|
line-height: 37px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input::first-line {
|
||||||
|
background-color: var(--color-bg-warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-field-label {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--color-text-base);
|
||||||
|
padding-left: 8px;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
32
src/components/svg/clear.vue
Normal file
32
src/components/svg/clear.vue
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<template>
|
||||||
|
<svg
|
||||||
|
class="clear-icon"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M14.3481 14.849C13.8791 15.318 13.1191 15.318 12.6511 14.849L10.0001 11.819L7.34907 14.848C6.88007 15.317 6.12007 15.317 5.65207 14.848C5.18307 14.379 5.18307 13.619 5.65207 13.151L8.41007 10.001L5.65107 6.84898C5.18207 6.37998 5.18207 5.62098 5.65107 5.15198C6.12007 4.68298 6.87907 4.68298 7.34807 5.15198L10.0001 8.18298L12.6511 5.15198C13.1201 4.68298 13.8791 4.68298 14.3481 5.15198C14.8171 5.62098 14.8171 6.38098 14.3481 6.84898L11.5901 10.001L14.3481 13.151C14.8171 13.62 14.8171 14.38 14.3481 14.849V14.849Z"
|
||||||
|
fill="#C8D4E3"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ClearIcon'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.clear-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear-icon:hover path {
|
||||||
|
fill: var(--color-danger);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
29
src/components/svg/dropDownChevron.vue
Normal file
29
src/components/svg/dropDownChevron.vue
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<svg
|
||||||
|
class="chevron-icon"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path d="M6.175 7.15002L10 10.975L13.825 7.15002L15 8.33336L10 13.3334L5 8.33336L6.175 7.15002Z" fill="#C8D4E3"/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'DropDownChevron'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.chevron-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chevron-icon:hover path {
|
||||||
|
fill: var(--color-accent);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user