web-component-gallery 2.2.1 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/js.umd.js +1 -1
- package/extensions/BuildTheme.js +39 -45
- package/extensions/UpdateTheme.js +32 -12
- package/lib/browse/style/index.less +1 -2
- package/lib/form-comp/ASliderVerify.vue +283 -0
- package/lib/form-comp/index.js +4 -1
- package/lib/form-comp/style/ASliderVerify.less +94 -0
- package/lib/form-comp/style/index.less +2 -1
- package/lib/modal/index.jsx +2 -2
- package/package.json +1 -1
package/extensions/BuildTheme.js
CHANGED
|
@@ -15,45 +15,37 @@ function extractColor(content, varName) {
|
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* 向LESS文件添加新变量并保持原有格式
|
|
18
|
-
* @param {string} lessContent - 原始LESS文件内容
|
|
19
18
|
* @param {Object} newVars - 要添加的新变量对象
|
|
19
|
+
* @param {string} lessContent - 原始LESS文件内容
|
|
20
20
|
* @param {Object} newVars.export - 需要导出的变量对象
|
|
21
21
|
* @param {Object} newVars.nonExport - 不需要导出的变量对象
|
|
22
22
|
* @returns {string} 修改后的LESS文件内容
|
|
23
23
|
*/
|
|
24
|
-
function addLessVariables(
|
|
25
|
-
const lines = lessContent
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (exportStartIndex === -1) exportStartIndex = lines.length
|
|
34
|
-
|
|
35
|
-
// 添加非导出变量
|
|
36
|
-
const addNonExportVars = () => {
|
|
37
|
-
const newVarLines = ['\n// 扩展变量']
|
|
38
|
-
for (const [lessVar, cssVar] of Object.entries(newVars.nonExport || {})) {
|
|
39
|
-
newVarLines.push(`${lessVar}: ${cssVar};`)
|
|
24
|
+
function addLessVariables(newVars, lessContent) {
|
|
25
|
+
const lines = lessContent?.split('\n') || []
|
|
26
|
+
const newLines = []
|
|
27
|
+
|
|
28
|
+
// 智能添加非导出变量(仅在newVars.nonExport存在时添加)
|
|
29
|
+
if (newVars.nonExport && Object.keys(newVars.nonExport).length > 0) {
|
|
30
|
+
newLines.push('\n// 扩展变量')
|
|
31
|
+
for (const [lessVar, cssVar] of Object.entries(newVars.nonExport)) {
|
|
32
|
+
newLines.push(`${lessVar}: ${cssVar};`)
|
|
40
33
|
}
|
|
41
|
-
return newVarLines
|
|
42
34
|
}
|
|
43
35
|
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
for (const [cssVar, lessVar] of Object.entries(newVars.export
|
|
48
|
-
|
|
36
|
+
// 智能添加导出变量(仅在newVars.export存在时添加)
|
|
37
|
+
if (newVars.export && Object.keys(newVars.export).length > 0) {
|
|
38
|
+
newLines.push('\n:root {')
|
|
39
|
+
for (const [cssVar, lessVar] of Object.entries(newVars.export)) {
|
|
40
|
+
newLines.push(` ${cssVar}: ${lessVar};`)
|
|
49
41
|
}
|
|
50
|
-
|
|
42
|
+
newLines.push('}')
|
|
51
43
|
}
|
|
52
44
|
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
45
|
+
// 在文件末尾插入新变量
|
|
46
|
+
if (newLines.length > 0) {
|
|
47
|
+
lines.splice(lines.length, 0, ...newLines)
|
|
48
|
+
}
|
|
57
49
|
|
|
58
50
|
return lines.join('\n')
|
|
59
51
|
}
|
|
@@ -86,29 +78,31 @@ async function processLessFiles(theme) {
|
|
|
86
78
|
const result = parseExtendVariables(cssVariables, fileAVariables)
|
|
87
79
|
|
|
88
80
|
processedContent = addLessVariables(
|
|
89
|
-
processedContent,
|
|
90
81
|
{
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
},
|
|
95
|
-
nonExport: result.nonExport
|
|
96
|
-
}
|
|
82
|
+
nonExport: result.nonExport
|
|
83
|
+
},
|
|
84
|
+
processedContent
|
|
97
85
|
)
|
|
98
86
|
|
|
99
87
|
const basePath = path.resolve(hostPath, '../src/styles')
|
|
100
88
|
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
fs.writeFileSync(outputPath, processedContent)
|
|
89
|
+
// 确保目录存在
|
|
90
|
+
fs.mkdirSync(basePath, { recursive: true })
|
|
104
91
|
|
|
105
|
-
//
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
// .join('\n') // 每行一个键值对
|
|
92
|
+
// 写入LESS文件
|
|
93
|
+
const lessOutPut = path.join(basePath, `${cssFileName}.less`)
|
|
94
|
+
fs.writeFileSync(lessOutPut, processedContent)
|
|
109
95
|
|
|
110
|
-
//
|
|
111
|
-
|
|
96
|
+
// 生成并写入CSS变量文件
|
|
97
|
+
const cssOutPut = path.join(basePath, 'root.css')
|
|
98
|
+
fs.writeFileSync(cssOutPut, addLessVariables(
|
|
99
|
+
{
|
|
100
|
+
export: {
|
|
101
|
+
...parseCSSVariables(cssVariables),
|
|
102
|
+
...result.export
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
))
|
|
112
106
|
|
|
113
107
|
return fileAVariables
|
|
114
108
|
} catch (error) {
|
|
@@ -184,7 +178,7 @@ const customFunctions = {
|
|
|
184
178
|
return new less.tree.Quoted('"', `fade(${defaultValue}, ${amount.value}%)`)
|
|
185
179
|
}
|
|
186
180
|
// 处理静态颜色值
|
|
187
|
-
const alpha = Math.max(0, Math.min(1, color.alpha * (
|
|
181
|
+
const alpha = Math.max(0, Math.min(1, color.alpha * (amount.value / 100)))
|
|
188
182
|
return new less.tree.Color(color.rgb, alpha)
|
|
189
183
|
})
|
|
190
184
|
}
|
|
@@ -100,26 +100,46 @@ function parseExtendVariables(extendVar, lessVariables) {
|
|
|
100
100
|
async function updateTheme(theme) {
|
|
101
101
|
if (!less || !less.modifyVars) return
|
|
102
102
|
|
|
103
|
-
const root = document.documentElement
|
|
104
|
-
//
|
|
105
|
-
const themeVariables = await
|
|
106
|
-
|
|
103
|
+
const root = document.documentElement
|
|
104
|
+
// 并行获取主题变量和CSS变量
|
|
105
|
+
const [themeVariables, cssVariables] = await Promise.all([
|
|
106
|
+
fetchAndParseLessFile(theme, true),
|
|
107
|
+
fetchAndParseLessFile(cssFileName, true)
|
|
108
|
+
])
|
|
109
|
+
// 解析CSS变量
|
|
107
110
|
const resetValue = parseCSSVariables(cssVariables, themeVariables)
|
|
108
111
|
|
|
109
|
-
const updateVariables = {
|
|
112
|
+
const updateVariables = {
|
|
113
|
+
css: {},
|
|
114
|
+
less: {}
|
|
115
|
+
}
|
|
110
116
|
|
|
111
|
-
|
|
112
|
-
|
|
117
|
+
// 对比新旧变量值,收集需要更新的变量
|
|
118
|
+
for (const [key, colorA] of Object.entries(resetValue)) {
|
|
113
119
|
const colorB = getComputedStyle(root).getPropertyValue(key).trim()
|
|
114
|
-
//
|
|
115
|
-
if (colorA !== colorB)
|
|
120
|
+
// 只有当颜色值确实发生变化时才更新
|
|
121
|
+
if (colorA !== colorB) {
|
|
122
|
+
updateVariables.css[key] = colorA
|
|
123
|
+
// 将CSS变量名转换为LESS变量名
|
|
124
|
+
updateVariables.less[`@${key.slice(2)}`] = colorA
|
|
125
|
+
}
|
|
116
126
|
}
|
|
117
127
|
|
|
118
|
-
less.modifyVars({
|
|
128
|
+
await less.modifyVars({
|
|
129
|
+
...themeVariables,
|
|
130
|
+
...updateVariables.less
|
|
131
|
+
}).then(console.log("换肤成功"))
|
|
119
132
|
|
|
120
|
-
if (!Object.keys(updateVariables).length) return
|
|
133
|
+
if (!Object.keys(updateVariables.css).length) return
|
|
121
134
|
|
|
122
|
-
|
|
135
|
+
// 解析并更新CSS变量
|
|
136
|
+
const updateCSSViables = {
|
|
137
|
+
...updateVariables.css,
|
|
138
|
+
...parseExtendVariables(
|
|
139
|
+
cssVariables,
|
|
140
|
+
updateVariables.less
|
|
141
|
+
).export
|
|
142
|
+
}
|
|
123
143
|
|
|
124
144
|
for (const [key, color] of Object.entries(updateCSSViables)) {
|
|
125
145
|
root.style.setProperty(key, color)
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
ref="sliderContainer"
|
|
4
|
+
class="slider-wrapper"
|
|
5
|
+
:style="sliderWrapperStyle"
|
|
6
|
+
@mousemove="handleDragMove"
|
|
7
|
+
@mouseup="handleDragEnd"
|
|
8
|
+
@mouseleave="handleDragEnd"
|
|
9
|
+
@touchmove="handleDragMove"
|
|
10
|
+
@touchend="handleDragEnd"
|
|
11
|
+
>
|
|
12
|
+
<!-- 背景轨道 -->
|
|
13
|
+
<div class="slider-track">
|
|
14
|
+
<!-- 进度条 -->
|
|
15
|
+
<div
|
|
16
|
+
class="slider-progress"
|
|
17
|
+
:class="{ 'progress-resetting': isResetting }"
|
|
18
|
+
ref="progressBar"
|
|
19
|
+
:style="progressBarStyle"
|
|
20
|
+
/>
|
|
21
|
+
|
|
22
|
+
<!-- 提示文字 -->
|
|
23
|
+
<div
|
|
24
|
+
class="slider-text"
|
|
25
|
+
ref="sliderText"
|
|
26
|
+
:style="sliderTextStyle"
|
|
27
|
+
>
|
|
28
|
+
<span v-if="!isVerified">{{ dragText }}</span>
|
|
29
|
+
<span v-else class="success-text">{{ successText }}</span>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<!-- 滑块手柄 -->
|
|
34
|
+
<div
|
|
35
|
+
class="slider-handle"
|
|
36
|
+
:class="{
|
|
37
|
+
'handle-resetting': isResetting,
|
|
38
|
+
'handle-success': isVerified
|
|
39
|
+
}"
|
|
40
|
+
@mousedown="handleDragStart"
|
|
41
|
+
@touchstart="handleDragStart"
|
|
42
|
+
ref="sliderHandle"
|
|
43
|
+
:style="sliderHandleStyle"
|
|
44
|
+
>
|
|
45
|
+
<IconFont
|
|
46
|
+
:type="currentIconType"
|
|
47
|
+
:style="{ fontSize: '16px', color: iconColor }"
|
|
48
|
+
/>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</template>
|
|
52
|
+
|
|
53
|
+
<script>
|
|
54
|
+
|
|
55
|
+
import debounce from 'lodash/debounce'
|
|
56
|
+
import IconFont from '../icon-font'
|
|
57
|
+
|
|
58
|
+
export default {
|
|
59
|
+
name: 'SliderVerify',
|
|
60
|
+
components: { IconFont },
|
|
61
|
+
props: {
|
|
62
|
+
successText: {
|
|
63
|
+
type: String,
|
|
64
|
+
default: '验证成功'
|
|
65
|
+
},
|
|
66
|
+
dragText: {
|
|
67
|
+
type: String,
|
|
68
|
+
default: '请按住滑块拖动到最右侧'
|
|
69
|
+
},
|
|
70
|
+
sliderHeight: {
|
|
71
|
+
type: Number,
|
|
72
|
+
default: 40
|
|
73
|
+
},
|
|
74
|
+
handleSize: {
|
|
75
|
+
type: Number,
|
|
76
|
+
default: 40
|
|
77
|
+
},
|
|
78
|
+
verifyThreshold: {
|
|
79
|
+
type: Number,
|
|
80
|
+
default: 85,
|
|
81
|
+
validator: (value) => value >= 0 && value <= 100
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
data() {
|
|
86
|
+
return {
|
|
87
|
+
// 拖拽状态
|
|
88
|
+
isDragging: false,
|
|
89
|
+
// 起始位置
|
|
90
|
+
startX: 0,
|
|
91
|
+
// 当前位置
|
|
92
|
+
currentX: 0,
|
|
93
|
+
// 是否通过
|
|
94
|
+
isVerified: false,
|
|
95
|
+
// 是否重置
|
|
96
|
+
isResetting: false,
|
|
97
|
+
// 容器宽度
|
|
98
|
+
containerWidth: 0,
|
|
99
|
+
// 拖拽开始时间
|
|
100
|
+
dragStartTime: null
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
computed: {
|
|
105
|
+
sliderWrapperStyle() {
|
|
106
|
+
return {
|
|
107
|
+
height: `${this.sliderHeight}px`
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
progressBarStyle() {
|
|
112
|
+
return {
|
|
113
|
+
width: `${this.progressWidth}px`,
|
|
114
|
+
background: this.isVerified ? '#52c41a' : '#1890ff',
|
|
115
|
+
transition: this.isResetting ? 'width 0.5s ease' : 'none'
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
sliderHandleStyle() {
|
|
120
|
+
return {
|
|
121
|
+
left: `${this.handlePosition}px`,
|
|
122
|
+
width: `${this.handleSize}px`,
|
|
123
|
+
height: `${this.handleSize}px`,
|
|
124
|
+
transition: this.isResetting ? 'left 0.5s ease' : 'none'
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
sliderTextStyle() {
|
|
129
|
+
return {
|
|
130
|
+
lineHeight: `${this.sliderHeight}px`,
|
|
131
|
+
color: this.isVerified ? '#fff' : 'transparent'
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
currentIconType() {
|
|
136
|
+
return this.isVerified ? 'passSlider' : 'arrowSlider'
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
iconColor() {
|
|
140
|
+
return this.isVerified ? '#01DC66' : '#666'
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
progressWidth() {
|
|
144
|
+
if (this.isVerified) {
|
|
145
|
+
return this.containerWidth
|
|
146
|
+
}
|
|
147
|
+
return this.currentX + this.handleSize / 2
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
handlePosition() {
|
|
151
|
+
if (this.isVerified) {
|
|
152
|
+
return this.containerWidth - this.handleSize
|
|
153
|
+
}
|
|
154
|
+
return this.currentX
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
maxDragDistance() {
|
|
158
|
+
return this.containerWidth - this.handleSize
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
thresholdDistance() {
|
|
162
|
+
return (this.verifyThreshold / 100) * this.maxDragDistance
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
watch: {
|
|
167
|
+
isVerified(newVal) {
|
|
168
|
+
this.$emit('update:isVerified', newVal)
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
mounted() {
|
|
173
|
+
this.initSlider()
|
|
174
|
+
this.$bus.$onWindow(this, 'resize', this.handleWindowResize)
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
methods: {
|
|
178
|
+
initSlider() {
|
|
179
|
+
this.updateContainerWidth()
|
|
180
|
+
this.setupCSSVariables()
|
|
181
|
+
},
|
|
182
|
+
|
|
183
|
+
updateContainerWidth() {
|
|
184
|
+
if (this.$refs.sliderContainer) {
|
|
185
|
+
this.containerWidth = this.$refs.sliderContainer.offsetWidth
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
|
|
189
|
+
setupCSSVariables() {
|
|
190
|
+
const container = this.$refs.sliderContainer
|
|
191
|
+
if (container) {
|
|
192
|
+
const halfWidth = Math.floor(this.containerWidth / 2)
|
|
193
|
+
container.style.setProperty('--slider-width', `${this.containerWidth}px`)
|
|
194
|
+
container.style.setProperty('--half-width', `${halfWidth}px`)
|
|
195
|
+
container.style.setProperty('--negative-half-width', `-${halfWidth}px`)
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
handleDragStart(event) {
|
|
200
|
+
if (this.isVerified) return
|
|
201
|
+
|
|
202
|
+
this.isDragging = true
|
|
203
|
+
this.dragStartTime = Date.now()
|
|
204
|
+
const handle = this.$refs.sliderHandle
|
|
205
|
+
const currentLeft = parseInt(handle.style.left || '0', 10)
|
|
206
|
+
|
|
207
|
+
this.startX = (event.pageX || event.touches[0].pageX) - currentLeft
|
|
208
|
+
},
|
|
209
|
+
|
|
210
|
+
handleDragMove(event) {
|
|
211
|
+
if (!this.isDragging || this.isVerified) return
|
|
212
|
+
|
|
213
|
+
const currentX = (event.pageX || event.touches[0].pageX) - this.startX
|
|
214
|
+
|
|
215
|
+
if (currentX > 0 && currentX <= this.maxDragDistance) {
|
|
216
|
+
this.currentX = currentX
|
|
217
|
+
this.$emit('dragging', {
|
|
218
|
+
currentX,
|
|
219
|
+
progress: (currentX / this.maxDragDistance) * 100
|
|
220
|
+
})
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
|
|
224
|
+
handleDragEnd(event) {
|
|
225
|
+
if (!this.isDragging || this.isVerified) return
|
|
226
|
+
|
|
227
|
+
const currentX = (event.pageX || event.changedTouches[0].pageX) - this.startX
|
|
228
|
+
|
|
229
|
+
if (currentX >= this.thresholdDistance) {
|
|
230
|
+
this.handleVerifySuccess()
|
|
231
|
+
} else {
|
|
232
|
+
this.handleVerifyFail()
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
this.isDragging = false
|
|
236
|
+
},
|
|
237
|
+
|
|
238
|
+
handleVerifySuccess() {
|
|
239
|
+
this.isVerified = true
|
|
240
|
+
this.currentX = this.maxDragDistance
|
|
241
|
+
const dragDuration = Date.now() - this.dragStartTime
|
|
242
|
+
|
|
243
|
+
this.$emit('verify-success', {
|
|
244
|
+
duration: dragDuration,
|
|
245
|
+
endTime: Date.now()
|
|
246
|
+
})
|
|
247
|
+
},
|
|
248
|
+
|
|
249
|
+
handleVerifyFail() {
|
|
250
|
+
this.isResetting = true
|
|
251
|
+
|
|
252
|
+
setTimeout(() => {
|
|
253
|
+
this.resetSlider()
|
|
254
|
+
this.isResetting = false
|
|
255
|
+
}, 500)
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
resetSlider() {
|
|
259
|
+
this.currentX = 0
|
|
260
|
+
this.isVerified = false
|
|
261
|
+
|
|
262
|
+
const handle = this.$refs.sliderHandle
|
|
263
|
+
const progressBar = this.$refs.progressBar
|
|
264
|
+
const text = this.$refs.sliderText
|
|
265
|
+
|
|
266
|
+
if (handle) handle.style.left = '0px'
|
|
267
|
+
if (progressBar) progressBar.style.width = '0px'
|
|
268
|
+
|
|
269
|
+
if (text) {
|
|
270
|
+
// 重新设置动画
|
|
271
|
+
// text.style.animation = 'slidetounlock 3s infinite'
|
|
272
|
+
text.style.color = 'transparent'
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
|
|
276
|
+
handleWindowResize: debounce(function() {
|
|
277
|
+
this.updateContainerWidth()
|
|
278
|
+
this.setupCSSVariables()
|
|
279
|
+
this.resetSlider()
|
|
280
|
+
}, 250)
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
</script>
|
package/lib/form-comp/index.js
CHANGED
|
@@ -13,6 +13,8 @@ import ARangePicker from './ARangePicker.vue'
|
|
|
13
13
|
import ADayTimePicker from './ADayTimePicker.vue'
|
|
14
14
|
/* 文件上传选择器 */
|
|
15
15
|
import AUpload from './AUpload.vue'
|
|
16
|
+
/* 滑块 */
|
|
17
|
+
import ASliderVerify from './ASliderVerify.vue'
|
|
16
18
|
|
|
17
19
|
const components = {
|
|
18
20
|
ACascaderMultiple,
|
|
@@ -21,7 +23,8 @@ const components = {
|
|
|
21
23
|
ATagsInput,
|
|
22
24
|
ARangePicker,
|
|
23
25
|
ADayTimePicker,
|
|
24
|
-
AUpload
|
|
26
|
+
AUpload,
|
|
27
|
+
ASliderVerify
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
const install = function (Vue) {
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
@import '~ant-design-vue/lib/style/themes/default.less';
|
|
2
|
+
@import '../../style/mixins.less';
|
|
3
|
+
|
|
4
|
+
.slider-wrapper {
|
|
5
|
+
position: relative;
|
|
6
|
+
overflow: hidden;
|
|
7
|
+
|
|
8
|
+
.slider-track {
|
|
9
|
+
position: relative;
|
|
10
|
+
background: fade(@black, 10%);
|
|
11
|
+
border-radius: @border-radius-base;
|
|
12
|
+
.layout();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.slider-progress {
|
|
16
|
+
height: 100%;
|
|
17
|
+
position: absolute;
|
|
18
|
+
background: @primary-color;
|
|
19
|
+
border-radius: @border-radius-base 0 0 @border-radius-base;
|
|
20
|
+
transition: width 0.3s ease;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.slider-text {
|
|
24
|
+
top: 0;
|
|
25
|
+
left: 0;
|
|
26
|
+
position: absolute;
|
|
27
|
+
text-align: center;
|
|
28
|
+
font-size: @font-size-base;
|
|
29
|
+
background: -webkit-gradient(
|
|
30
|
+
linear,
|
|
31
|
+
left top,
|
|
32
|
+
right top,
|
|
33
|
+
color-stop(0, @black),
|
|
34
|
+
color-stop(0.4, @black),
|
|
35
|
+
color-stop(0.5, @white),
|
|
36
|
+
color-stop(0.6, @black),
|
|
37
|
+
color-stop(1, @black)
|
|
38
|
+
);
|
|
39
|
+
-webkit-background-clip: text;
|
|
40
|
+
-webkit-text-fill-color: transparent;
|
|
41
|
+
animation: slidetounlock 3s infinite;
|
|
42
|
+
.layout();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.success-text {
|
|
46
|
+
color: @white;
|
|
47
|
+
-webkit-text-fill-color: @white;
|
|
48
|
+
animation: none;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.slider-handle {
|
|
52
|
+
top: 0;
|
|
53
|
+
left: 0;
|
|
54
|
+
z-index: 2;
|
|
55
|
+
cursor: move;
|
|
56
|
+
position: absolute;
|
|
57
|
+
background: @white;
|
|
58
|
+
border: 1px solid fade(@black, 10%);
|
|
59
|
+
border-radius: @border-radius-base 0 0 @border-radius-base;
|
|
60
|
+
transition: left 0.3s ease, background 0.3s ease;
|
|
61
|
+
.flex-mixins();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.handle-success {
|
|
65
|
+
border-color: @success-color;
|
|
66
|
+
border-radius: 0 @border-radius-base @border-radius-base 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.handle-resetting {
|
|
70
|
+
left: 0px;
|
|
71
|
+
transition: left 0.5s ease;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.progress-resetting {
|
|
75
|
+
width: 0px;
|
|
76
|
+
transition: width 0.5s ease;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* 触摸设备优化 */
|
|
81
|
+
@media (hover: none) and (pointer: coarse) {
|
|
82
|
+
.slider-handle {
|
|
83
|
+
cursor: pointer;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@keyframes slidetounlock {
|
|
88
|
+
0% {
|
|
89
|
+
background-position: var(--negative-half-width) 0;
|
|
90
|
+
}
|
|
91
|
+
100% {
|
|
92
|
+
background-position: var(--half-width) 0;
|
|
93
|
+
}
|
|
94
|
+
}
|
package/lib/modal/index.jsx
CHANGED
|
@@ -25,7 +25,7 @@ const ModalComp = {
|
|
|
25
25
|
},
|
|
26
26
|
methods: {
|
|
27
27
|
handleBlank() {
|
|
28
|
-
window.open(this.$attrs.
|
|
28
|
+
window.open(this.$attrs.externalLink, '_blank')
|
|
29
29
|
},
|
|
30
30
|
handleConvert() {
|
|
31
31
|
const currentIndex = this.modalModes.indexOf(this.internalMode)
|
|
@@ -62,7 +62,7 @@ const ModalComp = {
|
|
|
62
62
|
on={{ click: this.handleConvert }}
|
|
63
63
|
/>
|
|
64
64
|
{
|
|
65
|
-
$attrs.
|
|
65
|
+
$attrs.externalLink &&
|
|
66
66
|
<IconFont
|
|
67
67
|
type="modal_blank"
|
|
68
68
|
on={{ click: this.handleBlank }}
|