@didaoktv/didaoui-uniapp 1.3.4 → 1.3.6

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.
@@ -1,315 +1,316 @@
1
1
  <template>
2
- <view
3
- class="dd-keyboard"
4
- @touchmove.stop.prevent="noop"
5
- >
6
- <view
7
- v-for="(group, i) in abc ? engKeyBoardList : areaList"
8
- :key="i"
9
- class="dd-keyboard__button"
10
- :index="i"
11
- :class="[i + 1 === 4 && 'dd-keyboard__button--center']"
12
- >
2
+ <view class="dd-car-keyboard" :class="customClass" :style="customStyle">
3
+ <!-- 车牌格子:7 位普通 + 第 8 位新能源(绿框) -->
4
+ <view class="dd-car-keyboard__boxes">
13
5
  <view
14
- v-if="i === 3"
15
- class="dd-keyboard__button__inner-wrapper"
6
+ v-for="(char, index) in cells"
7
+ :key="index"
8
+ class="dd-car-keyboard__box"
9
+ :class="[
10
+ active === index && 'dd-car-keyboard__box--active',
11
+ index === 7 && 'dd-car-keyboard__box--energy'
12
+ ]"
13
+ @tap="onBoxTap(index)"
16
14
  >
17
15
  <view
18
- class="dd-keyboard__button__inner-wrapper__left"
19
- hover-class="dd-keyboard-hover"
20
- :hover-stay-time="200"
21
- @tap="changeCarInputMode"
22
- >
23
- <text
24
- class="dd-keyboard__button__inner-wrapper__left__lang"
25
- :class="[!abc && 'dd-keyboard__button__inner-wrapper__left__lang--active']"
26
- >中</text>
27
- <text class="dd-keyboard__button__inner-wrapper__left__line">/</text>
28
- <text
29
- class="dd-keyboard__button__inner-wrapper__left__lang"
30
- :class="[abc && 'dd-keyboard__button__inner-wrapper__left__lang--active']"
31
- >英</text>
32
- </view>
33
- </view>
34
- <view
35
- class="dd-keyboard__button__inner-wrapper"
36
- v-for="(item, j) in group"
37
- :key="j"
38
- >
16
+ v-if="active === index"
17
+ class="dd-car-keyboard__box-line"
18
+ ></view>
39
19
  <view
40
- class="dd-keyboard__button__inner-wrapper__inner"
41
- :hover-stay-time="200"
42
- @tap="carInputClick(i, j)"
43
- hover-class="dd-keyboard-hover"
20
+ v-if="index === 7"
21
+ class="dd-car-keyboard__badge"
44
22
  >
45
- <text class="dd-keyboard__button__inner-wrapper__inner__text">{{ item }}</text>
23
+ <text class="dd-car-keyboard__badge-text">新能源</text>
46
24
  </view>
25
+ <text class="dd-car-keyboard__box-text">{{ char }}</text>
47
26
  </view>
48
- <view
49
- v-if="i === 3"
50
- @touchstart="backspaceClick"
51
- @touchend="clearTimer"
52
- class="dd-keyboard__button__inner-wrapper"
53
- >
27
+ </view>
28
+
29
+ <!-- 键盘弹层:与其他键盘模式一致,经 dd-popup 弹出(遮罩/动效/底部安全区),0 位省份键盘,其余位字母数字键盘(按位锁键) -->
30
+ <dd-popup
31
+ v-model="popupShow"
32
+ position="bottom"
33
+ :z-index="zIndexConfig.popup"
34
+ >
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>
52
+ </view>
54
53
  <view
55
- class="dd-keyboard__button__inner-wrapper__right"
56
- hover-class="dd-keyboard-hover"
57
- :hover-stay-time="200"
54
+ v-for="(row, rowIndex) in keyRows"
55
+ :key="rowIndex"
56
+ class="dd-car-keyboard__row"
58
57
  >
59
- <dd-icon
60
- size="28"
61
- name="backspace"
62
- ></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>
63
78
  </view>
64
79
  </view>
65
- </view>
80
+ </dd-popup>
66
81
  </view>
67
82
  </template>
68
83
 
