From af5c1cc445b5f66830d386a5c6376a9cc61fd202 Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Tue, 10 Dec 2024 15:19:05 -0800 Subject: [PATCH 01/20] Initial diff from Jolt. --- .../spectacle/src/components/typography.tsx | 3 +- .../components/typography/fit-text.test.tsx | 28 +++++++++++ .../src/components/typography/fit-text.tsx | 46 +++++++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 packages/spectacle/src/components/typography/fit-text.test.tsx create mode 100644 packages/spectacle/src/components/typography/fit-text.tsx diff --git a/packages/spectacle/src/components/typography.tsx b/packages/spectacle/src/components/typography.tsx index 3e67c9206..29902396e 100644 --- a/packages/spectacle/src/components/typography.tsx +++ b/packages/spectacle/src/components/typography.tsx @@ -121,5 +121,6 @@ export { UnorderedList, ListItem, Link, - CodeSpan + CodeSpan, + FitText }; diff --git a/packages/spectacle/src/components/typography/fit-text.test.tsx b/packages/spectacle/src/components/typography/fit-text.test.tsx new file mode 100644 index 000000000..21b8e8e32 --- /dev/null +++ b/packages/spectacle/src/components/typography/fit-text.test.tsx @@ -0,0 +1,28 @@ +import { render } from '@testing-library/react'; +import { ThemeProvider } from 'styled-components'; +import defaultTheme from '../../theme/default-theme'; +import { FitText } from './fit-text'; + +const mountWithTheme = (tree: React.ReactElement) => { + return render( + {tree} + ); +}; + +describe('', () => { + it('should render text content', () => { + const { getByText } = mountWithTheme( + Spectacle! + ); + expect(getByText('Spectacle!')).toBeInTheDocument(); + }); + + it('should maintain text color from props', () => { + const { getByText } = mountWithTheme( + Colored Text + ); + expect(getByText('Colored Text')).toHaveStyle({ + color: defaultTheme.colors.secondary + }); + }); +}); \ No newline at end of file diff --git a/packages/spectacle/src/components/typography/fit-text.tsx b/packages/spectacle/src/components/typography/fit-text.tsx new file mode 100644 index 000000000..3c06ed856 --- /dev/null +++ b/packages/spectacle/src/components/typography/fit-text.tsx @@ -0,0 +1,46 @@ +import { FC, useRef, useState } from 'react'; +import styled from 'styled-components'; +import useResizeObserver from 'use-resize-observer'; +import { Text } from '../typography'; +import { CommonTypographyProps } from '../typography'; + +const FitContainer = styled.div` + width: 100%; + display: flex; + align-items: center; + justify-content: center; +`; + +const ScalableText = styled(Text)<{ scale: number }>` + transform-origin: center left; + transform: scale(${props => props.scale}); + white-space: nowrap; + max-width: ${props => `${100 / props.scale}%`}; +`; + +export const FitText: FC = (props) => { + const containerRef = useRef(null); + const textRef = useRef(null); + const [scale, setScale] = useState(1); + + useResizeObserver({ + ref: containerRef, + onResize: () => { + if (!containerRef.current || !textRef.current) return; + + const containerWidth = containerRef.current.offsetWidth; + const textWidth = textRef.current.offsetWidth; + + if (textWidth === 0) return; + + const newScale = Math.min(containerWidth / textWidth, 1); + setScale(newScale); + } + }); + + return ( + + + + ); +}; \ No newline at end of file From 0c9fdb5c411b7058e78a505d10fe17505d7c67d1 Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Tue, 10 Dec 2024 15:20:08 -0800 Subject: [PATCH 02/20] Fix lint --- .../src/components/typography/fit-text.test.tsx | 10 +++------- .../spectacle/src/components/typography/fit-text.tsx | 12 ++++++------ 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/packages/spectacle/src/components/typography/fit-text.test.tsx b/packages/spectacle/src/components/typography/fit-text.test.tsx index 21b8e8e32..d70f55d82 100644 --- a/packages/spectacle/src/components/typography/fit-text.test.tsx +++ b/packages/spectacle/src/components/typography/fit-text.test.tsx @@ -4,16 +4,12 @@ import defaultTheme from '../../theme/default-theme'; import { FitText } from './fit-text'; const mountWithTheme = (tree: React.ReactElement) => { - return render( - {tree} - ); + return render({tree}); }; describe('', () => { it('should render text content', () => { - const { getByText } = mountWithTheme( - Spectacle! - ); + const { getByText } = mountWithTheme(Spectacle!); expect(getByText('Spectacle!')).toBeInTheDocument(); }); @@ -25,4 +21,4 @@ describe('', () => { color: defaultTheme.colors.secondary }); }); -}); \ No newline at end of file +}); diff --git a/packages/spectacle/src/components/typography/fit-text.tsx b/packages/spectacle/src/components/typography/fit-text.tsx index 3c06ed856..2f69d71a0 100644 --- a/packages/spectacle/src/components/typography/fit-text.tsx +++ b/packages/spectacle/src/components/typography/fit-text.tsx @@ -13,9 +13,9 @@ const FitContainer = styled.div` const ScalableText = styled(Text)<{ scale: number }>` transform-origin: center left; - transform: scale(${props => props.scale}); + transform: scale(${(props) => props.scale}); white-space: nowrap; - max-width: ${props => `${100 / props.scale}%`}; + max-width: ${(props) => `${100 / props.scale}%`}; `; export const FitText: FC = (props) => { @@ -27,12 +27,12 @@ export const FitText: FC = (props) => { ref: containerRef, onResize: () => { if (!containerRef.current || !textRef.current) return; - + const containerWidth = containerRef.current.offsetWidth; const textWidth = textRef.current.offsetWidth; - + if (textWidth === 0) return; - + const newScale = Math.min(containerWidth / textWidth, 1); setScale(newScale); } @@ -43,4 +43,4 @@ export const FitText: FC = (props) => { ); -}; \ No newline at end of file +}; From d96bbe67ea8830a7c81cd3d21ad922d298ca49bc Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Tue, 10 Dec 2024 15:25:40 -0800 Subject: [PATCH 03/20] Fix import --- packages/spectacle/src/components/typography.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/spectacle/src/components/typography.tsx b/packages/spectacle/src/components/typography.tsx index 29902396e..f7d212292 100644 --- a/packages/spectacle/src/components/typography.tsx +++ b/packages/spectacle/src/components/typography.tsx @@ -11,6 +11,7 @@ import { BorderProps } from 'styled-system'; import { FC, PropsWithChildren } from 'react'; +export { FitText } from './typography/fit-text'; const decoration = system({ textDecoration: true }); type DecorationProps = Pick; @@ -121,6 +122,5 @@ export { UnorderedList, ListItem, Link, - CodeSpan, - FitText + CodeSpan }; From 737a967ef24d73520a57838b7d0ae76d1a9f390d Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Tue, 10 Dec 2024 15:59:56 -0800 Subject: [PATCH 04/20] Broken: TS error any'ed but still doesn't work. --- examples/js/index.js | 4 ++++ packages/spectacle/src/components/typography/fit-text.tsx | 2 +- packages/spectacle/src/index.ts | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/examples/js/index.js b/examples/js/index.js index 2ae8f6ded..165f93b05 100644 --- a/examples/js/index.js +++ b/examples/js/index.js @@ -12,6 +12,7 @@ import { Slide, Deck, Text, + FitText, Grid, Box, Image, @@ -138,6 +139,9 @@ const Presentation = () => ( + + This is a FitText component + These diff --git a/packages/spectacle/src/components/typography/fit-text.tsx b/packages/spectacle/src/components/typography/fit-text.tsx index 2f69d71a0..4bc025aef 100644 --- a/packages/spectacle/src/components/typography/fit-text.tsx +++ b/packages/spectacle/src/components/typography/fit-text.tsx @@ -16,7 +16,7 @@ const ScalableText = styled(Text)<{ scale: number }>` transform: scale(${(props) => props.scale}); white-space: nowrap; max-width: ${(props) => `${100 / props.scale}%`}; -`; +` as any; // TODO: FIX TS ERROR (remove `any`). export const FitText: FC = (props) => { const containerRef = useRef(null); diff --git a/packages/spectacle/src/index.ts b/packages/spectacle/src/index.ts index e6e75ff81..ee448226b 100644 --- a/packages/spectacle/src/index.ts +++ b/packages/spectacle/src/index.ts @@ -10,7 +10,8 @@ export { UnorderedList, Text, Link, - CodeSpan + CodeSpan, + FitText } from './components/typography'; export { Table, From aec76b753b30bad6a5a01abaed7c4e9824ff9ba9 Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Tue, 10 Dec 2024 17:23:59 -0800 Subject: [PATCH 05/20] Doesn't work, but builds now. --- .../spectacle/src/components/typography.tsx | 53 +++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/packages/spectacle/src/components/typography.tsx b/packages/spectacle/src/components/typography.tsx index f7d212292..d550a0722 100644 --- a/packages/spectacle/src/components/typography.tsx +++ b/packages/spectacle/src/components/typography.tsx @@ -10,8 +10,8 @@ import { SpaceProps, BorderProps } from 'styled-system'; -import { FC, PropsWithChildren } from 'react'; -export { FitText } from './typography/fit-text'; +import { FC, PropsWithChildren, useRef, useState } from 'react'; +import useResizeObserver from 'use-resize-observer'; const decoration = system({ textDecoration: true }); type DecorationProps = Pick; @@ -114,6 +114,52 @@ ListItem.defaultProps = { margin: 0 }; +const FitContainer = styled.div` + width: 100%; + display: flex; + align-items: center; + justify-content: center; +`; + +const ScalableText = styled(Text)<{ scale: number }>` + transform-origin: center left; + transform: scale(${(props) => props.scale}); + white-space: nowrap; + max-width: ${(props) => `${100 / props.scale}%`}; +` as any; // TODO: FIX TS ERROR (remove `any`). +ScalableText.defaultProps = { + ...Text.defaultProps, + scale: 1 +}; + +const FitText: FC = (props) => { + const containerRef = useRef(null); + const textRef = useRef(null); + const [scale, setScale] = useState(1); + + useResizeObserver({ + ref: containerRef, + onResize: () => { + if (!containerRef.current || !textRef.current) return; + + const containerWidth = containerRef.current.offsetWidth; + const textWidth = textRef.current.offsetWidth; + + if (textWidth === 0) return; + + const newScale = Math.min(containerWidth / textWidth, 1); + setScale(newScale); + } + }); + + return ( + + + + ); +}; + + export { Text, Heading, @@ -122,5 +168,6 @@ export { UnorderedList, ListItem, Link, - CodeSpan + CodeSpan, + FitText }; From d7ed264da2244d78d75ff92a086f178d92c4ad1d Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Tue, 10 Dec 2024 17:49:22 -0800 Subject: [PATCH 06/20] Wow, it kind of works. --- examples/js/index.js | 13 ++++++++++- .../spectacle/src/components/typography.tsx | 22 +++++++++++++++---- .../src/components/typography/fit-text.tsx | 5 +++++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/examples/js/index.js b/examples/js/index.js index 165f93b05..8b4cba898 100644 --- a/examples/js/index.js +++ b/examples/js/index.js @@ -53,6 +53,8 @@ const SlideFragments = () => ( ); +console.log({ FitText }); + const template = ; const Presentation = () => ( @@ -140,7 +142,16 @@ const Presentation = () => ( - This is a FitText component + This is a Heading + + This is a FitText component + + + Shorter fit text + + This is a Text. (Resize this window!) diff --git a/packages/spectacle/src/components/typography.tsx b/packages/spectacle/src/components/typography.tsx index d550a0722..7748d78ca 100644 --- a/packages/spectacle/src/components/typography.tsx +++ b/packages/spectacle/src/components/typography.tsx @@ -122,7 +122,7 @@ const FitContainer = styled.div` `; const ScalableText = styled(Text)<{ scale: number }>` - transform-origin: center left; + transform-origin: center; transform: scale(${(props) => props.scale}); white-space: nowrap; max-width: ${(props) => `${100 / props.scale}%`}; @@ -137,17 +137,32 @@ const FitText: FC = (props) => { const textRef = useRef(null); const [scale, setScale] = useState(1); + console.log('before useResizeObserver', { + containerRef: containerRef.current, + textRef: textRef.current + }); + useResizeObserver({ ref: containerRef, onResize: () => { + console.log('inside useResizeObserver', { + containerRef: containerRef.current, + textRef: textRef.current + }); + if (!containerRef.current || !textRef.current) return; const containerWidth = containerRef.current.offsetWidth; const textWidth = textRef.current.offsetWidth; - if (textWidth === 0) return; - const newScale = Math.min(containerWidth / textWidth, 1); + const newScale = Math.min(containerWidth / textWidth); + console.log('inside useResizeObserver', { + containerWidth, + textWidth, + newScale + }); + setScale(newScale); } }); @@ -159,7 +174,6 @@ const FitText: FC = (props) => { ); }; - export { Text, Heading, diff --git a/packages/spectacle/src/components/typography/fit-text.tsx b/packages/spectacle/src/components/typography/fit-text.tsx index 4bc025aef..4f95001f6 100644 --- a/packages/spectacle/src/components/typography/fit-text.tsx +++ b/packages/spectacle/src/components/typography/fit-text.tsx @@ -26,6 +26,11 @@ export const FitText: FC = (props) => { useResizeObserver({ ref: containerRef, onResize: () => { + console.log('onResize', { + containerRef: containerRef.current, + textRef: textRef.current + }); + if (!containerRef.current || !textRef.current) return; const containerWidth = containerRef.current.offsetWidth; From df4d543c10ca114601081cece1414dce1fdd1f1e Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Tue, 10 Dec 2024 17:52:41 -0800 Subject: [PATCH 07/20] Add color --- examples/js/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/js/index.js b/examples/js/index.js index 8b4cba898..b2ce01cbd 100644 --- a/examples/js/index.js +++ b/examples/js/index.js @@ -147,6 +147,7 @@ const Presentation = () => ( This is a FitText component Shorter fit text From 982202d8e9de111510c461050a4c128b3dc2f7b7 Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Tue, 10 Dec 2024 17:54:22 -0800 Subject: [PATCH 08/20] Remove unused stuff --- .../components/typography/fit-text.test.tsx | 24 --------- .../src/components/typography/fit-text.tsx | 51 ------------------- 2 files changed, 75 deletions(-) delete mode 100644 packages/spectacle/src/components/typography/fit-text.test.tsx delete mode 100644 packages/spectacle/src/components/typography/fit-text.tsx diff --git a/packages/spectacle/src/components/typography/fit-text.test.tsx b/packages/spectacle/src/components/typography/fit-text.test.tsx deleted file mode 100644 index d70f55d82..000000000 --- a/packages/spectacle/src/components/typography/fit-text.test.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { render } from '@testing-library/react'; -import { ThemeProvider } from 'styled-components'; -import defaultTheme from '../../theme/default-theme'; -import { FitText } from './fit-text'; - -const mountWithTheme = (tree: React.ReactElement) => { - return render({tree}); -}; - -describe('', () => { - it('should render text content', () => { - const { getByText } = mountWithTheme(Spectacle!); - expect(getByText('Spectacle!')).toBeInTheDocument(); - }); - - it('should maintain text color from props', () => { - const { getByText } = mountWithTheme( - Colored Text - ); - expect(getByText('Colored Text')).toHaveStyle({ - color: defaultTheme.colors.secondary - }); - }); -}); diff --git a/packages/spectacle/src/components/typography/fit-text.tsx b/packages/spectacle/src/components/typography/fit-text.tsx deleted file mode 100644 index 4f95001f6..000000000 --- a/packages/spectacle/src/components/typography/fit-text.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { FC, useRef, useState } from 'react'; -import styled from 'styled-components'; -import useResizeObserver from 'use-resize-observer'; -import { Text } from '../typography'; -import { CommonTypographyProps } from '../typography'; - -const FitContainer = styled.div` - width: 100%; - display: flex; - align-items: center; - justify-content: center; -`; - -const ScalableText = styled(Text)<{ scale: number }>` - transform-origin: center left; - transform: scale(${(props) => props.scale}); - white-space: nowrap; - max-width: ${(props) => `${100 / props.scale}%`}; -` as any; // TODO: FIX TS ERROR (remove `any`). - -export const FitText: FC = (props) => { - const containerRef = useRef(null); - const textRef = useRef(null); - const [scale, setScale] = useState(1); - - useResizeObserver({ - ref: containerRef, - onResize: () => { - console.log('onResize', { - containerRef: containerRef.current, - textRef: textRef.current - }); - - if (!containerRef.current || !textRef.current) return; - - const containerWidth = containerRef.current.offsetWidth; - const textWidth = textRef.current.offsetWidth; - - if (textWidth === 0) return; - - const newScale = Math.min(containerWidth / textWidth, 1); - setScale(newScale); - } - }); - - return ( - - - - ); -}; From f0f29e425b83e655c5adec419053313020e13138 Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Tue, 10 Dec 2024 17:54:53 -0800 Subject: [PATCH 09/20] Remove debug logs --- packages/spectacle/src/components/typography.tsx | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/packages/spectacle/src/components/typography.tsx b/packages/spectacle/src/components/typography.tsx index 7748d78ca..39e86ca96 100644 --- a/packages/spectacle/src/components/typography.tsx +++ b/packages/spectacle/src/components/typography.tsx @@ -145,11 +145,6 @@ const FitText: FC = (props) => { useResizeObserver({ ref: containerRef, onResize: () => { - console.log('inside useResizeObserver', { - containerRef: containerRef.current, - textRef: textRef.current - }); - if (!containerRef.current || !textRef.current) return; const containerWidth = containerRef.current.offsetWidth; @@ -157,12 +152,6 @@ const FitText: FC = (props) => { if (textWidth === 0) return; const newScale = Math.min(containerWidth / textWidth); - console.log('inside useResizeObserver', { - containerWidth, - textWidth, - newScale - }); - setScale(newScale); } }); From 6dcf04a2b34aa8a08b62fe23e966794c3dba9bfa Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Tue, 10 Dec 2024 17:55:03 -0800 Subject: [PATCH 10/20] Remove debug logs --- packages/spectacle/src/components/typography.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/spectacle/src/components/typography.tsx b/packages/spectacle/src/components/typography.tsx index 39e86ca96..df4512e8d 100644 --- a/packages/spectacle/src/components/typography.tsx +++ b/packages/spectacle/src/components/typography.tsx @@ -137,11 +137,6 @@ const FitText: FC = (props) => { const textRef = useRef(null); const [scale, setScale] = useState(1); - console.log('before useResizeObserver', { - containerRef: containerRef.current, - textRef: textRef.current - }); - useResizeObserver({ ref: containerRef, onResize: () => { From 8055c9b236d787dd797fc72cae503d266298340d Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Tue, 10 Dec 2024 17:56:52 -0800 Subject: [PATCH 11/20] Remove unused stuff --- packages/spectacle/src/components/typography.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/spectacle/src/components/typography.tsx b/packages/spectacle/src/components/typography.tsx index df4512e8d..3639560c8 100644 --- a/packages/spectacle/src/components/typography.tsx +++ b/packages/spectacle/src/components/typography.tsx @@ -125,7 +125,6 @@ const ScalableText = styled(Text)<{ scale: number }>` transform-origin: center; transform: scale(${(props) => props.scale}); white-space: nowrap; - max-width: ${(props) => `${100 / props.scale}%`}; ` as any; // TODO: FIX TS ERROR (remove `any`). ScalableText.defaultProps = { ...Text.defaultProps, From 7bcb05f742d066e055732e34a892ce544a20e671 Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Tue, 10 Dec 2024 19:26:29 -0800 Subject: [PATCH 12/20] Fix types and remove debug stuff --- examples/js/index.js | 2 -- packages/spectacle/src/components/typography.tsx | 8 +++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/js/index.js b/examples/js/index.js index b2ce01cbd..9f96f68e9 100644 --- a/examples/js/index.js +++ b/examples/js/index.js @@ -53,8 +53,6 @@ const SlideFragments = () => ( ); -console.log({ FitText }); - const template = ; const Presentation = () => ( diff --git a/packages/spectacle/src/components/typography.tsx b/packages/spectacle/src/components/typography.tsx index 3639560c8..aee06ddab 100644 --- a/packages/spectacle/src/components/typography.tsx +++ b/packages/spectacle/src/components/typography.tsx @@ -10,7 +10,7 @@ import { SpaceProps, BorderProps } from 'styled-system'; -import { FC, PropsWithChildren, useRef, useState } from 'react'; +import { FC, PropsWithChildren, RefAttributes, useRef, useState } from 'react'; import useResizeObserver from 'use-resize-observer'; const decoration = system({ textDecoration: true }); @@ -121,11 +121,13 @@ const FitContainer = styled.div` justify-content: center; `; -const ScalableText = styled(Text)<{ scale: number }>` +const ScalableText = styled( + Text as FC> +)<{ scale: number }>` transform-origin: center; transform: scale(${(props) => props.scale}); white-space: nowrap; -` as any; // TODO: FIX TS ERROR (remove `any`). +`; ScalableText.defaultProps = { ...Text.defaultProps, scale: 1 From 8bc61a52c02c3f027a085d8fb40fd1aa8c6d5557 Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Tue, 10 Dec 2024 21:25:13 -0800 Subject: [PATCH 13/20] Getting closer. Test mocks don't work --- examples/one-page/index.html | 10 ++++ .../src/components/typography.test.tsx | 57 ++++++++++++++++++- .../spectacle/src/components/typography.tsx | 2 +- 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/examples/one-page/index.html b/examples/one-page/index.html index 5cf3f9219..c778edf5b 100644 --- a/examples/one-page/index.html +++ b/examples/one-page/index.html @@ -60,6 +60,7 @@ Slide, Deck, Text, + FitText, Grid, Box, Image, @@ -170,6 +171,15 @@ + <${Slide}> + <${Heading}>This is a Heading + <${FitText}>This is a FitText component + <${FitText} color="secondary" style=${{ + textTransform: 'uppercase', + fontFamily: 'Comic Sans MS' + }}>Shorter fit text + <${Text}>This is a Text. (Resize this window!) + <${Slide}> <${FlexBox}> <${Text}>These diff --git a/packages/spectacle/src/components/typography.test.tsx b/packages/spectacle/src/components/typography.test.tsx index 9ea289970..4cf78d246 100644 --- a/packages/spectacle/src/components/typography.test.tsx +++ b/packages/spectacle/src/components/typography.test.tsx @@ -1,5 +1,6 @@ import { PropsWithChildren, ReactElement } from 'react'; import { ThemeProvider } from 'styled-components'; +import useResizeObserver from 'use-resize-observer'; import defaultTheme from '../theme/default-theme'; import { @@ -10,9 +11,13 @@ import { UnorderedList, ListItem, Link, - CodeSpan + CodeSpan, + FitText } from './typography'; import { render } from '@testing-library/react'; +// Mock useResizeObserver for FitText tests +jest.mock('use-resize-observer'); +const mockedUseResizeObserver = useResizeObserver as jest.Mock; const mountWithTheme = (tree: ReactElement | JSX.Element) => { const WrappingThemeProvider = (props: PropsWithChildren) => ( @@ -91,3 +96,53 @@ describe('', () => { expect(container.querySelector('code')?.innerHTML).toBe('Code!'); }); }); + +describe('', () => { + beforeEach(() => { + // Default mock implementation + mockedUseResizeObserver.mockImplementation(({ onResize }) => { + onResize({ width: 500, height: 100 }); + return { ref: null }; + }); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should render text content correctly', () => { + const { getByText } = mountWithTheme(Spectacle!); + expect(getByText('Spectacle!')).toBeInTheDocument(); + }); + + it('should apply color and typography props correctly', () => { + const { getByText } = mountWithTheme( + Spectacle! + ); + const textElement = getByText('Spectacle!'); + expect(textElement).toHaveStyle({ color: defaultTheme.colors.secondary }); + expect(textElement).toHaveStyle({ fontSize: 'h1' }); + }); + + it('should scale text when container size changes', () => { + // Simulate a container that's smaller than the text + mockedUseResizeObserver.mockImplementation(({ onResize }) => { + onResize({ width: 100, height: 100 }); + return { ref: null }; + }); + + const { container } = mountWithTheme(Long text that needs scaling); + const scaledText = container.querySelector('div[scale]'); + expect(scaledText).toHaveStyle({ transform: expect.stringContaining('scale') }); + }); + + it('should center text in container', () => { + const { container } = mountWithTheme(Centered text); + const fitContainer = container.firstChild; + expect(fitContainer).toHaveStyle({ + display: 'flex', + alignItems: 'center', + justifyContent: 'center' + }); + }); +}); diff --git a/packages/spectacle/src/components/typography.tsx b/packages/spectacle/src/components/typography.tsx index aee06ddab..a560cd848 100644 --- a/packages/spectacle/src/components/typography.tsx +++ b/packages/spectacle/src/components/typography.tsx @@ -133,7 +133,7 @@ ScalableText.defaultProps = { scale: 1 }; -const FitText: FC = (props) => { +const FitText: FC> = (props) => { const containerRef = useRef(null); const textRef = useRef(null); const [scale, setScale] = useState(1); From 522e263599561d3f4af6c32fad571a565816b541 Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Tue, 10 Dec 2024 22:07:20 -0800 Subject: [PATCH 14/20] Fix mocking --- .../src/components/typography.test.tsx | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/packages/spectacle/src/components/typography.test.tsx b/packages/spectacle/src/components/typography.test.tsx index 4cf78d246..390d75d0a 100644 --- a/packages/spectacle/src/components/typography.test.tsx +++ b/packages/spectacle/src/components/typography.test.tsx @@ -1,6 +1,5 @@ import { PropsWithChildren, ReactElement } from 'react'; import { ThemeProvider } from 'styled-components'; -import useResizeObserver from 'use-resize-observer'; import defaultTheme from '../theme/default-theme'; import { @@ -15,9 +14,6 @@ import { FitText } from './typography'; import { render } from '@testing-library/react'; -// Mock useResizeObserver for FitText tests -jest.mock('use-resize-observer'); -const mockedUseResizeObserver = useResizeObserver as jest.Mock; const mountWithTheme = (tree: ReactElement | JSX.Element) => { const WrappingThemeProvider = (props: PropsWithChildren) => ( @@ -100,9 +96,8 @@ describe('', () => { describe('', () => { beforeEach(() => { // Default mock implementation - mockedUseResizeObserver.mockImplementation(({ onResize }) => { - onResize({ width: 500, height: 100 }); - return { ref: null }; + jest.mock('use-resize-observer', () => { + return { width: 500, height: 100 }; }); }); @@ -117,7 +112,9 @@ describe('', () => { it('should apply color and typography props correctly', () => { const { getByText } = mountWithTheme( - Spectacle! + + Spectacle! + ); const textElement = getByText('Spectacle!'); expect(textElement).toHaveStyle({ color: defaultTheme.colors.secondary }); @@ -126,14 +123,15 @@ describe('', () => { it('should scale text when container size changes', () => { // Simulate a container that's smaller than the text - mockedUseResizeObserver.mockImplementation(({ onResize }) => { - onResize({ width: 100, height: 100 }); - return { ref: null }; + jest.mock('use-resize-observer', () => { + return { width: 100, height: 100 }; }); - const { container } = mountWithTheme(Long text that needs scaling); + const { container } = mountWithTheme( + Long text that needs scaling + ); const scaledText = container.querySelector('div[scale]'); - expect(scaledText).toHaveStyle({ transform: expect.stringContaining('scale') }); + expect(scaledText).toHaveStyle({ transform: 'scale(1)' }); // TODO: Not sure if this is a great test / expected. }); it('should center text in container', () => { From 2d241aa2fa7ec9a61b957ae43fc4fa5806c582e3 Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Tue, 10 Dec 2024 22:17:53 -0800 Subject: [PATCH 15/20] Update TS example --- examples/typescript/index.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/examples/typescript/index.tsx b/examples/typescript/index.tsx index 88aa01559..00845eb4c 100644 --- a/examples/typescript/index.tsx +++ b/examples/typescript/index.tsx @@ -12,6 +12,7 @@ import { Slide, Deck, Text, + FitText, Grid, Box, Image, @@ -137,6 +138,19 @@ const Presentation = () => ( + + This is a Heading + + This is a FitText component + + + Shorter fit text + + This is a Text. (Resize this window!) + These From 0ea80dad4d7e749b44fb78827b46ebcc307e279d Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Tue, 10 Dec 2024 23:40:45 -0800 Subject: [PATCH 16/20] Add docs. From Jolt. --- docs/api-reference.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/api-reference.md b/docs/api-reference.md index fd0857945..13ef867e6 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -56,6 +56,7 @@ These tags are for displaying textual content. | Tag Name | Theme Props | Additional Props | Default Props | |---------------------|-------------------------------------------------------------------------------------------------------------|----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **`Text`** | [**Space**](./props#space)
[**Color**](./props#color)
[**Typography**](./props#typography) | — | **color**: primary
**fontFamily**: text
**fontSize**: text
**textAlign**: left
**margin**: textMargin | +| **`FitText`** | [**Space**](./props#space)
[**Color**](./props#color)
[**Typography**](./props#typography) | — | **color**: primary
**fontFamily**: text
**fontSize**: text
**textAlign**: left
**margin**: textMargin | | **`Heading`** | [**Space**](./props#space)
[**Color**](./props#color)
[**Typography**](./props#typography) | — | **color**: secondary
**fontFamily**: header
**fontSize**: h1
**fontWeight**: bold
**textAlign**: center
**margin**: headerMargin | | **`Link`** | [**Space**](./props#space)
[**Color**](./props#color)
[**Typography**](./props#typography)
| **href**: PropTypes.string | **color**: quaternary
**fontFamily**: text
**fontSize**: text
**textDecoration**: underline
**textAlign**: left
**margin**: textMargin | | **`Quote`** | [**Space**](./props#space)
[**Color**](./props#color)
[**Typography**](./props#typography)
| — | **color**: primary
**fontFamily**: text
**fontSize**: text
**textAlign**: left
**borderLeft**: 1px solid secondary | From 7350339a04c68c16fe81fd3bc83bb51a6383f5be Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Tue, 10 Dec 2024 23:49:27 -0800 Subject: [PATCH 17/20] Update textAlign prop --- docs/api-reference.md | 2 +- packages/spectacle/src/components/typography.tsx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/api-reference.md b/docs/api-reference.md index 13ef867e6..6fe4b8d62 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -56,7 +56,7 @@ These tags are for displaying textual content. | Tag Name | Theme Props | Additional Props | Default Props | |---------------------|-------------------------------------------------------------------------------------------------------------|----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **`Text`** | [**Space**](./props#space)
[**Color**](./props#color)
[**Typography**](./props#typography) | — | **color**: primary
**fontFamily**: text
**fontSize**: text
**textAlign**: left
**margin**: textMargin | -| **`FitText`** | [**Space**](./props#space)
[**Color**](./props#color)
[**Typography**](./props#typography) | — | **color**: primary
**fontFamily**: text
**fontSize**: text
**textAlign**: left
**margin**: textMargin | +| **`FitText`** | [**Space**](./props#space)
[**Color**](./props#color)
[**Typography**](./props#typography) | — | **color**: primary
**fontFamily**: text
**fontSize**: text
**textAlign**: center
**margin**: textMargin | | **`Heading`** | [**Space**](./props#space)
[**Color**](./props#color)
[**Typography**](./props#typography) | — | **color**: secondary
**fontFamily**: header
**fontSize**: h1
**fontWeight**: bold
**textAlign**: center
**margin**: headerMargin | | **`Link`** | [**Space**](./props#space)
[**Color**](./props#color)
[**Typography**](./props#typography)
| **href**: PropTypes.string | **color**: quaternary
**fontFamily**: text
**fontSize**: text
**textDecoration**: underline
**textAlign**: left
**margin**: textMargin | | **`Quote`** | [**Space**](./props#space)
[**Color**](./props#color)
[**Typography**](./props#typography)
| — | **color**: primary
**fontFamily**: text
**fontSize**: text
**textAlign**: left
**borderLeft**: 1px solid secondary | diff --git a/packages/spectacle/src/components/typography.tsx b/packages/spectacle/src/components/typography.tsx index a560cd848..4eab01d76 100644 --- a/packages/spectacle/src/components/typography.tsx +++ b/packages/spectacle/src/components/typography.tsx @@ -130,6 +130,7 @@ const ScalableText = styled( `; ScalableText.defaultProps = { ...Text.defaultProps, + textAlign: 'center', scale: 1 }; From a6e2ced420275df31915bf795d7c7386de4f5c12 Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Tue, 10 Dec 2024 23:53:16 -0800 Subject: [PATCH 18/20] Add changeset --- .changeset/fuzzy-tips-build.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fuzzy-tips-build.md diff --git a/.changeset/fuzzy-tips-build.md b/.changeset/fuzzy-tips-build.md new file mode 100644 index 000000000..7c1bb9e54 --- /dev/null +++ b/.changeset/fuzzy-tips-build.md @@ -0,0 +1,5 @@ +--- +'spectacle': minor +--- + +Add `FitText` typography component. From 9f64d9b6244c287c27f7889baf4b57d98a6e842e Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Wed, 11 Dec 2024 15:23:55 -0800 Subject: [PATCH 19/20] remove onResize test --- .../src/components/typography.test.tsx | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/packages/spectacle/src/components/typography.test.tsx b/packages/spectacle/src/components/typography.test.tsx index 390d75d0a..b8eb73384 100644 --- a/packages/spectacle/src/components/typography.test.tsx +++ b/packages/spectacle/src/components/typography.test.tsx @@ -120,27 +120,4 @@ describe('', () => { expect(textElement).toHaveStyle({ color: defaultTheme.colors.secondary }); expect(textElement).toHaveStyle({ fontSize: 'h1' }); }); - - it('should scale text when container size changes', () => { - // Simulate a container that's smaller than the text - jest.mock('use-resize-observer', () => { - return { width: 100, height: 100 }; - }); - - const { container } = mountWithTheme( - Long text that needs scaling - ); - const scaledText = container.querySelector('div[scale]'); - expect(scaledText).toHaveStyle({ transform: 'scale(1)' }); // TODO: Not sure if this is a great test / expected. - }); - - it('should center text in container', () => { - const { container } = mountWithTheme(Centered text); - const fitContainer = container.firstChild; - expect(fitContainer).toHaveStyle({ - display: 'flex', - alignItems: 'center', - justifyContent: 'center' - }); - }); }); From 412e5b32a9238fdc377fa93a574c0af46c3f65aa Mon Sep 17 00:00:00 2001 From: Ryan Roemer Date: Fri, 13 Dec 2024 00:21:36 -0800 Subject: [PATCH 20/20] Minor type fix for FitText and enhance examples to use sub-components. --- examples/js/index.js | 2 +- examples/one-page/index.html | 2 +- examples/typescript/index.tsx | 2 +- packages/spectacle/src/components/typography.tsx | 13 +++++++++++-- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/examples/js/index.js b/examples/js/index.js index 9f96f68e9..b4e063b44 100644 --- a/examples/js/index.js +++ b/examples/js/index.js @@ -142,7 +142,7 @@ const Presentation = () => ( This is a Heading - This is a FitText component + This is a FitText component <${Slide}> <${Heading}>This is a Heading - <${FitText}>This is a FitText component + <${FitText}>This is a <${CodeSpan}>FitText component <${FitText} color="secondary" style=${{ textTransform: 'uppercase', fontFamily: 'Comic Sans MS' diff --git a/examples/typescript/index.tsx b/examples/typescript/index.tsx index 00845eb4c..15337ced5 100644 --- a/examples/typescript/index.tsx +++ b/examples/typescript/index.tsx @@ -141,7 +141,7 @@ const Presentation = () => ( This is a Heading - This is a FitText component + This is a FitText component > = (props) => { +const FitText: FC< + PropsWithChildren> +> = (props) => { const containerRef = useRef(null); const textRef = useRef(null); const [scale, setScale] = useState(1);