y-element-ultra 0.1.0 → 0.1.1

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.
@@ -72,3 +72,4 @@ export { default as YUploadList } from './y-upload-list/index';
72
72
  export { default as YViewer } from './y-viewer/index';
73
73
  export { default as YVirtualTable } from './y-virtual-table/index';
74
74
  export { default as YWatermark } from './y-watermark/index';
75
+ export { default as YRangeInput } from './y-range-input/index';
@@ -72,6 +72,7 @@ import { default as default72 } from "./y-upload-list/index";
72
72
  import { default as default73 } from "./y-viewer/index";
73
73
  import { default as default74 } from "./y-virtual-table/index";
74
74
  import { default as default75 } from "./y-watermark/index";
75
+ import { default as default76 } from "./y-range-input/index";
75
76
  export {
76
77
  default2 as YAdminLayout,
77
78
  default3 as YAlert,
@@ -123,6 +124,7 @@ export {
123
124
  default49 as YQrCode,
124
125
  default50 as YQrCodeSvg,
125
126
  default51 as YRadioGroup,
127
+ default76 as YRangeInput,
126
128
  default52 as YSegmented,
127
129
  default53 as YSelect,
128
130
  default54 as YSelectTree,
@@ -55,3 +55,4 @@
55
55
  @use '../y-upload-list/style/index.scss' as uploadList;
56
56
  @use '../y-viewer/style/index.scss' as viewer;
57
57
  @use '../y-virtual-table/style/index.scss' as virtualTable;
58
+ @use '../y-range-input/style/index.scss' as rangeInput;
@@ -1516,7 +1516,10 @@ $y: map.deep-merge(
1516
1516
  // 文本域大尺寸
1517
1517
  'padding-top': 8px,
1518
1518
  'padding-bottom': 8px
1519
- )
1519
+ ),
1520
+ 'range-input': (
1521
+ // 范围输入框
1522
+ ),
1520
1523
  ),
1521
1524
  $y
1522
1525
  );
@@ -3,7 +3,7 @@ declare function __VLS_template(): Partial<Record<NonNullable<string | number>,
3
3
  };
4
4
  declare const __VLS_component: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
5
5
  modelValue: {
6
- type: StringConstructor;
6
+ type: (NumberConstructor | StringConstructor)[];
7
7
  default: () => string;
8
8
  };
9
9
  inputType: {
@@ -26,7 +26,7 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
26
26
  "update:modelValue": (_value: any, _e?: MouseEvent | undefined) => void;
27
27
  }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
28
28
  modelValue: {
29
- type: StringConstructor;
29
+ type: (NumberConstructor | StringConstructor)[];
30
30
  default: () => string;
31
31
  };
