Merge pull request #32340 from Believe-SA/docs/hooks
feat(docs-ui): document BUI's hooks
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
import { HookGrid } from '@/components/HookGrid';
|
||||
|
||||
# Hooks
|
||||
|
||||
Backstage UI custom hooks provide easy access to design system features, style management, and responsive interface creation.
|
||||
|
||||
<HookGrid />
|
||||
@@ -0,0 +1,17 @@
|
||||
'use client';
|
||||
|
||||
import { useBreakpoint } from '@backstage/ui';
|
||||
|
||||
export function UseBreakpointExample() {
|
||||
const { breakpoint, up, down } = useBreakpoint();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>Current Breakpoint: {breakpoint}</p>
|
||||
{(up('md') && <p>The viewport is larger than 1024px.</p>) ||
|
||||
(down('sm') && <p>The viewport is smaller than 768px.</p>) || (
|
||||
<p>The viewport is between 768px and 1024px.</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { ChangelogComponent } from '@/components/ChangelogComponent';
|
||||
import { PageTitle } from '@/components/PageTitle';
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { Banner } from '@/components/Banner';
|
||||
import { useBreakpointReturnDefs } from './props-definition';
|
||||
import { useBreakpointExampleSnippet } from './snippets';
|
||||
import { UseBreakpointExample } from './components';
|
||||
|
||||
<PageTitle
|
||||
title="useBreakpoint"
|
||||
description="A hook to detect responsive breakpoints and manage responsive layouts."
|
||||
/>
|
||||
|
||||
## Usage
|
||||
|
||||
<Banner
|
||||
variant="warning"
|
||||
text="This hook has performance issues and should be used with caution."
|
||||
/>
|
||||
|
||||
The `useBreakpoint` hook returns the active breakpoint and two functions, `up` and `down`, to check if the viewport is above, or below a given breakpoint, letting you adjust your UI responsively.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
height={150}
|
||||
preview={<UseBreakpointExample />}
|
||||
code={useBreakpointExampleSnippet}
|
||||
/>
|
||||
|
||||
## Breakpoints
|
||||
|
||||
The default breakpoints are:
|
||||
|
||||
- **initial**: < 640px
|
||||
- **xs**: ≥ 640px < 768px
|
||||
- **sm**: ≥ 768px < 1024px
|
||||
- **md**: ≥ 1024px < 1280px
|
||||
- **lg**: ≥ 1280px < 1536px
|
||||
- **xl**: ≥ 1536px
|
||||
|
||||
## Return Value
|
||||
|
||||
<PropsTable data={useBreakpointReturnDefs} isHook />
|
||||
|
||||
<ChangelogComponent hook="use-breakpoint" />
|
||||
@@ -0,0 +1,23 @@
|
||||
import { type PropDef } from '@/utils/propDefs';
|
||||
|
||||
const Breakpoint = ['"initial"', '"xs"', '"sm"', '"md"', '"lg"', '"xl"'];
|
||||
|
||||
export const useBreakpointReturnDefs: Record<string, PropDef> = {
|
||||
breakpoint: {
|
||||
type: 'enum',
|
||||
values: Breakpoint,
|
||||
description: 'The current active breakpoint based on screen width',
|
||||
},
|
||||
up: {
|
||||
type: 'enum',
|
||||
values: [`(breakpoint: ${Breakpoint.join(' | ')}) => boolean`],
|
||||
description:
|
||||
'Function that takes a breakpoint and returns true if the screen width is at or above that breakpoint',
|
||||
},
|
||||
down: {
|
||||
type: 'enum',
|
||||
values: [`(breakpoint: ${Breakpoint.join(' | ')}) => boolean`],
|
||||
description:
|
||||
'Function that takes a breakpoint and returns true if the screen width is at or below that breakpoint',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
export const useBreakpointExampleSnippet = `import { useBreakpoint } from '@backstage/ui';
|
||||
|
||||
function ResponsiveComponent() {
|
||||
const { breakpoint, up, down } = useBreakpoint();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>Current Breakpoint: {breakpoint}</p>
|
||||
{up('md') && <p>The viewport is medium or larger.</p>}
|
||||
{down('sm') && <p>The viewport is small or smaller.</p>}
|
||||
</div>
|
||||
);
|
||||
}`;
|
||||
@@ -16,13 +16,13 @@
|
||||
.info {
|
||||
background-color: #f2f2f2;
|
||||
border-color: #cdcdcd;
|
||||
color: #888888;
|
||||
color: #4b4b4b;
|
||||
}
|
||||
|
||||
.warning {
|
||||
background-color: #fff2b9;
|
||||
border-color: #ffd000;
|
||||
color: #d79927;
|
||||
border-color: #d79927;
|
||||
color: #8a3d09;
|
||||
}
|
||||
|
||||
.icon {
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
import { changelog } from '@/utils/changelog';
|
||||
import { MDXRemote } from 'next-mdx-remote-client/rsc';
|
||||
import { formattedMDXComponents } from '@/mdx-components';
|
||||
import type { Component } from '@/utils/changelog';
|
||||
import type { AtLeastOne, Component, Hook } from '@/utils/changelog';
|
||||
import {
|
||||
Badge,
|
||||
BreakingBadge,
|
||||
generateChangelogMarkdown,
|
||||
} from '../Changelog/utils';
|
||||
|
||||
export const ChangelogComponent = ({ component }: { component: Component }) => {
|
||||
const componentChangelog = changelog.filter(c =>
|
||||
c.components.includes(component),
|
||||
type ChangelogComponentProps = AtLeastOne<{
|
||||
component: Component;
|
||||
hook: Hook;
|
||||
}>;
|
||||
|
||||
export const ChangelogComponent = ({
|
||||
component,
|
||||
hook,
|
||||
}: Readonly<ChangelogComponentProps>) => {
|
||||
const componentChangelog = changelog.filter(
|
||||
c => c.components?.includes(component) || c.hooks?.includes(hook),
|
||||
);
|
||||
|
||||
const content = `## Changelog
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.grid {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 10px 0;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: var(--primary);
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: var(--link);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
'use client';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { hooks } from '@/utils/data';
|
||||
import styles from './HookGrid.module.css';
|
||||
|
||||
export const HookGrid = () => {
|
||||
return (
|
||||
<div className={styles.grid}>
|
||||
{hooks.map(item => (
|
||||
<Link
|
||||
key={item.slug}
|
||||
href={`/hooks/${item.slug}`}
|
||||
className={styles.item}
|
||||
>
|
||||
{item.title}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export * from './HookGrid';
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
RiServiceLine,
|
||||
RiStackLine,
|
||||
} from '@remixicon/react';
|
||||
import { components } from '@/utils/data';
|
||||
import { components, hooks } from '@/utils/data';
|
||||
import styles from './Navigation.module.css';
|
||||
|
||||
interface NavigationProps {
|
||||
@@ -92,6 +92,29 @@ export const Navigation = ({ onLinkClick }: NavigationProps) => {
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
<div className={styles.sectionTitle}>
|
||||
<RiCollageLine size={20} /> <span>Hooks</span>
|
||||
</div>
|
||||
{hooks.map(item => {
|
||||
const isActive = pathname === `/hooks/${item.slug}`;
|
||||
return (
|
||||
<Link
|
||||
href={`/hooks/${item.slug}`}
|
||||
key={item.slug}
|
||||
className={clsx(styles.line, { [styles.active]: isActive })}
|
||||
onClick={onLinkClick}
|
||||
>
|
||||
<div className={styles.lineTitle}>{item.title}</div>
|
||||
<div className={styles.lineStatus}>
|
||||
{item.status === 'alpha' && 'Alpha'}
|
||||
{item.status === 'beta' && 'Beta'}
|
||||
{item.status === 'inProgress' && 'In Progress'}
|
||||
{item.status === 'stable' && 'Stable'}
|
||||
{item.status === 'deprecated' && 'Deprecated'}
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -138,3 +138,10 @@ export const components: Page[] = [
|
||||
slug: 'visually-hidden',
|
||||
},
|
||||
];
|
||||
|
||||
export const hooks: Page[] = [
|
||||
{
|
||||
title: 'useBreakpoint',
|
||||
slug: 'use-breakpoint',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -35,14 +35,22 @@ export type Component =
|
||||
| 'tooltip'
|
||||
| 'visually-hidden';
|
||||
|
||||
export type Hook = 'use-breakpoint';
|
||||
|
||||
export type Version = `${number}.${number}.${number}`;
|
||||
|
||||
export interface ChangelogProps {
|
||||
components: Component[];
|
||||
export type AtLeastOne<T, K extends keyof T = keyof T> = K extends string
|
||||
? Pick<T, K> & Partial<Omit<T, K>>
|
||||
: never;
|
||||
|
||||
export type ChangelogProps = {
|
||||
description: string;
|
||||
version: Version;
|
||||
prs: string[];
|
||||
breaking?: boolean;
|
||||
commitSha?: string;
|
||||
migration?: string;
|
||||
}
|
||||
} & AtLeastOne<{
|
||||
components: Component[];
|
||||
hooks: Hook[];
|
||||
}>;
|
||||
|
||||
Reference in New Issue
Block a user