Skip to content

Commit

Permalink
docs: add Hook docs pages (#3215)
Browse files Browse the repository at this point in the history
  • Loading branch information
sarahgm authored Jul 26, 2023
1 parent 3ec37df commit c767a09
Show file tree
Hide file tree
Showing 9 changed files with 266 additions and 1 deletion.
24 changes: 24 additions & 0 deletions docs/app/_components/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
allContentPages,
ComponentPage,
allComponentPages,
allHookPages,
} from 'contentlayer/generated';

import { siteConfig } from '@/lib/config';
Expand All @@ -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 }) => (
<div key={slug} className="flex flex-col gap-2">
<div className="border-secondary-300 ml-0.5 flex flex-col gap-2 border-l">
<NavLink
key={slug}
current={current === slug}
href={slug}
onClick={onClick}
>
{title}
</NavLink>
</div>
</div>
));
};

export const renderContentPages = ({ onClick, current }: RenderProps) => {
const pages = [...allContentPages].sort(
Expand Down Expand Up @@ -88,6 +107,11 @@ export const Navigation = ({ onClick }: NavigationProps) => {
<div className="font-semibold">Components</div>
{renderComponentPages({ onClick, current: pathname })}
</div>

<div className="flex flex-col gap-4">
<div className="font-semibold">Hooks</div>
{renderHookPages({ onClick, current: pathname })}
</div>
</nav>
);
};
59 changes: 59 additions & 0 deletions docs/app/hooks/[...slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -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<Metadata> {
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 (
<article className="prose py-6">
<Headline level="1">{page.title}</Headline>
<Mdx code={page.body.code} />
</article>
);
}
8 changes: 8 additions & 0 deletions docs/content/hooks/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
rules: {
/**
* We use default exports for demos.
*/
'import/no-anonymous-default-export': 'off',
},
};
66 changes: 66 additions & 0 deletions docs/content/hooks/useAsyncListData/async.demo.tsx
Original file line number Diff line number Diff line change
@@ -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<asyncData>({
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 (
<Table
aria-label="Example table with client side sorting"
sortDescriptor={list.sortDescriptor}
onSortChange={list.sort}
>
<Table.Header>
<Table.Column key="name" allowsSorting>
Name
</Table.Column>
<Table.Column key="height" allowsSorting>
Height
</Table.Column>
<Table.Column key="mass" allowsSorting>
Mass
</Table.Column>
<Table.Column key="birth_year" allowsSorting>
Birth Year
</Table.Column>
</Table.Header>
<Table.Body items={list.items}>
{item => (
<Table.Row key={(item as any).name}>
{columnKey => <Table.Cell>{(item as any)[columnKey]}</Table.Cell>}
</Table.Row>
)}
</Table.Body>
</Table>
);
};
29 changes: 29 additions & 0 deletions docs/content/hooks/useAsyncListData/useAsyncListData.mdx
Original file line number Diff line number Diff line change
@@ -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 [`<Table>`](/components/table/) component. The data will be loaded asynchronously.

<ComponentDemo file="./async.demo.tsx" />
24 changes: 24 additions & 0 deletions docs/content/hooks/useTheme/useTheme.demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { List } from '@marigold/components';
import { ThemeProvider, useTheme } from '@marigold/system';

export default () => {
const theme = useTheme();

return (
<ThemeProvider theme={theme}>
<div className="w-full overflow-auto">
{Object.entries(theme).map(([key, value]) => (
<List key={key}>
<strong>{key}</strong>
{Object.keys(value).map(item => (
<List.Item>
{item}
<br />
</List.Item>
))}
</List>
))}
</div>
</ThemeProvider>
);
};
30 changes: 30 additions & 0 deletions docs/content/hooks/useTheme/useTheme.mdx
Original file line number Diff line number Diff line change
@@ -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.

<ComponentDemo file="./useTheme.demo.tsx" />
26 changes: 25 additions & 1 deletion docs/contentlayer.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -166,5 +190,5 @@ export default makeSource({
],
],
},
documentTypes: [ContentPage, ComponentPage],
documentTypes: [ContentPage, ComponentPage, HookPage],
});
1 change: 1 addition & 0 deletions docs/scripts/build-registry.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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}': {
Expand Down

2 comments on commit c767a09

@vercel
Copy link

@vercel vercel bot commented on c767a09 Jul 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

marigold-docs – ./

marigold-docs-marigold.vercel.app
marigold-docs-git-main-marigold.vercel.app
marigold-docs.vercel.app

@vercel
Copy link

@vercel vercel bot commented on c767a09 Jul 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

marigold-storybook – ./

marigold-storybook-git-main-marigold.vercel.app
marigold-latest.vercel.app
marigold-storybook-marigold.vercel.app

Please sign in to comment.