wx-sky-ui 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.
Files changed (235) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +138 -0
  3. package/miniprogram_dist/action-sheet/index.d.ts +0 -0
  4. package/miniprogram_dist/action-sheet/index.js +67 -0
  5. package/miniprogram_dist/action-sheet/index.js.map +1 -0
  6. package/miniprogram_dist/action-sheet/index.json +6 -0
  7. package/miniprogram_dist/action-sheet/index.wxml +62 -0
  8. package/miniprogram_dist/action-sheet/index.wxss +227 -0
  9. package/miniprogram_dist/action-sheet/index.wxss.map +1 -0
  10. package/miniprogram_dist/badge/index.d.ts +0 -0
  11. package/miniprogram_dist/badge/index.js +114 -0
  12. package/miniprogram_dist/badge/index.js.map +1 -0
  13. package/miniprogram_dist/badge/index.json +6 -0
  14. package/miniprogram_dist/badge/index.wxml +16 -0
  15. package/miniprogram_dist/badge/index.wxss +105 -0
  16. package/miniprogram_dist/badge/index.wxss.map +1 -0
  17. package/miniprogram_dist/button/index.d.ts +0 -0
  18. package/miniprogram_dist/button/index.js +140 -0
  19. package/miniprogram_dist/button/index.js.map +1 -0
  20. package/miniprogram_dist/button/index.json +6 -0
  21. package/miniprogram_dist/button/index.wxml +28 -0
  22. package/miniprogram_dist/button/index.wxss +211 -0
  23. package/miniprogram_dist/button/index.wxss.map +1 -0
  24. package/miniprogram_dist/cell/index.d.ts +0 -0
  25. package/miniprogram_dist/cell/index.js +55 -0
  26. package/miniprogram_dist/cell/index.js.map +1 -0
  27. package/miniprogram_dist/cell/index.json +6 -0
  28. package/miniprogram_dist/cell/index.wxml +37 -0
  29. package/miniprogram_dist/cell/index.wxss +82 -0
  30. package/miniprogram_dist/cell/index.wxss.map +1 -0
  31. package/miniprogram_dist/checkbox/index.d.ts +0 -0
  32. package/miniprogram_dist/checkbox/index.js +50 -0
  33. package/miniprogram_dist/checkbox/index.js.map +1 -0
  34. package/miniprogram_dist/checkbox/index.json +6 -0
  35. package/miniprogram_dist/checkbox/index.wxml +16 -0
  36. package/miniprogram_dist/checkbox/index.wxss +87 -0
  37. package/miniprogram_dist/checkbox/index.wxss.map +1 -0
  38. package/miniprogram_dist/common/utils/index.d.ts +22 -0
  39. package/miniprogram_dist/common/utils/index.js +46 -0
  40. package/miniprogram_dist/common/utils/index.js.map +1 -0
  41. package/miniprogram_dist/datetime-picker/calendar.d.ts +1 -0
  42. package/miniprogram_dist/datetime-picker/calendar.js +424 -0
  43. package/miniprogram_dist/datetime-picker/calendar.js.map +1 -0
  44. package/miniprogram_dist/datetime-picker/calendar.json +8 -0
  45. package/miniprogram_dist/datetime-picker/calendar.wxml +86 -0
  46. package/miniprogram_dist/datetime-picker/calendar.wxss +352 -0
  47. package/miniprogram_dist/datetime-picker/calendar.wxss.map +1 -0
  48. package/miniprogram_dist/datetime-picker/index.d.ts +1 -0
  49. package/miniprogram_dist/datetime-picker/index.js +672 -0
  50. package/miniprogram_dist/datetime-picker/index.js.map +1 -0
  51. package/miniprogram_dist/datetime-picker/index.json +9 -0
  52. package/miniprogram_dist/datetime-picker/index.wxml +125 -0
  53. package/miniprogram_dist/datetime-picker/index.wxss +243 -0
  54. package/miniprogram_dist/datetime-picker/index.wxss.map +1 -0
  55. package/miniprogram_dist/datetime-picker/time-picker.d.ts +0 -0
  56. package/miniprogram_dist/datetime-picker/time-picker.js +83 -0
  57. package/miniprogram_dist/datetime-picker/time-picker.js.map +1 -0
  58. package/miniprogram_dist/datetime-picker/time-picker.json +6 -0
  59. package/miniprogram_dist/datetime-picker/time-picker.wxml +36 -0
  60. package/miniprogram_dist/datetime-picker/time-picker.wxss +75 -0
  61. package/miniprogram_dist/datetime-picker/time-picker.wxss.map +1 -0
  62. package/miniprogram_dist/datetime-picker/util.d.ts +172 -0
  63. package/miniprogram_dist/datetime-picker/util.js +404 -0
  64. package/miniprogram_dist/datetime-picker/util.js.map +1 -0
  65. package/miniprogram_dist/dialog/index.d.ts +0 -0
  66. package/miniprogram_dist/dialog/index.js +81 -0
  67. package/miniprogram_dist/dialog/index.js.map +1 -0
  68. package/miniprogram_dist/dialog/index.json +6 -0
  69. package/miniprogram_dist/dialog/index.wxml +55 -0
  70. package/miniprogram_dist/dialog/index.wxss +143 -0
  71. package/miniprogram_dist/dialog/index.wxss.map +1 -0
  72. package/miniprogram_dist/dropdown-select/index.d.ts +4 -0
  73. package/miniprogram_dist/dropdown-select/index.js +84 -0
  74. package/miniprogram_dist/dropdown-select/index.js.map +1 -0
  75. package/miniprogram_dist/dropdown-select/index.json +6 -0
  76. package/miniprogram_dist/dropdown-select/index.wxml +42 -0
  77. package/miniprogram_dist/dropdown-select/index.wxss +189 -0
  78. package/miniprogram_dist/dropdown-select/index.wxss.map +1 -0
  79. package/miniprogram_dist/editor/index.d.ts +0 -0
  80. package/miniprogram_dist/editor/index.js +254 -0
  81. package/miniprogram_dist/editor/index.js.map +1 -0
  82. package/miniprogram_dist/editor/index.json +6 -0
  83. package/miniprogram_dist/editor/index.wxml +142 -0
  84. package/miniprogram_dist/editor/index.wxss +613 -0
  85. package/miniprogram_dist/editor/index.wxss.map +1 -0
  86. package/miniprogram_dist/float-button/index.d.ts +0 -0
  87. package/miniprogram_dist/float-button/index.js +281 -0
  88. package/miniprogram_dist/float-button/index.js.map +1 -0
  89. package/miniprogram_dist/float-button/index.json +8 -0
  90. package/miniprogram_dist/float-button/index.wxml +68 -0
  91. package/miniprogram_dist/float-button/index.wxss +119 -0
  92. package/miniprogram_dist/float-button/index.wxss.map +1 -0
  93. package/miniprogram_dist/html-renderer/index.d.ts +1 -0
  94. package/miniprogram_dist/html-renderer/index.js +74 -0
  95. package/miniprogram_dist/html-renderer/index.js.map +1 -0
  96. package/miniprogram_dist/html-renderer/index.json +6 -0
  97. package/miniprogram_dist/html-renderer/index.wxml +79 -0
  98. package/miniprogram_dist/html-renderer/index.wxss +200 -0
  99. package/miniprogram_dist/html-renderer/index.wxss.map +1 -0
  100. package/miniprogram_dist/html-renderer/parser.d.ts +12 -0
  101. package/miniprogram_dist/html-renderer/parser.js +103 -0
  102. package/miniprogram_dist/html-renderer/parser.js.map +1 -0
  103. package/miniprogram_dist/icon/index.d.ts +1 -0
  104. package/miniprogram_dist/icon/index.js +231 -0
  105. package/miniprogram_dist/icon/index.js.map +1 -0
  106. package/miniprogram_dist/icon/index.json +6 -0
  107. package/miniprogram_dist/icon/index.wxml +13 -0
  108. package/miniprogram_dist/icon/index.wxss +14 -0
  109. package/miniprogram_dist/icon/index.wxss.map +1 -0
  110. package/miniprogram_dist/icon/presets.d.ts +7 -0
  111. package/miniprogram_dist/icon/presets.js +68 -0
  112. package/miniprogram_dist/icon/presets.js.map +1 -0
  113. package/miniprogram_dist/index.d.ts +6 -0
  114. package/miniprogram_dist/index.js +9 -0
  115. package/miniprogram_dist/index.js.map +1 -0
  116. package/miniprogram_dist/input/index.d.ts +0 -0
  117. package/miniprogram_dist/input/index.js +137 -0
  118. package/miniprogram_dist/input/index.js.map +1 -0
  119. package/miniprogram_dist/input/index.json +6 -0
  120. package/miniprogram_dist/input/index.wxml +57 -0
  121. package/miniprogram_dist/input/index.wxss +331 -0
  122. package/miniprogram_dist/input/index.wxss.map +1 -0
  123. package/miniprogram_dist/nav-bar/index.d.ts +0 -0
  124. package/miniprogram_dist/nav-bar/index.js +162 -0
  125. package/miniprogram_dist/nav-bar/index.js.map +1 -0
  126. package/miniprogram_dist/nav-bar/index.json +9 -0
  127. package/miniprogram_dist/nav-bar/index.wxml +46 -0
  128. package/miniprogram_dist/nav-bar/index.wxss +160 -0
  129. package/miniprogram_dist/nav-bar/index.wxss.map +1 -0
  130. package/miniprogram_dist/popup-select/index.d.ts +4 -0
  131. package/miniprogram_dist/popup-select/index.js +70 -0
  132. package/miniprogram_dist/popup-select/index.js.map +1 -0
  133. package/miniprogram_dist/popup-select/index.json +6 -0
  134. package/miniprogram_dist/popup-select/index.wxml +48 -0
  135. package/miniprogram_dist/popup-select/index.wxss +184 -0
  136. package/miniprogram_dist/popup-select/index.wxss.map +1 -0
  137. package/miniprogram_dist/progress/index.d.ts +0 -0
  138. package/miniprogram_dist/progress/index.js +120 -0
  139. package/miniprogram_dist/progress/index.js.map +1 -0
  140. package/miniprogram_dist/progress/index.json +6 -0
  141. package/miniprogram_dist/progress/index.wxml +31 -0
  142. package/miniprogram_dist/progress/index.wxss +163 -0
  143. package/miniprogram_dist/progress/index.wxss.map +1 -0
  144. package/miniprogram_dist/radio/index.d.ts +0 -0
  145. package/miniprogram_dist/radio/index.js +52 -0
  146. package/miniprogram_dist/radio/index.js.map +1 -0
  147. package/miniprogram_dist/radio/index.json +6 -0
  148. package/miniprogram_dist/radio/index.wxml +16 -0
  149. package/miniprogram_dist/radio/index.wxss +62 -0
  150. package/miniprogram_dist/radio/index.wxss.map +1 -0
  151. package/miniprogram_dist/rate/index.d.ts +0 -0
  152. package/miniprogram_dist/rate/index.js +128 -0
  153. package/miniprogram_dist/rate/index.js.map +1 -0
  154. package/miniprogram_dist/rate/index.json +6 -0
  155. package/miniprogram_dist/rate/index.wxml +31 -0
  156. package/miniprogram_dist/rate/index.wxss +89 -0
  157. package/miniprogram_dist/rate/index.wxss.map +1 -0
  158. package/miniprogram_dist/select-input/index.d.ts +0 -0
  159. package/miniprogram_dist/select-input/index.js +116 -0
  160. package/miniprogram_dist/select-input/index.js.map +1 -0
  161. package/miniprogram_dist/select-input/index.json +6 -0
  162. package/miniprogram_dist/select-input/index.wxml +43 -0
  163. package/miniprogram_dist/select-input/index.wxss +143 -0
  164. package/miniprogram_dist/select-input/index.wxss.map +1 -0
  165. package/miniprogram_dist/skeleton/index.d.ts +0 -0
  166. package/miniprogram_dist/skeleton/index.js +102 -0
  167. package/miniprogram_dist/skeleton/index.js.map +1 -0
  168. package/miniprogram_dist/skeleton/index.json +6 -0
  169. package/miniprogram_dist/skeleton/index.wxml +40 -0
  170. package/miniprogram_dist/skeleton/index.wxss +103 -0
  171. package/miniprogram_dist/skeleton/index.wxss.map +1 -0
  172. package/miniprogram_dist/slider/index.d.ts +0 -0
  173. package/miniprogram_dist/slider/index.js +180 -0
  174. package/miniprogram_dist/slider/index.js.map +1 -0
  175. package/miniprogram_dist/slider/index.json +6 -0
  176. package/miniprogram_dist/slider/index.wxml +38 -0
  177. package/miniprogram_dist/slider/index.wxss +132 -0
  178. package/miniprogram_dist/slider/index.wxss.map +1 -0
  179. package/miniprogram_dist/subsection/index.d.ts +0 -0
  180. package/miniprogram_dist/subsection/index.js +85 -0
  181. package/miniprogram_dist/subsection/index.js.map +1 -0
  182. package/miniprogram_dist/subsection/index.json +6 -0
  183. package/miniprogram_dist/subsection/index.wxml +55 -0
  184. package/miniprogram_dist/subsection/index.wxss +150 -0
  185. package/miniprogram_dist/subsection/index.wxss.map +1 -0
  186. package/miniprogram_dist/swipe-cell/index.d.ts +0 -0
  187. package/miniprogram_dist/swipe-cell/index.js +91 -0
  188. package/miniprogram_dist/swipe-cell/index.js.map +1 -0
  189. package/miniprogram_dist/swipe-cell/index.json +6 -0
  190. package/miniprogram_dist/swipe-cell/index.wxml +30 -0
  191. package/miniprogram_dist/swipe-cell/index.wxss +42 -0
  192. package/miniprogram_dist/swipe-cell/index.wxss.map +1 -0
  193. package/miniprogram_dist/swiper/index.d.ts +0 -0
  194. package/miniprogram_dist/swiper/index.js +82 -0
  195. package/miniprogram_dist/swiper/index.js.map +1 -0
  196. package/miniprogram_dist/swiper/index.json +6 -0
  197. package/miniprogram_dist/swiper/index.wxml +53 -0
  198. package/miniprogram_dist/swiper/index.wxss +123 -0
  199. package/miniprogram_dist/swiper/index.wxss.map +1 -0
  200. package/miniprogram_dist/switch/index.d.ts +0 -0
  201. package/miniprogram_dist/switch/index.js +53 -0
  202. package/miniprogram_dist/switch/index.js.map +1 -0
  203. package/miniprogram_dist/switch/index.json +6 -0
  204. package/miniprogram_dist/switch/index.wxml +21 -0
  205. package/miniprogram_dist/switch/index.wxss +198 -0
  206. package/miniprogram_dist/switch/index.wxss.map +1 -0
  207. package/miniprogram_dist/tag/index.d.ts +0 -0
  208. package/miniprogram_dist/tag/index.js +114 -0
  209. package/miniprogram_dist/tag/index.js.map +1 -0
  210. package/miniprogram_dist/tag/index.json +6 -0
  211. package/miniprogram_dist/tag/index.wxml +19 -0
  212. package/miniprogram_dist/tag/index.wxss +182 -0
  213. package/miniprogram_dist/tag/index.wxss.map +1 -0
  214. package/miniprogram_dist/textarea/index.d.ts +0 -0
  215. package/miniprogram_dist/textarea/index.js +143 -0
  216. package/miniprogram_dist/textarea/index.js.map +1 -0
  217. package/miniprogram_dist/textarea/index.json +6 -0
  218. package/miniprogram_dist/textarea/index.wxml +59 -0
  219. package/miniprogram_dist/textarea/index.wxss +242 -0
  220. package/miniprogram_dist/textarea/index.wxss.map +1 -0
  221. package/miniprogram_dist/toast/index.d.ts +0 -0
  222. package/miniprogram_dist/toast/index.js +92 -0
  223. package/miniprogram_dist/toast/index.js.map +1 -0
  224. package/miniprogram_dist/toast/index.json +8 -0
  225. package/miniprogram_dist/toast/index.wxml +30 -0
  226. package/miniprogram_dist/toast/index.wxss +116 -0
  227. package/miniprogram_dist/toast/index.wxss.map +1 -0
  228. package/miniprogram_dist/uploader/index.d.ts +8 -0
  229. package/miniprogram_dist/uploader/index.js +192 -0
  230. package/miniprogram_dist/uploader/index.js.map +1 -0
  231. package/miniprogram_dist/uploader/index.json +8 -0
  232. package/miniprogram_dist/uploader/index.wxml +88 -0
  233. package/miniprogram_dist/uploader/index.wxss +179 -0
  234. package/miniprogram_dist/uploader/index.wxss.map +1 -0
  235. package/package.json +70 -0
