Skip to content

Commit

Permalink
feat(util): add useDocument hook (#528)
Browse files Browse the repository at this point in the history
Migrates useDocument from the VE starter to this repo. Also moves
DocumentProvider. Documentation added to README.md

Co-authored-by: Matt Kilpatrick <[email protected]>
  • Loading branch information
brian-baugher and mkilpatrick authored Jul 23, 2024
1 parent 8fd95b1 commit f27199a
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ PagesJS is a collection of tools that make it easy to develop on [Yext Pages](ht
## Utility Functions

| Function |
| -------------------------------------------------------------------------------------------------------- |
| -------------------------------------------------------------------------------------------------------- | --- |
| [fetch()](https://github.com/yext/pages/blob/main/packages/pages/src/util/README.md#fetch) |
| [getRuntime()](https://github.com/yext/pages/blob/main/packages/pages/src/util/README.md#getRuntime) |
| [isProduction()](https://github.com/yext/pages/blob/main/packages/pages/src/util/README.md#isProduction) |
| [useDocument()](https://github.com/yext/pages/blob/main/packages/pages/src/util/README.md#useDocument) | |

## Development

Expand Down
31 changes: 31 additions & 0 deletions packages/pages/src/util/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,34 @@ Determines if the code is being executed on the production site on the client. T
## dynamic()

A component that will dynamically load an import, similar to React 18's lazy component.

## useDocument()

A React hook that returns a Content stream document stored in Context. Must be used within a
[DocumentProvider](#DocumentProvider)

ex.

```tsx
export const MyComponent = () => {
const {
hours,
address,
name: locationName,
c_hero: hero,
} = useDocument<LocationStream>();
};
```

## DocumentProvider

React component which should wrap any components using the above `useDocument()` hook.
Required argument to `value` should be the document from Content you wish to use.

ex.

```tsx
<DocumentProvider value={entityDocument}>
<MyComponent />
</DocumentProvider>
```
1 change: 1 addition & 0 deletions packages/pages/src/util/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { getRuntime } from "./runtime.js";
export { isProduction } from "./env.js";
export { dynamic, type DynamicOptions } from "./dynamic.js";
export { DocumentProvider, useDocument } from "./useDocument.js";
30 changes: 30 additions & 0 deletions packages/pages/src/util/useDocument.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import * as React from "react";

const DocumentContext = React.createContext<any | undefined>(undefined);

type DocumentProviderProps<T> = {
value: T;
children: React.ReactNode;
};

const DocumentProvider = <T,>({
value,
children,
}: DocumentProviderProps<T>) => {
return (
<DocumentContext.Provider value={value}>
{children}
</DocumentContext.Provider>
);
};

const useDocument = <T,>(): T => {
const context = React.useContext(DocumentContext);
if (!context) {
throw new Error("useDocument must be used within a DocumentProvider");
}

return context as T;
};

export { DocumentProvider, useDocument };

0 comments on commit f27199a

Please sign in to comment.