im-ui-mobile 0.1.0 → 0.1.2

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 (85) hide show
  1. package/components/im-avatar/im-avatar.vue +7 -7
  2. package/components/im-badge/im-badge.vue +326 -0
  3. package/components/im-button/im-button.vue +71 -34
  4. package/components/im-card/im-card.vue +563 -0
  5. package/components/im-chat-item/im-chat-item.vue +5 -4
  6. package/components/im-col/im-col.vue +191 -0
  7. package/components/im-dialog/im-dialog.vue +543 -0
  8. package/components/im-double-tap-view/im-double-tap-view.vue +93 -0
  9. package/components/im-emoji-picker/im-emoji-picker.vue +1143 -0
  10. package/components/im-friend-item/im-friend-item.vue +1 -1
  11. package/components/im-group-item/im-group-item.vue +1 -1
  12. package/components/im-group-member-selector/im-group-member-selector.vue +5 -5
  13. package/components/im-group-rtc-join/im-group-rtc-join.vue +8 -8
  14. package/components/im-icon/im-icon.vue +593 -0
  15. package/components/im-image-upload/im-image-upload.vue +0 -2
  16. package/components/im-link/im-link.vue +628 -0
  17. package/components/im-loading/im-loading.vue +13 -4
  18. package/components/im-mention-picker/im-mention-picker.vue +8 -7
  19. package/components/im-message-action/im-message-action.vue +678 -0
  20. package/components/im-message-item/im-message-item.vue +28 -26
  21. package/components/im-message-list/im-message-list.vue +1108 -0
  22. package/components/im-modal/im-modal.vue +373 -0
  23. package/components/im-nav-bar/im-nav-bar.vue +689 -75
  24. package/components/im-parse/im-parse.vue +1054 -0
  25. package/components/im-popup/im-popup.vue +467 -0
  26. package/components/im-read-receipt/im-read-receipt.vue +10 -10
  27. package/components/im-row/im-row.vue +189 -0
  28. package/components/im-search/im-search.vue +762 -0
  29. package/components/im-sku/im-sku.vue +720 -0
  30. package/components/im-sku/utils/helper.ts +182 -0
  31. package/components/im-stepper/im-stepper.vue +585 -0
  32. package/components/im-stepper/utils/helper.ts +167 -0
  33. package/components/im-tabs/im-tabs.vue +1022 -0
  34. package/components/im-tabs/tabs-navigation.vue +489 -0
  35. package/components/im-tabs/utils/helper.ts +181 -0
  36. package/components/im-tabs-tab-pane/im-tabs-tab-pane.vue +145 -0
  37. package/components/im-upload/im-upload.vue +1236 -0
  38. package/components/im-voice-input/im-voice-input.vue +1 -1
  39. package/index.js +3 -5
  40. package/index.scss +19 -0
  41. package/libs/emoji-data.ts +229 -0
  42. package/libs/index.ts +16 -16
  43. package/package.json +1 -2
  44. package/styles/button.scss +33 -33
  45. package/theme.scss +2 -2
  46. package/types/components/badge.d.ts +42 -0
  47. package/types/components/button.d.ts +2 -1
  48. package/types/components/card.d.ts +122 -0
  49. package/types/components/col.d.ts +37 -0
  50. package/types/components/dialog.d.ts +125 -0
  51. package/types/components/double-tap-view.d.ts +31 -0
  52. package/types/components/emoji-picker.d.ts +121 -0
  53. package/types/components/group-rtc-join.d.ts +1 -1
  54. package/types/components/icon.d.ts +77 -0
  55. package/types/components/link.d.ts +55 -0
  56. package/types/components/loading.d.ts +1 -0
  57. package/types/components/message-action.d.ts +96 -0
  58. package/types/components/message-item.d.ts +2 -2
  59. package/types/components/message-list.d.ts +136 -0
  60. package/types/components/modal.d.ts +106 -0
  61. package/types/components/nav-bar.d.ts +125 -0
  62. package/types/components/parse.d.ts +90 -0
  63. package/types/components/popup.d.ts +58 -0
  64. package/types/components/row.d.ts +31 -0
  65. package/types/components/search.d.ts +54 -0
  66. package/types/components/sku.d.ts +195 -0
  67. package/types/components/stepper.d.ts +99 -0
  68. package/types/components/tabs-tab-pane.d.ts +27 -0
  69. package/types/components/tabs.d.ts +117 -0
  70. package/types/components/upload.d.ts +137 -0
  71. package/types/components.d.ts +19 -1
  72. package/types/index.d.ts +38 -1
  73. package/types/libs/index.d.ts +10 -10
  74. package/types/utils/base64.d.ts +5 -0
  75. package/types/utils/dom.d.ts +3 -0
  76. package/types/utils/enums.d.ts +4 -5
  77. package/types/utils/validator.d.ts +74 -0
  78. package/utils/base64.js +18 -0
  79. package/utils/dom.js +353 -1
  80. package/utils/enums.js +4 -5
  81. package/utils/validator.js +230 -0
  82. package/components/im-file-upload/im-file-upload.vue +0 -309
  83. package/plugins/uview-plus.js +0 -29
  84. package/types/components/arrow-bar.d.ts +0 -14
  85. package/types/components/file-upload.d.ts +0 -58
