Skip to content

Commit

Permalink
[docs] Content 5: Menu, Preview Card (#959)
Browse files Browse the repository at this point in the history
  • Loading branch information
vladmoroz authored Dec 4, 2024
1 parent 7a5f1c7 commit 4f66e05
Show file tree
Hide file tree
Showing 21 changed files with 617 additions and 23 deletions.
2 changes: 1 addition & 1 deletion docs/data/api/input.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
"forwardsRefTo": "HTMLInputElement",
"filename": "/packages/react/src/input/Input.tsx",
"inheritance": null,
"demos": "<ul><li><a href=\"/components/react-input/\">Text Input</a></li></ul>",
"demos": "<ul><li><a href=\"/components/react-input/\">Input</a></li></ul>",
"cssComponent": false
}
2 changes: 1 addition & 1 deletion docs/data/components/input/input.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ githubLabel: 'component: input'
packageName: '@base-ui-components/react'
---

# Text Input
# Input

<Description />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import * as React from 'react';
import { Input } from '@base-ui-components/react/input';
import styles from './index.module.css';

export default function ExampleTextInput() {
export default function ExampleInput() {
return <Input placeholder="Name" className={styles.Input} />;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { Input } from '@base-ui-components/react/input';

export default function ExampleTextInput() {
export default function ExampleInput() {
return (
<Input
placeholder="Name"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
.Button {
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
gap: 0.375rem;
height: 2.5rem;
padding: 0 0.875rem;
margin: 0;
outline: 0;
border: 1px solid var(--color-gray-200);
border-radius: 0.375rem;
background-color: var(--color-gray-50);
font-family: inherit;
font-size: 1rem;
font-weight: 500;
line-height: 1.5rem;
color: var(--color-gray-900);
user-select: none;

@media (hover: hover) {
&:hover {
background-color: var(--color-gray-100);
}
}

&:active {
background-color: var(--color-gray-100);
}

&[data-popup-open] {
background-color: var(--color-gray-100);
}

&:focus-visible {
outline: 2px solid var(--color-blue);
outline-offset: -1px;
}
}

.ButtonIcon {
margin-right: -0.25rem;
}

.Positioner {
outline: 0;
}

.Popup {
box-sizing: border-box;
padding-block: 0.25rem;
border-radius: 0.375rem;
background-color: canvas;
color: var(--color-gray-900);
transform-origin: var(--transform-origin);
transition:
transform 150ms,
opacity 150ms;

&[data-starting-style],
&[data-ending-style] {
opacity: 0;
transform: scale(0.9);
}

@media (prefers-color-scheme: light) {
outline: 1px solid var(--color-gray-200);
box-shadow:
0px 10px 15px -3px var(--color-gray-200),
0px 4px 6px -4px var(--color-gray-200);
}

@media (prefers-color-scheme: dark) {
outline: 1px solid var(--color-gray-300);
outline-offset: -1px;
}
}

.Arrow {
display: flex;

&[data-side='top'] {
bottom: -8px;
rotate: 180deg;
}
&[data-side='bottom'] {
top: -8px;
rotate: 0deg;
}
&[data-side='left'] {
right: -13px;
rotate: 90deg;
}
&[data-side='right'] {
left: -13px;
rotate: -90deg;
}
}

.ArrowFill {
fill: canvas;
}

.ArrowOuterStroke {
@media (prefers-color-scheme: light) {
fill: var(--color-gray-200);
}
}

.ArrowInnerStroke {
@media (prefers-color-scheme: dark) {
fill: var(--color-gray-300);
}
}

.Item {
outline: 0;
cursor: default;
user-select: none;
padding-block: 0.5rem;
padding-left: 1rem;
padding-right: 2rem;
display: flex;
font-size: 0.9375rem;
line-height: 1rem;

&[data-highlighted] {
z-index: 0;
position: relative;
color: var(--color-gray-50);
}
&[data-highlighted]::before {
content: '';
z-index: -1;
position: absolute;
inset-block: 0;
inset-inline: 0.25rem;
border-radius: 0.25rem;
background-color: var(--color-gray-900);
}
}

.Separator {
margin: 0.375rem 1rem;
height: 1px;
background-color: var(--color-gray-200);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import * as React from 'react';
import { Menu } from '@base-ui-components/react/menu';
import styles from './index.module.css';

export default function ExampleMenu() {
return (
<Menu.Root>
<Menu.Trigger className={styles.Button}>
Song <ChevronDownIcon className={styles.ButtonIcon} />
</Menu.Trigger>
<Menu.Positioner className={styles.Positioner} sideOffset={8}>
<Menu.Popup className={styles.Popup}>
<Menu.Arrow className={styles.Arrow}>
<ArrowSvg />
</Menu.Arrow>
<Menu.Item className={styles.Item}>Add to Library</Menu.Item>
<Menu.Item className={styles.Item}>Add to Playlist</Menu.Item>
<Menu.Separator className={styles.Separator} />
<Menu.Item className={styles.Item}>Play</Menu.Item>
<Menu.Item className={styles.Item}>Play Next</Menu.Item>
<Menu.Item className={styles.Item}>Play Last</Menu.Item>
<Menu.Separator className={styles.Separator} />
<Menu.Item className={styles.Item}>Favorite</Menu.Item>
<Menu.Item className={styles.Item}>Share</Menu.Item>
</Menu.Popup>
</Menu.Positioner>
</Menu.Root>
);
}

function ArrowSvg(props: React.ComponentProps<'svg'>) {
return (
<svg width="20" height="10" viewBox="0 0 20 10" fill="none" {...props}>
<path
d="M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z"
className={styles.ArrowFill}
/>
<path
d="M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z"
className={styles.ArrowOuterStroke}
/>
<path
d="M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z"
className={styles.ArrowInnerStroke}
/>
</svg>
);
}

function ChevronDownIcon(props: React.ComponentProps<'svg'>) {
return (
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" {...props}>
<path d="M1 3.5L5 7.5L9 3.5" stroke="currentcolor" />
</svg>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
'use client';
export { default as CssModules } from './css-modules';
export { default as Tailwind } from './tailwind';
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import * as React from 'react';
import { Menu } from '@base-ui-components/react/menu';

export default function ExampleMenu() {
return (
<Menu.Root>
<Menu.Trigger className="flex h-10 items-center justify-center gap-1.5 rounded-md border border-gray-200 bg-gray-50 px-3.5 font-medium text-gray-900 select-none hover:bg-gray-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-blue-800 active:bg-gray-100 data-[popup-open]:bg-gray-100">
Song <ChevronDownIcon className="-mr-1" />
</Menu.Trigger>
<Menu.Positioner className="outline-0" sideOffset={8}>
<Menu.Popup className="origin-[var(--transform-origin)] rounded-md bg-[canvas] py-1 text-gray-900 shadow-lg shadow-gray-200 outline outline-gray-200 transition-[transform,scale,opacity] dark:shadow-none dark:-outline-offset-1 dark:outline-gray-300 [[data-starting-style],[data-ending-style]]:scale-90 [[data-starting-style],[data-ending-style]]:opacity-0">
<Menu.Arrow className="data-[side=bottom]:top-[-8px] data-[side=left]:right-[-13px] data-[side=left]:rotate-90 data-[side=right]:left-[-13px] data-[side=right]:-rotate-90 data-[side=top]:bottom-[-8px] data-[side=top]:rotate-180">
<ArrowSvg />
</Menu.Arrow>
<Menu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-0 select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:-z-1 data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
Add to Library
</Menu.Item>
<Menu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-0 select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:-z-1 data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
Add to Playlist
</Menu.Item>
<Menu.Separator className="mx-4 my-1.5 h-px bg-gray-200" />
<Menu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-0 select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:-z-1 data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
Play
</Menu.Item>
<Menu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-0 select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:-z-1 data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
Play Next
</Menu.Item>
<Menu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-0 select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:-z-1 data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
Play Last
</Menu.Item>
<Menu.Separator className="mx-4 my-1.5 h-px bg-gray-200" />
<Menu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-0 select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:-z-1 data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
Favorite
</Menu.Item>
<Menu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-0 select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:-z-1 data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900">
Share
</Menu.Item>
</Menu.Popup>
</Menu.Positioner>
</Menu.Root>
);
}

function ArrowSvg(props: React.ComponentProps<'svg'>) {
return (
<svg width="20" height="10" viewBox="0 0 20 10" fill="none" {...props}>
<path
d="M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z"
className="fill-[canvas]"
/>
<path
d="M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z"
className="fill-gray-200 dark:fill-none"
/>
<path
d="M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z"
className="dark:fill-gray-300"
/>
</svg>
);
}

function ChevronDownIcon(props: React.ComponentProps<'svg'>) {
return (
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" {...props}>
<path d="M1 3.5L5 7.5L9 3.5" stroke="currentcolor" />
</svg>
);
}
41 changes: 41 additions & 0 deletions docs/src/app/new/(content)/components/menu/page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Menu

<Subtitle>A list of actions in a dropdown, enhanced with keyboard navigation.</Subtitle>
<Meta
name="description"
content="A high-quality, unstyled React menu component that displays list of actions in a dropdown, enhanced with keyboard navigation."
/>

<Demo path="./demos/hero" />

## API reference

Import the component and place its parts the following way:

```jsx title="Anatomy"
import { Menu } from '@base-ui-components/react/menu';

<Menu.Root>
<Menu.Trigger />
<Menu.Positioner>
<Menu.Popup>
<Menu.Arrow />
<Menu.Item />
<Menu.Separator />
<Menu.Group>
<Menu.GroupLabel />
</Menu.Group>
<Menu.RadioGroup>
<Menu.RadioItem />
</Menu.RadioGroup>
<Menu.CheckboxItem />
</Menu.Popup>
</Menu.Positioner>
</Menu.Root>;
```

<Reference
component="Menu"
parts="Root, Trigger, Positioner, Popup, Arrow, Item, Group, GroupLabel, RadioGroup, RadioItem, RadioItemIndicator, CheckboxItem, CheckboxItemIndicator"
/>
{/* TODO: SubmenuTrigger and Separator are missing */}
4 changes: 1 addition & 3 deletions docs/src/app/new/(content)/components/number-field/page.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# Number Field

<Subtitle>
An numeric input element with increment and decrement buttons, and a scrub area.
</Subtitle>
<Subtitle>A numeric input element with increment and decrement buttons, and a scrub area.</Subtitle>

<Meta
name="description"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.Button {
.IconButton {
box-sizing: border-box;
display: flex;
align-items: center;
Expand Down Expand Up @@ -40,8 +40,10 @@
border-radius: 0.5rem;
background-color: canvas;
color: var(--color-gray-900);
transition: all 150ms;
transform-origin: var(--transform-origin);
transition:
transform 150ms,
opacity 150ms;

&[data-starting-style],
&[data-ending-style] {
Expand All @@ -63,6 +65,8 @@
}

.Arrow {
display: flex;

&[data-side='top'] {
bottom: -8px;
rotate: 180deg;
Expand Down
Loading

0 comments on commit 4f66e05

Please sign in to comment.