refactor(slider): new theme

This commit is contained in:
07akioni 2021-01-07 16:14:53 +08:00
parent d611d173cd
commit 0832415f55
8 changed files with 267 additions and 239 deletions

View File

@ -4,9 +4,9 @@
:class="{
'n-slider--disabled': disabled,
'n-slider--active': active,
'n-slider--with-mark': marks,
[`n-${mergedTheme}-theme`]: mergedTheme
'n-slider--with-mark': marks
}"
:style="cssVars"
@keydown.right="handleKeyDownRight"
@keydown.left="handleKeyDownLeft"
>
@ -61,9 +61,7 @@
<div
v-if="mergedShowTooltip1"
class="n-slider-handle-indicator"
:class="{
[`n-${mergedTheme}-theme`]: mergedTheme
}"
:style="indicatorCssVars"
>
{{ handleValue1 }}
</div>
@ -99,9 +97,7 @@
<div
v-if="mergedShowTooltip2"
class="n-slider-handle-indicator"
:class="{
[`n-${mergedTheme}-theme`]: mergedTheme
}"
:style="indicatorCssVars"
>
{{ handleValue2 }}
</div>
@ -122,13 +118,14 @@
</template>
<script>
import { ref, toRef, computed, watch, nextTick } from 'vue'
import { ref, toRef, computed, watch, nextTick, defineComponent } from 'vue'
import { VBinder, VTarget, VFollower } from 'vueuc'
import { useIsMounted, useMergedState } from 'vooks'
import { on, off } from 'evtd'
import { configurable, themeable, useFormItem, withCssr } from '../../_mixins'
import styles from './styles'
import { useTheme, useFormItem, useConfig } from '../../_mixins'
import { warn, call, useAdjustedTo } from '../../_utils'
import { sliderLight } from '../styles'
import style from './styles/index.cssr.js'
function handleHandleMouseMove (e, handleIndex) {
const { width: handleWidth } = this.handleRef1.getBoundingClientRect()
@ -151,14 +148,13 @@ function handleHandleMouseMove (e, handleIndex) {
}
}
export default {
export default defineComponent({
name: 'Slider',
components: {
VBinder,
VTarget,
VFollower
},
mixins: [configurable, themeable, withCssr(styles)],
props: {
defaultValue: {
type: [Number, Array],
@ -220,6 +216,8 @@ export default {
}
},
setup (props) {
const themeRef = useTheme('Slider', 'Slider', style, sliderLight, props)
const uncontrolledValueRef = ref(props.defaultValue)
const controlledValueRef = toRef(props, 'value')
const mergedValueRef = useMergedState(
@ -255,6 +253,8 @@ export default {
return handleClicked1Ref.value || handleClicked2Ref.value
})
return {
...useConfig(props),
...useFormItem(props),
uncontrolledValue: uncontrolledValueRef,
mergedValue: mergedValueRef,
isMounted: useIsMounted(),
@ -277,7 +277,74 @@ export default {
railRef: ref(null),
followerRef1: ref(null),
followerRef2: ref(null),
...useFormItem(props)
indicatorCssVars: computed(() => {
const {
self: {
fontSize,
indicatorColor,
indicatorBoxShadow,
indicatorTextColor,
indicatorBorderRadius
}
} = themeRef.value
return {
'--font-size': fontSize,
'--indicator-border-radius': indicatorBorderRadius,
'--indicator-box-shadow': indicatorBoxShadow,
'--indicator-color': indicatorColor,
'--indicator-text-color': indicatorTextColor
}
}),
cssVars: computed(() => {
const {
self: {
railColor,
railColorHover,
fillColor,
fillColorHover,
handleColor,
dotColor,
dotColorModal,
handleBoxShadow,
handleBoxShadowHover,
handleBoxShadowActive,
handleBoxShadowFocus,
dotBorder,
dotBoxShadow,
railHeight,
handleSize,
dotHeight,
dotWidth,
dotBorderRadius,
fontSize,
dotBorderActive
},
common: { cubicBezierEaseInOut }
} = themeRef.value
return {
'--bezier': cubicBezierEaseInOut,
'--dot-border': dotBorder,
'--dot-border-active': dotBorderActive,
'--dot-border-radius': dotBorderRadius,
'--dot-box-shadow': dotBoxShadow,
'--dot-color': dotColor,
'--dot-color-modal': dotColorModal,
'--dot-height': dotHeight,
'--dot-width': dotWidth,
'--fill-color': fillColor,
'--fill-color-hover': fillColorHover,
'--font-size': fontSize,
'--handle-box-shadow': handleBoxShadow,
'--handle-box-shadow-active': handleBoxShadowActive,
'--handle-box-shadow-focus': handleBoxShadowFocus,
'--handle-box-shadow-hover': handleBoxShadowHover,
'--handle-color': handleColor,
'--handle-size': handleSize,
'--rail-color': railColor,
'--rail-color-hover': railColorHover,
'--rail-height': railHeight
}
})
}
},
computed: {
@ -756,5 +823,5 @@ export default {
}
}
}
}
})
</script>

View File

@ -0,0 +1,170 @@
import { cB, c, cM, cE, insideModal } from '../../../_utils/cssr'
import fadeInScaleUpTransition from '../../../_styles/transitions/fade-in-scale-up'
// vars:
// --bezier
// --dot-border
// --dot-border-active
// --dot-border-radius
// --dot-box-shadow
// --dot-color
// --dot-color-modal
// --dot-height
// --dot-width
// --fill-color
// --fill-color-hover
// --font-size
// --handle-box-shadow
// --handle-box-shadow-active
// --handle-box-shadow-focus
// --handle-box-shadow-hover
// --handle-color
// --handle-size
// --indicator-border-radius
// --indicator-box-shadow
// --indicator-color
// --indicator-text-color
// --rail-color
// --rail-color-hover
// --rail-height
export default c([
cB('slider', `
display: block;
padding: calc((var(--handle-size) - var(--rail-height)) / 2) 0;
position: relative;
z-index: 0;
width: 100%;
cursor: pointer;
`, [
cB('slider-marks', `
position: absolute;
top: 18px;
left: calc(var(--handle-size) / 2);
right: calc(var(--handle-size) / 2);
`, [
cB('slider-mark', {
position: 'absolute',
transform: 'translateX(-50%)'
})
]),
cM('with-mark', `
width: 100%;
margin: 8px 0 32px 0;
`),
c('&:hover', [
cB('slider-rail', {
backgroundColor: 'var(--rail-color-hover)'
}, [
cE('fill', {
backgroundColor: 'var(--fill-color-hover)'
})
]),
cB('slider-handle', {
boxShadow: 'var(--handle-box-shadow-hover)'
})
]),
cM('active', [
cB('slider-rail', {
backgroundColor: 'var(--rail-color-hover)'
}, [
cE('fill', {
backgroundColor: 'var(--fill-color-hover)'
})
]),
cB('slider-handle', {
boxShadow: 'var(--handle-box-shadow-hover)'
})
]),
cB('slider-rail', `
width: 100%;
position: relative;
height: var(--rail-height);
background-color: var(--rail-color);
transition: background-color .3s var(--bezier);
border-radius: calc(var(--rail-height) / 2);
`, [
cE('fill', `
position: absolute;
top: 0;
bottom: 0;
border-radius: calc(var(--rail-height) / 2);
transition: background-color .3s var(--bezier);
background-color: var(--fill-color);
`)
]),
cB('slider-handle', `
outline: none;
height: var(--handle-size);
width: var(--handle-size);
border-radius: 50%;
transition: box-shadow .2s var(--bezier), background-color .3s var(--bezier);
position: absolute;
top: 0;
transform: translateX(-50%);
overflow: hidden;
cursor: pointer;
background-color: var(--handle-color);
box-shadow: var(--handle-box-shadow);
`, [
c('&:hover', {
boxShadow: 'var(--handle-box-shadow-hover)'
}),
c('&:hover:focus', {
boxShadow: 'var(--handle-box-shadow-active)'
}),
c('&:focus', {
boxShadow: 'var(--handle-box-shadow-focus)'
})
]),
cB('slider-dots', `
position: absolute;
top: 50%;
left: calc(var(--handle-size) / 2);
right: calc(var(--handle-size) / 2);
`, [
cM('transition-disabled', [
cB('slider-dot', {
transition: 'none'
})
]),
cB('slider-dot', `
transition:
border-color .3s var(--bezier),
box-shadow .3s var(--bezier),
background-color .3s var(--bezier);
position: absolute;
transform: translateX(-50%) translateY(-50%);
height: var(--dot-height);
width: var(--dot-width);
border-radius: var(--dot-border-radius);
overflow: hidden;
box-sizing: border-box;
border: var(--dot-border);
background-color: var(--dot-color);
box-shadow: var(--dot-box-shadow);
`, [
cM('active', {
border: 'var(--dot-border-active)'
})
])
])
]),
cB('slider-handle-indicator', `
font-size: var(--font-size);
padding: 8px 12px;
margin-bottom: 12px;
border-radius: var(--indicator-border-radius);
color: var(--indicator-text-color);
background-color: var(--indicator-color);
box-shadow: var(--indicator-box-shadow);
`, [
fadeInScaleUpTransition()
]),
insideModal(
cB('slider', [
cB('slider-dot', {
backgroundColor: 'var(--dot-color-modal)'
})
])
)
])

View File

@ -1,9 +0,0 @@
import baseStyle from './themed-base.cssr.js'
export default [
{
key: 'mergedTheme',
watch: ['mergedTheme'],
CNode: baseStyle
}
]

View File

@ -1,198 +0,0 @@
import { cTB, c, cB, cM, cE, insideModal } from '../../../_utils/cssr'
import fadeInScaleUpTransition from '../../../_styles/transitions/fade-in-scale-up'
import { depx, pxfy } from 'seemly'
export default c([
({ props }) => {
const {
$local: {
railColor,
railColorHover,
fillColor,
fillColorHover,
handleColor,
dotColor,
dotColorModal,
handleBoxShadow,
handleBoxShadowHover,
handleBoxShadowActive,
handleBoxShadowFocus,
indicatorColor,
indicatorBoxShadow,
indicatorTextColor,
dotBorder,
dotBoxShadow,
railHeight,
handleSize,
dotHeight,
dotWidth,
dotBorderRadius,
indicatorBorderRadius,
fontSize,
dotBorderActive
},
$global: {
cubicBezierEaseInOut,
transformDebounceScale
}
} = props
return [
cTB('slider', {
raw: `
display: block;
padding: calc((${handleSize} - ${railHeight}) / 2) 0;
position: relative;
z-index: 0;
width: 100%;
cursor: pointer;
`
}, [
cB('slider-marks', {
raw: `
position: absolute;
top: 18px;
left: calc(${handleSize} / 2);
right: calc(${handleSize} / 2);
`
}, [
cB('slider-mark', {
position: 'absolute',
transform: 'translateX(-50%)'
})
]),
cM('with-mark', {
raw: `
width: 100%;
margin: 8px 0 32px 0;
`
}),
c('&:hover', [
cB('slider-rail', {
backgroundColor: railColorHover
}, [
cE('fill', {
backgroundColor: fillColorHover
})
]),
cB('slider-handle', {
boxShadow: handleBoxShadowHover
})
]),
cM('active', [
cB('slider-rail', {
backgroundColor: railColorHover
}, [
cE('fill', {
backgroundColor: fillColorHover
})
]),
cB('slider-handle', {
boxShadow: handleBoxShadowHover
})
]),
cB('slider-rail', {
width: '100%',
position: 'relative',
height: railHeight,
backgroundColor: railColor,
transition: `background-color .3s ${cubicBezierEaseInOut}`,
borderRadius: pxfy(depx(railHeight) / 2)
}, [
cE('fill', {
raw: `
position: absolute;
top: 0;
bottom: 0;
border-radius: ${pxfy(depx(railHeight) / 2)};
transition: background-color .3s ${cubicBezierEaseInOut};
`,
backgroundColor: fillColor
})
]),
cB('slider-handle', {
raw: `
outline: none;
height: ${handleSize};
width: ${handleSize};
border-radius: 50%;
transition: box-shadow .2s ${cubicBezierEaseInOut}, background-color .3s ${cubicBezierEaseInOut};
position: absolute;
top: 0;
transform: translateX(-50%);
overflow: hidden;
cursor: pointer;
`,
backgroundColor: handleColor,
boxShadow: handleBoxShadow
}, [
c('&:hover', {
boxShadow: handleBoxShadowHover
}),
c('&:hover:focus', {
boxShadow: handleBoxShadowActive
}),
c('&:focus', {
boxShadow: handleBoxShadowFocus
})
]),
cB('slider-dots', {
raw: `
position: absolute;
top: 50%;
left: calc(${handleSize} / 2);
right: calc(${handleSize} / 2);
`
}, [
cM('transition-disabled', [
cB('slider-dot', {
transition: 'none'
})
]),
cB('slider-dot', {
raw: `
transition:
border-color .3s ${cubicBezierEaseInOut},
box-shadow .3s ${cubicBezierEaseInOut},
background-color .3s ${cubicBezierEaseInOut};
position: absolute;
transform: translateX(-50%) translateY(-50%);
height: ${dotHeight};
width: ${dotWidth};
border-radius: ${dotBorderRadius};
overflow: hidden;
box-sizing: border-box;
`,
border: dotBorder,
backgroundColor: dotColor,
boxShadow: dotBoxShadow
}, [
cM('active', {
border: dotBorderActive
})
])
])
]),
cTB('slider-handle-indicator', {
raw: `
transform: ${transformDebounceScale};
font-size: ${fontSize};
padding: 8px 12px;
margin-bottom: 12px;
`,
borderRadius: indicatorBorderRadius,
color: indicatorTextColor,
backgroundColor: indicatorColor,
boxShadow: indicatorBoxShadow
}, [
fadeInScaleUpTransition()
]),
insideModal(
cTB('slider', [
cB('slider-dot', {
backgroundColor: dotColorModal
})
])
)
]
}
])

View File

@ -1,12 +1,10 @@
import create from '../../_styles/utils/create-component-base'
import sizeVariables from './_common'
import { baseDark } from '../../_styles/base'
import { commonDark } from '../../_styles/new-common'
export default create({
export default {
name: 'Slider',
theme: 'dark',
peer: [baseDark],
getLocalVars (vars) {
common: commonDark,
self (vars) {
const boxShadow = '0 2px 8px 0 rgba(0, 0, 0, 0.12)'
const {
railColorOverlay,
@ -41,4 +39,4 @@ export default create({
dotBoxShadow: null
}
}
})
}

View File

@ -1,12 +1,10 @@
import create from '../../_styles/utils/create-component-base'
import sizeVariables from './_common'
import { baseLight } from '../../_styles/base'
import { commonLight } from '../../_styles/new-common'
export default create({
export default {
name: 'Slider',
theme: 'light',
peer: [baseLight],
getLocalVars (vars) {
common: commonLight,
self (vars) {
const indicatorColor = 'rgba(0, 0, 0, .85)'
const boxShadow = '0 2px 8px 0 rgba(0, 0, 0, 0.12)'
const {
@ -44,4 +42,4 @@ export default create({
dotBoxShadow: null
}
}
})
}

View File

@ -65,8 +65,8 @@ export { baseDark, baseLight } from './_styles/base'
// export { rateDark, rateLight } from './rate/styles'
// export { resultDark, resultLight } from './result/styles'
// export { scrollbarDark, scrollbarLight } from './scrollbar/styles'
export { selectDark, selectLight } from './select/styles'
export { sliderDark, sliderLight } from './slider/styles'
// export { selectDark, selectLight } from './select/styles'
// export { sliderDark, sliderLight } from './slider/styles'
export { spaceDark, spaceLight } from './space/styles'
export { spinDark, spinLight } from './spin/styles'
export { statisticDark, statisticLight } from './statistic/styles'

View File

@ -47,6 +47,7 @@ import { radioDark } from './radio/styles'
import { rateDark } from './rate/styles'
import { resultDark } from './result/styles'
import { scrollbarDark } from './scrollbar/styles'
import { sliderDark } from './slider/styles'
export const darkTheme = {
common: commonDark,
@ -97,5 +98,6 @@ export const darkTheme = {
Radio: radioDark,
Rate: rateDark,
Result: resultDark,
Scrollbar: scrollbarDark
Scrollbar: scrollbarDark,
Slider: sliderDark
}