refactor timi-web
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<t-popup v-model="visible" placement="bottom">
|
||||
<div class="bottom-popup" :style="{ height: props.height }">
|
||||
<div v-if="hasHeader" class="header">
|
||||
<div class="button left">
|
||||
<slot name="leftButton" :on-click="emitLeftButtonClick">
|
||||
<t-button v-if="leftButtonText" variant="text" size="small" @click="emitLeftButtonClick">
|
||||
<span v-text="leftButtonText" />
|
||||
</t-button>
|
||||
</slot>
|
||||
</div>
|
||||
<div class="title">
|
||||
<slot name="title">
|
||||
<span v-text="title" />
|
||||
</slot>
|
||||
</div>
|
||||
<div class="button right">
|
||||
<slot name="rightButton" :on-click="emitRightButtonClick">
|
||||
<t-button v-if="rightButtonText" theme="primary" variant="text" size="small" @click="emitRightButtonClick">
|
||||
<span v-text="rightButtonText" />
|
||||
</t-button>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
<div class="body">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</t-popup>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
defineOptions({
|
||||
name: "BottomPopup"
|
||||
});
|
||||
|
||||
export interface BottomPopupProps {
|
||||
modelValue?: boolean;
|
||||
leftButtonText?: string;
|
||||
rightButtonText?: string;
|
||||
height?: string | number;
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export interface BottomPopupSlots {
|
||||
default?: () => unknown;
|
||||
title?: () => unknown;
|
||||
leftButton?: (props: { onClick: () => void }) => unknown;
|
||||
rightButton?: (props: { onClick: () => void }) => unknown;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<BottomPopupProps>(), {
|
||||
modelValue: false,
|
||||
leftButtonText: "取消",
|
||||
rightButtonText: "确定",
|
||||
height: "auto",
|
||||
title: ""
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
"update:modelValue": [value: boolean];
|
||||
leftButtonClick: [];
|
||||
rightButtonClick: [];
|
||||
}>();
|
||||
|
||||
const slots = useSlots() as BottomPopupSlots;
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: value => emit("update:modelValue", value)
|
||||
});
|
||||
const hasHeader = computed<boolean>(() => Boolean(
|
||||
props.title
|
||||
|| props.leftButtonText
|
||||
|| props.rightButtonText
|
||||
|| slots.title
|
||||
|| slots.leftButton
|
||||
|| slots.rightButton
|
||||
));
|
||||
|
||||
function emitLeftButtonClick(): void {
|
||||
emit("leftButtonClick");
|
||||
}
|
||||
|
||||
function emitRightButtonClick(): void {
|
||||
emit("rightButtonClick");
|
||||
}
|
||||
|
||||
defineSlots<BottomPopupSlots>();
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.bottom-popup {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
padding-top: 1rem;
|
||||
background: var(--td-bg-color-container, #fff);
|
||||
border-radius: 1.25rem 1.25rem 0 0;
|
||||
flex-direction: column;
|
||||
|
||||
.header {
|
||||
flex: none;
|
||||
padding: 0 1rem;
|
||||
display: grid;
|
||||
align-items: center;
|
||||
grid-template-columns: 4rem 1fr 4rem;
|
||||
}
|
||||
|
||||
.button {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
|
||||
&.right {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.body {
|
||||
flex: 1;
|
||||
padding: .75rem 0 env(safe-area-inset-bottom, 0);
|
||||
overflow: auto;
|
||||
min-height: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user