|
|
@@ -13,7 +13,6 @@
|
|
|
<template #show="{ classNames }">
|
|
|
<view class="nana-bubble-box-popup-mask" @click="hide" />
|
|
|
<FlexView
|
|
|
- v-if="items?.length"
|
|
|
position="absolute"
|
|
|
:direction="direction"
|
|
|
:backgroundColor="backgroundColor"
|
|
|
@@ -42,29 +41,31 @@
|
|
|
borderLeftColor: 'transparent',
|
|
|
}"
|
|
|
/>
|
|
|
- <Touchable
|
|
|
- v-for="item in items"
|
|
|
- :key="item.text"
|
|
|
- direction="row"
|
|
|
- align-items="center"
|
|
|
- :gap="10"
|
|
|
- :padding="[5, 20]"
|
|
|
- v-bind="itemProps"
|
|
|
- @click="handleItemClick(item)"
|
|
|
- >
|
|
|
- <Icon
|
|
|
- :name="item.icon"
|
|
|
- :size="44"
|
|
|
- :color="item.textColor || itemTextColor"
|
|
|
- v-bind="{ ...itemIconProps, ...item.iconProps }"
|
|
|
- />
|
|
|
- <Text
|
|
|
- :wrap="false"
|
|
|
- v-bind="itemTextProps"
|
|
|
- :color="item.textColor || itemTextColor"
|
|
|
- :text="item.text"
|
|
|
- />
|
|
|
- </Touchable>
|
|
|
+ <slot name="content">
|
|
|
+ <Touchable
|
|
|
+ v-for="item in items"
|
|
|
+ :key="item.text"
|
|
|
+ direction="row"
|
|
|
+ align-items="center"
|
|
|
+ :gap="10"
|
|
|
+ :padding="[5, 20]"
|
|
|
+ v-bind="itemProps"
|
|
|
+ @click="handleItemClick(item)"
|
|
|
+ >
|
|
|
+ <Icon
|
|
|
+ :name="item.icon"
|
|
|
+ :size="44"
|
|
|
+ :color="item.textColor || itemTextColor"
|
|
|
+ v-bind="{ ...itemIconProps, ...item.iconProps }"
|
|
|
+ />
|
|
|
+ <Text
|
|
|
+ :wrap="false"
|
|
|
+ v-bind="itemTextProps"
|
|
|
+ :color="item.textColor || itemTextColor"
|
|
|
+ :text="item.text"
|
|
|
+ />
|
|
|
+ </Touchable>
|
|
|
+ </slot>
|
|
|
</FlexView>
|
|
|
</template>
|
|
|
</SimpleTransition>
|
|
|
@@ -74,7 +75,7 @@
|
|
|
<script setup lang="ts">
|
|
|
import { computed, ref } from 'vue';
|
|
|
import { propGetThemeVar, useTheme } from '../theme/ThemeDefine';
|
|
|
-import { selectObjectByType } from '../theme/ThemeTools';
|
|
|
+import { selectObjectByType, selectStyleType } from '../theme/ThemeTools';
|
|
|
import type { FlexProps } from '../layout/FlexView.vue';
|
|
|
import type { TextProps } from '../basic/Text.vue';
|
|
|
import Icon, { type IconProps } from '../basic/Icon.vue';
|
|
|
@@ -97,6 +98,11 @@ export interface BubbleBoxProps {
|
|
|
*/
|
|
|
position?: 'left' | 'right' | 'top' | 'bottom',
|
|
|
/**
|
|
|
+ * 气泡在横轴上的对齐位置,默认居中
|
|
|
+ * @default center
|
|
|
+ */
|
|
|
+ crossPosition?: 'left' | 'center' | 'right',
|
|
|
+ /**
|
|
|
* 触发点击事件模式
|
|
|
* @default click
|
|
|
*/
|
|
|
@@ -212,6 +218,68 @@ function hide() {
|
|
|
enterLock();
|
|
|
}
|
|
|
|
|
|
+const innerStyle = computed(() => {
|
|
|
+ const horzLayout = selectStyleType(props.crossPosition, 'left', {
|
|
|
+ left: {
|
|
|
+ k: 'top',
|
|
|
+ y: '0%',
|
|
|
+ t: 'translateY(0%)',
|
|
|
+ },
|
|
|
+ center: {
|
|
|
+ k: 'top',
|
|
|
+ y: '50%',
|
|
|
+ t: 'translateY(-50%)',
|
|
|
+ },
|
|
|
+ right: {
|
|
|
+ k: 'bottom',
|
|
|
+ y: '0',
|
|
|
+ t: 'translateY(0%)',
|
|
|
+ }
|
|
|
+ });
|
|
|
+ const vertLayout = selectStyleType(props.crossPosition, 'left', {
|
|
|
+ left: {
|
|
|
+ k: 'left',
|
|
|
+ x: '0%',
|
|
|
+ t: 'translateX(0%)',
|
|
|
+ },
|
|
|
+ center: {
|
|
|
+ k: 'left',
|
|
|
+ x: '50%',
|
|
|
+ t: 'translateX(-50%)',
|
|
|
+ },
|
|
|
+ right: {
|
|
|
+ k: 'right',
|
|
|
+ x: '0%',
|
|
|
+ t: 'translateX(0%)',
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return {
|
|
|
+ ...props.innerStyle,
|
|
|
+ ...selectStyleType(props.position, 'top', {
|
|
|
+ left: {
|
|
|
+ [horzLayout.k]: horzLayout.y,
|
|
|
+ right: '100%',
|
|
|
+ transform: horzLayout.t + ' translateX(0)',
|
|
|
+ },
|
|
|
+ right: {
|
|
|
+ [horzLayout.k]: horzLayout.y,
|
|
|
+ left: '100%',
|
|
|
+ transform: horzLayout.t + '',
|
|
|
+ },
|
|
|
+ top: {
|
|
|
+ top: '0%',
|
|
|
+ [vertLayout.k]: vertLayout.x,
|
|
|
+ transform: vertLayout.t + ' translateY(-100%)',
|
|
|
+ },
|
|
|
+ bottom: {
|
|
|
+ bottom: '0%',
|
|
|
+ [vertLayout.k]: vertLayout.x,
|
|
|
+ transform: vertLayout.t + ' translateY(100%)',
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
defineExpose<BubbleBoxExpose>({
|
|
|
show,
|
|
|
hide,
|
|
|
@@ -235,10 +303,6 @@ defineOptions({
|
|
|
transition: opacity ease-in-out 0.2s;
|
|
|
|
|
|
&.left {
|
|
|
- top: 50%;
|
|
|
- right: 100%;
|
|
|
- transform: translateY(-50%) translateX(0);
|
|
|
-
|
|
|
.nana-bubble-box-arrow {
|
|
|
top: 50%;
|
|
|
left: 100%;
|
|
|
@@ -246,10 +310,6 @@ defineOptions({
|
|
|
}
|
|
|
}
|
|
|
&.right {
|
|
|
- top: 50%;
|
|
|
- left: 100%;
|
|
|
- transform: translateY(-50%);
|
|
|
-
|
|
|
.nana-bubble-box-arrow {
|
|
|
top: 50%;
|
|
|
left: 0;
|
|
|
@@ -257,10 +317,6 @@ defineOptions({
|
|
|
}
|
|
|
}
|
|
|
&.top {
|
|
|
- bottom: -100%;
|
|
|
- left: 50%;
|
|
|
- transform: translateX(-50%) translateY(-100%);
|
|
|
-
|
|
|
.nana-bubble-box-arrow {
|
|
|
top: 100%;
|
|
|
left: 50%;
|
|
|
@@ -268,10 +324,6 @@ defineOptions({
|
|
|
}
|
|
|
}
|
|
|
&.bottom {
|
|
|
- top: 100%;
|
|
|
- left: 50%;
|
|
|
- transform: translateX(-50%);
|
|
|
-
|
|
|
.nana-bubble-box-arrow {
|
|
|
top: 0;
|
|
|
left: 50%;
|