| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- <template>
- <view class="nana-dropdown-menu">
- <view class="nana-dropdown-menu-bar">
- <slot />
- </view>
- <scroll-view scroll-x>
- <DropdownMenuProvide :isExtra="true">
- <view class="nana-dropdown-menu-extra">
- <slot name="extra" />
- </view>
- </DropdownMenuProvide>
- </scroll-view>
- </view>
- </template>
- <script setup lang="ts">
- import { provide, toRef, type Ref } from 'vue';
- import { propGetThemeVar, type ViewStyle } from '../theme/ThemeDefine';
- import DropdownMenuProvide from './DropdownMenuProvide.vue';
- export interface DropdownMenuProps {
- /**
- * 菜单标题和选项的选中态颜色
- */
- activeColor?: string;
- /**
- * 背景颜色
- */
- backgroundColor?: string;
- /**
- * 菜单选项的样式
- */
- itemStyle?: ViewStyle;
- /**
- * 菜单额外选项的样式
- */
- itemExtraStyle?: ViewStyle;
- /**
- * 菜单的方向
- */
- direction?: 'up'|'down';
- /**
- * 动画时长,单位ms,设置为 0 可以禁用动画
- */
- duration?: number;
- /**
- * 是否包含导航栏空间,这会影响弹出菜单的定位
- * @default true
- */
- includeNavBarSpace?: boolean;
- }
- const props = withDefaults(defineProps<DropdownMenuProps>(), {
- activeColor: () => propGetThemeVar('DropdownMenuActiveColor', 'primary'),
- backgroundColor: () => propGetThemeVar('DropdownMenuBackgroundColor', 'white'),
- direction: 'down',
- duration: 300,
- includeNavBarSpace: true,
- });
- let closeCb: (() => void)|null = null;
- function close() {
- if (closeCb) {
- closeCb();
- closeCb = null;
- }
- }
- export interface DropdownMenuContext {
- activeColor: Ref<string>;
- backgroundColor: Ref<string>;
- itemStyle: Ref<ViewStyle|undefined>;
- includeNavBarSpace: Ref<boolean>;
- itemExtraStyle: Ref<ViewStyle|undefined>;
- direction: Ref<'up'|'down'>;
- duration: Ref<number>;
- setCurrentOpen: (cb: () => void) => void,
- }
- provide<DropdownMenuContext>('DropdownMenuContext', {
- activeColor: toRef(props, 'activeColor'),
- backgroundColor: toRef(props, 'backgroundColor'),
- includeNavBarSpace: toRef(props, 'includeNavBarSpace'),
- itemStyle: toRef(props, 'itemStyle'),
- itemExtraStyle: toRef(props, 'itemExtraStyle'),
- direction: toRef(props, 'direction'),
- duration: toRef(props, 'duration'),
- setCurrentOpen(cb: () => void) {
- if (closeCb)
- closeCb();
- closeCb = cb;
- },
- });
- export interface DropdownMenuInstance {
- close: () => void;
- }
- defineExpose<DropdownMenuInstance>({
- close,
- })
- defineOptions({
- options: {
- inheritAttrs: false,
- styleIsolation: 'shared',
- }
- })
- </script>
- <style lang="scss">
- .nana-dropdown-menu {
- display: flex;
- flex-direction: column;
- width: 100%;
- }
- .nana-dropdown-menu-bar {
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- align-items: center;
- }
- .nana-dropdown-menu-extra {
- display: flex;
- flex-direction: row;
- justify-content: flex-start;
- align-items: center;
- padding: 16rpx 24rpx;
- }
- </style>
|