From 05eeced6aff1e54e00cd20e3f37b3aa2efaff6bd Mon Sep 17 00:00:00 2001 From: jingzouzou <827088092@qq.com> Date: Sun, 3 Nov 2024 15:40:23 +0800 Subject: [PATCH] fix: active bar always offset 1px --- src/PickerInput/Selector/RangeSelector.tsx | 24 +++++++++++++++++----- src/PickerInput/Selector/util.ts | 6 +++++- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/PickerInput/Selector/RangeSelector.tsx b/src/PickerInput/Selector/RangeSelector.tsx index 067b06e77..a5e36e80e 100644 --- a/src/PickerInput/Selector/RangeSelector.tsx +++ b/src/PickerInput/Selector/RangeSelector.tsx @@ -9,6 +9,7 @@ import useRootProps from './hooks/useRootProps'; import Icon, { ClearIcon } from './Icon'; import Input, { type InputRef } from './Input'; import { getoffsetUnit, getRealPlacement } from '../../utils/uiUtil'; +import { getWin } from './util'; export type SelectorIdType = | string @@ -184,13 +185,26 @@ function RangeSelector( const syncActiveOffset = useEvent(() => { const input = getInput(activeIndex); if (input) { - const { offsetWidth, offsetLeft, offsetParent } = input.nativeElement; - const parentWidth = (offsetParent as HTMLElement)?.offsetWidth || 0; - const activeOffset = placementRight ? parentWidth - offsetWidth - offsetLeft : offsetLeft; + const { offsetParent } = input.nativeElement; + // offsetLeft is an integer, which will cause incorrect reulst. + const { x = 0, width: inputWidth = 0 } = input.nativeElement.getBoundingClientRect() || {}; + const { x: pX = 0, width: parentWidth = 0 } = offsetParent?.getBoundingClientRect() || {}; + const parentStyles = + offsetParent && getWin(offsetParent as HTMLElement).getComputedStyle(offsetParent); + const parentBorderRightWidth = Number( + (placementRight ? parentStyles?.borderRightWidth : parentStyles?.borderLeftWidth)?.replace( + 'px', + '', + ) || 0, + ); + const offsetLeft = x - pX; + + const activeOffset = placementRight ? parentWidth - inputWidth - offsetLeft : offsetLeft; setActiveBarStyle(({ position }) => ({ position, - width: offsetWidth, - [offsetUnit]: activeOffset, + width: inputWidth, + // parent will have border while focus, so need to cut `parentBorderWidth` on opposite side. + [offsetUnit]: activeOffset - parentBorderRightWidth, })); onActiveOffset(activeOffset); } diff --git a/src/PickerInput/Selector/util.ts b/src/PickerInput/Selector/util.ts index 245b3dcc8..4eb7a6af8 100644 --- a/src/PickerInput/Selector/util.ts +++ b/src/PickerInput/Selector/util.ts @@ -12,4 +12,8 @@ export function getMaskRange(key: string): [startVal: number, endVal: number, de }; return PresetRange[key]; -} \ No newline at end of file +} + +export function getWin(ele: HTMLElement) { + return ele.ownerDocument.defaultView; +}