# or
yarn add @zag-js/pin-input @zag-js/react
```

## Anatomy

To set up the pin input correctly, you'll need to understand its anatomy and how
we name its parts.

> Each part includes a `data-part` attribute to help identify them in the DOM.



## Usage

First, import the pin input package into your project

```jsx
import * as pinInput from "@zag-js/pin-input"
```

The pin input package exports two key functions:

- `machine` â The state machine logic for the pin input widget.
- `connect` â The function that translates the machine's state to JSX attributes
  and event handlers.

> You'll need to provide a unique `id` to the `useMachine` hook. This is used to
> ensure that the every part has a unique identifier.

Next, import the required hooks and functions for your framework and use the pin
input machine in your project ð¥

```jsx
import * as pinInput from "@zag-js/pin-input"
import { useMachine, normalizeProps } from "@zag-js/react"

export function PinInput() {
  const service = useMachine(pinInput.machine, { id: "1" })

  const api = pinInput.connect(service, normalizeProps)

  return (
    <div>
      <div {...api.getRootProps()}>
        <input {...api.getInputProps({ index: 0 })} />
        <input {...api.getInputProps({ index: 1 })} />
        <input {...api.getInputProps({ index: 2 })} />
      </div>
      <button onClick={api.clearValue}>Clear</button>
    </div>
  )
}
```

### Setting a default value

Use the `defaultValue` context property to set the initial value of the pin
input. The value must be an array of strings.

```jsx {2}
const service = useMachine(pinInput.machine, {
  defaultValue: ["1", "2", ""],
})
```

### Controlled value

Use the `value` and `onValueChange` properties to programmatically control the
value of the pin input.

```tsx
import { useState } from "react"

export function ControlledPinInput() {
  const [value, setValue] = useState(["", "", "", ""])

  const service = useMachine(pinInput.machine, {
    value,
    onValueChange(details) {
      setValue(details.value)
    },
  })
}
```

### Changing the placeholder

To customize the default pin input placeholder (â) for each input, pass the
`placeholder` prop and set it to your desired value.

```jsx {2}
const service = useMachine(pinInput.machine, {
  placeholder: "*",
})
```

### Blur on complete

By default, the last input maintains focus when filled and we invoke the
`onComplete` callback. To blur the last input when the user completes the input,
set the `blurOnComplete: true` in the machine's context.

```jsx {2}
const service = useMachine(pinInput.machine, {
  blurOnComplete: true,
})
```

### Allowing alphanumeric values

By default, the pin input accepts only number values but you can choose between
`numeric`, `alphanumeric` and `alphabetic` values. To change the input mode,
pass the `type` context property and set its value to `alphanumeric`.

```jsx {2}
const service = useMachine(pinInput.machine, {
  type: "alphanumeric",
})
```

### Using OTP mode

To trigger smartphone OTP auto-suggestion, it is recommended to set the
`autocomplete` attribute to "one-time-code". The pin-input machine provides
support for this automatically when you set the `otp` context property to
`true`.

```jsx {2}
const service = useMachine(pinInput.machine, {
  otp: true,
})
```

### Securing the text input

When collecting private or sensitive information using the pin input, you might
need to mask the value entered, similar to `<input type="password"/>`. Pass the
`mask` context property and set it to `true`.

```jsx {2}
const service = useMachine(pinInput.machine, {
  mask: true,
})
```

### Listening for changes

The pin input machine invokes several callback functions when the user enters:

- `onValueChange` â Function invoked when the value is changed.
- `onValueComplete` â Function invoked when all fields have been completed (by
  typing or pasting).
- `onValueInvalid` â Function invoked when an invalid value is entered into the
  input. An invalid value is any value that doesn't match the specified "type".

```jsx
const service = useMachine(pinInput.machine, {
  onValueChange(value) {
    // value => string[]
    console.log("value changed to:", value)
  },
  onValueComplete(details) {
    // details => { value: string[], valueAsString: string }
    console.log("completed value:", details)
  },
  onValueInvalid(details) {
    // details => { index: number, value: string }
    console.log("invalid value:", details)
  },
})
```

### RTL support

The pin input machine supports RTL writing directions. To set the `dir` property
in the machine's context.

When this attribute is set, we attach a `dir` attribute to the root part.

```jsx {2}
const service = useMachine(pinInput.machine, {
  dir: "rtl",
})
```

## Styling guide

Earlier, we mentioned that each pin input's part has a `data-part` attribute
added to them to select and style them in the DOM.

### Completed state

When all values have been filled, we attach a `data-complete` attribute to the
root and input parts.

```css
[data-part="root"][data-complete] {
  /* styles for when all value has been filled */
}

[data-part="input"][data-complete] {
  /* styles for when all value has been filled */
}
```

### Invalid state

When an invalid value is entered, we attach a `data-invalid` attribute to the
affected input part.

```css
[data-part="input"][data-invalid] {
  /* styles for when the input is invalid */
}
```

### Disabled state

When the pin-input is disabled, we attach a `data-disabled` attribute to the
root and input parts.

```css
[data-part="root"][data-disabled] {
  /* styles for when the input is disabled */
}

