diff --git a/examples/.gitkeep b/examples/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/examples/custom-slicezone-props/README.md b/examples/custom-slicezone-props/README.md new file mode 100644 index 0000000..b1a34e9 --- /dev/null +++ b/examples/custom-slicezone-props/README.md @@ -0,0 +1,3 @@ +# Custom `SliceZone` Props + +This example shows how to pass custom props to Slice Zone components. This is helpful when your Slice components require data not contained with a Slice. It can also be helpful if your Slice component was not written specifically to accept a Slice as a prop. diff --git a/examples/custom-slicezone-props/index.tsx b/examples/custom-slicezone-props/index.tsx new file mode 100644 index 0000000..a7cc27e --- /dev/null +++ b/examples/custom-slicezone-props/index.tsx @@ -0,0 +1,91 @@ +/* eslint-disable react/prop-types */ +/* eslint-disable react/display-name */ + +import * as React from "react"; +import { + SliceZone, + SliceComponentProps, + SliceZoneComponents, +} from "@prismicio/react"; + +import { Slices, HeroSlice, ExampleSliceZone } from "./types"; + +// This is the contents of a Slice Zone field. +// Normally, this would be accessed at `document.data.body`, where `document` +// is a Prismic document and `body` is a Slice Zone. +const slices: ExampleSliceZone = [ + { + slice_type: "hero", + slice_label: null, + primary: { + heading: "Lorem ipsum", + buttonText: "Lorem ipsum", + }, + items: [], + }, + { + slice_type: "call_to_action", + slice_label: null, + primary: { + text: "Lorem ipsum dolor sit amet", + }, + items: [], + }, +]; + +// This React component is rendered for Hero Slices. +// It accepts a Slice object as a prop. +const HeroSlice = ({ slice }: SliceComponentProps) => { + return ( +
+

{slice.primary.heading}

+ +
+ ); +}; + +// This React component is rendered for Call To Action Slices. +// +// It does **not** accept a Slice object as a prop. +// +// The SliceZome component will need to extract the content from within the +// Slice object before rendering. +const CallToActionSlice = ({ + text, + disclaimer, +}: { + text: string; + disclaimer: string; +}) => { + return ( +
+

{text}

+ {disclaimer} +
+ ); +}; + +// This object contains a component for each type of Slice that can be rendered +// by ``. +// +// It is important to define this object *outside* the React component that +// uses ``. This ensures the React app will not re-render +// unnecessarily. +const components: SliceZoneComponents = { + // Since HeroSlice accepts a `slice` prop, we can pass the component directly. + hero: HeroSlice, + + // Since CallToActionSLice does not accept a `slice` prop, we must pass the + // props it expects using content from within the Slice object. + // + // We can also pass arbitrary data as well, such as the `disclaimer` prop. + call_to_action: ({ slice }) => ( + + ), +}; + +// We render the Slice Zone using the `` component by passing the +// list of Slices and component map. +export const App = (): JSX.Element => { + return ; +}; diff --git a/examples/custom-slicezone-props/package.json b/examples/custom-slicezone-props/package.json new file mode 100644 index 0000000..08521d4 --- /dev/null +++ b/examples/custom-slicezone-props/package.json @@ -0,0 +1,9 @@ +{ + "type": "module", + "dependencies": { + "@prismicio/react": "alpha" + }, + "devDependencies": { + "@prismicio/types": "^0.1.4" + } +} diff --git a/examples/custom-slicezone-props/types.ts b/examples/custom-slicezone-props/types.ts new file mode 100644 index 0000000..ae41190 --- /dev/null +++ b/examples/custom-slicezone-props/types.ts @@ -0,0 +1,20 @@ +import * as prismicT from "@prismicio/types"; + +export type HeroSlice = prismicT.Slice< + "hero", + { + heading: prismicT.KeyTextField; + buttonText: prismicT.KeyTextField; + } +>; + +export type CallToActionSlice = prismicT.Slice< + "call_to_action", + { + text: prismicT.KeyTextField; + } +>; + +export type Slices = HeroSlice | CallToActionSlice; + +export type ExampleSliceZone = prismicT.SliceZone; diff --git a/examples/router-link/README.md b/examples/router-link/README.md new file mode 100644 index 0000000..12c29a8 --- /dev/null +++ b/examples/router-link/README.md @@ -0,0 +1,3 @@ +# Router Link + +This example shows how to use a router-specific Link component with ``. This is helpful when links within your app need to use a special component for internal Links. `react-router-dom`, for example, requires using its `` component. diff --git a/examples/router-link/index.tsx b/examples/router-link/index.tsx new file mode 100644 index 0000000..73814f9 --- /dev/null +++ b/examples/router-link/index.tsx @@ -0,0 +1,26 @@ +import * as React from "react"; +import * as prismicT from "@prismicio/types"; +import { PrismicLink, LinkProps } from "@prismicio/react"; +import { Link } from "react-router-dom"; + +// This is an example Link field value. It contains a URL internal to the app. +const field: prismicT.LinkField = { + link_type: prismicT.LinkType.Web, + url: "/internal-url", +}; + +// This React component acts as a "shim" to convert the `href` prop provided by +// `` to the `to` prop required by react-router-dom's ``. +const LinkShim = ({ href, ...props }: LinkProps) => { + return ; +}; + +// We render the Link field using ``. Since the field contains an +// internal URL, react-router-dom's `` component will render. +export const App = (): JSX.Element => { + return ( +
+ +
+ ); +}; diff --git a/examples/router-link/package.json b/examples/router-link/package.json new file mode 100644 index 0000000..0075029 --- /dev/null +++ b/examples/router-link/package.json @@ -0,0 +1,11 @@ +{ + "type": "module", + "dependencies": { + "@prismicio/react": "alpha", + "react-router-dom": "^5.2.0" + }, + "devDependencies": { + "@prismicio/types": "^0.1.4", + "@types/react-router-dom": "^5.1.8" + } +} diff --git a/examples/router-link/types.ts b/examples/router-link/types.ts new file mode 100644 index 0000000..ae41190 --- /dev/null +++ b/examples/router-link/types.ts @@ -0,0 +1,20 @@ +import * as prismicT from "@prismicio/types"; + +export type HeroSlice = prismicT.Slice< + "hero", + { + heading: prismicT.KeyTextField; + buttonText: prismicT.KeyTextField; + } +>; + +export type CallToActionSlice = prismicT.Slice< + "call_to_action", + { + text: prismicT.KeyTextField; + } +>; + +export type Slices = HeroSlice | CallToActionSlice; + +export type ExampleSliceZone = prismicT.SliceZone; diff --git a/examples/with-provider/README.md b/examples/with-provider/README.md new file mode 100644 index 0000000..b1a34e9 --- /dev/null +++ b/examples/with-provider/README.md @@ -0,0 +1,3 @@ +# Custom `SliceZone` Props + +This example shows how to pass custom props to Slice Zone components. This is helpful when your Slice components require data not contained with a Slice. It can also be helpful if your Slice component was not written specifically to accept a Slice as a prop. diff --git a/examples/with-provider/index.tsx b/examples/with-provider/index.tsx new file mode 100644 index 0000000..abf053e --- /dev/null +++ b/examples/with-provider/index.tsx @@ -0,0 +1,77 @@ +/* eslint-disable react/prop-types */ +/* eslint-disable react/display-name */ + +import * as React from "react"; +import * as prismicT from "@prismicio/types"; +import { + PrismicProvider, + PrismicLink, + LinkProps, + JSXMapSerializer, + PrismicRichText, +} from "@prismicio/react"; +import { Link } from "react-router-dom"; + +// This is an example Link field value. It contains a URL internal to the app. +const linkField: prismicT.LinkField = { + link_type: prismicT.LinkType.Web, + url: "/internal-url", +}; + +// This is an example Rich Text field value. It contains a "Heading 1" block. +const richTextField: prismicT.RichTextField = [ + { + type: prismicT.RichTextNodeType.heading1, + text: "Lorem ipsum", + spans: [], + }, +]; + +// This React component acts as a "shim" to convert the `href` prop provided by +// `` to the `to` prop required by react-router-dom's ``. +const LinkShim = ({ href, ...props }: LinkProps) => { + return ; +}; + +// This React componetn is used for headings. We will use it when rendering +// "Heading 1" blocks in Rich Text fields. +const Heading = ({ children }: { children: React.ReactNode }) => { + return

