diff --git a/packages/next/cypress/support/commands.ts b/packages/next/cypress/support/commands.ts index 012519e..8f3a20c 100644 --- a/packages/next/cypress/support/commands.ts +++ b/packages/next/cypress/support/commands.ts @@ -4,10 +4,8 @@ Cypress.Commands.add('hasDimensions', { prevSubject: true }, (subject, width, height) => { - - expect(subject.width()).to.equal(width) - expect(subject.height()).to.equal(height) - return subject + cy.wrap(subject).invoke('width').should('equal', width) + cy.wrap(subject).invoke('height').should('equal', height) }) // Check that a video is playing @@ -28,7 +26,7 @@ declare global { hasDimensions( width: number, height: number - ): Chainable + ): Chainable isPlaying(): Chainable } diff --git a/packages/next/src/index.ts b/packages/next/src/index.ts index 9d7cc01..681f4f6 100644 --- a/packages/next/src/index.ts +++ b/packages/next/src/index.ts @@ -1,7 +1,4 @@ import NextVisual from './NextVisual' + export default NextVisual -export { - NextVisualProps, - ObjectFit, - ObjectFitOption, -} from './types/nextVisualTypes' +export { NextVisualProps } from './types/nextVisualTypes' diff --git a/packages/next/src/types/nextVisualTypes.ts b/packages/next/src/types/nextVisualTypes.ts index c2c27f5..45c4663 100644 --- a/packages/next/src/types/nextVisualTypes.ts +++ b/packages/next/src/types/nextVisualTypes.ts @@ -1,34 +1,5 @@ -import type { CSSProperties } from 'react' +import type { ReactVisualProps } from '@react-visual/react' -export type NextVisualProps = { - - image?: string - video?: string +export type NextVisualProps = ReactVisualProps & { placeholderData?: string - - expand?: boolean - aspect?: number // An explict aspect ratio - width?: number | string - height?: number | string - fit?: ObjectFitOption | ObjectFit - position?: string - - priority?: boolean - sizes?: string - imageLoader?: Function - - paused?: boolean - - alt: string - - className?: string - style?: CSSProperties -} - -export type ObjectFitOption = 'cover' | 'contain' - -// Deprecated -export enum ObjectFit { - Cover = 'cover', - Contain = 'contain', } diff --git a/packages/react/README.md b/packages/react/README.md index a64616b..926dcbe 100644 --- a/packages/react/README.md +++ b/packages/react/README.md @@ -1,3 +1,110 @@ # @react-visual/react [![react-visual](https://img.shields.io/endpoint?url=https://cloud.cypress.io/badge/simple/fn6c7w&style=flat&logo=cypress)](https://cloud.cypress.io/projects/fn6c7w/runs) -This component package isn't fully implemented yet, it's just olding some shared components but not ready to be implemented on it's own. + +Renders images and videos into a container. Features: + +- Supports a next.js style image loader for making srcsets +- Creates `` tags for different MIME types and media queries +- Easily render assets using aspect ratios +- Videos are lazyloaded (unless `priority` flag is set) + +## Install + +```sh +yarn add @react-visual/react +``` + +## Usage + +Play a video with a poster image. + +```jsx +import Visual from '@react-visual/react' + +export default function VideoExample() { + return ( + + ) +} +``` + +Generate multiple landscape and portrait sources in webp and avif using an image CDN to create a srcset. + +```jsx +import Visual from '@react-visual/react' + +export default function ResponsiveExample() { + return ( + { + const ext = type?.includes('webp') ? '.webp' : '' + const height = media?.includes('landscape') ? + width * 0.5 : width + return `https://placehold.co/${width}x${height}${ext}` + }} + aspect={300/150} + sizes='100vw' + alt='Example of responsive images' /> + ) +} +``` + +For more examples, read [the Cypress component tests](./cypress/component). + +## Props + +### Sources + +| Prop | Type | Description +| -- | -- | -- +| `image` | `string` | URL to an image asset. +| `video` | `string` | URL to a video asset asset. + +### Layout + +| Prop | Type | Description +| -- | -- | -- +| `expand` | `boolean` | Make the Visual fill it's container via CSS using absolute positioning. +| `aspect` | `number` | Force the Visual to a specific aspect ratio. +| `width` | `number`, `string` | A CSS dimension value or a px number. +| `height` | `number`, `string` | A CSS dimension value or a px number. +| `fit` | `string` | An [`object-fit`](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit) value that is applied to the assets. Defaults to `cover`. +| `position` | `string` | An [`object-position`](https://developer.mozilla.org/en-US/docs/Web/CSS/object-position) value. + +### Loading + +| Prop | Type | Description +| -- | -- | -- +| `priority` | `boolean` | Disables [`` attribute. +| `sourceTypes` | `string[]` | Specify image MIME types that will be passed to the `imageLoader` and used to create additional `` tags. Use this to create `webp` or `avif` sources with a CDN like Contentful. +| `sourceMedia` | `string[]` | Specify media queries that will be passed to the `imageLoader` and used to create additional `` tags. +| `imageLoader` | `Function` | Uses syntax that is similar [to `next/image`'s `loader` prop](https://nextjs.org/docs/app/api-reference/components/image#loader). A srcset is built with a hardcoded list of widths. + +### Video + +| Prop | Type | Description +| -- | -- | -- +| `paused` | `boolean` | Disables autoplay of videos. This prop is reactive, unlike the `paused` property of the html `