@caido-utils/components 0.1.0
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/dist/ButtonGroup/Container.d.vue.ts +34 -0
- package/dist/ButtonGroup/Container.vue +36 -0
- package/dist/ButtonGroup/Container.vue.d.ts +34 -0
- package/dist/Card/Container.d.vue.ts +12 -0
- package/dist/Card/Container.vue +21 -0
- package/dist/Card/Container.vue.d.ts +12 -0
- package/dist/ContextMenu/Container.d.vue.ts +9 -0
- package/dist/ContextMenu/Container.vue +38 -0
- package/dist/ContextMenu/Container.vue.d.ts +9 -0
- package/dist/DataTable/Container.d.vue.ts +68 -0
- package/dist/DataTable/Container.vue +295 -0
- package/dist/DataTable/Container.vue.d.ts +68 -0
- package/dist/Dialog/Container.d.vue.ts +64 -0
- package/dist/Dialog/Container.vue +89 -0
- package/dist/Dialog/Container.vue.d.ts +64 -0
- package/dist/HttpqlInput/Container.d.vue.ts +33 -0
- package/dist/HttpqlInput/Container.vue +225 -0
- package/dist/HttpqlInput/Container.vue.d.ts +33 -0
- package/dist/HttpqlInput/suggestions.d.ts +24 -0
- package/dist/HttpqlInput/suggestions.js +325 -0
- package/dist/Menu/Container.d.vue.ts +11 -0
- package/dist/Menu/Container.vue +40 -0
- package/dist/Menu/Container.vue.d.ts +11 -0
- package/dist/MenuButton/Container.d.vue.ts +43 -0
- package/dist/MenuButton/Container.vue +42 -0
- package/dist/MenuButton/Container.vue.d.ts +43 -0
- package/dist/MultiSelect/Container.d.vue.ts +54 -0
- package/dist/MultiSelect/Container.vue +57 -0
- package/dist/MultiSelect/Container.vue.d.ts +54 -0
- package/dist/RequestEditor/Container.d.vue.ts +30 -0
- package/dist/RequestEditor/Container.vue +67 -0
- package/dist/RequestEditor/Container.vue.d.ts +30 -0
- package/dist/ResponseEditor/Container.d.vue.ts +30 -0
- package/dist/ResponseEditor/Container.vue +67 -0
- package/dist/ResponseEditor/Container.vue.d.ts +30 -0
- package/dist/Table/Container.d.vue.ts +36 -0
- package/dist/Table/Container.vue +512 -0
- package/dist/Table/Container.vue.d.ts +36 -0
- package/dist/env.d.ts +5 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +12 -0
- package/package.json +32 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
title: string;
|
|
3
|
+
width: string;
|
|
4
|
+
showBack?: boolean;
|
|
5
|
+
showFooter?: boolean;
|
|
6
|
+
actionLabel?: string;
|
|
7
|
+
actionIcon?: string;
|
|
8
|
+
actionDisabled?: boolean;
|
|
9
|
+
actionLoading?: boolean;
|
|
10
|
+
cancelLabel?: string;
|
|
11
|
+
contentClass?: string;
|
|
12
|
+
};
|
|
13
|
+
declare var __VLS_26: {}, __VLS_28: {};
|
|
14
|
+
type __VLS_Slots = {} & {
|
|
15
|
+
default?: (props: typeof __VLS_26) => any;
|
|
16
|
+
} & {
|
|
17
|
+
footer?: (props: typeof __VLS_28) => any;
|
|
18
|
+
};
|
|
19
|
+
declare const __VLS_component: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
|
|
20
|
+
showBack: boolean;
|
|
21
|
+
showFooter: boolean;
|
|
22
|
+
actionLabel: string;
|
|
23
|
+
actionDisabled: boolean;
|
|
24
|
+
actionLoading: boolean;
|
|
25
|
+
cancelLabel: string;
|
|
26
|
+
}>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
|
|
27
|
+
showBack: boolean;
|
|
28
|
+
showFooter: boolean;
|
|
29
|
+
actionLabel: string;
|
|
30
|
+
actionDisabled: boolean;
|
|
31
|
+
actionLoading: boolean;
|
|
32
|
+
cancelLabel: string;
|
|
33
|
+
}>>>, {
|
|
34
|
+
showBack: boolean;
|
|
35
|
+
showFooter: boolean;
|
|
36
|
+
actionLabel: string;
|
|
37
|
+
actionDisabled: boolean;
|
|
38
|
+
actionLoading: boolean;
|
|
39
|
+
cancelLabel: string;
|
|
40
|
+
}, {}>;
|
|
41
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
42
|
+
export default _default;
|
|
43
|
+
type __VLS_WithDefaults<P, D> = {
|
|
44
|
+
[K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
|
|
45
|
+
default: D[K];
|
|
46
|
+
}> : P[K];
|
|
47
|
+
};
|
|
48
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
49
|
+
type __VLS_TypePropsToOption<T> = {
|
|
50
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? {
|
|
51
|
+
type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
|
|
52
|
+
} : {
|
|
53
|
+
type: import('vue').PropType<T[K]>;
|
|
54
|
+
required: true;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
58
|
+
new (): {
|
|
59
|
+
$slots: S;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
type __VLS_PrettifyLocal<T> = {
|
|
63
|
+
[K in keyof T]: T[K];
|
|
64
|
+
} & {};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import Button from "primevue/button";
|
|
3
|
+
import Dialog from "primevue/dialog";
|
|
4
|
+
|
|
5
|
+
withDefaults(
|
|
6
|
+
defineProps<{
|
|
7
|
+
title: string;
|
|
8
|
+
width: string;
|
|
9
|
+
showBack?: boolean;
|
|
10
|
+
showFooter?: boolean;
|
|
11
|
+
actionLabel?: string;
|
|
12
|
+
actionIcon?: string;
|
|
13
|
+
actionDisabled?: boolean;
|
|
14
|
+
actionLoading?: boolean;
|
|
15
|
+
cancelLabel?: string;
|
|
16
|
+
contentClass?: string;
|
|
17
|
+
}>(),
|
|
18
|
+
{
|
|
19
|
+
showBack: false,
|
|
20
|
+
showFooter: true,
|
|
21
|
+
actionLabel: "Confirm",
|
|
22
|
+
actionDisabled: false,
|
|
23
|
+
actionLoading: false,
|
|
24
|
+
cancelLabel: "Cancel",
|
|
25
|
+
},
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const emit = defineEmits<{
|
|
29
|
+
close: [];
|
|
30
|
+
back: [];
|
|
31
|
+
action: [];
|
|
32
|
+
}>();
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<template>
|
|
36
|
+
<Dialog
|
|
37
|
+
:visible="true"
|
|
38
|
+
modal
|
|
39
|
+
:closable="false"
|
|
40
|
+
:style="{ width }"
|
|
41
|
+
:content-class="contentClass"
|
|
42
|
+
@update:visible="emit('close')"
|
|
43
|
+
>
|
|
44
|
+
<template #header>
|
|
45
|
+
<div class="flex items-center justify-between w-full">
|
|
46
|
+
<div class="flex items-center gap-3">
|
|
47
|
+
<Button
|
|
48
|
+
v-if="showBack"
|
|
49
|
+
icon="fas fa-arrow-left"
|
|
50
|
+
text
|
|
51
|
+
severity="secondary"
|
|
52
|
+
size="small"
|
|
53
|
+
@click="emit('back')"
|
|
54
|
+
/>
|
|
55
|
+
<span class="font-semibold text-lg">{{ title }}</span>
|
|
56
|
+
</div>
|
|
57
|
+
<Button
|
|
58
|
+
icon="fas fa-times"
|
|
59
|
+
text
|
|
60
|
+
severity="secondary"
|
|
61
|
+
size="small"
|
|
62
|
+
@click="emit('close')"
|
|
63
|
+
/>
|
|
64
|
+
</div>
|
|
65
|
+
</template>
|
|
66
|
+
|
|
67
|
+
<slot />
|
|
68
|
+
|
|
69
|
+
<template v-if="showFooter" #footer>
|
|
70
|
+
<slot name="footer">
|
|
71
|
+
<div class="flex justify-end gap-2">
|
|
72
|
+
<Button
|
|
73
|
+
:label="cancelLabel"
|
|
74
|
+
severity="secondary"
|
|
75
|
+
text
|
|
76
|
+
@click="emit('close')"
|
|
77
|
+
/>
|
|
78
|
+
<Button
|
|
79
|
+
:label="actionLabel"
|
|
80
|
+
:icon="actionIcon"
|
|
81
|
+
:disabled="actionDisabled"
|
|
82
|
+
:loading="actionLoading"
|
|
83
|
+
@click="emit('action')"
|
|
84
|
+
/>
|
|
85
|
+
</div>
|
|
86
|
+
</slot>
|
|
87
|
+
</template>
|
|
88
|
+
</Dialog>
|
|
89
|
+
</template>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
title: string;
|
|
3
|
+
width: string;
|
|
4
|
+
showBack?: boolean;
|
|
5
|
+
showFooter?: boolean;
|
|
6
|
+
actionLabel?: string;
|
|
7
|
+
actionIcon?: string;
|
|
8
|
+
actionDisabled?: boolean;
|
|
9
|
+
actionLoading?: boolean;
|
|
10
|
+
cancelLabel?: string;
|
|
11
|
+
contentClass?: string;
|
|
12
|
+
};
|
|
13
|
+
declare var __VLS_26: {}, __VLS_28: {};
|
|
14
|
+
type __VLS_Slots = {} & {
|
|
15
|
+
default?: (props: typeof __VLS_26) => any;
|
|
16
|
+
} & {
|
|
17
|
+
footer?: (props: typeof __VLS_28) => any;
|
|
18
|
+
};
|
|
19
|
+
declare const __VLS_component: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
|
|
20
|
+
showBack: boolean;
|
|
21
|
+
showFooter: boolean;
|
|
22
|
+
actionLabel: string;
|
|
23
|
+
actionDisabled: boolean;
|
|
24
|
+
actionLoading: boolean;
|
|
25
|
+
cancelLabel: string;
|
|
26
|
+
}>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
|
|
27
|
+
showBack: boolean;
|
|
28
|
+
showFooter: boolean;
|
|
29
|
+
actionLabel: string;
|
|
30
|
+
actionDisabled: boolean;
|
|
31
|
+
actionLoading: boolean;
|
|
32
|
+
cancelLabel: string;
|
|
33
|
+
}>>>, {
|
|
34
|
+
showBack: boolean;
|
|
35
|
+
showFooter: boolean;
|
|
36
|
+
actionLabel: string;
|
|
37
|
+
actionDisabled: boolean;
|
|
38
|
+
actionLoading: boolean;
|
|
39
|
+
cancelLabel: string;
|
|
40
|
+
}, {}>;
|
|
41
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
42
|
+
export default _default;
|
|
43
|
+
type __VLS_WithDefaults<P, D> = {
|
|
44
|
+
[K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
|
|
45
|
+
default: D[K];
|
|
46
|
+
}> : P[K];
|
|
47
|
+
};
|
|
48
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
49
|
+
type __VLS_TypePropsToOption<T> = {
|
|
50
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? {
|
|
51
|
+
type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
|
|
52
|
+
} : {
|
|
53
|
+
type: import('vue').PropType<T[K]>;
|
|
54
|
+
required: true;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
58
|
+
new (): {
|
|
59
|
+
$slots: S;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
type __VLS_PrettifyLocal<T> = {
|
|
63
|
+
[K in keyof T]: T[K];
|
|
64
|
+
} & {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
modelValue: string;
|
|
3
|
+
placeholder?: string;
|
|
4
|
+
loading?: boolean;
|
|
5
|
+
};
|
|
6
|
+
declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
|
|
7
|
+
placeholder: string;
|
|
8
|
+
loading: boolean;
|
|
9
|
+
}>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
|
|
10
|
+
placeholder: string;
|
|
11
|
+
loading: boolean;
|
|
12
|
+
}>>>, {
|
|
13
|
+
placeholder: string;
|
|
14
|
+
loading: boolean;
|
|
15
|
+
}, {}>;
|
|
16
|
+
export default _default;
|
|
17
|
+
type __VLS_WithDefaults<P, D> = {
|
|
18
|
+
[K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
|
|
19
|
+
default: D[K];
|
|
20
|
+
}> : P[K];
|
|
21
|
+
};
|
|
22
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
23
|
+
type __VLS_TypePropsToOption<T> = {
|
|
24
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? {
|
|
25
|
+
type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
|
|
26
|
+
} : {
|
|
27
|
+
type: import('vue').PropType<T[K]>;
|
|
28
|
+
required: true;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
type __VLS_PrettifyLocal<T> = {
|
|
32
|
+
[K in keyof T]: T[K];
|
|
33
|
+
} & {};
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref, computed, nextTick } from "vue";
|
|
3
|
+
import {
|
|
4
|
+
getSuggestions,
|
|
5
|
+
tokenize,
|
|
6
|
+
type SuggestionItem,
|
|
7
|
+
type TokenType,
|
|
8
|
+
} from "./suggestions";
|
|
9
|
+
|
|
10
|
+
const props = withDefaults(
|
|
11
|
+
defineProps<{
|
|
12
|
+
modelValue: string;
|
|
13
|
+
placeholder?: string;
|
|
14
|
+
loading?: boolean;
|
|
15
|
+
}>(),
|
|
16
|
+
{
|
|
17
|
+
placeholder: "Enter an HTTPQL query...",
|
|
18
|
+
loading: false,
|
|
19
|
+
},
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
const emit = defineEmits<{
|
|
23
|
+
"update:modelValue": [value: string];
|
|
24
|
+
submit: [];
|
|
25
|
+
}>();
|
|
26
|
+
|
|
27
|
+
const inputRef = ref<HTMLInputElement>();
|
|
28
|
+
const cursorPos = ref(0);
|
|
29
|
+
const highlightedIndex = ref(0);
|
|
30
|
+
const showSuggestions = ref(false);
|
|
31
|
+
|
|
32
|
+
const context = computed(() =>
|
|
33
|
+
getSuggestions(props.modelValue, cursorPos.value),
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const filtered = computed(() => context.value.items);
|
|
37
|
+
const category = computed(() => context.value.category);
|
|
38
|
+
|
|
39
|
+
const tokens = computed(() => tokenize(props.modelValue));
|
|
40
|
+
|
|
41
|
+
const TOKEN_COLORS: Record<TokenType, string> = {
|
|
42
|
+
field: "text-[#90C191]",
|
|
43
|
+
operator: "text-[#FEC418]",
|
|
44
|
+
value: "text-[#CE9178]",
|
|
45
|
+
logical: "text-surface-100",
|
|
46
|
+
paren: "text-surface-100",
|
|
47
|
+
text: "text-surface-100",
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
function updateCursor() {
|
|
51
|
+
cursorPos.value = inputRef.value?.selectionStart ?? props.modelValue.length;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function onInput(e: Event) {
|
|
55
|
+
const target = e.target as HTMLInputElement;
|
|
56
|
+
emit("update:modelValue", target.value);
|
|
57
|
+
nextTick(() => {
|
|
58
|
+
updateCursor();
|
|
59
|
+
highlightedIndex.value = 0;
|
|
60
|
+
showSuggestions.value = filtered.value.length > 0;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function onKeydown(e: KeyboardEvent) {
|
|
65
|
+
if (!showSuggestions.value || filtered.value.length === 0) {
|
|
66
|
+
if (e.key === "Enter") {
|
|
67
|
+
emit("submit");
|
|
68
|
+
}
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
switch (e.key) {
|
|
73
|
+
case "ArrowDown":
|
|
74
|
+
e.preventDefault();
|
|
75
|
+
highlightedIndex.value =
|
|
76
|
+
(highlightedIndex.value + 1) % filtered.value.length;
|
|
77
|
+
break;
|
|
78
|
+
case "ArrowUp":
|
|
79
|
+
e.preventDefault();
|
|
80
|
+
highlightedIndex.value =
|
|
81
|
+
(highlightedIndex.value - 1 + filtered.value.length) %
|
|
82
|
+
filtered.value.length;
|
|
83
|
+
break;
|
|
84
|
+
case "Tab":
|
|
85
|
+
case "Enter":
|
|
86
|
+
e.preventDefault();
|
|
87
|
+
acceptSuggestion(filtered.value[highlightedIndex.value]!);
|
|
88
|
+
break;
|
|
89
|
+
case "Escape":
|
|
90
|
+
e.preventDefault();
|
|
91
|
+
showSuggestions.value = false;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function acceptSuggestion(item: SuggestionItem) {
|
|
97
|
+
const { partial, suffix } = context.value;
|
|
98
|
+
const before = props.modelValue.slice(0, cursorPos.value - partial.length);
|
|
99
|
+
const after = props.modelValue.slice(cursorPos.value);
|
|
100
|
+
const inserted = item.value + suffix;
|
|
101
|
+
const newValue = before + inserted + after;
|
|
102
|
+
const newCursor = before.length + inserted.length;
|
|
103
|
+
|
|
104
|
+
emit("update:modelValue", newValue);
|
|
105
|
+
showSuggestions.value = false;
|
|
106
|
+
highlightedIndex.value = 0;
|
|
107
|
+
|
|
108
|
+
nextTick(() => {
|
|
109
|
+
if (inputRef.value) {
|
|
110
|
+
inputRef.value.selectionStart = newCursor;
|
|
111
|
+
inputRef.value.selectionEnd = newCursor;
|
|
112
|
+
inputRef.value.focus();
|
|
113
|
+
cursorPos.value = newCursor;
|
|
114
|
+
// Re-evaluate suggestions after accepting (e.g. after namespace. show fields)
|
|
115
|
+
const ctx = getSuggestions(newValue, newCursor);
|
|
116
|
+
if (ctx.items.length > 0) {
|
|
117
|
+
showSuggestions.value = true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function onFocus() {
|
|
124
|
+
updateCursor();
|
|
125
|
+
if (filtered.value.length > 0) {
|
|
126
|
+
showSuggestions.value = true;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function onBlur() {
|
|
131
|
+
// Delay to allow click on suggestion item
|
|
132
|
+
setTimeout(() => {
|
|
133
|
+
showSuggestions.value = false;
|
|
134
|
+
}, 150);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function onClick() {
|
|
138
|
+
nextTick(() => {
|
|
139
|
+
updateCursor();
|
|
140
|
+
highlightedIndex.value = 0;
|
|
141
|
+
showSuggestions.value = filtered.value.length > 0;
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function onScroll() {
|
|
146
|
+
const overlay = inputRef.value?.previousElementSibling as HTMLElement | null;
|
|
147
|
+
if (overlay && inputRef.value) {
|
|
148
|
+
overlay.scrollLeft = inputRef.value.scrollLeft;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
</script>
|
|
152
|
+
|
|
153
|
+
<template>
|
|
154
|
+
<div class="relative">
|
|
155
|
+
<div
|
|
156
|
+
class="relative overflow-hidden rounded border border-surface-600 bg-surface-950 focus-within:border-surface-400 transition-colors"
|
|
157
|
+
>
|
|
158
|
+
<!-- Colored overlay -->
|
|
159
|
+
<div
|
|
160
|
+
class="absolute inset-0 px-3 py-1.5 text-sm font-mono whitespace-pre pointer-events-none overflow-hidden"
|
|
161
|
+
aria-hidden="true"
|
|
162
|
+
>
|
|
163
|
+
<span
|
|
164
|
+
v-for="(token, i) in tokens"
|
|
165
|
+
:key="i"
|
|
166
|
+
:class="TOKEN_COLORS[token.type]"
|
|
167
|
+
>{{ token.text }}</span
|
|
168
|
+
>
|
|
169
|
+
</div>
|
|
170
|
+
<!-- Actual input (transparent text, visible caret) -->
|
|
171
|
+
<input
|
|
172
|
+
ref="inputRef"
|
|
173
|
+
:value="modelValue"
|
|
174
|
+
:placeholder="placeholder"
|
|
175
|
+
type="text"
|
|
176
|
+
autocomplete="off"
|
|
177
|
+
spellcheck="false"
|
|
178
|
+
:class="[
|
|
179
|
+
'relative w-full bg-transparent py-1.5 pl-3 text-sm font-mono text-transparent caret-surface-100 placeholder-surface-500 outline-none',
|
|
180
|
+
loading ? 'pr-8' : 'pr-3',
|
|
181
|
+
]"
|
|
182
|
+
@input="onInput"
|
|
183
|
+
@keydown="onKeydown"
|
|
184
|
+
@focus="onFocus"
|
|
185
|
+
@blur="onBlur"
|
|
186
|
+
@click="onClick"
|
|
187
|
+
@scroll="onScroll"
|
|
188
|
+
/>
|
|
189
|
+
<i
|
|
190
|
+
v-if="loading"
|
|
191
|
+
class="fas fa-circle-notch animate-spin absolute right-2.5 top-1/2 mt-[-6px] text-surface-400 text-xs pointer-events-none"
|
|
192
|
+
/>
|
|
193
|
+
</div>
|
|
194
|
+
<div
|
|
195
|
+
v-if="showSuggestions && filtered.length > 0"
|
|
196
|
+
class="absolute left-0 right-0 top-full mt-1 z-50 border border-surface-600 rounded bg-surface-950 shadow-lg text-sm font-mono overflow-hidden"
|
|
197
|
+
>
|
|
198
|
+
<div
|
|
199
|
+
v-if="category"
|
|
200
|
+
class="px-3 py-1 text-xs text-surface-400 bg-surface-800 border-b border-surface-700"
|
|
201
|
+
>
|
|
202
|
+
{{ category }}
|
|
203
|
+
</div>
|
|
204
|
+
<ul class="max-h-48 overflow-y-auto">
|
|
205
|
+
<li
|
|
206
|
+
v-for="(item, index) in filtered"
|
|
207
|
+
:key="item.value"
|
|
208
|
+
class="flex items-center gap-2 px-3 py-1 cursor-pointer transition-colors"
|
|
209
|
+
:class="
|
|
210
|
+
index === highlightedIndex
|
|
211
|
+
? 'bg-white/15 text-surface-100'
|
|
212
|
+
: 'text-surface-300 hover:bg-white/10'
|
|
213
|
+
"
|
|
214
|
+
@mousedown.prevent="acceptSuggestion(item)"
|
|
215
|
+
>
|
|
216
|
+
<span class="text-surface-500 text-xs w-3 shrink-0">x</span>
|
|
217
|
+
<span class="flex-1">{{ item.value }}</span>
|
|
218
|
+
<span v-if="item.description" class="text-surface-500 text-xs">{{
|
|
219
|
+
item.description
|
|
220
|
+
}}</span>
|
|
221
|
+
</li>
|
|
222
|
+
</ul>
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
</template>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
modelValue: string;
|
|
3
|
+
placeholder?: string;
|
|
4
|
+
loading?: boolean;
|
|
5
|
+
};
|
|
6
|
+
declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
|
|
7
|
+
placeholder: string;
|
|
8
|
+
loading: boolean;
|
|
9
|
+
}>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
|
|
10
|
+
placeholder: string;
|
|
11
|
+
loading: boolean;
|
|
12
|
+
}>>>, {
|
|
13
|
+
placeholder: string;
|
|
14
|
+
loading: boolean;
|
|
15
|
+
}, {}>;
|
|
16
|
+
export default _default;
|
|
17
|
+
type __VLS_WithDefaults<P, D> = {
|
|
18
|
+
[K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
|
|
19
|
+
default: D[K];
|
|
20
|
+
}> : P[K];
|
|
21
|
+
};
|
|
22
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
23
|
+
type __VLS_TypePropsToOption<T> = {
|
|
24
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? {
|
|
25
|
+
type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
|
|
26
|
+
} : {
|
|
27
|
+
type: import('vue').PropType<T[K]>;
|
|
28
|
+
required: true;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
type __VLS_PrettifyLocal<T> = {
|
|
32
|
+
[K in keyof T]: T[K];
|
|
33
|
+
} & {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type SuggestionItem = {
|
|
2
|
+
value: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
};
|
|
5
|
+
export type SuggestionContext = {
|
|
6
|
+
/** Category label for the dropdown header */
|
|
7
|
+
category: string;
|
|
8
|
+
/** Suggestions to show */
|
|
9
|
+
items: SuggestionItem[];
|
|
10
|
+
/** The partial text being typed that should be replaced on accept */
|
|
11
|
+
partial: string;
|
|
12
|
+
/** Suffix to append after accepting (e.g. "." after namespace, " " after operator) */
|
|
13
|
+
suffix: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Analyze the query text left of the cursor to determine what suggestions to show.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getSuggestions(query: string, cursorPos: number): SuggestionContext;
|
|
19
|
+
export type TokenType = "field" | "operator" | "value" | "logical" | "paren" | "text";
|
|
20
|
+
export type Token = {
|
|
21
|
+
type: TokenType;
|
|
22
|
+
text: string;
|
|
23
|
+
};
|
|
24
|
+
export declare function tokenize(query: string): Token[];
|