feat: updates

This commit is contained in:
qier222 2022-05-29 17:53:27 +08:00
parent ffcc60b793
commit dd5361b8c4
No known key found for this signature in database
GPG key ID: 9C85007ED905F14D
106 changed files with 11989 additions and 4143 deletions

View file

@ -1,5 +1,5 @@
import { useRef, useState, useMemo, useCallback, useEffect } from 'react'
import cx from 'classnames'
import { cx } from '@emotion/css'
const Slider = ({
value,
@ -8,6 +8,8 @@ const Slider = ({
onChange,
onlyCallOnChangeAfterDragEnded = false,
orientation = 'horizontal',
alwaysShowTrack = false,
alwaysShowThumb = false,
}: {
value: number
min: number
@ -15,6 +17,8 @@ const Slider = ({
onChange: (value: number) => void
onlyCallOnChangeAfterDragEnded?: boolean
orientation?: 'horizontal' | 'vertical'
alwaysShowTrack?: boolean
alwaysShowThumb?: boolean
}) => {
const sliderRef = useRef<HTMLInputElement>(null)
const [isDragging, setIsDragging] = useState(false)
@ -29,24 +33,26 @@ const Slider = ({
* Get the value of the slider based on the position of the pointer
*/
const getNewValue = useCallback(
(val: number) => {
(pointer: { x: number; y: number }) => {
if (!sliderRef?.current) return 0
const sliderWidth = sliderRef.current.getBoundingClientRect().width
const newValue = (val / sliderWidth) * max
const slider = sliderRef.current.getBoundingClientRect()
const newValue =
orientation === 'horizontal'
? ((pointer.x - slider.x) / slider.width) * max
: ((slider.height - (pointer.y - slider.y)) / slider.height) * max
if (newValue < min) return min
if (newValue > max) return max
return newValue
},
[sliderRef, max, min]
[sliderRef, max, min, orientation]
)
/**
* Handle slider click event
*/
const handleClick = useCallback(
(e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
onChange(getNewValue(e.clientX))
},
(e: React.MouseEvent<HTMLDivElement>) =>
onChange(getNewValue({ x: e.clientX, y: e.clientY })),
[getNewValue, onChange]
)
@ -63,7 +69,7 @@ const Slider = ({
useEffect(() => {
const handlePointerMove = (e: { clientX: number; clientY: number }) => {
if (!isDragging) return
const newValue = getNewValue(e.clientX)
const newValue = getNewValue({ x: e.clientX, y: e.clientY })
onlyCallOnChangeAfterDragEnded
? setDraggingValue(newValue)
: onChange(newValue)
@ -109,32 +115,47 @@ const Slider = ({
/**
* Track and thumb styles
*/
const usedTrackStyle = useMemo(
() => ({ width: `${(memoedValue / max) * 100}%` }),
[max, memoedValue]
)
const thumbStyle = useMemo(
() => ({
left: `${(memoedValue / max) * 100}%`,
transform: `translateX(-10px)`,
}),
[max, memoedValue]
)
const usedTrackStyle = useMemo(() => {
const percentage = `${(memoedValue / max) * 100}%`
return orientation === 'horizontal'
? { width: percentage }
: { height: percentage }
}, [max, memoedValue, orientation])
const thumbStyle = useMemo(() => {
const percentage = `${(memoedValue / max) * 100}%`
return orientation === 'horizontal'
? { left: percentage }
: { bottom: percentage }
}, [max, memoedValue, orientation])
return (
<div
className='group flex h-2 -translate-y-[3px] items-center'
className={cx(
'group relative flex items-center',
orientation === 'horizontal' && 'h-2',
orientation === 'vertical' && 'h-full w-2 flex-col'
)}
ref={sliderRef}
onClick={handleClick}
>
{/* Track */}
<div className='absolute h-[2px] w-full bg-gray-500 bg-opacity-10'></div>
<div
className={cx(
'absolute bg-gray-500 bg-opacity-10',
orientation === 'horizontal' && 'h-[2px] w-full',
orientation === 'vertical' && 'h-full w-[2px]'
)}
></div>
{/* Passed track */}
<div
className={cx(
'absolute h-[2px] group-hover:bg-brand-500',
isDragging ? 'bg-brand-500' : 'bg-gray-300 dark:bg-gray-500'
'absolute group-hover:bg-brand-500',
isDragging || alwaysShowTrack
? 'bg-brand-500'
: 'bg-gray-300 dark:bg-gray-500',
orientation === 'horizontal' && 'h-[2px]',
orientation === 'vertical' && 'bottom-0 w-[2px]'
)}
style={usedTrackStyle}
></div>
@ -142,8 +163,12 @@ const Slider = ({
{/* Thumb */}
<div
className={cx(
'absolute flex h-5 w-5 items-center justify-center rounded-full bg-brand-500 bg-opacity-20 transition-opacity ',
isDragging ? 'opacity-100' : 'opacity-0 group-hover:opacity-100'
'absolute flex h-5 w-5 items-center justify-center rounded-full bg-brand-500 bg-opacity-20 transition-opacity',
isDragging || alwaysShowThumb
? 'opacity-100'
: 'opacity-0 group-hover:opacity-100',
orientation === 'horizontal' && '-translate-x-2.5',
orientation === 'vertical' && 'translate-y-2.5'
)}
style={thumbStyle}
onClick={e => e.stopPropagation()}