# Usage

Essential Kit wraps native iOS (UIKit) and Android UI components into a unified Unity interface. Essential Kit automatically initializes Native UI - no manual setup needed.

## Table of Contents

* [Understanding Core Concepts](#understanding-core-concepts)
* [Import Namespaces](#import-namespaces)
* [Alert Dialogs](#alert-dialogs)
* [Date and Time Pickers](#date-and-time-pickers)
* [Core APIs Reference](#core-apis-reference)
* [Data Properties](#data-properties)
* [Common Patterns](#common-patterns)
* [Error Handling](#error-handling)
* [Advanced Configuration](#advanced-configuration)

## Understanding Core Concepts

Native UI wraps a small set of platform widgets. Map each widget to the user journey before you start wiring code:

* **AlertDialog** surfaces blocking decisions or confirmations. Use it for urgent notices, desructive actions, or short forms that need one or two data points.
* **AlertDialogStyle.ActionSheet** provides iOS-style menus; it feels natural for secondary actions like sharing, saving, or discarding.
* **TextInputFieldOptions** lets you request the appropriate keyboard, secure entry, and placeholder to guide the player.
* **DatePicker** (and its `Date`, `Time`, `DateAndTime` modes) handles locale-aware scheduling tasks without reinventing spinners or calendars.
* **Dialog lifecycle**: Alerts and pickers suspend interaction with your scene. Always resume gameplay, timers, or animations once callbacks fire.

## Import Namespaces

```csharp
using VoxelBusters.EssentialKit;
```

## Alert Dialogs

Alert dialogs are modal windows that prompt users for decisions or display important information. Use `AlertDialog.CreateInstance()` to create dialogs with custom titles, messages, buttons, and text input fields.

### Basic Alert Dialog

Create a simple dialog with title, message, and buttons:

```csharp
public void ShowSimpleAlert()
{
    AlertDialog dialog = AlertDialog.CreateInstance();
    dialog.Title = "Confirmation";
    dialog.Message = "Are you sure you want to continue?";
    dialog.AddButton("Yes", () =>
    {
        Debug.Log("User confirmed");
    });
    dialog.AddCancelButton("No", () =>
    {
        Debug.Log("User cancelled");
    });
    dialog.Show();
}
```

### Multi-Button Dialog

Add multiple action buttons for complex choices:

```csharp
public void ShowMultiButtonDialog()
{
    AlertDialog dialog = AlertDialog.CreateInstance();
    dialog.Title = "Choose Difficulty";
    dialog.Message = "Select your preferred game difficulty:";

    dialog.AddButton("Easy", () =>
    {
        Debug.Log("Easy mode selected");
    });

    dialog.AddButton("Normal", () =>
    {
        Debug.Log("Normal mode selected");
    });

    dialog.AddButton("Hard", () =>
    {
        Debug.Log("Hard mode selected");
    });

    dialog.AddCancelButton("Cancel", () =>
    {
        Debug.Log("Selection cancelled");
    });

    dialog.Show();
}
```

### Text Input Dialog

Collect user input through native text fields:

```csharp
public void ShowTextInputDialog()
{
    AlertDialog dialog = AlertDialog.CreateInstance();
    dialog.Title = "Enter Name";
    dialog.Message = "Please enter your player name:";

    // Add text input field
    dialog.AddTextInputField();

    // Button callback receives input values
    dialog.AddButton("Submit", (inputTexts) =>
    {
        string playerName = inputTexts[0];
        Debug.Log("Player name: " + playerName);
    });

    dialog.AddCancelButton("Cancel", () =>
    {
        Debug.Log("Input cancelled");
    });

    dialog.Show();
}
```

### Text Input with Options

Configure text input field behavior:

```csharp
public void ShowCustomTextInput()
{
    AlertDialog dialog = AlertDialog.CreateInstance();
    dialog.Title = "Login";
    dialog.Message = "Enter your credentials:";

    // Username field with placeholder
    var usernameOptions = new TextInputFieldOptions.Builder()
        .SetPlaceholderText("Username")
        .Build();
    dialog.AddTextInputField(usernameOptions);

    // Password field (secure entry)
    var passwordOptions = new TextInputFieldOptions.Builder()
        .SetPlaceholderText("Password")
        .SetIsSecured(true)
        .Build();
    dialog.AddTextInputField(passwordOptions);

    dialog.AddButton("Login", (inputTexts) =>
    {
        string username = inputTexts[0];
        string password = inputTexts[1];
        Debug.Log($"Login attempt: {username}");
    });

    dialog.AddCancelButton("Cancel", () => { });

    dialog.Show();
}
```

### Alert Dialog Styles

Create action sheets on iOS for menu-style choices:

```csharp
public void ShowActionSheet()
{
    AlertDialog dialog = AlertDialog.CreateInstance(AlertDialogStyle.ActionSheet);
    dialog.Title = "Actions";
    dialog.Message = "Choose an action:";

    dialog.AddButton("Share", () => Debug.Log("Share selected"));
    dialog.AddButton("Save", () => Debug.Log("Save selected"));
    dialog.AddButton("Delete", () => Debug.Log("Delete selected"));
    dialog.AddCancelButton("Cancel", () => { });

    dialog.Show();
}
```

## Date and Time Pickers

Date pickers provide native interfaces for selecting dates and times. Use `DatePicker.CreateInstance()` with different modes for date-only, time-only, or combined pickers.

### Understanding Picker Modes

DatePicker supports three modes for different use cases:

**DatePickerMode.Date:**

* Shows day, month, and year selection
* Perfect for birthdays, event dates, and deadlines

**DatePickerMode.Time:**

* Shows hours and minutes selection
* Ideal for alarm settings and notification times

**DatePickerMode.DateAndTime:**

* Shows both date and time selection
* Best for scheduling specific moments (appointments, reminders)

### Date Picker

Let users select a specific date:

```csharp
public void ShowDatePicker()
{
    DatePicker datePicker = DatePicker.CreateInstance(DatePickerMode.Date);

    datePicker.SetOnCloseCallback((result) =>
    {
        if (result.SelectedDate.HasValue)
        {
            DateTime selectedDate = result.SelectedDate.Value;
            Debug.Log("Selected date: " + selectedDate.ToString("yyyy-MM-dd"));
        }
        else
        {
            Debug.Log("Date selection cancelled");
        }
    });

    datePicker.Show();
}
```

### Time Picker

Collect time input for alarms or reminders:

```csharp
public void ShowTimePicker()
{
    DatePicker timePicker = DatePicker.CreateInstance(DatePickerMode.Time);

    timePicker.SetOnCloseCallback((result) =>
    {
        if (result.SelectedDate.HasValue)
        {
            DateTime selectedTime = result.SelectedDate.Value;
            Debug.Log("Selected time: " + selectedTime.ToString("HH:mm"));
        }
    });

    timePicker.Show();
}
```

### Date and Time Picker

Combined picker for precise scheduling:

```csharp
public void ShowDateTimePicker()
{
    DatePicker picker = DatePicker.CreateInstance(DatePickerMode.DateAndTime);

    // Set initial date (optional)
    picker.SetInitialDate(DateTime.Now.AddDays(1));

    // Set date range constraints (optional)
    picker.SetMinimumDate(DateTime.Now);
    picker.SetMaximumDate(DateTime.Now.AddMonths(3));

    picker.SetOnCloseCallback((result) =>
    {
        if (result.SelectedDate.HasValue)
        {
            Debug.Log("Scheduled for: " + result.SelectedDate.Value.ToString("yyyy-MM-dd HH:mm"));
        }
    });

    picker.Show();
}
```

### Date Picker with Constraints

Restrict selectable date ranges:

```csharp
public void ShowConstrainedDatePicker()
{
    DatePicker datePicker = DatePicker.CreateInstance(DatePickerMode.Date);

    // Only allow future dates
    datePicker.SetMinimumDate(DateTime.Now);
    datePicker.SetMaximumDate(DateTime.Now.AddYears(1));

    // Set initial date to tomorrow
    datePicker.SetInitialDate(DateTime.Now.AddDays(1));

    datePicker.SetOnCloseCallback((result) =>
    {
        if (result.SelectedDate.HasValue)
        {
            Debug.Log("Tournament date: " + result.SelectedDate.Value.ToString("MMM dd, yyyy"));
        }
    });

    datePicker.Show();
}
```

## Core APIs Reference

### AlertDialog APIs

| API                                       | Purpose                             | Returns            |
| ----------------------------------------- | ----------------------------------- | ------------------ |
| `AlertDialog.CreateInstance(style)`       | Create new alert dialog instance    | AlertDialog object |
| `dialog.Title`                            | Set or get dialog title             | string property    |
| `dialog.Message`                          | Set or get dialog message           | string property    |
| `dialog.AddButton(title, callback)`       | Add action button                   | Void               |
| `dialog.AddButton(title, inputCallback)`  | Add button with text input callback | Void               |
| `dialog.AddCancelButton(title, callback)` | Add cancel-style button             | Void               |
| `dialog.AddTextInputField(options)`       | Add text input field                | Void               |
| `dialog.Show()`                           | Display the dialog                  | Void               |
| `dialog.Dismiss()`                        | Programmatically close dialog       | Void               |

### DatePicker APIs

| API                                   | Purpose                         | Returns                   |
| ------------------------------------- | ------------------------------- | ------------------------- |
| `DatePicker.CreateInstance(mode)`     | Create new date picker instance | DatePicker object         |
| `picker.SetInitialDate(date)`         | Set initial displayed date      | DatePicker (for chaining) |
| `picker.SetMinimumDate(date)`         | Set earliest selectable date    | DatePicker (for chaining) |
| `picker.SetMaximumDate(date)`         | Set latest selectable date      | DatePicker (for chaining) |
| `picker.SetOnCloseCallback(callback)` | Set result callback             | DatePicker (for chaining) |
| `picker.Show()`                       | Display the picker              | Void                      |

### Data Properties

| Property                        | Type        | Notes                                                                             |
| ------------------------------- | ----------- | --------------------------------------------------------------------------------- |
| `DatePickerResult.SelectedDate` | `DateTime?` | Selected date/time value; `null` when the picker is dismissed without a selection |
| `TextInputFieldOptions`         | Class       | Configure placeholder, keyboard, secure entry                                     |

## Common Patterns

### Pattern 1: Confirmation Dialog

Standard Yes/No confirmation:

```csharp
public void ConfirmPurchase(string itemName, int cost)
{
    AlertDialog dialog = AlertDialog.CreateInstance();
    dialog.Title = "Confirm Purchase";
    dialog.Message = $"Buy {itemName} for {cost} coins?";

    dialog.AddButton("Buy", () =>
    {
        ProcessPurchase(itemName, cost);
    });

    dialog.AddCancelButton("Cancel", () =>
    {
        Debug.Log("Purchase cancelled");
    });

    dialog.Show();
}

void ProcessPurchase(string item, int cost)
{
    Debug.Log($"Purchased {item} for {cost} coins");
}
```

### Pattern 2: User Input Collection

Collect and validate user input:

```csharp
public void ShowNameInput()
{
    AlertDialog dialog = AlertDialog.CreateInstance();
    dialog.Title = "Player Name";
    dialog.Message = "Enter your name (3-15 characters):";

    var options = new TextInputFieldOptions.Builder()
        .SetPlaceholderText("Your name")
        .Build();
    dialog.AddTextInputField(options);

    dialog.AddButton("OK", (inputTexts) =>
    {
        string name = inputTexts[0];

        if (name.Length >= 3 && name.Length <= 15)
        {
            SavePlayerName(name);
        }
        else
        {
            ShowError("Name must be 3-15 characters");
        }
    });

    dialog.AddCancelButton("Cancel", () => { });

    dialog.Show();
}

void SavePlayerName(string name)
{
    Debug.Log("Player name saved: " + name);
}

void ShowError(string message)
{
    AlertDialog errorDialog = AlertDialog.CreateInstance();
    errorDialog.Title = "Error";
    errorDialog.Message = message;
    errorDialog.AddButton("OK", () => { });
    errorDialog.Show();
}
```

### Pattern 3: Tournament Scheduling

Date picker for event scheduling:

```csharp
public void ScheduleTournament()
{
    DatePicker datePicker = DatePicker.CreateInstance(DatePickerMode.DateAndTime);

    // Tournament must be at least 24 hours in future
    datePicker.SetMinimumDate(DateTime.Now.AddDays(1));
    datePicker.SetMaximumDate(DateTime.Now.AddMonths(1));
    datePicker.SetInitialDate(DateTime.Now.AddDays(7));

    datePicker.SetOnCloseCallback((result) =>
    {
        if (result.SelectedDate.HasValue)
        {
            ShowConfirmation(result.SelectedDate.Value);
        }
    });

    datePicker.Show();
}

void ShowConfirmation(DateTime tournamentDate)
{
    AlertDialog dialog = AlertDialog.CreateInstance();
    dialog.Title = "Confirm Tournament";
    dialog.Message = $"Schedule tournament for {tournamentDate:MMM dd 'at' HH:mm}?";

    dialog.AddButton("Confirm", () =>
    {
        Debug.Log("Tournament scheduled for: " + tournamentDate);
    });

    dialog.AddCancelButton("Cancel", () => { });

    dialog.Show();
}
```

### Pattern 4: Reminder Time Selection

Time picker for notifications:

```csharp
public void SetDailyReminder()
{
    DatePicker timePicker = DatePicker.CreateInstance(DatePickerMode.Time);

    timePicker.SetOnCloseCallback((result) =>
    {
        if (result.SelectedDate.HasValue)
        {
            TimeSpan reminderTime = result.SelectedDate.Value.TimeOfDay;
            Debug.Log($"Daily reminder set for {reminderTime.Hours:00}:{reminderTime.Minutes:00}");
            ScheduleDailyNotification(reminderTime);
        }
    });

    timePicker.Show();
}

void ScheduleDailyNotification(TimeSpan time)
{
    Debug.Log($"Scheduling daily notification at {time}");
}
```

## Error Handling

| Scenario                                | Trigger                                              | Recommended Action                                                                                                              |
| --------------------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| Dialog dismissed without confirmation   | Player taps outside the alert or presses system back | Treat `OnCloseCallback` with `SelectedDate == null` (or cancel button callbacks) as a no-op and keep the previous state intact. |
| Input validation fails                  | Text field callback receives empty or invalid data   | Re-open a lightweight alert explaining the requirement and focus the relevant field again.                                      |
| Dialogs invoked while another is active | Multiple modals launched simultaneously              | Track outstanding dialogs; dismiss the existing one before showing the next to avoid stacking errors.                           |
| App backgrounded while dialog open      | OS hides the alert/picker                            | In `OnApplicationPause(false)` re-check pending work and show the dialog again if the action is critical.                       |

## Advanced Configuration

{% hint style="danger" %}
Manual initialization is for advanced scenarios only. Essential Kit auto-initializes Native UI using the Essential Kit Settings asset. Only use `Initialize()` for runtime-generated settings.
{% endhint %}

Override settings at runtime if needed:

```csharp
void Awake()
{
    var settings = new NativeUIUnitySettings(isEnabled: true);
    // Configure advanced settings if needed (custom UI collection, etc.)
    NativeUI.Initialize(settings);
}
```

**Use cases for manual initialization:**

* Custom dialog themes based on app branding
* Runtime configuration from server
* Environment-specific UI behaviors

{% hint style="warning" %}
For most games, configure settings in the ScriptableObject instead of manual initialization.
{% endhint %}

## Related Guides

* Demo scene: `Assets/Plugins/VoxelBusters/EssentialKit/Examples/Scenes/NativeUIDemo.unity`
* Use with **Utilities.OpenApplicationSettings()** for permission recovery flows
* Combine with **Notification Services** for reminder and alarm date selection
* See [Testing Guide](https://github.com/voxelbusters/essential-kit-docs/blob/master/tutorials/v3/features/native-ui/testing.md) to validate dialogs across platforms


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://assetstore.essentialkit.voxelbusters.com/features/native-ui/usage.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
