hy-app 0.2.5 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/common/index.ts +2 -1
  2. package/common/shakeService.ts +60 -0
  3. package/components/hy-action-sheet/hy-action-sheet.vue +184 -0
  4. package/components/hy-action-sheet/index.scss +123 -0
  5. package/components/hy-action-sheet/props.ts +18 -0
  6. package/components/hy-action-sheet/typing.d.ts +96 -0
  7. package/components/hy-address-picker/hy-address-picker.vue +75 -91
  8. package/components/hy-avatar/hy-avatar.vue +64 -73
  9. package/components/hy-button/hy-button.vue +3 -3
  10. package/components/hy-button/typing.d.ts +35 -31
  11. package/components/hy-cell/typing.d.ts +27 -24
  12. package/components/hy-empty/hy-empty.vue +30 -37
  13. package/components/hy-empty/icon.ts +78 -0
  14. package/components/hy-empty/index.scss +2 -1
  15. package/components/hy-empty/props.ts +10 -9
  16. package/components/hy-empty/typing.d.ts +39 -14
  17. package/components/hy-float-button/hy-float-button.vue +183 -17
  18. package/components/hy-float-button/props.ts +17 -15
  19. package/components/hy-float-button/typing.d.ts +51 -27
  20. package/components/hy-icon/hy-icon.vue +39 -41
  21. package/components/hy-icon/props.ts +17 -16
  22. package/components/hy-icon/typing.d.ts +24 -20
  23. package/components/hy-image/hy-image.vue +69 -104
  24. package/components/hy-image/index.scss +21 -5
  25. package/components/hy-image/props.ts +11 -10
  26. package/components/hy-image/typing.d.ts +23 -19
  27. package/components/hy-modal/hy-modal.vue +42 -54
  28. package/components/hy-modal/index.scss +56 -32
  29. package/components/hy-modal/props.ts +15 -14
  30. package/components/hy-modal/typing.d.ts +23 -17
  31. package/components/hy-popover/hy-popover.vue +200 -0
  32. package/components/hy-popover/index.scss +83 -0
  33. package/components/hy-popover/props.ts +13 -0
  34. package/components/hy-popover/typing.d.ts +56 -0
  35. package/components/hy-popup/index.scss +2 -2
  36. package/components/hy-popup/props.ts +7 -7
  37. package/components/hy-popup/typing.d.ts +17 -17
  38. package/components/hy-qrcode/hy-qrcode.vue +44 -45
  39. package/components/hy-rate/props.ts +6 -6
  40. package/components/hy-signature/props.ts +14 -14
  41. package/components/hy-tooltip/index.scss +2 -2
  42. package/components/hy-transition/hy-transition.vue +64 -72
  43. package/components/hy-transition/typing.d.ts +10 -6
  44. package/composables/index.ts +4 -2
  45. package/composables/usePopover.ts +221 -0
  46. package/composables/useQueue.ts +52 -0
  47. package/libs/css/_config.scss +5 -0
  48. package/libs/css/_function.scss +89 -0
  49. package/libs/css/mixin.scss +146 -21
  50. package/libs/css/vars.css +3 -1
  51. package/package.json +2 -2
  52. package/theme.scss +2 -1
  53. package/utils/inside.ts +96 -108
  54. package/utils/inspect.ts +48 -40
  55. package/utils/utils.ts +170 -187
@@ -2,9 +2,9 @@
2
2
  <HyPopup
3
3
  mode="center"
4
4
  :zoom="zoom"
5
- :show="show"
5
+ :show="modelValue"
6
+ :round="round"
6
7
  :customStyle="{
7
- borderRadius: '6px',
8
8
  overflow: 'hidden',
9
9
  marginTop: `-${addUnit(negativeTop)}`,
10
10
  }"
@@ -32,53 +32,41 @@
32
32
  </text>
33
33
  </slot>
34
34
  </view>
35
- <view
36
- class="hy-modal__button-group--confirm-button"
37
- v-if="$slots.confirmButton"
38
- >
35
+ <view class="hy-modal__button-group--confirm-button" v-if="$slots.confirmButton">
39
36
  <slot name="confirmButton"></slot>
40
37
  </view>
41
38
  <template v-else>
42
39
  <view
