feat: update slider

pull/2682/head
tangjinzhou 2020-07-20 22:47:06 +08:00
parent a3592033be
commit 2c3492face
17 changed files with 260 additions and 325 deletions

View File

@ -1,24 +1,14 @@
import { inject } from 'vue';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
import BaseMixin from '../_util/BaseMixin'; import BaseMixin from '../_util/BaseMixin';
import { getOptionProps, getListeners } from '../_util/props-util'; import { getOptionProps } from '../_util/props-util';
import VcSlider from '../vc-slider/src/Slider'; import VcSlider from '../vc-slider/src/Slider';
import VcRange from '../vc-slider/src/Range'; import VcRange from '../vc-slider/src/Range';
import VcHandle from '../vc-slider/src/Handle'; import VcHandle from '../vc-slider/src/Handle';
import Tooltip from '../tooltip'; import Tooltip from '../tooltip';
import Base from '../base';
import { ConfigConsumerProps } from '../config-provider'; import { ConfigConsumerProps } from '../config-provider';
import abstractTooltipProps from '../tooltip/abstractTooltipProps'; import abstractTooltipProps from '../tooltip/abstractTooltipProps';
// export interface SliderMarks {
// [key]: React.ReactNode | {
// style: React.CSSProperties,
// label: React.ReactNode,
// };
// }
// const SliderMarks = PropTypes.shape({
// style: PropTypes.object,
// label: PropTypes.any,
// }).loose
const tooltipProps = abstractTooltipProps(); const tooltipProps = abstractTooltipProps();
export const SliderProps = () => ({ export const SliderProps = () => ({
prefixCls: PropTypes.string, prefixCls: PropTypes.string,
@ -41,21 +31,23 @@ export const SliderProps = () => ({
getTooltipPopupContainer: PropTypes.func, getTooltipPopupContainer: PropTypes.func,
}); });
const defaultTipFormatter = value => value.toString();
const Slider = { const Slider = {
name: 'ASlider', name: 'ASlider',
model: { inheritAttrs: false,
prop: 'value', // model: {
event: 'change', // prop: 'value',
}, // event: 'change',
// },
mixins: [BaseMixin], mixins: [BaseMixin],
inject: { setup() {
configProvider: { default: () => ConfigConsumerProps }, return {
configProvider: inject('configProvider', ConfigConsumerProps),
};
}, },
props: { props: {
...SliderProps(), ...SliderProps(),
tipFormatter: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).def(value =>
value.toString(),
),
}, },
data() { data() {
return { return {
@ -71,13 +63,9 @@ const Slider = {
}, },
})); }));
}, },
handleWithTooltip( handleWithTooltip(tooltipPrefixCls, prefixCls, { value, dragging, index, ...restProps }) {
tooltipPrefixCls,
prefixCls,
{ value, dragging, index, directives, on, ...restProps },
) {
const { const {
tipFormatter, tipFormatter = defaultTipFormatter,
tooltipVisible, tooltipVisible,
tooltipPlacement, tooltipPlacement,
getTooltipPopupContainer, getTooltipPopupContainer,
@ -86,28 +74,20 @@ const Slider = {
const isTipFormatter = tipFormatter ? visibles[index] || dragging : false; const isTipFormatter = tipFormatter ? visibles[index] || dragging : false;
const visible = tooltipVisible || (tooltipVisible === undefined && isTipFormatter); const visible = tooltipVisible || (tooltipVisible === undefined && isTipFormatter);
const tooltipProps = { const tooltipProps = {
props: { prefixCls: tooltipPrefixCls,
prefixCls: tooltipPrefixCls, title: tipFormatter ? tipFormatter(value) : '',
title: tipFormatter ? tipFormatter(value) : '', visible,
visible, placement: tooltipPlacement || 'top',
placement: tooltipPlacement || 'top', transitionName: 'zoom-down',
transitionName: 'zoom-down', overlayClassName: `${prefixCls}-tooltip`,
overlayClassName: `${prefixCls}-tooltip`, getPopupContainer: getTooltipPopupContainer || (() => document.body),
getPopupContainer: getTooltipPopupContainer || (() => document.body),
},
key: index, key: index,
}; };
const handleProps = { const handleProps = {
props: { value,
value, ...restProps,
...restProps, onMouseenter: () => this.toggleTooltipVisible(index, true),
}, onMouseleave: () => this.toggleTooltipVisible(index, false),
directives,
on: {
...on,
mouseenter: () => this.toggleTooltipVisible(index, true),
mouseleave: () => this.toggleTooltipVisible(index, false),
},
}; };
return ( return (
<Tooltip {...tooltipProps}> <Tooltip {...tooltipProps}>
@ -115,11 +95,14 @@ const Slider = {
</Tooltip> </Tooltip>
); );
}, },
saveSlider(node) {
this.vcSlider = node;
},
focus() { focus() {
this.$refs.sliderRef.focus(); this.vcSlider.focus();
}, },
blur() { blur() {
this.$refs.sliderRef.blur(); this.vcSlider.blur();
}, },
}, },
render() { render() {
@ -128,42 +111,34 @@ const Slider = {
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,
tooltipPrefixCls: customizeTooltipPrefixCls, tooltipPrefixCls: customizeTooltipPrefixCls,
...restProps ...restProps
} = getOptionProps(this); } = { ...getOptionProps(this), ...this.$attrs };
const getPrefixCls = this.configProvider.getPrefixCls; const getPrefixCls = this.configProvider.getPrefixCls;
const prefixCls = getPrefixCls('slider', customizePrefixCls); const prefixCls = getPrefixCls('slider', customizePrefixCls);
const tooltipPrefixCls = getPrefixCls('tooltip', customizeTooltipPrefixCls); const tooltipPrefixCls = getPrefixCls('tooltip', customizeTooltipPrefixCls);
const listeners = getListeners(this);
if (range) { if (range) {
const vcRangeProps = { const vcRangeProps = {
props: {
...restProps,
prefixCls,
tooltipPrefixCls,
handle: info => this.handleWithTooltip(tooltipPrefixCls, prefixCls, info),
},
ref: 'sliderRef',
on: listeners,
};
return <VcRange {...vcRangeProps} />;
}
const vcSliderProps = {
props: {
...restProps, ...restProps,
prefixCls, prefixCls,
tooltipPrefixCls, tooltipPrefixCls,
handle: info => this.handleWithTooltip(tooltipPrefixCls, prefixCls, info), handle: info => this.handleWithTooltip(tooltipPrefixCls, prefixCls, info),
}, ref: this.saveSlider,
ref: 'sliderRef', };
on: listeners, return <VcRange {...vcRangeProps} />;
}
const vcSliderProps = {
...restProps,
prefixCls,
tooltipPrefixCls,
handle: info => this.handleWithTooltip(tooltipPrefixCls, prefixCls, info),
ref: this.saveSlider,
}; };
return <VcSlider {...vcSliderProps} />; return <VcSlider {...vcSliderProps} />;
}, },
}; };
/* istanbul ignore next */ /* istanbul ignore next */
Slider.install = function(Vue) { Slider.install = function(app) {
Vue.use(Base); app.component(Slider.name, Slider);
Vue.component(Slider.name, Slider);
}; };
export default Slider; export default Slider;

