mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
feat(react): add slider preview component (#710)
This commit is contained in:
@@ -15,3 +15,24 @@ export function getTimeSliderCSSVars(state: TimeSliderState): Record<string, str
|
||||
[SliderCSSVars.buffer]: `${state.bufferPercent.toFixed(3)}%`,
|
||||
};
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Slider Preview
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export type SliderPreviewOverflow = 'clamp' | 'visible';
|
||||
|
||||
/** Compute structural positioning styles for a slider preview element. */
|
||||
export function getSliderPreviewStyle(width: number, overflow: SliderPreviewOverflow) {
|
||||
const halfWidth = width / 2;
|
||||
|
||||
return {
|
||||
position: 'absolute',
|
||||
left:
|
||||
overflow === 'visible'
|
||||
? `calc(var(${SliderCSSVars.pointer}) - ${halfWidth}px)`
|
||||
: `min(max(0px, calc(var(${SliderCSSVars.pointer}) - ${halfWidth}px)), calc(100% - ${width}px))`,
|
||||
width: 'max-content',
|
||||
pointerEvents: 'none',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { createSliderState, createTimeSliderState } from '../../tests/test-helpers';
|
||||
import { getSliderCSSVars, getTimeSliderCSSVars } from '../slider-css-vars';
|
||||
import { getSliderCSSVars, getSliderPreviewStyle, getTimeSliderCSSVars } from '../slider-css-vars';
|
||||
|
||||
describe('getSliderCSSVars', () => {
|
||||
it('returns fill and pointer CSS vars with 3-decimal precision', () => {
|
||||
@@ -55,3 +55,36 @@ describe('getTimeSliderCSSVars', () => {
|
||||
expect(vars['--media-slider-buffer']).toBe('33.333%');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSliderPreviewStyle', () => {
|
||||
it('returns structural positioning properties', () => {
|
||||
const style = getSliderPreviewStyle(100, 'clamp');
|
||||
|
||||
expect(style.position).toBe('absolute');
|
||||
expect(style.width).toBe('max-content');
|
||||
expect(style.pointerEvents).toBe('none');
|
||||
});
|
||||
|
||||
it('clamps left within slider bounds by default', () => {
|
||||
const style = getSliderPreviewStyle(100, 'clamp');
|
||||
|
||||
expect(style.left).toContain('min(');
|
||||
expect(style.left).toContain('max(');
|
||||
expect(style.left).toContain('var(--media-slider-pointer)');
|
||||
expect(style.left).toContain('50px');
|
||||
expect(style.left).toContain('100px');
|
||||
});
|
||||
|
||||
it('uses unclamped calc when overflow is visible', () => {
|
||||
const style = getSliderPreviewStyle(100, 'visible');
|
||||
|
||||
expect(style.left).toBe('calc(var(--media-slider-pointer) - 50px)');
|
||||
expect(style.left).not.toContain('min(');
|
||||
});
|
||||
|
||||
it('handles zero width', () => {
|
||||
const style = getSliderPreviewStyle(0, 'clamp');
|
||||
|
||||
expect(style.left).toContain('0px');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user