Skip to content

mobile-ui@main: manifest blade paths do not resolve against core (see correction — original report was wrong) #58

Description

@CodyPChristian

Installing mobile-ui at main against nativephp/mobile at main leaves most components unregistered, silently. The app boots and renders, but <button>, every text input, <modal>, <bottom-sheet>, <progress-bar> and around twenty other tags produce no node at all — no error, no warning, nothing in the log.

A login screen renders its headings and then simply stops: no fields, no submit button.

Environment

ref
nativephp/mobile dev-main @ bf4fd2a (current main HEAD)
mobile-ui attempted dev-main @ 130bdc8
mobile-ui working dev-layout-drawer @ 664d545

PHP 8.4, Laravel 12, iOS 26.3 simulator.

mobile-ui@main declares "nativephp/mobile": "^4.0", which core satisfies, so Composer resolves it without complaint.

What happens

mobile-ui@main's nativephp.json declares 59 components. Loading its src/ alongside the installed core and testing every class named in the manifest:

declared           59
element resolves   58   (missing: 1 -> horizontal_divider)
blade  resolves    34   (missing: 25)
BOTH resolve       34

At runtime:

count(Native\Mobile\Edge\ElementRegistry::all());
// dev-layout-drawer -> 52
// dev-main          -> 27

Cause

The manifest's blade paths do not match where core ships those classes:

manifest:   Native\Mobile\Edge\Components\Text
core ships: Native\Mobile\Edge\Components\Native\Text
                                          ^^^^^^^

Confirmed directly:

Native\Mobile\Edge\Components\Text            missing
Native\Mobile\Edge\Components\Native\Text     EXISTS
Native\Mobile\Edge\Components\Column          missing
Native\Mobile\Edge\Components\Native\Column   EXISTS

Core's full Edge/Components/Native/ set (17): Canvas, Circle, Column, Divider, GestureArea, Image, LazyGrid, Line, NativeBladeComponent, Pressable, Rect, Refreshable, Row, ScrollView, Spacer, Stack, Text.

24 of the 25 unresolvable blade entries are Native\Mobile\Edge\Components\* and differ only by that segment:

text image column row stack scroll_view lazy_grid gesture_area refreshable
pressable canvas spacer divider rect circle line top_bar top_bar_action
bottom_nav bottom_nav_item side_nav side_nav_item side_nav_group side_nav_header

The twenty-fifth is icon -> Native\Mobile\UI\Components\Icon, and the one unresolvable element is horizontal_divider -> Native\Mobile\Edge\Elements\HorizontalDivider.

Native\Mobile\UI\Elements\* (Button, OutlinedTextInput, Modal, BottomSheet and the rest) all resolve — those ship inside mobile-ui itself. The mismatch is only where the manifest reaches into core.

One thing I could not account for: 34 components have both classes resolvable, but only 27 register. There is some further gating I did not chase — platform or renderer checks seem the likely candidates. Flagging rather than guessing.

Reproduction

composer require nativephp/mobile-ui:dev-main -W    # against core dev-main @ bf4fd2a
php artisan tinker --execute='echo count(Native\Mobile\Edge\ElementRegistry::all());'
# 27   (52 on dev-layout-drawer)

Then render any view containing <button> or <outlined-text-input>. The tag produces no node.

Suggestions

1. Make the registration failure loud. This matters more than the namespace bug itself. A manifest entry whose class is missing is skipped in silence, so a plugin can be half dead while everything appears fine. The symptom surfaces as "my button does not render", a long way from the cause. A warning in debug mode would turn this class of problem into a five minute fix. Worth noting this is not hypothetical or limited to this repo: the same silent skip hides a stale namespace in any third party plugin manifest, and it is genuinely hard to find from the symptom.

2. Fix the blade paths to Native\Mobile\Edge\Components\Native\*, or move core's classes up a level if the manifest reflects the intended shape.

3. Express the real core requirement. ^4.0 is satisfied by a core that cannot drive this manifest. If main targets an unreleased core, a dev constraint would let Composer say so rather than producing a half working install.

Happy to test a fix against the setup above.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions