@veltra/desktop 1.6.6 → 1.7.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/dist/components/action/style2.css +1 -1
- package/dist/components/auto-complete/style2.css +1 -1
- package/dist/components/badge/style2.css +1 -1
- package/dist/components/batch-edit/style2.css +1 -1
- package/dist/components/breadcrumb/style2.css +1 -1
- package/dist/components/button/style2.css +1 -1
- package/dist/components/calendar/style2.css +1 -1
- package/dist/components/card/style2.css +1 -1
- package/dist/components/cascade/style2.css +1 -1
- package/dist/components/check-tag/style2.css +1 -1
- package/dist/components/checkbox/style2.css +1 -1
- package/dist/components/checkbox-group/style2.css +1 -1
- package/dist/components/code-editor/style2.css +1 -1
- package/dist/components/collapse/style2.css +1 -1
- package/dist/components/condition-editor/style2.css +1 -1
- package/dist/components/contextmenu/style2.css +1 -1
- package/dist/components/date-panel/style2.css +1 -1
- package/dist/components/date-picker/style2.css +1 -1
- package/dist/components/date-range-picker/style2.css +1 -1
- package/dist/components/dialog/style2.css +1 -1
- package/dist/components/drawer/style2.css +1 -1
- package/dist/components/dropdown/style2.css +1 -1
- package/dist/components/dual-nav/style2.css +1 -1
- package/dist/components/empty/style2.css +1 -1
- package/dist/components/expression-editor/style2.css +1 -1
- package/dist/components/file-picker/style2.css +1 -1
- package/dist/components/file-viewer/style2.css +1 -1
- package/dist/components/float-button/style2.css +1 -1
- package/dist/components/form/style2.css +1 -1
- package/dist/components/form-item/style2.css +1 -1
- package/dist/components/gantt-chart/style2.css +1 -1
- package/dist/components/grid/style2.css +1 -1
- package/dist/components/grid-input/style2.css +1 -1
- package/dist/components/group-input/style2.css +1 -1
- package/dist/components/group-nav/style2.css +1 -1
- package/dist/components/icon/style2.css +1 -1
- package/dist/components/index.d.ts +2 -1
- package/dist/components/index.js +3 -1
- package/dist/components/index.js.map +1 -1
- package/dist/components/input/style2.css +1 -1
- package/dist/components/kbd/style2.css +1 -1
- package/dist/components/layout/style2.css +1 -1
- package/dist/components/list/style2.css +1 -1
- package/dist/components/loading/style2.css +1 -1
- package/dist/components/message/style2.css +1 -1
- package/dist/components/message-confirm/style2.css +1 -1
- package/dist/components/multi-select/style2.css +1 -1
- package/dist/components/multi-tree-select/style2.css +1 -1
- package/dist/components/nav/style2.css +1 -1
- package/dist/components/node-render/style2.css +1 -1
- package/dist/components/notification/style2.css +1 -1
- package/dist/components/number/style2.css +1 -1
- package/dist/components/number-input/style2.css +1 -1
- package/dist/components/number-range-input/style2.css +1 -1
- package/dist/components/paginator/style2.css +1 -1
- package/dist/components/palette/style2.css +1 -1
- package/dist/components/password-input/style2.css +1 -1
- package/dist/components/pop-confirm/style2.css +1 -1
- package/dist/components/progress/style2.css +1 -1
- package/dist/components/progress-nodes/style2.css +1 -1
- package/dist/components/radio/style2.css +1 -1
- package/dist/components/radio-group/style2.css +4 -13
- package/dist/components/rich-text-editor/style2.css +1 -1
- package/dist/components/scroll/style2.css +1 -1
- package/dist/components/segment/segment.js +98 -0
- package/dist/components/segment/segment.js.map +1 -0
- package/dist/components/segment/style.d.ts +1 -0
- package/dist/components/segment/style.js +1 -0
- package/dist/components/segment/style2.css +113 -0
- package/dist/components/select/select.js +12 -6
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/select/style2.css +1 -1
- package/dist/components/slider/style2.css +1 -1
- package/dist/components/steps/style2.css +1 -1
- package/dist/components/switch/style2.css +1 -1
- package/dist/components/table/style2.css +1 -1
- package/dist/components/table-editor/style2.css +1 -1
- package/dist/components/tabs/style2.css +1 -1
- package/dist/components/tag/style2.css +1 -1
- package/dist/components/text/style2.css +1 -1
- package/dist/components/textarea/style2.css +1 -1
- package/dist/components/theme/style2.css +1 -1
- package/dist/components/theme/theme.js +2 -1
- package/dist/components/theme/theme.js.map +1 -1
- package/dist/components/tip/style2.css +1 -1
- package/dist/components/tree/style2.css +1 -1
- package/dist/components/tree-select/style2.css +1 -1
- package/dist/components/watermark/style2.css +1 -1
- package/dist/index.d.ts +20 -18
- package/dist/index.js +19 -18
- package/dist/style.js +1 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/segment.d.ts +41 -0
- package/package.json +6 -6
- package/src/components/index.ts +2 -0
- package/src/components/radio-group/__test__/radio-group.test.ts +113 -0
- package/src/components/radio-group/style.scss +4 -15
- package/src/components/segment/__test__/segment.test.ts +264 -0
- package/src/components/segment/index.ts +1 -0
- package/src/components/segment/segment.vue +77 -0
- package/src/components/segment/style.scss +92 -0
- package/src/components/segment/style.ts +1 -0
- package/src/components/select/__test__/select.test.ts +36 -0
- package/src/components/select/select.vue +18 -12
- package/src/components/theme/theme.vue +6 -1
- package/src/style.ts +1 -0
- package/src/types/index.ts +1 -0
- package/src/types/segment.ts +42 -0
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* --u-height-default: 32px;
|
|
15
15
|
* --u-height-small: 24px;
|
|
16
16
|
*/
|
|
17
|
-
/**
|
|
17
|
+
/** 暗色:`UITheme.render()` 按主题系列写入 html[data-theme] */
|
|
18
18
|
.u-pop-confirm--main {
|
|
19
19
|
max-width: 200px;
|
|
20
20
|
width: max-content;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* --u-height-default: 32px;
|
|
15
15
|
* --u-height-small: 24px;
|
|
16
16
|
*/
|
|
17
|
-
/**
|
|
17
|
+
/** 暗色:`UITheme.render()` 按主题系列写入 html[data-theme] */
|
|
18
18
|
.u-progress__bar-wrap {
|
|
19
19
|
height: 1.3em;
|
|
20
20
|
background-color: var(--u-bg-color-hover);
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* --u-height-default: 32px;
|
|
15
15
|
* --u-height-small: 24px;
|
|
16
16
|
*/
|
|
17
|
-
/**
|
|
17
|
+
/** 暗色:`UITheme.render()` 按主题系列写入 html[data-theme] */
|
|
18
18
|
.u-progress-nodes {
|
|
19
19
|
position: relative;
|
|
20
20
|
color: var(--u-text-color-placeholder);
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* --u-height-default: 32px;
|
|
15
15
|
* --u-height-small: 24px;
|
|
16
16
|
*/
|
|
17
|
-
/**
|
|
17
|
+
/** 暗色:`UITheme.render()` 按主题系列写入 html[data-theme] */
|
|
18
18
|
.u-radio-group {
|
|
19
19
|
vertical-align: middle;
|
|
20
20
|
display: inline-flex;
|
|
@@ -25,6 +25,9 @@
|
|
|
25
25
|
.u-radio-group .u-radio {
|
|
26
26
|
margin: 0;
|
|
27
27
|
}
|
|
28
|
+
.u-radio-group .u-radio + .u-radio-group .u-radio {
|
|
29
|
+
margin-left: 0;
|
|
30
|
+
}
|
|
28
31
|
.u-radio-group--small {
|
|
29
32
|
gap: 0 calc(var(--u-gap-small) * 2);
|
|
30
33
|
}
|
|
@@ -40,15 +43,3 @@
|
|
|
40
43
|
.u-radio-group.is-block .u-radio {
|
|
41
44
|
display: flex;
|
|
42
45
|
}
|
|
43
|
-
.u-radio-group__button-item {
|
|
44
|
-
margin: 0px !important;
|
|
45
|
-
border-right: 0 !important;
|
|
46
|
-
border-radius: 0 !important;
|
|
47
|
-
}
|
|
48
|
-
.u-radio-group__button-item:first-child {
|
|
49
|
-
border-radius: var(--u-radius-default) 0 0 var(--u-radius-default) !important;
|
|
50
|
-
}
|
|
51
|
-
.u-radio-group__button-item:last-child {
|
|
52
|
-
border-right: var(--u-border-muted) !important;
|
|
53
|
-
border-radius: 0 var(--u-radius-default) var(--u-radius-default) 0 !important;
|
|
54
|
-
}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* --u-height-default: 32px;
|
|
15
15
|
* --u-height-small: 24px;
|
|
16
16
|
*/
|
|
17
|
-
/**
|
|
17
|
+
/** 暗色:`UITheme.render()` 按主题系列写入 html[data-theme] */
|
|
18
18
|
.u-rich-text-editor {
|
|
19
19
|
width: 100%;
|
|
20
20
|
border: 1px solid var(--u-border-muted-color);
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { Fragment, computed, createElementBlock, createElementVNode, createTextVNode, defineComponent, mergeModels, mergeProps, normalizeClass, openBlock, renderList, renderSlot, toDisplayString, unref, useModel, withKeys, withModifiers } from "vue";
|
|
2
|
+
import { useFormFallbackProps } from "@veltra/compositions";
|
|
3
|
+
import { FORM_EMPTY_CONTENT, bem, fieldKey, injectFormContext } from "@veltra/utils";
|
|
4
|
+
//#region src/components/segment/segment.vue
|
|
5
|
+
const _hoisted_1 = [
|
|
6
|
+
"aria-checked",
|
|
7
|
+
"aria-disabled",
|
|
8
|
+
"onClick",
|
|
9
|
+
"onKeydown"
|
|
10
|
+
];
|
|
11
|
+
const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
12
|
+
name: "USegment",
|
|
13
|
+
inheritAttrs: false,
|
|
14
|
+
__name: "segment",
|
|
15
|
+
props: /*@__PURE__*/ mergeModels({
|
|
16
|
+
modelValue: {},
|
|
17
|
+
items: { default: () => [] },
|
|
18
|
+
valueKey: { default: "value" },
|
|
19
|
+
labelKey: { default: "label" },
|
|
20
|
+
disabled: {
|
|
21
|
+
type: Boolean,
|
|
22
|
+
default: void 0
|
|
23
|
+
},
|
|
24
|
+
disabledItem: {},
|
|
25
|
+
block: {
|
|
26
|
+
type: Boolean,
|
|
27
|
+
default: false
|
|
28
|
+
},
|
|
29
|
+
tips: {},
|
|
30
|
+
span: {},
|
|
31
|
+
label: {},
|
|
32
|
+
field: {},
|
|
33
|
+
readonly: {
|
|
34
|
+
type: Boolean,
|
|
35
|
+
default: void 0
|
|
36
|
+
},
|
|
37
|
+
rules: {},
|
|
38
|
+
size: {}
|
|
39
|
+
}, {
|
|
40
|
+
"modelValue": {},
|
|
41
|
+
"modelModifiers": {}
|
|
42
|
+
}),
|
|
43
|
+
emits: /*@__PURE__*/ mergeModels(["update:modelValue", "change"], ["update:modelValue"]),
|
|
44
|
+
setup(__props, { emit: __emit }) {
|
|
45
|
+
const props = __props;
|
|
46
|
+
const model = useModel(__props, "modelValue");
|
|
47
|
+
const emit = __emit;
|
|
48
|
+
const { formProps } = injectFormContext();
|
|
49
|
+
const { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {
|
|
50
|
+
size: "default",
|
|
51
|
+
disabled: false,
|
|
52
|
+
readonly: false
|
|
53
|
+
});
|
|
54
|
+
const cls = bem("segment");
|
|
55
|
+
const labelKey = computed(() => fieldKey(props.labelKey, "label"));
|
|
56
|
+
const valueKey = computed(() => fieldKey(props.valueKey, "value"));
|
|
57
|
+
const handleSelect = (item) => {
|
|
58
|
+
if (disabled.value || props.disabledItem?.(item)) return;
|
|
59
|
+
const val = item[valueKey.value];
|
|
60
|
+
if (model.value === val) return;
|
|
61
|
+
model.value = val;
|
|
62
|
+
emit("change", item);
|
|
63
|
+
};
|
|
64
|
+
return (_ctx, _cache) => {
|
|
65
|
+
return !unref(readonly) ? (openBlock(), createElementBlock("div", mergeProps({ key: 0 }, _ctx.$attrs, {
|
|
66
|
+
class: [
|
|
67
|
+
unref(cls).b,
|
|
68
|
+
unref(bem).is("block", __props.block),
|
|
69
|
+
unref(bem).is("disabled", unref(disabled)),
|
|
70
|
+
unref(cls).m(unref(size))
|
|
71
|
+
],
|
|
72
|
+
role: "radiogroup"
|
|
73
|
+
}), [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item) => {
|
|
74
|
+
return openBlock(), createElementBlock("div", {
|
|
75
|
+
key: item[valueKey.value],
|
|
76
|
+
class: normalizeClass([
|
|
77
|
+
unref(cls).e("item"),
|
|
78
|
+
unref(bem).is("active", item[valueKey.value] === model.value),
|
|
79
|
+
unref(bem).is("disabled", unref(disabled) || Boolean(__props.disabledItem?.(item)))
|
|
80
|
+
]),
|
|
81
|
+
role: "radio",
|
|
82
|
+
"aria-checked": item[valueKey.value] === model.value,
|
|
83
|
+
"aria-disabled": unref(disabled) || Boolean(__props.disabledItem?.(item)),
|
|
84
|
+
tabindex: "0",
|
|
85
|
+
onClick: ($event) => handleSelect(item),
|
|
86
|
+
onKeydown: [withKeys(withModifiers(($event) => handleSelect(item), ["prevent"]), ["enter"]), withKeys(withModifiers(($event) => handleSelect(item), ["prevent"]), ["space"])]
|
|
87
|
+
}, [renderSlot(_ctx.$slots, "item", {
|
|
88
|
+
item,
|
|
89
|
+
active: item[valueKey.value] === model.value
|
|
90
|
+
}, () => [createElementVNode("span", { class: normalizeClass(unref(cls).e("item-label")) }, toDisplayString(item[labelKey.value]), 3)])], 42, _hoisted_1);
|
|
91
|
+
}), 128))], 16)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode(toDisplayString(__props.items.find((item) => item[valueKey.value] === model.value)?.[labelKey.value] || unref(FORM_EMPTY_CONTENT)), 1)], 64));
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
//#endregion
|
|
96
|
+
export { _sfc_main as default };
|
|
97
|
+
|
|
98
|
+
//# sourceMappingURL=segment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segment.js","names":["$attrs"],"sources":["../../../src/components/segment/segment.vue"],"sourcesContent":["<template>\n <div\n v-if=\"!readonly\"\n v-bind=\"$attrs\"\n :class=\"[cls.b, bem.is('block', block), bem.is('disabled', disabled), cls.m(size)]\"\n role=\"radiogroup\"\n >\n <div\n v-for=\"item of items\"\n :key=\"item[valueKey]\"\n :class=\"[\n cls.e('item'),\n bem.is('active', item[valueKey] === model),\n bem.is('disabled', disabled || Boolean(disabledItem?.(item)))\n ]\"\n role=\"radio\"\n :aria-checked=\"item[valueKey] === model\"\n :aria-disabled=\"disabled || Boolean(disabledItem?.(item))\"\n tabindex=\"0\"\n @click=\"handleSelect(item)\"\n @keydown.enter.prevent=\"handleSelect(item)\"\n @keydown.space.prevent=\"handleSelect(item)\"\n >\n <slot name=\"item\" :item=\"item\" :active=\"item[valueKey] === model\">\n <span :class=\"cls.e('item-label')\">{{ item[labelKey] }}</span>\n </slot>\n </div>\n </div>\n\n <template v-else>\n {{ items.find((item) => item[valueKey] === model)?.[labelKey] || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFormFallbackProps } from '@veltra/compositions'\nimport { bem, fieldKey, FORM_EMPTY_CONTENT, injectFormContext } from '@veltra/utils'\nimport { computed } from 'vue'\n\nimport type { SegmentEmits, SegmentItem, SegmentProps } from '../../types'\n\ndefineOptions({ name: 'USegment', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SegmentProps>(), {\n items: () => [],\n labelKey: 'label',\n valueKey: 'value',\n disabled: undefined,\n readonly: undefined,\n block: false\n})\n\nconst model = defineModel<any>()\n\nconst emit = defineEmits<SegmentEmits>()\n\nconst { formProps } = injectFormContext()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default',\n disabled: false,\n readonly: false\n})\n\nconst cls = bem('segment')\n\nconst labelKey = computed(() => fieldKey(props.labelKey, 'label'))\nconst valueKey = computed(() => fieldKey(props.valueKey, 'value'))\n\nconst handleSelect = (item: SegmentItem) => {\n if (disabled.value || props.disabledItem?.(item)) return\n const val = item[valueKey.value]\n if (model.value === val) return\n model.value = val\n emit('change', item)\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2CA,MAAM,QAAQ;EASd,MAAM,QAAQ,SAAgB,SAAA,YAAC;EAE/B,MAAM,OAAO;EAEb,MAAM,EAAE,cAAc,kBAAkB;EAExC,MAAM,EAAE,MAAM,UAAU,aAAa,qBAAqB,CAAC,aAAa,CAAC,GAAG,KAAK,GAAG;GAClF,MAAM;GACN,UAAU;GACV,UAAU;EACZ,CAAC;EAED,MAAM,MAAM,IAAI,SAAS;EAEzB,MAAM,WAAW,eAAe,SAAS,MAAM,UAAU,OAAO,CAAC;EACjE,MAAM,WAAW,eAAe,SAAS,MAAM,UAAU,OAAO,CAAC;EAEjE,MAAM,gBAAgB,SAAsB;GAC1C,IAAI,SAAS,SAAS,MAAM,eAAe,IAAI,GAAG;GAClD,MAAM,MAAM,KAAK,SAAS;GAC1B,IAAI,MAAM,UAAU,KAAK;GACzB,MAAM,QAAQ;GACd,KAAK,UAAU,IAAI;EACrB;;GAzEW,OAAA,CAAA,MAAA,QAAA,KADT,UAAA,GAAA,mBA0BM,OA1BN,WA0BM,EAAA,KAAA,EAAA,GAxBIA,KAAAA,QAAM;IACb,OAAK;KAAG,MAAA,GAAA,CAAG,CAAC;KAAG,MAAA,GAAA,CAAG,CAAC,GAAE,SAAU,QAAA,KAAK;KAAG,MAAA,GAAA,CAAG,CAAC,GAAE,YAAa,MAAA,QAAA,CAAQ;KAAG,MAAA,GAAA,CAAG,CAAC,EAAE,MAAA,IAAA,CAAI;IAAA;IAChF,MAAK;GAEL,CAAA,GAAA,EAAA,UAAA,IAAA,GAAA,mBAmBM,UAAA,MAAA,WAlBW,QAAA,QAAR,SAAI;IADb,OAAA,UAAA,GAAA,mBAmBM,OAAA;KAjBH,KAAK,KAAK,SAAA;KACV,OAAK,eAAA;MAAY,MAAA,GAAA,CAAG,CAAC,EAAC,MAAA;MAAkB,MAAA,GAAA,CAAG,CAAC,GAAE,UAAW,KAAK,SAAA,WAAc,MAAA,KAAK;MAAW,MAAA,GAAA,CAAG,CAAC,GAAE,YAAa,MAAA,QAAA,KAAY,QAAQ,QAAA,eAAe,IAAI,CAAA,CAAA;;KAKvJ,MAAK;KACJ,gBAAc,KAAK,SAAA,WAAc,MAAA;KACjC,iBAAe,MAAA,QAAA,KAAY,QAAQ,QAAA,eAAe,IAAI,CAAA;KACvD,UAAS;KACR,UAAK,WAAE,aAAa,IAAI;KACxB,WAAO,CAAgB,SAAA,eAAA,WAAA,aAAa,IAAI,GAAA,CAAA,SAAA,CAAA,GAAA,CAAA,OAAA,CAAA,GACjB,SAAA,eAAA,WAAA,aAAa,IAAI,GAAA,CAAA,SAAA,CAAA,GAAA,CAAA,OAAA,CAAA,CAAA;IAEzC,GAAA,CAAA,WAEO,KAAA,QAAA,QAAA;KAFkB;KAAO,QAAQ,KAAK,SAAA,WAAc,MAAA;IAA3D,SAEO,CADL,mBAA8D,QAAA,EAAvD,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,YAAA,CAAA,EAAmB,GAAA,gBAAA,KAAK,SAAA,MAAQ,GAAA,CAAA,CAAA,CAAA,CAAA,GAAA,IAAA,UAAA;GAKzD,CAAA,GAAA,GAAA,EAAA,GAAA,EAAA,MAAA,UAAA,GAAA,mBAEW,UAAA,EAAA,KAAA,EAAA,GAAA,CADN,gBAAA,gBAAA,QAAA,MAAM,MAAM,SAAS,KAAK,SAAA,WAAc,MAAA,KAAK,CAAA,GAAI,SAAA,UAAa,MAAA,kBAAA,CAAkB,GAAA,CAAA,CAAA,GAAA,EAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "./style2.css";
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
/** flex布局 */
|
|
3
|
+
/**
|
|
4
|
+
* 设置css变量
|
|
5
|
+
* 参数1:变量前缀
|
|
6
|
+
* 参数2: 一个由值组成的列表或者由key, value组成的map
|
|
7
|
+
* css-var(height, (
|
|
8
|
+
* large: 40px
|
|
9
|
+
* default: 32px
|
|
10
|
+
* small: 24px
|
|
11
|
+
* ))
|
|
12
|
+
* 生成的css变量:
|
|
13
|
+
* --u-height-large: 40px;
|
|
14
|
+
* --u-height-default: 32px;
|
|
15
|
+
* --u-height-small: 24px;
|
|
16
|
+
*/
|
|
17
|
+
/** 暗色:`UITheme.render()` 按主题系列写入 html[data-theme] */
|
|
18
|
+
.u-segment {
|
|
19
|
+
vertical-align: middle;
|
|
20
|
+
display: inline-flex;
|
|
21
|
+
justify-content: flex-start;
|
|
22
|
+
align-items: center;
|
|
23
|
+
flex-wrap: nowrap;
|
|
24
|
+
gap: 2px;
|
|
25
|
+
padding: 2px;
|
|
26
|
+
background-color: var(--u-bg-color-bottom);
|
|
27
|
+
box-sizing: border-box;
|
|
28
|
+
}
|
|
29
|
+
.u-segment--small {
|
|
30
|
+
border-radius: var(--u-radius-small);
|
|
31
|
+
}
|
|
32
|
+
.u-segment--small .u-segment__item {
|
|
33
|
+
height: calc(var(--u-form-component-height-small) - 4px);
|
|
34
|
+
padding: 0 calc(var(--u-gap-small) * 1.5);
|
|
35
|
+
border-radius: calc(var(--u-radius-small) - 2px);
|
|
36
|
+
font-size: var(--u-font-size-main-small);
|
|
37
|
+
}
|
|
38
|
+
.u-segment--default {
|
|
39
|
+
border-radius: var(--u-radius-default);
|
|
40
|
+
}
|
|
41
|
+
.u-segment--default .u-segment__item {
|
|
42
|
+
height: calc(var(--u-form-component-height-default) - 4px);
|
|
43
|
+
padding: 0 calc(var(--u-gap-default) * 1.5);
|
|
44
|
+
border-radius: calc(var(--u-radius-default) - 2px);
|
|
45
|
+
font-size: var(--u-font-size-main-default);
|
|
46
|
+
}
|
|
47
|
+
.u-segment--large {
|
|
48
|
+
border-radius: var(--u-radius-large);
|
|
49
|
+
}
|
|
50
|
+
.u-segment--large .u-segment__item {
|
|
51
|
+
height: calc(var(--u-form-component-height-large) - 4px);
|
|
52
|
+
padding: 0 calc(var(--u-gap-large) * 1.5);
|
|
53
|
+
border-radius: calc(var(--u-radius-large) - 2px);
|
|
54
|
+
font-size: var(--u-font-size-main-large);
|
|
55
|
+
}
|
|
56
|
+
.u-segment__item {
|
|
57
|
+
margin: 0;
|
|
58
|
+
display: inline-flex;
|
|
59
|
+
align-items: center;
|
|
60
|
+
justify-content: center;
|
|
61
|
+
background-color: transparent;
|
|
62
|
+
box-shadow: none;
|
|
63
|
+
font-weight: 500;
|
|
64
|
+
color: var(--u-text-color-second);
|
|
65
|
+
cursor: pointer;
|
|
66
|
+
user-select: none;
|
|
67
|
+
outline: none;
|
|
68
|
+
transition: color var(--u-transition-fast) var(--u-transition-ease), background-color var(--u-transition-fast) var(--u-transition-ease), box-shadow var(--u-transition-fast) var(--u-transition-ease);
|
|
69
|
+
}
|
|
70
|
+
.u-segment__item:hover:not(.is-active):not(.is-disabled) {
|
|
71
|
+
color: var(--u-text-color-title);
|
|
72
|
+
background-color: var(--u-color-primary-a-5);
|
|
73
|
+
}
|
|
74
|
+
.u-segment__item.is-active {
|
|
75
|
+
color: var(--u-color-primary);
|
|
76
|
+
background-color: var(--u-bg-color-top);
|
|
77
|
+
box-shadow: var(--u-shadow-sm);
|
|
78
|
+
font-weight: 600;
|
|
79
|
+
}
|
|
80
|
+
.u-segment__item.is-disabled {
|
|
81
|
+
opacity: 0.5;
|
|
82
|
+
cursor: not-allowed;
|
|
83
|
+
color: var(--u-text-color-disabled);
|
|
84
|
+
}
|
|
85
|
+
.u-segment__item:focus-visible:not(.is-disabled) {
|
|
86
|
+
box-shadow: var(--u-focus-ring);
|
|
87
|
+
}
|
|
88
|
+
.u-segment__item-label {
|
|
89
|
+
overflow: hidden;
|
|
90
|
+
text-overflow: ellipsis;
|
|
91
|
+
white-space: nowrap;
|
|
92
|
+
display: inline-flex;
|
|
93
|
+
align-items: center;
|
|
94
|
+
justify-content: center;
|
|
95
|
+
}
|
|
96
|
+
.u-segment.is-block {
|
|
97
|
+
display: flex;
|
|
98
|
+
width: 100%;
|
|
99
|
+
}
|
|
100
|
+
.u-segment.is-block .u-segment__item {
|
|
101
|
+
flex: 1 1 0%;
|
|
102
|
+
width: 0;
|
|
103
|
+
min-width: 0;
|
|
104
|
+
display: inline-flex;
|
|
105
|
+
justify-content: center;
|
|
106
|
+
}
|
|
107
|
+
.u-segment.is-disabled {
|
|
108
|
+
opacity: 0.7;
|
|
109
|
+
cursor: not-allowed;
|
|
110
|
+
}
|
|
111
|
+
.u-segment.is-disabled .u-segment__item {
|
|
112
|
+
cursor: not-allowed;
|
|
113
|
+
}
|
|
@@ -87,6 +87,8 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
87
87
|
});
|
|
88
88
|
const { queryString, options, allOptions, temOptionsToCreatedOptions, clearCreatedOptions } = useOptions({ props });
|
|
89
89
|
const dropdownVisible = shallowRef(false);
|
|
90
|
+
/** 选中临时选项后待转正标记:面板关闭后再落定,避免关闭动画期间列表恢复全量导致面板变长 */
|
|
91
|
+
let pendingTempPromote = false;
|
|
90
92
|
/**
|
|
91
93
|
* 是否处于查询态:决定触发输入框显示查询串还是选中标签。
|
|
92
94
|
* 与面板可见状态解耦 —— 选择后立即退出查询态,
|
|
@@ -192,8 +194,15 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
192
194
|
if (selectedEl) scrollIntoContainerView(selectedEl, scroll.containerRef ?? null);
|
|
193
195
|
}
|
|
194
196
|
});
|
|
197
|
+
/** 落定待转正的临时选项(面板 DOM 已卸载,列表恢复全量用户不可见) */
|
|
198
|
+
function promotePendingTemp() {
|
|
199
|
+
if (!pendingTempPromote) return;
|
|
200
|
+
pendingTempPromote = false;
|
|
201
|
+
temOptionsToCreatedOptions();
|
|
202
|
+
}
|
|
195
203
|
watch(dropdownVisible, (visible) => {
|
|
196
204
|
if (visible) {
|
|
205
|
+
promotePendingTemp();
|
|
197
206
|
if (filterable.value) {
|
|
198
207
|
queryString.value = "";
|
|
199
208
|
querying.value = true;
|
|
@@ -202,11 +211,9 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
202
211
|
} else {
|
|
203
212
|
querying.value = false;
|
|
204
213
|
queryString.value = "";
|
|
214
|
+
promotePendingTemp();
|
|
205
215
|
}
|
|
206
216
|
});
|
|
207
|
-
const handleDropdownVisible = (visible) => {
|
|
208
|
-
if (!visible) queryString.value = "";
|
|
209
|
-
};
|
|
210
217
|
/** 单选:用户动作内 O(1) 写入值与文案,跳过 modelValue 回显的 O(n) 查找 */
|
|
211
218
|
const handleSelect = userAction((option, _index) => {
|
|
212
219
|
const value = option?.[valueKey.value];
|
|
@@ -214,9 +221,8 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
214
221
|
emit("update:modelValue", value);
|
|
215
222
|
setLabel(option?.[labelKey.value]);
|
|
216
223
|
emit("change", option);
|
|
217
|
-
if (option.__isTemp)
|
|
224
|
+
if (option.__isTemp) pendingTempPromote = true;
|
|
218
225
|
querying.value = false;
|
|
219
|
-
queryString.value = "";
|
|
220
226
|
currentIndex.value = options.value.findIndex((item) => o(item).get(valueKey.value) === value);
|
|
221
227
|
if (currentIndex.value >= 0) selected.value = options.value[currentIndex.value];
|
|
222
228
|
dropdownRef.value?.close();
|
|
@@ -246,7 +252,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
246
252
|
ref_key: "dropdownRef",
|
|
247
253
|
ref: dropdownRef,
|
|
248
254
|
visible: dropdownVisible.value,
|
|
249
|
-
"onUpdate:visible":
|
|
255
|
+
"onUpdate:visible": _cache[0] || (_cache[0] = ($event) => dropdownVisible.value = $event),
|
|
250
256
|
"content-class": [
|
|
251
257
|
unref(cls).e("panel"),
|
|
252
258
|
unref(cls).em("panel", unref(size)),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.js","names":["$attrs","$slots"],"sources":["../../../src/components/select/select.vue"],"sourcesContent":["<template>\n <u-dropdown\n v-if=\"!readonly\"\n v-bind=\"$attrs\"\n trigger=\"click\"\n :class=\"[cls.b, bem.is('disabled', disabled)]\"\n ref=\"dropdownRef\"\n v-model:visible=\"dropdownVisible\"\n :content-class=\"[cls.e('panel'), cls.em('panel', size), contentClass]\"\n :content-style=\"contentStyle\"\n :disabled=\"disabled\"\n :min-width=\"minWidth\"\n :width=\"width\"\n @keydown=\"handleKeydown\"\n @update:visible=\"handleDropdownVisible\"\n @mouseenter=\"hovered = true\"\n @mouseleave=\"hovered = false\"\n >\n <!-- 触发 -->\n <template #trigger>\n <u-input\n ref=\"inputRef\"\n :size=\"size\"\n :disabled=\"disabled\"\n :placeholder=\"inputPlaceholder\"\n :clearable=\"false\"\n :model-value=\"inputValue\"\n @update:model-value=\"handleQueryInput\"\n @keydown=\"handleKeydown\"\n :native-readonly=\"!filterable || !querying\"\n @click.capture=\"handleTriggerClickCapture\"\n >\n <template #prefix v-if=\"$slots.prefix\">\n <slot name=\"prefix\" />\n </template>\n\n <template #suffix>\n <transition name=\"zoom-in\" mode=\"out-in\">\n <u-icon\n v-if=\"showClear\"\n :class=\"cls.e('clear')\"\n title=\"清除\"\n key=\"clear\"\n @click.stop=\"handleClear\"\n >\n <Close />\n </u-icon>\n <u-icon v-else :class=\"cls.e('arrow')\" key=\"arrow\">\n <ArrowDown />\n </u-icon>\n </transition>\n </template>\n </u-input>\n </template>\n\n <!-- 下拉内容 -->\n <template #content>\n <!--\n 单选列表。虚拟化启用时,内容容器 height 由 useVirtualizer 命令式写入;\n 此处 content-style 仅承担 grid 相关样式,避免 height 变化触发模板重渲染。\n -->\n <u-scroll\n v-if=\"options.length\"\n tag=\"ul\"\n :class=\"cls.e('options')\"\n ref=\"scrollRef\"\n :content-class=\"[\n cls.e('options-wrap'),\n bem.is('virtual', virtualEnabled),\n bem.is('grid', !!grid)\n ]\"\n :content-style=\"{\n gridTemplateColumns: grid ? `repeat(${grid.cols}, minmax(0px, 1fr))` : undefined,\n gridGap: grid ? withUnit(grid.gap, 'px') : undefined\n }\"\n >\n <template v-if=\"virtualEnabled\">\n <!-- @vue-ignore -->\n <li\n v-for=\"{ option, index, val, label, key, offset } of virtualOptions\"\n :class=\"[optionClass, bem.is('selected', index === currentIndex)]\"\n @click=\"handleSelect(option, index)\"\n :key=\"key\"\n :style=\"{ transform: `translateY(${offset}px)` }\"\n :data-index=\"index\"\n :ref=\"(el) => measureElement(index, el as Element | null)\"\n >\n <slot v-bind=\"{ option, index }\">\n {{ label }}\n </slot>\n </li>\n </template>\n\n <template v-else>\n <li\n v-for=\"(option, index) of options\"\n :class=\"[optionClass, bem.is('selected', index === currentIndex)]\"\n @click=\"handleSelect(option, index)\"\n :data-index=\"index\"\n :title=\"o(option).get(labelKey)\"\n :key=\"o(option).get(valueKey)\"\n >\n <slot v-bind=\"{ option, index }\">\n {{ o(option).get(labelKey) }}\n </slot>\n </li>\n </template>\n </u-scroll>\n\n <div v-else :class=\"cls.e('empty')\">\n <UEmpty />\n </div>\n </template>\n </u-dropdown>\n\n <template v-else>\n {{ displayedValue || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { o } from '@cat-kit/core'\nimport { useFormFallbackProps, useUserAction, useVirtualizer } from '@veltra/compositions'\nimport { ArrowDown, Close } from '@veltra/icons/normal'\nimport { bem, fieldKey, FORM_EMPTY_CONTENT, scrollIntoContainerView, withUnit } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed, nextTick, shallowRef, useTemplateRef, watch } from 'vue'\n\nimport type {\n SelectEmits,\n SelectProps,\n _SelectExposed,\n DropdownExposed,\n InputExposed,\n ScrollExposed\n} from '../../types'\nimport { UDropdown } from '../dropdown'\nimport { UEmpty } from '../empty'\nimport { UIcon } from '../icon'\nimport { UInput } from '../input'\nimport { UScroll } from '../scroll'\nimport { useKeyboard } from './use-keyboard'\nimport { useOptions } from './use-options'\n\ndefineOptions({ name: 'USelect', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SelectProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n placeholder: '请选择',\n clearable: true,\n disabled: undefined,\n readonly: undefined\n})\n\nconst emit = defineEmits<SelectEmits>()\n\ndefineSlots<{\n /** 前缀插槽 */\n prefix?: () => any\n /** 默认插槽 */\n default?: (scope: { option: Record<string, any>; index: number }) => any\n}>()\n\nconst cls = bem('select')\n\nconst labelKey = computed(() => fieldKey(props.labelKey, 'label'))\nconst valueKey = computed(() => fieldKey(props.valueKey, 'value'))\n\nconst optionClass = cls.e('option')\n\nconst { formProps } = injectFormContext()\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default',\n disabled: false,\n readonly: false\n})\n\nconst currentIndex = shallowRef(-1)\n/** 内部展示文案,仅由选项推导;通过 update:text 单向通知父级 */\nconst label = shallowRef<string>()\nconst selected = shallowRef<Record<string, any>>()\n\nconst displayedValue = computed(() => {\n if (label.value) return label.value\n\n return selected.value ? o(selected.value).get(labelKey.value) : String(props.modelValue ?? '')\n})\n\nconst dropdownRef = shallowRef<DropdownExposed>()\nconst scrollRef = shallowRef<ScrollExposed>()\nconst inputRef = useTemplateRef<InputExposed>('inputRef')\n\nconst filterable = computed(() => {\n return props.filterable || typeof props.options === 'function'\n})\n\nconst { queryString, options, allOptions, temOptionsToCreatedOptions, clearCreatedOptions } =\n useOptions({ props })\n\nconst dropdownVisible = shallowRef(false)\n\n/**\n * 是否处于查询态:决定触发输入框显示查询串还是选中标签。\n * 与面板可见状态解耦 —— 选择后立即退出查询态,\n * 不等面板关闭动画结束(否则显示值会延迟一个动画时长才恢复)。\n */\nconst querying = shallowRef(false)\n\n/** 触发输入框的值:查询态下承载查询串,否则展示选中标签 */\nconst inputValue = computed(() => {\n if (filterable.value && querying.value) return queryString.value\n return displayedValue.value\n})\n\n/** 查询态下已选标签降级为占位提示 */\nconst inputPlaceholder = computed(() => {\n if (filterable.value && querying.value && displayedValue.value) {\n return displayedValue.value\n }\n return props.placeholder\n})\n\nfunction handleQueryInput(value: string) {\n if (!filterable.value) return\n queryString.value = value\n}\n\nconst hovered = shallowRef(false)\n\n/** 悬停且存在选中值时展示清除按钮(替代下拉箭头) */\nconst showClear = computed(() => {\n return props.clearable && !disabled.value && hovered.value && !!displayedValue.value\n})\n\n/**\n * 过滤模式下拦截输入区域的点击:\n * 阻止 dropdown 的 trigger 开合切换,保持面板展开以不中断输入。\n * 非输入区域(箭头、留白)放行,维持原开合行为。\n */\nfunction handleTriggerClickCapture(e: MouseEvent) {\n if (!filterable.value || disabled.value) return\n if (!(e.target instanceof HTMLInputElement)) return\n\n e.stopPropagation()\n if (!dropdownVisible.value) dropdownRef.value?.open()\n}\n\nconst { userAction, isUserActive } = useUserAction()\n\n/** 更新内部文案;值变化时单向 emit update:text */\nfunction setLabel(next?: string) {\n if (label.value === next) return\n label.value = next\n emit('update:text', next)\n}\n\n/** 按 modelValue 与完整选项列表同步高亮索引、选中项与显示标签(外部回显用,O(n)) */\nfunction syncSelected(modelValue: any, sourceOptions: Record<string, any>[] | undefined) {\n // 查询输入期间高亮第一项(创建模式下通常是临时项,便于回车创建)\n if (queryString.value) {\n currentIndex.value = options.value.length ? 0 : -1\n return\n }\n\n if (!sourceOptions?.length) return\n\n if (modelValue !== undefined && modelValue !== null && modelValue !== '') {\n currentIndex.value = sourceOptions.findIndex(\n (option) => o(option).get(valueKey.value) === modelValue\n )\n selected.value = currentIndex.value >= 0 ? sourceOptions[currentIndex.value] : undefined\n setLabel(selected.value ? o(selected.value).get(labelKey.value) : undefined)\n } else {\n currentIndex.value = -1\n selected.value = undefined\n setLabel(undefined)\n }\n}\n\n// 回显:以 allOptions 匹配,避免过滤列表缺项时清掉已选文案;用户动作期内跳过\nwatch(\n [() => props.modelValue, allOptions],\n ([modelValue]) => {\n if (isUserActive()) return\n syncSelected(modelValue, allOptions.value)\n },\n { immediate: true }\n)\n\n// 过滤时单独同步高亮(allOptions 不变,不会触发上方回显 watch)\nwatch([queryString, options], () => {\n if (!queryString.value) return\n currentIndex.value = options.value.length ? 0 : -1\n})\n\nconst baseVirtualEnabled = computed(() => options.value.length > 80)\nconst virtualEnabled = computed(() => baseVirtualEnabled.value && !props.grid)\n\nconst { virtualizer, items } = useVirtualizer({\n count: computed(() => options.value.length),\n scrollEl: () => scrollRef.value?.containerRef ?? null,\n contentEl: () => (virtualEnabled.value ? (scrollRef.value?.contentRef ?? null) : null),\n gap: 4,\n estimateSize: () => 40\n})\n\nconst virtualOptions = computed(() => {\n const _options = options.value\n return items.value.map((item) => {\n const option = _options[item.index]!\n return {\n option,\n index: item.index,\n label: o(option).get(labelKey.value),\n val: o(option).get(valueKey.value),\n key: item.index,\n offset: item.start\n }\n })\n})\n\nconst measureElement: (index: number, el: Element | null) => void = (index, el) =>\n virtualizer.measureElement(index, el)\n\nfunction scrollTo(index: number): void {\n virtualizer.scrollToIndex(index, { align: 'center' })\n}\n\nwatch([scrollRef, virtualEnabled], ([scroll, virtualEnabled]) => {\n if (!scroll || !props.modelValue) return\n\n if (virtualEnabled) {\n const index = options.value.findIndex((option) => option === selected.value)\n index !== -1 && dropdownVisible.value && nextTick(() => scrollTo(index))\n } else {\n const selectedEl = scroll?.contentRef?.getElementsByClassName('is-selected')[0]\n if (selectedEl) {\n scrollIntoContainerView(selectedEl as HTMLElement, scroll.containerRef ?? null)\n }\n }\n})\n\nwatch(dropdownVisible, (visible) => {\n if (visible) {\n // 面板展开后进入查询态并聚焦输入框,可以立即输入查询\n if (filterable.value) {\n queryString.value = ''\n querying.value = true\n nextTick(() => inputRef.value?.el?.focus())\n }\n } else {\n querying.value = false\n queryString.value = ''\n }\n})\n\nconst handleDropdownVisible = (visible: boolean) => {\n if (!visible) {\n queryString.value = ''\n }\n}\n\n/** 单选:用户动作内 O(1) 写入值与文案,跳过 modelValue 回显的 O(n) 查找 */\nconst handleSelect = userAction((option: Record<string, any>, _index: number) => {\n const value = option?.[valueKey.value]\n selected.value = option\n\n emit('update:modelValue', value)\n setLabel(option?.[labelKey.value])\n emit('change', option)\n if (option.__isTemp) {\n // 转正后列表同步重建为完整源(临时项置顶索引失效),必须按 value 重定位\n temOptionsToCreatedOptions()\n }\n // 立即退出查询态,输入框同步恢复显示选中标签\n querying.value = false\n queryString.value = ''\n // 按当前列表定位高亮,避免创建项转正后仍停留在点击时的临时索引(通常为 0)\n currentIndex.value = options.value.findIndex((item) => o(item).get(valueKey.value) === value)\n if (currentIndex.value >= 0) {\n selected.value = options.value[currentIndex.value]\n }\n dropdownRef.value?.close()\n})\n\n/** 清除选项 */\nconst handleClear = userAction(() => {\n selected.value = undefined\n currentIndex.value = -1\n setLabel(undefined)\n clearCreatedOptions()\n emit('update:modelValue', undefined)\n emit('change', undefined)\n})\n\nfunction getCurrentEl() {\n return scrollRef.value?.contentRef?.querySelector('li.is-selected') as HTMLElement | undefined\n}\n\nconst { handleKeydown } = useKeyboard({\n options,\n currentIndex,\n selectOption: handleSelect,\n getCurrentEl\n})\n</script>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"select.js","names":["$attrs","$slots"],"sources":["../../../src/components/select/select.vue"],"sourcesContent":["<template>\n <u-dropdown\n v-if=\"!readonly\"\n v-bind=\"$attrs\"\n trigger=\"click\"\n :class=\"[cls.b, bem.is('disabled', disabled)]\"\n ref=\"dropdownRef\"\n v-model:visible=\"dropdownVisible\"\n :content-class=\"[cls.e('panel'), cls.em('panel', size), contentClass]\"\n :content-style=\"contentStyle\"\n :disabled=\"disabled\"\n :min-width=\"minWidth\"\n :width=\"width\"\n @keydown=\"handleKeydown\"\n @mouseenter=\"hovered = true\"\n @mouseleave=\"hovered = false\"\n >\n <!-- 触发 -->\n <template #trigger>\n <u-input\n ref=\"inputRef\"\n :size=\"size\"\n :disabled=\"disabled\"\n :placeholder=\"inputPlaceholder\"\n :clearable=\"false\"\n :model-value=\"inputValue\"\n @update:model-value=\"handleQueryInput\"\n @keydown=\"handleKeydown\"\n :native-readonly=\"!filterable || !querying\"\n @click.capture=\"handleTriggerClickCapture\"\n >\n <template #prefix v-if=\"$slots.prefix\">\n <slot name=\"prefix\" />\n </template>\n\n <template #suffix>\n <transition name=\"zoom-in\" mode=\"out-in\">\n <u-icon\n v-if=\"showClear\"\n :class=\"cls.e('clear')\"\n title=\"清除\"\n key=\"clear\"\n @click.stop=\"handleClear\"\n >\n <Close />\n </u-icon>\n <u-icon v-else :class=\"cls.e('arrow')\" key=\"arrow\">\n <ArrowDown />\n </u-icon>\n </transition>\n </template>\n </u-input>\n </template>\n\n <!-- 下拉内容 -->\n <template #content>\n <!--\n 单选列表。虚拟化启用时,内容容器 height 由 useVirtualizer 命令式写入;\n 此处 content-style 仅承担 grid 相关样式,避免 height 变化触发模板重渲染。\n -->\n <u-scroll\n v-if=\"options.length\"\n tag=\"ul\"\n :class=\"cls.e('options')\"\n ref=\"scrollRef\"\n :content-class=\"[\n cls.e('options-wrap'),\n bem.is('virtual', virtualEnabled),\n bem.is('grid', !!grid)\n ]\"\n :content-style=\"{\n gridTemplateColumns: grid ? `repeat(${grid.cols}, minmax(0px, 1fr))` : undefined,\n gridGap: grid ? withUnit(grid.gap, 'px') : undefined\n }\"\n >\n <template v-if=\"virtualEnabled\">\n <!-- @vue-ignore -->\n <li\n v-for=\"{ option, index, val, label, key, offset } of virtualOptions\"\n :class=\"[optionClass, bem.is('selected', index === currentIndex)]\"\n @click=\"handleSelect(option, index)\"\n :key=\"key\"\n :style=\"{ transform: `translateY(${offset}px)` }\"\n :data-index=\"index\"\n :ref=\"(el) => measureElement(index, el as Element | null)\"\n >\n <slot v-bind=\"{ option, index }\">\n {{ label }}\n </slot>\n </li>\n </template>\n\n <template v-else>\n <li\n v-for=\"(option, index) of options\"\n :class=\"[optionClass, bem.is('selected', index === currentIndex)]\"\n @click=\"handleSelect(option, index)\"\n :data-index=\"index\"\n :title=\"o(option).get(labelKey)\"\n :key=\"o(option).get(valueKey)\"\n >\n <slot v-bind=\"{ option, index }\">\n {{ o(option).get(labelKey) }}\n </slot>\n </li>\n </template>\n </u-scroll>\n\n <div v-else :class=\"cls.e('empty')\">\n <UEmpty />\n </div>\n </template>\n </u-dropdown>\n\n <template v-else>\n {{ displayedValue || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { o } from '@cat-kit/core'\nimport { useFormFallbackProps, useUserAction, useVirtualizer } from '@veltra/compositions'\nimport { ArrowDown, Close } from '@veltra/icons/normal'\nimport { bem, fieldKey, FORM_EMPTY_CONTENT, scrollIntoContainerView, withUnit } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed, nextTick, shallowRef, useTemplateRef, watch } from 'vue'\n\nimport type {\n SelectEmits,\n SelectProps,\n _SelectExposed,\n DropdownExposed,\n InputExposed,\n ScrollExposed\n} from '../../types'\nimport { UDropdown } from '../dropdown'\nimport { UEmpty } from '../empty'\nimport { UIcon } from '../icon'\nimport { UInput } from '../input'\nimport { UScroll } from '../scroll'\nimport { useKeyboard } from './use-keyboard'\nimport { useOptions } from './use-options'\n\ndefineOptions({ name: 'USelect', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SelectProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n placeholder: '请选择',\n clearable: true,\n disabled: undefined,\n readonly: undefined\n})\n\nconst emit = defineEmits<SelectEmits>()\n\ndefineSlots<{\n /** 前缀插槽 */\n prefix?: () => any\n /** 默认插槽 */\n default?: (scope: { option: Record<string, any>; index: number }) => any\n}>()\n\nconst cls = bem('select')\n\nconst labelKey = computed(() => fieldKey(props.labelKey, 'label'))\nconst valueKey = computed(() => fieldKey(props.valueKey, 'value'))\n\nconst optionClass = cls.e('option')\n\nconst { formProps } = injectFormContext()\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default',\n disabled: false,\n readonly: false\n})\n\nconst currentIndex = shallowRef(-1)\n/** 内部展示文案,仅由选项推导;通过 update:text 单向通知父级 */\nconst label = shallowRef<string>()\nconst selected = shallowRef<Record<string, any>>()\n\nconst displayedValue = computed(() => {\n if (label.value) return label.value\n\n return selected.value ? o(selected.value).get(labelKey.value) : String(props.modelValue ?? '')\n})\n\nconst dropdownRef = shallowRef<DropdownExposed>()\nconst scrollRef = shallowRef<ScrollExposed>()\nconst inputRef = useTemplateRef<InputExposed>('inputRef')\n\nconst filterable = computed(() => {\n return props.filterable || typeof props.options === 'function'\n})\n\nconst { queryString, options, allOptions, temOptionsToCreatedOptions, clearCreatedOptions } =\n useOptions({ props })\n\nconst dropdownVisible = shallowRef(false)\n\n/** 选中临时选项后待转正标记:面板关闭后再落定,避免关闭动画期间列表恢复全量导致面板变长 */\nlet pendingTempPromote = false\n\n/**\n * 是否处于查询态:决定触发输入框显示查询串还是选中标签。\n * 与面板可见状态解耦 —— 选择后立即退出查询态,\n * 不等面板关闭动画结束(否则显示值会延迟一个动画时长才恢复)。\n */\nconst querying = shallowRef(false)\n\n/** 触发输入框的值:查询态下承载查询串,否则展示选中标签 */\nconst inputValue = computed(() => {\n if (filterable.value && querying.value) return queryString.value\n return displayedValue.value\n})\n\n/** 查询态下已选标签降级为占位提示 */\nconst inputPlaceholder = computed(() => {\n if (filterable.value && querying.value && displayedValue.value) {\n return displayedValue.value\n }\n return props.placeholder\n})\n\nfunction handleQueryInput(value: string) {\n if (!filterable.value) return\n queryString.value = value\n}\n\nconst hovered = shallowRef(false)\n\n/** 悬停且存在选中值时展示清除按钮(替代下拉箭头) */\nconst showClear = computed(() => {\n return props.clearable && !disabled.value && hovered.value && !!displayedValue.value\n})\n\n/**\n * 过滤模式下拦截输入区域的点击:\n * 阻止 dropdown 的 trigger 开合切换,保持面板展开以不中断输入。\n * 非输入区域(箭头、留白)放行,维持原开合行为。\n */\nfunction handleTriggerClickCapture(e: MouseEvent) {\n if (!filterable.value || disabled.value) return\n if (!(e.target instanceof HTMLInputElement)) return\n\n e.stopPropagation()\n if (!dropdownVisible.value) dropdownRef.value?.open()\n}\n\nconst { userAction, isUserActive } = useUserAction()\n\n/** 更新内部文案;值变化时单向 emit update:text */\nfunction setLabel(next?: string) {\n if (label.value === next) return\n label.value = next\n emit('update:text', next)\n}\n\n/** 按 modelValue 与完整选项列表同步高亮索引、选中项与显示标签(外部回显用,O(n)) */\nfunction syncSelected(modelValue: any, sourceOptions: Record<string, any>[] | undefined) {\n // 查询输入期间高亮第一项(创建模式下通常是临时项,便于回车创建)\n if (queryString.value) {\n currentIndex.value = options.value.length ? 0 : -1\n return\n }\n\n if (!sourceOptions?.length) return\n\n if (modelValue !== undefined && modelValue !== null && modelValue !== '') {\n currentIndex.value = sourceOptions.findIndex(\n (option) => o(option).get(valueKey.value) === modelValue\n )\n selected.value = currentIndex.value >= 0 ? sourceOptions[currentIndex.value] : undefined\n setLabel(selected.value ? o(selected.value).get(labelKey.value) : undefined)\n } else {\n currentIndex.value = -1\n selected.value = undefined\n setLabel(undefined)\n }\n}\n\n// 回显:以 allOptions 匹配,避免过滤列表缺项时清掉已选文案;用户动作期内跳过\nwatch(\n [() => props.modelValue, allOptions],\n ([modelValue]) => {\n if (isUserActive()) return\n syncSelected(modelValue, allOptions.value)\n },\n { immediate: true }\n)\n\n// 过滤时单独同步高亮(allOptions 不变,不会触发上方回显 watch)\nwatch([queryString, options], () => {\n if (!queryString.value) return\n currentIndex.value = options.value.length ? 0 : -1\n})\n\nconst baseVirtualEnabled = computed(() => options.value.length > 80)\nconst virtualEnabled = computed(() => baseVirtualEnabled.value && !props.grid)\n\nconst { virtualizer, items } = useVirtualizer({\n count: computed(() => options.value.length),\n scrollEl: () => scrollRef.value?.containerRef ?? null,\n contentEl: () => (virtualEnabled.value ? (scrollRef.value?.contentRef ?? null) : null),\n gap: 4,\n estimateSize: () => 40\n})\n\nconst virtualOptions = computed(() => {\n const _options = options.value\n return items.value.map((item) => {\n const option = _options[item.index]!\n return {\n option,\n index: item.index,\n label: o(option).get(labelKey.value),\n val: o(option).get(valueKey.value),\n key: item.index,\n offset: item.start\n }\n })\n})\n\nconst measureElement: (index: number, el: Element | null) => void = (index, el) =>\n virtualizer.measureElement(index, el)\n\nfunction scrollTo(index: number): void {\n virtualizer.scrollToIndex(index, { align: 'center' })\n}\n\nwatch([scrollRef, virtualEnabled], ([scroll, virtualEnabled]) => {\n if (!scroll || !props.modelValue) return\n\n if (virtualEnabled) {\n const index = options.value.findIndex((option) => option === selected.value)\n index !== -1 && dropdownVisible.value && nextTick(() => scrollTo(index))\n } else {\n const selectedEl = scroll?.contentRef?.getElementsByClassName('is-selected')[0]\n if (selectedEl) {\n scrollIntoContainerView(selectedEl as HTMLElement, scroll.containerRef ?? null)\n }\n }\n})\n\n/** 落定待转正的临时选项(面板 DOM 已卸载,列表恢复全量用户不可见) */\nfunction promotePendingTemp() {\n if (!pendingTempPromote) return\n pendingTempPromote = false\n temOptionsToCreatedOptions()\n}\n\nwatch(dropdownVisible, (visible) => {\n if (visible) {\n // 关闭动画期间被重新打开时补一次转正,保证已选临时项落到完整列表\n promotePendingTemp()\n // 面板展开后进入查询态并聚焦输入框,可以立即输入查询\n if (filterable.value) {\n queryString.value = ''\n querying.value = true\n nextTick(() => inputRef.value?.el?.focus())\n }\n } else {\n // 面板完全关闭(动画结束、DOM 卸载)后才清空查询串并转正,关闭动画期间列表保持过滤态\n querying.value = false\n queryString.value = ''\n promotePendingTemp()\n }\n})\n\n/** 单选:用户动作内 O(1) 写入值与文案,跳过 modelValue 回显的 O(n) 查找 */\nconst handleSelect = userAction((option: Record<string, any>, _index: number) => {\n const value = option?.[valueKey.value]\n selected.value = option\n\n emit('update:modelValue', value)\n setLabel(option?.[labelKey.value])\n emit('change', option)\n if (option.__isTemp) {\n // 转正延迟到面板关闭后:动画期间保持过滤列表,避免列表瞬间恢复全量导致面板变长闪烁\n pendingTempPromote = true\n }\n // 立即退出查询态,输入框同步恢复显示选中标签;查询串保留至面板关闭,避免关闭动画期间列表恢复全量\n querying.value = false\n // 按当前列表定位高亮(临时项尚未转正,仍在过滤列表中,通常为 0)\n currentIndex.value = options.value.findIndex((item) => o(item).get(valueKey.value) === value)\n if (currentIndex.value >= 0) {\n selected.value = options.value[currentIndex.value]\n }\n dropdownRef.value?.close()\n})\n\n/** 清除选项 */\nconst handleClear = userAction(() => {\n selected.value = undefined\n currentIndex.value = -1\n setLabel(undefined)\n clearCreatedOptions()\n emit('update:modelValue', undefined)\n emit('change', undefined)\n})\n\nfunction getCurrentEl() {\n return scrollRef.value?.contentRef?.querySelector('li.is-selected') as HTMLElement | undefined\n}\n\nconst { handleKeydown } = useKeyboard({\n options,\n currentIndex,\n selectOption: handleSelect,\n getCurrentEl\n})\n</script>\n"],"mappings":"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"}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* --u-height-default: 32px;
|
|
15
15
|
* --u-height-small: 24px;
|
|
16
16
|
*/
|
|
17
|
-
/**
|
|
17
|
+
/** 暗色:`UITheme.render()` 按主题系列写入 html[data-theme] */
|
|
18
18
|
.u-table-editor .u-table__body .u-table__cell {
|
|
19
19
|
padding: 2px;
|
|
20
20
|
}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* --u-height-default: 32px;
|
|
15
15
|
* --u-height-small: 24px;
|
|
16
16
|
*/
|
|
17
|
-
/**
|
|
17
|
+
/** 暗色:`UITheme.render()` 按主题系列写入 html[data-theme] */
|
|
18
18
|
/** shadcn 风格 TabsList:hover 背景底色容器 + 白底活动态;rounded=true 时水平为胶囊状。 */
|
|
19
19
|
/* ===== 复合标签页:bar + content 布局容器 ===== */
|
|
20
20
|
.u-tabs {
|
|
@@ -50,7 +50,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
50
50
|
});
|
|
51
51
|
watch(sourceTheme, (theme) => {
|
|
52
52
|
if (!props.theme && theme === editorTheme.value) return;
|
|
53
|
-
const nextTheme = props.theme ? theme : new UITheme(createThemeSnapshot(theme.theme));
|
|
53
|
+
const nextTheme = props.theme ? theme : new UITheme(createThemeSnapshot(theme.theme), { series: theme.series });
|
|
54
54
|
editorTheme.value = nextTheme;
|
|
55
55
|
baselineTheme.value = createThemeSnapshot(nextTheme.theme);
|
|
56
56
|
baselineLabel.value = theme === darkTheme ? "深色预设" : theme === lightTheme ? "浅色预设" : props.theme ? "外部主题" : "当前主题";
|
|
@@ -159,6 +159,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
159
159
|
editorTheme.value.render();
|
|
160
160
|
}
|
|
161
161
|
function applyPreset(type) {
|
|
162
|
+
if (editorTheme.value) editorTheme.value.series = type;
|
|
162
163
|
applySnapshot(type === "dark" ? darkPreset : lightPreset, type === "dark" ? "深色预设" : "浅色预设");
|
|
163
164
|
}
|
|
164
165
|
function handleResetTheme() {
|