@king-design/intact 2.0.17-beta.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/cascader/index.md +18 -0
- package/components/cascader/index.spec.ts +56 -0
- package/components/cascader/index.ts +35 -12
- package/components/cascader/index.vdt +9 -8
- package/components/cascader/useFields.ts +22 -0
- package/components/cascader/useFilterable.ts +23 -8
- package/components/cascader/useLabel.ts +7 -4
- package/components/cascader/useLoad.ts +4 -2
- package/components/code/demos/basic.md +1 -1
- package/components/colorpicker/index.md +16 -0
- package/components/colorpicker/index.ts +4 -0
- package/components/colorpicker/index.vdt +3 -2
- package/components/datepicker/index.md +11 -0
- package/components/dialog/index.spec.ts +2 -2
- package/components/dropdown/dropdown.ts +34 -71
- package/components/dropdown/index.spec.ts +53 -4
- package/components/dropdown/item.ts +18 -7
- package/components/dropdown/menu.ts +3 -3
- package/components/dropdown/usePosition.ts +12 -1
- package/components/editable/index.ts +17 -3
- package/components/editable/index.vdt +1 -0
- package/components/input/demos/autoRows.md +44 -0
- package/components/input/demos/password.md +12 -0
- package/components/input/demos/textarea.md +2 -2
- package/components/input/index.md +1 -0
- package/components/input/index.spec.ts +97 -1
- package/components/input/index.ts +17 -3
- package/components/input/index.vdt +29 -6
- package/components/input/styles.ts +18 -1
- package/components/input/useAutoRows.ts +65 -0
- package/components/input/useAutoWidth.ts +12 -3
- package/components/input/useShowPassword.ts +27 -0
- package/components/menu/demos/collapse.md +1 -1
- package/components/menu/index.spec.ts +9 -1
- package/components/menu/item.ts +7 -0
- package/components/pagination/index.spec.ts +24 -1
- package/components/pagination/index.ts +2 -1
- package/components/portal.ts +4 -4
- package/components/position.ts +5 -1
- package/components/select/base.ts +3 -1
- package/components/select/base.vdt +2 -0
- package/components/select/index.md +11 -1
- package/components/table/cell.ts +4 -5
- package/components/table/demos/hideHeader.md +33 -0
- package/components/table/demos/pagination.md +53 -0
- package/components/table/index.md +22 -0
- package/components/table/index.spec.ts +73 -1
- package/components/table/row.ts +3 -3
- package/components/table/styles.ts +5 -0
- package/components/table/table.ts +29 -4
- package/components/table/table.vdt +21 -3
- package/components/table/useChecked.ts +21 -6
- package/components/table/useDisableRow.ts +3 -2
- package/components/table/useDraggable.ts +11 -8
- package/components/table/useGroup.ts +2 -0
- package/components/table/useMerge.ts +6 -3
- package/components/table/usePagination.ts +71 -0
- package/components/table/useRestRowStatus.ts +4 -1
- package/components/table/useTree.ts +4 -3
- package/components/timepicker/index.md +11 -0
- package/components/tooltip/content.ts +15 -1
- package/components/tooltip/content.vdt +6 -1
- package/components/tooltip/demos/trigger.md +1 -1
- package/components/tooltip/index.md +1 -1
- package/components/tooltip/index.spec.ts +65 -6
- package/components/tooltip/styles.ts +1 -1
- package/components/tooltip/tooltip.ts +8 -0
- package/components/treeSelect/index.md +9 -0
- package/components/virtual.ts +98 -0
- package/es/components/cascader/index.d.ts +22 -11
- package/es/components/cascader/index.js +9 -12
- package/es/components/cascader/index.spec.js +81 -0
- package/es/components/cascader/index.vdt.js +10 -8
- package/es/components/cascader/useFields.d.ts +2 -0
- package/es/components/cascader/useFields.js +18 -0
- package/es/components/cascader/useFilterable.d.ts +2 -1
- package/es/components/cascader/useFilterable.js +17 -6
- package/es/components/cascader/useLabel.d.ts +2 -1
- package/es/components/cascader/useLabel.js +4 -4
- package/es/components/cascader/useLoad.d.ts +2 -1
- package/es/components/cascader/useLoad.js +9 -7
- package/es/components/colorpicker/index.d.ts +2 -0
- package/es/components/colorpicker/index.js +7 -2
- package/es/components/colorpicker/index.vdt.js +3 -6
- package/es/components/dialog/index.spec.js +2 -2
- package/es/components/dropdown/dropdown.d.ts +6 -5
- package/es/components/dropdown/dropdown.js +40 -69
- package/es/components/dropdown/index.spec.js +96 -17
- package/es/components/dropdown/item.d.ts +1 -1
- package/es/components/dropdown/item.js +19 -7
- package/es/components/dropdown/usePosition.js +11 -2
- package/es/components/editable/index.d.ts +1 -0
- package/es/components/editable/index.js +20 -6
- package/es/components/editable/index.vdt.js +2 -1
- package/es/components/input/index.d.ts +10 -2
- package/es/components/input/index.js +10 -3
- package/es/components/input/index.spec.js +169 -1
- package/es/components/input/index.vdt.js +26 -7
- package/es/components/input/styles.js +8 -3
- package/es/components/input/useAutoRows.d.ts +2 -0
- package/es/components/input/useAutoRows.js +79 -0
- package/es/components/input/useAutoWidth.js +13 -3
- package/es/components/input/useShowPassword.d.ts +7 -0
- package/es/components/input/useShowPassword.js +31 -0
- package/es/components/menu/index.spec.js +26 -15
- package/es/components/menu/item.d.ts +2 -0
- package/es/components/menu/item.js +5 -0
- package/es/components/pagination/index.js +2 -1
- package/es/components/pagination/index.spec.js +51 -4
- package/es/components/portal.d.ts +6 -2
- package/es/components/portal.js +4 -3
- package/es/components/position.js +2 -1
- package/es/components/select/base.d.ts +2 -1
- package/es/components/select/base.js +3 -1
- package/es/components/select/base.vdt.js +3 -1
- package/es/components/table/cell.js +1 -6
- package/es/components/table/index.spec.js +130 -19
- package/es/components/table/row.d.ts +1 -1
- package/es/components/table/row.js +2 -1
- package/es/components/table/styles.js +1 -1
- package/es/components/table/table.d.ts +15 -0
- package/es/components/table/table.js +16 -7
- package/es/components/table/table.vdt.js +20 -6
- package/es/components/table/useChecked.d.ts +3 -2
- package/es/components/table/useChecked.js +23 -12
- package/es/components/table/useDisableRow.d.ts +2 -1
- package/es/components/table/useDisableRow.js +4 -4
- package/es/components/table/useDraggable.d.ts +3 -2
- package/es/components/table/useDraggable.js +11 -8
- package/es/components/table/useGroup.js +3 -0
- package/es/components/table/useMerge.d.ts +2 -1
- package/es/components/table/useMerge.js +5 -4
- package/es/components/table/usePagination.d.ts +8 -0
- package/es/components/table/usePagination.js +81 -0
- package/es/components/table/useTree.d.ts +2 -1
- package/es/components/table/useTree.js +3 -4
- package/es/components/tooltip/content.d.ts +1 -0
- package/es/components/tooltip/content.js +18 -1
- package/es/components/tooltip/content.vdt.js +3 -1
- package/es/components/tooltip/index.spec.js +117 -10
- package/es/components/tooltip/styles.d.ts +22 -0
- package/es/components/tooltip/styles.js +1 -1
- package/es/components/tooltip/tooltip.d.ts +1 -0
- package/es/components/tooltip/tooltip.js +11 -0
- package/es/components/virtual.d.ts +8 -0
- package/es/components/virtual.js +126 -0
- package/es/index.d.ts +3 -3
- package/es/index.js +3 -3
- package/es/packages/kpc-react/__tests__/components/cascader.spec.d.ts +1 -0
- package/es/packages/kpc-react/__tests__/components/cascader.spec.js +79 -0
- package/es/site/data/components/input/demos/autoRows/index.d.ts +9 -0
- package/es/site/data/components/input/demos/autoRows/index.js +24 -0
- package/es/site/data/components/input/demos/autoRows/react.d.ts +8 -0
- package/es/site/data/components/input/demos/autoRows/react.js +62 -0
- package/es/site/data/components/input/demos/password/index.d.ts +5 -0
- package/es/site/data/components/input/demos/password/index.js +17 -0
- package/es/site/data/components/input/demos/password/react.d.ts +5 -0
- package/es/site/data/components/input/demos/password/react.js +41 -0
- package/es/site/data/components/input/demos/textarea/react.js +4 -2
- package/es/site/data/components/menu/demos/collapse/index.js +1 -1
- package/es/site/data/components/menu/demos/collapse/react.js +1 -1
- package/es/site/data/components/table/demos/hideHeader/index.d.ts +12 -0
- package/es/site/data/components/table/demos/hideHeader/index.js +30 -0
- package/es/site/data/components/table/demos/hideHeader/react.d.ts +11 -0
- package/es/site/data/components/table/demos/hideHeader/react.js +60 -0
- package/es/site/data/components/table/demos/pagination/index.d.ts +12 -0
- package/es/site/data/components/table/demos/pagination/index.js +35 -0
- package/es/site/data/components/table/demos/pagination/react.d.ts +16 -0
- package/es/site/data/components/table/demos/pagination/react.js +65 -0
- package/es/styles/fonts/ionicons.js +1 -1
- package/index.ts +3 -3
- package/package.json +5 -4
- package/styles/fonts/ionicons.ts +0 -1
|
@@ -6,9 +6,11 @@ import {isNullOrUndefined, EMPTY_OBJ} from 'intact-shared';
|
|
|
6
6
|
import {useAutoWidth} from './useAutoWidth';
|
|
7
7
|
import {useFrozen} from './useFrozen';
|
|
8
8
|
import {CommonInputHTMLAttributes, Events} from '../types';
|
|
9
|
+
import {useAutoRows} from './useAutoRows';
|
|
10
|
+
import { useShowPassword } from './useShowPassword';
|
|
9
11
|
export * from './search';
|
|
10
12
|
|
|
11
|
-
type HTMLInputTypes =
|
|
13
|
+
export type HTMLInputTypes =
|
|
12
14
|
| 'textarea' // for textarea
|
|
13
15
|
| 'button'
|
|
14
16
|
| 'checkbox'
|
|
@@ -56,7 +58,7 @@ export interface InputProps<V extends Value = Value> extends InputHTMLAttributes
|
|
|
56
58
|
clearable?: boolean
|
|
57
59
|
disabled?: boolean
|
|
58
60
|
size?: Sizes
|
|
59
|
-
rows?: string | number
|
|
61
|
+
rows?: string | number | 'auto' | AutoRows
|
|
60
62
|
autoWidth?: boolean
|
|
61
63
|
fluid?: boolean
|
|
62
64
|
width?: number | string
|
|
@@ -64,8 +66,15 @@ export interface InputProps<V extends Value = Value> extends InputHTMLAttributes
|
|
|
64
66
|
frozenOnInput?: boolean
|
|
65
67
|
inline?: boolean
|
|
66
68
|
waveDisabled?: boolean
|
|
69
|
+
resize?: 'none' | 'vertical' | 'horizontal' | 'both'
|
|
70
|
+
showPassword?: boolean
|
|
67
71
|
}
|
|
68
72
|
|
|
73
|
+
export type AutoRows = {
|
|
74
|
+
min?: number
|
|
75
|
+
max?: number
|
|
76
|
+
}
|
|
77
|
+
|
|
69
78
|
export interface InputEvents {
|
|
70
79
|
clear: [MouseEvent]
|
|
71
80
|
focus: [FocusEvent]
|
|
@@ -89,7 +98,7 @@ const typeDefs: Required<TypeDefs<Omit<InputProps, keyof InputHTMLAttributes>>>
|
|
|
89
98
|
clearable: Boolean,
|
|
90
99
|
disabled: Boolean,
|
|
91
100
|
size: sizes,
|
|
92
|
-
rows: [String, Number],
|
|
101
|
+
rows: [String, Number, 'auto', Object],
|
|
93
102
|
autoWidth: Boolean,
|
|
94
103
|
fluid: Boolean,
|
|
95
104
|
width: [Number, String],
|
|
@@ -97,12 +106,15 @@ const typeDefs: Required<TypeDefs<Omit<InputProps, keyof InputHTMLAttributes>>>
|
|
|
97
106
|
frozenOnInput: Boolean,
|
|
98
107
|
inline: Boolean,
|
|
99
108
|
waveDisabled: Boolean,
|
|
109
|
+
resize: ['none', 'vertical', 'horizontal', 'both'],
|
|
110
|
+
showPassword: Boolean,
|
|
100
111
|
}
|
|
101
112
|
|
|
102
113
|
const defaults = (): Partial<InputProps> => ({
|
|
103
114
|
type: 'text', // text | textarea
|
|
104
115
|
size: 'default',
|
|
105
116
|
rows: 2,
|
|
117
|
+
resize: 'vertical',
|
|
106
118
|
});
|
|
107
119
|
|
|
108
120
|
const events: Events<InputEvents> = {
|
|
@@ -121,6 +133,8 @@ export class Input<V extends Value = Value> extends Component<InputProps<V>, Inp
|
|
|
121
133
|
private inputRef = createRef<HTMLInputElement>();
|
|
122
134
|
private autoWidth = useAutoWidth();
|
|
123
135
|
private frozen = useFrozen();
|
|
136
|
+
private autoRows = useAutoRows(this.inputRef);
|
|
137
|
+
private showPassword = useShowPassword();
|
|
124
138
|
|
|
125
139
|
focus() {
|
|
126
140
|
this.inputRef.value!.focus();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {Icon} from '../icon';
|
|
2
2
|
import {addStyle, isTextBlock, getRestProps} from '../utils';
|
|
3
3
|
import {makeStyles} from './styles';
|
|
4
|
-
import {noop, isNullOrUndefined} from 'intact-shared';
|
|
4
|
+
import {noop, isNullOrUndefined, isStringOrNumber} from 'intact-shared';
|
|
5
5
|
import {Wave} from '../wave';
|
|
6
6
|
import {context as ErrorContext} from '../form/useError';
|
|
7
7
|
|
|
@@ -9,7 +9,7 @@ const {
|
|
|
9
9
|
className, style, type, value, defaultValue, placeholder,
|
|
10
10
|
clearable, disabled, size, rows, autoWidth, fluid,
|
|
11
11
|
width, stackClearIcon, frozenOnInput, readonly, inline,
|
|
12
|
-
waveDisabled,
|
|
12
|
+
waveDisabled, resize,
|
|
13
13
|
|
|
14
14
|
'ev-click': click,
|
|
15
15
|
'ev-mounseenter': mouseenter,
|
|
@@ -24,6 +24,8 @@ const {
|
|
|
24
24
|
startInput, onInput, endInput
|
|
25
25
|
} = this.frozen;
|
|
26
26
|
|
|
27
|
+
const isNotAutoRows = isStringOrNumber(rows) && rows !== 'auto';
|
|
28
|
+
|
|
27
29
|
const classNameObj = {
|
|
28
30
|
'k-input': true,
|
|
29
31
|
[`k-${size}`]: size !== 'default',
|
|
@@ -36,11 +38,21 @@ const classNameObj = {
|
|
|
36
38
|
'k-fluid': fluid,
|
|
37
39
|
'k-stack-clear': stackClearIcon,
|
|
38
40
|
'k-inline': inline,
|
|
41
|
+
[`k-resize-${resize}`]: type === 'textarea' && isNotAutoRows,
|
|
42
|
+
[`k-resize-none`]: type === 'textarea' && !isNotAutoRows,
|
|
39
43
|
[className]: className,
|
|
40
44
|
[makeStyles()]: true,
|
|
41
45
|
}
|
|
42
46
|
|
|
47
|
+
const {
|
|
48
|
+
isShow: isShowPassword,
|
|
49
|
+
toggleShow: toggleShowPassword,
|
|
50
|
+
type: showPasswordType,
|
|
51
|
+
showIcon: showPasswordIcon,
|
|
52
|
+
} = this.showPassword;
|
|
53
|
+
|
|
43
54
|
const {fakeRef, width: {value: fakeWidth}} = this.autoWidth;
|
|
55
|
+
const height = this.autoRows;
|
|
44
56
|
|
|
45
57
|
const inputValue = frozenOnInput && inputing ? originalValue : value;
|
|
46
58
|
const hasInputValue = !isNullOrUndefined(inputValue);
|
|
@@ -55,7 +67,7 @@ const inputProps = {
|
|
|
55
67
|
placeholder,
|
|
56
68
|
disabled,
|
|
57
69
|
ref: this.inputRef,
|
|
58
|
-
style: autoWidth ? {width: fakeWidth + 'px'} : undefined,
|
|
70
|
+
style: autoWidth && fakeWidth ? {width: fakeWidth + 'px'} : undefined,
|
|
59
71
|
};
|
|
60
72
|
// if we pass value to input element, the input is controlled and the
|
|
61
73
|
// defaultValue does not work
|
|
@@ -90,14 +102,25 @@ if (hasInputValue) {
|
|
|
90
102
|
<input v-if={type !== 'textarea'}
|
|
91
103
|
{...inputProps}
|
|
92
104
|
class="k-input-inner"
|
|
93
|
-
type={
|
|
105
|
+
type={showPasswordType.value}
|
|
94
106
|
/>
|
|
95
107
|
<textarea v-else
|
|
96
108
|
{...inputProps}
|
|
97
109
|
class="k-input-inner k-textarea"
|
|
98
|
-
rows={rows}
|
|
110
|
+
rows={isNotAutoRows ? rows : 1}
|
|
111
|
+
style={height.value ? addStyle(inputProps.style, { height: height.value + 'px' }) : inputProps.style}
|
|
99
112
|
></textarea>
|
|
100
|
-
<div class="k-input-suffix" v-if={$blocks.suffix || clearable && !disabled}>
|
|
113
|
+
<div class="k-input-suffix" v-if={$blocks.suffix || clearable && !disabled || showPasswordIcon.value}>
|
|
114
|
+
<template v-if={showPasswordIcon.value}>
|
|
115
|
+
<Icon hoverable
|
|
116
|
+
class={{
|
|
117
|
+
"k-input-show-password": true,
|
|
118
|
+
"ion-eye-disabled": !isShowPassword.value,
|
|
119
|
+
"ion-eye": isShowPassword.value,
|
|
120
|
+
}}
|
|
121
|
+
ev-click={toggleShowPassword}
|
|
122
|
+
/>{' '}
|
|
123
|
+
</template>
|
|
101
124
|
<Icon v-if={clearable && !disabled}
|
|
102
125
|
class={{
|
|
103
126
|
"k-input-clear ion-ios-close": true,
|
|
@@ -2,6 +2,7 @@ import {css} from '@emotion/css';
|
|
|
2
2
|
import {theme, setDefault} from '../../styles/theme';
|
|
3
3
|
import {deepDefaults, sizes, Sizes} from '../../styles/utils';
|
|
4
4
|
import '../../styles/global';
|
|
5
|
+
import {Input} from './';
|
|
5
6
|
|
|
6
7
|
const defaults = deepDefaults(
|
|
7
8
|
{
|
|
@@ -24,7 +25,7 @@ const defaults = deepDefaults(
|
|
|
24
25
|
clearIconGap: '3px',
|
|
25
26
|
|
|
26
27
|
// textarea
|
|
27
|
-
get textareaPadding() { return `
|
|
28
|
+
get textareaPadding() { return `6px ${input.paddingGap}` },
|
|
28
29
|
|
|
29
30
|
// group
|
|
30
31
|
get groupBgColor() { return theme.color.bg },
|
|
@@ -129,6 +130,11 @@ export function makeStyles() {
|
|
|
129
130
|
pointer-events: all;
|
|
130
131
|
}
|
|
131
132
|
|
|
133
|
+
// show password
|
|
134
|
+
.k-input-show-password {
|
|
135
|
+
color: ${input.clearIconColor};
|
|
136
|
+
}
|
|
137
|
+
|
|
132
138
|
// stack clear icon
|
|
133
139
|
&.k-stack-clear {
|
|
134
140
|
.k-input-clear {
|
|
@@ -282,6 +288,15 @@ export function makeStyles() {
|
|
|
282
288
|
line-height: 1.5;
|
|
283
289
|
vertical-align: top;
|
|
284
290
|
}
|
|
291
|
+
${(Input.typeDefs.resize as string[]).map(type => {
|
|
292
|
+
return css`
|
|
293
|
+
&.k-resize-${type} {
|
|
294
|
+
.k-textarea {
|
|
295
|
+
resize: ${type};
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
`
|
|
299
|
+
})}
|
|
285
300
|
|
|
286
301
|
// fake dom for get value's width
|
|
287
302
|
.k-input-fake {
|
|
@@ -292,7 +307,9 @@ export function makeStyles() {
|
|
|
292
307
|
}
|
|
293
308
|
&.k-auto-width {
|
|
294
309
|
width: auto;
|
|
310
|
+
max-width: 100%;
|
|
295
311
|
.k-input-inner {
|
|
312
|
+
max-width: 100%;
|
|
296
313
|
box-sizing: content-box;
|
|
297
314
|
}
|
|
298
315
|
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {useInstance, createRef, onMounted, RefObject, watch} from 'intact';
|
|
2
|
+
import type {Input} from './';
|
|
3
|
+
import {useState} from '../../hooks/useState';
|
|
4
|
+
import { isObject } from 'intact-shared';
|
|
5
|
+
|
|
6
|
+
export function useAutoRows(inputRef: RefObject<HTMLInputElement>) {
|
|
7
|
+
const instance = useInstance() as Input;
|
|
8
|
+
const height = useState<number>(0);
|
|
9
|
+
|
|
10
|
+
let lineHeight: number;
|
|
11
|
+
let paddingTop: number;
|
|
12
|
+
let paddingBottom: number;
|
|
13
|
+
let isBorderBox: boolean;
|
|
14
|
+
|
|
15
|
+
function getStyles() {
|
|
16
|
+
if (instance.get('type') === 'textarea') {
|
|
17
|
+
const styles = getComputedStyle(inputRef.value!);
|
|
18
|
+
|
|
19
|
+
lineHeight = parseInt(styles.lineHeight);
|
|
20
|
+
paddingTop = parseInt(styles.paddingTop);
|
|
21
|
+
paddingBottom = parseInt(styles.paddingBottom);
|
|
22
|
+
isBorderBox = styles.boxSizing === 'border-box';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
onMounted(getStyles);
|
|
27
|
+
instance.watch('type', getStyles, { presented: true });
|
|
28
|
+
|
|
29
|
+
instance.watch('value', adjust, {inited: true, presented: true});
|
|
30
|
+
instance.watch('placeholder', adjust, {inited: true, presented: true});
|
|
31
|
+
instance.watch('rows', adjust, {inited: true, presented: true});
|
|
32
|
+
onMounted(adjust);
|
|
33
|
+
|
|
34
|
+
function adjust() {
|
|
35
|
+
const { rows, type } = instance.get();
|
|
36
|
+
if (type === 'textarea' && (rows === 'auto' || isObject(rows))) {
|
|
37
|
+
const textarea = inputRef.value!;
|
|
38
|
+
const originheight = textarea.style.height;
|
|
39
|
+
// we shuold remove height before get scrollHeight,
|
|
40
|
+
// otherwise we cannot shrink the height when we remove the text
|
|
41
|
+
textarea.style.height = '';
|
|
42
|
+
const scrollHeight = textarea.scrollHeight;
|
|
43
|
+
const lines = (scrollHeight - paddingTop - paddingBottom) / lineHeight;
|
|
44
|
+
textarea.style.height = originheight;
|
|
45
|
+
|
|
46
|
+
let actualLines = lines;
|
|
47
|
+
if (rows !== 'auto') {
|
|
48
|
+
const { min, max } = rows;
|
|
49
|
+
if (min && lines <= min) {
|
|
50
|
+
actualLines = min;
|
|
51
|
+
}
|
|
52
|
+
if (max && lines >= max) {
|
|
53
|
+
actualLines = max;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
height.set(lineHeight * actualLines + (isBorderBox ? paddingTop + paddingBottom + 2 /* border */ : 0));
|
|
57
|
+
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
height.set(0);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return height;
|
|
65
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {useInstance, createRef, onMounted} from 'intact';
|
|
1
|
+
import {useInstance, createRef, onMounted, nextTick} from 'intact';
|
|
2
2
|
import type {Input} from './';
|
|
3
3
|
import {useState} from '../../hooks/useState';
|
|
4
4
|
|
|
@@ -13,10 +13,19 @@ export function useAutoWidth() {
|
|
|
13
13
|
|
|
14
14
|
function adjustWidth() {
|
|
15
15
|
if (instance.get('autoWidth')) {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
nextTick(() => {
|
|
17
|
+
const fakeElem = fakeRef.value;
|
|
18
|
+
if (isVisible(fakeElem)) {
|
|
19
|
+
const _width = fakeElem!.offsetWidth || 1;
|
|
20
|
+
width.set(_width);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
18
23
|
}
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
return {fakeRef, width};
|
|
22
27
|
}
|
|
28
|
+
|
|
29
|
+
function isVisible(elem: HTMLDivElement | null) {
|
|
30
|
+
return elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
|
|
31
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {useInstance, createRef, onMounted, RefObject, watch} from 'intact';
|
|
2
|
+
import type {Input, HTMLInputTypes} from './';
|
|
3
|
+
import {useState} from '../../hooks/useState';
|
|
4
|
+
import { useReceive } from '../../hooks/useReceive';
|
|
5
|
+
|
|
6
|
+
export function useShowPassword() {
|
|
7
|
+
const instance = useInstance() as Input;
|
|
8
|
+
const isShow = useState(false);
|
|
9
|
+
const type = useState<HTMLInputTypes | undefined>(undefined);
|
|
10
|
+
const showIcon = useState(false);
|
|
11
|
+
|
|
12
|
+
instance.on('$receive:type', (_type) => {
|
|
13
|
+
type.set(_type);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
useReceive<Input>(['type', 'showPassword'], () => {
|
|
17
|
+
const { showPassword, type } = instance.get();
|
|
18
|
+
showIcon.set(type === 'password' && !!showPassword);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
function toggleShow() {
|
|
22
|
+
isShow.set(!isShow.value);
|
|
23
|
+
type.set(isShow.value ? 'text' : 'password');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return { isShow, type, toggleShow, showIcon };
|
|
27
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {Component} from 'intact';
|
|
2
|
+
import BasicDemo from '~/components/menu/demos/basic';
|
|
2
3
|
import CollapseDemo from '~/components/menu/demos/collapse';
|
|
3
4
|
import AccordionDemo from '~/components/menu/demos/accordion';
|
|
4
5
|
import {mount, unmount, dispatchEvent, getElement, wait} from '../../test/utils';
|
|
@@ -8,13 +9,17 @@ describe('Menu', () => {
|
|
|
8
9
|
afterEach(() => unmount());
|
|
9
10
|
|
|
10
11
|
it('expand and shrink sub menu', async () => {
|
|
11
|
-
const [instance, element] = mount(
|
|
12
|
+
const [instance, element] = mount(BasicDemo);
|
|
13
|
+
|
|
14
|
+
await wait();
|
|
12
15
|
|
|
16
|
+
// shrink
|
|
13
17
|
const title = element.querySelector('.k-expanded .k-menu-title') as HTMLElement;
|
|
14
18
|
title.click();
|
|
15
19
|
await wait(500);
|
|
16
20
|
expect(element.outerHTML).to.matchSnapshot();
|
|
17
21
|
expect(instance.get('expandedKeys')).to.eql([]);
|
|
22
|
+
|
|
18
23
|
title.click();
|
|
19
24
|
await wait(500);
|
|
20
25
|
expect(element.outerHTML).to.matchSnapshot();
|
|
@@ -24,6 +29,9 @@ describe('Menu', () => {
|
|
|
24
29
|
it('select', async () => {
|
|
25
30
|
const [instance, element] = mount(CollapseDemo);
|
|
26
31
|
|
|
32
|
+
instance.set('collapse', false);
|
|
33
|
+
await wait();
|
|
34
|
+
|
|
27
35
|
expect(element.innerHTML).to.matchSnapshot();
|
|
28
36
|
|
|
29
37
|
const [title, disabledTitle] = element.querySelectorAll<HTMLElement>('.k-menu-title');
|
package/components/menu/item.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {useDropdown} from './useDropdown';
|
|
|
9
9
|
import {useRouter, navigate} from '../../hooks/useRouter';
|
|
10
10
|
import {useRecordItem} from '../../hooks/useRecordComponent';
|
|
11
11
|
import {MENU_RECORD_KEY, useHighlightItem} from './useHighlight';
|
|
12
|
+
import {Events} from '../types';
|
|
12
13
|
|
|
13
14
|
export interface MenuItemProps {
|
|
14
15
|
key: Key
|
|
@@ -32,11 +33,17 @@ const typeDefs: Required<TypeDefs<MenuItemProps>> = {
|
|
|
32
33
|
disabled: Boolean,
|
|
33
34
|
};
|
|
34
35
|
|
|
36
|
+
const events: Events<MenuItemEvents> = {
|
|
37
|
+
click: true,
|
|
38
|
+
select: true,
|
|
39
|
+
};
|
|
40
|
+
|
|
35
41
|
export const MENU_ITEM = 'MenuItem';
|
|
36
42
|
|
|
37
43
|
export class MenuItem extends Component<MenuItemProps, MenuItemEvents> {
|
|
38
44
|
static template = template;
|
|
39
45
|
static typeDefs = typeDefs;
|
|
46
|
+
static events = events;
|
|
40
47
|
|
|
41
48
|
public rootMenu = inject<Menu>(ROOT_MENU)!;
|
|
42
49
|
public parentMenu = inject<Menu>(MENU)!;
|
|
@@ -3,9 +3,11 @@ import GotoDemo from '~/components/pagination/demos/goto';
|
|
|
3
3
|
import CurrentDemo from '~/components/pagination/demos/current';
|
|
4
4
|
import DisableDemo from '~/components/pagination/demos/disable';
|
|
5
5
|
import {mount, unmount, dispatchEvent, wait} from '../../test/utils';
|
|
6
|
+
import { Component } from 'intact';
|
|
7
|
+
import { Pagination } from '.';
|
|
6
8
|
|
|
7
9
|
describe('Pagination', () => {
|
|
8
|
-
afterEach(() => unmount());
|
|
10
|
+
// afterEach(() => unmount());
|
|
9
11
|
|
|
10
12
|
it('basic test', async () => {
|
|
11
13
|
const [instance, element] = mount(BasicDemo);
|
|
@@ -89,4 +91,25 @@ describe('Pagination', () => {
|
|
|
89
91
|
expect(input.value).to.eql('10');
|
|
90
92
|
expect(instance.get('value2')).to.eql(10);
|
|
91
93
|
});
|
|
94
|
+
|
|
95
|
+
it('should not set value to 0 when total is 0 on intialization', async () => {
|
|
96
|
+
class Demo extends Component {
|
|
97
|
+
static template = `
|
|
98
|
+
const { Pagination } = this;
|
|
99
|
+
<Pagination total={0} v-model="page" />
|
|
100
|
+
`;
|
|
101
|
+
|
|
102
|
+
static defaults() {
|
|
103
|
+
return {
|
|
104
|
+
page: 1,
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private Pagination = Pagination;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const [instance] = mount(Demo);
|
|
112
|
+
// await wait();
|
|
113
|
+
expect(instance.get('page')).to.eql(1);
|
|
114
|
+
});
|
|
92
115
|
});
|
package/components/portal.ts
CHANGED
|
@@ -46,7 +46,7 @@ export class Portal<T extends PortalProps = PortalProps> extends Component<T> {
|
|
|
46
46
|
nextVNode: VNodeComponentClass<this>,
|
|
47
47
|
parentDom: Element,
|
|
48
48
|
anchor: IntactDom | null,
|
|
49
|
-
mountedQueue: Function[]
|
|
49
|
+
mountedQueue: Function[] & { priority?: Function[] } // in React, it has priority property to add some prior functions
|
|
50
50
|
) {
|
|
51
51
|
/**
|
|
52
52
|
* In React, we cannot render real elements in mountedQueue.
|
|
@@ -56,7 +56,7 @@ export class Portal<T extends PortalProps = PortalProps> extends Component<T> {
|
|
|
56
56
|
const nextProps = nextVNode.props!;
|
|
57
57
|
const fakeContainer = document.createDocumentFragment();
|
|
58
58
|
|
|
59
|
-
mountedQueue.push(() => {
|
|
59
|
+
(mountedQueue.priority || mountedQueue).push(() => {
|
|
60
60
|
const parentDom = this.$lastInput!.dom!.parentElement!;
|
|
61
61
|
this.initContainer(nextProps.container, parentDom, anchor);
|
|
62
62
|
this.container!.appendChild(fakeContainer);
|
|
@@ -79,7 +79,7 @@ export class Portal<T extends PortalProps = PortalProps> extends Component<T> {
|
|
|
79
79
|
nextVNode: VNodeComponentClass<this>,
|
|
80
80
|
parentDom: Element,
|
|
81
81
|
anchor: IntactDom | null,
|
|
82
|
-
mountedQueue: Function[],
|
|
82
|
+
mountedQueue: Function[] & { priority?: Function[] },
|
|
83
83
|
force: boolean,
|
|
84
84
|
) {
|
|
85
85
|
// update container if it has changed
|
|
@@ -121,7 +121,7 @@ export class Portal<T extends PortalProps = PortalProps> extends Component<T> {
|
|
|
121
121
|
|
|
122
122
|
if (!this.container) {
|
|
123
123
|
// in react, sometimes $update will be called before mountedQueue in $render
|
|
124
|
-
mountedQueue.push(update);
|
|
124
|
+
(mountedQueue.priority || mountedQueue).push(update);
|
|
125
125
|
} else {
|
|
126
126
|
update();
|
|
127
127
|
}
|
package/components/position.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { isArray } from 'intact-shared';
|
|
2
|
+
|
|
1
3
|
export type Options = {
|
|
2
4
|
of?: Window | HTMLElement | Document | MouseEvent
|
|
3
5
|
at?: string | [string, string]
|
|
@@ -265,7 +267,9 @@ export default function position(elem: HTMLElement, options: Options) {
|
|
|
265
267
|
} = getDimensions(target);
|
|
266
268
|
const basePosition = Object.assign({}, targetOffset);
|
|
267
269
|
// don't detect collison if the target is not in viewport
|
|
268
|
-
const collision = isInViewport(targetRect)
|
|
270
|
+
const collision = isInViewport(targetRect)
|
|
271
|
+
? (!isArray(options.collision) ? (options.collision || 'flip').split(' ') : options.collision)
|
|
272
|
+
: ['none', 'none'];
|
|
269
273
|
const offsets = {} as {my: [string, string], at: [string, string]};
|
|
270
274
|
const within = getWithinInfo(options.within);
|
|
271
275
|
const scrollInfo = getScrollInfo(within);
|
|
@@ -12,7 +12,7 @@ import {SELECT} from './constants';
|
|
|
12
12
|
import type {Input} from '../input';
|
|
13
13
|
import {useShowHideEvents} from '../../hooks/useShowHideEvents';
|
|
14
14
|
import {bind} from '../utils';
|
|
15
|
-
import {Dropdown} from '../dropdown';
|
|
15
|
+
import {Dropdown, DropdownProps} from '../dropdown';
|
|
16
16
|
import {State} from '../../hooks/useState';
|
|
17
17
|
import {useInput} from './useInput';
|
|
18
18
|
import {Container} from '../portal';
|
|
@@ -36,6 +36,7 @@ export interface BaseSelectProps<V, Multipe extends boolean = boolean, Attach =
|
|
|
36
36
|
container?: Container
|
|
37
37
|
width?: string | number
|
|
38
38
|
show?: boolean
|
|
39
|
+
position?: DropdownProps['position']
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
export interface BaseSelectEvents {
|
|
@@ -68,6 +69,7 @@ const typeDefs: Required<TypeDefs<BaseSelectProps<any>>> = {
|
|
|
68
69
|
container: [Function, String],
|
|
69
70
|
width: [String, Number],
|
|
70
71
|
show: Boolean,
|
|
72
|
+
position: Dropdown.typeDefs.position,
|
|
71
73
|
};
|
|
72
74
|
|
|
73
75
|
const defaults = (): Partial<BaseSelectProps<any>> => ({
|
|
@@ -15,6 +15,7 @@ const {
|
|
|
15
15
|
clearable, filterable,
|
|
16
16
|
className, container,
|
|
17
17
|
inline, style, width, show,
|
|
18
|
+
position,
|
|
18
19
|
} = this.get();
|
|
19
20
|
|
|
20
21
|
const classNameObj = {
|
|
@@ -43,6 +44,7 @@ const {onFocusout, triggerRef} = this.focusout;
|
|
|
43
44
|
disabled={disabled}
|
|
44
45
|
container={container}
|
|
45
46
|
v-model="show"
|
|
47
|
+
position={position}
|
|
46
48
|
>
|
|
47
49
|
<div {...getRestProps(this)}
|
|
48
50
|
class={classNameObj}
|
|
@@ -32,8 +32,18 @@ sidebar: doc
|
|
|
32
32
|
| card | 是否展示`card`模式 | `boolean` | `false` |
|
|
33
33
|
| autoDisableArrow | 是否在没有更多可选项时,给箭头一个`disabled`状态来提示用户 | `boolean` | `false` |
|
|
34
34
|
| show | 是否展示菜单项 | `boolean` | `false` |
|
|
35
|
+
| position | 菜单弹出的位置,默认与触发器左侧对齐向下偏移`8px`的地方 | `Position` | `"left"` | `"bottom"` | `"right"` | `"top"` | `{my: 'left top+8', 'left bottom'}` |
|
|
35
36
|
|
|
36
37
|
```ts
|
|
38
|
+
type Position = {
|
|
39
|
+
my?: string | [string, string]
|
|
40
|
+
at?: string | [string, string]
|
|
41
|
+
collision?: Collision | [Collision, Collision]
|
|
42
|
+
collisionDirection?: ['left'] | ['top'] | ['left', 'top']
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
type Collision = 'fit' | 'flip' | 'flipfit' | 'none'
|
|
46
|
+
|
|
37
47
|
export type Container = string | ((parentDom: Element, anchor: Node | null) => Element)
|
|
38
48
|
```
|
|
39
49
|
|
|
@@ -60,7 +70,7 @@ export type Container = string | ((parentDom: Element, anchor: Node | null) => E
|
|
|
60
70
|
| --- | --- | --- |
|
|
61
71
|
| value | 自定义选择结果的展示 | `([value: any, label: Children]) => Children` |
|
|
62
72
|
| values | 自定义多选的选择结果的展示 | `([values: any[], labels: Children[]]) => Children` |
|
|
63
|
-
| prefix |
|
|
73
|
+
| prefix | 自定义输入框前面展示的内容 | - |
|
|
64
74
|
| suffix | 自定义输入框后面展示的内容 | - |
|
|
65
75
|
| menu | 自定义整个菜单的内容 | - |
|
|
66
76
|
|
package/components/table/cell.ts
CHANGED
|
@@ -35,11 +35,10 @@ export class TableCell extends Component<TableCellProps> {
|
|
|
35
35
|
|
|
36
36
|
let isSame = true;
|
|
37
37
|
for (const key in lastProps) {
|
|
38
|
-
if (
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (key === 'props' && nextProps.props.$blocks) {
|
|
38
|
+
if (
|
|
39
|
+
lastProps[key] !== nextProps[key] ||
|
|
40
|
+
key === 'props' && nextProps.props.$blocks
|
|
41
|
+
) {
|
|
43
42
|
isSame = false;
|
|
44
43
|
break;
|
|
45
44
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 隐藏表头
|
|
3
|
+
order: 29
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
添加`hideHeader`属性,即可隐藏表头
|
|
7
|
+
|
|
8
|
+
```vdt
|
|
9
|
+
import {Table, TableColumn, Switch} from 'kpc';
|
|
10
|
+
|
|
11
|
+
<div>
|
|
12
|
+
<p>hideHeader: <Switch v-model="hideHeader" /></p>
|
|
13
|
+
<Table data={this.get('data')} resizable hideHeader={this.get('hideHeader')}>
|
|
14
|
+
<TableColumn key="a" title="Title 1" />
|
|
15
|
+
<TableColumn key="b" title="Title 2" />
|
|
16
|
+
</Table>
|
|
17
|
+
</div>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
export default class extends Component {
|
|
22
|
+
static template = template;
|
|
23
|
+
static defaults() {
|
|
24
|
+
return {
|
|
25
|
+
data: [
|
|
26
|
+
{a: 'Cell 1-1', b: 'Cell 1-2'},
|
|
27
|
+
{a: 'Cell 2-1', b: 'Cell 2-2'}
|
|
28
|
+
],
|
|
29
|
+
hideHeader: true,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|