-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5343c69
commit f8c94fc
Showing
6 changed files
with
413 additions
and
78 deletions.
There are no files selected for viewing
159 changes: 159 additions & 0 deletions
159
vue3/packages/common/components/collapse-card/collapseCard.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
<template> | ||
<div class="sm-component-collapse-card" :style="getTextColorStyle"> | ||
<div | ||
v-if="iconClass" | ||
:class="{ | ||
['sm-component-collapse-card__icon']: true, | ||
['is-' + position]: true, | ||
[`is-click-${isShow ? 'out' : 'in'}`]: true, | ||
['is-not-header']: !headerName, | ||
['icon-box-shadow']: !isShow | ||
}" | ||
:style="[collapseCardHeaderBgStyle, headingTextColorStyle]" | ||
@click="iconClicked" | ||
> | ||
<!-- <i :style="iconStyle" :class="{ [iconClass]: true, ['is-auto-rotate']: autoRotate }" /> --> | ||
<SwitcherOutlined /> | ||
</div> | ||
<transition name="sm-component-zoom-in" @after-leave="toggleTransition('leave')" @enter="toggleTransition('enter')"> | ||
<div | ||
v-show="isShow" | ||
:class="{ | ||
['sm-component-collapse-card__content']: true, | ||
['is-not-header']: !headerName, | ||
['is-' + position]: true, | ||
['is-icon']: iconClass | ||
}" | ||
:style="getCardStyle" | ||
> | ||
<div | ||
v-if="headerName" | ||
:class="{'sm-component-collapse-card__header': true, 'with-split-line': splitLine, ['is-' + position]: true}" | ||
:style="[collapseCardHeaderBgStyle, headingTextColorStyle]" | ||
> | ||
<span class="sm-component-collapse-card__header-name">{{ headerName }}</span> | ||
</div> | ||
<div :style="getCardStyle" class="sm-component-collapse-card__body"> | ||
<slot></slot> | ||
</div> | ||
</div> | ||
</transition> | ||
</div> | ||
</template> | ||
|
||
<script setup> | ||
// import Theme from 'vue-iclient/src/common/_mixin/Theme'; | ||
import { ref, computed, watch, onMounted, onBeforeMount, nextTick } from 'vue'; | ||
import { SwitcherOutlined } from '@ant-design/icons-vue'; | ||
const props = defineProps({ | ||
iconPosition: { | ||
type: String, | ||
default: 'top-left' | ||
}, | ||
iconClass: { | ||
type: String | ||
}, | ||
autoRotate: { | ||
type: Boolean, | ||
default: false | ||
}, | ||
headerName: { | ||
type: String | ||
}, | ||
collapsed: { | ||
type: Boolean, | ||
default: false | ||
}, | ||
splitLine: { | ||
type: Boolean, | ||
default: true | ||
} | ||
}); | ||
const isShow = ref(true); | ||
const transform = ref(null); | ||
// 计算属性 | ||
const getCardStyle = computed(() => { | ||
const style = { background: 'transparent' }; | ||
// return !props.iconClass && !props.headerName ? style : collapseCardBackgroundStyle; | ||
return !props.iconClass && !props.headerName ? style : {}; | ||
}); | ||
const iconStyle = computed(() => { | ||
return { | ||
transform: transform.value | ||
}; | ||
}); | ||
const position = computed(() => props.iconPosition); | ||
const rotateDeg = computed(() => { | ||
return { | ||
'top-right': ['rotate(-45deg)', 'rotate(135deg)'], | ||
'top-left': ['rotate(-135deg)', 'rotate(45deg)'], | ||
'bottom-left': ['rotate(135deg)', 'rotate(-45deg)'], | ||
'bottom-right': ['rotate(45deg)', 'rotate(-135deg)'] | ||
}; | ||
}); | ||
const hasHeaderRotateDeg = computed(() => { | ||
return { | ||
'top-right': ['rotate(-45deg)', 'rotate(135deg)'], | ||
'top-left': ['rotate(-135deg)', 'rotate(45deg)'], | ||
'bottom-left': ['rotate(-135deg)', 'rotate(45deg)'], | ||
'bottom-right': ['rotate(-45deg)', 'rotate(135deg)'] | ||
}; | ||
}); | ||
// watch 监听 | ||
watch(() => props.iconClass, (newVal, oldVal) => { | ||
if (newVal && !oldVal) { | ||
isShow.value = !props.collapsed; | ||
toggleTransition(props.collapsed ? 'leave' : 'enter'); | ||
} else if (!newVal) { | ||
// 如果iconClass 为空 则默认显示内容 | ||
isShow.value = true; | ||
} | ||
}); | ||
watch(() => props.iconPosition, () => { | ||
resetIconTransform(); | ||
}); | ||
if (props.iconClass) { | ||
isShow.value = !props.collapsed; | ||
} | ||
resetIconTransform(); | ||
onMounted(() => { | ||
toggleTransition(props.collapsed ? 'leave' : 'enter'); | ||
}); | ||
function iconClicked() { | ||
isShow.value = !isShow.value; | ||
resetIconTransform(); | ||
emit('content-show-state', isShow.value); | ||
}; | ||
function toggleTransition(type) { | ||
nextTick(() => { | ||
const iconDom = document.querySelector('.sm-component-collapse-card__icon'); | ||
if (iconDom) { | ||
iconDom.style.position = type === 'leave' ? 'relative' : 'absolute'; | ||
} | ||
}); | ||
}; | ||
function resetIconTransform() { | ||
let rotateDegObj = props.headerName ? hasHeaderRotateDeg.value : rotateDeg.value; | ||
if (props.autoRotate) { | ||
transform.value = rotateDegObj[position.value][isShow.value ? 1 : 0]; | ||
} | ||
}; | ||
const emit = defineEmits(['content-show-state']); | ||
</script> | ||
|
||
<style lang="scss"></style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
import '@supermapgis/common/theme-chalk/collapseCard.scss' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
@use './mixins/mixins.scss' as *; | ||
@use './base/theme.scss' as *; | ||
|
||
@include b(collapse-card) { | ||
$collapse-card-prefix: &; | ||
|
||
position: relative; | ||
overflow: visible; | ||
font-size: 12px; | ||
color: $text-color; | ||
.icon-box-shadow { | ||
box-shadow: 0 3px 13px 0px $shadow-color; | ||
} | ||
@include e(icon) { | ||
z-index: 100; | ||
background: $collapse-card-header-bg; | ||
color: $heading-color; | ||
cursor: pointer; | ||
box-sizing: border-box; | ||
font-size: 16px; | ||
width: 32px; | ||
height: 32px; | ||
line-height: 32px; | ||
text-align: center; | ||
&:hover { | ||
background: #ffffff; | ||
border-color: $hover-color !important; | ||
color: $hover-color !important; | ||
} | ||
> i { | ||
display: block; | ||
} | ||
@include when(not-header) { | ||
@include when(bottom-right) { | ||
bottom: 0; | ||
top: unset; | ||
} | ||
@include when(bottom-left) { | ||
bottom: 0; | ||
top: unset; | ||
} | ||
} | ||
@include when(click-in) { | ||
border-radius: 4px; | ||
@include when(top-right) { | ||
float: right; | ||
} | ||
@include when(bottom-right) { | ||
float: right; | ||
} | ||
@include when(top-left) { | ||
float: left !important; | ||
} | ||
@include when(bottom-left) { | ||
float: left !important; | ||
} | ||
} | ||
@include when(click-out) { | ||
border: none; | ||
background: transparent !important; | ||
} | ||
@include when(top-left) { | ||
top: 0; | ||
left: 0; | ||
& .sm-component-collapse-card__component-icon.is-auto-rotate { | ||
transform: rotate(45deg); | ||
} | ||
} | ||
@include when(bottom-left) { | ||
top: 0; | ||
left: 0; | ||
& .sm-component-collapse-card__component-icon.is-auto-rotate { | ||
transform: rotate(45deg); | ||
} | ||
} | ||
@include when(top-right) { | ||
top: 0; | ||
right: 0; | ||
& .sm-component-collapse-card__component-icon.is-auto-rotate { | ||
transform: rotate(135deg); | ||
} | ||
} | ||
@include when(bottom-right) { | ||
top: 0; | ||
right: 0; | ||
& .sm-component-collapse-card__component-icon.is-auto-rotate { | ||
transform: rotate(135deg); | ||
} | ||
} | ||
} | ||
|
||
@include e(header) { | ||
height: 32px; | ||
line-height: 32px; | ||
padding-left: 8px; | ||
box-shadow: 0px 1px 0px 0px $shadow-color; | ||
color: $heading-color; | ||
background: $collapse-card-header-bg; | ||
border-radius: 4px 4px 0 0; | ||
&.with-split-line { | ||
border-bottom: 1px solid $collapse-card-split-line; | ||
} | ||
+ #{$collapse-card-prefix}__body { | ||
border-top-left-radius: 0; | ||
border-top-right-radius: 0; | ||
} | ||
@include when(top-right) { | ||
padding-right: 30px; | ||
} | ||
@include when(bottom-right) { | ||
padding-right: 30px; | ||
} | ||
@include when(top-left) { | ||
padding-left: 30px; | ||
} | ||
@include when(bottom-left) { | ||
padding-left: 30px; | ||
} | ||
} | ||
@include e(content) { | ||
box-shadow: 0 3px 13px 0px $shadow-color; | ||
background: $collapse-card-bg; | ||
position: relative; | ||
border-radius: 4px; | ||
&.sm-component-zoom-in-enter-active { | ||
animation: zoom-in .5s; | ||
} | ||
&.sm-component-zoom-in-leave-active { | ||
animation: zoom-in .5s reverse; | ||
} | ||
@keyframes zoom-in { | ||
0% { | ||
transform: scale(0); | ||
opacity: 0; | ||
} | ||
100% { | ||
transform: scale(1); | ||
opacity: 1; | ||
} | ||
} | ||
@include when(top-left) { | ||
transform-origin: top left; | ||
@include when(icon) { | ||
& > .sm-component-collapse-card__header { | ||
padding-left: 38px; | ||
} | ||
} | ||
} | ||
@include when(bottom-left) { | ||
transform-origin: top left; | ||
@include when(icon) { | ||
& > .sm-component-collapse-card__header { | ||
padding-left: 38px; | ||
} | ||
} | ||
} | ||
@include when(not-header) { | ||
@include when(bottom-right) { | ||
transform-origin: bottom right; | ||
} | ||
@include when(bottom-left) { | ||
transform-origin: bottom left; | ||
} | ||
} | ||
@include when(bottom-right) { | ||
transform-origin: top right; | ||
} | ||
@include when(top-right) { | ||
transform-origin: top right; | ||
} | ||
} | ||
@include e(body) { | ||
height: 100%; | ||
border-radius: 4px; | ||
} | ||
} |
Oops, something went wrong.