@didaoktv/didaoui-uniapp 1.3.5 → 1.3.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.
@@ -26,48 +26,66 @@
26
26
  </view>
27
27
  </view>
28
28
 
29
- <!-- 键盘弹层:0 位省份键盘,其余位字母数字键盘(按位锁键) -->
30
- <view
31
- v-if="active >= 0"
32
- class="dd-car-keyboard__panel"
33
- @touchmove.stop.prevent="noop"
29
+ <!-- 键盘弹层:与其他键盘模式一致,经 dd-popup 弹出(遮罩/动效/底部安全区),0 位省份键盘,其余位字母数字键盘(按位锁键) -->
30
+ <dd-popup
31
+ v-model="popupShow"
32
+ position="bottom"
33
+ :z-index="zIndexConfig.popup"
34
34
  >
35
- <view class="dd-car-keyboard__close" @tap="closeKeyboard">
36
- <text class="dd-car-keyboard__close-text">关闭</text>
37
- </view>
38
- <view
39
- v-for="(row, rowIndex) in keyRows"
40
- :key="rowIndex"
41
- class="dd-car-keyboard__row"
42
- >
43
- <view
44
- v-for="item in row"
45
- :key="item.label"
46
- class="dd-car-keyboard__key"
47
- :class="[item.locked && 'dd-car-keyboard__key--lock']"
48
- hover-class="dd-car-keyboard__key--hover"
49
- :hover-stay-time="100"
50
- @tap="onKeyTap(item)"
51
- >
52
- <text class="dd-car-keyboard__key-text">{{ item.label }}</text>
35
+ <view class="dd-car-keyboard__panel">
36
+ <view class="dd-car-keyboard__tooltip">
37
+ <view hover-class="dd-car-keyboard__hover" :hover-stay-time="100">
38
+ <text
39
+ class="dd-car-keyboard__tooltip-item dd-car-keyboard__tooltip-item--cancel"
40
+ @tap="closeKeyboard"
41
+ >取消</text>
42
+ </view>
43
+ <view>
44
+ <text class="dd-car-keyboard__tooltip-item dd-car-keyboard__tooltip-item--tips">车牌键盘</text>
45
+ </view>
46
+ <view hover-class="dd-car-keyboard__hover" :hover-stay-time="100">
47
+ <text
48
+ class="dd-car-keyboard__tooltip-item dd-car-keyboard__tooltip-item--submit"
49
+ @tap="closeKeyboard"
50
+ >完成</text>
51
+ </view>
53
52
  </view>
54
53
  <view
55
- v-if="rowIndex === 3"
56
- class="dd-car-keyboard__key dd-car-keyboard__key--del"
57
- hover-class="dd-car-keyboard__key--hover"
58
- :hover-stay-time="100"
59
- @tap="onBackspaceTap"
54
+ v-for="(row, rowIndex) in keyRows"
55
+ :key="rowIndex"
56
+ class="dd-car-keyboard__row"
60
57
  >
61
- <dd-icon size="22" name="backspace"></dd-icon>
58
+ <view
59
+ v-for="item in row"
60
+ :key="item.label"
61
+ class="dd-car-keyboard__key"
62
+ :class="[item.locked && 'dd-car-keyboard__key--lock']"
63
+ hover-class="dd-car-keyboard__key--hover"
64
+ :hover-stay-time="100"
65
+ @tap="onKeyTap(item)"
66
+ >
67
+ <text class="dd-car-keyboard__key-text">{{ item.label }}</text>
68
+ </view>
69
+ <view
70
+ v-if="rowIndex === 3"
71
+ class="dd-car-keyboard__key dd-car-keyboard__key--del"
72
+ hover-class="dd-car-keyboard__key--hover"
73
+ :hover-stay-time="100"
74
+ @tap="onBackspaceTap"
75
+ >
76
+ <dd-icon size="22" name="backspace"></dd-icon>
77
+ </view>
62
78
  </view>
63
79
  </view>
