From 4137f63ec78728105e3e659eed3ee10478bf6304 Mon Sep 17 00:00:00 2001 From: Jeroen Reumkens Date: Mon, 15 May 2023 16:38:02 +0200 Subject: [PATCH] CAL-1664: Improve flash of toggle group when rerendering (#8900) * CAL-1664: Improve flash of toggle group when rerendering, because active element moves into position. * Added back newline --- .../form/toggleGroup/ToggleGroup.tsx | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/packages/ui/components/form/toggleGroup/ToggleGroup.tsx b/packages/ui/components/form/toggleGroup/ToggleGroup.tsx index dfe1584f82..08f0d7a336 100644 --- a/packages/ui/components/form/toggleGroup/ToggleGroup.tsx +++ b/packages/ui/components/form/toggleGroup/ToggleGroup.tsx @@ -1,6 +1,6 @@ import * as RadixToggleGroup from "@radix-ui/react-toggle-group"; import type { ReactNode } from "react"; -import { useEffect, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { classNames } from "@calcom/lib"; import { Tooltip } from "@calcom/ui"; @@ -29,7 +29,7 @@ const OptionalTooltipWrapper = ({ export const ToggleGroup = ({ options, onValueChange, isFullWidth, ...props }: ToggleGroupProps) => { const [value, setValue] = useState(props.defaultValue); - const [activeToggleElement, setActiveToggleElement] = useState(null); + const activeRef = useRef(null); useEffect(() => { if (value && onValueChange) onValueChange(value); @@ -48,9 +48,15 @@ export const ToggleGroup = ({ options, onValueChange, isFullWidth, ...props }: T )}> {/* Active toggle. It's a separate element so we can animate it nicely. */} {options.map((option) => ( @@ -65,8 +71,12 @@ export const ToggleGroup = ({ options, onValueChange, isFullWidth, ...props }: T isFullWidth && "w-full" )} ref={(node) => { - if (node && value === option.value && activeToggleElement !== node) { - setActiveToggleElement(node); + if (node && value === option.value) { + // Sets position of active toggle element with inline styles. + // This way we trigger as little rerenders as possible. + if (!activeRef.current || activeRef?.current.style.left === `${node.offsetLeft}px`) return; + activeRef.current.style.left = `${node.offsetLeft}px`; + activeRef.current.style.width = `${node.offsetWidth}px`; } return node; }}>