/** @jsxImportSource @compiled/react */ // eslint-disable-next-line import/no-extraneous-dependencies import { styled } from '@compiled/react'; import { render } from '@testing-library/react'; const em = (str: string | number) => str; describe('styled component', () => { it('should render a simple styled div using an object', () => { const StyledDiv = styled.div({ fontSize: '12px', }); const { getByText } = render(hello world); expect(getByText('hello world')).toHaveCompiledCss('font-size', '12px'); }); it('should render a simple styled div using a template literal', () => { const StyledDiv = styled.div` font-size: 30px; `; const { getByText } = render(hello world); expect(getByText('hello world')).toHaveCompiledCss('font-size', '30px'); }); it('should interpolate a simple number value', () => { const size = '12px'; const StyledDiv = styled.div<{ fontSize: string }>` font-size: ${(props) => props.fontSize}; `; const { getByText } = render(hello world); expect(getByText('hello world')).toHaveCompiledCss('font-size', '12px'); }); it('should at runtime use a call expression inline', () => { const size = 12; const StyledDiv = styled.div({ fontSize: em(size), }); const { getByText } = render(hello world); expect(getByText('hello world')).toHaveCompiledCss('font-size', '12px'); }); it('should at runtime use a identifier referencing a call expression', () => { const size = em(12); const StyledDiv = styled.div({ fontSize: size, }); const { getByText } = render(hello world); expect(getByText('hello world')).toHaveCompiledCss('font-size', '12px'); }); it('should not pass down invalid html attributes to the node', () => { const size = '12px'; const StyledDiv = styled.div<{ fonty: string }>` font-size: ${(props) => props.fonty}; `; const { getByText } = render(hello world); expect(getByText('hello world').getAttribute('fonty')).toBe(null); }); it('should automatically add suffix on template literal', () => { const size = 12; const StyledDiv = styled.div<{ size: number }>` height: ${(props) => props.size}px; width: ${(props) => props.size}px; `; const { getByText } = render(hello world); expect(getByText('hello world')).toHaveCompiledCss({ height: '12px', width: '12px', }); }); it('should automatically add suffix on css object', () => { const size = 12; const StyledDiv = styled.div<{ size: number }>({ height: (props) => `${props.size}px`, width: (props) => `${props.size}px`, }); const { getByText } = render(hello world); expect(getByText('hello world')).toHaveCompiledCss({ height: '12px', width: '12px', }); }); it('should allow passing down native attributes', () => { const Link = styled.a``; const { getByText } = render(hello world); expect(getByText('hello world').getAttribute('href')).toEqual('#'); }); it('should not type error with nested selectors', () => { expect(() => { styled.div({ color: 'currentColor', textDecoration: 'none', position: 'relative', ':before': { opacity: 0, content: '⚓', position: 'absolute', left: '-5rem', fontSize: '3rem', }, ':hover': { ':before': { opacity: 1, }, }, }); }).not.toThrow(); }); it('should not have a display name', () => { process.env.NODE_ENV = 'production'; const StyledDiv = styled.div` font-size: 12px; `; expect(StyledDiv.displayName).toEqual(undefined); }); it('should have a display name', () => { process.env.NODE_ENV = 'development'; const StyledDiv = styled.div` font-size: 12px; `; expect(StyledDiv.displayName).toEqual('StyledDiv'); }); it('should not type error with nested arrow funcs', () => { expect(() => { styled.div<{ fontSize: string }>({ color: 'currentColor', textDecoration: 'none', position: 'relative', fontSize: (props) => props.fontSize, ':before': { fontSize: (props) => props.fontSize, opacity: 0, content: '⚓', position: 'absolute', left: '-5rem', }, ':hover': { fontSize: (props) => props.fontSize, ':before': { fontSize: (props) => props.fontSize, opacity: 1, }, }, }); }).not.toThrow(); }); it('should forward ref', () => { let ref: HTMLAnchorElement | null = null; const Link = styled.a``; render( (ref = r)} href="#"> hello world ); expect(ref).toHaveProperty('tagName', 'A'); }); it('should override the underlying markup with a span', () => { const Heading = styled.h1` color: red; `; const { getByText } = render(Hello world); expect(getByText('Hello world').tagName).toEqual('SPAN'); }); it('should compose a component using template literal', () => { const Div = (props: Record) =>
; const StyledDiv = styled(Div)` font-size: 12px; `; const { getByText } = render(Hello world); expect(getByText('Hello world').tagName).toEqual('DIV'); }); it('should override css prop styles', () => { const Child = (props: { children: any; className?: string }) => (

); const Override = styled(Child)` font-size: 12px; `; const { getByText } = render(Hello world); expect(getByText('Hello world')).toHaveCompiledCss({ fontSize: '12px', }); }); it('should compose a component using object literal', () => { const Div = (props: Record) =>
; const StyledDiv = styled(Div)({ fontSize: 12, }); const { getByText } = render(Hello world); expect(getByText('Hello world').tagName).toEqual('DIV'); }); it('should inherit types from composed component', () => { const Link = (props: React.PropsWithChildren<{ href: string }>) => ; const StyledLink = styled(Link)({ fontSize: 12, }); const { getByText } = render(Hello world); expect(getByText('Hello world').getAttribute('href')).toEqual('/world'); }); it('should compose from array', () => { const extra = { color: 'blue', }; const StyledLink = styled.div([ { fontSize: 12, }, extra, ]); const { getByText } = render(Hello world); expect(getByText('Hello world')).toHaveCompiledCss({ color: 'blue', 'font-size': '12px', }); }); it('should not type error', () => { expect(() => { styled.div<{ primary: string }>({ fontSize: '20px', color: (props) => props.primary, margin: '20px', ':hover': { color: 'red', }, }); }).not.toThrow(); }); it('should create css from string', () => { const StyledDiv = styled.div('font-size: 15px;'); const { getByText } = render(hello world); expect(getByText('hello world')).toHaveCompiledCss('font-size', '15px'); }); it('should create css from template literal', () => { const StyledDiv = styled.div(`font-size: 15px;`); const { getByText } = render(hello world); expect(getByText('hello world')).toHaveCompiledCss('font-size', '15px'); }); it('should create css from array', () => { const base = { fontSize: 12 }; const next = ` font-size: 15px; `; const StyledDiv = styled.div([base, next]); const { getByText } = render(hello world); expect(getByText('hello world')).toHaveCompiledCss('font-size', '15px'); }); it('should accept css args', () => { const StyledDiv = styled.div( { fontSize: 12 }, `font-size: 15px;`, { color: 'blue', display: 'none' }, [{ color: 'red' }] ); const { getByText } = render(hello world); expect(getByText('hello world')).toHaveCompiledCss({ fontSize: '15px', color: 'red', display: 'none', }); }); });