Components
@ng-native/components is the element set: <view>, <text>, <scroll-view>,
<text-input> and the rest, each an Angular component that commits as a real native view through
React Native's Fabric renderer. There is no DOM underneath any of them and no React in the render
path. A <view> is a UIView on iOS and an Android View; a <text> is a native text layer; a
<switch> is the platform's own switch control. Reach for this package for anything that ends up
on screen; styling comes from [style] bindings and a component's own styles, compiled into a
native stylesheet at build time - see the theming guide, not this one.
import { ViewBase } from '@ng-native/components';
Every element is a separate Angular component, and Angular's own import rules apply to it like
anything else: a template that writes <scroll-view> must have ScrollView in its imports
array. Miss the import and the template still compiles, but the element renders as a plain,
unstyled view instead, with nothing but a development-mode console message to say so. When an
element does not behave as documented, check the import list first.
One name, two layers
<view> is two things with one name. The engine keeps a table of element names and the native
view each commits as - view is View, scroll-view is ScrollView, text is Paragraph - so
a bare <view> reaches native even with nothing imported. The component in this package takes the
element name as its selector (View is selector: 'view'), so importing it does not change the tag.
It attaches to the same element and adds what the table cannot: typed inputs, React Native's
default props, accessibility, events, and for <text> the text layer itself. There is no second,
prefixed set of wrappers to reach for; <view> with View imported is the wrapper.
That is also what the console message is about. On the first commit of a known element that no component has claimed, development builds log:
[angular-native] <text> is used in a template that does not import Text. Add it to the
component's `imports` from '@ng-native/components'; without it the element renders as a plain view.A name that nothing accounts for at all - not in the table, not the host of a component, and not an element selector of any directive a template imports - is almost always a typo, and gets a message of its own, once per name:
[angular-native] <veiw> is not a known element: no component, directive or registered native
view claims it, so it renders as an empty view. Check the spelling, or import the component that
owns it.Your own components' hosts (<app-card>) never trigger it, whatever their selector, and neither
do names registered with registerViewName or registerExpoView.
A misspelt input or attribute on an element is caught the same way. [numberofLines] on a
<text> binds no input, so Angular hands it on as a property and native ignores it. Development
builds compare each element's props with what its component declares, its inputs and the native
props it writes, and log the rest once per element and name:
[angular-native] <text> has no prop 'numberofLines', so native ignores it. Did you mean
'numberOfLines'? Check the spelling against the Text page, or declare it with
declareNativeProps('text', ['numberofLines']) if the native view does read it.Styles, events, the accessibility and identity props, data-* and aria-* attributes, a bare
marker attribute such as listHeader, and any attribute a directive in the template selects on or
takes as an input never trigger it. A prop the native view does read but the component has no input
for is declared once with declareNativeProps from @ng-native/fabric. Release builds skip the
check.
The names carry no prefix on purpose. They are React Native's own names in kebab case, so
React Native's documentation for ScrollView is the documentation for <scroll-view>. And ng-,
the obvious prefix, is Angular's: ng-container and ng-template are framework constructs, and
an <ng-view> would read as one. On the web, where text, image and switch are also SVG
element names, @ng-native/web creates every one of them in the HTML namespace, never as SVG: a
<text> is its own HTML element styled by the reset stylesheet, and a <switch> is a real
checkbox.
Most elements come from the package's main entry point:
import {
View,
Text,
ScrollView,
TextInput,
Pressable,
Image,
Switch,
ActivityIndicator,
Modal,
VirtualList,
SafeAreaProvider,
SafeAreaView,
} from '@ng-native/components';Gestures, Animated and Reanimated's worklets are the exception: each reaches into React
Native's own uncompiled source, which Node cannot parse, so the test suite that runs this
package's own code under Node would break if the main entry point tried to load it. Import these
from their own files - @ng-native/components/gestures,
@ng-native/components/animations, @ng-native/components/reanimated - covered
on the gestures and animation pages.
The smallest thing that works:
import { Component, input } from '@angular/core';
import { View, Text } from '@ng-native/components';
@Component({
selector: 'app-greeting',
imports: [View, Text],
template: `
<view>
<text>Hello, {{ name() }}</text>
</view>
`,
})
export class Greeting {
readonly name = input('there');
}Shared props
<view>, <text> and every other element extend one abstract base that carries the props every
native view accepts: accessibility (accessibilityLabel/aria-label, accessibilityRole/role,
accessibilityState and its aria-* aliases), identity and hit testing (nativeID/id,
testID, hitSlop, pointerEvents). None of these show up in a specific element's own table
below; they are all here instead.
ViewBasedirective@ng-native/componentsimport { ViewBase } from '@ng-native/components';and add ViewBase to the component's importsInputs
accessiblebooleanWhether the view is an accessibility element. Defaults to false for a plain view.
accessibilityLabelstringWhat a screen reader announces for the view.
aria-labelstringaria-label : web spelling of accessibilityLabel .
accessibilityLabelledBystring | readonly string[] Android: nativeID s of the views that label this one.
aria-labelledbystring | readonly string[]aria-labelledby : web spelling of accessibilityLabelledBy .
accessibilityHintstringWhat happens when the user acts on the view, when the label alone does not say.
accessibilityRoleAccessibilityRoleThe kind of control this is, for assistive technologies.
roleAccessibilityRolerole : the web spelling of accessibilityRole .
accessibilityStateAccessibilityStateDisabled, selected, checked, busy and expanded, as one object.
aria-busybooleanaria-busy .
aria-checkedboolean | 'mixed'aria-checked .
aria-disabledbooleanaria-disabled .
aria-expandedbooleanaria-expanded .
aria-selectedbooleanaria-selected .
accessibilityValueAccessibilityValueThe current value of an adjustable control, for a screen reader.
aria-valueminnumberaria-valuemin .
aria-valuemaxnumberaria-valuemax .
aria-valuenownumberaria-valuenow .
aria-valuetextstringaria-valuetext .
accessibilityActionsreadonly AccessibilityAction[] Custom actions a screen reader can invoke; each arrives as (accessibilityAction) .
accessibilityLiveRegionAccessibilityLiveRegionAndroid: announce changes to this view's content without focus moving to it.
aria-liveAccessibilityLiveRegionaria-live .
accessibilityElementsHiddenbooleaniOS: hide this view and its children from assistive technologies.
aria-hiddenbooleanaria-hidden : accessibilityElementsHidden on iOS, no-hide-descendants on Android.
importantForAccessibilityImportantForAccessibilityAndroid: whether this view is exposed to accessibility, and whether its children are.
accessibilityViewIsModalbooleaniOS: VoiceOver ignores every sibling while this view is shown, as a modal expects.
aria-modalbooleanaria-modal .
accessibilityIgnoresInvertColorsbooleaniOS: keep the view's colours when the Invert Colors setting is on; images want this.
accessibilityLanguagestringiOS: the language VoiceOver reads the label in, as a BCP 47 tag.
accessibilityLargeContentTitlestringiOS: the title shown by the Large Content Viewer on a long press with large text on.
accessibilityShowsLargeContentViewerbooleaniOS: opt this view into the Large Content Viewer.
accessibilityRespondsToUserInteractionbooleaniOS: tell VoiceOver the view responds to a tap even without a role that implies it.
nativeIDstring A handle native code can find the view by; also what :id selectors match.
idstringid : the web spelling of nativeID .
testIDstringA handle for end-to-end test tooling.
hitSlopInsets | numberExtend the touchable area beyond the view's bounds, without moving anything visible.
pointerEventsPointerEventsWhether this view, its children, or neither can be the target of a touch.
collapsablebooleanSet to false to keep a layout-only view alive; Fabric otherwise removes it from the tree.
collapsableChildrenbooleanSet to false to keep this view's layout-only children from being flattened.
removeClippedSubviewsbooleanDetach children that are outside the visible bounds. A scroll view optimisation.
needsOffscreenAlphaCompositingbooleanComposite the view offscreen so a translucent view with children blends correctly.
focusableboolean Android: whether the view takes keyboard or TV focus. RN's tabIndex is this.
shouldRasterizeIOSbooleaniOS: render the view to a bitmap once and reuse it; for a static view that animates.
renderToHardwareTextureAndroidboolean Android: cache the view in a hardware texture; the same trade as shouldRasterizeIOS .
nativeBackgroundAndroidAndroidDrawableAndroid: a ripple or theme drawable painted behind the view's content.
nativeForegroundAndroidAndroidDrawableAndroid: a ripple or theme drawable painted over the view's content.
Methods
settleProps(): voidWrite what the inputs say, for an element whose view has not been checked by the time the host commits it. Nothing for one that has.
Events
Most element events are not Angular outputs. They are bound like DOM events,
(name)="handler($event)", and routed by the renderer to the matching Fabric event name -
(layout) to topLayout, (touchStart) to topTouchStart. Binding an event is what tells
native to start sending it; an @Output() would opt every instance into layout and touch events
whether or not anything was listening. Payload types - LayoutEvent, TouchEvent, ScrollEvent
and the rest - live in @ng-native/components, typed by what native actually sends, so a
handler can be written against a real interface instead of a cast.
A directive built on top of the renderer's own events can still expose a real Angular output where
that is a better fit: Pressable's press, pressIn, pressOut and longPress are output()s,
resolved from the raw touch-responder negotiation rather than passed through unchanged. Use
(press) the way any other output is used; it is the renderer events underneath it, (layout) and
the rest, that are the exception to Angular's usual output binding, not the other way round.
Events bubble from the view they happened on to the root, as React Native's do, except the ones
React Native delivers to the target alone (layout, scroll and the other scroll events, load,
error). Every handler receives a NativeSyntheticEvent, with the payload on nativeEvent and
React Native's stopPropagation() and isPropagationStopped(). Calling stopPropagation() ends
the bubble after the current view; other handlers on that same view still run:
<view (touchEnd)="dismiss()">
<view (touchEnd)="$event.stopPropagation(); keep()"></view>
</view>An error thrown by anything in the dispatch that is not an Angular listener - a responder handler,
a listener registered on the Engine directly - is caught and handed to the app's ErrorHandler
rather than thrown back into the native code that delivered the event.
Where each element lives
The layout page covers <view> and Yoga's flexbox defaults, and
safe area covers keeping content clear of the notch. The text page covers <text>, why nothing renders without
one, and fonts. The input page covers <text-input>, keyboards and
the props Signal Forms binds to. The pressable page covers
<pressable> and <touchable-opacity>, and the responder negotiation behind press events; the
gestures page covers react-native-gesture-handler. The
scroll view page covers <scroll-view> and pull-to-refresh,
and the lists page covers <virtual-list> and <section-list>. The
keyboard-avoiding view page covers moving content
clear of the on-screen keyboard. The image page covers <image> and
<image-background>; the activity indicator and
switch pages cover those elements on their own; the
modal page covers presenting content over everything else. The
animation page covers plain CSS transitions, AnimatedStyle and
Reanimated worklets.
Every page
Layout - layout, safe area, scroll view, keyboard-avoiding view, lists
Content - text, image, activity indicator