@ecolovo/uniapp-components 2.0.1 → 2.0.3

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 (91) hide show
  1. package/components/aspect/aspect.vue +4 -2
  2. package/components/badge/badge.scss +3 -1
  3. package/components/badge/badge.vue +15 -11
  4. package/components/button/button.vue +100 -27
  5. package/components/checkbox/checkbox.scss +1 -1
  6. package/components/checkbox/checkbox.vue +54 -23
  7. package/components/checkbox-group/checkbox-group.vue +11 -4
  8. package/components/checkbox-group2/checkbox-group2.vue +23 -8
  9. package/components/checkbox-group2/checkbox2.vue +11 -4
  10. package/components/data-list/data-list.vue +25 -5
  11. package/components/date-picker/date-picker-view.vue +45 -16
  12. package/components/date-picker/date-picker.vue +58 -18
  13. package/components/dialog/dialog-content.vue +39 -12
  14. package/components/dialog/dialog.vue +30 -19
  15. package/components/dropdown/dropdown.vue +29 -6
  16. package/components/empty/empty.vue +10 -3
  17. package/components/flex/flex.vue +16 -6
  18. package/components/form-item/form-item.vue +13 -4
  19. package/components/icon/icon.scss +9 -0
  20. package/components/icon/icon.vue +46 -8
  21. package/components/image/image.vue +13 -8
  22. package/components/index.d.ts +50 -0
  23. package/components/index.js +50 -0
  24. package/components/index.ts +50 -0
  25. package/components/input/input.vue +13 -3
  26. package/components/input/password-input.vue +2 -2
  27. package/components/list-page/list-page.vue +24 -6
  28. package/components/load-more/load-more.vue +7 -2
  29. package/components/loading/animations/loading-animation3.vue +10 -5
  30. package/components/loading/animations/loading-animation4.vue +65 -8
  31. package/components/loading/loading.vue +7 -6
  32. package/components/message-box/message-box.d.ts +18 -0
  33. package/components/message-box/message-box.js +1 -0
  34. package/components/message-box/message-box.ts +18 -0
  35. package/components/message-box/message-box.vue +53 -21
  36. package/components/number-dialog/number-dialog.vue +61 -21
  37. package/components/number-input/number-input.vue +53 -18
  38. package/components/numpad/numpad.vue +11 -5
  39. package/components/page/page-body.scss +1 -1
  40. package/components/page/page-body.vue +79 -11
  41. package/components/page/page-footer.vue +11 -5
  42. package/components/page/page-header.vue +49 -24
  43. package/components/page/page.scss +2 -1
  44. package/components/page/page.vue +74 -29
  45. package/components/picker/picker-popup.vue +96 -68
  46. package/components/picker/picker.vue +11 -5
  47. package/components/popover/popover-content.vue +59 -19
  48. package/components/popover/popover-mask.vue +18 -11
  49. package/components/popover/popover.vue +13 -3
  50. package/components/popup/popup-content.vue +35 -11
  51. package/components/popup/popup.vue +36 -17
  52. package/components/price/price.scss +1 -0
  53. package/components/price/price.vue +18 -7
  54. package/components/search/search.vue +24 -10
  55. package/components/searching/searching.scss +14 -0
  56. package/components/searching/searching.vue +17 -10
  57. package/components/selector/selector.vue +10 -3
  58. package/components/switch/switch.vue +31 -10
  59. package/components/tab/tab.vue +41 -8
  60. package/components/textarea/textarea.vue +55 -13
  61. package/composable/component-name.js +2 -1
  62. package/composable/component-name.ts +2 -1
  63. package/composable/message-box.d.ts +35 -0
  64. package/composable/message-box.js +56 -0
  65. package/composable/message-box.ts +98 -0
  66. package/configs/index.d.ts +8 -1
  67. package/configs/index.js +14 -3
  68. package/configs/index.ts +8 -1
  69. package/easyCom.js +10 -5
  70. package/easyCom.ts +10 -5
  71. package/globals.d.ts +36 -0
  72. package/index.d.ts +5 -0
  73. package/index.js +5 -0
  74. package/index.ts +5 -0
  75. package/package.json +14 -6
  76. package/styles/global.scss +123 -2
  77. package/styles/reset.scss +5 -0
  78. package/styles/utils/css-var.scss +11 -11
  79. package/styles/utils/index.scss +0 -1
  80. package/styles/var/component.scss +23 -20
  81. package/styles/var/theme.scss +3 -3
  82. package/utils/date.d.ts +7 -2
  83. package/utils/date.js +31 -10
  84. package/utils/date.ts +20 -6
  85. package/utils/price.d.ts +4 -1
  86. package/utils/price.js +12 -7
  87. package/utils/price.ts +8 -3
  88. package/utils/round.js +4 -1
  89. package/utils/round.ts +4 -1
  90. package/utils/windowInfo.d.ts +0 -1
  91. package/styles/utils/z-index.scss +0 -10
