# @hero-design/react-native-month-year-picker

## Overview

A React Native library that provides native month and year picker components for iOS and Android. It includes platform-specific implementations (`MonthYearPickerViewIOS` for iOS, `MonthYearPickerDialogueAndroid` for Android), date range constraints, internationalization support, theme support (light/dark mode), and is used internally by `@hero-design/rn` Calendar and DatePicker components.

## Installation

```sh
npm install @hero-design/react-native-month-year-picker
# or
yarn add @hero-design/react-native-month-year-picker
```

**Peer Dependencies:**

```sh
yarn add react@18.3.1 react-native@0.77.3
```

**Requirements:**

- React 18.3.1
- React Native >=0.71.0 (New Architecture / Codegen support requires 0.71+)
- Node.js >= 20.0.0 (20.x or 22.x supported)
- Yarn >= 4.0.2 (enabled via Corepack: `corepack enable`)
- iOS Simulator (iPhone 14, iOS 18+) or Android Emulator (Pixel 6, API 30) for development

### iOS Setup

After installing, you need to run pod install:

```sh
cd ios && pod install
```

**Note:** This package uses native modules and cannot be used with Expo Go. You must use a development build or bare React Native project.

## Usage

### iOS - MonthYearPickerViewIOS

The iOS component renders a native month/year picker view:

```tsx
import { MonthYearPickerViewIOS } from '@hero-design/react-native-month-year-picker';

function MyDatePicker() {
  const [selectedDate, setSelectedDate] = useState(new Date());

  return (
    <MonthYearPickerViewIOS
      value={selectedDate}
      onChange={(date) => setSelectedDate(date)}
      minimumDate={new Date(2020, 0, 1)}
      maximumDate={new Date(2030, 11, 31)}
      locale="en"
      textColor="#000000"
      style={{ height: '100%', width: '100%' }}
    />
  );
}
```

### Android - MonthYearPickerDialogueAndroid

The Android component displays a native dialog picker:

```tsx
import { MonthYearPickerDialogueAndroid } from '@hero-design/react-native-month-year-picker';

function MyDatePicker() {
  const [selectedDate, setSelectedDate] = useState(new Date());

  return (
    <MonthYearPickerDialogueAndroid
      value={selectedDate}
      onChange={(action, date) => {
        if (action === 'dateSetAction' && date) {
          setSelectedDate(date);
        }
      }}
      minimumDate={new Date(2020, 0, 1)}
      maximumDate={new Date(2030, 11, 31)}
      doneButtonLabel="Done"
      cancelButtonLabel="Cancel"
      locale="en"
      themeVariant="light"
    />
  );
}
```

### Platform-Specific Usage

For cross-platform usage, use Platform to conditionally render:

```tsx
import { Platform } from 'react-native';
import {
  MonthYearPickerViewIOS,
  MonthYearPickerDialogueAndroid,
} from '@hero-design/react-native-month-year-picker';

function MonthYearPicker({ value, onChange, ...props }) {
  if (Platform.OS === 'ios') {
    return (
      <MonthYearPickerViewIOS value={value} onChange={onChange} {...props} />
    );
  }

  return (
    <MonthYearPickerDialogueAndroid
      value={value}
      onChange={onChange}
      {...props}
    />
  );
}
```

## API Reference

### MonthYearPickerViewIOS Props

| Prop          | Type                   | Default      | Description                       |
| ------------- | ---------------------- | ------------ | --------------------------------- |
| `value`       | `Date`                 | `new Date()` | Currently selected date           |
| `onChange`    | `(date: Date) => void` | **Required** | Callback when date changes        |
| `minimumDate` | `Date?`                | `undefined`  | Minimum selectable date           |
| `maximumDate` | `Date?`                | `undefined`  | Maximum selectable date           |
| `locale`      | `string`               | `'en'`       | Locale for date formatting        |
| `textColor`   | `string?`              | `undefined`  | Text color for the picker         |
| `autoTheme`   | `boolean`              | `false`      | Automatically detect system theme |
| `style`       | `ViewStyle?`           | `undefined`  | Style for the container view      |

### MonthYearPickerDialogueAndroid Props

