Skip to content

Commit

Permalink
Add documentation for hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
acelaya committed Sep 2, 2024
1 parent c1aa030 commit 97a7d07
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/hooks/use-click-away.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type UseClickAwayOptions = {

/**
* Listen on document.body for click events. If a click event's target is
* outside of the `container` element, invoke the `callback`. Do not listen if
* outside the `container` element, invoke the `callback`. Do not listen if
* not `enabled`.
*/
export function useClickAway(
Expand Down
12 changes: 9 additions & 3 deletions src/pattern-library/components/Library.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -544,18 +544,24 @@ function Code({ size, title, ...rest }: LibraryCodeProps) {
}

export type LibraryUsageProps = {
componentName: string;
/** @deprecated. Use symbolName instead */
componentName?: string;
symbolName?: string;
size?: 'sm' | 'md';
};

/**
* Render import "usage" of a given `componentName`
*/
function Usage({ componentName, size = 'md' }: LibraryUsageProps) {
function Usage({
componentName,
symbolName = componentName,
size = 'md',
}: LibraryUsageProps) {
const importPath = '@hypothesis/frontend-shared';
return (
<Code
content={`import { ${componentName} } from '${importPath}';
content={`import { ${symbolName} } from '${importPath}';
`}
size={size}
/>
Expand Down
10 changes: 10 additions & 0 deletions src/pattern-library/components/PlaygroundApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,12 @@ export default function PlaygroundApp({

const prototypeRoutes = getRoutes('prototype');

const hookRoutes = getRoutes('hooks');

const groupKeys = Object.keys(componentGroups) as Array<
keyof typeof componentGroups
>;

return (
<Router base={baseURL}>
<div className="w-full bg-stone-200">
Expand Down Expand Up @@ -194,6 +197,13 @@ export default function PlaygroundApp({
);
})}

<NavHeader>Hooks</NavHeader>
<NavList>
{hookRoutes.map(route => (
<NavLink key={route.title} route={route} />
))}
</NavList>

{prototypeRoutes.length > 0 && (
<>
<NavHeader>Prototypes</NavHeader>
Expand Down
88 changes: 88 additions & 0 deletions src/pattern-library/components/patterns/hooks/UseClickAwayPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import Library from '../../Library';

export default function UseClickAwayPage() {
return (
<Library.Page
title="useClickAway"
intro={
<p>
<code>useClickAway</code> is a hook to listen for click events on{' '}
<code>document.body</code>. If an event{"'"}s target is outside the
container element, it invokes a callback.
</p>
}
>
<Library.Section>
<Library.Pattern>
<Library.Usage symbolName="useClickAway" />
<Library.Example>
<Library.Demo
withSource
title="Basic useClickAway"
exampleFile="use-click-away-basic"
/>
</Library.Example>
</Library.Pattern>

<Library.Pattern title="Hook arguments">
<Library.Example title="container">
<Library.Info>
<Library.InfoItem label="description">
A Ref to the DOM element used to evaluate if clicking happened{' '}
{'"'}
away{'"'}.
</Library.InfoItem>
<Library.InfoItem label="type">
<code>{`RefObject<HTMLElement | undefined>`}</code>
</Library.InfoItem>
</Library.Info>
</Library.Example>
<Library.Example title="callback">
<Library.Info>
<Library.InfoItem label="description">
The callback to be invoked when clicking away. The click event
object is passed to it.
</Library.InfoItem>
<Library.InfoItem label="type">
<code>{`(e: Event) => void`}</code>
</Library.InfoItem>
</Library.Info>
</Library.Example>
<Library.Example title="options">
<Library.Info>
<Library.InfoItem label="description">
Options to configure the hook{"'"}s behavior.
</Library.InfoItem>
<Library.InfoItem label="type">
See{' '}
<Library.Link href="#hook-options">hook options</Library.Link>{' '}
below for details.
</Library.InfoItem>
</Library.Info>
</Library.Example>
</Library.Pattern>

<Library.Pattern title="Hook options" id="hook-options">
<Library.Example title="enabled">
<Library.Info>
<Library.InfoItem label="description">
Allows the hook to be conditionally enabled or disabled, for
example, if the container it handles is dynamically hidden or
unmounted.
</Library.InfoItem>
<Library.InfoItem label="type">
<code>{`boolean`}</code>
</Library.InfoItem>
<Library.InfoItem label="default">
<code>{`true`}</code>
</Library.InfoItem>
</Library.Info>
<Library.Code
content={`useClickAway(containerRef, callback, { enabled: false })`}
/>
</Library.Example>
</Library.Pattern>
</Library.Section>
</Library.Page>
);
}
27 changes: 27 additions & 0 deletions src/pattern-library/examples/use-click-away-basic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import classnames from 'classnames';
import { useRef, useState } from 'preact/hooks';

import { Button } from '../../components/input';
import { useClickAway } from '../../hooks/use-click-away';

export default function App() {
const [clickedAway, setClickedAway] = useState(false);
const containerRef = useRef<HTMLDivElement | null>(null);

useClickAway(containerRef, () => setClickedAway(true));

return (
<div
ref={containerRef}
className={classnames(
'rounded-lg h-32 w-full p-2 flex items-center justify-center gap-2',
{ 'bg-red-100': clickedAway, 'bg-amber-100': !clickedAway },
)}
>
{clickedAway ? 'You clicked outside the area' : 'Click outside this area'}
{clickedAway && (
<Button onClick={() => setClickedAway(false)}>Reset</Button>
)}
</div>
);
}
8 changes: 8 additions & 0 deletions src/pattern-library/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import CalloutPage from './components/patterns/feedback/CalloutPage';
import DialogPage from './components/patterns/feedback/DialogPage';
import SpinnerPage from './components/patterns/feedback/SpinnerPage';
import ToastMessagesPage from './components/patterns/feedback/ToastMessagesPage';
import UseClickAwayPage from './components/patterns/hooks/UseClickAwayPage';
import ButtonsPage from './components/patterns/input/ButtonPage';
import CheckboxPage from './components/patterns/input/CheckboxPage';
import CloseButtonPage from './components/patterns/input/CloseButtonPage';
Expand Down Expand Up @@ -53,6 +54,7 @@ export type PlaygroundRouteGroup =
| 'home'
| 'foundations'
| 'components'
| 'hooks'
| 'prototype'
| 'custom';

Expand Down Expand Up @@ -262,6 +264,12 @@ const routes: PlaygroundRoute[] = [
component: SliderPage,
route: '/transitions-slider',
},
{
title: 'useClickAway',
group: 'hooks',
component: UseClickAwayPage,
route: '/hooks-use-click-away',
},
{
title: 'Import/Export Dialog',
group: 'prototype',
Expand Down

0 comments on commit 97a7d07

Please sign in to comment.