Skip to main content
Firstlight

Firstlight / Docs

Recipes for the screens a forms app needs, setup for your coding agent, Laravel on native screens, and accessibility.

View source
Code Editor

Code Editor

Code Editor edits plain-text configuration and code — JSON, YAML, .env files, and plain text — in a monospaced native text view with line numbers, language-aware indentation, and a key row above the software keyboard. It has no syntax highlighting.

Complete example

<firstlight:code-editor
    label="Environment"
    language="env"
    helper="One KEY=value per line."
    native:model.debounce.500ms="environment"
/>

A read-only live log that stays at the newest line:

<firstlight:code-editor
    label="Deployment log"
    :read-only="true"
    :follow="true"
    :wrap="false"
    :max-lines="24"
    :value="$log"
/>

Props

API Accepted type Purpose
value / native:model string Published PHP value, sent verbatim; omission defaults to ''.
language enum string plain, json, yaml, or env; defaults to plain. Selects indentation rules and key-row symbols. It never validates or reformats content.
label string Visible label and accessibility-name fallback.
helper string Supporting guidance below the field.
error string Validation feedback that replaces helper text.
required bool Communicates required metadata without performing validation.
disabled bool Prevents focus and editing.
read-only bool Keeps native selection, copy, and scrolling while preventing edits; hides the key row.
line-numbers bool Shows the line-number gutter; defaults to true.
wrap bool Wraps long lines; defaults to true. false scrolls horizontally.
indent int 2 or 4 spaces per level; defaults to 2.
follow bool Keeps the view pinned to the end across programmatic updates; defaults to false. Requires read-only.
min-lines positive int Minimum visible lines; defaults to 6.
max-lines positive int Maximum visible lines before native scrolling; defaults to 20.
a11y-label string Explicit accessible name when no visible label is appropriate.
a11y-hint string Additional VoiceOver or TalkBack guidance.
class string External EDGE layout for the complete field.

max-lines must be greater than or equal to min-lines.

NativePHP publishes at most 64 KB of props for one element, so the value must stay under about 60 KB of UTF-8. Larger content throws a contract exception instead of reaching the device as an empty editor. For live logs, keep only the newest lines. Public Blade examples use kebab-case. The PHP element also accepts lineNumbers, readOnly, minLines, and maxLines aliases.

Code Editor always turns off autocorrect, autocapitalization, and spell checking, and uses the system monospaced font at the platform's text size. placeholder, autocorrect, autocapitalize, keyboard, content-type, icons, secure, @submit, and styling attributes are rejected.

Editing

Return keeps the current line's leading spaces or tabs. In json, Return after an opening { or [ adds one level, and Return between a bracket pair splits it onto three lines. Typing } or ] at the start of a line removes one level. In yaml, Return after a line ending in : adds one level; comments are ignored. env and plain only keep the current indentation.

Indent and Outdent act on the current line or every selected line. Toggle comment, in yaml and env, adds or removes # on the current or selected lines. Indentation always inserts spaces; existing tabs are kept.

Key row

While the field is focused and editable, a key row sits above the software keyboard. It is hidden when a hardware keyboard is attached, where Tab and Shift-Tab indent and outdent.

Language Keys after Indent, Outdent, Undo, Redo
json { } [ ] " : ,
yaml : - # " ' |, Toggle comment
env = # " $ { } _, Toggle comment
plain ( ) [ ] { } " '

Each key press is one undoable edit. Key names and accessible names are package chrome; see Localize Firstlight chrome.

Events and synchronisation

@change receives the complete current string. Plain native:model and .live publish while editing. .blur and .lazy publish on focus loss. .debounce.500ms publishes after the quiet period and flushes on blur. Durations below 50 milliseconds are rejected.

While the field is focused, the native buffer, cursor, selection, IME composition, scroll position, and undo history stay local. PHP acknowledgements do not replace them. Unfocused programmatic updates replace the text, clear undo history, and never emit @change.

Scroll position and follow

A programmatic update never jumps to the top. The first visible line stays in place when lines are appended or removed from the start, and otherwise the previous scroll offset is kept.

With follow, the view starts at the end and stays there across updates while it is within one line of the end, including when PHP trims the start of the content. Scrolling up stops following; scrolling back to the end resumes it. While a person holds a selection in a read-only editor, updates wait until the selection collapses so copying is never interrupted. Updates are not announced to VoiceOver or TalkBack.

Validation and accessibility

Contract exceptions reject invalid types, unknown languages, indents other than 2 or 4, unordered line bounds, follow without read-only, and unsupported sync modes before publication. Screens that use ValidatesFields auto-bind the first MessageBag message for the field's native:model or error-for name; an authored error wins. See Validate fields.

A visible label or explicit a11y-label is required during development. Line numbers are hidden from assistive technology, so validation messages should quote the offending key or content rather than only a line number. Every key-row key has an accessible name and meets the 44 pt / 48 dp target. Code text stays left-to-right in right-to-left layouts.

Security

.env content often contains secrets. Code Editor is not a secure field: it does not mask values, block screenshots, or guarantee that keyboards skip learning what is typed. Decide whether editing secrets on the device is acceptable for your application.

Platform behaviour

iOS uses a TextKit 2 UITextView in Apple-native field composition, with a line-number gutter, an input-accessory key row with a Done button, and the text view's own undo manager. Android uses Compose BasicTextField on TextFieldState inside Material 3 outlined decoration, with a line-number gutter, a Material key row above the keyboard, and the text field's undo history. Both platforms run the same indentation and scroll-anchor rules, checked against shared test fixtures.

Screenshots

Platform Light Dark
iOS Code Editor on iOS in light mode Code Editor on iOS in dark mode
Android Code Editor on Android in light mode Code Editor on Android in dark mode

Served from firstlightui/nativephp on GitHub.