69
- <script>
70
- import { props } from './props';
71
- import { mpMixin } from '../../libs/mixin/mpMixin';
72
- import { mixin } from '../../libs/mixin/mixin';
73
- import { randomArray, sleep } from '../../libs/function/index';
74
- /**
75
- * keyboard 键盘组件
76
- * @description 自定义的键盘面板,内含了数字键盘,车牌号键,身份证号键盘3种模式,都有可以打乱按键顺序的选项。
77
- * @property {Boolean} random 是否打乱键盘的顺序
78
- * @event {Function} change 点击键盘触发
79
- * @event {Function} backspace 点击退格键触发
80
- * @example <dd-keyboard ref="carKeyboard" mode="car" v-model="show"></dd-keyboard>
81
- */
82
- export default {
83
- name: "dd-car-keyboard",
84
- mixins: [mpMixin, mixin, props],
85
- data() {
86
- return {
87
- // 车牌输入时,abc=true为输入车牌号码,bac=false为输入省份中文简称
88
- abc: false
89
- };
90
- },
91
- computed: {
92
- areaList() {
93
- let data = [
94
- '',
95
- '沪',
96
- '粤',
97
- '津',
98
- '',
99
- '',
100
- '',
101
- '辽',
102
- '黑',
103
- '湘',
104
- '',
105
- '鲁',
106
- '苏',
107
- '浙',
108
- '赣',
109
- '鄂',
110
- '桂',
111
- '甘',
112
- '晋',
113
- '陕',
114
- '',
115
- '',
116
- '闽',
117
- '贵',
118
- '渝',
119
- '川',
120
- '青',
121
- '琼',
122
- '',
123
- '',
124
- '藏',
125
- '港',
126
- '澳',
127
- '新',
128
- '使',
129
- '学'
130
- ];
131
- let tmp = [];
132
- // 打乱顺序
133
- if (this.random) data = randomArray(data);
134
- // 切割成二维数组
135
- tmp[0] = data.slice(0, 10);
136
- tmp[1] = data.slice(10, 20);
137
- tmp[2] = data.slice(20, 30);
138
- tmp[3] = data.slice(30, 36);
139
- return tmp;
140
- },
141
- engKeyBoardList() {
142
- let data = [
143
- 1,
144
- 2,
145
- 3,
146
- 4,
147
- 5,
148
- 6,
149
- 7,
150
- 8,
151
- 9,
152
- 0,
153
- 'Q',
154
- 'W',
155
- 'E',
156
- 'R',
157
- 'T',
158
- 'Y',
159
- 'U',
160
- 'I',
161
- 'O',
162
- 'P',
163
- 'A',
164
- 'S',
165
- 'D',
166
- 'F',
167
- 'G',
168
- 'H',
169
- 'J',
170
- 'K',
171
- 'L',
172
- 'Z',
173
- 'X',
174
- 'C',
175
- 'V',
176
- 'B',
177
- 'N',
178
- 'M'
179
- ];
180
- let tmp = [];
181
- if (this.random) data = randomArray(data);
182
- tmp[0] = data.slice(0, 10);
183
- tmp[1] = data.slice(10, 20);
184
- tmp[2] = data.slice(20, 30);
185
- tmp[3] = data.slice(30, 36);
186
- return tmp;
187
- }
188
- },
189
- emits: ["change", "backspace"],
190
- methods: {
191
- // 点击键盘按钮
192
- carInputClick(i, j) {
193
- let value = '';
194
- // 不同模式,获取不同数组的值
195
- if (this.abc) value = this.engKeyBoardList[i][j];
196
- else value = this.areaList[i][j];
197
- // 如果允许自动切换,则将中文状态切换为英文
198
- if (!this.abc && this.autoChange) sleep(200).then(() => this.abc = true)
199
- this.$emit('change', value);
200
- },
201
- // 修改汽车牌键盘的输入模式,中文|英文
202
- changeCarInputMode() {
203
- this.abc = !this.abc;
204
- },
205
- // 点击退格键
206
- backspaceClick() {
207
- this.$emit('backspace');
208
- clearInterval(this.timer); //再次清空定时器,防止重复注册定时器
209
- this.timer = null;
210
- this.timer = setInterval(() => {
211
- this.$emit('backspace');
212
- }, 250);
213
- },
214
- clearTimer() {
215
- clearInterval(this.timer);
216
- this.timer = null;
217
- },
218
- }
219
- };
84
+ <script setup lang="ts">
85
+ import { computed, ref, watch } from 'vue'
86
+ import zIndexConfig from '../../libs/config/zIndex.js'
87
+ import DdIcon from '../dd-icon/dd-icon.vue'
88
+ import DdPopup from '../dd-popup/dd-popup.vue'
89
+ import { MAX_LEN, getKeyRows, nextPos, type KeyItem } from './carPlate'
90
+
91
+ /**
92
+ * dd-car-keyboard 车牌号输入键盘
93
+ * 车牌格子 + 弹出键盘一体:0 位省份简称,其余位字母数字,按位锁键,末位为新能源(绿牌)位
94
+ * @property {String} modelValue 车牌号(v-model)
95
+ * @event {Function} update:modelValue 输入变化
96
+ * @event {Function} focus 键盘弹出
97
+ * @event {Function} blur 键盘收起(含遮罩/取消/完成触发)
98
+ * @example <dd-car-keyboard v-model="plateNo" />
99
+ */
100
+
101
+ interface Props {
102
+ modelValue?: string
103
+ customClass?: string
104
+ customStyle?: string
105
+ }
106
+ const props = withDefaults(defineProps<Props>(), {
107
+ modelValue: '',
108
+ customClass: '',
109
+ customStyle: ''
110
+ })
111
+
112
+ const emit = defineEmits<{
113
+ (e: 'update:modelValue', val: string): void
114
+ (e: 'focus', val: string): void
115
+ (e: 'blur', val: string): void
116
+ }>()
117
+
118
+ // 空位用空格占位(与退格逻辑配合:清当前位后停留在该位)
119
+ const cells = ref<string[]>(Array(MAX_LEN).fill(' '))
120
+ const active = ref(-1)
121
+
122
+ // 键位布局/按位锁键纯逻辑见 ./carPlate
123
+ const keyRows = computed(() => getKeyRows(active.value))
124
+
125
+ // 外部 v-model 同步到格子(支持清空与部分更新)
126
+ watch(
127
+ () => props.modelValue,
128
+ (val) => {
129
+ const list = (val || '').split('')
130
+ cells.value = Array.from({ length: MAX_LEN }, (_, i) => list[i] ?? ' ')
131
+ },
132
+ { immediate: true }
133
+ )
134
+
135
+ const keyboardVisible = computed(() => active.value >= 0)
136
+ watch(keyboardVisible, (visible) => {
137
+ if (visible) emit('focus', props.modelValue)
138
+ else emit('blur', props.modelValue)
139
+ })
140
+
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
+ })
148
+
149
+ function onBoxTap(index: number) {
150
+ active.value = index
151
+ }
152
+
153
+ function onKeyTap(item: KeyItem) {
154
+ if (item.locked || active.value < 0) return
155
+ cells.value[active.value] = item.label
156
+ active.value = nextPos(active.value)
157
+ emitValue()
158
+ }
159
+
160
+ function closeKeyboard() {
161
+ active.value = -1
162
+ }
163
+
164
+ function onBackspaceTap() {
165
+ if (active.value < 0) return
166
+ if (cells.value[active.value] === ' ' && active.value > 0) {
167
+ active.value--
168
+ }
169
+ cells.value[active.value] = ' '
170
+ emitValue()
171
+ }
172
+
173
+ function emitValue() {
174
+ emit('update:modelValue', cells.value.join('').trim())
175
+ }
220
176
  </script>
