feat(components): 添加 Public_SmallBorder 组件

This commit is contained in:
Free-sss 2025-09-08 13:57:19 +08:00
parent 9bec16e4b8
commit 0cad8a2b2c
4 changed files with 507 additions and 0 deletions

View File

@ -0,0 +1,10 @@
<svg class="svg-background" viewBox="0 0 400 262" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect id="&#231;&#159;&#169;&#229;&#189;&#162;" opacity="0.7" x="1" y="1" width="398" height="260" rx="4"
fill="#0F121A" stroke="url(#paint0_linear_22_88)" />
<defs>
<linearGradient id="paint0_linear_22_88" x1="200" y1="1" x2="200" y2="261" gradientUnits="userSpaceOnUse">
<stop stop-color="#536D80" stop-opacity="0" />
<stop offset="1" stop-color="#485A66" />
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 581 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 176 KiB

View File

@ -0,0 +1,136 @@
<template>
<div class="go-small-border">
<div class="header flex">
<img src="./assets/Header.svg" alt="标题" class="svg ih">
<span class="title">
{{ titleText }}
</span>
<span class="right-select">
<ConsumSelect v-show="selectOption.show" :options="selectOption.dataset"
:selectedValue="selectOption.selectValue" @change="handleSelectChange"
:select-style-config="selectStyleConfig" />
</span>
</div>
<div class="content flex">
<img src="./assets/Background.svg" alt="" class="svg ic">
<slot>
</slot>
</div>
</div>
</template>
<script lang="ts" setup>
import ConsumSelect from './select.vue'
const props = defineProps({
titleText: {
type: String,
required: true
},
selectOption: {
type: Object,
default: () => ({
show: false,
selectValue: 'day',
dataset: [
{
label: '当天',
value: 'day'
},
{
label: '本周',
value: 'week'
},
{
label: '当月',
value: 'month'
},
{
label: '本季度',
value: 'quarter'
},
{
label: '当年',
value: 'year'
}
]
})
}, selectStyleConfig: {
default: () => ({
showAngle: true
}),
required: false
}
})
const emits = defineEmits(['change'])
const handleSelectChange = (value: any) => {
emits('change', value)
}
</script>
<style scoped>
.go-small-border {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.flex {
display: flex;
}
.header {
position: relative;
height: 35px;
width: 90%;
/* background-color: antiquewhite; */
align-items: center;
padding-bottom: 2px;
justify-content: space-between;
.ih {
top: 2px;
}
.title {
margin-left: 70px;
margin-top: 8px;
z-index: 10;
white-space: nowrap;
font-family: 'CustomFont';
font-style: italic;
letter-spacing: 0.5px;
color: #eee;
text-shadow: 1px 3px 10px #000000;
font-size: 16px;
/* background-color: #eee; */
}
}
.content {
height: calc(100% - 30px);
/* min-height: calc(100% - 15px); */
margin-top: 2px;
width: 90%;
padding: 5px 10px;
box-sizing: border-box;
position: relative;
/* background-color: aquamarine; */
.ic {
height: 100%;
}
}
.svg {
position: absolute;
height: 99%;
width: 100%;
top: 0;
left: 0;
}
}
</style>

View File

@ -0,0 +1,163 @@
<template>
<div class="custom-select" @click="toggleDropdown">
<div class="select-display" :style="selectStyleConfig">
<span class="select-text">{{ getSelectedLabel() }}</span>
<span v-if="selectStyleConfig.showAngle" class="select-arrow"
:class="{ 'arrow-up': isDropdownOpen }"></span>
</div>
<div class="select-dropdown" v-show="isDropdownOpen"
:style="{ backgroundColor: selectStyleConfig.backgroundColor }">
<div v-for="item in options" :key="item.value"
:style="{ backgroundColor: selectStyleConfig.backgroundColor }" class="select-option"
:class="{ 'selected': item.value === selectedValue }" @click.stop="selectOption(item)">
{{ item.label }}
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
// props
const props = defineProps<{
options: Array<{ label: string; value: any }>
selectedValue: any,
selectStyleConfig: any
}>()
// emits
const emit = defineEmits<{
change: [value: any]
}>()
//
const isDropdownOpen = ref(false)
//
const toggleDropdown = (event: Event) => {
event.stopPropagation()
isDropdownOpen.value = !isDropdownOpen.value
}
//
const selectOption = (item: any) => {
emit('change', item.value)
isDropdownOpen.value = false
}
//
const getSelectedLabel = () => {
const selectedItem = props.options.find(
(item: any) => item.value === props.selectedValue
)
return selectedItem ? selectedItem.label : '请选择'
}
//
const handleClickOutside = (event: Event) => {
const target = event.target as HTMLElement
if (!target.closest('.custom-select')) {
isDropdownOpen.value = false
}
}
//
onMounted(() => {
document.addEventListener('click', handleClickOutside)
})
//
onUnmounted(() => {
document.removeEventListener('click', handleClickOutside)
})
</script>
<style lang="scss" scoped>
.custom-select {
position: absolute;
top: 8px;
right: 14px;
font-size: 12px;
z-index: 1000;
}
.select-display {
display: flex;
align-items: center;
justify-content: space-between;
height: 22px;
padding: 0 10px;
background-color: rgb(48, 110, 100);
color: #fff;
border-radius: 10px;
cursor: pointer;
transition: all 0.3s ease;
}
.select-text {
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.select-arrow {
margin-left: 8px;
font-size: 10px;
transition: transform 0.3s ease;
&.arrow-up {
transform: rotate(180deg);
}
}
.select-dropdown {
position: absolute;
top: 100%;
left: 0;
right: 0;
background-color: rgb(48, 110, 100);
border-radius: 6px;
margin-top: 2px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
overflow: hidden;
animation: slideDown 0.2s ease;
}
.select-option {
padding: 10px 0px;
color: #fff;
cursor: pointer;
transition: background-color 0.2s ease;
text-align: center;
width: 100%;
text-wrap: nowrap;
background-color: #8e8e8e;
&:hover {
background-color: rgba(255, 255, 255, 0.1);
}
&.selected {
background-color: rgba(255, 255, 255, 0.2);
font-weight: bold;
}
&:not(:last-child) {
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
</style>