Update dependencies and fix code issues

This commit is contained in:
Eko Haryadi
2024-02-20 18:44:11 +07:00
parent 2758481259
commit a0ccf13466
65 changed files with 3454 additions and 2271 deletions

View File

@@ -1,107 +1,115 @@
<script setup lang="ts">
interface DataItem {
id: number;
name: string;
import { type PropType } from 'vue'
import Multiselect from '@vueform/multiselect'
interface Tags {
id: number
value: string,
label: string
}
import { ref, computed, onMounted } from 'vue'
import {
Combobox,
ComboboxInput,
ComboboxButton,
ComboboxOptions,
ComboboxOption,
TransitionRoot
} from '@headlessui/vue'
import { CheckIcon, ChevronUpDownIcon } from '@heroicons/vue/20/solid'
const props = defineProps({
defineProps({
placeholder: {
type: String,
default: ''
},
data: {
type: Array as () => DataItem[],
default: []
tags: {
type: Array as PropType<Tags[]>,
required: true
},
useLabel: {
type: Boolean,
default: false
},
label: {
type: String,
default: ''
}
})
const emit = defineEmits(["update:selected"])
const data = computed(() => [{ id: 0, name: props.placeholder }, ...props.data]);
let selected = ref<DataItem[]>([data.value[0]])
let query = ref('')
let filteredData = computed(() =>
query.value === ''
? data.value
: data.value.filter((item: DataItem) =>
item.name
.toLowerCase()
.replace(/\s+/g, '')
.includes(query.value.toLowerCase().replace(/\s+/g, ''))
)
)
const show = ref(false)
const removeJenis = (item: DataItem) => {
selected.value = selected.value.filter((i) => i.id !== item.id)
}
onMounted(() => {
})
</script>
<template>
<Combobox @update:modelValue="value => emit('update:selected', value)" v-model="selected" v-slot="{ open }" multiple>
<div class="relative mt-1">
<div
class="relative w-full cursor-default overflow-hidden rounded-lg bg-gray-200 text-left focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 focus-visible:ring-offset-2 focus-visible:ring-offset-teal-300 sm:text-sm">
<ComboboxInput class="w-full border-none py-2 pl-3 pr-10 bg-gray-200 text-sm leading-5 text-gray-900 focus:ring-0"
:displayValue="(item: any) => (show || open ? '' : item.name)" @change="query = $event.target.value"
@click="show = true" @blur="show = false" defaultValue="" />
<ComboboxButton id="Test" class="absolute inset-y-0 right-0 flex items-center pr-2">
<ChevronUpDownIcon class="h-5 w-5 text-gray-400" aria-hidden="true" />
</ComboboxButton>
</div>
<span class="flex flex-wrap gap-2">
<span v-if="selected.length == 0" class="p-0.5">Empty</span>
<span v-for="item in selected" :key="item.id" class="inline-flex items-center rounded-md bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-700/10">
<span>{{ item.name }}</span>
<svg class="h-4 w-4 cursor-pointer" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg" @click.stop.prevent="removeJenis(item)">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</span>
</span>
<TransitionRoot :show="show || open" leave="transition ease-in duration-100" leaveFrom="opacity-100"
leaveTo="opacity-0" @after-leave="query = ''">
<ComboboxOptions static
class="absolute mt-1 z-10 max-h-60 w-full overflow-auto rounded-md bg-gray-200 py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
<div v-if="filteredData.length === 0 && query !== ''"
class="relative cursor-default select-none py-2 px-4 text-gray-700">
Nothing found.
</div>
<ComboboxOption v-for="item in filteredData" as="template" :key="item.id" :value="item"
v-slot="{ selected, active }">
<li class="relative cursor-default select-none py-2 pl-10 pr-4" :class="{
'bg-teal-600 text-white': active,
'text-gray-900': !active
}">
<span class="block truncate" :class="{ 'font-medium': selected, 'font-normal': !selected }">
{{ item.name }}
</span>
<span v-if="selected" class="absolute inset-y-0 left-0 flex items-center pl-3"
:class="{ 'text-white': active, 'text-teal-600': !active }">
<CheckIcon class="h-5 w-5" aria-hidden="true" />
</span>
</li>
</ComboboxOption>
</ComboboxOptions>
</TransitionRoot>
</div>
</Combobox>
</template>
<div class="flex flex-col">
<Multiselect
mode="tags"
:placeholder="placeholder"
:close-on-select="false"
:searchable="true"
:create-option="true"
:options="tags"
:classes="{
container:
'relative py-[5px] mx-auto w-full flex items-center justify-end cursor-pointer rounded-lg bg-gray-200 text-left text-base leading-snug outline-none',
containerDisabled: 'cursor-default bg-gray-50',
containerOpen: 'rounded-b-none',
containerOpenTop: 'rounded-t-none',
containerActive: '',
wrapper:
'relative mx-auto w-full flex items-center justify-end box-border cursor-pointer outline-none',
singleLabel:
'flex items-center h-full max-w-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 pr-16 box-border rtl:left-auto rtl:right-0 rtl:pl-0 rtl:pr-3.5',
singleLabelText: 'overflow-ellipsis overflow-hidden block whitespace-nowrap max-w-full',
multipleLabel:
'flex items-center h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 rtl:left-auto rtl:right-0 rtl:pl-0 rtl:pr-3.5',
search:
'w-full absolute inset-0 outline-none focus:ring-0 appearance-none box-border border-0 text-base font-sans bg-white rounded pl-3.5 rtl:pl-0 rtl:pr-3.5',
tags: 'flex-grow flex-shrink flex flex-wrap items-center mt-1 pl-2 min-w-0 rtl:pl-0 rtl:pr-2',
tag: 'bg-primary-500 text-white text-sm font-semibold py-0.5 pl-2 rounded mr-1 mb-1 flex items-center whitespace-nowrap min-w-0 rtl:pl-0 rtl:pr-2 rtl:mr-0 rtl:ml-1',
tagDisabled: 'pr-2 opacity-50 rtl:pl-2',
tagWrapper: 'whitespace-nowrap overflow-hidden overflow-ellipsis',
tagWrapperBreak: 'whitespace-normal break-all',
tagRemove:
'flex items-center justify-center p-1 mx-0.5 rounded-sm hover:bg-black hover:bg-opacity-10 group',
tagRemoveIcon:
'bg-multiselect-remove bg-center bg-no-repeat opacity-30 inline-block w-3 h-3 group-hover:opacity-60',
tagsSearchWrapper: 'inline-block relative mx-1 mb-1 flex-grow flex-shrink h-full',
tagsSearch:
' bg-gray-200 absolute inset-0 border-0 outline-none focus:ring-0 appearance-none p-0 text-base font-sans box-border w-full',
tagsSearchCopy: 'invisible whitespace-pre-wrap inline-block h-px',
placeholder:
'flex items-center text-sm h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 text-gray-400 rtl:left-auto rtl:right-0 rtl:pl-0 rtl:pr-3.5',
caret:
'bg-multiselect-caret bg-center bg-no-repeat w-2.5 h-4 py-px box-content mr-3.5 relative z-10 opacity-40 flex-shrink-0 flex-grow-0 transition-transform transform pointer-events-none rtl:mr-0 rtl:ml-3.5',
caretOpen: 'rotate-180 pointer-events-auto',
clear:
'pr-3.5 relative z-10 opacity-40 transition duration-300 flex-shrink-0 flex-grow-0 flex hover:opacity-80 rtl:pr-0 rtl:pl-3.5',
clearIcon:
'bg-multiselect-remove bg-center bg-no-repeat w-2.5 h-4 py-px box-content inline-block',
spinner:
'bg-multiselect-spinner bg-center bg-no-repeat w-4 h-4 z-10 mr-3.5 animate-spin flex-shrink-0 flex-grow-0 rtl:mr-0 rtl:ml-3.5',
infinite: 'flex items-center justify-center w-full',
infiniteSpinner:
'bg-multiselect-spinner bg-center bg-no-repeat w-4 h-4 z-10 animate-spin flex-shrink-0 flex-grow-0 m-3.5',
dropdown:
'max-h-60 absolute -left-px -right-px bottom-0 transform translate-y-full border border-gray-300 -mt-px overflow-y-scroll z-50 bg-white flex flex-col rounded-b',
dropdownTop: '-translate-y-full top-px bottom-auto rounded-b-none rounded-t',
dropdownHidden: 'hidden',
options: 'flex flex-col p-0 m-0 list-none',
optionsTop: '',
group: 'p-0 m-0',
groupLabel:
'flex text-sm box-border items-center justify-start text-left py-1 px-3 font-semibold bg-gray-200 cursor-default leading-normal',
groupLabelPointable: 'cursor-pointer',
groupLabelPointed: 'bg-gray-300 text-gray-700',
groupLabelSelected: 'bg-green-600 text-white',
groupLabelDisabled: 'bg-gray-100 text-gray-300 cursor-not-allowed',
groupLabelSelectedPointed: 'bg-green-600 text-white opacity-90',
groupLabelSelectedDisabled: 'text-green-100 bg-green-600 bg-opacity-50 cursor-not-allowed',
groupOptions: 'p-0 m-0',
option:
'flex items-center justify-start box-border text-left cursor-pointer text-base leading-snug py-2 px-3',
optionPointed: 'text-gray-800 bg-gray-100',
optionSelected: 'text-white bg-green-500',
optionDisabled: 'text-gray-300 cursor-not-allowed',
optionSelectedPointed: 'text-white bg-green-500 opacity-90',
optionSelectedDisabled: 'text-green-100 bg-green-500 bg-opacity-50 cursor-not-allowed',
noOptions: 'py-2 px-3 text-gray-600 bg-white text-left rtl:text-right',
noResults: 'py-2 px-3 text-gray-600 bg-white text-left rtl:text-right',
fakeInput:
'bg-transparent absolute left-0 right-0 -bottom-px w-full h-px border-0 p-0 appearance-none outline-none text-transparent',
assist: 'absolute -m-px w-px h-px overflow-hidden',
spacer: 'box-content'
}"
/>
</div>
</template>