32
32
  inputType: {
@@ -48,7 +48,7 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
48
48
  }>> & Readonly<{
49
49
  "onUpdate:modelValue"?: ((_value: any, _e?: MouseEvent | undefined) => any) | undefined;
50
50
  }>, {
51
- modelValue: string;
51
+ modelValue: string | number;
52
52
  inputType: string;
53
53
  placeholder: string;
54
54
  decimalLimit: number;
@@ -5,7 +5,7 @@ import { ExtractPropTypes } from 'vue';
5
5
  */
6
6
  export declare const inputProps: {
7
7
  modelValue: {
8
- type: StringConstructor;
8
+ type: (StringConstructor | NumberConstructor)[];
9
9
  default: () => string;
10
10
  };
11
11
  inputType: {
@@ -1,7 +1,7 @@
1
1
  const inputProps = {
2
2
  // v-model绑定的值
3
3
  modelValue: {
4
- type: String,
4
+ type: [String, Number],
5
5
  default: () => ""
6
6
  },
7
7
  // 拓展类型标注(text、amount、phone、integer、decimal、idCard)
@@ -0,0 +1,113 @@
1
+ import { RangeInputValue } from './props';
2
+
3
+ declare function __VLS_template(): {
4
+ prefix?(_: {}): any;
5
+ suffix?(_: {}): any;
6
+ };
7
+ declare const __VLS_component: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
8
+ modelValue: {
9
+ type: import('vue').PropType<RangeInputValue>;
10
+ default: () => never[];
11
+ };
12
+ min: {
13
+ type: NumberConstructor;
14
+ default: number;
15
+ };
16
+ max: {
17
+ type: NumberConstructor;
18
+ default: number;
19
+ };
20
+ precision: {
21
+ type: NumberConstructor;
22
+ default: number;
23
+ };
24
+ rangeSeparator: {
25
+ type: StringConstructor;
26
+ default: string;
27
+ };
28
+ clearable: {
29
+ type: BooleanConstructor;
30
+ default: boolean;
31
+ };
32
+ disabled: {
33
+ type: BooleanConstructor;
34
+ default: boolean;
35
+ };
36
+ minPlaceholder: {
37
+ type: StringConstructor;
38
+ default: string;
39
+ };
40
+ maxPlaceholder: {
41
+ type: StringConstructor;
42
+ default: string;
43
+ };
44
+ size: {
45
+ type: import('vue').PropType<import('./props').RangeInputSize>;
46
+ default: string;
47
+ };
48
+ }>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
49
+ "update:modelValue": (_value: RangeInputValue) => void;
50
+ clear: () => void;
51
+ }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
52
+ modelValue: {
53
+ type: import('vue').PropType<RangeInputValue>;
54
+ default: () => never[];
55
+ };
56
+ min: {
57
+ type: NumberConstructor;
58
+ default: number;
59
+ };
60
+ max: {
61
+ type: NumberConstructor;
62
+ default: number;
63
+ };
64
+ precision: {
65
+ type: NumberConstructor;
66
+ default: number;
67
+ };
68
+ rangeSeparator: {
69
+ type: StringConstructor;
70
+ default: string;
71
+ };
72
+ clearable: {
73
+ type: BooleanConstructor;
74
+ default: boolean;
75
+ };
76
+ disabled: {
77
+ type: BooleanConstructor;
78
+ default: boolean;
79
+ };
80
+ minPlaceholder: {
81
+ type: StringConstructor;
82
+ default: string;
83
+ };
84
+ maxPlaceholder: {
85
+ type: StringConstructor;
86
+ default: string;
87
+ };
88
+ size: {
89
+ type: import('vue').PropType<import('./props').RangeInputSize>;
90
+ default: string;
91
+ };
92
+ }>> & Readonly<{
93
+ "onUpdate:modelValue"?: ((_value: RangeInputValue) => any) | undefined;
94
+ onClear?: (() => any) | undefined;
95
+ }>, {
96
+ modelValue: RangeInputValue;
97
+ min: number;
98
+ max: number;
99
+ precision: number;
100
+ rangeSeparator: string;
101
+ clearable: boolean;
102
+ disabled: boolean;
103
+ minPlaceholder: string;
104
+ maxPlaceholder: string;
105
+ size: import('./props').RangeInputSize;
106
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
107
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, ReturnType<typeof __VLS_template>>;
108
+ export default _default;
109
+ type __VLS_WithTemplateSlots<T, S> = T & {
110
+ new (): {
111
+ $slots: S;
112
+ };
113
+ };
@@ -0,0 +1,152 @@
1
+ import { defineComponent, ref, computed, watch, resolveComponent, createElementBlock, openBlock, normalizeClass, createBlock, createElementVNode, createSlots, withCtx, renderSlot, toDisplayString, createCommentVNode, unref, withModifiers, createVNode, nextTick } from "vue";
2
+ import { ElIcon } from "element-plus";
3
+ import { CloseCircleFilled } from "../icons/index";
4
+ import { rangeInputEmits, rangeInputProps } from "./props";
5
+ const _hoisted_1 = { class: "y-range-separator" };
6
+ const _hoisted_2 = { class: "y-range-input-suffix" };
7
+ const _hoisted_3 = {
8
+ key: 0,
9
+ class: "y-range-input-suffix-content"
10
+ };
11
+ const _sfc_main = /* @__PURE__ */ defineComponent({
12
+ ...{ name: "YRangeInput" },
13
+ __name: "index",
14
+ props: rangeInputProps,
15
+ emits: rangeInputEmits,
16
+ setup(__props, { emit: __emit }) {
17
+ const props = __props;
18
+ const emit = __emit;
19
+ const displayValue = ref([null, null]);
20
+ const inputRenderKey = ref(0);
21
+ const isClearing = ref(false);
22
+ const hasValue = computed(
23
+ () => displayValue.value.some((item) => item !== null)
24
+ );
25
+ const showClear = computed(() => !props.disabled && hasValue.value);
26
+ const normalizeInputValue = (value) => {
27
+ if (value == null || Number.isNaN(value)) {
28
+ return null;
29
+ }
30
+ return value;
31
+ };
32
+ watch(
33
+ () => props.modelValue,
34
+ (val) => {
35
+ if (val.length === 0) {
36
+ displayValue.value = [null, null];
37
+ return;
38
+ }
39
+ displayValue.value = [...val];
40
+ },
41
+ { immediate: true }
42
+ );
43
+ const updateDisplayValue = (index, value) => {
44
+ if (isClearing.value) {
45
+ return;
46
+ }
47
+ const nextValue = normalizeInputValue(value);
48
+ const nextDisplay = [...displayValue.value];
49
+ nextDisplay[index] = nextValue;
50
+ displayValue.value = nextDisplay;
51
+ };
52
+ const onChange = (index) => {
53
+ if (isClearing.value) {
54
+ return;
55
+ }
56
+ let left = displayValue.value[0];
57
+ let right = displayValue.value[1];
58
+ if (left !== null && right !== null) {
59
+ if (left > right) {
60
+ if (index === 0) left = right;
61
+ else right = left;
62
+ displayValue.value = [left, right];
63
+ }
64
+ }
65
+ if (left === null && right === null) {
66
+ emit("update:modelValue", []);
67
+ return;
68
+ }
69
+ emit("update:modelValue", [left, right]);
70
+ };
71
+ const onClear = async () => {
72
+ if (!showClear.value) return;
73
+ isClearing.value = true;
74
+ displayValue.value = [null, null];
75
+ inputRenderKey.value += 1;
76
+ emit("update:modelValue", []);
77
+ emit("clear");
78
+ await nextTick();
79
+ isClearing.value = false;
80
+ };
81
+ return (_ctx, _cache) => {
82
+ const _component_el_input_number = resolveComponent("el-input-number");
83
+ return openBlock(), createElementBlock("div", {
84
+ class: normalizeClass([{
85
+ "is-disabled": props.disabled
86
+ }, "y-range-input"])
87
+ }, [
88
+ (openBlock(), createBlock(_component_el_input_number, {
89
+ key: `left-${inputRenderKey.value}`,
90
+ "model-value": displayValue.value[0],
91
+ placeholder: props.minPlaceholder,
92
+ disabled: props.disabled,
93
+ min: props.min,
94
+ max: displayValue.value[1] !== null ? displayValue.value[1] : props.max,
95
+ size: props.size,
96
+ precision: props.precision,
97
+ controls: false,
98
+ class: "y-input-number-left",
99
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => updateDisplayValue(0, $event)),
100
+ onChange: _cache[1] || (_cache[1] = ($event) => onChange(0))
101
+ }, createSlots({ _: 2 }, [
102
+ _ctx.$slots.prefix ? {
103
+ name: "prefix",
104
+ fn: withCtx(() => [
105
+ renderSlot(_ctx.$slots, "prefix")
106
+ ]),
107
+ key: "0"
108
+ } : void 0
109
+ ]), 1032, ["model-value", "placeholder", "disabled", "min", "max", "size", "precision"])),
110
+ createElementVNode("span", _hoisted_1, toDisplayString(props.rangeSeparator), 1),
111
+ (openBlock(), createBlock(_component_el_input_number, {
112
+ key: `right-${inputRenderKey.value}`,
113
+ "model-value": displayValue.value[1],
114
+ placeholder: props.maxPlaceholder,
115
+ disabled: props.disabled,
116
+ min: displayValue.value[0] !== null ? displayValue.value[0] : props.min,
117
+ max: props.max,
118
+ size: props.size,
119
+ controls: false,
120
+ precision: props.precision,
121
+ class: "y-input-number-right",
122
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => updateDisplayValue(1, $event)),
123
+ onChange: _cache[4] || (_cache[4] = ($event) => onChange(1))
124
+ }, {
125
+ suffix: withCtx(() => [
126
+ createElementVNode("div", _hoisted_2, [
127
+ _ctx.$slots.suffix ? (openBlock(), createElementBlock("div", _hoisted_3, [
128
+ renderSlot(_ctx.$slots, "suffix")
129
+ ])) : createCommentVNode("", true),
130
+ showClear.value ? (openBlock(), createBlock(unref(ElIcon), {
131
+ key: 1,
132
+ class: "y-range-input-clear",
133
+ onMousedown: _cache[2] || (_cache[2] = withModifiers(() => {
134
+ }, ["prevent"])),
135
+ onClick: withModifiers(onClear, ["stop"])
136
+ }, {
137
+ default: withCtx(() => [
138
+ createVNode(unref(CloseCircleFilled))
139
+ ]),
140
+ _: 1
141
+ })) : createCommentVNode("", true)
142
+ ])
143
+ ]),
144
+ _: 3
145
+ }, 8, ["model-value", "placeholder", "disabled", "min", "max", "size", "precision"]))
146
+ ], 2);
147
+ };
148
+ }
149
+ });
150
+ export {
151
+ _sfc_main as default
152
+ };
@@ -0,0 +1,62 @@
1
+ import { ExtractPropTypes, PropType } from 'vue';
2
+
3
+ export type RangeInputValue = Array<number | null>;
4
+ export type RangeInputSize = '' | 'default' | 'small' | 'large';
5
+ /** 属性 */
6
+ export declare const rangeInputProps: {
7
+ /** 输入框范围输入值 */
8
+ modelValue: {
9
+ type: PropType<RangeInputValue>;
10
+ default: () => never[];
11
+ };
12
+ /** 最小值 */
13
+ min: {
14
+ type: NumberConstructor;
15
+ default: number;
16
+ };
17
+ /** 最大值 */
18
+ max: {
19
+ type: NumberConstructor;
20
+ default: number;
21
+ };
22
+ /** 精度 */
23
+ precision: {
24
+ type: NumberConstructor;
25
+ default: number;
26
+ };
27
+ /** 分隔符 */
28
+ rangeSeparator: {
29
+ type: StringConstructor;
30
+ default: string;
31
+ };
32
+ /** 是否可清空 */
33
+ clearable: {
34
+ type: BooleanConstructor;
35
+ default: boolean;
36
+ };
37
+ /** 是否禁用 */
38
+ disabled: {
39
+ type: BooleanConstructor;
40
+ default: boolean;
41
+ };
42
+ /** 最小值占位符 */
43
+ minPlaceholder: {
44
+ type: StringConstructor;
45
+ default: string;
46
+ };
47
+ /** 最大值占位符 */
48
+ maxPlaceholder: {
49
+ type: StringConstructor;
50
+ default: string;
51
+ };
52
+ /** 输入框范围输入大小 */
53
+ size: {
54
+ type: PropType<RangeInputSize>;
55
+ default: string;
56
+ };
57
+ };
58
+ export type RangeInputProps = ExtractPropTypes<typeof rangeInputProps>;
59
+ export declare const rangeInputEmits: {
60
+ 'update:modelValue': (_value: RangeInputValue) => boolean;
61
+ clear: () => boolean;
62
+ };
@@ -0,0 +1,60 @@
1
+ const rangeInputProps = {
2
+ /** 输入框范围输入值 */
3
+ modelValue: {
4
+ type: Array,
5
+ default: () => []
6
+ },
7
+ /** 最小值 */
8
+ min: {
9
+ type: Number,
10
+ default: -Infinity
11
+ },
12
+ /** 最大值 */
13
+ max: {
14
+ type: Number,
15
+ default: Infinity
16
+ },
17
+ /** 精度 */
18
+ precision: {
19
+ type: Number,
20
+ default: 0
21
+ },
22
+ /** 分隔符 */
23
+ rangeSeparator: {
24
+ type: String,
25
+ default: "To"
26
+ },
27
+ /** 是否可清空 */
28
+ clearable: {
29
+ type: Boolean,
30
+ default: false
31
+ },
32
+ /** 是否禁用 */
33
+ disabled: {
34
+ type: Boolean,
35
+ default: false
36
+ },
37
+ /** 最小值占位符 */
38
+ minPlaceholder: {
39
+ type: String,
40
+ default: "最小值"
41
+ },
42
+ /** 最大值占位符 */
43
+ maxPlaceholder: {
44
+ type: String,
45
+ default: "最大值"
46
+ },
47
+ /** 输入框范围输入大小 */
48
+ size: {
49
+ type: String,
50
+ default: "default"
51
+ }
52
+ };
53
+ const rangeInputEmits = {
54
+ "update:modelValue": (_value) => true,
55
+ clear: () => true
56
+ };
57
+ export {
58
+ rangeInputEmits,
59
+ rangeInputProps
60
+ };
@@ -0,0 +1,9 @@
1
+ @use '../../style/util.scss' as *;
2
+
3
+ /* 高级表单主题变量 */
4
+ @mixin set-range-input-var($var) {
5
+ .y-range-input {
6
+ @include set-y-var('input', $var);
7
+ @include set-y-var('input-error', $var);
8
+ }
9
+ }
@@ -0,0 +1 @@
1
+
@@ -0,0 +1 @@
1
+ import "./index.scss";
@@ -0,0 +1,124 @@
1
+ @use '../../style/themes/default.scss' as *;
2
+ @use '../../style/util.scss' as *;
3
+ @use './css-var.scss' as *;
4
+
5
+ @include set-range-input-var($y);
6
+
7
+ .el-form-item.is-error {
8
+ .y-range-input {
9
+ background: yVar('input-error', 'bg');
10
+ border-color: elVar('color-error');
11
+ box-shadow: yVar('input', 'hover-shadow');
12
+
13
+ &:hover:not(.is-disabled) {
14
+ background: yVar('input-error', 'hover-bg');
15
+ border-color: elVar('color-error');
16
+ box-shadow: yVar('input', 'hover-shadow');
17
+ }
18
+
19
+ &:focus-within:not(.is-disabled) {
20
+ background: yVar('input-error', 'focus-bg');
21
+ border-color: elVar('color-error');
22
+ box-shadow: yVar('input', 'focus-shadow');
23
+ }
24
+ }
25
+ }
26
+
27
+ .y-range-input {
28
+ width: 100%;
29
+ min-height: elVar('input', 'height');
30
+ display: flex;
31
+ align-items: center;
32
+ justify-content: space-between;
33
+ border: yVar('input', 'border');
34
+ background: yVar('input', 'bg');
35
+ border-radius: yVar('input', 'radius');
36
+ box-sizing: border-box;
37
+ transition: all $transition-base;
38
+ overflow: hidden;
39
+ cursor: text;
40
+ padding-left: yVar('input', 'padding-left');
41
+ padding-right: yVar('input', 'padding-right');
42
+
43
+ &:hover:not(.is-disabled) {
44
+ border-color: elVar('color-primary');
45
+ background: yVar('input', 'hover-bg');
46
+ box-shadow: yVar('input', 'hover-shadow');
47
+
48
+ .y-range-input-clear {
49
+ display: block;
50
+ }
51
+ }
52
+
53
+ &:focus-within:not(.is-disabled) {
54
+ border-color: elVar('color-primary');
55
+ background: yVar('input', 'hover-bg');
56
+ box-shadow: yVar('input', 'hover-shadow');
57
+ }
58
+
59
+ /** 左边数字输入 **/
60
+ .y-input-number-left {
61
+ .el-input__wrapper {
62
+ padding-left: 0 !important;
63
+ }
64
+ }
65
+
66
+ /** 右边数字输入 */
67
+ .y-input-number-right {
68
+ .el-input__wrapper {
69
+ padding-right: 0 !important;
70
+ }
71
+ }
72
+
73
+ .el-input-number {
74
+ width: 50%;
75
+
76
+ .el-input {
77
+ --el-input-hover-border-color: transparent;
78
+ --el-input-focus-border-color: transparent;
79
+ }
80
+
81
+ .el-input__wrapper {
82
+ border: none !important;
83
+ background: transparent !important;
84
+ box-shadow: none !important;
85
+ }
86
+ }
87
+
88
+ .y-range-separator {
89
+ flex-shrink: 0;
90
+ padding: 0 8px;
91
+ color: elVar('text-color', 'placeholder');
92
+ user-select: none;
93
+ }
94
+
95
+ .y-range-input-suffix {
96
+ display: flex;
97
+ align-items: center;
98
+ gap: yVar('input', 'icon-space');
99
+ }
100
+
101
+ .y-range-input-suffix-content {
102
+ display: flex;
103
+ align-items: center;
104
+ color: inherit;
105
+ }
106
+
107
+ .y-range-input-clear {
108
+ cursor: pointer;
109
+ color: yVar('input', 'clear-color');
110
+ transition: color $transition-base;
111
+ display: none;
112
+ }
113
+
114
+ &.is-disabled {
115
+ border: yVar('input', 'disabled-border');
116
+ background: yVar('input', 'disabled-bg');
117
+ box-shadow: none;
118
+ cursor: not-allowed;
119
+
120
+ .y-range-separator {
121
+ color: yVar('input', 'disabled-color');
122
+ }
123
+ }
124
+ }
@@ -74,6 +74,7 @@ const index$16 = require("./y-upload-list/index");
74
74
  const index$17 = require("./y-viewer/index");