[data-part="input"][data-invalid] {
  /* styles for when the input is disabled */
}
```

## Methods and Properties

### Machine Context

The pin input machine exposes the following context properties:

**`name`**
Type: `string`
Description: The name of the input element. Useful for form submission.

**`form`**
Type: `string`
Description: The associate form of the underlying input element.

**`pattern`**
Type: `string`
Description: The regular expression that the user-entered input value is checked against.

**`ids`**
Type: `Partial<{ root: string; hiddenInput: string; label: string; control: string; input: (id: string) => string; }>`
Description: The ids of the elements in the pin input. Useful for composition.

**`disabled`**
Type: `boolean`
Description: Whether the inputs are disabled

**`placeholder`**
Type: `string`
Description: The placeholder text for the input

**`autoFocus`**
Type: `boolean`
Description: Whether to auto-focus the first input.

**`invalid`**
Type: `boolean`
Description: Whether the pin input is in the invalid state

**`required`**
Type: `boolean`
Description: Whether the pin input is required

**`readOnly`**
Type: `boolean`
Description: Whether the pin input is in the valid state

**`otp`**
Type: `boolean`
Description: If `true`, the pin input component signals to its fields that they should
use `autocomplete="one-time-code"`.

**`value`**
Type: `string[]`
Description: The controlled value of the the pin input.

**`defaultValue`**
Type: `string[]`
Description: The initial value of the the pin input when rendered.
Use when you don't need to control the value of the pin input.

**`type`**
Type: `"alphanumeric" | "numeric" | "alphabetic"`
Description: The type of value the pin-input should allow

**`onValueComplete`**
Type: `(details: ValueChangeDetails) => void`
Description: Function called when all inputs have valid values

**`onValueChange`**
Type: `(details: ValueChangeDetails) => void`
Description: Function called on input change

**`onValueInvalid`**
Type: `(details: ValueInvalidDetails) => void`
Description: Function called when an invalid value is entered

**`mask`**
Type: `boolean`
Description: If `true`, the input's value will be masked just like `type=password`

**`blurOnComplete`**
Type: `boolean`
Description: Whether to blur the input when the value is complete

**`selectOnFocus`**
Type: `boolean`
Description: Whether to select input value when input is focused

**`translations`**
Type: `IntlTranslations`
Description: Specifies the localized strings that identifies the accessibility elements and their states

**`count`**
Type: `number`
Description: The number of inputs to render to improve SSR aria attributes.
This will be required in next major version.

**`dir`**
Type: `"ltr" | "rtl"`
Description: The document's text/writing direction.

**`id`**
Type: `string`
Description: The unique identifier of the machine.

**`getRootNode`**
Type: `() => ShadowRoot | Node | Document`
Description: A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.

### Machine API

The pin input `api` exposes the following methods:

**`value`**
Type: `string[]`
Description: The value of the input as an array of strings.

**`valueAsString`**
Type: `string`
Description: The value of the input as a string.

**`complete`**
Type: `boolean`
Description: Whether all inputs are filled.

**`count`**
Type: `number`
Description: The number of inputs to render

**`items`**
Type: `number[]`
Description: The array of input values.

**`setValue`**
Type: `(value: string[]) => void`
Description: Function to set the value of the inputs.

**`clearValue`**
Type: `VoidFunction`
Description: Function to clear the value of the inputs.

**`setValueAtIndex`**
Type: `(index: number, value: string) => void`
Description: Function to set the value of the input at a specific index.

**`focus`**
Type: `VoidFunction`
Description: Function to focus the pin-input. This will focus the first input.

### Data Attributes

**`Root`**

**`data-scope`**: pin-input
**`data-part`**: root
**`data-invalid`**: Present when invalid
**`data-disabled`**: Present when disabled
**`data-complete`**: Present when the pin-input value is complete
**`data-readonly`**: Present when read-only

**`Label`**

**`data-scope`**: pin-input
**`data-part`**: label
**`data-invalid`**: Present when invalid
**`data-disabled`**: Present when disabled
**`data-complete`**: Present when the label value is complete
**`data-required`**: Present when required
**`data-readonly`**: Present when read-only

**`Input`**

**`data-scope`**: pin-input
**`data-part`**: input
**`data-disabled`**: Present when disabled
**`data-complete`**: Present when the input value is complete
**`data-index`**: The index of the item
**`data-invalid`**: Present when invalid

## Accessibility

### Keyboard Interactions

**`ArrowLeft`**
Description: Moves focus to the previous input

**`ArrowRight`**
Description: Moves focus to the next input

**`Backspace`**
Description: Deletes the value in the current input and moves focus to the previous input

**`Delete`**
Description: Deletes the value in the current input

**`Control + V`**
Description: Pastes the value into the input fields
A popover is a non-modal dialog that floats around a trigger. It is used to
display contextual information to the user, and should be paired with a
clickable trigger element.

## Resources


[Latest version: v1.33.1](https://www.npmjs.com/package/@zag-js/popover)
[Logic Visualizer](https://zag-visualizer.vercel.app/popover)
[Source Code](https://github.com/chakra-ui/zag/tree/main/packages/machines/popover)



**Features**

- Focus is managed and can be customized
- Supports modal and non-modal modes
- Ensures correct DOM order after tabbing out of the popover, whether it's
  portalled or not

## Installation

To use the popover machine in your project, run the following command in your
command line:

```bash
npm install @zag-js/popover @zag-js/react