From c767a0949e23e90279943abd4bb26e7de6460201 Mon Sep 17 00:00:00 2001
From: sarahgm <38324334+sarahgm@users.noreply.github.com>
Date: Wed, 26 Jul 2023 08:26:34 +0200
Subject: [PATCH] docs: add Hook docs pages (#3215)
---
docs/app/_components/Navigation.tsx | 24 +++++++
docs/app/hooks/[...slug]/page.tsx | 59 +++++++++++++++++
docs/content/hooks/.eslintrc.js | 8 +++
.../hooks/useAsyncListData/async.demo.tsx | 66 +++++++++++++++++++
.../useAsyncListData/useAsyncListData.mdx | 29 ++++++++
docs/content/hooks/useTheme/useTheme.demo.tsx | 24 +++++++
docs/content/hooks/useTheme/useTheme.mdx | 30 +++++++++
docs/contentlayer.config.ts | 26 +++++++-
docs/scripts/build-registry.mjs | 1 +
9 files changed, 266 insertions(+), 1 deletion(-)
create mode 100644 docs/app/hooks/[...slug]/page.tsx
create mode 100644 docs/content/hooks/.eslintrc.js
create mode 100644 docs/content/hooks/useAsyncListData/async.demo.tsx
create mode 100644 docs/content/hooks/useAsyncListData/useAsyncListData.mdx
create mode 100644 docs/content/hooks/useTheme/useTheme.demo.tsx
create mode 100644 docs/content/hooks/useTheme/useTheme.mdx
diff --git a/docs/app/_components/Navigation.tsx b/docs/app/_components/Navigation.tsx
index e8140fa690..20327ceb20 100644
--- a/docs/app/_components/Navigation.tsx
+++ b/docs/app/_components/Navigation.tsx
@@ -6,6 +6,7 @@ import {
allContentPages,
ComponentPage,
allComponentPages,
+ allHookPages,
} from 'contentlayer/generated';
import { siteConfig } from '@/lib/config';
@@ -17,6 +18,24 @@ export interface RenderProps {
onClick?: () => void;
current: string;
}
+export const renderHookPages = ({ onClick, current }: RenderProps) => {
+ const pages = [...allHookPages];
+
+ return pages.map(({ title, slug }) => (
+
+ ));
+};
export const renderContentPages = ({ onClick, current }: RenderProps) => {
const pages = [...allContentPages].sort(
@@ -88,6 +107,11 @@ export const Navigation = ({ onClick }: NavigationProps) => {
Components
{renderComponentPages({ onClick, current: pathname })}
+
+
+
Hooks
+ {renderHookPages({ onClick, current: pathname })}
+
);
};
diff --git a/docs/app/hooks/[...slug]/page.tsx b/docs/app/hooks/[...slug]/page.tsx
new file mode 100644
index 0000000000..1fa75adfb2
--- /dev/null
+++ b/docs/app/hooks/[...slug]/page.tsx
@@ -0,0 +1,59 @@
+import { notFound } from 'next/navigation';
+import { Metadata } from 'next';
+import { allHookPages } from 'contentlayer/generated';
+
+import { Headline } from '@/ui';
+import { Mdx } from '@/ui/mdx';
+
+interface HookPageProps {
+ params: {
+ slug: string[];
+ };
+}
+
+async function getPageFromParams(params: HookPageProps['params']) {
+ const slug = params?.slug?.join('/');
+ const page = allHookPages.find(page => page.slugAsParams === slug);
+
+ if (!page) {
+ return null;
+ }
+
+ return page;
+}
+
+export async function generateMetadata({
+ params,
+}: HookPageProps): Promise {
+ const page = await getPageFromParams(params);
+
+ if (!page) {
+ return {};
+ }
+
+ return {
+ title: page.title,
+ };
+}
+
+export async function generateStaticParams(): Promise<
+ HookPageProps['params'][]
+> {
+ return allHookPages.map(page => ({
+ slug: page.slugAsParams.split('/'),
+ }));
+}
+
+export default async function ContentPage({ params }: HookPageProps) {
+ const page = await getPageFromParams(params);
+ if (!page) {
+ notFound();
+ }
+
+ return (
+
+ {page.title}
+
+
+ );
+}
diff --git a/docs/content/hooks/.eslintrc.js b/docs/content/hooks/.eslintrc.js
new file mode 100644
index 0000000000..ed0d67d029
--- /dev/null
+++ b/docs/content/hooks/.eslintrc.js
@@ -0,0 +1,8 @@
+module.exports = {
+ rules: {
+ /**
+ * We use default exports for demos.
+ */
+ 'import/no-anonymous-default-export': 'off',
+ },
+};
diff --git a/docs/content/hooks/useAsyncListData/async.demo.tsx b/docs/content/hooks/useAsyncListData/async.demo.tsx
new file mode 100644
index 0000000000..6fd5c02035
--- /dev/null
+++ b/docs/content/hooks/useAsyncListData/async.demo.tsx
@@ -0,0 +1,66 @@
+import { Table, useAsyncList } from '@marigold/components';
+
+export interface asyncData {
+ name: string;
+ height: string;
+ mass: string;
+ birth_year: string;
+}
+
+export default () => {
+ let list = useAsyncList({
+ async load({ signal }) {
+ let res = await fetch(`https://swapi.py4e.com/api/people/?search`, {
+ signal,
+ });
+ let json = await res.json();
+ return {
+ items: json.results,
+ };
+ },
+ async sort({ items, sortDescriptor }) {
+ return {
+ items: items.sort((a, b) => {
+ let first = a[sortDescriptor.column as keyof asyncData];
+ let second = b[sortDescriptor.column as keyof asyncData];
+ let cmp =
+ (parseInt(first) || first) < (parseInt(second) || second) ? -1 : 1;
+ if (sortDescriptor.direction === 'descending') {
+ cmp *= -1;
+ }
+ return cmp;
+ }),
+ };
+ },
+ });
+
+ return (
+
+
+
+ Name
+
+
+ Height
+
+
+ Mass
+
+
+ Birth Year
+
+
+
+ {item => (
+
+ {columnKey => {(item as any)[columnKey]}}
+
+ )}
+
+
+ );
+};
diff --git a/docs/content/hooks/useAsyncListData/useAsyncListData.mdx b/docs/content/hooks/useAsyncListData/useAsyncListData.mdx
new file mode 100644
index 0000000000..9fda26b17b
--- /dev/null
+++ b/docs/content/hooks/useAsyncListData/useAsyncListData.mdx
@@ -0,0 +1,29 @@
+---
+title: useAsyncListData
+caption: Hook that returns async data
+---
+
+We use the `useAsyncListData` hook from [`react-spectrum stately package`](https://github.com/adobe/react-spectrum/tree/main/packages/%40react-stately). It extends the `useListData` which is also from `react-spectrum`.
+
+It supports async loading, pagination, sorting and filtering.
+It also manages loading and error states, supports abortable requests and works with any data fetchig library or the built-in browser fetch API.
+
+More information can be found in the [react-spectrum documentation](https://react-spectrum.adobe.com/react-stately/useAsyncList.html).
+
+## Usage
+
+### Import
+
+To import the hook you just have to use this code below.
+
+```tsx
+import { useAsyncListData, useListData } from '@marigold/components';
+```
+
+## Examples
+
+### Async Table
+
+This is an example from the [``](/components/table/) component. The data will be loaded asynchronously.
+
+
diff --git a/docs/content/hooks/useTheme/useTheme.demo.tsx b/docs/content/hooks/useTheme/useTheme.demo.tsx
new file mode 100644
index 0000000000..1c56c8a028
--- /dev/null
+++ b/docs/content/hooks/useTheme/useTheme.demo.tsx
@@ -0,0 +1,24 @@
+import { List } from '@marigold/components';
+import { ThemeProvider, useTheme } from '@marigold/system';
+
+export default () => {
+ const theme = useTheme();
+
+ return (
+
+
+ {Object.entries(theme).map(([key, value]) => (
+
+ {key}
+ {Object.keys(value).map(item => (
+
+ {item}
+
+
+ ))}
+
+ ))}
+
+
+ );
+};
diff --git a/docs/content/hooks/useTheme/useTheme.mdx b/docs/content/hooks/useTheme/useTheme.mdx
new file mode 100644
index 0000000000..cb75c2925f
--- /dev/null
+++ b/docs/content/hooks/useTheme/useTheme.mdx
@@ -0,0 +1,30 @@
+---
+title: useTheme
+caption: Hook that applies a theme
+---
+
+The `useTheme` is a hook that gets you the current theme and all of its attributes and properties.
+
+The `useTheme` hook returns the current `theme`, if there isn't a theme it uses the `defaultTheme`
+
+```tsx
+const theme = useTheme();
+```
+
+## Usage
+
+### Import
+
+To import the hook you just have to use this code below.
+
+```tsx
+import { useTheme } from '@marigold/system';
+```
+
+## Examples
+
+### Get all the Theme Properties
+
+Here is an example which shows you the chosen theme from the theme switcher on the top of the page. With the `useTheme` hook you can get the particular values for the available properties.
+
+
diff --git a/docs/contentlayer.config.ts b/docs/contentlayer.config.ts
index 37b919948a..1c6786cf69 100644
--- a/docs/contentlayer.config.ts
+++ b/docs/contentlayer.config.ts
@@ -80,6 +80,30 @@ export const ComponentPage = defineDocumentType(() => ({
},
}));
+export const HookPage = defineDocumentType(() => ({
+ name: 'HookPage',
+ filePathPattern: 'hooks/**/*.mdx',
+ contentType: 'mdx',
+ fields: {
+ ...commonFields,
+ },
+ computedFields: {
+ slug: {
+ type: 'string',
+ resolve: doc =>
+ `/${doc._raw.flattenedPath.substring(
+ 0,
+ doc._raw.flattenedPath.lastIndexOf('/')
+ )}`,
+ },
+ slugAsParams: {
+ type: 'string',
+ // Slugs are matched agains the name of the component or rather the file name
+ resolve: doc => doc._raw.sourceFileName.split('.')[0],
+ },
+ },
+}));
+
// Config
// ---------------
const contentDirPath = './content';
@@ -166,5 +190,5 @@ export default makeSource({
],
],
},
- documentTypes: [ContentPage, ComponentPage],
+ documentTypes: [ContentPage, ComponentPage, HookPage],
});
diff --git a/docs/scripts/build-registry.mjs b/docs/scripts/build-registry.mjs
index 65561e2a03..23965f6708 100644
--- a/docs/scripts/build-registry.mjs
+++ b/docs/scripts/build-registry.mjs
@@ -17,6 +17,7 @@ import dynamic from 'next/dynamic';
export const registry = {`;
for (const item of demoPath) {
+ console.log(item);
const name = basename(item, '.demo.tsx');
index += `
'${name}': {