distinctui-uni 0.0.1 → 0.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.
package/README.md CHANGED
@@ -16,7 +16,7 @@ uni-app 项目 pages.json 配置
16
16
  "easycom": {
17
17
  "autoscan": true,
18
18
  "custom": {
19
- "dist-(.*)": "distinctui-uni/components/distinctui/dist-$1/dist-$1.vue"
19
+ "d-(.*)": "distinctui-uni/components/distinctui/d-$1/d-$1.vue"
20
20
  }
21
21
  }
22
22
  ```
@@ -0,0 +1,385 @@
1
+ <template>
2
+ <view
3
+ class="d-button__wrap"
4
+ :style="{
5
+ maxWidth: maxWidth,
6
+ minWidth: minWidth,
7
+ width: getWidth,
8
+ height: getHeight,
9
+ borderRadius: getBorderRadius,
10
+ margin: getMargin
11
+ }"
12
+ >
13
+ <button
14
+ class="d-button"
15
+ :class="{ 'd-button__ellipse': ellipsis }"
16
+ :loading="loading"
17
+ :style="{
18
+ maxWidth: maxWidth,
19
+ minWidth: minWidth,
20
+ width: getWidth,
21
+ height: getHeight,
22
+ borderRadius: getRadius,
23
+ backgroundColor: getBackgroundColor,
24
+ color: getColor,
25
+ borderColor: getBorderColor,
26
+ padding: padding,
27
+ fontSize: getFontSize
28
+ }"
29
+ :hover-class="!loading && !disabled && type ? `d-button-hover--${type}` : 'none'"
30
+ :form-type="formType"
31
+ :open-type="openType"
32
+ :app-parameter="appParameter"
33
+ @getuserinfo="bindGetUserInfo"
34
+ @getphonenumber="bindGetPhoneNumber"
35
+ @contact="bindContact"
36
+ @error="bindError"
37
+ @opensetting="bindOpenSetting"
38
+ @chooseavatar="bindChooseAvatar"
39
+ @launchapp="bindLaunchApp"
40
+ :disabled="disabled"
41
+ :scope="scope"
42
+ @tap.stop="handleTap"
43
+ >
44
+ <text v-if="text">{{ text }}</text>
45
+ <slot></slot>
46
+ </button>
47
+ <!-- <view
48
+ class="d-button_thin-border"
49
+ :style="{
50
+ borderRadius: getBorderRadius,
51
+ borderColor: getBorderColor
52
+ }"
53
+ ></view> -->
54
+ </view>
55
+ </template>
56
+
57
+ <script>
58
+ const BTN_SIZE = {
59
+ normal: {
60
+ height: "80rpx",
61
+ radius: "50rpx",
62
+ fontSize: "32rpx"
63
+ },
64
+ small: {
65
+ height: "68rpx",
66
+ radius: "40rpx",
67
+ fontSize: "28rpx"
68
+ },
69
+ mini: {
70
+ height: "58rpx",
71
+ radius: "30rpx",
72
+ fontSize: "24rpx"
73
+ }
74
+ };
75
+ const TYPE_STYLE = {
76
+ // 一级按钮
77
+ primary: {
78
+ styles: {
79
+ borderColor: "#006D83",
80
+ backgroundColor: "#006D83",
81
+ color: "#FFFFFF"
82
+ },
83
+ disabledStyles: {
84
+ backgroundColor: "rgba(0,111,131,0.28)",
85
+ color: "#FFFFFF"
86
+ }
87
+ },
88
+ // 二级按钮
89
+ secondary: {
90
+ styles: {
91
+ borderColor: "#006D83",
92
+ backgroundColor: "#FFFFFF",
93
+ color: "#006D83"
94
+ },
95
+ disabledStyles: {
96
+ backgroundColor: "rgba(0,111,131,0.28)",
97
+ color: "#FFFFFF"
98
+ }
99
+ },
100
+ // 三级按钮
101
+ tertiary: {
102
+ styles: {
103
+ borderColor: "#E1E1E1",
104
+ backgroundColor: "#FFFFFF",
105
+ color: "#006D83"
106
+ },
107
+ disabledStyles: {
108
+ borderColor: "#E1E1E1",
109
+ backgroundColor: "#FFFFFF",
110
+ color: "#E1E1E1"
111
+ }
112
+ },
113
+ // 警示按钮
114
+ danger: {
115
+ styles: {
116
+ backgroundColor: "#FF5B4C",
117
+ color: "#FFFFFF"
118
+ },
119
+ disabledStyles: {
120
+ backgroundColor: "rgba(255,91,76,0.28)",
121
+ color: "#FFFFFF"
122
+ }
123
+ }
124
+ };
125
+ export default {
126
+ name: "d-button",
127
+ emits: ["click", "getuserinfo", "contact", "getphonenumber", "error", "opensetting"],
128
+ behaviors: ["uni://form-field"],
129
+ props: {
130
+ // 按钮类型:primary,secondary,tertiary,danger
131
+ type: {
132
+ type: String,
133
+ default: "primary"
134
+ },
135
+ // 按钮背景色,当传入值时type失效
136
+ background: {
137
+ type: String,
138
+ default: ""
139
+ },
140
+ borderColor: {
141
+ type: String,
142
+ default: ""
143
+ },
144
+ // 按钮显示文本
145
+ text: {
146
+ type: String,
147
+ default: ""
148
+ },
149
+ // 按钮字体颜色
150
+ color: {
151
+ type: String,
152
+ default: "#FFFFFF"
153
+ },
154
+ // 是否显示加载图标
155
+ loading: {
156
+ type: Boolean,
157
+ default: false
158
+ },
159
+ // 是否禁用
160
+ disabled: {
161
+ type: Boolean,
162
+ default: false
163
+ },
164
+ // 按钮宽度
165
+ width: {
166
+ type: String,
167
+ default: "100%"
168
+ },
169
+ // 按钮最大宽度
170
+ maxWidth: {
171
+ type: String,
172
+ default: ""
173
+ },
174
+ // 按钮最小宽度
175
+ minWidth: {
176
+ type: String,
177
+ default: ""
178
+ },
179
+ // 按钮高度
180
+ height: {
181
+ type: String,
182
+ default: ""
183
+ },
184
+ // 圆角大小
185
+ radius: {
186
+ type: String,
187
+ default: "50rpx"
188
+ },
189
+ // 外边距
190
+ margin: {
191
+ type: String,
192
+ default: "0"
193
+ },
194
+ // 内边距,默认左右间距为16
195
+ padding: {
196
+ type: String,
197
+ default: "0 16rpx"
198
+ },
199
+ // 按钮大小,设置height后按钮的size失效
200
+ size: {
201
+ type: String,
202
+ default: "normal"
203
+ },
204
+ // 是否超过省略
205
+ ellipsis: {
206
+ type: Boolean,
207
+ default: true
208
+ },
209
+ formType: {
210
+ type: String,
211
+ default: ""
212
+ },
213
+ openType: {
214
+ type: String,
215
+ default: ""
216
+ },
217
+ appParameter: {
218
+ type: String,
219
+ default: ""
220
+ }
221
+ },
222
+ computed: {
223
+ getMargin() {
224
+ return this.margin || 0;
225
+ },
226
+ getTypeStyle() {
227
+ return TYPE_STYLE[this.type] || {};
228
+ },
229
+ getButtonStyle() {
230
+ const typeStyles = this.getTypeStyle;
231
+ if (this.disabled) {
232
+ return typeStyles.disabledStyles || {};
233
+ } else if (this.loading) {
234
+ // loading字体颜色需加透明度,这里用16进制实现,34%透明度为0x56
235
+ return { ...typeStyles.styles, color: `${typeStyles.styles.color}56` };
236
+ } else {
237
+ return typeStyles.styles || {};
238
+ }
239
+ },
240
+ getBackgroundColor() {
241
+ let backgroundColor = this.background || this.getButtonStyle?.backgroundColor;
242
+ return backgroundColor || "transparent";
243
+ },
244
+ getBorderColor() {
245
+ if (this.background && !this.borderColor) return "transparent";
246
+ let borderColor = this.borderColor || this.getButtonStyle?.borderColor;
247
+ return borderColor || "transparent";
248
+ },
249
+ getWidth() {
250
+ let width = this.width;
251
+ return width;
252
+ },
253
+ getHeight() {
254
+ let height = this.height;
255
+ if (this.size) {
256
+ height = BTN_SIZE[this.size].height || height;
257
+ }
258
+ return height;
259
+ },
260
+ getBorderRadius() {
261
+ let radius = this.radius || BTN_SIZE[this.size].radius;
262
+ radius = this.radius || radius;
263
+ const unitConfig = ["rpx", "px", "%"];
264
+ unitConfig.some(i => {
265
+ if (~radius.indexOf(i)) {
266
+ radius = Number(radius.replace(i, "")) * 2 + i;
267
+ return true;
268
+ }
269
+ return false;
270
+ });
271
+ return radius;
272
+ },
273
+ getRadius() {
274
+ const radius = this.radius || BTN_SIZE[this.size].radius;
275
+ return radius;
276
+ },
277
+ getColor() {
278
+ return this.getButtonStyle?.color || "#FFFFFF";
279
+ },
280
+ getFontSize() {
281
+ const fontSize = this.fontSize || BTN_SIZE[this.size].fontSize;
282
+ return fontSize;
283
+ }
284
+ },
285
+ data() {
286
+ return {};
287
+ },
288
+ methods: {
289
+ handleTap() {
290
+ if (this.disabled) return;
291
+ this.$emit("click");
292
+ },
293
+ bindGetUserInfo({ detail = {} } = {}) {
294
+ this.$emit("getuserinfo", detail);
295
+ },
296
+ bindContact({ detail = {} } = {}) {
297
+ this.$emit("contact", detail);
298
+ },
299
+ bindGetPhoneNumber({ detail = {} } = {}) {
300
+ this.$emit("getphonenumber", detail);
301
+ },
302
+ bindError({ detail = {} } = {}) {
303
+ this.$emit("error", detail);
304
+ },
305
+ bindOpenSetting({ detail = {} } = {}) {
306
+ this.$emit("opensetting", detail);
307
+ },
308
+ bindChooseAvatar({ detail = {} } = {}) {
309
+ this.$emit("chooseavatar", detail);
310
+ },
311
+ bindLaunchApp({ detail = {} } = {}) {
312
+ this.$emit("launchapp", detail);
313
+ }
314
+ }
315
+ };
316
+ </script>
317
+
318
+ <style lang="less" scoped>
319
+ .d-button__wrap {
320
+ position: relative;
321
+ }
322
+ .d-button {
323
+ border-width: 2rpx;
324
+ display: flex;
325
+ align-items: center;
326
+ justify-content: center;
327
+ box-sizing: border-box;
328
+ border-style: solid;
329
+ position: relative;
330
+ padding-left: 0;
331
+ padding-right: 0;
332
+ overflow: hidden;
333
+ transform: translateZ(0);
334
+ user-select: none;
335
+ }
336
+ .d-button_thin-border {
337
+ position: absolute;
338
+ width: 200%;
339
+ height: 200%;
340
+ transform-origin: 0 0;
341
+ transform: scale(0.5, 0.5) translateZ(0);
342
+ box-sizing: border-box;
343
+ left: 0;
344
+ top: 0;
345
+ border-width: 2rpx;
346
+ border-radius: 32rpx;
347
+ border-style: solid;
348
+ pointer-events: none;
349
+ }
350
+
351
+ .d-button-hover--primary {
352
+ background-color: #005667 !important;
353
+ }
354
+
355
+ .d-button-hover--secondary {
356
+ background-color: #daecee !important;
357
+ }
358
+
359
+ .d-button-hover--tertiary {
360
+ background-color: #e1e1e1 !important;
361
+ }
362
+
363
+ .d-button-hover--danger {
364
+ background-color: #e04335 !important;
365
+ }
366
+
367
+ .d-button__flex-1 {
368
+ flex: 1;
369
+ width: 100%;
370
+ }
371
+
372
+ .d-button::after {
373
+ border: 0;
374
+ }
375
+
376
+ .d-button__ellipse {
377
+ word-break: break-all;
378
+ text-overflow: ellipsis;
379
+ display: -webkit-box;
380
+ /*! autoprefixer: off */
381
+ -webkit-box-orient: vertical;
382
+ -webkit-line-clamp: 1;
383
+ overflow: hidden;
384
+ }
385
+ </style>
@@ -0,0 +1,242 @@
1
+ <template>
2
+ <view
3
+ @tap="maskClose"
4
+ :style="{ background: maskBackground }"
5
+ class="d-dialog__wrap"
6
+ :class="{ 'd-wrap__show': show }"
7
+ @touchmove.stop.prevent="stop"
8
+ v-if="visible"
9
+ ref="d_dialog_ani"
10
+ >
11
+ <view class="d-dialog__inner" :style="{ background: background, borderRadius: radius + 'rpx', marginTop: `-${contentTop}px` }" @tap.stop="stop">
12
+ <slot name="top"></slot>
13
+ <text class="d-dialog__title" :style="{ color: titleColor }" v-if="title">{{ title }}</text>
14
+ <view class="d-dialog__body" :class="{ 'd-dialog__mtop': !title }">
15
+ <text class="d-dialog__desc" :style="{ color: contentColor }" v-if="content">{{ content }}</text>
16
+ <slot></slot>
17
+ </view>
18
+ <view class="d-dialog__footer" :class="{ 'd-dialog__footer--vertical': layout === 'vertical' }">
19
+ <text
20
+ v-for="(item, index) in buttons"
21
+ :key="index"
22
+ :style="{ color: item.color || '#333333' }"
23
+ class="d-dialog__btn"
24
+ :class="{ 'd-dialog__btn--vertical': layout === 'vertical', 'd-dialog__btn-first': index === 0 }"
25
+ @tap="handleClick(index)"
26
+ >
27
+ {{ item.text }}
28
+ </text>
29
+ </view>
30
+ </view>
31
+ </view>
32
+ </template>
33
+
34
+ <script>
35
+ const animation = uni.createAnimation({
36
+ duration: 200,
37
+ timingFunction: "ease-in"
38
+ });
39
+ export default {
40
+ name: "d-dialog",
41
+ emits: ["click"],
42
+ props: {
43
+ show: {
44
+ type: Boolean,
45
+ default: false
46
+ },
47
+ title: {
48
+ type: String,
49
+ default: ""
50
+ },
51
+ titleColor: {
52
+ type: String,
53
+ default: "#333"
54
+ },
55
+ content: {
56
+ type: String,
57
+ default: ""
58
+ },
59
+ contentColor: {
60
+ type: String,
61
+ default: "#333"
62
+ },
63
+ // 布局;vertical, default
64
+ layout: {
65
+ type: String,
66
+ default: "default"
67
+ },
68
+ buttons: {
69
+ type: Array,
70
+ default() {
71
+ return [];
72
+ }
73
+ },
74
+ background: {
75
+ type: String,
76
+ default: "#ffffff"
77
+ },
78
+ radius: {
79
+ type: [Number, String],
80
+ default: "24rpx"
81
+ },
82
+ maskBackground: {
83
+ type: String,
84
+ default: "rgba(0,0,0,.6)"
85
+ },
86
+ // 点击遮罩是否关闭,前提show需要sync
87
+ maskClosable: {
88
+ type: Boolean,
89
+ default: true
90
+ }
91
+ },
92
+ data() {
93
+ return {
94
+ visible: false,
95
+ contentTop: 0 // 状态栏加导航栏高度
96
+ };
97
+ },
98
+ mounted() {
99
+ const systemInfo = uni.getSystemInfoSync();
100
+ if (!systemInfo) return;
101
+ this.contentTop = systemInfo.screenHeight - systemInfo.windowHeight; // 屏幕高度 - 可使用高度
102
+ },
103
+ watch: {
104
+ show: {
105
+ handler(newVal) {
106
+ if (newVal) {
107
+ this.open();
108
+ } else {
109
+ this.close();
110
+ }
111
+ },
112
+ immediate: true
113
+ }
114
+ },
115
+ methods: {
116
+ handleClick(index) {
117
+ this.$emit("click", {
118
+ index,
119
+ ...this.buttons[index]
120
+ });
121
+ },
122
+ maskClose() {
123
+ if (!this.maskClosable) return;
124
+ this.$emit("update:show", false);
125
+ },
126
+ open() {
127
+ this.visible = true;
128
+ this.$nextTick(() => {
129
+ setTimeout(() => {
130
+ this._animation(true);
131
+ }, 50);
132
+ });
133
+ },
134
+ close(type) {
135
+ this._animation(false);
136
+ },
137
+ _animation(type) {
138
+ animation.opacity(type ? 1 : 0).step();
139
+ if (!this.$refs["d_dialog_ani"]) return;
140
+ this.$refs["d_dialog_ani"].ref.animate(animation.export(), () => {
141
+ this.visible = type;
142
+ });
143
+ },
144
+ stop() {}
145
+ }
146
+ };
147
+ </script>
148
+
149
+ <style scoped>
150
+ .d-dialog__wrap {
151
+ position: fixed;
152
+ z-index: 996;
153
+ top: 0;
154
+ right: 0;
155
+ left: 0;
156
+ bottom: 0;
157
+ transition-property: all;
158
+ transition-timing-function: ease-in;
159
+ transition-duration: 0.2s;
160
+ display: flex;
161
+ transform: scale3d(1, 1, 0);
162
+ visibility: hidden;
163
+ align-items: center;
164
+ justify-content: center;
165
+ opacity: 0;
166
+ }
167
+
168
+ .d-dialog__inner {
169
+ width: 680rpx;
170
+ overflow: hidden;
171
+ display: flex;
172
+ max-height: 60%;
173
+ flex-direction: column;
174
+ }
175
+
176
+ .d-dialog__title {
177
+ padding: 40rpx 40rpx 0;
178
+ font-weight: 700;
179
+ font-size: 32rpx;
180
+ text-align: center;
181
+ }
182
+
183
+ .d-dialog__body {
184
+ padding: 20rpx 40rpx 40rpx;
185
+ word-break: break-all;
186
+ hyphens: auto;
187
+ }
188
+
189
+ .d-dialog__desc {
190
+ font-size: 28rpx;
191
+ font-weight: normal;
192
+ text-align: left;
193
+ }
194
+
195
+ .d-dialog__mtop {
196
+ margin-top: 20rpx;
197
+ }
198
+
199
+ .d-dialog__footer {
200
+ display: flex;
201
+ flex-direction: row;
202
+ position: relative;
203
+ line-height: 90rpx;
204
+ border-top: 2rpx solid #f1f1f1;
205
+ }
206
+
207
+ .d-dialog__footer--vertical {
208
+ display: flex;
209
+ flex-direction: column;
210
+ }
211
+
212
+ .d-dialog__btn {
213
+ display: block;
214
+ text-decoration: none;
215
+ flex: 1;
216
+ height: 90rpx;
217
+ line-height: 90rpx;
218
+ position: relative;
219
+ font-size: 32rpx;
220
+ border-left: 2rpx solid #f1f1f1;
221
+ text-align: center;
222
+ }
223
+
224
+ .d-dialog__btn--vertical {
225
+ border-top: 2rpx solid #f1f1f1;
226
+ }
227
+
228
+ .d-dialog__btn:active {
229
+ background-color: #e1e1e1;
230
+ }
231
+
232
+ .d-dialog__btn-first {
233
+ border-left-width: 0;
234
+ border-top-width: 0;
235
+ }
236
+
237
+ .d-wrap__show {
238
+ opacity: 1;
239
+ transform: scale3d(1, 1, 1);
240
+ visibility: visible;
241
+ }
242
+ </style>
@@ -0,0 +1,108 @@
1
+ <template>
2
+ <view
3
+ class="d-popup-wrap"
4
+ :class="{ 'd-popup__wrap-show': show }"
5
+ :style="{ zIndex: zIndex, background: maskBackground }"
6
+ @tap.stop="handleClose"
7
+ @touchmove.stop.prevent="stop"
8
+ >
9
+ <view
10
+ class="d-popup__popup"
11
+ :class="{ 'd-popup__popup-show': show }"
12
+ :style="{ borderTopLeftRadius: radius + 'rpx', borderTopRightRadius: radius + 'rpx', background: background }"
13
+ @tap.stop="stop"
14
+ >
15
+ <slot></slot>
16
+ </view>
17
+ </view>
18
+ </template>
19
+
20
+ <script>
21
+ /*如果底部有自定义导航栏,可适当设置内容padding-bottom值*/
22
+ export default {
23
+ name: "d-popup",
24
+ emits: [],
25
+ props: {
26
+ show: {
27
+ type: Boolean,
28
+ default: false
29
+ },
30
+ //背景颜色
31
+ background: {
32
+ type: String,
33
+ default: "#fff"
34
+ },
35
+ //圆角
36
+ radius: {
37
+ type: [Number, String],
38
+ default: 24
39
+ },
40
+ zIndex: {
41
+ type: [Number, String],
42
+ default: 996
43
+ },
44
+ //点击遮罩 是否可关闭
45
+ maskClosable: {
46
+ type: Boolean,
47
+ default: true
48
+ },
49
+ maskBackground: {
50
+ type: String,
51
+ default: "rgba(0,0,0,.6)"
52
+ }
53
+ },
54
+ data() {
55
+ return {
56
+ iphoneX: false
57
+ };
58
+ },
59
+ methods: {
60
+ handleClose() {
61
+ if (!this.maskClosable) return;
62
+ this.$emit("update:show", false);
63
+ },
64
+
65
+ stop() {}
66
+ }
67
+ };
68
+ </script>
69
+
70
+ <style scoped>
71
+ .d-popup-wrap {
72
+ position: fixed;
73
+ left: 0;
74
+ right: 0;
75
+ top: 0;
76
+ bottom: 0;
77
+ z-index: 1001;
78
+ display: flex;
79
+ flex-direction: row;
80
+ align-items: flex-end;
81
+ justify-content: center;
82
+ transition: all ease-in-out 0.2s;
83
+ visibility: hidden;
84
+ border-bottom-width: 0;
85
+ overflow: hidden;
86
+ opacity: 0;
87
+ }
88
+
89
+ .d-popup__wrap-show {
90
+ opacity: 1;
91
+ visibility: visible;
92
+ }
93
+
94
+ .d-popup__popup {
95
+ width: 100%;
96
+ transform: translate3d(0, 100%, 0);
97
+ transition: all 0.3s ease-in-out;
98
+ min-height: 20rpx;
99
+ overflow: hidden;
100
+ padding-bottom: constant(safe-area-inset-bottom);
101
+ padding-bottom: env(safe-area-inset-bottom);
102
+ flex: 1;
103
+ }
104
+
105
+ .d-popup__popup-show {
106
+ transform: translate3d(0, 0, 0);
107
+ }
108
+ </style>
@@ -0,0 +1,429 @@
1
+ <template>
2
+ <scroll-view
3
+ class="d-tabs__scroll-box"
4
+ :class="{ 'd-tabs__fixed': isFixed && !isSticky, 'd-tabs__sticky': isSticky }"
5
+ :scroll-with-animation="true"
6
+ :scroll-x="scroll"
7
+ :show-scrollbar="false"
8
+ :scroll-into-view="scrollInto"
9
+ :style="{ background: background, zIndex: isFixed || isSticky ? zIndex : 1, top: isFixed || isSticky ? top + 'px' : 'auto' }"
10
+ >
11
+ <view class="d-scroll__view" :class="{ 'd-tabs__full': !alignLeft }">
12
+ <view
13
+ v-for="(tab, index) in vals"
14
+ :key="index"
15
+ class="d-tabs__item"
16
+ :class="{ 'd-tabs__full': !alignLeft }"
17
+ :id="tab.d_s_id"
18
+ @tap="switchTab(index)"
19
+ >
20
+ <view
21
+ class="d-tabs__text-wrap"
22
+ :class="{ 'd-tabs__wrap-disabled': tab.disabled, 'd-tabs__item-column': itemDirection === 'column' && tab.icon }"
23
+ :style="{ height: height + 'rpx' }"
24
+ >
25
+ <view class="d-tabs__line-wrap" :style="{ bottom: bottom + 'rpx', left: `-${padding}rpx`, right: `-${padding}rpx` }" v-if="isSlider">
26
+ <view
27
+ class="d-tabs__ac-line"
28
+ :class="{ 'd-tabs__line-short': short, 'd-tabs__full': !short }"
29
+ :style="{
30
+ height: sliderHeight + 'rpx',
31
+ background: getSliderBgColor,
32
+ borderRadius: sliderRadius == -1 ? sliderHeight + 'rpx' : sliderRadius + 'rpx',
33
+ transform: `scale(${tabIndex === index ? scale : 0})`
34
+ }"
35
+ ></view>
36
+ </view>
37
+ <image
38
+ class="d-tabs__icon"
39
+ :class="{ 'd-tabs__icon-column': direction === 'column' }"
40
+ :src="tabIndex === index && tab.selectedIcon ? tab.selectedIcon : tab.icon"
41
+ v-if="tab.icon"
42
+ ></image>
43
+ <view
44
+ class="d-tabs__text"
45
+ :style="{
46
+ fontSize: size + 'rpx',
47
+ color: tabIndex === index ? getSelectedColor : color,
48
+ fontWeight: tabIndex === index ? selectedFontWeight : fontWeight,
49
+ transform: `scale(${tabIndex === index ? scale : 1})`
50
+ }"
51
+ >
52
+ {{ tab.name }}
53
+ <text
54
+ :class="{ 'd-tabs__badge-color': !getBadgeBgColor, 'd-tabs__badge-dot': isDot, 'd-tabs__badge': !isDot }"
55
+ :style="{ color: badgeColor, background: getBadgeBgColor }"
56
+ v-if="tab.badge"
57
+ >
58
+ {{ isDot ? "" : tab.badge }}
59
+ </text>
60
+ </view>
61
+ </view>
62
+ </view>
63
+ </view>
64
+ </scroll-view>
65
+ </template>
66
+
67
+ <script>
68
+ export default {
69
+ name: "d-tabs",
70
+ emits: ["change"],
71
+ options: {
72
+ virtualHost: true
73
+ },
74
+ props: {
75
+ // 标签页数据源
76
+ tabs: {
77
+ type: Array,
78
+ default() {
79
+ return [];
80
+ }
81
+ },
82
+ // 当前选项卡
83
+ current: {
84
+ type: Number,
85
+ default: 0
86
+ },
87
+ // 是否可以滚动
88
+ scroll: {
89
+ type: Boolean,
90
+ default: false
91
+ },
92
+ // tab高度 rpx
93
+ height: {
94
+ type: [Number, String],
95
+ default: 100
96
+ },
97
+ background: {
98
+ type: String,
99
+ default: "#fff"
100
+ },
101
+ //字体大小
102
+ size: {
103
+ type: [Number, String],
104
+ default: 28
105
+ },
106
+ // 字体颜色
107
+ color: {
108
+ type: String,
109
+ default: "#666666"
110
+ },
111
+ //选中前字重
112
+ fontWeight: {
113
+ type: [Number, String],
114
+ default: "normal"
115
+ },
116
+ //选中后字体颜色
117
+ selectedColor: {
118
+ type: String,
119
+ default: "#006F83"
120
+ },
121
+ //选中后字重
122
+ selectedFontWeight: {
123
+ type: [Number, String],
124
+ default: 500
125
+ },
126
+ //选中后字体缩放倍数
127
+ scale: {
128
+ type: [Number, String],
129
+ default: 1.2
130
+ },
131
+ badgeColor: {
132
+ type: String,
133
+ default: "#fff"
134
+ },
135
+ badgeBackground: {
136
+ type: String,
137
+ default: ""
138
+ },
139
+ isDot: {
140
+ type: Boolean,
141
+ default: false
142
+ },
143
+ isSlider: {
144
+ type: Boolean,
145
+ default: true
146
+ },
147
+ //滑块高度
148
+ sliderHeight: {
149
+ type: [Number, String],
150
+ default: 8
151
+ },
152
+ // 滑块背景颜色
153
+ sliderBackground: {
154
+ type: String,
155
+ default: "#006F83"
156
+ },
157
+ //滑块 radius
158
+ sliderRadius: {
159
+ type: [Number, String],
160
+ default: 178
161
+ },
162
+ //滑块左右padding值
163
+ padding: {
164
+ type: [Number, String],
165
+ default: 0
166
+ },
167
+ //滑块bottom
168
+ bottom: {
169
+ type: [Number, String],
170
+ default: 0
171
+ },
172
+ //滑块是否固定为较短的长度50rpx
173
+ short: {
174
+ type: Boolean,
175
+ default: true
176
+ },
177
+ //是否固定
178
+ isFixed: {
179
+ type: Boolean,
180
+ default: false
181
+ },
182
+ //吸顶效果,为true时isFixed失效
183
+ isSticky: {
184
+ type: Boolean,
185
+ default: false
186
+ },
187
+ //isFixed或isSticky为true时,tabs top值 px
188
+ top: {
189
+ type: [Number, String],
190
+ default: 0
191
+ },
192
+ //当数据不满一屏时,item项是否靠左对齐,默认均分铺满
193
+ alignLeft: {
194
+ type: Boolean,
195
+ default: false
196
+ },
197
+ //tabs item项排列方式:row、column
198
+ itemDirection: {
199
+ type: String,
200
+ default: "row"
201
+ },
202
+ zIndex: {
203
+ type: [Number, String],
204
+ default: 996
205
+ }
206
+ },
207
+ watch: {
208
+ tabs(vals) {
209
+ this.initData(vals);
210
+ },
211
+ current(newVal, oldVal) {
212
+ this.switchTab(newVal);
213
+ }
214
+ },
215
+ created() {
216
+ this.initData(this.tabs);
217
+ },
218
+ computed: {
219
+ getSelectedColor() {
220
+ let color = this.selectedColor;
221
+ return color;
222
+ },
223
+ getSliderBgColor() {
224
+ let color = this.sliderBackground;
225
+ return color;
226
+ },
227
+ getBadgeBgColor() {
228
+ let color = this.badgeBackground;
229
+ return color;
230
+ }
231
+ },
232
+ data() {
233
+ return {
234
+ vals: [],
235
+ scrollInto: "",
236
+ tabIndex: 0
237
+ };
238
+ },
239
+ methods: {
240
+ getId() {
241
+ return `d_${Math.ceil(Math.random() * 10e5).toString(36)}`;
242
+ },
243
+ initData(vals) {
244
+ if (vals && vals.length > 0) {
245
+ if (typeof vals[0] === "object") {
246
+ vals.map(item => {
247
+ const scrollId = this.getId();
248
+ item.d_s_id = scrollId;
249
+ });
250
+ } else {
251
+ //字符串
252
+ vals = vals.map(item => {
253
+ const scrollId = this.getId();
254
+ return {
255
+ name: item,
256
+ d_s_id: scrollId
257
+ };
258
+ });
259
+ }
260
+ this.vals = vals;
261
+ this.$nextTick(() => {
262
+ setTimeout(() => {
263
+ this.switchTab(this.current);
264
+ }, 50);
265
+ });
266
+ }
267
+ },
268
+ switchTab(index) {
269
+ const item = {
270
+ ...this.vals[index]
271
+ };
272
+ if (this.tabIndex === index || item.disabled) return;
273
+ this.tabIndex = index;
274
+ let scrollIndex = index - 1 < 0 ? 0 : index - 1;
275
+ this.scrollInto = this.vals[scrollIndex].d_s_id;
276
+ delete item.d_s_id;
277
+ this.$emit("change", {
278
+ index: index,
279
+ ...item
280
+ });
281
+ }
282
+ }
283
+ };
284
+ </script>
285
+
286
+ <style scoped>
287
+ .d-tabs__scroll-box {
288
+ width: 100%;
289
+ flex: 1;
290
+ flex-direction: row;
291
+ overflow: hidden;
292
+ }
293
+
294
+ .d-tabs__fixed {
295
+ position: fixed;
296
+ left: 0;
297
+ right: 0;
298
+ }
299
+
300
+ .d-tabs__sticky {
301
+ position: sticky;
302
+ left: 0;
303
+ right: 0;
304
+ }
305
+
306
+ .d-scroll__view {
307
+ min-width: 100%;
308
+ white-space: nowrap;
309
+ display: flex;
310
+ flex-direction: row;
311
+ align-items: center;
312
+ position: relative;
313
+ }
314
+
315
+ .d-scroll__view::after {
316
+ content: " ";
317
+ width: 100%;
318
+ height: 1px;
319
+ background: #f1f1f1;
320
+ position: absolute;
321
+ left: 0;
322
+ bottom: 0;
323
+ }
324
+
325
+ .d-tabs__item {
326
+ display: flex;
327
+ flex-shrink: 0;
328
+ flex-direction: row;
329
+ align-items: center;
330
+ justify-content: center;
331
+ padding-left: 32rpx;
332
+ padding-right: 32rpx;
333
+ position: relative;
334
+ }
335
+
336
+ .d-tabs__full {
337
+ flex: 1;
338
+ }
339
+
340
+ .d-tabs__text-wrap {
341
+ position: relative;
342
+ display: flex;
343
+ flex-direction: row;
344
+ align-items: center;
345
+ justify-content: center;
346
+ z-index: 3;
347
+ }
348
+
349
+ .d-tabs__wrap-disabled {
350
+ opacity: 0.5;
351
+ }
352
+
353
+ .d-tabs__icon {
354
+ width: 40rpx;
355
+ height: 40rpx;
356
+ margin-right: 12rpx;
357
+ }
358
+
359
+ .d-tabs__item-column {
360
+ flex-direction: column !important;
361
+ }
362
+
363
+ .d-tabs__icon-column {
364
+ margin-right: 0 !important;
365
+ margin-bottom: 8rpx;
366
+ }
367
+
368
+ .d-tabs__text {
369
+ white-space: nowrap;
370
+ display: block;
371
+ transition: transform 0.2s linear;
372
+ z-index: 3;
373
+ position: relative;
374
+ }
375
+
376
+ .d-tabs__badge {
377
+ height: 36rpx;
378
+ padding: 0 12rpx;
379
+ color: #ffffff;
380
+ font-size: 24rpx;
381
+ line-height: 36rpx;
382
+ border-radius: 100px;
383
+ position: absolute;
384
+ min-width: 36rpx !important;
385
+ display: flex;
386
+ box-sizing: border-box;
387
+ right: -32rpx;
388
+ top: -18rpx;
389
+ z-index: 10;
390
+ flex-direction: row;
391
+ align-items: center;
392
+ justify-content: center;
393
+ transform: scale(0.9);
394
+ }
395
+
396
+ .d-tabs__badge-dot {
397
+ height: 8px !important;
398
+ width: 8px !important;
399
+ position: absolute;
400
+ display: inline-block;
401
+ right: -6px;
402
+ top: -3px;
403
+ border-radius: 50%;
404
+ z-index: 10;
405
+ }
406
+
407
+ .d-tabs__line-wrap {
408
+ position: absolute;
409
+ border-radius: 2px;
410
+ z-index: 2;
411
+ flex: 1;
412
+ display: flex;
413
+ flex-direction: row;
414
+ justify-content: center;
415
+ left: 0;
416
+ }
417
+
418
+ .d-tabs__ac-line {
419
+ transition: transform 0.2s linear;
420
+ }
421
+
422
+ .d-tabs__line-short {
423
+ width: 50rpx !important;
424
+ }
425
+
426
+ .d-tabs__badge-color {
427
+ background: var(--d-color-danger, #ff2b2b) !important;
428
+ }
429
+ </style>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "distinctui-uni",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "卓正医疗小程序UI组件库",
5
5
  "main": "main.js",
6
6
  "files": [
@@ -1,16 +0,0 @@
1
- <template>
2
- <view>未完成按钮</view>
3
- </template>
4
-
5
- <script>
6
- export default {
7
- data() {
8
- return {};
9
- },
10
- computed: {},
11
- onLoad() {},
12
- methods: {}
13
- };
14
- </script>
15
-
16
- <style scoped></style>