Search by

laratribe / native-datepicker

rnsharma93

A native date picker EDGE component for NativePHP Mobile v4 with compact (calendar) and wheel modes (SwiftUI + Jetpack Compose).

Package info

github.com/laratribe/native-php-datepicker

Type:nativephp-plugin

pkg:composer/laratribe/native-datepicker

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0 2026-10-29 11:25 UTC

This package is auto-updated.

Last update: 2026-10-29 15:19:17 UTC


README

Latest Version on Packagist GitHub Tests Total Downloads License NativePHP Mobile PHP Version

A native date picker EDGE component for NativePHP Mobile v4. It renders real, high-performance native OS controls on both iOS and Androidβ€”not a web view or HTML input.

🌟 Highlights

  • 100% Native UI:
    • iOS: Rendered using SwiftUI DatePicker(.graphical) and Picker(.wheel).
    • Android: Rendered using Jetpack Compose Material 3 DatePicker and snapping drum wheels.
  • Two Display Modes (mode):
    • compact (default): Month calendar grid for quick date browsing.
    • wheel: Smooth day / month / year drum wheels with haptic snapping.
  • Two Presentation Styles (presentation):
    • field (default): An interactive trigger input that opens a native sheet (iOS) or modal dialog (Android).
    • inline: Embedded directly within your screen layout.
  • Two-Way Data Binding: Seamless integration with native:model and native:model.live.
  • Date Constraints: Set min-date and max-date down to the exact day (e.g., max-date="today"), with automatic year-range clamping.
  • Timezone-Aware "Today": Guarantees that "today" resolves accurately across client and server clocks.
  • Internationalization: Localize month names via BCP-47 locale tags (en, fr-FR, ja, etc.) while keeping consistent PHP data formats.
  • Theme & Design Tokens: Automatically inherits NativePHP light/dark UI tokens or accepts custom hex color overrides.
  • Built-in Accessibility: Native screen reader (VoiceOver and TalkBack) labels and hints.

Why <native:laratribe-date-picker>?
nativephp/mobile-ui already claims the default date_picker element. This package uses the laratribe_date_picker element type and <native:laratribe-date-picker> Blade tag to avoid namespace conflicts.

πŸ“‹ Requirements

Dependency Minimum Version
PHP ^8.2
NativePHP Mobile ^4.0
nativephp/mobile-ui ^0.8
iOS 16.0+
Android API 26+ (Android 8.0 Oreo)

πŸš€ Installation

1. Install via Composer

Install the package via Composer:

composer require laratribe/native-datepicker

Installing directly from GitHub repository:
If the package is not yet published on Packagist or you are using the repository directly, add the VCS repository to your root composer.json:

{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/laratribe/native-php-datepicker.git"
        }
    ]
}

Then run:

composer require laratribe/native-datepicker:dev-main

2. Register Plugin & Publish Assets

Register the plugin in your NativePHP application:

# Publish plugin configuration (optional)
php artisan vendor:publish --tag=date-picker-config

# Ensure plugins provider is published
php artisan vendor:publish --tag=nativephp-plugins-provider

# Register and validate the plugin
php artisan native:plugin:register laratribe/native-datepicker
php artisan native:plugin:validate
php artisan native:plugin:list

3. Build & Run the Native App

Because this plugin contains native Kotlin and Swift code, you must rebuild the application:

# Run on iOS simulator or device
php artisan native:run ios

# Or run on Android emulator or device
php artisan native:run android

Note on Hot Reloading:
PHP and Blade changes will hot-reload instantly. However, changes to native renderer source code, the manifest, or plugin registration require re-running native:run (or php artisan native:install --force).

βš™οΈ Configuration

Publish the config file to customize package defaults:

php artisan vendor:publish --tag=date-picker-config

This creates config/date-picker.php:

return [
    /*
    | Default mode: 'compact' (calendar grid) or 'wheel' (day/month/year drum).
    | Default presentation: 'field' (input + sheet/dialog) or 'inline'.
    */
    'mode' => 'compact',
    'presentation' => 'field',

    'year_start' => 1990,
    'year_end' => null, // Defaults to current year + 20
    'format' => 'Y-m-d',

    /*
    | Leave keys null to inherit Native UI light/dark tokens.
    | Specify hex colors to override.
    */
    'theme' => [
        'bg' => null,
        'card' => null,
        'border' => null,
        'text' => null,
        'muted' => null,
        'muted_2' => null,
        'accent' => null,
    ],

    /*
    | Sizing options for wheel mode (density-independent dp/pt).
    */
    'size' => [
        'row_height' => 44,
        'visible_items' => 5, // Clamped to 3, 5, or 7
        'wheel_height' => null,
        'card_padding' => 16,
        'corner_radius' => 20,
        'selected_font' => 20,
        'muted_font' => 15,
    ],
];