75
75
  const index$18 = require("./y-virtual-table/index");
76
76
  const index$19 = require("./y-watermark/index");
77
+ const index$1a = require("./y-range-input/index");
77
78
  exports.YAdminLayout = index;
78
79
  exports.YAlert = index$1;
79
80
  exports.YApp = index$2;
@@ -148,3 +149,4 @@ exports.YUploadList = index$16;
148
149
  exports.YViewer = index$17;
149
150
  exports.YVirtualTable = index$18;
150
151
  exports.YWatermark = index$19;
152
+ exports.YRangeInput = index$1a;
@@ -72,3 +72,4 @@ export { default as YUploadList } from './y-upload-list/index';
72
72
  export { default as YViewer } from './y-viewer/index';
73
73
  export { default as YVirtualTable } from './y-virtual-table/index';
74
74
  export { default as YWatermark } from './y-watermark/index';
75
+ export { default as YRangeInput } from './y-range-input/index';
@@ -55,3 +55,4 @@
55
55
  @use '../y-upload-list/style/index.scss' as uploadList;
56
56
  @use '../y-viewer/style/index.scss' as viewer;
57
57
  @use '../y-virtual-table/style/index.scss' as virtualTable;
58
+ @use '../y-range-input/style/index.scss' as rangeInput;
@@ -1516,7 +1516,10 @@ $y: map.deep-merge(
1516
1516
  // 文本域大尺寸
1517
1517
  'padding-top': 8px,
1518
1518
  'padding-bottom': 8px
1519
- )
1519
+ ),
1520
+ 'range-input': (
1521
+ // 范围输入框
1522
+ ),
1520
1523
  ),
