@c2-markdown-ui/react 0.4.4 → 0.4.5

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 (73) hide show
  1. package/README.md +24 -6
  2. package/dist/index.js +4365 -3733
  3. package/package.json +2 -2
  4. package/src/lib/MarkdownUI.tsx +47 -9
  5. package/src/lib/widgets.css +2188 -1372
  6. package/src/widgets/Button.tsx +39 -39
  7. package/src/widgets/ButtonGroup.tsx +47 -47
  8. package/src/widgets/Cascader.tsx +3 -2
  9. package/src/widgets/Chart.tsx +237 -237
  10. package/src/widgets/DatePicker.tsx +451 -434
  11. package/src/widgets/Form.tsx +512 -372
  12. package/src/widgets/Incomplete.tsx +3 -3
  13. package/src/widgets/MultipleChoiceQuestion.tsx +82 -82
  14. package/src/widgets/Quiz.tsx +320 -320
  15. package/src/widgets/Radio.tsx +57 -26
  16. package/src/widgets/Select.tsx +178 -142
  17. package/src/widgets/SelectMulti.tsx +105 -72
  18. package/src/widgets/ShortAnswerQuestion.tsx +101 -101
  19. package/src/widgets/Slider.tsx +70 -56
  20. package/src/widgets/Switch.tsx +14 -2
  21. package/src/widgets/TextInput.tsx +76 -38
  22. package/src/widgets/TreeSelect.tsx +649 -0
  23. package/src/widgets/Widget.tsx +130 -82
  24. package/src/widgets/choiceUtils.ts +90 -45
  25. package/src/widgets/index.ts +17 -16
  26. package/dist/index.d.ts +0 -2
  27. package/dist/index.d.ts.map +0 -1
  28. package/dist/lib/MarkdownUI.d.ts +0 -10
  29. package/dist/lib/MarkdownUI.d.ts.map +0 -1
  30. package/dist/lib/index.d.ts +0 -4
  31. package/dist/lib/index.d.ts.map +0 -1
  32. package/dist/widgets/Button.d.ts +0 -15
  33. package/dist/widgets/Button.d.ts.map +0 -1
  34. package/dist/widgets/ButtonGroup.d.ts +0 -11
  35. package/dist/widgets/ButtonGroup.d.ts.map +0 -1
  36. package/dist/widgets/Cascader.d.ts +0 -34
  37. package/dist/widgets/Cascader.d.ts.map +0 -1
  38. package/dist/widgets/Chart.d.ts +0 -20
  39. package/dist/widgets/Chart.d.ts.map +0 -1
  40. package/dist/widgets/DatePicker.d.ts +0 -28
  41. package/dist/widgets/DatePicker.d.ts.map +0 -1
  42. package/dist/widgets/Form.d.ts +0 -47
  43. package/dist/widgets/Form.d.ts.map +0 -1
  44. package/dist/widgets/Incomplete.d.ts +0 -3
  45. package/dist/widgets/Incomplete.d.ts.map +0 -1
  46. package/dist/widgets/MultipleChoiceQuestion.d.ts +0 -15
  47. package/dist/widgets/MultipleChoiceQuestion.d.ts.map +0 -1
  48. package/dist/widgets/NumberInput.d.ts +0 -26
  49. package/dist/widgets/NumberInput.d.ts.map +0 -1
  50. package/dist/widgets/Quiz.d.ts +0 -37
  51. package/dist/widgets/Quiz.d.ts.map +0 -1
  52. package/dist/widgets/Radio.d.ts +0 -24
  53. package/dist/widgets/Radio.d.ts.map +0 -1
  54. package/dist/widgets/Select.d.ts +0 -15
  55. package/dist/widgets/Select.d.ts.map +0 -1
  56. package/dist/widgets/SelectMulti.d.ts +0 -20
  57. package/dist/widgets/SelectMulti.d.ts.map +0 -1
  58. package/dist/widgets/ShortAnswerQuestion.d.ts +0 -16
  59. package/dist/widgets/ShortAnswerQuestion.d.ts.map +0 -1
  60. package/dist/widgets/Slider.d.ts +0 -13
  61. package/dist/widgets/Slider.d.ts.map +0 -1
  62. package/dist/widgets/Switch.d.ts +0 -17
  63. package/dist/widgets/Switch.d.ts.map +0 -1
  64. package/dist/widgets/TextInput.d.ts +0 -11
  65. package/dist/widgets/TextInput.d.ts.map +0 -1
  66. package/dist/widgets/Widget.d.ts +0 -7
  67. package/dist/widgets/Widget.d.ts.map +0 -1
  68. package/dist/widgets/chartRemoteData.d.ts +0 -18
  69. package/dist/widgets/chartRemoteData.d.ts.map +0 -1
  70. package/dist/widgets/choiceUtils.d.ts +0 -24
  71. package/dist/widgets/choiceUtils.d.ts.map +0 -1
  72. package/dist/widgets/index.d.ts +0 -18
  73. package/dist/widgets/index.d.ts.map +0 -1