πŸ’‘ Usage

Basic Example

Bind the date picker directly to a property in your NativeComponent:

namespace App\Native\Screens;

use Native\Mobile\Edge\NativeComponent;

class ProfileScreen extends NativeComponent
{
    public string $birthday = '2000-01-15';

    public function render()
    {
        return view('native.profile');
    }
}

In your Blade view (resources/views/native/profile.blade.php):

<native:laratribe-date-picker
    native:model="birthday"
    label="Birth Date"
    title="Select your birthday"
    format="Y-m-d"
    mode="compact"
    presentation="field"
    confirm-label="Confirm"
    a11y-label="Select your birthday"
/>

πŸ“– In-Depth Examples

1. Modes & Presentations

You can mix and match mode and presentation:

{{-- 1. Calendar inside a modal dialog / bottom sheet (Default) --}}
<native:laratribe-date-picker
    native:model="appointmentDate"
    mode="compact"
    presentation="field"
    label="Appointment Date"
/>

{{-- 2. Drum wheels drawn inline with a footer (Today / Cancel / Done) --}}
<native:laratribe-date-picker
    native:model="birthday"
    mode="wheel"
    presentation="inline"
    :visible-items="5"
/>

{{-- 3. Drum wheels opened via a trigger field --}}
<native:laratribe-date-picker
    native:model="deliveryDate"
    mode="wheel"
    presentation="field"
    placeholder="Choose Delivery Date"
/>

2. Constraining Dates (min-date & max-date)

Bound selectable dates down to the exact day. Useful for age verification or disabling past/future dates:

{{-- Age restriction: Must be at least 18 years old and not in the future --}}
<native:laratribe-date-picker
    native:model="birthDate"
    label="Birthday"
    :max-date="now()->subYears(18)->toDateString()"
    year-start="1940"
/>

{{-- Booking: Only future dates within the next 30 days --}}
<native:laratribe-date-picker
    native:model="checkIn"
    min-date="today"
    :max-date="now()->addDays(30)->toDateString()"
    timezone="America/New_York"
/>

Automatic Clamping: When min-date or max-date are supplied, year-start and year-end are automatically adjusted so that the user cannot scroll the year wheel outside the valid day range.

3. Date Formats & Timezones

Supported Formats

Supports PHP date() format tokens (Y, m, d) with common separators (-, /, ., or space), as well as standard aliases:

  • Y-m-d or YYYY-MM-DD (e.g. 2026-07-16)
  • d-m-Y or DD-MM-YYYY (e.g. 16-07-2026)
  • m/d/Y or MM/DD/YYYY (e.g. 07/16/2026)
  • d.m.Y or DD.MM.YYYY (e.g. 16.07.2026)
<native:laratribe-date-picker
    native:model="bookingDate"
    format="d/m/Y"
/>

Strict Validation: Unrecognized format tokens (like j, n, y) will immediately throw an InvalidArgumentException in PHP to avoid silent parsing errors on native devices.

Timezone Handling

Pass an IANA timezone to prevent mismatch between client device time and UTC server calculations:

<native:laratribe-date-picker
    max-date="today"
    timezone="Asia/Kolkata"
/>

4. Localization (locale)

Localize month and weekday labels on the native picker using standard BCP-47 locale tags. The committed value sent to your PHP component always preserves the designated format:

<native:laratribe-date-picker
    native:model="date"
    locale="fr-FR"
/>

5. Event Handling (on-change, on-done, on-cancel)

<native:laratribe-date-picker
    native:model="eventDate"
    on-change="handleDateChanged"
    on-done="handleConfirmed"
    on-cancel="handleCancelled"
/>

In your NativeComponent:

public function handleDateChanged(string $value): void
{
    // Fires when the value changes and is confirmed
}

public function handleConfirmed(string $value): void
{
    // Fires whenever Done is tapped, even if the user re-selected the current value
}