@@ -17,7 +17,10 @@
17
17
  <!-- header 插槽 -->
18
18
  <slot name="header"></slot>
19
19
 
20
- <scroll-view :class="$style['PopoverContent--body-scroll']" scroll-y="true">
20
+ <scroll-view
21
+ :class="$style['PopoverContent--body-scroll']"
22
+ scroll-y="true"
23
+ >
21
24
  <view :class="$style['PopoverContent--body']">
22
25
  <!-- 默认插槽 -->
23
26
  <slot></slot>
@@ -39,7 +42,10 @@
39
42
  <script lang="ts" setup>
40
43
  import { ref, computed, nextTick, onMounted } from 'vue';
41
44
  import useClassNames from '../../composable/component-name';
42
- import { navBarBottomOffset, safeAreaInsetBottom } from '../../utils/windowInfo';
45
+ import {
46
+ navBarBottomOffset,
47
+ safeAreaInsetBottom,
48
+ } from '../../utils/windowInfo';
43
49
  import IconCpn from '../icon/icon.vue';
44
50
 
45
51
  defineOptions({
@@ -75,13 +81,16 @@ const initialized = ref(false);
75
81
 
76
82
  /** 计算后的位置值 */
77
83
  const usingPosition = computed(() => {
78
- return ['top', 'bottom', 'left', 'right', 'center'].includes(props.position) ? props.position : 'center';
84
+ return ['top', 'bottom', 'left', 'right', 'center'].includes(props.position)
85
+ ? props.position
86
+ : 'center';
79
87
  });
80
88
 
81
89
  const inlineCssVar = computed(() => {
82
- return [`--page-header-bottom: ${navBarBottomOffset}px;`, `--safe-area-bottom: ${safeAreaInsetBottom}px;`].join(
83
- ' '
84
- );
90
+ return [
91
+ `--page-header-bottom: ${navBarBottomOffset}px;`,
92
+ `--safe-area-bottom: ${safeAreaInsetBottom}px;`,
93
+ ].join(' ');
85
94
  });
86
95
 
87
96
  onMounted(() => {
@@ -97,7 +106,11 @@ onMounted(() => {
97
106
 
98
107
  // 定义外部变量
99
108
  %external-vars {
100
- @include UTILS__DEFINE_COMPONENT_VARS($popover, 'popover');
109
+ @include UTILS__DEFINE_COMPONENT_VARS('popover', $popover);
110
+ }
111
+
112
+ :host {
113
+ display: block;
101
114
  }
102
115
 
103
116
  .PopoverContent {
@@ -114,7 +127,9 @@ onMounted(() => {
114
127
  min-height: UTILS__LOCAL_VAR(min-height);
115
128
  max-height: UTILS__LOCAL_VAR(max-height);
116
129
  transform: translate(0, -100%) scale(1);
117
- --content-radius: 0 0 #{UTILS__LOCAL_VAR(radius)} #{UTILS__LOCAL_VAR(radius)};
130
+ --content-radius: 0 0 #{UTILS__LOCAL_VAR(radius)} #{UTILS__LOCAL_VAR(
131
+ radius
132
+ )};
118
133
  --scroll-max-height: #{UTILS__LOCAL_VAR(max-height)};
119
134
  }
120
135
  &.PopoverContent--at-bottom {
@@ -124,7 +139,9 @@ onMounted(() => {
124
139
  min-height: UTILS__LOCAL_VAR(min-height);
125
140
  max-height: UTILS__LOCAL_VAR(max-height);
126
141
  transform: translate(0, 100%) scale(1);
127
- --content-radius: #{UTILS__LOCAL_VAR(radius)} #{UTILS__LOCAL_VAR(radius)} 0 0;
142
+ --content-radius: #{UTILS__LOCAL_VAR(radius)} #{UTILS__LOCAL_VAR(
143
+ radius
144
+ )} 0 0;
128
145
  --scroll-max-height: #{UTILS__LOCAL_VAR(max-height)};
129
146
  }
130
147
  &.PopoverContent--at-left {
@@ -133,7 +150,9 @@ onMounted(() => {
133
150
  width: UTILS__LOCAL_VAR(width);
134
151
  height: 100%;
135
152
  transform: translate(-100%, 0) scale(1);
136
- --content-radius: 0 #{UTILS__LOCAL_VAR(radius)} #{UTILS__LOCAL_VAR(radius)} 0;
153
+ --content-radius: 0 #{UTILS__LOCAL_VAR(radius)} #{UTILS__LOCAL_VAR(
154
+ radius
155
+ )} 0;
137
156
  --scroll-max-height: 100vh;
138
157
  }
139
158
  &.PopoverContent--at-right {
@@ -142,7 +161,9 @@ onMounted(() => {
142
161
  width: UTILS__LOCAL_VAR(width);
143
162
  height: 100%;
144
163
  transform: translate(100%, 0) scale(1);
145
- --content-radius: #{UTILS__LOCAL_VAR(radius)} 0 0 #{UTILS__LOCAL_VAR(radius)};
164
+ --content-radius: #{UTILS__LOCAL_VAR(radius)} 0 0 #{UTILS__LOCAL_VAR(
165
+ radius
166
+ )};
146
167
  --scroll-max-height: 100vh;
147
168
  }
148
169
  &.PopoverContent--at-center {
@@ -151,10 +172,17 @@ onMounted(() => {
151
172
  min-height: UTILS__LOCAL_VAR(min-height);
152
173
  max-height: UTILS__LOCAL_VAR(max-height);
153
174
  opacity: 0;
175
+ // 出现时 scale 从 0.8 变为 1
154
176
  transform: translate(-50%, -50%) scale(0.8);
155
177
  --appear-transform: translate(-50%, -50%) scale(1);
156
178
  --content-radius: #{UTILS__LOCAL_VAR(radius)};
157
179
  --scroll-max-height: #{UTILS__LOCAL_VAR(max-height)};
180
+ :global(.PopoverMask--animated:not(.PopoverMask--visible)) & {
181
+ // 防止在关闭动画中用户点击
182
+ pointer-events: none;
183
+ // 消失时 scale 从 1 变为 0
184
+ transform: translate(-50%, -50%) scale(0);
185
+ }
158
186
  }
159
187
  &.PopoverContent--fullscreen {
160
188
  width: 100vw;
@@ -167,10 +195,11 @@ onMounted(() => {
167
195
  // 内容部分显示动画
168
196
  &.PopoverContent--content-initialized {
169
197
  transition: transform 0.3s, opacity 0.3s;
170
- }
171
- :global(.PopoverMask--visible) &.PopoverContent--content-initialized {
172
- opacity: 1;
173
- transform: var(--appear-transform);
198
+
199
+ :global(.PopoverMask--visible) & {
200
+ opacity: 1;
201
+ transform: var(--appear-transform);
202
+ }
174
203
  }
175
204
 
176
205
  .PopoverContent--content {
@@ -221,10 +250,21 @@ onMounted(() => {
221
250
 
222
251
  // scroll-view
223
252
  .PopoverContent--body-scroll {
224
- $header-padding: calc(var(--safe-top-padding, 0px) + #{UTILS__LOCAL_VAR(header-height)});
225
- $footer-padding: calc(var(--safe-bottom-padding, 0px) + #{UTILS__LOCAL_VAR(footer-height)});
226
- min-height: max(calc(#{UTILS__LOCAL_VAR(min-height)} - #{$header-padding} - #{$footer-padding}), 0px);
227
- max-height: calc(var(--scroll-max-height) - #{$header-padding} - #{$footer-padding});
253
+ $header-padding: calc(
254
+ var(--safe-top-padding, 0px) + #{UTILS__LOCAL_VAR(header-height)}
255
+ );
256
+ $footer-padding: calc(
257
+ var(--safe-bottom-padding, 0px) + #{UTILS__LOCAL_VAR(footer-height)}
258
+ );
259
+ min-height: max(
260
+ calc(
261
+ #{UTILS__LOCAL_VAR(min-height)} - #{$header-padding} - #{$footer-padding}
262
+ ),
263
+ 0px
264
+ );
265
+ max-height: calc(
266
+ var(--scroll-max-height) - #{$header-padding} - #{$footer-padding}
267
+ );
228
268
  }
229
269
 
230
270
  .PopoverContent--body {
@@ -3,14 +3,18 @@
3
3
  :class="[
4
4
  ...classNames,
5
5
  $style['PopoverMask'],
6
- { [$style['PopoverMask--visible']]: isVisible, 'PopoverMask--visible': isVisible },
6
+ {
7
+ [$style['PopoverMask--visible']]: isVisible,
8
+ 'PopoverMask--visible': isVisible,
9
+ },
10
+ {
11
+ [$style['PopoverMask--animated']]: isInitialized,
12
+ 'PopoverMask--animated': isInitialized,
13
+ },
7
14
  ]"
8
15
  @touchmove.stop.prevent
9
16
  >
10
- <view
11
- :class="[$style['PopoverMask--mask'], { [$style['PopoverMask--animated']]: isInitialized }]"
12
- @click="onMask()"
13
- ></view>
17
+ <view :class="[$style['PopoverMask--mask']]" @click="onMask()"></view>
14
18
 
15
19
  <slot></slot>
16
20
  </view>
@@ -86,14 +90,18 @@ defineExpose({ close });
86
90
 
87
91
  // 定义外部变量
88
92
  %external-vars {
89
- @include UTILS__DEFINE_COMPONENT_VARS($popover, 'popover');
93
+ @include UTILS__DEFINE_COMPONENT_VARS('popover', $popover);
94
+ }
95
+
96
+ :host {
97
+ display: block;
90
98
  }
91
99
 
92
100
  .PopoverMask {
93
101
  @extend %external-vars;
94
102
  position: fixed;
95
103
  inset: 0;
96
- z-index: UTILS__z-index('popover');
104
+ z-index: UTILS__GLOBAL_VAR(z-index, popover);
97
105
 
98
106
  // 遮罩层
99
107
  .PopoverMask--mask {
@@ -101,13 +109,12 @@ defineExpose({ close });
101
109
  inset: 0;
102
110
  background-color: UTILS__LOCAL_VAR(mask-color);
103
111
  opacity: 0;
104
- &.PopoverMask--animated {
105
- transition: opacity 0.3s;
106
- }
107
112
  }
108
113
  &.PopoverMask--visible .PopoverMask--mask {
109
- transition: opacity 0.3s;
110
114
  opacity: 1;
111
115
  }
116
+ &.PopoverMask--animated .PopoverMask--mask {
117
+ transition: opacity 0.3s;
118
+ }
112
119
  }
113
120
  </style>
@@ -9,12 +9,22 @@
9
9
  @close="$emit('close')"
10
10
  @closed="$emit('closed')"
11
11
  >
12
- <popover-content-cpn v-if="$slots.custom" :position="position" :fullscreen="fullscreen" :loading="loading">
12
+ <popover-content-cpn
13
+ v-if="$slots.custom"
14
+ :position="position"
15
+ :fullscreen="fullscreen"
16
+ :loading="loading"
17
+ >
13
18
  <template #custom>
14
19
  <slot name="custom"></slot>
15
20
  </template>
16
21
  </popover-content-cpn>
17
- <popover-content-cpn v-else :position="position" :fullscreen="fullscreen" :loading="loading">
22
+ <popover-content-cpn
23
+ v-else
24
+ :position="position"
25
+ :fullscreen="fullscreen"
26
+ :loading="loading"
27
+ >
18
28
  <template v-if="$slots.header" #header>
19
29
  <slot name="header"></slot>
20
30
  </template>
@@ -82,5 +92,5 @@ defineExpose({ close });
82
92
  </script>
83
93
 
84
94
  <style lang="scss" module>
85
- @use '../../styles/index' as *;
95
+ @use '../../styles/utils' as *;
86
96
  </style>
@@ -4,18 +4,28 @@
4
4
  <!-- 内容上方标题 -->
5
5
  <template #header>
6
6
  <slot v-if="$slots.header" name="header"></slot>
7
- <view v-else-if="title || showClose" :class="$style['PopupContent--header']">
7
+ <view
8
+ v-else-if="title || showClose"
9
+ :class="$style['PopupContent--header']"
10
+ >
8
11
  <view
9
12
  :class="[
10
13
  $style['PopupContent--title'],
11
- { [$style['PopupContent--title-center']]: centerTitle },
14
+ {
15
+ [$style['PopupContent--title-center']]:
16
+ centerTitle,
17
+ },
12
18
  ]"
13
19
  >
14
20
  <slot name="title">
15
21
  <text>{{ title }}</text>
16
22
  </slot>
17
23
  </view>
18
- <view v-if="showClose" :class="$style['PopupContent--close']" @click="$emit('close')">
24
+ <view
25
+ v-if="showClose"
26
+ :class="$style['PopupContent--close']"
27
+ @click="$emit('close')"
28
+ >
19
29
  <icon-cpn icon="close" tap-size="80rpx" />
20
30
  </view>
21
31
  </view>
@@ -27,7 +37,10 @@
27
37
  <!-- 内容下方操作按钮 -->
28
38
  <template #footer>
29
39
  <slot v-if="$slots.footer" name="footer"></slot>
30
- <view v-else-if="cancel || confirm" :class="$style['PopupContent--footer']">
40
+ <view
41
+ v-else-if="cancel || confirm"
42
+ :class="$style['PopupContent--footer']"
43
+ >
31
44
  <view v-if="cancel" :class="$style['PopupContent--button']">
32
45
  <slot name="cancel">
33
46
  <button-cpn plain @click="$emit('cancel')">
@@ -35,7 +48,10 @@
35
48
  </button-cpn>
36
49
  </slot>
37
50
  </view>
38
- <view v-if="confirm" :class="$style['PopupContent--button']">
51
+ <view
52
+ v-if="confirm"
53
+ :class="$style['PopupContent--button']"
54
+ >
39
55
  <slot name="confirm">
40
56
  <button-cpn @click="$emit('confirm')">
41
57
  {{ confirm }}
@@ -100,14 +116,22 @@ defineEmits<{
100
116
 
101
117
  // 定义外部变量
102
118
  %external-vars {
103
- @include UTILS__DEFINE_COMPONENT_VARS($popup, 'popup');
119
+ @include UTILS__DEFINE_COMPONENT_VARS('popup', $popup);
120
+ }
121
+
122
+ :host {
123
+ display: block;
104
124
  }
105
125
 
106
126
  .PopupContent {
107
127
  @extend %external-vars;
108
- #{UTILS__VAR_NAME(header-height, popover)}: #{UTILS__LOCAL_VAR(header-height)};
109
- #{UTILS__VAR_NAME(footer-height, popover)}: #{UTILS__LOCAL_VAR(footer-height)};
110
- #{UTILS__VAR_NAME(padding, popover)}: 20rpx 30rpx;
128
+ #{UTILS__VAR_NAME(popover, header-height )}: #{UTILS__LOCAL_VAR(
129
+ header-height
130
+ )};
131
+ #{UTILS__VAR_NAME(popover, footer-height )}: #{UTILS__LOCAL_VAR(
132
+ footer-height
133
+ )};
134
+ #{UTILS__VAR_NAME(popover, padding )}: 20rpx 30rpx;
111
135
 
112
136
  .PopupContent--header {
113
137
  position: relative;
@@ -148,8 +172,8 @@ defineEmits<{
148
172
  }
149
173
  .PopupContent--button {
150
174
  flex: 1;
151
- #{UTILS__VAR_NAME(height, button)}: 84rpx;
152
- #{UTILS__VAR_NAME(border-radius, button)}: 20rpx;
175
+ #{UTILS__VAR_NAME(button, height)}: 84rpx;
176
+ #{UTILS__VAR_NAME(button, border-radius)}: 20rpx;
153
177
  & + #{UTILS__LAST_SELECTOR(&)} {
154
178
  margin-left: 20rpx;
155
179
  }
@@ -17,8 +17,8 @@
17
17
  :cancel="cancel"
18
18
  :confirm="confirm"
19
19
  @close="onClose()"
20
- @cancel="onButton('cancel', closeOnCancel)"
21
- @confirm="onButton('confirm', closeOnConfirm)"
20
+ @cancel="onCancel()"
21
+ @confirm="onConfirm()"
22
22
  >
23
23
  <slot></slot>
24
24
  </popup-content-cpn>
@@ -86,7 +86,10 @@ const emit = defineEmits<{
86
86
  (e: 'close'): void;
87
87
  (e: 'closed'): void;
88
88
  (e: 'cancel', closeFn?: VoidFunction): void;
89
- (e: 'confirm', payload?: Omit<PromiseWithResolvers<unknown>, 'promise'> | VoidFunction): void;
89
+ (
90
+ e: 'confirm',
91
+ payload?: UniApp.PromiseResolvers<unknown> | VoidFunction
92
+ ): void;
90
93
  }>();
91
94
 
92
95
  const isAsyncLoading = ref(false);
@@ -105,16 +108,34 @@ const onClose = () => {
105
108
  close();
106
109
  };
107
110
 
108
- /** 点击取消或确认按钮
109
- * @param {'cancel' | 'confirm'} btnType 按钮类型
110
- * @param {boolean} shouldClose 是否自动关闭对话框
111
- */
112
- const onButton = (btnType: 'cancel' | 'confirm', shouldClose: boolean) => {
111
+ /** 点击取消按钮响应 */
112
+ const onCancel = () => {
113
113
  if (isLoading.value) return;
114
114
 
115
- if (btnType === 'confirm' && props.async) {
115
+ if (props.closeOnCancel) {
116
+ emit('cancel');
117
+ close();
118
+ return;
119
+ }
120
+
121
+ emit('cancel', maskRef.value?.close.bind(maskRef.value));
122
+ };
123
+
124
+ /** 点击确认按钮响应 */
125
+ const onConfirm = () => {
126
+ if (isLoading.value) return;
127
+
128
+ if (props.async) {
116
129
  isAsyncLoading.value = true;
117
- const { promise, resolve, reject } = Promise.withResolvers();
130
+
131
+ // const { promise, resolve, reject } = Promise.withResolvers();
132
+ let resolve: UniApp.PromiseResolver<unknown>,
133
+ reject: UniApp.PromiseRejector<unknown>;
134
+ const promise = new Promise((res, rej) => {
135
+ resolve = res;
136
+ reject = rej;
137
+ });
138
+
118
139
  promise
119
140
  .then((willClose = true) => {
120
141
  if (willClose === false) {
@@ -130,24 +151,22 @@ const onButton = (btnType: 'cancel' | 'confirm', shouldClose: boolean) => {
130
151
  }
131
152
  isAsyncLoading.value = false;
132
153
  });
133
- emit(btnType, { resolve, reject });
154
+ emit('confirm', { resolve, reject });
134
155
  return;
135
156
  }
136
157
 
137
- if (shouldClose) {
138
- // @ts-expect-error 这里语法是正确的
139
- emit(btnType);
158
+ if (props.closeOnConfirm) {
159
+ emit('confirm');
140
160
  close();
141
161
  return;
142
162
  }
143
163
 
144
- // @ts-expect-error 这里语法是正确的
145
- emit(btnType, maskRef.value?.close.bind(maskRef.value));
164
+ emit('confirm', maskRef.value?.close.bind(maskRef.value));
146
165
  };
147
166
 
148
167
  defineExpose({ close });
149
168
  </script>
150
169
 
151
170
  <style lang="scss" module>
152
- @use '../../styles/index' as *;
171
+ @use '../../styles/utils' as *;
153
172
  </style>
@@ -13,6 +13,7 @@ $price-default: (
13
13
  decimal-color: UTILS__LOCAL_VAR(color),
14
14
  decimal-font-size: UTILS__LOCAL_VAR(font-size),
15
15
  decimal-font-weight: UTILS__LOCAL_VAR(font-weight),
16
+ unit-spacing: 0,
16
17
  unit-color: UTILS__LOCAL_VAR(color),
17
18
  unit-font-size: UTILS__LOCAL_VAR(font-size),
18
19
  unit-font-weight: UTILS__LOCAL_VAR(font-weight),
@@ -6,12 +6,20 @@
6
6
  <text :class="$style['Price--default-prefix-unit']">¥</text>
7
7
  </slot>
8
8
  </text>
9
- <text v-if="showSymbol || formattedPrice.negative" :class="$style['Price--integer']">
9
+ <text
10
+ v-if="showSymbol || formattedPrice.negative"
11
+ :class="$style['Price--integer']"
12
+ >
10
13
  {{ formattedPrice.negative ? '-' : '+' }}
11
14
  </text>
12
- <text :class="$style['Price--integer']"> {{ formattedPrice.integer }} </text>
13
- <text v-if="alwaysShowDecimal || formattedPrice.decimal !== '00'" :class="$style['Price--decimal']">
14
- .{{ formattedPrice.decimal }}
15
+ <text :class="$style['Price--integer']">
16
+ {{ formattedPrice.integer }}
17
+ </text>
18
+ <text
19
+ v-if="alwaysShowDecimal || formattedPrice.decimal !== '.00'"
20
+ :class="$style['Price--decimal']"
21
+ >
22
+ {{ formattedPrice.decimal }}
15
23
  </text>
16
24
  <text v-if="!prefixUnit" :class="$style['Price--unit']">
17
25
  <!-- 默认插槽用于放置单位 -->
@@ -62,7 +70,11 @@ const formattedPrice = computed(() => formatPrice(props.value));
62
70
 
63
71
  // 定义外部变量
64
72
  %external-vars {
65
- @include UTILS__DEFINE_COMPONENT_VARS($price, 'price');
73
+ @include UTILS__DEFINE_COMPONENT_VARS('price', $price);
74
+ }
75
+
76
+ :host {
77
+ display: inline;
66
78
  }
67
79
 
68
80
  .Price {
@@ -72,8 +84,7 @@ const formattedPrice = computed(() => formatPrice(props.value));
72
84
  font-weight: UTILS__LOCAL_VAR(font-weight);
73
85
  }
74
86
  .Price--default-prefix-unit {
75
- margin-left: 0.25em;
76
- margin-right: 0.25em;
87
+ margin-right: UTILS__LOCAL_VAR(unit-spacing);
77
88
  }
78
89
  .Price--integer {
79
90
  color: UTILS__LOCAL_VAR(integer-color);
@@ -1,7 +1,11 @@
1
1
  <template>
2
2
  <view :class="[...classNames, $style['Search']]">
3
3
  <view :class="$style['Search--wrapper']">
4
- <icon-cpn icon="search" :class="[$style['Search--icon'], $style['Search--prefix-icon']]"> </icon-cpn>
4
+ <icon-cpn
5
+ icon="search"
6
+ :class="[$style['Search--icon'], $style['Search--prefix-icon']]"
7
+ >
8
+ </icon-cpn>
5
9
  <view
6
10
  v-if="readonly"
7
11
  :class="[
@@ -27,7 +31,7 @@
27
31
  v-if="clearable && searchValue"
28
32
  icon="close-circle-filled"
29
33
  :class="[$style['Search--icon'], $style['Search--close-icon']]"
30
- @click="onClear"
34
+ @tap.stop="onClear"
31
35
  >
32
36
  </icon-cpn>
33
37
  </view>
@@ -45,7 +49,7 @@
45
49
 
46
50
  <script lang="ts" setup>
47
51
  import { computed, ref } from 'vue';
48
- import debounceFn from 'lodash-es/debounce';
52
+ import { debounce as debounceFn } from 'lodash-es';
49
53
  import useClassNames from '../../composable/component-name';
50
54
  import ButtonCpn from '../button/button.vue';
51
55
  import IconCpn from '../icon/icon.vue';
@@ -70,16 +74,16 @@ type _Props = {
70
74
  debounce?: number;
71
75
  /** 是否有清空按钮 */
72
76
  clearable?: boolean;
73
- /** 是否只读 */
77
+ /** 是否禁用 */
74
78
  disabled?: boolean;
75
79
  /** 是否只读 */
76
80
  readonly?: boolean;
77
- /** 是否显示搜索按钮 */
81
+ /** 是否显示取消按钮 */
78
82
  cancelButton?: boolean;
79
83
  };
80
84
 
81
85
  const props = withDefaults(defineProps<_Props>(), {
82
- modelValue: '',
86
+ modelValue: undefined,
83
87
  maxlength: 140,
84
88
  placeholder: '请输入搜索内容',
85
89
  debounce: 300,
@@ -103,7 +107,10 @@ const innerSearchValue = ref('');
103
107
 
104
108
  /** 当前搜索值 */
105
109
  const searchValue = computed({
106
- get: () => (props.modelValue === undefined ? innerSearchValue.value : props.modelValue),
110
+ get: () =>
111
+ props.modelValue === undefined
112
+ ? innerSearchValue.value
113
+ : props.modelValue,
107
114
  set: (value) => {
108
115
  emit('update:modelValue', value);
109
116
  innerSearchValue.value = value;
@@ -146,7 +153,14 @@ const onCancel = () => {
146
153
 
147
154
  // 定义外部变量
148
155
  %external-vars {
149
- @include UTILS__DEFINE_COMPONENT_VARS($search, 'search');
156
+ @include UTILS__DEFINE_COMPONENT_VARS('search', $search);
157
+ }
158
+
159
+ :host {
160
+ display: block;
161
+ }
162
+ :host(.display-inline) {
163
+ display: inline;
150
164
  }
151
165
 
152
166
  .Search {
@@ -190,7 +204,7 @@ const onCancel = () => {
190
204
  flex: none;
191
205
  font-size: UTILS__GLOBAL_VAR(font-size, normal);
192
206
  height: 100%;
193
- #{UTILS__VAR_NAME(color, button)}: #999;
194
- #{UTILS__VAR_NAME(padding, button)}: 0 0 0 24rpx;
207
+ #{UTILS__VAR_NAME(button, color)}: #999;
208
+ #{UTILS__VAR_NAME(button, padding)}: 0 0 0 24rpx;
195
209
  }
196
210
  </style>
@@ -0,0 +1,14 @@
1
+ @use 'sass:map';
2
+ @use '../../styles/utils' as *;
3
+
4
+ // 可配置的变量
5
+ $search: () !default;
6
+ $search-default: (
7
+ $image-size: 300rpx,
8
+ $image-width: var(--image-size),
9
+ $image-height: var(--image-size),
10
+ $space: 20rpx,
11
+ $color: #999999,
12
+ $font-size: UTILS__GLOBAL_VAR(font-size, normal),
13
+ );
14
+ $search: map.merge($search-default, $search);
@@ -37,9 +37,16 @@ withDefaults(defineProps<_Props>(), {
37
37
  </script>
38
38
 
39
39
  <style lang="scss" module>
40
- @use '../../styles/index' as *;
40
+ @use '../../styles/utils' as *;
41
+ @use './searching' as *;
42
+
43
+ // 定义外部变量
44
+ %external-vars {
45
+ @include UTILS__DEFINE_COMPONENT_VARS('searching', $searching);
46
+ }
41
47
 
42
48
  .Searching {
49
+ @extend %external-vars;
43
50
  display: flex;
44
51
  flex-direction: column;
45
52
  justify-content: center;
@@ -47,28 +54,28 @@ withDefaults(defineProps<_Props>(), {
47
54
  }
48
55
  .Searching--image {
49
56
  position: relative;
50
- width: 300rpx;
51
- height: 300rpx;
57
+ width: var(--image-width);
58
+ height: var(--image-height);
52
59
  }
53
60
  .Searching--search-icon-animation {
54
61
  width: 100rpx;
55
62
  height: 100rpx;
56
63
  transform-origin: center center;
57
- animation: circle 1.5s infinite linear;
64
+ animation: Searching--circle 1.5s infinite linear;
58
65
  }
59
66
  .Searching--search-icon {
60
67
  position: absolute;
61
68
  font-size: 60rpx;
62
- color: #999;
63
- animation: circle 1.5s linear infinite reverse;
69
+ color: var(--color);
70
+ animation: Searching--circle 1.5s linear infinite reverse;
64
71
  }
65
72
  .Searching--text {
66
- margin-top: 20rpx;
67
- color: #999;
68
- font-size: 28rpx;
73
+ margin-top: var(--space);
74
+ color: var(--color);
75
+ font-size: var(--font-size);
69
76
  }
70
77
 
71
- @keyframes circle {
78
+ @keyframes Searching--circle {
72
79
  0% {
73
80
  transform: rotate(0deg);
74
81
  }
@@ -3,10 +3,17 @@
3
3
  <text v-if="isReadonly || modelValue" :class="$style['Selector--text']">
4
4
  <slot>{{ modelValue || '' }}</slot>
5
5
  </text>
6
- <text v-else :class="[$style['Selector--text'], $style['Selector--placeholder']]">
6
+ <text
7
+ v-else
8
+ :class="[$style['Selector--text'], $style['Selector--placeholder']]"
9
+ >
7
10
  {{ placeholder }}
8
11
  </text>
9
- <icon-cpn v-if="!isReadonly" icon="picker-arrow" :class="$style['Selector--icon']"></icon-cpn>
12
+ <icon-cpn
13
+ v-if="!isReadonly"
14
+ icon="picker-arrow"
15
+ :class="$style['Selector--icon']"
16
+ ></icon-cpn>
10
17
  </view>
11
18
  </template>
12
19
 
@@ -60,7 +67,7 @@ const onClick = () => {
60
67
  </script>
61
68
 
62
69
  <style lang="scss" module>
63
- @use '../../styles/index' as *;
70
+ @use '../../styles/utils' as *;
64
71
 
65
72
  .Selector {
66
73
  width: 100%;