> ## Documentation Index
> Fetch the complete documentation index at: https://docs.overflow.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom elements reference

> Shared options, events, and value shapes for text, number, select, and checkbox elements.

Complete reference for the four custom element types and the options they share.

## Factories

```typescript theme={null}
overflow.text(options: CustomTextElementOptions): CustomTextElement
overflow.number(options: CustomNumberElementOptions): CustomNumberElement
overflow.select<TValue extends string>(
  options: CustomSelectElementOptions<TValue>,
): CustomSelectElement<TValue>
overflow.checkbox(options: CustomCheckboxElementOptions): CustomCheckboxElement
```

## Shared options

Every custom element extends the same base:

```typescript theme={null}
type CustomElementBase<TElementType extends string, TValue> = {
  elementType: TElementType;
  name: string;                       // unique per Overflow instance
  label: string;                      // required
  placeholder?: string;
  defaultValue?: TValue;
  autocomplete?: AutoFill;            // HTML autofill token
  disabled?: boolean;
  readOnly?: boolean;
  id?: string;
  ariaLabel?: string;
  locale?: string;
  required?: boolean;
  validate?: (value: TValue) => string | null;
};
```

| Key            | Notes                                                                                                                                                                                                                                                     |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`         | Unique per `Overflow` instance. Used as the key inside `checkout.value.customElements[name]`, the `field` string on emitted `FieldError`, and the registry key for `checkout.getCustomElement(name)`. Duplicates log a warning and return a no-op handle. |
| `label`        | Required. Renders as `<label>` and interpolates into the default `required` error message (`"<label> is required"`).                                                                                                                                      |
| `placeholder`  | Placeholder text on `text` and `number`. On `select`, when set, renders a selectable empty option at the top of the list. Not applicable to `checkbox`.                                                                                                   |
| `defaultValue` | Seeds the DOM value on mount. No `onChange` fires from the seed. Read the seeded value via `element.value` before any interaction.                                                                                                                        |
| `autocomplete` | Forwarded to the input's `autocomplete` DOM attribute. Accepts the full HTML autofill token grammar. Not applicable to `checkbox`.                                                                                                                        |
| `required`     | `false` by default. When `true`, an empty input (or unchecked box) emits a `FieldError` with `code: 'required'`.                                                                                                                                          |
| `validate`     | Overrides all built-in checks when supplied. See [Validate](/payment-elements/options/validate).                                                                                                                                                          |
| `disabled`     | Renders the input disabled.                                                                                                                                                                                                                               |
| `readOnly`     | Renders the input read-only. Not applicable to `checkbox`.                                                                                                                                                                                                |
| `id`           | Custom `id` on the underlying input.                                                                                                                                                                                                                      |
| `ariaLabel`    | Custom `aria-label`.                                                                                                                                                                                                                                      |
| `locale`       | Reserved for future localization overrides.                                                                                                                                                                                                               |

## Value shapes

| Element    | `onChange.value` | `onSubmit.value` |
| ---------- | ---------------- | ---------------- |
| `text`     | `string \| null` | `string`         |
| `number`   | `number \| null` | `number`         |
| `select`   | `TValue \| null` | `TValue`         |
| `checkbox` | `boolean`        | `boolean`        |

`text`, `number`, and `select` emit `null` while empty or mid-typing an unparseable value. `checkbox` always has a state.

## Events

Custom elements support the same six core events as built-in elements: `onReady`, `onChange`, `onSubmit`, `onError`, `onFocus`, `onBlur`, plus `onEscapeKeyPressed`. Wallet-only events (`onClick`, `onExit`) are not emitted.

## Validation

* Without `validate`, the only built-in check is the synchronous `required` empty check (unchecked-box on `checkbox`). Format checks are intentionally not provided because custom elements collect arbitrary merchant-defined data.
* `number` adds built-in `min` and `max` range checks when `validate` is not supplied.
* `select` accepts only values that match one of `options[].value`.
* Providing `validate` skips every built-in check. The callback receives the current value (including `null` for empty inputs) and owns the entire validity contract. Return `null` for valid, or a non-empty string to surface a `FieldError` with `code: 'custom'`.

## `FieldError`

```typescript theme={null}
interface FieldError {
  field: string;    // equals the element's configured `name`
  code: string;     // 'required', 'custom', 'min', 'max', 'invalid_format', ...
  message: string;  // already localized, safe to render
}
```

`field` always equals the element's `name`. Bucket errors by field to place them next to the matching input.

## Imperative `.value` getter

Every custom element handle exposes a read-only `.value` property returning the current snapshot.

```javascript theme={null}
const tip = overflow.number({ name: 'tip', label: 'Tip', defaultValue: 5 });
tip.mount('#tip');

tip.value; // 5, before any shopper interaction
```

* `text`, `number`, `select` return `null` when empty.
* `checkbox` always returns a `boolean`.

## Inside Checkout

Custom elements can be configured under `customElements` on `overflow.checkout()`. Each slot appears on the aggregated envelope as:

```typescript theme={null}
value.customElements[name] = { elementType, value, complete };
```

Subscribe to a single slot's events with `checkout.getCustomElement(name)`.

Inside Checkout, `appearance` is not allowed on custom slots. Style the whole Checkout as one cohesive unit; see [Theming](/payment-elements/theming/overview).

## Duplicate names

Two elements with the same `name` on the same `Overflow` instance log a warning; the second one returns a no-op handle. Its `mount`, `on`, `update`, and `submit` calls are silently ignored.

## See also

* [Custom elements introduction](/payment-elements/elements/custom/introduction)
* [Text](/payment-elements/elements/custom/text) · [Number](/payment-elements/elements/custom/number) · [Select](/payment-elements/elements/custom/select) · [Checkbox](/payment-elements/elements/custom/checkbox)
* [Custom elements section (inside Checkout)](/payment-elements/elements/checkout/sections/custom-elements)
* [Options: `required`](/payment-elements/options/required) · [Options: `validate`](/payment-elements/options/validate)