public function handleCancelled(): void
{
    // Fires when the sheet/dialog is dismissed or Cancel is tapped
}

Why use on-done?
If a user opens the picker, navigates around, and selects the same date they started with, native:model and on-change will not fire because the value did not change (oldValue === newValue). Use on-done if you need custom logic to execute every time the user taps Done.

6. Custom Colors & Sizing

You can override colors and sizing either via config or inline per tag:

<native:laratribe-date-picker
    mode="wheel"
    :row-height="48"
    :visible-items="5"
    :card-padding="20"
    :corner-radius="16"
    :colors="[
        'card' => '#FFFFFF',
        'border' => '#E5E7EB',
        'text' => '#111827',
        'accent' => '#3B82F6',
    ]"
/>
  • visible-items: Clamped to 3, 5, or 7 to preserve vertical centering and optical balance.
  • Theme keys: bg, card, border, text, muted, muted_2, and accent.

πŸ“‘ Attributes Reference

Attribute Type Default Description
native:model string null Two-way data binding property name in your NativeComponent.
value string '' Initial date value (if not using native:model).
mode string 'compact' Display style: 'compact' (month calendar grid) or 'wheel' (drum picker).
presentation string 'field' Presentation mode: 'field' (trigger field + dialog/sheet) or 'inline'.
label string '' Floating label text above the field.
title string 'Select date' Header title shown in the dialog/sheet.
placeholder string format Placeholder text when no date is selected.
format string 'Y-m-d' PHP date pattern (Y, m, d tokens only) or aliases (YYYY-MM-DD, etc.).
min-date string null Minimum selectable date (e.g. '2020-01-01' or 'today').
max-date string null Maximum selectable date (e.g. '2030-12-31' or 'today').
year-start int 1990 Lower bound for year picker.
year-end int current + 20 Upper bound for year picker.
timezone string 'UTC' IANA timezone used to evaluate 'today'.
locale string Device locale BCP-47 tag for localizing month names (e.g. 'en', 'fr-FR', 'de').
default-to-today bool false When true, commits today's date if value is unbound. Otherwise value remains empty until confirmed.
confirm-label string 'Done' Text for the confirmation button.
cancel-label string 'Cancel' Text for the cancellation button.
show-footer bool true in inline Whether to show the footer with Today/Cancel/Done buttons.
:colors array [] Color overrides (card, border, text, muted, accent, etc.).
:row-height int 44 Row height in points/density-independent pixels (wheel mode).
:visible-items int 5 Number of visible items (3, 5, or 7).
:card-padding int 16 Internal padding of the picker container.
:corner-radius int 20 Rounded corner radius in dp/pt.
on-change string null Component method to call when date changes upon confirmation.
on-done string null Component method to call unconditionally when Done is tapped.
on-cancel string null Component method to call when dismissed or cancelled.
a11y-label string label Screen reader accessibility label (VoiceOver / TalkBack).
a11y-hint string null Screen reader accessibility hint.

πŸ§ͺ Testing

Write tests for your screens using Native::test():

use Native\Mobile\Testing\Native;
use App\Native\Screens\ProfileScreen;

it('renders date picker with correct value', function () {
    Native::test(ProfileScreen::class)
        ->assertElement('laratribe_date_picker', function ($node) {
            return $node['props']['value'] === '2000-01-15'
                && $node['props']['mode'] === 'compact';
        });
});

To run unit tests inside this package:

composer test

❓ FAQ & Troubleshooting

1. Why do .lazy, .debounce, or .blur throw an error?

Date pickers in NativePHP commit their state when the user taps Done. Modifiers like native:model.blur or native:model.debounce do not apply and will throw an InvalidArgumentException rather than failing silently. Use plain native:model or native:model.live.

2. Can I use this in React or Vue?

No. This plugin is built as an EDGE native component for NativePHP Mobile screens. It contains no web view or JavaScript bridge API.

3. Why is my selected date empty when the form loads?

By default, if no initial value is bound to native:model, the wire value is left as empty string ('') so your application can distinguish between "user made no selection" and a real date. To automatically commit today's date when unbound, add default-to-today="true".

πŸ‘€ Author

Vishal Tiwadi

If you find this package useful, please give it a ⭐️ on GitHub!

πŸ“„ License

The MIT License (MIT). Please see License File for more information.