niuma-ui 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -1
- package/package.json +1 -1
- package/src/__tests__/RsDatePicker.spec.ts +21 -0
- package/src/__tests__/RsDialog.spec.ts +61 -0
- package/src/__tests__/RsForm.spec.ts +5 -5
- package/src/__tests__/RsFormItem.spec.ts +478 -0
- package/src/__tests__/RsFormList.spec.ts +109 -0
- package/src/__tests__/RsInput.spec.ts +93 -0
- package/src/__tests__/RsInputNumber.spec.ts +33 -0
- package/src/__tests__/RsSelect.spec.ts +423 -1
- package/src/__tests__/RsSwitch.spec.ts +30 -0
- package/src/__tests__/RsTimePicker.spec.ts +9 -0
- package/src/__tests__/RsTooltip.spec.ts +43 -0
- package/src/__tests__/css-token.spec.ts +51 -0
- package/src/__tests__/date-picker-utils.spec.ts +49 -0
- package/src/__tests__/dialog-utils.spec.ts +43 -0
- package/src/__tests__/form-path.spec.ts +46 -0
- package/src/__tests__/form-rules.spec.ts +63 -0
- package/src/__tests__/theme.spec.ts +2 -0
- package/src/components/RsAlert.vue +1 -1
- package/src/components/RsAvatar.vue +1 -1
- package/src/components/RsBadge.vue +1 -1
- package/src/components/RsBreadcrumb.vue +1 -1
- package/src/components/RsButton.vue +4 -4
- package/src/components/RsCalendarGrid.vue +3 -3
- package/src/components/RsCard.vue +4 -4
- package/src/components/RsCodeBlock.vue +4 -4
- package/src/components/RsCodeEditor.vue +8 -8
- package/src/components/RsConfirmDialog.vue +2 -2
- package/src/components/RsContextMenu.vue +6 -4
- package/src/components/RsDatePicker.vue +75 -31
- package/src/components/RsDateTimePicker.vue +9 -1
- package/src/components/RsDescriptions.vue +2 -2
- package/src/components/RsDialog.vue +26 -16
- package/src/components/RsDrawer.vue +1 -1
- package/src/components/RsDropdown.vue +1 -1
- package/src/components/RsDynamicTags.vue +18 -4
- package/src/components/RsEmpty.vue +1 -1
- package/src/components/RsForm.vue +68 -1
- package/src/components/RsFormItem.vue +423 -0
- package/src/components/RsFormItemControl.vue +21 -0
- package/src/components/RsFormList.vue +117 -0
- package/src/components/RsInput.vue +411 -18
- package/src/components/RsInputNumber.vue +13 -4
- package/src/components/RsLink.vue +1 -1
- package/src/components/RsMarkdown.vue +5 -5
- package/src/components/RsMenu.vue +2 -2
- package/src/components/RsMonacoEditor.vue +9 -3
- package/src/components/RsPagination.vue +1 -1
- package/src/components/RsProseEditor.vue +3 -3
- package/src/components/RsSelect.vue +332 -611
- package/src/components/RsSidebarGroup.vue +1 -1
- package/src/components/RsSplitPane.vue +22 -1
- package/src/components/RsStatCard.vue +2 -2
- package/src/components/RsSteps.vue +2 -2
- package/src/components/RsSwitch.vue +20 -7
- package/src/components/RsTabs.vue +9 -9
- package/src/components/RsTag.vue +1 -1
- package/src/components/RsTerminal.vue +58 -19
- package/src/components/RsTimePicker.vue +28 -4
- package/src/components/RsTimePickerColumns.vue +4 -4
- package/src/components/RsToaster.vue +7 -7
- package/src/components/RsTooltip.vue +10 -1
- package/src/components/RsTooltipProvider.vue +11 -1
- package/src/components/RsTree.vue +6 -6
- package/src/components/RsUpload.vue +2 -2
- package/src/components/date-picker-utils.ts +113 -2
- package/src/components/dialog-utils.ts +37 -2
- package/src/components/form-item-control.ts +55 -0
- package/src/components/form-path.ts +92 -0
- package/src/components/form-rules.ts +64 -10
- package/src/components/form-utils.ts +94 -2
- package/src/components/select-utils.ts +272 -12
- package/src/components/table/RsTableHeaderFilter.vue +1 -1
- package/src/components/table/rs-table.css +1 -1
- package/src/components/use-rs-select.ts +436 -0
- package/src/composables/useRsConfig.ts +10 -3
- package/src/composables/useRsI18n.ts +16 -5
- package/src/index.ts +69 -1
- package/src/locale/interpolate.ts +32 -0
- package/src/locale/messages.ts +10 -0
- package/src/styles.css +68 -12
- package/src/theme/brand.example.css +4 -1
- package/src/theme/css-token.ts +107 -0
- package/src/theme/types.ts +1 -0
|
@@ -210,6 +210,10 @@ function finishDrag(index: number): void {
|
|
|
210
210
|
setDraggingUi(false, index)
|
|
211
211
|
const final = pendingDragSizes ?? sizes.value
|
|
212
212
|
pendingDragSizes = null
|
|
213
|
+
// 清掉拖拽期手写的 flex-grow,交回 Vue :style,避免残留内联样式干扰后续布局
|
|
214
|
+
paneElements().forEach((el) => {
|
|
215
|
+
el.style.removeProperty('flex-grow')
|
|
216
|
+
})
|
|
213
217
|
commit(final)
|
|
214
218
|
emitBoundaryTransitions(dragStartSizes, final)
|
|
215
219
|
emit('resize-end', final.slice())
|
|
@@ -369,12 +373,15 @@ function materializeAutoPanes(): void {
|
|
|
369
373
|
function paneStyle(index: number): Record<string, string> {
|
|
370
374
|
if (autoFlags.value[index]) {
|
|
371
375
|
const pane = props.panes[index]
|
|
376
|
+
const vertical = props.orientation === 'vertical'
|
|
377
|
+
// auto 面板必须按内容撑开;不能继承基类 min-height/min-width:0,否则在
|
|
378
|
+
// 「另一侧 flex-grow 吃满」的分栏里会被算成 0 高/宽(KeepAlive 切页后常见)。
|
|
372
379
|
const style: Record<string, string> = {
|
|
373
380
|
flexGrow: '0',
|
|
374
381
|
flexShrink: '0',
|
|
375
382
|
flexBasis: 'auto',
|
|
383
|
+
[vertical ? 'minHeight' : 'minWidth']: 'min-content',
|
|
376
384
|
}
|
|
377
|
-
const vertical = props.orientation === 'vertical'
|
|
378
385
|
if (typeof pane?.min === 'number' && pane.min > 0) {
|
|
379
386
|
style[vertical ? 'minHeight' : 'minWidth'] = `${pane.min}%`
|
|
380
387
|
}
|
|
@@ -523,6 +530,20 @@ defineExpose({ collapse, expand, reset, getSizes: () => sizes.value.slice() })
|
|
|
523
530
|
.rs-split__pane--auto {
|
|
524
531
|
/* 内容撑开;超出 max 时在面板内滚动 */
|
|
525
532
|
overflow: auto;
|
|
533
|
+
flex: 0 0 auto;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/* 覆盖基类 min-*:0,避免 auto 面板被弹性侧压成 0 */
|
|
537
|
+
.rs-split--vertical > .rs-split__pane--auto {
|
|
538
|
+
min-height: min-content;
|
|
539
|
+
height: auto;
|
|
540
|
+
max-height: none;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
.rs-split--horizontal > .rs-split__pane--auto {
|
|
544
|
+
min-width: min-content;
|
|
545
|
+
width: auto;
|
|
546
|
+
max-width: none;
|
|
526
547
|
}
|
|
527
548
|
|
|
528
549
|
.rs-split__pane--collapsed {
|
|
@@ -66,8 +66,8 @@ withDefaults(
|
|
|
66
66
|
.rs-stat-card__value {
|
|
67
67
|
margin-top: var(--rs-space-sm);
|
|
68
68
|
color: var(--rs-text);
|
|
69
|
-
font-size:
|
|
70
|
-
font-weight:
|
|
69
|
+
font-size: var(--rs-font-size-3xl);
|
|
70
|
+
font-weight: var(--rs-font-weight-bold);
|
|
71
71
|
line-height: 1.1;
|
|
72
72
|
}
|
|
73
73
|
.rs-stat-card__description {
|
|
@@ -97,7 +97,7 @@ function selectStep(item: RsStepItem): void {
|
|
|
97
97
|
background: var(--rs-surface-hover);
|
|
98
98
|
color: var(--rs-muted);
|
|
99
99
|
font-size: var(--rs-font-size-xs);
|
|
100
|
-
font-weight:
|
|
100
|
+
font-weight: var(--rs-font-weight-bold);
|
|
101
101
|
}
|
|
102
102
|
.rs-steps--sm .rs-steps__indicator {
|
|
103
103
|
width: 1.5rem;
|
|
@@ -119,7 +119,7 @@ function selectStep(item: RsStepItem): void {
|
|
|
119
119
|
.rs-steps__title {
|
|
120
120
|
color: var(--rs-text);
|
|
121
121
|
font-size: var(--rs-font-size-sm);
|
|
122
|
-
font-weight:
|
|
122
|
+
font-weight: var(--rs-font-weight-semibold);
|
|
123
123
|
}
|
|
124
124
|
.rs-steps__description {
|
|
125
125
|
color: var(--rs-muted);
|
|
@@ -4,7 +4,10 @@ import type { RsComponentSize } from '../theme/types'
|
|
|
4
4
|
import { SwitchRoot, SwitchThumb } from './reka'
|
|
5
5
|
import { useResolvedRsComponentSize } from './resolve-size'
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
/** Switch v-model 取值:默认 boolean,也可为业务码如 'Y'/'N'、1/0 */
|
|
8
|
+
export type RsSwitchValue = boolean | string | number
|
|
9
|
+
|
|
10
|
+
const model = defineModel<RsSwitchValue>({ default: false })
|
|
8
11
|
|
|
9
12
|
const props = withDefaults(
|
|
10
13
|
defineProps<{
|
|
@@ -13,32 +16,42 @@ const props = withDefaults(
|
|
|
13
16
|
/** 无障碍名称;有默认插槽文案时可省略 */
|
|
14
17
|
ariaLabel?: string
|
|
15
18
|
id?: string
|
|
19
|
+
/** 打开时写入 v-model 的值,默认 true */
|
|
20
|
+
checkedValue?: RsSwitchValue
|
|
21
|
+
/** 关闭时写入 v-model 的值,默认 false */
|
|
22
|
+
uncheckedValue?: RsSwitchValue
|
|
16
23
|
}>(),
|
|
17
24
|
{
|
|
18
25
|
disabled: false,
|
|
26
|
+
checkedValue: true,
|
|
27
|
+
uncheckedValue: false,
|
|
19
28
|
},
|
|
20
29
|
)
|
|
21
30
|
|
|
22
31
|
const emit = defineEmits<{
|
|
23
|
-
change: [value:
|
|
32
|
+
change: [value: RsSwitchValue]
|
|
24
33
|
}>()
|
|
25
34
|
|
|
26
35
|
const autoId = useId()
|
|
27
36
|
const inputId = computed(() => props.id || autoId)
|
|
28
37
|
const resolvedSize = useResolvedRsComponentSize(() => props.size)
|
|
38
|
+
/** Reka Switch 只吃 boolean;对外 v-model 按 checkedValue / uncheckedValue 映射 */
|
|
39
|
+
const isChecked = computed(() => Object.is(model.value, props.checkedValue))
|
|
29
40
|
|
|
30
41
|
const rootClass = computed(() => [
|
|
31
42
|
'rs-switch',
|
|
32
43
|
`rs-switch--${resolvedSize.value}`,
|
|
33
44
|
{
|
|
34
|
-
'rs-switch--checked':
|
|
45
|
+
'rs-switch--checked': isChecked.value,
|
|
35
46
|
'rs-switch--disabled': props.disabled,
|
|
36
47
|
},
|
|
37
48
|
])
|
|
38
49
|
|
|
39
|
-
function onUpdate(
|
|
40
|
-
|
|
41
|
-
|
|
50
|
+
function onUpdate(checked: boolean): void {
|
|
51
|
+
const next = checked ? props.checkedValue : props.uncheckedValue
|
|
52
|
+
if (Object.is(model.value, next)) return
|
|
53
|
+
model.value = next
|
|
54
|
+
emit('change', next)
|
|
42
55
|
}
|
|
43
56
|
</script>
|
|
44
57
|
|
|
@@ -47,7 +60,7 @@ function onUpdate(value: boolean): void {
|
|
|
47
60
|
<SwitchRoot
|
|
48
61
|
:id="inputId"
|
|
49
62
|
class="rs-switch__root"
|
|
50
|
-
:model-value="
|
|
63
|
+
:model-value="isChecked"
|
|
51
64
|
:disabled="disabled"
|
|
52
65
|
:aria-label="ariaLabel"
|
|
53
66
|
@update:model-value="onUpdate"
|
|
@@ -409,8 +409,8 @@ function onDragEnd(): void {
|
|
|
409
409
|
<div
|
|
410
410
|
ref="navViewportRef"
|
|
411
411
|
class="rs-tabs__nav-viewport"
|
|
412
|
-
@scroll="onNavScroll"
|
|
413
|
-
|
|
412
|
+
@scroll.passive="onNavScroll"
|
|
413
|
+
v-bind="useScrollOverflow ? { onWheel: onNavWheel } : {}"
|
|
414
414
|
>
|
|
415
415
|
<TabsList class="rs-tabs__list">
|
|
416
416
|
<RsContextMenu
|
|
@@ -679,7 +679,7 @@ function onDragEnd(): void {
|
|
|
679
679
|
}
|
|
680
680
|
|
|
681
681
|
.rs-tabs__trigger--fixed {
|
|
682
|
-
font-weight:
|
|
682
|
+
font-weight: var(--rs-font-weight-medium);
|
|
683
683
|
}
|
|
684
684
|
|
|
685
685
|
.rs-tabs--draggable .rs-tabs__trigger--movable {
|
|
@@ -733,7 +733,7 @@ function onDragEnd(): void {
|
|
|
733
733
|
background: var(--rs-surface-hover);
|
|
734
734
|
color: var(--rs-muted);
|
|
735
735
|
font-size: var(--rs-font-size-xs);
|
|
736
|
-
font-weight:
|
|
736
|
+
font-weight: var(--rs-font-weight-medium);
|
|
737
737
|
font-variant-numeric: tabular-nums;
|
|
738
738
|
line-height: 1.4;
|
|
739
739
|
}
|
|
@@ -910,7 +910,7 @@ function onDragEnd(): void {
|
|
|
910
910
|
|
|
911
911
|
.rs-tabs__more--active {
|
|
912
912
|
color: var(--rs-primary);
|
|
913
|
-
font-weight:
|
|
913
|
+
font-weight: var(--rs-font-weight-medium);
|
|
914
914
|
}
|
|
915
915
|
|
|
916
916
|
.rs-tabs__more-menu {
|
|
@@ -944,7 +944,7 @@ function onDragEnd(): void {
|
|
|
944
944
|
|
|
945
945
|
.rs-tabs__more-item--active {
|
|
946
946
|
color: var(--rs-primary);
|
|
947
|
-
font-weight:
|
|
947
|
+
font-weight: var(--rs-font-weight-medium);
|
|
948
948
|
background: color-mix(in srgb, var(--rs-primary) 12%, transparent);
|
|
949
949
|
}
|
|
950
950
|
|
|
@@ -1034,7 +1034,7 @@ function onDragEnd(): void {
|
|
|
1034
1034
|
|
|
1035
1035
|
.rs-tabs--line .rs-tabs__trigger[data-state='active'] {
|
|
1036
1036
|
color: var(--rs-primary);
|
|
1037
|
-
font-weight:
|
|
1037
|
+
font-weight: var(--rs-font-weight-medium);
|
|
1038
1038
|
}
|
|
1039
1039
|
|
|
1040
1040
|
.rs-tabs--line .rs-tabs__trigger[data-state='active']::after {
|
|
@@ -1113,7 +1113,7 @@ function onDragEnd(): void {
|
|
|
1113
1113
|
.rs-tabs--segmented .rs-tabs__trigger[data-state='active'] {
|
|
1114
1114
|
color: var(--rs-primary);
|
|
1115
1115
|
background: var(--rs-surface);
|
|
1116
|
-
font-weight:
|
|
1116
|
+
font-weight: var(--rs-font-weight-medium);
|
|
1117
1117
|
box-shadow: 0 1px 2px color-mix(in srgb, var(--rs-text) 8%, transparent);
|
|
1118
1118
|
}
|
|
1119
1119
|
|
|
@@ -1169,7 +1169,7 @@ function onDragEnd(): void {
|
|
|
1169
1169
|
|
|
1170
1170
|
.rs-tabs--card .rs-tabs__trigger[data-state='active'] {
|
|
1171
1171
|
color: var(--rs-primary);
|
|
1172
|
-
font-weight:
|
|
1172
|
+
font-weight: var(--rs-font-weight-medium);
|
|
1173
1173
|
background: var(--rs-surface);
|
|
1174
1174
|
border-color: var(--rs-border);
|
|
1175
1175
|
margin-bottom: -1px;
|
package/src/components/RsTag.vue
CHANGED
|
@@ -84,7 +84,7 @@ function onClose(event: MouseEvent): void {
|
|
|
84
84
|
gap: var(--rs-space-xs);
|
|
85
85
|
max-width: 100%;
|
|
86
86
|
border-radius: var(--rs-tag-radius, var(--rs-radius-sm));
|
|
87
|
-
font-weight: var(--rs-tag-font-weight,
|
|
87
|
+
font-weight: var(--rs-tag-font-weight, 400);
|
|
88
88
|
line-height: var(--rs-line-height-tight);
|
|
89
89
|
box-sizing: border-box;
|
|
90
90
|
vertical-align: middle;
|
|
@@ -5,6 +5,12 @@ import { Terminal } from '@xterm/xterm'
|
|
|
5
5
|
import '@xterm/xterm/css/xterm.css'
|
|
6
6
|
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
|
7
7
|
import { useRsI18n } from '../composables/useRsI18n'
|
|
8
|
+
import {
|
|
9
|
+
readTerminalFontFamily,
|
|
10
|
+
readTerminalFontSizePx,
|
|
11
|
+
readTerminalFontWeight,
|
|
12
|
+
readTerminalFontWeightBold,
|
|
13
|
+
} from '../theme/css-token'
|
|
8
14
|
import {
|
|
9
15
|
beginClipboardPrefetch,
|
|
10
16
|
copyTextToClipboard,
|
|
@@ -29,16 +35,33 @@ import {
|
|
|
29
35
|
|
|
30
36
|
const TERMINAL_LINE_HEIGHT = 1.2
|
|
31
37
|
|
|
38
|
+
type RsTerminalFontWeight =
|
|
39
|
+
| 'normal'
|
|
40
|
+
| 'bold'
|
|
41
|
+
| '100'
|
|
42
|
+
| '200'
|
|
43
|
+
| '300'
|
|
44
|
+
| '400'
|
|
45
|
+
| '500'
|
|
46
|
+
| '600'
|
|
47
|
+
| '700'
|
|
48
|
+
| '800'
|
|
49
|
+
| '900'
|
|
50
|
+
|
|
32
51
|
const props = withDefaults(
|
|
33
52
|
defineProps<{
|
|
34
53
|
loading?: boolean
|
|
35
54
|
overlay?: string
|
|
36
55
|
inputEnabled?: boolean
|
|
37
56
|
cursorBlink?: boolean
|
|
57
|
+
/** 缺省读取 `--rs-terminal-font-family` / `--rs-font-mono` */
|
|
38
58
|
fontFamily?: string
|
|
59
|
+
/** 缺省读取 `--rs-terminal-font-size`(对齐 `--rs-font-size-sm`) */
|
|
39
60
|
fontSize?: number
|
|
40
|
-
|
|
41
|
-
|
|
61
|
+
/** 缺省读取 `--rs-terminal-font-weight` */
|
|
62
|
+
fontWeight?: RsTerminalFontWeight
|
|
63
|
+
/** 缺省读取 `--rs-terminal-font-weight-bold` */
|
|
64
|
+
fontWeightBold?: RsTerminalFontWeight
|
|
42
65
|
allowTransparency?: boolean
|
|
43
66
|
/** auto 跟随 data-rs-theme;也可强制 light / dark */
|
|
44
67
|
themeMode?: RsTerminalThemeMode
|
|
@@ -68,11 +91,6 @@ const props = withDefaults(
|
|
|
68
91
|
overlay: '',
|
|
69
92
|
inputEnabled: true,
|
|
70
93
|
cursorBlink: true,
|
|
71
|
-
fontFamily:
|
|
72
|
-
'"SF Mono", "Cascadia Code", "Cascadia Mono", Consolas, "Liberation Mono", Menlo, monospace',
|
|
73
|
-
fontSize: 13,
|
|
74
|
-
fontWeight: '300',
|
|
75
|
-
fontWeightBold: '400',
|
|
76
94
|
allowTransparency: false,
|
|
77
95
|
themeMode: 'auto',
|
|
78
96
|
theme: () => ({}),
|
|
@@ -109,13 +127,34 @@ const zebraRowStepPx = ref<number | null>(null)
|
|
|
109
127
|
|
|
110
128
|
const showLoading = computed(() => !terminalReady.value || props.loading)
|
|
111
129
|
|
|
130
|
+
function asTerminalFontWeight(value: string): RsTerminalFontWeight {
|
|
131
|
+
return value as RsTerminalFontWeight
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function resolveTerminalFontFamily(): string {
|
|
135
|
+
return props.fontFamily || readTerminalFontFamily(hostEl.value)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function resolveTerminalFontSize(): number {
|
|
139
|
+
return props.fontSize ?? readTerminalFontSizePx(hostEl.value)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function resolveTerminalFontWeight(): RsTerminalFontWeight {
|
|
143
|
+
return props.fontWeight ?? asTerminalFontWeight(readTerminalFontWeight(hostEl.value))
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function resolveTerminalFontWeightBold(): RsTerminalFontWeight {
|
|
147
|
+
return props.fontWeightBold ?? asTerminalFontWeight(readTerminalFontWeightBold(hostEl.value))
|
|
148
|
+
}
|
|
149
|
+
|
|
112
150
|
const zebraStyle = computed((): Record<string, string> | undefined => {
|
|
113
151
|
if (!props.zebraStripes) {
|
|
114
152
|
return undefined
|
|
115
153
|
}
|
|
116
|
-
const
|
|
154
|
+
const fontSize = resolveTerminalFontSize()
|
|
155
|
+
const step = zebraRowStepPx.value ?? fontSize * TERMINAL_LINE_HEIGHT
|
|
117
156
|
return {
|
|
118
|
-
'--rs-terminal-font-size': `${
|
|
157
|
+
'--rs-terminal-font-size': `${fontSize}px`,
|
|
119
158
|
'--rs-terminal-line-height': String(TERMINAL_LINE_HEIGHT),
|
|
120
159
|
'--rs-terminal-zebra-step': `${step}px`,
|
|
121
160
|
}
|
|
@@ -468,10 +507,10 @@ watch(
|
|
|
468
507
|
}
|
|
469
508
|
refreshResolvedTheme()
|
|
470
509
|
terminal.options.cursorBlink = props.cursorBlink
|
|
471
|
-
terminal.options.fontFamily =
|
|
472
|
-
terminal.options.fontSize =
|
|
473
|
-
terminal.options.fontWeight =
|
|
474
|
-
terminal.options.fontWeightBold =
|
|
510
|
+
terminal.options.fontFamily = resolveTerminalFontFamily()
|
|
511
|
+
terminal.options.fontSize = resolveTerminalFontSize()
|
|
512
|
+
terminal.options.fontWeight = resolveTerminalFontWeight()
|
|
513
|
+
terminal.options.fontWeightBold = resolveTerminalFontWeightBold()
|
|
475
514
|
terminal.options.allowTransparency = resolveAllowTransparency()
|
|
476
515
|
terminal.options.convertEol = props.convertEol
|
|
477
516
|
attachWheelGuard()
|
|
@@ -487,10 +526,10 @@ onMounted(async () => {
|
|
|
487
526
|
refreshResolvedTheme()
|
|
488
527
|
terminal = new Terminal({
|
|
489
528
|
cursorBlink: props.cursorBlink,
|
|
490
|
-
fontFamily:
|
|
491
|
-
fontSize:
|
|
492
|
-
fontWeight:
|
|
493
|
-
fontWeightBold:
|
|
529
|
+
fontFamily: resolveTerminalFontFamily(),
|
|
530
|
+
fontSize: resolveTerminalFontSize(),
|
|
531
|
+
fontWeight: resolveTerminalFontWeight(),
|
|
532
|
+
fontWeightBold: resolveTerminalFontWeightBold(),
|
|
494
533
|
lineHeight: TERMINAL_LINE_HEIGHT,
|
|
495
534
|
allowTransparency: resolveAllowTransparency(),
|
|
496
535
|
drawBoldTextInBrightColors: true,
|
|
@@ -636,7 +675,7 @@ defineExpose({
|
|
|
636
675
|
pointer-events: none;
|
|
637
676
|
font-family: var(--rs-font-mono);
|
|
638
677
|
font-size: var(--rs-font-size-xs);
|
|
639
|
-
font-weight:
|
|
678
|
+
font-weight: var(--rs-font-weight-regular);
|
|
640
679
|
line-height: var(--rs-line-height-normal);
|
|
641
680
|
}
|
|
642
681
|
|
|
@@ -658,7 +697,7 @@ defineExpose({
|
|
|
658
697
|
}
|
|
659
698
|
|
|
660
699
|
.rs-terminal--zebra :deep(.xterm) {
|
|
661
|
-
font-size: var(--rs-terminal-font-size
|
|
700
|
+
font-size: var(--rs-terminal-font-size);
|
|
662
701
|
line-height: var(--rs-terminal-line-height, 1.2);
|
|
663
702
|
}
|
|
664
703
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed, nextTick, ref, useId, useTemplateRef, watch } from 'vue'
|
|
2
|
+
import { computed, nextTick, ref, useAttrs, useId, useTemplateRef, watch } from 'vue'
|
|
3
3
|
import { PopoverContent, PopoverPortal, PopoverRoot, PopoverTrigger } from './reka'
|
|
4
4
|
import RsIcon from './RsIcon.vue'
|
|
5
5
|
import RsTimePickerColumns from './RsTimePickerColumns.vue'
|
|
6
6
|
import { useRsI18n } from '../composables/useRsI18n'
|
|
7
7
|
import { RS_COMPONENT_SIZE_ICON_PX, type RsComponentSize } from '../theme/types'
|
|
8
8
|
import { useResolvedRsComponentSize } from './resolve-size'
|
|
9
|
+
import { isRsFormItemBoundControl, useRsFormItemContext } from './form-utils'
|
|
9
10
|
import {
|
|
10
11
|
EMPTY_TIME_RANGE,
|
|
11
12
|
formatTimeFromParts,
|
|
@@ -21,7 +22,7 @@ import {
|
|
|
21
22
|
type RsTimeUnit,
|
|
22
23
|
} from './time-picker-utils'
|
|
23
24
|
|
|
24
|
-
defineOptions({ name: 'RsTimePicker' })
|
|
25
|
+
defineOptions({ name: 'RsTimePicker', inheritAttrs: false })
|
|
25
26
|
|
|
26
27
|
export type { RsTimeRangeValue } from './time-picker-utils'
|
|
27
28
|
export type RsTimePickerLabelPosition = 'top' | 'left'
|
|
@@ -47,6 +48,8 @@ const props = withDefaults(
|
|
|
47
48
|
embedded?: boolean
|
|
48
49
|
labelPosition?: RsTimePickerLabelPosition
|
|
49
50
|
size?: RsComponentSize
|
|
51
|
+
id?: string
|
|
52
|
+
invalid?: boolean
|
|
50
53
|
}>(),
|
|
51
54
|
{
|
|
52
55
|
disabled: false,
|
|
@@ -59,7 +62,14 @@ const props = withDefaults(
|
|
|
59
62
|
)
|
|
60
63
|
|
|
61
64
|
const fieldId = useId()
|
|
65
|
+
const attrs = useAttrs()
|
|
62
66
|
const { t } = useRsI18n()
|
|
67
|
+
const formItem = useRsFormItemContext()
|
|
68
|
+
const boundToItem = computed(() => isRsFormItemBoundControl(formItem, { id: props.id }))
|
|
69
|
+
const isInvalid = computed(() =>
|
|
70
|
+
Boolean(props.invalid || (boundToItem.value && formItem?.invalid.value)),
|
|
71
|
+
)
|
|
72
|
+
const triggerId = computed(() => props.id || fieldId)
|
|
63
73
|
const resolvedSize = useResolvedRsComponentSize(() => props.size)
|
|
64
74
|
const triggerIconSize = computed(() => RS_COMPONENT_SIZE_ICON_PX[resolvedSize.value])
|
|
65
75
|
const columnsRef = useTemplateRef<InstanceType<typeof RsTimePickerColumns>>('columnsRef')
|
|
@@ -294,14 +304,17 @@ watch(open, async (isOpen) => {
|
|
|
294
304
|
<div class="rs-time-picker">
|
|
295
305
|
<PopoverRoot v-model:open="open" :modal="!embedded">
|
|
296
306
|
<PopoverTrigger
|
|
297
|
-
|
|
307
|
+
v-bind="embedded ? undefined : attrs"
|
|
308
|
+
:id="embedded ? undefined : triggerId"
|
|
298
309
|
type="button"
|
|
299
310
|
class="rs-time-picker__trigger"
|
|
300
311
|
:class="{
|
|
301
312
|
'rs-time-picker__trigger--placeholder': isEmpty,
|
|
302
313
|
'rs-time-picker__trigger--embedded': embedded,
|
|
314
|
+
'rs-time-picker__trigger--invalid': !embedded && isInvalid,
|
|
303
315
|
}"
|
|
304
316
|
:disabled="disabled"
|
|
317
|
+
:aria-invalid="!embedded && isInvalid ? true : undefined"
|
|
305
318
|
>
|
|
306
319
|
<span class="rs-time-picker__leading">
|
|
307
320
|
<RsIcon
|
|
@@ -421,6 +434,7 @@ watch(open, async (isOpen) => {
|
|
|
421
434
|
line-height: var(--rs-line-height-tight);
|
|
422
435
|
text-align: left;
|
|
423
436
|
cursor: pointer;
|
|
437
|
+
outline: none;
|
|
424
438
|
box-shadow: var(--rs-input-shadow, none);
|
|
425
439
|
transition:
|
|
426
440
|
border-color var(--rs-transition-fast),
|
|
@@ -472,6 +486,16 @@ watch(open, async (isOpen) => {
|
|
|
472
486
|
.rs-time-picker__trigger--placeholder .rs-time-picker__value {
|
|
473
487
|
color: var(--rs-placeholder);
|
|
474
488
|
}
|
|
489
|
+
.rs-time-picker__trigger--invalid {
|
|
490
|
+
border-color: var(--rs-danger, var(--rs-color-danger, #dc2626));
|
|
491
|
+
}
|
|
492
|
+
.rs-time-picker__trigger--invalid:focus-visible {
|
|
493
|
+
border-color: var(--rs-danger, var(--rs-color-danger, #dc2626));
|
|
494
|
+
box-shadow:
|
|
495
|
+
var(--rs-input-shadow, none),
|
|
496
|
+
0 0 0 var(--rs-focus-ring-width, 2px)
|
|
497
|
+
color-mix(in srgb, var(--rs-danger, #dc2626) 14%, transparent);
|
|
498
|
+
}
|
|
475
499
|
.rs-time-picker__leading {
|
|
476
500
|
display: inline-flex;
|
|
477
501
|
min-width: 0;
|
|
@@ -536,7 +560,7 @@ watch(open, async (isOpen) => {
|
|
|
536
560
|
}
|
|
537
561
|
.rs-time-picker__pane-title {
|
|
538
562
|
font-size: var(--rs-font-size-xs);
|
|
539
|
-
font-weight:
|
|
563
|
+
font-weight: var(--rs-font-weight-semibold);
|
|
540
564
|
color: var(--rs-muted);
|
|
541
565
|
}
|
|
542
566
|
.rs-time-picker__footer {
|
|
@@ -186,7 +186,7 @@ defineExpose({
|
|
|
186
186
|
--rs-time-columns-list-max-height: 10rem;
|
|
187
187
|
--rs-time-columns-item-padding-y: 0.375rem;
|
|
188
188
|
--rs-time-columns-item-font-size: var(--rs-font-size-sm);
|
|
189
|
-
--rs-time-columns-label-font-size:
|
|
189
|
+
--rs-time-columns-label-font-size: var(--rs-font-size-xs);
|
|
190
190
|
}
|
|
191
191
|
.rs-time-columns--seconds {
|
|
192
192
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
@@ -195,14 +195,14 @@ defineExpose({
|
|
|
195
195
|
--rs-time-columns-list-max-height: 7.5rem;
|
|
196
196
|
--rs-time-columns-item-padding-y: 0.2rem;
|
|
197
197
|
--rs-time-columns-item-font-size: var(--rs-font-size-xs);
|
|
198
|
-
--rs-time-columns-label-font-size:
|
|
198
|
+
--rs-time-columns-label-font-size: var(--rs-font-size-xs);
|
|
199
199
|
gap: var(--rs-space-xs);
|
|
200
200
|
}
|
|
201
201
|
.rs-time-columns--sm {
|
|
202
202
|
--rs-time-columns-list-max-height: 8.5rem;
|
|
203
203
|
--rs-time-columns-item-padding-y: 0.28rem;
|
|
204
204
|
--rs-time-columns-item-font-size: var(--rs-font-size-xs);
|
|
205
|
-
--rs-time-columns-label-font-size:
|
|
205
|
+
--rs-time-columns-label-font-size: var(--rs-font-size-xs);
|
|
206
206
|
}
|
|
207
207
|
.rs-time-columns--lg {
|
|
208
208
|
--rs-time-columns-list-max-height: 12rem;
|
|
@@ -219,7 +219,7 @@ defineExpose({
|
|
|
219
219
|
.rs-time-columns__label {
|
|
220
220
|
text-align: center;
|
|
221
221
|
font-size: var(--rs-time-columns-label-font-size);
|
|
222
|
-
font-weight:
|
|
222
|
+
font-weight: var(--rs-font-weight-medium);
|
|
223
223
|
letter-spacing: 0.02em;
|
|
224
224
|
color: var(--rs-muted);
|
|
225
225
|
}
|
|
@@ -220,17 +220,17 @@ const sonnerTheme = computed<'light' | 'dark'>(() => {
|
|
|
220
220
|
.rs-toast__title {
|
|
221
221
|
margin: 0;
|
|
222
222
|
color: var(--rs-text);
|
|
223
|
-
font-size:
|
|
224
|
-
font-weight:
|
|
225
|
-
line-height:
|
|
223
|
+
font-size: var(--rs-font-size-sm);
|
|
224
|
+
font-weight: var(--rs-font-weight-semibold);
|
|
225
|
+
line-height: var(--rs-line-height-tight);
|
|
226
226
|
letter-spacing: -0.012em;
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
.rs-toast__description {
|
|
230
230
|
margin: 0;
|
|
231
231
|
color: color-mix(in srgb, var(--rs-muted) 94%, var(--rs-text) 6%);
|
|
232
|
-
font-size:
|
|
233
|
-
line-height:
|
|
232
|
+
font-size: var(--rs-font-size-xs);
|
|
233
|
+
line-height: var(--rs-line-height-normal);
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
.rs-toast [data-close-button].rs-toast__close {
|
|
@@ -301,8 +301,8 @@ const sonnerTheme = computed<'light' | 'dark'>(() => {
|
|
|
301
301
|
border-radius: 999px;
|
|
302
302
|
background: color-mix(in srgb, var(--rs-primary) 92%, white 8%);
|
|
303
303
|
color: var(--rs-primary-foreground);
|
|
304
|
-
font-size:
|
|
305
|
-
font-weight:
|
|
304
|
+
font-size: var(--rs-font-size-xs);
|
|
305
|
+
font-weight: var(--rs-font-weight-semibold);
|
|
306
306
|
line-height: 1;
|
|
307
307
|
letter-spacing: 0.01em;
|
|
308
308
|
box-shadow:
|
|
@@ -10,6 +10,11 @@ const props = withDefaults(
|
|
|
10
10
|
align?: 'start' | 'center' | 'end'
|
|
11
11
|
sideOffset?: number
|
|
12
12
|
disabled?: boolean
|
|
13
|
+
/**
|
|
14
|
+
* 仅键盘 `:focus-visible` 时因焦点打开 tip。
|
|
15
|
+
* 默认 true:避免 Dialog/Popover 关闭回焦误开(对齐 Reka 推荐与 RsButton tooltip)。
|
|
16
|
+
*/
|
|
17
|
+
ignoreNonKeyboardFocus?: boolean
|
|
13
18
|
/** 单行展示并按内容撑开宽度(适合集合名等标识符) */
|
|
14
19
|
nowrap?: boolean
|
|
15
20
|
/**
|
|
@@ -25,6 +30,7 @@ const props = withDefaults(
|
|
|
25
30
|
align: 'center',
|
|
26
31
|
sideOffset: 6,
|
|
27
32
|
disabled: false,
|
|
33
|
+
ignoreNonKeyboardFocus: true,
|
|
28
34
|
nowrap: false,
|
|
29
35
|
icon: false,
|
|
30
36
|
iconName: 'info',
|
|
@@ -37,7 +43,10 @@ const iconAriaLabel = computed(() => props.content?.trim() || 'Help')
|
|
|
37
43
|
</script>
|
|
38
44
|
|
|
39
45
|
<template>
|
|
40
|
-
<TooltipRoot
|
|
46
|
+
<TooltipRoot
|
|
47
|
+
:disabled="disabled"
|
|
48
|
+
:ignore-non-keyboard-focus="ignoreNonKeyboardFocus"
|
|
49
|
+
>
|
|
41
50
|
<template v-if="icon">
|
|
42
51
|
<span class="rs-tooltip__with-icon">
|
|
43
52
|
<span v-if="hasLabelSlot" class="rs-tooltip__label">
|
|
@@ -5,16 +5,26 @@ withDefaults(
|
|
|
5
5
|
defineProps<{
|
|
6
6
|
delayDuration?: number
|
|
7
7
|
skipDelayDuration?: number
|
|
8
|
+
/**
|
|
9
|
+
* 仅键盘 focus-visible 时因焦点打开 tip。
|
|
10
|
+
* 默认 true:避免 Dialog/Popover 关闭回焦、切页签等非键盘焦点误开(对齐 Reka 推荐与 RsButton tooltip)。
|
|
11
|
+
*/
|
|
12
|
+
ignoreNonKeyboardFocus?: boolean
|
|
8
13
|
}>(),
|
|
9
14
|
{
|
|
10
15
|
delayDuration: 300,
|
|
11
16
|
skipDelayDuration: 0,
|
|
17
|
+
ignoreNonKeyboardFocus: true,
|
|
12
18
|
},
|
|
13
19
|
)
|
|
14
20
|
</script>
|
|
15
21
|
|
|
16
22
|
<template>
|
|
17
|
-
<TooltipProvider
|
|
23
|
+
<TooltipProvider
|
|
24
|
+
:delay-duration="delayDuration"
|
|
25
|
+
:skip-delay-duration="skipDelayDuration"
|
|
26
|
+
:ignore-non-keyboard-focus="ignoreNonKeyboardFocus"
|
|
27
|
+
>
|
|
18
28
|
<slot />
|
|
19
29
|
</TooltipProvider>
|
|
20
30
|
</template>
|
|
@@ -1096,8 +1096,8 @@ defineExpose({
|
|
|
1096
1096
|
|
|
1097
1097
|
.rs-tree__toggle-caret {
|
|
1098
1098
|
display: block;
|
|
1099
|
-
font-size:
|
|
1100
|
-
font-weight:
|
|
1099
|
+
font-size: var(--rs-font-size-lg);
|
|
1100
|
+
font-weight: var(--rs-font-weight-medium);
|
|
1101
1101
|
line-height: 1;
|
|
1102
1102
|
transform: translateY(-0.5px);
|
|
1103
1103
|
transition: transform var(--rs-transition-fast);
|
|
@@ -1212,7 +1212,7 @@ defineExpose({
|
|
|
1212
1212
|
border-radius: 2px;
|
|
1213
1213
|
background: color-mix(in srgb, var(--rs-warning) 45%, transparent);
|
|
1214
1214
|
color: inherit;
|
|
1215
|
-
font-weight:
|
|
1215
|
+
font-weight: var(--rs-font-weight-semibold);
|
|
1216
1216
|
}
|
|
1217
1217
|
|
|
1218
1218
|
.rs-tree__pad {
|
|
@@ -1232,7 +1232,7 @@ defineExpose({
|
|
|
1232
1232
|
}
|
|
1233
1233
|
|
|
1234
1234
|
.rs-tree--ssm .rs-tree__toggle-caret {
|
|
1235
|
-
font-size:
|
|
1235
|
+
font-size: var(--rs-font-size-sm);
|
|
1236
1236
|
}
|
|
1237
1237
|
|
|
1238
1238
|
.rs-tree--sm .rs-tree__label,
|
|
@@ -1247,7 +1247,7 @@ defineExpose({
|
|
|
1247
1247
|
}
|
|
1248
1248
|
|
|
1249
1249
|
.rs-tree--sm .rs-tree__toggle-caret {
|
|
1250
|
-
font-size:
|
|
1250
|
+
font-size: var(--rs-font-size-base);
|
|
1251
1251
|
}
|
|
1252
1252
|
|
|
1253
1253
|
.rs-tree--lg .rs-tree__label {
|
|
@@ -1261,6 +1261,6 @@ defineExpose({
|
|
|
1261
1261
|
}
|
|
1262
1262
|
|
|
1263
1263
|
.rs-tree--lg .rs-tree__toggle-caret {
|
|
1264
|
-
font-size:
|
|
1264
|
+
font-size: var(--rs-font-size-xl);
|
|
1265
1265
|
}
|
|
1266
1266
|
</style>
|
|
@@ -273,7 +273,7 @@ function fileIcon(file: File): string {
|
|
|
273
273
|
.rs-upload__label {
|
|
274
274
|
color: var(--rs-text);
|
|
275
275
|
font-size: var(--rs-font-size-sm);
|
|
276
|
-
font-weight:
|
|
276
|
+
font-weight: var(--rs-font-weight-semibold);
|
|
277
277
|
line-height: var(--rs-line-height-tight);
|
|
278
278
|
}
|
|
279
279
|
|
|
@@ -367,7 +367,7 @@ function fileIcon(file: File): string {
|
|
|
367
367
|
overflow: hidden;
|
|
368
368
|
color: var(--rs-text);
|
|
369
369
|
font-size: var(--rs-font-size-sm);
|
|
370
|
-
font-weight:
|
|
370
|
+
font-weight: var(--rs-font-weight-medium);
|
|
371
371
|
line-height: var(--rs-line-height-tight);
|
|
372
372
|
text-overflow: ellipsis;
|
|
373
373
|
white-space: nowrap;
|