@king-design/intact 3.6.0-beta.0 → 3.6.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.
- package/components/button/demos/basic.md +0 -1
- package/components/cascader/index.spec.ts +7 -6
- package/components/copy/index.spec.ts +9 -14
- package/components/datepicker/basepicker.ts +26 -314
- package/components/datepicker/calendar.ts +3 -1
- package/components/datepicker/calendar.vdt +5 -2
- package/components/datepicker/dayjs.ts +2 -16
- package/components/datepicker/demos/multiple.md +5 -0
- package/components/datepicker/demos/yearMonth.md +2 -8
- package/components/datepicker/helpers.ts +5 -7
- package/components/datepicker/index.md +1 -2
- package/components/datepicker/index.spec.ts +596 -157
- package/components/datepicker/index.ts +16 -33
- package/components/datepicker/index.vdt +41 -35
- package/components/datepicker/shortcuts.ts +1 -1
- package/components/datepicker/styles.ts +27 -18
- package/components/datepicker/useConfirm.ts +82 -0
- package/components/datepicker/useDisabled.ts +29 -31
- package/components/datepicker/useFormats.ts +8 -4
- package/components/datepicker/useHighlight.ts +81 -0
- package/components/datepicker/useKeyboards.ts +2 -1
- package/components/datepicker/useMergeRange.ts +12 -12
- package/components/datepicker/useMonths.ts +6 -3
- package/components/datepicker/usePanel.ts +19 -19
- package/components/datepicker/useShowDate.ts +21 -41
- package/components/datepicker/useStatus.ts +34 -15
- package/components/datepicker/useValue.ts +43 -72
- package/components/datepicker/useValueBase.ts +312 -0
- package/components/datepicker/useWeeks.ts +1 -1
- package/components/datepicker/useYears.ts +7 -3
- package/components/dropdown/dropdown.ts +5 -4
- package/components/dropdown/index.md +1 -0
- package/components/dropdown/item.ts +1 -1
- package/components/dropdown/useKeyboard.ts +0 -1
- package/components/form/form.ts +4 -0
- package/components/form/index.md +2 -1
- package/components/form/index.spec.ts +2 -0
- package/components/input/index.spec.ts +42 -0
- package/components/input/index.ts +8 -0
- package/components/input/index.vdt +3 -4
- package/components/input/useAutoWidth.ts +19 -1
- package/components/menu/demos/horizontal.md +7 -1
- package/components/menu/index.spec.ts +19 -0
- package/components/menu/styles.ts +2 -1
- package/components/scrollSelect/useMouseEvents.ts +5 -4
- package/components/select/base.ts +3 -2
- package/components/select/base.vdt +2 -1
- package/components/select/demos/creatable.md +2 -2
- package/components/select/index.md +1 -1
- package/components/select/index.spec.ts +142 -36
- package/components/select/menu.ts +1 -1
- package/components/select/option.ts +2 -1
- package/components/select/select.ts +1 -0
- package/components/select/styles.ts +3 -1
- package/components/select/useCard.ts +22 -4
- package/components/select/useInput.ts +5 -9
- package/components/spinner/index.spec.ts +18 -0
- package/components/spinner/useValue.ts +2 -1
- package/components/table/index.spec.ts +69 -1
- package/components/table/useStickyHeader.ts +1 -1
- package/components/timepicker/index.spec.ts +145 -27
- package/components/timepicker/panelPicker.ts +10 -4
- package/components/timepicker/panelPicker.vdt +3 -5
- package/components/timepicker/styles.ts +1 -0
- package/components/timepicker/useConfirm.ts +33 -0
- package/components/timepicker/useDefaultValue.ts +30 -0
- package/components/timepicker/useDisabled.ts +17 -4
- package/components/timepicker/useFormats.ts +1 -1
- package/components/timepicker/useValue.ts +22 -19
- package/components/tour/index.spec.ts +1 -1
- package/es/components/cascader/index.spec.js +18 -19
- package/es/components/copy/index.spec.js +14 -31
- package/es/components/datepicker/basepicker.d.ts +6 -27
- package/es/components/datepicker/basepicker.js +23 -268
- package/es/components/datepicker/calendar.d.ts +4 -2
- package/es/components/datepicker/dayjs.d.ts +2 -13
- package/es/components/datepicker/helpers.d.ts +3 -2
- package/es/components/datepicker/helpers.js +2 -3
- package/es/components/datepicker/index.d.ts +21 -29
- package/es/components/datepicker/index.js +22 -32
- package/es/components/datepicker/index.spec.js +1277 -484
- package/es/components/datepicker/index.vdt.js +39 -38
- package/es/components/datepicker/shortcuts.d.ts +1 -1
- package/es/components/datepicker/styles.d.ts +7 -2
- package/es/components/datepicker/styles.js +10 -15
- package/es/components/datepicker/useConfirm.d.ts +6 -0
- package/es/components/datepicker/useConfirm.js +65 -0
- package/es/components/datepicker/useDisabled.d.ts +5 -3
- package/es/components/datepicker/useDisabled.js +22 -27
- package/es/components/datepicker/useFormats.d.ts +2 -2
- package/es/components/datepicker/useFormats.js +6 -2
- package/es/components/datepicker/useHighlight.d.ts +14 -0
- package/es/components/datepicker/useHighlight.js +60 -0
- package/es/components/datepicker/useKeyboards.js +2 -1
- package/es/components/datepicker/useMergeRange.d.ts +1 -1
- package/es/components/datepicker/useMergeRange.js +11 -16
- package/es/components/datepicker/useMonths.js +5 -3
- package/es/components/datepicker/usePanel.d.ts +1 -10
- package/es/components/datepicker/usePanel.js +19 -32
- package/es/components/datepicker/useShowDate.d.ts +1 -1
- package/es/components/datepicker/useShowDate.js +15 -40
- package/es/components/datepicker/useStatus.js +33 -16
- package/es/components/datepicker/useValue.d.ts +11 -6
- package/es/components/datepicker/useValue.js +49 -69
- package/es/components/datepicker/useValueBase.d.ts +28 -0
- package/es/components/datepicker/useValueBase.js +280 -0
- package/es/components/datepicker/useYears.js +6 -3
- package/es/components/dropdown/dropdown.d.ts +1 -0
- package/es/components/dropdown/dropdown.js +7 -4
- package/es/components/form/form.d.ts +1 -0
- package/es/components/form/form.js +7 -0
- package/es/components/form/index.spec.js +10 -8
- package/es/components/input/index.d.ts +2 -0
- package/es/components/input/index.js +6 -0
- package/es/components/input/index.spec.js +45 -0
- package/es/components/input/index.vdt.js +4 -3
- package/es/components/input/useAutoWidth.d.ts +2 -0
- package/es/components/input/useAutoWidth.js +19 -1
- package/es/components/menu/index.spec.js +28 -0
- package/es/components/menu/styles.js +2 -2
- package/es/components/scrollSelect/useMouseEvents.js +5 -4
- package/es/components/select/base.d.ts +1 -1
- package/es/components/select/base.js +3 -2
- package/es/components/select/base.vdt.js +4 -3
- package/es/components/select/index.spec.js +346 -218
- package/es/components/select/menu.js +1 -1
- package/es/components/select/option.js +2 -1
- package/es/components/select/select.js +2 -1
- package/es/components/select/styles.d.ts +79 -0
- package/es/components/select/styles.js +1 -0
- package/es/components/select/useCard.d.ts +4 -3
- package/es/components/select/useCard.js +15 -4
- package/es/components/select/useInput.d.ts +1 -1
- package/es/components/select/useInput.js +4 -4
- package/es/components/spinner/index.spec.js +82 -44
- package/es/components/spinner/useValue.js +2 -1
- package/es/components/table/index.spec.js +84 -6
- package/es/components/table/useStickyHeader.js +1 -1
- package/es/components/timepicker/index.spec.js +298 -128
- package/es/components/timepicker/panelPicker.d.ts +21 -16
- package/es/components/timepicker/panelPicker.js +7 -4
- package/es/components/timepicker/panelPicker.vdt.js +5 -9
- package/es/components/timepicker/selectPicker.d.ts +4 -3
- package/es/components/timepicker/styles.js +1 -1
- package/es/components/timepicker/useConfirm.d.ts +6 -0
- package/es/components/timepicker/useConfirm.js +19 -0
- package/es/components/timepicker/useDefaultValue.d.ts +4 -0
- package/es/components/timepicker/useDefaultValue.js +27 -0
- package/es/components/timepicker/useDisabled.d.ts +6 -3
- package/es/components/timepicker/useDisabled.js +13 -4
- package/es/components/timepicker/useFormats.d.ts +1 -1
- package/es/components/timepicker/useValue.d.ts +13 -8
- package/es/components/timepicker/useValue.js +14 -15
- package/es/components/tour/index.spec.js +1 -1
- package/es/index.d.ts +2 -2
- package/es/index.js +2 -2
- package/es/site/data/components/button/demos/basic/react.js +0 -2
- package/es/site/data/components/datepicker/demos/multiple/index.d.ts +1 -0
- package/es/site/data/components/datepicker/demos/multiple/index.js +2 -1
- package/es/site/data/components/datepicker/demos/multiple/react.d.ts +1 -0
- package/es/site/data/components/datepicker/demos/multiple/react.js +13 -2
- package/es/site/data/components/datepicker/demos/yearMonth/index.d.ts +0 -2
- package/es/site/data/components/datepicker/demos/yearMonth/index.js +1 -3
- package/es/site/data/components/datepicker/demos/yearMonth/react.d.ts +0 -2
- package/es/site/data/components/datepicker/demos/yearMonth/react.js +1 -21
- package/es/site/data/components/menu/demos/horizontal/react.js +5 -1
- package/es/site/data/components/select/demos/creatable/react.js +2 -2
- package/es/site/data/components/select/demos/searchable/index.js +1 -1
- package/es/site/data/components/select/demos/searchable/react.js +1 -1
- package/es/site/data/components/tour/demos/customText/index.d.ts +19 -6
- package/es/site/data/components/tour/demos/customText/index.js +18 -17
- package/es/site/data/components/tour/demos/customText/react.d.ts +20 -6
- package/es/site/data/components/tour/demos/customText/react.js +31 -27
- package/es/test/demos.js +1 -1
- package/index.ts +2 -2
- package/package.json +2 -2
- package/components/datepicker/demos/nowrap.md +0 -35
- package/components/datepicker/usePosition.ts +0 -169
- package/es/components/datepicker/usePosition.d.ts +0 -10
- package/es/components/datepicker/usePosition.js +0 -166
- package/es/site/data/components/datepicker/demos/nowrap/index.d.ts +0 -10
- package/es/site/data/components/datepicker/demos/nowrap/index.js +0 -19
- package/es/site/data/components/datepicker/demos/nowrap/react.d.ts +0 -10
- package/es/site/data/components/datepicker/demos/nowrap/react.js +0 -49
- package/es/site/data/components/tour/demos/customButtons/index.d.ts +0 -33
- package/es/site/data/components/tour/demos/customButtons/index.js +0 -55
- package/es/site/data/components/tour/demos/customButtons/react.d.ts +0 -33
- package/es/site/data/components/tour/demos/customButtons/react.js +0 -99
|
@@ -66,6 +66,7 @@ const filterInput = <Input v-if={filterable}
|
|
|
66
66
|
container={container}
|
|
67
67
|
v-model="show"
|
|
68
68
|
position={position}
|
|
69
|
+
alwaysShowOnClick={$props.alwaysShowOnClick}
|
|
69
70
|
>
|
|
70
71
|
<div {...getRestProps(this)}
|
|
71
72
|
class={classNameObj}
|
|
@@ -74,6 +75,7 @@ const filterInput = <Input v-if={filterable}
|
|
|
74
75
|
ev-focusout={onFocusout}
|
|
75
76
|
style={!isNullOrUndefined(width) ? addStyle(style, {width: `${width}px`}) : style}
|
|
76
77
|
ref={triggerRef}
|
|
78
|
+
ev-click={$props.onClick}
|
|
77
79
|
>
|
|
78
80
|
<div class={`${k}-select-prefix`} v-if={$blocks.prefix}>
|
|
79
81
|
<b:prefix />
|
|
@@ -95,7 +97,6 @@ const filterInput = <Input v-if={filterable}
|
|
|
95
97
|
readonly={!show}
|
|
96
98
|
waveDisabled={true}
|
|
97
99
|
flat={flat}
|
|
98
|
-
ev-click={$props.onClick}
|
|
99
100
|
/>
|
|
100
101
|
<div class={`${k}-select-placeholder c-ellipsis`}
|
|
101
102
|
v-else-if={!filterable && !hasValue}
|
|
@@ -31,7 +31,7 @@ import {Select, Option} from 'kpc';
|
|
|
31
31
|
</Select>
|
|
32
32
|
Days: {JSON.stringify(this.get('days'))}
|
|
33
33
|
<br /><br />
|
|
34
|
-
<Select v-model="dayWithKeywords" filterable multiple creatable keepKeywords style="margin-right: 10px">
|
|
34
|
+
<Select v-model="dayWithKeywords" filterable multiple creatable keepKeywords={false} style="margin-right: 10px">
|
|
35
35
|
<Option value="Monday">星期一</Option>
|
|
36
36
|
<Option value="Tuesday">星期二</Option>
|
|
37
37
|
<Option value="Wednesday">星期三</Option>
|
|
@@ -40,7 +40,7 @@ import {Select, Option} from 'kpc';
|
|
|
40
40
|
<Option value="Saturday">星期六</Option>
|
|
41
41
|
<Option value="Sunday">星期天</Option>
|
|
42
42
|
</Select>
|
|
43
|
-
Day with keepKeywords: {JSON.stringify(this.get('dayWithKeywords'))}
|
|
43
|
+
Day with keepKeywords=false: {JSON.stringify(this.get('dayWithKeywords'))}
|
|
44
44
|
</div>
|
|
45
45
|
```
|
|
46
46
|
|
|
@@ -31,7 +31,7 @@ sidebar: doc
|
|
|
31
31
|
| labelMap | 建立值`value`到展示标签`label`的映射,可以在`value`不在`Option`集合中时,依然能够正确展示相应的`label` | `Map<any, string>` | `new Map()` |
|
|
32
32
|
| card | 是否展示`card`模式 | `boolean` | `false` |
|
|
33
33
|
| autoDisableArrow | 是否在没有更多可选项时,给箭头一个`disabled`状态来提示用户 | `boolean` | `false` |
|
|
34
|
-
| keepKeywords | 是否在选中选项后保留搜索关键字,配合`filterable`使用 | `boolean` | `
|
|
34
|
+
| keepKeywords | 是否在选中选项后保留搜索关键字,配合`filterable`使用 | `boolean` | `true` |
|
|
35
35
|
| show | 是否展示菜单项 | `boolean` | `false` |
|
|
36
36
|
| position | 菜单弹出的位置,默认与触发器左侧对齐向下偏移`8px`的地方 | `Position` | `"left"` | `"bottom"` | `"right"` | `"top"` | `{my: 'left top+8', 'left bottom'}` |
|
|
37
37
|
| flat | 是否展示扁平样式 | `boolean` | `false` |
|
|
@@ -12,9 +12,9 @@ import SearchableDemo from '~/components/select/demos/searchable';
|
|
|
12
12
|
import ImmutableDemo from '~/components/select/demos/immutable';
|
|
13
13
|
|
|
14
14
|
describe('Select', () => {
|
|
15
|
-
afterEach((
|
|
15
|
+
afterEach(async () => {
|
|
16
16
|
unmount();
|
|
17
|
-
|
|
17
|
+
await wait(500);
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
it('should select value correctly', async () => {
|
|
@@ -188,6 +188,39 @@ describe('Select', () => {
|
|
|
188
188
|
expect(dropdown2.innerHTML).to.matchSnapshot();
|
|
189
189
|
});
|
|
190
190
|
|
|
191
|
+
it('should select the first card of group on filtering', async () => {
|
|
192
|
+
const [instance, element] = mount(GroupDemo);
|
|
193
|
+
|
|
194
|
+
instance.set<string>('day', 'Saturday');
|
|
195
|
+
await wait();
|
|
196
|
+
const [, trigger] = element.querySelectorAll<HTMLElement>('.k-select');
|
|
197
|
+
trigger.click();
|
|
198
|
+
await wait();
|
|
199
|
+
const dropdown = getElement('.k-select-menu')!;
|
|
200
|
+
defaultStatusTest();
|
|
201
|
+
|
|
202
|
+
// filter
|
|
203
|
+
const input = trigger.querySelector('.k-input-inner') as HTMLInputElement;
|
|
204
|
+
input.value = 'm';
|
|
205
|
+
dispatchEvent(input, 'input');
|
|
206
|
+
await wait();
|
|
207
|
+
const firstTab = dropdown.querySelector('.k-tab') as HTMLElement;
|
|
208
|
+
expect(firstTab.classList.contains('k-active')).to.eql(true);
|
|
209
|
+
|
|
210
|
+
// clear
|
|
211
|
+
input.value = '';
|
|
212
|
+
dispatchEvent(input, 'input');
|
|
213
|
+
await wait();
|
|
214
|
+
defaultStatusTest();
|
|
215
|
+
|
|
216
|
+
function defaultStatusTest() {
|
|
217
|
+
const secondTab = dropdown.querySelector('.k-tab:nth-child(2)') as HTMLElement;
|
|
218
|
+
const item = dropdown.querySelector('.k-dropdown-item') as HTMLElement;
|
|
219
|
+
expect(secondTab.classList.contains('k-active')).to.eql(true);
|
|
220
|
+
expect(item.classList.contains('k-active')).to.eql(true);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
|
|
191
224
|
it('keyboard operations', async () => {
|
|
192
225
|
const [instance, element] = mount(BasicDemo);
|
|
193
226
|
|
|
@@ -206,6 +239,9 @@ describe('Select', () => {
|
|
|
206
239
|
const [instance, element] = mount(CreatableDemo);
|
|
207
240
|
|
|
208
241
|
const input = element.querySelector('.k-input-inner') as HTMLInputElement;
|
|
242
|
+
|
|
243
|
+
expect(instance.get('day')).to.be.null;
|
|
244
|
+
|
|
209
245
|
input.click();
|
|
210
246
|
await wait();
|
|
211
247
|
input.value = 'xxx';
|
|
@@ -213,38 +249,82 @@ describe('Select', () => {
|
|
|
213
249
|
await wait();
|
|
214
250
|
const dropdown = getElement('.k-select-menu')!;
|
|
215
251
|
expect(dropdown.innerHTML).to.matchSnapshot();
|
|
216
|
-
|
|
252
|
+
|
|
253
|
+
// check the created option appears in dropdown
|
|
254
|
+
const createOption = dropdown.querySelector('.k-select-option');
|
|
255
|
+
expect(createOption).to.exist;
|
|
256
|
+
expect(createOption!.textContent).to.contain('xxx');
|
|
257
|
+
|
|
258
|
+
// press enter to select the custom option
|
|
217
259
|
dispatchEvent(document, 'keydown', {keyCode: 13});
|
|
218
260
|
await wait();
|
|
219
261
|
expect(instance.get('day')).to.eql('xxx');
|
|
262
|
+
expect(input.value).to.eql('xxx');
|
|
220
263
|
|
|
221
|
-
//
|
|
264
|
+
// reopen dropdown
|
|
222
265
|
input.click();
|
|
223
266
|
await wait();
|
|
224
267
|
expect(element.innerHTML).to.matchSnapshot();
|
|
225
268
|
expect(dropdown.innerHTML).to.matchSnapshot();
|
|
226
|
-
|
|
227
|
-
// input
|
|
269
|
+
|
|
270
|
+
// input another custom option
|
|
228
271
|
input.value = 'yyy';
|
|
229
272
|
dispatchEvent(input, 'input');
|
|
230
273
|
await wait();
|
|
231
274
|
expect(element.innerHTML).to.matchSnapshot();
|
|
232
275
|
expect(dropdown.innerHTML).to.matchSnapshot();
|
|
233
276
|
|
|
234
|
-
|
|
277
|
+
const newCreateOption = dropdown.querySelector('.k-select-option');
|
|
278
|
+
expect(newCreateOption).to.exist;
|
|
279
|
+
expect(newCreateOption!.textContent).to.contain('yyy');
|
|
280
|
+
|
|
281
|
+
// click outside to cancel selection
|
|
235
282
|
dispatchEvent(document, 'click');
|
|
236
283
|
await wait();
|
|
237
284
|
expect(element.innerHTML).to.matchSnapshot();
|
|
238
|
-
expect(instance.get('day')).to.eql('xxx');
|
|
285
|
+
expect(instance.get('day')).to.eql('xxx'); // should keep the original value
|
|
286
|
+
expect(input.value).to.eql('xxx'); // should restore the original value
|
|
287
|
+
|
|
288
|
+
// test multiple creatable
|
|
289
|
+
const [, multipleInput] = element.querySelectorAll<HTMLInputElement>('.k-input-inner');
|
|
290
|
+
expect(instance.get('days')).to.eql([]);
|
|
291
|
+
|
|
292
|
+
multipleInput.click();
|
|
293
|
+
await wait();
|
|
294
|
+
multipleInput.value = 'custom1';
|
|
295
|
+
dispatchEvent(multipleInput, 'input');
|
|
296
|
+
await wait();
|
|
297
|
+
|
|
298
|
+
// press enter to create and select the first custom option
|
|
299
|
+
dispatchEvent(document, 'keydown', {keyCode: 13});
|
|
300
|
+
await wait();
|
|
301
|
+
expect(instance.get('days')).to.include('custom1');
|
|
302
|
+
expect(multipleInput.value).to.eql('custom1');
|
|
303
|
+
|
|
304
|
+
// input the same option again
|
|
305
|
+
dispatchEvent(document, 'keydown', {keyCode: 13});
|
|
306
|
+
await wait();
|
|
307
|
+
expect(instance.get('days')).to.eql([]);
|
|
308
|
+
expect(multipleInput.value).to.eql('custom1');
|
|
309
|
+
|
|
310
|
+
// test select original options
|
|
311
|
+
multipleInput.value = 'Monday';
|
|
312
|
+
dispatchEvent(multipleInput, 'input');
|
|
313
|
+
await wait();
|
|
314
|
+
const multipleDropdown = getElement('.k-select-menu')!;
|
|
315
|
+
const mondayOption = multipleDropdown.querySelector('.k-select-option') as HTMLElement;
|
|
316
|
+
expect(mondayOption.textContent).to.eql('星期一');
|
|
317
|
+
mondayOption.click();
|
|
318
|
+
await wait();
|
|
319
|
+
expect(instance.get('days')).to.include('Monday');
|
|
239
320
|
});
|
|
240
321
|
|
|
241
322
|
it('keepKeywords', async () => {
|
|
242
|
-
// 创建一个测试组件,包含keepKeywords功能
|
|
243
323
|
class KeepKeywordsDemo extends Component<{days: string[]}> {
|
|
244
324
|
static template = `
|
|
245
325
|
const {Select, Option} = this;
|
|
246
326
|
<div>
|
|
247
|
-
<Select v-model="days" filterable multiple creatable keepKeywords>
|
|
327
|
+
<Select v-model="days" filterable multiple creatable keepKeywords={false}>
|
|
248
328
|
<Option value="Monday">星期一</Option>
|
|
249
329
|
<Option value="Tuesday">星期二</Option>
|
|
250
330
|
<Option value="Wednesday">星期三</Option>
|
|
@@ -263,50 +343,50 @@ describe('Select', () => {
|
|
|
263
343
|
const [instance, element] = mount(KeepKeywordsDemo);
|
|
264
344
|
const input = element.querySelector('.k-input-inner') as HTMLInputElement;
|
|
265
345
|
|
|
266
|
-
//
|
|
346
|
+
// input custom option "custom1"
|
|
267
347
|
input.click();
|
|
268
348
|
await wait();
|
|
269
349
|
input.value = 'custom1';
|
|
270
350
|
dispatchEvent(input, 'input');
|
|
271
351
|
await wait();
|
|
272
352
|
|
|
273
|
-
//
|
|
353
|
+
// check the created option appears in dropdown
|
|
274
354
|
const dropdown = getElement('.k-select-menu')!;
|
|
275
355
|
expect(dropdown.innerHTML).to.contain('custom1');
|
|
276
356
|
|
|
277
|
-
//
|
|
357
|
+
// press enter to create and select
|
|
278
358
|
dispatchEvent(document, 'keydown', {keyCode: 13});
|
|
279
359
|
await wait();
|
|
280
360
|
|
|
281
|
-
//
|
|
361
|
+
// check the option is selected, and the input is cleared
|
|
282
362
|
expect(instance.get('days')).to.eql(['custom1']);
|
|
283
|
-
expect(input.value).to.eql('');
|
|
363
|
+
expect(input.value).to.eql('');
|
|
284
364
|
|
|
285
|
-
//
|
|
365
|
+
// input the same option "custom1" again
|
|
286
366
|
input.value = 'custom1';
|
|
287
367
|
dispatchEvent(input, 'input');
|
|
288
368
|
await wait();
|
|
289
369
|
|
|
290
|
-
//
|
|
370
|
+
// press enter again
|
|
291
371
|
dispatchEvent(document, 'keydown', {keyCode: 13});
|
|
292
372
|
await wait();
|
|
293
373
|
|
|
294
|
-
//
|
|
295
|
-
expect(instance.get('days')).to.eql(['custom1']); //
|
|
296
|
-
expect(input.value).to.eql(''); //
|
|
374
|
+
// check the option is still selected (not be unselected), and the input is cleared
|
|
375
|
+
expect(instance.get('days')).to.eql(['custom1']); // should be selected
|
|
376
|
+
expect(input.value).to.eql(''); // should be cleared
|
|
297
377
|
|
|
298
|
-
//
|
|
378
|
+
// input another custom option "custom2"
|
|
299
379
|
input.value = 'custom2';
|
|
300
380
|
dispatchEvent(input, 'input');
|
|
301
381
|
await wait();
|
|
302
382
|
dispatchEvent(document, 'keydown', {keyCode: 13});
|
|
303
383
|
await wait();
|
|
304
384
|
|
|
305
|
-
//
|
|
385
|
+
// check two options are selected
|
|
306
386
|
expect(instance.get('days')).to.eql(['custom1', 'custom2']);
|
|
307
387
|
expect(input.value).to.eql('');
|
|
308
388
|
|
|
309
|
-
//
|
|
389
|
+
// test the normal behavior of original options
|
|
310
390
|
input.click();
|
|
311
391
|
await wait();
|
|
312
392
|
const mondayOption = dropdown.querySelector('[data-value="Monday"]') as HTMLElement;
|
|
@@ -315,7 +395,7 @@ describe('Select', () => {
|
|
|
315
395
|
await wait();
|
|
316
396
|
expect(instance.get('days')).to.include('Monday');
|
|
317
397
|
|
|
318
|
-
//
|
|
398
|
+
// click again should be unselected (original options are not affected by keepKeywords)
|
|
319
399
|
mondayOption.click();
|
|
320
400
|
await wait();
|
|
321
401
|
expect(instance.get('days')).to.not.include('Monday');
|
|
@@ -383,21 +463,47 @@ describe('Select', () => {
|
|
|
383
463
|
});
|
|
384
464
|
|
|
385
465
|
it('Searchable with multiple should show correct initial checkbox state', async () => {
|
|
386
|
-
|
|
466
|
+
class Demo extends Component {
|
|
467
|
+
static template = `
|
|
468
|
+
const {Select, Option} = this;
|
|
469
|
+
<Select v-model="days" searchable multiple>
|
|
470
|
+
<Option value="Monday" disabled>星期一</Option>
|
|
471
|
+
<Option value="Tuesday">星期二</Option>
|
|
472
|
+
<Option value="Wednesday">星期三</Option>
|
|
473
|
+
<Option value="Thursday">星期四</Option>
|
|
474
|
+
<Option value="Friday">星期五</Option>
|
|
475
|
+
<Option value="Saturday">星期六</Option>
|
|
476
|
+
<Option value="Sunday">星期天</Option>
|
|
477
|
+
<b:values args="[value]">
|
|
478
|
+
<div class="k-value">
|
|
479
|
+
已选择{value.length}项 / 共7项
|
|
480
|
+
</div>
|
|
481
|
+
</b:values>
|
|
482
|
+
</Select>
|
|
483
|
+
`;
|
|
484
|
+
static defaults() {
|
|
485
|
+
return {
|
|
486
|
+
days: ['Tuesday']
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
private Tooltip = Tooltip;
|
|
490
|
+
private Select = Select;
|
|
491
|
+
private Option = Option;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
const [instance, element] = mount(Demo as any);
|
|
387
495
|
|
|
388
|
-
// 验证初始值
|
|
389
496
|
expect(instance.get('days')).to.eql(['Tuesday']);
|
|
390
497
|
|
|
391
|
-
//
|
|
392
|
-
|
|
393
|
-
select.click();
|
|
498
|
+
// first open dropdown, check initial state
|
|
499
|
+
element.click();
|
|
394
500
|
await wait();
|
|
395
501
|
|
|
396
502
|
const dropdown = getElement('.k-select-menu')!;
|
|
397
503
|
const checkboxes = dropdown.querySelectorAll<HTMLInputElement>('.k-checkbox input[type="checkbox"]');
|
|
398
504
|
const options = dropdown.querySelectorAll<HTMLElement>('.k-select-option');
|
|
399
505
|
|
|
400
|
-
//
|
|
506
|
+
// find the checkbox of Tuesday option
|
|
401
507
|
let tuesdayCheckbox: HTMLInputElement | null = null;
|
|
402
508
|
let tuesdayOption: HTMLElement | null = null;
|
|
403
509
|
|
|
@@ -408,21 +514,21 @@ describe('Select', () => {
|
|
|
408
514
|
}
|
|
409
515
|
});
|
|
410
516
|
|
|
411
|
-
//
|
|
517
|
+
// check the checkbox of Tuesday should be checked
|
|
412
518
|
expect(tuesdayCheckbox).to.exist;
|
|
413
519
|
expect(tuesdayCheckbox!.checked).to.be.true;
|
|
414
520
|
|
|
415
|
-
//
|
|
521
|
+
// check the Tuesday option should have active style
|
|
416
522
|
expect(tuesdayOption).to.exist;
|
|
417
523
|
expect(tuesdayOption!.className).to.include('k-active');
|
|
418
524
|
|
|
419
|
-
//
|
|
525
|
+
// close dropdown
|
|
420
526
|
const [cancel] = dropdown.querySelectorAll<HTMLElement>('.k-select-footer .k-btn');
|
|
421
527
|
cancel.click();
|
|
422
528
|
await wait();
|
|
423
529
|
|
|
424
|
-
//
|
|
425
|
-
|
|
530
|
+
// reopen dropdown, check the state is still correct
|
|
531
|
+
element.click();
|
|
426
532
|
await wait();
|
|
427
533
|
|
|
428
534
|
const dropdown2 = getElement('.k-select-menu')!;
|
|
@@ -439,7 +545,7 @@ describe('Select', () => {
|
|
|
439
545
|
}
|
|
440
546
|
});
|
|
441
547
|
|
|
442
|
-
//
|
|
548
|
+
// check the state is still correct when reopen
|
|
443
549
|
expect(tuesdayCheckbox2!.checked).to.be.true;
|
|
444
550
|
expect(tuesdayOption2!.className).to.include('k-active');
|
|
445
551
|
});
|
|
@@ -12,7 +12,7 @@ export class SelectMenu extends Component<{values: any[]}> {
|
|
|
12
12
|
static template = template;
|
|
13
13
|
|
|
14
14
|
public select: Select<any, boolean> = inject(SELECT)!;
|
|
15
|
-
private card = useCard(this.select.label.activeIndices);
|
|
15
|
+
private card = useCard(this.select.label.activeIndices, this.select.input.keywords);
|
|
16
16
|
private searchable = useSearchable();
|
|
17
17
|
private config = useConfigContext();
|
|
18
18
|
}
|
|
@@ -40,7 +40,8 @@ export class Option extends Component<OptionProps> {
|
|
|
40
40
|
} else {
|
|
41
41
|
let values = select.get('value');
|
|
42
42
|
|
|
43
|
-
if (keepKeywords && isCreated && Array.isArray(values) && values.includes(value)) {
|
|
43
|
+
if (!keepKeywords && isCreated && Array.isArray(values) && values.includes(value)) {
|
|
44
|
+
select.resetKeywords();
|
|
44
45
|
return;
|
|
45
46
|
}
|
|
46
47
|
|
|
@@ -5,7 +5,7 @@ import '../../styles/global';
|
|
|
5
5
|
import { cache } from '../utils';
|
|
6
6
|
|
|
7
7
|
type SizeStyles = {
|
|
8
|
-
padding
|
|
8
|
+
padding: string,
|
|
9
9
|
height: string,
|
|
10
10
|
fontSize: string,
|
|
11
11
|
}
|
|
@@ -118,6 +118,8 @@ setDefault(() => {
|
|
|
118
118
|
makeGroupStyles?.clearCache();
|
|
119
119
|
});
|
|
120
120
|
|
|
121
|
+
export { select }
|
|
122
|
+
|
|
121
123
|
export const makeStyles = cache(function makeStyles(k: string) {
|
|
122
124
|
return css`
|
|
123
125
|
display: inline-flex;
|
|
@@ -2,13 +2,31 @@ import {Component, TypeDefs, useInstance, Children, Blocks, createRef, NonNullab
|
|
|
2
2
|
import {eachChildren, isComponentVNode, last} from '../utils';
|
|
3
3
|
import {EMPTY_OBJ} from 'intact-shared';
|
|
4
4
|
import {OptionGroup} from './group';
|
|
5
|
-
import {useState} from '../../hooks/useState';
|
|
5
|
+
import {useState, State, watchState} from '../../hooks/useState';
|
|
6
|
+
import type { SelectMenu } from './menu';
|
|
6
7
|
|
|
7
|
-
export function useCard(
|
|
8
|
-
|
|
8
|
+
export function useCard(
|
|
9
|
+
defaultActiveIndex: NonNullableRefObject<number[]>,
|
|
10
|
+
keywords: State<string>
|
|
11
|
+
) {
|
|
12
|
+
const instance = useInstance() as SelectMenu;
|
|
9
13
|
const activeIndex = useState<number>(last(defaultActiveIndex.value) || 0);
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
watchState(keywords, (keywords) => {
|
|
16
|
+
if (keywords) {
|
|
17
|
+
activeIndex.set(0);
|
|
18
|
+
} else {
|
|
19
|
+
setDefaultActiveIndex();
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
instance.select.on('show', setDefaultActiveIndex);
|
|
24
|
+
|
|
25
|
+
function setDefaultActiveIndex() {
|
|
26
|
+
activeIndex.set(last(defaultActiveIndex.value) || 0);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function process(children: Children, isSearching: boolean) {
|
|
12
30
|
const groupLabels: Children[] | Blocks[string][] = [];
|
|
13
31
|
const _children: Children[] = [];
|
|
14
32
|
let index = 0;
|
|
@@ -11,13 +11,9 @@ import {
|
|
|
11
11
|
} from 'intact';
|
|
12
12
|
import {useState, State} from '../../hooks/useState';
|
|
13
13
|
import type {Select, SelectProps} from './select';
|
|
14
|
-
import {Option, OptionProps} from './option';
|
|
15
|
-
import {OptionGroup, OptionGroupProps} from './group';
|
|
16
|
-
import {isNullOrUndefined, EMPTY_OBJ, isStringOrNumber} from 'intact-shared';
|
|
17
|
-
import {getTextByChildren, mapChildren, isComponentVNode} from '../utils';
|
|
18
14
|
import type {Input} from '../input';
|
|
19
15
|
|
|
20
|
-
export function useInput(resetKeywords: (
|
|
16
|
+
export function useInput(resetKeywords: () => void) {
|
|
21
17
|
const component = useInstance() as Select;
|
|
22
18
|
const keywords = useState('');
|
|
23
19
|
const inputRef = createRef<Input>();
|
|
@@ -50,9 +46,9 @@ export function useInput(resetKeywords: (keywords: State<string>) => void) {
|
|
|
50
46
|
component.on('$changed:show', show => {
|
|
51
47
|
if (show) {
|
|
52
48
|
focusInput();
|
|
53
|
-
resetKeywords(
|
|
49
|
+
resetKeywords();
|
|
54
50
|
} else if (component.get('multiple')) {
|
|
55
|
-
resetKeywords(
|
|
51
|
+
resetKeywords();
|
|
56
52
|
}
|
|
57
53
|
});
|
|
58
54
|
component.on('$changed:value', () => {
|
|
@@ -63,8 +59,8 @@ export function useInput(resetKeywords: (keywords: State<string>) => void) {
|
|
|
63
59
|
* don't reset keywords on multiple mode for continue selection
|
|
64
60
|
* https://github.com/ksc-fe/kpc/issues/983
|
|
65
61
|
*/
|
|
66
|
-
if (keepKeywords) {
|
|
67
|
-
resetKeywords(
|
|
62
|
+
if (!keepKeywords) {
|
|
63
|
+
resetKeywords();
|
|
68
64
|
}
|
|
69
65
|
}
|
|
70
66
|
});
|
|
@@ -227,6 +227,24 @@ describe('Spinner', () => {
|
|
|
227
227
|
expect(instance.get('value1')).to.eql(8.4);
|
|
228
228
|
});
|
|
229
229
|
|
|
230
|
+
it('forceStep without min value', async () => {
|
|
231
|
+
class Demo extends Component {
|
|
232
|
+
static template = `const {Spinner} = this;
|
|
233
|
+
<Spinner step={1} v-model="value" forceStep />
|
|
234
|
+
`;
|
|
235
|
+
static defaults() {
|
|
236
|
+
return {value: 1};
|
|
237
|
+
}
|
|
238
|
+
private Spinner = Spinner;
|
|
239
|
+
}
|
|
240
|
+
const [instance, element] = mount(Demo);
|
|
241
|
+
expect(instance.get('value')).to.eql(1);
|
|
242
|
+
|
|
243
|
+
instance.set<number>('value', -1);
|
|
244
|
+
await wait();
|
|
245
|
+
expect(instance.get('value')).to.eql(-1);
|
|
246
|
+
});
|
|
247
|
+
|
|
230
248
|
it('dynamic step', async () => {
|
|
231
249
|
const [instance, element] = mount(DynamicStepDemo);
|
|
232
250
|
|
|
@@ -78,7 +78,8 @@ export function minMaxStep(value: number, min: number, max: number, step: number
|
|
|
78
78
|
if (value >= max) return max;
|
|
79
79
|
if (value <= min) return min;
|
|
80
80
|
if (step) {
|
|
81
|
-
|
|
81
|
+
let _min = min === -Infinity ? 0 : min;
|
|
82
|
+
value = Number((Math.round((value - _min) / step) * step + _min).toFixed(10))
|
|
82
83
|
// value = Number((Math.round(value / step) * step).toFixed(10))
|
|
83
84
|
return minMaxStep(value, min, max, null);
|
|
84
85
|
}
|
|
@@ -496,7 +496,6 @@ describe('Table', () => {
|
|
|
496
496
|
checkbox.click();
|
|
497
497
|
await wait();
|
|
498
498
|
expect(element.innerHTML).to.matchSnapshot();
|
|
499
|
-
debugger;
|
|
500
499
|
expect(table.getCheckedData()).to.have.lengthOf(8);
|
|
501
500
|
|
|
502
501
|
const arrow = element.querySelector('.k-table-arrow') as HTMLElement;
|
|
@@ -723,4 +722,73 @@ describe('Table', () => {
|
|
|
723
722
|
expect(spy.callCount).to.eql(5);
|
|
724
723
|
expect(spy.lastCall.lastArg).to.eql({value: 2, limit: 10});
|
|
725
724
|
});
|
|
725
|
+
|
|
726
|
+
it('fixHeader with Affix header scroll sync', async () => {
|
|
727
|
+
interface Props {
|
|
728
|
+
data: any[]
|
|
729
|
+
fixHeader: boolean | number
|
|
730
|
+
virtual: boolean
|
|
731
|
+
stickScrollbar: boolean | number
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
class Demo extends Component<Props> {
|
|
735
|
+
static template = `
|
|
736
|
+
const {Table, TableColumn} = this;
|
|
737
|
+
const {data, fixHeader, virtual, stickScrollbar} = this.get();
|
|
738
|
+
<Table data={data} fixHeader={fixHeader} virtual={virtual} stickScrollbar={stickScrollbar} ref="table">
|
|
739
|
+
<TableColumn fixed="left" key="name" title="Name" width="200" />
|
|
740
|
+
<TableColumn key="column1" title="Column1" width="300" />
|
|
741
|
+
<TableColumn key="column2" title="Column2" width="300" />
|
|
742
|
+
<TableColumn key="column3" title="Column3" width="300" />
|
|
743
|
+
<TableColumn fixed="right" key="action" title="Action" width="200" />
|
|
744
|
+
</Table>
|
|
745
|
+
`;
|
|
746
|
+
|
|
747
|
+
static defaults() {
|
|
748
|
+
return {
|
|
749
|
+
data: Array.from({length: 10}, (_, i) => ({
|
|
750
|
+
name: `Name ${i}`,
|
|
751
|
+
column1: `Column1 ${i}`,
|
|
752
|
+
column2: `Column2 ${i}`,
|
|
753
|
+
column3: `Column3 ${i}`,
|
|
754
|
+
action: `Action ${i}`
|
|
755
|
+
})),
|
|
756
|
+
fixHeader: 200,
|
|
757
|
+
virtual: false,
|
|
758
|
+
stickScrollbar: false
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
private Table = Table;
|
|
763
|
+
private TableColumn = TableColumn;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
const [instance, element] = mount(Demo);
|
|
767
|
+
|
|
768
|
+
// Test 1: fixHeader only - scroll left 50px
|
|
769
|
+
await wait();
|
|
770
|
+
const scrollContainer = element.querySelector('.k-table-wrapper') as HTMLElement;
|
|
771
|
+
scrollContainer.scrollLeft = 50;
|
|
772
|
+
await wait(100);
|
|
773
|
+
const affixWrapper1 = element.querySelector('.k-table-affix-header .k-affix-wrapper') as HTMLElement;
|
|
774
|
+
expect(affixWrapper1.scrollLeft).to.eql(50);
|
|
775
|
+
|
|
776
|
+
// Test 2: fixHeader + virtual - scroll left 50px more (total 100px)
|
|
777
|
+
instance.set('virtual', true);
|
|
778
|
+
await wait();
|
|
779
|
+
scrollContainer.scrollLeft = 100;
|
|
780
|
+
await wait(100);
|
|
781
|
+
|
|
782
|
+
const affixWrapper2 = element.querySelector('.k-table-affix-header .k-affix-wrapper') as HTMLElement;
|
|
783
|
+
expect(affixWrapper2.scrollLeft).to.eql(100);
|
|
784
|
+
|
|
785
|
+
// Test 3: stickScrollbar + fixHeader - scroll right 50px (back to 50px)
|
|
786
|
+
instance.set('stickScrollbar', true);
|
|
787
|
+
await wait();
|
|
788
|
+
scrollContainer.scrollLeft = 50;
|
|
789
|
+
await wait(100);
|
|
790
|
+
|
|
791
|
+
const affixWrapper3 = element.querySelector('.k-table-affix-header .k-affix-wrapper') as HTMLElement;
|
|
792
|
+
expect(affixWrapper3.scrollLeft).to.eql(50);
|
|
793
|
+
});
|
|
726
794
|
});
|
|
@@ -22,7 +22,7 @@ export function useStickyHeader(callbacks: ScrollCallback[]) {
|
|
|
22
22
|
|
|
23
23
|
// when the scroll element scroll horizontally, scroll the sticky header too
|
|
24
24
|
callbacks.push(scrollLeft => {
|
|
25
|
-
if (isNull(stickHeader.value)) return;
|
|
25
|
+
if (isNull(stickHeader.value) && !instance.get('fixHeader')) return;
|
|
26
26
|
|
|
27
27
|
const affixHeadWrapper = headRef.value!.parentElement as HTMLElement;
|
|
28
28
|
affixHeadWrapper.scrollLeft = scrollLeft;
|