From 8ac53373e3c99fa811202905095667d20d9bdd83 Mon Sep 17 00:00:00 2001 From: Ian Sanders Date: Wed, 19 Apr 2023 15:01:56 -0400 Subject: [PATCH 1/4] Fix `useDynamicTextareaHeight` initial render with slots --- src/drafts/hooks/useDynamicTextareaHeight.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/drafts/hooks/useDynamicTextareaHeight.ts b/src/drafts/hooks/useDynamicTextareaHeight.ts index 0eba40c0970..ac835820038 100644 --- a/src/drafts/hooks/useDynamicTextareaHeight.ts +++ b/src/drafts/hooks/useDynamicTextareaHeight.ts @@ -1,4 +1,4 @@ -import {RefObject, useLayoutEffect, useState} from 'react' +import {RefObject, useCallback, useLayoutEffect, useState} from 'react' import {SxProp} from '../../sx' import {getCharacterCoordinates} from '../utils/character-coordinates' @@ -32,7 +32,7 @@ export const useDynamicTextareaHeight = ({ const [minHeight, setMinHeight] = useState(undefined) const [maxHeight, setMaxHeight] = useState(undefined) - useLayoutEffect(() => { + const refreshHeight = useCallback(() => { const element = elementRef.current if (!element) return @@ -58,5 +58,12 @@ export const useDynamicTextareaHeight = ({ // `value` is an unnecessary dependency but it enables us to recalculate as the user types }, [minHeightLines, maxHeightLines, value, elementRef]) + useLayoutEffect(refreshHeight, [refreshHeight]) + + // With Slots, initial render of the component is delayed and so the initial layout effect can occur + // before the target element has actually been calculated in the DOM. But if we only use regular effects, + // there will be a visible flash on initial render when not using slots + useEffect(refreshHeight, []) + return {height, minHeight, maxHeight, boxSizing: 'content-box'} } From 1f6a6606352bc83f7193ed3759ade5379610ab6e Mon Sep 17 00:00:00 2001 From: Ian Sanders Date: Wed, 19 Apr 2023 15:08:57 -0400 Subject: [PATCH 2/4] Create pink-papayas-relate.md --- .changeset/pink-papayas-relate.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/pink-papayas-relate.md diff --git a/.changeset/pink-papayas-relate.md b/.changeset/pink-papayas-relate.md new file mode 100644 index 00000000000..86ec2997696 --- /dev/null +++ b/.changeset/pink-papayas-relate.md @@ -0,0 +1,5 @@ +--- +"@primer/react": patch +--- + +Fix `useDynamicTextareaHeight` initial render with slots From 7ef86e7ccc8d7c637c0b47738bb5be89498c8e5a Mon Sep 17 00:00:00 2001 From: Ian Sanders Date: Thu, 20 Apr 2023 16:41:50 +0000 Subject: [PATCH 3/4] Fix lint errors --- src/drafts/hooks/useDynamicTextareaHeight.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/drafts/hooks/useDynamicTextareaHeight.ts b/src/drafts/hooks/useDynamicTextareaHeight.ts index ac835820038..d0fcdaa94b6 100644 --- a/src/drafts/hooks/useDynamicTextareaHeight.ts +++ b/src/drafts/hooks/useDynamicTextareaHeight.ts @@ -1,4 +1,4 @@ -import {RefObject, useCallback, useLayoutEffect, useState} from 'react' +import {RefObject, useCallback, useEffect, useLayoutEffect, useState} from 'react' import {SxProp} from '../../sx' import {getCharacterCoordinates} from '../utils/character-coordinates' @@ -56,6 +56,7 @@ export const useDynamicTextareaHeight = ({ if (minHeightLines !== undefined) setMinHeight(`calc(${minHeightLines} * ${lineHeight})`) if (maxHeightLines !== undefined) setMaxHeight(`calc(${maxHeightLines} * ${lineHeight})`) // `value` is an unnecessary dependency but it enables us to recalculate as the user types + // eslint-disable-next-line react-hooks/exhaustive-deps }, [minHeightLines, maxHeightLines, value, elementRef]) useLayoutEffect(refreshHeight, [refreshHeight]) @@ -63,6 +64,7 @@ export const useDynamicTextareaHeight = ({ // With Slots, initial render of the component is delayed and so the initial layout effect can occur // before the target element has actually been calculated in the DOM. But if we only use regular effects, // there will be a visible flash on initial render when not using slots + // eslint-disable-next-line react-hooks/exhaustive-deps useEffect(refreshHeight, []) return {height, minHeight, maxHeight, boxSizing: 'content-box'} From acf606fbad237c00defe952abe317559e596e65a Mon Sep 17 00:00:00 2001 From: Josh Black Date: Tue, 20 Jun 2023 11:13:45 -0500 Subject: [PATCH 4/4] chore: run format --- src/drafts/hooks/useDynamicTextareaHeight.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drafts/hooks/useDynamicTextareaHeight.ts b/src/drafts/hooks/useDynamicTextareaHeight.ts index 790f3f0c0f2..b6a1b2c44e0 100644 --- a/src/drafts/hooks/useDynamicTextareaHeight.ts +++ b/src/drafts/hooks/useDynamicTextareaHeight.ts @@ -60,7 +60,7 @@ export const useDynamicTextareaHeight = ({ if (minHeightLines !== undefined) setMinHeight(`calc(${minHeightLines} * ${lineHeight})`) if (maxHeightLines !== undefined) setMaxHeight(`calc(${maxHeightLines} * ${lineHeight})`) // `value` is an unnecessary dependency but it enables us to recalculate as the user types - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [minHeightLines, maxHeightLines, value, elementRef, disabled]) useLayoutEffect(refreshHeight, [refreshHeight])