diff --git a/.gitignore b/.gitignore index 2bfd415..72ca2e1 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,5 @@ dist example/.cache .DS_Store .vscode -*.js -*.d.ts \ No newline at end of file +/*.js +*.d.ts diff --git a/src/Link.tsx b/src/Link.tsx new file mode 100644 index 0000000..1e0dee0 --- /dev/null +++ b/src/Link.tsx @@ -0,0 +1,34 @@ +import { createResource } from './createResource'; + +type LinkProps = { + rel: string; + href: string; + as?: string; + media?: string; +}; + +export const LinkResource = createResource( + load, + ({ rel, href }) => `${rel}.${href}` +); + +function load({ rel, href, as, media = 'all' }: LinkProps) { + return new Promise((resolve, reject) => { + const link = document.createElement('link'); + link.rel = rel; + if (as) { + link.as = as; + } + link.media = media; + link.href = href; + link.onload = resolve; + link.onerror = reject; + document.body.appendChild(link); + }); +} + +export const Link: React.FC = props => { + LinkResource.read(props); + + return null; +}; diff --git a/src/Prefetch.tsx b/src/Prefetch.tsx new file mode 100644 index 0000000..ea02ad4 --- /dev/null +++ b/src/Prefetch.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { Link } from './Link'; + +type PrefetchProps = { + href: string; + as: string; + media?: string; +}; + +export const Prefetch: React.FC = props => { + return ; +}; diff --git a/src/Preload.tsx b/src/Preload.tsx index 1505af9..68befbb 100644 --- a/src/Preload.tsx +++ b/src/Preload.tsx @@ -1,4 +1,5 @@ -import { createResource } from './createResource'; +import React from 'react'; +import { Link } from './Link'; type PreloadProps = { href: string; @@ -6,30 +7,6 @@ type PreloadProps = { media?: string; }; -export const PreloadResource = createResource( - load, - ({ href, as }) => `${href}.${as}` -); - -function load({ href, as, media = 'all' }: PreloadProps) { - return new Promise((resolve, reject) => { - const link = document.createElement('link'); - link.rel = 'preload'; - link.as = as; - link.media = media; - link.href = href; - link.onload = resolve; - link.onerror = reject; - document.body.appendChild(link); - }); -} - -export const Preload: React.FC = ({ children, ...rest }) => { - PreloadResource.read(rest); - - if (typeof children === 'function') { - return children(); - } - - return children; +export const Preload: React.FC = props => { + return ; }; diff --git a/src/Stylesheet.tsx b/src/Stylesheet.tsx index cf94555..c706106 100644 --- a/src/Stylesheet.tsx +++ b/src/Stylesheet.tsx @@ -1,33 +1,15 @@ import React from 'react'; -import { createResource } from './createResource'; +import { Link, LinkResource } from './Link'; type StylesheetProps = { href: string; media?: string; }; -export const StylesheetResource = createResource( - load, - ({ href, media }) => `${href}.${media}` -); - -function load({ href, media = 'all' }: StylesheetProps) { - return new Promise((resolve, reject) => { - const link = document.createElement('link'); - link.rel = 'stylesheet'; - link.href = href; - link.media = media; - link.onload = resolve; - link.onerror = reject; - document.body.appendChild(link); - }); -} - export const Stylesheet: React.FC = props => { - StylesheetResource.read(props); - return ; + return ; }; export function useStylesheet(props: StylesheetProps) { - return StylesheetResource.read(props); + return LinkResource.read({ ...props, rel: 'stylesheet' }); } diff --git a/tests/Prefetch.test.js b/tests/Prefetch.test.js new file mode 100644 index 0000000..e627b1d --- /dev/null +++ b/tests/Prefetch.test.js @@ -0,0 +1,25 @@ +import React from 'react'; +import { render, Simulate, cleanup } from 'react-testing-library'; +import { Prefetch } from '../src/Prefetch'; + +function App() { + return ( + + + + ); +} + +afterEach(cleanup); + +describe('Prefetch', () => { + test('renders link tag', () => { + const { baseElement } = render(); + const link = baseElement.querySelector('link'); + + expect(link).toBeInTheDocument(); + expect(link).toHaveAttribute('rel', 'prefetch'); + expect(link).toHaveAttribute('href', 'href'); + expect(link.as).toBe('script'); + }); +}); diff --git a/tests/Preload.test.js b/tests/Preload.test.js new file mode 100644 index 0000000..b1772f3 --- /dev/null +++ b/tests/Preload.test.js @@ -0,0 +1,25 @@ +import React from 'react'; +import { render, Simulate, cleanup } from 'react-testing-library'; +import { Preload } from '../src/Preload'; + +function App() { + return ( + + + + ); +} + +afterEach(cleanup); + +describe('Preload', () => { + test('renders link tag', () => { + const { baseElement } = render(); + const link = baseElement.querySelector('link'); + + expect(link).toBeInTheDocument(); + expect(link).toHaveAttribute('rel', 'preload'); + expect(link).toHaveAttribute('href', 'href'); + expect(link.as).toBe('script'); // jsdom does not support 'as' attribute + }); +}); diff --git a/tests/Stylesheet.test.js b/tests/Stylesheet.test.js new file mode 100644 index 0000000..82ac7f7 --- /dev/null +++ b/tests/Stylesheet.test.js @@ -0,0 +1,24 @@ +import React from 'react'; +import { render, Simulate, cleanup } from 'react-testing-library'; +import { Stylesheet } from '../src/Stylesheet'; + +function App() { + return ( + + + + ); +} + +afterEach(cleanup); + +describe('Stylesheet', () => { + test('renders link tag', () => { + const { baseElement } = render(); + const link = baseElement.querySelector('link'); + + expect(link).toBeInTheDocument(); + expect(link).toHaveAttribute('rel', 'stylesheet'); + expect(link).toHaveAttribute('href', 'href'); + }); +});