Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

99 feature create menucontext apis #101

Merged
merged 14 commits into from
May 30, 2024
16 changes: 0 additions & 16 deletions .github/workflows/docs-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,3 @@ jobs:
- run: pnpm install
- run: pnpm run lint
working-directory: ./docs

docs-build:
runs-on: ubuntu-latest
name: Docs Build
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9.1.2
- uses: actions/setup-node@v4
with:
cache: 'pnpm'

- run: pnpm install
- run: pnpm run build
working-directory: ./docs
5 changes: 3 additions & 2 deletions docs/app/icons/all/components/icons-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ export default function IconsList(props: IconsListProps) {
css({
marginInlineStart: 'auto',
marginInlineEnd: 'auto',
w: 'max-content',
md: {
gridTemplateColumns: 'repeat(13, 4rem)',
gap: '3.5',
w: 'max-content',
},
}),
grid({
Expand All @@ -46,9 +46,10 @@ export default function IconsList(props: IconsListProps) {
>
<Link
className={vstack({
display: 'flex !important',
bgColor: 'neutral.surface.200',
h: 'full',
justify: 'center',
justify: 'center !important',
w: 'full',
rounded: 'md',
transition: 'background-color, color 250ms ease-in-out',
Expand Down
6 changes: 4 additions & 2 deletions docs/app/icons/all/components/searchable-icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,14 @@ export default function SearchableIcons() {
<div
className={container({
position: 'relative',
mt: '4',
})}
>
<div
className={css({
bgColor: 'neutral.surface.100',
position: 'sticky',
py: '2',
top: '0',
top: '-1.75rem',
zIndex: 'sticky',
_after: {
bottom: '-1.8rem',
Expand All @@ -38,6 +37,9 @@ export default function SearchableIcons() {
position: 'absolute',
right: '0',
},
lg: {
top: '-2.5rem',
},
})}
>
<label aria-label="search icons">
Expand Down
4 changes: 1 addition & 3 deletions docs/app/icons/all/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ export default function AllIconsPage() {
return (
<>
<PageMainContent>
<main>
<SearchableIcons />
</main>
<SearchableIcons />
</PageMainContent>

<PageSections>
Expand Down
25 changes: 5 additions & 20 deletions docs/app/preset/colors/components/ColorSwatch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { useThemeContext } from '@cerberus-design/react'
import type { SemanticToken, Sentiment } from '@cerberus-design/panda-preset'
import { useEffect, useMemo, useState } from 'react'
import { css, cx } from '@cerberus-design/styled-system/css'
import { hstack, vstack } from '@cerberus-design/styled-system/patterns'
import { Checkmark } from '@cerberus-design/icons'
import { vstack } from '@cerberus-design/styled-system/patterns'
import { hasWhiteBase } from '@/app/utils/colors'
import Link from 'next/link'

// We have to use !important to override the .MDX styles

const paletteTextStyles = css({
textAlign: 'center',

Expand Down Expand Up @@ -111,11 +111,12 @@ export default function ColorSwatch(props: ColorSwatchProps) {
return (
<Link
className={vstack({
alignItems: 'center',
alignItems: 'center !important',
display: 'flex !important',
justifyContent: 'center',
h: '10rem',
gap: '4',
rounded: 'xl',
rounded: 'xl !important',
textDecoration: 'none',
transition: 'scale 250ms ease-in-out',
w: 'full',
Expand All @@ -127,22 +128,6 @@ export default function ColorSwatch(props: ColorSwatchProps) {
href={`/preset/colors/${props.tokenName}`}
style={bgColor}
>
{copied && (
<span
className={hstack({
bgColor: 'success.surface.active',
color: 'success.text.inverse',
gap: '1',
pxi: '2',
mb: '2',
rounded: 'md',
textStyle: 'body-xs',
})}
>
<Checkmark />
Copied
</span>
)}
<div
data-palette={props.palette}
data-mode={mode}
Expand Down
2 changes: 1 addition & 1 deletion docs/app/react/button/doc.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ define function Button(props: ButtonProps): ReactNode | null

### Props

The `Button` component the following props:
The `Button` component accepts the following props:

| Name | Default | Description |
| -------- | ------- | ------------------------------------------------------------- |
Expand Down
73 changes: 73 additions & 0 deletions docs/app/react/nav-menu/components/nav-menu-preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
'use client'

import { OverflowMenuVertical } from '@cerberus-design/icons'
import {
NavMenu,
NavMenuLink,
NavMenuList,
NavMenuTrigger,
} from '@cerberus-design/react'
import { css, cx } from '@cerberus-design/styled-system/css'
import { button } from '@cerberus-design/styled-system/recipes'
import { forwardRef, type ForwardedRef, type PropsWithChildren } from 'react'

// TODO: Replace with IconButton
function IconButtonEl(
props: PropsWithChildren,
ref: ForwardedRef<HTMLButtonElement>,
) {
return (
<button
aria-label="More options"
className={cx(
css({
pxi: '0.5',
}),
button({
usage: 'text',
shape: 'rounded',
}),
)}
{...props}
ref={ref}
>
<OverflowMenuVertical size={32} />
</button>
)
}
const IconButton = forwardRef(IconButtonEl)

export function BasicNavMenuPreview() {
return (
<NavMenu>
<NavMenuTrigger controls="basic:nav">Features</NavMenuTrigger>
<NavMenuList id="basic:nav">
<NavMenuLink>Something</NavMenuLink>
</NavMenuList>
</NavMenu>
)
}

export function CustomNavMenuPreview() {
return (
<NavMenu>
<NavMenuTrigger as={IconButton} controls="basic:nav">
Features
</NavMenuTrigger>
<NavMenuList id="basic:nav">
<NavMenuLink>Something</NavMenuLink>
</NavMenuList>
</NavMenu>
)
}

export function PositionNavMenuPreview() {
return (
<NavMenu>
<NavMenuTrigger controls="basic:nav">Features</NavMenuTrigger>
<NavMenuList id="basic:nav" position="right">
<NavMenuLink>RightPosition</NavMenuLink>
</NavMenuList>
</NavMenu>
)
}
173 changes: 173 additions & 0 deletions docs/app/react/nav-menu/doc.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
---
npm: '@cerberus-design/react'
source: 'context/navMenu.tsx'
recipe: ''
---

import {
NoteAdmonition,
WhenToUseAdmonition,
WhenNotToUseAdmonition,
} from '@/app/components/Admonition'
import CodePreview from '@/app/components/CodePreview'
import { BasicNavMenuPreview, CustomNavMenuPreview, PositionNavMenuPreview } from '@/app/react/nav-menu/components/nav-menu-preview'

# Nav Menu

A menu that uses a [disclosure pattern](https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/) to show and hide navigation links.

```ts
import {
NavMenu,
NavMenuTrigger,
NavMenuList,
NavMenuLink
} from '@cerberus-design/react'
```

<WhenToUseAdmonition description="When you need display a list of navigation links that show/hide when a button is clicked." />

## Usage

<CodePreview preview={<BasicNavMenuPreview />}>
```tsx title="nav.tsx"
import {
NavMenu,
NavMenuTrigger,
NavMenuList,
NavMenuLink
} from '@cerberus-design/react'

function BasicNavMenuPreview() {
return (
<NavMenu>
<NavMenuTrigger controls="basic:nav">Features</NavMenuTrigger>
<NavMenuList id="basic:nav">
<NavMenuLink>Something</NavMenuLink>
</NavMenuList>
</NavMenu>
)
}
```
</CodePreview>

## NextJS Usage

To use the `NavMenuLink` component with NextJS, you should use the `Link` component from `next/link` for the `as` prop.

<CodePreview preview={<CustomNavMenuPreview />}>
```tsx title="nav.tsx" {8,15}
import {
NavMenu,
NavMenuTrigger,
NavMenuList,
NavMenuLink
} from '@cerberus-design/react'
import MoreOptionsButton from './MoreOptionsButton'
import Link from '@next/link'

function BasicNavMenuPreview() {
return (
<NavMenu>
<NavMenuTrigger as={MoreOptionsButton} controls="basic:nav">Features</NavMenuTrigger>
<NavMenuList id="basic:nav">
<NavMenuLink as={Link}>Something</NavMenuLink>
</NavMenuList>
</NavMenu>
)
}
```
</CodePreview>

## Positions

The `NavMenuList` component accepts a `position` prop to determine where the menu will be positioned relative to the trigger. [See available positions](#navmenulist).

<CodePreview preview={<PositionNavMenuPreview />}>
```tsx title="nav.tsx" {12}
import {
NavMenu,
NavMenuTrigger,
NavMenuList,
NavMenuLink
} from '@cerberus-design/react'

function PositionNavMenuPreview() {
return (
<NavMenu>
<NavMenuTrigger controls="basic:nav">Features</NavMenuTrigger>
<NavMenuList id="basic:nav" position="right">
<NavMenuLink>RightPosition</NavMenuLink>
</NavMenuList>
</NavMenu>
)
}
```
</CodePreview>

## API

### NavMenuTrigger

```ts showLineNumbers=false
export interface NavMenuTriggerProps
extends ButtonHTMLAttributes<HTMLButtonElement>,
ButtonProps,
NavTriggerAriaValues {
as?: ElementType
}

define function NavMenuTrigger(props: NavMenuTriggerProps): ReactNode | null
```

#### Props

The `NavMenuTrigger` component accepts the following props in addition to the props of the [Button](./button) component:

| Name | Default | Description |
| -------- | ------- | ------------------------------------------------------------- |
| as | null | A custom component to render as the Trigger. |
| controls | null | REQUIRED. The `id` of the menu the trigger will control. |
| expanded | false | A custom component to render as the Trigger. |

<NoteAdmonition description="Custom components must be able to recieve a 'ref' object via 'forwardRef'." />

### NavMenuList

```ts showLineNumbers=false
export interface NavMenuListProps extends HTMLAttributes<HTMLUListElement> {
id: string
}

define function NavMenuList(props: NavMenuListProps): ReactNode | null
```

#### Props

The `NavMenuList` component accepts the following props:

| Name | Default | Description |
| -------- | ------- | ------------------------------------------------------------- |
| id | null | REQUIRED. A custom `id` to associate with the trigger. |
| position | `left` | The position of the menu relative to the trigger. Can be `left`, `right`, `top`, or `bottom`. |

### NavMenuLink

```ts showLineNumbers=false
export interface NavMenuLinkProps
extends AnchorHTMLAttributes<HTMLAnchorElement> {
as?: ElementType
}

define function NavMenuLink(props: NavMenuLinkProps): ReactNode | null
```

#### Props

The `NavMenuLink` component accepts the following props:

| Name | Default | Description |
| -------- | ------- | ------------------------------------------------------------- |
| as | null | A custom component to render as the Trigger. |

<NoteAdmonition description="Custom components must be able to recieve a 'ref' object via 'forwardRef'." />
Loading