PHPackages                             nativephp/native-ui - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. nativephp/native-ui

ActiveNativephp-ui-plugin

nativephp/native-ui
===================

A NativePHP Mobile plugin

89↑2566.7%2[2 PRs](https://github.com/NativePHP/mobile-ui/pulls)SwiftCI passing

Since Apr 26Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/NativePHP/mobile-ui)[ Packagist](https://packagist.org/packages/nativephp/native-ui)[ RSS](/packages/nativephp-native-ui/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)DependenciesVersions (5)Used By (0)

NativeUI Plugin for NativePHP Mobile
====================================

[](#nativeui-plugin-for-nativephp-mobile)

A NativePHP Mobile plugin

Installation
------------

[](#installation)

```
composer require nativephp/mobile-ui
```

Usage
-----

[](#usage)

```
use Native\Mobile\UI\Facades\NativeUI;

// Execute functionality
$result = NativeUI::execute(['option1' => 'value']);

// Get status
$status = NativeUI::getStatus();
```

Listening for Events
--------------------

[](#listening-for-events)

```
use Livewire\Attributes\On;

#[On('native:Native\Mobile\UI\Events\NativeUICompleted')]
public function handleNativeUICompleted($result, $id = null)
{
    // Handle the event
}
```

Theming &amp; Colors
--------------------

[](#theming--colors)

Theme tokens live in `config/native-ui.php` (publish with `php artisan vendor:publish --tag=native-ui-config`). Every authored color — theme tokens, element color props, and arbitrary-value classes — accepts the same grammar:

```
'light' => [
    'primary'   => 'violet-600',      // Tailwind palette name
    'secondary' => 'fuchsia-500/70',  // opacity modifier → tonal fill
    'surface'   => '#F8FAFC',         // plain hex (#RGB / #RRGGBB)
    'accent'    => '#00AAA680',       // CSS alpha hex (#RRGGBBAA)
],
```

Alpha hex is authored in CSS `#RRGGBBAA` order; the framework converts to the native wire format. Dark mode is auto-derived from `light` (alpha preserved) unless a `dark` block overrides specific tokens.

Disabled controls draw from the `surface-variant` (fill) and `on-surface-variant` (label) tokens on both platforms — adjust those two tokens to tune disabled contrast app-wide.

Icons accept platform enum overrides in Blade, matching the fluent API:

```

```

Accessibility
-------------

[](#accessibility)

Every element accepts a screen-reader label and an optional hint, via Blade attributes (`a11y-label` / `a11y-hint`, or the camelCase spellings `a11yLabel` / `a11yHint`) or the fluent API (`->a11yLabel()` / `->a11yHint()`). The label maps to `accessibilityLabel` on iOS and `contentDescription` on Android; the hint maps to `accessibilityHint` on iOS and is appended to the content description on Android.

```

```

```
use Native\Mobile\UI\Elements\Button;

Button::make()
    ->icon('plus')
    ->a11yLabel('Add item')
    ->a11yHint('Adds a new item to the list')
    ->onPress('addItem');
```

Always set `a11y-label` on icon-only buttons, chips, and tabs — without visible text there is nothing for VoiceOver / TalkBack to announce. Icons are decorative (silent to screen readers) unless given an `a11y-label`. List items with a trailing icon button take `trailing-a11y-label` (fluent: `->trailingA11yLabel()`) to label that button separately from the row.

Testing
-------

[](#testing)

Theme normalization and config write-back are pure PHP — no device, emulator, or bridge round-trip required. `Theme::load()` / `Theme::merge()` resolve authored color tokens (Tailwind names, `red-300/20` opacity modifiers, CSS `#RRGGBBAA` alpha hex) to wire-format hex, auto-derive a dark block, and mirror the effective set into `config('native-ui.theme.…')`. You can assert every step of that in a unit test:

```
use Illuminate\Config\Repository;
use Illuminate\Container\Container;
use Native\Mobile\UI\Theme;

it('normalizes tokens and mirrors them into config', function () {
    Container::getInstance()->instance('config', new Repository);

    try {
        Theme::load([
            'light' => ['primary' => 'red-300', 'accent' => '#8B5CF680'],
            'dark'  => ['primary' => 'red-800'],
        ]);

        // Normalized tokens are readable via Theme::get('mode.token'):
        expect(Theme::get('light.primary'))->toBe('#FCA5A5');   // palette name
        expect(Theme::get('light.accent'))->toBe('#808B5CF6');  // CSS alpha → wire ARGB

        // …and mirrored back so core's theme() helper reads wire-format hex:
        expect(config('native-ui.theme.light.primary'))->toBe('#FCA5A5');
        expect(config('native-ui.theme.dark.primary'))->toBe('#991B1B');
    } finally {
        Container::setInstance(null);
    }
});
```

Element color and typography props share the same grammar and serialize the same way. Elements expose `toArray(new CallbackRegistry)` (via `NativeElementCollector`), so you can assert what lands on the wire:

```
use Native\Mobile\Edge\CallbackRegistry;
use Native\Mobile\UI\Elements\Button;

it('serializes typography props on an element', function () {
    $props = Button::make('Save')->font('Inter-Bold')->toArray(new CallbackRegistry)['props'];

    expect($props['font_name'])->toBe('Inter-Bold');
});
```

### Keeping `Theme::pushToNative()` off the wire

[](#keeping-themepushtonative-off-the-wire)

`Theme::load()` / `merge()` fire a `NativeUI.Theme.Set` bridge call on every change. In a full Laravel test app, `pushToNative()`'s `runningUnitTests()`guard suppresses it. In **plain Pest** (no booted app), that guard can't trip, so mute the bridge in `beforeEach()` — the same pattern the plugin's own tests use — and `reset()` between tests:

```
use Native\Mobile\JumpBridge;
use Native\Mobile\UI\Theme;

beforeEach(function () {
    JumpBridge::instance()->mute();
    Theme::reset();
});

afterEach(fn () => Theme::reset());
```

License
-------

[](#license)

MIT

###  Health Score

26

—

LowBetter than 40% of packages

Maintenance61

Regular maintenance activity

Popularity14

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity17

Early-stage or recently created project

 Bus Factor1

Top contributor holds 97.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/16cc4d562d3f6f302901f1c65eb3ce819c0fb24ab2616241c605126102812ca4?d=identicon)[shanerbaner82](/maintainers/shanerbaner82)

---

Top Contributors

[![shanerbaner82](https://avatars.githubusercontent.com/u/5580860?v=4)](https://github.com/shanerbaner82 "shanerbaner82 (84 commits)")[![simonhamp](https://avatars.githubusercontent.com/u/31628?v=4)](https://github.com/simonhamp "simonhamp (2 commits)")

### Embed Badge

![Health badge](/badges/nativephp-native-ui/health.svg)

```
[![Health](https://phpackages.com/badges/nativephp-native-ui/health.svg)](https://phpackages.com/packages/nativephp-native-ui)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