@@ -0,0 +1,281 @@
1
+ "use strict";
2
+ Component({
3
+ options: {
4
+ virtualHost: true,
5
+ multipleSlots: true
6
+ },
7
+ properties: {
8
+ // 按钮内置预设图标名称
9
+ icon: {
10
+ type: String,
11
+ value: ''
12
+ },
13
+ // 按钮文本,为空时退化为圆形按钮
14
+ text: {
15
+ type: String,
16
+ value: ''
17
+ },
18
+ // 按钮背景色,支持 hex, rgb, linear-gradient 渐变色
19
+ color: {
20
+ type: String,
21
+ value: '#6366f1' // 默认使用高品质的极客紫蓝
22
+ },
23
+ // 按钮文字与图标颜色
24
+ textColor: {
25
+ type: String,
26
+ value: '#ffffff'
27
+ },
28
+ // 智能发光阴影颜色。支持传入十六进制或rgba,将自动解析为具有羽化质感的浮光投影
29
+ shadowColor: {
30
+ type: String,
31
+ value: 'rgba(99, 102, 241, 0.35)' // 默认与主题色呼应的柔和阴影
32
+ },
33
+ // 定位属性
34
+ bottom: {
35
+ type: null,
36
+ value: '140rpx'
37
+ },
38
+ right: {
39
+ type: null,
40
+ value: '40rpx'
41
+ },
42
+ left: {
43
+ type: null,
44
+ value: ''
45
+ },
46
+ top: {
47
+ type: null,
48
+ value: ''
49
+ },
50
+ // 手动控制折叠态
51
+ folded: {
52
+ type: Boolean,
53
+ value: false,
54
+ observer(newVal) {
55
+ this.setData({ isFolded: newVal });
56
+ }
57
+ },
58
+ // 页面滚动高度绑定,用于实现丝滑的滚动自动折叠文字动效
59
+ scrollTop: {
60
+ type: Number,
61
+ value: 0,
62
+ observer(newVal) {
63
+ this.handleScroll(newVal);
64
+ }
65
+ },
66
+ // 滚动折叠敏感度 (单位 px)
67
+ scrollThreshold: {
68
+ type: Number,
69
+ value: 10
70
+ },
71
+ // 子菜单操作项列表
72
+ actions: {
73
+ type: Array,
74
+ value: [] // 格式: [{ icon: 'shezhi', text: '设置', color: '#10b981', textColor: '#fff', shadowColor: 'rgba(...)' }]
75
+ },
76
+ // 子菜单展开状态
77
+ open: {
78
+ type: Boolean,
79
+ value: false,
80
+ observer(newVal) {
81
+ if (newVal !== this.data.innerOpen) {
82
+ this.setData({ innerOpen: newVal });
83
+ }
84
+ }
85
+ },
86
+ // 是否开启滑动页面往右边缘收起隐藏的开关,默认不开启
87
+ scrollShrink: {
88
+ type: Boolean,
89
+ value: false
90
+ },
91
+ // 自定义样式
92
+ customStyle: {
93
+ type: String,
94
+ value: ''
95
+ }
96
+ },
97
+ data: {
98
+ positionStyle: '', // 计算后的定位样式串
99
+ buttonStyle: '', // 计算后的按钮样式串
100
+ isFolded: false, // 内部的折叠状态
101
+ innerOpen: false, // 内部的展开状态
102
+ isShrinked: false, // 内部的滑动收缩边缘隐藏状态
103
+ lastScrollTop: 0, // 上次滚动位置 (px)
104
+ scrollAccumulator: 0, // 滚动增量累加器
105
+ shrinkTimer: 0, // 收缩边缘隐藏定时器 ID
106
+ },
107
+ observers: {
108
+ // 监听定位与视觉属性,属性改变时主动重新计算样式,支持全动态热更新
109
+ 'left, right, top, bottom, color, shadowColor': function () {
110
+ this.initStyles();
111
+ }
112
+ },
113
+ lifetimes: {
114
+ attached() {
115
+ // 在加载时主动计算并更新定位和按钮样式,防止某些环境下 observers 初始化未触发导致定位丢失
116
+ this.initStyles();
117
+ // 初始化状态同步
118
+ this.setData({
119
+ isFolded: this.properties.folded,
120
+ innerOpen: this.properties.open,
121
+ isShrinked: false
122
+ });
123
+ },
124
+ detached() {
125
+ if (this.data.shrinkTimer) {
126
+ clearTimeout(this.data.shrinkTimer);
127
+ }
128
+ }
129
+ },
130
+ methods: {
131
+ // 统一初始化并更新组件的绝对定位与主视觉样式
132
+ initStyles() {
133
+ const { left, right, top, bottom, color, shadowColor } = this.properties;
134
+ // 1. 物理位置定位计算
135
+ const parseUnit = (val) => {
136
+ if (val === undefined || val === null || val === '')
137
+ return '';
138
+ return typeof val === 'number' ? `${val}rpx` : val;
139
+ };
140
+ const posStyles = [];
141
+ const l = parseUnit(left);
142
+ const r = parseUnit(right);
143
+ const t = parseUnit(top);
144
+ const b = parseUnit(bottom);
145
+ if (l) {
146
+ posStyles.push(`left: ${l};`);
147
+ }
148
+ else if (r) {
149
+ posStyles.push(`right: ${r};`);
150
+ }
151
+ else {
152
+ posStyles.push(`right: 40rpx;`); // 默认在右侧合适位置
153
+ }
154
+ if (t) {
155
+ posStyles.push(`top: ${t};`);
156
+ }
157
+ else if (b) {
158
+ posStyles.push(`bottom: ${b};`);
159
+ }
160
+ else {
161
+ posStyles.push(`bottom: 140rpx;`); // 默认在右下角稍上(避让底部安全区)
162
+ }
163
+ // 2. 主按钮发光背景与霓虹阴影计算
164
+ const btnStyles = [];
165
+ if (color) {
166
+ if (color.indexOf('gradient') !== -1) {
167
+ btnStyles.push(`background: ${color};`);
168
+ btnStyles.push(`border: none;`);
169
+ }
170
+ else {
171
+ btnStyles.push(`background-color: ${color};`);
172
+ }
173
+ }
174
+ if (shadowColor) {
175
+ btnStyles.push(`box-shadow: 0 8px 26px ${shadowColor};`);
176
+ }
177
+ else {
178
+ btnStyles.push(`box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);`);
179
+ }
180
+ this.setData({
181
+ positionStyle: posStyles.join(' '),
182
+ buttonStyle: btnStyles.join(' ')
183
+ });
184
+ },
185
+ // 核心滚动检测算法,用于高流畅度的滚动联动折叠效果与自动往右侧边缘隐藏缩拢效果
186
+ handleScroll(scrollTop) {
187
+ const threshold = this.properties.scrollThreshold;
188
+ const lastScrollTop = this.data.lastScrollTop;
189
+ let scrollAccumulator = this.data.scrollAccumulator;
190
+ const diff = scrollTop - lastScrollTop;
191
+ // 避免初始值为 0 或页面边界异常导致闪烁
192
+ if (scrollTop <= 5) {
193
+ if (this.data.isFolded) {
194
+ this.setData({ isFolded: false });
195
+ this.triggerEvent('foldchange', { folded: false });
196
+ }
197
+ // 如果开启了滚动隐藏,回到顶部时也要恢复展开
198
+ if (this.properties.scrollShrink && this.data.isShrinked) {
199
+ if (this.data.shrinkTimer) {
200
+ clearTimeout(this.data.shrinkTimer);
201
+ }
202
+ this.setData({ isShrinked: false });
203
+ }
204
+ this.setData({ lastScrollTop: scrollTop, scrollAccumulator: 0 });
205
+ return;
206
+ }
207
+ // --- 新增:滑动页面向右收缩边缘隐藏防抖逻辑 ---
208
+ if (this.properties.scrollShrink) {
209
+ if (!this.data.isShrinked) {
210
+ this.setData({
211
+ isShrinked: true,
212
+ innerOpen: false, // 滚动时自动收起已经展开的快捷子菜单
213
+ open: false
214
+ });
215
+ }
216
+ if (this.data.shrinkTimer) {
217
+ clearTimeout(this.data.shrinkTimer);
218
+ }
219
+ const timer = setTimeout(() => {
220
+ this.setData({ isShrinked: false });
221
+ }, 500); // 500毫秒静止无滚动,自动弹回,高级交互感拉满!
222
+ this.setData({ shrinkTimer: timer });
223
+ }
224
+ // 累加滚动增量
225
+ scrollAccumulator += diff;
226
+ if (diff > 0) {
227
+ // 向上滑动页面 (手指往上划,页面向下滚):折叠文字收起,隐藏次要信息以让路内容展示
228
+ if (scrollAccumulator > threshold && !this.data.isFolded) {
229
+ this.setData({ isFolded: true });
230
+ this.triggerEvent('foldchange', { folded: true });
231
+ scrollAccumulator = 0;
232
+ }
233
+ }
234
+ else if (diff < 0) {
235
+ // 向下滑动页面 (手指往下划,页面向上滚):重新展开按钮释放完整交互功能
236
+ if (Math.abs(scrollAccumulator) > threshold && this.data.isFolded) {
237
+ this.setData({ isFolded: false });
238
+ this.triggerEvent('foldchange', { folded: false });
239
+ scrollAccumulator = 0;
240
+ }
241
+ }
242
+ // 限制累加器大小,防止过度积压
243
+ if (Math.abs(scrollAccumulator) > 100) {
244
+ scrollAccumulator = scrollAccumulator > 0 ? 100 : -100;
245
+ }
246
+ this.setData({ lastScrollTop: scrollTop, scrollAccumulator: scrollAccumulator });
247
+ },
248
+ // 点击主按钮逻辑
249
+ onMainTap(event) {
250
+ const { actions } = this.properties;
251
+ const { innerOpen } = this.data;
252
+ if (actions && actions.length > 0) {
253
+ // 存在子菜单,执行折叠/展开的开关逻辑
254
+ const newOpenState = !innerOpen;
255
+ this.setData({
256
+ innerOpen: newOpenState,
257
+ open: newOpenState // 支持双向绑定或手动同步
258
+ });
259
+ this.triggerEvent('change', { open: newOpenState });
260
+ }
261
+ else {
262
+ // 普通悬浮按钮,直接触发 tap 点击事件
263
+ this.triggerEvent('click', event.detail);
264
+ }
265
+ },
266
+ // 点击子菜单项
267
+ onActionTap(event) {
268
+ const { index, item } = event.currentTarget.dataset;
269
+ // 分发事件通知外界
270
+ this.triggerEvent('actionclick', { index, item });
271
+ // 点击后,自动优雅地收回子菜单
272
+ this.setData({
273
+ innerOpen: false,
274
+ open: false
275
+ });
276
+ this.triggerEvent('change', { open: false });
277
+ }
278
+ }
279
+ });
280
+
281
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/float-button/index.ts"],"names":[],"mappings":";AAAA,SAAS,CAAC;IACR,OAAO,EAAE;QACP,WAAW,EAAE,IAAI;QACjB,aAAa,EAAE,IAAI;KACpB;IAED,UAAU,EAAE;QACV,aAAa;QACb,IAAI,EAAE;YACJ,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,EAAE;SACV;QACD,kBAAkB;QAClB,IAAI,EAAE;YACJ,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,EAAE;SACV;QACD,yCAAyC;QACzC,KAAK,EAAE;YACL,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,SAAS,CAAC,eAAe;SACjC;QACD,YAAY;QACZ,SAAS,EAAE;YACT,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,SAAS;SACjB;QACD,2CAA2C;QAC3C,WAAW,EAAE;YACX,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,0BAA0B,CAAC,gBAAgB;SACnD;QACD,OAAO;QACP,MAAM,EAAE;YACN,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,QAAQ;SAChB;QACD,KAAK,EAAE;YACL,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,OAAO;SACf;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,EAAE;SACV;QACD,GAAG,EAAE;YACH,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,EAAE;SACV;QACD,UAAU;QACV,MAAM,EAAE;YACN,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,KAAK;YACZ,QAAQ,CAAC,MAAM;gBACb,IAAI,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;YACrC,CAAC;SACF;QACD,6BAA6B;QAC7B,SAAS,EAAE;YACT,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,CAAC;YACR,QAAQ,CAAC,MAAM;gBACb,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YAC5B,CAAC;SACF;QACD,kBAAkB;QAClB,eAAe,EAAE;YACf,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,EAAE;SACV;QACD,WAAW;QACX,OAAO,EAAE;YACP,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,EAAE,CAAC,sGAAsG;SACjH;QACD,UAAU;QACV,IAAI,EAAE;YACJ,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,KAAK;YACZ,QAAQ,CAAC,MAAM;gBACb,IAAI,MAAM,KAAK,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;oBACnC,IAAI,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC;SACF;QACD,4BAA4B;QAC5B,YAAY,EAAE;YACZ,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,KAAK;SACb;QACD,QAAQ;QACR,WAAW,EAAE;YACX,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,EAAE;SACV;KACF;IAED,IAAI,EAAE;QACJ,aAAa,EAAE,EAAE,EAAE,YAAY;QAC/B,WAAW,EAAE,EAAE,EAAI,YAAY;QAC/B,QAAQ,EAAE,KAAK,EAAI,UAAU;QAC7B,SAAS,EAAE,KAAK,EAAG,UAAU;QAC7B,UAAU,EAAE,KAAK,EAAE,gBAAgB;QACnC,aAAa,EAAE,CAAC,EAAG,cAAc;QACjC,iBAAiB,EAAE,CAAC,EAAE,UAAU;QAChC,WAAW,EAAE,CAAC,EAAK,eAAe;KACnC;IAED,SAAS,EAAE;QACT,mCAAmC;QACnC,8CAA8C,EAAE;YAC9C,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,CAAC;KACF;IAED,SAAS,EAAE;QACT,QAAQ;YACN,oDAAoD;YACpD,IAAI,CAAC,UAAU,EAAE,CAAC;YAElB,UAAU;YACV,IAAI,CAAC,OAAO,CAAC;gBACX,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM;gBAChC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI;gBAC/B,UAAU,EAAE,KAAK;aAClB,CAAC,CAAC;QACL,CAAC;QACD,QAAQ;YACN,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;gBAC1B,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;KACF;IAED,OAAO,EAAE;QACP,wBAAwB;QACxB,UAAU;YACR,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC;YAEzE,cAAc;YACd,MAAM,SAAS,GAAG,CAAC,GAAQ,EAAE,EAAE;gBAC7B,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,EAAE;oBAAE,OAAO,EAAE,CAAC;gBAC/D,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;YACrD,CAAC,CAAC;YAEF,MAAM,SAAS,GAAG,EAAE,CAAC;YACrB,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YAC1B,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YAC3B,MAAM,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;YACzB,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;YAE5B,IAAI,CAAC,EAAE,CAAC;gBACN,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YAChC,CAAC;iBAAM,IAAI,CAAC,EAAE,CAAC;gBACb,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YACjC,CAAC;iBAAM,CAAC;gBACN,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,YAAY;YAC/C,CAAC;YAED,IAAI,CAAC,EAAE,CAAC;gBACN,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC/B,CAAC;iBAAM,IAAI,CAAC,EAAE,CAAC;gBACb,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YAClC,CAAC;iBAAM,CAAC;gBACN,SAAS,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,oBAAoB;YACzD,CAAC;YAED,oBAAoB;YACpB,MAAM,SAAS,GAAG,EAAE,CAAC;YACrB,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;oBACrC,SAAS,CAAC,IAAI,CAAC,eAAe,KAAK,GAAG,CAAC,CAAC;oBACxC,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;gBAClC,CAAC;qBAAM,CAAC;oBACN,SAAS,CAAC,IAAI,CAAC,qBAAqB,KAAK,GAAG,CAAC,CAAC;gBAChD,CAAC;YACH,CAAC;YAED,IAAI,WAAW,EAAE,CAAC;gBAChB,SAAS,CAAC,IAAI,CAAC,0BAA0B,WAAW,GAAG,CAAC,CAAC;YAC3D,CAAC;iBAAM,CAAC;gBACN,SAAS,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;YAChE,CAAC;YAED,IAAI,CAAC,OAAO,CAAC;gBACX,aAAa,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;gBAClC,WAAW,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;aACjC,CAAC,CAAC;QACL,CAAC;QAED,yCAAyC;QACzC,YAAY,CAAC,SAAiB;YAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC;YAClD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;YAC9C,IAAI,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC;YACpD,MAAM,IAAI,GAAG,SAAS,GAAG,aAAa,CAAC;YAEvC,uBAAuB;YACvB,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;gBACnB,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACvB,IAAI,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;oBAClC,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;gBACrD,CAAC;gBACD,wBAAwB;gBACxB,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;oBACzD,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;wBAC1B,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;oBACtC,CAAC;oBACD,IAAI,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;gBACtC,CAAC;gBACD,IAAI,CAAC,OAAO,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC,CAAC;gBACjE,OAAO;YACT,CAAC;YAED,8BAA8B;YAC9B,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC;gBACjC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;oBAC1B,IAAI,CAAC,OAAO,CAAC;wBACX,UAAU,EAAE,IAAI;wBAChB,SAAS,EAAE,KAAK,EAAE,oBAAoB;wBACtC,IAAI,EAAE,KAAK;qBACZ,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;oBAC1B,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBACtC,CAAC;gBACD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;oBAC5B,IAAI,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;gBACtC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,2BAA2B;gBACpC,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;YACvC,CAAC;YAED,SAAS;YACT,iBAAiB,IAAI,IAAI,CAAC;YAE1B,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;gBACb,4CAA4C;gBAC5C,IAAI,iBAAiB,GAAG,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACzD,IAAI,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;oBACjC,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;oBAClD,iBAAiB,GAAG,CAAC,CAAC;gBACxB,CAAC;YACH,CAAC;iBAAM,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;gBACpB,sCAAsC;gBACtC,IAAI,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,GAAG,SAAS,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAClE,IAAI,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;oBAClC,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;oBACnD,iBAAiB,GAAG,CAAC,CAAC;gBACxB,CAAC;YACH,CAAC;YAED,iBAAiB;YACjB,IAAI,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,GAAG,GAAG,EAAE,CAAC;gBACtC,iBAAiB,GAAG,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YACzD,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,CAAC,CAAC;QACnF,CAAC;QAED,UAAU;QACV,SAAS,CAAC,KAAmC;YAC3C,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC;YACpC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;YAEhC,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAClC,qBAAqB;gBACrB,MAAM,YAAY,GAAG,CAAC,SAAS,CAAC;gBAChC,IAAI,CAAC,OAAO,CAAC;oBACX,SAAS,EAAE,YAAY;oBACvB,IAAI,EAAE,YAAY,CAAC,cAAc;iBAClC,CAAC,CAAC;gBACH,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;YACtD,CAAC;iBAAM,CAAC;gBACN,uBAAuB;gBACvB,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QAED,SAAS;QACT,WAAW,CAAC,KAAmC;YAC7C,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC;YAEpD,WAAW;YACX,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAElD,iBAAiB;YACjB,IAAI,CAAC,OAAO,CAAC;gBACX,SAAS,EAAE,KAAK;gBAChB,IAAI,EAAE,KAAK;aACZ,CAAC,CAAC;YACH,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/C,CAAC;KACF;CACF,CAAC,CAAC","file":"index.js","sourcesContent":["Component({\r\n options: {\r\n virtualHost: true,\r\n multipleSlots: true\r\n },\r\n\r\n properties: {\r\n // 按钮内置预设图标名称\r\n icon: {\r\n type: String,\r\n value: ''\r\n },\r\n // 按钮文本,为空时退化为圆形按钮\r\n text: {\r\n type: String,\r\n value: ''\r\n },\r\n // 按钮背景色,支持 hex, rgb, linear-gradient 渐变色\r\n color: {\r\n type: String,\r\n value: '#6366f1' // 默认使用高品质的极客紫蓝\r\n },\r\n // 按钮文字与图标颜色\r\n textColor: {\r\n type: String,\r\n value: '#ffffff'\r\n },\r\n // 智能发光阴影颜色。支持传入十六进制或rgba,将自动解析为具有羽化质感的浮光投影\r\n shadowColor: {\r\n type: String,\r\n value: 'rgba(99, 102, 241, 0.35)' // 默认与主题色呼应的柔和阴影\r\n },\r\n // 定位属性\r\n bottom: {\r\n type: null,\r\n value: '140rpx'\r\n },\r\n right: {\r\n type: null,\r\n value: '40rpx'\r\n },\r\n left: {\r\n type: null,\r\n value: ''\r\n },\r\n top: {\r\n type: null,\r\n value: ''\r\n },\r\n // 手动控制折叠态\r\n folded: {\r\n type: Boolean,\r\n value: false,\r\n observer(newVal) {\r\n this.setData({ isFolded: newVal });\r\n }\r\n },\r\n // 页面滚动高度绑定,用于实现丝滑的滚动自动折叠文字动效\r\n scrollTop: {\r\n type: Number,\r\n value: 0,\r\n observer(newVal) {\r\n this.handleScroll(newVal);\r\n }\r\n },\r\n // 滚动折叠敏感度 (单位 px)\r\n scrollThreshold: {\r\n type: Number,\r\n value: 10\r\n },\r\n // 子菜单操作项列表\r\n actions: {\r\n type: Array,\r\n value: [] // 格式: [{ icon: 'shezhi', text: '设置', color: '#10b981', textColor: '#fff', shadowColor: 'rgba(...)' }]\r\n },\r\n // 子菜单展开状态\r\n open: {\r\n type: Boolean,\r\n value: false,\r\n observer(newVal) {\r\n if (newVal !== this.data.innerOpen) {\r\n this.setData({ innerOpen: newVal });\r\n }\r\n }\r\n },\r\n // 是否开启滑动页面往右边缘收起隐藏的开关,默认不开启\r\n scrollShrink: {\r\n type: Boolean,\r\n value: false\r\n },\r\n // 自定义样式\r\n customStyle: {\r\n type: String,\r\n value: ''\r\n }\r\n },\r\n\r\n data: {\r\n positionStyle: '', // 计算后的定位样式串\r\n buttonStyle: '', // 计算后的按钮样式串\r\n isFolded: false, // 内部的折叠状态\r\n innerOpen: false, // 内部的展开状态\r\n isShrinked: false, // 内部的滑动收缩边缘隐藏状态\r\n lastScrollTop: 0, // 上次滚动位置 (px)\r\n scrollAccumulator: 0, // 滚动增量累加器\r\n shrinkTimer: 0, // 收缩边缘隐藏定时器 ID\r\n },\r\n\r\n observers: {\r\n // 监听定位与视觉属性,属性改变时主动重新计算样式,支持全动态热更新\r\n 'left, right, top, bottom, color, shadowColor': function() {\r\n this.initStyles();\r\n }\r\n },\r\n\r\n lifetimes: {\r\n attached() {\r\n // 在加载时主动计算并更新定位和按钮样式,防止某些环境下 observers 初始化未触发导致定位丢失\r\n this.initStyles();\r\n\r\n // 初始化状态同步\r\n this.setData({\r\n isFolded: this.properties.folded,\r\n innerOpen: this.properties.open,\r\n isShrinked: false\r\n });\r\n },\r\n detached() {\r\n if (this.data.shrinkTimer) {\r\n clearTimeout(this.data.shrinkTimer);\r\n }\r\n }\r\n },\r\n\r\n methods: {\r\n // 统一初始化并更新组件的绝对定位与主视觉样式\r\n initStyles() {\r\n const { left, right, top, bottom, color, shadowColor } = this.properties;\r\n \r\n // 1. 物理位置定位计算\r\n const parseUnit = (val: any) => {\r\n if (val === undefined || val === null || val === '') return '';\r\n return typeof val === 'number' ? `${val}rpx` : val;\r\n };\r\n\r\n const posStyles = [];\r\n const l = parseUnit(left);\r\n const r = parseUnit(right);\r\n const t = parseUnit(top);\r\n const b = parseUnit(bottom);\r\n\r\n if (l) {\r\n posStyles.push(`left: ${l};`);\r\n } else if (r) {\r\n posStyles.push(`right: ${r};`);\r\n } else {\r\n posStyles.push(`right: 40rpx;`); // 默认在右侧合适位置\r\n }\r\n\r\n if (t) {\r\n posStyles.push(`top: ${t};`);\r\n } else if (b) {\r\n posStyles.push(`bottom: ${b};`);\r\n } else {\r\n posStyles.push(`bottom: 140rpx;`); // 默认在右下角稍上(避让底部安全区)\r\n }\r\n\r\n // 2. 主按钮发光背景与霓虹阴影计算\r\n const btnStyles = [];\r\n if (color) {\r\n if (color.indexOf('gradient') !== -1) {\r\n btnStyles.push(`background: ${color};`);\r\n btnStyles.push(`border: none;`);\r\n } else {\r\n btnStyles.push(`background-color: ${color};`);\r\n }\r\n }\r\n\r\n if (shadowColor) {\r\n btnStyles.push(`box-shadow: 0 8px 26px ${shadowColor};`);\r\n } else {\r\n btnStyles.push(`box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);`);\r\n }\r\n\r\n this.setData({\r\n positionStyle: posStyles.join(' '),\r\n buttonStyle: btnStyles.join(' ')\r\n });\r\n },\r\n\r\n // 核心滚动检测算法,用于高流畅度的滚动联动折叠效果与自动往右侧边缘隐藏缩拢效果\r\n handleScroll(scrollTop: number) {\r\n const threshold = this.properties.scrollThreshold;\r\n const lastScrollTop = this.data.lastScrollTop;\r\n let scrollAccumulator = this.data.scrollAccumulator;\r\n const diff = scrollTop - lastScrollTop;\r\n\r\n // 避免初始值为 0 或页面边界异常导致闪烁\r\n if (scrollTop <= 5) {\r\n if (this.data.isFolded) {\r\n this.setData({ isFolded: false });\r\n this.triggerEvent('foldchange', { folded: false });\r\n }\r\n // 如果开启了滚动隐藏,回到顶部时也要恢复展开\r\n if (this.properties.scrollShrink && this.data.isShrinked) {\r\n if (this.data.shrinkTimer) {\r\n clearTimeout(this.data.shrinkTimer);\r\n }\r\n this.setData({ isShrinked: false });\r\n }\r\n this.setData({ lastScrollTop: scrollTop, scrollAccumulator: 0 });\r\n return;\r\n }\r\n\r\n // --- 新增:滑动页面向右收缩边缘隐藏防抖逻辑 ---\r\n if (this.properties.scrollShrink) {\r\n if (!this.data.isShrinked) {\r\n this.setData({\r\n isShrinked: true,\r\n innerOpen: false, // 滚动时自动收起已经展开的快捷子菜单\r\n open: false\r\n });\r\n }\r\n if (this.data.shrinkTimer) {\r\n clearTimeout(this.data.shrinkTimer);\r\n }\r\n const timer = setTimeout(() => {\r\n this.setData({ isShrinked: false });\r\n }, 500); // 500毫秒静止无滚动,自动弹回,高级交互感拉满!\r\n this.setData({ shrinkTimer: timer });\r\n }\r\n\r\n // 累加滚动增量\r\n scrollAccumulator += diff;\r\n\r\n if (diff > 0) {\r\n // 向上滑动页面 (手指往上划,页面向下滚):折叠文字收起,隐藏次要信息以让路内容展示\r\n if (scrollAccumulator > threshold && !this.data.isFolded) {\r\n this.setData({ isFolded: true });\r\n this.triggerEvent('foldchange', { folded: true });\r\n scrollAccumulator = 0;\r\n }\r\n } else if (diff < 0) {\r\n // 向下滑动页面 (手指往下划,页面向上滚):重新展开按钮释放完整交互功能\r\n if (Math.abs(scrollAccumulator) > threshold && this.data.isFolded) {\r\n this.setData({ isFolded: false });\r\n this.triggerEvent('foldchange', { folded: false });\r\n scrollAccumulator = 0;\r\n }\r\n }\r\n\r\n // 限制累加器大小,防止过度积压\r\n if (Math.abs(scrollAccumulator) > 100) {\r\n scrollAccumulator = scrollAccumulator > 0 ? 100 : -100;\r\n }\r\n\r\n this.setData({ lastScrollTop: scrollTop, scrollAccumulator: scrollAccumulator });\r\n },\r\n\r\n // 点击主按钮逻辑\r\n onMainTap(event: WechatMiniprogram.TouchEvent) {\r\n const { actions } = this.properties;\r\n const { innerOpen } = this.data;\r\n\r\n if (actions && actions.length > 0) {\r\n // 存在子菜单,执行折叠/展开的开关逻辑\r\n const newOpenState = !innerOpen;\r\n this.setData({\r\n innerOpen: newOpenState,\r\n open: newOpenState // 支持双向绑定或手动同步\r\n });\r\n this.triggerEvent('change', { open: newOpenState });\r\n } else {\r\n // 普通悬浮按钮,直接触发 tap 点击事件\r\n this.triggerEvent('click', event.detail);\r\n }\r\n },\r\n\r\n // 点击子菜单项\r\n onActionTap(event: WechatMiniprogram.TouchEvent) {\r\n const { index, item } = event.currentTarget.dataset;\r\n \r\n // 分发事件通知外界\r\n this.triggerEvent('actionclick', { index, item });\r\n\r\n // 点击后,自动优雅地收回子菜单\r\n this.setData({\r\n innerOpen: false,\r\n open: false\r\n });\r\n this.triggerEvent('change', { open: false });\r\n }\r\n }\r\n});\r\n"]}
@@ -0,0 +1,8 @@
1
+ {
2
+ "component": true,
3
+ "renderer": "skyline",
4
+ "componentFramework": "glass-easel",
5
+ "usingComponents": {
6
+ "sky-icon": "../icon/index"
7
+ }
8
+ }
@@ -0,0 +1,68 @@
1
+ <view
2
+ class="sky-float-button-wrap {{ isShrinked ? 'sky-float-button-wrap--shrink' : '' }}"
3
+ style="{{ positionStyle }} {{ customStyle }}"
4
+ >
5
+ <!-- 子操作菜单列表 (Speed Dial Actions) -->
6
+ <view
7
+ wx:if="{{ actions && actions.length > 0 }}"
8
+ class="sky-float-button__actions {{ open ? 'sky-float-button__actions--open' : '' }}"
9
+ >
10
+ <view
11
+ wx:for="{{ actions }}"
12
+ wx:key="index"
13
+ class="sky-float-button__action-item {{ open ? 'sky-float-button__action-item--open' : '' }}"
14
+ style="transition-delay: {{ open ? (actions.length - 1 - index) * 50 : index * 50 }}ms; transform: translateY({{ open ? '0' : (actions.length - index) * 60 + 'px' }}) scale({{ open ? 1 : 0.6 }}); opacity: {{ open ? 1 : 0 }};"
15
+ catchtap="onActionTap"
16
+ data-index="{{ index }}"
17
+ data-item="{{ item }}"
18
+ >
19
+ <!-- 子操作项文字标签 -->
20
+ <text
21
+ wx:if="{{ item.text }}"
22
+ class="sky-float-button__action-text"
23
+ style="{{ item.textColor ? 'color: ' + item.textColor : '' }}"
24
+ >{{ item.text }}</text>
25
+
26
+ <!-- 子操作项圆形按钮 -->
27
+ <view
28
+ class="sky-float-button__action-btn"
29
+ style="background: {{ item.color || '#ffffff' }}; box-shadow: {{ item.shadowColor ? '0 4px 10px ' + item.shadowColor : '0 4px 12px rgba(0, 0, 0, 0.08)' }};"
30
+ >
31
+ <sky-icon
32
+ wx:if="{{ item.icon }}"
33
+ name="{{ item.icon }}"
34
+ color="{{ item.textColor || '#475569' }}"
35
+ size="38rpx"
36
+ />
37
+ </view>
38
+ </view>
39
+ </view>
40
+
41
+ <!-- 主悬浮按钮 (Main FAB Button) -->
42
+ <view
43
+ class="sky-float-button {{ text && !isFolded ? 'sky-float-button--capsule' : 'sky-float-button--circle' }} {{ open ? 'sky-float-button--open' : '' }}"
44
+ style="{{ buttonStyle }}"
45
+ hover-class="sky-float-button--active"
46
+ hover-stay-time="70"
47
+ bindtap="onMainTap"
48
+ >
49
+ <!-- 主图标 -->
50
+ <view class="sky-float-button__icon-wrap {{ open && actions.length > 0 ? 'sky-float-button__icon-wrap--rotated' : '' }}">
51
+ <slot name="icon" wx:if="{{ !icon }}"></slot>
52
+ <sky-icon
53
+ wx:else
54
+ name="{{ icon }}"
55
+ color="{{ textColor }}"
56
+ size="42rpx"
57
+ />
58
+ </view>
59
+
60
+ <!-- 胶囊文字:通过宽度与边距 transition 实现优雅的折叠收起动画 -->
61
+ <view
62
+ class="sky-float-button__text-wrap {{ isFolded ? 'sky-float-button__text-wrap--folded' : '' }}"
63
+ style="max-width: {{ isFolded ? '0px' : '200rpx' }}; margin-left: {{ isFolded ? '0px' : '10rpx' }}; opacity: {{ isFolded ? 0 : 1 }};"
64
+ >
65
+ <text class="sky-float-button__text" style="color: {{ textColor }};">{{ text }}</text>
66
+ </view>
67
+ </view>
68
+ </view>
@@ -0,0 +1,119 @@
1
+ .sky-float-button-wrap {
2
+ position: fixed;
3
+ z-index: 1000;
4
+ display: flex;
5
+ flex-direction: column-reverse;
6
+ align-items: flex-end;
7
+ pointer-events: none;
8
+ transition: transform 320ms cubic-bezier(0.4, 0, 0.2, 1), opacity 320ms ease;
9
+ }
10
+ .sky-float-button-wrap--shrink {
11
+ transform: translateX(76rpx);
12
+ opacity: 0.4;
13
+ }
14
+
15
+ .sky-float-button {
16
+ display: flex;
17
+ flex-direction: row;
18
+ align-items: center;
19
+ justify-content: center;
20
+ pointer-events: auto;
21
+ transition: all 250ms cubic-bezier(0.4, 0, 0.2, 1);
22
+ box-sizing: border-box;
23
+ overflow: hidden;
24
+ }
25
+ .sky-float-button--circle {
26
+ width: 96rpx;
27
+ height: 96rpx;
28
+ border-radius: 48rpx;
29
+ }
30
+ .sky-float-button--capsule {
31
+ height: 96rpx;
32
+ padding: 0 32rpx;
33
+ border-radius: 48rpx;
34
+ }
35
+ .sky-float-button--active {
36
+ transform: scale(0.92);
37
+ opacity: 0.9;
38
+ filter: brightness(0.95);
39
+ }
40
+ .sky-float-button__icon-wrap {
41
+ display: flex;
42
+ align-items: center;
43
+ justify-content: center;
44
+ transition: transform 300ms cubic-bezier(0.34, 1.56, 0.64, 1);
45
+ }
46
+ .sky-float-button__icon-wrap--rotated {
47
+ transform: rotate(135deg);
48
+ }
49
+ .sky-float-button__text-wrap {
50
+ display: flex;
51
+ align-items: center;
52
+ justify-content: center;
53
+ overflow: hidden;
54
+ transition: max-width 250ms cubic-bezier(0.4, 0, 0.2, 1), margin-left 250ms cubic-bezier(0.4, 0, 0.2, 1), opacity 200ms cubic-bezier(0.4, 0, 0.2, 1);
55
+ }
56
+ .sky-float-button__text-wrap--folded {
57
+ max-width: 0 !important;
58
+ margin-left: 0 !important;
59
+ opacity: 0 !important;
60
+ }
61
+ .sky-float-button__text {
62
+ font-size: 28rpx;
63
+ font-weight: 600;
64
+ white-space: nowrap;
65
+ letter-spacing: 1rpx;
66
+ }
67
+
68
+ .sky-float-button__actions {
69
+ display: flex;
70
+ flex-direction: column-reverse;
71
+ align-items: flex-end;
72
+ margin-bottom: 24rpx;
73
+ pointer-events: none;
74
+ transition: opacity 250ms ease;
75
+ }
76
+ .sky-float-button__actions--open {
77
+ pointer-events: auto;
78
+ }
79
+
80
+ .sky-float-button__action-item {
81
+ display: flex;
82
+ flex-direction: row;
83
+ align-items: center;
84
+ justify-content: flex-end;
85
+ margin-bottom: 20rpx;
86
+ opacity: 0;
87
+ pointer-events: auto;
88
+ transition: transform 320ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 300ms ease, scale 300ms cubic-bezier(0.34, 1.56, 0.64, 1);
89
+ }
90
+ .sky-float-button__action-item:first-child {
91
+ margin-bottom: 0;
92
+ }
93
+
94
+ .sky-float-button__action-btn {
95
+ width: 80rpx;
96
+ height: 80rpx;
97
+ border-radius: 40rpx;
98
+ display: flex;
99
+ align-items: center;
100
+ justify-content: center;
101
+ box-sizing: border-box;
102
+ transition: transform 150ms ease;
103
+ }
104
+ .sky-float-button__action-btn:active {
105
+ transform: scale(0.88);
106
+ }
107
+
108
+ .sky-float-button__action-text {
109
+ font-size: 24rpx;
110
+ font-weight: 500;
111
+ color: #495057;
112
+ background-color: rgba(255, 255, 255, 0.96);
113
+ padding: 8rpx 18rpx;
114
+ border-radius: 10rpx;
115
+ margin-right: 20rpx;
116
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
117
+ border: 1rpx solid rgba(0, 0, 0, 0.03);
118
+ white-space: nowrap;
119
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["float-button/index.scss","common/style/theme.scss"],"names":[],"mappings":"AAIA;EACE;EACA;EACA;EACA;EACA;EACA;EAGA;;AAIA;EACE;EACA;;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKJ;EACE;EACA;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;;AAIA;EACE;;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAKJ;EACE;EACA;EACA,OC9FiB;ED+FjB;EACA;EACA;EACA;EACA;EACA;EACA","file":"index.wxss","sourcesContent":["@use \"../common/style/theme.scss\" as *;\n@use \"../common/style/mixins.scss\" as *;\n\n// 悬浮按钮绝对定位容器\n.sky-float-button-wrap {\n position: fixed;\n z-index: 1000;\n display: flex;\n flex-direction: column-reverse; // 从下至上垂直排列,极其自然地把子菜单托在主按钮上方\n align-items: flex-end;\n pointer-events: none; // 容器穿透,防止挡住页面底层元素的交互\n\n // 核心!向右滑动收缩到屏幕边缘的动画过渡配置\n transition: transform 320ms cubic-bezier(0.4, 0, 0.2, 1),\n opacity 320ms ease;\n\n // 滑动收缩状态:向右平移收拢,只露出一小弯月牙弧度作为高保真视觉暗示,极其灵动!\n &--shrink {\n transform: translateX(76rpx); // 按钮宽度为96rpx,向右位移76rpx相当于在屏幕最右侧留下20rpx的月牙圆弧边缘,极具设计质感!\n opacity: 0.4; // 半透明化避免遮挡视线\n }\n}\n\n// 主悬浮按钮\n.sky-float-button {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n pointer-events: auto; // 恢复事件响应\n transition: all 250ms cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n overflow: hidden;\n\n // 圆形状态(默认 / 折叠态)\n &--circle {\n width: 96rpx;\n height: 96rpx;\n border-radius: 48rpx;\n }\n\n // 胶囊状态(有文字且未折叠时)\n &--capsule {\n height: 96rpx;\n padding: 0 32rpx;\n border-radius: 48rpx;\n }\n\n // 按压态反馈,带来极其舒适的阻尼微缩放与发光减弱感\n &--active {\n transform: scale(0.92);\n opacity: 0.9;\n filter: brightness(0.95);\n }\n\n // 图标旋转动画包裹层\n &__icon-wrap {\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 300ms cubic-bezier(0.34, 1.56, 0.64, 1); // 带有舒适回弹效果的旋转\n\n &--rotated {\n transform: rotate(135deg); // 顺时针旋转135度,将 '+' 图标或常规图标优雅转换为 'X'\n }\n }\n\n // 胶囊文本部分\n &__text-wrap {\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n transition: max-width 250ms cubic-bezier(0.4, 0, 0.2, 1),\n margin-left 250ms cubic-bezier(0.4, 0, 0.2, 1),\n opacity 200ms cubic-bezier(0.4, 0, 0.2, 1);\n\n &--folded {\n max-width: 0 !important;\n margin-left: 0 !important;\n opacity: 0 !important;\n }\n }\n\n &__text {\n font-size: 28rpx;\n font-weight: 600;\n white-space: nowrap;\n letter-spacing: 1rpx;\n }\n}\n\n// 子操作菜单列表 (Speed Dial Actions)\n.sky-float-button__actions {\n display: flex;\n flex-direction: column-reverse;\n align-items: flex-end;\n margin-bottom: 24rpx; // 与主按钮保留舒适的呼应空隙\n pointer-events: none;\n transition: opacity 250ms ease;\n\n &--open {\n pointer-events: auto; // 展开时恢复事件响应\n }\n}\n\n// 子操作菜单项\n.sky-float-button__action-item {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: flex-end;\n margin-bottom: 20rpx;\n opacity: 0;\n pointer-events: auto;\n // 贝塞尔曲线带有弹性回弹,让子按钮像气泡一样轻盈弹出\n transition: transform 320ms cubic-bezier(0.34, 1.56, 0.64, 1),\n opacity 300ms ease,\n scale 300ms cubic-bezier(0.34, 1.56, 0.64, 1);\n\n &:first-child {\n margin-bottom: 0; // 最上面的子项不需要间距\n }\n}\n\n// 子操作圆形按钮\n.sky-float-button__action-btn {\n width: 80rpx;\n height: 80rpx;\n border-radius: 40rpx;\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n transition: transform 150ms ease;\n\n &:active {\n transform: scale(0.88); // 独立子按钮的舒适微按压态\n }\n}\n\n// 子操作文本标签(高质感气泡旁白)\n.sky-float-button__action-text {\n font-size: 24rpx;\n font-weight: 500;\n color: $sky-color-gray-7;\n background-color: rgba(255, 255, 255, 0.96);\n padding: 8rpx 18rpx;\n border-radius: 10rpx;\n margin-right: 20rpx;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);\n border: 1rpx solid rgba(0, 0, 0, 0.03);\n white-space: nowrap;\n}\n","// ==========================================\r\n// Skyline-UI 极具质感的现代设计系统 (SCSS)\r\n// ==========================================\r\n\r\n// --- 品牌色体系 (HSL Tailored Colors) ---\r\n$sky-brand-h: 250; // 主品牌色相 (优雅深紫/蓝色调)\r\n$sky-brand-s: 85%;\r\n$sky-brand-l: 55%;\r\n\r\n$sky-color-primary: hsl($sky-brand-h, $sky-brand-s, $sky-brand-l);\r\n$sky-color-primary-hover: hsl($sky-brand-h, $sky-brand-s, $sky-brand-l - 8%);\r\n$sky-color-primary-active: hsl($sky-brand-h, $sky-brand-s, $sky-brand-l - 15%);\r\n$sky-color-primary-light: hsl($sky-brand-h, $sky-brand-s, 95%);\r\n\r\n// 辅助色体系 (意图表达)\r\n$sky-color-success: hsl(150, 80%, 40%);\r\n$sky-color-success-active: hsl(150, 80%, 32%);\r\n$sky-color-success-light: hsl(150, 80%, 96%);\r\n\r\n$sky-color-warning: hsl(35, 90%, 50%);\r\n$sky-color-warning-active: hsl(35, 90%, 42%);\r\n$sky-color-warning-light: hsl(35, 90%, 96%);\r\n\r\n$sky-color-danger: hsl(355, 85%, 55%);\r\n$sky-color-danger-active: hsl(355, 85%, 45%);\r\n$sky-color-danger-light: hsl(355, 85%, 96%);\r\n\r\n$sky-color-info: hsl(200, 85%, 50%);\r\n$sky-color-info-active: hsl(200, 85%, 42%);\r\n$sky-color-info-light: hsl(200, 85%, 96%);\r\n\r\n// --- Tag 标签组件专用色系 (莫兰迪低饱和) ---\r\n$sky-tag-blue: #edf2ff;\r\n$sky-tag-blue-text: #3b5bdb;\r\n$sky-tag-green: #ebfbee;\r\n$sky-tag-green-text: #2b8a3e;\r\n$sky-tag-yellow: #fff9db;\r\n$sky-tag-yellow-text: #f08c00;\r\n$sky-tag-red: #ffeef0;\r\n$sky-tag-red-text: #fa5252;\r\n$sky-tag-info: #e7f5ff;\r\n$sky-tag-info-text: #1c7ed6;\r\n\r\n// --- 纯净的中性色调 (Sleek Grays) ---\r\n$sky-color-white: #ffffff;\r\n$sky-color-gray-1: #f8f9fa; // 极浅背景\r\n$sky-color-gray-2: #f1f3f5; // 浅灰背景\r\n$sky-color-gray-3: #e9ecef; // 边框线/失效态\r\n$sky-color-gray-4: #dee2e6;\r\n$sky-color-gray-5: #adb5bd; // 提示文本\r\n$sky-color-gray-6: #868e96;\r\n$sky-color-gray-7: #495057; // 次级文本\r\n$sky-color-gray-8: #343a40;\r\n$sky-color-gray-9: #212529; // 主级文本\r\n\r\n// --- 阴影系统 (Premium Shadows) ---\r\n$sky-shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.04);\r\n$sky-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);\r\n$sky-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12);\r\n$sky-shadow-primary: 0 4px 14px rgba(100, 80, 240, 0.2);\r\n\r\n// --- 圆角规范 (Borders) ---\r\n$sky-border-radius-xs: 4rpx;\r\n$sky-border-radius-sm: 8rpx;\r\n$sky-border-radius-md: 12rpx;\r\n$sky-border-radius-lg: 20rpx;\r\n$sky-border-radius-round: 9999rpx;\r\n\r\n// --- 字体与字号规范 (Typography) ---\r\n$sky-font-family: -apple-system, BlinkMacSystemFont, \"Helvetica Neue\", Helvetica, \"Segoe UI\", Arial, Roboto, sans-serif;\r\n$sky-font-size-xs: 20rpx;\r\n$sky-font-size-sm: 24rpx;\r\n$sky-font-size-md: 28rpx;\r\n$sky-font-size-lg: 32rpx;\r\n$sky-font-size-xl: 36rpx;\r\n\r\n// --- 动效与过渡 (Transitions) ---\r\n$sky-transition-duration: 200ms;\r\n$sky-transition-timing: cubic-bezier(0.4, 0, 0.2, 1);\r\n\r\n// --- 间距规范 (Spacing) ---\r\n$sky-spacing-xs: 8rpx;\r\n$sky-spacing-sm: 16rpx;\r\n$sky-spacing-md: 24rpx;\r\n$sky-spacing-lg: 32rpx;\r\n$sky-spacing-xl: 48rpx;\r\n\r\n// --- 组件高度规范 (Component Heights) ---\r\n$sky-height-sm: 56rpx;\r\n$sky-height-md: 72rpx;\r\n$sky-height-lg: 88rpx;\r\n$sky-height-xl: 96rpx;\r\n\r\n// --- 层级规范 (Z-Index) ---\r\n$sky-z-dropdown: 100;\r\n$sky-z-fixed: 500;\r\n$sky-z-popup: 1000;\r\n$sky-z-toast: 2000;\r\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const parser_1 = require("./parser");
4
+ Component({
5
+ options: {
6
+ virtualHost: true // 开启虚拟节点降低 Skyline DOM 层级嵌套
7
+ },
8
+ properties: {
9
+ // 待渲染的 HTML 富文本内容
10
+ content: {
11
+ type: String,
12
+ value: '',
13
+ observer(val) {
14
+ this.parseContent(val);
15
+ }
16
+ },
17
+ // 是否支持文本的长按复制选中
18
+ selectable: {
19
+ type: Boolean,
20
+ value: true
21
+ },
22
+ // 附加自定义样式
23
+ customStyle: {
24
+ type: String,
25
+ value: ''
26
+ }
27
+ },
28
+ data: {
29
+ nodes: [] // 解析后的 AST 节点数组
30
+ },
31
+ lifetimes: {
32
+ attached() {
33
+ if (this.data.content) {
34
+ this.parseContent(this.data.content);
35
+ }
36
+ }
37
+ },
38
+ methods: {
39
+ // 调用 AST 词法状态机执行极速解析
40
+ parseContent(html) {
41
+ if (!html) {
42
+ this.setData({ nodes: [] });
43
+ return;
44
+ }
45
+ // 执行状态机词法转换
46
+ try {
47
+ const parsedNodes = (0, parser_1.parseHtml)(html);
48
+ this.setData({
49
+ nodes: parsedNodes
50
+ });
51
+ }
52
+ catch (err) {
53
+ console.error('HtmlRenderer parse error:', err);
54
+ // 异常兜底,防止小程序崩溃
55
+ this.setData({
56
+ nodes: [{
57
+ name: 'p',
58
+ type: 'block',
59
+ attrs: {},
60
+ children: [{
61
+ name: '#text',
62
+ type: 'text',
63
+ text: html,
64
+ attrs: {},
65
+ children: []
66
+ }]
67
+ }]
68
+ });
69
+ }
70
+ }
71
+ }
72
+ });
73
+
74
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/html-renderer/index.ts"],"names":[],"mappings":";;AAAA,qCAA+C;AAE/C,SAAS,CAAC;IACR,OAAO,EAAE;QACP,WAAW,EAAE,IAAI,CAAC,4BAA4B;KAC/C;IAED,UAAU,EAAE;QACV,kBAAkB;QAClB,OAAO,EAAE;YACP,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,EAAE;YACT,QAAQ,CAAC,GAAG;gBACV,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;YACzB,CAAC;SACF;QACD,gBAAgB;QAChB,UAAU,EAAE;YACV,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,IAAI;SACZ;QACD,UAAU;QACV,WAAW,EAAE;YACX,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,EAAE;SACV;KACF;IAED,IAAI,EAAE;QACJ,KAAK,EAAE,EAAgB,CAAC,gBAAgB;KACzC;IAED,SAAS,EAAE;QACT,QAAQ;YACN,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACtB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;KACF;IAED,OAAO,EAAE;QACP,qBAAqB;QACrB,YAAY,CAAC,IAAY;YACvB,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC5B,OAAO;YACT,CAAC;YAED,YAAY;YACZ,IAAI,CAAC;gBACH,MAAM,WAAW,GAAG,IAAA,kBAAS,EAAC,IAAI,CAAC,CAAC;gBACpC,IAAI,CAAC,OAAO,CAAC;oBACX,KAAK,EAAE,WAAW;iBACnB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAC;gBAChD,eAAe;gBACf,IAAI,CAAC,OAAO,CAAC;oBACX,KAAK,EAAE,CAAC;4BACN,IAAI,EAAE,GAAG;4BACT,IAAI,EAAE,OAAO;4BACb,KAAK,EAAE,EAAE;4BACT,QAAQ,EAAE,CAAC;oCACT,IAAI,EAAE,OAAO;oCACb,IAAI,EAAE,MAAM;oCACZ,IAAI,EAAE,IAAI;oCACV,KAAK,EAAE,EAAE;oCACT,QAAQ,EAAE,EAAE;iCACb,CAAC;yBACH,CAAC;iBACH,CAAC,CAAC;YACL,CAAC;QACH,CAAC;KACF;CACF,CAAC,CAAC","file":"index.js","sourcesContent":["import { parseHtml, HtmlNode } from './parser';\r\n\r\nComponent({\r\n options: {\r\n virtualHost: true // 开启虚拟节点降低 Skyline DOM 层级嵌套\r\n },\r\n\r\n properties: {\r\n // 待渲染的 HTML 富文本内容\r\n content: {\r\n type: String,\r\n value: '',\r\n observer(val) {\r\n this.parseContent(val);\r\n }\r\n },\r\n // 是否支持文本的长按复制选中\r\n selectable: {\r\n type: Boolean,\r\n value: true\r\n },\r\n // 附加自定义样式\r\n customStyle: {\r\n type: String,\r\n value: ''\r\n }\r\n },\r\n\r\n data: {\r\n nodes: [] as HtmlNode[] // 解析后的 AST 节点数组\r\n },\r\n\r\n lifetimes: {\r\n attached() {\r\n if (this.data.content) {\r\n this.parseContent(this.data.content);\r\n }\r\n }\r\n },\r\n\r\n methods: {\r\n // 调用 AST 词法状态机执行极速解析\r\n parseContent(html: string) {\r\n if (!html) {\r\n this.setData({ nodes: [] });\r\n return;\r\n }\r\n\r\n // 执行状态机词法转换\r\n try {\r\n const parsedNodes = parseHtml(html);\r\n this.setData({\r\n nodes: parsedNodes\r\n });\r\n } catch (err) {\r\n console.error('HtmlRenderer parse error:', err);\r\n // 异常兜底,防止小程序崩溃\r\n this.setData({\r\n nodes: [{\r\n name: 'p',\r\n type: 'block',\r\n attrs: {},\r\n children: [{\r\n name: '#text',\r\n type: 'text',\r\n text: html,\r\n attrs: {},\r\n children: []\r\n }]\r\n }]\r\n });\r\n }\r\n }\r\n }\r\n});\r\n"]}
@@ -0,0 +1,6 @@
1
+ {
2
+ "component": true,
3
+ "renderer": "skyline",
4
+ "componentFramework": "glass-easel",
5
+ "usingComponents": {}
6
+ }