1521
1524
  $y
1522
1525
  );
@@ -3,7 +3,7 @@ declare function __VLS_template(): Partial<Record<NonNullable<string | number>,
3
3
  };
4
4
  declare const __VLS_component: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
5
5
  modelValue: {
6
- type: StringConstructor;
6
+ type: (NumberConstructor | StringConstructor)[];
7
7
  default: () => string;
8
8
  };
9
9
  inputType: {
@@ -26,7 +26,7 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
26
26
  "update:modelValue": (_value: any, _e?: MouseEvent | undefined) => void;
27
27
  }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
28
28
  modelValue: {
29
- type: StringConstructor;
29
+ type: (NumberConstructor | StringConstructor)[];
30
30
  default: () => string;
31
31
  };
32
32
  inputType: {
@@ -48,7 +48,7 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
48
48
  }>> & Readonly<{
49
49
  "onUpdate:modelValue"?: ((_value: any, _e?: MouseEvent | undefined) => any) | undefined;
50
50
  }>, {
51
- modelValue: string;
51
+ modelValue: string | number;
52
52
  inputType: string;
53
53
  placeholder: string;
54
54
  decimalLimit: number;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const inputProps = {
4
4
  // v-model绑定的值
5
5
  modelValue: {
6
- type: String,
6
+ type: [String, Number],
7
7
  default: () => ""
8
8
  },
9
9
  // 拓展类型标注(text、amount、phone、integer、decimal、idCard)
@@ -5,7 +5,7 @@ import { ExtractPropTypes } from 'vue';
5
5
  */
6
6
  export declare const inputProps: {
7
7
  modelValue: {
8
- type: StringConstructor;
8
+ type: (StringConstructor | NumberConstructor)[];
9
9
  default: () => string;
10
10
  };
11
11
  inputType: {
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+ const vue = require("vue");
3
+ const elementPlus = require("element-plus");
4
+ const index = require("../icons/index");
5
+ const props = require("./props");
6
+ const _hoisted_1 = { class: "y-range-separator" };
7
+ const _hoisted_2 = { class: "y-range-input-suffix" };
8
+ const _hoisted_3 = {
9
+ key: 0,
10
+ class: "y-range-input-suffix-content"
11
+ };
12
+ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
13
+ ...{ name: "YRangeInput" },
14
+ __name: "index",
15
+ props: props.rangeInputProps,
16
+ emits: props.rangeInputEmits,
17
+ setup(__props, { emit: __emit }) {
18
+ const props2 = __props;
19
+ const emit = __emit;
20
+ const displayValue = vue.ref([null, null]);
21
+ const inputRenderKey = vue.ref(0);
22
+ const isClearing = vue.ref(false);
23
+ const hasValue = vue.computed(
24
+ () => displayValue.value.some((item) => item !== null)
25
+ );
26
+ const showClear = vue.computed(() => !props2.disabled && hasValue.value);
27
+ const normalizeInputValue = (value) => {
28
+ if (value == null || Number.isNaN(value)) {
29
+ return null;
30
+ }
31
+ return value;
32
+ };
33
+ vue.watch(
34
+ () => props2.modelValue,
35
+ (val) => {
36
+ if (val.length === 0) {
37
+ displayValue.value = [null, null];
38
+ return;
39
+ }
40
+ displayValue.value = [...val];
41
+ },
42
+ { immediate: true }
43
+ );
44
+ const updateDisplayValue = (index2, value) => {
45
+ if (isClearing.value) {
46
+ return;
47
+ }
48
+ const nextValue = normalizeInputValue(value);
49
+ const nextDisplay = [...displayValue.value];
50
+ nextDisplay[index2] = nextValue;
51
+ displayValue.value = nextDisplay;
52
+ };
53
+ const onChange = (index2) => {
54
+ if (isClearing.value) {
55
+ return;
56
+ }
57
+ let left = displayValue.value[0];
58
+ let right = displayValue.value[1];
59
+ if (left !== null && right !== null) {
60
+ if (left > right) {
61
+ if (index2 === 0) left = right;
62
+ else right = left;
63
+ displayValue.value = [left, right];
64
+ }
65
+ }
66
+ if (left === null && right === null) {
67
+ emit("update:modelValue", []);
68
+ return;
69
+ }
70
+ emit("update:modelValue", [left, right]);
71
+ };
72
+ const onClear = async () => {
73
+ if (!showClear.value) return;
74
+ isClearing.value = true;
75
+ displayValue.value = [null, null];
76
+ inputRenderKey.value += 1;
77
+ emit("update:modelValue", []);
78
+ emit("clear");
79
+ await vue.nextTick();
80
+ isClearing.value = false;
81
+ };
82
+ return (_ctx, _cache) => {
83
+ const _component_el_input_number = vue.resolveComponent("el-input-number");
84
+ return vue.openBlock(), vue.createElementBlock("div", {
85
+ class: vue.normalizeClass([{
86
+ "is-disabled": props2.disabled
87
+ }, "y-range-input"])
88
+ }, [
89
+ (vue.openBlock(), vue.createBlock(_component_el_input_number, {
90
+ key: `left-${inputRenderKey.value}`,
91
+ "model-value": displayValue.value[0],
92
+ placeholder: props2.minPlaceholder,
93
+ disabled: props2.disabled,
94
+ min: props2.min,
95
+ max: displayValue.value[1] !== null ? displayValue.value[1] : props2.max,
96
+ size: props2.size,
97
+ precision: props2.precision,
98
+ controls: false,
99
+ class: "y-input-number-left",
100
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => updateDisplayValue(0, $event)),
101
+ onChange: _cache[1] || (_cache[1] = ($event) => onChange(0))
102
+ }, vue.createSlots({ _: 2 }, [
103
+ _ctx.$slots.prefix ? {
104
+ name: "prefix",
105
+ fn: vue.withCtx(() => [
106
+ vue.renderSlot(_ctx.$slots, "prefix")
107
+ ]),
108
+ key: "0"
109
+ } : void 0
110
+ ]), 1032, ["model-value", "placeholder", "disabled", "min", "max", "size", "precision"])),
111
+ vue.createElementVNode("span", _hoisted_1, vue.toDisplayString(props2.rangeSeparator), 1),
112
+ (vue.openBlock(), vue.createBlock(_component_el_input_number, {
113
+ key: `right-${inputRenderKey.value}`,
114
+ "model-value": displayValue.value[1],
115
+ placeholder: props2.maxPlaceholder,
116
+ disabled: props2.disabled,
117
+ min: displayValue.value[0] !== null ? displayValue.value[0] : props2.min,
118
+ max: props2.max,
119
+ size: props2.size,
120
+ controls: false,
121
+ precision: props2.precision,
122
+ class: "y-input-number-right",
123
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => updateDisplayValue(1, $event)),
124
+ onChange: _cache[4] || (_cache[4] = ($event) => onChange(1))
125
+ }, {
126
+ suffix: vue.withCtx(() => [
127
+ vue.createElementVNode("div", _hoisted_2, [
128
+ _ctx.$slots.suffix ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3, [
129
+ vue.renderSlot(_ctx.$slots, "suffix")
130
+ ])) : vue.createCommentVNode("", true),
131
+ showClear.value ? (vue.openBlock(), vue.createBlock(vue.unref(elementPlus.ElIcon), {
132
+ key: 1,
133
+ class: "y-range-input-clear",
134
+ onMousedown: _cache[2] || (_cache[2] = vue.withModifiers(() => {
135
+ }, ["prevent"])),
136
+ onClick: vue.withModifiers(onClear, ["stop"])
137
+ }, {
138
+ default: vue.withCtx(() => [
139
+ vue.createVNode(vue.unref(index.CloseCircleFilled))
140
+ ]),
141
+ _: 1
142
+ })) : vue.createCommentVNode("", true)
143
+ ])
144
+ ]),
145
+ _: 3
146
+ }, 8, ["model-value", "placeholder", "disabled", "min", "max", "size", "precision"]))
147
+ ], 2);
148
+ };
149
+ }
150
+ });
151
+ module.exports = _sfc_main;
@@ -0,0 +1,113 @@
1
+ import { RangeInputValue } from './props';
2
+
3
+ declare function __VLS_template(): {
4
+ prefix?(_: {}): any;
5
+ suffix?(_: {}): any;
6
+ };
7
+ declare const __VLS_component: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
8
+ modelValue: {
9
+ type: import('vue').PropType<RangeInputValue>;
10
+ default: () => never[];
11
+ };
12
+ min: {
13
+ type: NumberConstructor;
14
+ default: number;
15
+ };
16
+ max: {
17
+ type: NumberConstructor;
18
+ default: number;
19
+ };
20
+ precision: {
21
+ type: NumberConstructor;
22
+ default: number;
23
+ };
24
+ rangeSeparator: {
25
+ type: StringConstructor;
26
+ default: string;
27
+ };
28
+ clearable: {
29
+ type: BooleanConstructor;
30
+ default: boolean;
31
+ };
32
+ disabled: {
33
+ type: BooleanConstructor;
34
+ default: boolean;
35
+ };
36
+ minPlaceholder: {
37
+ type: StringConstructor;
38
+ default: string;
39
+ };
40
+ maxPlaceholder: {
41
+ type: StringConstructor;
42
+ default: string;
43
+ };
44
+ size: {
45
+ type: import('vue').PropType<import('./props').RangeInputSize>;
46
+ default: string;
47
+ };
48
+ }>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
49
+ "update:modelValue": (_value: RangeInputValue) => void;
50
+ clear: () => void;
51
+ }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
52
+ modelValue: {
53
+ type: import('vue').PropType<RangeInputValue>;
54
+ default: () => never[];
55
+ };
56
+ min: {
57
+ type: NumberConstructor;
58
+ default: number;
59
+ };
60
+ max: {
61
+ type: NumberConstructor;
62
+ default: number;
63
+ };
64
+ precision: {
65
+ type: NumberConstructor;
66
+ default: number;
67
+ };
68
+ rangeSeparator: {
69
+ type: StringConstructor;
70
+ default: string;
71
+ };
72
+ clearable: {
73
+ type: BooleanConstructor;
74
+ default: boolean;
75
+ };
76
+ disabled: {
77
+ type: BooleanConstructor;
78
+ default: boolean;
79
+ };
80
+ minPlaceholder: {
81
+ type: StringConstructor;
82
+ default: string;
83
+ };
84
+ maxPlaceholder: {
85
+ type: StringConstructor;
86
+ default: string;
87
+ };
88
+ size: {
89
+ type: import('vue').PropType<import('./props').RangeInputSize>;
90
+ default: string;
91
+ };
92
+ }>> & Readonly<{
93
+ "onUpdate:modelValue"?: ((_value: RangeInputValue) => any) | undefined;
94
+ onClear?: (() => any) | undefined;
95
+ }>, {
96
+ modelValue: RangeInputValue;
97
+ min: number;
98
+ max: number;
99
+ precision: number;
100
+ rangeSeparator: string;
101
+ clearable: boolean;
102
+ disabled: boolean;
103
+ minPlaceholder: string;
104
+ maxPlaceholder: string;
105
+ size: import('./props').RangeInputSize;
106
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
107
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, ReturnType<typeof __VLS_template>>;
108
+ export default _default;
109
+ type __VLS_WithTemplateSlots<T, S> = T & {
110
+ new (): {
111
+ $slots: S;
112
+ };
113
+ };
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const rangeInputProps = {
4
+ /** 输入框范围输入值 */
5
+ modelValue: {
6
+ type: Array,
7
+ default: () => []
8
+ },
9
+ /** 最小值 */
10
+ min: {
11
+ type: Number,
12
+ default: -Infinity
13
+ },
14
+ /** 最大值 */
15
+ max: {
16
+ type: Number,
17
+ default: Infinity
18
+ },
19
+ /** 精度 */
20
+ precision: {
21
+ type: Number,
22
+ default: 0
23
+ },
24
+ /** 分隔符 */
25
+ rangeSeparator: {
26
+ type: String,
27
+ default: "To"
28
+ },
29
+ /** 是否可清空 */
30
+ clearable: {
31
+ type: Boolean,
32
+ default: false
33
+ },
34
+ /** 是否禁用 */
35
+ disabled: {
36
+ type: Boolean,
37
+ default: false
38
+ },
39
+ /** 最小值占位符 */
40
+ minPlaceholder: {
41
+ type: String,
42
+ default: "最小值"
43
+ },
44
+ /** 最大值占位符 */
45
+ maxPlaceholder: {
46
+ type: String,
47
+ default: "最大值"
48
+ },
49
+ /** 输入框范围输入大小 */
50
+ size: {
51
+ type: String,
52
+ default: "default"
53
+ }
54
+ };
55
+ const rangeInputEmits = {
56
+ "update:modelValue": (_value) => true,
57
+ clear: () => true
58
+ };
59
+ exports.rangeInputEmits = rangeInputEmits;
60
+ exports.rangeInputProps = rangeInputProps;
@@ -0,0 +1,62 @@
1
+ import { ExtractPropTypes, PropType } from 'vue';
2
+
3
+ export type RangeInputValue = Array<number | null>;
4
+ export type RangeInputSize = '' | 'default' | 'small' | 'large';
5
+ /** 属性 */
6
+ export declare const rangeInputProps: {
7
+ /** 输入框范围输入值 */
8
+ modelValue: {
9
+ type: PropType<RangeInputValue>;
10
+ default: () => never[];
11
+ };
12
+ /** 最小值 */
13
+ min: {
14
+ type: NumberConstructor;
15
+ default: number;
16
+ };
17
+ /** 最大值 */
18
+ max: {
19
+ type: NumberConstructor;
20
+ default: number;
21
+ };
22
+ /** 精度 */
23
+ precision: {
24
+ type: NumberConstructor;
25
+ default: number;
26
+ };
27
+ /** 分隔符 */
28
+ rangeSeparator: {
29
+ type: StringConstructor;
30
+ default: string;
31
+ };
32
+ /** 是否可清空 */
33
+ clearable: {
34
+ type: BooleanConstructor;
35
+ default: boolean;
36
+ };
37
+ /** 是否禁用 */
38
+ disabled: {
39
+ type: BooleanConstructor;
40
+ default: boolean;
41
+ };
42
+ /** 最小值占位符 */
43
+ minPlaceholder: {
44
+ type: StringConstructor;
45
+ default: string;
46
+ };
47
+ /** 最大值占位符 */
48
+ maxPlaceholder: {
49
+ type: StringConstructor;
50
+ default: string;
51
+ };
52
+ /** 输入框范围输入大小 */
53
+ size: {
54
+ type: PropType<RangeInputSize>;
55
+ default: string;
56
+ };
57
+ };
58
+ export type RangeInputProps = ExtractPropTypes<typeof rangeInputProps>;
59
+ export declare const rangeInputEmits: {
60
+ 'update:modelValue': (_value: RangeInputValue) => boolean;
61
+ clear: () => boolean;
62
+ };
@@ -0,0 +1,9 @@
1
+ @use '../../style/util.scss' as *;
2
+
3
+ /* 高级表单主题变量 */
4
+ @mixin set-range-input-var($var) {
5
+ .y-range-input {
6
+ @include set-y-var('input', $var);
7
+ @include set-y-var('input-error', $var);
8
+ }
9
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ require("./index.scss");
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,124 @@
1
+ @use '../../style/themes/default.scss' as *;
2
+ @use '../../style/util.scss' as *;
3
+ @use './css-var.scss' as *;
4
+
5
+ @include set-range-input-var($y);
6
+
7
+ .el-form-item.is-error {
8
+ .y-range-input {
9
+ background: yVar('input-error', 'bg');
10
+ border-color: elVar('color-error');
11
+ box-shadow: yVar('input', 'hover-shadow');
12
+
13
+ &:hover:not(.is-disabled) {
14
+ background: yVar('input-error', 'hover-bg');
15
+ border-color: elVar('color-error');
16
+ box-shadow: yVar('input', 'hover-shadow');
17
+ }
18
+
19
+ &:focus-within:not(.is-disabled) {
20
+ background: yVar('input-error', 'focus-bg');
21
+ border-color: elVar('color-error');
22
+ box-shadow: yVar('input', 'focus-shadow');
23
+ }
24
+ }
25
+ }
26
+
27
+ .y-range-input {
28
+ width: 100%;
29
+ min-height: elVar('input', 'height');
30
+ display: flex;
31
+ align-items: center;
32
+ justify-content: space-between;
33
+ border: yVar('input', 'border');
34
+ background: yVar('input', 'bg');
35
+ border-radius: yVar('input', 'radius');
36
+ box-sizing: border-box;
37
+ transition: all $transition-base;
38
+ overflow: hidden;
39
+ cursor: text;
40
+ padding-left: yVar('input', 'padding-left');
41
+ padding-right: yVar('input', 'padding-right');
42
+
43
+ &:hover:not(.is-disabled) {
44
+ border-color: elVar('color-primary');
45
+ background: yVar('input', 'hover-bg');
46
+ box-shadow: yVar('input', 'hover-shadow');
47
+
48
+ .y-range-input-clear {
49
+ display: block;
50
+ }
51
+ }
52
+
53
+ &:focus-within:not(.is-disabled) {
54
+ border-color: elVar('color-primary');
55
+ background: yVar('input', 'hover-bg');
56
+ box-shadow: yVar('input', 'hover-shadow');
57
+ }
58
+
59
+ /** 左边数字输入 **/
60
+ .y-input-number-left {
61
+ .el-input__wrapper {
62
+ padding-left: 0 !important;
63
+ }
64
+ }
65
+
66
+ /** 右边数字输入 */
67
+ .y-input-number-right {
68
+ .el-input__wrapper {
69
+ padding-right: 0 !important;
70
+ }
71
+ }
72
+
73
+ .el-input-number {
74
+ width: 50%;
75
+
76
+ .el-input {
77
+ --el-input-hover-border-color: transparent;
78
+ --el-input-focus-border-color: transparent;
79
+ }
80
+
81
+ .el-input__wrapper {
82
+ border: none !important;
83
+ background: transparent !important;
84
+ box-shadow: none !important;
85
+ }
86
+ }
87
+
88
+ .y-range-separator {
89
+ flex-shrink: 0;
90
+ padding: 0 8px;
91
+ color: elVar('text-color', 'placeholder');
92
+ user-select: none;
93
+ }
94
+
95
+ .y-range-input-suffix {
96
+ display: flex;
97
+ align-items: center;
98
+ gap: yVar('input', 'icon-space');
99
+ }
100
+
101
+ .y-range-input-suffix-content {
102
+ display: flex;
103
+ align-items: center;
104
+ color: inherit;
105
+ }
106
+
107
+ .y-range-input-clear {
108
+ cursor: pointer;
109
+ color: yVar('input', 'clear-color');
110
+ transition: color $transition-base;
111
+ display: none;
112
+ }
113
+
114
+ &.is-disabled {
115
+ border: yVar('input', 'disabled-border');
116
+ background: yVar('input', 'disabled-bg');
117
+ box-shadow: none;
118
+ cursor: not-allowed;
119
+
120
+ .y-range-separator {
121
+ color: yVar('input', 'disabled-color');
122
+ }
123
+ }
124
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "y-element-ultra",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite --host",
@@ -60,6 +60,7 @@ declare module 'vue' {
60
60
  YQrCode: (typeof import('y-element-ultra'))['YQrCode'];
61
61
  YQrCodeSvg: (typeof import('y-element-ultra'))['YQrCodeSvg'];
62
62
  YRadioGroup: (typeof import('y-element-ultra'))['YRadioGroup'];
63
+ YRangeInput: (typeof import('y-element-ultra'))['YRangeInput'];
63
64
  YSegmented: (typeof import('y-element-ultra'))['YSegmented'];
64
65
  YSelect: (typeof import('y-element-ultra'))['YSelect'];
65
66
  YSelectTree: (typeof import('y-element-ultra'))['YSelectTree'];