| Prop                | Type                                                | Default      | Description                                    |
| ------------------- | --------------------------------------------------- | ------------ | ---------------------------------------------- |
| `value`             | `Date`                                              | `new Date()` | Currently selected date                        |
| `onChange`          | `(action: string, date: Date \| undefined) => void` | **Required** | Callback when dialog action occurs             |
| `minimumDate`       | `Date?`                                             | `undefined`  | Minimum selectable date                        |
| `maximumDate`       | `Date?`                                             | `undefined`  | Maximum selectable date                        |
| `doneButtonLabel`   | `string`                                            | `'Done'`     | Label for the done button                      |
| `cancelButtonLabel` | `string`                                            | `'Cancel'`   | Label for the cancel button                    |
| `locale`            | `string`                                            | `'en'`       | Locale for date formatting                     |
| `themeVariant`      | `'light' \| 'dark'`                                 | `undefined`  | Theme variant (ignored if `autoTheme` is true) |
| `autoTheme`         | `boolean`                                           | `false`      | Automatically detect system theme              |

### Action Types

For Android `onChange` callback, the action parameter can be:

- `'dateSetAction'` - User confirmed the date selection
- `'dismissedAction'` - User dismissed the dialog without selecting

## Theming

### iOS Theming

The iOS picker supports text color customization and automatic theme detection:

```tsx
import { useTheme } from '@hero-design/rn';

function ThemedPicker() {
  const theme = useTheme();

  return (
    <MonthYearPickerViewIOS
      value={selectedDate}
      onChange={setSelectedDate}
      textColor={theme.colors.onDefaultGlobalSurface}
      autoTheme={true}
    />
  );
}
```

### Android Theming

The Android picker supports light/dark theme variants:

```tsx
import { useTheme } from '@hero-design/rn';

function ThemedPicker() {
  const theme = useTheme();

  return (
    <MonthYearPickerDialogueAndroid
      value={selectedDate}
      onChange={handleChange}
      themeVariant={theme.themeMode === 'dark' ? 'dark' : 'light'}
      autoTheme={true}
    />
  );
}
```

**Note:** When `autoTheme` is set to `true`, the `themeVariant` prop is ignored and the system theme is automatically detected.

## Examples

### Integration with Calendar Component

This picker is used internally by the `@hero-design/rn` Calendar component:

```tsx
import Calendar from '@hero-design/rn';

function MyCalendar() {
  return (
    <Calendar
      value={selectedDate}
      onChange={setSelectedDate}
      onToggleMonthPicker={(visible) => {
        // Month picker visibility is handled internally
      }}
      monthPickerConfirmLabel="Done"
      monthPickerCancelLabel="Cancel"
    />
  );
}
```

### Integration with DatePicker Component

Used in DatePicker for month-year selection variant:

```tsx
import { DatePicker } from '@hero-design/rn';

function MyDatePicker() {
  return (
    <DatePicker
      value={selectedDate}
      onChange={setSelectedDate}
      variant="month-year"
      label="Select Month & Year"
    />
  );
}
```

### Custom Dialog Implementation

Example of wrapping the Android picker in a custom dialog:

```tsx
import { useState } from 'react';
import { Button } from '@hero-design/rn';
import { MonthYearPickerDialogueAndroid } from '@hero-design/react-native-month-year-picker';

function CustomMonthPicker() {
  const [date, setDate] = useState(new Date());
  const [visible, setVisible] = useState(false);

  return (
    <>
      <Button text="Select Month/Year" onPress={() => setVisible(true)} />
      {visible && (
        <MonthYearPickerDialogueAndroid
          value={date}
          onChange={(action, newDate) => {
            if (action === 'dateSetAction' && newDate) {
              setDate(newDate);
            }
            setVisible(false);
          }}
          doneButtonLabel="Confirm"
          cancelButtonLabel="Cancel"
        />
      )}
    </>
  );
}
```

## Contributing

Contributions to `@hero-design/react-native-month-year-picker` are welcome!

To get started:

1. Clone the repository: `git clone git@github.com:Thinkei/hero-design.git`
2. Enable Corepack: `corepack enable`
3. Install dependencies: `yarn install`
4. Bootstrap the example app: `yarn workspace @hero-design/react-native-month-year-picker bootstrap`
5. Build the package: `yarn turbo run build --filter=@hero-design/react-native-month-year-picker`

For detailed contributing guidelines, see [CONTRIBUTING.md](./CONTRIBUTING.md).

## License

MIT

---

Made with [react-native-builder-bob](https://github.com/callstack/react-native-builder-bob)
