add vc-slider-demo

pull/9/head
wangxueliang 7 years ago
parent d3a59a5aae
commit 12bd8af6fc

@ -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}
>
<Handle {...handleProps} />
</Tooltip>
)
}
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 (
<Tooltip
{...tooltipProps}
>
<Handle
{...handleProps}
/>
</Tooltip>
)
}
const wrapperStyle = 'width: 400px; margin: 50px'
return (
@ -44,10 +106,10 @@ export default {
<p>Slider with custom handle</p>
<Slider min={0} max={20} defaultValue={3} handle={handle} />
</div>
{/* <div style={wrapperStyle}>
<div style={wrapperStyle}>
<p>Range with custom handle</p>
<Range min={0} max={20} defaultValue={[3, 10]} tipFormatter={value => `${value}%`} />
</div> */}
<Range min={0} max={20} defaultValue={[3, 10]} handle={handleRange} />
</div>
</div>
)
},

@ -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',
}

@ -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))
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 (
<Track
class={trackClassName}
vertical={vertical}
included={included}
offset={offsets[i - 1]}
length={offsets[i] - offsets[i - 1]}
style={trackStyle[index]}
key={i}
/>
)
})
},
renderSlider (h) {
const {
sHandle,
bounds,
prefixCls,
vertical,
included,
disabled,
min,
max,
handle: handleGenerator,
trackStyle,
handleStyle,
tabIndex,
} = this
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 offsets = bounds.map(v => this.calcOffset(v))
const tracks = bounds.slice(0, -1).map((_, index) => {
const i = index + 1
const trackClassName = classNames({
[`${prefixCls}-track`]: true,
[`${prefixCls}-track-${i}`]: true,
})
return (
<Track
className={trackClassName}
vertical={vertical}
included={included}
offset={offsets[i - 1]}
length={offsets[i] - offsets[i - 1]}
style={trackStyle[index]}
key={i}
/>
)
})
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, handles }
return {
tracks: this.getTrack({ bounds, prefixCls, vertical, included, offsets, trackStyle }),
handles,
}
},
},
}

@ -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,
}
},
},
}

@ -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 <Handle {...handleProps} />
@ -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,

@ -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 <Component {...this.$props} handle={this.handleWithTooltip} />
const componentProps = {
props: {
...getOptionProps(this),
handle: this.handleWithTooltip,
},
}
return <Component {...componentProps}/>
},
}
}

@ -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)
}
}
}
}

@ -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 [

Loading…
Cancel
Save