> ## 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

> Typed wrappers around text, number, select, and checkbox inputs for merchant-defined fields.

Custom elements let you collect arbitrary merchant-defined data (gift messages, quantities, opt-ins, etc.) inside the SDK's event, validation, and theming pipeline. Each type is a real `OverflowElement` you can mount standalone or configure under `customElements` inside [Checkout](/payment-elements/elements/checkout/sections/custom-elements).

## Elements

| Element  | Factory               | Value            |
| -------- | --------------------- | ---------------- |
| Text     | `overflow.text()`     | `string \| null` |
| Number   | `overflow.number()`   | `number \| null` |
| Select   | `overflow.select()`   | `string \| null` |
| Checkbox | `overflow.checkbox()` | `boolean`        |

## Shared options

Every custom element extends the same base:

```typescript theme={null}
type CustomElementBase = {
  elementType: 'text' | 'number' | 'select' | 'checkbox';
  name: string;                // unique per Overflow instance
  label: string;               // required
  placeholder?: string;
  defaultValue?: unknown;      // element-specific type
  autocomplete?: string;       // HTML autofill token
  disabled?: boolean;
  readOnly?: boolean;
  id?: string;
  ariaLabel?: string;
  locale?: string;
  required?: boolean;
  validate?: (value) => string | null;
};
```

### `name`

Uniquely identifies the element on the `Overflow` instance. Used as:

* The key inside the Checkout `value.customElements[name]` envelope.
* The `field` string on every emitted `FieldError`.
* The registry key for `checkout.getCustomElement(name)`.

Names must be unique per `Overflow` instance. Duplicates log a warning and return a no-op handle.

### `label`

Required. Renders as the input's `<label>` and interpolates into default error messages (for example, `"<label> is required"`).

### `defaultValue`

Seeds the DOM on mount. No `onChange` fires from the seed; the value is visible via `element.value` before any interaction.

### `autocomplete`

Forwarded to the input's `autocomplete` DOM attribute. Accepts the full HTML autofill token grammar (`'off'`, `'organization-title'`, `'shipping street-address'`, etc.).

## Validation precedence

When you supply `validate?`, the built-in `required` check is skipped and your callback owns validity. Without `validate?`, the only built-in check is `required` (empty input on text/number/select, unchecked box on checkbox); custom elements do not run format checks because the data is merchant-defined.

## Emit shape

* `text`, `number`, `select`: `value` is the current typed value or `null` while empty, unparseable, or unselected.
* `checkbox`: `value` is always a `boolean`; there is no `null` state.

## Standalone example

```javascript theme={null}
const message = overflow.text({
  name: 'giftMessage',
  label: 'Gift message (optional)',
  placeholder: 'Add a personal note',
});

message.on('onChange', ({ value, complete }) => console.log(value, complete));
message.mount('#gift-message');
```

## Inside Checkout

```javascript theme={null}
overflow.checkout({
  paymentMethods: ['card'],
  customElements: {
    giftMessage: { elementType: 'text', label: 'Gift message (optional)' },
    tipAmount: { elementType: 'number', label: 'Add a tip', min: 0 },
    shirtSize: {
      elementType: 'select',
      label: 'Shirt size',
      required: true,
      options: [
        { label: 'Medium', value: 'M' },
        { label: 'Large', value: 'L' },
      ],
    },
    coverFee: { elementType: 'checkbox', label: 'Cover the processing fee' },
  },
});
```

Access an individual slot with `checkout.getCustomElement(name)`. See [Custom elements section](/payment-elements/elements/checkout/sections/custom-elements).

## Element pages

<CardGroup cols={2}>
  <Card title="Text" href="/payment-elements/elements/custom/text">Free-form text input.</Card>
  <Card title="Number" href="/payment-elements/elements/custom/number">Numeric input with mode, precision, min, max, and adornments.</Card>
  <Card title="Select" href="/payment-elements/elements/custom/select">Dropdown with typed options.</Card>
  <Card title="Checkbox" href="/payment-elements/elements/custom/checkbox">Boolean opt-in or hard consent.</Card>
</CardGroup>

See the [Custom reference](/payment-elements/elements/custom/reference) for the consolidated option table.
