plain-design 1.0.0-beta.78 → 1.0.0-beta.79
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/plain-design.commonjs.min.js +2 -2
- package/dist/plain-design.min.css +1 -0
- package/dist/plain-design.min.js +2 -2
- package/dist/report.html +2 -2
- package/package.json +1 -1
- package/src/packages/components/$search/SearchFooter.tsx +32 -0
- package/src/packages/components/$search/SearchList.tsx +206 -0
- package/src/packages/components/$search/SearchServicePanel.tsx +233 -0
- package/src/packages/components/$search/createSearchService.tsx +43 -0
- package/src/packages/components/$search/index.tsx +6 -0
- package/src/packages/components/$search/search-service.scss +220 -0
- package/src/packages/components/$search/search.utils.tsx +112 -0
- package/src/packages/components/Input/index.tsx +9 -1
- package/src/packages/components/Input/input.utils.ts +2 -1
- package/src/packages/components/Input/uses/useInputSuffixIcon.tsx +1 -1
- package/src/packages/components/Scroll/index.tsx +34 -0
- package/src/packages/components/Table/standard/PlcTree/PlcTree.renderNode.tsx +3 -0
- package/src/packages/entry.tsx +8 -0
- package/src/packages/i18n/lang/en-us.ts +9 -1
- package/src/packages/i18n/lang/zh-cn.ts +11 -3
- package/src/packages/utils/createListUtils.ts +38 -0
@@ -0,0 +1,220 @@
|
|
1
|
+
@include comp(dialog) {
|
2
|
+
&.#{componentName(search-service)} {
|
3
|
+
align-items: flex-start;
|
4
|
+
padding: 80px 0;
|
5
|
+
|
6
|
+
.dialog-content {
|
7
|
+
overflow: hidden;
|
8
|
+
}
|
9
|
+
|
10
|
+
@include comp(empty) {
|
11
|
+
min-height: 100px;
|
12
|
+
}
|
13
|
+
|
14
|
+
.search-service-input-box {
|
15
|
+
@include comp(input) {
|
16
|
+
border-color: plv(primary-6) !important;
|
17
|
+
|
18
|
+
.input-box {
|
19
|
+
color: plv(primary-6) !important;
|
20
|
+
font-size: 1.2em;
|
21
|
+
height: 2.5em !important;
|
22
|
+
}
|
23
|
+
|
24
|
+
.input-prefix-icon {
|
25
|
+
width: 2em;
|
26
|
+
font-size: 1.6em;
|
27
|
+
display: flex;
|
28
|
+
align-items: center;
|
29
|
+
justify-content: center;
|
30
|
+
color: plv(primary-6);
|
31
|
+
position: relative;
|
32
|
+
left: 0.15em;
|
33
|
+
}
|
34
|
+
.input-suffix-icon-wrapper {
|
35
|
+
width: 1.5em;
|
36
|
+
font-size: 1.6em;
|
37
|
+
}
|
38
|
+
@include comp(loading) {
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
.search-service-foot {
|
44
|
+
display: flex;
|
45
|
+
align-items: center;
|
46
|
+
justify-content: center;
|
47
|
+
font-size: 0.8em;
|
48
|
+
color: plv(text-3);
|
49
|
+
border-top: solid 1px plv(border-color);
|
50
|
+
|
51
|
+
& > * + * {
|
52
|
+
display: inline-block;
|
53
|
+
margin-left: 1em;
|
54
|
+
}
|
55
|
+
|
56
|
+
svg {
|
57
|
+
position: relative;
|
58
|
+
top: -1px;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
.search-service-option-virtual-list {
|
63
|
+
height: 50vh;
|
64
|
+
}
|
65
|
+
|
66
|
+
.search-service-option-item {
|
67
|
+
user-select: none;
|
68
|
+
|
69
|
+
.search-service-option-item-default {
|
70
|
+
text-align: left;
|
71
|
+
box-sizing: border-box;
|
72
|
+
|
73
|
+
&[data-service-item-type="group"] {
|
74
|
+
.search-service-option-item-default-title {
|
75
|
+
font-weight: 600;
|
76
|
+
color: plv(primary-6);
|
77
|
+
font-size: 1em;
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
&:not([data-service-item-type="group"]) {
|
82
|
+
background-color: plv(bg-4);
|
83
|
+
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.25);
|
84
|
+
transition: all ease 150ms;
|
85
|
+
|
86
|
+
.search-service-option-item-default-box {
|
87
|
+
display: flex;
|
88
|
+
align-items: center;
|
89
|
+
|
90
|
+
.search-service-option-item-default-label {
|
91
|
+
flex: 1;
|
92
|
+
display: flex;
|
93
|
+
flex-direction: column;
|
94
|
+
}
|
95
|
+
|
96
|
+
.search-service-option-item-default-button {
|
97
|
+
opacity: 0;
|
98
|
+
display: flex;
|
99
|
+
align-items: center;
|
100
|
+
}
|
101
|
+
}
|
102
|
+
}
|
103
|
+
|
104
|
+
}
|
105
|
+
|
106
|
+
&[data-active=true] {
|
107
|
+
.search-service-option-item-default {
|
108
|
+
&:not([data-service-item-type="group"]) {
|
109
|
+
background-color: plv(primary-6);
|
110
|
+
|
111
|
+
svg, .search-service-option-item-default-label {
|
112
|
+
color: plv(pbfc);
|
113
|
+
|
114
|
+
span {
|
115
|
+
color: plv(pbfc) !important;
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
.search-service-option-item-default-button {
|
120
|
+
opacity: 1;
|
121
|
+
}
|
122
|
+
}
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
126
|
+
.search-service-option-item-default-button {
|
127
|
+
padding: 0.2em;
|
128
|
+
|
129
|
+
&[data-search-button="favorite"], &[data-search-button="remove"] {
|
130
|
+
&:hover {
|
131
|
+
background-color: plv(primary-8);
|
132
|
+
border-radius: 99px;
|
133
|
+
}
|
134
|
+
}
|
135
|
+
|
136
|
+
&[data-search-button="favorite"] {
|
137
|
+
&:hover {
|
138
|
+
path {
|
139
|
+
fill: plv(pbfc)
|
140
|
+
}
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
& + .search-service-option-item-default-button {
|
145
|
+
margin-left: 0.1em !important;
|
146
|
+
}
|
147
|
+
}
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
151
|
+
@include comp(search-service-panel) {
|
152
|
+
@include sizeMixin(box, ()) {
|
153
|
+
.search-service-input-box {
|
154
|
+
padding: $margin;
|
155
|
+
@include comp(input) {
|
156
|
+
border-radius: calc(#{$border-radius} / 1.5);
|
157
|
+
}
|
158
|
+
}
|
159
|
+
.search-service-foot {
|
160
|
+
padding: calc(#{$margin});
|
161
|
+
}
|
162
|
+
|
163
|
+
.search-service-option-item {
|
164
|
+
width: calc(100% - (#{$margin} * 2));
|
165
|
+
margin-left: $margin;
|
166
|
+
padding-bottom: 8px;
|
167
|
+
|
168
|
+
.search-service-option-item-default {
|
169
|
+
border-radius: calc(#{$border-radius} / 1.5);
|
170
|
+
|
171
|
+
&:not([data-service-item-type="group"]) {
|
172
|
+
padding: calc(#{$margin} / 2);
|
173
|
+
cursor: pointer;
|
174
|
+
|
175
|
+
.search-service-option-item-default-box {
|
176
|
+
min-height: calc(3.5em - #{$margin} / 2);
|
177
|
+
|
178
|
+
& > * + * {
|
179
|
+
margin-left: 0.5em;
|
180
|
+
}
|
181
|
+
|
182
|
+
.search-service-option-item-default-tree {
|
183
|
+
width: 1.8em;
|
184
|
+
height: 3.2em;
|
185
|
+
}
|
186
|
+
|
187
|
+
.search-service-option-item-default-label {
|
188
|
+
|
189
|
+
& > span:nth-child(1) {
|
190
|
+
color: plv(text-1);
|
191
|
+
}
|
192
|
+
|
193
|
+
& > span:nth-child(2) {
|
194
|
+
color: plv(text-3);
|
195
|
+
font-size: 0.8em;
|
196
|
+
margin-top: 0.25em;
|
197
|
+
}
|
198
|
+
}
|
199
|
+
}
|
200
|
+
}
|
201
|
+
}
|
202
|
+
}
|
203
|
+
.search-service-option-item-default {
|
204
|
+
&[data-service-item-type="group"] {
|
205
|
+
.search-service-option-item-default-title {
|
206
|
+
}
|
207
|
+
}
|
208
|
+
}
|
209
|
+
|
210
|
+
.search-service-empty {
|
211
|
+
padding-bottom: $margin;
|
212
|
+
margin: $margin 0;
|
213
|
+
|
214
|
+
svg + div {
|
215
|
+
margin-top: $margin;
|
216
|
+
}
|
217
|
+
}
|
218
|
+
}
|
219
|
+
}
|
220
|
+
}
|
@@ -0,0 +1,112 @@
|
|
1
|
+
import {iMouseEvent} from "plain-design-composition";
|
2
|
+
|
3
|
+
export interface iSearchDataRender {
|
4
|
+
(dataMeta: iSearchDataMeta): any;
|
5
|
+
}
|
6
|
+
|
7
|
+
export interface iSearchDataMeta {
|
8
|
+
title?: string,
|
9
|
+
desc?: string,
|
10
|
+
type: 'group' | 'page' | 'header' | 'sub_header' | 'content' | 'favorite' | 'history',
|
11
|
+
data?: any
|
12
|
+
}
|
13
|
+
|
14
|
+
export interface iSearchServiceDefaultConfig {
|
15
|
+
width: number,
|
16
|
+
render?: iSearchDataRender,
|
17
|
+
placeholder: string,
|
18
|
+
footer?: () => any,
|
19
|
+
cacheName?: string,
|
20
|
+
}
|
21
|
+
|
22
|
+
export interface iSearchServiceCustomConfig {
|
23
|
+
getData: (searchKey: string) => Promise<iSearchDataMeta[]>,
|
24
|
+
onSelect: (data: iSearchDataMeta) => void,
|
25
|
+
}
|
26
|
+
|
27
|
+
export type iSearchServiceConfig = iSearchServiceDefaultConfig & iSearchServiceCustomConfig
|
28
|
+
|
29
|
+
export const SearchType2Icon: Record<iSearchDataMeta['type'], () => any> = {
|
30
|
+
group: () => null,
|
31
|
+
page: () => (
|
32
|
+
<svg width="20" height="20" viewBox="0 0 20 20">
|
33
|
+
<path d="M17 6v12c0 .52-.2 1-1 1H4c-.7 0-1-.33-1-1V2c0-.55.42-1 1-1h8l5 5zM14 8h-3.13c-.51 0-.87-.34-.87-.87V4" stroke="currentColor" fill="none" fillRule="evenodd" strokeLinejoin="round"></path>
|
34
|
+
</svg>
|
35
|
+
),
|
36
|
+
header: () => (
|
37
|
+
<svg width="20" height="20" viewBox="0 0 20 20">
|
38
|
+
<path d="M13 13h4-4V8H7v5h6v4-4H7V8H3h4V3v5h6V3v5h4-4v5zm-6 0v4-4H3h4z" stroke="currentColor" fill="none" fillRule="evenodd" strokeLinecap="round" strokeLinejoin="round"></path>
|
39
|
+
</svg>
|
40
|
+
),
|
41
|
+
sub_header: () => (
|
42
|
+
<svg width="20" height="20" viewBox="0 0 20 20">
|
43
|
+
<path d="M13 13h4-4V8H7v5h6v4-4H7V8H3h4V3v5h6V3v5h4-4v5zm-6 0v4-4H3h4z" stroke="currentColor" fill="none" fillRule="evenodd" strokeLinecap="round" strokeLinejoin="round"></path>
|
44
|
+
</svg>
|
45
|
+
),
|
46
|
+
content: () => (
|
47
|
+
<svg width="20" height="20" viewBox="0 0 20 20">
|
48
|
+
<path d="M17 5H3h14zm0 5H3h14zm0 5H3h14z" stroke="currentColor" fill="none" fillRule="evenodd" strokeLinejoin="round"></path>
|
49
|
+
</svg>
|
50
|
+
),
|
51
|
+
history: () => (
|
52
|
+
<svg width="20" height="20" viewBox="0 0 20 20">
|
53
|
+
<g stroke="currentColor" fill="none" fillRule="evenodd" strokeLinecap="round" strokeLinejoin="round">
|
54
|
+
<path d="M3.18 6.6a8.23 8.23 0 1112.93 9.94h0a8.23 8.23 0 01-11.63 0"></path>
|
55
|
+
<path d="M6.44 7.25H2.55V3.36M10.45 6v5.6M10.45 11.6L13 13"></path>
|
56
|
+
</g>
|
57
|
+
</svg>
|
58
|
+
),
|
59
|
+
favorite: () => (
|
60
|
+
<svg width="20" height="20" viewBox="0 0 20 20">
|
61
|
+
<path d="M10 14.2L5 17l1-5.6-4-4 5.5-.7 2.5-5 2.5 5 5.6.8-4 4 .9 5.5z" stroke="currentColor" fill="none" fillRule="evenodd" strokeLinejoin="round"></path>
|
62
|
+
</svg>
|
63
|
+
),
|
64
|
+
};
|
65
|
+
|
66
|
+
export const SearchTreeIcon = {
|
67
|
+
normal: () => (<svg className="search-service-option-item-default-tree" viewBox="0 0 24 54">
|
68
|
+
<g stroke="currentColor" fill="none" fillRule="evenodd" strokeLinecap="round" strokeLinejoin="round">
|
69
|
+
<path d="M8 6v42M20 27H8.3"></path>
|
70
|
+
</g>
|
71
|
+
</svg>),
|
72
|
+
last: () => (
|
73
|
+
<svg className="search-service-option-item-default-tree" viewBox="0 0 24 54">
|
74
|
+
<g stroke="currentColor" fill="none" fillRule="evenodd" strokeLinecap="round" strokeLinejoin="round">
|
75
|
+
<path d="M8 6v21M20 27H8.3"></path>
|
76
|
+
</g>
|
77
|
+
</svg>
|
78
|
+
)
|
79
|
+
};
|
80
|
+
|
81
|
+
export const SearchOptionButton = {
|
82
|
+
normal: (onClick?: (e: iMouseEvent) => void) => {
|
83
|
+
return (
|
84
|
+
<div key="normal" className="search-service-option-item-default-button" data-search-button="normal" onClick={onClick}>
|
85
|
+
<svg width="20" height="20" viewBox="0 0 20 20">
|
86
|
+
<g stroke="currentColor" fill="none" fillRule="evenodd" strokeLinecap="round" strokeLinejoin="round">
|
87
|
+
<path d="M18 3v4c0 2-2 4-4 4H2"></path>
|
88
|
+
<path d="M8 17l-6-6 6-6"></path>
|
89
|
+
</g>
|
90
|
+
</svg>
|
91
|
+
</div>
|
92
|
+
);
|
93
|
+
},
|
94
|
+
favorite: (onClick?: (e: iMouseEvent) => void) => {
|
95
|
+
return (
|
96
|
+
<div key="favorite" className="search-service-option-item-default-button" data-search-button="favorite" onClick={onClick}>
|
97
|
+
<svg width="20" height="20" viewBox="0 0 20 20">
|
98
|
+
<path d="M10 14.2L5 17l1-5.6-4-4 5.5-.7 2.5-5 2.5 5 5.6.8-4 4 .9 5.5z" stroke="currentColor" fill="none" fillRule="evenodd" strokeLinejoin="round"></path>
|
99
|
+
</svg>
|
100
|
+
</div>
|
101
|
+
);
|
102
|
+
},
|
103
|
+
remove: (onClick?: (e: iMouseEvent) => void) => {
|
104
|
+
return (
|
105
|
+
<div key="remove" className="search-service-option-item-default-button" data-search-button="remove" onClick={onClick}>
|
106
|
+
<svg width="20" height="20" viewBox="0 0 20 20">
|
107
|
+
<path d="M10 10l5.09-5.09L10 10l5.09 5.09L10 10zm0 0L4.91 4.91 10 10l-5.09 5.09L10 10z" stroke="currentColor" fill="none" fillRule="evenodd" strokeLinecap="round" strokeLinejoin="round"></path>
|
108
|
+
</svg>
|
109
|
+
</div>
|
110
|
+
);
|
111
|
+
},
|
112
|
+
};
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {computed, designComponent, Fragment, getComponentCls, iHTMLDivElement, mergeAttrs, useClasses, useRefs, useStyles} from "plain-design-composition";
|
1
|
+
import {computed, designComponent, Fragment, getComponentCls, iHTMLDivElement, mergeAttrs, onMounted, useClasses, useRefs, useStyles} from "plain-design-composition";
|
2
2
|
import './index.scss';
|
3
3
|
import {ThemeStatus, useStyle} from "../../uses/useStyle";
|
4
4
|
import {useEdit} from "../../uses/useEdit";
|
@@ -17,6 +17,7 @@ import {useFocusHandler} from "../../uses/useFocusHandler";
|
|
17
17
|
import {useSuggestionInput} from "./useSuggestionInput";
|
18
18
|
import {useMultipleModel} from "../../uses/useMultipleModel";
|
19
19
|
import {useParentPopupId} from "../usePopup/utils/popup.utils";
|
20
|
+
import {delay} from "plain-utils/utils/delay";
|
20
21
|
|
21
22
|
export const Input = designComponent({
|
22
23
|
name: '-input',
|
@@ -106,6 +107,13 @@ export const Input = designComponent({
|
|
106
107
|
hooks.onInput.use(val => emit.onInput(val));
|
107
108
|
hooks.onSuggestion.use(data => emit.onSuggestion(data));
|
108
109
|
|
110
|
+
onMounted(async () => {
|
111
|
+
await delay(78);
|
112
|
+
if (attrs.autoFocus) {
|
113
|
+
refs.input?.focus();
|
114
|
+
}
|
115
|
+
});
|
116
|
+
|
109
117
|
return {
|
110
118
|
refer: {
|
111
119
|
model,
|
@@ -26,10 +26,11 @@ export const InputPropsOption = {
|
|
26
26
|
multipleSeparator: { default: /[\s\n,,]/ }, // 多值输入的时候的分隔符。类型为字符串或者正则表达式;有这个分隔符的话,会自动按照这个分隔符对输入的文本分割
|
27
27
|
fixedWidth: { type: Boolean }, // InputGroup下是否固定宽度
|
28
28
|
bare: { type: Boolean }, // 去掉包裹节点
|
29
|
+
loadingType: { type: String }, // loading类型
|
29
30
|
|
30
31
|
/*clear*/
|
31
32
|
noClear: { type: Boolean }, // 去掉清空按钮
|
32
|
-
clearHandler: { type: Function as PropType<(e: iMouseEvent) => void> },
|
33
|
+
clearHandler: { type: Function as PropType<(e: iMouseEvent) => void> }, // 自定义处理清空逻辑
|
33
34
|
|
34
35
|
/*textarea*/
|
35
36
|
textarea: { type: Boolean }, // 当前是否为文本域输入框
|
@@ -59,7 +59,7 @@ export function useInputSuffixIcon({ slots, hooks, props, editComputed, model, e
|
|
59
59
|
<span className="input-suffix-icon-wrapper" onMouseDown={handler.onMousedownSuffix}>
|
60
60
|
{hasSuffixIcon.value && slots.suffixIconContent(<Icon icon={props.suffixIcon} className="input-suffix-icon"/>)}
|
61
61
|
{hasSuffixClear.value && (<Icon icon="pi-close-circle-fill" className="input-suffix-clear"/>)}
|
62
|
-
{editComputed.value.loading && <Loading/>}
|
62
|
+
{editComputed.value.loading && <Loading type={props.loadingType}/>}
|
63
63
|
</span>
|
64
64
|
);
|
65
65
|
|
@@ -8,6 +8,7 @@ import {VerticalScrollbar} from "./VerticalScrollbar";
|
|
8
8
|
import {HorizontalScrollbar} from "./HorizontalScrollbar";
|
9
9
|
import {ResizeDetectFuncParam, useResizeDetector} from "../../directives/ResizeDetector";
|
10
10
|
import {createScrollUtils} from "../createScrollUtils";
|
11
|
+
import {getRectAutoFormat} from "plain-utils/dom/getRectAutoFormat";
|
11
12
|
|
12
13
|
export enum PLAIN_SCROLL_VERTICAL_POSITION {
|
13
14
|
top = 'top',
|
@@ -213,6 +214,39 @@ export const Scroll = designComponent({
|
|
213
214
|
autoScrollLeft() {scrollUtils.autoScrollLeft();},
|
214
215
|
autoScrollRight() {scrollUtils.autoScrollRight();},
|
215
216
|
stopAutoScroll() {scrollUtils.stopAutoScroll();},
|
217
|
+
showElement: (elementSelector: string | HTMLElement): boolean => {
|
218
|
+
if (!refs.host || !refs.content) {return false;}
|
219
|
+
const selectElement = typeof elementSelector === "string" ? refs.content?.querySelector(elementSelector) : elementSelector;
|
220
|
+
|
221
|
+
if (selectElement == null) {return false;}
|
222
|
+
const selectElementRect = getRectAutoFormat(selectElement as any);
|
223
|
+
const contentElementRect = getRectAutoFormat(refs.content);
|
224
|
+
const hostElementRect = getRectAutoFormat(refs.host);
|
225
|
+
|
226
|
+
/*vertical*/
|
227
|
+
if (selectElementRect.bottom >= hostElementRect.bottom) {
|
228
|
+
/*在下面*/
|
229
|
+
const offsetTop = selectElementRect.top - contentElementRect.top;
|
230
|
+
methods.scrollTop(offsetTop - (hostElementRect.height - selectElementRect.height));
|
231
|
+
} else if (selectElementRect.top <= hostElementRect.top) {
|
232
|
+
/*在上面*/
|
233
|
+
const offsetTop = selectElementRect.top - contentElementRect.top;
|
234
|
+
methods.scrollTop(offsetTop);
|
235
|
+
}
|
236
|
+
|
237
|
+
/*horizontal*/
|
238
|
+
if (selectElementRect.right >= hostElementRect.right) {
|
239
|
+
/*在右边*/
|
240
|
+
const offsetLeft = selectElementRect.left - contentElementRect.left;
|
241
|
+
methods.scrollLeft(offsetLeft - (hostElementRect.width - selectElementRect.width));
|
242
|
+
} else if (selectElementRect.left <= hostElementRect.left) {
|
243
|
+
/*在左边*/
|
244
|
+
const offsetLeft = selectElementRect.left - contentElementRect.left;
|
245
|
+
methods.scrollLeft(offsetLeft);
|
246
|
+
}
|
247
|
+
|
248
|
+
return true;
|
249
|
+
},
|
216
250
|
/**
|
217
251
|
* 禁用list的队列动画,300ms后恢复正常
|
218
252
|
* @author 韦胜健
|
@@ -58,6 +58,9 @@ export function usePlcTreeRenderNode(
|
|
58
58
|
*/
|
59
59
|
const renderTreeNode = (renderScope: iTableCellRenderScope) => {
|
60
60
|
const treeNode = treeCore.flatNodeComputedData.value[renderScope.node.state.index];
|
61
|
+
if (!treeNode) {
|
62
|
+
return null;
|
63
|
+
}
|
61
64
|
return (
|
62
65
|
<RenderPlcTreeNode
|
63
66
|
treeCore={treeCore}
|
package/src/packages/entry.tsx
CHANGED
@@ -189,6 +189,14 @@ export type {
|
|
189
189
|
iPlainResponseDataType,
|
190
190
|
iHttpResponseDataType
|
191
191
|
} from './components/createHttp/http.utils';
|
192
|
+
export type {
|
193
|
+
iSearchServiceCustomConfig,
|
194
|
+
iSearchServiceConfig,
|
195
|
+
iSearchServiceDefaultConfig,
|
196
|
+
iSearchDataMeta,
|
197
|
+
iSearchDataRender,
|
198
|
+
} from './components/$search/search.utils';
|
199
|
+
export {$search} from './components/$search';
|
192
200
|
|
193
201
|
export {Address} from './components/Address';
|
194
202
|
export {AddressCascade} from './components/AddressCascade';
|
@@ -305,5 +305,13 @@ export const EnUsLocale: tZhCnLocale = {
|
|
305
305
|
洋红: 'Magenta',
|
306
306
|
极昼: 'Light',
|
307
307
|
黑夜: 'Dark',
|
308
|
-
}
|
308
|
+
},
|
309
|
+
search: {
|
310
|
+
select: 'Select',
|
311
|
+
switch: 'Switch',
|
312
|
+
noHistory: 'No Search History',
|
313
|
+
noMatch: 'There are no search result that can match "{val}"',
|
314
|
+
searchHistory: 'Search History',
|
315
|
+
favorite: 'Favorite'
|
316
|
+
},
|
309
317
|
};
|
@@ -115,8 +115,8 @@ export const ZhCnLocale = {
|
|
115
115
|
save: '保存',
|
116
116
|
done: '完成',
|
117
117
|
},
|
118
|
-
yes:'是',
|
119
|
-
no:'否',
|
118
|
+
yes: '是',
|
119
|
+
no: '否',
|
120
120
|
},
|
121
121
|
formatter: {
|
122
122
|
week: 'gggg年第ww周',
|
@@ -303,7 +303,15 @@ export const ZhCnLocale = {
|
|
303
303
|
洋红: '洋红',
|
304
304
|
极昼: '极昼',
|
305
305
|
黑夜: '黑夜',
|
306
|
-
}
|
306
|
+
},
|
307
|
+
search: {
|
308
|
+
select: '选择',
|
309
|
+
switch: '切换',
|
310
|
+
noHistory: '没有搜索历史',
|
311
|
+
noMatch: '无法找到搜索结果 "{val}"',
|
312
|
+
searchHistory: '搜索历史',
|
313
|
+
favorite: '收藏'
|
314
|
+
},
|
307
315
|
} as const;
|
308
316
|
|
309
317
|
type ZhCnLocaleUtils<T> = { [k in keyof T]: T[k] extends string ? string : ZhCnLocaleUtils<T[k]> }
|
@@ -0,0 +1,38 @@
|
|
1
|
+
export function createListUtils<T>(
|
2
|
+
{
|
3
|
+
getList,
|
4
|
+
current,
|
5
|
+
}: {
|
6
|
+
getList: () => T[],
|
7
|
+
current: () => number | undefined | null,
|
8
|
+
}
|
9
|
+
) {
|
10
|
+
return {
|
11
|
+
prevIndex: () => {
|
12
|
+
const list = getList();
|
13
|
+
if (!list.length) {
|
14
|
+
return -1;
|
15
|
+
}
|
16
|
+
let curIdx = current();
|
17
|
+
if (curIdx == null || curIdx - 1 < 0) {
|
18
|
+
curIdx = list.length - 1;
|
19
|
+
} else {
|
20
|
+
curIdx = curIdx - 1;
|
21
|
+
}
|
22
|
+
return curIdx;
|
23
|
+
},
|
24
|
+
nextIndex: () => {
|
25
|
+
const list = getList();
|
26
|
+
if (!list.length) {
|
27
|
+
return -1;
|
28
|
+
}
|
29
|
+
let curIdx = current();
|
30
|
+
if (curIdx == null || curIdx + 1 > list.length - 1) {
|
31
|
+
curIdx = 0;
|
32
|
+
} else {
|
33
|
+
curIdx = curIdx + 1;
|
34
|
+
}
|
35
|
+
return curIdx;
|
36
|
+
},
|
37
|
+
};
|
38
|
+
}
|