64
- </view>
80
+ </dd-popup>
65
81
  </view>
66
82
  </template>
67
83
 
68
84
  <script setup lang="ts">
69
85
  import { computed, ref, watch } from 'vue'
86
+ import zIndexConfig from '../../libs/config/zIndex.js'
70
87
  import DdIcon from '../dd-icon/dd-icon.vue'
88
+ import DdPopup from '../dd-popup/dd-popup.vue'
71
89
  import { MAX_LEN, getKeyRows, nextPos, type KeyItem } from './carPlate'
72
90
 
73
91
  /**
@@ -76,7 +94,7 @@ import { MAX_LEN, getKeyRows, nextPos, type KeyItem } from './carPlate'
76
94
  * @property {String} modelValue 车牌号(v-model)
77
95
  * @event {Function} update:modelValue 输入变化
78
96
  * @event {Function} focus 键盘弹出
79
- * @event {Function} blur 键盘收起
97
+ * @event {Function} blur 键盘收起(含遮罩/取消/完成触发)
80
98
  * @example <dd-car-keyboard v-model="plateNo" />
81
99
  */
82
100
 
@@ -120,7 +138,13 @@ watch(keyboardVisible, (visible) => {
120
138
  else emit('blur', props.modelValue)
121
139
  })
122
140
 
123
- function noop() {}
141
+ // dd-popup 关闭路径(遮罩/取消/完成)统一经 update:modelValue 收敛回 active
142
+ const popupShow = computed({
143
+ get: () => active.value >= 0,
144
+ set: (val: boolean) => {
145
+ if (!val) active.value = -1
146
+ }
147
+ })
124
148
 