@@ -1,1373 +1,2189 @@
1
- /* Markdown UI React Widgets - Optional Styling */
2
- /* Users can import this CSS file to apply consistent styling to all widget components */
3
-
4
- /* Base widget container */
5
- .widget {
6
- margin: 1rem 0;
7
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
8
- line-height: 1.5;
9
- }
10
-
11
- /* Form container */
12
- .widget-form {
13
- display: flex;
14
- flex-direction: column;
15
- gap: 1rem;
16
- padding: 1.5rem;
17
- border: 1px solid #e2e8f0;
18
- border-radius: 8px;
19
- background-color: #ffffff;
20
- box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
21
- }
22
-
23
- .widget-form > button[type="button"]:last-child {
24
- align-self: flex-start;
25
- margin-top: 0.5rem;
26
- padding: 0.75rem 1.5rem;
27
- background-color: #3b82f6;
28
- color: #ffffff;
29
- border: none;
30
- border-radius: 6px;
31
- font-size: 0.875rem;
32
- font-weight: 500;
33
- cursor: pointer;
34
- transition: background-color 0.2s ease;
35
- }
36
-
37
- /* Form actions(提交/取消/清空按钮组,data-align 控制对齐) */
38
- .widget-form-actions {
39
- display: flex;
40
- gap: 0.5rem;
41
- margin-top: 0.5rem;
42
- }
43
-
44
- .widget-form-actions[data-align="left"] { justify-content: flex-start; }
45
- .widget-form-actions[data-align="center"] { justify-content: center; }
46
- .widget-form-actions[data-align="right"] { justify-content: flex-end; }
47
-
48
- .widget-form-actions button[type="button"] {
49
- padding: 0.75rem 1.5rem;
50
- border-radius: 6px;
51
- font-size: 0.875rem;
52
- font-weight: 500;
53
- cursor: pointer;
54
- transition: background-color 0.2s ease;
55
- }
56
-
57
- .widget-form-actions .widget-form-submit {
58
- border: none;
59
- background-color: #3b82f6;
60
- color: #ffffff;
61
- }
62
-
63
- .widget-form-actions .widget-form-submit:hover {
64
- background-color: #2563eb;
65
- }
66
-
67
- .widget-form-actions .widget-form-cancel,
68
- .widget-form-actions .widget-form-reset {
69
- background-color: #ffffff;
70
- color: #374151;
71
- border: 1px solid #d1d5db;
72
- }
73
-
74
- .widget-form-actions .widget-form-cancel:hover,
75
- .widget-form-actions .widget-form-reset:hover {
76
- background-color: #f9fafb;
77
- border-color: #9ca3af;
78
- }
79
-
80
- .widget-form-actions button[type="button"]:focus {
81
- outline: none;
82
- box-shadow: 0 0 0 2px #3b82f6;
83
- }
84
-
85
- /* Button Group */
86
-
87
- /* 单个按钮组件(大/中/小三档尺寸,背景色完全由 color 属性的内联 style 控制) */
88
- .widget-button {
89
- display: inline-flex;
90
- align-items: center;
91
- justify-content: center;
92
- border: none;
93
- border-radius: 6px;
94
- font-weight: 500;
95
- cursor: pointer;
96
- transition: filter 0.2s ease;
97
- }
98
-
99
- .widget-button:hover { filter: brightness(0.9); }
100
- .widget-button:focus { outline: none; box-shadow: 0 0 0 2px #3b82f6; }
101
-
102
- .widget-button.size-small { padding: 0.25rem 0.75rem; font-size: 0.75rem; }
103
- .widget-button.size-medium { padding: 0.5rem 1.25rem; font-size: 0.875rem; }
104
- .widget-button.size-large { padding: 0.75rem 1.75rem; font-size: 1rem; }
105
- .widget-button-group {
106
- display: flex;
107
- flex-direction: column;
108
- gap: 0.5rem;
109
- }
110
-
111
- .widget-button-group label {
112
- font-weight: 500;
113
- color: #374151;
114
- margin-bottom: 0.25rem;
115
- }
116
-
117
- .widget-button-group div[role="group"] {
118
- display: flex;
119
- gap: 0.25rem;
120
- flex-wrap: wrap;
121
- }
122
-
123
- .widget-form .widget-button-group button,
124
- .widget-button-group button {
125
- padding: 0.5rem 1rem;
126
- border: 1px solid #d1d5db;
127
- background-color: #ffffff;
128
- color: #374151;
129
- border-radius: 6px;
130
- cursor: pointer;
131
- transition: all 0.2s ease;
132
- font-size: 0.875rem;
133
- font-weight: 500;
134
- }
135
-
136
- .widget-form .widget-button-group button:hover,
137
- .widget-button-group button:hover {
138
- background-color: #f9fafb;
139
- border-color: #9ca3af;
140
- }
141
-
142
- .widget-form .widget-button-group button[aria-pressed="true"],
143
- .widget-button-group button[aria-pressed="true"] {
144
- background-color: #3b82f6;
145
- color: #ffffff;
146
- border-color: #3b82f6;
147
- }
148
-
149
- .widget-form .widget-button-group button:focus,
150
- .widget-button-group button:focus {
151
- outline: none;
152
- box-shadow: 0 0 0 2px #3b82f6;
153
- }
154
-
155
- /* Text Input */
156
- .widget-text-input {
157
- display: flex;
158
- flex-direction: column;
159
- gap: 0.5rem;
160
- }
161
-
162
- .widget-text-input label {
163
- font-weight: 500;
164
- color: #374151;
165
- }
166
-
167
- .widget-text-input input[type="text"] {
168
- padding: 0.75rem;
169
- border: 1px solid #d1d5db;
170
- border-radius: 6px;
171
- font-size: 0.875rem;
172
- background-color: #ffffff;
173
- transition: border-color 0.2s ease, box-shadow 0.2s ease;
174
- }
175
-
176
- .widget-text-input input[type="text"]:focus {
177
- outline: none;
178
- border-color: #3b82f6;
179
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
180
- }
181
-
182
- .widget-text-input input[type="text"]::placeholder {
183
- color: #9ca3af;
184
- }
185
-
186
- /* Select and Select Multi */
187
- .selector,
188
- .selector-multi {
189
- display: flex;
190
- flex-direction: column;
191
- gap: 0.5rem;
192
- }
193
-
194
- .selector label,
195
- .selector-multi-label {
196
- font-weight: 500;
197
- color: #374151;
198
- }
199
-
200
- .selector select {
201
- padding: 0.75rem;
202
- border: 1px solid #d1d5db;
203
- border-radius: 6px;
204
- font-size: 0.875rem;
205
- background-color: #ffffff;
206
- cursor: pointer;
207
- transition: border-color 0.2s ease, box-shadow 0.2s ease;
208
- }
209
-
210
- .selector select:focus {
211
- outline: none;
212
- border-color: #3b82f6;
213
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
214
- }
215
-
216
- .selector option {
217
- padding: 0.5rem;
218
- }
219
-
220
- /* Checkbox-based Multi Select */
221
- .checkbox-group {
222
- display: flex;
223
- flex-direction: column;
224
- gap: 0.5rem;
225
- padding: 0.75rem;
226
- border: 1px solid #d1d5db;
227
- border-radius: 6px;
228
- background-color: #ffffff;
229
- max-height: 200px;
230
- overflow-y: auto;
231
- }
232
-
233
- /* 选项布局:横向(flex-wrap 换行);自定义列数(grid,列宽由 inline style 注入) */
234
- .checkbox-group[data-direction="horizontal"] {
235
- flex-direction: row;
236
- flex-wrap: wrap;
237
- gap: 0.5rem 1.5rem;
238
- }
239
-
240
- .checkbox-group[data-direction="grid"] {
241
- display: grid;
242
- gap: 0.5rem;
243
- }
244
-
245
- .checkbox-item {
246
- display: flex;
247
- align-items: center;
248
- gap: 0.5rem;
249
- cursor: pointer;
250
- padding: 0.25rem 0;
251
- font-weight: normal;
252
- }
253
-
254
- .checkbox-item input[type="checkbox"] {
255
- margin: 0;
256
- cursor: pointer;
257
- }
258
-
259
- .checkbox-item span {
260
- font-size: 0.875rem;
261
- color: #374151;
262
- }
263
-
264
- /* --- 单选 RadioGroup:圆点单选(antd Radio 默认样式) --- */
265
- .radio-group {
266
- display: flex;
267
- flex-direction: column;
268
- gap: 0.5rem;
269
- padding: 0.75rem;
270
- border: 1px solid #d1d5db;
271
- border-radius: 6px;
272
- background-color: #ffffff;
273
- }
274
-
275
- /* 选项布局:横向(flex-wrap 换行);自定义列数(grid,列宽由 inline style 注入) */
276
- .radio-group[data-direction="horizontal"] {
277
- flex-direction: row;
278
- flex-wrap: wrap;
279
- gap: 0.5rem 1.5rem;
280
- }
281
-
282
- .radio-group[data-direction="grid"] {
283
- display: grid;
284
- gap: 0.5rem;
285
- }
286
-
287
- .radio-item {
288
- display: flex;
289
- align-items: center;
290
- gap: 0.5rem;
291
- cursor: pointer;
292
- padding: 0.25rem 0;
293
- font-weight: normal;
294
- }
295
-
296
- .radio-item input[type="radio"] {
297
- margin: 0;
298
- cursor: pointer;
299
- accent-color: #3b82f6;
300
- }
301
-
302
- .radio-item span {
303
- font-size: 0.875rem;
304
- color: #374151;
305
- }
306
-
307
- .radio-item:hover {
308
- background-color: #f9fafb;
309
- border-radius: 4px;
310
- margin: -0.25rem 0;
311
- padding: 0.5rem 0.25rem;
312
- }
313
-
314
- /* --- 单选 RadioGroup:按钮组样式(antd Radio optionType:button) --- */
315
- .radio-button-group {
316
- display: flex;
317
- gap: 0.25rem;
318
- flex-wrap: wrap;
319
- }
320
-
321
- .radio-button-group[data-direction="vertical"] {
322
- flex-direction: column;
323
- flex-wrap: nowrap;
324
- }
325
-
326
- .radio-button-group[data-direction="grid"] {
327
- display: grid;
328
- gap: 0.5rem;
329
- }
330
-
331
- .checkbox-item:hover {
332
- background-color: #f9fafb;
333
- border-radius: 4px;
334
- margin: -0.25rem 0;
335
- padding: 0.5rem 0.25rem;
336
- }
337
-
338
- /* Slider */
339
- .widget-slider {
340
- display: flex;
341
- flex-direction: column;
342
- gap: 0.5rem;
343
- }
344
-
345
- .widget-slider label {
346
- font-weight: 500;
347
- color: #374151;
348
- }
349
-
350
- .slider-container {
351
- display: flex;
352
- flex-direction: column;
353
- gap: 0.25rem;
354
- }
355
-
356
- .slider-values {
357
- display: flex;
358
- justify-content: space-between;
359
- align-items: center;
360
- font-size: 0.75rem;
361
- color: #6b7280;
362
- margin-bottom: 0.25rem;
363
- }
364
-
365
- .current-value {
366
- font-weight: 600;
367
- color: #3b82f6;
368
- background: #eff6ff;
369
- padding: 0.25rem 0.5rem;
370
- border-radius: 4px;
371
- min-width: 2rem;
372
- text-align: center;
373
- }
374
-
375
- .min-value, .max-value {
376
- font-weight: 500;
377
- }
378
-
379
- .widget-slider input[type="range"] {
380
- width: 100%;
381
- height: 6px;
382
- border-radius: 3px;
383
- background: #e2e8f0;
384
- outline: none;
385
- cursor: pointer;
386
- }
387
-
388
- .widget-slider input[type="range"]::-webkit-slider-thumb {
389
- appearance: none;
390
- width: 20px;
391
- height: 20px;
392
- border-radius: 50%;
393
- background: #3b82f6;
394
- cursor: pointer;
395
- transition: background-color 0.2s ease;
396
- }
397
-
398
- .widget-slider input[type="range"]::-webkit-slider-thumb:hover {
399
- background: #2563eb;
400
- }
401
-
402
- .widget-slider input[type="range"]::-moz-range-thumb {
403
- width: 20px;
404
- height: 20px;
405
- border-radius: 50%;
406
- background: #3b82f6;
407
- cursor: pointer;
408
- border: none;
409
- transition: background-color 0.2s ease;
410
- }
411
-
412
- .widget-slider input[type="range"]::-moz-range-thumb:hover {
413
- background: #2563eb;
414
- }
415
-
416
- /* Switch(参考 antd Switch) */
417
- .widget-switch {
418
- display: flex;
419
- flex-direction: column;
420
- gap: 0.5rem;
421
- }
422
-
423
- .widget-switch > label {
424
- font-weight: 500;
425
- color: #374151;
426
- }
427
-
428
- .switch-track {
429
- position: relative;
430
- display: inline-flex;
431
- align-items: center;
432
- box-sizing: content-box;
433
- width: 44px;
434
- height: 22px;
435
- padding: 0;
436
- border: none;
437
- border-radius: 11px;
438
- background-color: rgba(0, 0, 0, 0.25);
439
- cursor: pointer;
440
- transition: background-color 0.2s ease;
441
- flex-shrink: 0;
442
- }
443
-
444
- .switch-track[data-checked="true"] {
445
- background-color: #3b82f6;
446
- }
447
-
448
- .switch-track:hover:not(:disabled) {
449
- background-color: rgba(0, 0, 0, 0.35);
450
- }
451
-
452
- .switch-track[data-checked="true"]:hover:not(:disabled) {
453
- background-color: #2563eb;
454
- }
455
-
456
- .switch-track .switch-thumb {
457
- display: block;
458
- width: 18px;
459
- height: 18px;
460
- margin: 2px;
461
- border-radius: 50%;
462
- background-color: #ffffff;
463
- box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
464
- transition: transform 0.2s ease;
465
- }
466
-
467
- .switch-track[data-checked="true"] .switch-thumb {
468
- transform: translateX(22px);
469
- }
470
-
471
- .switch-track .switch-text {
472
- position: absolute;
473
- top: 50%;
474
- transform: translateY(-50%);
475
- font-size: 0.75rem;
476
- font-weight: 500;
477
- color: #ffffff;
478
- line-height: 1;
479
- user-select: none;
480
- }
481
-
482
- /* 文案位置与 antd 一致:选中后滑块移至右侧,选中文案露在左侧;未选中时滑块在左,未选中文案露在右侧 */
483
- .switch-track .switch-text-unchecked {
484
- right: 6px;
485
- }
486
-
487
- .switch-track .switch-text-checked {
488
- left: 6px;
489
- }
490
-
491
- /* 仅显示当前状态对应的文案 */
492
- .switch-track[data-checked="true"] .switch-text-unchecked {
493
- display: none;
494
- }
495
-
496
- .switch-track[data-checked="false"] .switch-text-checked {
497
- display: none;
498
- }
499
-
500
- .switch-track:disabled {
501
- cursor: not-allowed;
502
- opacity: 0.5;
503
- }
504
-
505
- .switch-track:focus-visible {
506
- outline: none;
507
- box-shadow: 0 0 0 2px #3b82f6;
508
- }
509
-
510
- /* Form submit button styling - hover and focus states */
511
- .widget-form > button[type="button"]:last-child:hover {
512
- background-color: #2563eb;
513
- }
514
-
515
- .widget-form > button[type="button"]:last-child:focus {
516
- outline: none;
517
- box-shadow: 0 0 0 2px #3b82f6;
518
- }
519
-
520
- /* Form row grid layout (24-column grid, similar to antd Row/Col) */
521
- .widget-form-row {
522
- display: grid;
523
- grid-template-columns: repeat(24, minmax(0, 1fr));
524
- column-gap: var(--row-gutter, 1rem);
525
- }
526
-
527
- .widget-form-row .widget-form-field {
528
- min-width: 0;
529
- }
530
-
531
- /* 传统 fields 模式 + 显式 span:切换为 24 栅格(无 span 字段占满整行) */
532
- .widget-form.widget-form-fields-grid {
533
- display: grid;
534
- grid-template-columns: repeat(24, minmax(0, 1fr));
535
- column-gap: 1rem;
536
- row-gap: 1rem;
537
- align-items: start;
538
- }
539
-
540
- .widget-form-fields-grid .widget-form-field {
541
- min-width: 0;
542
- }
543
-
544
- .widget-form-fields-grid .widget-form-field[data-field-type="button"] {
545
- width: max-content;
546
- max-width: 100%;
547
- align-self: end;
548
- padding-bottom: 0;
549
- }
550
-
551
- .widget-form-fields-grid .widget-form-actions {
552
- grid-column: 1 / -1;
553
- }
554
-
555
- /* inline 模式 + 显式 span 覆盖 flex-basis 后,收回默认 flex-grow */
556
- .widget-form-inline .widget-form-field[style*="flex: 0 1"] {
557
- flex-grow: 0;
558
- }
559
-
560
- /* Error styling for unknown widgets */
561
- .widget span[style*="color:red"] {
562
- color: #ef4444 !important;
563
- font-weight: 500;
564
- padding: 0.75rem;
565
- background-color: #fef2f2;
566
- border: 1px solid #fecaca;
567
- border-radius: 6px;
568
- display: inline-block;
569
- }
570
-
571
- /* Multiple Choice Question */
572
- .widget-mcq {
573
- display: flex;
574
- flex-direction: column;
575
- gap: 1rem;
576
- padding: 1.5rem;
577
- border: 1px solid #e2e8f0;
578
- border-radius: 8px;
579
- background-color: #ffffff;
580
- }
581
-
582
- .mcq-question {
583
- font-weight: 600;
584
- font-size: 1.1rem;
585
- color: #1f2937;
586
- margin-bottom: 0.5rem;
587
- }
588
-
589
- .mcq-choices {
590
- display: flex;
591
- flex-direction: column;
592
- gap: 0.75rem;
593
- }
594
-
595
- .mcq-choice {
596
- padding: 1rem;
597
- border: 2px solid #e5e7eb;
598
- border-radius: 8px;
599
- background-color: #ffffff;
600
- text-align: left;
601
- cursor: pointer;
602
- transition: all 0.2s ease;
603
- font-size: 0.9rem;
604
- }
605
-
606
- .mcq-choice:hover:not(:disabled) {
607
- border-color: #9ca3af;
608
- background-color: #f9fafb;
609
- }
610
-
611
- .mcq-choice-selected {
612
- border-color: #3b82f6;
613
- background-color: #eff6ff;
614
- }
615
-
616
- .mcq-choice-correct {
617
- border-color: #10b981;
618
- background-color: #ecfdf5;
619
- color: #065f46;
620
- }
621
-
622
- .mcq-choice-incorrect {
623
- border-color: #ef4444;
624
- background-color: #fef2f2;
625
- color: #991b1b;
626
- }
627
-
628
- .mcq-choice:disabled {
629
- cursor: not-allowed;
630
- opacity: 0.8;
631
- }
632
-
633
- .mcq-feedback {
634
- padding: 0.75rem;
635
- border-radius: 6px;
636
- font-weight: 500;
637
- font-size: 0.9rem;
638
- }
639
-
640
- .mcq-feedback.correct {
641
- background-color: #ecfdf5;
642
- color: #065f46;
643
- border: 1px solid #a7f3d0;
644
- }
645
-
646
- .mcq-feedback.incorrect {
647
- background-color: #fef2f2;
648
- color: #991b1b;
649
- border: 1px solid #fecaca;
650
- }
651
-
652
- /* Short Answer Question */
653
- .widget-saq {
654
- display: flex;
655
- flex-direction: column;
656
- gap: 1rem;
657
- padding: 1.5rem;
658
- border: 1px solid #e2e8f0;
659
- border-radius: 8px;
660
- background-color: #ffffff;
661
- }
662
-
663
- .saq-question {
664
- font-weight: 600;
665
- font-size: 1.1rem;
666
- color: #1f2937;
667
- margin-bottom: 0.5rem;
668
- }
669
-
670
- .saq-input-container {
671
- display: flex;
672
- gap: 0.75rem;
673
- align-items: stretch;
674
- }
675
-
676
- .saq-input {
677
- flex: 1;
678
- padding: 0.75rem;
679
- border: 2px solid #e5e7eb;
680
- border-radius: 6px;
681
- font-size: 0.9rem;
682
- background-color: #ffffff;
683
- transition: border-color 0.2s ease, box-shadow 0.2s ease;
684
- }
685
-
686
- .saq-input:focus {
687
- outline: none;
688
- border-color: #3b82f6;
689
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
690
- }
691
-
692
- .saq-input-correct {
693
- border-color: #10b981;
694
- background-color: #ecfdf5;
695
- }
696
-
697
- .saq-input-incorrect {
698
- border-color: #ef4444;
699
- background-color: #fef2f2;
700
- }
701
-
702
- .saq-submit {
703
- padding: 0.75rem 1.25rem;
704
- background-color: #3b82f6;
705
- color: #ffffff;
706
- border: none;
707
- border-radius: 6px;
708
- font-size: 0.875rem;
709
- font-weight: 500;
710
- cursor: pointer;
711
- transition: background-color 0.2s ease;
712
- white-space: nowrap;
713
- }
714
-
715
- .saq-submit:hover:not(:disabled) {
716
- background-color: #2563eb;
717
- }
718
-
719
- .saq-submit:disabled {
720
- background-color: #f5f5f5;
721
- color: rgba(0, 0, 0, 0.4);
722
- cursor: not-allowed;
723
- }
724
-
725
- .saq-feedback {
726
- padding: 0.75rem;
727
- border-radius: 6px;
728
- font-weight: 500;
729
- font-size: 0.9rem;
730
- }
731
-
732
- .saq-feedback.correct {
733
- background-color: #ecfdf5;
734
- color: #065f46;
735
- border: 1px solid #a7f3d0;
736
- }
737
-
738
- .saq-feedback.incorrect {
739
- background-color: #fef2f2;
740
- color: #991b1b;
741
- border: 1px solid #fecaca;
742
- }
743
-
744
- /* Responsive design */
745
- @media (max-width: 640px) {
746
- .widget-button-group div[role="group"] {
747
- flex-direction: column;
748
- }
749
-
750
- .widget-button-group button {
751
- width: 100%;
752
- }
753
-
754
- .widget-form {
755
- padding: 1rem;
756
- }
757
-
758
- .saq-input-container {
759
- flex-direction: column;
760
- }
761
-
762
- .widget-mcq,
763
- .widget-saq,
764
- .widget-quiz {
765
- padding: 1rem;
766
- }
767
- }
768
-
769
- /* Quiz Component */
770
- .widget-quiz {
771
- max-width: 800px;
772
- margin: 0 auto;
773
- background: #ffffff;
774
- border: 1px solid #e2e8f0;
775
- border-radius: 12px;
776
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
777
- }
778
-
779
- .quiz-header {
780
- padding: 2rem 2rem 1rem;
781
- border-bottom: 1px solid #e2e8f0;
782
- background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
783
- color: white;
784
- border-radius: 12px 12px 0 0;
785
- }
786
-
787
- .quiz-title {
788
- font-size: 1.5rem;
789
- font-weight: 700;
790
- margin: 0 0 1rem 0;
791
- text-align: center;
792
- color: white;
793
- }
794
-
795
- .quiz-stats {
796
- display: flex;
797
- justify-content: space-between;
798
- align-items: center;
799
- gap: 2rem;
800
- flex-wrap: wrap;
801
- color: white;
802
- }
803
-
804
- .quiz-progress {
805
- flex: 1;
806
- min-width: 200px;
807
- }
808
-
809
- .quiz-progress-text {
810
- font-size: 0.9rem;
811
- font-weight: 500;
812
- margin-bottom: 0.5rem;
813
- display: block;
814
- color: white;
815
- }
816
-
817
- .quiz-progress-bar {
818
- width: 100%;
819
- height: 8px;
820
- background: rgba(255, 255, 255, 0.2);
821
- border-radius: 4px;
822
- overflow: hidden;
823
- }
824
-
825
- .quiz-progress-fill {
826
- height: 100%;
827
- background: linear-gradient(90deg, #10b981, #34d399);
828
- border-radius: 4px;
829
- transition: width 0.3s ease;
830
- }
831
-
832
- .quiz-score {
833
- text-align: right;
834
- }
835
-
836
- .quiz-score-text {
837
- font-size: 1.1rem;
838
- font-weight: 600;
839
- color: white;
840
- }
841
-
842
- .quiz-questions {
843
- padding: 1.5rem;
844
- }
845
-
846
- .quiz-question {
847
- margin-bottom: 2rem;
848
- padding: 1.5rem;
849
- border: 2px solid #f1f5f9;
850
- border-radius: 8px;
851
- background: #fafbfc;
852
- transition: all 0.2s ease;
853
- }
854
-
855
- .quiz-question:hover {
856
- border-color: #e2e8f0;
857
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
858
- }
859
-
860
- .quiz-question-header {
861
- display: flex;
862
- justify-content: space-between;
863
- align-items: flex-start;
864
- margin-bottom: 1rem;
865
- gap: 1rem;
866
- }
867
-
868
- .quiz-question-text {
869
- font-size: 1.1rem;
870
- font-weight: 600;
871
- color: #1f2937;
872
- margin: 0;
873
- flex: 1;
874
- }
875
-
876
- .quiz-question-points {
877
- background: #3b82f6;
878
- color: white;
879
- padding: 0.25rem 0.75rem;
880
- border-radius: 12px;
881
- font-size: 0.8rem;
882
- font-weight: 600;
883
- white-space: nowrap;
884
- }
885
-
886
- .quiz-choices {
887
- display: flex;
888
- flex-direction: column;
889
- gap: 0.75rem;
890
- }
891
-
892
- .quiz-choice {
893
- padding: 1rem 1.25rem;
894
- border: 2px solid #e5e7eb;
895
- border-radius: 8px;
896
- background: #ffffff;
897
- text-align: left;
898
- cursor: pointer;
899
- transition: all 0.2s ease;
900
- font-size: 0.95rem;
901
- font-weight: 500;
902
- }
903
-
904
- .quiz-choice:hover:not(:disabled) {
905
- border-color: #3b82f6;
906
- background: #eff6ff;
907
- transform: translateY(-1px);
908
- }
909
-
910
- .quiz-choice-selected {
911
- border-color: #3b82f6;
912
- background: #eff6ff;
913
- }
914
-
915
- .quiz-choice-correct {
916
- border-color: #10b981;
917
- background: #ecfdf5;
918
- color: #065f46;
919
- }
920
-
921
- .quiz-choice-incorrect {
922
- border-color: #ef4444;
923
- background: #fef2f2;
924
- color: #991b1b;
925
- }
926
-
927
- .quiz-choice:disabled {
928
- cursor: not-allowed;
929
- opacity: 0.9;
930
- }
931
-
932
- .quiz-input-container {
933
- display: flex;
934
- gap: 0.75rem;
935
- align-items: stretch;
936
- }
937
-
938
- .quiz-input {
939
- flex: 1;
940
- padding: 0.75rem 1rem;
941
- border: 2px solid #e5e7eb;
942
- border-radius: 6px;
943
- font-size: 0.95rem;
944
- background: #ffffff;
945
- transition: border-color 0.2s ease, box-shadow 0.2s ease;
946
- }
947
-
948
- .quiz-input:focus {
949
- outline: none;
950
- border-color: #3b82f6;
951
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
952
- }
953
-
954
- .quiz-input-correct {
955
- border-color: #10b981;
956
- background: #ecfdf5;
957
- }
958
-
959
- .quiz-input-incorrect {
960
- border-color: #ef4444;
961
- background: #fef2f2;
962
- }
963
-
964
- .quiz-submit {
965
- padding: 0.75rem 1.5rem;
966
- background: #3b82f6;
967
- color: white;
968
- border: none;
969
- border-radius: 6px;
970
- font-size: 0.875rem;
971
- font-weight: 600;
972
- cursor: pointer;
973
- transition: background-color 0.2s ease;
974
- white-space: nowrap;
975
- }
976
-
977
- .quiz-submit:hover:not(:disabled) {
978
- background: #2563eb;
979
- }
980
-
981
- .quiz-submit:disabled {
982
- background-color: #f5f5f5;
983
- color: rgba(0, 0, 0, 0.4);
984
- cursor: not-allowed;
985
- }
986
-
987
- .quiz-feedback {
988
- margin-top: 1rem;
989
- padding: 1rem;
990
- border-radius: 6px;
991
- font-weight: 600;
992
- font-size: 0.95rem;
993
- }
994
-
995
- .quiz-feedback.correct {
996
- background: #ecfdf5;
997
- color: #065f46;
998
- border: 1px solid #a7f3d0;
999
- }
1000
-
1001
- .quiz-feedback.incorrect {
1002
- background: #fef2f2;
1003
- color: #991b1b;
1004
- border: 1px solid #fecaca;
1005
- }
1006
-
1007
- .quiz-summary {
1008
- margin-top: 2rem;
1009
- padding: 2rem;
1010
- background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
1011
- border-radius: 8px;
1012
- text-align: center;
1013
- border: 2px solid #e2e8f0;
1014
- }
1015
-
1016
- .quiz-summary h3 {
1017
- font-size: 1.5rem;
1018
- font-weight: 700;
1019
- color: #1f2937;
1020
- margin: 0 0 1rem 0;
1021
- }
1022
-
1023
- .quiz-final-score {
1024
- font-size: 1.2rem;
1025
- font-weight: 600;
1026
- color: #374151;
1027
- margin-bottom: 1rem;
1028
- }
1029
-
1030
- .quiz-result {
1031
- font-size: 1.1rem;
1032
- font-weight: 700;
1033
- padding: 0.75rem 1.5rem;
1034
- border-radius: 6px;
1035
- display: inline-block;
1036
- }
1037
-
1038
- .quiz-result.passed {
1039
- background: #ecfdf5;
1040
- color: #065f46;
1041
- border: 1px solid #a7f3d0;
1042
- }
1043
-
1044
- .quiz-result.failed {
1045
- background: #fef2f2;
1046
- color: #991b1b;
1047
- border: 1px solid #fecaca;
1048
- }
1049
-
1050
- /* ============================================================ */
1051
- /* === Disabled 状态统一置灰样式(所有交互组件 disabled 后视觉反馈) === */
1052
- /* ============================================================ */
1053
-
1054
- /* --- 单按钮组件 Button:含内联 color 时仅置灰文字 --- */
1055
- .widget-button:disabled {
1056
- background-color: #f5f5f5 !important;
1057
- color: rgba(0, 0, 0, 0.4) !important;
1058
- cursor: not-allowed;
1059
- filter: none;
1060
- }
1061
- .widget-button:disabled:hover { filter: none; }
1062
-
1063
- /* --- 按钮组 ButtonGroup --- */
1064
- .widget-form .widget-button-group button:disabled,
1065
- .widget-button-group button:disabled {
1066
- background-color: #f5f5f5;
1067
- color: rgba(0, 0, 0, 0.4);
1068
- border-color: #e5e7eb;
1069
- cursor: not-allowed;
1070
- opacity: 1;
1071
- }
1072
- /* 选中态按钮禁用后保持浅蓝底可辨识 */
1073
- .widget-form .widget-button-group button[aria-pressed="true"]:disabled,
1074
- .widget-button-group button[aria-pressed="true"]:disabled {
1075
- background-color: #93c5fd;
1076
- border-color: #93c5fd;
1077
- color: rgba(255, 255, 255, 0.8);
1078
- cursor: not-allowed;
1079
- }
1080
-
1081
- /* --- 文本输入 TextInput --- */
1082
- .widget-text-input input[type="text"]:disabled {
1083
- background-color: #f5f5f5;
1084
- color: rgba(0, 0, 0, 0.4);
1085
- border-color: #e5e7eb;
1086
- cursor: not-allowed;
1087
- }
1088
-
1089
- /* --- 数字输入 NumberInput --- */
1090
- .ni-wrap input:disabled {
1091
- background-color: #f5f5f5;
1092
- color: rgba(0, 0, 0, 0.4);
1093
- border-color: #e5e7eb;
1094
- cursor: not-allowed;
1095
- }
1096
- .ni-steps button:disabled {
1097
- color: #d1d5db;
1098
- cursor: not-allowed;
1099
- }
1100
-
1101
- /* --- 滑块 Slider:轨道变浅 + 拇指置灰 --- */
1102
- .widget-slider input[type="range"]:disabled {
1103
- background: #f0f0f0;
1104
- cursor: not-allowed;
1105
- }
1106
- .widget-slider input[type="range"]:disabled::-webkit-slider-thumb {
1107
- background: #d1d5db;
1108
- cursor: not-allowed;
1109
- }
1110
- .widget-slider input[type="range"]:disabled::-moz-range-thumb {
1111
- background: #d1d5db;
1112
- cursor: not-allowed;
1113
- }
1114
- .widget-slider input[type="range"]:disabled::-webkit-slider-thumb:hover {
1115
- background: #d1d5db;
1116
- }
1117
- .widget-slider input[type="range"]:disabled::-moz-range-thumb:hover {
1118
- background: #d1d5db;
1119
- }
1120
- /* 数字值徽标同步置灰 */
1121
- .widget-slider:has(input:disabled) .current-value {
1122
- color: rgba(0, 0, 0, 0.4);
1123
- background: #f5f5f5;
1124
- }
1125
-
1126
- /* --- 下拉选择 Select --- */
1127
- .selector select:disabled {
1128
- background-color: #f5f5f5;
1129
- color: rgba(0, 0, 0, 0.4);
1130
- border-color: #e5e7eb;
1131
- cursor: not-allowed;
1132
- }
1133
-
1134
- /* --- 多选 SelectMulti:checkbox 与文字置灰 --- */
1135
- .checkbox-group:has(input:disabled) {
1136
- background-color: #f5f5f5;
1137
- border-color: #e5e7eb;
1138
- }
1139
- .checkbox-group:has(input:disabled) .checkbox-item {
1140
- cursor: not-allowed;
1141
- }
1142
- .checkbox-group:has(input:disabled) .checkbox-item:hover {
1143
- background-color: transparent;
1144
- }
1145
- .checkbox-group:has(input:disabled) .checkbox-item span {
1146
- color: rgba(0, 0, 0, 0.4);
1147
- }
1148
-
1149
- /* --- 单选 RadioGroup:圆点与文字置灰 --- */
1150
- .radio-group:has(input:disabled) {
1151
- background-color: #f5f5f5;
1152
- border-color: #e5e7eb;
1153
- }
1154
- .radio-group:has(input:disabled) .radio-item {
1155
- cursor: not-allowed;
1156
- }
1157
- .radio-group:has(input:disabled) .radio-item:hover {
1158
- background-color: transparent;
1159
- }
1160
- .radio-group:has(input:disabled) .radio-item span {
1161
- color: rgba(0, 0, 0, 0.4);
1162
- }
1163
-
1164
- /* --- Form 提交/重置/取消按钮 --- */
1165
- .widget-form-actions button[type="button"]:disabled {
1166
- background-color: #f5f5f5;
1167
- color: rgba(0, 0, 0, 0.4);
1168
- border-color: #e5e7eb;
1169
- cursor: not-allowed;
1170
- box-shadow: none;
1171
- }
1172
- /* 主按钮禁用保持淡蓝底区分 */
1173
- .widget-form-actions .widget-form-submit:disabled {
1174
- background-color: #93c5fd;
1175
- color: rgba(255, 255, 255, 0.8);
1176
- }
1177
- .widget-form-actions button[type="button"]:disabled:hover {
1178
- background-color: #f5f5f5;
1179
- border-color: #e5e7eb;
1180
- }
1181
- .widget-form-actions .widget-form-submit:disabled:hover {
1182
- background-color: #93c5fd;
1183
- }
1184
-
1185
- /* 传统模式(无 actions 容器)的提交按钮 */
1186
- .widget-form > button[type="button"]:last-child:disabled {
1187
- background-color: #93c5fd;
1188
- color: rgba(255, 255, 255, 0.8);
1189
- cursor: not-allowed;
1190
- }
1191
- .widget-form > button[type="button"]:last-child:disabled:hover {
1192
- background-color: #93c5fd;
1193
- }
1194
-
1195
- /* --- 选择题 MCQ 选项(反馈态对/错优先于置灰) --- */
1196
- .mcq-choice:disabled {
1197
- cursor: not-allowed;
1198
- opacity: 1;
1199
- }
1200
- .mcq-choice:disabled:not(.mcq-choice-correct):not(.mcq-choice-incorrect):not(.mcq-choice-selected) {
1201
- background-color: #f5f5f5;
1202
- color: rgba(0, 0, 0, 0.4);
1203
- border-color: #e5e7eb;
1204
- }
1205
-
1206
- /* --- 简答题 SAQ 输入框 --- */
1207
- .saq-input:disabled {
1208
- background-color: #f5f5f5;
1209
- color: rgba(0, 0, 0, 0.4);
1210
- border-color: #e5e7eb;
1211
- cursor: not-allowed;
1212
- }
1213
-
1214
- /* --- Quiz 内题目选项与输入 --- */
1215
- .quiz-choice:disabled {
1216
- cursor: not-allowed;
1217
- opacity: 1;
1218
- }
1219
- .quiz-choice:disabled:not(.quiz-choice-correct):not(.quiz-choice-incorrect):not(.quiz-choice-selected) {
1220
- background-color: #f5f5f5;
1221
- color: rgba(0, 0, 0, 0.4);
1222
- border-color: #e5e7eb;
1223
- }
1224
- .quiz-input:disabled {
1225
- background-color: #f5f5f5;
1226
- color: rgba(0, 0, 0, 0.4);
1227
- border-color: #e5e7eb;
1228
- cursor: not-allowed;
1229
- }
1230
-
1231
- /* --- DatePicker 输入按钮 --- */
1232
- .dp-input:disabled {
1233
- background-color: #f5f5f5;
1234
- color: rgba(0, 0, 0, 0.4);
1235
- border-color: #e5e7eb;
1236
- cursor: not-allowed;
1237
- }
1238
- .dp-input:disabled:hover {
1239
- border-color: #e5e7eb;
1240
- }
1241
-
1242
- /* --- Cascader 级联选择器 --- */
1243
- .widget-cascader {
1244
- position: relative;
1245
- }
1246
-
1247
- .cas-input {
1248
- display: flex;
1249
- align-items: center;
1250
- gap: 0.375rem;
1251
- width: 100%;
1252
- padding: 0.625rem 0.75rem;
1253
- border: 1px solid #d1d5db;
1254
- border-radius: 6px;
1255
- font-size: 0.875rem;
1256
- background-color: #ffffff;
1257
- cursor: pointer;
1258
- transition: border-color 0.2s ease, box-shadow 0.2s ease;
1259
- text-align: left;
1260
- }
1261
- .cas-input:hover { border-color: #93c5fd; }
1262
- .cas-input:focus {
1263
- outline: none;
1264
- border-color: #3b82f6;
1265
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
1266
- }
1267
- /* 禁用态:置灰 + 禁止交互 */
1268
- .cas-input:disabled {
1269
- background-color: #f5f5f5;
1270
- color: rgba(0, 0, 0, 0.4);
1271
- border-color: #e5e7eb;
1272
- cursor: not-allowed;
1273
- }
1274
- .cas-input:disabled:hover { border-color: #e5e7eb; }
1275
-
1276
- .cas-input-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1 1 auto; min-width: 0; }
1277
- .cas-placeholder { color: #9ca3af; }
1278
- .cas-arrow { color: #9ca3af; font-size: 0.75rem; transition: transform 0.2s ease; }
1279
- .cas-arrow-open { transform: rotate(180deg); }
1280
- .cas-clear {
1281
- padding: 0 0.25rem;
1282
- color: #9ca3af;
1283
- font-size: 1rem;
1284
- line-height: 1;
1285
- }
1286
- .cas-clear:hover { color: #374151; }
1287
-
1288
- /* 级联面板:横向多级菜单并排 */
1289
- .cas-panel {
1290
- position: absolute;
1291
- z-index: 50;
1292
- top: calc(100% + 4px);
1293
- left: 0;
1294
- display: flex;
1295
- background: #ffffff;
1296
- border: 1px solid #e5e7eb;
1297
- border-radius: 8px;
1298
- box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
1299
- }
1300
- .cas-menu {
1301
- width: 160px;
1302
- max-height: 240px;
1303
- overflow-y: auto;
1304
- padding: 0.375rem;
1305
- }
1306
- .cas-menu + .cas-menu {
1307
- border-left: 1px solid #f3f4f6;
1308
- }
1309
- .cas-option {
1310
- display: flex;
1311
- align-items: center;
1312
- justify-content: space-between;
1313
- gap: 0.5rem;
1314
- width: 100%;
1315
- padding: 0.375rem 0.5rem;
1316
- border: none;
1317
- border-radius: 4px;
1318
- background: transparent;
1319
- font-size: 0.875rem;
1320
- color: #111827;
1321
- cursor: pointer;
1322
- text-align: left;
1323
- transition: background 0.15s ease;
1324
- }
1325
- .cas-option:hover { background: #f3f4f6; }
1326
- .cas-option-active { background: #eff6ff; color: #1d4ed8; font-weight: 500; }
1327
- .cas-option-active:hover { background: #dbeafe; }
1328
- .cas-option-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1329
- .cas-option-arrow { color: #9ca3af; font-size: 0.875rem; flex: 0 0 auto; }
1330
- .cas-empty {
1331
- padding: 0.75rem 0.5rem;
1332
- font-size: 0.8125rem;
1333
- color: #9ca3af;
1334
- text-align: center;
1335
- }
1336
-
1337
- /* --- Select 可搜索模式(searchable):面板内置搜索框的单列下拉 --- */
1338
- /* 内容区:relative 供面板 absolute 定位(复用 .widget-field-content) */
1339
- .widget-select-content {
1340
- position: relative;
1341
- display: flex;
1342
- flex-direction: column;
1343
- }
1344
- /* 单列面板:纵向排搜索框 + 选项列表,宽度跟随触发按钮 */
1345
- .cas-panel-single {
1346
- flex-direction: column;
1347
- min-width: 100%;
1348
- width: auto;
1349
- }
1350
- /* 搜索框区:面板顶部固定,不随选项滚动 */
1351
- .cas-search {
1352
- padding: 0.5rem;
1353
- border-bottom: 1px solid #f3f4f6;
1354
- }
1355
- .cas-search-input {
1356
- width: 100%;
1357
- padding: 0.375rem 0.625rem;
1358
- border: 1px solid #d1d5db;
1359
- border-radius: 4px;
1360
- font-size: 0.8125rem;
1361
- box-sizing: border-box;
1362
- }
1363
- .cas-search-input:focus {
1364
- outline: none;
1365
- border-color: #3b82f6;
1366
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
1367
- }
1368
- /* 选项列表:占满面板宽度并滚动 */
1369
- .cas-menu-full {
1370
- width: 100%;
1371
- flex: 1 1 auto;
1372
- min-width: 0;
1
+ /* C2 Markdown UI React Widgets - Optional Styling */
2
+ /* Users can import this CSS file to apply consistent styling to all widget components */
3
+
4
+ /* Base widget container */
5
+ .widget {
6
+ margin: 1rem 0;
7
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
8
+ line-height: 1.5;
9
+ }
10
+
11
+ /* Form container */
12
+ .widget-form {
13
+ display: flex;
14
+ flex-direction: column;
15
+ gap: 1rem;
16
+ padding: 1.5rem;
17
+ border: 1px solid #f0f0f0;
18
+ border-radius: 8px;
19
+ background-color: #ffffff;
20
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
21
+ }
22
+
23
+ .widget-form > button[type="button"]:last-child {
24
+ align-self: flex-start;
25
+ margin-top: 0.5rem;
26
+ padding: 0.75rem 1.5rem;
27
+ background-color: #1677ff;
28
+ color: #ffffff;
29
+ border: none;
30
+ border-radius: 6px;
31
+ font-size: 0.875rem;
32
+ font-weight: 500;
33
+ cursor: pointer;
34
+ transition: background-color 0.2s ease;
35
+ }
36
+
37
+ /* Form actions(提交/取消/清空按钮组,data-align 控制对齐) */
38
+ .widget-form-actions {
39
+ display: flex;
40
+ gap: 0.5rem;
41
+ margin-top: 0.5rem;
42
+ }
43
+
44
+ .widget-form-actions[data-align="left"] { justify-content: flex-start; }
45
+ .widget-form-actions[data-align="center"] { justify-content: center; }
46
+ .widget-form-actions[data-align="right"] { justify-content: flex-end; }
47
+
48
+ .widget-form-actions button[type="button"] {
49
+ padding: 0.75rem 1.5rem;
50
+ border-radius: 6px;
51
+ font-size: 0.875rem;
52
+ font-weight: 500;
53
+ cursor: pointer;
54
+ transition: background-color 0.2s ease;
55
+ }
56
+
57
+ .widget-form-actions .widget-form-submit {
58
+ border: none;
59
+ background-color: #1677ff;
60
+ color: #ffffff;
61
+ }
62
+
63
+ .widget-form-actions .widget-form-submit:hover {
64
+ background-color: #4096ff;
65
+ }
66
+
67
+ .widget-form-actions .widget-form-cancel,
68
+ .widget-form-actions .widget-form-reset {
69
+ background-color: #ffffff;
70
+ color: rgba(0, 0, 0, 0.88);
71
+ border: 1px solid #d9d9d9;
72
+ }
73
+
74
+ .widget-form-actions .widget-form-cancel:hover,
75
+ .widget-form-actions .widget-form-reset:hover {
76
+ background-color: #fafafa;
77
+ border-color: rgba(0, 0, 0, 0.45);
78
+ }
79
+
80
+ .widget-form-actions button[type="button"]:focus {
81
+ outline: none;
82
+ box-shadow: 0 0 0 2px #1677ff;
83
+ }
84
+
85
+ /* === 字段内容区与控件宽度(所有布局生效) ===
86
+ 内容区占满字段宽(纵向模式下 select/input 才能跟随栅格 span 自适应) */
87
+ .widget-text-input > .widget-field-content,
88
+ .selector > .widget-field-content,
89
+ .selector-multi > .widget-field-content,
90
+ .widget-cascader > .widget-field-content,
91
+ .widget-slider > .widget-field-content {
92
+ width: 100%;
93
+ max-width: 100%;
94
+ }
95
+
96
+ /* 控件填满内容区:text input / select 拉伸到栅格列宽 */
97
+ .widget-text-input input[type="text"],
98
+ .selector select {
99
+ width: 100%;
100
+ max-width: 100%;
101
+ box-sizing: border-box;
102
+ }
103
+
104
+ /* 多选勾选组 / slider 容器同样填满 */
105
+ .widget-field-content > .checkbox-group,
106
+ .widget-field-content > .radio-group,
107
+ .widget-field-content > .slider-container {
108
+ width: 100%;
109
+ max-width: 100%;
110
+ }
111
+
112
+ /* === 表单项说明图标(hint):label 后 ⓘ,悬浮显示 tooltip === */
113
+ .widget-label-row {
114
+ display: flex;
115
+ align-items: center;
116
+ gap: 0.375rem;
117
+ }
118
+
119
+ .widget-hint {
120
+ position: relative;
121
+ display: inline-flex;
122
+ align-items: center;
123
+ justify-content: center;
124
+ width: 1rem;
125
+ height: 1rem;
126
+ font-size: 0.75rem;
127
+ font-weight: 600;
128
+ font-style: normal;
129
+ line-height: 1;
130
+ color: rgba(0, 0, 0, 0.65);
131
+ border: 1px solid #d9d9d9;
132
+ border-radius: 50%;
133
+ background-color: #fafafa;
134
+ cursor: help;
135
+ flex-shrink: 0;
136
+ user-select: none;
137
+ }
138
+
139
+ .widget-hint:hover {
140
+ color: #4096ff;
141
+ border-color: #4096ff;
142
+ background-color: #e6f4ff;
143
+ }
144
+
145
+ /* tooltip 气泡:纯 CSS,向上弹出 */
146
+ .widget-hint::before {
147
+ content: attr(data-hint);
148
+ position: absolute;
149
+ bottom: calc(100% + 8px);
150
+ left: 50%;
151
+ transform: translateX(-50%) translateY(4px);
152
+ padding: 0.5rem 0.75rem;
153
+ min-width: 8rem;
154
+ max-width: 18rem;
155
+ width: max-content;
156
+ white-space: normal;
157
+ font-size: 0.75rem;
158
+ font-weight: 400;
159
+ color: #fafafa;
160
+ background-color: rgba(0, 0, 0, 0.88);
161
+ border-radius: 6px;
162
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
163
+ opacity: 0;
164
+ visibility: hidden;
165
+ pointer-events: none;
166
+ transition: opacity 0.15s ease, transform 0.15s ease;
167
+ z-index: 100;
168
+ }
169
+
170
+ /* tooltip 小三角 */
171
+ .widget-hint::after {
172
+ content: "";
173
+ position: absolute;
174
+ bottom: calc(100% + 3px);
175
+ left: 50%;
176
+ transform: translateX(-50%) translateY(4px);
177
+ border: 5px solid transparent;
178
+ border-top-color: rgba(0, 0, 0, 0.88);
179
+ opacity: 0;
180
+ visibility: hidden;
181
+ pointer-events: none;
182
+ transition: opacity 0.15s ease, transform 0.15s ease;
183
+ z-index: 100;
184
+ }
185
+
186
+ .widget-hint:hover::before,
187
+ .widget-hint:hover::after,
188
+ .widget-hint:focus-visible::before,
189
+ .widget-hint:focus-visible::after {
190
+ opacity: 1;
191
+ visibility: visible;
192
+ transform: translateX(-50%) translateY(0);
193
+ }
194
+
195
+ /* === 表单项校验:必填红星 / 错误提示 / 红边框 === */
196
+
197
+ /* 必填标记:label 前红色 * */
198
+ .widget-required-mark {
199
+ color: #ff4d4f;
200
+ font-weight: 600;
201
+ line-height: 1;
202
+ flex-shrink: 0;
203
+ user-select: none;
204
+ }
205
+
206
+ /* 校验错误提示文案 */
207
+ .widget-error-text {
208
+ font-size: 0.75rem;
209
+ color: #ff4d4f;
210
+ line-height: 1.4;
211
+ margin-top: -0.25rem;
212
+ }
213
+
214
+ /* 输入框错误态:红边框 + 淡红聚焦光晕 */
215
+ .widget-text-input input.widget-input-error {
216
+ border-color: #ff4d4f;
217
+ }
218
+
219
+ .widget-text-input input.widget-input-error:focus {
220
+ border-color: #ff4d4f;
221
+ box-shadow: 0 0 0 3px rgba(255, 77, 79, 0.1);
222
+ }
223
+
224
+ /* 下拉触发器错误态:红边框 */
225
+ .cas-input.widget-input-error,
226
+ .dp-input.widget-input-error,
227
+ .ts-trigger.widget-input-error {
228
+ border-color: #ff4d4f;
229
+ }
230
+
231
+ /* 多选组错误态:checkbox 容器红边框 */
232
+ .widget-field-error .checkbox-group,
233
+ .widget-field-error .radio-group {
234
+ border-color: #ff4d4f;
235
+ }
236
+
237
+ /* Button Group */
238
+
239
+ /* 单个按钮组件(大/中/小三档尺寸,背景色完全由 color 属性的内联 style 控制) */
240
+ .widget-button {
241
+ display: inline-flex;
242
+ align-items: center;
243
+ justify-content: center;
244
+ border: none;
245
+ border-radius: 6px;
246
+ font-weight: 500;
247
+ cursor: pointer;
248
+ transition: filter 0.2s ease;
249
+ }
250
+
251
+ .widget-button:hover { filter: brightness(0.9); }
252
+ .widget-button:focus { outline: none; box-shadow: 0 0 0 2px #1677ff; }
253
+
254
+ .widget-button.size-small { padding: 0.25rem 0.75rem; font-size: 0.75rem; }
255
+ .widget-button.size-medium { padding: 0.5rem 1.25rem; font-size: 0.875rem; }
256
+ .widget-button.size-large { padding: 0.75rem 1.75rem; font-size: 1rem; }
257
+ .widget-button-group {
258
+ display: flex;
259
+ flex-direction: column;
260
+ gap: 0.5rem;
261
+ }
262
+
263
+ .widget-button-group label {
264
+ font-weight: 500;
265
+ color: rgba(0, 0, 0, 0.88);
266
+ margin-bottom: 0.25rem;
267
+ }
268
+
269
+ .widget-button-group div[role="group"] {
270
+ display: flex;
271
+ gap: 0.25rem;
272
+ flex-wrap: wrap;
273
+ }
274
+
275
+ .widget-form .widget-button-group button,
276
+ .widget-button-group button {
277
+ padding: 0.5rem 1rem;
278
+ border: 1px solid #d9d9d9;
279
+ background-color: #ffffff;
280
+ color: rgba(0, 0, 0, 0.88);
281
+ border-radius: 6px;
282
+ cursor: pointer;
283
+ transition: all 0.2s ease;
284
+ font-size: 0.875rem;
285
+ font-weight: 500;
286
+ }
287
+
288
+ .widget-form .widget-button-group button:hover,
289
+ .widget-button-group button:hover {
290
+ background-color: #fafafa;
291
+ border-color: rgba(0, 0, 0, 0.45);
292
+ }
293
+
294
+ .widget-form .widget-button-group button[aria-pressed="true"],
295
+ .widget-button-group button[aria-pressed="true"] {
296
+ background-color: #1677ff;
297
+ color: #ffffff;
298
+ border-color: #1677ff;
299
+ }
300
+
301
+ .widget-form .widget-button-group button:focus,
302
+ .widget-button-group button:focus {
303
+ outline: none;
304
+ box-shadow: 0 0 0 2px #1677ff;
305
+ }
306
+
307
+ /* Text Input */
308
+ .widget-text-input {
309
+ display: flex;
310
+ flex-direction: column;
311
+ gap: 0.5rem;
312
+ }
313
+
314
+ .widget-text-input label {
315
+ font-weight: 500;
316
+ color: rgba(0, 0, 0, 0.88);
317
+ }
318
+
319
+ .widget-text-input input[type="text"] {
320
+ padding: 0.75rem;
321
+ border: 1px solid #d9d9d9;
322
+ border-radius: 6px;
323
+ font-size: 0.875rem;
324
+ background-color: #ffffff;
325
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
326
+ }
327
+
328
+ .widget-text-input input[type="text"]:focus {
329
+ outline: none;
330
+ border-color: #1677ff;
331
+ box-shadow: 0 0 0 3px rgba(5, 145, 255, 0.1);
332
+ }
333
+
334
+ .widget-text-input input[type="text"]::placeholder {
335
+ color: rgba(0, 0, 0, 0.45);
336
+ }
337
+
338
+ /* Select and Select Multi */
339
+ .selector,
340
+ .selector-multi {
341
+ display: flex;
342
+ flex-direction: column;
343
+ gap: 0.5rem;
344
+ }
345
+
346
+ .selector label,
347
+ .selector-multi-label {
348
+ font-weight: 500;
349
+ color: rgba(0, 0, 0, 0.88);
350
+ }
351
+
352
+ .selector select {
353
+ padding: 0.75rem;
354
+ border: 1px solid #d9d9d9;
355
+ border-radius: 6px;
356
+ font-size: 0.875rem;
357
+ background-color: #ffffff;
358
+ cursor: pointer;
359
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
360
+ }
361
+
362
+ .selector select:focus {
363
+ outline: none;
364
+ border-color: #1677ff;
365
+ box-shadow: 0 0 0 3px rgba(5, 145, 255, 0.1);
366
+ }
367
+
368
+ .selector option {
369
+ padding: 0.5rem;
370
+ }
371
+
372
+ /* Checkbox-based Multi Select */
373
+ .checkbox-group {
374
+ display: flex;
375
+ flex-direction: column;
376
+ gap: 0.5rem;
377
+ padding: 0.75rem;
378
+ border: 1px solid #d9d9d9;
379
+ border-radius: 6px;
380
+ background-color: #ffffff;
381
+ max-height: 200px;
382
+ overflow-y: auto;
383
+ }
384
+
385
+ /* 选项布局:横向(flex-wrap 换行);自定义列数(grid,列宽由 inline style 注入) */
386
+ .checkbox-group[data-direction="horizontal"] {
387
+ flex-direction: row;
388
+ flex-wrap: wrap;
389
+ gap: 0.5rem 1.5rem;
390
+ }
391
+
392
+ .checkbox-group[data-direction="grid"] {
393
+ display: grid;
394
+ gap: 0.5rem;
395
+ }
396
+
397
+ .checkbox-item {
398
+ display: flex;
399
+ align-items: center;
400
+ gap: 0.5rem;
401
+ cursor: pointer;
402
+ padding: 0.25rem 0;
403
+ font-weight: normal;
404
+ }
405
+
406
+ .checkbox-item input[type="checkbox"] {
407
+ margin: 0;
408
+ cursor: pointer;
409
+ }
410
+
411
+ .checkbox-item span {
412
+ font-size: 0.875rem;
413
+ color: rgba(0, 0, 0, 0.88);
414
+ }
415
+
416
+ /* --- 单选 RadioGroup:圆点单选(antd Radio 默认样式) --- */
417
+ .radio-group {
418
+ display: flex;
419
+ flex-direction: column;
420
+ gap: 0.5rem;
421
+ padding: 0.75rem;
422
+ border: 1px solid #d9d9d9;
423
+ border-radius: 6px;
424
+ background-color: #ffffff;
425
+ }
426
+
427
+ /* 选项布局:横向(flex-wrap 换行);自定义列数(grid,列宽由 inline style 注入) */
428
+ .radio-group[data-direction="horizontal"] {
429
+ flex-direction: row;
430
+ flex-wrap: wrap;
431
+ gap: 0.5rem 1.5rem;
432
+ }
433
+
434
+ .radio-group[data-direction="grid"] {
435
+ display: grid;
436
+ gap: 0.5rem;
437
+ }
438
+
439
+ .radio-item {
440
+ display: flex;
441
+ align-items: center;
442
+ gap: 0.5rem;
443
+ cursor: pointer;
444
+ padding: 0.25rem 0;
445
+ font-weight: normal;
446
+ }
447
+
448
+ .radio-item input[type="radio"] {
449
+ margin: 0;
450
+ cursor: pointer;
451
+ accent-color: #1677ff;
452
+ }
453
+
454
+ .radio-item span {
455
+ font-size: 0.875rem;
456
+ color: rgba(0, 0, 0, 0.88);
457
+ }
458
+
459
+ .radio-item:hover {
460
+ background-color: #fafafa;
461
+ border-radius: 4px;
462
+ margin: -0.25rem 0;
463
+ padding: 0.5rem 0.25rem;
464
+ }
465
+
466
+ /* --- 单选 RadioGroup:按钮组样式(antd Radio optionType:button) --- */
467
+ .radio-button-group {
468
+ display: flex;
469
+ gap: 0.25rem;
470
+ flex-wrap: wrap;
471
+ }
472
+
473
+ .radio-button-group[data-direction="vertical"] {
474
+ flex-direction: column;
475
+ flex-wrap: nowrap;
476
+ }
477
+
478
+ .radio-button-group[data-direction="grid"] {
479
+ display: grid;
480
+ gap: 0.5rem;
481
+ }
482
+
483
+ .checkbox-item:hover {
484
+ background-color: #fafafa;
485
+ border-radius: 4px;
486
+ margin: -0.25rem 0;
487
+ padding: 0.5rem 0.25rem;
488
+ }
489
+
490
+ /* Slider */
491
+ .widget-slider {
492
+ display: flex;
493
+ flex-direction: column;
494
+ gap: 0.5rem;
495
+ }
496
+
497
+ .widget-slider label {
498
+ font-weight: 500;
499
+ color: rgba(0, 0, 0, 0.88);
500
+ }
501
+
502
+ .slider-container {
503
+ display: flex;
504
+ flex-direction: column;
505
+ gap: 0.25rem;
506
+ }
507
+
508
+ .slider-values {
509
+ display: flex;
510
+ justify-content: space-between;
511
+ align-items: center;
512
+ font-size: 0.75rem;
513
+ color: rgba(0, 0, 0, 0.65);
514
+ margin-bottom: 0.25rem;
515
+ }
516
+
517
+ .current-value {
518
+ font-weight: 600;
519
+ color: #1677ff;
520
+ background: #e6f4ff;
521
+ padding: 0.25rem 0.5rem;
522
+ border-radius: 4px;
523
+ min-width: 2rem;
524
+ text-align: center;
525
+ }
526
+
527
+ .min-value, .max-value {
528
+ font-weight: 500;
529
+ }
530
+
531
+ .widget-slider input[type="range"] {
532
+ width: 100%;
533
+ height: 6px;
534
+ border-radius: 3px;
535
+ background: #f0f0f0;
536
+ outline: none;
537
+ cursor: pointer;
538
+ }
539
+
540
+ .widget-slider input[type="range"]::-webkit-slider-thumb {
541
+ appearance: none;
542
+ width: 20px;
543
+ height: 20px;
544
+ border-radius: 50%;
545
+ background: #1677ff;
546
+ cursor: pointer;
547
+ transition: background-color 0.2s ease;
548
+ }
549
+
550
+ .widget-slider input[type="range"]::-webkit-slider-thumb:hover {
551
+ background: #4096ff;
552
+ }
553
+
554
+ .widget-slider input[type="range"]::-moz-range-thumb {
555
+ width: 20px;
556
+ height: 20px;
557
+ border-radius: 50%;
558
+ background: #1677ff;
559
+ cursor: pointer;
560
+ border: none;
561
+ transition: background-color 0.2s ease;
562
+ }
563
+
564
+ .widget-slider input[type="range"]::-moz-range-thumb:hover {
565
+ background: #4096ff;
566
+ }
567
+
568
+ /* Switch(参考 antd Switch) */
569
+ .widget-switch {
570
+ display: flex;
571
+ flex-direction: column;
572
+ gap: 0.5rem;
573
+ }
574
+
575
+ .widget-switch > label {
576
+ font-weight: 500;
577
+ color: rgba(0, 0, 0, 0.88);
578
+ }
579
+
580
+ .switch-track {
581
+ position: relative;
582
+ display: inline-flex;
583
+ align-items: center;
584
+ box-sizing: content-box;
585
+ width: 44px;
586
+ height: 22px;
587
+ padding: 0;
588
+ border: none;
589
+ border-radius: 11px;
590
+ background-color: rgba(0, 0, 0, 0.25);
591
+ cursor: pointer;
592
+ transition: background-color 0.2s ease;
593
+ flex-shrink: 0;
594
+ }
595
+
596
+ .switch-track[data-checked="true"] {
597
+ background-color: #1677ff;
598
+ }
599
+
600
+ .switch-track:hover:not(:disabled) {
601
+ background-color: rgba(0, 0, 0, 0.45);
602
+ }
603
+
604
+ .switch-track[data-checked="true"]:hover:not(:disabled) {
605
+ background-color: #4096ff;
606
+ }
607
+
608
+ .switch-track .switch-thumb {
609
+ display: block;
610
+ width: 18px;
611
+ height: 18px;
612
+ margin: 2px;
613
+ border-radius: 50%;
614
+ background-color: #ffffff;
615
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
616
+ transition: transform 0.2s ease;
617
+ }
618
+
619
+ .switch-track[data-checked="true"] .switch-thumb {
620
+ transform: translateX(22px);
621
+ }
622
+
623
+ .switch-track .switch-text {
624
+ position: absolute;
625
+ top: 50%;
626
+ transform: translateY(-50%);
627
+ font-size: 0.75rem;
628
+ font-weight: 500;
629
+ color: #ffffff;
630
+ line-height: 1;
631
+ user-select: none;
632
+ }
633
+
634
+ /* 文案位置与 antd 一致:选中后滑块移至右侧,选中文案露在左侧;未选中时滑块在左,未选中文案露在右侧 */
635
+ .switch-track .switch-text-unchecked {
636
+ right: 6px;
637
+ }
638
+
639
+ .switch-track .switch-text-checked {
640
+ left: 6px;
641
+ }
642
+
643
+ /* 仅显示当前状态对应的文案 */
644
+ .switch-track[data-checked="true"] .switch-text-unchecked {
645
+ display: none;
646
+ }
647
+
648
+ .switch-track[data-checked="false"] .switch-text-checked {
649
+ display: none;
650
+ }
651
+
652
+ .switch-track:disabled {
653
+ cursor: not-allowed;
654
+ opacity: 0.5;
655
+ }
656
+
657
+ .switch-track:focus-visible {
658
+ outline: none;
659
+ box-shadow: 0 0 0 2px #1677ff;
660
+ }
661
+
662
+ /* Form submit button styling - hover and focus states */
663
+ .widget-form > button[type="button"]:last-child:hover {
664
+ background-color: #4096ff;
665
+ }
666
+
667
+ .widget-form > button[type="button"]:last-child:focus {
668
+ outline: none;
669
+ box-shadow: 0 0 0 2px #1677ff;
670
+ }
671
+
672
+ /* Form row grid layout (24-column grid, similar to antd Row/Col) */
673
+ .widget-form-row {
674
+ display: grid;
675
+ grid-template-columns: repeat(24, minmax(0, 1fr));
676
+ column-gap: var(--row-gutter, 1rem);
677
+ }
678
+
679
+ .widget-form-row .widget-form-field {
680
+ min-width: 0;
681
+ }
682
+
683
+ /* 传统 fields 模式 + 显式 span:切换为 24 栅格(无 span 字段占满整行) */
684
+ .widget-form.widget-form-fields-grid {
685
+ display: grid;
686
+ grid-template-columns: repeat(24, minmax(0, 1fr));
687
+ column-gap: 1rem;
688
+ row-gap: 1rem;
689
+ align-items: start;
690
+ }
691
+
692
+ .widget-form-fields-grid .widget-form-field {
693
+ min-width: 0;
694
+ }
695
+
696
+ .widget-form-fields-grid .widget-form-field[data-field-type="button"] {
697
+ width: max-content;
698
+ max-width: 100%;
699
+ align-self: end;
700
+ padding-bottom: 0;
701
+ }
702
+
703
+ .widget-form-fields-grid .widget-form-actions {
704
+ grid-column: 1 / -1;
705
+ }
706
+
707
+ /* inline 模式 + 显式 span 覆盖 flex-basis 后,收回默认 flex-grow */
708
+ .widget-form-inline .widget-form-field[style*="flex: 0 1"] {
709
+ flex-grow: 0;
710
+ }
711
+
712
+ /* === 表单左右布局(layout:horizontal):label 与内容同一行 === */
713
+ /* CSS 变量由 Form 根容器注入:
714
+ --form-label-width:label 固定宽度(默认 80px)
715
+ --form-content-width:内容宽度(未设置则 flex 填满剩余空间) */
716
+
717
+ /* 字段组件整体横排:label-row 固定宽 + 控件区填满 */
718
+ .widget-form-layout-horizontal .widget-form-field > .widget-text-input,
719
+ .widget-form-layout-horizontal .widget-form-field > .selector,
720
+ .widget-form-layout-horizontal .widget-form-field > .selector-multi,
721
+ .widget-form-layout-horizontal .widget-form-field > .widget-cascader,
722
+ .widget-form-layout-horizontal .widget-form-field > .widget-slider,
723
+ .widget-form-layout-horizontal .widget-form-field > .widget-switch {
724
+ display: flex;
725
+ flex-direction: row;
726
+ align-items: flex-start;
727
+ gap: 0.75rem;
728
+ }
729
+
730
+ /* label 行:固定宽度、右对齐、不收缩;超宽省略 */
731
+ .widget-form-layout-horizontal .widget-label-row {
732
+ flex: 0 0 var(--form-label-width, 80px);
733
+ width: var(--form-label-width, 80px);
734
+ justify-content: flex-end;
735
+ text-align: right;
736
+ }
737
+
738
+ /* label 文本超宽省略,悬浮完整显示 */
739
+ .widget-form-layout-horizontal .widget-label-row > label,
740
+ .widget-form-layout-horizontal .widget-label-row > .selector-multi-label {
741
+ overflow: hidden;
742
+ text-overflow: ellipsis;
743
+ white-space: nowrap;
744
+ }
745
+
746
+ /* 必填红星随行内排布(label-row 已 flex-end 对齐) */
747
+ .widget-form-layout-horizontal .widget-required-mark {
748
+ order: -1;
749
+ }
750
+
751
+ /* 内容区:跟随 label 之后填满剩余空间(或指定宽度);内部纵向排控件+错误提示 */
752
+ .widget-form-layout-horizontal .widget-text-input > .widget-field-content,
753
+ .widget-form-layout-horizontal .selector > .widget-field-content,
754
+ .widget-form-layout-horizontal .selector-multi > .widget-field-content,
755
+ .widget-form-layout-horizontal .widget-cascader > .widget-field-content,
756
+ .widget-form-layout-horizontal .widget-slider > .widget-field-content,
757
+ .widget-form-layout-horizontal .widget-switch > .widget-field-content {
758
+ flex: 1 1 auto;
759
+ width: var(--form-content-width, auto);
760
+ max-width: 100%;
761
+ /* 允许收缩到 0:窄容器(如小 span 栅格)时不溢出 */
762
+ min-width: 0;
763
+ display: flex;
764
+ flex-direction: column;
765
+ gap: 0.375rem;
766
+ }
767
+
768
+ /* 内容区内部控件填满内容区 */
769
+ .widget-form-layout-horizontal .widget-field-content > input,
770
+ .widget-form-layout-horizontal .widget-field-content > select,
771
+ .widget-form-layout-horizontal .widget-field-content > .slider-container,
772
+ .widget-form-layout-horizontal .widget-field-content > .checkbox-group,
773
+ .widget-form-layout-horizontal .widget-field-content > .radio-group {
774
+ width: 100%;
775
+ max-width: 100%;
776
+ }
777
+
778
+ /* 指定内容宽度时按该宽度排布,但允许收缩避免窄容器溢出 */
779
+ .widget-form-layout-horizontal[style*="--form-content-width"] .widget-text-input > .widget-field-content,
780
+ .widget-form-layout-horizontal[style*="--form-content-width"] .selector > .widget-field-content,
781
+ .widget-form-layout-horizontal[style*="--form-content-width"] .selector-multi > .widget-field-content,
782
+ .widget-form-layout-horizontal[style*="--form-content-width"] .widget-cascader > .widget-field-content,
783
+ .widget-form-layout-horizontal[style*="--form-content-width"] .widget-slider > .widget-field-content,
784
+ .widget-form-layout-horizontal[style*="--form-content-width"] .widget-switch > .widget-field-content {
785
+ flex: 0 1 var(--form-content-width);
786
+ }
787
+
788
+ /* 无 label 字段(纯 placeholder):内容对齐留出 label 列空位,视觉整齐 */
789
+ .widget-form-layout-horizontal .widget-form-field > .widget-text-input:not(:has(.widget-label-row)) > .widget-field-content,
790
+ .widget-form-layout-horizontal .widget-form-field > .selector:not(:has(.widget-label-row)) > .widget-field-content,
791
+ .widget-form-layout-horizontal .widget-form-field > .selector-multi:not(:has(.widget-label-row)) > .widget-field-content,
792
+ .widget-form-layout-horizontal .widget-form-field > .widget-cascader:not(:has(.widget-label-row)) > .widget-field-content,
793
+ .widget-form-layout-horizontal .widget-form-field > .widget-slider:not(:has(.widget-label-row)) > .widget-field-content,
794
+ .widget-form-layout-horizontal .widget-form-field > .widget-switch:not(:has(.widget-label-row)) > .widget-field-content {
795
+ margin-left: calc(var(--form-label-width, 80px) + 0.75rem);
796
+ }
797
+
798
+ /* inline 模式 + 左右布局组合:字段内 label/内容横排,字段间照常 flex-wrap */
799
+ .widget-form-layout-horizontal.widget-form-inline .widget-form-field {
800
+ display: flex;
801
+ align-items: flex-start;
802
+ }
803
+
804
+ /* 表单左右布局:数字输入框与其他字段组件一致的横排规则 */
805
+ .widget-form-layout-horizontal .widget-form-field > .widget-number-input {
806
+ display: flex;
807
+ flex-direction: row;
808
+ align-items: flex-start;
809
+ gap: 0.75rem;
810
+ }
811
+
812
+ .widget-form-layout-horizontal .widget-number-input > .widget-field-content {
813
+ flex: 1 1 auto;
814
+ width: var(--form-content-width, auto);
815
+ max-width: 100%;
816
+ min-width: 0;
817
+ display: flex;
818
+ flex-direction: column;
819
+ gap: 0.375rem;
820
+ }
821
+
822
+ .widget-form-layout-horizontal[style*="--form-content-width"] .widget-number-input > .widget-field-content {
823
+ flex: 0 1 var(--form-content-width);
824
+ }
825
+
826
+ .widget-form-layout-horizontal .widget-form-field > .widget-number-input:not(:has(.widget-label-row)) > .widget-field-content {
827
+ margin-left: calc(var(--form-label-width, 80px) + 0.75rem);
828
+ }
829
+
830
+ /* Error styling for unknown widgets */
831
+ .widget span[style*="color:red"] {
832
+ color: #ff4d4f !important;
833
+ font-weight: 500;
834
+ padding: 0.75rem;
835
+ background-color: #fff2f0;
836
+ border: 1px solid #ffccc7;
837
+ border-radius: 6px;
838
+ display: inline-block;
839
+ }
840
+
841
+ /* Multiple Choice Question */
842
+ .widget-mcq {
843
+ display: flex;
844
+ flex-direction: column;
845
+ gap: 1rem;
846
+ padding: 1.5rem;
847
+ border: 1px solid #f0f0f0;
848
+ border-radius: 8px;
849
+ background-color: #ffffff;
850
+ }
851
+
852
+ .mcq-question {
853
+ font-weight: 600;
854
+ font-size: 1.1rem;
855
+ color: rgba(0, 0, 0, 0.88);
856
+ margin-bottom: 0.5rem;
857
+ }
858
+
859
+ .mcq-choices {
860
+ display: flex;
861
+ flex-direction: column;
862
+ gap: 0.75rem;
863
+ }
864
+
865
+ .mcq-choice {
866
+ padding: 1rem;
867
+ border: 2px solid #d9d9d9;
868
+ border-radius: 8px;
869
+ background-color: #ffffff;
870
+ text-align: left;
871
+ cursor: pointer;
872
+ transition: all 0.2s ease;
873
+ font-size: 0.9rem;
874
+ }
875
+
876
+ .mcq-choice:hover:not(:disabled) {
877
+ border-color: rgba(0, 0, 0, 0.45);
878
+ background-color: #fafafa;
879
+ }
880
+
881
+ .mcq-choice-selected {
882
+ border-color: #1677ff;
883
+ background-color: #e6f4ff;
884
+ }
885
+
886
+ .mcq-choice-correct {
887
+ border-color: #52c41a;
888
+ background-color: #f6ffed;
889
+ color: #389e0d;
890
+ }
891
+
892
+ .mcq-choice-incorrect {
893
+ border-color: #ff4d4f;
894
+ background-color: #fff2f0;
895
+ color: #cf1322;
896
+ }
897
+
898
+ .mcq-choice:disabled {
899
+ cursor: not-allowed;
900
+ opacity: 0.8;
901
+ }
902
+
903
+ .mcq-feedback {
904
+ padding: 0.75rem;
905
+ border-radius: 6px;
906
+ font-weight: 500;
907
+ font-size: 0.9rem;
908
+ }
909
+
910
+ .mcq-feedback.correct {
911
+ background-color: #f6ffed;
912
+ color: #389e0d;
913
+ border: 1px solid #b7eb8f;
914
+ }
915
+
916
+ .mcq-feedback.incorrect {
917
+ background-color: #fff2f0;
918
+ color: #cf1322;
919
+ border: 1px solid #ffccc7;
920
+ }
921
+
922
+ /* Short Answer Question */
923
+ .widget-saq {
924
+ display: flex;
925
+ flex-direction: column;
926
+ gap: 1rem;
927
+ padding: 1.5rem;
928
+ border: 1px solid #f0f0f0;
929
+ border-radius: 8px;
930
+ background-color: #ffffff;
931
+ }
932
+
933
+ .saq-question {
934
+ font-weight: 600;
935
+ font-size: 1.1rem;
936
+ color: rgba(0, 0, 0, 0.88);
937
+ margin-bottom: 0.5rem;
938
+ }
939
+
940
+ .saq-input-container {
941
+ display: flex;
942
+ gap: 0.75rem;
943
+ align-items: stretch;
944
+ }
945
+
946
+ .saq-input {
947
+ flex: 1;
948
+ padding: 0.75rem;
949
+ border: 2px solid #d9d9d9;
950
+ border-radius: 6px;
951
+ font-size: 0.9rem;
952
+ background-color: #ffffff;
953
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
954
+ }
955
+
956
+ .saq-input:focus {
957
+ outline: none;
958
+ border-color: #1677ff;
959
+ box-shadow: 0 0 0 3px rgba(5, 145, 255, 0.1);
960
+ }
961
+
962
+ .saq-input-correct {
963
+ border-color: #52c41a;
964
+ background-color: #f6ffed;
965
+ }
966
+
967
+ .saq-input-incorrect {
968
+ border-color: #ff4d4f;
969
+ background-color: #fff2f0;
970
+ }
971
+
972
+ .saq-submit {
973
+ padding: 0.75rem 1.25rem;
974
+ background-color: #1677ff;
975
+ color: #ffffff;
976
+ border: none;
977
+ border-radius: 6px;
978
+ font-size: 0.875rem;
979
+ font-weight: 500;
980
+ cursor: pointer;
981
+ transition: background-color 0.2s ease;
982
+ white-space: nowrap;
983
+ }
984
+
985
+ .saq-submit:hover:not(:disabled) {
986
+ background-color: #4096ff;
987
+ }
988
+
989
+ .saq-submit:disabled {
990
+ background-color: #f5f5f5;
991
+ color: rgba(0, 0, 0, 0.25);
992
+ cursor: not-allowed;
993
+ }
994
+
995
+ .saq-feedback {
996
+ padding: 0.75rem;
997
+ border-radius: 6px;
998
+ font-weight: 500;
999
+ font-size: 0.9rem;
1000
+ }
1001
+
1002
+ .saq-feedback.correct {
1003
+ background-color: #f6ffed;
1004
+ color: #389e0d;
1005
+ border: 1px solid #b7eb8f;
1006
+ }
1007
+
1008
+ .saq-feedback.incorrect {
1009
+ background-color: #fff2f0;
1010
+ color: #cf1322;
1011
+ border: 1px solid #ffccc7;
1012
+ }
1013
+
1014
+ /* Responsive design */
1015
+ @media (max-width: 640px) {
1016
+ .widget-button-group div[role="group"] {
1017
+ flex-direction: column;
1018
+ }
1019
+
1020
+ .widget-button-group button {
1021
+ width: 100%;
1022
+ }
1023
+
1024
+ .widget-form {
1025
+ padding: 1rem;
1026
+ }
1027
+
1028
+ .saq-input-container {
1029
+ flex-direction: column;
1030
+ }
1031
+
1032
+ .widget-mcq,
1033
+ .widget-saq,
1034
+ .widget-quiz {
1035
+ padding: 1rem;
1036
+ }
1037
+ }
1038
+
1039
+ /* Quiz Component */
1040
+ .widget-quiz {
1041
+ max-width: 800px;
1042
+ margin: 0 auto;
1043
+ background: #ffffff;
1044
+ border: 1px solid #f0f0f0;
1045
+ border-radius: 12px;
1046
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
1047
+ }
1048
+
1049
+ .quiz-header {
1050
+ padding: 2rem 2rem 1rem;
1051
+ border-bottom: 1px solid #f0f0f0;
1052
+ background: linear-gradient(135deg, #1677ff 0%, #0958d9 100%);
1053
+ color: white;
1054
+ border-radius: 12px 12px 0 0;
1055
+ }
1056
+
1057
+ .quiz-title {
1058
+ font-size: 1.5rem;
1059
+ font-weight: 700;
1060
+ margin: 0 0 1rem 0;
1061
+ text-align: center;
1062
+ color: white;
1063
+ }
1064
+
1065
+ .quiz-stats {
1066
+ display: flex;
1067
+ justify-content: space-between;
1068
+ align-items: center;
1069
+ gap: 2rem;
1070
+ flex-wrap: wrap;
1071
+ color: white;
1072
+ }
1073
+
1074
+ .quiz-progress {
1075
+ flex: 1;
1076
+ min-width: 200px;
1077
+ }
1078
+
1079
+ .quiz-progress-text {
1080
+ font-size: 0.9rem;
1081
+ font-weight: 500;
1082
+ margin-bottom: 0.5rem;
1083
+ display: block;
1084
+ color: white;
1085
+ }
1086
+
1087
+ .quiz-progress-bar {
1088
+ width: 100%;
1089
+ height: 8px;
1090
+ background: rgba(255, 255, 255, 0.2);
1091
+ border-radius: 4px;
1092
+ overflow: hidden;
1093
+ }
1094
+
1095
+ .quiz-progress-fill {
1096
+ height: 100%;
1097
+ background: linear-gradient(90deg, #52c41a, #73d13d);
1098
+ border-radius: 4px;
1099
+ transition: width 0.3s ease;
1100
+ }
1101
+
1102
+ .quiz-score {
1103
+ text-align: right;
1104
+ }
1105
+
1106
+ .quiz-score-text {
1107
+ font-size: 1.1rem;
1108
+ font-weight: 600;
1109
+ color: white;
1110
+ }
1111
+
1112
+ .quiz-questions {
1113
+ padding: 1.5rem;
1114
+ }
1115
+
1116
+ .quiz-question {
1117
+ margin-bottom: 2rem;
1118
+ padding: 1.5rem;
1119
+ border: 2px solid #f0f0f0;
1120
+ border-radius: 8px;
1121
+ background: #fafafa;
1122
+ transition: all 0.2s ease;
1123
+ }
1124
+
1125
+ .quiz-question:hover {
1126
+ border-color: #f0f0f0;
1127
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
1128
+ }
1129
+
1130
+ .quiz-question-header {
1131
+ display: flex;
1132
+ justify-content: space-between;
1133
+ align-items: flex-start;
1134
+ margin-bottom: 1rem;
1135
+ gap: 1rem;
1136
+ }
1137
+
1138
+ .quiz-question-text {
1139
+ font-size: 1.1rem;
1140
+ font-weight: 600;
1141
+ color: rgba(0, 0, 0, 0.88);
1142
+ margin: 0;
1143
+ flex: 1;
1144
+ }
1145
+
1146
+ .quiz-question-points {
1147
+ background: #1677ff;
1148
+ color: white;
1149
+ padding: 0.25rem 0.75rem;
1150
+ border-radius: 12px;
1151
+ font-size: 0.8rem;
1152
+ font-weight: 600;
1153
+ white-space: nowrap;
1154
+ }
1155
+
1156
+ .quiz-choices {
1157
+ display: flex;
1158
+ flex-direction: column;
1159
+ gap: 0.75rem;
1160
+ }
1161
+
1162
+ .quiz-choice {
1163
+ padding: 1rem 1.25rem;
1164
+ border: 2px solid #d9d9d9;
1165
+ border-radius: 8px;
1166
+ background: #ffffff;
1167
+ text-align: left;
1168
+ cursor: pointer;
1169
+ transition: all 0.2s ease;
1170
+ font-size: 0.95rem;
1171
+ font-weight: 500;
1172
+ }
1173
+
1174
+ .quiz-choice:hover:not(:disabled) {
1175
+ border-color: #1677ff;
1176
+ background: #e6f4ff;
1177
+ transform: translateY(-1px);
1178
+ }
1179
+
1180
+ .quiz-choice-selected {
1181
+ border-color: #1677ff;
1182
+ background: #e6f4ff;
1183
+ }
1184
+
1185
+ .quiz-choice-correct {
1186
+ border-color: #52c41a;
1187
+ background: #f6ffed;
1188
+ color: #389e0d;
1189
+ }
1190
+
1191
+ .quiz-choice-incorrect {
1192
+ border-color: #ff4d4f;
1193
+ background: #fff2f0;
1194
+ color: #cf1322;
1195
+ }
1196
+
1197
+ .quiz-choice:disabled {
1198
+ cursor: not-allowed;
1199
+ opacity: 0.9;
1200
+ }
1201
+
1202
+ .quiz-input-container {
1203
+ display: flex;
1204
+ gap: 0.75rem;
1205
+ align-items: stretch;
1206
+ }
1207
+
1208
+ .quiz-input {
1209
+ flex: 1;
1210
+ padding: 0.75rem 1rem;
1211
+ border: 2px solid #d9d9d9;
1212
+ border-radius: 6px;
1213
+ font-size: 0.95rem;
1214
+ background: #ffffff;
1215
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
1216
+ }
1217
+
1218
+ .quiz-input:focus {
1219
+ outline: none;
1220
+ border-color: #1677ff;
1221
+ box-shadow: 0 0 0 3px rgba(5, 145, 255, 0.1);
1222
+ }
1223
+
1224
+ .quiz-input-correct {
1225
+ border-color: #52c41a;
1226
+ background: #f6ffed;
1227
+ }
1228
+
1229
+ .quiz-input-incorrect {
1230
+ border-color: #ff4d4f;
1231
+ background: #fff2f0;
1232
+ }
1233
+
1234
+ .quiz-submit {
1235
+ padding: 0.75rem 1.5rem;
1236
+ background: #1677ff;
1237
+ color: white;
1238
+ border: none;
1239
+ border-radius: 6px;
1240
+ font-size: 0.875rem;
1241
+ font-weight: 600;
1242
+ cursor: pointer;
1243
+ transition: background-color 0.2s ease;
1244
+ white-space: nowrap;
1245
+ }
1246
+
1247
+ .quiz-submit:hover:not(:disabled) {
1248
+ background: #4096ff;
1249
+ }
1250
+
1251
+ .quiz-submit:disabled {
1252
+ background-color: #f5f5f5;
1253
+ color: rgba(0, 0, 0, 0.25);
1254
+ cursor: not-allowed;
1255
+ }
1256
+
1257
+ .quiz-feedback {
1258
+ margin-top: 1rem;
1259
+ padding: 1rem;
1260
+ border-radius: 6px;
1261
+ font-weight: 600;
1262
+ font-size: 0.95rem;
1263
+ }
1264
+
1265
+ .quiz-feedback.correct {
1266
+ background: #f6ffed;
1267
+ color: #389e0d;
1268
+ border: 1px solid #b7eb8f;
1269
+ }
1270
+
1271
+ .quiz-feedback.incorrect {
1272
+ background: #fff2f0;
1273
+ color: #cf1322;
1274
+ border: 1px solid #ffccc7;
1275
+ }
1276
+
1277
+ .quiz-summary {
1278
+ margin-top: 2rem;
1279
+ padding: 2rem;
1280
+ background: linear-gradient(135deg, #fafafa 0%, #f0f0f0 100%);
1281
+ border-radius: 8px;
1282
+ text-align: center;
1283
+ border: 2px solid #f0f0f0;
1284
+ }
1285
+
1286
+ .quiz-summary h3 {
1287
+ font-size: 1.5rem;
1288
+ font-weight: 700;
1289
+ color: rgba(0, 0, 0, 0.88);
1290
+ margin: 0 0 1rem 0;
1291
+ }
1292
+
1293
+ .quiz-final-score {
1294
+ font-size: 1.2rem;
1295
+ font-weight: 600;
1296
+ color: rgba(0, 0, 0, 0.88);
1297
+ margin-bottom: 1rem;
1298
+ }
1299
+
1300
+ .quiz-result {
1301
+ font-size: 1.1rem;
1302
+ font-weight: 700;
1303
+ padding: 0.75rem 1.5rem;
1304
+ border-radius: 6px;
1305
+ display: inline-block;
1306
+ }
1307
+
1308
+ .quiz-result.passed {
1309
+ background: #f6ffed;
1310
+ color: #389e0d;
1311
+ border: 1px solid #b7eb8f;
1312
+ }
1313
+
1314
+ .quiz-result.failed {
1315
+ background: #fff2f0;
1316
+ color: #cf1322;
1317
+ border: 1px solid #ffccc7;
1318
+ }
1319
+
1320
+ /* ============================================================ */
1321
+ /* === Disabled 状态统一置灰样式(所有交互组件 disabled 后视觉反馈) === */
1322
+ /* ============================================================ */
1323
+
1324
+ /* --- 单按钮组件 Button:含内联 color 时仅置灰文字 --- */
1325
+ .widget-button:disabled {
1326
+ background-color: #f5f5f5 !important;
1327
+ color: rgba(0, 0, 0, 0.25) !important;
1328
+ cursor: not-allowed;
1329
+ filter: none;
1330
+ }
1331
+ .widget-button:disabled:hover { filter: none; }
1332
+
1333
+ /* --- 按钮组 ButtonGroup --- */
1334
+ .widget-form .widget-button-group button:disabled,
1335
+ .widget-button-group button:disabled {
1336
+ background-color: #f5f5f5;
1337
+ color: rgba(0, 0, 0, 0.25);
1338
+ border-color: #d9d9d9;
1339
+ cursor: not-allowed;
1340
+ opacity: 1;
1341
+ }
1342
+ /* 选中态按钮禁用后保持浅蓝底可辨识 */
1343
+ .widget-form .widget-button-group button[aria-pressed="true"]:disabled,
1344
+ .widget-button-group button[aria-pressed="true"]:disabled {
1345
+ background-color: #91caff;
1346
+ border-color: #91caff;
1347
+ color: rgba(255, 255, 255, 0.8);
1348
+ cursor: not-allowed;
1349
+ }
1350
+
1351
+ /* --- 文本输入 TextInput --- */
1352
+ .widget-text-input input[type="text"]:disabled {
1353
+ background-color: #f5f5f5;
1354
+ color: rgba(0, 0, 0, 0.25);
1355
+ border-color: #d9d9d9;
1356
+ cursor: not-allowed;
1357
+ }
1358
+
1359
+ /* --- 数字输入 NumberInput --- */
1360
+ .ni-wrap input:disabled {
1361
+ background-color: #f5f5f5;
1362
+ color: rgba(0, 0, 0, 0.25);
1363
+ border-color: #d9d9d9;
1364
+ cursor: not-allowed;
1365
+ }
1366
+ .ni-steps button:disabled {
1367
+ color: #d9d9d9;
1368
+ cursor: not-allowed;
1369
+ }
1370
+
1371
+ /* --- 滑块 Slider:轨道变浅 + 拇指置灰 --- */
1372
+ .widget-slider input[type="range"]:disabled {
1373
+ background: #f0f0f0;
1374
+ cursor: not-allowed;
1375
+ }
1376
+ .widget-slider input[type="range"]:disabled::-webkit-slider-thumb {
1377
+ background: #d9d9d9;
1378
+ cursor: not-allowed;
1379
+ }
1380
+ .widget-slider input[type="range"]:disabled::-moz-range-thumb {
1381
+ background: #d9d9d9;
1382
+ cursor: not-allowed;
1383
+ }
1384
+ .widget-slider input[type="range"]:disabled::-webkit-slider-thumb:hover {
1385
+ background: #d9d9d9;
1386
+ }
1387
+ .widget-slider input[type="range"]:disabled::-moz-range-thumb:hover {
1388
+ background: #d9d9d9;
1389
+ }
1390
+ /* 数字值徽标同步置灰 */
1391
+ .widget-slider:has(input:disabled) .current-value {
1392
+ color: rgba(0, 0, 0, 0.25);
1393
+ background: #f5f5f5;
1394
+ }
1395
+
1396
+ /* --- 下拉选择 Select --- */
1397
+ .selector select:disabled {
1398
+ background-color: #f5f5f5;
1399
+ color: rgba(0, 0, 0, 0.25);
1400
+ border-color: #d9d9d9;
1401
+ cursor: not-allowed;
1402
+ }
1403
+
1404
+ /* --- 多选 SelectMulti:checkbox 与文字置灰 --- */
1405
+ .checkbox-group:has(input:disabled) {
1406
+ background-color: #f5f5f5;
1407
+ border-color: #d9d9d9;
1408
+ }
1409
+ .checkbox-group:has(input:disabled) .checkbox-item {
1410
+ cursor: not-allowed;
1411
+ }
1412
+ .checkbox-group:has(input:disabled) .checkbox-item:hover {
1413
+ background-color: transparent;
1414
+ }
1415
+ .checkbox-group:has(input:disabled) .checkbox-item span {
1416
+ color: rgba(0, 0, 0, 0.25);
1417
+ }
1418
+
1419
+ /* --- 单选 RadioGroup:圆点与文字置灰 --- */
1420
+ .radio-group:has(input:disabled) {
1421
+ background-color: #f5f5f5;
1422
+ border-color: #d9d9d9;
1423
+ }
1424
+ .radio-group:has(input:disabled) .radio-item {
1425
+ cursor: not-allowed;
1426
+ }
1427
+ .radio-group:has(input:disabled) .radio-item:hover {
1428
+ background-color: transparent;
1429
+ }
1430
+ .radio-group:has(input:disabled) .radio-item span {
1431
+ color: rgba(0, 0, 0, 0.25);
1432
+ }
1433
+
1434
+ /* --- Form 提交/重置/取消按钮 --- */
1435
+ .widget-form-actions button[type="button"]:disabled {
1436
+ background-color: #f5f5f5;
1437
+ color: rgba(0, 0, 0, 0.25);
1438
+ border-color: #d9d9d9;
1439
+ cursor: not-allowed;
1440
+ box-shadow: none;
1441
+ }
1442
+ /* 主按钮禁用保持淡蓝底区分 */
1443
+ .widget-form-actions .widget-form-submit:disabled {
1444
+ background-color: #91caff;
1445
+ color: rgba(255, 255, 255, 0.8);
1446
+ }
1447
+ .widget-form-actions button[type="button"]:disabled:hover {
1448
+ background-color: #f5f5f5;
1449
+ border-color: #d9d9d9;
1450
+ }
1451
+ .widget-form-actions .widget-form-submit:disabled:hover {
1452
+ background-color: #91caff;
1453
+ }
1454
+
1455
+ /* 传统模式(无 actions 容器)的提交按钮 */
1456
+ .widget-form > button[type="button"]:last-child:disabled {
1457
+ background-color: #91caff;
1458
+ color: rgba(255, 255, 255, 0.8);
1459
+ cursor: not-allowed;
1460
+ }
1461
+ .widget-form > button[type="button"]:last-child:disabled:hover {
1462
+ background-color: #91caff;
1463
+ }
1464
+
1465
+ /* --- 选择题 MCQ 选项(反馈态对/错优先于置灰) --- */
1466
+ .mcq-choice:disabled {
1467
+ cursor: not-allowed;
1468
+ opacity: 1;
1469
+ }
1470
+ .mcq-choice:disabled:not(.mcq-choice-correct):not(.mcq-choice-incorrect):not(.mcq-choice-selected) {
1471
+ background-color: #f5f5f5;
1472
+ color: rgba(0, 0, 0, 0.25);
1473
+ border-color: #d9d9d9;
1474
+ }
1475
+
1476
+ /* --- 简答题 SAQ 输入框 --- */
1477
+ .saq-input:disabled {
1478
+ background-color: #f5f5f5;
1479
+ color: rgba(0, 0, 0, 0.25);
1480
+ border-color: #d9d9d9;
1481
+ cursor: not-allowed;
1482
+ }
1483
+
1484
+ /* --- Quiz 内题目选项与输入 --- */
1485
+ .quiz-choice:disabled {
1486
+ cursor: not-allowed;
1487
+ opacity: 1;
1488
+ }
1489
+ .quiz-choice:disabled:not(.quiz-choice-correct):not(.quiz-choice-incorrect):not(.quiz-choice-selected) {
1490
+ background-color: #f5f5f5;
1491
+ color: rgba(0, 0, 0, 0.25);
1492
+ border-color: #d9d9d9;
1493
+ }
1494
+ .quiz-input:disabled {
1495
+ background-color: #f5f5f5;
1496
+ color: rgba(0, 0, 0, 0.25);
1497
+ border-color: #d9d9d9;
1498
+ cursor: not-allowed;
1499
+ }
1500
+
1501
+ /* --- DatePicker 日期选择器 --- */
1502
+ .widget-date-picker {
1503
+ position: relative;
1504
+ }
1505
+
1506
+ .dp-input {
1507
+ display: flex;
1508
+ align-items: center;
1509
+ gap: 0.375rem;
1510
+ width: 100%;
1511
+ padding: 0.625rem 0.75rem;
1512
+ border: 1px solid #d9d9d9;
1513
+ border-radius: 6px;
1514
+ font-size: 0.875rem;
1515
+ background-color: #ffffff;
1516
+ cursor: pointer;
1517
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
1518
+ text-align: left;
1519
+ }
1520
+ .dp-input:hover { border-color: #4096ff; }
1521
+ .dp-input:focus-within,
1522
+ .dp-input:focus {
1523
+ outline: none;
1524
+ border-color: #1677ff;
1525
+ box-shadow: 0 0 0 2px rgba(5, 145, 255, 0.1);
1526
+ }
1527
+ .dp-input-icon { font-size: 0.875rem; }
1528
+ .dp-input-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1529
+ .dp-seg { flex: 1 1 0; min-width: 0; }
1530
+ .dp-sep { color: rgba(0, 0, 0, 0.45); font-size: 0.75rem; }
1531
+ .dp-placeholder { color: rgba(0, 0, 0, 0.45); }
1532
+ .dp-clear {
1533
+ padding: 0 0.25rem;
1534
+ color: rgba(0, 0, 0, 0.45);
1535
+ font-size: 1rem;
1536
+ line-height: 1;
1537
+ }
1538
+ .dp-clear:hover { color: rgba(0, 0, 0, 0.88); }
1539
+
1540
+ .dp-panel {
1541
+ position: absolute;
1542
+ z-index: 50;
1543
+ top: calc(100% + 4px);
1544
+ left: 0;
1545
+ width: 288px;
1546
+ padding: 0.75rem;
1547
+ background: #ffffff;
1548
+ border: 1px solid #d9d9d9;
1549
+ border-radius: 8px;
1550
+ box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
1551
+ }
1552
+ /* range 模式:双月历并排,宽度自适应 */
1553
+ .dp-panel.dp-range { width: auto; }
1554
+ .dp-panels { display: flex; gap: 0.75rem; }
1555
+ .dp-calendar { width: 264px; }
1556
+
1557
+ .dp-header {
1558
+ display: flex;
1559
+ align-items: center;
1560
+ justify-content: space-between;
1561
+ margin-bottom: 0.5rem;
1562
+ }
1563
+ .dp-title { font-weight: 600; font-size: 0.875rem; color: rgba(0, 0, 0, 0.88); }
1564
+ /* antd 风格:年份弱化、月份强调 */
1565
+ .dp-title-year { font-weight: 400; color: rgba(0, 0, 0, 0.45); margin-right: 0.25rem; }
1566
+ .dp-header-nav { display: flex; align-items: center; gap: 0.125rem; min-width: 3.25rem; }
1567
+ .dp-header-nav:last-child { justify-content: flex-end; }
1568
+ .dp-nav {
1569
+ width: 1.5rem;
1570
+ height: 1.5rem;
1571
+ display: flex;
1572
+ align-items: center;
1573
+ justify-content: center;
1574
+ border: none;
1575
+ background: transparent;
1576
+ color: rgba(0, 0, 0, 0.65);
1577
+ font-size: 1.1rem;
1578
+ cursor: pointer;
1579
+ border-radius: 4px;
1580
+ }
1581
+ .dp-nav:hover { background: #f5f5f5; color: rgba(0, 0, 0, 0.88); }
1582
+
1583
+ .dp-week-header {
1584
+ display: grid;
1585
+ grid-template-columns: repeat(7, 1fr);
1586
+ margin-bottom: 0.25rem;
1587
+ }
1588
+ .dp-week {
1589
+ text-align: center;
1590
+ font-size: 0.75rem;
1591
+ color: rgba(0, 0, 0, 0.45);
1592
+ padding: 0.25rem 0;
1593
+ }
1594
+
1595
+ .dp-grid {
1596
+ display: grid;
1597
+ grid-template-columns: repeat(7, 1fr);
1598
+ gap: 2px;
1599
+ }
1600
+ .dp-cell {
1601
+ position: relative;
1602
+ height: 2rem;
1603
+ border: none;
1604
+ background: transparent;
1605
+ border-radius: 4px;
1606
+ font-size: 0.8125rem;
1607
+ color: rgba(0, 0, 0, 0.88);
1608
+ cursor: pointer;
1609
+ transition: background 0.15s ease;
1610
+ }
1611
+ .dp-cell:hover:not(.dp-cell-disabled) { background: #f5f5f5; }
1612
+ .dp-cell-out { color: rgba(0, 0, 0, 0.25); }
1613
+ .dp-cell-disabled { color: rgba(0, 0, 0, 0.25); cursor: not-allowed; }
1614
+ .dp-cell-today { color: #1677ff; font-weight: 600; }
1615
+ .dp-cell-selected,
1616
+ .dp-cell-range-start,
1617
+ .dp-cell-range-end {
1618
+ background: #1677ff;
1619
+ color: #ffffff;
1620
+ font-weight: 600;
1621
+ }
1622
+ /* antd 风格:区间首尾胶囊圆角 */
1623
+ .dp-cell-range-start { border-radius: 4px 0 0 4px; }
1624
+ .dp-cell-range-end { border-radius: 0 4px 4px 0; }
1625
+ .dp-cell-range-start.dp-cell-range-end { border-radius: 4px; }
1626
+ .dp-cell-in-range { background: #e6f4ff; color: #1677ff; }
1627
+ .dp-cell-in-range:hover { background: #bae0ff; }
1628
+
1629
+ .dp-time {
1630
+ margin-top: 0.75rem;
1631
+ padding-top: 0.75rem;
1632
+ border-top: 1px solid #f0f0f0;
1633
+ }
1634
+ .dp-time-groups {
1635
+ display: flex;
1636
+ align-items: center;
1637
+ gap: 0.5rem;
1638
+ flex-wrap: wrap;
1639
+ }
1640
+ .dp-time-group {
1641
+ display: flex;
1642
+ align-items: center;
1643
+ gap: 0.25rem;
1644
+ }
1645
+ .dp-time-label { font-size: 0.75rem; color: rgba(0, 0, 0, 0.65); }
1646
+ .dp-time-arrow { color: rgba(0, 0, 0, 0.45); font-size: 0.75rem; }
1647
+ .dp-time-input {
1648
+ width: 2.75rem;
1649
+ padding: 0.25rem;
1650
+ text-align: center;
1651
+ border: 1px solid #d9d9d9;
1652
+ border-radius: 4px;
1653
+ font-size: 0.8125rem;
1654
+ }
1655
+ .dp-time-input:focus {
1656
+ outline: none;
1657
+ border-color: #1677ff;
1658
+ box-shadow: 0 0 0 2px rgba(5, 145, 255, 0.1);
1659
+ }
1660
+ .dp-time-sep { color: rgba(0, 0, 0, 0.65); }
1661
+ .dp-footer {
1662
+ display: flex;
1663
+ justify-content: flex-end;
1664
+ margin-top: 0.5rem;
1665
+ }
1666
+ .dp-ok {
1667
+ margin-left: auto;
1668
+ padding: 0.3rem 0.75rem;
1669
+ background: #1677ff;
1670
+ color: #ffffff;
1671
+ border: none;
1672
+ border-radius: 4px;
1673
+ font-size: 0.8125rem;
1674
+ cursor: pointer;
1675
+ }
1676
+ .dp-ok:hover:not(:disabled) { background: #4096ff; }
1677
+ .dp-ok:disabled { background: #91caff; cursor: not-allowed; }
1678
+
1679
+ /* --- DatePicker 输入按钮 --- */
1680
+ .dp-input:disabled {
1681
+ background-color: #f5f5f5;
1682
+ color: rgba(0, 0, 0, 0.25);
1683
+ border-color: #d9d9d9;
1684
+ cursor: not-allowed;
1685
+ }
1686
+ .dp-input:disabled:hover {
1687
+ border-color: #d9d9d9;
1688
+ }
1689
+
1690
+ /* --- Cascader 级联选择器 --- */
1691
+ .widget-cascader {
1692
+ position: relative;
1693
+ }
1694
+
1695
+ .cas-input {
1696
+ display: flex;
1697
+ align-items: center;
1698
+ gap: 0.375rem;
1699
+ width: 100%;
1700
+ padding: 0.625rem 0.75rem;
1701
+ border: 1px solid #d9d9d9;
1702
+ border-radius: 6px;
1703
+ font-size: 0.875rem;
1704
+ background-color: #ffffff;
1705
+ cursor: pointer;
1706
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
1707
+ text-align: left;
1708
+ }
1709
+ .cas-input:hover { border-color: #4096ff; }
1710
+ .cas-input:focus {
1711
+ outline: none;
1712
+ border-color: #1677ff;
1713
+ box-shadow: 0 0 0 3px rgba(5, 145, 255, 0.1);
1714
+ }
1715
+ /* 禁用态:置灰 + 禁止交互 */
1716
+ .cas-input:disabled {
1717
+ background-color: #f5f5f5;
1718
+ color: rgba(0, 0, 0, 0.25);
1719
+ border-color: #d9d9d9;
1720
+ cursor: not-allowed;
1721
+ }
1722
+ .cas-input:disabled:hover { border-color: #d9d9d9; }
1723
+
1724
+ .cas-input-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1 1 auto; min-width: 0; }
1725
+ .cas-placeholder { color: rgba(0, 0, 0, 0.45); }
1726
+ .cas-arrow { color: rgba(0, 0, 0, 0.45); font-size: 0.75rem; transition: transform 0.2s ease; }
1727
+ .cas-arrow-open { transform: rotate(180deg); }
1728
+ .cas-clear {
1729
+ padding: 0 0.25rem;
1730
+ color: rgba(0, 0, 0, 0.45);
1731
+ font-size: 1rem;
1732
+ line-height: 1;
1733
+ }
1734
+ .cas-clear:hover { color: rgba(0, 0, 0, 0.88); }
1735
+
1736
+ /* 级联面板:横向多级菜单并排 */
1737
+ .cas-panel {
1738
+ position: absolute;
1739
+ z-index: 50;
1740
+ top: calc(100% + 4px);
1741
+ left: 0;
1742
+ display: flex;
1743
+ background: #ffffff;
1744
+ border: 1px solid #d9d9d9;
1745
+ border-radius: 8px;
1746
+ box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
1747
+ }
1748
+ .cas-menu {
1749
+ width: 160px;
1750
+ max-height: 240px;
1751
+ overflow-y: auto;
1752
+ padding: 0.375rem;
1753
+ }
1754
+ .cas-menu + .cas-menu {
1755
+ border-left: 1px solid #f5f5f5;
1756
+ }
1757
+ .cas-option {
1758
+ display: flex;
1759
+ align-items: center;
1760
+ justify-content: space-between;
1761
+ gap: 0.5rem;
1762
+ width: 100%;
1763
+ padding: 0.375rem 0.5rem;
1764
+ border: none;
1765
+ border-radius: 4px;
1766
+ background: transparent;
1767
+ font-size: 0.875rem;
1768
+ color: rgba(0, 0, 0, 0.88);
1769
+ cursor: pointer;
1770
+ text-align: left;
1771
+ transition: background 0.15s ease;
1772
+ }
1773
+ .cas-option:hover { background: #f5f5f5; }
1774
+ .cas-option-active { background: #e6f4ff; color: #0958d9; font-weight: 500; }
1775
+ .cas-option-active:hover { background: #bae0ff; }
1776
+ .cas-option-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1777
+ .cas-option-arrow { color: rgba(0, 0, 0, 0.45); font-size: 0.875rem; flex: 0 0 auto; }
1778
+ .cas-empty {
1779
+ padding: 0.75rem 0.5rem;
1780
+ font-size: 0.8125rem;
1781
+ color: rgba(0, 0, 0, 0.45);
1782
+ text-align: center;
1783
+ }
1784
+
1785
+ /* --- Select 可搜索模式(searchable):面板内置搜索框的单列下拉 --- */
1786
+ /* 内容区:relative 供面板 absolute 定位(复用 .widget-field-content) */
1787
+ .widget-select-content {
1788
+ position: relative;
1789
+ display: flex;
1790
+ flex-direction: column;
1791
+ }
1792
+ /* 单列面板:纵向排搜索框 + 选项列表,宽度跟随触发按钮 */
1793
+ .cas-panel-single {
1794
+ flex-direction: column;
1795
+ min-width: 100%;
1796
+ width: auto;
1797
+ }
1798
+ /* 搜索框区:面板顶部固定,不随选项滚动 */
1799
+ .cas-search {
1800
+ padding: 0.5rem;
1801
+ border-bottom: 1px solid #f5f5f5;
1802
+ }
1803
+ .cas-search-input {
1804
+ width: 100%;
1805
+ padding: 0.375rem 0.625rem;
1806
+ border: 1px solid #d9d9d9;
1807
+ border-radius: 4px;
1808
+ font-size: 0.8125rem;
1809
+ box-sizing: border-box;
1810
+ }
1811
+ .cas-search-input:focus {
1812
+ outline: none;
1813
+ border-color: #1677ff;
1814
+ box-shadow: 0 0 0 2px rgba(5, 145, 255, 0.1);
1815
+ }
1816
+ /* 选项列表:占满面板宽度并滚动 */
1817
+ .cas-menu-full {
1818
+ width: 100%;
1819
+ flex: 1 1 auto;
1820
+ min-width: 0;
1821
+ }
1822
+
1823
+ /* === Number Input(参考 antd InputNumber):右侧上下步进按钮 === */
1824
+ .widget-number-input {
1825
+ display: flex;
1826
+ flex-direction: column;
1827
+ gap: 0.5rem;
1828
+ }
1829
+
1830
+ .widget-number-input > .widget-field-content {
1831
+ width: 100%;
1832
+ max-width: 100%;
1833
+ }
1834
+
1835
+ .ni-wrap {
1836
+ position: relative;
1837
+ display: flex;
1838
+ width: 100%;
1839
+ max-width: 100%;
1840
+ box-sizing: border-box;
1841
+ }
1842
+
1843
+ .ni-wrap input {
1844
+ width: 100%;
1845
+ min-width: 0;
1846
+ box-sizing: border-box;
1847
+ padding: 0.6875rem 2rem 0.6875rem 0.75rem;
1848
+ border: 1px solid #d9d9d9;
1849
+ border-radius: 6px;
1850
+ font-size: 0.875rem;
1851
+ background-color: #ffffff;
1852
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
1853
+ }
1854
+
1855
+ .ni-wrap input:focus {
1856
+ outline: none;
1857
+ border-color: #1677ff;
1858
+ box-shadow: 0 0 0 3px rgba(5, 145, 255, 0.1);
1859
+ }
1860
+
1861
+ .ni-wrap input::placeholder {
1862
+ color: rgba(0, 0, 0, 0.45);
1863
+ }
1864
+
1865
+ .ni-wrap input.widget-input-error {
1866
+ border-color: #ff4d4f;
1867
+ }
1868
+
1869
+ .ni-wrap input.widget-input-error:focus {
1870
+ border-color: #ff4d4f;
1871
+ box-shadow: 0 0 0 3px rgba(255, 77, 79, 0.1);
1872
+ }
1873
+
1874
+ .ni-wrap:focus-within .ni-steps {
1875
+ border-color: #1677ff;
1876
+ }
1877
+
1878
+ .ni-steps {
1879
+ position: absolute;
1880
+ top: 1px;
1881
+ right: 1px;
1882
+ bottom: 1px;
1883
+ display: flex;
1884
+ flex-direction: column;
1885
+ width: 1.375rem;
1886
+ border-left: 1px solid #d9d9d9;
1887
+ border-radius: 0 5px 5px 0;
1888
+ background-color: #fafafa;
1889
+ overflow: hidden;
1890
+ }
1891
+
1892
+ .ni-steps button {
1893
+ flex: 1;
1894
+ display: flex;
1895
+ align-items: center;
1896
+ justify-content: center;
1897
+ padding: 0;
1898
+ border: none;
1899
+ background: transparent;
1900
+ color: rgba(0, 0, 0, 0.65);
1901
+ cursor: pointer;
1902
+ min-height: 0;
1903
+ }
1904
+
1905
+ .ni-step-down {
1906
+ border-top: 1px solid #d9d9d9;
1907
+ }
1908
+
1909
+ .ni-steps button:hover:not(:disabled) {
1910
+ color: #4096ff;
1911
+ background-color: #e6f4ff;
1912
+ }
1913
+
1914
+ /* === TreeSelect 下拉树选择器(参考 antd TreeSelect) === */
1915
+ .widget-tree-select {
1916
+ position: relative;
1917
+ }
1918
+
1919
+ .ts-trigger {
1920
+ position: relative;
1921
+ display: flex;
1922
+ align-items: center;
1923
+ gap: 0.375rem;
1924
+ width: 100%;
1925
+ padding: 0.625rem 0.75rem;
1926
+ border: 1px solid #d9d9d9;
1927
+ border-radius: 6px;
1928
+ font-size: 0.875rem;
1929
+ background-color: #ffffff;
1930
+ cursor: pointer;
1931
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
1932
+ text-align: left;
1933
+ }
1934
+ .ts-trigger:hover { border-color: #4096ff; }
1935
+ .ts-trigger:focus {
1936
+ outline: none;
1937
+ border-color: #1677ff;
1938
+ box-shadow: 0 0 0 2px rgba(5, 145, 255, 0.1);
1939
+ }
1940
+ .ts-trigger:disabled {
1941
+ background-color: #f5f5f5;
1942
+ color: rgba(0, 0, 0, 0.25);
1943
+ border-color: #d9d9d9;
1944
+ cursor: not-allowed;
1945
+ }
1946
+ .ts-trigger:disabled:hover { border-color: #d9d9d9; }
1947
+
1948
+ .ts-value {
1949
+ flex: 1 1 auto;
1950
+ min-width: 0;
1951
+ overflow: hidden;
1952
+ text-overflow: ellipsis;
1953
+ white-space: nowrap;
1954
+ color: rgba(0, 0, 0, 0.88);
1955
+ }
1956
+ .ts-placeholder {
1957
+ flex: 1 1 auto;
1958
+ color: rgba(0, 0, 0, 0.45);
1959
+ }
1960
+ .ts-placeholder-empty { color: rgba(0, 0, 0, 0.45); }
1961
+ .ts-arrow { color: rgba(0, 0, 0, 0.45); font-size: 0.75rem; transition: transform 0.2s ease; }
1962
+ .ts-arrow-open { transform: rotate(180deg); }
1963
+ .ts-clear {
1964
+ padding: 0 0.25rem;
1965
+ color: rgba(0, 0, 0, 0.45);
1966
+ font-size: 1rem;
1967
+ line-height: 1;
1968
+ }
1969
+ .ts-clear:hover { color: rgba(0, 0, 0, 0.88); }
1970
+
1971
+ /* 触发器悬浮提示:展示全部已选项(maxTagCount 截断时补全) */
1972
+ .ts-trigger[data-full]:not([data-full=''])::after {
1973
+ content: attr(data-full);
1974
+ position: absolute;
1975
+ top: calc(100% + 8px);
1976
+ left: 0;
1977
+ padding: 0.5rem 0.75rem;
1978
+ max-width: 18rem;
1979
+ width: max-content;
1980
+ white-space: normal;
1981
+ word-break: break-all;
1982
+ font-size: 0.75rem;
1983
+ font-weight: 400;
1984
+ text-align: left;
1985
+ color: #fafafa;
1986
+ background-color: rgba(0, 0, 0, 0.88);
1987
+ border-radius: 6px;
1988
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
1989
+ opacity: 0;
1990
+ visibility: hidden;
1991
+ pointer-events: none;
1992
+ transition: opacity 0.15s ease;
1993
+ z-index: 100;
1994
+ }
1995
+ .ts-trigger[data-full]:not([data-full='']):not([aria-expanded='true']):hover::after {
1996
+ opacity: 1;
1997
+ visibility: visible;
1998
+ }
1999
+
2000
+ /* 下拉面板:纵向排搜索框 + 工具栏 + 树节点列表 */
2001
+ .ts-panel {
2002
+ position: absolute;
2003
+ z-index: 50;
2004
+ top: calc(100% + 4px);
2005
+ left: 0;
2006
+ right: 0;
2007
+ display: flex;
2008
+ flex-direction: column;
2009
+ background: #ffffff;
2010
+ border: 1px solid #d9d9d9;
2011
+ border-radius: 8px;
2012
+ box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
2013
+ max-height: 280px;
2014
+ overflow: hidden;
2015
+ }
2016
+
2017
+ .ts-search {
2018
+ padding: 0.5rem;
2019
+ border-bottom: 1px solid #f0f0f0;
2020
+ flex-shrink: 0;
2021
+ }
2022
+ .ts-search-input {
2023
+ width: 100%;
2024
+ padding: 0.375rem 0.625rem;
2025
+ border: 1px solid #d9d9d9;
2026
+ border-radius: 4px;
2027
+ font-size: 0.8125rem;
2028
+ box-sizing: border-box;
2029
+ }
2030
+ .ts-search-input:focus {
2031
+ outline: none;
2032
+ border-color: #1677ff;
2033
+ box-shadow: 0 0 0 2px rgba(5, 145, 255, 0.1);
2034
+ }
2035
+
2036
+ .ts-toolbar {
2037
+ display: flex;
2038
+ gap: 0.5rem;
2039
+ padding: 0.375rem 0.5rem;
2040
+ border-bottom: 1px solid #f0f0f0;
2041
+ flex-shrink: 0;
2042
+ }
2043
+ .ts-tool-btn {
2044
+ padding: 0.125rem 0.5rem;
2045
+ border: 1px solid #d9d9d9;
2046
+ border-radius: 4px;
2047
+ background: #ffffff;
2048
+ font-size: 0.75rem;
2049
+ color: rgba(0, 0, 0, 0.65);
2050
+ cursor: pointer;
2051
+ transition: all 0.15s ease;
2052
+ }
2053
+ .ts-tool-btn:hover {
2054
+ border-color: #1677ff;
2055
+ color: #1677ff;
2056
+ }
2057
+
2058
+ .ts-tree {
2059
+ flex: 1 1 auto;
2060
+ overflow-y: auto;
2061
+ padding: 0.375rem 0;
2062
+ min-height: 60px;
2063
+ }
2064
+
2065
+ .ts-node {
2066
+ display: flex;
2067
+ align-items: center;
2068
+ gap: 0.25rem;
2069
+ padding: 0.25rem 0.5rem;
2070
+ cursor: pointer;
2071
+ border-radius: 4px;
2072
+ transition: background 0.15s ease;
2073
+ }
2074
+ .ts-node:hover { background: #f5f5f5; }
2075
+ .ts-node-selected { background: #e6f4ff; }
2076
+ /* 树连接线(antd treeLine):横向连线 + 纵向缩进引导线 */
2077
+ .ts-node.ts-tree-line { position: relative; }
2078
+ .ts-node.ts-tree-line::before {
2079
+ content: '';
2080
+ position: absolute;
2081
+ top: 0;
2082
+ bottom: 0;
2083
+ left: 8px;
2084
+ border-left: 1px solid #d9d9d9;
2085
+ }
2086
+ .ts-node.ts-tree-line:first-child::before { top: 50%; }
2087
+ .ts-node.ts-tree-line:last-child::before { bottom: 50%; }
2088
+ .ts-node.ts-tree-line::after {
2089
+ content: '';
2090
+ position: absolute;
2091
+ top: 50%;
2092
+ left: 8px;
2093
+ width: 12px;
2094
+ border-top: 1px solid #d9d9d9;
2095
+ }
2096
+
2097
+ .ts-expand-btn {
2098
+ display: flex;
2099
+ align-items: center;
2100
+ justify-content: center;
2101
+ width: 18px;
2102
+ height: 18px;
2103
+ border: none;
2104
+ background: transparent;
2105
+ padding: 0;
2106
+ cursor: pointer;
2107
+ flex-shrink: 0;
2108
+ }
2109
+ .ts-expand-arrow {
2110
+ font-size: 0.625rem;
2111
+ color: rgba(0, 0, 0, 0.45);
2112
+ transition: transform 0.2s ease;
2113
+ display: inline-block;
2114
+ }
2115
+ .ts-expand-arrow.ts-expanded { transform: rotate(90deg); }
2116
+
2117
+ .ts-loading-icon {
2118
+ display: inline-block;
2119
+ width: 12px;
2120
+ height: 12px;
2121
+ border: 2px solid #d9d9d9;
2122
+ border-top-color: #1677ff;
2123
+ border-radius: 50%;
2124
+ animation: ts-spin 0.8s linear infinite;
2125
+ }
2126
+ @keyframes ts-spin {
2127
+ to { transform: rotate(360deg); }
2128
+ }
2129
+
2130
+ .ts-leaf-spacer {
2131
+ display: inline-block;
2132
+ width: 18px;
2133
+ flex-shrink: 0;
2134
+ }
2135
+
2136
+ .ts-checkbox {
2137
+ display: flex;
2138
+ align-items: center;
2139
+ justify-content: center;
2140
+ width: 16px;
2141
+ height: 16px;
2142
+ border: 1px solid #d9d9d9;
2143
+ border-radius: 4px;
2144
+ background: #ffffff;
2145
+ cursor: pointer;
2146
+ flex-shrink: 0;
2147
+ transition: all 0.15s ease;
2148
+ padding: 0;
2149
+ }
2150
+ .ts-checkbox:hover { border-color: #1677ff; }
2151
+ .ts-checkbox.ts-checked {
2152
+ background: #1677ff;
2153
+ border-color: #1677ff;
2154
+ color: #ffffff;
2155
+ }
2156
+ .ts-checkbox.ts-indeterminate {
2157
+ background: #1677ff;
2158
+ border-color: #1677ff;
2159
+ color: #ffffff;
2160
+ }
2161
+
2162
+ .ts-check-icon {
2163
+ font-size: 0.75rem;
2164
+ font-weight: 700;
2165
+ line-height: 1;
2166
+ }
2167
+
2168
+ .ts-label {
2169
+ flex: 1 1 auto;
2170
+ min-width: 0;
2171
+ border: none;
2172
+ background: transparent;
2173
+ font-size: 0.875rem;
2174
+ color: rgba(0, 0, 0, 0.88);
2175
+ cursor: pointer;
2176
+ text-align: left;
2177
+ padding: 0;
2178
+ overflow: hidden;
2179
+ text-overflow: ellipsis;
2180
+ white-space: nowrap;
2181
+ }
2182
+ .ts-label.ts-label-selected { color: #1677ff; font-weight: 500; }
2183
+
2184
+ .ts-empty {
2185
+ padding: 0.75rem 0.5rem;
2186
+ font-size: 0.8125rem;
2187
+ color: rgba(0, 0, 0, 0.45);
2188
+ text-align: center;
1373
2189
  }