prismicio / prismic-react

React components and hooks to fetch and present Prismic content
https://prismic.io/docs/technologies/homepage-reactjs
Apache License 2.0
153 stars 40 forks source link

fix: support untyped or partially typed Slices in `<SliceZone>` #154

Closed angeloashmore closed 1 year ago

angeloashmore commented 1 year ago

Types of changes

Description

This PR changes <SliceZone> to accept untyped or partially typed Slices. The changes affect both the provided Slices (the slices prop) and components (the components prop).

It effectively removes any type checking between the slices and components props.

It also defaults Slice components' slice prop to any rather than SliceLike. This was done to support Prismic's Rest API and GraphQL API with the same set of types.

Developers can still provide types to their API responses via @prismicio/client's type parameters and Slice components via @prismicio/react's SliceComponentProps. This PR does not include breaking changes.

While these changes may seem like a step backwards, it broadens the library's support to include projects with insufficient type data. Today, projects with insufficient types is common. This can happen when Slice components are properly typed, but the API data is not. This is even the case in Prismic-provided integrations like Slice Simulator.

Rather than force developers to hand-type their projects, the library has been updated to gracefully support untyped or partially typed data and components.

For more details on what prompted this change, see https://github.com/prismicio/prismic-types/issues/34.


Component Type Examples

<SliceZone> will accept any of these typed components.

Fully typing a Slice component for Prismic's Rest API:

import { SliceComponentProps } from "@prismicio/react";
import * as prismicT from "@prismicio/types";

type ImageSlice = prismicT.SharedSlice<
  "image",
  prismicT.SharedSliceVariation<
    "default",
    {
      image: prismicT.ImageField;
    },
    never
  >
>;

const Image = ({ slice }: SliceComponentProps<ImageSlice>) => {
  return <section>{/* implementation */}</section>;
};

Fully typing a Slice component for Prismic's GraphQL API using a generated type (e.g. from GraphQL Code Generator):

import { SliceComponentProps } from "@prismicio/react";

// A type generated from a tool like GraphQL Code Generator
import { ImageSlice } from "../types.generated";

const Image = ({ slice }: SliceComponentProps<ImageSlice>) => {
  return <section>{/* implementation */}</section>;
};

Partially typing a Slice component (restricted to Prismic's Rest API):

import { SliceComponentProps, SliceLikeRestV2 } from "@prismicio/react";

const Image = ({ slice }: SliceComponentProps<SliceLikeRestV2>) => {
  return <section>{/* implementation */}</section>;
};

Partially typing a Slice component (restricted to Prismic's GraphQL API):

import { SliceComponentProps, SliceLikeGraphQL } from "@prismicio/react";

const Image = ({ slice }: SliceComponentProps<SliceLikeGraphQL>) => {
  return <section>{/* implementation */}</section>;
};

Partially typing a Slice component (any API):

import { SliceComponentProps } from "@prismicio/react";

// `slice` is typed as `any`
const Image = ({ slice }: SliceComponentProps) => {
  return <section>{/* implementation */}</section>;
};

Checklist:

🦢

codecov-commenter commented 1 year ago

Codecov Report

Merging #154 (c328833) into master (1eb04d8) will not change coverage. The diff coverage is 100.00%.

@@           Coverage Diff           @@
##           master     #154   +/-   ##
=======================================
  Coverage   91.61%   91.61%           
=======================================
  Files          18       18           
  Lines         334      334           
  Branches       84       84           
=======================================
  Hits          306      306           
  Misses          5        5           
  Partials       23       23           
Impacted Files Coverage Δ
src/SliceZone.tsx 84.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update 1eb04d8...c328833. Read the comment docs.

github-actions[bot] commented 1 year ago

size-limit report 📦

Path Size
dist/index.js 5.63 KB (0%)
dist/index.cjs 7.16 KB (0%)