@@ -0,0 +1,191 @@
1
+ <template>
2
+ <view
3
+ class="im-col"
4
+ :class="[
5
+ `im-col--span-${span}`,
6
+ `im-col--offset-${offset}`,
7
+ `im-col--order-${order}`,
8
+ `im-col--align-self-${alignSelf}`,
9
+ { 'im-col--gutter': hasGutter }
10
+ ]"
11
+ :style="colStyle"
12
+ @tap="handleClick"
13
+ >
14
+ <slot></slot>
15
+ </view>
16
+ </template>
17
+
18
+ <script setup lang="ts">
19
+ import { computed, inject } from 'vue'
20
+
21
+ // 定义 Props
22
+ interface Props {
23
+ // 布局配置
24
+ span?: number | string
25
+ offset?: number | string
26
+ order?: number | string
27
+ alignSelf?: 'auto' | 'start' | 'end' | 'center' | 'stretch'
28
+ flex?: string
29
+
30
+ // 响应式配置
31
+ xs?: number | string
32
+ sm?: number | string
33
+ md?: number | string
34
+ lg?: number | string
35
+ xl?: number | string
36
+
37
+ // 样式配置
38
+ width?: string
39
+ height?: string
40
+ margin?: string
41
+ padding?: string
42
+ bgColor?: string
43
+ borderColor?: string
44
+ borderRadius?: string
45
+
46
+ // 点击事件
47
+ clickable?: boolean
48
+ }
49
+
50
+ // 定义 Emits
51
+ interface Emits {
52
+ (e: 'click', event: any): void
53
+ }
54
+
55
+ // 定义 Props 默认值
56
+ const props = withDefaults(defineProps<Props>(), {
57
+ span: 24,
58
+ offset: 0,
59
+ order: 0,
60
+ alignSelf: 'auto',
61
+ flex: 'none',
62
+
63
+ xs: 0,
64
+ sm: 0,
65
+ md: 0,
66
+ lg: 0,
67
+ xl: 0,
68
+
69
+ width: 'auto',
70
+ height: 'auto',
71
+ margin: '0',
72
+ padding: '0',
73
+ bgColor: 'transparent',
74
+ borderColor: 'transparent',
75
+ borderRadius: '0',
76
+
77
+ clickable: false
78
+ })
79
+
80
+ const emit = defineEmits<Emits>()
81
+
82
+ // 注入 row context
83
+ const rowContext = inject('imRowContext', { gutter: 0 })
84
+
85
+ // 计算是否有 gutter
86
+ const hasGutter = computed(() => {
87
+ return Number(rowContext.gutter) > 0
88
+ })
89
+
90
+ // 计算响应式 span
91
+ const computedSpan = computed(() => {
92
+ // 这里可以添加响应式逻辑,根据屏幕宽度返回不同的 span
93
+ // 简化版本:直接使用 props.span
94
+ return props.span
95
+ })
96
+
97
+ // 计算列样式
98
+ const colStyle = computed(() => {
99
+ const style: any = {
100
+ width: props.width,
101
+ height: props.height,
102
+ margin: props.margin,
103
+ padding: props.padding,
104
+ backgroundColor: props.bgColor,
105
+ borderColor: props.borderColor,
106
+ borderRadius: props.borderRadius,
107
+ order: props.order,
108
+ alignSelf: props.alignSelf
109
+ }
110
+
111
+ // 设置 flex
112
+ if (props.flex !== 'none') {
113
+ style.flex = props.flex
114
+ }
115
+
116
+ // 设置边框
117
+ if (props.borderColor !== 'transparent') {
118
+ style.borderWidth = '2rpx'
119
+ style.borderStyle = 'solid'
120
+ }
121
+
122
+ // 设置 gutter
123
+ if (hasGutter.value) {
124
+ const gutter = typeof rowContext.gutter === 'number'
125
+ ? `${rowContext.gutter}rpx`
126
+ : rowContext.gutter
127
+
128
+ style.paddingLeft = `calc(${gutter} / 2)`
129
+ style.paddingRight = `calc(${gutter} / 2)`
130
+ }
131
+
132
+ return style
133
+ })
134
+
135
+ // 点击事件
136
+ const handleClick = (event: any) => {
137
+ if (props.clickable) {
138
+ emit('click', event)
139
+ }
140
+ }
141
+ </script>
142
+
143
+ <style lang="scss" scoped>
144
+ .im-col {
145
+ box-sizing: border-box;
146
+ position: relative;
147
+
148
+ // 基本 span 类
149
+ @for $i from 1 through 24 {
150
+ &--span-#{$i} {
151
+ width: calc(100% * $i / 24);
152
+ }
153
+
154
+ &--offset-#{$i} {
155
+ margin-left: calc(100% * $i / 24);
156
+ }
157
+
158
+ &--order-#{$i} {
159
+ order: $i;
160
+ }
161
+ }
162
+
163
+ // 对齐方式
164
+ &--align-self-auto {
165
+ align-self: auto;
166
+ }
167
+
168
+ &--align-self-start {
169
+ align-self: flex-start;
170
+ }
171
+
172
+ &--align-self-end {
173
+ align-self: flex-end;
174
+ }
175
+
176
+ &--align-self-center {
177
+ align-self: center;
178
+ }
179
+
180
+ &--align-self-stretch {
181
+ align-self: stretch;
182
+ }
183
+
184
+ // 点击效果
185
+ &:active {
186
+ &.im-col--clickable {
187
+ opacity: 0.7;
188
+ }
189
+ }
190
+ }
191
+ </style>
@@ -0,0 +1,543 @@
1
+ <template>
2
+ <im-modal
3
+ ref="modalRef"
4
+ v-model:show="visible"
5
+ :title="title"
6
+ :subtitle="subtitle"
7
+ :show-header="showHeader"
8
+ :show-subtitle="showSubtitle"
9
+ :show-footer="showFooter"
10
+ :show-cancel="showCancel && type !== 'alert'"
11
+ :show-confirm="showConfirm"
12
+ :cancel-text="cancelText"
13
+ :confirm-text="confirmText"
14
+ :cancel-type="cancelType"
15
+ :confirm-type="confirmType"
16
+ :cancel-disabled="cancelDisabled"
17
+ :confirm-disabled="confirmDisabled"
18
+ :cancel-loading="cancelLoading"
19
+ :confirm-loading="confirmLoading"
20
+ :button-size="buttonSize"
21
+ :position="position"
22
+ :animation="animation"
23
+ :duration="duration"
24
+ :show-overlay="showOverlay"
25
+ :overlay-color="overlayColor"
26
+ :overlay-opacity="overlayOpacity"
27
+ :close-on-click-overlay="closeOnClickOverlay"
28
+ :lock-scroll="lockScroll"
29
+ :width="width"
30
+ :border-radius="borderRadius"
31
+ :background-color="backgroundColor"
32
+ :z-index="zIndex"
33
+ :show-close="showClose"
34
+ :safe-area-inset-bottom="safeAreaInsetBottom"
35
+ :custom-class="customClass"
36
+ :close-on-click-action="closeOnClickAction"
37
+ @open="handleOpen"
38
+ @opened="handleOpened"
39
+ @close="handleClose"
40
+ @closed="handleClosed"
41
+ @click-overlay="handleClickOverlay"
42
+ @confirm="handleConfirm"
43
+ @cancel="handleCancel"
44
+ >
45
+ <!-- 内容区域 -->
46
+ <view class="im-dialog__content" :style="contentStyle">
47
+ <!-- 图标 -->
48
+ <view v-if="showIcon" class="im-dialog__icon">
49
+ <im-icon size="80" :name="type==='success'?'ok':type" />
50
+ <slot v-if="$slots.icon" name="icon">
51
+ <view class="im-dialog__icon-content" :class="`im-dialog__icon--${type}`">
52
+ <text v-if="type === 'success'" class="im-dialog__icon-text">✓</text>
53
+ <text v-else-if="type === 'error'" class="im-dialog__icon-text">✕</text>
54
+ <text v-else-if="type === 'warning'" class="im-dialog__icon-text">!</text>
55
+ <text v-else-if="type === 'info'" class="im-dialog__icon-text">i</text>
56
+ <text v-else class="im-dialog__icon-text">?</text>
57
+ </view>
58
+ </slot>
59
+ </view>
60
+
61
+ <!-- 输入框(prompt类型) -->
62
+ <template v-if="type === 'prompt'">
63
+ <view class="im-dialog__prompt">
64
+ <text v-if="promptLabel" class="im-dialog__prompt-label">{{ promptLabel }}</text>
65
+ <input
66
+ v-model="inputValue"
67
+ class="im-dialog__input"
68
+ :type="inputType"
69
+ :placeholder="promptPlaceholder"
70
+ :maxlength="maxlength"
71
+ :disabled="inputDisabled"
72
+ @input="handleInput"
73
+ @focus="handleInputFocus"
74
+ @blur="handleInputBlur"
75
+ />
76
+ <text v-if="showCharCount" class="im-dialog__char-count">
77
+ {{ inputValue.length }} / {{ maxlength }}
78
+ </text>
79
+ <text v-if="inputError" class="im-dialog__input-error">{{ inputError }}</text>
80
+ </view>
81
+ </template>
82
+
83
+ <!-- 内容文本 -->
84
+ <template v-else-if="type === 'html'">
85
+ <view class="im-dialog__html" v-html="content"/>
86
+ </template>
87
+
88
+ <template v-else>
89
+ <text class="im-dialog__text">{{ content }}</text>
90
+ </template>
91
+
92
+ <!-- 自定义插槽 -->
93
+ <slot></slot>
94
+ </view>
95
+ </im-modal>
96
+ </template>
97
+
98
+ <script setup lang="ts">
99
+ import { ref, computed, watch, nextTick } from 'vue'
100
+ import type { Modal as ModalType } from 'im-ui-mobile'
101
+
102
+ // 定义对话框类型
103
+ type DialogType = 'alert' | 'confirm' | 'prompt' | 'success' | 'error' | 'warning' | 'info' | 'html' | 'custom'
104
+
105
+ // 定义 Props
106
+ interface Props {
107
+ // 显示控制
108
+ show?: boolean
109
+ modelValue?: boolean
110
+
111
+ // 对话框类型
112
+ type?: DialogType
113
+
114
+ // 标题和内容
115
+ title?: string
116
+ subtitle?: string
117
+ content?: string
118
+
119
+ // 头部配置
120
+ showHeader?: boolean
121
+ showSubtitle?: boolean
122
+ showIcon?: boolean
123
+
124
+ // 内容样式
125
+ contentStyle?: Record<string, string>
126
+
127
+ // Prompt 类型配置
128
+ promptLabel?: string
129
+ promptPlaceholder?: string
130
+ inputType?: 'text' | 'number' | 'password' | 'textarea'
131
+ maxlength?: number
132
+ showCharCount?: boolean
133
+ inputDisabled?: boolean
134
+
135
+ // 按钮配置
136
+ showFooter?: boolean
137
+ showCancel?: boolean
138
+ showConfirm?: boolean
139
+ cancelText?: string
140
+ confirmText?: string
141
+ cancelType?: 'default' | 'primary' | 'warning' | 'error'
142
+ confirmType?: 'default' | 'primary' | 'warning' | 'error'
143
+ cancelDisabled?: boolean
144
+ confirmDisabled?: boolean
145
+ cancelLoading?: boolean
146
+ confirmLoading?: boolean
147
+ buttonSize?: 'small' | 'medium' | 'large'
148
+
149
+ // 弹窗配置
150
+ position?: 'center' | 'top' | 'bottom' | 'left' | 'right'
151
+ animation?: 'fade' | 'slide' | 'zoom' | 'none'
152
+ duration?: number
153
+ showOverlay?: boolean
154
+ overlayColor?: string
155
+ overlayOpacity?: number
156
+ closeOnClickOverlay?: boolean
157
+ lockScroll?: boolean
158
+ width?: string
159
+ borderRadius?: string
160
+ backgroundColor?: string
161
+ zIndex?: number
162
+ showClose?: boolean
163
+ safeAreaInsetBottom?: boolean
164
+ customClass?: string
165
+ closeOnClickAction?: boolean
166
+
167
+ // 验证函数
168
+ validator?: (value: string) => string | boolean
169
+
170
+ // 自动关闭
171
+ autoClose?: boolean
172
+ autoCloseDelay?: number
173
+
174
+ // 输入框初始值
175
+ defaultValue?: string
176
+ }
177
+
178
+ // 定义 Emits
179
+ interface Emits {
180
+ (e: 'update:show', value: boolean): void
181
+ (e: 'update:modelValue', value: boolean): void
182
+ (e: 'open'): void
183
+ (e: 'opened'): void
184
+ (e: 'close'): void
185
+ (e: 'closed'): void
186
+ (e: 'click-overlay'): void
187
+ (e: 'confirm', value?: string): void
188
+ (e: 'cancel'): void
189
+ (e: 'input', value: string): void
190
+ (e: 'focus'): void
191
+ (e: 'blur'): void
192
+ }
193
+
194
+ // 定义 Props 默认值
195
+ const props = withDefaults(defineProps<Props>(), {
196
+ show: false,
197
+ modelValue: false,
198
+
199
+ type: 'alert',
200
+
201
+ title: '',
202
+ subtitle: '',
203
+ content: '',
204
+
205
+ showHeader: true,
206
+ showSubtitle: true,
207
+ showIcon: false,
208
+
209
+ contentStyle: () => ({}),
210
+
211
+ promptLabel: '',
212
+ promptPlaceholder: '请输入',
213
+ inputType: 'text',
214
+ maxlength: 100,
215
+ showCharCount: false,
216
+ inputDisabled: false,
217
+
218
+ showFooter: true,
219
+ showCancel: true,
220
+ showConfirm: true,
221
+ cancelText: '取消',
222
+ confirmText: '确定',
223
+ cancelType: 'default',
224
+ confirmType: 'primary',
225
+ cancelDisabled: false,
226
+ confirmDisabled: false,
227
+ cancelLoading: false,
228
+ confirmLoading: false,
229
+ buttonSize: 'medium',
230
+
231
+ position: 'center',
232
+ animation: 'zoom',
233
+ duration: 300,
234
+ showOverlay: true,
235
+ overlayColor: '#000',
236
+ overlayOpacity: 0.5,
237
+ closeOnClickOverlay: true,
238
+ lockScroll: true,
239
+ width: '640rpx',
240
+ borderRadius: '16rpx',
241
+ backgroundColor: '#fff',
242
+ zIndex: 1000,
243
+ showClose: false,
244
+ safeAreaInsetBottom: true,
245
+ customClass: '',
246
+ closeOnClickAction: true,
247
+
248
+ autoClose: false,
249
+ autoCloseDelay: 3000,
250
+
251
+ defaultValue: ''
252
+ })
253
+
254
+ const emit = defineEmits<Emits>()
255
+
256
+ // 组件引用
257
+ const modalRef = ref<InstanceType<typeof ModalType>>()
258
+
259
+ // 内部状态
260
+ const visible = computed({
261
+ get: () => props.show || props.modelValue,
262
+ set: (val) => {
263
+ emit('update:show', val)
264
+ emit('update:modelValue', val)
265
+ }
266
+ })
267
+
268
+ // 输入值
269
+ const inputValue = ref(props.defaultValue)
270
+ const inputError = ref('')
271
+
272
+ // 自动关闭计时器
273
+ let autoCloseTimer: any = null
274
+
275
+ // 根据类型设置默认值
276
+ const computedTitle = computed(() => {
277
+ if (props.title) return props.title
278
+
279
+ const titleMap: Record<string, string> = {
280
+ success: '操作成功',
281
+ error: '操作失败',
282
+ warning: '警告',
283
+ info: '提示',
284
+ alert: '提示',
285
+ confirm: '确认',
286
+ prompt: '请输入'
287
+ }
288
+
289
+ return titleMap[props.type] || '提示'
290
+ })
291
+
292
+ const computedIcon = computed(() => props.showIcon || ['success', 'error', 'warning', 'info'].includes(props.type))
293
+
294
+ // 监听显示状态变化
295
+ watch(visible, (val) => {
296
+ if (val) {
297
+ // 打开时重置输入值
298
+ inputValue.value = props.defaultValue
299
+ inputError.value = ''
300
+
301
+ // 设置自动关闭 && props.type === 'alert'
302
+ if (props.autoClose) {
303
+ autoCloseTimer = setTimeout(() => {
304
+ close()
305
+ }, props.autoCloseDelay)
306
+ }
307
+ } else {
308
+ // 关闭时清除计时器
309
+ if (autoCloseTimer) {
310
+ clearTimeout(autoCloseTimer)
311
+ autoCloseTimer = null
312
+ }
313
+ }
314
+ })
315
+
316
+ // 处理打开
317
+ const handleOpen = () => {
318
+ emit('open')
319
+ }
320
+
321
+ const handleOpened = () => {
322
+ emit('opened')
323
+
324
+ // 如果是prompt类型,自动聚焦输入框
325
+ if (props.type === 'prompt') {
326
+ nextTick(() => {
327
+ // 这里可以添加输入框自动聚焦逻辑
328
+ })
329
+ }
330
+ }
331
+
332
+ // 处理关闭
333
+ const handleClose = () => {
334
+ emit('close')
335
+ }
336
+
337
+ const handleClosed = () => {
338
+ emit('closed')
339
+ }
340
+
341
+ // 处理遮罩点击
342
+ const handleClickOverlay = () => {
343
+ emit('click-overlay')
344
+ }
345
+
346
+ // 处理输入
347
+ const handleInput = (event: any) => {
348
+ const value = event.detail?.value || event.target?.value || ''
349
+ inputValue.value = value
350
+ emit('input', value)
351
+
352
+ // 验证输入
353
+ if (props.validator) {
354
+ const result = props.validator(value)
355
+ if (typeof result === 'string') {
356
+ inputError.value = result
357
+ } else if (result === false) {
358
+ inputError.value = '输入无效'
359
+ } else {
360
+ inputError.value = ''
361
+ }
362
+ }
363
+ }
364
+
365
+ // 处理输入框焦点
366
+ const handleInputFocus = () => {
367
+ emit('focus')
368
+ }
369
+
370
+ const handleInputBlur = () => {
371
+ emit('blur')
372
+ }
373
+
374
+ // 处理确认
375
+ const handleConfirm = () => {
376
+ // 验证输入
377
+ if (props.type === 'prompt' && props.validator) {
378
+ const result = props.validator(inputValue.value)
379
+ if (typeof result === 'string') {
380
+ inputError.value = result
381
+ return
382
+ } else if (result === false) {
383
+ inputError.value = '输入无效'
384
+ return
385
+ }
386
+ }
387
+
388
+ emit('confirm', inputValue.value)
389
+
390
+ if (props.closeOnClickAction) {
391
+ visible.value = false
392
+ }
393
+ }
394
+
395
+ // 处理取消
396
+ const handleCancel = () => {
397
+ emit('cancel')
398
+ if (props.closeOnClickAction) {
399
+ visible.value = false
400
+ }
401
+ }
402
+
403
+ // 打开对话框
404
+ const open = (options?: Partial<Props>) => {
405
+ if (options) {
406
+ // 这里可以动态更新props,但实际项目中可能需要更复杂的处理
407
+ // console.log('动态选项:', options)
408
+ }
409
+ modalRef.value.open()
410
+ }
411
+
412
+ // 关闭对话框
413
+ const close = () => {
414
+ modalRef.value.close()
415
+ }
416
+
417
+ // 切换显示状态
418
+ const toggle = () => {
419
+ modalRef.value.toggle()
420
+ }
421
+
422
+ // 清空输入
423
+ const clearInput = () => {
424
+ inputValue.value = ''
425
+ inputError.value = ''
426
+ }
427
+
428
+ // 暴露方法给父组件
429
+ defineExpose({
430
+ open,
431
+ close,
432
+ toggle,
433
+ clearInput
434
+ })
435
+ </script>
436
+
437
+ <style lang="scss" scoped>
438
+ .im-dialog {
439
+ &__content {
440
+ // padding: 40rpx;
441
+ text-align: center;
442
+ }
443
+
444
+ &__icon {
445
+ margin-bottom: 32rpx;
446
+
447
+ &-content {
448
+ display: inline-flex;
449
+ align-items: center;
450
+ justify-content: center;
451
+ width: 80rpx;
452
+ height: 80rpx;
453
+ border-radius: 50%;
454
+ font-size: 48rpx;
455
+ font-weight: bold;
456
+ color: white;
457
+
458
+ &--success {
459
+ background-color: #52c41a;
460
+ }
461
+
462
+ &--error {
463
+ background-color: #ff4d4f;
464
+ }
465
+
466
+ &--warning {
467
+ background-color: #faad14;
468
+ }
469
+
470
+ &--info {
471
+ background-color: #1890ff;
472
+ }
473
+ }
474
+
475
+ &-text {
476
+ line-height: 1;
477
+ }
478
+ }
479
+
480
+ &__text {
481
+ display: block;
482
+ font-size: 30rpx;
483
+ color: #666;
484
+ line-height: 1.6;
485
+ }
486
+
487
+ &__html {
488
+ font-size: 30rpx;
489
+ color: #666;
490
+ line-height: 1.6;
491
+ text-align: left;
492
+ }
493
+
494
+ &__prompt {
495
+ text-align: left;
496
+ // padding:20rpx;
497
+ // border:solid 1px red;
498
+ }
499
+
500
+ &__prompt-label {
501
+ display: block;
502
+ font-size: 28rpx;
503
+ color: #333;
504
+ margin-bottom: 16rpx;
505
+ }
506
+
507
+ &__input {
508
+ // width: 100%;
509
+ padding: 24rpx;
510
+ border: 2rpx solid #dcdfe6;
511
+ border-radius: 8rpx;
512
+ font-size: 28rpx;
513
+ background-color: #fff;
514
+ transition: border-color 0.3s;
515
+
516
+ &:focus {
517
+ border-color: #409eff;
518
+ outline: none;
519
+ }
520
+
521
+ &:disabled {
522
+ background-color: #f5f7fa;
523
+ color: #c0c4cc;
524
+ cursor: not-allowed;
525
+ }
526
+ }
527
+
528
+ &__char-count {
529
+ display: block;
530
+ text-align: right;
531
+ font-size: 24rpx;
532
+ color: #999;
533
+ margin-top: 12rpx;
534
+ }
535
+
536
+ &__input-error {
537
+ display: block;
538
+ font-size: 24rpx;
539
+ color: #ff4d4f;
540
+ margin-top: 12rpx;
541
+ }
542
+ }
543
+ </style>