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,489 @@
1
+ <!-- components/im-tabs/tabs-navigation.vue -->
2
+ <template>
3
+ <view ref="navRef" :class="[
4
+ 'im-tabs-nav',
5
+ navClass,
6
+ {
7
+ 'im-tabs-nav-scrollable': scrollable,
8
+ 'im-tabs-nav-centered': centered && !scrollable
9
+ }
10
+ ]" :style="navStyle" :scroll-x="scrollable" :scroll-with-animation="true" :scroll-left="scrollLeft"
11
+ :scroll-into-view="scrollIntoView" @scroll="onScroll">
12
+ <!-- 标签项 -->
13
+ <view v-for="(item, index) in items" :key="item.id || index" :id="`tab-${index}`" :class="[
14
+ 'im-tabs-tab',
15
+ item.class,
16
+ `im-tabs-tab-icon-${iconPosition}`,
17
+ {
18
+ 'im-tabs-tab-active': currentIndex === index,
19
+ 'im-tabs-tab-disabled': item.disabled
20
+ }
21
+ ]" :style="[tabStyle, item.style]" :data-index="index" @click="handleTabClick(index, item)"
22
+ @touchstart="onTouchStart">
23
+ <!-- 自定义渲染 -->
24
+ <template v-if="item.renderTitle">
25
+ <view class="im-tabs-tab-content">
26
+ {{ item.renderTitle(item, currentIndex === index) }}
27
+ </view>
28
+ </template>
29
+
30
+ <template v-else>
31
+ <view class="im-tabs-tab-content"
32
+ :class="{ 'im-tabs-tab-content-badge': item.badge || item.badgeType === 'dot' }">
33
+ <!-- 图标 -->
34
+ <im-icon v-if="showIcon && (item.icon || item.activeIcon)"
35
+ :name="currentIndex === index && item.activeIcon ? item.activeIcon : item.icon"
36
+ class="im-tabs-tab-icon" :color="getIconColor(item, index)" />
37
+
38
+ <!-- 徽标 -->
39
+ <template v-if="item.badge || item.badgeType === 'dot'">
40
+ <im-badge v-if="item.badgeType === 'dot'" size="small" dot>
41
+ <!-- 标题 -->
42
+ <text class="im-tabs-tab-title">
43
+ {{ item.title }}
44
+ </text>
45
+ </im-badge>
46
+ <im-badge v-else-if="item.badgeType === 'number' && item.badge" size="small"
47
+ :value="item.badge">
48
+ <!-- 标题 -->
49
+ <text class="im-tabs-tab-title">
50
+ {{ item.title }}
51
+ </text>
52
+ </im-badge>
53
+ <im-badge v-else-if="item.badgeType === 'text' && item.badge" size="small" :value="item.badge">
54
+ <!-- 标题 -->
55
+ <text class="im-tabs-tab-title">
56
+ {{ item.title }}
57
+ </text>
58
+ </im-badge>
59
+ </template>
60
+ <!-- 标题 -->
61
+ <text v-else class="im-tabs-tab-title">
62
+ {{ item.title }}
63
+ </text>
64
+ </view>
65
+ </template>
66
+ </view>
67
+
68
+ <!-- 滑动条 -->
69
+ <view v-if="showSlider && type === 'line'" class="im-tabs-slider" :style="sliderStyle" />
70
+ </view>
71
+ </template>
72
+
73
+ <script lang="ts" setup>
74
+ import { ref, computed, watch, inject } from 'vue'
75
+ import type { TabItem } from '../../types/components/tabs'
76
+
77
+ // 注入父组件数据
78
+ const tabsData = inject<any>('tabs')
79
+
80
+ if (!tabsData) {
81
+ console.error('tabs-navigation: 未找到父组件注入的 tabs 数据')
82
+ }
83
+
84
+ const {
85
+ items = [],
86
+ type = 'line',
87
+ showSlider = true,
88
+ sliderStyle = {},
89
+ scrollable = false,
90
+ centered = false,
91
+ gutter = 0,
92
+ showIcon = false,
93
+ iconPosition = 'left',
94
+ minTabWidth = 0,
95
+ maxTabWidth = 0,
96
+ onTabClick,
97
+ navClass = ''
98
+ } = tabsData || {}
99
+
100
+ const navRef = ref<any>(null)
101
+ const scrollLeft = ref(0)
102
+ const scrollIntoView = ref('')
103
+
104
+ // 定义属性
105
+ const props = defineProps<{
106
+ currentIndex: 0
107
+ }>()
108
+
109
+ // 监听 currentIndex 变化,更新 scroll-into-view
110
+ watch(() => props.currentIndex, (newVal) => {
111
+ if (scrollable && newVal >= 0) {
112
+ scrollIntoView.value = `tab-${newVal}`
113
+
114
+ // 在小程序环境中,延迟更新以确保生效
115
+ setTimeout(() => {
116
+ scrollIntoView.value = `tab-${newVal}`
117
+ }, 50)
118
+ }
119
+ }, { immediate: true })
120
+
121
+ // 计算属性
122
+ const navStyle = computed(() => {
123
+ const style: Record<string, any> = {}
124
+
125
+ if (gutter > 0) {
126
+ style.gap = `${gutter}px`
127
+ }
128
+
129
+ // 如果是可滚动模式,设置滚动相关样式
130
+ if (scrollable) {
131
+ style.whiteSpace = 'nowrap'
132
+ style.display = 'flex'
133
+ style.flexWrap = 'nowrap'
134
+ }
135
+
136
+ return style
137
+ })
138
+
139
+ const tabStyle = computed(() => {
140
+ const style: Record<string, any> = {}
141
+
142
+ if (minTabWidth > 0) {
143
+ style.minWidth = `${minTabWidth}px`
144
+ }
145
+
146
+ if (maxTabWidth > 0) {
147
+ style.maxWidth = `${maxTabWidth}px`
148
+ }
149
+
150
+ if (centered && !scrollable) {
151
+ style.flex = 1
152
+ }
153
+
154
+ // 如果是可滚动模式,设置为行内块元素
155
+ if (scrollable) {
156
+ style.display = 'inline-flex'
157
+ style.flexShrink = 0
158
+ }
159
+
160
+ return style
161
+ })
162
+
163
+ // 获取图标颜色
164
+ const getIconColor = (item: TabItem, index: number | string) => {
165
+ if (item.disabled) {
166
+ return '#c8c9cc'
167
+ }
168
+
169
+ if (props.currentIndex === index) {
170
+ return '#1989fa'
171
+ }
172
+
173
+ return '#646566'
174
+ }
175
+
176
+ // 触摸开始
177
+ const onTouchStart = () => {
178
+ // 可以在这里添加触摸反馈
179
+ }
180
+
181
+ // 滚动事件
182
+ const onScroll = (event: any) => {
183
+ if (scrollable) {
184
+ scrollLeft.value = event.detail?.scrollLeft || 0
185
+ }
186
+ }
187
+
188
+ // 标签点击
189
+ const handleTabClick = (index: number | string, tab: TabItem) => {
190
+ if (onTabClick) {
191
+ onTabClick(index, tab)
192
+ }
193
+ }
194
+
195
+ // 暴露方法供父组件调用
196
+ defineExpose({
197
+ getNavRef: () => navRef.value,
198
+ getScrollLeft: () => scrollLeft.value
199
+ })
200
+ </script>
201
+
202
+ <style lang="scss" scoped>
203
+ .im-tabs-nav {
204
+ display: flex;
205
+ position: relative;
206
+ flex-shrink: 0;
207
+ z-index: 1;
208
+ overflow: hidden;
209
+
210
+ // 水平布局
211
+ .im-tabs-top &,
212
+ .im-tabs-bottom & {
213
+ flex-direction: row;
214
+ }
215
+
216
+ // 垂直布局
217
+ .im-tabs-left &,
218
+ .im-tabs-right & {
219
+ flex-direction: column;
220
+ width: auto;
221
+ min-width: 80px;
222
+ max-width: 200px;
223
+ }
224
+
225
+ // 可滚动模式
226
+ &-scrollable {
227
+ flex-wrap: nowrap;
228
+ overflow-x: auto;
229
+ -webkit-overflow-scrolling: touch;
230
+
231
+ &::-webkit-scrollbar {
232
+ display: none;
233
+ }
234
+
235
+ .im-tabs-tab {
236
+ flex-shrink: 0;
237
+ }
238
+ }
239
+
240
+ // 居中模式(非滚动时)
241
+ &-centered {
242
+ justify-content: center;
243
+ }
244
+ }
245
+
246
+ .im-tabs-tab {
247
+ position: relative;
248
+ display: flex;
249
+ align-items: center;
250
+ justify-content: center;
251
+ flex-shrink: 0;
252
+ cursor: pointer;
253
+ transition: all 0.3s;
254
+ user-select: none;
255
+ padding: 0 12px;
256
+ box-sizing: border-box;
257
+
258
+ // 水平布局
259
+ .im-tabs-top &,
260
+ .im-tabs-bottom & {
261
+ height: 100%;
262
+ }
263
+
264
+ // 垂直布局
265
+ .im-tabs-left &,
266
+ .im-tabs-right & {
267
+ width: 100%;
268
+ padding: 12px;
269
+ justify-content: flex-start;
270
+ }
271
+
272
+ // 禁用状态
273
+ &-disabled {
274
+ cursor: not-allowed;
275
+ opacity: 0.5;
276
+
277
+ &:active {
278
+ opacity: 0.5;
279
+ }
280
+ }
281
+
282
+ // 激活状态
283
+ &-active {
284
+ font-weight: 600;
285
+ }
286
+
287
+ // 图标位置
288
+ &-icon-left {
289
+ flex-direction: row;
290
+
291
+ .im-tabs-tab-icon {
292
+ margin-right: 4px;
293
+ }
294
+ }
295
+
296
+ &-icon-right {
297
+ flex-direction: row-reverse;
298
+
299
+ .im-tabs-tab-icon {
300
+ margin-left: 4px;
301
+ }
302
+ }
303
+
304
+ &-icon-top {
305
+ flex-direction: column;
306
+
307
+ .im-tabs-tab-icon {
308
+ margin-bottom: 4px;
309
+ }
310
+ }
311
+
312
+ &-icon-bottom {
313
+ flex-direction: column-reverse;
314
+
315
+ .im-tabs-tab-icon {
316
+ margin-top: 4px;
317
+ }
318
+ }
319
+ }
320
+
321
+ .im-tabs-tab-content {
322
+ display: flex;
323
+ align-items: center;
324
+ justify-content: center;
325
+ position: relative;
326
+ white-space: nowrap;
327
+
328
+ &-badge {
329
+ height: 77rpx;
330
+ }
331
+ }
332
+
333
+ .im-tabs-tab-title {
334
+ font-size: 14px;
335
+ line-height: 1.4;
336
+ transition: color 0.3s;
337
+
338
+ .im-tabs-line & {
339
+ color: #646566;
340
+ }
341
+
342
+ .im-tabs-tab-active & {
343
+ color: #1989fa;
344
+ }
345
+
346
+ .im-tabs-card &,
347
+ .im-tabs-button &,
348
+ .im-tabs-segment & {
349
+ color: #323233;
350
+ }
351
+
352
+ .im-tabs-card &-active,
353
+ .im-tabs-button &-active,
354
+ .im-tabs-segment &-active {
355
+ color: #1989fa;
356
+ }
357
+ }
358
+
359
+ .im-tabs-tab-icon {
360
+ display: flex;
361
+ align-items: center;
362
+ justify-content: center;
363
+ font-size: 18px;
364
+ transition: color 0.3s;
365
+
366
+ .im-tabs-line & {
367
+ color: #646566;
368
+ }
369
+
370
+ .im-tabs-tab-active & {
371
+ color: #1989fa;
372
+ }
373
+ }
374
+
375
+ // 滑动条
376
+ .im-tabs-slider {
377
+ position: absolute;
378
+ bottom: 0;
379
+ left: 0;
380
+ z-index: 1;
381
+ border-radius: 2px;
382
+
383
+ .im-tabs-bottom & {
384
+ top: 0;
385
+ bottom: auto;
386
+ }
387
+
388
+ .im-tabs-left & {
389
+ right: 0;
390
+ left: auto;
391
+ top: 0;
392
+ width: 2px;
393
+ height: auto;
394
+ }
395
+
396
+ .im-tabs-right & {
397
+ left: 0;
398
+ top: 0;
399
+ width: 2px;
400
+ height: auto;
401
+ }
402
+ }
403
+
404
+ // 不同类型
405
+ .im-tabs-nav {
406
+ .im-tabs-line & {
407
+ .im-tabs-tab {
408
+ background-color: transparent;
409
+ }
410
+ }
411
+
412
+ .im-tabs-card & {
413
+ background-color: #f2f3f5;
414
+ padding: 4px;
415
+ border-radius: 8px;
416
+
417
+ .im-tabs-tab {
418
+ background-color: transparent;
419
+ border-radius: 6px;
420
+ margin: 0 2px;
421
+
422
+ &-active {
423
+ background-color: #ffffff;
424
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
425
+ }
426
+ }
427
+ }
428
+
429
+ .im-tabs-button & {
430
+ .im-tabs-tab {
431
+ border: 1px solid #ebedf0;
432
+ margin: 0 4px;
433
+ border-radius: 20px;
434
+
435
+ &:first-child {
436
+ margin-left: 0;
437
+ }
438
+
439
+ &:last-child {
440
+ margin-right: 0;
441
+ }
442
+
443
+ &-active {
444
+ border-color: #1989fa;
445
+ background-color: #1989fa;
446
+
447
+ .im-tabs-tab-title,
448
+ .im-tabs-tab-icon {
449
+ color: #ffffff;
450
+ }
451
+ }
452
+ }
453
+ }
454
+
455
+ .im-tabs-segment & {
456
+ background-color: #f2f3f5;
457
+ border-radius: 20px;
458
+ padding: 2px;
459
+
460
+ .im-tabs-tab {
461
+ flex: 1;
462
+ border-radius: 18px;
463
+
464
+ &-active {
465
+ background-color: #ffffff;
466
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
467
+ }
468
+ }
469
+ }
470
+ }
471
+
472
+ // 响应式
473
+ @media (max-width: 768px) {
474
+ .im-tabs-tab-title {
475
+ font-size: 13px;
476
+ }
477
+
478
+ .im-tabs-tab-icon {
479
+ font-size: 16px;
480
+ }
481
+
482
+ .im-tabs-left,
483
+ .im-tabs-right {
484
+ .im-tabs-nav {
485
+ min-width: 70px;
486
+ }
487
+ }
488
+ }
489
+ </style>
@@ -0,0 +1,181 @@
1
+ import type { TabItem } from '../../../types/components/tabs'
2
+
3
+ /**
4
+ * 验证标签页配置
5
+ */
6
+ export function validateTabsConfig(config: any) {
7
+ const errors: string[] = []
8
+
9
+ if (!Array.isArray(config.items)) {
10
+ errors.push('items 必须是数组')
11
+ }
12
+
13
+ if (config.height && config.height < 30) {
14
+ errors.push('高度不能小于30px')
15
+ }
16
+
17
+ if (config.duration && config.duration < 0) {
18
+ errors.push('动画持续时间不能为负数')
19
+ }
20
+
21
+ return errors
22
+ }
23
+
24
+ /**
25
+ * 计算标签宽度
26
+ */
27
+ export function calculateTabWidth(
28
+ tabs: TabItem[],
29
+ options: {
30
+ containerWidth?: number
31
+ minTabWidth?: number
32
+ maxTabWidth?: number
33
+ gutter?: number
34
+ centered?: boolean
35
+ }
36
+ ): number {
37
+ if (!tabs.length) return 0
38
+
39
+ const { containerWidth = 0, minTabWidth = 0, maxTabWidth = 0, gutter = 0, centered = false } = options
40
+
41
+ // 如果有容器宽度,计算合适的宽度
42
+ if (containerWidth > 0) {
43
+ const availableWidth = containerWidth - gutter * (tabs.length - 1)
44
+ let calculatedWidth = availableWidth / tabs.length
45
+
46
+ // 应用最小和最大宽度限制
47
+ if (minTabWidth > 0) {
48
+ calculatedWidth = Math.max(calculatedWidth, minTabWidth)
49
+ }
50
+
51
+ if (maxTabWidth > 0) {
52
+ calculatedWidth = Math.min(calculatedWidth, maxTabWidth)
53
+ }
54
+
55
+ return calculatedWidth
56
+ }
57
+
58
+ // 如果没有容器宽度,返回0(使用内容自适应)
59
+ return 0
60
+ }
61
+
62
+ /**
63
+ * 获取激活的标签索引
64
+ */
65
+ export function getActiveIndex(
66
+ items: TabItem[],
67
+ modelValue?: number,
68
+ activeKey?: string | number
69
+ ): number {
70
+ if (activeKey !== undefined) {
71
+ const index = items.findIndex(item =>
72
+ (item.id !== undefined && item.id === activeKey) ||
73
+ item.title === activeKey
74
+ )
75
+ if (index !== -1) return index
76
+ }
77
+
78
+ if (modelValue !== undefined) {
79
+ return Math.max(0, Math.min(modelValue, items.length - 1))
80
+ }
81
+
82
+ return 0
83
+ }
84
+
85
+ /**
86
+ * 更新标签徽标
87
+ */
88
+ export function updateTabBadge(
89
+ items: TabItem[],
90
+ index: number,
91
+ badge: number | string,
92
+ type: 'number' | 'text' = 'number'
93
+ ): TabItem[] {
94
+ return items.map((item, i) => {
95
+ if (i === index) {
96
+ return {
97
+ ...item,
98
+ badge: typeof badge === 'number' ? badge : undefined,
99
+ badgeText: typeof badge === 'string' ? badge : undefined,
100
+ badgeType: type
101
+ }
102
+ }
103
+ return item
104
+ })
105
+ }
106
+
107
+ /**
108
+ * 更新标签红点状态
109
+ */
110
+ export function updateTabRedDot(
111
+ items: TabItem[],
112
+ index: number,
113
+ showRedDot: boolean
114
+ ): TabItem[] {
115
+ return items.map((item, i) => {
116
+ if (i === index) {
117
+ return {
118
+ ...item,
119
+ showRedDot
120
+ }
121
+ }
122
+ return item
123
+ })
124
+ }
125
+
126
+ /**
127
+ * 禁用/启用标签
128
+ */
129
+ export function toggleTabDisabled(
130
+ items: TabItem[],
131
+ index: number,
132
+ disabled: boolean
133
+ ): TabItem[] {
134
+ return items.map((item, i) => {
135
+ if (i === index) {
136
+ return {
137
+ ...item,
138
+ disabled
139
+ }
140
+ }
141
+ return item
142
+ })
143
+ }
144
+
145
+ /**
146
+ * 生成标签样式
147
+ */
148
+ export function generateTabStyles(options: {
149
+ type?: string
150
+ position?: string
151
+ height?: number
152
+ background?: string
153
+ border?: boolean
154
+ }): Record<string, any> {
155
+ const styles: Record<string, any> = {}
156
+
157
+ // 基础样式
158
+ if (options.height) {
159
+ styles.height = `${options.height}px`
160
+ }
161
+
162
+ if (options.background) {
163
+ styles.backgroundColor = options.background
164
+ }
165
+
166
+ // 位置相关样式
167
+ if (options.position === 'left' || options.position === 'right') {
168
+ styles.flexDirection = 'column'
169
+ }
170
+
171
+ // 边框样式
172
+ if (options.border) {
173
+ if (options.position === 'top') {
174
+ styles.borderBottom = '1px solid #ebedf0'
175
+ } else if (options.position === 'bottom') {
176
+ styles.borderTop = '1px solid #ebedf0'
177
+ }
178
+ }
179
+
180
+ return styles
181
+ }