{children}

; +}; + +// This object contains components used to render a Rich Text field. +// +// Here we configure PrismicRichText to render the `` component for +// "Heading 1" blocks. +const richTextComponents: JSXMapSerializer = { + heading1: ({ children }) => {children}, +}; + +// This component acts as the main part of the example app. We use +// `` and `` with example fields. +// +// Note that we do not need to pass configuration since it is provided to +// `` higher in the tree (see the "App" component below). +const MyComponent = () => { + return ( +
+ + +
+ ); +}; + +// This React component acts as the app, including the top-level +// ``. We pass global Prismic configuration to the provider at +// this level. By doing so, it becomes available automatically to all Prismic +// components lower in the tree. +export const App = (): JSX.Element => { + return ( + + + + ); +}; diff --git a/examples/with-provider/package.json b/examples/with-provider/package.json new file mode 100644 index 0000000..0075029 --- /dev/null +++ b/examples/with-provider/package.json @@ -0,0 +1,11 @@ +{ + "type": "module", + "dependencies": { + "@prismicio/react": "alpha", + "react-router-dom": "^5.2.0" + }, + "devDependencies": { + "@prismicio/types": "^0.1.4", + "@types/react-router-dom": "^5.1.8" + } +} diff --git a/examples/with-provider/types.ts b/examples/with-provider/types.ts new file mode 100644 index 0000000..ae41190 --- /dev/null +++ b/examples/with-provider/types.ts @@ -0,0 +1,20 @@ +import * as prismicT from "@prismicio/types"; + +export type HeroSlice = prismicT.Slice< + "hero", + { + heading: prismicT.KeyTextField; + buttonText: prismicT.KeyTextField; + } +>; + +export type CallToActionSlice = prismicT.Slice< + "call_to_action", + { + text: prismicT.KeyTextField; + } +>; + +export type Slices = HeroSlice | CallToActionSlice; + +export type ExampleSliceZone = prismicT.SliceZone; diff --git a/src/index.ts b/src/index.ts index c49f14b..6eca45a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -40,3 +40,5 @@ export { usePrismicDocumentsByType, useSinglePrismicDocument, } from "./hooks"; + +export type { JSXMapSerializer, JSXFunctionSerializer } from "./types";