124 lines
3.2 KiB
Vue
124 lines
3.2 KiB
Vue
<script setup>
|
|
import { defineProps, computed } from "vue";
|
|
import VueDatePicker from "@vuepic/vue-datepicker";
|
|
import "@vuepic/vue-datepicker/dist/main.css";
|
|
import { zhTW } from "date-fns/locale";
|
|
import { twMerge } from "tailwind-merge";
|
|
import { useI18n } from "vue-i18n";
|
|
const { t } = useI18n();
|
|
const props = defineProps({
|
|
items: Array,
|
|
withLine: Boolean,
|
|
label: String,
|
|
inputClass: String,
|
|
borderColor: String,
|
|
isTopLabelExist: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
isBottomLabelExist: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
className: String,
|
|
width: String,
|
|
});
|
|
|
|
const curWidth = computed(() => {
|
|
if (props.width) {
|
|
return {
|
|
style: {
|
|
width: `${props.width}px`,
|
|
},
|
|
class: "",
|
|
};
|
|
} else {
|
|
return {
|
|
class: "w-80 max-w-sm",
|
|
};
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
:class="twMerge('form-control', className, curWidth.class)"
|
|
:style="curWidth.style"
|
|
>
|
|
<div :class="twMerge(isTopLabelExist ? 'label' : '')">
|
|
<span class="label-text text-lg"><slot name="topLeft"></slot></span>
|
|
<span class="label-text-alt"> <slot name="topRight"></slot></span>
|
|
</div>
|
|
<div class="flex text-white items-center">
|
|
<template v-for="item in items" :key="item.key">
|
|
<VueDatePicker
|
|
:name="item.name || item.key"
|
|
:month-picker="Boolean(item.monthPicker)"
|
|
:year-picker="Boolean(item.yearPicker)"
|
|
dark
|
|
:action-row="{
|
|
showNow: false,
|
|
showCancel: false,
|
|
showPreview: false,
|
|
}"
|
|
v-model="item.value"
|
|
locale='en-US'
|
|
:format="item.dateFormat"
|
|
:enable-time-picker="false"
|
|
:time-picker="Boolean(item.timePicker)"
|
|
:placeholder="item.placeholder"
|
|
:selectText="t('button.submit')"
|
|
:input-class-name="
|
|
twMerge('dp-custom-input', 'btn border', inputClass)
|
|
"
|
|
calendar-cell-class-name="dp-custom-cell"
|
|
:class="twMerge(withLine ? 'line my-1' : '')"
|
|
:max-date="item.maxDate"
|
|
:max-time="item.maxTime"
|
|
:start-date="item.startDate"
|
|
:start-time="item.startTime"
|
|
:min-date="item.minDate"
|
|
></VueDatePicker>
|
|
</template>
|
|
</div>
|
|
|
|
<div :class="twMerge(isBottomLabelExist ? 'label' : '')">
|
|
<span class="label-text-alt"> <slot name="bottomLeft"></slot></span>
|
|
<span class="label-text-alt"> <slot name="bottomRight"></slot></span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="css" coped>
|
|
.dp__theme_dark {
|
|
--dp-primary-color: var(--primary);
|
|
}
|
|
|
|
.dp__input.dp-custom-input {
|
|
@apply bg-transparent rounded-md min-w-[155px] border-info hover:border-info text-white hover:bg-transparent;
|
|
}
|
|
|
|
.dp__input.dp-custom-input.shadow-none {
|
|
box-shadow: none !important;
|
|
}
|
|
|
|
.dp-custom-cell {
|
|
@apply rounded-full;
|
|
}
|
|
.dp__today {
|
|
@apply border-active;
|
|
}
|
|
.dp__active_date {
|
|
@apply border-active bg-active;
|
|
}
|
|
|
|
.dp__action_buttons .dp__action_button.dp__action_select {
|
|
@apply bg-white text-dark text-lg;
|
|
}
|
|
</style>
|
|
<style scoped>
|
|
.line {
|
|
@apply mr-3 relative z-20 after:absolute after:top-1/2 after:-right-3 after:w-3 after:h-[1px] after:bg-info after:z-10 last:after:h-0;
|
|
}
|
|
</style>
|