Use AutoComplete and better UI performance

pull/6798/head
Cagatay Civici 2024-11-14 10:25:06 +03:00
parent 2f9528cd99
commit 08414febba
4 changed files with 44 additions and 29 deletions

View File

@ -1,6 +1,6 @@
<template> <template>
<Drawer v-model:visible="$appState.designerActive" header="Theme Designer" position="right" class="designer !w-screen md:!w-[48rem]" :modal="false" :dismissable="false"> <Drawer v-model:visible="$appState.designerActive" header="Theme Designer" position="right" class="designer !w-screen md:!w-[48rem]" :modal="false" :dismissable="false" @after-show="onShow" @after-hide="onHide">
<Tabs v-model:value="activeTab"> <Tabs v-model:value="activeTab" :lazy="deferredTabs">
<TabList> <TabList>
<Tab value="0">Base</Tab> <Tab value="0">Base</Tab>
<Tab value="1">Primitive</Tab> <Tab value="1">Primitive</Tab>
@ -181,6 +181,7 @@ export default {
data() { data() {
return { return {
activeTab: '0', activeTab: '0',
deferredTabs: true,
preset: { preset: {
primitive: NoirPreset.primitive, primitive: NoirPreset.primitive,
semantic: NoirPreset.semantic semantic: NoirPreset.semantic
@ -537,6 +538,12 @@ app.mount("#app");
this.apply(); this.apply();
event.preventDefault(); event.preventDefault();
} }
},
onShow() {
this.deferredTabs = false;
},
onHide() {
this.deferredTabs = true;
} }
}, },
computed: { computed: {

View File

@ -2,19 +2,25 @@
<div> <div>
<label :for="inputId" class="text-sm">{{ label }}</label> <label :for="inputId" class="text-sm">{{ label }}</label>
<div :id="id" class="relative"> <div :id="id" class="relative">
<input <AutoComplete
:id="inputId" :modelValue="modelValue"
:list="listId"
autocomplete="off"
type="text"
:value="modelValue"
@input="onInput" @input="onInput"
@change="onChange" :inputId="inputId"
:class="['relative border border-surface-300 dark:border-surface-600 rounded-lg py-2 px-2 w-full', { 'pr-8': type === 'color' }]" :suggestions="items"
@complete="search"
unstyled
:showEmptyMessage="false"
:pt="{
pcInputText: {
root: ['border border-surface-300 dark:border-surface-600 rounded-lg py-2 px-2 w-full', { 'pr-8': type === 'color' }]
},
overlay: 'border border-surface-200 dark:border-surface-700 bg-surface-0 dark:bg-surface-950 shadow-2 rounded-md',
listContainer: 'max-h-40 overflow-auto',
list: 'm-0 py-2 px-0 list-none',
option: 'cursor-pointer py-1 px-2 text-sm text-surface-700 dark:text-white/80 data-[p-focus=true]:bg-surface-100 data-[p-focus=true]:dark:bg-surface-800'
}"
@option-select="onOptionSelect"
/> />
<datalist :id="listId">
<option v-for="item of items" :key="item">{{ item }}</option>
</datalist>
<div v-if="type === 'color'" class="absolute right-[4px] top-1/2 -mt-3 w-6 h-6 rounded-md border border-surface-300 dark:border-surface-600" :style="{ backgroundColor: previewColor }"></div> <div v-if="type === 'color'" class="absolute right-[4px] top-1/2 -mt-3 w-6 h-6 rounded-md border border-surface-300 dark:border-surface-600" :style="{ backgroundColor: previewColor }"></div>
</div> </div>
</div> </div>
@ -51,22 +57,21 @@ export default {
this.id = 'dt_field_' + UniqueComponentId(); this.id = 'dt_field_' + UniqueComponentId();
}, },
methods: { methods: {
onOptionSelect(event) {
this.$emit('update:modelValue', event.value);
event.originalEvent.stopPropagation();
},
onInput(event) { onInput(event) {
const value = event.target.value; this.$emit('update:modelValue', event.target.value);
},
search(event) {
const query = event.query;
this.$emit('update:modelValue', value); if (query.startsWith('{')) {
this.items = this.$acTokens.filter((t) => t.startsWith(query));
if (value.startsWith('{')) {
this.search(value);
} else { } else {
this.items = null; this.items = null;
} }
},
onChange() {
this.items = null;
},
search(query) {
this.items = this.$acTokens.filter((t) => t.startsWith(query));
} }
}, },
computed: { computed: {
@ -75,9 +80,6 @@ export default {
}, },
inputId() { inputId() {
return this.id + '_input'; return this.id + '_input';
},
listId() {
return this.id + '_list';
} }
} }
}; };

View File

@ -256,7 +256,7 @@ export interface DrawerEmitsOptions {
*/ */
'update:visible'(value: boolean): void; 'update:visible'(value: boolean): void;
/** /**
* Callback to invoke when drawer gets shown. * Callback to invoke when drawer is shown.
*/ */
show(): void; show(): void;
/** /**
@ -267,6 +267,11 @@ export interface DrawerEmitsOptions {
* Callback to invoke after drawer is hidden. * Callback to invoke after drawer is hidden.
*/ */
'after-hide'(): void; 'after-hide'(): void;
/**
* Callback to invoke after drawer is shown.
*/
'after-show'(): void;
} }
export declare type DrawerEmits = EmitFn<DrawerEmitsOptions>; export declare type DrawerEmits = EmitFn<DrawerEmitsOptions>;

View File

@ -54,7 +54,7 @@ export default {
name: 'Drawer', name: 'Drawer',
extends: BaseDrawer, extends: BaseDrawer,
inheritAttrs: false, inheritAttrs: false,
emits: ['update:visible', 'show', 'hide', 'after-hide'], emits: ['update:visible', 'show', 'after-show', 'hide', 'after-hide'],
data() { data() {
return { return {
containerVisible: this.visible containerVisible: this.visible
@ -107,6 +107,7 @@ export default {
}, },
onAfterEnter() { onAfterEnter() {
this.enableDocumentSettings(); this.enableDocumentSettings();
this.$emit('after-show');
}, },
onBeforeLeave() { onBeforeLeave() {
if (this.modal) { if (this.modal) {