@363045841yyt/klinechart 0.8.5 → 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.
Files changed (43) hide show
  1. package/README.md +6 -1
  2. package/dist/components/BaseModal.vue.d.ts +54 -0
  3. package/dist/components/BaseModal.vue.d.ts.map +1 -0
  4. package/dist/components/BatchStockDialog.vue.d.ts.map +1 -1
  5. package/dist/components/ChartSettingsDialog.vue.d.ts.map +1 -1
  6. package/dist/components/ColorPresetPanel.vue.d.ts +4 -1
  7. package/dist/components/ColorPresetPanel.vue.d.ts.map +1 -1
  8. package/dist/components/DrawingStyleToolbar.vue.d.ts.map +1 -1
  9. package/dist/components/ExportProgressDialog.vue.d.ts.map +1 -1
  10. package/dist/components/IndicatorParams.vue.d.ts.map +1 -1
  11. package/dist/components/IndicatorSelector.vue.d.ts.map +1 -1
  12. package/dist/components/KLineChart.vue.d.ts.map +1 -1
  13. package/dist/components/RangeSelectionExport.vue.d.ts +23 -0
  14. package/dist/components/RangeSelectionExport.vue.d.ts.map +1 -0
  15. package/dist/components/common/CanvasToolbar.vue.d.ts +14 -0
  16. package/dist/components/common/CanvasToolbar.vue.d.ts.map +1 -0
  17. package/dist/components/common/CanvasToolbarStack.vue.d.ts +14 -0
  18. package/dist/components/common/CanvasToolbarStack.vue.d.ts.map +1 -0
  19. package/dist/composables/chart/useRangeSelection.d.ts +1 -0
  20. package/dist/composables/chart/useRangeSelection.d.ts.map +1 -1
  21. package/dist/composables/useTeleportedPopup.d.ts.map +1 -1
  22. package/dist/index.cjs +6 -6
  23. package/dist/index.css +1 -1
  24. package/dist/index.js +1293 -1215
  25. package/dist/web-component.d.ts.map +1 -1
  26. package/package.json +1 -1
  27. package/src/components/BaseModal.vue +292 -0
  28. package/src/components/BatchStockDialog.vue +15 -180
  29. package/src/components/ChartSettingsDialog.vue +248 -405
  30. package/src/components/ColorPresetPanel.vue +58 -106
  31. package/src/components/CompareSymbolSelector.vue +2 -2
  32. package/src/components/DrawingStyleToolbar.vue +33 -72
  33. package/src/components/ExportProgressDialog.vue +25 -133
  34. package/src/components/IndicatorParams.vue +194 -321
  35. package/src/components/IndicatorSelector.vue +188 -405
  36. package/src/components/KLineChart.vue +34 -138
  37. package/src/components/LeftToolbar.vue +1 -1
  38. package/src/components/RangeSelectionExport.vue +117 -0
  39. package/src/components/SymbolSelector.vue +2 -2
  40. package/src/components/common/CanvasToolbar.vue +70 -0
  41. package/src/components/common/CanvasToolbarStack.vue +32 -0
  42. package/src/composables/chart/useRangeSelection.ts +7 -0
  43. package/src/composables/useTeleportedPopup.ts +15 -2
@@ -1,123 +1,110 @@
1
1
  <template>
2
- <Teleport :to="teleportTarget">
3
- <Transition name="overlay">
4
- <div v-if="visible" class="params-overlay" @click="$emit('close')">
5
- <Transition name="modal">
6
- <div class="indicator-params" @click.stop>
7
- <!-- 头部 -->
8
- <div class="params-header">
9
- <div class="header-left">
10
- <span class="params-title">{{ indicatorName }}</span>
11
- <span class="params-subtitle">参数设置</span>
12
- </div>
13
- <div class="header-right">
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 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" fill="currentColor" />
22
- </svg>
23
- </button>
24
- <button class="params-close" @click="$emit('close')">
25
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
26
- <path d="M18 6L6 18M6 6l12 12" />
27
- </svg>
28
- </button>
29
- </div>
30
- </div>
31
-
32
- <!-- 指标描述 -->
33
- <Transition name="slide">
34
- <div v-if="showDescription && indicatorDescription" class="indicator-description">
35
- <p>{{ indicatorDescription }}</p>
36
- </div>
37
- </Transition>
38
-
39
- <!-- 体部 -->
40
- <div class="params-body">
41
- <div
42
- v-for="param in params"
43
- :key="param.key"
44
- class="param-item"
45
- :class="{ 'has-desc': showDescription && param.description }"
46
- >
47
- <div class="param-header">
48
- <label class="param-label">
49
- <span class="param-label-text">{{ param.label }}</span>
50
- <span
51
- v-if="param.min !== undefined || param.max !== undefined"
52
- class="param-range"
53
- >
54
- {{ param.min ?? '-∞' }} ~ {{ param.max ?? '+∞' }}
55
- </span>
56
- </label>
57
- <div class="input-wrapper">
58
- <button
59
- class="stepper-btn"
60
- :disabled="param.min !== undefined && (localValues[param.key] ?? 0) <= param.min"
61
- @click="step(param, -1)"
62
- >
63
-
64
- </button>
65
- <input
66
- v-if="param.type === 'number'"
67
- type="number"
68
- class="param-input"
69
- :value="localValues[param.key]"
70
- :min="param.min"
71
- :max="param.max"
72
- :step="param.step || 1"
73
- @input="onInput(param.key, $event)"
74
- />
75
- <button
76
- class="stepper-btn"
77
- :disabled="param.max !== undefined && (localValues[param.key] ?? 0) >= param.max"
78
- @click="step(param, 1)"
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
- </Transition>
115
- </Teleport>
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, computed } from 'vue'
120
- import { useFullscreenTeleportTarget } from '../composables/useFullscreenTeleportTarget'
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 20px;
314
- background: color-mix(in srgb, var(--klc-color-alert-active) 10%, var(--klc-color-background));
315
- border-bottom: 1px solid color-mix(in srgb, var(--klc-color-alert-active) 20%, transparent);
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.6;
322
- color: var(--klc-color-alert-active);
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: 10px;
200
+ gap: 4px;
331
201
  }
332
202
 
333
203
  .param-item {
334
- padding: 10px 14px;
335
- border-radius: 8px;
336
- background: var(--klc-color-background);
337
- border: 1px solid var(--klc-color-grid-major);
338
- transition: border-color 0.2s;
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
- border-color: var(--klc-color-axis-text);
213
+ background: var(--klc-color-grid-minor);
343
214
  }
344
215
 
345
216
  .param-item.has-desc {
346
- padding: 10px 14px 8px;
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: 8px;
376
- padding-top: 8px;
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.5;
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: 32px;
388
- border: 1px solid var(--klc-color-axis-line);
389
- border-radius: 7px;
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-tag-bg-white);
392
- transition: border-color 0.2s;
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: var(--klc-color-grid-minor);
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: background 0.15s, color 0.15s;
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-border-button);
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: 60px;
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-grid-major);
429
- border-right: 1px solid var(--klc-color-grid-major);
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
- gap: 5px;
467
- padding: 6px 14px;
468
- border-radius: 7px;
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.4;
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: 12px;
479
- height: 12px;
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-axis-line);
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: #c0392b;
492
- color: #e74c3c;
493
- background: rgba(231, 76, 60, 0.08);
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-axis-line);
500
- color: var(--klc-color-axis-text);
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-tag-bg-hover);
505
- color: var(--klc-color-foreground);
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
- background: var(--klc-color-foreground);
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
- transform: translateY(0);
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>