43
- class="hy-modal__button-group"
40
+ :class="[
41
+ 'hy-modal__button-group',
42
+ showCancelButton &&
43
+ showConfirmButton &&
44
+ (!buttonReverse ? 'hy-modal__button-exact' : 'hy-modal__button-exact--reverse'),
45
+ ]"
44
46
  :style="{
45
47
  flexDirection: buttonReverse ? 'row-reverse' : 'row',
46
48
  }"
47
49
  >
48
50
  <view
49
- class="hy-modal__button-group__wrapper u-modal__button-group__wrapper--cancel"
51
+ class="hy-modal__button-group__wrapper hy-modal__button-group__wrapper--cancel"
50
52
  :hover-stay-time="150"
51
53
  hover-class="hy-modal__button-group__wrapper--hover"
52
- :class="[
53
- showCancelButton &&
54
- !showConfirmButton &&
55
- 'hy-modal__button-group__wrapper--only-cancel',
56
- ]"
57
54
  v-if="showCancelButton"
58
55
  @tap.stop="cancelHandler"
59
56
  >
60
57
  <text
61
- class="hy-modal__button-group__wrapper__text"
58
+ class="hy-modal__button-group__wrapper__text hy-modal__button-group__wrapper--cancel-text"
62
59
  :style="{
63
60
  color: cancelColor,
64
61
  }"
65
- >{{ cancelText }}</text
66
62
  >
63
+ {{ cancelText }}
64
+ </text>
67
65
  </view>
68
- <hy-line
69
- v-if="showConfirmButton && showCancelButton"
70
- length="48px"
71
- direction="column"
72
- ></hy-line>
73
66
  <view
74
67
  class="hy-modal__button-group__wrapper hy-modal__button-group__wrapper--confirm"
75
68
  :hover-stay-time="150"
76
69
  hover-class="hy-modal__button-group__wrapper--hover"
77
- :class="[
78
- !showCancelButton &&
79
- showConfirmButton &&
80
- 'hy-modal__button-group__wrapper--only-confirm',
81
- ]"
82
70
  v-if="showConfirmButton"
83
71
  @tap="confirmHandler"
84
72
  >
@@ -89,8 +77,9 @@
89
77
  :style="{
90
78
  color: confirmColor,
91
79
  }"
92
- >{{ confirmText }}</text
93
80
  >
81
+ {{ confirmText }}
82
+ </text>
94
83
  </view>
95
84
  </view>
96
85
  </template>
@@ -100,38 +89,37 @@
100
89
 
101
90
  <script lang="ts">
102
91
  export default {
103
- name: "hy-modal",
92
+ name: 'hy-modal',
104
93
  options: {
105
94
  addGlobalClass: true,
106
95
  virtualHost: true,
107
- styleIsolation: "shared",
96
+ styleIsolation: 'shared',
108
97
  },
109
- };
98
+ }
110
99
  </script>
111
100
 
112
101
  <script setup lang="ts">
113
- import { ref, toRefs, watch } from "vue";
114
- import defaultProps from "./props";
115
- import type IProps from "./typing";
116
- import { addUnit } from "../../utils";
102
+ import { ref, toRefs, watch } from 'vue'
103
+ import defaultProps from './props'
104
+ import type IProps from './typing'
105
+ import { addUnit } from '../../utils'
117
106
 
118
107
  // 组件
119
- import HyLine from "../hy-line/hy-line.vue";
120
- import HyPopup from "../hy-popup/hy-popup.vue";
121
- import HyLoading from "../hy-loading/hy-loading.vue";
108
+ import HyPopup from '../hy-popup/hy-popup.vue'
109
+ import HyLoading from '../hy-loading/hy-loading.vue'
122
110
 
123
- const props = withDefaults(defineProps<IProps>(), defaultProps);
124
- const { show, asyncClose, closeOnClickOverlay } = toRefs(props);
125
- const emit = defineEmits(["confirm", "cancel", "close", "update:show"]);
111
+ const props = withDefaults(defineProps<IProps>(), defaultProps)
112
+ const { modelValue, asyncClose, closeOnClickOverlay } = toRefs(props)
113
+ const emit = defineEmits(['confirm', 'cancel', 'close', 'update:modelValue'])
126
114
 
127
- const loading = ref<boolean>(false);
115
+ const loading = ref<boolean>(false)
128
116
 
