Vistas nativas de verdad. Sin WebView por ninguna parte.
Escribe Angular. Obtienes un UIView, un android.view.View, un NSView o una
vista de SwiftUI — el control de verdad, del sistema de verdad, en ocho
plataformas.
$npx @angular/cli@latest new mi-app$cd mi-app && an init
25 primitivas · 8 plataformas · un núcleo en Rust
Todo el argumento
Una plantilla. Lo que esa plataforma traiga de verdad.
Aquí no se dibuja nada para que se parezca a un control. La plantilla no cambia de una plataforma a otra: lo que cambia es la clase que monta el framework, y donde una plataforma no tiene equivalente no se monta nada y el host dice por qué.
<an-view[style.gap]="'16'">
<an-text[fontSize]="28">Avisos</an-text>
<an-switch
[on]="avisos()"
(onChange)="avisos.set($event)"/>
</an-view>
an-switch se convierte en
UISwitch
El interruptor del propio sistema: su animación, su háptico, su rasgo de accesibilidad, y el aspecto que tenga en la siguiente versión de iOS.
MaterialSwitch
Material 3, resuelto sin Gradle. Sigue el tema del dispositivo, incluido el color dinámico que el usuario haya sacado de su fondo de pantalla.
NSSwitch
AppKit, en una ventana que se redimensiona — con un puntero que tiene forma y un estado de hover, dos cosas que un dedo no tiene.
Toggle
El único host que no es una jerarquía de vistas: el árbol se replica en un modelo que SwiftUI repinta.
UISwitch
El mismo host que el móvil, en una escena con ventana. Una ventana en el espacio no es una pantalla, pero sigue siendo UIKit.
MaterialSwitch
El host del móvil en una pantalla redonda, donde el área segura es por donde llega el margen del bisel.
no se monta nada
UISwitch no está en el SDK de tvOS: una tele se maneja con un mando. El layout deja el hueco que había medido y el host lo dice una vez, en el log.
Controles de verdad, no imitaciones
Aquí no se dibuja nada para que se parezca a un control. El interruptor de tu plantilla es el del sistema, así que se ve y se comporta como ese control se comporte en esa versión del sistema, y envejece con la plataforma en vez de con este repositorio.
iOS · iPadOSUISwitch
AndroidMaterialSwitch
macOSNSSwitch
watchOSToggle
visionOSUISwitch
tvOSno está en el SDK
El layout no es de la plataforma
UIKit, AppKit y Android colocan de formas distintas, y SwiftUI directamente no te deja colocar — así que el layout se va de la plataforma entera. Flexbox corre una vez, en un núcleo de Rust sobre taffy, y a cada host se le entregan frames absolutos en puntos lógicos. La misma plantilla se coloca igual en un móvil, en una tele y en un reloj.
Angular tal cual es
Señales, @if, @for, el router con parámetros, plantillas AOT, inyección de dependencias. Sin zonas, y no de forma opcional: sin zone.js no hay timers ni XHR que parchear dentro del motor, que es la mayor parte de lo que hace doloroso esto en otros sitios. Sin dialecto, sin subconjunto.
Un hueco nunca es silencioso
Una prop que ningún host lee, un estilo que nadie reconoce, un evento que una plataforma no puede entregar, un plugin al que le falta una plataforma: cada uno avisa, o detiene la compilación. Una primitiva que no está soportada en algún sitio tiene que decirlo por escrito, y hay scripts que lo exigen.
[angular-native] (pinch) does not arrive on watchOS:
MagnifyGesture is @available(watchOS, unavailable),
and two fingers do not fit on a 40 mm screen
Grabado en un simulador, no maquetado
Dos apps de examples/, funcionando.
Las dos son componentes de Angular normales —señales, @for, @if— y todos los controles que llevan son los de la plataforma. Las grabaciones son el simulador de iOS, manejado a mano: el campo de búsqueda es un UISearchBar, el selector de talla un UISegmentedControl, la cantidad un UIStepper y las estrellas son SF Symbols.
Una galería que recoloca
Dos columnas repartidas por altura acumulada, un campo de búsqueda del sistema, una tira de categorías y tirar para recargar. En el motor de layout no hay grid y no hace falta: una cascada son dos columnas flex, resueltas una vez en Rust.
El carrusel es lo único aquí que no es un control del sistema, porque ninguna plataforma trae uno — así que es un gesto de arrastre moviendo una transformación, y al soltar el resto lo termina la plataforma en su propio hilo de dibujo. El stepper y el interruptor de al lado son de UIKit.
El mismo bundle en todas. Lo que cambia no es el código: es qué controles trae esa plataforma, y cada hueco está contado con su motivo.
iOS · iPadOS
Pinta conUIKit
Las 25 primitivas
Android
Pinta conandroid.view + Material 3
Las 25 primitivas
macOS
Pinta conAppKit
Las 25 primitivas
tvOS
Pinta conUIKit + motor de foco
20 de 25 — una tele no tiene interruptor ni deslizador
visionOS
Pinta conUIKit en una escena con ventana
Las 25 primitivas
watchOS
Pinta conSwiftUI
17 de 25
Wear OS
Pinta conandroid.view
18 de 25
HarmonyOS · Windows
Pinta con—
Sin empezar
En un minuto
Cuatro comandos sobre un proyecto que ya tenías
Un proyecto de la CLI de Angular, sin modificar, corriendo sobre vistas nativas. No se mueve nada a este repositorio y ng build sigue funcionando igual.
an init
Dependencias, tsconfig y punto de entrada. No toca src/main.ts ni angular.json.
an add ios
Escribe ios/Info.plist, y a partir de ahí es tuyo.
an ios
Compila, monta el .app sin Xcode y lo lanza en el simulador.
Ventana de terminal
npx@angular/cli@latestnewmi-app&&cdmi-app
aninit
anaddios
anios
Escribe Angular. Publica nativo.
Un proyecto de ng new corriente, cuatro comandos, y está corriendo sobre vistas de UIKit y de Material de verdad.