@363045841yyt/klinechart 0.8.4 → 0.8.6
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 +6 -1
- package/dist/components/BaseModal.vue.d.ts +54 -0
- package/dist/components/BaseModal.vue.d.ts.map +1 -0
- package/dist/components/BatchStockDialog.vue.d.ts +13 -0
- package/dist/components/BatchStockDialog.vue.d.ts.map +1 -0
- package/dist/components/ChartSettingsDialog.vue.d.ts.map +1 -1
- package/dist/components/ColorPresetPanel.vue.d.ts +4 -1
- package/dist/components/ColorPresetPanel.vue.d.ts.map +1 -1
- package/dist/components/CompareSymbolSelector.vue.d.ts.map +1 -1
- package/dist/components/DrawingStyleToolbar.vue.d.ts.map +1 -1
- package/dist/components/Dropdown.vue.d.ts.map +1 -1
- package/dist/components/ExportProgressDialog.vue.d.ts +15 -0
- package/dist/components/ExportProgressDialog.vue.d.ts.map +1 -0
- package/dist/components/IndicatorParams.vue.d.ts.map +1 -1
- package/dist/components/IndicatorSelector.vue.d.ts.map +1 -1
- package/dist/components/KLineChart.vue.d.ts +5 -9
- package/dist/components/KLineChart.vue.d.ts.map +1 -1
- package/dist/components/LeftToolbar.vue.d.ts.map +1 -1
- package/dist/components/RangeSelectionExport.vue.d.ts +23 -0
- package/dist/components/RangeSelectionExport.vue.d.ts.map +1 -0
- package/dist/components/SymbolSelector.vue.d.ts.map +1 -1
- package/dist/components/TopToolbar.vue.d.ts.map +1 -1
- package/dist/components/common/CanvasToolbar.vue.d.ts +14 -0
- package/dist/components/common/CanvasToolbar.vue.d.ts.map +1 -0
- package/dist/components/common/CanvasToolbarStack.vue.d.ts +14 -0
- package/dist/components/common/CanvasToolbarStack.vue.d.ts.map +1 -0
- package/dist/composables/chart/useChartTheme.d.ts +329 -0
- package/dist/composables/chart/useChartTheme.d.ts.map +1 -0
- package/dist/composables/chart/useDrawingManager.d.ts +86 -0
- package/dist/composables/chart/useDrawingManager.d.ts.map +1 -0
- package/dist/composables/chart/useIndicatorManager.d.ts +38 -0
- package/dist/composables/chart/useIndicatorManager.d.ts.map +1 -0
- package/dist/composables/chart/useRangeSelection.d.ts +66 -0
- package/dist/composables/chart/useRangeSelection.d.ts.map +1 -0
- package/dist/composables/useTeleportedPopup.d.ts +8 -0
- package/dist/composables/useTeleportedPopup.d.ts.map +1 -0
- package/dist/index.cjs +9 -2
- package/dist/index.css +1 -1
- package/dist/index.js +2149 -1409
- package/dist/tools/calcRangeOverlayPixel.d.ts +15 -0
- package/dist/tools/calcRangeOverlayPixel.d.ts.map +1 -0
- package/dist/tools/getKLineIndexByTimestamp.d.ts +4 -0
- package/dist/tools/getKLineIndexByTimestamp.d.ts.map +1 -0
- package/dist/web-component.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/BaseModal.vue +292 -0
- package/src/components/BatchStockDialog.vue +128 -0
- package/src/components/ChartSettingsDialog.vue +248 -405
- package/src/components/ColorPresetPanel.vue +58 -106
- package/src/components/CompareSymbolSelector.vue +37 -10
- package/src/components/DrawingStyleToolbar.vue +33 -72
- package/src/components/Dropdown.vue +42 -19
- package/src/components/ExportProgressDialog.vue +118 -0
- package/src/components/IndicatorParams.vue +194 -321
- package/src/components/IndicatorSelector.vue +188 -405
- package/src/components/KLineChart.vue +228 -403
- package/src/components/LeftToolbar.vue +3 -2
- package/src/components/RangeSelectionExport.vue +117 -0
- package/src/components/SymbolSelector.vue +37 -10
- package/src/components/TopToolbar.vue +55 -2
- package/src/components/common/CanvasToolbar.vue +70 -0
- package/src/components/common/CanvasToolbarStack.vue +32 -0
- package/src/composables/chart/useChartTheme.ts +86 -0
- package/src/composables/chart/useDrawingManager.ts +67 -0
- package/src/composables/chart/useIndicatorManager.ts +307 -0
- package/src/composables/chart/useRangeSelection.ts +424 -0
- package/src/composables/useTeleportedPopup.ts +46 -0
- package/src/tools/calcRangeOverlayPixel.ts +28 -0
- package/src/tools/getKLineIndexByTimestamp.ts +40 -0
|
@@ -1,123 +1,110 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
>
|
|
80
|
-
+
|
|
81
|
-
</button>
|
|
82
|
-
</div>
|
|
83
|
-
</div>
|
|
84
|
-
<Transition name="slide">
|
|
85
|
-
<div v-if="showDescription && param.description" class="param-description">
|
|
86
|
-
{{ param.description }}
|
|
87
|
-
</div>
|
|
88
|
-
</Transition>
|
|
89
|
-
</div>
|
|
90
|
-
</div>
|
|
91
|
-
|
|
92
|
-
<!-- 底部 -->
|
|
93
|
-
<div class="params-footer">
|
|
94
|
-
<button class="params-btn reset" @click="onReset">
|
|
95
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
96
|
-
<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" />
|
|
97
|
-
<path d="M3 3v5h5" />
|
|
98
|
-
</svg>
|
|
99
|
-
重置
|
|
100
|
-
</button>
|
|
101
|
-
<div class="footer-right">
|
|
102
|
-
<button class="params-btn cancel" @click="$emit('close')">取消</button>
|
|
103
|
-
<button class="params-btn confirm" @click="onConfirm">
|
|
104
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
|
|
105
|
-
<path d="M20 6L9 17l-5-5" />
|
|
106
|
-
</svg>
|
|
107
|
-
确定
|
|
108
|
-
</button>
|
|
109
|
-
</div>
|
|
110
|
-
</div>
|
|
2
|
+
<BaseModal
|
|
3
|
+
:show="visible"
|
|
4
|
+
:title="indicatorName"
|
|
5
|
+
subtitle="参数设置"
|
|
6
|
+
width="90vw"
|
|
7
|
+
max-width="420px"
|
|
8
|
+
transition-variant="compact"
|
|
9
|
+
overlay-padding="0"
|
|
10
|
+
footer-align="space-between"
|
|
11
|
+
@close="$emit('close')"
|
|
12
|
+
>
|
|
13
|
+
<template #header-extra>
|
|
14
|
+
<button
|
|
15
|
+
class="toggle-desc-btn"
|
|
16
|
+
:class="{ active: showDescription }"
|
|
17
|
+
@click="showDescription = !showDescription"
|
|
18
|
+
title="显示/隐藏说明"
|
|
19
|
+
>
|
|
20
|
+
<svg viewBox="0 0 1024 1024">
|
|
21
|
+
<path
|
|
22
|
+
d="M512 97.52381c228.912762 0 414.47619 185.563429 414.47619 414.47619s-185.563429 414.47619-414.47619 414.47619S97.52381 740.912762 97.52381 512 283.087238 97.52381 512 97.52381z m0 73.142857C323.486476 170.666667 170.666667 323.486476 170.666667 512s152.81981 341.333333 341.333333 341.333333 341.333333-152.81981 341.333333-341.333333S700.513524 170.666667 512 170.666667z m36.571429 268.190476v292.571428h-73.142858V438.857143h73.142858z m0-121.904762v73.142857h-73.142858v-73.142857h73.142858z"
|
|
23
|
+
fill="currentColor"
|
|
24
|
+
/>
|
|
25
|
+
</svg>
|
|
26
|
+
</button>
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
<Transition name="slide">
|
|
30
|
+
<div v-if="showDescription && indicatorDescription" class="indicator-description">
|
|
31
|
+
<p>{{ indicatorDescription }}</p>
|
|
32
|
+
</div>
|
|
33
|
+
</Transition>
|
|
34
|
+
|
|
35
|
+
<div class="params-body">
|
|
36
|
+
<div
|
|
37
|
+
v-for="param in params"
|
|
38
|
+
:key="param.key"
|
|
39
|
+
class="param-item"
|
|
40
|
+
:class="{ 'has-desc': showDescription && param.description }"
|
|
41
|
+
>
|
|
42
|
+
<div class="param-header">
|
|
43
|
+
<label class="param-label">
|
|
44
|
+
<span class="param-label-text">{{ param.label }}</span>
|
|
45
|
+
<span v-if="param.min !== undefined || param.max !== undefined" class="param-range">
|
|
46
|
+
{{ param.min ?? '-∞' }} ~ {{ param.max ?? '+∞' }}
|
|
47
|
+
</span>
|
|
48
|
+
</label>
|
|
49
|
+
<div class="input-wrapper">
|
|
50
|
+
<button
|
|
51
|
+
class="stepper-btn"
|
|
52
|
+
:disabled="param.min !== undefined && (localValues[param.key] ?? 0) <= param.min"
|
|
53
|
+
@click="step(param, -1)"
|
|
54
|
+
>
|
|
55
|
+
−
|
|
56
|
+
</button>
|
|
57
|
+
<input
|
|
58
|
+
v-if="param.type === 'number'"
|
|
59
|
+
type="number"
|
|
60
|
+
class="param-input"
|
|
61
|
+
:value="localValues[param.key]"
|
|
62
|
+
:min="param.min"
|
|
63
|
+
:max="param.max"
|
|
64
|
+
:step="param.step || 1"
|
|
65
|
+
@input="onInput(param.key, $event)"
|
|
66
|
+
/>
|
|
67
|
+
<button
|
|
68
|
+
class="stepper-btn"
|
|
69
|
+
:disabled="param.max !== undefined && (localValues[param.key] ?? 0) >= param.max"
|
|
70
|
+
@click="step(param, 1)"
|
|
71
|
+
>
|
|
72
|
+
+
|
|
73
|
+
</button>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
<Transition name="slide">
|
|
77
|
+
<div v-if="showDescription && param.description" class="param-description">
|
|
78
|
+
{{ param.description }}
|
|
111
79
|
</div>
|
|
112
80
|
</Transition>
|
|
113
81
|
</div>
|
|
114
|
-
</
|
|
115
|
-
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<template #footer>
|
|
85
|
+
<button class="params-btn reset" @click="onReset">
|
|
86
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
87
|
+
<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" />
|
|
88
|
+
<path d="M3 3v5h5" />
|
|
89
|
+
</svg>
|
|
90
|
+
重置
|
|
91
|
+
</button>
|
|
92
|
+
<div class="footer-right">
|
|
93
|
+
<button class="params-btn cancel" @click="$emit('close')">取消</button>
|
|
94
|
+
<button class="params-btn confirm" @click="onConfirm">
|
|
95
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
|
|
96
|
+
<path d="M20 6L9 17l-5-5" />
|
|
97
|
+
</svg>
|
|
98
|
+
确定
|
|
99
|
+
</button>
|
|
100
|
+
</div>
|
|
101
|
+
</template>
|
|
102
|
+
</BaseModal>
|
|
116
103
|
</template>
|
|
117
104
|
|
|
118
105
|
<script setup lang="ts">
|
|
119
|
-
import { ref, watch
|
|
120
|
-
import
|
|
106
|
+
import { ref, watch } from 'vue'
|
|
107
|
+
import BaseModal from './BaseModal.vue'
|
|
121
108
|
|
|
122
109
|
export interface ParamConfig {
|
|
123
110
|
key: string
|
|
@@ -147,21 +134,19 @@ const emit = defineEmits<{
|
|
|
147
134
|
const localValues = ref<Record<string, number>>({ ...props.values })
|
|
148
135
|
const showDescription = ref(true)
|
|
149
136
|
|
|
150
|
-
const teleportTarget = useFullscreenTeleportTarget()
|
|
151
|
-
|
|
152
137
|
watch(
|
|
153
138
|
() => props.values,
|
|
154
139
|
(newValues) => {
|
|
155
140
|
localValues.value = { ...newValues }
|
|
156
141
|
},
|
|
157
|
-
{ deep: true, immediate: true }
|
|
142
|
+
{ deep: true, immediate: true },
|
|
158
143
|
)
|
|
159
144
|
|
|
160
145
|
watch(
|
|
161
146
|
() => props.visible,
|
|
162
147
|
(visible) => {
|
|
163
148
|
if (visible) localValues.value = { ...props.values }
|
|
164
|
-
}
|
|
149
|
+
},
|
|
165
150
|
)
|
|
166
151
|
|
|
167
152
|
function onInput(key: string, event: Event) {
|
|
@@ -192,158 +177,44 @@ function onConfirm() {
|
|
|
192
177
|
</script>
|
|
193
178
|
|
|
194
179
|
<style scoped>
|
|
195
|
-
/* ── 遮罩 ── */
|
|
196
|
-
.params-overlay {
|
|
197
|
-
position: fixed;
|
|
198
|
-
inset: 0;
|
|
199
|
-
background: rgba(0, 0, 0, 0.3);
|
|
200
|
-
backdrop-filter: blur(4px);
|
|
201
|
-
display: flex;
|
|
202
|
-
align-items: center;
|
|
203
|
-
justify-content: center;
|
|
204
|
-
z-index: 1000;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/* ── 弹窗 ── */
|
|
208
|
-
.indicator-params {
|
|
209
|
-
background: var(--klc-color-tag-bg-white);
|
|
210
|
-
border: 1px solid var(--klc-color-border-button);
|
|
211
|
-
border-radius: 12px;
|
|
212
|
-
box-shadow: 0 8px 40px rgba(0, 0, 0, 0.15);
|
|
213
|
-
min-width: 340px;
|
|
214
|
-
max-width: 420px;
|
|
215
|
-
width: 90vw;
|
|
216
|
-
overflow: hidden;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/* ── 头部 ── */
|
|
220
|
-
.params-header {
|
|
221
|
-
display: flex;
|
|
222
|
-
justify-content: space-between;
|
|
223
|
-
align-items: center;
|
|
224
|
-
padding: 16px 20px;
|
|
225
|
-
background: var(--klc-color-background);
|
|
226
|
-
border-bottom: 1px solid var(--klc-color-grid-major);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
.header-left {
|
|
230
|
-
display: flex;
|
|
231
|
-
align-items: baseline;
|
|
232
|
-
gap: 8px;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
.header-right {
|
|
236
|
-
display: flex;
|
|
237
|
-
align-items: center;
|
|
238
|
-
gap: 8px;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
.params-title {
|
|
242
|
-
font-size: 14px;
|
|
243
|
-
font-weight: 600;
|
|
244
|
-
color: var(--klc-color-foreground);
|
|
245
|
-
letter-spacing: 0.2px;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
.params-subtitle {
|
|
249
|
-
font-size: 11px;
|
|
250
|
-
color: var(--klc-color-axis-text);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
.toggle-desc-btn {
|
|
254
|
-
background: var(--klc-color-tag-bg-white);
|
|
255
|
-
border: 1px solid var(--klc-color-border-button);
|
|
256
|
-
border-radius: 6px;
|
|
257
|
-
width: 28px;
|
|
258
|
-
height: 28px;
|
|
259
|
-
display: flex;
|
|
260
|
-
align-items: center;
|
|
261
|
-
justify-content: center;
|
|
262
|
-
cursor: pointer;
|
|
263
|
-
color: var(--klc-color-axis-text);
|
|
264
|
-
transition: all 0.2s;
|
|
265
|
-
padding: 0;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
.toggle-desc-btn:hover {
|
|
269
|
-
background: var(--klc-color-tag-bg-hover);
|
|
270
|
-
color: var(--klc-color-foreground);
|
|
271
|
-
border-color: var(--klc-color-axis-line);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
.toggle-desc-btn.active {
|
|
275
|
-
background: var(--klc-color-foreground);
|
|
276
|
-
border-color: var(--klc-color-foreground);
|
|
277
|
-
color: var(--klc-color-background);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
.toggle-desc-btn svg {
|
|
281
|
-
width: 14px;
|
|
282
|
-
height: 14px;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
.params-close {
|
|
286
|
-
background: var(--klc-color-tag-bg-white);
|
|
287
|
-
border: 1px solid var(--klc-color-border-button);
|
|
288
|
-
border-radius: 6px;
|
|
289
|
-
width: 28px;
|
|
290
|
-
height: 28px;
|
|
291
|
-
display: flex;
|
|
292
|
-
align-items: center;
|
|
293
|
-
justify-content: center;
|
|
294
|
-
cursor: pointer;
|
|
295
|
-
color: var(--klc-color-axis-text);
|
|
296
|
-
transition: background 0.15s, color 0.15s, border-color 0.15s;
|
|
297
|
-
padding: 0;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
.params-close:hover {
|
|
301
|
-
background: var(--klc-color-tag-bg-hover);
|
|
302
|
-
color: var(--klc-color-foreground);
|
|
303
|
-
border-color: var(--klc-color-axis-line);
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
.params-close svg {
|
|
307
|
-
width: 14px;
|
|
308
|
-
height: 14px;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
180
|
/* ── 指标描述 ── */
|
|
312
181
|
.indicator-description {
|
|
313
|
-
padding: 12px
|
|
314
|
-
background:
|
|
315
|
-
border-
|
|
182
|
+
padding: 8px 12px;
|
|
183
|
+
background: var(--klc-color-grid-minor);
|
|
184
|
+
border-left: 3px solid var(--klc-color-alert-active);
|
|
185
|
+
border-radius: 4px;
|
|
186
|
+
margin-bottom: 12px;
|
|
316
187
|
}
|
|
317
188
|
|
|
318
189
|
.indicator-description p {
|
|
319
190
|
margin: 0;
|
|
320
191
|
font-size: 12px;
|
|
321
|
-
line-height: 1.
|
|
322
|
-
color: var(--klc-color-
|
|
192
|
+
line-height: 1.5;
|
|
193
|
+
color: var(--klc-color-axis-text);
|
|
323
194
|
}
|
|
324
195
|
|
|
325
196
|
/* ── 体部 ── */
|
|
326
197
|
.params-body {
|
|
327
|
-
padding: 16px 20px;
|
|
328
198
|
display: flex;
|
|
329
199
|
flex-direction: column;
|
|
330
|
-
gap:
|
|
200
|
+
gap: 4px;
|
|
331
201
|
}
|
|
332
202
|
|
|
333
203
|
.param-item {
|
|
334
|
-
padding:
|
|
335
|
-
border-radius:
|
|
336
|
-
background:
|
|
337
|
-
border: 1px solid
|
|
338
|
-
transition:
|
|
204
|
+
padding: 8px 12px;
|
|
205
|
+
border-radius: 6px;
|
|
206
|
+
background: transparent;
|
|
207
|
+
border: 1px solid transparent;
|
|
208
|
+
transition: background 0.15s ease;
|
|
339
209
|
}
|
|
340
210
|
|
|
211
|
+
.param-item:hover,
|
|
341
212
|
.param-item:has(.param-input:focus) {
|
|
342
|
-
|
|
213
|
+
background: var(--klc-color-grid-minor);
|
|
343
214
|
}
|
|
344
215
|
|
|
345
216
|
.param-item.has-desc {
|
|
346
|
-
padding:
|
|
217
|
+
padding: 8px 12px 6px;
|
|
347
218
|
}
|
|
348
219
|
|
|
349
220
|
.param-header {
|
|
@@ -372,24 +243,57 @@ function onConfirm() {
|
|
|
372
243
|
|
|
373
244
|
/* ── 参数描述 ── */
|
|
374
245
|
.param-description {
|
|
375
|
-
margin-top:
|
|
376
|
-
padding-top:
|
|
246
|
+
margin-top: 6px;
|
|
247
|
+
padding-top: 6px;
|
|
377
248
|
border-top: 1px dashed var(--klc-color-border-button);
|
|
378
249
|
font-size: 11px;
|
|
379
|
-
line-height: 1.
|
|
250
|
+
line-height: 1.4;
|
|
380
251
|
color: var(--klc-color-axis-text);
|
|
381
252
|
}
|
|
382
253
|
|
|
254
|
+
/* ── 描述切换按钮 ── */
|
|
255
|
+
.toggle-desc-btn {
|
|
256
|
+
background: transparent;
|
|
257
|
+
border: 1px solid var(--klc-color-border-button);
|
|
258
|
+
border-radius: 6px;
|
|
259
|
+
width: 32px;
|
|
260
|
+
height: 32px;
|
|
261
|
+
display: flex;
|
|
262
|
+
align-items: center;
|
|
263
|
+
justify-content: center;
|
|
264
|
+
cursor: pointer;
|
|
265
|
+
color: var(--klc-color-axis-text);
|
|
266
|
+
transition: all 0.15s ease;
|
|
267
|
+
padding: 0;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.toggle-desc-btn:hover {
|
|
271
|
+
background: var(--klc-color-grid-minor);
|
|
272
|
+
color: var(--klc-color-foreground);
|
|
273
|
+
border-color: var(--klc-color-axis-line);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.toggle-desc-btn.active {
|
|
277
|
+
background: var(--klc-color-grid-minor);
|
|
278
|
+
border-color: var(--klc-color-axis-line);
|
|
279
|
+
color: var(--klc-color-foreground);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.toggle-desc-btn svg {
|
|
283
|
+
width: 14px;
|
|
284
|
+
height: 14px;
|
|
285
|
+
}
|
|
286
|
+
|
|
383
287
|
/* ── 步进输入框 ── */
|
|
384
288
|
.input-wrapper {
|
|
385
289
|
display: flex;
|
|
386
290
|
align-items: stretch;
|
|
387
|
-
height:
|
|
388
|
-
border: 1px solid var(--klc-color-
|
|
389
|
-
border-radius:
|
|
291
|
+
height: 30px;
|
|
292
|
+
border: 1px solid var(--klc-color-border-button);
|
|
293
|
+
border-radius: 6px;
|
|
390
294
|
overflow: hidden;
|
|
391
|
-
background: var(--klc-color-
|
|
392
|
-
transition: border-color 0.
|
|
295
|
+
background: var(--klc-color-background);
|
|
296
|
+
transition: border-color 0.15s ease;
|
|
393
297
|
}
|
|
394
298
|
|
|
395
299
|
.input-wrapper:focus-within {
|
|
@@ -398,7 +302,7 @@ function onConfirm() {
|
|
|
398
302
|
|
|
399
303
|
.stepper-btn {
|
|
400
304
|
width: 28px;
|
|
401
|
-
background:
|
|
305
|
+
background: transparent;
|
|
402
306
|
border: none;
|
|
403
307
|
cursor: pointer;
|
|
404
308
|
font-size: 15px;
|
|
@@ -407,13 +311,15 @@ function onConfirm() {
|
|
|
407
311
|
display: flex;
|
|
408
312
|
align-items: center;
|
|
409
313
|
justify-content: center;
|
|
410
|
-
transition:
|
|
314
|
+
transition:
|
|
315
|
+
background 0.15s,
|
|
316
|
+
color 0.15s;
|
|
411
317
|
flex-shrink: 0;
|
|
412
318
|
line-height: 1;
|
|
413
319
|
}
|
|
414
320
|
|
|
415
321
|
.stepper-btn:hover:not(:disabled) {
|
|
416
|
-
background: var(--klc-color-
|
|
322
|
+
background: var(--klc-color-grid-minor);
|
|
417
323
|
color: var(--klc-color-foreground);
|
|
418
324
|
}
|
|
419
325
|
|
|
@@ -423,10 +329,13 @@ function onConfirm() {
|
|
|
423
329
|
}
|
|
424
330
|
|
|
425
331
|
.param-input {
|
|
426
|
-
width:
|
|
332
|
+
width: auto;
|
|
333
|
+
field-sizing: content;
|
|
334
|
+
min-width: 60px;
|
|
335
|
+
padding: 0 8px;
|
|
427
336
|
border: none;
|
|
428
|
-
border-left: 1px solid var(--klc-color-
|
|
429
|
-
border-right: 1px solid var(--klc-color-
|
|
337
|
+
border-left: 1px solid var(--klc-color-border-button);
|
|
338
|
+
border-right: 1px solid var(--klc-color-border-button);
|
|
430
339
|
font-size: 13px;
|
|
431
340
|
font-weight: 600;
|
|
432
341
|
text-align: center;
|
|
@@ -446,64 +355,58 @@ function onConfirm() {
|
|
|
446
355
|
}
|
|
447
356
|
|
|
448
357
|
/* ── 底部 ── */
|
|
449
|
-
.params-footer {
|
|
450
|
-
display: flex;
|
|
451
|
-
align-items: center;
|
|
452
|
-
justify-content: space-between;
|
|
453
|
-
padding: 12px 20px;
|
|
454
|
-
background: var(--klc-color-background);
|
|
455
|
-
border-top: 1px solid var(--klc-color-grid-major);
|
|
456
|
-
}
|
|
457
|
-
|
|
458
358
|
.footer-right {
|
|
459
359
|
display: flex;
|
|
460
360
|
gap: 8px;
|
|
461
361
|
}
|
|
462
362
|
|
|
463
363
|
.params-btn {
|
|
464
|
-
display: flex;
|
|
364
|
+
display: inline-flex;
|
|
465
365
|
align-items: center;
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
366
|
+
justify-content: center;
|
|
367
|
+
gap: 6px;
|
|
368
|
+
min-width: 68px;
|
|
369
|
+
height: 34px;
|
|
370
|
+
padding: 0 16px;
|
|
371
|
+
border-radius: 6px;
|
|
469
372
|
font-size: 13px;
|
|
470
373
|
font-weight: 500;
|
|
471
374
|
cursor: pointer;
|
|
472
375
|
border: 1px solid transparent;
|
|
473
|
-
transition: all 0.15s;
|
|
474
|
-
line-height: 1
|
|
376
|
+
transition: all 0.15s ease;
|
|
377
|
+
line-height: 1;
|
|
378
|
+
white-space: nowrap;
|
|
475
379
|
}
|
|
476
380
|
|
|
477
381
|
.params-btn svg {
|
|
478
|
-
width:
|
|
479
|
-
height:
|
|
382
|
+
width: 13px;
|
|
383
|
+
height: 13px;
|
|
480
384
|
flex-shrink: 0;
|
|
481
385
|
}
|
|
482
386
|
|
|
483
387
|
/* 重置 */
|
|
484
388
|
.params-btn.reset {
|
|
485
389
|
background: transparent;
|
|
486
|
-
border-color: var(--klc-color-
|
|
390
|
+
border-color: var(--klc-color-border-button);
|
|
487
391
|
color: var(--klc-color-axis-text);
|
|
488
392
|
}
|
|
489
393
|
|
|
490
394
|
.params-btn.reset:hover {
|
|
491
|
-
border-color: #
|
|
492
|
-
color: #
|
|
493
|
-
background: rgba(
|
|
395
|
+
border-color: #f0a020;
|
|
396
|
+
color: #f0a020;
|
|
397
|
+
background: rgba(240, 160, 32, 0.08);
|
|
494
398
|
}
|
|
495
399
|
|
|
496
400
|
/* 取消 */
|
|
497
401
|
.params-btn.cancel {
|
|
498
402
|
background: transparent;
|
|
499
|
-
border-color: var(--klc-color-
|
|
500
|
-
color: var(--klc-color-
|
|
403
|
+
border-color: var(--klc-color-border-button);
|
|
404
|
+
color: var(--klc-color-foreground);
|
|
501
405
|
}
|
|
502
406
|
|
|
503
407
|
.params-btn.cancel:hover {
|
|
504
|
-
background: var(--klc-color-
|
|
505
|
-
color: var(--klc-color-
|
|
506
|
-
border-color: var(--klc-color-axis-text);
|
|
408
|
+
background: var(--klc-color-grid-minor);
|
|
409
|
+
border-color: var(--klc-color-axis-line);
|
|
507
410
|
}
|
|
508
411
|
|
|
509
412
|
/* 确定 */
|
|
@@ -514,50 +417,19 @@ function onConfirm() {
|
|
|
514
417
|
}
|
|
515
418
|
|
|
516
419
|
.params-btn.confirm:hover {
|
|
517
|
-
|
|
518
|
-
border-color: var(--klc-color-foreground);
|
|
519
|
-
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
|
|
520
|
-
transform: translateY(-1px);
|
|
420
|
+
opacity: 0.9;
|
|
521
421
|
}
|
|
522
422
|
|
|
523
423
|
.params-btn.confirm:active {
|
|
524
|
-
|
|
525
|
-
box-shadow: none;
|
|
424
|
+
opacity: 0.8;
|
|
526
425
|
}
|
|
527
426
|
|
|
528
427
|
/* ── 动画 ── */
|
|
529
|
-
.overlay-enter-active,
|
|
530
|
-
.overlay-leave-active {
|
|
531
|
-
transition: opacity 0.2s ease;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
.overlay-enter-from,
|
|
535
|
-
.overlay-leave-to {
|
|
536
|
-
opacity: 0;
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
.modal-enter-active {
|
|
540
|
-
transition: all 0.22s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
.modal-leave-active {
|
|
544
|
-
transition: all 0.16s ease-in;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
.modal-enter-from {
|
|
548
|
-
opacity: 0;
|
|
549
|
-
transform: scale(0.88) translateY(-16px);
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
.modal-leave-to {
|
|
553
|
-
opacity: 0;
|
|
554
|
-
transform: scale(0.94) translateY(8px);
|
|
555
|
-
}
|
|
556
|
-
|
|
557
428
|
.slide-enter-active,
|
|
558
429
|
.slide-leave-active {
|
|
559
430
|
transition: all 0.2s ease;
|
|
560
431
|
overflow: hidden;
|
|
432
|
+
max-height: 200px;
|
|
561
433
|
}
|
|
562
434
|
|
|
563
435
|
.slide-enter-from,
|
|
@@ -567,5 +439,6 @@ function onConfirm() {
|
|
|
567
439
|
padding-top: 0;
|
|
568
440
|
padding-bottom: 0;
|
|
569
441
|
margin-top: 0;
|
|
442
|
+
margin-bottom: 0;
|
|
570
443
|
}
|
|
571
444
|
</style>
|