129
117
  watch(
130
- () => show.value,
118
+ () => modelValue.value,
131
119
  (newValue) => {
132
- if (newValue && loading.value) loading.value = false;
120
+ if (newValue && loading.value) loading.value = false
133
121
  },
134
- );
122
+ )
135
123
 
136
124
  /**
137
125
  * @description 点击确定按钮
@@ -139,34 +127,34 @@ watch(
139
127
  const confirmHandler = () => {
140
128
  // 如果配置了异步关闭,将按钮值为loading状态
141
129
  if (asyncClose.value) {
142
- loading.value = true;
130
+ loading.value = true
143
131
  } else {
144
- emit("update:show", false);
132
+ emit('update:modelValue', false)
145
133
  }
146
- emit("confirm");
147
- };
134
+ emit('confirm')
135
+ }
148
136
 
149
137
  /**
150
138
  * @description 点击取消按钮
151
139
  * */
152
140
  const cancelHandler = () => {
153
- emit("update:show", false);
154
- emit("cancel");
155
- };
141
+ emit('update:modelValue', false)
142
+ emit('cancel')
143
+ }
156
144
 
157
145
  /**
158
146
  * @description 点击遮罩
159
147
  * */
160
148
  const clickHandler = () => {
161
149
  if (closeOnClickOverlay.value) {
162
- emit("update:show", false);
163
- emit("close");
150
+ emit('update:modelValue', false)
151
+ emit('close')
164
152
  }
165
- };
153
+ }
166
154
  </script>
167
155
 
168
156
  <style lang="scss" scoped>
169
- @import "./index.scss";
157
+ @import './index.scss';
170
158
  .modal__content__text {
171
159
  text-align: v-bind(contentTextAlign);
172
160
  }
@@ -6,70 +6,94 @@
6
6
  border-radius: $hy-border-radius-base;
7
7
  overflow: hidden;
8
8
 
9
+ /* 标题 */
9
10
  &__title {
10
11
  display: flex;
11
12
  flex-direction: column;
12
13
  justify-content: center;
13
14
  align-items: center;
14
- font-size: 16px;
15
+ font-size: $hy-font-size-base;
15
16
  font-weight: bold;
16
17
  color: $hy-text-color;
17
18
  text-align: center;
18
19
  padding-top: 25px;
19
20
  }
20
21
 
22
+ /* 内容 */
21
23
  &__content {
22
24
  padding: 20px;
23
25
  @include flex;
24
26
  justify-content: center;
25
27
 
26
28
  &__text {
27
- font-size: 15px;
29
+ font-size: $hy-font-size-sm;
28
30
  color: $hy-text-color--grey;
29
31
  flex: 1;
30
32
  text-align: center;
31
33
  }
32
34
  }
33
35
 
