179 lines
3.8 KiB
Vue
179 lines
3.8 KiB
Vue
<template>
|
|
<view class="date-range-selector tn-flex tn-flex-col-center">
|
|
<picker mode="date" @change="onStartChange" class="date-picker date-picker--start">
|
|
<view class="date-card" :class="{ 'is-empty': !start, 'is-active': start }">
|
|
<view class="date-card-header tn-flex tn-flex-row-between tn-flex-col-center">
|
|
<text class="date-label">{{ resolvedStartLabel }}</text>
|
|
<view class="date-icon-wrap">
|
|
<text class="tn-icon-calendar"></text>
|
|
</view>
|
|
</view>
|
|
<view class="date-value">{{ start || resolvedStartPlaceholder }}</view>
|
|
</view>
|
|
</picker>
|
|
|
|
<view class="range-connector">
|
|
<view class="connector-line"></view>
|
|
<text class="connector-text">{{ $tr('至') }}</text>
|
|
<view class="connector-line"></view>
|
|
</view>
|
|
|
|
<picker mode="date" @change="onEndChange" class="date-picker date-picker--end">
|
|
<view class="date-card" :class="{ 'is-empty': !end, 'is-active': end }">
|
|
<view class="date-card-header tn-flex tn-flex-row-between tn-flex-col-center">
|
|
<text class="date-label">{{ resolvedEndLabel }}</text>
|
|
<view class="date-icon-wrap">
|
|
<text class="tn-icon-calendar"></text>
|
|
</view>
|
|
</view>
|
|
<view class="date-value">{{ end || resolvedEndPlaceholder }}</view>
|
|
</view>
|
|
</picker>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'DateRangeSelector',
|
|
props: {
|
|
start: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
end: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
startLabel: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
endLabel: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
startPlaceholder: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
endPlaceholder: {
|
|
type: String,
|
|
default: ''
|
|
}
|
|
},
|
|
computed: {
|
|
resolvedStartLabel() {
|
|
return this.startLabel || this.$tr('预计入住')
|
|
},
|
|
resolvedEndLabel() {
|
|
return this.endLabel || this.$tr('预计离开')
|
|
},
|
|
resolvedStartPlaceholder() {
|
|
return this.startPlaceholder || this.$tr('请选择入住日期')
|
|
},
|
|
resolvedEndPlaceholder() {
|
|
return this.endPlaceholder || this.$tr('请选择离开日期')
|
|
}
|
|
},
|
|
methods: {
|
|
onStartChange(e) {
|
|
this.$emit('update:start', e.detail.value)
|
|
},
|
|
onEndChange(e) {
|
|
this.$emit('update:end', e.detail.value)
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
$text-primary: #1A2233;
|
|
$text-secondary: #6A7A99;
|
|
$text-tertiary: #A1B0C4;
|
|
|
|
.date-range-selector {
|
|
width: 100%;
|
|
}
|
|
|
|
.date-picker {
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
.date-card {
|
|
background: #F4F8FF;
|
|
border-radius: 20rpx;
|
|
padding: 24rpx;
|
|
border: 2rpx solid transparent;
|
|
transition: all 0.25s ease;
|
|
|
|
&.is-active {
|
|
background: #FFFFFF;
|
|
border-color: rgba($brand-primary, 0.25);
|
|
box-shadow: 0 6rpx 20rpx rgba($brand-primary, 0.08);
|
|
|
|
.date-value {
|
|
color: $text-primary;
|
|
font-weight: 700;
|
|
}
|
|
}
|
|
|
|
&.is-empty .date-value {
|
|
color: $text-tertiary;
|
|
font-weight: normal;
|
|
}
|
|
}
|
|
|
|
.date-card-header {
|
|
margin-bottom: 16rpx;
|
|
}
|
|
|
|
.date-label {
|
|
font-size: 22rpx;
|
|
color: $text-secondary;
|
|
}
|
|
|
|
.date-icon-wrap {
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
border-radius: 12rpx;
|
|
background: rgba($brand-primary, 0.1);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
|
|
text {
|
|
font-size: 22rpx;
|
|
color: $brand-primary;
|
|
}
|
|
}
|
|
|
|
.date-value {
|
|
font-size: 28rpx;
|
|
color: $text-primary;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.range-connector {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 0 18rpx;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.connector-line {
|
|
width: 2rpx;
|
|
height: 24rpx;
|
|
background: rgba($brand-primary, 0.25);
|
|
}
|
|
|
|
.connector-text {
|
|
font-size: 22rpx;
|
|
color: $brand-primary;
|
|
font-weight: 700;
|
|
margin: 8rpx 0;
|
|
}
|
|
</style>
|