@king-design/intact 3.5.2 → 3.6.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/button/index.md +1 -0
- package/components/datepicker/basepicker.ts +60 -13
- package/components/datepicker/calendar.ts +5 -1
- package/components/datepicker/calendar.vdt +20 -6
- package/components/datepicker/dayjs.ts +22 -2
- package/components/datepicker/demos/multiple.md +0 -5
- package/components/datepicker/demos/nowrap.md +35 -0
- package/components/datepicker/demos/yearMonth.md +8 -2
- package/components/datepicker/helpers.ts +5 -5
- package/components/datepicker/index.md +3 -2
- package/components/datepicker/index.spec.ts +107 -90
- package/components/datepicker/index.ts +23 -5
- package/components/datepicker/index.vdt +34 -35
- package/components/datepicker/styles.ts +102 -3
- package/components/datepicker/useDisabled.ts +3 -3
- package/components/datepicker/useFormats.ts +2 -0
- package/components/datepicker/useMergeRange.ts +54 -0
- package/components/datepicker/usePosition.ts +169 -0
- package/components/datepicker/useQuarters.ts +47 -0
- package/components/datepicker/useShowDate.ts +42 -11
- package/components/datepicker/useValue.ts +35 -4
- package/components/datepicker/useWeeks.ts +58 -0
- package/components/dialog/useFixBody.ts +7 -64
- package/components/ellipsis/styles.ts +4 -0
- package/components/form/styles.ts +1 -0
- package/components/scrollSelect/index.spec.ts +3 -3
- package/components/scrollSelect/useMouseEvents.ts +23 -10
- package/components/select/base.vdt +2 -1
- package/components/select/demos/creatable.md +13 -0
- package/components/select/index.md +1 -0
- package/components/select/index.spec.ts +146 -0
- package/components/select/option.ts +9 -1
- package/components/select/select.ts +2 -0
- package/components/select/useFilterable.ts +1 -1
- package/components/select/useInput.ts +4 -2
- package/components/select/useSearchable.ts +2 -2
- package/components/timepicker/demos/step.md +1 -1
- package/components/timepicker/panelPicker.vdt +5 -1
- package/components/timepicker/styles.ts +0 -1
- package/components/tour/demos/basic.md +73 -0
- package/components/tour/demos/beforeChange.md +109 -0
- package/components/tour/demos/closable.md +70 -0
- package/components/tour/demos/custom.md +98 -0
- package/components/tour/demos/customText.md +94 -0
- package/components/tour/demos/declarative.md +72 -0
- package/components/tour/demos/events.md +101 -0
- package/components/tour/demos/maskClosable.md +76 -0
- package/components/tour/demos/notarget.md +59 -0
- package/components/tour/index.md +48 -0
- package/components/tour/index.spec.ts +259 -0
- package/components/tour/index.ts +2 -0
- package/components/tour/step.ts +55 -0
- package/components/tour/step.vdt +75 -0
- package/components/tour/styles.ts +283 -0
- package/components/tour/tour.ts +107 -0
- package/components/tour/tour.vdt +83 -0
- package/components/tour/useArrow.ts +46 -0
- package/components/tour/useFixBody.ts +22 -0
- package/components/tour/useHighlight.ts +36 -0
- package/components/tour/useMaskClosable.ts +26 -0
- package/components/tour/useNavigation.ts +46 -0
- package/components/tour/usePosition.ts +91 -0
- package/components/tour/useSteps.ts +80 -0
- package/es/components/datepicker/basepicker.d.ts +4 -2
- package/es/components/datepicker/basepicker.js +46 -13
- package/es/components/datepicker/calendar.d.ts +34 -6
- package/es/components/datepicker/calendar.js +4 -0
- package/es/components/datepicker/calendar.vdt.js +21 -5
- package/es/components/datepicker/dayjs.d.ts +13 -2
- package/es/components/datepicker/dayjs.js +6 -0
- package/es/components/datepicker/helpers.d.ts +5 -5
- package/es/components/datepicker/index.d.ts +17 -2
- package/es/components/datepicker/index.js +23 -5
- package/es/components/datepicker/index.spec.js +356 -355
- package/es/components/datepicker/index.vdt.js +25 -29
- package/es/components/datepicker/styles.d.ts +17 -0
- package/es/components/datepicker/styles.js +29 -2
- package/es/components/datepicker/useDisabled.d.ts +2 -2
- package/es/components/datepicker/useDisabled.js +1 -1
- package/es/components/datepicker/useFormats.js +3 -1
- package/es/components/datepicker/useMergeRange.d.ts +5 -0
- package/es/components/datepicker/useMergeRange.js +50 -0
- package/es/components/datepicker/usePosition.d.ts +10 -0
- package/es/components/datepicker/usePosition.js +166 -0
- package/es/components/datepicker/useQuarters.d.ts +15 -0
- package/es/components/datepicker/useQuarters.js +36 -0
- package/es/components/datepicker/useShowDate.d.ts +1 -1
- package/es/components/datepicker/useShowDate.js +42 -9
- package/es/components/datepicker/useStatus.d.ts +1 -1
- package/es/components/datepicker/useValue.d.ts +1 -0
- package/es/components/datepicker/useValue.js +26 -2
- package/es/components/datepicker/useWeeks.d.ts +19 -0
- package/es/components/datepicker/useWeeks.js +48 -0
- package/es/components/dialog/useFixBody.js +6 -58
- package/es/components/ellipsis/styles.js +1 -1
- package/es/components/form/styles.js +1 -1
- package/es/components/scrollSelect/index.spec.js +4 -6
- package/es/components/scrollSelect/useMouseEvents.js +21 -9
- package/es/components/select/base.vdt.js +4 -2
- package/es/components/select/index.spec.js +235 -62
- package/es/components/select/option.d.ts +1 -0
- package/es/components/select/option.js +9 -2
- package/es/components/select/select.d.ts +1 -0
- package/es/components/select/select.js +2 -1
- package/es/components/select/useFilterable.js +2 -1
- package/es/components/select/useInput.js +5 -2
- package/es/components/select/useSearchable.js +1 -0
- package/es/components/timepicker/panelPicker.d.ts +2 -1
- package/es/components/timepicker/panelPicker.vdt.js +12 -4
- package/es/components/timepicker/selectPicker.d.ts +1 -1
- package/es/components/timepicker/styles.js +1 -1
- package/es/components/timepicker/useDisabled.d.ts +1 -1
- package/es/components/timepicker/useValue.d.ts +1 -0
- package/es/components/tour/index.d.ts +2 -0
- package/es/components/tour/index.js +2 -0
- package/es/components/tour/index.spec.d.ts +1 -0
- package/es/components/tour/index.spec.js +356 -0
- package/es/components/tour/step.d.ts +23 -0
- package/es/components/tour/step.js +46 -0
- package/es/components/tour/step.vdt.js +74 -0
- package/es/components/tour/styles.d.ts +7 -0
- package/es/components/tour/styles.js +84 -0
- package/es/components/tour/tour.d.ts +73 -0
- package/es/components/tour/tour.js +70 -0
- package/es/components/tour/tour.vdt.js +66 -0
- package/es/components/tour/useArrow.d.ts +4 -0
- package/es/components/tour/useArrow.js +40 -0
- package/es/components/tour/useFixBody.d.ts +4 -0
- package/es/components/tour/useFixBody.js +17 -0
- package/es/components/tour/useHighlight.d.ts +4 -0
- package/es/components/tour/useHighlight.js +31 -0
- package/es/components/tour/useMaskClosable.d.ts +1 -0
- package/es/components/tour/useMaskClosable.js +25 -0
- package/es/components/tour/useNavigation.d.ts +5 -0
- package/es/components/tour/useNavigation.js +103 -0
- package/es/components/tour/usePosition.d.ts +6 -0
- package/es/components/tour/usePosition.js +93 -0
- package/es/components/tour/useSteps.d.ts +6 -0
- package/es/components/tour/useSteps.js +68 -0
- package/es/hooks/useFixBody.d.ts +11 -0
- package/es/hooks/useFixBody.js +72 -0
- package/es/index.d.ts +3 -2
- package/es/index.js +3 -2
- package/es/site/data/components/datepicker/demos/multiple/index.d.ts +0 -1
- package/es/site/data/components/datepicker/demos/multiple/index.js +1 -2
- package/es/site/data/components/datepicker/demos/multiple/react.d.ts +0 -1
- package/es/site/data/components/datepicker/demos/multiple/react.js +2 -13
- package/es/site/data/components/datepicker/demos/nowrap/index.d.ts +10 -0
- package/es/site/data/components/datepicker/demos/nowrap/index.js +19 -0
- package/es/site/data/components/datepicker/demos/nowrap/react.d.ts +10 -0
- package/es/site/data/components/datepicker/demos/nowrap/react.js +49 -0
- package/es/site/data/components/datepicker/demos/yearMonth/index.d.ts +2 -0
- package/es/site/data/components/datepicker/demos/yearMonth/index.js +3 -1
- package/es/site/data/components/datepicker/demos/yearMonth/react.d.ts +2 -0
- package/es/site/data/components/datepicker/demos/yearMonth/react.js +21 -1
- package/es/site/data/components/select/demos/creatable/index.d.ts +1 -0
- package/es/site/data/components/select/demos/creatable/index.js +2 -1
- package/es/site/data/components/select/demos/creatable/react.d.ts +1 -0
- package/es/site/data/components/select/demos/creatable/react.js +31 -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/basic/index.d.ts +17 -0
- package/es/site/data/components/tour/demos/basic/index.js +46 -0
- package/es/site/data/components/tour/demos/basic/react.d.ts +16 -0
- package/es/site/data/components/tour/demos/basic/react.js +82 -0
- package/es/site/data/components/tour/demos/beforeChange/index.d.ts +20 -0
- package/es/site/data/components/tour/demos/beforeChange/index.js +69 -0
- package/es/site/data/components/tour/demos/beforeChange/react.d.ts +19 -0
- package/es/site/data/components/tour/demos/beforeChange/react.js +129 -0
- package/es/site/data/components/tour/demos/closable/index.d.ts +18 -0
- package/es/site/data/components/tour/demos/closable/index.js +42 -0
- package/es/site/data/components/tour/demos/closable/react.d.ts +17 -0
- package/es/site/data/components/tour/demos/closable/react.js +85 -0
- package/es/site/data/components/tour/demos/custom/index.d.ts +11 -0
- package/es/site/data/components/tour/demos/custom/index.js +35 -0
- package/es/site/data/components/tour/demos/custom/react.d.ts +11 -0
- package/es/site/data/components/tour/demos/custom/react.js +108 -0
- package/es/site/data/components/tour/demos/customButtons/index.d.ts +33 -0
- package/es/site/data/components/tour/demos/customButtons/index.js +55 -0
- package/es/site/data/components/tour/demos/customButtons/react.d.ts +33 -0
- package/es/site/data/components/tour/demos/customButtons/react.js +99 -0
- package/es/site/data/components/tour/demos/customText/index.d.ts +20 -0
- package/es/site/data/components/tour/demos/customText/index.js +54 -0
- package/es/site/data/components/tour/demos/customText/react.d.ts +19 -0
- package/es/site/data/components/tour/demos/customText/react.js +95 -0
- package/es/site/data/components/tour/demos/declarative/index.d.ts +11 -0
- package/es/site/data/components/tour/demos/declarative/index.js +36 -0
- package/es/site/data/components/tour/demos/declarative/react.d.ts +10 -0
- package/es/site/data/components/tour/demos/declarative/react.js +80 -0
- package/es/site/data/components/tour/demos/events/index.d.ts +18 -0
- package/es/site/data/components/tour/demos/events/index.js +58 -0
- package/es/site/data/components/tour/demos/events/react.d.ts +18 -0
- package/es/site/data/components/tour/demos/events/react.js +101 -0
- package/es/site/data/components/tour/demos/maskClosable/index.d.ts +18 -0
- package/es/site/data/components/tour/demos/maskClosable/index.js +47 -0
- package/es/site/data/components/tour/demos/maskClosable/react.d.ts +17 -0
- package/es/site/data/components/tour/demos/maskClosable/react.js +95 -0
- package/es/site/data/components/tour/demos/notarget/index.d.ts +11 -0
- package/es/site/data/components/tour/demos/notarget/index.js +35 -0
- package/es/site/data/components/tour/demos/notarget/react.d.ts +10 -0
- package/es/site/data/components/tour/demos/notarget/react.js +61 -0
- package/es/site/data/components/tour/index.d.ts +57 -0
- package/es/site/data/components/tour/index.js +32 -0
- package/hooks/useFixBody.ts +87 -0
- package/index.ts +3 -2
- package/package.json +1 -1
|
@@ -28,12 +28,12 @@ export function useMouseEvents(
|
|
|
28
28
|
},
|
|
29
29
|
|
|
30
30
|
onMove(e: MouseEvent) {
|
|
31
|
-
const deltaY = e.clientY - y;
|
|
31
|
+
const deltaY = (e.clientY - y) * 0.8;
|
|
32
32
|
dragged = !!deltaY;
|
|
33
33
|
y = e.clientY;
|
|
34
34
|
|
|
35
35
|
const _deltaY = y - initY;
|
|
36
|
-
let offsetIndex = Math.floor(Math.abs(_deltaY) / itemHeight);
|
|
36
|
+
let offsetIndex = Math.floor(Math.abs(_deltaY) / itemHeight * 1.2);
|
|
37
37
|
if (offsetIndex) {
|
|
38
38
|
if (_deltaY < 0) {
|
|
39
39
|
offsetIndex = -offsetIndex;
|
|
@@ -63,25 +63,38 @@ export function useMouseEvents(
|
|
|
63
63
|
|
|
64
64
|
function onWheel(e: WheelEvent) {
|
|
65
65
|
e.preventDefault();
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
66
|
+
|
|
67
|
+
itemHeight = getItemHeight();
|
|
68
|
+
|
|
69
|
+
const threshold = itemHeight * 0.6;
|
|
70
|
+
deltaY = (deltaY || 0) + e.deltaY;
|
|
71
|
+
|
|
72
|
+
if (Math.abs(deltaY) >= threshold) {
|
|
73
|
+
if (deltaY > 0) {
|
|
74
|
+
setByRelativeIndex(1, null, true);
|
|
75
|
+
} else {
|
|
76
|
+
setByRelativeIndex(-1, null, true);
|
|
77
|
+
}
|
|
78
|
+
deltaY = 0;
|
|
72
79
|
}
|
|
73
80
|
}
|
|
74
81
|
|
|
75
82
|
// throttle onWheel
|
|
76
|
-
const _onWheel = throttle(onWheel,
|
|
83
|
+
const _onWheel = throttle(onWheel, 50, e => e.preventDefault());
|
|
77
84
|
|
|
78
85
|
function onClick(item: any, index: number) {
|
|
79
|
-
// if
|
|
86
|
+
// if dragged, do not trigger click event
|
|
80
87
|
if (dragged) return;
|
|
81
88
|
|
|
82
89
|
const {count} = instance.get();
|
|
83
90
|
const half = Math.floor(count! / 2);
|
|
84
91
|
const itemHeight = getItemHeight();
|
|
92
|
+
|
|
93
|
+
const currentIndex = list.data.value.findIndex(v => v.value === list.value.value);
|
|
94
|
+
const targetOffset = index - half;
|
|
95
|
+
if (currentIndex + targetOffset < 0 || currentIndex + targetOffset >= list.data.value.length) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
85
98
|
|
|
86
99
|
translate.set(translate.value - itemHeight * (index - half));
|
|
87
100
|
marginTop.set(marginTop.value + itemHeight * (index - half));
|
|
@@ -17,7 +17,7 @@ const {
|
|
|
17
17
|
className, container,
|
|
18
18
|
inline, style, width, show,
|
|
19
19
|
position, flat, nowrap,
|
|
20
|
-
draggable,
|
|
20
|
+
draggable, range,
|
|
21
21
|
} = this.get();
|
|
22
22
|
const { k } = this.config;
|
|
23
23
|
|
|
@@ -95,6 +95,7 @@ const filterInput = <Input v-if={filterable}
|
|
|
95
95
|
readonly={!show}
|
|
96
96
|
waveDisabled={true}
|
|
97
97
|
flat={flat}
|
|
98
|
+
ev-click={$props.onClick}
|
|
98
99
|
/>
|
|
99
100
|
<div class={`${k}-select-placeholder c-ellipsis`}
|
|
100
101
|
v-else-if={!filterable && !hasValue}
|
|
@@ -30,6 +30,17 @@ import {Select, Option} from 'kpc';
|
|
|
30
30
|
<Option value="Sunday">星期天</Option>
|
|
31
31
|
</Select>
|
|
32
32
|
Days: {JSON.stringify(this.get('days'))}
|
|
33
|
+
<br /><br />
|
|
34
|
+
<Select v-model="dayWithKeywords" filterable multiple creatable keepKeywords style="margin-right: 10px">
|
|
35
|
+
<Option value="Monday">星期一</Option>
|
|
36
|
+
<Option value="Tuesday">星期二</Option>
|
|
37
|
+
<Option value="Wednesday">星期三</Option>
|
|
38
|
+
<Option value="Thursday">星期四</Option>
|
|
39
|
+
<Option value="Friday">星期五</Option>
|
|
40
|
+
<Option value="Saturday">星期六</Option>
|
|
41
|
+
<Option value="Sunday">星期天</Option>
|
|
42
|
+
</Select>
|
|
43
|
+
Day with keepKeywords: {JSON.stringify(this.get('dayWithKeywords'))}
|
|
33
44
|
</div>
|
|
34
45
|
```
|
|
35
46
|
|
|
@@ -37,6 +48,7 @@ import {Select, Option} from 'kpc';
|
|
|
37
48
|
interface Props {
|
|
38
49
|
day?: string | null
|
|
39
50
|
days?: string[]
|
|
51
|
+
dayWithKeywords?: string[]
|
|
40
52
|
}
|
|
41
53
|
|
|
42
54
|
export default class extends Component<Props> {
|
|
@@ -45,6 +57,7 @@ export default class extends Component<Props> {
|
|
|
45
57
|
return {
|
|
46
58
|
day: null,
|
|
47
59
|
days: [],
|
|
60
|
+
dayWithKeywords: [],
|
|
48
61
|
} as Props;
|
|
49
62
|
}
|
|
50
63
|
}
|
|
@@ -31,6 +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` | `false` |
|
|
34
35
|
| show | 是否展示菜单项 | `boolean` | `false` |
|
|
35
36
|
| position | 菜单弹出的位置,默认与触发器左侧对齐向下偏移`8px`的地方 | `Position` | `"left"` | `"bottom"` | `"right"` | `"top"` | `{my: 'left top+8', 'left bottom'}` |
|
|
36
37
|
| flat | 是否展示扁平样式 | `boolean` | `false` |
|
|
@@ -238,6 +238,90 @@ describe('Select', () => {
|
|
|
238
238
|
expect(instance.get('day')).to.eql('xxx');
|
|
239
239
|
});
|
|
240
240
|
|
|
241
|
+
it('keepKeywords', async () => {
|
|
242
|
+
// 创建一个测试组件,包含keepKeywords功能
|
|
243
|
+
class KeepKeywordsDemo extends Component<{days: string[]}> {
|
|
244
|
+
static template = `
|
|
245
|
+
const {Select, Option} = this;
|
|
246
|
+
<div>
|
|
247
|
+
<Select v-model="days" filterable multiple creatable keepKeywords>
|
|
248
|
+
<Option value="Monday">星期一</Option>
|
|
249
|
+
<Option value="Tuesday">星期二</Option>
|
|
250
|
+
<Option value="Wednesday">星期三</Option>
|
|
251
|
+
</Select>
|
|
252
|
+
</div>
|
|
253
|
+
`;
|
|
254
|
+
static defaults() {
|
|
255
|
+
return {
|
|
256
|
+
days: [] as string[],
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
private Select = Select as any;
|
|
260
|
+
private Option = Option as any;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const [instance, element] = mount(KeepKeywordsDemo);
|
|
264
|
+
const input = element.querySelector('.k-input-inner') as HTMLInputElement;
|
|
265
|
+
|
|
266
|
+
// 1. 输入自定义选项 "custom1"
|
|
267
|
+
input.click();
|
|
268
|
+
await wait();
|
|
269
|
+
input.value = 'custom1';
|
|
270
|
+
dispatchEvent(input, 'input');
|
|
271
|
+
await wait();
|
|
272
|
+
|
|
273
|
+
// 验证创建的选项出现在dropdown中
|
|
274
|
+
const dropdown = getElement('.k-select-menu')!;
|
|
275
|
+
expect(dropdown.innerHTML).to.contain('custom1');
|
|
276
|
+
|
|
277
|
+
// 2. 按回车创建并选中
|
|
278
|
+
dispatchEvent(document, 'keydown', {keyCode: 13});
|
|
279
|
+
await wait();
|
|
280
|
+
|
|
281
|
+
// 验证选项被选中,且输入框被清空
|
|
282
|
+
expect(instance.get('days')).to.eql(['custom1']);
|
|
283
|
+
expect(input.value).to.eql(''); // keepKeywords=true时应该清空输入框
|
|
284
|
+
|
|
285
|
+
// 3. 再次输入相同的选项 "custom1"
|
|
286
|
+
input.value = 'custom1';
|
|
287
|
+
dispatchEvent(input, 'input');
|
|
288
|
+
await wait();
|
|
289
|
+
|
|
290
|
+
// 4. 再次按回车
|
|
291
|
+
dispatchEvent(document, 'keydown', {keyCode: 13});
|
|
292
|
+
await wait();
|
|
293
|
+
|
|
294
|
+
// 验证选项仍然被选中(不会被取消选中),且输入框被清空
|
|
295
|
+
expect(instance.get('days')).to.eql(['custom1']); // 应该保持选中状态
|
|
296
|
+
expect(input.value).to.eql(''); // 输入框应该被清空
|
|
297
|
+
|
|
298
|
+
// 5. 输入另一个自定义选项 "custom2"
|
|
299
|
+
input.value = 'custom2';
|
|
300
|
+
dispatchEvent(input, 'input');
|
|
301
|
+
await wait();
|
|
302
|
+
dispatchEvent(document, 'keydown', {keyCode: 13});
|
|
303
|
+
await wait();
|
|
304
|
+
|
|
305
|
+
// 验证两个选项都被选中
|
|
306
|
+
expect(instance.get('days')).to.eql(['custom1', 'custom2']);
|
|
307
|
+
expect(input.value).to.eql('');
|
|
308
|
+
|
|
309
|
+
// 6. 测试原有选项的正常行为
|
|
310
|
+
input.click();
|
|
311
|
+
await wait();
|
|
312
|
+
const mondayOption = dropdown.querySelector('[data-value="Monday"]') as HTMLElement;
|
|
313
|
+
if (mondayOption) {
|
|
314
|
+
mondayOption.click();
|
|
315
|
+
await wait();
|
|
316
|
+
expect(instance.get('days')).to.include('Monday');
|
|
317
|
+
|
|
318
|
+
// 再次点击应该能取消选中(原有选项不受keepKeywords影响)
|
|
319
|
+
mondayOption.click();
|
|
320
|
+
await wait();
|
|
321
|
+
expect(instance.get('days')).to.not.include('Monday');
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
|
|
241
325
|
it('Tooltip with Select', async () => {
|
|
242
326
|
class Demo extends Component {
|
|
243
327
|
static template = `
|
|
@@ -298,6 +382,68 @@ describe('Select', () => {
|
|
|
298
382
|
expect(instance.get('days')).include('Monday')
|
|
299
383
|
});
|
|
300
384
|
|
|
385
|
+
it('Searchable with multiple should show correct initial checkbox state', async () => {
|
|
386
|
+
const [instance, element] = mount(SearchableDemo);
|
|
387
|
+
|
|
388
|
+
// 验证初始值
|
|
389
|
+
expect(instance.get('days')).to.eql(['Tuesday']);
|
|
390
|
+
|
|
391
|
+
// 第一次打开dropdown,检查初始状态
|
|
392
|
+
const [, select] = element.querySelectorAll<HTMLElement>('.k-select');
|
|
393
|
+
select.click();
|
|
394
|
+
await wait();
|
|
395
|
+
|
|
396
|
+
const dropdown = getElement('.k-select-menu')!;
|
|
397
|
+
const checkboxes = dropdown.querySelectorAll<HTMLInputElement>('.k-checkbox input[type="checkbox"]');
|
|
398
|
+
const options = dropdown.querySelectorAll<HTMLElement>('.k-select-option');
|
|
399
|
+
|
|
400
|
+
// 找到Tuesday选项对应的checkbox
|
|
401
|
+
let tuesdayCheckbox: HTMLInputElement | null = null;
|
|
402
|
+
let tuesdayOption: HTMLElement | null = null;
|
|
403
|
+
|
|
404
|
+
options.forEach((option, index) => {
|
|
405
|
+
if (option.textContent?.includes('星期二')) {
|
|
406
|
+
tuesdayCheckbox = checkboxes[index];
|
|
407
|
+
tuesdayOption = option;
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
// 验证Tuesday的checkbox应该被选中
|
|
412
|
+
expect(tuesdayCheckbox).to.exist;
|
|
413
|
+
expect(tuesdayCheckbox!.checked).to.be.true;
|
|
414
|
+
|
|
415
|
+
// 验证Tuesday选项应该有active样式
|
|
416
|
+
expect(tuesdayOption).to.exist;
|
|
417
|
+
expect(tuesdayOption!.className).to.include('k-active');
|
|
418
|
+
|
|
419
|
+
// 关闭dropdown
|
|
420
|
+
const [cancel] = dropdown.querySelectorAll<HTMLElement>('.k-select-footer .k-btn');
|
|
421
|
+
cancel.click();
|
|
422
|
+
await wait();
|
|
423
|
+
|
|
424
|
+
// 再次打开dropdown,验证状态仍然正确
|
|
425
|
+
select.click();
|
|
426
|
+
await wait();
|
|
427
|
+
|
|
428
|
+
const dropdown2 = getElement('.k-select-menu')!;
|
|
429
|
+
const checkboxes2 = dropdown2.querySelectorAll<HTMLInputElement>('.k-checkbox input[type="checkbox"]');
|
|
430
|
+
const options2 = dropdown2.querySelectorAll<HTMLElement>('.k-select-option');
|
|
431
|
+
|
|
432
|
+
let tuesdayCheckbox2: HTMLInputElement | null = null;
|
|
433
|
+
let tuesdayOption2: HTMLElement | null = null;
|
|
434
|
+
|
|
435
|
+
options2.forEach((option, index) => {
|
|
436
|
+
if (option.textContent?.includes('星期二')) {
|
|
437
|
+
tuesdayCheckbox2 = checkboxes2[index];
|
|
438
|
+
tuesdayOption2 = option;
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
// 验证第二次打开时状态依然正确
|
|
443
|
+
expect(tuesdayCheckbox2!.checked).to.be.true;
|
|
444
|
+
expect(tuesdayOption2!.className).to.include('k-active');
|
|
445
|
+
});
|
|
446
|
+
|
|
301
447
|
it('disabled option does not allow clearable and close', async () => {
|
|
302
448
|
const [instance, element] = mount(ImmutableDemo);
|
|
303
449
|
|
|
@@ -9,6 +9,7 @@ export interface OptionProps {
|
|
|
9
9
|
value: any
|
|
10
10
|
label?: string
|
|
11
11
|
disabled?: boolean
|
|
12
|
+
isCreated?: boolean
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
const typeDefs: Required<TypeDefs<OptionProps>> = {
|
|
@@ -17,6 +18,7 @@ const typeDefs: Required<TypeDefs<OptionProps>> = {
|
|
|
17
18
|
},
|
|
18
19
|
label: String,
|
|
19
20
|
disabled: Boolean,
|
|
21
|
+
isCreated: Boolean,
|
|
20
22
|
};
|
|
21
23
|
|
|
22
24
|
export class Option extends Component<OptionProps> {
|
|
@@ -29,13 +31,19 @@ export class Option extends Component<OptionProps> {
|
|
|
29
31
|
@bind
|
|
30
32
|
private onSelect() {
|
|
31
33
|
const select = this.select!;
|
|
32
|
-
const multiple = select.get(
|
|
34
|
+
const {multiple, keepKeywords} = select.get();
|
|
33
35
|
const value = this.get('value');
|
|
36
|
+
const isCreated = this.get('isCreated');
|
|
34
37
|
|
|
35
38
|
if (!multiple) {
|
|
36
39
|
select.set('value', this.get('value'));
|
|
37
40
|
} else {
|
|
38
41
|
let values = select.get('value');
|
|
42
|
+
|
|
43
|
+
if (keepKeywords && isCreated && Array.isArray(values) && values.includes(value)) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
39
47
|
values = toggleArray(values, value);
|
|
40
48
|
select.set('value', values);
|
|
41
49
|
}
|
|
@@ -21,6 +21,7 @@ export interface SelectProps<T = string, Multipe extends boolean = boolean> exte
|
|
|
21
21
|
labelMap?: Map<any, Children>
|
|
22
22
|
card?: boolean
|
|
23
23
|
autoDisableArrow?: boolean
|
|
24
|
+
keepKeywords?: boolean
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
export interface SelectEvents extends BaseSelectEvents { }
|
|
@@ -37,6 +38,7 @@ const typeDefs: Required<TypeDefs<SelectProps>> = {
|
|
|
37
38
|
labelMap: Map,
|
|
38
39
|
card: Boolean,
|
|
39
40
|
autoDisableArrow: Boolean,
|
|
41
|
+
keepKeywords: Boolean,
|
|
40
42
|
};
|
|
41
43
|
|
|
42
44
|
const defaults = (): Partial<SelectProps> => ({
|
|
@@ -56,14 +56,16 @@ export function useInput(resetKeywords: (keywords: State<string>) => void) {
|
|
|
56
56
|
}
|
|
57
57
|
});
|
|
58
58
|
component.on('$changed:value', () => {
|
|
59
|
-
const {multiple, filterable} = component.get();
|
|
59
|
+
const {multiple, filterable, keepKeywords} = component.get();
|
|
60
60
|
if (multiple && filterable) {
|
|
61
61
|
focusInput();
|
|
62
62
|
/**
|
|
63
63
|
* don't reset keywords on multiple mode for continue selection
|
|
64
64
|
* https://github.com/ksc-fe/kpc/issues/983
|
|
65
65
|
*/
|
|
66
|
-
|
|
66
|
+
if (keepKeywords) {
|
|
67
|
+
resetKeywords(keywords);
|
|
68
|
+
}
|
|
67
69
|
}
|
|
68
70
|
});
|
|
69
71
|
|
|
@@ -47,8 +47,8 @@ export function useSearchable() {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
select.watch('value', initCheckedKeys);
|
|
50
|
-
select.on('hide', initCheckedKeys)
|
|
51
|
-
|
|
50
|
+
select.on('hide', initCheckedKeys);
|
|
51
|
+
initCheckedKeys();
|
|
52
52
|
return {checkedKeys, selectAll, unselectAll, toggleSelect, confirm};
|
|
53
53
|
}
|
|
54
54
|
|
|
@@ -6,7 +6,7 @@ order: 2
|
|
|
6
6
|
当指定了`step`属性时,组件将展示成`Select`样式,只能选择固定的几个时间点。通过`min`和`max`限定
|
|
7
7
|
选择时间范围(默认:00:00:00 ~ 23:59:59),`step`指定步长,它们值类型都为时间字符串
|
|
8
8
|
|
|
9
|
-
> 可以通过`
|
|
9
|
+
> 可以通过`showFormat`或`format`来格式化时间字符串,来隐藏“秒”
|
|
10
10
|
|
|
11
11
|
```vdt
|
|
12
12
|
import {Timepicker} from 'kpc';
|
|
@@ -8,13 +8,14 @@ import {PanelFlags} from '../datepicker/usePanel';
|
|
|
8
8
|
import {last} from '../datepicker/helpers';
|
|
9
9
|
import {ScrollSelect} from '../scrollSelect';
|
|
10
10
|
|
|
11
|
-
const {className, range, multiple} = this.get();
|
|
11
|
+
const {className, range, multiple, min, max} = this.get();
|
|
12
12
|
const {
|
|
13
13
|
value: {value},
|
|
14
14
|
onConfirm,
|
|
15
15
|
onChangeTime,
|
|
16
16
|
onChangeTimeByStep,
|
|
17
17
|
getTimeValue,
|
|
18
|
+
setMoment,
|
|
18
19
|
} = this.value;
|
|
19
20
|
const lastValue = last(value);
|
|
20
21
|
const { k } = this.config;
|
|
@@ -65,6 +66,9 @@ const generatePanel = flag => {
|
|
|
65
66
|
{range ? generatePanel(PanelFlags.End) : null}
|
|
66
67
|
</div>
|
|
67
68
|
<div class={`${k}-datepicker-footer`}>
|
|
69
|
+
<Button v-if={!range && !multiple && !max && !min} type="link" size="small"
|
|
70
|
+
ev-click={setMoment}
|
|
71
|
+
>{_$('此刻')}</Button>
|
|
68
72
|
<Button type="primary" size="small"
|
|
69
73
|
disabled={isDisabledConfirm()}
|
|
70
74
|
ev-click={onConfirm}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 基础用法
|
|
3
|
+
order: 0
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
```vdt
|
|
7
|
+
import {Tour, Button} from 'kpc';
|
|
8
|
+
|
|
9
|
+
<div>
|
|
10
|
+
<div class="example-container">
|
|
11
|
+
<Button id="btn1">示例元素1</Button>
|
|
12
|
+
<Button id="btn2" style="margin-left: 20px;">示例元素2</Button>
|
|
13
|
+
</div>
|
|
14
|
+
<Tour
|
|
15
|
+
v-model="currentStep"
|
|
16
|
+
visible={this.get('showTour')}
|
|
17
|
+
data={this.get('tourData')}
|
|
18
|
+
ev-finish={this.close}
|
|
19
|
+
/>
|
|
20
|
+
<div style="margin-top: 20px;">
|
|
21
|
+
<Button ev-click={this.settour}>
|
|
22
|
+
启动引导
|
|
23
|
+
</Button>
|
|
24
|
+
<span style="margin-left: 10px;">
|
|
25
|
+
当前步骤: {this.get('currentStep') >= 0 ? this.get('currentStep') + 1 : '未启动'}
|
|
26
|
+
</span>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import {bind} from 'kpc';
|
|
33
|
+
import {TourStepProps} from 'kpc';
|
|
34
|
+
|
|
35
|
+
export default class extends Component {
|
|
36
|
+
static template = template;
|
|
37
|
+
static defaults() {
|
|
38
|
+
return {
|
|
39
|
+
currentStep: 0 as number,
|
|
40
|
+
showTour: false, // 默认不显示
|
|
41
|
+
tourData: [
|
|
42
|
+
{
|
|
43
|
+
target: '#btn1',
|
|
44
|
+
title: '第一步',
|
|
45
|
+
content: '这是第一步的引导说明',
|
|
46
|
+
position: 'bottom'
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
target: '#btn2',
|
|
50
|
+
title: '第二步',
|
|
51
|
+
content: '这是第二步的引导说明',
|
|
52
|
+
position: 'right'
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@bind
|
|
59
|
+
settour() {
|
|
60
|
+
this.set({
|
|
61
|
+
showTour: true,
|
|
62
|
+
currentStep: 0
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@bind
|
|
67
|
+
close() {
|
|
68
|
+
this.set({
|
|
69
|
+
showTour: false
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 步骤控制
|
|
3
|
+
order: 3
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
```vdt
|
|
7
|
+
import {Tour, Button, Input} from 'kpc';
|
|
8
|
+
|
|
9
|
+
<div>
|
|
10
|
+
<div class="example-container">
|
|
11
|
+
<Button id="step1">步骤1</Button>
|
|
12
|
+
<Button id="step2" style="margin-left: 20px;">步骤2</Button>
|
|
13
|
+
<div style="margin-top: 20px;">
|
|
14
|
+
<Input class="step3-input" placeholder="通过验证才能进入下一步" v-model="inputValue" />
|
|
15
|
+
</div>
|
|
16
|
+
<Button id="step4" style="margin-top: 20px;">步骤4</Button>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<Tour
|
|
20
|
+
v-model="currentStep"
|
|
21
|
+
visible={this.get('showTour')}
|
|
22
|
+
data={this.get('tourData')}
|
|
23
|
+
beforeChange={this.handleBeforeChange}
|
|
24
|
+
ev-finish={this.finishTour}
|
|
25
|
+
/>
|
|
26
|
+
|
|
27
|
+
<div style="margin-top: 20px;">
|
|
28
|
+
<Button ev-click={this.startTour}>
|
|
29
|
+
启动引导
|
|
30
|
+
</Button>
|
|
31
|
+
<span style="margin-left: 10px;">
|
|
32
|
+
当前步骤: {this.get('currentStep') >= 0 ? this.get('currentStep') + 1 : '未启动'}
|
|
33
|
+
</span>
|
|
34
|
+
<div style="margin-top: 10px; color: #f56c6c" v-if={this.get('errorMsg')}>
|
|
35
|
+
{this.get('errorMsg')}
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import {bind, Message} from 'kpc';
|
|
43
|
+
|
|
44
|
+
export default class extends Component {
|
|
45
|
+
static template = template;
|
|
46
|
+
static defaults() {
|
|
47
|
+
return {
|
|
48
|
+
currentStep: 0,
|
|
49
|
+
showTour: false,
|
|
50
|
+
inputValue: '',
|
|
51
|
+
errorMsg: '',
|
|
52
|
+
tourData: [
|
|
53
|
+
{
|
|
54
|
+
target: '#step1',
|
|
55
|
+
title: '第一步',
|
|
56
|
+
content: '这是第一步的引导说明',
|
|
57
|
+
position: 'bottom'
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
target: '#step2',
|
|
61
|
+
title: '第二步',
|
|
62
|
+
content: '这是第二步的引导说明',
|
|
63
|
+
position: 'right'
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
target: '.step3-input',
|
|
67
|
+
title: '第三步',
|
|
68
|
+
content: '请在输入框中输入"next"以继续',
|
|
69
|
+
position: 'bottom'
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
target: '#step4',
|
|
73
|
+
title: '最后一步',
|
|
74
|
+
content: '恭喜您完成了所有步骤',
|
|
75
|
+
position: 'top'
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@bind
|
|
82
|
+
startTour() {
|
|
83
|
+
this.set({
|
|
84
|
+
showTour: true,
|
|
85
|
+
currentStep: 0,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@bind
|
|
90
|
+
finishTour() {
|
|
91
|
+
this.set({
|
|
92
|
+
showTour: false
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@bind
|
|
98
|
+
handleBeforeChange(current: number) {
|
|
99
|
+
const inputValue = this.get('inputValue') as string;
|
|
100
|
+
if (current === 3) {
|
|
101
|
+
if (inputValue !== 'next') {
|
|
102
|
+
Message.error('请在输入框中输入"next"才能进入下一步');
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 禁用关闭图标
|
|
3
|
+
order: 7
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
```vdt
|
|
7
|
+
import {Tour, Button, Switch} from 'kpc';
|
|
8
|
+
|
|
9
|
+
<div>
|
|
10
|
+
<div class="example-container">
|
|
11
|
+
<Button id="closabelDemo">目标元素1</Button>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<Tour
|
|
15
|
+
v-model="currentStep"
|
|
16
|
+
visible={this.get('showTour')}
|
|
17
|
+
data={this.get('tourData')}
|
|
18
|
+
closable={this.get('closable')}
|
|
19
|
+
ev-finish={this.finishTour}
|
|
20
|
+
/>
|
|
21
|
+
|
|
22
|
+
<div style="margin-top: 20px;">
|
|
23
|
+
<div style="margin-bottom: 10px;">
|
|
24
|
+
<Switch v-model="closable" />
|
|
25
|
+
<span style="margin-left: 10px;">关闭图标: {this.get('closable') ? '启用' : '禁用'}</span>
|
|
26
|
+
</div>
|
|
27
|
+
<Button ev-click={this.startTour}>
|
|
28
|
+
启动引导
|
|
29
|
+
</Button>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import {bind} from 'kpc';
|
|
36
|
+
|
|
37
|
+
export default class extends Component {
|
|
38
|
+
static template = template;
|
|
39
|
+
static defaults() {
|
|
40
|
+
return {
|
|
41
|
+
currentStep: 0,
|
|
42
|
+
showTour: false,
|
|
43
|
+
closable: false,
|
|
44
|
+
tourData: [
|
|
45
|
+
{
|
|
46
|
+
target: '#closabelDemo',
|
|
47
|
+
title: '禁用关闭图标',
|
|
48
|
+
content: '当closable为true时,header区域关闭图标隐藏',
|
|
49
|
+
position: 'right'
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@bind
|
|
56
|
+
startTour() {
|
|
57
|
+
this.set({
|
|
58
|
+
showTour: true,
|
|
59
|
+
currentStep: 0
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@bind
|
|
64
|
+
finishTour() {
|
|
65
|
+
this.set({
|
|
66
|
+
showTour: false
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|