cdui-js 1.0.23 → 1.0.25
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/css/all.css +1 -2
- package/css/datewidget.css +1 -0
- package/css/{datepicker.css → dropdown.css} +6 -10
- package/css/popup.css +39 -18
- package/demo/css/css.md +6 -10
- package/demo/src/App.tsx +22 -0
- package/demo/src/css/atomic.css +6 -8
- package/demo/src/pages/Canlendar.tsx +1 -1
- package/demo/src/pages/ComboBox.tsx +17 -14
- package/demo/src/pages/DatePicker.tsx +6 -1
- package/demo/src/pages/Form.tsx +65 -59
- package/package.json +1 -1
- package/src/components/ComboBox.tsx +57 -53
- package/src/components/DatePicker.tsx +139 -38
- package/src/dialog.ts +9 -5
- package/src/index.ts +2 -1
- package/src/popup.ts +319 -11
- package/src/reactive.ts +1 -1
- package/css/combobox.css +0 -38
- package/src/components/Popup.tsx +0 -261
package/css/all.css
CHANGED
|
@@ -7,9 +7,8 @@
|
|
|
7
7
|
@import url(button.css);
|
|
8
8
|
@import url(textbox.css);
|
|
9
9
|
@import url(popup.css);
|
|
10
|
-
@import url(combobox.css);
|
|
11
10
|
@import url(datewidget.css);
|
|
12
|
-
@import url(
|
|
11
|
+
@import url(dropdown.css);
|
|
13
12
|
@import url(mobile-datepicker.css);
|
|
14
13
|
@import url(form.css);
|
|
15
14
|
@import url(carousel.css);
|
package/css/datewidget.css
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
|
+
.combobox,
|
|
1
2
|
.datepicker {
|
|
2
|
-
position: relative;
|
|
3
|
-
width: 100px;
|
|
4
|
-
height: 32px;
|
|
5
|
-
overflow: visible;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
.datepicker-host {
|
|
9
3
|
display: flex;
|
|
10
4
|
justify-content: center;
|
|
11
5
|
align-items: center;
|
|
12
|
-
width:
|
|
13
|
-
height:
|
|
6
|
+
width: 120px;
|
|
7
|
+
height: 32px;
|
|
14
8
|
}
|
|
15
9
|
|
|
10
|
+
.combobox-input,
|
|
16
11
|
.datepicker-input {
|
|
17
12
|
flex: auto;
|
|
18
13
|
width: 100%;
|
|
@@ -26,7 +21,8 @@
|
|
|
26
21
|
font-size: inherit;
|
|
27
22
|
}
|
|
28
23
|
|
|
29
|
-
.
|
|
24
|
+
.combobox-icon,
|
|
25
|
+
.datepicker-icon {
|
|
30
26
|
display: flex;
|
|
31
27
|
justify-items: center;
|
|
32
28
|
align-items: center;
|
package/css/popup.css
CHANGED
|
@@ -1,33 +1,54 @@
|
|
|
1
1
|
.popup {
|
|
2
|
-
position:
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
/* 不允许内边距,否则动画的高度不能小于内边距 */
|
|
2
|
+
position: fixed;
|
|
3
|
+
z-index: 9;
|
|
4
|
+
/* 不允许边框和内边距,否则动画的高度不能小于内边距 */
|
|
5
|
+
border: none !important;
|
|
7
6
|
padding: 0 !important;
|
|
8
7
|
will-change: height;
|
|
9
8
|
transition: height 0.2s linear;
|
|
10
9
|
overflow: hidden;
|
|
11
10
|
}
|
|
12
11
|
|
|
13
|
-
.popup-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
.popup-fixed-left,
|
|
13
|
+
.popup-fixed-right {
|
|
14
|
+
display: flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
top: 0;
|
|
17
|
+
height: 100%;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.popup-fixed-left > *,
|
|
21
|
+
.popup-fixed-right > * {
|
|
22
|
+
height: 100 !important;
|
|
23
|
+
max-height: 100% !important;
|
|
16
24
|
}
|
|
17
25
|
|
|
18
|
-
.popup-
|
|
19
|
-
left:
|
|
26
|
+
.popup-fixed-left {
|
|
27
|
+
left: 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.popup-fixed-right {
|
|
20
31
|
right: 0;
|
|
21
32
|
}
|
|
22
33
|
|
|
23
|
-
.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
left:
|
|
28
|
-
|
|
34
|
+
.popup-fixed-top,
|
|
35
|
+
.popup-fixed-bottom {
|
|
36
|
+
display: flex;
|
|
37
|
+
justify-content: center;
|
|
38
|
+
left: 0;
|
|
39
|
+
width: 100%;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.popup-fixed-top > *,
|
|
43
|
+
.popup-fixed-bottom > * {
|
|
29
44
|
width: 100% !important;
|
|
30
45
|
max-width: 100% !important;
|
|
31
|
-
|
|
32
|
-
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.popup-fixed-top {
|
|
49
|
+
top: 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.popup-fixed-bottom {
|
|
53
|
+
bottom: 0;
|
|
33
54
|
}
|
package/demo/css/css.md
CHANGED
|
@@ -283,18 +283,19 @@
|
|
|
283
283
|
|
|
284
284
|
# combobox 下拉框
|
|
285
285
|
|
|
286
|
-
.combobox { border: 1px solid #e4e4e4; background:
|
|
286
|
+
.combobox { border: 1px solid #e4e4e4; background: #ffffff; }
|
|
287
287
|
.combobox:has(.combobox-input:focus) { border: 1px solid #1b212d; }
|
|
288
|
+
.combobox-popup { border: 1px solid #e4e4e4; background: #ffffff; }
|
|
288
289
|
|
|
289
290
|
|
|
290
291
|
# canlendar monthwidget yearwidget 日历 年月 年
|
|
291
292
|
|
|
292
|
-
.datewidget { border: 1px solid #e4e4e4; }
|
|
293
|
+
.datewidget { border: 1px solid #e4e4e4; background: #ffffff; }
|
|
293
294
|
.datewidget-header > .icon { stroke: #1b212d; }
|
|
294
295
|
.datewidget-item.disabled { color: #e4e4e4; }
|
|
295
296
|
.datewidget-item.prev-block, .datewidget-item.next-block { color: #888f97; }
|
|
296
297
|
.datewidget-item.today::before { background: #f5f5f5; }
|
|
297
|
-
.datewidget-item.selected { color:
|
|
298
|
+
.datewidget-item.selected { color: #ffffff; }
|
|
298
299
|
.datewidget-item.selected::before { background: #ff4000; }
|
|
299
300
|
|
|
300
301
|
.canlendar-weeks > span { color: #888f97; }
|
|
@@ -302,17 +303,12 @@
|
|
|
302
303
|
|
|
303
304
|
# datepicker 日期选择
|
|
304
305
|
|
|
305
|
-
.datepicker { border: 1px solid #e4e4e4; background:
|
|
306
|
+
.datepicker { border: 1px solid #e4e4e4; background: #ffffff; }
|
|
306
307
|
.datepicker:has(.datepicker-input:focus) { border: 1px solid #1b212d; }
|
|
307
308
|
|
|
308
309
|
|
|
309
|
-
# popup 弹出层
|
|
310
|
-
|
|
311
|
-
.popup { border: 1px solid #e4e4e4; background: white; }
|
|
312
|
-
|
|
313
|
-
|
|
314
310
|
# carousel 轮播
|
|
315
311
|
|
|
316
312
|
.carousel-backward, .carousel-forward { background: rgba(255, 255, 255, 0.1); }
|
|
317
313
|
.carousel-dot { background: rgba(65, 72, 90, 1); }
|
|
318
|
-
.carousel-dot.selected { background:
|
|
314
|
+
.carousel-dot.selected { background: #ffffff; }
|
package/demo/src/App.tsx
CHANGED
|
@@ -1,9 +1,31 @@
|
|
|
1
|
+
import { showPopup } from '../../src/popup';
|
|
1
2
|
import { CanlendarPage } from './pages/Canlendar';
|
|
2
3
|
import { CarouselPage } from './pages/Carousel';
|
|
3
4
|
import { ComboBoxPage } from './pages/ComboBox';
|
|
4
5
|
import { DatePickerPage } from './pages/DatePicker';
|
|
5
6
|
import { FormPage } from './pages/Form';
|
|
6
7
|
|
|
8
|
+
let objects = [];
|
|
9
|
+
for (let i = 0; i < 1000000; i++) {
|
|
10
|
+
objects[i] = {};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let map = new WeakMap();
|
|
14
|
+
let now = performance.now();
|
|
15
|
+
|
|
16
|
+
for (let i = 0; i < 1000000; i++) {
|
|
17
|
+
map.set(objects[i], i);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
console.log(performance.now() - now);
|
|
21
|
+
|
|
22
|
+
const openDropdown = (align: HTMLElement) => {
|
|
23
|
+
const popup = showPopup(<div style={{ padding: '100px 0', background: 'silver' }}>11111111111111111111</div>, {
|
|
24
|
+
align,
|
|
25
|
+
transition: true,
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
7
29
|
export const App = () => {
|
|
8
30
|
return (
|
|
9
31
|
<div style={{ 'min-height': '100%' }}>
|
package/demo/src/css/atomic.css
CHANGED
|
@@ -909,27 +909,25 @@ body { stroke: #A2A7AD; fill: #A2A7AD; }
|
|
|
909
909
|
.textbox:focus { border: 1px solid #1b212d; }
|
|
910
910
|
|
|
911
911
|
|
|
912
|
-
.combobox { border: 1px solid #e4e4e4; background:
|
|
912
|
+
.combobox { border: 1px solid #e4e4e4; background: #ffffff; }
|
|
913
913
|
.combobox:has(.combobox-input:focus) { border: 1px solid #1b212d; }
|
|
914
|
+
.combobox-popup { border: 1px solid #e4e4e4; background: #ffffff; }
|
|
914
915
|
|
|
915
916
|
|
|
916
|
-
.datewidget { border: 1px solid #e4e4e4; }
|
|
917
|
+
.datewidget { border: 1px solid #e4e4e4; background: #ffffff; }
|
|
917
918
|
.datewidget-header > .icon { stroke: #1b212d; }
|
|
918
919
|
.datewidget-item.disabled { color: #e4e4e4; }
|
|
919
920
|
.datewidget-item.prev-block, .datewidget-item.next-block { color: #888f97; }
|
|
920
921
|
.datewidget-item.today::before { background: #f5f5f5; }
|
|
921
|
-
.datewidget-item.selected { color:
|
|
922
|
+
.datewidget-item.selected { color: #ffffff; }
|
|
922
923
|
.datewidget-item.selected::before { background: #ff4000; }
|
|
923
924
|
.canlendar-weeks > span { color: #888f97; }
|
|
924
925
|
|
|
925
926
|
|
|
926
|
-
.datepicker { border: 1px solid #e4e4e4; background:
|
|
927
|
+
.datepicker { border: 1px solid #e4e4e4; background: #ffffff; }
|
|
927
928
|
.datepicker:has(.datepicker-input:focus) { border: 1px solid #1b212d; }
|
|
928
929
|
|
|
929
930
|
|
|
930
|
-
.popup { border: 1px solid #e4e4e4; background: white; }
|
|
931
|
-
|
|
932
|
-
|
|
933
931
|
.carousel-backward, .carousel-forward { background: rgba(255, 255, 255, 0.1); }
|
|
934
932
|
.carousel-dot { background: rgba(65, 72, 90, 1); }
|
|
935
|
-
.carousel-dot.selected { background:
|
|
933
|
+
.carousel-dot.selected { background: #ffffff; }
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { reactive } from '../../../src';
|
|
1
|
+
import { reactive } from '../../../src/reactive';
|
|
2
|
+
import { PopupApi } from '../../../src/popup';
|
|
2
3
|
import { ComboBox } from '../../../src/components/ComboBox';
|
|
3
4
|
|
|
4
5
|
export const ComboBoxPage = () => {
|
|
5
|
-
let combobox;
|
|
6
|
+
let combobox: PopupApi;
|
|
6
7
|
|
|
7
8
|
const state = reactive({
|
|
8
9
|
value: '111',
|
|
@@ -10,18 +11,20 @@ export const ComboBoxPage = () => {
|
|
|
10
11
|
|
|
11
12
|
return (
|
|
12
13
|
<ComboBox
|
|
13
|
-
api={(api) => (combobox = api)}
|
|
14
14
|
value={state.value}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
15
|
+
api={(api) => (combobox = api)}
|
|
16
|
+
popup={() => (
|
|
17
|
+
<div
|
|
18
|
+
style={{ width: '200px', padding: '8px 0' }}
|
|
19
|
+
onclick={(event) => {
|
|
20
|
+
state.value = event.target.textContent;
|
|
21
|
+
combobox.closePopup();
|
|
22
|
+
}}
|
|
23
|
+
>
|
|
24
|
+
<div>111</div>
|
|
25
|
+
<div>222</div>
|
|
26
|
+
</div>
|
|
27
|
+
)}
|
|
28
|
+
></ComboBox>
|
|
26
29
|
);
|
|
27
30
|
};
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
import { reactive } from '../../../src/reactive';
|
|
1
2
|
import { DatePicker } from '../../../src/components/DatePicker';
|
|
2
3
|
|
|
3
4
|
export const DatePickerPage = () => {
|
|
4
|
-
|
|
5
|
+
let state = reactive({
|
|
6
|
+
value: null,
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
return <DatePicker value={state.value} onchange={(event) => (state.value = event.detail)}></DatePicker>;
|
|
5
10
|
};
|
package/demo/src/pages/Form.tsx
CHANGED
|
@@ -33,16 +33,18 @@ export const FormPage = () => {
|
|
|
33
33
|
<ComboBox
|
|
34
34
|
api={(api) => (combobox = api)}
|
|
35
35
|
value={state.b}
|
|
36
|
-
popup={
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
36
|
+
popup={() => (
|
|
37
|
+
<div
|
|
38
|
+
onclick={(event) => {
|
|
39
|
+
state.b = +event.target.textContent;
|
|
40
|
+
combobox.closePopup();
|
|
41
|
+
}}
|
|
42
|
+
>
|
|
43
|
+
<div>1</div>
|
|
44
|
+
<div>2</div>
|
|
45
|
+
</div>
|
|
46
|
+
)}
|
|
47
|
+
></ComboBox>
|
|
46
48
|
);
|
|
47
49
|
},
|
|
48
50
|
},
|
|
@@ -51,65 +53,69 @@ export const FormPage = () => {
|
|
|
51
53
|
b: 2,
|
|
52
54
|
|
|
53
55
|
form: {
|
|
54
|
-
username: ''
|
|
55
|
-
}
|
|
56
|
+
username: '',
|
|
57
|
+
},
|
|
56
58
|
});
|
|
57
59
|
|
|
58
60
|
let form: FormApi;
|
|
59
61
|
|
|
60
|
-
let form2: FormApi
|
|
62
|
+
let form2: FormApi;
|
|
61
63
|
|
|
62
64
|
return (
|
|
63
65
|
<>
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
66
|
+
<Form data={state} rules={{}} align={state.align} labelWidth={state.labelWidth} api={(api) => (form = api)}>
|
|
67
|
+
<For each={state.items}>
|
|
68
|
+
{(item) => (
|
|
69
|
+
<FormItem field={item.field} label={item.label} required={item.required}>
|
|
70
|
+
<div>
|
|
71
|
+
<item.Input></item.Input>
|
|
72
|
+
</div>
|
|
73
|
+
</FormItem>
|
|
74
|
+
)}
|
|
75
|
+
</For>
|
|
76
|
+
<div>{`a: ${state.a} b: ${state.b}`}</div>
|
|
77
|
+
<button
|
|
78
|
+
type="button"
|
|
79
|
+
onclick={() =>
|
|
80
|
+
state.items.push({
|
|
81
|
+
field: '?',
|
|
82
|
+
label: '???',
|
|
83
|
+
required: false,
|
|
84
|
+
labelWidth: '100px',
|
|
85
|
+
Input: () => <TextBox></TextBox>,
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
>
|
|
89
|
+
append
|
|
90
|
+
</button>
|
|
91
|
+
<button type="button" onclick={() => (state.align = state.align === 'left' ? 'top' : 'left')}>
|
|
92
|
+
align
|
|
93
|
+
</button>
|
|
94
|
+
<button type="button" onclick={() => (state.labelWidth = parseInt(state.labelWidth) + 10 + 'px')}>
|
|
95
|
+
labelWidth
|
|
96
|
+
</button>
|
|
97
|
+
<button type="button" onclick={() => form.validate()}>
|
|
98
|
+
validate
|
|
99
|
+
</button>
|
|
100
|
+
<button type="button" onclick={() => form.clearErrors()}>
|
|
101
|
+
clearErrors
|
|
102
|
+
</button>
|
|
103
|
+
</Form>
|
|
104
|
+
|
|
105
|
+
<Form data={state.form} rules={{}} api={(api) => (form2 = api)}>
|
|
106
|
+
<FormItem label="username" required field="username">
|
|
107
|
+
<input value={state.form.username} onchange={(e) => (state.form.username = e.target.value)} />
|
|
108
|
+
</FormItem>
|
|
109
|
+
</Form>
|
|
110
|
+
|
|
75
111
|
<button
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
label: '???',
|
|
81
|
-
required: false,
|
|
82
|
-
labelWidth: '100px',
|
|
83
|
-
Input: () => <TextBox></TextBox>,
|
|
84
|
-
})
|
|
85
|
-
}
|
|
112
|
+
onclick={async () => {
|
|
113
|
+
const valid = await form2.validate();
|
|
114
|
+
console.log(valid);
|
|
115
|
+
}}
|
|
86
116
|
>
|
|
87
|
-
|
|
88
|
-
</button>
|
|
89
|
-
<button type="button" onclick={() => (state.align = state.align === 'left' ? 'top' : 'left')}>
|
|
90
|
-
align
|
|
91
|
-
</button>
|
|
92
|
-
<button type="button" onclick={() => (state.labelWidth = parseInt(state.labelWidth) + 10 + 'px')}>
|
|
93
|
-
labelWidth
|
|
117
|
+
click
|
|
94
118
|
</button>
|
|
95
|
-
<button type="button" onclick={() => form.validate()}>
|
|
96
|
-
validate
|
|
97
|
-
</button>
|
|
98
|
-
<button type="button" onclick={() => form.clearErrors()}>
|
|
99
|
-
clearErrors
|
|
100
|
-
</button>
|
|
101
|
-
</Form>
|
|
102
|
-
|
|
103
|
-
<Form data={state.form} rules={{}} api={(api) => (form2 = api)}>
|
|
104
|
-
<FormItem label="username" required field='username'>
|
|
105
|
-
<input value={state.form.username} onchange={e => state.form.username = e.target.value} />
|
|
106
|
-
</FormItem>
|
|
107
|
-
</Form>
|
|
108
|
-
|
|
109
|
-
<button onclick={async() => {
|
|
110
|
-
const valid = await form2.validate()
|
|
111
|
-
console.log(valid)
|
|
112
|
-
}}>click</button>
|
|
113
119
|
</>
|
|
114
120
|
);
|
|
115
121
|
};
|
package/package.json
CHANGED
|
@@ -1,43 +1,49 @@
|
|
|
1
1
|
import { JSX } from '../jsx';
|
|
2
2
|
import { combineClass, omitProps, useContext, watch } from '../reactive';
|
|
3
3
|
import { disableAutoCloseEvent } from '../dom';
|
|
4
|
-
import {
|
|
4
|
+
import { PopupApi, initDropdown } from '../popup';
|
|
5
|
+
|
|
5
6
|
import { FormItemContext } from './provider';
|
|
6
7
|
|
|
7
|
-
const OMIT_PROPS = ['class', 'value', '
|
|
8
|
+
const OMIT_PROPS = ['class', 'value', 'format', /*'readonly', */ 'popup', 'popupOnFocus', 'api'] as const;
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* 下拉框组件
|
|
11
12
|
*/
|
|
12
13
|
export const ComboBox = (
|
|
13
|
-
props?: JSX.HTMLAttributes<never> &
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
14
|
+
props?: Omit<JSX.HTMLAttributes<never>, 'children'> & {
|
|
15
|
+
/**
|
|
16
|
+
* 弹出层
|
|
17
|
+
*/
|
|
18
|
+
popup: () => JSX.Element;
|
|
19
|
+
/**
|
|
20
|
+
* 值
|
|
21
|
+
*/
|
|
22
|
+
value?: any;
|
|
23
|
+
/**
|
|
24
|
+
* 值样式
|
|
25
|
+
*
|
|
26
|
+
* @param value 当前值
|
|
27
|
+
*/
|
|
28
|
+
format?(value: any): string;
|
|
29
|
+
// /**
|
|
30
|
+
// * 是否只读
|
|
31
|
+
// */
|
|
32
|
+
// readonly?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* 获取焦点时是否自动弹出
|
|
35
|
+
*/
|
|
36
|
+
popupOnFocus?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* 值变更事件
|
|
39
|
+
*/
|
|
40
|
+
onchange?: (event: CustomEvent<Date>) => void;
|
|
41
|
+
/**
|
|
42
|
+
* 外部调用接口
|
|
43
|
+
*/
|
|
44
|
+
api: (api: PopupApi) => void;
|
|
45
|
+
},
|
|
38
46
|
) => {
|
|
39
|
-
let popup: PopupApi;
|
|
40
|
-
|
|
41
47
|
const formItem = useContext(FormItemContext);
|
|
42
48
|
|
|
43
49
|
const initFormItem = (dom: HTMLInputElement) => {
|
|
@@ -49,31 +55,29 @@ export const ComboBox = (
|
|
|
49
55
|
formItem.init(dom);
|
|
50
56
|
};
|
|
51
57
|
|
|
58
|
+
let api: PopupApi;
|
|
59
|
+
|
|
52
60
|
return (
|
|
53
|
-
<div
|
|
54
|
-
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
{...props.popup}
|
|
74
|
-
>
|
|
75
|
-
{props.children}
|
|
76
|
-
</Popup>
|
|
61
|
+
<div
|
|
62
|
+
ref={(dom) => {
|
|
63
|
+
api = initDropdown(dom, () => <div class="combobox-popup">{props.popup()}</div>);
|
|
64
|
+
props.api && props.api(api);
|
|
65
|
+
}}
|
|
66
|
+
class={combineClass('combobox', props.class)}
|
|
67
|
+
{...disableAutoCloseEvent}
|
|
68
|
+
{...omitProps(props, OMIT_PROPS)}
|
|
69
|
+
>
|
|
70
|
+
<input
|
|
71
|
+
ref={formItem && initFormItem}
|
|
72
|
+
class="combobox-input"
|
|
73
|
+
value={props.format ? props.format(props.value) : '' + (props.value || '')}
|
|
74
|
+
readonly={true}
|
|
75
|
+
onfocus={() => props.popupOnFocus && api.openPopup()}
|
|
76
|
+
onclick={() => !props.popupOnFocus && api.togglePopup()}
|
|
77
|
+
></input>
|
|
78
|
+
<svg class="combobox-icon icon icon-s" aria-hidden={true} onclick={() => api.togglePopup()}>
|
|
79
|
+
<use href="#icon-dropdown"></use>
|
|
80
|
+
</svg>
|
|
77
81
|
</div>
|
|
78
82
|
);
|
|
79
83
|
};
|