221
177
 
222
178
  <style lang="scss" scoped>
179
+ /* 头部固定引入;只消费 $dd-* token,样式值写 var(--dd-x, $dd-x) 兜底形式 */
223
180
  @import '../../scss/variables';
224
181
  @import '../../scss/dd-shared';
225
- $dd-car-keyboard-background-color: var(--dd-bg-section, #{$dd-bg-section}) !default;
226
- $dd-car-keyboard-padding:6px 0 6px !default;
227
- $dd-car-keyboard-button-inner-width:64rpx !default;
228
- $dd-car-keyboard-button-inner-background-color:var(--dd-surface-container-high, #{$dd-surface-container-high}) !default;
229
- $dd-car-keyboard-button-height:80rpx !default;
230
- $dd-car-keyboard-button-inner-box-shadow:0 1px 0px var(--dd-bg, #{$dd-bg}) !default;
231
- $dd-car-keyboard-button-border-radius:4px !default;
232
- $dd-car-keyboard-button-inner-margin:8rpx 5rpx !default;
233
- $dd-car-keyboard-button-text-font-size:16px !default;
234
- $dd-car-keyboard-button-text-color:var(--dd-text-primary, #{$dd-text-primary}) !default;
235
- $dd-car-keyboard-center-inner-margin: 0 4rpx !default;
236
- $dd-car-keyboard-special-button-width:134rpx !default;
237
- $dd-car-keyboard-lang-font-size:16px !default;
238
- $dd-car-keyboard-lang-color:var(--dd-text-primary, #{$dd-text-primary}) !default;
239
- $dd-car-keyboard-active-color:var(--dd-primary-400, #{$dd-primary-400}) !default;
240
- $dd-car-keyboard-line-font-size:15px !default;
241
- $dd-car-keyboard-line-color:var(--dd-text-primary, #{$dd-text-primary}) !default;
242
- $dd-car-keyboard-line-margin:0 1px !default;
243
- $dd-car-keyboard-dd-keyboard-hover-background-color:var(--dd-surface-hover, #{$dd-surface-hover}) !default;
244
-
245
- .dd-keyboard {
246
- @include flex(column);
247
- justify-content: space-around;
248
- background-color: $dd-car-keyboard-background-color;
249
- align-items: stretch;
250
- padding: $dd-car-keyboard-padding;
251
-
252
- &__button {
253
- @include flex;
254
- justify-content: center;
182
+
183
+ $dd-car-keyboard-gap: 8rpx !default;
184
+ $dd-car-keyboard-box-height: 76rpx !default;
185
+ $dd-car-keyboard-box-border: 1px solid var(--dd-border-default, #{$dd-border-default}) !default;
186
+ $dd-car-keyboard-key-height: 76rpx !default;
187
+ $dd-car-keyboard-panel-padding: 0 var(--dd-space-2, #{$dd-space-2}) var(--dd-space-2, #{$dd-space-2}) !default;
188
+
189
+ .dd-car-keyboard {
190
+ &__boxes {
191
+ @include flex;
192
+ gap: $dd-car-keyboard-gap;
193
+ }
194
+
195
+ &__box {
196
+ @include flex;
197
+ position: relative;
198
+ justify-content: center;
199
+ align-items: center;
200
+ flex: 1;
201
+ height: $dd-car-keyboard-box-height;
202
+ border: $dd-car-keyboard-box-border;
203
+ border-radius: var(--dd-radius-md, #{$dd-radius-md});
204
+
205
+ &--active {
206
+ border-color: var(--dd-primary-400, #{$dd-primary-400});
207
+ }
208
+
209
+ &--energy {
210
+ border-color: var(--dd-success-500, #{$dd-success-500});
211
+ }
212
+ }
213
+
214
+ &__box-line {
215
+ position: absolute;
216
+ bottom: 6rpx;
217
+ left: 15%;
218
+ width: 70%;
219
+ height: 4rpx;
220
+ background-color: var(--dd-primary-400, #{$dd-primary-400});
221
+ }
222
+
223
+ &__box-text {
224
+ font-size: 17px;
225
+ color: var(--dd-text-primary, #{$dd-text-primary});
226
+ }
227
+
228
+ &__badge {
229
+ @include flex;
230
+ justify-content: center;
231
+ position: absolute;
232
+ top: -14rpx;
233
+ left: 50%;
234
+ transform: translateX(-50%);
235
+ padding: 0 6rpx;
236
+ background-color: var(--dd-success-500, #{$dd-success-500});
237
+ border-radius: var(--dd-radius-sm, #{$dd-radius-sm});
238
+ }
239
+
240
+ &__badge-text {
241
+ font-size: 10px;
242
+ color: var(--dd-success-contrast, #{$dd-success-contrast});
243
+ }
244
+
245
+ &__panel {
246
+ padding: $dd-car-keyboard-panel-padding;
247
+ }
248
+
249
+ // 工具条对齐 dd-keyboard:取消 / 提示 / 完成
250
+ &__tooltip {
251
+ @include flex;
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});
255
258
  flex: 1;
256
- /* #ifndef APP-NVUE */
257
- /* #endif */
258
-
259
- &__inner-wrapper {
260
- box-shadow: $dd-car-keyboard-button-inner-box-shadow;
261
- margin: $dd-car-keyboard-button-inner-margin;
262
- border-radius: $dd-car-keyboard-button-border-radius;
263
-
264
- &__inner {
265
- @include flex;
266
- justify-content: center;
267
- align-items: center;
268
- width: $dd-car-keyboard-button-inner-width;
269
- background-color: $dd-car-keyboard-button-inner-background-color;
270
- height: $dd-car-keyboard-button-height;
271
- border-radius: $dd-car-keyboard-button-border-radius;
272
-
273
- &__text {
274
- font-size: $dd-car-keyboard-button-text-font-size;
275
- color: $dd-car-keyboard-button-text-color;
276
- }
277
- }
278
-
279
- &__left,
280
- &__right {
281
- border-radius: $dd-car-keyboard-button-border-radius;
282
- width: $dd-car-keyboard-special-button-width;
283
- height: $dd-car-keyboard-button-height;
284
- background-color: $dd-car-keyboard-dd-keyboard-hover-background-color;
285
- color: $dd-car-keyboard-button-text-color; // 退格图标 color=inherit,由此处控制
286
- @include flex;
287
- justify-content: center;
288
- align-items: center;
289
- box-shadow: $dd-car-keyboard-button-inner-box-shadow;
290
- }
291
-
292
- &__left {
293
- &__line {
294
- font-size: $dd-car-keyboard-line-font-size;
295
- color: $dd-car-keyboard-line-color;
296
- margin: $dd-car-keyboard-line-margin;
297
- }
298
-
299
- &__lang {
300
- font-size: $dd-car-keyboard-lang-font-size;
301
- color: $dd-car-keyboard-lang-color;
302
-
303
- &--active {
304
- color: $dd-car-keyboard-active-color;
305
- }
306
- }
307
- }
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});
308
274
  }
309
275
  }
310
276
  }
311
277
 
312
- .dd-keyboard-hover {
313
- background-color: $dd-car-keyboard-dd-keyboard-hover-background-color;
278
+ &__hover {
279
+ opacity: 0.7;
280
+ }
281
+
282
+ &__row {
283
+ @include flex;
284
+ margin-top: var(--dd-space-2, #{$dd-space-2});
285
+ gap: $dd-car-keyboard-gap;
286
+ }
287
+
288
+ &__key {
289
+ @include flex;
290
+ justify-content: center;
291
+ align-items: center;
292
+ flex: 1;
293
+ height: $dd-car-keyboard-key-height;
294
+ background-color: var(--dd-surface-container-high, #{$dd-surface-container-high});
295
+ border-radius: var(--dd-radius-md, #{$dd-radius-md});
296
+
297
+ &--lock {
298
+ opacity: 0.35;
299
+ }
300
+
301
+ &--hover {
302
+ background-color: var(--dd-surface-hover, #{$dd-surface-hover});
303
+ }
304
+
305
+ &--del {
306
+ flex: 2;
307
+ color: var(--dd-text-primary, #{$dd-text-primary}); // 图标 color=inherit,由此处控制
308
+ }
309
+ }
310
+
311
+ &__key-text {
312
+ font-size: 16px;
313
+ color: var(--dd-text-primary, #{$dd-text-primary});
314
314
  }
315
+ }
315
316
  </style>
@@ -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 {
@@ -1,4 +1,5 @@
1
1
  <template>
2
+ <dd-portal>
2
3
  <view class="dd-dp" :class="{ 'dd-dp--open': show }">
3
4
  <view class="dd-dp__mask" @click="onMaskClick"></view>
4
5
  <view class="dd-dp__sheet">
@@ -21,10 +22,12 @@
21
22
  </picker-view>
22
23
  </view>
23
24
  </view>
25
+ </dd-portal>
24
26
  </template>
25
27
 
26
28
  <script setup lang="ts">
27
29
  import { computed, ref, watch } from 'vue'
30
+ import DdPortal from '../dd-portal/dd-portal.vue'
28
31
 
29
32
  interface Props {
30
33
  show?: boolean