Use AutoComplete and better UI performance
parent
2f9528cd99
commit
08414febba
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<Drawer v-model:visible="$appState.designerActive" header="Theme Designer" position="right" class="designer !w-screen md:!w-[48rem]" :modal="false" :dismissable="false">
|
||||
<Tabs v-model:value="activeTab">
|
||||
<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" :lazy="deferredTabs">
|
||||
<TabList>
|
||||
<Tab value="0">Base</Tab>
|
||||
<Tab value="1">Primitive</Tab>
|
||||
|
@ -181,6 +181,7 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
activeTab: '0',
|
||||
deferredTabs: true,
|
||||
preset: {
|
||||
primitive: NoirPreset.primitive,
|
||||
semantic: NoirPreset.semantic
|
||||
|
@ -537,6 +538,12 @@ app.mount("#app");
|
|||
this.apply();
|
||||
event.preventDefault();
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.deferredTabs = false;
|
||||
},
|
||||
onHide() {
|
||||
this.deferredTabs = true;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
|
|
@ -2,19 +2,25 @@
|
|||
<div>
|
||||
<label :for="inputId" class="text-sm">{{ label }}</label>
|
||||
<div :id="id" class="relative">
|
||||
<input
|
||||
:id="inputId"
|
||||
:list="listId"
|
||||
autocomplete="off"
|
||||
type="text"
|
||||
:value="modelValue"
|
||||
<AutoComplete
|
||||
:modelValue="modelValue"
|
||||
@input="onInput"
|
||||
@change="onChange"
|
||||
:class="['relative border border-surface-300 dark:border-surface-600 rounded-lg py-2 px-2 w-full', { 'pr-8': type === 'color' }]"
|
||||
:inputId="inputId"
|
||||
: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>
|
||||
</div>
|
||||
|
@ -51,22 +57,21 @@ export default {
|
|||
this.id = 'dt_field_' + UniqueComponentId();
|
||||
},
|
||||
methods: {
|
||||
onOptionSelect(event) {
|
||||
this.$emit('update:modelValue', event.value);
|
||||
event.originalEvent.stopPropagation();
|
||||
},
|
||||
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 (value.startsWith('{')) {
|
||||
this.search(value);
|
||||
if (query.startsWith('{')) {
|
||||
this.items = this.$acTokens.filter((t) => t.startsWith(query));
|
||||
} else {
|
||||
this.items = null;
|
||||
}
|
||||
},
|
||||
onChange() {
|
||||
this.items = null;
|
||||
},
|
||||
search(query) {
|
||||
this.items = this.$acTokens.filter((t) => t.startsWith(query));
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -75,9 +80,6 @@ export default {
|
|||
},
|
||||
inputId() {
|
||||
return this.id + '_input';
|
||||
},
|
||||
listId() {
|
||||
return this.id + '_list';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -256,7 +256,7 @@ export interface DrawerEmitsOptions {
|
|||
*/
|
||||
'update:visible'(value: boolean): void;
|
||||
/**
|
||||
* Callback to invoke when drawer gets shown.
|
||||
* Callback to invoke when drawer is shown.
|
||||
*/
|
||||
show(): void;
|
||||
/**
|
||||
|
@ -267,6 +267,11 @@ export interface DrawerEmitsOptions {
|
|||
* Callback to invoke after drawer is hidden.
|
||||
*/
|
||||
'after-hide'(): void;
|
||||
|
||||
/**
|
||||
* Callback to invoke after drawer is shown.
|
||||
*/
|
||||
'after-show'(): void;
|
||||
}
|
||||
|
||||
export declare type DrawerEmits = EmitFn<DrawerEmitsOptions>;
|
||||
|
|
|
@ -54,7 +54,7 @@ export default {
|
|||
name: 'Drawer',
|
||||
extends: BaseDrawer,
|
||||
inheritAttrs: false,
|
||||
emits: ['update:visible', 'show', 'hide', 'after-hide'],
|
||||
emits: ['update:visible', 'show', 'after-show', 'hide', 'after-hide'],
|
||||
data() {
|
||||
return {
|
||||
containerVisible: this.visible
|
||||
|
@ -107,6 +107,7 @@ export default {
|
|||
},
|
||||
onAfterEnter() {
|
||||
this.enableDocumentSettings();
|
||||
this.$emit('after-show');
|
||||
},
|
||||
onBeforeLeave() {
|
||||
if (this.modal) {
|
||||
|
|
Loading…
Reference in New Issue