View File

@ -116,7 +116,7 @@ export default {
}, },
getPopupDomNode() { getPopupDomNode() {
return this.$refs.trigger.getPopupDomNode(); return this.trigger.getPopupDomNode();
}, },
getOpenClassName() { getOpenClassName() {
@ -133,13 +133,8 @@ export default {
const rootNode = findDOMNode(this); const rootNode = findDOMNode(this);
if (rootNode && overlayNode && rootNode.offsetWidth > overlayNode.offsetWidth) { if (rootNode && overlayNode && rootNode.offsetWidth > overlayNode.offsetWidth) {
overlayNode.style.minWidth = `${rootNode.offsetWidth}px`; overlayNode.style.minWidth = `${rootNode.offsetWidth}px`;
if ( if (this.trigger && this.trigger._component && this.trigger._component.alignInstance) {
this.$refs.trigger && this.trigger._component.alignInstance.forceAlign();
this.$refs.trigger._component &&
this.$refs.trigger._component.$refs &&
this.$refs.trigger._component.$refs.alignInstance
) {
this.$refs.trigger._component.$refs.alignInstance.forceAlign();
} }
} }
} }
@ -152,6 +147,9 @@ export default {
? cloneElement(children[0], { class: this.getOpenClassName() }, false) ? cloneElement(children[0], { class: this.getOpenClassName() }, false)
: children; : children;
}, },
saveTrigger(node) {
this.trigger = node;
},
}, },
render() { render() {
@ -192,7 +190,7 @@ export default {
getPopupContainer, getPopupContainer,
onPopupVisibleChange: this.onVisibleChange, onPopupVisibleChange: this.onVisibleChange,
popup: this.getMenuElementOrLambda(), popup: this.getMenuElementOrLambda(),
ref: 'trigger', ref: this.saveTrigger,
}; };
return <Trigger {...triggerProps}>{this.renderChildren()}</Trigger>; return <Trigger {...triggerProps}>{this.renderChildren()}</Trigger>;
}, },

View File

@ -1,7 +1,4 @@
// base rc-slider 8.7.1 // base rc-slider 8.7.1
import Vue from 'vue';
import ref from 'vue-ref';
import Slider from './src/'; import Slider from './src/';
Vue.use(ref, { name: 'ant-ref' });
export default Slider; export default Slider;

