NativePHP for Mobile v4 is here — build real native UIs from Blade with SuperNative

Text


Overview#

Displays text content using platform-native typography. Text content goes between the opening and closing tags.

Copied!
<native:text class="text-lg font-bold text-theme-on-surface">
Hello, world!
</native:text>

Props#

All shared layout and style attributes are supported, plus:

  • font-size - Text size in sp/pt (optional, float, default: 16)

  • font-weight - Weight 1-7 (optional, int, default: 3):

    • 1 thin
    • 2 light
    • 3 regular (normal)
    • 4 medium
    • 5 semibold
    • 6 bold
    • 7 heavy (extrabold)

    Values outside 1-7 are clamped to the nearest supported weight.

  • color - Text color as hex string (optional, default: #000000)

  • text-align - Alignment: left, center, or right — a label, a TextAlign case, or the integer 0/1/2 (optional, default: left)

  • max-lines - Maximum lines before truncating with ellipsis (optional, int)

  • font-style - 0=normal, 1=italic (optional, int)

  • font-family - Typeface: 0=sans, 1=serif, 2=mono (optional, int)

  • underline - Underline: 1=on, 0=off (optional, int)

  • line-through - Strikethrough: 1=on, 0=off (optional, int)

  • text-transform - Case: 0=none, 1=uppercase, 2=lowercase, 3=capitalize (optional, int)

  • letter-spacing - Tracking in em relative to font size (optional, float)

  • font - Custom font: a resources/fonts/ file token or a config alias like accent (optional, string) — see Custom fonts

Line height is set with leading-* classes — see Line height.

Custom fonts#

Ship a font with your app and use it by name. Drop .ttf, .otf, or .ttc files into your app's resources/fonts/ directory, then reference one by its filename (without the extension) with the font attribute:

Copied!
<native:text font="RockSalt-Regular" class="text-2xl text-theme-on-surface">
Custom heading
</native:text>

So resources/fonts/Inter-Bold.ttf becomes font="Inter-Bold". The build bundles the files into the native project automatically — no configuration needed. On iOS the font is registered and matched by its PostScript name; on Android it's loaded from the app's assets. An unresolved name falls back to the system font.

font also works on <native:button> and the text inputs, and is available fluently as ->font('Inter-Bold').

Downloading from Google Fonts#

The native:font command downloads a Google Fonts family into resources/fonts/ and registers it in your config — no API key needed:

Copied!
php artisan native:font
php artisan native:font "Rock Salt"
php artisan native:font Inter --default

Run bare, the command opens a searchable list of the whole catalog; pass a family name (quoted when it contains spaces, matched case-insensitively) to skip the search. Either way you then pick which styles to download from a multiselect — Regular (400) is preselected — and the command handles one family per run.

Files are named <Family>-<Style>.ttf (Inter-Bold.ttf, Inter-BoldItalic.ttf, …), so the basename is ready to use as a font token. Every downloaded style is also written to the fonts array in config/native-ui.php as an alias — the command suggests a key per style (inter, inter-bold, …) that you can rename at the prompt, and asks whether one style should become the app-wide default. Google Fonts are libre-licensed (OFL / Apache), so bundling them in your app is permitted.

  • --default — make the downloaded font the app-wide default alias without asking
  • --force — overwrite files that already exist in resources/fonts/ (and skip the --reset confirmation)
  • --reset — delete every font file in resources/fonts/ and reset the config to 'default' => 'System' (asks first)
  • --clear-cache — clear the cached catalog (the family list is cached for 24 hours)

Non-interactive runs (--no-interaction, CI) require the family argument, download only Regular (400) — or the first listed style for families without one — write the suggested alias keys as-is, and skip existing files unless --force is passed.

Font aliases & the app-wide default#

Give bundled fonts semantic names in config/native-ui.php and use the alias anywhere a font token works — the font attribute, chrome ->font() builders, or a layout's $font:

Copied!
'fonts' => [
'default' => 'Inter-Regular', // the app-wide default font
'accent' => 'DynaPuff-Regular',
],
Copied!
<native:text font="accent">Playful headline</native:text>

Alias names are yours to choose (brand, heading, …) — only default is special: it applies everywhere — text, buttons, inputs, and navigation chrome — without touching individual elements. Per-element font attributes and explicit font-serif / font-mono classes still win over it. Swapping a font app-wide becomes a one-line config change; blades keep their semantic names. Each alias must point directly at a file token (no alias-to-alias chaining).

native:font maintains this array for you — every downloaded style gets an entry, and the --default flag (or the prompt) sets default. Prefer aliases over the older font-family theme token (which fonts.default supersedes when both are set); native:font --default only falls back to writing font-family when the config has no fonts block.

Line height#

Control the leading (line spacing) with Tailwind leading-* classes — unitless multipliers of the font size:

  • leading-none (1) · leading-tight (1.25) · leading-snug (1.375)
  • leading-normal (1.5) · leading-relaxed (1.625) · leading-loose (2)

Arbitrary values are supported too: leading-[1.4] (multiplier) or leading-[24px] (absolute).

Copied!
<native:text class="text-base leading-relaxed text-theme-on-surface">
A comfortably spaced paragraph that wraps across several lines with a little
extra breathing room between them.
</native:text>

Line height only affects multi-line text.

Text styling#

Style text with Tailwind classes — these compose with text-* size and font-* weight:

  • Italicitalic, not-italic
  • Decorationunderline, line-through, no-underline. underline and line-through are independent flags, so they combine; no-underline clears both.
  • Transformuppercase, lowercase, capitalize, normal-case
  • Letter spacing (tracking)tracking-tighter, tracking-tight, tracking-normal, tracking-wide, tracking-wider, tracking-widest (in em, relative to the font size)
  • Font familyfont-sans (default), font-serif, font-mono
Copied!
<native:text class="text-lg font-semibold italic underline tracking-wide text-theme-on-surface">
Styled with Tailwind
</native:text>

Inline runs#

Nest <native:text> elements inside a <native:text> to style spans within a single paragraph. The nested runs and the surrounding text compose into one attributed string that wraps together as a unit — each run carries its own classes (weight, color, size):

Copied!
<native:text class="text-base text-theme-on-surface">
Use <native:text class="font-bold">bold</native:text> and
<native:text class="text-theme-primary font-semibold">color</native:text> inline.
</native:text>

Runs render in document order, so interleaved text and nested <native:text> stay in sequence. A <native:text> with no nested runs behaves exactly like a plain string.

Text selection#

Text isn't selectable by default. Add select-text to make a subtree long-press-selectable (the native Copy menu). It's container-scoped and inherited, so it covers every descendant — put it on a wrapping element to make a whole region selectable. Use select-none to opt a nested subtree back out:

Copied!
<native:column class="select-text">
<native:text class="text-lg font-bold text-theme-on-surface">Selectable heading</native:text>
<native:text class="text-base text-theme-on-surface">This body copy can be selected and copied.</native:text>
 
<native:text class="select-none text-xs text-theme-on-surface-variant">Not selectable</native:text>
</native:column>

Dark Mode#

Use the dark: prefix with Tailwind classes or pass a dark-mode color override.

Copied!
<native:text class="text-slate-900 dark:text-white text-lg">
Adapts to dark mode
</native:text>

Examples#

Font weight scale#

Copied!
<native:text :font-weight="1" :font-size="18" class="text-theme-on-surface">Thin (1)</native:text>
<native:text :font-weight="2" :font-size="18" class="text-theme-on-surface">Light (2)</native:text>
<native:text :font-weight="3" :font-size="18" class="text-theme-on-surface">Regular (3)</native:text>
<native:text :font-weight="4" :font-size="18" class="text-theme-on-surface">Medium (4)</native:text>
<native:text :font-weight="5" :font-size="18" class="text-theme-on-surface">SemiBold (5)</native:text>
<native:text :font-weight="6" :font-size="18" class="text-theme-on-surface">Bold (6)</native:text>
<native:text :font-weight="7" :font-size="18" class="text-theme-on-surface">Heavy (7)</native:text>

Truncated text#

Copied!
<native:text class="text-base text-theme-on-surface-variant" :max-lines="2">
This text will be truncated with an ellipsis after two lines if it overflows
the available space in its container.
</native:text>

Centered heading#

Copied!
<native:text class="text-3xl font-extrabold text-center text-theme-primary">
Welcome Back
</native:text>

Tappable text#

Copied!
<native:text class="text-base font-semibold text-theme-primary" @press="openLink">
Learn more
</native:text>

Dynamic content#

Copied!
@php $score = 1250; @endphp
 
<native:text class="text-lg font-semibold text-theme-primary">
Score: {{ $score }}
</native:text>

Here $score stands in for a public property on your component — public int $score = 1250;.

Element#

Copied!
use Native\Mobile\Edge\Elements\Text;
use Native\Mobile\Edge\Enums\TextAlign;
 
Text::make('Hello')
->fontSize(18)
->fontWeight(6)
->color('#1E293B')
->textAlign(TextAlign::Center)
->maxLines(2);
  • make(string $text = '') - Create text with content
  • fontSize(float $size) - Text size
  • font(string $name) - Custom font (file token or config alias)
  • fontWeight(int $weight) - 1-7 (clamped to the nearest supported weight)
  • bold() - Shortcut for fontWeight(7)
  • fontStyle(int $style) - 0=normal, 1=italic
  • italic() - Shortcut for fontStyle(1)
  • color(string $hex) - Text color
  • textAlign(int|string|TextAlign $align) - left/center/right, a TextAlign case, or 0/1/2
  • maxLines(int $lines) - Truncate after N lines
  • selectable(bool $on = true) - Make the subtree selectable (mirrors select-text / select-none)