mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
fix(html): slider interaction and edge alignment broken (#721)
This commit is contained in:
@@ -72,6 +72,7 @@ export function useSlider<State extends SliderState = SliderState>(
|
||||
getStepPercent: () => optionsRef.current.getStepPercent(),
|
||||
getLargeStepPercent: () => optionsRef.current.getLargeStepPercent(),
|
||||
commitThrottle: optionsRef.current.commitThrottle,
|
||||
adjustPercent: optionsRef.current.adjustPercent,
|
||||
onValueChange: (percent) => optionsRef.current.onValueChange?.(percent),
|
||||
onValueCommit: (percent) => optionsRef.current.onValueCommit?.(percent),
|
||||
onDragStart: () => optionsRef.current.onDragStart?.(),
|
||||
@@ -98,23 +99,8 @@ export function useSlider<State extends SliderState = SliderState>(
|
||||
}
|
||||
}, [state.thumbAlignment]);
|
||||
|
||||
// Adjust CSS var percents for edge thumb alignment when DOM elements are available.
|
||||
const rootEl = rootElementRef.current;
|
||||
const thumbEl = thumbElementRef.current;
|
||||
let cssState = state;
|
||||
|
||||
if (state.thumbAlignment === 'edge' && rootEl && thumbEl && options.adjustPercent) {
|
||||
const isHorizontal = state.orientation === 'horizontal';
|
||||
const thumbSize = isHorizontal ? thumbEl.offsetWidth : thumbEl.offsetHeight;
|
||||
const trackSize = isHorizontal ? rootEl.offsetWidth : rootEl.offsetHeight;
|
||||
cssState = {
|
||||
...state,
|
||||
fillPercent: options.adjustPercent(state.fillPercent, thumbSize, trackSize),
|
||||
pointerPercent: options.adjustPercent(state.pointerPercent, thumbSize, trackSize),
|
||||
};
|
||||
}
|
||||
|
||||
const cssVars = options.getCSSVars(cssState);
|
||||
// Adjust CSS var percents for edge thumb alignment using live DOM measurements.
|
||||
const cssVars = options.getCSSVars(slider.adjustForAlignment(state));
|
||||
|
||||
// Ref callbacks for root and thumb elements.
|
||||
const rootRef = useCallback((element: HTMLElement | null) => {
|
||||
|
||||
@@ -36,6 +36,7 @@ const { mockSliderApi } = vi.hoisted(() => ({
|
||||
onFocus: vi.fn(),
|
||||
onBlur: vi.fn(),
|
||||
},
|
||||
adjustForAlignment: <S,>(state: S): S => state,
|
||||
destroy: vi.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
@@ -27,6 +27,7 @@ const { mockSliderApi, mockThumbnailApi } = vi.hoisted(() => ({
|
||||
onFocus: vi.fn(),
|
||||
onBlur: vi.fn(),
|
||||
},
|
||||
adjustForAlignment: <S,>(state: S): S => state,
|
||||
destroy: vi.fn(),
|
||||
}),
|
||||
mockThumbnailApi: () => ({
|
||||
|
||||
@@ -10,7 +10,11 @@ import { SliderTrack } from '../slider-track';
|
||||
import { SliderValue } from '../slider-value';
|
||||
|
||||
const { mockSliderApi } = vi.hoisted(() => ({
|
||||
mockSliderApi: () => ({
|
||||
mockSliderApi: (options?: {
|
||||
getElement?: () => HTMLElement;
|
||||
getThumbElement?: () => HTMLElement | null;
|
||||
adjustPercent?: (raw: number, thumb: number, track: number) => number;
|
||||
}) => ({
|
||||
input: {
|
||||
current: {
|
||||
pointerPercent: 0,
|
||||
@@ -31,6 +35,22 @@ const { mockSliderApi } = vi.hoisted(() => ({
|
||||
onFocus: vi.fn(),
|
||||
onBlur: vi.fn(),
|
||||
},
|
||||
adjustForAlignment<
|
||||
S extends { thumbAlignment?: string; orientation?: string; fillPercent: number; pointerPercent: number },
|
||||
>(state: S): S {
|
||||
if (!options?.adjustPercent || state.thumbAlignment !== 'edge') return state;
|
||||
const thumbEl = options.getThumbElement?.();
|
||||
if (!thumbEl) return state;
|
||||
const rootEl = options.getElement!();
|
||||
const isHorizontal = state.orientation === 'horizontal';
|
||||
const thumbSize = isHorizontal ? thumbEl.offsetWidth : thumbEl.offsetHeight;
|
||||
const trackSize = isHorizontal ? rootEl.offsetWidth : rootEl.offsetHeight;
|
||||
return {
|
||||
...state,
|
||||
fillPercent: options.adjustPercent(state.fillPercent, thumbSize, trackSize),
|
||||
pointerPercent: options.adjustPercent(state.pointerPercent, thumbSize, trackSize),
|
||||
};
|
||||
},
|
||||
destroy: vi.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
@@ -34,6 +34,7 @@ const { mockSliderApi, mockTimeState, mockBufferState } = vi.hoisted(() => ({
|
||||
onFocus: vi.fn(),
|
||||
onBlur: vi.fn(),
|
||||
},
|
||||
adjustForAlignment: <S,>(state: S): S => state,
|
||||
destroy: vi.fn(),
|
||||
}),
|
||||
mockTimeState: {
|
||||
|
||||
@@ -33,6 +33,7 @@ const { mockSliderApi, mockVolumeState } = vi.hoisted(() => ({
|
||||
onFocus: vi.fn(),
|
||||
onBlur: vi.fn(),
|
||||
},
|
||||
adjustForAlignment: <S,>(state: S): S => state,
|
||||
destroy: vi.fn(),
|
||||
}),
|
||||
mockVolumeState: {
|
||||
|
||||
Reference in New Issue
Block a user