34
- &__button-group {
35
- border-top: $hy-border-line;
36
- @include flex;
37
-
38
- &--confirm-button {
39
- flex-direction: column;
40
- padding: 0 25px 15px;
36
+ /* 底部按钮 */
37
+ &__button {
38
+ /* 两个按钮的样式 */
39
+ &-exact {
40
+ view:first-child {
41
+ margin-right: $hy-border-margin-padding-lg;
42
+ }
43
+ &--reverse {
44
+ view:last-child {
45
+ margin-right: $hy-border-margin-padding-lg;
46
+ }
47
+ }
41
48
  }
42
49
 
43
- &__wrapper {
44
- flex: 1;
50
+
51
+ &-group {
45
52
  @include flex;
46
- justify-content: center;
47
- align-items: center;
48
- height: 48px;
53
+ padding: 20px;
49
54
 
50
- &--confirm,
51
- &--only-cancel {
52
- border-bottom-right-radius: $hy-border-radius-base;
55
+ /* 自定义底部按钮 */
56
+ &--confirm-button {
57
+ flex-direction: column;
58
+ padding: 0 25px 15px;
53
59
  }
54
60
 
55
- &--cancel,
56
- &--only-confirm {
57
- border-bottom-left-radius: $hy-border-radius-base;
58
- }
59
61
 
60
- &--hover {
61
- background-color: $hy-background--hover;
62
- }
62
+ &__wrapper {
63
+ flex: 1;
64
+ @include flex;
65
+ justify-content: center;
66
+ align-items: center;
67
+ height: 43px;
68
+ border-radius: $hy-border-radius-semicircle;
63
69
 
64
- &__text {
65
- color: $hy-text-color--2;
66
- font-size: 16px;
67
- text-align: center;
68
- }
70
+ /* 确认 */
71
+ &--confirm {
72
+ background-color: $hy-primary;
73
+ &-text {
74
+ color: #FFFFFF;
75
+ }
76
+ }
77
+
78
+ /* 取消 */
79
+ &--cancel {
80
+ //background-color: $hy-background--empty;
81
+ background-color: #323233;
82
+
83
+ &-text {
84
+ color: $hy-text-color;
85
+ }
86
+ }
87
+
88
+ &--hover {
89
+ opacity: 0.7;
90
+ }
69
91
 
70
- &--confirm-text {
71
- color: $hy-primary;
92
+ &__text {
93
+ font-size: 16px;
94
+ text-align: center;
95
+ }
72
96
  }
73
97
  }
74
98
  }
75
- }
99
+ }
@@ -1,24 +1,25 @@
1
- import type IProps from "./typing";
2
- import { ColorConfig } from "../../config";
1
+ import type IProps from './typing'
2
+ import { ColorConfig } from '../../config'
3
3
 
4
4
  const defaultProps: IProps = {
5
- show: false,
6
- title: "",
7
- content: "",
8
- confirmText: "确认",
9
- cancelText: "取消",
5
+ modelValue: false,
6
+ title: '',
7
+ content: '',
8
+ confirmText: '确认',
9
+ cancelText: '取消',
10
10
  showConfirmButton: true,
11
11
  showCancelButton: false,
12
- confirmColor: "",
13
- cancelColor: "",
12
+ confirmColor: '',
13
+ cancelColor: '',
14
14
  buttonReverse: false,
15
15
  zoom: true,
16
+ round: 16,
16
17
  asyncClose: false,
17
18
  closeOnClickOverlay: false,
18
19
  negativeTop: 0,
19
- width: "550rpx",
20
- confirmButtonShape: "",
21
- contentTextAlign: "left",
22
- };
20
+ width: '550rpx',
21
+ confirmButtonShape: '',
22
+ contentTextAlign: 'left',
23
+ }
23
24
 
24
- export default defaultProps;
25
+ export default defaultProps
@@ -1,70 +1,76 @@
1
+ import { RowCenterType } from 'hy-app/typing/modules/common'
2
+
1
3
  export default interface HyModalProps {
2
4
  /**
3
5
  * @description 是否显示模态框,请赋值给show (默认 false )
4
6
  * */
5
- show: boolean;
7
+ modelValue: boolean
6
8
  /**
7
9
  * @description 标题内容
8
10
  * */
9
- title?: string;
11
+ title?: string
10
12
  /**
11
13
  * @description 模态框内容,如传入slot内容,则此参数无效
12
14
  * */
13
- content?: string;
15
+ content?: string
14
16
  /**
15
17
  * @description 确认按钮的文字 (默认 '确认' )
16
18
  * */
17
- confirmText?: string;
19
+ confirmText?: string
18
20
  /**
19
21
  * @description 取消按钮的文字 (默认 '取消' )
20
22
  * */
21
- cancelText?: string;
23
+ cancelText?: string
22
24
  /**
23
25
  * @description 是否显示确认按钮 (默认 true )
24
26
  * */
25
- showConfirmButton?: boolean;
27
+ showConfirmButton?: boolean
26
28
  /**
27
29
  * @description 是否显示取消按钮 (默认 false )
28
30
  * */
29
- showCancelButton?: boolean;
31
+ showCancelButton?: boolean
30
32
  /**
31
33
  * @description 确认按钮的颜色 (默认 '#2979ff' )
32
34
  * */
33
- confirmColor?: string;
35
+ confirmColor?: string
34
36
  /**
35
37
  * @description 取消按钮的颜色 (默认 '#606266' )
36
38
  * */
37
- cancelColor?: string;
39
+ cancelColor?: string
38
40
  /**
39
41
  * @description 对调确认和取消的位置 (默认 false )
40
42
  * */
41
- buttonReverse?: boolean;
43
+ buttonReverse?: boolean
42
44
  /**
43
45
  * @description 是否开启缩放模式 (默认 true )
44
46
  * */
45
- zoom?: boolean;
47
+ zoom?: boolean
48
+ /**
49
+ * @description 弹窗的圆角 (默认 16 )
50
+ * */
51
+ round?: string | number
46
52
  /**
47
53
  * @description 是否异步关闭,只对确定按钮有效,见上方说明 (默认 false )
48
54
  * */
49
- asyncClose?: boolean;
55
+ asyncClose?: boolean
50
56
  /**
51
57
  * @description 是否允许点击遮罩关闭Modal (默认 false )
52
58
  * */
53
- closeOnClickOverlay?: boolean;
59
+ closeOnClickOverlay?: boolean
54
60
  /**
55
61
  * @description 往上偏移的值,给一个负的margin-top,往上偏移,避免和键盘重合的情况,单位任意,数值则默认为px单位 (默认 0 )
56
62
  * */
57
- negativeTop?: number;
63
+ negativeTop?: number
58
64
  /**
59
65
  * @description modal宽度,不支持百分比,可以数值,px,rpx单位 (默认 '650rpx' )
60
66
  * */
61
- width?: string | number;
67
+ width?: string | number
62
68
  /**
63
69
  * @description 确认按钮的样式,如设置,将不会显示取消按钮
64
70
  * */
65
- confirmButtonShape?: HyApp.ShapeType | "";
71
+ confirmButtonShape?: HyApp.ShapeType | ''
66
72
  /**
67
73
  * @description 文案对齐方式
68
74
  * */
69
- contentTextAlign?: HyApp.LeftRightType | "center";
75
+ contentTextAlign?: HyApp.RowCenterType
70
76
  }
@@ -0,0 +1,200 @@
1
+ <template>
2
+ <view class="hy-popover" :style="customStyle" id="popover" @click.stop="popover.noop">
3
+ <!-- 使用插槽时无法获取正确宽高 -->
4
+ <view class="hy-popover__pos hy-popover__hidden" id="pos">
5
+ <view class="hy-popover__container">
6
+ <view v-if="mode === 'normal'" class="hy-popover__inner">
7
+ {{ content }}
8
+ </view>
9
+ <view v-if="mode === 'menu' && typeof content === 'object'" class="hy-popover__menu">
10
+ <view
11
+ v-for="(item, index) in content"
12
+ :key="index"
13
+ class="hy-popover__menu-inner"
14
+ @click="menuClick(index)"
15
+ >
16
+ <hy-icon v-if="item.iconClass" :name="item.iconClass" custom-class="hy-popover__icon" />
17
+ <text>{{ item.content }}</text>
18
+ </view>
19
+ </view>
20
+ </view>
21
+ </view>
22
+ <hy-transition
23
+ class="hy-popover__pos"
24
+ :custom-style="popover.popStyle.value"
25
+ :show="showPopover"
26
+ name="fade"
27
+ :duration="200"
28
+ >
29
+ <view class="hy-popover__container">
30
+ <!-- 三角形 -->
31
+ <view
32
+ :class="`hy-popover__arrow ${popover.arrowClass.value}`"
33
+ :style="popover.arrowStyle.value"
34
+ ></view>
35
+ <!-- 三角形 -->
36
+
37
+ <!-- 普通模式 -->
38
+ <view v-if="mode === 'normal'" class="hy-popover__inner">
39
+ {{ content }}
40
+ </view>
41
+ <!-- 普通模式 -->
42
+
43
+ <!-- 列表模式 -->
44
+ <view v-if="mode === 'menu'" class="hy-popover__menu">
45
+ <view
46
+ v-for="(item, index) in content"
47
+ :key="index"
48
+ class="hy-popover__menu-inner"
49
+ @click="menuClick(index)"
50
+ :style="index === 0 ? 'border-top: none' : ''"
51
+ >
52
+ <hy-icon
53
+ v-if="typeof item === 'object' && item.iconClass"
54
+ :name="item.iconClass"
55
+ custom-class="hy-popover__icon"
56
+ />
57
+ <view style="display: inline-block">
58
+ {{ typeof item === 'object' && item.content ? item.content : item }}
59
+ </view>
60
+ </view>
61
+ </view>
62
+ <!-- 列表模式 -->
63
+
64
+ <!-- 用户自定义样式 -->
65
+ <slot name="content" v-else />
66
+ <!-- 用户自定义样式 -->
67
+ </view>
68
+ <hy-icon
69
+ v-if="showClose"
70
+ name="close"
71
+ custom-class="hy-popover__close-icon"
72
+ @click="toggle"
73
+ ></hy-icon>
74
+ </hy-transition>
75
+ <view @click="toggle" class="hy-popover__target" id="target">
76
+ <slot />
77
+ </view>
78
+ </view>
79
+ </template>
80
+
81
+ <script lang="ts">
82
+ export default {
83
+ name: 'hy-popover',
84
+ options: {
85
+ virtualHost: true,
86
+ addGlobalClass: true,
87
+ styleIsolation: 'shared',
88
+ },
89
+ }
90
+ </script>
91
+
92
+ <script lang="ts" setup>
93
+ import { getCurrentInstance, onMounted, ref, toRefs, watch } from 'vue'
94
+ import defaultProps from './props'
95
+ import IProps, { type PopoverExpose } from './typing'
96
+ import { isArray } from '../../utils'
97
+ import { type Queue, queueKey, usePopover } from '../../composables'
98
+
99
+ // 组件
100
+ import HyIcon from '../hy-icon/hy-icon.vue'
101
+ import HyTransition from '../hy-transition/hy-transition.vue'
102
+
103
+ const props = withDefaults(defineProps<IProps>(), defaultProps)
104
+ const { modelValue, content, mode, placement } = toRefs(props)
105
+ const emit = defineEmits(['update:modelValue', 'menuClick', 'change', 'open', 'close'])
106
+
107
+ const queue = inject<Queue | null>(queueKey, null)
108
+ const selector: string = 'popover'
109
+ const { proxy } = getCurrentInstance() as any
110
+ const popover = usePopover()
111
+ const showPopover = ref<boolean>(false) // 控制popover显隐
112
+
113
+ watch(
114
+ () => content.value,
115
+ (newVal) => {
116
+ if (mode.value === 'normal' && typeof newVal !== 'string') {
117
+ console.error('在“normal”模式下,值类型必须为字符串类型。')
118
+ } else if (mode.value === 'menu' && !isArray(newVal)) {
119
+ console.error('在“menu”模式下,值类型必须是数组类型。')
120
+ }
121
+ },
122
+ )
123
+
124
+ watch(
125
+ () => props.placement,
126
+ () => {
127
+ popover.init(placement.value, true, selector)
128
+ },
129
+ )
130
+
131
+ watch(
132
+ () => modelValue.value,
133
+ (newValue: boolean) => {
134
+ showPopover.value = newValue
135
+ },
136
+ )
137
+
138
+ watch(
139
+ () => showPopover.value,
140
+ (newValue) => {
141
+ if (newValue) {
142
+ popover.control(placement.value, props.offset)
143
+ // if (queue && queue.closeOther) {
144
+ // queue.closeOther(proxy)
145
+ // }
146
+ queue.closeOther(proxy)
147
+ }
148
+ popover.showStyle.value = newValue ? 'display: inline-block;' : 'display: none;'
149
+ emit('change', { show: newValue })
150
+ emit(`${newValue ? 'open' : 'close'}`)
151
+ },
152
+ )
153
+
154
+ onMounted(() => {
155
+ popover.init(placement.value, true, selector)
156
+ })
157
+
158
+ onBeforeMount(() => {
159
+ queue.pushToQueue(proxy)
160
+ popover.showStyle.value = showPopover.value ? 'opacity: 1;' : 'opacity: 0;'
161
+ })
162
+
163
+ onBeforeUnmount(() => {
164
+ queue.removeFromQueue(proxy)
165
+ })
166
+
167
+ const menuClick = (index: number) => {
168
+ updateModelValue(false)
169
+ emit('menuClick', {
170
+ item: (props.content as Array<Record<string, any>>)[index],
171
+ index,
172
+ })
173
+ }
174
+
175
+ const toggle = () => {
176
+ if (props.disabled) return
177
+ updateModelValue(!showPopover.value)
178
+ }
179
+
180
+ const open = () => {
181
+ updateModelValue(true)
182
+ }
183
+
184
+ const close = () => {
185
+ updateModelValue(false)
186
+ }
187
+
188
+ function updateModelValue(value: boolean) {
189
+ showPopover.value = value
190
+ emit('update:modelValue', value)
191
+ }
192
+
193
+ defineExpose<PopoverExpose>({
194
+ open,
195
+ close,
196
+ })
197
+ </script>
198
+ <style lang="scss" scoped>
199
+ @import './index.scss';
200
+ </style>