From 4a2226a0574e3b670602f76cd9c2ff4cea208075 Mon Sep 17 00:00:00 2001 From: Vitaly Rtishchev Date: Sun, 24 Sep 2023 12:37:17 +0400 Subject: [PATCH] [@mantine/core] SegmentedControl: Fix error when selected item removed from the data array (#4122) --- .../SegmentedControl.story.tsx | 20 +++++++++- .../SegmentedControl/SegmentedControl.tsx | 38 ++++++++++--------- 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/mantine-core/src/components/SegmentedControl/SegmentedControl.story.tsx b/src/mantine-core/src/components/SegmentedControl/SegmentedControl.story.tsx index 74504a827d3..0a14ca3c404 100644 --- a/src/mantine-core/src/components/SegmentedControl/SegmentedControl.story.tsx +++ b/src/mantine-core/src/components/SegmentedControl/SegmentedControl.story.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { SegmentedControl } from './SegmentedControl'; import { MantineThemeProvider } from '../../core'; @@ -77,3 +77,21 @@ export function FocusRingAlways() { ); } + +export function SelectedItemRemoved() { + const [value, setValue] = useState(''); + const [breakingThings, setBreakingThings] = useState(false); + + const dataList = + breakingThings === true ? ['1', '2', '3'].filter((elem) => elem !== '3') : ['1', '2', '3']; + + return ( +
+ + + +
+ ); +} diff --git a/src/mantine-core/src/components/SegmentedControl/SegmentedControl.tsx b/src/mantine-core/src/components/SegmentedControl/SegmentedControl.tsx index 96a8331dc39..f81f95009db 100644 --- a/src/mantine-core/src/components/SegmentedControl/SegmentedControl.tsx +++ b/src/mantine-core/src/components/SegmentedControl/SegmentedControl.tsx @@ -181,23 +181,27 @@ export const SegmentedControl = factory((_props, ref) = useEffect(() => { if (_value in refs.current && observerRef.current) { const element = refs.current[_value]; - const elementRect = element.getBoundingClientRect(); - const scaledValue = element.offsetWidth / elementRect.width; - const width = element.clientWidth * scaledValue || 0; - const height = element.clientHeight * scaledValue || 0; - - const offsetRight = - containerRect.width - element.parentElement!.offsetLeft + WRAPPER_PADDING - width; - const offsetLeft = element.parentElement!.offsetLeft - WRAPPER_PADDING; - - setActivePosition({ - width, - height, - translate: [ - dir === 'rtl' ? offsetRight * -1 : offsetLeft, - element.parentElement!.offsetTop - WRAPPER_PADDING, - ], - }); + if (element) { + const elementRect = element.getBoundingClientRect(); + const scaledValue = element.offsetWidth / elementRect.width; + const width = element.clientWidth * scaledValue || 0; + const height = element.clientHeight * scaledValue || 0; + + const offsetRight = + containerRect.width - element.parentElement!.offsetLeft + WRAPPER_PADDING - width; + const offsetLeft = element.parentElement!.offsetLeft - WRAPPER_PADDING; + + setActivePosition({ + width, + height, + translate: [ + dir === 'rtl' ? offsetRight * -1 : offsetLeft, + element.parentElement!.offsetTop - WRAPPER_PADDING, + ], + }); + } else { + setActivePosition({ width: 0, height: 0, translate: [0, 0] }); + } } }, [_value, containerRect, dir]);