Merge branch 'next' of github.com:vueComponent/ant-design-vue into next

feat-dayjs
tangjinzhou 2020-10-17 22:22:44 +08:00
commit dbb67a7b81
30 changed files with 301 additions and 235 deletions

View File

@ -2,7 +2,7 @@ export interface RefObject extends Function {
current?: any;
}
function createRef(): RefObject {
function createRef(): any {
const func: RefObject = (node: any) => {
func.current = node;
};

View File

@ -42,7 +42,7 @@ const responsiveObserve = {
if (!subscribers.size) this.unregister();
},
unregister() {
Object.keys(responsiveMap).forEach((screen: Breakpoint) => {
Object.keys(responsiveMap).forEach((screen: string) => {
const matchMediaQuery = responsiveMap[screen]!;
const handler = this.matchHandlers[matchMediaQuery];
handler?.mql.removeListener(handler?.listener);
@ -50,7 +50,7 @@ const responsiveObserve = {
subscribers.clear();
},
register() {
Object.keys(responsiveMap).forEach((screen: Breakpoint) => {
Object.keys(responsiveMap).forEach((screen: string) => {
const matchMediaQuery = responsiveMap[screen]!;
const listener = ({ matches }: { matches: boolean }) => {
this.dispatch({

View File

@ -19,17 +19,10 @@ const AffixMounter = {
render() {
return (
<div>
<div ref="container" class="container">
<Affix
class="fixed"
target={() => this.$refs.container}
ref="affix"
{...{ props: this.$props }}
>
<Button type="primary">Fixed at the top of container</Button>
</Affix>
</div>
<div ref="container" class="container">
<Affix class="fixed" target={() => this.$refs.container} ref="affix">
<Button type="primary">Fixed at the top of container</Button>
</Affix>
</div>
);
},

View File

@ -150,6 +150,6 @@ AutoComplete.install = function(app: App) {
};
export default AutoComplete as typeof AutoComplete & {
readonly Option: typeof AutoComplete.Option;
readonly OptGroup: typeof AutoComplete.OptGroup;
readonly Option: typeof Option;
readonly OptGroup: typeof OptGroup;
};

View File

@ -59,7 +59,7 @@ exports[`Button should not render as link button when href is undefined 1`] = `
`;
exports[`Button should support link button 1`] = `
<a target="_blank" href="http://ant.design" class="ant-btn">
<a target="_blank" class="ant-btn" href="http://ant.design">
<!----><span>link button</span>
</a>
`;

View File

@ -96,7 +96,7 @@ const Card = defineComponent({
} = this.$props;
const { $slots } = this;
const children = getSlot(this);
const getPrefixCls = this.configProvider.getPrefixCls;
const { getPrefixCls } = this.configProvider;
const prefixCls = getPrefixCls('card', customizePrefixCls);
const tabBarExtraContent = getComponent(this, 'tabBarExtraContent');

View File

@ -19,9 +19,9 @@ export default defineComponent({
props: {
name: PropTypes.string,
prefixCls: PropTypes.string,
defaultValue: { type: Array as PropType<Array<CheckboxValueType>>},
value: { type: Array as PropType<Array<CheckboxValueType>>},
options: {type: Array as PropType<Array<CheckboxOptionType | string>>},
defaultValue: { type: Array as PropType<Array<CheckboxValueType>> },
value: { type: Array as PropType<Array<CheckboxValueType>> },
options: { type: Array as PropType<Array<CheckboxOptionType | string>> },
disabled: PropTypes.looseBool,
onChange: PropTypes.func,
},
@ -48,7 +48,7 @@ export default defineComponent({
},
methods: {
getOptions() {
const { options, $slots } = this;
const { options = [], $slots } = this;
return options.map(option => {
if (typeof option === 'string') {
return {

View File

@ -8,11 +8,11 @@ describe('ConfigProvider', () => {
mountTest({
render() {
return (
<div>
<>
<ConfigProvider>
<div />
</ConfigProvider>
</div>
</>
);
},
});

View File

@ -89,16 +89,16 @@ const ACol = defineComponent<ColProps>({
let mergedStyle: CSSProperties = {};
if (gutter) {
mergedStyle = {
...(gutter[0]! > 0
...(gutter[0] > 0
? {
paddingLeft: gutter[0]! / 2,
paddingRight: gutter[0]! / 2,
paddingLeft: `${gutter[0] / 2}px`,
paddingRight: `${gutter[0] / 2}px`,
}
: {}),
...(gutter[1]! > 0
...(gutter[1] > 0
? {
paddingTop: gutter[1]! / 2,
paddingBottom: gutter[1]! / 2,
paddingTop: `${gutter[1] / 2}px`,
paddingBottom: `${gutter[1] / 2}px`,
}
: {}),
...mergedStyle,
@ -109,7 +109,7 @@ const ACol = defineComponent<ColProps>({
}
return (
<div style={mergedStyle} class={classes}>
<div class={classes} style={mergedStyle}>
{slots.default?.()}
</div>
);

View File

@ -104,16 +104,16 @@ const ARow = defineComponent<RowProps>({
[`${prefixCls}-${align}`]: align,
});
const rowStyle = {
...(gutter[0]! > 0
...(gutter[0] > 0
? {
marginLeft: gutter[0]! / -2,
marginRight: gutter[0]! / -2,
marginLeft: `${gutter[0] / -2}px`,
marginRight: `${gutter[0] / -2}px`,
}
: {}),
...(gutter[1]! > 0
...(gutter[1] > 0
? {
marginTop: gutter[1]! / -2,
marginBottom: gutter[1]! / 2,
marginTop: `${gutter[1] / -2}px`,
marginBottom: `${gutter[1] / -2}px`,
}
: {}),
};

View File

@ -3,12 +3,24 @@
exports[`Grid renders wrapped Col correctly 1`] = `
<div class="ant-row" style="margin-left: -10px; margin-right: -10px;">
<div>
<div class="ant-col ant-col-12" style="padding-left: 10px; padding-right: 10px;"></div>
<div class="ant-col ant-col-12" style="padding-left: 10px; padding-right: 10px;">
<!---->
</div>
</div>
<div class="ant-col ant-col-12" style="padding-left: 10px; padding-right: 10px;">
<!---->
</div>
<div class="ant-col ant-col-12" style="padding-left: 10px; padding-right: 10px;"></div>
</div>
`;
exports[`Grid should render Col 1`] = `<div class="ant-col ant-col-2"></div>`;
exports[`Grid should render Col 1`] = `
<div class="ant-col ant-col-2">
<!---->
</div>
`;
exports[`Grid should render Row 1`] = `<div class="ant-row"></div>`;
exports[`Grid should render Row 1`] = `
<div class="ant-row">
<!---->
</div>
`;

View File

@ -121,7 +121,7 @@ describe('message', () => {
}, 0);
});
it('should allow custom icon', async () => {
message.open({ content: 'Message', icon: () => <SmileOutlined /> }); // eslint-disable-line
message.open({ content: 'Message', icon: <SmileOutlined /> });
await asyncExpect(() => {
expect(document.querySelectorAll('.anticon-smile').length).toBe(1);
}, 0);

View File

@ -1,70 +0,0 @@
import { Circle as VCCircle } from '../vc-progress';
import { validProgress } from './utils';
const statusColorMap = {
normal: '#108ee9',
exception: '#ff5500',
success: '#87d068',
};
function getPercentage({ percent, successPercent }) {
const ptg = validProgress(percent);
if (!successPercent) return ptg;
const successPtg = validProgress(successPercent);
return [successPercent, validProgress(ptg - successPtg)];
}
function getStrokeColor({ progressStatus, successPercent, strokeColor }) {
const color = strokeColor || statusColorMap[progressStatus];
if (!successPercent) return color;
return [statusColorMap.success, color];
}
const Circle = (_, { attrs, slots }) => {
const {
prefixCls,
width,
strokeWidth,
trailColor,
strokeLinecap,
gapPosition,
gapDegree,
type,
} = attrs;
const circleSize = width || 120;
const circleStyle = {
width: typeof circleSize === 'number' ? `${circleSize}px` : circleSize,
height: typeof circleSize === 'number' ? `${circleSize}px` : circleSize,
fontSize: `${circleSize * 0.15 + 6}px`,
};
const circleWidth = strokeWidth || 6;
const gapPos = gapPosition || (type === 'dashboard' && 'bottom') || 'top';
const gapDeg = gapDegree || (type === 'dashboard' && 75);
const strokeColor = getStrokeColor(attrs);
const isGradient = Object.prototype.toString.call(strokeColor) === '[object Object]';
const wrapperClassName = {
[`${prefixCls}-inner`]: true,
[`${prefixCls}-circle-gradient`]: isGradient,
};
return (
<div class={wrapperClassName} style={circleStyle}>
<VCCircle
percent={getPercentage(attrs)}
strokeWidth={circleWidth}
trailWidth={circleWidth}
strokeColor={strokeColor}
strokeLinecap={strokeLinecap}
trailColor={trailColor}
prefixCls={prefixCls}
gapDegree={gapDeg}
gapPosition={gapPos}
/>
{slots?.default()}
</div>
);
};
export default Circle;

View File

@ -0,0 +1,85 @@
import { defineComponent, ExtractPropTypes } from 'vue';
import { Circle as VCCircle } from '../vc-progress';
import PropTypes from '../_util/vue-types';
import { validProgress } from './utils';
import { ProgressProps } from './props';
const CircleProps = {
...ProgressProps,
progressStatus: PropTypes.string,
};
const statusColorMap: Record<string, string> = {
normal: '#108ee9',
exception: '#ff5500',
success: '#87d068',
};
export type ICircleProps = ExtractPropTypes<typeof CircleProps>;
function getPercentage({ percent, successPercent }: ICircleProps) {
const ptg = validProgress(percent);
if (!successPercent) return ptg;
const successPtg = validProgress(successPercent);
return [successPercent, validProgress(ptg - successPtg)];
}
function getStrokeColor({ progressStatus, successPercent, strokeColor }: ICircleProps) {
const color = strokeColor || statusColorMap[progressStatus];
if (!successPercent) return color;
return [statusColorMap.success, color];
}
const Circle = defineComponent({
props: CircleProps,
setup(props, { slots }) {
return () => {
const {
prefixCls,
width,
strokeWidth,
trailColor,
strokeLinecap,
gapPosition,
gapDegree,
type,
} = props;
const circleSize = width || 120;
const circleStyle = {
width: typeof circleSize === 'number' ? `${circleSize}px` : circleSize,
height: typeof circleSize === 'number' ? `${circleSize}px` : circleSize,
fontSize: `${circleSize * 0.15 + 6}px`,
};
const circleWidth = strokeWidth || 6;
const gapPos = gapPosition || (type === 'dashboard' && 'bottom') || 'top';
const gapDeg = gapDegree || (type === 'dashboard' && 75);
const strokeColor = getStrokeColor(props);
const isGradient = Object.prototype.toString.call(strokeColor) === '[object Object]';
const wrapperClassName = {
[`${prefixCls}-inner`]: true,
[`${prefixCls}-circle-gradient`]: isGradient,
};
return (
<div class={wrapperClassName} style={circleStyle}>
<VCCircle
percent={getPercentage(props)}
strokeWidth={circleWidth}
trailWidth={circleWidth}
strokeColor={strokeColor}
strokeLinecap={strokeLinecap}
trailColor={trailColor}
prefixCls={prefixCls}
gapDegree={gapDeg}
gapPosition={gapPos}
/>
{slots?.default()}
</div>
);
};
},
});
export default Circle;

View File

@ -1,9 +1,10 @@
import { App } from 'vue';
import Progress from './progress';
export { ProgressProps } from './progress';
export { ProgressProps } from './props';
/* istanbul ignore next */
Progress.install = function(app) {
Progress.install = function(app: App) {
app.component(Progress.name, Progress);
return app;
};

View File

@ -1,7 +1,7 @@
import { inject } from 'vue';
import { defineComponent, inject } from 'vue';
import classNames from '../_util/classNames';
import PropTypes from '../_util/vue-types';
import { getOptionProps, initDefaultProps } from '../_util/props-util';
import { getOptionProps } from '../_util/props-util';
import initDefaultProps from '../_util/props-util/initDefaultProps';
import { defaultConfigProvider } from '../config-provider';
import CloseOutlined from '@ant-design/icons-vue/CloseOutlined';
import CheckOutlined from '@ant-design/icons-vue/CheckOutlined';
@ -10,30 +10,9 @@ import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
import Line from './line';
import Circle from './circle';
import { validProgress } from './utils';
import { ProgressProps, ProgressStatuses } from './props';
const ProgressStatuses = ['normal', 'exception', 'active', 'success'];
export const ProgressType = PropTypes.oneOf(['line', 'circle', 'dashboard']);
export const ProgressSize = PropTypes.oneOf(['default', 'small']);
export const ProgressProps = {
prefixCls: PropTypes.string,
type: ProgressType,
percent: PropTypes.number,
successPercent: PropTypes.number,
format: PropTypes.func,
status: PropTypes.oneOf(ProgressStatuses),
showInfo: PropTypes.looseBool,
strokeWidth: PropTypes.number,
strokeLinecap: PropTypes.oneOf(['butt', 'round', 'square']),
strokeColor: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
trailColor: PropTypes.string,
width: PropTypes.number,
gapDegree: PropTypes.number,
gapPosition: PropTypes.oneOf(['top', 'bottom', 'left', 'right']),
size: ProgressSize,
};
export default {
export default defineComponent({
name: 'AProgress',
props: initDefaultProps(ProgressProps, {
type: 'line',
@ -65,7 +44,7 @@ export default {
}
return status || 'normal';
},
renderProcessInfo(prefixCls, progressStatus) {
renderProcessInfo(prefixCls: string, progressStatus: typeof ProgressStatuses[number]) {
const { showInfo, format, type, percent, successPercent } = this.$props;
if (!showInfo) return null;
@ -93,7 +72,7 @@ export default {
render() {
const props = getOptionProps(this);
const { prefixCls: customizePrefixCls, size, type, showInfo } = props;
const getPrefixCls = this.configProvider.getPrefixCls;
const { getPrefixCls } = this.configProvider;
const prefixCls = getPrefixCls('progress', customizePrefixCls);
const progressStatus = this.getProgressStatus();
const progressInfo = this.renderProcessInfo(prefixCls, progressStatus);
@ -128,4 +107,4 @@ export default {
};
return <div {...progressProps}>{progress}</div>;
},
};
});

View File

@ -0,0 +1,24 @@
import PropTypes from '../_util/vue-types';
import { tuple } from '../_util/type';
export const ProgressStatuses = tuple('normal', 'exception', 'active', 'success');
export const ProgressType = PropTypes.oneOf(tuple('line', 'circle', 'dashboard'));
export const ProgressSize = PropTypes.oneOf(tuple('default', 'small'));
export const ProgressProps = {
prefixCls: PropTypes.string,
type: ProgressType,
percent: PropTypes.number,
successPercent: PropTypes.number,
format: PropTypes.func,
status: PropTypes.oneOf(ProgressStatuses),
showInfo: PropTypes.looseBool,
strokeWidth: PropTypes.number,
strokeLinecap: PropTypes.oneOf(['butt', 'round', 'square']),
strokeColor: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
trailColor: PropTypes.string,
width: PropTypes.number,
gapDegree: PropTypes.number,
gapPosition: PropTypes.oneOf(tuple('top', 'bottom', 'left', 'right')),
size: ProgressSize,
};

View File

@ -1,4 +1,4 @@
export function validProgress(progress) {
export function validProgress(progress?: number) {
if (!progress || progress < 0) {
return 0;
}

View File

@ -1,6 +1,8 @@
import { inject, App, CSSProperties, SetupContext } from 'vue';
import { inject, App, defineComponent, PropType } from 'vue';
import PropTypes from '../_util/vue-types';
import { filterEmpty } from '../_util/props-util';
import { defaultConfigProvider, SizeType } from '../config-provider';
import { tuple } from '../_util/type';
const spaceSize = {
small: 8,
@ -8,67 +10,74 @@ const spaceSize = {
large: 24,
};
export interface SpaceProps {
prefixCls?: string;
className?: string;
style?: CSSProperties;
size?: SizeType | number;
direction?: 'horizontal' | 'vertical';
// No `stretch` since many components do not support that.
align?: 'start' | 'end' | 'center' | 'baseline';
}
const Space = defineComponent({
name: 'ASpace',
props: {
prefixCls: PropTypes.string,
size: {
type: [String, Number] as PropType<number | SizeType>,
},
direction: PropTypes.oneOf(tuple('horizontal', 'vertical')),
align: PropTypes.oneOf(tuple('start', 'end', 'center', 'baseline')),
},
setup(props, { slots }) {
const configProvider = inject('configProvider', defaultConfigProvider);
const {
align,
size = 'small',
direction = 'horizontal',
prefixCls: customizePrefixCls,
} = props;
const Space = (props: SpaceProps, { slots }: SetupContext) => {
const configProvider = inject('configProvider', defaultConfigProvider);
const { align, size = 'small', direction = 'horizontal', prefixCls: customizePrefixCls } = props;
const { getPrefixCls } = configProvider;
const { getPrefixCls } = configProvider;
const prefixCls = getPrefixCls('space', customizePrefixCls);
const items = filterEmpty(slots.default?.());
const len = items.length;
return () => {
const prefixCls = getPrefixCls('space', customizePrefixCls);
const items = filterEmpty(slots.default?.());
const len = items.length;
if (len === 0) {
return null;
}
if (len === 0) {
return null;
}
const mergedAlign = align === undefined && direction === 'horizontal' ? 'center' : align;
const mergedAlign = align === undefined && direction === 'horizontal' ? 'center' : align;
const someSpaceClass = {
[prefixCls]: true,
[`${prefixCls}-${direction}`]: true,
[`${prefixCls}-align-${mergedAlign}`]: mergedAlign,
};
const someSpaceClass = {
[prefixCls]: true,
[`${prefixCls}-${direction}`]: true,
[`${prefixCls}-align-${mergedAlign}`]: mergedAlign,
};
const itemClassName = `${prefixCls}-item`;
const marginDirection = 'marginRight'; // directionConfig === 'rtl' ? 'marginLeft' : 'marginRight';
const itemClassName = `${prefixCls}-item`;
const marginDirection = 'marginRight'; // directionConfig === 'rtl' ? 'marginLeft' : 'marginRight';
return (
<div class={someSpaceClass}>
{items.map((child, i) => (
<div
class={itemClassName}
key={`${itemClassName}-${i}`}
style={
i === len - 1
? {}
: {
[direction === 'vertical' ? 'marginBottom' : marginDirection]:
typeof size === 'string' ? `${spaceSize[size]}px` : `${size}px`,
}
}
>
{child}
return (
<div class={someSpaceClass}>
{items.map((child, i) => (
<div
class={itemClassName}
key={`${itemClassName}-${i}`}
style={
i === len - 1
? {}
: {
[direction === 'vertical' ? 'marginBottom' : marginDirection]:
typeof size === 'string' ? `${spaceSize[size]}px` : `${size}px`,
}
}
>
{child}
</div>
))}
</div>
))}
</div>
);
};
Space.displayName = 'ASpace';
);
};
},
});
/* istanbul ignore next */
Space.install = function(app: App) {
app.component(Space.displayName, Space);
app.component(Space.name, Space);
return app;
};

View File

@ -1,25 +1,26 @@
import { defineComponent } from 'vue';
import moment from 'moment';
import interopDefault from '../_util/interopDefault';
import { initDefaultProps } from '../_util/props-util';
import initDefaultProps from '../_util/props-util/initDefaultProps';
import Statistic, { StatisticProps } from './Statistic';
import { formatCountdown } from './utils';
import { formatCountdown, countdownValueType, FormatConfig } from './utils';
const REFRESH_INTERVAL = 1000 / 30;
function getTime(value) {
function getTime(value?: countdownValueType) {
return interopDefault(moment)(value).valueOf();
}
export default {
export default defineComponent({
name: 'AStatisticCountdown',
props: initDefaultProps(StatisticProps, {
format: 'HH:mm:ss',
}),
created() {
this.countdownId = undefined;
setup() {
return {
countdownId: undefined,
} as { countdownId: number };
},
mounted() {
this.syncTimer();
},
@ -46,7 +47,7 @@ export default {
startTimer() {
if (this.countdownId) return;
this.countdownId = window.setInterval(() => {
this.$refs.statistic.$forceUpdate();
(this.$refs.statistic as any).$forceUpdate();
this.syncTimer();
}, REFRESH_INTERVAL);
},
@ -64,7 +65,7 @@ export default {
}
},
formatCountdown({ value, config }) {
formatCountdown({ value, config }: { value: countdownValueType; config: FormatConfig }) {
const { format } = this.$props;
return formatCountdown(value, { ...config, format });
},
@ -84,4 +85,4 @@ export default {
/>
);
},
};
});

View File

@ -1,13 +1,18 @@
import padEnd from 'lodash-es/padEnd';
import { createVNode } from 'vue';
import { FunctionalComponent, VNodeTypes } from 'vue';
import { FormatConfig, valueType } from './utils';
const Number = (_, { attrs }) => {
const { value, formatter, precision, decimalSeparator, groupSeparator = '', prefixCls } = attrs;
let valueNode;
interface NumberProps extends FormatConfig {
value: valueType;
}
const Number: FunctionalComponent<NumberProps> = props => {
const { value, formatter, precision, decimalSeparator, groupSeparator = '', prefixCls } = props;
let valueNode: VNodeTypes;
if (typeof formatter === 'function') {
// Customize formatter
valueNode = formatter({ value, h: createVNode });
valueNode = formatter({ value });
} else {
// Internal formatter
const val = String(value);

View File

@ -1,26 +1,30 @@
import { inject } from 'vue';
import { defineComponent, inject, PropType } from 'vue';
import PropTypes from '../_util/vue-types';
import { getComponent, initDefaultProps } from '../_util/props-util';
import { getComponent } from '../_util/props-util';
import initDefaultProps from '../_util/props-util/initDefaultProps';
import { defaultConfigProvider } from '../config-provider';
import StatisticNumber from './Number';
import { countdownValueType } from './utils';
export const StatisticProps = {
prefixCls: PropTypes.string,
decimalSeparator: PropTypes.string,
groupSeparator: PropTypes.string,
format: PropTypes.string,
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.object]),
valueStyle: PropTypes.any,
value: {
type: [String, Number, Object] as PropType<countdownValueType>,
},
valueStyle: PropTypes.style,
valueRender: PropTypes.any,
formatter: PropTypes.any,
precision: PropTypes.number,
prefix: PropTypes.any,
suffix: PropTypes.any,
title: PropTypes.any,
prefix: PropTypes.VNodeChild,
suffix: PropTypes.VNodeChild,
title: PropTypes.VNodeChild,
onFinish: PropTypes.func,
};
export default {
export default defineComponent({
name: 'AStatistic',
props: initDefaultProps(StatisticProps, {
decimalSeparator: '.',
@ -35,7 +39,7 @@ export default {
render() {
const { prefixCls: customizePrefixCls, value = 0, valueStyle, valueRender } = this.$props;
const getPrefixCls = this.configProvider.getPrefixCls;
const { getPrefixCls } = this.configProvider;
const prefixCls = getPrefixCls('statistic', customizePrefixCls);
const title = getComponent(this, 'title');
@ -64,4 +68,4 @@ export default {
</div>
);
},
};
});

View File

@ -1,9 +1,10 @@
import Statistic from './Statistic';
import Countdown from './Countdown';
import { App } from 'vue';
Statistic.Countdown = Countdown;
/* istanbul ignore next */
Statistic.install = function(app) {
Statistic.install = function(app: App) {
app.component(Statistic.name, Statistic);
app.component(Statistic.Countdown.name, Statistic.Countdown);
return app;

View File

@ -1,10 +1,32 @@
import { VNodeTypes } from 'vue';
import moment from 'moment';
import padStart from 'lodash-es/padStart';
import interopDefault from '../_util/interopDefault';
export type valueType = number | string;
export type countdownValueType = valueType | string;
export type Formatter =
| false
| 'number'
| 'countdown'
| (({ value, config }: { value: valueType; config?: FormatConfig }) => VNodeTypes);
export interface FormatConfig {
formatter?: Formatter;
decimalSeparator?: string;
groupSeparator?: string;
precision?: number;
prefixCls?: string;
}
export interface CountdownFormatConfig extends FormatConfig {
format?: string;
}
// Countdown
const timeUnits = [
const timeUnits: [string, number][] = [
['Y', 1000 * 60 * 60 * 24 * 365], // years
['M', 1000 * 60 * 60 * 24 * 30], // months
['D', 1000 * 60 * 60 * 24], // days
@ -14,8 +36,8 @@ const timeUnits = [
['S', 1], // million seconds
];
export function formatTimeStr(duration, format) {
let leftDuration = duration;
export function formatTimeStr(duration: number, format: string) {
let leftDuration: number = duration;
const escapeRegex = /\[[^\]]*\]/g;
const keepList = (format.match(escapeRegex) || []).map(str => str.slice(1, -1));
@ -41,7 +63,7 @@ export function formatTimeStr(duration, format) {
});
}
export function formatCountdown(value, config) {
export function formatCountdown(value: countdownValueType, config: CountdownFormatConfig) {
const { format = '' } = config;
const target = interopDefault(moment)(value).valueOf();
const current = interopDefault(moment)().valueOf();

View File

@ -75,7 +75,6 @@ export const BaseProps = () => ({
// Options
options: PropTypes.array,
children: PropTypes.array.def([]),
mode: PropTypes.string,
// Value

View File

@ -9,7 +9,7 @@ const Item: FunctionalComponent<ItemProps> = ({ setRef }, { slots }) => {
return children && children.length
? cloneVNode(children[0], {
ref: setRef,
ref: setRef as any,
})
: children;
};
@ -19,4 +19,5 @@ Item.props = {
default: () => {},
},
};
export default Item;

View File

@ -45,7 +45,7 @@ function renderChildren<T>(
});
const key = getKey(item);
return (
<Item key={key} setRef={ele => setNodeRef(item, ele)}>
<Item key={key} setRef={ele => setNodeRef(item, ele as HTMLElement)}>
{node}
</Item>
);
@ -102,7 +102,7 @@ const List = defineComponent({
mergedData: computed(() => props.data || EMPTY_DATA) as any,
});
const componentRef = ref<Element>();
const componentRef = ref<HTMLDivElement>();
// =============================== Item Key ===============================
const getKey = (item: Record<string, any>) => {
@ -257,8 +257,8 @@ const List = defineComponent({
const removeEventListener = () => {
if (componentRef.value) {
componentRef.value.removeEventListener('wheel', onRawWheel);
componentRef.value.removeEventListener('DOMMouseScroll' as any, onFireFoxScroll);
componentRef.value.removeEventListener('MozMousePixelScroll', onMozMousePixelScroll);
componentRef.value.removeEventListener('DOMMouseScroll', onFireFoxScroll as any);
componentRef.value.removeEventListener('MozMousePixelScroll', onMozMousePixelScroll as any);
}
};
watchEffect(() => {
@ -266,8 +266,8 @@ const List = defineComponent({
if (componentRef.value) {
removeEventListener();
componentRef.value.addEventListener('wheel', onRawWheel);
componentRef.value.addEventListener('DOMMouseScroll' as any, onFireFoxScroll);
componentRef.value.addEventListener('MozMousePixelScroll', onMozMousePixelScroll);
componentRef.value.addEventListener('DOMMouseScroll', onFireFoxScroll as any);
componentRef.value.addEventListener('MozMousePixelScroll', onMozMousePixelScroll as any);
}
});
});

View File

@ -4,7 +4,7 @@ const SMOOTH_PTG = 14 / 15;
export default function useMobileTouchMove(
inVirtual: Ref<boolean>,
listRef: Ref<Element | undefined>,
listRef: Ref<HTMLDivElement | undefined>,
callback: (offsetY: number, smoothOffset?: boolean) => boolean,
) {
let touched = false;