jvs-ppt-ui 0.0.14 → 0.0.16

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 (67) hide show
  1. package/dist/lib/check_imgs.html +18 -0
  2. package/dist/lib/jvs-ppt-ui/iconfont/iconfont.css +187 -27
  3. package/dist/lib/jvs-ppt-ui/iconfont/iconfont.js +1 -1
  4. package/dist/lib/jvs-ppt-ui/iconfont/iconfont.json +345 -65
  5. package/dist/lib/jvs-ppt-ui/iconfont/iconfont.ttf +0 -0
  6. package/dist/lib/jvs-ppt-ui/iconfont/iconfont.woff +0 -0
  7. package/dist/lib/jvs-ppt-ui/iconfont/iconfont.woff2 +0 -0
  8. package/dist/lib/jvs-ppt-ui/img/al.png +0 -0
  9. package/dist/lib/jvs-ppt-ui/img/d.png +0 -0
  10. package/dist/lib/jvs-ppt-ui/img/dl.png +0 -0
  11. package/dist/lib/jvs-ppt-ui/img/l.png +0 -0
  12. package/dist/lib/jvs-ppt-ui.es.js +44973 -43349
  13. package/dist/lib/jvs-ppt-ui.umd.js +102 -102
  14. package/dist/lib/style.css +1 -1
  15. package/package.json +1 -1
  16. package/scripts/check-icons.mjs +22 -0
  17. package/scripts/patch-anim-icons.mjs +45 -0
  18. package/src/assets/iconfont/iconfont.css +187 -27
  19. package/src/assets/iconfont/iconfont.js +1 -1
  20. package/src/assets/iconfont/iconfont.json +345 -65
  21. package/src/assets/iconfont/iconfont.ttf +0 -0
  22. package/src/assets/iconfont/iconfont.woff +0 -0
  23. package/src/assets/iconfont/iconfont.woff2 +0 -0
  24. package/src/components/CanvasArea.vue +218 -193
  25. package/src/components/ChartTypeSelector.vue +509 -148
  26. package/src/components/Header.vue +327 -44
  27. package/src/components/PresentationGroupChild.vue +44 -13
  28. package/src/components/PresentationMode.vue +84 -33
  29. package/src/components/QuickBorderPopover.vue +51 -11
  30. package/src/components/QuickColorPopover.vue +65 -21
  31. package/src/components/SidebarLeft.vue +286 -107
  32. package/src/components/SidebarRight.vue +45 -38
  33. package/src/components/TemplateGallery.vue +1110 -1237
  34. package/src/components/ToastNotification.vue +2 -2
  35. package/src/components/Toolbar.vue +825 -733
  36. package/src/components/canvas/CanvasQuickToolbar.vue +17 -30
  37. package/src/components/canvas/elements/CanvasGroupElement.vue +6 -0
  38. package/src/components/canvas/elements/CanvasShapeElement.vue +198 -38
  39. package/src/components/canvas/elements/CanvasTextElement.vue +4 -3
  40. package/src/components/sidebar/common/SidebarAlignGroup.vue +104 -50
  41. package/src/components/sidebar/common/SidebarBorderAccordion.vue +375 -148
  42. package/src/components/sidebar/common/SidebarPositionGroup.vue +358 -149
  43. package/src/components/sidebar/common/SidebarReflectionAccordion.vue +429 -203
  44. package/src/components/sidebar/common/SidebarShadowAccordion.vue +844 -416
  45. package/src/components/sidebar/panels/GradientEditor.vue +671 -316
  46. package/src/components/sidebar/panels/LayoutThumbSvg.vue +33 -16
  47. package/src/components/sidebar/panels/SidebarAnimationPanel.vue +701 -138
  48. package/src/components/sidebar/panels/SidebarChartFormatPanel.vue +3 -3
  49. package/src/components/sidebar/panels/SidebarDesignPanel.vue +1754 -416
  50. package/src/components/sidebar/panels/SidebarMediaFormatPanel.vue +12 -0
  51. package/src/components/sidebar/panels/SidebarShapeFormatPanel.vue +813 -174
  52. package/src/components/sidebar/panels/SidebarTableFormatPanel.vue +2 -2
  53. package/src/components/sidebar/panels/SidebarTextFormatPanel.vue +1938 -1427
  54. package/src/components/sidebar/panels/SidebarTransitionPanel.vue +791 -210
  55. package/src/composables/canvas/useCanvasShortcuts.ts +20 -6
  56. package/src/composables/canvas/useCanvasText.ts +1 -1
  57. package/src/composables/canvas/useCanvasTransform.ts +44 -0
  58. package/src/composables/presetThemes.ts +43 -44
  59. package/src/composables/sidebar/useSidebarAnimation.ts +101 -25
  60. package/src/composables/sidebar/useSidebarDesign.ts +30 -11
  61. package/src/composables/sidebar/useSidebarElementTransform.ts +10 -1
  62. package/src/composables/sidebar/useSidebarImage.ts +10 -2
  63. package/src/composables/sidebar/useSidebarShapeFormat.ts +562 -107
  64. package/src/composables/useSlides.ts +331 -153
  65. package/src/main.ts +2 -0
  66. package/src/style.css +926 -359
  67. package/src/utils/canvas/elementStyles.ts +42 -1
