|
@@ -4,6 +4,13 @@ import {RenderOptions} from '@tesseract-design/web-option-react'; |
|
|
import clsx from 'clsx'; |
|
|
import clsx from 'clsx'; |
|
|
import styles from './style.module.css'; |
|
|
import styles from './style.module.css'; |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
* Caveat for slider: |
|
|
|
|
|
* |
|
|
|
|
|
* Since sliders are not as customizable as other components, especially with orientations, prefer using sliders where |
|
|
|
|
|
* using horizontal sliders would be as acceptable as vertical sliders and vv. |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
export type SliderOrientation = 'horizontal' | 'vertical'; |
|
|
export type SliderOrientation = 'horizontal' | 'vertical'; |
|
|
|
|
|
|
|
|
type SliderDerivedElement = HTMLInputElement; |
|
|
type SliderDerivedElement = HTMLInputElement; |
|
@@ -56,7 +63,7 @@ export const Slider = React.forwardRef<SliderDerivedElement, SliderProps>(({ |
|
|
slider.setAttribute('orient', orient); |
|
|
slider.setAttribute('orient', orient); |
|
|
wrapper.dataset[browser] = orient; |
|
|
wrapper.dataset[browser] = orient; |
|
|
wrapper.removeAttribute('data-orient'); |
|
|
wrapper.removeAttribute('data-orient'); |
|
|
grandParent.style.width = '0px'; |
|
|
|
|
|
|
|
|
grandParent.style.width = children ? '2.5em' : '1em'; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return () => { |
|
|
return () => { |
|
@@ -67,7 +74,7 @@ export const Slider = React.forwardRef<SliderDerivedElement, SliderProps>(({ |
|
|
slider.removeAttribute('orient'); |
|
|
slider.removeAttribute('orient'); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
}, [ref, orient, browser]); |
|
|
|
|
|
|
|
|
}, [ref, orient, children, browser]); |
|
|
|
|
|
|
|
|
React.useEffect(() => { |
|
|
React.useEffect(() => { |
|
|
if (!(typeof ref === 'object' && ref)) { |
|
|
if (!(typeof ref === 'object' && ref)) { |
|
@@ -126,16 +133,41 @@ export const Slider = React.forwardRef<SliderDerivedElement, SliderProps>(({ |
|
|
Array.from(tickMarks).forEach((tickMarkRaw) => { |
|
|
Array.from(tickMarks).forEach((tickMarkRaw) => { |
|
|
const tickMark = tickMarkRaw as HTMLElement; |
|
|
const tickMark = tickMarkRaw as HTMLElement; |
|
|
const offset = tickMark.dataset.offset as string; |
|
|
const offset = tickMark.dataset.offset as string; |
|
|
|
|
|
const tickMarkWrapper = tickMark.children[0] as HTMLElement; |
|
|
|
|
|
const tickMarkLine = tickMarkWrapper.children[0] as HTMLElement; |
|
|
|
|
|
const tickMarkLabel = tickMarkLine.nextElementSibling as HTMLElement | null; |
|
|
if (isNotFirefox) { |
|
|
if (isNotFirefox) { |
|
|
tickMark.style.left = offset; |
|
|
tickMark.style.left = offset; |
|
|
tickMark.style.bottom = ''; |
|
|
tickMark.style.bottom = ''; |
|
|
|
|
|
tickMarkWrapper.style.translate = '-50%'; |
|
|
|
|
|
tickMarkWrapper.style.flexDirection = 'column'; |
|
|
|
|
|
tickMarkLine.style.width = '1px'; |
|
|
|
|
|
tickMarkLine.style.height = '0.5em'; |
|
|
|
|
|
if (tickMarkLabel) { |
|
|
|
|
|
tickMarkLabel.style.writingMode = 'initial'; |
|
|
|
|
|
} |
|
|
} else if (isFirefox && orient === 'horizontal') { |
|
|
} else if (isFirefox && orient === 'horizontal') { |
|
|
tickMark.style.left = offset; |
|
|
tickMark.style.left = offset; |
|
|
tickMark.style.bottom = ''; |
|
|
tickMark.style.bottom = ''; |
|
|
|
|
|
tickMarkWrapper.style.translate = '-50%'; |
|
|
|
|
|
tickMarkWrapper.style.flexDirection = 'column'; |
|
|
|
|
|
tickMarkLine.style.width = '1px'; |
|
|
|
|
|
tickMarkLine.style.height = '0.5em'; |
|
|
|
|
|
if (tickMarkLabel) { |
|
|
|
|
|
tickMarkLabel.style.writingMode = 'initial'; |
|
|
|
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
tickMark.style.bottom = offset; |
|
|
tickMark.style.bottom = offset; |
|
|
tickMark.style.left = ''; |
|
|
tickMark.style.left = ''; |
|
|
|
|
|
tickMarkWrapper.style.translate = '0 50%'; |
|
|
|
|
|
tickMarkWrapper.style.flexDirection = 'row'; |
|
|
|
|
|
tickMarkLine.style.width = '0.5em'; |
|
|
|
|
|
tickMarkLine.style.height = '1px'; |
|
|
|
|
|
if (tickMarkLabel) { |
|
|
|
|
|
tickMarkLabel.style.writingMode = 'sideways-lr'; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
console.log(tickMarkWrapper); |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
}, [ref, orient, browser]); |
|
|
}, [ref, orient, browser]); |
|
@@ -194,9 +226,7 @@ export const Slider = React.forwardRef<SliderDerivedElement, SliderProps>(({ |
|
|
)} |
|
|
)} |
|
|
/> |
|
|
/> |
|
|
{Array.isArray(children) && ( |
|
|
{Array.isArray(children) && ( |
|
|
<div className={clsx( |
|
|
|
|
|
styles['tick-mark-container'], |
|
|
|
|
|
)}> |
|
|
|
|
|
|
|
|
<div className="select-none"> |
|
|
<div className="relative w-full h-full"> |
|
|
<div className="relative w-full h-full"> |
|
|
{children.map((c) => ( |
|
|
{children.map((c) => ( |
|
|
<div |
|
|
<div |
|
@@ -207,17 +237,15 @@ export const Slider = React.forwardRef<SliderDerivedElement, SliderProps>(({ |
|
|
)} |
|
|
)} |
|
|
data-offset={`${(Number(c.props.value) - Number(min)) / (Number(max) - Number(min)) * 100}%`} |
|
|
data-offset={`${(Number(c.props.value) - Number(min)) / (Number(max) - Number(min)) * 100}%`} |
|
|
> |
|
|
> |
|
|
{/* TODO fix translateX */} |
|
|
|
|
|
<div |
|
|
<div |
|
|
className="flex flex-col text-xs items-center justify-between translate-x-[-50%] h-full" |
|
|
|
|
|
|
|
|
className="flex h-full text-xs items-center justify-between" |
|
|
> |
|
|
> |
|
|
<div |
|
|
<div |
|
|
className={clsx( |
|
|
|
|
|
'w-[1px] h-2', |
|
|
|
|
|
'bg-current', |
|
|
|
|
|
)} |
|
|
|
|
|
|
|
|
className="bg-current" |
|
|
/> |
|
|
/> |
|
|
{c.props.children} |
|
|
|
|
|
|
|
|
<div> |
|
|
|
|
|
{c.props.children} |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
))} |
|
|
))} |
|
|