yymini-pop-content 1.0.0

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 ADDED
@@ -0,0 +1,28 @@
1
+ # yymini-pop-content
2
+ 抖音小程序轻量级居中确认弹出框自定义组件,无需额外依赖,开箱即用。
3
+
4
+ ## 🌟 特性
5
+ - 原生小程序语法,兼容所有抖音小程序基础库
6
+ - 支持自定义 标题、内容、明细、图片、背景图等
7
+ - 提供 确认/取消 回调,支持遮罩关闭
8
+ - 样式简洁美观,可自定义修改
9
+
10
+ ## 📦 安装
11
+ 在你的抖音小程序项目根目录执行:
12
+
13
+ ```bash
14
+ npm install yymini-pop-content --save
15
+ or
16
+ yarn add yymini-pop-content
17
+
18
+
19
+ ## 抖音小程序(必读)
20
+ - 抖音小程序在解析组件时,把 yymini-pop-content 当成了“相对路径组件”,而不是 npm 组件
21
+ - 所以必须显式指向组件文件路径。
22
+
23
+ ```json
24
+ {
25
+ "usingComponents": {
26
+ "pop-content": "/miniprogram_npm/yymini-pop-content/pop-content"
27
+ }
28
+ }
package/back.png ADDED
Binary file
package/bgSrc.png ADDED
Binary file
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "yymini-pop-content",
3
+ "version": "1.0.0",
4
+ "description": "小程序(抖音、微信)-底部内容弹出框 自定义组件",
5
+ "main": "pop-content.js",
6
+ "miniprogram": ".",
7
+ "keywords": [
8
+ "douyin",
9
+ "weixin",
10
+ "miniProgram",
11
+ "抖音小程序",
12
+ "微信小程序",
13
+ "confirm",
14
+ "modal",
15
+ "弹出框",
16
+ "底部弹出框"
17
+ ],
18
+ "author": "Allen.ge <gyjshow@163.com>",
19
+ "license": "MIT",
20
+ "repository": {
21
+ "type": "",
22
+ "url": ""
23
+ },
24
+ "bugs": {
25
+ "url": ""
26
+ },
27
+ "homepage": "",
28
+ "private": false,
29
+ "files": [
30
+ "back.png",
31
+ "bgSrc.png",
32
+ "pop-content.*",
33
+ "README.md"
34
+ ],
35
+ "scripts": {
36
+ "test": "echo \"Error: no test specified\" && exit 1"
37
+ }
38
+ }
package/pop-content.js ADDED
@@ -0,0 +1,126 @@
1
+ Component({
2
+ properties: {
3
+ visible: { // 接收页面传递的显示状态
4
+ type: Boolean,
5
+ value: false,
6
+ observer(newVal) {
7
+ this.setData({
8
+ show: newVal
9
+ });
10
+ }
11
+ },
12
+ zindex: {
13
+ type: Number,
14
+ value: 999
15
+ }, //遮罩层弹出框的 层级
16
+ height: {
17
+ type: Number,
18
+ value: 85
19
+ }, // 弹窗高度 80%
20
+ title: {
21
+ type: String,
22
+ value: ''
23
+ }, // 弹窗标题
24
+ name: {
25
+ type: String,
26
+ value: null
27
+ }, // 内容标题
28
+ desc: {
29
+ type: String,
30
+ value: null
31
+ }, // 内容信息
32
+ imgSrc: {
33
+ type: String,
34
+ value: null
35
+ }, // 图片地址
36
+ bgSrc: {
37
+ type: String,
38
+ value: "bgSrc.png"
39
+ }, // 背景图片地址
40
+ cancelText: {
41
+ type: String,
42
+ value: '取消'
43
+ }, // 取消按钮文本
44
+ confirmText: {
45
+ type: String,
46
+ value: '确认'
47
+ }, // 确认按钮文本
48
+ showClose: {
49
+ type: Boolean,
50
+ value: true
51
+ }, // 是否显示关闭按钮
52
+ showCancel: {
53
+ type: Boolean,
54
+ value: false
55
+ }, // 是否显示取消按钮
56
+ hideFooter: {
57
+ type: Boolean,
58
+ value: true
59
+ }, // 是否隐藏底部按钮
60
+ maskCloseable: {
61
+ type: Boolean,
62
+ value: false
63
+ } // 遮罩点击是否关闭
64
+ },
65
+
66
+ data: {
67
+ show: false // 内部维护显示状态,避免异步延迟
68
+ },
69
+
70
+ methods: {
71
+ // 遮罩点击:关闭弹窗+触发取消事件
72
+ onMaskClick() {
73
+ if (this.data.maskCloseable) {
74
+ this.setData({
75
+ show: false
76
+ })
77
+ this.triggerEvent('close', {
78
+ type: 'mask'
79
+ });
80
+ this.triggerEvent('cancel');
81
+ }
82
+ },
83
+
84
+ // 阻止内容区点击穿透到遮罩
85
+ stopPropagation() {},
86
+
87
+ // 取消按钮
88
+ onCancel(e) {
89
+ console.log('onCancel onCancel.... ', e);
90
+ this.setData({
91
+ show: false
92
+ })
93
+
94
+ this.triggerEvent('close', {
95
+ type: 'cancel'
96
+ });
97
+ this.triggerEvent('cancel');
98
+ },
99
+
100
+ // 确认按钮:透传参数给业务组件
101
+ onConfirm() {
102
+ this.setData({
103
+ show: false
104
+ })
105
+ this.triggerEvent('close', {
106
+ type: 'confirm'
107
+ });
108
+ this.triggerEvent('confirm', {
109
+ from: 'base-popup-bottom'
110
+ });
111
+ },
112
+
113
+ // 关闭按钮
114
+ onClose() {
115
+ this.setData({
116
+ show: false
117
+ })
118
+ this.triggerEvent('close', {
119
+ type: 'close'
120
+ });
121
+ this.triggerEvent('cancel');
122
+ }
123
+
124
+ }
125
+
126
+ });
@@ -0,0 +1,4 @@
1
+ {
2
+ "component": true,
3
+ "usingComponents": {}
4
+ }
@@ -0,0 +1,35 @@
1
+ <!-- 遮罩层:全屏,控制显示/隐藏 -->
2
+ <view class="view-mask {{show ? 'show' : ''}}" style="z-index: {{zindex}};" bindtap="onMaskClick">
3
+ <!-- 弹窗主体:固定在底部,宽度100% -->
4
+ <view class="view-content" style="height: {{height}}%;" catchtap="stopPropagation">
5
+ <!-- 背景图 -->
6
+ <image tt:if="{{bgSrc}}" src="{{bgSrc}}" class="img-bg"></image>
7
+
8
+ <view class="view-area">
9
+ <!-- 返回按钮左上角 -->
10
+ <view class="popup-close" bindtap="onCancel">
11
+ <image src="back.png" class="comment_zuo"></image>
12
+ </view>
13
+
14
+ <!-- 标题 -->
15
+ <view tt:if="{{title}}" class="popup-title" bindtap="onCancel">
16
+ {{title}}
17
+ </view>
18
+
19
+ <view class="view-top">
20
+ <view tt:if="{{name}}" class="view-name">{{name}}</view>
21
+ <view tt:if="{{desc}}" class="view-desc">{{desc}}</view>
22
+ <view tt:if="imgSrc">
23
+ <image class="img" mode="widthFix" src="{{imgSrc}}"></image>
24
+ </view>
25
+
26
+ <!-- 底部按钮区:可选 -->
27
+ <view class="popup-footer" tt:if="{{!hideFooter}}">
28
+ <button class="btn cancel" bindtap="onCancel" tt:if="{{showCancel}}">{{cancelText}}</button>
29
+ <button class="btn confirm" bindtap="onConfirm">{{confirmText}}</button>
30
+ </view>
31
+ </view>
32
+ </view>
33
+
34
+ </view>
35
+ </view>
@@ -0,0 +1,201 @@
1
+ /* 遮罩层:全屏、透明、不可点击(初始状态) */
2
+ .view-mask {
3
+ position: fixed;
4
+ top: 0;
5
+ left: 0;
6
+ right: 0;
7
+ bottom: 0;
8
+ background: rgba(0, 0, 0, 0.45);
9
+
10
+ opacity: 0;
11
+ pointer-events: none;
12
+ transition: opacity 0.3s ease;
13
+
14
+ /* z-index: 999; */
15
+
16
+ }
17
+
18
+ /* 遮罩显示:不透明+可点击 */
19
+ .view-mask.show {
20
+ opacity: 1;
21
+ pointer-events: auto;
22
+ }
23
+
24
+ /* 弹窗主体:固定底部,初始滑出屏幕 */
25
+ .view-content {
26
+ position: absolute;
27
+ bottom: 0;
28
+ left: 0;
29
+ right: 0;
30
+
31
+ display: flex;
32
+ flex-direction: column;
33
+
34
+ background: #ffffff;
35
+ border-top-left-radius: 40rpx;
36
+ border-top-right-radius: 40rpx;
37
+
38
+ box-sizing: border-box;
39
+ /* 初始状态:滑出屏幕底部 */
40
+ transform: translateY(100%);
41
+ transition: transform 0.3s ease-out;
42
+
43
+ /* height: 20%;
44
+ min-height: 45%; */
45
+ }
46
+
47
+ .view-area {
48
+ position: absolute;
49
+ top: 0;
50
+ bottom: 0;
51
+ left: 0;
52
+ right: 0;
53
+ display: flex;
54
+ flex-direction: column;
55
+ }
56
+
57
+ .img-bg {
58
+ position: absolute;
59
+ top: 0;
60
+ right: 0;
61
+ bottom: 0;
62
+ left: 0;
63
+ width: 100%;
64
+ height: 100%;
65
+ }
66
+
67
+ /* 弹窗显示:滑入屏幕 */
68
+ .view-mask.show .view-content {
69
+ transform: translateY(0);
70
+ }
71
+
72
+ /* 通用样式:适配抖音规范 */
73
+ .popup-title {
74
+ display: flex;
75
+ justify-content: center;
76
+ align-items: center;
77
+ height: 130rpx;
78
+ font-size: 40rpx;
79
+ font-weight: 500;
80
+ color: #232832;
81
+ /* background-color: #f7f7f7; */
82
+ }
83
+
84
+ .view-top {
85
+ display: flex;
86
+ flex: 1;
87
+ flex-direction: column;
88
+ margin: 0 24rpx 0rpx;
89
+ border-top-left-radius: 20rpx;
90
+ border-top-right-radius: 20rpx;
91
+ background-color: #FFFFFF;
92
+ overflow-y: auto;
93
+ padding-bottom: 30rpx;
94
+ }
95
+
96
+ .view-name {
97
+ font-size: 32rpx;
98
+ font-weight: 500;
99
+ color: #232832;
100
+ padding: 40rpx 34rpx 12rpx;
101
+ }
102
+
103
+ .view-desc {
104
+ font-size: 28rpx;
105
+ font-weight: 500;
106
+ color: #999999;
107
+ line-height: 40rpx;
108
+ padding: 0rpx 34rpx 30rpx;
109
+ }
110
+
111
+ .img {
112
+ width: 100%;
113
+ }
114
+
115
+
116
+
117
+ .popup-close {
118
+ position: absolute;
119
+ top: 0;
120
+ left: 0;
121
+
122
+ width: 100rpx;
123
+ height: 130rpx;
124
+
125
+ display: flex;
126
+ align-items: center;
127
+ padding-left: 24rpx;
128
+ border-top-left-radius: 20rpx;
129
+ /* background-color: #f7f7f7; */
130
+ }
131
+
132
+ .comment_zuo {
133
+ width: 48rpx;
134
+ height: 48rpx;
135
+
136
+ transition: all 0.12s ease;
137
+ transform-origin: center center;
138
+
139
+ }
140
+
141
+
142
+ .popup-close:active .comment_zuo {
143
+ opacity: 0.65;
144
+ transform: scale(0.88);
145
+ filter: brightness(0.8);
146
+ filter: brightness(0.8) drop-shadow(0 1rpx 2rpx rgba(0, 0, 0, 0.1));
147
+ }
148
+
149
+ .popup-footer {
150
+ display: flex;
151
+ margin: 30rpx 30rpx 40rpx;
152
+ gap: 20rpx;
153
+ }
154
+
155
+
156
+ /* 核心重置:只解决伪元素遮挡+原生外观问题(必写) */
157
+ button {
158
+ -webkit-appearance: none !important;
159
+ /* 去掉原生外观(关键) */
160
+ appearance: none !important;
161
+ border: none !important;
162
+ /* 清空默认边框 */
163
+ }
164
+
165
+ button::after {
166
+ content: none !important;
167
+ /* 直接移除遮挡的伪元素(核心) */
168
+ }
169
+
170
+ .btn {
171
+ flex: 1;
172
+ height: 80rpx;
173
+ line-height: 80rpx;
174
+ border-radius: 40rpx;
175
+ border: none;
176
+ font-size: 28rpx;
177
+ padding: 0;
178
+ }
179
+
180
+ .cancel {
181
+ background: #FFFFFF;
182
+ color: #333333;
183
+ border: 2rpx solid #D1D1D6 !important;
184
+ /* transition: background-color 0.1s; */
185
+
186
+ /* box-shadow: 0 0 0 rgba(0, 0, 0, 0);
187
+ transition: box-shadow 0.1s; */
188
+ /* 按压 */
189
+ }
190
+
191
+ .cancel:active {
192
+ background-color: #f5f5f5;
193
+
194
+ /* box-shadow: inset 0 2rpx 4rpx rgba(0, 0, 0, 0.2); */
195
+ /* 按压 */
196
+ }
197
+
198
+ .confirm {
199
+ background: linear-gradient(180deg, #FF8684 0%, #CB6DF3 100%);
200
+ color: #ffffff;
201
+ }
@@ -0,0 +1,35 @@
1
+ <!-- 遮罩层:全屏,控制显示/隐藏 -->
2
+ <view class="view-mask {{show ? 'show' : ''}}" style="z-index: {{zindex}};" bindtap="onMaskClick">
3
+ <!-- 弹窗主体:固定在底部,宽度100% -->
4
+ <view class="view-content" style="height: {{height}}%;" catchtap="stopPropagation">
5
+ <!-- 背景图 -->
6
+ <image wx:if="{{bgSrc}}" src="{{bgSrc}}" class="img-bg"></image>
7
+
8
+ <view class="view-area">
9
+ <!-- 返回按钮左上角 -->
10
+ <view class="popup-close" bindtap="onCancel">
11
+ <image src="back.png" class="comment_zuo"></image>
12
+ </view>
13
+
14
+ <!-- 标题 -->
15
+ <view wx:if="{{title}}" class="popup-title" bindtap="onCancel">
16
+ {{title}}
17
+ </view>
18
+
19
+ <view class="view-top">
20
+ <view wx:if="{{name}}" class="view-name">{{name}}</view>
21
+ <view wx:if="{{desc}}" class="view-desc">{{desc}}</view>
22
+ <view wx:if="imgSrc">
23
+ <image class="img" mode="widthFix" src="{{imgSrc}}"></image>
24
+ </view>
25
+
26
+ <!-- 底部按钮区:可选 -->
27
+ <view class="popup-footer" wx:if="{{!hideFooter}}">
28
+ <button class="btn cancel" bindtap="onCancel" wx:if="{{showCancel}}">{{cancelText}}</button>
29
+ <button class="btn confirm" bindtap="onConfirm">{{confirmText}}</button>
30
+ </view>
31
+ </view>
32
+ </view>
33
+
34
+ </view>
35
+ </view>
@@ -0,0 +1,201 @@
1
+ /* 遮罩层:全屏、透明、不可点击(初始状态) */
2
+ .view-mask {
3
+ position: fixed;
4
+ top: 0;
5
+ left: 0;
6
+ right: 0;
7
+ bottom: 0;
8
+ background: rgba(0, 0, 0, 0.45);
9
+
10
+ opacity: 0;
11
+ pointer-events: none;
12
+ transition: opacity 0.3s ease;
13
+
14
+ /* z-index: 999; */
15
+
16
+ }
17
+
18
+ /* 遮罩显示:不透明+可点击 */
19
+ .view-mask.show {
20
+ opacity: 1;
21
+ pointer-events: auto;
22
+ }
23
+
24
+ /* 弹窗主体:固定底部,初始滑出屏幕 */
25
+ .view-content {
26
+ position: absolute;
27
+ bottom: 0;
28
+ left: 0;
29
+ right: 0;
30
+
31
+ display: flex;
32
+ flex-direction: column;
33
+
34
+ background: #ffffff;
35
+ border-top-left-radius: 40rpx;
36
+ border-top-right-radius: 40rpx;
37
+
38
+ box-sizing: border-box;
39
+ /* 初始状态:滑出屏幕底部 */
40
+ transform: translateY(100%);
41
+ transition: transform 0.3s ease-out;
42
+
43
+ /* height: 20%;
44
+ min-height: 45%; */
45
+ }
46
+
47
+ .view-area {
48
+ position: absolute;
49
+ top: 0;
50
+ bottom: 0;
51
+ left: 0;
52
+ right: 0;
53
+ display: flex;
54
+ flex-direction: column;
55
+ }
56
+
57
+ .img-bg {
58
+ position: absolute;
59
+ top: 0;
60
+ right: 0;
61
+ bottom: 0;
62
+ left: 0;
63
+ width: 100%;
64
+ height: 100%;
65
+ }
66
+
67
+ /* 弹窗显示:滑入屏幕 */
68
+ .view-mask.show .view-content {
69
+ transform: translateY(0);
70
+ }
71
+
72
+ /* 通用样式:适配抖音规范 */
73
+ .popup-title {
74
+ display: flex;
75
+ justify-content: center;
76
+ align-items: center;
77
+ height: 130rpx;
78
+ font-size: 40rpx;
79
+ font-weight: 500;
80
+ color: #232832;
81
+ /* background-color: #f7f7f7; */
82
+ }
83
+
84
+ .view-top {
85
+ display: flex;
86
+ flex: 1;
87
+ flex-direction: column;
88
+ margin: 0 24rpx 0rpx;
89
+ border-top-left-radius: 20rpx;
90
+ border-top-right-radius: 20rpx;
91
+ background-color: #FFFFFF;
92
+ overflow-y: auto;
93
+ padding-bottom: 30rpx;
94
+ }
95
+
96
+ .view-name {
97
+ font-size: 32rpx;
98
+ font-weight: 500;
99
+ color: #232832;
100
+ padding: 40rpx 34rpx 12rpx;
101
+ }
102
+
103
+ .view-desc {
104
+ font-size: 28rpx;
105
+ font-weight: 500;
106
+ color: #999999;
107
+ line-height: 40rpx;
108
+ padding: 0rpx 34rpx 30rpx;
109
+ }
110
+
111
+ .img {
112
+ width: 100%;
113
+ }
114
+
115
+
116
+
117
+ .popup-close {
118
+ position: absolute;
119
+ top: 0;
120
+ left: 0;
121
+
122
+ width: 100rpx;
123
+ height: 130rpx;
124
+
125
+ display: flex;
126
+ align-items: center;
127
+ padding-left: 24rpx;
128
+ border-top-left-radius: 20rpx;
129
+ /* background-color: #f7f7f7; */
130
+ }
131
+
132
+ .comment_zuo {
133
+ width: 48rpx;
134
+ height: 48rpx;
135
+
136
+ transition: all 0.12s ease;
137
+ transform-origin: center center;
138
+
139
+ }
140
+
141
+
142
+ .popup-close:active .comment_zuo {
143
+ opacity: 0.65;
144
+ transform: scale(0.88);
145
+ filter: brightness(0.8);
146
+ filter: brightness(0.8) drop-shadow(0 1rpx 2rpx rgba(0, 0, 0, 0.1));
147
+ }
148
+
149
+ .popup-footer {
150
+ display: flex;
151
+ margin: 30rpx 30rpx 40rpx;
152
+ gap: 20rpx;
153
+ }
154
+
155
+
156
+ /* 核心重置:只解决伪元素遮挡+原生外观问题(必写) */
157
+ button {
158
+ -webkit-appearance: none !important;
159
+ /* 去掉原生外观(关键) */
160
+ appearance: none !important;
161
+ border: none !important;
162
+ /* 清空默认边框 */
163
+ }
164
+
165
+ button::after {
166
+ content: none !important;
167
+ /* 直接移除遮挡的伪元素(核心) */
168
+ }
169
+
170
+ .btn {
171
+ flex: 1;
172
+ height: 80rpx;
173
+ line-height: 80rpx;
174
+ border-radius: 40rpx;
175
+ border: none;
176
+ font-size: 28rpx;
177
+ padding: 0;
178
+ }
179
+
180
+ .cancel {
181
+ background: #FFFFFF;
182
+ color: #333333;
183
+ border: 2rpx solid #D1D1D6 !important;
184
+ /* transition: background-color 0.1s; */
185
+
186
+ /* box-shadow: 0 0 0 rgba(0, 0, 0, 0);
187
+ transition: box-shadow 0.1s; */
188
+ /* 按压 */
189
+ }
190
+
191
+ .cancel:active {
192
+ background-color: #f5f5f5;
193
+
194
+ /* box-shadow: inset 0 2rpx 4rpx rgba(0, 0, 0, 0.2); */
195
+ /* 按压 */
196
+ }
197
+
198
+ .confirm {
199
+ background: linear-gradient(180deg, #FF8684 0%, #CB6DF3 100%);
200
+ color: #ffffff;
201
+ }