@@ -1,6 +1,7 @@
1
1
  <script setup lang="ts">
2
- import { ref } from 'vue'
2
+ import { ref, computed } from 'vue'
3
3
  import QuickColorPopover from '../../QuickColorPopover.vue'
4
+ import { parseColor } from '../../../composables/sidebar/useSidebarShapeFormat'
4
5
 
5
6
  const props = withDefaults(defineProps<{
6
7
  isBorderEnabled?: boolean
@@ -17,7 +18,7 @@ const props = withDefaults(defineProps<{
17
18
  borderHex: '#000000',
18
19
  borderWidth: 1,
19
20
  borderStyle: 'solid',
20
- borderAlpha: 0,
21
+ borderAlpha: 100,
21
22
  showAlpha: true,
22
23
  recentColors: () => []
23
24
  })
@@ -59,74 +60,172 @@ function toggleExpand() {
59
60
  emit('update:isBorderExpanded', !props.isBorderExpanded)
60
61
  }
61
62
 
63
+ const displayBorderOpacity = computed(() => {
64
+ if (props.borderHex === 'transparent' || props.borderHex === 'none') {
65
+ return 0
66
+ }
67
+ const alpha = props.borderAlpha !== undefined ? props.borderAlpha : 100
68
+ return Math.max(0, Math.min(100, Math.round(alpha)))
69
+ })
70
+
71
+ function handleBorderOpacityInput(e: Event) {
72
+ const target = e.target as HTMLInputElement
73
+ let val = parseInt(target.value)
74
+ if (isNaN(val)) val = 100
75
+ val = Math.max(0, Math.min(100, val))
76
+ emit('update:borderAlpha', val)
77
+ }
78
+
79
+ function onSelectBorderColor(color: string) {
80
+ if (!color || color === 'transparent' || color === 'none') {
81
+ emit('update:borderHex', 'transparent')
82
+ emit('update:borderAlpha', 0)
83
+ return
84
+ }
85
+ const parsed = parseColor(color)
86
+ emit('update:borderHex', parsed.hex)
87
+ if (parsed.alpha !== undefined && parsed.alpha < 100) {
88
+ emit('update:borderAlpha', parsed.alpha)
89
+ } else if (!props.borderAlpha || props.borderAlpha === 0) {
90
+ emit('update:borderAlpha', 100)
91
+ }
92
+ }
93
+
62
94
  function toggleSwitch(val: any) {
63
95
  const boolVal = !!val
64
96
  emit('update:isBorderEnabled', boolVal)
65
97
  emit('update:isBorderExpanded', boolVal)
66
98
  }
99
+
100
+ function handleBorderOpacityBlur(e: Event) {
101
+ const target = e.target as HTMLInputElement
102
+ if (target.value === '' || isNaN(Number(target.value))) {
103
+ target.value = String(displayBorderOpacity.value)
104
+ } else {
105
+ let val = parseInt(target.value)
106
+ val = Math.max(0, Math.min(100, val))
107
+ target.value = String(val)
108
+ emit('update:borderAlpha', val)
109
+ }
110
+ }
111
+
112
+ const borderWidthInputRef = ref<HTMLInputElement | null>(null)
113
+
114
+ function focusBorderWidthInput(e: MouseEvent) {
115
+ if (e.target !== borderWidthInputRef.value) {
116
+ borderWidthInputRef.value?.focus()
117
+ borderWidthInputRef.value?.select()
118
+ }
119
+ }
120
+
121
+ function onBorderWidthInput(e: Event) {
122
+ const target = e.target as HTMLInputElement
123
+ const raw = target.value
124
+ if (raw === '') return
125
+ const val = Number(raw)
126
+ if (isNaN(val)) return
127
+ const safeVal = Math.max(0, Math.min(100, Math.round(val)))
128
+ emit('update:borderWidth', safeVal)
129
+ }
130
+
131
+ function onBorderWidthBlur(e: Event) {
132
+ const target = e.target as HTMLInputElement
133
+ if (target.value === '' || isNaN(Number(target.value))) {
134
+ target.value = String(props.borderWidth ?? 1)
135
+ } else {
136
+ const val = Number(target.value)
137
+ const safeVal = Math.max(0, Math.min(100, Math.round(val)))
138
+ target.value = String(safeVal)
139
+ emit('update:borderWidth', safeVal)
140
+ }
141
+ }
67
142
  </script>
68
143
 
69
144
  <template>
70
145
  <div class="control-group shape-accordion-group">
146
+ <!-- Header -->
71
147
  <div class="shape-accordion-header" @click="toggleHeader">
72
148
  <span class="control-label shape-accordion-header-label">
73
- <span class="accordion-arrow" @click.stop="toggleExpand"
74
- :style="{ transform: (isBorderEnabled && isBorderExpanded) ? 'rotate(90deg)' : 'rotate(0deg)' }">▶</span>边框
149
+ <span>边框</span>
150
+ <span class="accordion-arrow">
151
+ <svg class="icon" style="width: 14px; height: 14px;">
152
+ <use :href="(isBorderEnabled && isBorderExpanded) ? '#icon-xiala-zhankai' : '#icon-xiala-shouqi'"
153
+ :xlink:href="(isBorderEnabled && isBorderExpanded) ? '#icon-xiala-zhankai' : '#icon-xiala-shouqi'"></use>
154
+ </svg>
155
+ </span>
75
156
  </span>
76
157
  <el-switch :model-value="isBorderEnabled" size="small" @click.stop @change="toggleSwitch" />
77
158
  </div>
78
159
 
160
+ <!-- Content -->
79
161
  <div v-show="isBorderExpanded && isBorderEnabled" class="shape-accordion-content">
80
- <!-- Border Color -->
81
- <div class="shape-property-row">
82
- <span class="shape-property-label">颜色</span>
83
- <QuickColorPopover v-model:visible="borderPopoverVisible" :color="borderHex || '#000000'"
84
- :recent-colors="recentColors" @select-color="emit('update:borderHex', $event)">
162
+ <!-- Row 1: Border Color Swatch Pill (Full-width) -->
163
+ <div class="full-color-pill">
164
+ <QuickColorPopover v-model:visible="borderPopoverVisible" :color="borderHex || '#000000'" :alpha="props.borderAlpha"
165
+ :recent-colors="recentColors" @select-color="onSelectBorderColor">
85
166
  <template #reference>
86
- <div class="color-picker-pill-wrapper">
87
- <div class="color-pill-inner">
88
- <div :style="{ background: borderHex || '#000000' }" class="color-square-preview"></div>
89
- <span class="color-hex-text">
90
- {{ formatHexDisplay(borderHex || '#000000') }}
91
- </span>
92
- </div>
167
+ <div class="color-left-info">
168
+ <div :style="{ background: borderHex || '#000000' }" class="color-square-preview"></div>
169
+ <span class="color-hex-text">
170
+ {{ formatHexDisplay(borderHex || '#000000') }}
171
+ </span>
93
172
  </div>
94
173
  </template>
95
174
  </QuickColorPopover>
96
- </div>
97
-
98
- <!-- Border Style & Width -->
99
- <div class="shape-property-row">
100
- <span class="shape-property-label">样式</span>
101
- <div class="shape-border-style-wrapper">
102
- <!-- Border style dropdown -->
103
- <el-select :model-value="borderStyle || 'solid'" @update:model-value="emit('update:borderStyle', $event)"
104
- size="small" class="custom-select" style="width: 96px; flex-shrink: 0;">
105
- <el-option label="───" value="solid" />
106
- <el-option label="---" value="dashed" />
107
- </el-select>
108
- <!-- Border width selector -->
109
- <div class="shape-border-width-wrapper" style="width: 96px; flex: none;">
110
- <svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2"
111
- style="margin-right: 6px; color: var(--text-secondary); flex-shrink: 0;">
112
- <line x1="3" y1="6" x2="21" y2="6" />
113
- <line x1="3" y1="12" x2="21" y2="12" />
114
- <line x1="3" y1="18" x2="21" y2="18" />
115
- </svg>
116
- <input type="number" :value="borderWidth ?? 1"
117
- @input="emit('update:borderWidth', Number(($event.target as HTMLInputElement).value))" :min="0" :max="100"
118
- class="shape-num-field" />
119
- </div>
175
+ <div class="color-opacity-input-wrapper" @click.stop title="边框不透明度 (0%为全透明,100%为完全不透明)">
176
+ <input
177
+ type="text"
178
+ inputmode="numeric"
179
+ class="color-opacity-num-input"
180
+ :value="displayBorderOpacity"
181
+ @input="handleBorderOpacityInput"
182
+ @blur="handleBorderOpacityBlur"
183
+ @keydown.enter="($event.target as HTMLElement).blur()"
184
+ :style="{ width: `calc(${String(displayBorderOpacity).length}ch + 2px)` }"
185
+ />
186
+ <span class="percent-unit">%</span>
120
187
  </div>
121
188
  </div>
122
189
 
123
- <!-- Border Transparency (optional) -->
124
- <div v-if="showAlpha" class="shape-property-row">
125
- <span class="shape-property-label">透明度</span>
126
- <div class="shape-slider-wrapper">
127
- <el-slider :model-value="borderAlpha || 0" @update:model-value="emit('update:borderAlpha', $event as number)"
128
- :min="0" :max="100" size="small" style="flex: 1;" class="custom-slider" :show-tooltip="false" show-input
129
- :show-input-controls="false" />
190
+ <!-- Row 2: Border Style & Width -->
191
+ <div class="border-style-width-row">
192
+ <!-- Border style dropdown -->
193
+ <el-select :model-value="borderStyle || 'solid'" @update:model-value="emit('update:borderStyle', $event)"
194
+ size="small" class="border-style-select" :teleported="true">
195
+ <template #prefix>
196
+ <div class="border-style-line-preview" :class="borderStyle || 'solid'"></div>
197
+ </template>
198
+ <el-option label="实线" value="solid">
199
+ <div class="style-option-line solid-line"></div>
200
+ </el-option>
201
+ <el-option label="虚线" value="dashed">
202
+ <div class="style-option-line dashed-line"></div>
203
+ </el-option>
204
+ <el-option label="点线" value="dotted">
205
+ <div class="style-option-line dotted-line"></div>
206
+ </el-option>
207
+ </el-select>
208
+
209
+ <!-- Border width input -->
210
+ <div class="border-width-input-pill" @click="focusBorderWidthInput">
211
+ <span class="border-width-icon">
212
+ <svg viewBox="0 0 16 16" width="14" height="14" fill="currentColor">
213
+ <rect x="2" y="3.5" width="12" height="1.8" rx="0.9" />
214
+ <rect x="2" y="7.25" width="12" height="1.8" rx="0.9" />
215
+ <rect x="2" y="11" width="12" height="1.8" rx="0.9" />
216
+ </svg>
217
+ </span>
218
+ <input
219
+ ref="borderWidthInputRef"
220
+ type="text"
221
+ inputmode="numeric"
222
+ :value="borderWidth ?? 1"
223
+ @input="onBorderWidthInput"
224
+ @blur="onBorderWidthBlur"
225
+ @keydown.enter="($event.target as HTMLElement).blur()"
226
+ class="border-num-field"
227
+ :style="{ width: `calc(${String(borderWidth ?? 1).length}ch + 4px)` }"
228
+ />
130
229
  </div>
131
230
  </div>
132
231
  </div>
@@ -135,184 +234,312 @@ function toggleSwitch(val: any) {
135
234
 
136
235
  <style scoped lang="scss">
137
236
  .shape-accordion-group {
138
- border-bottom: 1px solid #EEEFF0;
237
+ border-bottom: 1px solid #f1f5f9;
139
238
  padding-bottom: 12px;
140
- margin-bottom: 8px;
239
+ margin-bottom: 12px;
141
240
  }
142
241
 
143
242
  .shape-accordion-header {
144
243
  display: flex;
145
244
  align-items: center;
245
+ justify-content: space-between;
146
246
  padding: 0 16px;
147
- height: 32px;
247
+ height: 34px;
148
248
  cursor: pointer;
249
+ user-select: none;
149
250
  }
150
251
 
151
252
  .shape-accordion-header-label {
152
- font-size: 13px;
153
- font-weight: 600;
154
- color: var(--text-primary);
253
+ font-size: 14px;
254
+ font-weight: 400;
255
+ color: #1e293b;
155
256
  display: flex;
156
257
  align-items: center;
157
258
  gap: 6px;
158
- width: 80px;
159
259
  flex-shrink: 0;
160
- text-align: left;
161
260
  }
162
261
 
163
262
  .accordion-arrow {
164
- font-size: 9px;
165
- transition: transform 0.2s;
166
- display: inline-block;
167
- color: #475569;
263
+ display: flex;
264
+ align-items: center;
265
+ justify-content: center;
266
+ color: #64748b;
267
+ }
268
+
269
+ :deep(.el-switch) {
270
+ --el-switch-on-color: #2563eb;
271
+ --el-switch-off-color: #cbd5e1;
168
272
  }
169
273
 
170
274
  .shape-accordion-content {
171
- padding: 12px 16px 0 16px;
275
+ padding: 8px 16px 0 16px;
172
276
  display: flex;
173
277
  flex-direction: column;
174
- gap: 12px;
278
+ gap: 8px;
175
279
  }
176
280
 
177
- .shape-property-row {
281
+ .full-color-pill {
282
+ width: 100%;
283
+ height: 32px;
284
+ background: #FAFAFA;
285
+ border: 1px solid #edf0f3;
286
+ border-radius: 8px;
287
+ padding: 0 10px;
288
+ box-sizing: border-box;
178
289
  display: flex;
179
290
  align-items: center;
180
291
  justify-content: space-between;
181
- height: 32px;
182
- padding: 0;
183
- gap: 8px;
184
- }
292
+ cursor: pointer;
293
+ transition: all 0.15s ease;
185
294
 
186
- .shape-property-label {
187
- font-size: 12px;
188
- color: var(--text-secondary, #64748b);
189
- width: 80px;
190
- flex-shrink: 0;
191
- text-align: left;
295
+ &:hover {
296
+ border-color: #cbd5e1;
297
+ }
298
+
299
+ &:focus-within {
300
+ border-color: #2563eb;
301
+ box-shadow: 0 0 0 1px #2563eb;
302
+ }
192
303
  }
193
304
 
194
- .color-picker-pill-wrapper {
195
- position: relative;
196
- display: flex;
197
- align-items: center;
198
- justify-content: space-between;
199
- background: #F5F6F7;
200
- border-radius: 4px;
201
- padding: 0 10px;
202
- height: 32px;
203
- flex: 1;
204
- cursor: pointer;
205
- border: none;
206
- box-sizing: border-box;
305
+ :deep(.el-popover__reference-wrapper),
306
+ :deep(.color-span-box) {
307
+ display: flex !important;
308
+ align-items: center !important;
309
+ height: 100% !important;
207
310
  }
208
311
 
209
- .color-pill-inner {
312
+ .color-left-info {
210
313
  display: flex;
211
314
  align-items: center;
212
315
  gap: 8px;
316
+ cursor: pointer;
317
+ height: 100%;
213
318
  }
214
319
 
215
320
  .color-square-preview {
216
- width: 14px;
217
- height: 14px;
218
- border-radius: 3px;
321
+ width: 16px;
322
+ height: 16px;
323
+ border-radius: 4px;
219
324
  border: 1px solid rgba(0, 0, 0, 0.1);
220
325
  flex-shrink: 0;
326
+ transition: transform 0.15s ease;
327
+
328
+ &:hover {
329
+ transform: scale(1.08);
330
+ }
221
331
  }
222
332
 
223
333
  .color-hex-text {
224
- font-size: 11px;
225
- color: var(--text-primary);
226
- font-family: monospace;
334
+ font-size: 13px;
227
335
  font-weight: 500;
336
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
337
+ color: #1e293b;
338
+ letter-spacing: 0.2px;
339
+ user-select: none;
228
340
  }
229
341
 
230
- .shape-border-style-wrapper {
231
- display: flex;
342
+ .color-opacity-input-wrapper {
343
+ display: inline-flex;
232
344
  align-items: center;
233
- gap: 8px;
234
- flex: 1;
235
345
  justify-content: flex-end;
236
- }
237
-
238
- .shape-border-width-wrapper {
239
- display: flex;
240
- align-items: center;
241
- background: #F5F6F7;
242
- border: none;
346
+ height: 24px;
347
+ padding: 0 2px;
243
348
  border-radius: 4px;
244
- padding: 0 8px;
245
- flex: 1;
246
- height: 32px;
247
- box-sizing: border-box;
248
- position: relative;
349
+ transition: all 0.15s ease;
350
+ background: transparent;
351
+ cursor: text;
352
+
353
+ &:hover {
354
+ background: rgba(0, 0, 0, 0.04);
355
+ }
356
+
357
+ &:focus-within {
358
+ background: rgba(37, 99, 235, 0.08);
359
+ }
249
360
  }
250
361
 
251
- .shape-num-field {
362
+ .color-opacity-num-input {
363
+ width: auto;
364
+ min-width: 1ch;
252
365
  border: none;
253
366
  background: transparent;
254
367
  outline: none;
255
- font-size: 12px;
256
- color: var(--text-primary);
257
- width: 100%;
258
- text-align: left;
368
+ font-size: 13px;
369
+ font-weight: 500;
370
+ color: #1e293b;
371
+ text-align: right;
372
+ padding: 0;
373
+ margin: 0;
374
+ font-family: inherit;
375
+ font-variant-numeric: tabular-nums;
376
+ box-sizing: content-box;
259
377
 
260
378
  &::-webkit-outer-spin-button,
261
379
  &::-webkit-inner-spin-button {
262
380
  -webkit-appearance: none;
381
+ display: none !important;
263
382
  margin: 0;
264
383
  }
265
384
  }
266
385
 
267
- .shape-slider-wrapper {
268
- display: flex;
386
+ .percent-unit {
387
+ font-size: 12px;
388
+ font-weight: 500;
389
+ color: #1e293b;
390
+ margin-left: 2px;
391
+ user-select: none;
392
+ line-height: 1;
393
+ }
394
+
395
+ .border-style-width-row {
396
+ display: grid;
397
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
398
+ gap: 8px;
399
+ width: 100%;
269
400
  align-items: center;
270
- gap: 10px;
271
- flex: 1;
272
401
  }
273
402
 
274
- .custom-slider {
275
- --el-slider-height: 4px !important;
276
- --el-slider-button-size: 16px !important;
277
- --el-slider-button-wrapper-offset: -16px !important;
403
+ .border-style-select {
404
+ width: 100%;
405
+ height: 32px !important;
278
406
 
279
- :deep(.show-input) {
280
- margin-right: 16px;
407
+ :deep(.el-select__wrapper),
408
+ :deep(.el-input__wrapper) {
409
+ height: 32px !important;
410
+ min-height: 32px !important;
411
+ max-height: 32px !important;
412
+ line-height: 30px !important;
413
+ background-color: #FAFAFA !important;
414
+ border: 1px solid #edf0f3 !important;
415
+ border-radius: 8px !important;
416
+ box-shadow: none !important;
417
+ padding: 0 10px !important;
418
+ box-sizing: border-box !important;
419
+ display: flex !important;
420
+ align-items: center !important;
421
+ justify-content: space-between !important;
422
+ transition: all 0.15s ease;
281
423
  }
282
424
 
283
- :deep(.el-input-number) {
284
- width: 48px;
285
- height: 30px;
425
+ :deep(.el-select__wrapper:hover),
426
+ :deep(.el-input__wrapper:hover) {
427
+ border-color: #cbd5e1 !important;
428
+ }
286
429
 
287
- .el-input__wrapper {
288
- padding: 4px;
289
- background: #F5F6F7;
290
- border: none;
291
- border-radius: 4px;
292
- box-shadow: none;
293
- }
430
+ :deep(.el-select__wrapper.is-focused),
431
+ :deep(.el-select__wrapper.is-focus),
432
+ :deep(.el-input__wrapper.is-focus) {
433
+ border-color: #2563eb !important;
434
+ box-shadow: 0 0 0 1px #2563eb !important;
435
+ }
294
436
 
295
- .el-input__inner {
296
- text-align: center;
297
- font-size: 12px;
298
- color: var(--text-primary);
299
- }
437
+ :deep(.el-select__prefix),
438
+ :deep(.el-input__prefix) {
439
+ display: flex !important;
440
+ align-items: center !important;
441
+ margin-right: 0 !important;
442
+ flex: 1 !important;
443
+ }
444
+
445
+ :deep(.el-select__selection),
446
+ :deep(.el-select__selected-item),
447
+ :deep(.el-select__placeholder),
448
+ :deep(.el-input__inner) {
449
+ display: none !important;
450
+ }
451
+
452
+ :deep(.el-select__suffix) {
453
+ display: flex !important;
454
+ align-items: center !important;
455
+ color: #64748b !important;
456
+ margin-left: auto !important;
457
+ }
458
+ }
459
+
460
+ .border-style-line-preview {
461
+ width: 48px;
462
+ height: 0;
463
+ border-top: 2px solid #1e293b;
464
+ pointer-events: none;
465
+
466
+ &.dashed {
467
+ border-top: 2px dashed #1e293b;
468
+ }
469
+
470
+ &.dotted {
471
+ border-top: 2px dotted #1e293b;
472
+ }
473
+ }
474
+
475
+ .style-option-line {
476
+ width: 100%;
477
+ height: 2px;
478
+ margin: 8px 0;
479
+
480
+ &.solid-line {
481
+ background: #1e293b;
482
+ }
483
+
484
+ &.dashed-line {
485
+ border-top: 2px dashed #1e293b;
486
+ }
487
+
488
+ &.dotted-line {
489
+ border-top: 2px dotted #1e293b;
300
490
  }
301
491
  }
302
492
 
303
- :deep(.el-switch__core) {
304
- border-radius: 4px !important;
493
+ .border-width-input-pill {
494
+ width: 100%;
495
+ height: 32px;
496
+ background: #FAFAFA;
497
+ border: 1px solid #edf0f3;
498
+ border-radius: 8px;
499
+ padding: 0 10px;
500
+ box-sizing: border-box;
501
+ display: flex;
502
+ align-items: center;
503
+ gap: 6px;
504
+ cursor: text;
505
+ transition: all 0.15s ease;
506
+
507
+ &:hover {
508
+ border-color: #cbd5e1;
509
+ }
510
+
511
+ &:focus-within {
512
+ border-color: #2563eb;
513
+ box-shadow: 0 0 0 1px #2563eb;
514
+ }
305
515
  }
306
516
 
307
- :deep(.el-switch__action) {
308
- border-radius: 3px !important;
517
+ .border-width-icon {
518
+ color: #1e293b;
519
+ display: flex;
520
+ align-items: center;
521
+ flex-shrink: 0;
309
522
  }
310
523
 
311
- :deep(.custom-select .el-input__wrapper) {
312
- background-color: #F5F6F7 !important;
313
- box-shadow: none !important;
314
- border: none !important;
315
- height: 32px !important;
316
- border-radius: 4px !important;
524
+ .border-num-field {
525
+ width: auto;
526
+ min-width: 1ch;
527
+ border: none;
528
+ background: transparent;
529
+ outline: none;
530
+ font-size: 13px;
531
+ font-weight: 500;
532
+ color: #1e293b;
533
+ padding: 0;
534
+ margin: 0;
535
+ font-variant-numeric: tabular-nums;
536
+ box-sizing: content-box;
537
+
538
+ &::-webkit-outer-spin-button,
539
+ &::-webkit-inner-spin-button {
540
+ -webkit-appearance: none;
541
+ display: none !important;
542
+ margin: 0;
543
+ }
317
544
  }
318
545
  </style>