---
name: "Picker"
mode: "component"
versionRequirements:
  - { name: "@ray-js/ray", version: "0.5.10" }
title: "Picker - Scroll picker that pops up from the bottom"
---

## Picker

> [VERSION] @ray-js/ray >= 0.5.10

### Description

A scrolling picker that pops up from the bottom, supporting standard, multi-column, time, and date modes.

### Props

| Property | Type | Required | Default | Since | Description |
| --- | --- | --- | --- | --- | --- |
| `name` | `string` | No | - | - | Form field name, used as the key on form submit |
| `mode` | `"selector" \| "multiSelector" \| "time" \| "date"` | No | `"selector"` | - | Picker types: selector: standard picker; multiSelector: multi-column picker; time: time picker; date: date picker |
| `disabled` | `boolean` | No | `false` | - | Whether disabled |
| `range` | `string \| number \| Record<string, unknown>[] \| string \| number \| Record<string, unknown>[][]` | No | `[]` | - | Effective when mode is selector or multiSelector; the data source for a single or multiple columns |
| `rangeKey` | `string` | No | `""` | - | When range is an array of objects, specifies the field name used for display text |
| `value` | `number \| number[] \| string` | No | `""` | - | Selected value: for selector, the index; for multiSelector, an index array; for time/date, a string in "hh:mm"/"YYYY-MM-DD" format |
| `start` | `string` | No | `""` | - | When mode is time, start of the valid time range, format hh:mm; when mode is date, YYYY-MM-DD |
| `end` | `string` | No | `""` | - | When mode is time, end of the valid time range, format hh:mm; when mode is date, YYYY-MM-DD |
| `fields` | `"year" \| "month" \| "day"` | No | `"day"` | - | When mode is date, granularity: year / month / day |
| `cancelText` | `string` | No | `"取消"` | - | Cancel button text |
| `confirmText` | `string` | No | `"确定"` | - | Confirm button text |
| `onCancel` | `(event: PickerCancelEvent) => void` | No | - | `1.9.90` | Triggers on cancel |
| `onChange` | `(event: PickerChangeEvent) => void` | No | - | - | Triggers when the picker value changes (after confirming the selection) |
| `onColumnChange` | `(event: PickerColumnChangeEvent) => void` | No | - | - | Triggered when a column in a multi-column picker changes |

### Referenced Types

##### `interface` PickerCancelEvent

| Property | Type | Description |
| --- | --- | --- |
| `detail` | `PickerCancelDetail` | Event data |

##### `interface` PickerChangeEvent

| Property | Type | Description |
| --- | --- | --- |
| `detail` | `PickerChangeDetail` | Event data |
| `value` | `number \| number[] \| string \| string[]` | Current selected value |

##### `interface` PickerColumnChangeEvent

| Property | Type | Description |
| --- | --- | --- |
| `detail` | `PickerColumnChangeDetail` | Event data |

##### `interface` PickerCancelDetail

```typescript
export interface PickerCancelDetail {
  [key: string]: unknown;
}
```

##### `interface` BaseEvent

| Property | Type | Description |
| --- | --- | --- |
| `type` | `string` | Event type |
| `timeStamp` | `number` | Time in milliseconds since the page opened |
| `target` | `Target` | Source component of the event |
| `currentTarget` | `Target` | Collection of property values for the current component |
| `mark` | `any` | Event mark data |

##### `interface` PickerChangeDetail

| Property | Type | Description |
| --- | --- | --- |
| `value` | `number \| number[] \| string \| string[]` | Current selected value |

##### `interface` PickerColumnChangeDetail

| Property | Type | Description |
| --- | --- | --- |
| `column` | `number` | Index of the changed column |
| `value` | `number` | Current value of the changed column |

##### `interface` Target

| Property | Type | Description |
| --- | --- | --- |
| `id` | `string` | id of the event source component |
| `dataset` | `Record<string, unknown>` | Collection of custom attributes from the `dataset` on the event source component |


### Examples

#### Basic usage

```tsx
import React from 'react';
import { Picker, View, Text } from '@ray-js/ray';

export default function () {
  const [current, setCurrent] = React.useState(0);
  const range = ['United States', 'China', 'Brazil', 'Japan'];

  return (
    <View style={{ padding: '20px' }}>
      <Picker
        mode="selector"
        onChange={(e) => {
          console.log('Selection changed:', e.detail.value);
          setCurrent(e.detail.value);
        }}
        range={range}
        value={current}
      >
        <View style={{ padding: '10px', backgroundColor: '#f5f5f5' }}>
          <Text>当前选择: {range[current]}</Text>
        </View>
      </Picker>
    </View>
  );
}
```

#### Time picker

```tsx
import React from 'react';
import { Picker, View, Text } from '@ray-js/ray';

export default function () {
  const [time, setTime] = React.useState('12:00');

  return (
    <View style={{ padding: '20px' }}>
      <Picker
        mode="time"
        value={time}
        start="09:00"
        end="18:00"
        onChange={(e) => {
          console.log('Time changed:', e.detail.value);
          setTime(e.detail.value);
        }}
      >
        <View style={{ padding: '10px', backgroundColor: '#f5f5f5' }}>
          <Text>当前时间: {time}</Text>
        </View>
      </Picker>
    </View>
  );
}
```

#### Date picker

```tsx
import React from 'react';
import { Picker, View, Text } from '@ray-js/ray';

export default function () {
  const [date, setDate] = React.useState('2026-01-01');

  return (
    <View style={{ padding: '20px' }}>
      <Picker
        mode="date"
        value={date}
        start="2020-01-01"
        end="2030-12-31"
        fields="day"
        onChange={(e) => {
          console.log('Date changed:', e.detail.value);
          setDate(e.detail.value);
        }}
        onCancel={() => console.log('Selection canceled')}
      >
        <View style={{ padding: '10px', backgroundColor: '#f5f5f5' }}>
          <Text>当前日期: {date}</Text>
        </View>
      </Picker>
    </View>
  );
}
```

#### Multi-column picker

```tsx
import React from 'react';
import { Picker, View, Text } from '@ray-js/ray';

export default function () {
  const [value, setValue] = React.useState([0, 0]);
  const range = [
    ['Guangdong', 'Zhejiang', 'Jiangsu'],
    ['Guangzhou', 'Hangzhou', 'Nanjing'],
  ];

  return (
    <View style={{ padding: '20px' }}>
      <Picker
        mode="multiSelector"
        range={range}
        value={value}
        disabled={false}
        confirmText="Confirm"
        cancelText="Cancel"
        onChange={(e) => {
          console.log('Multi-column selection:', e.detail.value);
          setValue(e.detail.value);
        }}
        onColumnChange={(e) => console.log('Column changed:', e.detail.column, e.detail.value)}
        onCancel={() => console.log('Selection canceled')}
      >
        <View style={{ padding: '10px', backgroundColor: '#f5f5f5' }}>
          <Text>当前选择: {range[0][value[0]]} - {range[1][value[1]]}</Text>
        </View>
      </Picker>
    </View>
  );
}
```
