Skip to content

Commit

Permalink
[docs] Convert alpha component docs to new docs template (#392)
Browse files Browse the repository at this point in the history
  • Loading branch information
colmtuite authored Jun 6, 2024
1 parent f85d13d commit 67ab706
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 179 deletions.
98 changes: 34 additions & 64 deletions docs/data/base/components/checkbox/checkbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,108 +10,78 @@ packageName: '@base_ui/react'

# Checkbox

<p class="description">Checkboxes give users binary choices when presented with multiple options in a series.</p>
<p class="description">Checkbox gives users a binary choice between multiple options in a series.</p>

{{"component": "@mui/docs/ComponentLinkHeader", "design": false}}

{{"component": "modules/components/ComponentPageTabs.js"}}

## Introduction

The Checkbox component provides users with a checkbox for toggling a checked state.

{{"demo": "UnstyledCheckboxIntroduction", "defaultCodeOpen": false, "bg": "gradient"}}

## Component
## Installation

```jsx
import * as Checkbox from '@base_ui/react/Checkbox';
```
Base UI components are all available as a single package.

### Anatomy
<codeblock storageKey="package-manager">

The `Checkbox` component is composed of a root component and an indicator child component:

```tsx
<Checkbox.Root>
<Checkbox.Indicator />
</Checkbox.Root>
```bash npm
npm install @base_ui/react
```

The indicator can contain children, such as an icon:

```tsx
<Checkbox.Root>
<Checkbox.Indicator>
<MyCheckIcon />
</Checkbox.Indicator>
</Checkbox.Root>
```bash yarn
yarn add @base_ui/react
```

The indicator conditionally unmounts its children when the checkbox is unchecked. For CSS animations, you can use the `keepMounted` prop to transition `visibility` and `opacity` for example:

```tsx
<Checkbox.Root>
<Checkbox.Indicator keepMounted>
<MyCheckIcon />
</Checkbox.Indicator>
</Checkbox.Root>
```bash pnpm
pnpm add @base_ui/react
```

### Custom structure
</codeblock>

Use the `render` prop to override the rendered checkbox or indicator element with your own components:
Once you have the package installed, import the component.

```jsx
<Checkbox.Root render={(props) => <MyCheckbox {...props} />}>
<Checkbox.Indicator render={(props) => <MyCheckboxIndicator {...props} />} />
</Checkbox.Root>
```ts
import * as Checkbox from '@base_ui/react/Checkbox';
```

To ensure behavior works as expected:
## Anatomy

- **Forward all props**: Your component should spread all props to the underlying element.
- **Forward the `ref`**: Your component should use [`forwardRef`](https://react.dev/reference/react/forwardRef) to ensure the Checkbox components can access the element via a ref.
Checkbox is composed of two components:

A custom component that adheres to these two principles looks like this:
- `<Checkbox.Root />` renders a `<button>`.
- `<Checkbox.Indicator />` renders a `<span>` for providing a visual indicator. You could place an icon inside this component.

```jsx
const MyCheckbox = React.forwardRef(function MyCheckbox(props, ref) {
return <button ref={ref} {...props} />;
});
```tsx
<Checkbox.Root>
<Checkbox.Indicator />
</Checkbox.Root>
```

### Indeterminate state
## Indeterminate state

To make the checkbox indeterminate, add the `indeterminate` prop to override the appearance of the checkbox. The checkbox remains in an indeterminate state regardless of user interaction until set back to `false`.
To make the Checkbox indeterminate, add the `indeterminate` prop to override the appearance of the Checkbox. The Checkbox remains in an indeterminate state regardless of user interaction until set back to `false`.

{{"demo": "UnstyledCheckboxIndeterminate.js"}}

An indeterminate checkbox's main use case is representing the state of a parent checkbox where only some of its children are checked:
The primary use case for an indeterminate checkbox is representing the state of a parent checkbox where only some of its children are checked.

{{"demo": "UnstyledCheckboxIndeterminateGroup.js", "defaultCodeOpen": false}}

It's a **visual-only** state, so it can still have its internal `checked` state change.

## Hook
It's a _visual-only_ state, so its internal `checked` state can still be changed.

```js
import { useCheckbox } from '@base_ui/react/useCheckbox';
```
## Overriding default components

The `useCheckbox` hook lets you apply the functionality of a Checkbox to a fully custom component.
It returns props to be placed on the custom component, along with fields representing the component's internal state.
Use the `render` prop to override the rendered checkbox or indicator element with your own components.

:::info
Hooks give you the most room for customization, but require more work to implement.
With hooks, you can take full control over how your component is rendered, and define all the custom props and CSS classes you need.

You may not need to use hooks unless you find that you're limited by the customization options of their component counterparts—for instance, if your component requires significantly different [HTML structure](#anatomy).
:::
```jsx
<Checkbox.Root render={(props) => <MyCheckbox {...props} />}>
<Checkbox.Indicator render={(props) => <MyCheckboxIndicator {...props} />} />
</Checkbox.Root>
```

## Accessibility

Ensure the checkbox has an accessible name via a `label` element.
Ensure the Checkbox has an accessible name via a `<label>` element.

```jsx
<Checkbox.Root id="my-checkbox">
Expand Down
143 changes: 68 additions & 75 deletions docs/data/base/components/number-field/number-field.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,51 @@ packageName: '@base_ui/react'

# Number Field

<p class="description">The Number Field component provides users with a field for number values, with stepper buttons and a scrub area to increment or decrement the value.</p>
<p class="description">Number Field provides users with a numeric input, with buttons and a scrub area to increment or decrement its value.</p>

{{"component": "@mui/docs/ComponentLinkHeader", "design": false}}

{{"component": "modules/components/ComponentPageTabs.js"}}

## Introduction
{{"demo": "UnstyledNumberFieldIntroduction", "defaultCodeOpen": false, "bg": "gradient"}}

A number field is a UI element that accepts numeric values from the user. `NumberField` is a customizable replacement for the native HTML `<input type="number">` that solves some usability and visual issues while enhancing its functionality.
## Installation

{{"demo": "UnstyledNumberFieldIntroduction", "defaultCodeOpen": false, "bg": "gradient"}}
Base UI components are all available as a single package.

## Component
<codeblock storageKey="package-manager">

```jsx
```bash npm
npm install @base_ui/react
```

```bash yarn
yarn add @base_ui/react
```

```bash pnpm
pnpm add @base_ui/react
```

</codeblock>

Once you have the package installed, import the component.

```ts
import * as NumberField from '@base_ui/react/NumberField';
```

### Anatomy
## Anatomy

Number Field is implemented using a collection of related components:

The `NumberField` component is composed of a root component and a group component which contains an input, and optionally, an increment button, decrement button, and a scrub area with a virtual cursor:
- `<NumberField.Root />` is a top-level component that wraps all other components.
- `<NumberField.Group />` semantically groups the input with the buttons.
- `<NumberField.Input />` is the input itself.
- `<NumberField.Increment />` is an optional button for incrementing the input value.
- `<NumberField.Decrement />` is an optional button for decrementing the input value.
- `<NumberField.ScrubArea />` can wrap an area, icon, or `<label/>` to make it scrubbable.
- `<NumberField.ScrubAreaCursor />` is an optional component for rendering a virtual cursor while scrubbing.

```tsx
<NumberField.Root>
Expand All @@ -45,34 +69,25 @@ The `NumberField` component is composed of a root component and a group componen
</NumberField.Root>
```

### Custom structure

Use the `render` prop to override the rendered elements with your own components:
## Value

```jsx
<NumberField.Root render={(props) => <MyNumberField {...props} />}>
{/* Subcomponents */}
</NumberField.Root>
```

All subcomponents accept the `render` prop.

To ensure behavior works as expected:

- **Forward all props**: Your component should spread all props to the underlying element.
- **Forward the `ref`**: Your component should use [`forwardRef`](https://react.dev/reference/react/forwardRef) to ensure the Number Field components can access the element via a ref.
### Default value

A custom component that adheres to these two principles looks like this:
When Number Field is uncontrolled, the `defaultValue` prop sets the initial value of the input.

```jsx
const MyNumberField = React.forwardRef(function MyNumberField(props, ref) {
return <div ref={ref} {...props} />;
});
<NumberField.Root defaultValue={10}>
<NumberField.Group>
<NumberField.Decrement>&minus;</NumberField.Decrement>
<NumberField.Input />
<NumberField.Increment>+</NumberField.Increment>
</NumberField.Group>
</NumberField.Root>
```

### Value
### Controlled

The `value` prop holds the number value, and `onChange` is called when it updates:
The `value` prop holds the number value, and `onChange` is called when it updates.

```jsx
function App() {
Expand All @@ -89,25 +104,11 @@ function App() {
}
```

This is the controlled way of handling the number field.
## Validation

### Default value
### Min and max

When the number field is uncontrolled, the `defaultValue` prop sets the initial value of the input:

```jsx
<NumberField.Root defaultValue={10}>
<NumberField.Group>
<NumberField.Decrement>&minus;</NumberField.Decrement>
<NumberField.Input />
<NumberField.Increment>+</NumberField.Increment>
</NumberField.Group>
</NumberField.Root>
```

### Min and max values

To prevent the value from going below or above a certain amount, the `min` and `max` props can be used:
The `min` and `max` props can be used to prevent the value from going above or below a certain range.

```jsx
<NumberField.Root min={0} max={100}>
Expand All @@ -121,7 +122,7 @@ To prevent the value from going below or above a certain amount, the `min` and `

### Step

The `step` prop snaps values of the input to ones that are multiples of the given number, affecting how the stepper buttons change the value:
The `step` prop snaps the input value to multiples of the given number. In the below example, the input value snaps to multiples of `step` starting from the `min` value: `2`, `7`, `12`, `17`, and so on.

```jsx
<NumberField.Root step={5} min={2}>
Expand All @@ -133,12 +134,10 @@ The `step` prop snaps values of the input to ones that are multiples of the give
</NumberField.Root>
```

In the above example, the numbers are snapped to multiples of `step` starting from the `min` value: `2`, `7`, `12`, `17` and so on.
You can specify the `largeStep` and `smallStep` props to change the step when the user holds a modifier key:

The `largeStep` and `smallStep` props can be specified to change the step when a modifier key is held:

- `largeStep` is used when <kbd>shift</kbd> is held, incrementing and snapping to multiples of `10`.
- `smallStep` is used when <kbd>alt</kbd> is held, incrementing and snapping to multiples of `0.1`.
- `largeStep` applies when <kbd>shift</kbd> is held, snapping to multiples of 10 by default.
- `smallStep` applies when <kbd>alt</kbd> is held, snapping to multiples of 0.1 by default.

```jsx
<NumberField.Root step={5} largeStep={50} smallStep={0.5}>
Expand All @@ -150,19 +149,19 @@ The `largeStep` and `smallStep` props can be specified to change the step when a
</NumberField.Root>
```

### Format
## Format

The `format` prop accepts [`Intl.NumberFormat` options](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) to customize the formatting of the input value:

{{"demo": "UnstyledNumberFieldFormat.js"}}

### Scrubbing
## Scrubbing

The `ScrubArea` subcomponent lets users scrub the value with their pointer as a faster alternative to the stepper buttons. This is useful in high-density UIs, such as an image editor that changes the width, height, or location of a layer:
The `NumberField.ScrubArea` subcomponent lets users increment/decrement the value via a click+drag interaction with pointer, as a faster alternative to the stepper buttons. This is useful in high-density UIs, such as an image editor that changes the width, height, or location of a layer. You could wrap an icon or a `<label/>` in the `NumberField.ScrubArea` component.

{{"demo": "UnstyledNumberFieldScrub.js"}}

The pointer is locked while scrubbing, allowing the user to scrub infinitely without hitting the window boundary. Since this hides the cursor, you can add a virtual cursor asset using the `NumberField.ScrubAreaCursor` subcomponent, which automatically loops around the boundary:
The pointer is locked while scrubbing, allowing the user to scrub infinitely without hitting the window boundary. Since this hides the cursor, you can add a virtual cursor asset using the `<NumberField.ScrubAreaCursor />` subcomponent, which automatically loops around the boundary.

```jsx
<NumberField.ScrubArea direction="horizontal" style={{ cursor: 'ew-resize' }}>
Expand Down Expand Up @@ -191,46 +190,40 @@ The pointer is locked while scrubbing, allowing the user to scrub infinitely wit
</NumberField.ScrubArea>
```

In your CSS, ensure any `label` elements inside the `ScrubArea` specify `cursor: unset`. You can rotate the above macOS-style cursor 90 degrees using a `transform` style.
In your CSS, ensure any `<label>` elements inside `<ScrubArea />` specify `cursor: unset`. You can rotate the above macOS-style cursor 90 degrees using a `transform` style.

:::info
In Safari, the pointer is not locked. However, this doesn't affect the ability to scrub infinitely.
:::

#### Teleport distance
### Teleport distance

To teleport the virtual cursor closer to the input rather than the entire viewport, use the `teleportDistance` prop:
Rather than teleporting the virtual cursor at the viewport boundary, you can use the `teleportDistance` prop to teleport the cursor at a custom boundary.

```js
<NumberField.ScrubArea teleportDistance={200}>
<NumberField.ScrubAreaCursor />
</NumberField.ScrubArea>
```

This specifies in pixels the distance the cursor can travel around the center of the scrub area element before it loops back around.
This specifies the `px` distance the cursor can travel from the center of the scrub area element before it loops back around.

#### Wheel scrubbing
### Wheel scrubbing

To allow the input to be scrubbed using the mouse wheel, add the `allowWheelScrub` prop:
To allow the input to be scrubbed using the mouse wheel, add the `allowWheelScrub` prop. The input must be focused and the pointer must be hovering over it.

{{"demo": "UnstyledNumberFieldWheelScrub.js"}}

## Hook

```js
import { useNumberField } from '@base_ui/react/useNumberField';
```
## Overriding default components

The `useNumberField` hook lets you apply the functionality of a Number Field to a fully custom component.
It returns props to be placed on the custom component, along with fields representing the component's internal state.
Use the `render` prop to override the rendered elements with your own components.

:::info
Hooks give you the most room for customization, but require more work to implement.
With hooks, you can take full control over how your component is rendered, and define all the custom props and CSS classes you need.
```jsx
<NumberField.Input render={(props) => <MyCustomInput {...props} />}> />
```

You may not need to use hooks unless you find that you're limited by the customization options of their component counterparts—for instance, if your component requires significantly different [HTML structure](#anatomy).
:::
All subcomponents accept the `render` prop.

## Accessibility

Ensure the number field has an accessible name via a `label` element.
Ensure the Number Field has an accessible name via a `<label>` element.
Loading

0 comments on commit 67ab706

Please sign in to comment.