diff --git a/components/vc-slider/demo/handle.jsx b/components/vc-slider/demo/handle.jsx
index fd812ed61..b2af8e3ff 100644
--- a/components/vc-slider/demo/handle.jsx
+++ b/components/vc-slider/demo/handle.jsx
@@ -3,16 +3,22 @@ import Tooltip from '../../vc-tooltip'
import '../assets/index.less'
import '../../vc-tooltip/assets/bootstrap.less'
-const { createSliderWithTooltip, Handle } = Slider
-const Range = createSliderWithTooltip(Slider.Range)
+const { Handle, Range } = Slider
export default {
data () {
return {
+ visibles: [],
}
},
+ methods: {
+ handleTooltipVisibleChange (index, visible) {
+ this.visibles[index] = visible
+ this.visibles = { ...this.visibles }
+ },
+ },
render () {
- const handle = (props) => {
+ const handle = (h, props) => {
const { value, dragging, index, refStr, ...restProps } = props
const handleProps = {
props: {
@@ -32,10 +38,66 @@ export default {
placement='top'
key={index}
>
+
)
}
+
+ const handleRange = (h, { value, dragging, index, disabled, ...restProps }) => {
+ const tipFormatter = value => `${value}%`
+ const handleStyle = [{}]
+ const tipProps = {}
+
+ const {
+ prefixCls = 'rc-slider-tooltip',
+ overlay = tipFormatter(value),
+ placement = 'top',
+ visible = visible || false,
+ ...restTooltipProps } = tipProps
+
+ let handleStyleWithIndex
+ if (Array.isArray(handleStyle)) {
+ handleStyleWithIndex = handleStyle[index] || handleStyle[0]
+ } else {
+ handleStyleWithIndex = handleStyle
+ }
+
+ const tooltipProps = {
+ props: {
+ prefixCls,
+ overlay,
+ placement,
+ visible: (!disabled && (this.visibles[index] || dragging)) || visible,
+ ...restTooltipProps,
+ },
+ key: index,
+ }
+ const handleProps = {
+ props: {
+ value,
+ ...restProps,
+ },
+ on: {
+ mouseenter: () => this.handleTooltipVisibleChange(index, true),
+ mouseleave: () => this.handleTooltipVisibleChange(index, false),
+ },
+ style: {
+ ...handleStyleWithIndex,
+ },
+ }
+
+ return (
+
+
+
+
+ )
+ }
const wrapperStyle = 'width: 400px; margin: 50px'
return (
@@ -44,10 +106,10 @@ export default {
Slider with custom handle
- {/*
+
Range with custom handle
-
`${value}%`} />
- */}
+
+
)
},
diff --git a/components/vc-slider/src/Handle.jsx b/components/vc-slider/src/Handle.jsx
index 4d8d7c800..b8386d59f 100644
--- a/components/vc-slider/src/Handle.jsx
+++ b/components/vc-slider/src/Handle.jsx
@@ -1,8 +1,12 @@
import PropTypes from '../../_util/vue-types'
import addEventListener from '../../_util/Dom/addEventListener'
import BaseMixin from '../../_util/BaseMixin'
+import { getOptionProps } from '../../_util/props-util'
+
+function noop () {}
export default {
+ name: 'Handle',
mixins: [BaseMixin],
props: {
prefixCls: PropTypes.string,
@@ -14,6 +18,8 @@ export default {
value: PropTypes.number,
tabIndex: PropTypes.number,
refStr: PropTypes.any,
+ handleFocus: PropTypes.func.def(noop),
+ handleBlur: PropTypes.func.def(noop),
},
data () {
return {
@@ -22,6 +28,8 @@ export default {
},
mounted () {
this.$nextTick(() => {
+ // mouseup won't trigger if mouse moved out of handle,
+ // so we listen on document here.
this.onMouseUpListener = addEventListener(document, 'mouseup', this.handleMouseUp)
this.refStr = this.$props.refStr
})
@@ -42,8 +50,12 @@ export default {
this.setClickFocus(true)
}
},
- handleBlur () {
+ onBlur (e) {
this.setClickFocus(false)
+ this.handleBlur(e)
+ },
+ onFocus (e) {
+ this.handleFocus(e)
},
handleKeyDown () {
this.setClickFocus(false)
@@ -61,8 +73,8 @@ export default {
},
render () {
const {
- prefixCls, vertical, offset, disabled, min, max, value, tabIndex, refStr, ...restProps
- } = this.$props
+ prefixCls, vertical, offset, disabled, min, max, value, tabIndex, refStr,
+ } = getOptionProps(this)
const className = {
[`${prefixCls}-handle`]: true,
@@ -89,13 +101,14 @@ export default {
tabIndex: disabled ? null : (tabIndex || 0),
refStr,
...ariaProps,
- ...restProps,
},
style: elStyle,
class: className,
on: {
- blur: this.handleBlur,
+ blur: this.onBlur,
+ focus: this.onFocus,
keydown: this.handleKeyDown,
+ ...this.$listeners,
},
ref: 'handle',
}
diff --git a/components/vc-slider/src/Range.jsx b/components/vc-slider/src/Range.jsx
index f0cfa1ce2..1d3c0797c 100644
--- a/components/vc-slider/src/Range.jsx
+++ b/components/vc-slider/src/Range.jsx
@@ -19,6 +19,7 @@ const rangeProps = {
tabIndex: PropTypes.arrayOf(PropTypes.number),
}
const Range = {
+ name: 'Range',
displayName: 'Range',
mixins: [BaseMixin],
props: initDefaultProps(rangeProps, {
@@ -39,7 +40,7 @@ const Range = {
const bounds = value.map((v, i) => this.trimAlignValue(v, i))
const recent = bounds[0] === max ? 0 : bounds.length - 1
return {
- handle: null,
+ sHandle: null,
recent,
bounds,
}
@@ -86,7 +87,7 @@ const Range = {
if (isNotControlled) {
this.setState(state)
} else if (state.handle !== undefined) {
- this.setState({ handle: state.handle })
+ this.setState({ sHandle: state.handle })
}
const data = { ...this.$data, ...state }
@@ -103,7 +104,7 @@ const Range = {
this.prevMovedHandleIndex = this.getBoundNeedMoving(value, closestBound)
this.setState({
- handle: this.prevMovedHandleIndex,
+ sHandle: this.prevMovedHandleIndex,
recent: this.prevMovedHandleIndex,
})
@@ -115,14 +116,15 @@ const Range = {
this.$emit('change', { bounds: nextBounds })
},
onEnd () {
+ this.setState({ sHandle: null })
this.removeDocumentEvents()
this.$emit('afterChange', this.bounds)
},
onMove (e, position) {
utils.pauseEvent(e)
- const { bounds, handle } = this
+ const { bounds, sHandle } = this
const value = this.calcValueByPos(position)
- const oldValue = bounds[handle]
+ const oldValue = bounds[sHandle]
if (value === oldValue) return
this.moveTo(value)
@@ -132,8 +134,8 @@ const Range = {
if (valueMutator) {
utils.pauseEvent(e)
- const { bounds, handle } = this
- const oldValue = bounds[handle]
+ const { bounds, sHandle } = this
+ const oldValue = bounds[sHandle]
const mutatedValue = valueMutator(oldValue, this.$props)
const value = this.trimAlignValue(mutatedValue)
if (value === oldValue) return
@@ -194,18 +196,18 @@ const Range = {
return this._getPointsCache.points
},
moveTo (value, isFromKeyboardEvent) {
- const { bounds, handle } = this
+ const { bounds, sHandle } = this
const nextBounds = [...bounds]
- nextBounds[handle] = value
- let nextHandle = handle
+ nextBounds[sHandle] = value
+ let nextHandle = sHandle
if (this.pushable !== false) {
this.pushSurroundingHandles(nextBounds, nextHandle)
} else if (this.allowCross) {
nextBounds.sort((a, b) => a - b)
nextHandle = nextBounds.indexOf(value)
}
- this.$emit('change', {
- handle: nextHandle,
+ this.onChange({
+ sHandle: nextHandle,
bounds: nextBounds,
})
if (isFromKeyboardEvent) {
@@ -276,7 +278,7 @@ const Range = {
return true
},
trimAlignValue (v, handle, nextProps = {}) {
- const mergedProps = { ...this, ...nextProps }
+ const mergedProps = { ...this.$props, ...nextProps }
const valInRange = utils.ensureValueInRange(v, mergedProps)
const valNotConflict = this.ensureValueNotConflict(handle, valInRange, mergedProps)
return utils.ensureValuePrecision(valNotConflict, mergedProps)
@@ -284,7 +286,7 @@ const Range = {
ensureValueNotConflict (handle, val, { allowCross, pushable: thershold }) {
const state = this.$data || {}
const { bounds } = state
- handle = handle === undefined ? state.handle : handle
+ handle = handle === undefined ? state.sHandle : handle
thershold = Number(thershold)
/* eslint-disable eqeqeq */
if (!allowCross && handle != null && bounds !== undefined) {
@@ -298,65 +300,71 @@ const Range = {
/* eslint-enable eqeqeq */
return val
},
- },
- render () {
- const {
- handle,
- bounds,
- prefixCls,
- vertical,
- included,
- disabled,
- min,
- max,
- handle: handleGenerator,
- trackStyle,
- handleStyle,
- tabIndex,
- } = this
-
- const offsets = bounds.map(v => this.calcOffset(v))
-
- const handleClassName = `${prefixCls}-handle`
- const handles = bounds.map((v, i) => handleGenerator({
- className: classNames({
- [handleClassName]: true,
- [`${handleClassName}-${i + 1}`]: true,
- }),
- prefixCls,
- vertical,
- offset: offsets[i],
- value: v,
- dragging: handle === i,
- index: i,
- tabIndex: tabIndex[i] || 0,
- min,
- max,
- disabled,
- style: handleStyle[i],
- refStr: 'handleRef' + i,
- }))
-
- const tracks = bounds.slice(0, -1).map((_, index) => {
- const i = index + 1
- const trackClassName = classNames({
- [`${prefixCls}-track`]: true,
- [`${prefixCls}-track-${i}`]: true,
+ getTrack ({ bounds, prefixCls, vertical, included, offsets, trackStyle }) {
+ return bounds.slice(0, -1).map((_, index) => {
+ const i = index + 1
+ const trackClassName = classNames({
+ [`${prefixCls}-track`]: true,
+ [`${prefixCls}-track-${i}`]: true,
+ })
+ return (
+
+ )
})
- return (
-
- )
- })
+ },
+ renderSlider (h) {
+ const {
+ sHandle,
+ bounds,
+ prefixCls,
+ vertical,
+ included,
+ disabled,
+ min,
+ max,
+ handle: handleGenerator,
+ trackStyle,
+ handleStyle,
+ tabIndex,
+ } = this
- return { tracks, handles }
+ const offsets = bounds.map(v => this.calcOffset(v))
+
+ const handleClassName = `${prefixCls}-handle`
+ const handles = bounds.map((v, i) => handleGenerator(h, {
+ className: classNames({
+ [handleClassName]: true,
+ [`${handleClassName}-${i + 1}`]: true,
+ }),
+ prefixCls,
+ vertical,
+ offset: offsets[i],
+ value: v,
+ dragging: sHandle === i,
+ index: i,
+ tabIndex: tabIndex[i] || 0,
+ min,
+ max,
+ disabled,
+ style: handleStyle[i],
+ refStr: 'handleRef' + i,
+ handleFocus: this.onFocus,
+ handleBlur: this.onBlur,
+ }))
+
+ return {
+ tracks: this.getTrack({ bounds, prefixCls, vertical, included, offsets, trackStyle }),
+ handles,
+ }
+ },
},
}
diff --git a/components/vc-slider/src/Slider.jsx b/components/vc-slider/src/Slider.jsx
index bf7c90b44..f8bbe4587 100644
--- a/components/vc-slider/src/Slider.jsx
+++ b/components/vc-slider/src/Slider.jsx
@@ -7,6 +7,7 @@ import createSlider from './common/createSlider'
import * as utils from './utils'
const Slider = {
+ name: 'Slider',
mixins: [BaseMixin],
props: {
defaultValue: PropTypes.number,
@@ -151,43 +152,45 @@ const Slider = {
/>
)
},
- },
- render () {
- const {
- prefixCls,
- vertical,
- included,
- disabled,
- minimumTrackStyle,
- trackStyle,
- handleStyle,
- tabIndex,
- min,
- max,
- handle: handleGenerator,
- } = this
- const { sValue, dragging } = this
- const offset = this.calcOffset(sValue)
- const handle = handleGenerator({
- prefixCls,
- vertical,
- offset,
- value: sValue,
- dragging,
- disabled,
- min,
- max,
- index: 0,
- tabIndex,
- style: handleStyle[0] || handleStyle,
- refStr: 'handleRef0',
- })
+ renderSlider (h) {
+ const {
+ prefixCls,
+ vertical,
+ included,
+ disabled,
+ minimumTrackStyle,
+ trackStyle,
+ handleStyle,
+ tabIndex,
+ min,
+ max,
+ handle: handleGenerator,
+ } = this
+ const { sValue, dragging } = this
+ const offset = this.calcOffset(sValue)
+ const handle = handleGenerator(h, {
+ prefixCls,
+ vertical,
+ offset,
+ value: sValue,
+ dragging,
+ disabled,
+ min,
+ max,
+ index: 0,
+ tabIndex,
+ style: handleStyle[0] || handleStyle,
+ refStr: 'handleRef0',
+ handleFocus: this.onFocus,
+ handleBlur: this.onBlur,
+ })
- const _trackStyle = trackStyle[0] || trackStyle
- return {
- tracks: this.getTrack({ prefixCls, vertical, included, offset, minimumTrackStyle, _trackStyle }),
- handles: handle,
- }
+ const _trackStyle = trackStyle[0] || trackStyle
+ return {
+ tracks: this.getTrack({ prefixCls, vertical, included, offset, minimumTrackStyle, _trackStyle }),
+ handles: handle,
+ }
+ },
},
}
diff --git a/components/vc-slider/src/common/createSlider.jsx b/components/vc-slider/src/common/createSlider.jsx
index d8fb0f244..23ca08b78 100644
--- a/components/vc-slider/src/common/createSlider.jsx
+++ b/components/vc-slider/src/common/createSlider.jsx
@@ -34,6 +34,7 @@ export default function createSlider (Component) {
autoFocus: PropTypes.bool,
}
return {
+ name: 'createSlider',
mixins: [Component],
props: initDefaultProps(propTypes, {
...Component.defaultProps,
@@ -42,7 +43,7 @@ export default function createSlider (Component) {
max: 100,
step: 1,
marks: {},
- handle ({ index, refStr, ...restProps }) {
+ handle (h, { index, refStr, className, ...restProps }) {
delete restProps.dragging
const handleProps = {
props: {
@@ -51,6 +52,7 @@ export default function createSlider (Component) {
attrs: {
refStr,
},
+ class: className,
key: index,
}
return
@@ -167,8 +169,11 @@ export default function createSlider (Component) {
/* eslint-enable no-unused-expressions */
},
onMouseUp () {
- if (this.handlesRefs[this.prevMovedHandleIndex]) {
- this.handlesRefs[this.prevMovedHandleIndex].clickFocus()
+ if (this.$children && this.$children[this.prevMovedHandleIndex]) {
+ const handleCom = utils.getComponentProps(this.$children[this.prevMovedHandleIndex], 'clickFocus')
+ if (handleCom) {
+ handleCom.clickFocus()
+ }
}
},
onMouseMove (e) {
@@ -239,7 +244,7 @@ export default function createSlider (Component) {
this.$emit('change', { value })
},
},
- render () {
+ render (h) {
const {
prefixCls,
marks,
@@ -255,7 +260,7 @@ export default function createSlider (Component) {
dotStyle,
activeDotStyle,
} = this
- const { tracks, handles } = Component.render.call(this)
+ const { tracks, handles } = this.renderSlider(h)
const sliderClassName = classNames(prefixCls, {
[`${prefixCls}-with-marks`]: Object.keys(marks).length,
diff --git a/components/vc-slider/src/createSliderWithTooltip.jsx b/components/vc-slider/src/createSliderWithTooltip.jsx
index a315eceb5..93e11c4af 100644
--- a/components/vc-slider/src/createSliderWithTooltip.jsx
+++ b/components/vc-slider/src/createSliderWithTooltip.jsx
@@ -1,11 +1,12 @@
import PropTypes from '../../_util/vue-types'
import BaseMixin from '../../_util/BaseMixin'
import Tooltip from '../../vc-tooltip'
+import { getOptionProps } from '../../_util/props-util'
import Handle from './Handle'
export default function createSliderWithTooltip (Component) {
return {
- mixins: [BaseMixin],
+ mixins: [BaseMixin, Component],
props: {
tipFormatter: PropTypes.func.def((value) => { return value }),
handleStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.arrayOf(PropTypes.object)]).def([{}]),
@@ -85,7 +86,13 @@ export default function createSliderWithTooltip (Component) {
},
},
render () {
- return
+ const componentProps = {
+ props: {
+ ...getOptionProps(this),
+ handle: this.handleWithTooltip,
+ },
+ }
+ return
},
}
}
diff --git a/components/vc-slider/src/utils.js b/components/vc-slider/src/utils.js
index 170f2ccf1..594af75bd 100644
--- a/components/vc-slider/src/utils.js
+++ b/components/vc-slider/src/utils.js
@@ -89,3 +89,18 @@ export function getKeyboardValueMutator (e) {
default: return undefined
}
}
+
+export function getComponentProps (obj, prop) {
+ if (obj[prop]) {
+ return obj
+ } else if (obj.$children.length) {
+ const len = obj.$children.length
+ for (let i = 0; i < len; i++) {
+ if (obj.$children[i][prop]) {
+ return obj.$children[i]
+ } else if (obj.$children[i].$children.length) {
+ return getComponentProps(obj.$children[i], prop)
+ }
+ }
+ }
+}
diff --git a/examples/routes.js b/examples/routes.js
index 9ea148250..136f1b381 100644
--- a/examples/routes.js
+++ b/examples/routes.js
@@ -3,7 +3,7 @@ const AsyncComp = () => {
const hashs = window.location.hash.split('/')
const d = hashs[hashs.length - 1]
return {
- component: import(`../components/vc-table/demo/${d}`),
+ component: import(`../components/vc-slider/demo/${d}`),
}
}
export default [