125
149
  function onBoxTap(index: number) {
126
150
  active.value = index
@@ -219,25 +243,40 @@ $dd-car-keyboard-panel-padding: 0 var(--dd-space-2, #{$dd-space-2}) var(--dd-spa
219
243
  }
220
244
 
221
245
  &__panel {
222
- position: fixed;
223
- right: 0;
224
- bottom: 0;
225
- left: 0;
226
- z-index: 10075; // ponytail: 取 libs/config/zIndex.js popup 值,模板内不能用表达式故字面量
227
- background-color: var(--dd-bg-section, #{$dd-bg-section});
228
246
  padding: $dd-car-keyboard-panel-padding;
229
247
  }
230
248
 
231
- &__close {
249
+ // 工具条对齐 dd-keyboard:取消 / 提示 / 完成
250
+ &__tooltip {
232
251
  @include flex;
233
- justify-content: flex-end;
234
- padding: var(--dd-space-2, #{$dd-space-2}) 0;
252
+ justify-content: space-between;
253
+ background-color: var(--dd-bg-elevated, #{$dd-bg-elevated});
254
+ padding: 14px 12px;
255
+
256
+ &-item {
257
+ color: var(--dd-text-primary, #{$dd-text-primary});
258
+ flex: 1;
259
+ text-align: center;
260
+ font-size: 15px;
261
+
262
+ &--cancel {
263
+ text-align: left;
264
+ color: var(--dd-text-tertiary, #{$dd-text-tertiary});
265
+ }
266
+
267
+ &--tips {
268
+ color: var(--dd-text-tertiary, #{$dd-text-tertiary});
269
+ }
270
+
271
+ &--submit {
272
+ text-align: right;
273
+ color: var(--dd-primary-400, #{$dd-primary-400});
274
+ }
275
+ }
235
276
  }
236
277
 
237
- &__close-text {
238
- padding: 0 var(--dd-space-2, #{$dd-space-2});
239
- font-size: 13.5px;
240
- color: var(--dd-text-secondary, #{$dd-text-secondary});
278
+ &__hover {
279
+ opacity: 0.7;
241
280
  }
242
281
 
243
282
  &__row {
@@ -124,15 +124,20 @@ function handleClick(e: Event) {
124
124
  padding: 0 24rpx 0 $dd-space-4;
125
125
  background: var(--dd-bg-elevated, #{$dd-bg-elevated});
126
126
  font-size: $dd-font-size-body;
127
+ // vant 式恒定行高(24px),title/value/label/icon 全部基线对齐
128
+ line-height: $dd-line-height-lead;
127
129
  color: var(--dd-text-primary, #{$dd-text-primary});
128
130
  @include dd-hairline-bottom(var(--dd-border-subtle, #{$dd-border-subtle}));
129
131
 
132
+ // vant 式:高度 = 垂直 padding + 行高(12/16px × 2 + 23.8px ≈ 96/112rpx),内容天然居中
130
133
  &--normal {
131
- min-height: 96rpx;
134
+ padding-top: $dd-space-3;
135
+ padding-bottom: $dd-space-3;
132
136
  }
133
137
 
134
138
  &--large {
135
- min-height: 112rpx;
139
+ padding-top: $dd-space-4;
140
+ padding-bottom: $dd-space-4;
136
141
  }
137
142
 
138
143
  &--center {
@@ -154,7 +159,8 @@ function handleClick(e: Event) {
154
159
  margin-right: $dd-space-2;
155
160
  display: flex;
156
161
  align-items: center;
157
- height: 100%;
162
+ // ponytail: stretch 拉伸到兄弟 content 高度使图标居中于首行;title+label 多行时会居中于整块而非首行(vant 是贴首行),如需精确可改为固定行高盒
163
+ align-self: stretch;
158
164
  }
159
165
 
160
166
  &__icon-text {
@@ -167,7 +173,7 @@ function handleClick(e: Event) {
167
173
  color: var(--dd-error, #{$dd-error});
168
174
  font-size: $dd-font-size-body;
169
175
  margin-right: 4rpx;
170
- line-height: $dd-line-height-caption;
176
+ line-height: inherit;
171
177
  text {
172
178
  line-height: 1;
173
179
  }
@@ -179,7 +185,6 @@ function handleClick(e: Event) {
179
185
  display: flex;
180
186
  flex-direction: column;
181
187
  justify-content: center;
182
- padding: $dd-space-2 0;
183
188
  }
184
189
 
185
190
  &__title {
@@ -42,7 +42,6 @@ withDefaults(defineProps<Props>(), {
42
42
  &--inset {
43
43
  border-radius: $dd-radius-lg;
44
44
  overflow: hidden;
45
- margin: 0 24rpx;
46
45
  }
47
46
 
48
47
  &--border {
@@ -17,8 +17,9 @@
17
17
  <text class="dd-dialog__title">{{ title }}</text>
18
18
  </view>
19
19
  <view class="dd-dialog__body" :class="{ 'dd-dialog__body--isolated': !title }">
20
+ <!-- message 与 slot 共存(slot 在下):prompt 型弹窗需同时展示说明文案与输入内容 -->
20
21
  <text v-if="message" class="dd-dialog__message">{{ message }}</text>
21
- <slot v-else></slot>
22
+ <slot></slot>
22
23
  </view>
23
24
  <view v-if="showConfirmButton || showCancelButton" class="dd-dialog__footer" :class="`dd-dialog__footer--${theme}`">
24
25
  <template v-if="theme === 'round-button'">
@@ -83,6 +84,8 @@ interface Props {
83
84
  cancelColor?: string
84
85
  width?: string | number
85
86
  closeOnClickOverlay?: boolean
87
+ /** 异步关闭:确认/取消/遮罩只发事件不自动关窗,由调用方(如表单校验)自行控制 modelValue */
88
+ asyncClose?: boolean
86
89
  }
87
90
 
88
91
  const props = withDefaults(defineProps<Props>(), {
@@ -98,6 +101,7 @@ const props = withDefaults(defineProps<Props>(), {
98
101
  cancelColor: '',
99
102
  width: '640rpx',
100
103
  closeOnClickOverlay: false,
104
+ asyncClose: false,
101
105
  })
102
106
 
103
107
  const emit = defineEmits<{
@@ -133,17 +137,17 @@ function close() {
133
137
  function onOverlayClick() {
134
138
  if (!props.closeOnClickOverlay) return
135
139
  emit('cancel')
136
- close()
140
+ if (!props.asyncClose) close()
137
141
  }
138
142
 
139
143
  function onConfirm() {
140
144
  emit('confirm')
141
- close()
145
+ if (!props.asyncClose) close()
142
146
  }
143
147
 
144
148
  function onCancel() {
145
149
  emit('cancel')
146
- close()
150
+ if (!props.asyncClose) close()
147
151
  }
148
152
  </script>
149
153
 
@@ -237,6 +241,11 @@ function onCancel() {
237
241
  &--cancel {
238
242
  border-right: 1px solid var(--dd-border-subtle, #{$dd-border-subtle});
239
243
  }
244
+
245
+ /* 确认按钮文字默认主色;confirmColor 传入时走内联样式覆盖 */
246
+ &--confirm .dd-dialog__btn-text {
247
+ color: var(--dd-primary, #{$dd-primary});
248
+ }
240
249
  }
241
250
 
242
251
  &__btn-text {
@@ -88,11 +88,11 @@ function onAction() {
88
88
 
89
89
  &__icon {
90
90
  margin-bottom: $dd-space-4;
91
+ font-size: 120rpx;
92
+ line-height: 1;
91
93
  }
92
94
 
93
95
  &__emoji {
94
- font-size: 120rpx;
95
- line-height: 1;
96
96
  animation: dd-empty-float 3s ease-in-out infinite;
97
97
  }
98
98
 
@@ -10,6 +10,7 @@
10
10
  >
11
11
  <view
12
12
  class="dd-keyboard__button-wrapper__button"
13
+ :class="[btnBgGray(index) && 'dd-keyboard__button-wrapper__button--gray']"
13
14
  :style="[itemStyle(index)]"
14
15
  @tap="keyboardClick(item)"
15
16
  hover-class="dd-keyboard-hover"
@@ -25,8 +26,10 @@
25
26
  class="dd-keyboard__button-wrapper__button dd-keyboard__button-wrapper__button--gray"
26
27
  hover-class="dd-keyboard-hover"
27
28
  :hover-stay-time="200"
28
- @touchstart.stop="backspaceClick"
29
+ @touchstart.stop="backspaceTouchStart"
29
30
  @touchend="clearTimer"
31
+ @touchcancel="clearTimer"
32
+ @tap="backspaceTap"
30
33
  >
31
34
  <dd-icon
32
35
  name="backspace"
@@ -61,6 +64,7 @@
61
64
  backspace: 'backspace', // 退格键内容
62
65
  dot: '.', // 点
63
66
  timer: null, // 长按多次删除的事件监听
67
+ isTouch: false, // 本次退格是否来自触摸(防 tap 重复删除)
64
68
  cardX: 'X' // 身份证的X符号
65
69
  };
66
70
  },
@@ -88,15 +92,15 @@
88
92
  }
89
93
  }
90
94
  },
91
- // 按键的样式,在非乱序&&数字键盘&&不显示点按钮时,index为9时,按键占位两个空间
95
+ // 按键的样式,在非乱序&&数字键盘&&不显示点按钮时,index为9时,"0"键占位两个空间(flex 拉伸为 2 倍宽)
92
96
  itemStyle() {
93
97
  return index => {
94
98
  let style = {};
95
- if (this.mode == 'number' && this.dotDisabled && index == 9) style.width = '464rpx';
99
+ if (this.mode == 'number' && this.dotDisabled && index == 9) style.flex = '2 1 30%';
96
100
  return style;
97
101
  };
98
102
  },
99
- // 是否让按键显示灰色,只在非乱序&&数字键盘&&且允许点按键的时候
103
+ // 是否让按键显示灰色,只在非乱序&&数字键盘&&且允许点按键的时候("."键 / 身份证"X"键)
100
104
  btnBgGray() {
101
105
  return index => {
102
106
  if (!this.random && index == 9 && (this.mode != 'number' || (this.mode == 'number' && !this
@@ -109,8 +113,9 @@
109
113
  },
110
114
  emits: ["backspace", "change"],
111
115
  methods: {
112
- // 点击退格键
113
- backspaceClick() {
116
+ // 点击退格键(触摸路径:touchstart 立删 + 长按连删;鼠标路径:tap 单删,isTouch 防移动端触摸后 tap 二次删除)
117
+ backspaceTouchStart() {
118
+ this.isTouch = true
114
119
  this.$emit('backspace');
115
120
  clearInterval(this.timer); //再次清空定时器,防止重复注册定时器
116
121
  this.timer = null;
@@ -118,6 +123,13 @@
118
123
  this.$emit('backspace');
119
124
  }, 250);
120
125
  },
126
+ backspaceTap() {
127
+ if (this.isTouch) {
128
+ this.isTouch = false;
129
+ return;
130
+ }
131
+ this.$emit('backspace');
132
+ },
121
133
  clearTimer() {
122
134
  clearInterval(this.timer);
123
135
  this.timer = null;
@@ -137,12 +149,8 @@
137
149
  @import '../../scss/dd-shared';
138
150
  $dd-number-keyboard-background-color: var(--dd-bg-section, #{$dd-bg-section}) !default;
139
151
  $dd-number-keyboard-padding:8px 10rpx 8px 10rpx !default;
140
- $dd-number-keyboard-button-width:222rpx !default;
141
- $dd-number-keyboard-button-margin:4px 6rpx !default;
142
- $dd-number-keyboard-button-border-top-left-radius:4px !default;
143
- $dd-number-keyboard-button-border-top-right-radius:4px !default;
144
- $dd-number-keyboard-button-border-bottom-left-radius:4px !default;
145
- $dd-number-keyboard-button-border-bottom-right-radius:4px !default;
152
+ $dd-number-keyboard-gap:6rpx !default;
153
+ $dd-number-keyboard-button-border-radius:var(--dd-radius-sm, #{$dd-radius-sm}) !default;
146
154
  $dd-number-keyboard-button-height: 90rpx!default;
147
155
  $dd-number-keyboard-button-background-color:var(--dd-surface-container-high, #{$dd-surface-container-high}) !default;
148
156
  $dd-number-keyboard-button-box-shadow:0 2px 0px var(--dd-bg, #{$dd-bg}) !default;
@@ -155,30 +163,25 @@
155
163
  .dd-keyboard {
156
164
  @include flex;
157
165
  flex-direction: row;
158
- justify-content: space-around;
159
- background-color: $dd-number-keyboard-background-color;
160
166
  flex-wrap: wrap;
167
+ gap: $dd-number-keyboard-gap;
168
+ background-color: $dd-number-keyboard-background-color;
161
169
  padding: $dd-number-keyboard-padding;
162
170
 
171
+ // ponytail: 弹性三等分替代固定 222rpx 宽——容器宽度不足 702rpx 时固定宽会挤成 2 列
163
172
  &__button-wrapper {
173
+ flex: 1 1 30%;
164
174
  box-shadow: $dd-number-keyboard-button-box-shadow;
165
- margin: $dd-number-keyboard-button-margin;
166
- border-top-left-radius: $dd-number-keyboard-button-border-top-left-radius;
167
- border-top-right-radius: $dd-number-keyboard-button-border-top-right-radius;
168
- border-bottom-left-radius: $dd-number-keyboard-button-border-bottom-left-radius;
169
- border-bottom-right-radius: $dd-number-keyboard-button-border-bottom-right-radius;
175
+ border-radius: $dd-number-keyboard-button-border-radius;
170
176
 
171
177
  &__button {
172
- width: $dd-number-keyboard-button-width;
178
+ width: 100%;
173
179
  height: $dd-number-keyboard-button-height;
174
180
  background-color: $dd-number-keyboard-button-background-color;
175
181
  @include flex;
176
182
  justify-content: center;
177
183
  align-items: center;
178
- border-top-left-radius: $dd-number-keyboard-button-border-top-left-radius;
179
- border-top-right-radius: $dd-number-keyboard-button-border-top-right-radius;
180
- border-bottom-left-radius: $dd-number-keyboard-button-border-bottom-left-radius;
181
- border-bottom-right-radius: $dd-number-keyboard-button-border-bottom-right-radius;
184
+ border-radius: $dd-number-keyboard-button-border-radius;
182
185
 
183
186
  &__text {
184
187
  font-size: $dd-number-keyboard-text-font-size;
@@ -187,9 +190,9 @@
187
190
  }
188
191
 
189
192
  &--gray {
190
- background-color: $dd-number-keyboard-gray-background-color;
191
- color: $dd-number-keyboard-text-color; // 退格图标 color=inherit,由此处控制
192
- }
193
+ background-color: $dd-number-keyboard-gray-background-color;
194
+ color: $dd-number-keyboard-text-color; // 退格图标 color=inherit,由此处控制
195
+ }
193
196
  }
194
197
  }
195
198
  }
@@ -2,6 +2,7 @@
2
2
  <view
3
3
  v-if="variant === 'pill'"
4
4
  class="dd-seg dd-seg--pill"
5
+ :class="{ 'dd-seg--sm': size === 'sm' }"
5
6
  >
6
7
  <view
7
8
  ref="trackRef"
@@ -22,7 +23,11 @@
22
23
  ></view>
23
24
  </view>
24
25
  </view>
25
- <view v-else class="dd-seg dd-seg--text">
26
+ <view
27
+ v-else
28
+ class="dd-seg dd-seg--text"
29
+ :class="{ 'dd-seg--sm': size === 'sm' }"
30
+ >
26
31
  <view
27
32
  v-for="(opt, index) in options"
28
33
  :key="index"
@@ -44,12 +49,15 @@ interface Props {
44
49
  modelValue?: number
45
50
  options?: (string | { label: string })[]
46
51
  variant?: 'pill' | 'text'
52
+ /** 尺寸:md 标准;sm 小号(与页面 24rpx 字号胶囊控件同高,用于工具行等紧凑场景) */
53
+ size?: 'sm' | 'md'
47
54
  }
48
55
 
49
56
  const props = withDefaults(defineProps<Props>(), {
50
57
  modelValue: 0,
51
58
  options: () => [],
52
59
  variant: 'pill',
60
+ size: 'md',
53
61
  })
54
62
 
55
63
  const emit = defineEmits<{
@@ -135,6 +143,15 @@ watch(() => props.options, measure)
135
143
  }
136
144
  }
137
145
 
146
+ // sm 小号:字号 caption(12px=24rpx)、更紧内边距,整体高度对齐页面 24rpx 字号胶囊
147
+ &.dd-seg--sm {
148
+ .dd-seg__item {
149
+ min-width: 96rpx;
150
+ padding: $dd-space-1;
151
+ font-size: $dd-font-size-caption;
152
+ }
153
+ }
154
+
138
155
  .dd-seg__indicator {
139
156
  position: absolute;
140
157
  top: $dd-space-1;
@@ -154,6 +171,12 @@ watch(() => props.options, measure)
154
171
  flex-direction: row;
155
172
  gap: $dd-space-6;
156
173
 
174
+ &.dd-seg--sm {
175
+ .dd-seg-text__item {
176
+ font-size: $dd-font-size-caption;
177
+ }
178
+ }
179
+
157
180
  .dd-seg-text__item {
158
181
  position: relative;
159
182
  padding: $dd-space-2 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@didaoktv/didaoui-uniapp",
3
- "version": "1.3.5",
3
+ "version": "1.3.7",
4
4
  "description": "帝到KTV UniApp 组件库",
5
5
  "main": "index.ts",
6
6
  "types": "index.ts",