View File

@ -1,12 +1,13 @@
import classNames from 'classnames'; import classNames from 'classnames';
import PropTypes from '../../_util/vue-types'; import PropTypes from '../../_util/vue-types';
import BaseMixin from '../../_util/BaseMixin'; import BaseMixin from '../../_util/BaseMixin';
import { getOptionProps, getListeners } from '../../_util/props-util'; import { getOptionProps } from '../../_util/props-util';
import addEventListener from '../../vc-util/Dom/addEventListener'; import addEventListener from '../../vc-util/Dom/addEventListener';
export default { export default {
name: 'Handle', name: 'Handle',
mixins: [BaseMixin], mixins: [BaseMixin],
inheritAttrs: false,
props: { props: {
prefixCls: PropTypes.string, prefixCls: PropTypes.string,
vertical: PropTypes.bool, vertical: PropTypes.bool,
@ -16,7 +17,6 @@ export default {
max: PropTypes.number, max: PropTypes.number,
value: PropTypes.number, value: PropTypes.number,
tabindex: PropTypes.number, tabindex: PropTypes.number,
className: PropTypes.string,
reverse: PropTypes.bool, reverse: PropTypes.bool,
// handleFocus: PropTypes.func.def(noop), // handleFocus: PropTypes.func.def(noop),
// handleBlur: PropTypes.func.def(noop), // handleBlur: PropTypes.func.def(noop),
@ -37,11 +37,14 @@ export default {
} }
}, },
methods: { methods: {
setHandleRef(node) {
this.handle = node;
},
setClickFocus(focused) { setClickFocus(focused) {
this.setState({ clickFocused: focused }); this.setState({ clickFocused: focused });
}, },
handleMouseUp() { handleMouseUp() {
if (document.activeElement === this.$refs.handle) { if (document.activeElement === this.handle) {
this.setClickFocus(true); this.setClickFocus(true);
} }
}, },
@ -57,10 +60,10 @@ export default {
this.focus(); this.focus();
}, },
focus() { focus() {
this.$refs.handle.focus(); this.handle.focus();
}, },
blur() { blur() {
this.$refs.handle.blur(); this.handle.blur();
}, },
// when click can not focus in vue, use mousedown trigger focus // when click can not focus in vue, use mousedown trigger focus
handleMousedown(e) { handleMousedown(e) {
@ -80,7 +83,7 @@ export default {
value, value,
tabindex, tabindex,
} = getOptionProps(this); } = getOptionProps(this);
const className = classNames(this.$props.className, { const className = classNames(this.$attrs.class, {
[`${prefixCls}-handle-click-focused`]: this.clickFocused, [`${prefixCls}-handle-click-focused`]: this.clickFocused,
}); });
@ -102,26 +105,26 @@ export default {
'aria-valuenow': value, 'aria-valuenow': value,
'aria-disabled': !!disabled, 'aria-disabled': !!disabled,
}; };
const elStyle = {
...this.$attrs.style,
...positionStyle,
};
let _tabIndex = tabindex || 0; let _tabIndex = tabindex || 0;
if (disabled || tabindex === null) { if (disabled || tabindex === null) {
_tabIndex = null; _tabIndex = null;
} }
const handleProps = { const handleProps = {
attrs: { ...this.$attrs,
role: 'slider', role: 'slider',
tabindex: _tabIndex, tabindex: _tabIndex,
...ariaProps, ...ariaProps,
},
class: className, class: className,
on: { onBlur: this.handleBlur,
...getListeners(this), onKeydown: this.handleKeyDown,
blur: this.handleBlur, onMousedown: this.handleMousedown,
keydown: this.handleKeyDown, ref: this.setHandleRef,
mousedown: this.handleMousedown, style: elStyle,
},
ref: 'handle',
style: positionStyle,
}; };
return <div {...handleProps} />; return <div {...handleProps} />;
}, },

View File

@ -38,6 +38,7 @@ const rangeProps = {
}; };
const Range = { const Range = {
name: 'Range', name: 'Range',
inheritAttrs: false,
displayName: 'Range', displayName: 'Range',
mixins: [BaseMixin], mixins: [BaseMixin],
props: initDefaultProps(rangeProps, { props: initDefaultProps(rangeProps, {
@ -407,7 +408,7 @@ const Range = {
_tabIndex = null; _tabIndex = null;
} }
return handleGenerator({ return handleGenerator({
className: classNames({ class: classNames({
[handleClassName]: true, [handleClassName]: true,
[`${handleClassName}-${i + 1}`]: true, [`${handleClassName}-${i + 1}`]: true,
}), }),
@ -423,16 +424,9 @@ const Range = {
reverse, reverse,
disabled, disabled,
style: handleStyle[i], style: handleStyle[i],
directives: [ ref: h => this.saveHandle(i, h),
{ onFocus: this.onFocus,
name: 'ant-ref', onBlur: this.onBlur,
value: h => this.saveHandle(i, h),
},
],
on: {
focus: this.onFocus,
blur: this.onBlur,
},
}); });
}); });

View File

@ -1,5 +1,4 @@
import PropTypes from '../../_util/vue-types'; import PropTypes from '../../_util/vue-types';
import warning from '../../_util/warning';
import BaseMixin from '../../_util/BaseMixin'; import BaseMixin from '../../_util/BaseMixin';
import { hasProp } from '../../_util/props-util'; import { hasProp } from '../../_util/props-util';
import Track from './common/Track'; import Track from './common/Track';
@ -8,6 +7,7 @@ import * as utils from './utils';
const Slider = { const Slider = {
name: 'Slider', name: 'Slider',
inheritAttrs: false,
mixins: [BaseMixin], mixins: [BaseMixin],
props: { props: {
defaultValue: PropTypes.number, defaultValue: PropTypes.number,
@ -22,17 +22,6 @@ const Slider = {
data() { data() {
const defaultValue = this.defaultValue !== undefined ? this.defaultValue : this.min; const defaultValue = this.defaultValue !== undefined ? this.defaultValue : this.min;
const value = this.value !== undefined ? this.value : defaultValue; const value = this.value !== undefined ? this.value : defaultValue;
warning(
!hasProp(this, 'minimumTrackStyle'),
'Slider',
'minimumTrackStyle will be deprecate, please use trackStyle instead.',
);
warning(
!hasProp(this, 'maximumTrackStyle'),
'Slider',
'maximumTrackStyle will be deprecate, please use railStyle instead.',
);
return { return {
sValue: this.trimAlignValue(value), sValue: this.trimAlignValue(value),
dragging: false, dragging: false,
@ -170,7 +159,7 @@ const Slider = {
const { sValue, dragging } = this; const { sValue, dragging } = this;
const offset = this.calcOffset(sValue); const offset = this.calcOffset(sValue);
const handles = handleGenerator({ const handles = handleGenerator({
className: `${prefixCls}-handle`, class: `${prefixCls}-handle`,
prefixCls, prefixCls,
vertical, vertical,
offset, offset,
@ -183,16 +172,9 @@ const Slider = {
index: 0, index: 0,
tabindex, tabindex,
style: handleStyle[0] || handleStyle, style: handleStyle[0] || handleStyle,
directives: [ ref: h => this.saveHandle(0, h),
{ onFocus: this.onFocus,
name: 'ant-ref', onBlur: this.onBlur,
value: h => this.saveHandle(0, h),
},
],
on: {
focus: this.onFocus,
blur: this.onBlur,
},
}); });
const _trackStyle = trackStyle[0] || trackStyle; const _trackStyle = trackStyle[0] || trackStyle;

View File

@ -1,73 +1,71 @@
import classNames from 'classnames'; import classNames from 'classnames';
import { isValidElement } from '../../../_util/props-util'; import { isValidElement } from '../../../_util/props-util';
const Marks = { const Marks = (_, { attrs }) => {
functional: true, const {
render(h, context) { className,
const { vertical,
className, reverse,
vertical, marks,
reverse, included,
marks, upperBound,
included, lowerBound,
upperBound, max,
lowerBound, min,
max, onClickLabel,
min, } = attrs;
} = context.props; const marksKeys = Object.keys(marks);
const { clickLabel } = context.listeners;
const marksKeys = Object.keys(marks);
const range = max - min; const range = max - min;
const elements = marksKeys const elements = marksKeys
.map(parseFloat) .map(parseFloat)
.sort((a, b) => a - b) .sort((a, b) => a - b)
.map(point => { .map(point => {
const markPoint = typeof marks[point] === 'function' ? marks[point](h) : marks[point]; const markPoint = typeof marks[point] === 'function' ? marks[point](h) : marks[point];
const markPointIsObject = typeof markPoint === 'object' && !isValidElement(markPoint); const markPointIsObject = typeof markPoint === 'object' && !isValidElement(markPoint);
const markLabel = markPointIsObject ? markPoint.label : markPoint; const markLabel = markPointIsObject ? markPoint.label : markPoint;
if (!markLabel && markLabel !== 0) { if (!markLabel && markLabel !== 0) {
return null; return null;
} }
const isActive = const isActive =
(!included && point === upperBound) || (!included && point === upperBound) ||
(included && point <= upperBound && point >= lowerBound); (included && point <= upperBound && point >= lowerBound);
const markClassName = classNames({ const markClassName = classNames({
[`${className}-text`]: true, [`${className}-text`]: true,
[`${className}-text-active`]: isActive, [`${className}-text-active`]: isActive,
});
const bottomStyle = {
marginBottom: '-50%',
[reverse ? 'top' : 'bottom']: `${((point - min) / range) * 100}%`,
};
const leftStyle = {
transform: `translateX(-50%)`,
msTransform: `translateX(-50%)`,
[reverse ? 'right' : 'left']: reverse
? `${((point - min / 4) / range) * 100}%`
: `${((point - min) / range) * 100}%`,
};
const style = vertical ? bottomStyle : leftStyle;
const markStyle = markPointIsObject ? { ...style, ...markPoint.style } : style;
return (
<span
class={markClassName}
style={markStyle}
key={point}
onMousedown={e => clickLabel(e, point)}
onTouchstart={e => clickLabel(e, point)}
>
{markLabel}
</span>
);
}); });
return <div class={className}>{elements}</div>; const bottomStyle = {
}, marginBottom: '-50%',
[reverse ? 'top' : 'bottom']: `${((point - min) / range) * 100}%`,
};
const leftStyle = {
transform: `translateX(-50%)`,
msTransform: `translateX(-50%)`,
[reverse ? 'right' : 'left']: reverse
? `${((point - min / 4) / range) * 100}%`
: `${((point - min) / range) * 100}%`,
};
const style = vertical ? bottomStyle : leftStyle;
const markStyle = markPointIsObject ? { ...style, ...markPoint.style } : style;
return (
<span
class={markClassName}
style={markStyle}
key={point}
onMousedown={e => onClickLabel(e, point)}
onTouchstart={e => onClickLabel(e, point)}
>
{markLabel}
</span>
);
});
return <div class={className}>{elements}</div>;
}; };
Marks.inheritAttrs = false;
export default Marks; export default Marks;

View File

@ -20,49 +20,47 @@ const calcPoints = (vertical, marks, dots, step, min, max) => {
return points; return points;
}; };
const Steps = { const Steps = (_, { attrs }) => {
functional: true, const {
render(h, context) { prefixCls,
const { vertical,
prefixCls, reverse,
vertical, marks,
reverse, dots,
marks, step,
dots, included,
step, lowerBound,
included, upperBound,
lowerBound, max,
upperBound, min,
max, dotStyle,
min, activeDotStyle,
dotStyle, } = attrs;
activeDotStyle, const range = max - min;
} = context.props; const elements = calcPoints(vertical, marks, dots, step, min, max).map(point => {
const range = max - min; const offset = `${(Math.abs(point - min) / range) * 100}%`;
const elements = calcPoints(vertical, marks, dots, step, min, max).map(point => {
const offset = `${(Math.abs(point - min) / range) * 100}%`;
const isActived = const isActived =
(!included && point === upperBound) || (!included && point === upperBound) ||
(included && point <= upperBound && point >= lowerBound); (included && point <= upperBound && point >= lowerBound);
let style = vertical let style = vertical
? { ...dotStyle, [reverse ? 'top' : 'bottom']: offset } ? { ...dotStyle, [reverse ? 'top' : 'bottom']: offset }
: { ...dotStyle, [reverse ? 'right' : 'left']: offset }; : { ...dotStyle, [reverse ? 'right' : 'left']: offset };
if (isActived) { if (isActived) {
style = { ...style, ...activeDotStyle }; style = { ...style, ...activeDotStyle };
} }
const pointClassName = classNames({ const pointClassName = classNames({
[`${prefixCls}-dot`]: true, [`${prefixCls}-dot`]: true,
[`${prefixCls}-dot-active`]: isActived, [`${prefixCls}-dot-active`]: isActived,
[`${prefixCls}-dot-reverse`]: reverse, [`${prefixCls}-dot-reverse`]: reverse,
});
return <span class={pointClassName} style={style} key={point} />;
}); });
return <div class={`${prefixCls}-step`}>{elements}</div>; return <span class={pointClassName} style={style} key={point} />;
}, });
return <div class={`${prefixCls}-step`}>{elements}</div>;
}; };
Steps.inheritAttrs = false;
export default Steps; export default Steps;

View File

@ -1,28 +1,25 @@
/* eslint-disable */ /* eslint-disable */
const Track = { const Track = (_, { attrs }) => {
functional: true, const { included, vertical, offset, length, reverse, style, class: className } = attrs;
render(h, context) {
const { included, vertical, offset, length, reverse } = context.props;
const { style, class: className } = context.data;
const positonStyle = vertical const positonStyle = vertical
? { ? {
[reverse ? 'top' : 'bottom']: `${offset}%`, [reverse ? 'top' : 'bottom']: `${offset}%`,
[reverse ? 'bottom' : 'top']: 'auto', [reverse ? 'bottom' : 'top']: 'auto',
height: `${length}%`, height: `${length}%`,
} }
: { : {
[reverse ? 'right' : 'left']: `${offset}%`, [reverse ? 'right' : 'left']: `${offset}%`,
[reverse ? 'left' : 'right']: 'auto', [reverse ? 'left' : 'right']: 'auto',
width: `${length}%`, width: `${length}%`,
}; };
const elStyle = { const elStyle = {
...style, ...style,
...positonStyle, ...positonStyle,
}; };
return included ? <div class={className} style={elStyle} /> : null; return included ? <div class={className} style={elStyle} /> : null;
},
}; };
Track.inheritAttrs = false;
export default Track; export default Track;

View File

@ -2,7 +2,7 @@ import classNames from 'classnames';
import PropTypes from '../../../_util/vue-types'; import PropTypes from '../../../_util/vue-types';
import addEventListener from '../../../vc-util/Dom/addEventListener'; import addEventListener from '../../../vc-util/Dom/addEventListener';
import warning from '../../../_util/warning'; import warning from '../../../_util/warning';
import { initDefaultProps } from '../../../_util/props-util'; import { initDefaultProps, getSlot } from '../../../_util/props-util';
import Steps from './Steps'; import Steps from './Steps';
import Marks from './Marks'; import Marks from './Marks';
import Handle from '../Handle'; import Handle from '../Handle';
@ -35,11 +35,12 @@ export default function createSlider(Component) {
}; };
return { return {
name: 'createSlider', name: 'createSlider',
inheritAttrs: false,
mixins: [Component], mixins: [Component],
model: { // model: {
prop: 'value', // prop: 'value',
event: 'change', // event: 'change',
}, // },
props: initDefaultProps(propTypes, { props: initDefaultProps(propTypes, {
prefixCls: 'rc-slider', prefixCls: 'rc-slider',
min: 0, min: 0,
@ -73,7 +74,7 @@ export default function createSlider(Component) {
mounted() { mounted() {
this.$nextTick(() => { this.$nextTick(() => {
// Snapshot testing cannot handle refs, so be sure to null-check this. // Snapshot testing cannot handle refs, so be sure to null-check this.
this.document = this.$refs.sliderRef && this.$refs.sliderRef.ownerDocument; this.document = this.sliderRef && this.sliderRef.ownerDocument;
// this.setHandleRefs() // this.setHandleRefs()
const { autofocus, disabled } = this; const { autofocus, disabled } = this;
if (autofocus && !disabled) { if (autofocus && !disabled) {
@ -88,20 +89,16 @@ export default function createSlider(Component) {
}); });
}, },
methods: { methods: {
defaultHandle({ index, directives, className, style, on, ...restProps }) { defaultHandle({ index, directives, className, style, ...restProps }) {
delete restProps.dragging; delete restProps.dragging;
if (restProps.value === null) { if (restProps.value === null) {
return null; return null;
} }
const handleProps = { const handleProps = {
props: { ...restProps,
...restProps,
},
class: className, class: className,
style, style,
key: index, key: index,
directives,
on,
}; };
return <Handle {...handleProps} />; return <Handle {...handleProps} />;
}, },
@ -159,7 +156,7 @@ export default function createSlider(Component) {
} }
}, },
onMouseMove(e) { onMouseMove(e) {
if (!this.$refs.sliderRef) { if (!this.sliderRef) {
this.onEnd(); this.onEnd();
return; return;
} }
@ -167,7 +164,7 @@ export default function createSlider(Component) {
this.onMove(e, position - this.dragOffset); this.onMove(e, position - this.dragOffset);
}, },
onTouchMove(e) { onTouchMove(e) {
if (utils.isNotTouchEvent(e) || !this.$refs.sliderRef) { if (utils.isNotTouchEvent(e) || !this.sliderRef) {
this.onEnd(); this.onEnd();
return; return;
} }
@ -176,7 +173,7 @@ export default function createSlider(Component) {
this.onMove(e, position - this.dragOffset); this.onMove(e, position - this.dragOffset);
}, },
onKeyDown(e) { onKeyDown(e) {
if (this.$refs.sliderRef && utils.isEventFromHandle(e, this.handlesRefs)) { if (this.sliderRef && utils.isEventFromHandle(e, this.handlesRefs)) {
this.onKeyboard(e); this.onKeyboard(e);
} }
}, },
@ -186,7 +183,7 @@ export default function createSlider(Component) {
this.setState({ sValue: value }, () => this.onEnd(true)); this.setState({ sValue: value }, () => this.onEnd(true));
}, },
getSliderStart() { getSliderStart() {
const slider = this.$refs.sliderRef; const slider = this.sliderRef;
const { vertical, reverse } = this; const { vertical, reverse } = this;
const rect = slider.getBoundingClientRect(); const rect = slider.getBoundingClientRect();
if (vertical) { if (vertical) {
@ -195,7 +192,7 @@ export default function createSlider(Component) {
return window.pageXOffset + (reverse ? rect.right : rect.left); return window.pageXOffset + (reverse ? rect.right : rect.left);
}, },
getSliderLength() { getSliderLength() {
const slider = this.$refs.sliderRef; const slider = this.sliderRef;
if (!slider) { if (!slider) {
return 0; return 0;
} }
@ -252,11 +249,14 @@ export default function createSlider(Component) {
const ratio = (value - min) / (max - min); const ratio = (value - min) / (max - min);
return ratio * 100; return ratio * 100;
}, },
saveSlider(slider) {
this.sliderRef = slider;
},
saveHandle(index, handle) { saveHandle(index, handle) {
this.handlesRefs[index] = handle; this.handlesRefs[index] = handle;
}, },
}, },
render(h) { render() {
const { const {
prefixCls, prefixCls,
marks, marks,
@ -273,32 +273,29 @@ export default function createSlider(Component) {
dotStyle, dotStyle,
activeDotStyle, activeDotStyle,
} = this; } = this;
const { tracks, handles } = this.renderSlider(h); const { class: className, style } = this.$attrs;
const { tracks, handles } = this.renderSlider();
const sliderClassName = classNames(prefixCls, { const sliderClassName = classNames(prefixCls, className, {
[`${prefixCls}-with-marks`]: Object.keys(marks).length, [`${prefixCls}-with-marks`]: Object.keys(marks).length,
[`${prefixCls}-disabled`]: disabled, [`${prefixCls}-disabled`]: disabled,
[`${prefixCls}-vertical`]: vertical, [`${prefixCls}-vertical`]: vertical,
}); });
const markProps = { const markProps = {
props: { vertical,
vertical, marks,
marks, included,
included, lowerBound: this.getLowerBound(),
lowerBound: this.getLowerBound(), upperBound: this.getUpperBound(),
upperBound: this.getUpperBound(), max,
max, min,
min, reverse,
reverse, class: `${prefixCls}-mark`,
className: `${prefixCls}-mark`, onClickLabel: disabled ? noop : this.onClickMarkLabel,
},
on: {
clickLabel: disabled ? noop : this.onClickMarkLabel,
},
}; };
return ( return (
<div <div
ref="sliderRef" ref={this.saveSlider}
tabindex="-1" tabindex="-1"
class={sliderClassName} class={sliderClassName}
onTouchstart={disabled ? noop : this.onTouchStart} onTouchstart={disabled ? noop : this.onTouchStart}
@ -307,6 +304,7 @@ export default function createSlider(Component) {
onKeydown={disabled ? noop : this.onKeyDown} onKeydown={disabled ? noop : this.onKeyDown}
onFocus={disabled ? noop : this.onFocus} onFocus={disabled ? noop : this.onFocus}
onBlur={disabled ? noop : this.onBlur} onBlur={disabled ? noop : this.onBlur}
style={style}
> >
<div <div
class={`${prefixCls}-rail`} class={`${prefixCls}-rail`}
@ -333,7 +331,7 @@ export default function createSlider(Component) {
/> />
{handles} {handles}
<Marks {...markProps} /> <Marks {...markProps} />
{this.$slots.default} {getSlot(this)}
</div> </div>
); );
}, },

View File

@ -6,6 +6,8 @@ import Handle from './Handle';
export default function createSliderWithTooltip(Component) { export default function createSliderWithTooltip(Component) {
return { return {
name: 'SliderTooltip',
inheritAttrs: false,
mixins: [BaseMixin, Component], mixins: [BaseMixin, Component],
props: { props: {
...Component.props, ...Component.props,
@ -50,27 +52,19 @@ export default function createSliderWithTooltip(Component) {
} }
const tooltipProps = { const tooltipProps = {
props: { ...restTooltipProps,
...restTooltipProps, prefixCls,
prefixCls, overlay,
overlay, placement,
placement, visible: (!disabled && (this.visibles[index] || dragging)) || visible,
visible: (!disabled && (this.visibles[index] || dragging)) || visible,
},
key: index, key: index,
}; };
const handleProps = { const handleProps = {
props: { value,
value, ...restProps,
...restProps, onMouseenter: () => this.handleTooltipVisibleChange(index, true),
}, onMouseleave: () => this.handleTooltipVisibleChange(index, false),
on: { style: handleStyleWithIndex,
mouseenter: () => this.handleTooltipVisibleChange(index, true),
mouseleave: () => this.handleTooltipVisibleChange(index, false),
},
style: {
...handleStyleWithIndex,
},
}; };
return ( return (
@ -82,10 +76,8 @@ export default function createSliderWithTooltip(Component) {
}, },
render() { render() {
const componentProps = { const componentProps = {
props: { ...getOptionProps(this),
...getOptionProps(this), handle: this.handleWithTooltip,
handle: this.handleWithTooltip,
},
}; };
return <Component {...componentProps} />; return <Component {...componentProps} />;
}, },

View File

@ -1,9 +1,10 @@
import keyCode from '../../_util/KeyCode'; import keyCode from '../../_util/KeyCode';
import { findDOMNode } from '../../_util/props-util';
export function isEventFromHandle(e, handles) { export function isEventFromHandle(e, handles) {
try { try {
return Object.keys(handles).some( return Object.keys(handles).some(
key => e.target === handles[key].$el || e.target === handles[key], key => e.target === findDOMNode(handles[key]) || e.target === handles[key],
); );
} catch (error) { } catch (error) {
return false; return false;

View File

@ -6,7 +6,7 @@ import LazyRenderBox from './LazyRenderBox';
import animate from '../_util/css-animation'; import animate from '../_util/css-animation';
import BaseMixin from '../_util/BaseMixin'; import BaseMixin from '../_util/BaseMixin';
import { saveRef } from './utils'; import { saveRef } from './utils';
import { getListeners, splitAttrs, findDOMNode } from '../_util/props-util'; import { splitAttrs, findDOMNode } from '../_util/props-util';
export default { export default {
name: 'VCTriggerPopup', name: 'VCTriggerPopup',
@ -82,8 +82,8 @@ export default {
this.currentAlignClassName = currentAlignClassName; this.currentAlignClassName = currentAlignClassName;
popupDomNode.className = this.getClassName(currentAlignClassName); popupDomNode.className = this.getClassName(currentAlignClassName);
} }
const listeners = getListeners(this); const { onaAlign } = this.$attrs;
listeners.align && listeners.align(popupDomNode, align); onaAlign && onaAlign(popupDomNode, align);
}, },
// Record size if stretch needed // Record size if stretch needed

View File

@ -560,8 +560,8 @@ export default {
return action.indexOf('focus') !== -1 || hideAction.indexOf('blur') !== -1; return action.indexOf('focus') !== -1 || hideAction.indexOf('blur') !== -1;
}, },
forcePopupAlign() { forcePopupAlign() {
if (this.$data.sPopupVisible && this._component && this._component.$refs.alignInstance) { if (this.$data.sPopupVisible && this._component && this._component.alignInstance) {
this._component.$refs.alignInstance.forceAlign(); this._component.alignInstance.forceAlign();
} }
}, },
fireEvents(type, e) { fireEvents(type, e) {

View File

@ -4,7 +4,7 @@
</div> </div>
</template> </template>
<script> <script>
import demo from '../antdv-demo/docs/tree-select/demo/treeData'; import demo from '../antdv-demo/docs/slider/demo/basic';
export default { export default {
components: { components: {

View File

@ -30,6 +30,7 @@ import {
Tree, Tree,
TreeSelect, TreeSelect,
Transfer, Transfer,
Slider,
notification, notification,
message, message,
} from 'ant-design-vue'; } from 'ant-design-vue';
@ -80,4 +81,5 @@ app
.use(Tree) .use(Tree)
.use(TreeSelect) .use(TreeSelect)
.use(Transfer) .use(Transfer)
.use(Slider)
.mount('#app'); .mount('#app');

View File

@ -76,7 +76,7 @@
"@commitlint/config-conventional": "^8.0.0", "@commitlint/config-conventional": "^8.0.0",
"@octokit/rest": "^16.0.0", "@octokit/rest": "^16.0.0",
"@vue/cli-plugin-eslint": "^4.0.0", "@vue/cli-plugin-eslint": "^4.0.0",
"@vue/compiler-sfc": "^3.0.0-rc.1", "@vue/compiler-sfc": "^3.0.0-rc.2",
"@vue/server-test-utils": "1.0.0-beta.16", "@vue/server-test-utils": "1.0.0-beta.16",
"@vue/test-utils": "^2.0.0-alpha.6", "@vue/test-utils": "^2.0.0-alpha.6",
"acorn": "^7.0.0", "acorn": "^7.0.0",
@ -152,7 +152,7 @@
"terser-webpack-plugin": "^3.0.3", "terser-webpack-plugin": "^3.0.3",
"through2": "^3.0.0", "through2": "^3.0.0",
"url-loader": "^3.0.0", "url-loader": "^3.0.0",
"vue": "^3.0.0-rc.1", "vue": "^3.0.0-rc.2",
"vue-antd-md-loader": "^1.1.0", "vue-antd-md-loader": "^1.1.0",
"vue-clipboard2": "0.3.1", "vue-clipboard2": "0.3.1",
"vue-draggable-resizable": "^2.1.0", "vue-draggable-resizable": "^2.1.0",