@c2-markdown-ui/svelte 0.0.0-stage → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1754 @@
1
+ /* C2 Markdown UI Svelte 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
+ /* === Inline form: 所有字段横排 (flex-wrap) === */
24
+ .widget-form.widget-form-inline {
25
+ flex-direction: row;
26
+ flex-wrap: wrap;
27
+ align-items: flex-end;
28
+ gap: 1rem;
29
+ }
30
+
31
+ .widget-form-inline .widget-form-field {
32
+ flex: 1 1 calc(33.333% - 1rem);
33
+ min-width: 180px;
34
+ }
35
+
36
+ /* 用户指定 columns 数时 */
37
+ .widget-form-inline[style*="--form-columns"] .widget-form-field {
38
+ flex-basis: calc((100% - (var(--form-columns) - 1) * 1rem) / var(--form-columns));
39
+ min-width: 120px;
40
+ }
41
+
42
+ /* inline 模式下 submit 按钮也保持一致 */
43
+ .widget-form-inline > button:last-child {
44
+ flex: 0 0 auto;
45
+ }
46
+
47
+ /* === Row 分组模式(24 栅格,类似 antd Row/Col) === */
48
+ .widget-form-row {
49
+ display: grid;
50
+ grid-template-columns: repeat(24, minmax(0, 1fr));
51
+ column-gap: var(--row-gutter, 1rem);
52
+ /* 行间距:与表单整体 gap 一致,避免行与行(含按钮行)紧贴 */
53
+ row-gap: 1rem;
54
+ }
55
+
56
+ /* === 传统 fields 模式 + 显式 span:切换为 24 栅格(无 span 字段占满整行) === */
57
+ .widget-form.widget-form-fields-grid {
58
+ display: grid;
59
+ grid-template-columns: repeat(24, minmax(0, 1fr));
60
+ column-gap: 1rem;
61
+ row-gap: 1rem;
62
+ align-items: start;
63
+ }
64
+
65
+ .widget-form-fields-grid .widget-form-field {
66
+ min-width: 0;
67
+ }
68
+
69
+ /* 按钮字段与 row 模式一致:文字横排自适应,不随窄 span 压缩成竖排 */
70
+ .widget-form-fields-grid .widget-form-field[data-field-type="button"] {
71
+ width: max-content;
72
+ max-width: 100%;
73
+ align-self: end;
74
+ padding-bottom: 0;
75
+ }
76
+
77
+ /* 操作按钮行:跨全部列,不被栅格分列 */
78
+ .widget-form-fields-grid .widget-form-actions {
79
+ grid-column: 1 / -1;
80
+ }
81
+
82
+ /* inline 模式 + 显式 span 覆盖 flex-basis 后,收回默认 flex-grow */
83
+ .widget-form-inline .widget-form-field[style*="flex: 0 1"] {
84
+ flex-grow: 0;
85
+ }
86
+
87
+ .widget-form-row .widget-form-field {
88
+ min-width: 0;
89
+ }
90
+
91
+ /* 按钮字段:栅格内宽度由文字横排自适应决定,不随窄 span 压缩成竖排 */
92
+ .widget-form-row .widget-form-field[data-field-type="button"] {
93
+ width: max-content;
94
+ max-width: 100%;
95
+ /* 与其他字段(label + 控件)基线对齐,保证上下间距视觉一致 */
96
+ align-self: end;
97
+ padding-bottom: 0;
98
+ }
99
+
100
+ /* 按钮文字不折行,横排自适应 */
101
+ .widget-button {
102
+ white-space: nowrap;
103
+ }
104
+
105
+ /* === 独立栅格组件 row/col(24 栅格,类似 antd Row/Col) === */
106
+ .widget-grid-row {
107
+ display: grid;
108
+ grid-template-columns: repeat(24, minmax(0, 1fr));
109
+ column-gap: var(--row-gutter, 1rem);
110
+ row-gap: 1rem;
111
+ margin: 1rem 0;
112
+ }
113
+
114
+ .widget-grid-col {
115
+ min-width: 0;
116
+ }
117
+
118
+ /* 按钮列:宽度由文字横排自适应,与其他列底部对齐 */
119
+ .widget-grid-col[data-field-type="button"] {
120
+ width: max-content;
121
+ max-width: 100%;
122
+ align-self: end;
123
+ }
124
+
125
+ /* === 纯文字组件 text(栅格/表单内静态文字) === */
126
+ .widget-text {
127
+ margin: 0;
128
+ font-size: 14px;
129
+ line-height: 1.6;
130
+ color: inherit;
131
+ word-break: break-word;
132
+ overflow-wrap: anywhere;
133
+ }
134
+
135
+ /* === 文字 Alert 风格(参考 antd Alert) === */
136
+ .widget-alert {
137
+ display: flex;
138
+ align-items: flex-start;
139
+ gap: 8px;
140
+ padding: 8px 12px;
141
+ border-radius: 8px;
142
+ border: 1px solid transparent;
143
+ font-size: 14px;
144
+ line-height: 1.5714;
145
+ word-break: break-word;
146
+ overflow-wrap: anywhere;
147
+ }
148
+
149
+ /* 图标:固定宽度对齐,圆形背景(antdOutlined 图标风格) */
150
+ .widget-alert .widget-alert-icon {
151
+ flex-shrink: 0;
152
+ display: inline-flex;
153
+ align-items: center;
154
+ justify-content: center;
155
+ width: 16px;
156
+ height: 16px;
157
+ font-size: 12px;
158
+ font-weight: 600;
159
+ font-style: normal;
160
+ line-height: 1;
161
+ border-radius: 50%;
162
+ margin-top: 2px;
163
+ user-select: none;
164
+ }
165
+
166
+ .widget-alert .widget-alert-message {
167
+ flex: 1 1 auto;
168
+ min-width: 0;
169
+ }
170
+
171
+ /* info:antd 蓝 */
172
+ .widget-alert-info {
173
+ background-color: #e6f4ff;
174
+ border-color: #91caff;
175
+ }
176
+ .widget-alert-info .widget-alert-icon {
177
+ color: #ffffff;
178
+ background-color: #1677ff;
179
+ }
180
+ .widget-alert-info .widget-alert-message {
181
+ color: #1677ff;
182
+ }
183
+
184
+ /* warning:antd 黄 */
185
+ .widget-alert-warning {
186
+ background-color: #fffbe6;
187
+ border-color: #ffe58f;
188
+ }
189
+ .widget-alert-warning .widget-alert-icon {
190
+ color: #ffffff;
191
+ background-color: #faad14;
192
+ }
193
+ .widget-alert-warning .widget-alert-message {
194
+ color: #d48806;
195
+ }
196
+
197
+ /* error:antd 红 */
198
+ .widget-alert-error {
199
+ background-color: #fff2f0;
200
+ border-color: #ffccc7;
201
+ }
202
+ .widget-alert-error .widget-alert-icon {
203
+ color: #ffffff;
204
+ background-color: #ff4d4f;
205
+ }
206
+ .widget-alert-error .widget-alert-message {
207
+ color: #ff4d4f;
208
+ }
209
+
210
+ .widget-form > button[type="button"]:last-child {
211
+ align-self: flex-start;
212
+ margin-top: 0.5rem;
213
+ padding: 0.75rem 1.5rem;
214
+ background-color: #1677ff;
215
+ color: #ffffff;
216
+ border: none;
217
+ border-radius: 6px;
218
+ font-size: 0.875rem;
219
+ font-weight: 500;
220
+ cursor: pointer;
221
+ transition: background-color 0.2s ease;
222
+ }
223
+
224
+ /* Form actions(提交/取消/清空按钮组,data-align 控制对齐) */
225
+ .widget-form-actions {
226
+ display: flex;
227
+ gap: 0.5rem;
228
+ margin-top: 0.5rem;
229
+ }
230
+
231
+ .widget-form-actions[data-align="left"] { justify-content: flex-start; }
232
+ .widget-form-actions[data-align="center"] { justify-content: center; }
233
+ .widget-form-actions[data-align="right"] { justify-content: flex-end; }
234
+
235
+ .widget-form-actions button[type="button"] {
236
+ padding: 0.75rem 1.5rem;
237
+ border-radius: 6px;
238
+ font-size: 0.875rem;
239
+ font-weight: 500;
240
+ cursor: pointer;
241
+ transition: background-color 0.2s ease;
242
+ }
243
+
244
+ .widget-form-actions .widget-form-submit {
245
+ border: none;
246
+ background-color: #1677ff;
247
+ color: #ffffff;
248
+ }
249
+
250
+ .widget-form-actions .widget-form-submit:hover {
251
+ background-color: #4096ff;
252
+ }
253
+
254
+ .widget-form-actions .widget-form-cancel,
255
+ .widget-form-actions .widget-form-reset {
256
+ background-color: #ffffff;
257
+ color: rgba(0, 0, 0, 0.88);
258
+ border: 1px solid #d9d9d9;
259
+ }
260
+
261
+ .widget-form-actions .widget-form-cancel:hover,
262
+ .widget-form-actions .widget-form-reset:hover {
263
+ background-color: #fafafa;
264
+ border-color: rgba(0, 0, 0, 0.45);
265
+ }
266
+
267
+ .widget-form-actions button[type="button"]:focus {
268
+ outline: none;
269
+ box-shadow: 0 0 0 2px #1677ff;
270
+ }
271
+
272
+ /* Button Group */
273
+
274
+ /* 单个按钮组件(大/中/小三档尺寸,背景色完全由 color 属性的内联 style 控制) */
275
+ .widget-button {
276
+ display: inline-flex;
277
+ align-items: center;
278
+ justify-content: center;
279
+ border: none;
280
+ border-radius: 6px;
281
+ font-weight: 500;
282
+ cursor: pointer;
283
+ transition: filter 0.2s ease;
284
+ }
285
+
286
+ .widget-button:hover { filter: brightness(0.9); }
287
+ .widget-button:focus { outline: none; box-shadow: 0 0 0 2px #1677ff; }
288
+
289
+ .widget-button.size-small { padding: 0.25rem 0.75rem; font-size: 0.75rem; }
290
+ .widget-button.size-medium { padding: 0.5rem 1.25rem; font-size: 0.875rem; }
291
+ .widget-button.size-large { padding: 0.75rem 1.75rem; font-size: 1rem; }
292
+ .widget-button-group {
293
+ display: flex;
294
+ flex-direction: column;
295
+ gap: 0.5rem;
296
+ }
297
+
298
+ .widget-button-group label {
299
+ font-weight: 500;
300
+ color: rgba(0, 0, 0, 0.88);
301
+ margin-bottom: 0.25rem;
302
+ }
303
+
304
+ .widget-button-group div[role="group"] {
305
+ display: flex;
306
+ gap: 0.25rem;
307
+ flex-wrap: wrap;
308
+ }
309
+
310
+ .widget-form .widget-button-group button,
311
+ .widget-button-group button {
312
+ padding: 0.5rem 1rem;
313
+ border: 1px solid #d9d9d9;
314
+ background-color: #ffffff;
315
+ color: rgba(0, 0, 0, 0.88);
316
+ border-radius: 6px;
317
+ cursor: pointer;
318
+ transition: all 0.2s ease;
319
+ font-size: 0.875rem;
320
+ font-weight: 500;
321
+ }
322
+
323
+ .widget-form .widget-button-group button:hover,
324
+ .widget-button-group button:hover {
325
+ background-color: #fafafa;
326
+ border-color: rgba(0, 0, 0, 0.45);
327
+ }
328
+
329
+ .widget-form .widget-button-group button[aria-pressed="true"],
330
+ .widget-button-group button[aria-pressed="true"] {
331
+ background-color: #1677ff;
332
+ color: #ffffff;
333
+ border-color: #1677ff;
334
+ }
335
+
336
+ .widget-form .widget-button-group button:focus,
337
+ .widget-button-group button:focus {
338
+ outline: none;
339
+ box-shadow: 0 0 0 2px rgba(5, 145, 255, 0.1);
340
+ }
341
+
342
+ /* Text Input */
343
+ .widget-text-input {
344
+ display: flex;
345
+ flex-direction: column;
346
+ gap: 0.5rem;
347
+ }
348
+
349
+ /* === 字段内容区与控件宽度(所有布局生效) ===
350
+ 内容区占满字段宽(纵向模式下 select/input 才能跟随栅格 span 自适应) */
351
+ .widget-text-input > .widget-field-content,
352
+ .selector > .widget-field-content,
353
+ .selector-multi > .widget-field-content,
354
+ .widget-cascader > .widget-field-content,
355
+ .widget-slider > .widget-field-content {
356
+ width: 100%;
357
+ max-width: 100%;
358
+ }
359
+
360
+ /* 控件填满内容区:text input / select 拉伸到栅格列宽 */
361
+ .widget-text-input input[type="text"],
362
+ .selector select {
363
+ width: 100%;
364
+ max-width: 100%;
365
+ box-sizing: border-box;
366
+ }
367
+
368
+ /* 多选勾选组 / slider 容器同样填满 */
369
+ .widget-field-content > .checkbox-group,
370
+ .widget-field-content > .radio-group,
371
+ .widget-field-content > .slider-container {
372
+ width: 100%;
373
+ max-width: 100%;
374
+ }
375
+
376
+ /* === 表单项说明图标(hint):label 后 ⓘ,悬浮显示 tooltip === */
377
+ .widget-label-row {
378
+ display: flex;
379
+ align-items: center;
380
+ gap: 0.375rem;
381
+ }
382
+
383
+ /* === 表单左右布局(layout:horizontal):label 与内容同一行 === */
384
+ /* CSS 变量由 Form.svelte 根容器注入:
385
+ --form-label-width:label 固定宽度(默认 80px)
386
+ --form-content-width:内容宽度(未设置则 flex 填满剩余空间) */
387
+
388
+ /* 字段组件整体横排:label-row 固定宽 + 控件区填满 */
389
+ .widget-form-layout-horizontal .widget-form-field > .widget-text-input,
390
+ .widget-form-layout-horizontal .widget-form-field > .selector,
391
+ .widget-form-layout-horizontal .widget-form-field > .selector-multi,
392
+ .widget-form-layout-horizontal .widget-form-field > .widget-cascader,
393
+ .widget-form-layout-horizontal .widget-form-field > .widget-slider,
394
+ .widget-form-layout-horizontal .widget-form-field > .widget-switch {
395
+ display: flex;
396
+ flex-direction: row;
397
+ align-items: flex-start;
398
+ gap: 0.75rem;
399
+ }
400
+
401
+ /* label 行:固定宽度、右对齐、不收缩;超宽省略 */
402
+ .widget-form-layout-horizontal .widget-label-row {
403
+ flex: 0 0 var(--form-label-width, 80px);
404
+ width: var(--form-label-width, 80px);
405
+ justify-content: flex-end;
406
+ text-align: right;
407
+ }
408
+
409
+ /* label 文本超宽省略,悬浮完整显示 */
410
+ .widget-form-layout-horizontal .widget-label-row > label,
411
+ .widget-form-layout-horizontal .widget-label-row > .selector-multi-label {
412
+ overflow: hidden;
413
+ text-overflow: ellipsis;
414
+ white-space: nowrap;
415
+ }
416
+
417
+ /* 必填红星随行内排布(label-row 已 flex-end 对齐) */
418
+ .widget-form-layout-horizontal .widget-required-mark {
419
+ order: -1;
420
+ }
421
+
422
+ /* 内容区:跟随 label 之后填满剩余空间(或指定宽度);内部纵向排控件+错误提示 */
423
+ .widget-form-layout-horizontal .widget-text-input > .widget-field-content,
424
+ .widget-form-layout-horizontal .selector > .widget-field-content,
425
+ .widget-form-layout-horizontal .selector-multi > .widget-field-content,
426
+ .widget-form-layout-horizontal .widget-cascader > .widget-field-content,
427
+ .widget-form-layout-horizontal .widget-slider > .widget-field-content,
428
+ .widget-form-layout-horizontal .widget-switch > .widget-field-content {
429
+ flex: 1 1 auto;
430
+ width: var(--form-content-width, auto);
431
+ max-width: 100%;
432
+ /* 允许收缩到 0:窄容器(如小 span 栅格)时不溢出 */
433
+ min-width: 0;
434
+ display: flex;
435
+ flex-direction: column;
436
+ gap: 0.375rem;
437
+ }
438
+
439
+ /* 内容区内部控件填满内容区 */
440
+ .widget-form-layout-horizontal .widget-field-content > input,
441
+ .widget-form-layout-horizontal .widget-field-content > select,
442
+ .widget-form-layout-horizontal .widget-field-content > .slider-container,
443
+ .widget-form-layout-horizontal .widget-field-content > .checkbox-group,
444
+ .widget-form-layout-horizontal .widget-field-content > .radio-group {
445
+ width: 100%;
446
+ max-width: 100%;
447
+ }
448
+
449
+ /* 指定内容宽度时按该宽度排布,但允许收缩避免窄容器溢出 */
450
+ .widget-form-layout-horizontal[style*="--form-content-width"] .widget-text-input > .widget-field-content,
451
+ .widget-form-layout-horizontal[style*="--form-content-width"] .selector > .widget-field-content,
452
+ .widget-form-layout-horizontal[style*="--form-content-width"] .selector-multi > .widget-field-content,
453
+ .widget-form-layout-horizontal[style*="--form-content-width"] .widget-cascader > .widget-field-content,
454
+ .widget-form-layout-horizontal[style*="--form-content-width"] .widget-slider > .widget-field-content,
455
+ .widget-form-layout-horizontal[style*="--form-content-width"] .widget-switch > .widget-field-content {
456
+ flex: 0 1 var(--form-content-width);
457
+ }
458
+
459
+ /* 无 label 字段(纯 placeholder):内容对齐留出 label 列空位,视觉整齐 */
460
+ .widget-form-layout-horizontal .widget-form-field > .widget-text-input:not(:has(.widget-label-row)) > .widget-field-content,
461
+ .widget-form-layout-horizontal .widget-form-field > .selector:not(:has(.widget-label-row)) > .widget-field-content,
462
+ .widget-form-layout-horizontal .widget-form-field > .selector-multi:not(:has(.widget-label-row)) > .widget-field-content,
463
+ .widget-form-layout-horizontal .widget-form-field > .widget-cascader:not(:has(.widget-label-row)) > .widget-field-content,
464
+ .widget-form-layout-horizontal .widget-form-field > .widget-slider:not(:has(.widget-label-row)) > .widget-field-content,
465
+ .widget-form-layout-horizontal .widget-form-field > .widget-switch:not(:has(.widget-label-row)) > .widget-field-content {
466
+ margin-left: calc(var(--form-label-width, 80px) + 0.75rem);
467
+ }
468
+
469
+ /* inline 模式 + 左右布局组合:字段内 label/内容横排,字段间照常 flex-wrap */
470
+ .widget-form-layout-horizontal.widget-form-inline .widget-form-field {
471
+ display: flex;
472
+ align-items: flex-start;
473
+ }
474
+
475
+ .widget-hint {
476
+ position: relative;
477
+ display: inline-flex;
478
+ align-items: center;
479
+ justify-content: center;
480
+ width: 1rem;
481
+ height: 1rem;
482
+ font-size: 0.75rem;
483
+ font-weight: 600;
484
+ font-style: normal;
485
+ line-height: 1;
486
+ color: rgba(0, 0, 0, 0.65);
487
+ border: 1px solid #d9d9d9;
488
+ border-radius: 50%;
489
+ background-color: #fafafa;
490
+ cursor: help;
491
+ flex-shrink: 0;
492
+ user-select: none;
493
+ }
494
+
495
+ .widget-hint:hover {
496
+ color: #4096ff;
497
+ border-color: #4096ff;
498
+ background-color: #e6f4ff;
499
+ }
500
+
501
+ /* tooltip 气泡:纯 CSS,向上弹出 */
502
+ .widget-hint::before {
503
+ content: attr(data-hint);
504
+ position: absolute;
505
+ bottom: calc(100% + 8px);
506
+ left: 50%;
507
+ transform: translateX(-50%) translateY(4px);
508
+ padding: 0.5rem 0.75rem;
509
+ min-width: 8rem;
510
+ max-width: 18rem;
511
+ width: max-content;
512
+ white-space: normal;
513
+ font-size: 0.75rem;
514
+ font-weight: 400;
515
+ color: #fafafa;
516
+ background-color: rgba(0, 0, 0, 0.88);
517
+ border-radius: 6px;
518
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
519
+ opacity: 0;
520
+ visibility: hidden;
521
+ pointer-events: none;
522
+ transition: opacity 0.15s ease, transform 0.15s ease;
523
+ z-index: 100;
524
+ }
525
+
526
+ /* tooltip 小三角 */
527
+ .widget-hint::after {
528
+ content: "";
529
+ position: absolute;
530
+ bottom: calc(100% + 3px);
531
+ left: 50%;
532
+ transform: translateX(-50%) translateY(4px);
533
+ border: 5px solid transparent;
534
+ border-top-color: rgba(0, 0, 0, 0.88);
535
+ opacity: 0;
536
+ visibility: hidden;
537
+ pointer-events: none;
538
+ transition: opacity 0.15s ease, transform 0.15s ease;
539
+ z-index: 100;
540
+ }
541
+
542
+ .widget-hint:hover::before,
543
+ .widget-hint:hover::after,
544
+ .widget-hint:focus-visible::before,
545
+ .widget-hint:focus-visible::after {
546
+ opacity: 1;
547
+ visibility: visible;
548
+ transform: translateX(-50%) translateY(0);
549
+ }
550
+
551
+ /* === 表单项校验:必填红星 / 错误提示 / 红边框 === */
552
+
553
+ /* 必填标记:label 前红色 * */
554
+ .widget-required-mark {
555
+ color: #ff4d4f;
556
+ font-weight: 600;
557
+ line-height: 1;
558
+ flex-shrink: 0;
559
+ user-select: none;
560
+ }
561
+
562
+ /* 校验错误提示文案 */
563
+ .widget-error-text {
564
+ font-size: 0.75rem;
565
+ color: #ff4d4f;
566
+ line-height: 1.4;
567
+ margin-top: -0.25rem;
568
+ }
569
+
570
+ /* 输入框错误态:红边框 + 淡红聚焦光晕 */
571
+ .widget-text-input input.widget-input-error {
572
+ border-color: #ff4d4f;
573
+ }
574
+
575
+ .widget-text-input input.widget-input-error:focus {
576
+ border-color: #ff4d4f;
577
+ box-shadow: 0 0 0 3px rgba(255, 77, 79, 0.1);
578
+ }
579
+
580
+ /* 多选组错误态:checkbox 容器红边框 */
581
+ .widget-field-error .checkbox-group,
582
+ .widget-field-error .radio-group {
583
+ border-color: #ff4d4f;
584
+ }
585
+
586
+ .widget-text-input label {
587
+ font-weight: 500;
588
+ color: rgba(0, 0, 0, 0.88);
589
+ }
590
+
591
+ .widget-text-input input[type="text"] {
592
+ padding: 0.75rem;
593
+ border: 1px solid #d9d9d9;
594
+ border-radius: 6px;
595
+ font-size: 0.875rem;
596
+ background-color: #ffffff;
597
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
598
+ }
599
+
600
+ .widget-text-input input[type="text"]:focus {
601
+ outline: none;
602
+ border-color: #1677ff;
603
+ box-shadow: 0 0 0 3px rgba(5, 145, 255, 0.1);
604
+ }
605
+
606
+ .widget-text-input input[type="text"]::placeholder {
607
+ color: rgba(0, 0, 0, 0.45);
608
+ }
609
+
610
+ /* === Number Input(参考 antd InputNumber):右侧上下步进按钮 === */
611
+ .widget-number-input {
612
+ display: flex;
613
+ flex-direction: column;
614
+ gap: 0.5rem;
615
+ }
616
+
617
+ .widget-number-input > .widget-field-content {
618
+ width: 100%;
619
+ max-width: 100%;
620
+ }
621
+
622
+ .ni-wrap {
623
+ position: relative;
624
+ display: flex;
625
+ width: 100%;
626
+ max-width: 100%;
627
+ box-sizing: border-box;
628
+ }
629
+
630
+ .ni-wrap input {
631
+ width: 100%;
632
+ min-width: 0;
633
+ box-sizing: border-box;
634
+ padding: 0.6875rem 2rem 0.6875rem 0.75rem;
635
+ border: 1px solid #d9d9d9;
636
+ border-radius: 6px;
637
+ font-size: 0.875rem;
638
+ background-color: #ffffff;
639
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
640
+ }
641
+
642
+ .ni-wrap input:focus {
643
+ outline: none;
644
+ border-color: #1677ff;
645
+ box-shadow: 0 0 0 3px rgba(5, 145, 255, 0.1);
646
+ }
647
+
648
+ .ni-wrap input::placeholder {
649
+ color: rgba(0, 0, 0, 0.45);
650
+ }
651
+
652
+ .ni-wrap input.widget-input-error {
653
+ border-color: #ff4d4f;
654
+ }
655
+
656
+ .ni-wrap input.widget-input-error:focus {
657
+ border-color: #ff4d4f;
658
+ box-shadow: 0 0 0 3px rgba(255, 77, 79, 0.1);
659
+ }
660
+
661
+ .ni-wrap:focus-within .ni-steps {
662
+ border-color: #1677ff;
663
+ }
664
+
665
+ .ni-steps {
666
+ position: absolute;
667
+ top: 1px;
668
+ right: 1px;
669
+ bottom: 1px;
670
+ display: flex;
671
+ flex-direction: column;
672
+ width: 1.375rem;
673
+ border-left: 1px solid #d9d9d9;
674
+ border-radius: 0 5px 5px 0;
675
+ background-color: #fafafa;
676
+ overflow: hidden;
677
+ }
678
+
679
+ .ni-steps button {
680
+ flex: 1;
681
+ display: flex;
682
+ align-items: center;
683
+ justify-content: center;
684
+ padding: 0;
685
+ border: none;
686
+ background: transparent;
687
+ color: rgba(0, 0, 0, 0.65);
688
+ cursor: pointer;
689
+ min-height: 0;
690
+ }
691
+
692
+ .ni-step-down {
693
+ border-top: 1px solid #d9d9d9;
694
+ }
695
+
696
+ .ni-steps button:hover:not(:disabled) {
697
+ color: #4096ff;
698
+ background-color: #e6f4ff;
699
+ }
700
+
701
+ .ni-steps button:disabled {
702
+ color: #d9d9d9;
703
+ cursor: not-allowed;
704
+ }
705
+
706
+ /* 表单左右布局:与其他字段组件一致的横排规则 */
707
+ .widget-form-layout-horizontal .widget-form-field > .widget-number-input {
708
+ display: flex;
709
+ flex-direction: row;
710
+ align-items: flex-start;
711
+ gap: 0.75rem;
712
+ }
713
+
714
+ .widget-form-layout-horizontal .widget-number-input > .widget-field-content {
715
+ flex: 1 1 auto;
716
+ width: var(--form-content-width, auto);
717
+ max-width: 100%;
718
+ min-width: 0;
719
+ display: flex;
720
+ flex-direction: column;
721
+ gap: 0.375rem;
722
+ }
723
+
724
+ .widget-form-layout-horizontal[style*="--form-content-width"] .widget-number-input > .widget-field-content {
725
+ flex: 0 1 var(--form-content-width);
726
+ }
727
+
728
+ .widget-form-layout-horizontal .widget-form-field > .widget-number-input:not(:has(.widget-label-row)) > .widget-field-content {
729
+ margin-left: calc(var(--form-label-width, 80px) + 0.75rem);
730
+ }
731
+
732
+ /* Select and Select Multi */
733
+ .selector,
734
+ .selector-multi {
735
+ display: flex;
736
+ flex-direction: column;
737
+ gap: 0.5rem;
738
+ }
739
+
740
+ .selector label,
741
+ .selector-multi-label {
742
+ font-weight: 500;
743
+ color: rgba(0, 0, 0, 0.88);
744
+ }
745
+
746
+ .selector select {
747
+ padding: 0.75rem;
748
+ border: 1px solid #d9d9d9;
749
+ border-radius: 6px;
750
+ font-size: 0.875rem;
751
+ background-color: #ffffff;
752
+ cursor: pointer;
753
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
754
+ }
755
+
756
+ .selector select:focus {
757
+ outline: none;
758
+ border-color: #1677ff;
759
+ box-shadow: 0 0 0 3px rgba(5, 145, 255, 0.1);
760
+ }
761
+
762
+ .selector option {
763
+ padding: 0.5rem;
764
+ }
765
+
766
+ /* Checkbox-based Multi Select */
767
+ .checkbox-group {
768
+ display: flex;
769
+ flex-direction: column;
770
+ gap: 0.5rem;
771
+ padding: 0.75rem;
772
+ border: 1px solid #d9d9d9;
773
+ border-radius: 6px;
774
+ background-color: #ffffff;
775
+ max-height: 200px;
776
+ overflow-y: auto;
777
+ }
778
+
779
+ /* 选项布局:横向(flex-wrap 换行);自定义列数(grid,列宽由 inline style 注入) */
780
+ .checkbox-group[data-direction="horizontal"] {
781
+ flex-direction: row;
782
+ flex-wrap: wrap;
783
+ gap: 0.5rem 1.5rem;
784
+ }
785
+
786
+ .checkbox-group[data-direction="grid"] {
787
+ display: grid;
788
+ gap: 0.5rem;
789
+ }
790
+
791
+ /* --- 单选 RadioGroup:圆点单选(antd Radio 默认样式) --- */
792
+ .radio-group {
793
+ display: flex;
794
+ flex-direction: column;
795
+ gap: 0.5rem;
796
+ padding: 0.75rem;
797
+ border: 1px solid #d9d9d9;
798
+ border-radius: 6px;
799
+ background-color: #ffffff;
800
+ width: 100%;
801
+ max-width: 100%;
802
+ box-sizing: border-box;
803
+ }
804
+
805
+ /* 选项布局:横向(flex-wrap 换行);自定义列数(grid,列宽由 inline style 注入) */
806
+ .radio-group[data-direction="horizontal"] {
807
+ flex-direction: row;
808
+ flex-wrap: wrap;
809
+ gap: 0.5rem 1.5rem;
810
+ }
811
+
812
+ .radio-group[data-direction="grid"] {
813
+ display: grid;
814
+ gap: 0.5rem;
815
+ }
816
+
817
+ .radio-item {
818
+ display: flex;
819
+ align-items: center;
820
+ gap: 0.5rem;
821
+ cursor: pointer;
822
+ padding: 0.25rem 0;
823
+ font-weight: normal;
824
+ }
825
+
826
+ .radio-item input[type="radio"] {
827
+ margin: 0;
828
+ cursor: pointer;
829
+ accent-color: #1677ff;
830
+ }
831
+
832
+ .radio-item span {
833
+ font-size: 0.875rem;
834
+ color: rgba(0, 0, 0, 0.88);
835
+ }
836
+
837
+ .radio-item:hover {
838
+ background-color: #fafafa;
839
+ border-radius: 4px;
840
+ margin: -0.25rem 0;
841
+ padding: 0.5rem 0.25rem;
842
+ }
843
+
844
+ /* --- 单选 RadioGroup:按钮组样式(antd Radio optionType:button) --- */
845
+ .radio-button-group {
846
+ display: flex;
847
+ gap: 0.25rem;
848
+ flex-wrap: wrap;
849
+ }
850
+
851
+ .radio-button-group[data-direction="vertical"] {
852
+ flex-direction: column;
853
+ flex-wrap: nowrap;
854
+ }
855
+
856
+ .radio-button-group[data-direction="grid"] {
857
+ display: grid;
858
+ gap: 0.5rem;
859
+ }
860
+
861
+ .checkbox-item {
862
+ display: flex;
863
+ align-items: center;
864
+ gap: 0.5rem;
865
+ cursor: pointer;
866
+ padding: 0.25rem 0;
867
+ font-weight: normal;
868
+ }
869
+
870
+ .checkbox-item input[type="checkbox"] {
871
+ margin: 0;
872
+ cursor: pointer;
873
+ }
874
+
875
+ .checkbox-item span {
876
+ font-size: 0.875rem;
877
+ color: rgba(0, 0, 0, 0.88);
878
+ }
879
+
880
+ .checkbox-item:hover {
881
+ background-color: #fafafa;
882
+ border-radius: 4px;
883
+ margin: -0.25rem 0;
884
+ padding: 0.5rem 0.25rem;
885
+ }
886
+
887
+ /* Slider */
888
+ .widget-slider {
889
+ display: flex;
890
+ flex-direction: column;
891
+ gap: 0.5rem;
892
+ }
893
+
894
+ .widget-slider label {
895
+ font-weight: 500;
896
+ color: rgba(0, 0, 0, 0.88);
897
+ }
898
+
899
+ .slider-container {
900
+ display: flex;
901
+ flex-direction: column;
902
+ gap: 0.25rem;
903
+ }
904
+
905
+ .slider-values {
906
+ display: flex;
907
+ justify-content: space-between;
908
+ align-items: center;
909
+ font-size: 0.75rem;
910
+ color: rgba(0, 0, 0, 0.65);
911
+ margin-bottom: 0.25rem;
912
+ }
913
+
914
+ .current-value {
915
+ font-weight: 600;
916
+ color: #1677ff;
917
+ background: #e6f4ff;
918
+ padding: 0.25rem 0.5rem;
919
+ border-radius: 4px;
920
+ min-width: 2rem;
921
+ text-align: center;
922
+ }
923
+
924
+ .min-value, .max-value {
925
+ font-weight: 500;
926
+ }
927
+
928
+ .widget-slider input[type="range"] {
929
+ width: 100%;
930
+ height: 6px;
931
+ border-radius: 3px;
932
+ background: #f0f0f0;
933
+ outline: none;
934
+ cursor: pointer;
935
+ }
936
+
937
+ .widget-slider input[type="range"]::-webkit-slider-thumb {
938
+ appearance: none;
939
+ width: 20px;
940
+ height: 20px;
941
+ border-radius: 50%;
942
+ background: #1677ff;
943
+ cursor: pointer;
944
+ transition: background-color 0.2s ease;
945
+ }
946
+
947
+ .widget-slider input[type="range"]::-webkit-slider-thumb:hover {
948
+ background: #4096ff;
949
+ }
950
+
951
+ .widget-slider input[type="range"]::-moz-range-thumb {
952
+ width: 20px;
953
+ height: 20px;
954
+ border-radius: 50%;
955
+ background: #1677ff;
956
+ cursor: pointer;
957
+ border: none;
958
+ transition: background-color 0.2s ease;
959
+ }
960
+
961
+ .widget-slider input[type="range"]::-moz-range-thumb:hover {
962
+ background: #4096ff;
963
+ }
964
+
965
+ /* Switch(参考 antd Switch):与其他字段同构——label-row 在前、内容在后,
966
+ 表单 layout:horizontal 时自动变为 label 在左、开关在右 */
967
+ .widget-switch {
968
+ display: flex;
969
+ flex-direction: column;
970
+ gap: 0.5rem;
971
+ }
972
+
973
+ .widget-switch label {
974
+ font-weight: 500;
975
+ color: rgba(0, 0, 0, 0.88);
976
+ }
977
+
978
+ .switch-track {
979
+ position: relative;
980
+ display: inline-flex;
981
+ align-items: center;
982
+ box-sizing: content-box;
983
+ width: 44px;
984
+ height: 22px;
985
+ padding: 0;
986
+ border: none;
987
+ border-radius: 11px;
988
+ background-color: rgba(0, 0, 0, 0.25);
989
+ cursor: pointer;
990
+ transition: background-color 0.2s ease;
991
+ flex-shrink: 0;
992
+ }
993
+
994
+ .switch-track[data-checked="true"] {
995
+ background-color: #1677ff;
996
+ }
997
+
998
+ .switch-track:hover:not(:disabled) {
999
+ background-color: rgba(0, 0, 0, 0.45);
1000
+ }
1001
+
1002
+ .switch-track[data-checked="true"]:hover:not(:disabled) {
1003
+ background-color: #4096ff;
1004
+ }
1005
+
1006
+ .switch-track .switch-thumb {
1007
+ display: block;
1008
+ width: 18px;
1009
+ height: 18px;
1010
+ margin: 2px;
1011
+ border-radius: 50%;
1012
+ background-color: #ffffff;
1013
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
1014
+ transition: transform 0.2s ease;
1015
+ }
1016
+
1017
+ .switch-track[data-checked="true"] .switch-thumb {
1018
+ transform: translateX(22px);
1019
+ }
1020
+
1021
+ .switch-track .switch-text {
1022
+ position: absolute;
1023
+ top: 50%;
1024
+ transform: translateY(-50%);
1025
+ font-size: 0.75rem;
1026
+ font-weight: 500;
1027
+ color: #ffffff;
1028
+ line-height: 1;
1029
+ user-select: none;
1030
+ }
1031
+
1032
+ .switch-track .switch-text-unchecked {
1033
+ right: 6px;
1034
+ }
1035
+
1036
+ .switch-track .switch-text-checked {
1037
+ left: 6px;
1038
+ }
1039
+
1040
+ /* 仅显示当前状态对应的文案 */
1041
+ .switch-track[data-checked="true"] .switch-text-unchecked {
1042
+ display: none;
1043
+ }
1044
+
1045
+ .switch-track[data-checked="false"] .switch-text-checked {
1046
+ display: none;
1047
+ }
1048
+
1049
+ .switch-track:disabled {
1050
+ cursor: not-allowed;
1051
+ opacity: 0.5;
1052
+ }
1053
+
1054
+ .switch-track:focus-visible {
1055
+ outline: none;
1056
+ box-shadow: 0 0 0 2px #1677ff;
1057
+ }
1058
+
1059
+ /* Form submit button styling - hover and focus states */
1060
+ .widget-form > button[type="button"]:last-child:hover {
1061
+ background-color: #4096ff;
1062
+ }
1063
+
1064
+ .widget-form > button[type="button"]:last-child:focus {
1065
+ outline: none;
1066
+ box-shadow: 0 0 0 2px rgba(5, 145, 255, 0.1);
1067
+ }
1068
+
1069
+ /* Error styling for unknown widgets */
1070
+ .widget span[style*="color:red"] {
1071
+ color: #ff4d4f !important;
1072
+ font-weight: 500;
1073
+ padding: 0.75rem;
1074
+ background-color: #fff2f0;
1075
+ border: 1px solid #ffccc7;
1076
+ border-radius: 6px;
1077
+ display: inline-block;
1078
+ }
1079
+
1080
+ /* Multiple Choice Question */
1081
+ .widget-mcq {
1082
+ display: flex;
1083
+ flex-direction: column;
1084
+ gap: 1rem;
1085
+ padding: 1.5rem;
1086
+ border: 1px solid #f0f0f0;
1087
+ border-radius: 8px;
1088
+ background-color: #ffffff;
1089
+ }
1090
+
1091
+ .mcq-question {
1092
+ font-weight: 600;
1093
+ font-size: 1.1rem;
1094
+ color: rgba(0, 0, 0, 0.88);
1095
+ margin-bottom: 0.5rem;
1096
+ }
1097
+
1098
+ .mcq-choices {
1099
+ display: flex;
1100
+ flex-direction: column;
1101
+ gap: 0.75rem;
1102
+ }
1103
+
1104
+ .mcq-choice {
1105
+ padding: 1rem;
1106
+ border: 2px solid #d9d9d9;
1107
+ border-radius: 8px;
1108
+ background-color: #ffffff;
1109
+ text-align: left;
1110
+ cursor: pointer;
1111
+ transition: all 0.2s ease;
1112
+ font-size: 0.9rem;
1113
+ }
1114
+
1115
+ .mcq-choice:hover:not(:disabled) {
1116
+ border-color: rgba(0, 0, 0, 0.45);
1117
+ background-color: #fafafa;
1118
+ }
1119
+
1120
+ .mcq-choice-selected {
1121
+ border-color: #1677ff;
1122
+ background-color: #e6f4ff;
1123
+ }
1124
+
1125
+ .mcq-choice-correct {
1126
+ border-color: #52c41a;
1127
+ background-color: #f6ffed;
1128
+ color: #389e0d;
1129
+ }
1130
+
1131
+ .mcq-choice-incorrect {
1132
+ border-color: #ff4d4f;
1133
+ background-color: #fff2f0;
1134
+ color: #cf1322;
1135
+ }
1136
+
1137
+ .mcq-choice:disabled {
1138
+ cursor: not-allowed;
1139
+ opacity: 0.8;
1140
+ }
1141
+
1142
+ .mcq-feedback {
1143
+ padding: 0.75rem;
1144
+ border-radius: 6px;
1145
+ font-weight: 500;
1146
+ font-size: 0.9rem;
1147
+ }
1148
+
1149
+ .mcq-feedback.correct {
1150
+ background-color: #f6ffed;
1151
+ color: #389e0d;
1152
+ border: 1px solid #b7eb8f;
1153
+ }
1154
+
1155
+ .mcq-feedback.incorrect {
1156
+ background-color: #fff2f0;
1157
+ color: #cf1322;
1158
+ border: 1px solid #ffccc7;
1159
+ }
1160
+
1161
+ /* Short Answer Question */
1162
+ .widget-saq {
1163
+ display: flex;
1164
+ flex-direction: column;
1165
+ gap: 1rem;
1166
+ padding: 1.5rem;
1167
+ border: 1px solid #f0f0f0;
1168
+ border-radius: 8px;
1169
+ background-color: #ffffff;
1170
+ }
1171
+
1172
+ .saq-question {
1173
+ font-weight: 600;
1174
+ font-size: 1.1rem;
1175
+ color: rgba(0, 0, 0, 0.88);
1176
+ margin-bottom: 0.5rem;
1177
+ }
1178
+
1179
+ .saq-input-container {
1180
+ display: flex;
1181
+ gap: 0.75rem;
1182
+ align-items: stretch;
1183
+ }
1184
+
1185
+ .saq-input {
1186
+ flex: 1;
1187
+ padding: 0.75rem;
1188
+ border: 2px solid #d9d9d9;
1189
+ border-radius: 6px;
1190
+ font-size: 0.9rem;
1191
+ background-color: #ffffff;
1192
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
1193
+ }
1194
+
1195
+ .saq-input:focus {
1196
+ outline: none;
1197
+ border-color: #1677ff;
1198
+ box-shadow: 0 0 0 3px rgba(5, 145, 255, 0.1);
1199
+ }
1200
+
1201
+ .saq-input-correct {
1202
+ border-color: #52c41a;
1203
+ background-color: #f6ffed;
1204
+ }
1205
+
1206
+ .saq-input-incorrect {
1207
+ border-color: #ff4d4f;
1208
+ background-color: #fff2f0;
1209
+ }
1210
+
1211
+ .saq-submit {
1212
+ padding: 0.75rem 1.25rem;
1213
+ background-color: #1677ff;
1214
+ color: #ffffff;
1215
+ border: none;
1216
+ border-radius: 6px;
1217
+ font-size: 0.875rem;
1218
+ font-weight: 500;
1219
+ cursor: pointer;
1220
+ transition: background-color 0.2s ease;
1221
+ white-space: nowrap;
1222
+ }
1223
+
1224
+ .saq-submit:hover:not(:disabled) {
1225
+ background-color: #4096ff;
1226
+ }
1227
+
1228
+ .saq-submit:disabled {
1229
+ background-color: #f5f5f5;
1230
+ color: rgba(0, 0, 0, 0.25);
1231
+ cursor: not-allowed;
1232
+ }
1233
+
1234
+ .saq-feedback {
1235
+ padding: 0.75rem;
1236
+ border-radius: 6px;
1237
+ font-weight: 500;
1238
+ font-size: 0.9rem;
1239
+ }
1240
+
1241
+ .saq-feedback.correct {
1242
+ background-color: #f6ffed;
1243
+ color: #389e0d;
1244
+ border: 1px solid #b7eb8f;
1245
+ }
1246
+
1247
+ .saq-feedback.incorrect {
1248
+ background-color: #fff2f0;
1249
+ color: #cf1322;
1250
+ border: 1px solid #ffccc7;
1251
+ }
1252
+
1253
+ /* Quiz Component */
1254
+ .widget-quiz {
1255
+ max-width: 800px;
1256
+ margin: 0 auto;
1257
+ background: #ffffff;
1258
+ border: 1px solid #f0f0f0;
1259
+ border-radius: 12px;
1260
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
1261
+ }
1262
+
1263
+ .quiz-header {
1264
+ padding: 2rem 2rem 1rem;
1265
+ border-bottom: 1px solid #f0f0f0;
1266
+ background: linear-gradient(135deg, #1677ff 0%, #0958d9 100%);
1267
+ color: white;
1268
+ border-radius: 12px 12px 0 0;
1269
+ }
1270
+
1271
+ .quiz-title {
1272
+ font-size: 1.5rem;
1273
+ font-weight: 700;
1274
+ margin: 0 0 1rem 0;
1275
+ text-align: center;
1276
+ color: white;
1277
+ }
1278
+
1279
+ .quiz-stats {
1280
+ display: flex;
1281
+ justify-content: space-between;
1282
+ align-items: center;
1283
+ gap: 2rem;
1284
+ flex-wrap: wrap;
1285
+ color: white;
1286
+ }
1287
+
1288
+ .quiz-progress {
1289
+ flex: 1;
1290
+ min-width: 200px;
1291
+ }
1292
+
1293
+ .quiz-progress-text {
1294
+ font-size: 0.9rem;
1295
+ font-weight: 500;
1296
+ margin-bottom: 0.5rem;
1297
+ display: block;
1298
+ color: white;
1299
+ }
1300
+
1301
+ .quiz-progress-bar {
1302
+ width: 100%;
1303
+ height: 8px;
1304
+ background: rgba(255, 255, 255, 0.2);
1305
+ border-radius: 4px;
1306
+ overflow: hidden;
1307
+ }
1308
+
1309
+ .quiz-progress-fill {
1310
+ height: 100%;
1311
+ background: linear-gradient(90deg, #52c41a, #73d13d);
1312
+ border-radius: 4px;
1313
+ transition: width 0.3s ease;
1314
+ }
1315
+
1316
+ .quiz-score {
1317
+ text-align: right;
1318
+ }
1319
+
1320
+ .quiz-score-text {
1321
+ font-size: 1.1rem;
1322
+ font-weight: 600;
1323
+ color: white;
1324
+ }
1325
+
1326
+ .quiz-questions {
1327
+ padding: 1.5rem;
1328
+ }
1329
+
1330
+ .quiz-question {
1331
+ margin-bottom: 2rem;
1332
+ padding: 1.5rem;
1333
+ border: 2px solid #f0f0f0;
1334
+ border-radius: 8px;
1335
+ background: #fafafa;
1336
+ transition: all 0.2s ease;
1337
+ }
1338
+
1339
+ .quiz-question:hover {
1340
+ border-color: #f0f0f0;
1341
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
1342
+ }
1343
+
1344
+ .quiz-question-header {
1345
+ display: flex;
1346
+ justify-content: space-between;
1347
+ align-items: flex-start;
1348
+ margin-bottom: 1rem;
1349
+ gap: 1rem;
1350
+ }
1351
+
1352
+ .quiz-question-text {
1353
+ font-size: 1.1rem;
1354
+ font-weight: 600;
1355
+ color: rgba(0, 0, 0, 0.88);
1356
+ margin: 0;
1357
+ flex: 1;
1358
+ }
1359
+
1360
+ .quiz-question-points {
1361
+ background: #1677ff;
1362
+ color: white;
1363
+ padding: 0.25rem 0.75rem;
1364
+ border-radius: 12px;
1365
+ font-size: 0.8rem;
1366
+ font-weight: 600;
1367
+ white-space: nowrap;
1368
+ }
1369
+
1370
+ .quiz-choices {
1371
+ display: flex;
1372
+ flex-direction: column;
1373
+ gap: 0.75rem;
1374
+ }
1375
+
1376
+ .quiz-choice {
1377
+ padding: 0.75rem 1rem;
1378
+ border: 2px solid #d9d9d9;
1379
+ border-radius: 6px;
1380
+ background: #ffffff;
1381
+ text-align: left;
1382
+ cursor: pointer;
1383
+ transition: all 0.2s ease;
1384
+ font-size: 0.95rem;
1385
+ }
1386
+
1387
+ .quiz-choice:hover:not(:disabled) {
1388
+ border-color: rgba(0, 0, 0, 0.45);
1389
+ background: #fafafa;
1390
+ }
1391
+
1392
+ .quiz-choice-selected { /* kept for parity if needed */
1393
+ border-color: #1677ff;
1394
+ background: #e6f4ff;
1395
+ }
1396
+
1397
+ .quiz-choice-correct {
1398
+ border-color: #52c41a;
1399
+ background: #f6ffed;
1400
+ color: #389e0d;
1401
+ }
1402
+
1403
+ .quiz-choice-incorrect {
1404
+ border-color: #ff4d4f;
1405
+ background: #fff2f0;
1406
+ color: #cf1322;
1407
+ }
1408
+
1409
+ .quiz-choice:disabled {
1410
+ cursor: not-allowed;
1411
+ opacity: 0.9;
1412
+ }
1413
+
1414
+ .quiz-input-container {
1415
+ display: flex;
1416
+ gap: 0.75rem;
1417
+ align-items: stretch;
1418
+ }
1419
+
1420
+ .quiz-input {
1421
+ flex: 1;
1422
+ padding: 0.75rem 1rem;
1423
+ border: 2px solid #d9d9d9;
1424
+ border-radius: 6px;
1425
+ font-size: 0.95rem;
1426
+ background: #ffffff;
1427
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
1428
+ }
1429
+
1430
+ .quiz-input:focus {
1431
+ outline: none;
1432
+ border-color: #1677ff;
1433
+ box-shadow: 0 0 0 3px rgba(5, 145, 255, 0.1);
1434
+ }
1435
+
1436
+ .quiz-input-correct {
1437
+ border-color: #52c41a;
1438
+ background: #f6ffed;
1439
+ }
1440
+
1441
+ .quiz-input-incorrect {
1442
+ border-color: #ff4d4f;
1443
+ background: #fff2f0;
1444
+ }
1445
+
1446
+ .quiz-submit {
1447
+ padding: 0.75rem 1.5rem;
1448
+ background: #1677ff;
1449
+ color: white;
1450
+ border: none;
1451
+ border-radius: 6px;
1452
+ font-size: 0.875rem;
1453
+ font-weight: 600;
1454
+ cursor: pointer;
1455
+ transition: background-color 0.2s ease;
1456
+ white-space: nowrap;
1457
+ }
1458
+
1459
+ .quiz-submit:hover:not(:disabled) {
1460
+ background: #4096ff;
1461
+ }
1462
+
1463
+ .quiz-submit:disabled {
1464
+ background-color: #f5f5f5;
1465
+ color: rgba(0, 0, 0, 0.25);
1466
+ cursor: not-allowed;
1467
+ }
1468
+
1469
+ .quiz-feedback {
1470
+ margin-top: 1rem;
1471
+ padding: 1rem;
1472
+ border-radius: 6px;
1473
+ font-weight: 600;
1474
+ font-size: 0.95rem;
1475
+ }
1476
+
1477
+ .quiz-feedback.correct {
1478
+ background: #f6ffed;
1479
+ color: #389e0d;
1480
+ border: 1px solid #b7eb8f;
1481
+ }
1482
+
1483
+ .quiz-feedback.incorrect {
1484
+ background: #fff2f0;
1485
+ color: #cf1322;
1486
+ border: 1px solid #ffccc7;
1487
+ }
1488
+
1489
+ .quiz-summary {
1490
+ margin-top: 2rem;
1491
+ padding: 2rem;
1492
+ background: linear-gradient(135deg, #fafafa 0%, #f0f0f0 100%);
1493
+ border-radius: 8px;
1494
+ text-align: center;
1495
+ border: 2px solid #f0f0f0;
1496
+ }
1497
+
1498
+ .quiz-summary h3 {
1499
+ font-size: 1.5rem;
1500
+ font-weight: 700;
1501
+ color: rgba(0, 0, 0, 0.88);
1502
+ margin: 0 0 1rem 0;
1503
+ }
1504
+
1505
+ .quiz-final-score {
1506
+ font-size: 1.2rem;
1507
+ font-weight: 600;
1508
+ color: rgba(0, 0, 0, 0.88);
1509
+ margin-bottom: 1rem;
1510
+ }
1511
+
1512
+ .quiz-result {
1513
+ font-size: 1.1rem;
1514
+ font-weight: 700;
1515
+ padding: 0.75rem 1.5rem;
1516
+ border-radius: 6px;
1517
+ display: inline-block;
1518
+ }
1519
+
1520
+ .quiz-result.passed {
1521
+ background: #f6ffed;
1522
+ color: #389e0d;
1523
+ border: 1px solid #b7eb8f;
1524
+ }
1525
+
1526
+ .quiz-result.failed {
1527
+ background: #fff2f0;
1528
+ color: #cf1322;
1529
+ border: 1px solid #ffccc7;
1530
+ }
1531
+
1532
+ /* Responsive design */
1533
+ @media (max-width: 640px) {
1534
+ .widget-button-group div[role="group"] {
1535
+ flex-direction: column;
1536
+ }
1537
+
1538
+ .widget-button-group button {
1539
+ width: 100%;
1540
+ }
1541
+
1542
+ .widget-form {
1543
+ padding: 1rem;
1544
+ }
1545
+ .saq-input-container {
1546
+ flex-direction: column;
1547
+ }
1548
+ .widget-mcq,
1549
+ .widget-saq,
1550
+ .widget-quiz {
1551
+ padding: 1rem;
1552
+ }
1553
+ }
1554
+
1555
+ /* ============================================================ */
1556
+ /* === Disabled 状态统一置灰样式(所有交互组件 disabled 后视觉反馈) === */
1557
+ /* ============================================================ */
1558
+
1559
+ /* --- 单按钮组件 Button:含内联 color 时仅置灰文字 --- */
1560
+ .widget-button:disabled {
1561
+ background-color: #f5f5f5 !important;
1562
+ color: rgba(0, 0, 0, 0.25) !important;
1563
+ cursor: not-allowed;
1564
+ filter: none;
1565
+ }
1566
+ .widget-button:disabled:hover { filter: none; }
1567
+
1568
+ /* --- 按钮组 ButtonGroup --- */
1569
+ .widget-form .widget-button-group button:disabled,
1570
+ .widget-button-group button:disabled {
1571
+ background-color: #f5f5f5;
1572
+ color: rgba(0, 0, 0, 0.25);
1573
+ border-color: #d9d9d9;
1574
+ cursor: not-allowed;
1575
+ opacity: 1;
1576
+ }
1577
+ /* 选中态按钮禁用后保持浅蓝底可辨识 */
1578
+ .widget-form .widget-button-group button[aria-pressed="true"]:disabled,
1579
+ .widget-button-group button[aria-pressed="true"]:disabled {
1580
+ background-color: #91caff;
1581
+ border-color: #91caff;
1582
+ color: rgba(255, 255, 255, 0.8);
1583
+ cursor: not-allowed;
1584
+ }
1585
+
1586
+ /* --- 文本输入 TextInput --- */
1587
+ .widget-text-input input[type="text"]:disabled {
1588
+ background-color: #f5f5f5;
1589
+ color: rgba(0, 0, 0, 0.25);
1590
+ border-color: #d9d9d9;
1591
+ cursor: not-allowed;
1592
+ }
1593
+
1594
+ /* --- 数字输入 NumberInput(输入框 + 步进按钮) --- */
1595
+ .ni-wrap input:disabled {
1596
+ background-color: #f5f5f5;
1597
+ color: rgba(0, 0, 0, 0.25);
1598
+ border-color: #d9d9d9;
1599
+ cursor: not-allowed;
1600
+ }
1601
+
1602
+ /* --- 滑块 Slider:轨道变浅 + 拇指置灰 --- */
1603
+ .widget-slider input[type="range"]:disabled {
1604
+ background: #f0f0f0;
1605
+ cursor: not-allowed;
1606
+ }
1607
+ .widget-slider input[type="range"]:disabled::-webkit-slider-thumb {
1608
+ background: #d9d9d9;
1609
+ cursor: not-allowed;
1610
+ }
1611
+ .widget-slider input[type="range"]:disabled::-moz-range-thumb {
1612
+ background: #d9d9d9;
1613
+ cursor: not-allowed;
1614
+ }
1615
+ .widget-slider input[type="range"]:disabled::-webkit-slider-thumb:hover {
1616
+ background: #d9d9d9;
1617
+ }
1618
+ .widget-slider input[type="range"]:disabled::-moz-range-thumb:hover {
1619
+ background: #d9d9d9;
1620
+ }
1621
+ /* 数字值徽标同步置灰 */
1622
+ .widget-slider:has(input:disabled) .current-value {
1623
+ color: rgba(0, 0, 0, 0.25);
1624
+ background: #f5f5f5;
1625
+ }
1626
+
1627
+ /* --- 下拉选择 Select --- */
1628
+ .selector select:disabled {
1629
+ background-color: #f5f5f5;
1630
+ color: rgba(0, 0, 0, 0.25);
1631
+ border-color: #d9d9d9;
1632
+ cursor: not-allowed;
1633
+ }
1634
+
1635
+ /* --- 多选 SelectMulti:checkbox 与文字置灰 --- */
1636
+ .checkbox-group:has(input:disabled) {
1637
+ background-color: #f5f5f5;
1638
+ border-color: #d9d9d9;
1639
+ }
1640
+ .checkbox-group:has(input:disabled) .checkbox-item {
1641
+ cursor: not-allowed;
1642
+ }
1643
+ .checkbox-group:has(input:disabled) .checkbox-item:hover {
1644
+ background-color: transparent;
1645
+ }
1646
+ .checkbox-group:has(input:disabled) .checkbox-item span {
1647
+ color: rgba(0, 0, 0, 0.25);
1648
+ }
1649
+
1650
+ /* --- 单选 RadioGroup:圆点与文字置灰 --- */
1651
+ .radio-group:has(input:disabled) {
1652
+ background-color: #f5f5f5;
1653
+ border-color: #d9d9d9;
1654
+ }
1655
+ .radio-group:has(input:disabled) .radio-item {
1656
+ cursor: not-allowed;
1657
+ }
1658
+ .radio-group:has(input:disabled) .radio-item:hover {
1659
+ background-color: transparent;
1660
+ }
1661
+ .radio-group:has(input:disabled) .radio-item span {
1662
+ color: rgba(0, 0, 0, 0.25);
1663
+ }
1664
+
1665
+ /* --- Form 提交/重置/取消按钮 --- */
1666
+ .widget-form-actions button[type="button"]:disabled {
1667
+ background-color: #f5f5f5;
1668
+ color: rgba(0, 0, 0, 0.25);
1669
+ border-color: #d9d9d9;
1670
+ cursor: not-allowed;
1671
+ box-shadow: none;
1672
+ }
1673
+ /* 主按钮禁用保持淡蓝底区分 */
1674
+ .widget-form-actions .widget-form-submit:disabled {
1675
+ background-color: #91caff;
1676
+ color: rgba(255, 255, 255, 0.8);
1677
+ }
1678
+ .widget-form-actions button[type="button"]:disabled:hover {
1679
+ background-color: #f5f5f5;
1680
+ border-color: #d9d9d9;
1681
+ }
1682
+ .widget-form-actions .widget-form-submit:disabled:hover {
1683
+ background-color: #91caff;
1684
+ }
1685
+
1686
+ /* 传统模式(无 actions 容器)的提交按钮 */
1687
+ .widget-form > button[type="button"]:last-child:disabled {
1688
+ background-color: #91caff;
1689
+ color: rgba(255, 255, 255, 0.8);
1690
+ cursor: not-allowed;
1691
+ }
1692
+ .widget-form > button[type="button"]:last-child:disabled:hover {
1693
+ background-color: #91caff;
1694
+ }
1695
+
1696
+ /* --- 选择题 MCQ 选项 --- */
1697
+ .mcq-choice:disabled {
1698
+ cursor: not-allowed;
1699
+ opacity: 1;
1700
+ }
1701
+ .mcq-choice:disabled:not(.mcq-choice-correct):not(.mcq-choice-incorrect):not(.mcq-choice-selected) {
1702
+ background-color: #f5f5f5;
1703
+ color: rgba(0, 0, 0, 0.25);
1704
+ border-color: #d9d9d9;
1705
+ }
1706
+ /* 已作答反馈态(对/错)优先于 disabled 置灰 */
1707
+ .mcq-choice:disabled.mcq-choice-correct,
1708
+ .mcq-choice:disabled.mcq-choice-incorrect {
1709
+ opacity: 1;
1710
+ }
1711
+
1712
+ /* --- 简答题 SAQ 输入框 --- */
1713
+ .saq-input:disabled {
1714
+ background-color: #f5f5f5;
1715
+ color: rgba(0, 0, 0, 0.25);
1716
+ border-color: #d9d9d9;
1717
+ cursor: not-allowed;
1718
+ }
1719
+
1720
+ /* --- Quiz 内题目选项与输入 --- */
1721
+ .quiz-choice:disabled {
1722
+ cursor: not-allowed;
1723
+ opacity: 1;
1724
+ }
1725
+ .quiz-choice:disabled:not(.quiz-choice-correct):not(.quiz-choice-incorrect):not(.quiz-choice-selected) {
1726
+ background-color: #f5f5f5;
1727
+ color: rgba(0, 0, 0, 0.25);
1728
+ border-color: #d9d9d9;
1729
+ }
1730
+ .quiz-input:disabled {
1731
+ background-color: #f5f5f5;
1732
+ color: rgba(0, 0, 0, 0.25);
1733
+ border-color: #d9d9d9;
1734
+ cursor: not-allowed;
1735
+ }
1736
+
1737
+ /* --- DatePicker 输入按钮(dp-input 样式在组件内嵌 <style> 中,此处补充禁用态) --- */
1738
+ .dp-input:disabled {
1739
+ background-color: #f5f5f5;
1740
+ color: rgba(0, 0, 0, 0.25);
1741
+ border-color: #d9d9d9;
1742
+ cursor: not-allowed;
1743
+ }
1744
+ .dp-input:disabled:hover {
1745
+ border-color: #d9d9d9;
1746
+ }
1747
+
1748
+ /* --- 兼容旧版 opacity 置灰(部分组件原有 opacity: 0.8/0.9) --- */
1749
+ .mcq-choice:disabled { opacity: 1; }
1750
+ .quiz-choice:disabled { opacity: 1; }
1751
+ .ni-steps button:disabled {
1752
+ color: #d9d9d9;
1753
+ cursor: not-allowed;
1754
+ }