-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
56 lines (56 loc) · 39.3 KB
/
Copy pathindex.html
File metadata and controls
56 lines (56 loc) · 39.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<!DOCTYPE html><html lang="en" dir="ltr" data-theme="dark" data-has-hero class="astro-g5ptsecz"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><title>angular-native | angular-native</title><link rel="canonical" href="https://angular-native.github.io/"/><link rel="alternate" hreflang="en" href="https://angular-native.github.io/"/><link rel="alternate" hreflang="es" href="https://angular-native.github.io/es/"/><link rel="alternate" hreflang="x-default" href="https://angular-native.github.io/"/><link rel="sitemap" href="/sitemap-index.xml"/><link rel="shortcut icon" href="/favicon.svg" type="image/svg+xml"/><meta name="generator" content="Astro v7.3.1"/><meta name="generator" content="Starlight v0.42.0"/><meta property="og:title" content="angular-native"/><meta property="og:type" content="article"/><meta property="og:url" content="https://angular-native.github.io/"/><meta property="og:locale" content="en"/><meta property="og:description" content="Angular apps that render real native views on eight platforms. No WebView anywhere."/><meta property="og:site_name" content="angular-native"/><meta name="twitter:card" content="summary_large_image"/><meta name="description" content="Angular apps that render real native views on eight platforms. No WebView anywhere."/><meta name="theme-color" content="#12151a" media="(prefers-color-scheme: dark)"/><meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)"/><script>
window.StarlightThemeProvider = (() => {
const storedTheme =
typeof localStorage !== 'undefined' && localStorage.getItem('starlight-theme');
const theme =
storedTheme ||
(window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark');
document.documentElement.dataset.theme = theme === 'light' ? 'light' : 'dark';
return {
updatePickers(theme = storedTheme || 'auto') {
document.querySelectorAll('starlight-theme-select').forEach((picker) => {
const select = picker.querySelector('select');
if (select) select.value = theme;
/** @type {HTMLTemplateElement | null} */
const tmpl = document.querySelector(`#theme-icons`);
const newIcon = tmpl && tmpl.content.querySelector('.' + theme);
if (newIcon) {
const oldIcon = picker.querySelector('svg.label-icon');
if (oldIcon) {
oldIcon.replaceChildren(...newIcon.cloneNode(true).childNodes);
}
}
});
},
};
})();
</script><template id="theme-icons"><svg aria-hidden="true" class="light astro-hkc32dio" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M5 12a1 1 0 0 0-1-1H3a1 1 0 0 0 0 2h1a1 1 0 0 0 1-1Zm.64 5-.71.71a1 1 0 0 0 0 1.41 1 1 0 0 0 1.41 0l.71-.71A1 1 0 0 0 5.64 17ZM12 5a1 1 0 0 0 1-1V3a1 1 0 0 0-2 0v1a1 1 0 0 0 1 1Zm5.66 2.34a1 1 0 0 0 .7-.29l.71-.71a1 1 0 1 0-1.41-1.41l-.66.71a1 1 0 0 0 0 1.41 1 1 0 0 0 .66.29Zm-12-.29a1 1 0 0 0 1.41 0 1 1 0 0 0 0-1.41l-.71-.71a1.004 1.004 0 1 0-1.43 1.41l.73.71ZM21 11h-1a1 1 0 0 0 0 2h1a1 1 0 0 0 0-2Zm-2.64 6A1 1 0 0 0 17 18.36l.71.71a1 1 0 0 0 1.41 0 1 1 0 0 0 0-1.41l-.76-.66ZM12 6.5a5.5 5.5 0 1 0 5.5 5.5A5.51 5.51 0 0 0 12 6.5Zm0 9a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7Zm0 3.5a1 1 0 0 0-1 1v1a1 1 0 0 0 2 0v-1a1 1 0 0 0-1-1Z"/></svg><svg aria-hidden="true" class="dark astro-hkc32dio" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21.64 13a1 1 0 0 0-1.05-.14 8.049 8.049 0 0 1-3.37.73 8.15 8.15 0 0 1-8.14-8.1 8.59 8.59 0 0 1 .25-2A1 1 0 0 0 8 2.36a10.14 10.14 0 1 0 14 11.69 1 1 0 0 0-.36-1.05Zm-9.5 6.69A8.14 8.14 0 0 1 7.08 5.22v.27a10.15 10.15 0 0 0 10.14 10.14 9.784 9.784 0 0 0 2.1-.22 8.11 8.11 0 0 1-7.18 4.32v-.04Z"/></svg><svg aria-hidden="true" class="auto astro-hkc32dio" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21 14h-1V7a3 3 0 0 0-3-3H7a3 3 0 0 0-3 3v7H3a1 1 0 0 0-1 1v2a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-2a1 1 0 0 0-1-1ZM6 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v7H6V7Zm14 10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-1h16v1Z"/></svg></template><link rel="stylesheet" href="/_astro/print.ehPL0gv-.css" media="print"><link rel="stylesheet" href="/_astro/common.B2GuNxy_.css"><style>@layer starlight.components{.card-grid:where(.astro-7qmvx3iy){grid-template-columns:100%;gap:1rem;display:grid}.card-grid:where(.astro-7qmvx3iy)>*{margin-top:0!important}@media (width>=50rem){.card-grid:where(.astro-7qmvx3iy){grid-template-columns:1fr 1fr;gap:1.5rem}.stagger:where(.astro-7qmvx3iy){--stagger-height:5rem;padding-bottom:var(--stagger-height)}.stagger:where(.astro-7qmvx3iy)>:nth-child(2n){transform:translateY(var(--stagger-height))}}starlight-tabs:where(.astro-scn3uvmv){display:block}.tablist-wrapper:where(.astro-scn3uvmv){overflow-x:auto}:where(.astro-scn3uvmv)[role=tablist]{border-bottom:2px solid var(--sl-color-gray-5);padding:0;list-style:none;display:flex}.tab:where(.astro-scn3uvmv){display:flex}.tab:where(.astro-scn3uvmv)>:where(.astro-scn3uvmv)[role=tab]{--sl-tab-color-border:var(--sl-color-gray-5);line-height:var(--sl-line-height-headings);box-shadow:0 2px 0 var(--sl-tab-color-border);color:var(--sl-color-gray-3);outline-offset:var(--sl-outline-offset-inside);overflow-wrap:initial;align-items:center;gap:.5rem;padding:.275rem 1.25rem;text-decoration:none;display:flex}.tab:where(.astro-scn3uvmv) :where(.astro-scn3uvmv)[role=tab][aria-selected=true]{--sl-tab-color-border:var(--sl-color-text-accent);color:var(--sl-color-white);font-weight:600}.tablist-wrapper:where(.astro-scn3uvmv)~[role=tabpanel]{margin-top:1rem}.sl-link-card:where(.astro-zaaezwya){border:1px solid var(--sl-color-gray-5);box-shadow:var(--sl-shadow-sm);border-radius:.5rem;grid-template-columns:1fr auto;gap:.5rem;padding:1rem;display:grid;position:relative}a:where(.astro-zaaezwya){line-height:var(--sl-line-height-headings);text-decoration:none}a:where(.astro-zaaezwya):before{content:"";position:absolute;inset:0}.stack:where(.astro-zaaezwya){flex-direction:column;gap:.5rem}.title:where(.astro-zaaezwya){color:var(--sl-color-white);font-weight:600;font-size:var(--sl-text-lg)}.description:where(.astro-zaaezwya){color:var(--sl-color-gray-3);line-height:1.5}.icon:where(.astro-zaaezwya){color:var(--sl-color-gray-3)}.sl-link-card:where(.astro-zaaezwya):hover{background:var(--sl-color-gray-7,var(--sl-color-gray-6));border-color:var(--sl-color-gray-2)}.sl-link-card:where(.astro-zaaezwya):hover .icon:where(.astro-zaaezwya){color:var(--sl-color-white)}.sl-steps{--bullet-size:calc(var(--sl-line-height) * 1rem);--bullet-margin:.375rem;counter-reset:steps-counter var(--sl-steps-start,0);padding-inline-start:0;list-style:none}.sl-steps>li{counter-increment:steps-counter;padding-inline-start:calc(var(--bullet-size) + 1rem);min-height:calc(var(--bullet-size) + var(--bullet-margin));padding-bottom:1px;position:relative}.sl-steps>li+li{margin-top:0}.sl-steps>li:before{content:counter(steps-counter);top:0;width:var(--bullet-size);height:var(--bullet-size);line-height:var(--bullet-size);font-size:var(--sl-text-xs);text-align:center;color:var(--sl-color-white);background-color:var(--sl-color-gray-6);box-shadow:inset 0 0 0 1px var(--sl-color-gray-5);border-radius:99rem;font-weight:600;position:absolute;inset-inline-start:0}.sl-steps>li:after{--guide-width:1px;content:"";top:calc(var(--bullet-size) + var(--bullet-margin));bottom:var(--bullet-margin);width:var(--guide-width);background-color:var(--sl-color-hairline-light);position:absolute;inset-inline-start:calc((var(--bullet-size) - var(--guide-width)) / 2)}}@layer starlight.content{.sl-steps>li>:first-child{--lh:calc(1em * var(--sl-line-height));--shift-y:calc(.5 * (var(--bullet-size) - var(--lh)));transform:translateY(var(--shift-y));margin-bottom:var(--shift-y)}.sl-steps>li>:first-child:where(h1,h2,h3,h4,h5,h6){--lh:calc(1em * var(--sl-line-height-headings))}@supports (--prop:1lh){.sl-steps>li>:first-child{--lh:1lh}}}
@layer starlight.components{svg:where(.astro-hkc32dio){color:var(--sl-icon-color);font-size:var(--sl-icon-size,1em);width:1em;height:1em}}
@layer starlight.components{.sl-link-button:where(.astro-dcqstdaq){font-size:var(--sl-text-sm);outline-offset:.25rem;border:1px solid #0000;border-radius:999rem;align-items:center;gap:.5em;padding:.4375rem 1.125rem;line-height:1.1875;text-decoration:none;display:inline-flex}.sl-link-button:where(.astro-dcqstdaq).primary{background:var(--sl-color-text-accent);border-color:var(--sl-color-text-accent);color:var(--sl-color-black)}.sl-link-button:where(.astro-dcqstdaq).primary:hover{color:var(--sl-color-black)}.sl-link-button:where(.astro-dcqstdaq).secondary{border-color:inherit;color:var(--sl-color-white)}.sl-link-button:where(.astro-dcqstdaq).minimal{color:var(--sl-color-white);padding-inline:0}.sl-link-button:where(.astro-dcqstdaq) svg{flex-shrink:0}@media (width>=50rem){.sl-link-button:where(.astro-dcqstdaq){font-size:var(--sl-text-base);padding:.9375rem 1.25rem}}.sl-markdown-content .sl-link-button:where(.astro-dcqstdaq){margin-inline-end:1rem}.sl-markdown-content .sl-link-button:where(.astro-dcqstdaq):not(:where(p *)){margin-block:1rem}}
</style><script type="module" src="/_astro/page.Dwipeu-R.js"></script></head><body class="astro-g5ptsecz"><a class="sl-skip-link astro-qb7clj6f" href="#_top">Skip to content</a><div class="page sl-flex astro-yntsjkba"><header class="header astro-yntsjkba"><div class="header astro-by6fddyj"><div class="title-wrapper sl-flex astro-by6fddyj"><a href="/" class="site-title sl-flex astro-6rvad3va"><img class="light:sl-hidden print:hidden astro-6rvad3va" alt src="/_astro/logo-dark.DW_oTXuh.svg" width="38" height="24"><img class="dark:sl-hidden print:block astro-6rvad3va" alt src="/_astro/logo-light.B5c7Bpuj.svg" width="38" height="24"><span class="astro-6rvad3va" translate="no">angular-native</span></a></div><div class="sl-flex print:hidden astro-by6fddyj"><site-search class="astro-by6fddyj astro-b5kgnn7o" data-translations="{"placeholder":"Search"}"><button data-open-modal disabled aria-label="Search" aria-keyshortcuts="Control+K" class="astro-b5kgnn7o"><svg aria-hidden="true" class="astro-b5kgnn7o astro-hkc32dio" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21.71 20.29 18 16.61A9 9 0 1 0 16.61 18l3.68 3.68a.999.999 0 0 0 1.42 0 1 1 0 0 0 0-1.39ZM11 18a7 7 0 1 1 0-14 7 7 0 0 1 0 14Z"/></svg><span class="sl-hidden md:sl-block astro-b5kgnn7o" aria-hidden="true">Search</span><kbd class="sl-hidden md:sl-flex astro-b5kgnn7o" style="display: none;"><kbd class="astro-b5kgnn7o">Ctrl</kbd><kbd class="astro-b5kgnn7o">K</kbd></kbd></button><dialog style="padding:0" aria-label="Search" class="astro-b5kgnn7o"><div class="dialog-frame sl-flex astro-b5kgnn7o"><button data-close-modal class="sl-flex md:sl-hidden astro-b5kgnn7o">Cancel</button><div class="search-container astro-b5kgnn7o"><div id="starlight__search" class="astro-b5kgnn7o"></div></div></div></dialog></site-search><script>
(() => {
const openBtn = document.querySelector('button[data-open-modal]');
const shortcut = openBtn?.querySelector('kbd');
if (!openBtn || !(shortcut instanceof HTMLElement)) return;
const platformKey = shortcut.querySelector('kbd');
if (platformKey && /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)) {
platformKey.textContent = '⌘';
openBtn.setAttribute('aria-keyshortcuts', 'Meta+K');
}
shortcut.style.display = '';
})();
</script><script type="module" src="/_astro/Search.astro_astro_type_script_index_0_lang.B-Vh4ymV.js"></script></div><div class="sl-hidden md:sl-flex print:hidden right-group astro-by6fddyj"><div class="sl-flex social-icons astro-by6fddyj"><a href="https://github.com/angular-native/angular-native" rel="me" class="sl-flex astro-n2mnl6yq"><span class="sr-only astro-n2mnl6yq">GitHub</span><svg aria-hidden="true" class="astro-n2mnl6yq astro-hkc32dio" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M12 .3a12 12 0 0 0-3.8 23.38c.6.12.83-.26.83-.57L9 21.07c-3.34.72-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.08-.74.09-.73.09-.73 1.2.09 1.83 1.24 1.83 1.24 1.08 1.83 2.81 1.3 3.5 1 .1-.78.42-1.31.76-1.61-2.67-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.14-.3-.54-1.52.1-3.18 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0c2.28-1.55 3.29-1.23 3.29-1.23.64 1.66.24 2.88.12 3.18a4.65 4.65 0 0 1 1.23 3.22c0 4.61-2.8 5.63-5.48 5.92.42.36.81 1.1.81 2.22l-.01 3.29c0 .31.2.69.82.57A12 12 0 0 0 12 .3Z"/></svg></a></div><starlight-theme-select><label style="--sl-select-width: 6.25em" class="astro-2z5xp7gb"><span class="sr-only astro-2z5xp7gb">Select theme</span><svg aria-hidden="true" class="icon label-icon astro-2z5xp7gb astro-hkc32dio" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21 14h-1V7a3 3 0 0 0-3-3H7a3 3 0 0 0-3 3v7H3a1 1 0 0 0-1 1v2a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-2a1 1 0 0 0-1-1ZM6 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v7H6V7Zm14 10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-1h16v1Z"/></svg><select autocomplete="off" class="astro-2z5xp7gb"><option value="dark" class="astro-2z5xp7gb">Dark</option><option value="light" class="astro-2z5xp7gb">Light</option><option value="auto" selected class="astro-2z5xp7gb">Auto</option></select><svg aria-hidden="true" class="icon caret astro-2z5xp7gb astro-hkc32dio" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M17 9.17a1 1 0 0 0-1.41 0L12 12.71 8.46 9.17a1 1 0 1 0-1.41 1.42l4.24 4.24a1.002 1.002 0 0 0 1.42 0L17 10.59a1.002 1.002 0 0 0 0-1.42Z"/></svg></label></starlight-theme-select><script>
StarlightThemeProvider.updatePickers();
</script><script type="module">var e=`starlight-theme`,t=e=>e===`auto`||e===`dark`||e===`light`?e:`auto`,n=()=>t(typeof localStorage<`u`&&localStorage.getItem(e));function r(t){typeof localStorage<`u`&&localStorage.setItem(e,t===`light`||t===`dark`?t:``)}var i=()=>matchMedia(`(prefers-color-scheme: light)`).matches?`light`:`dark`;function a(e){StarlightThemeProvider.updatePickers(e),document.documentElement.dataset.theme=e===`auto`?i():e,r(e)}matchMedia(`(prefers-color-scheme: light)`).addEventListener(`change`,()=>{n()===`auto`&&a(`auto`)});var o=class extends HTMLElement{constructor(){super(),a(n()),this.querySelector(`select`)?.addEventListener(`change`,e=>{e.currentTarget instanceof HTMLSelectElement&&a(t(e.currentTarget.value))})}};customElements.define(`starlight-theme-select`,o);</script><starlight-lang-select><label style="--sl-select-width: 7em" class="astro-2z5xp7gb"><span class="sr-only astro-2z5xp7gb">Select language</span><svg aria-hidden="true" class="icon label-icon astro-2z5xp7gb astro-hkc32dio" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path fill-rule="evenodd" d="M8.516 3a.94.94 0 0 0-.941.94v1.15H2.94a.94.94 0 1 0 0 1.882h7.362a7.422 7.422 0 0 1-1.787 3.958 7.42 7.42 0 0 1-1.422-2.425.94.94 0 1 0-1.774.627 9.303 9.303 0 0 0 1.785 3.043 7.422 7.422 0 0 1-4.164 1.278.94.94 0 1 0 0 1.881 9.303 9.303 0 0 0 5.575-1.855 9.303 9.303 0 0 0 4.11 1.74l-.763 1.525a.968.968 0 0 0-.016.034l-1.385 2.77a.94.94 0 1 0 1.683.841l1.133-2.267h5.806l1.134 2.267a.94.94 0 0 0 1.683-.841l-1.385-2.769a.95.95 0 0 0-.018-.036l-3.476-6.951a.94.94 0 0 0-1.682 0l-1.82 3.639a7.423 7.423 0 0 1-3.593-1.256 9.303 9.303 0 0 0 2.27-5.203h1.894a.94.94 0 0 0 0-1.881H9.456V3.94A.94.94 0 0 0 8.516 3Zm6.426 11.794a1.068 1.068 0 0 1-.02.039l-.703 1.407h3.924l-1.962-3.924-1.24 2.478Z" clip-rule="evenodd"/></svg><select autocomplete="off" class="astro-2z5xp7gb"><option value="/" class="astro-2z5xp7gb">English</option><option value="/es/" class="astro-2z5xp7gb">Español</option></select><svg aria-hidden="true" class="icon caret astro-2z5xp7gb astro-hkc32dio" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M17 9.17a1 1 0 0 0-1.41 0L12 12.71 8.46 9.17a1 1 0 1 0-1.41 1.42l4.24 4.24a1.002 1.002 0 0 0 1.42 0L17 10.59a1.002 1.002 0 0 0 0-1.42Z"/></svg></label></starlight-lang-select><script type="module">var e=class extends HTMLElement{constructor(){super();let e=this.querySelector(`select`);e&&(e.addEventListener(`change`,e=>{e.currentTarget instanceof HTMLSelectElement&&(window.location.pathname=e.currentTarget.value)}),window.addEventListener(`pageshow`,t=>{if(!t.persisted)return;let n=e.querySelector(`option[selected]`)?.index;n!==e.selectedIndex&&(e.selectedIndex=n??0)}))}};customElements.define(`starlight-lang-select`,e);</script></div></div></header><div class="main-frame astro-yntsjkba"><script type="module">var e=document.getElementById(`starlight__sidebar`),t=e?.querySelector(`sl-sidebar-state-persist`),n=`sl-sidebar-state`,r=()=>{let r=[],i=t?.dataset.hash||``;try{let e=sessionStorage.getItem(n),t=JSON.parse(e||`{}`);Array.isArray(t.open)&&t.hash===i&&(r=t.open)}catch{}return{hash:i,open:r,scroll:e?.scrollTop||0}},i=e=>{try{sessionStorage.setItem(n,JSON.stringify(e))}catch{}},a=()=>i(r()),o=(e,t)=>{let n=r();n.open[t]=e,i(n)};t?.addEventListener(`click`,e=>{if(!(e.target instanceof Element))return;let t=e.target.closest(`summary`)?.closest(`details`);if(!t)return;let n=t.querySelector(`sl-sidebar-restore`),r=parseInt(n?.dataset.index||``);isNaN(r)||o(!t.open,r)}),addEventListener(`visibilitychange`,()=>{document.visibilityState===`hidden`&&a()});</script><div class="lg:sl-flex astro-lrzkfocr"><div class="main-pane astro-lrzkfocr"><main data-pagefind-body class="astro-g5ptsecz" lang="en" dir="ltr"><div class="content-panel astro-a7po4psb"><div class="sl-container astro-a7po4psb"><div class="an-hero not-content"><div class="an-hero__grid" aria-hidden="true"><span class="an-glint" data-axis="x" style="--at: 4.5rem; --wait: 0s"></span><span class="an-glint" data-axis="x" style="--at: 13.5rem; --wait: 3.1s"></span><span class="an-glint" data-axis="y" style="--at: 22.5rem; --wait: 1.4s"></span><span class="an-glint" data-axis="y" style="--at: 36rem; --wait: 5.2s"></span></div><a class="an-announce" href="/extending/plugins-on-the-mac-and-the-watch/"><span class="an-announce__dot" aria-hidden="true"></span>Plugins now load on macOS and the Apple Watch<span class="an-announce__arrow" aria-hidden="true">→</span></a><h1 id="_top" data-page-title>Real native views.<br /><em>No WebView anywhere.</em>
</h1><div class="an-hero__tagline">Write Angular. Get a UIView, an android.view.View, an NSView or a SwiftUI
view — the real control, from the real system, on eight platforms.
</div><div class="an-hero__actions"><a class="sl-link-button not-content primary astro-dcqstdaq" href="/guide/quick-start/">Quick start<svg aria-hidden="true" class="astro-dcqstdaq astro-hkc32dio" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M17.92 11.62a1.001 1.001 0 0 0-.21-.33l-5-5a1.003 1.003 0 1 0-1.42 1.42l3.3 3.29H7a1 1 0 0 0 0 2h7.59l-3.3 3.29a1.002 1.002 0 0 0 .325 1.639 1 1 0 0 0 1.095-.219l5-5a1 1 0 0 0 .21-.33 1 1 0 0 0 0-.76Z"/></svg></a><a class="sl-link-button not-content minimal astro-dcqstdaq" href="/guide/how-it-works/">Why not a WebView<svg aria-hidden="true" class="astro-dcqstdaq astro-hkc32dio" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M21.17 2.06A13.1 13.1 0 0 0 19 1.87a12.94 12.94 0 0 0-7 2.05 12.94 12.94 0 0 0-7-2 13.1 13.1 0 0 0-2.17.19 1 1 0 0 0-.83 1v12a1 1 0 0 0 1.17 1 10.9 10.9 0 0 1 8.25 1.91l.12.07h.11a.91.91 0 0 0 .7 0h.11l.12-.07A10.899 10.899 0 0 1 20.83 16 1 1 0 0 0 22 15V3a1 1 0 0 0-.83-.94ZM11 15.35a12.87 12.87 0 0 0-6-1.48H4v-10c.333-.02.667-.02 1 0a10.86 10.86 0 0 1 6 1.8v9.68Zm9-1.44h-1a12.87 12.87 0 0 0-6 1.48V5.67a10.86 10.86 0 0 1 6-1.8c.333-.02.667-.02 1 0v10.04Zm1.17 4.15a13.098 13.098 0 0 0-2.17-.19 12.94 12.94 0 0 0-7 2.05 12.94 12.94 0 0 0-7-2.05c-.727.003-1.453.066-2.17.19A1 1 0 0 0 2 19.21a1 1 0 0 0 1.17.79 10.9 10.9 0 0 1 8.25 1.91 1 1 0 0 0 1.16 0A10.9 10.9 0 0 1 20.83 20a1 1 0 0 0 1.17-.79 1 1 0 0 0-.83-1.15Z"/></svg></a></div><div class="an-command"><span class="an-command__prompt" aria-hidden="true">$</span><code>npx @angular/cli@latest new my-app</code><span class="an-command__prompt" aria-hidden="true">$</span><code>cd my-app && an init</code><button class="an-command__copy" type="button" data-command="npx @angular/cli@latest new my-app
cd my-app && an init" data-copied="expressiveCode.copyButtonCopied" aria-label="expressiveCode.copyButtonTooltip" title="expressiveCode.copyButtonTooltip"><svg viewBox="0 0 16 16" width="15" height="15" aria-hidden="true"><path fill="none" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round" d="M5.5 5.5h7v7h-7zM10.5 5.5v-2h-7v7h2"></path></svg></button></div><p class="an-hero__eyebrow">25 primitives · 8 platforms · one Rust core</p></div><script type="module">document.querySelectorAll(`.an-command__copy`).forEach(e=>{e.addEventListener(`click`,async()=>{let t=e.dataset.command;if(!t)return;try{await navigator.clipboard.writeText(t)}catch{return}let n=e.getAttribute(`aria-label`);e.classList.add(`is-copied`),e.setAttribute(`aria-label`,e.dataset.copied||`Copied`),window.setTimeout(()=>{e.classList.remove(`is-copied`),n&&e.setAttribute(`aria-label`,n)},1600)})});</script><div class="sl-markdown-content"><section class="an-signature not-content" data-signature><header class="an-signature__head"><p class="an-signature__eyebrow">The whole argument</p><h2 class="an-signature__title">One template. Whatever that platform actually ships.</h2><p class="an-signature__body">Nothing here is drawn to resemble a control. The template does not change between one platform and the next — what changes is the class the framework mounts, and where a platform has no equivalent, nothing is mounted and the host says why.</p></header><div class="an-signature__panels"><div class="an-signature__code"><div class="expressive-code"><link rel="stylesheet" href="/_astro/ec.00uqy.css"><script type="module" src="/_astro/ec.0vx5m.js"></script><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="html"><code><div class="ec-line"><div class="code"><span style="--0:#8B8B8B;--1:#686868"><</span><span style="--0:#55987B;--1:#1E754F">an-view</span><span style="--0:#DBD7CAEE;--1:#393A34"> </span><span style="--0:#BD976A;--1:#876037">[style.gap]</span><span style="--0:#8B8B8B;--1:#686868">=</span><span style="--0:#C98A7DE4;--1:#96574AFD">"</span><span style="--0:#C98A7D;--1:#96574A">'16'</span><span style="--0:#C98A7DE4;--1:#96574AFD">"</span><span style="--0:#8B8B8B;--1:#686868">></span></div></div><div class="ec-line"><div class="code"><span style="--0:#8B8B8B;--1:#686868"><</span><span style="--0:#55987B;--1:#1E754F">an-text</span><span style="--0:#DBD7CAEE;--1:#393A34"> </span><span style="--0:#BD976A;--1:#876037">[fontSize]</span><span style="--0:#8B8B8B;--1:#686868">=</span><span style="--0:#C98A7DE4;--1:#96574AFD">"</span><span style="--0:#C98A7D;--1:#96574A">28</span><span style="--0:#C98A7DE4;--1:#96574AFD">"</span><span style="--0:#8B8B8B;--1:#686868">></span><span style="--0:#DBD7CAEE;--1:#393A34">Alerts</span><span style="--0:#8B8B8B;--1:#686868"></</span><span style="--0:#55987B;--1:#1E754F">an-text</span><span style="--0:#8B8B8B;--1:#686868">></span></div></div><div class="ec-line"><div class="code"><span style="--0:#8B8B8B;--1:#686868"><</span><span style="--0:#55987B;--1:#1E754F">an-switch</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#BD976A;--1:#876037">[on]</span><span style="--0:#8B8B8B;--1:#686868">=</span><span style="--0:#C98A7DE4;--1:#96574AFD">"</span><span style="--0:#C98A7D;--1:#96574A">alerts()</span><span style="--0:#C98A7DE4;--1:#96574AFD">"</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#BD976A;--1:#876037">(onChange)</span><span style="--0:#8B8B8B;--1:#686868">=</span><span style="--0:#C98A7DE4;--1:#96574AFD">"</span><span style="--0:#C98A7D;--1:#96574A">alerts.set($event)</span><span style="--0:#C98A7DE4;--1:#96574AFD">"</span><span style="--0:#DBD7CAEE;--1:#393A34"> </span><span style="--0:#8B8B8B;--1:#686868">/></span></div></div><div class="ec-line"><div class="code"><span style="--0:#8B8B8B;--1:#686868"></</span><span style="--0:#55987B;--1:#1E754F">an-view</span><span style="--0:#8B8B8B;--1:#686868">></span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button title="Copy to clipboard" data-copied="Copied!" data-code="<an-view [style.gap]="'16'"><an-text [fontSize]="28">Alerts</an-text><an-switch [on]="alerts()" (onChange)="alerts.set($event)" /></an-view>"><div></div></button></div></figure></div></div><div class="an-signature__answer"><div class="an-signature__chips" role="group" aria-label="an-switch becomes"><button type="button" class="an-signature__chip" data-answer="0" aria-pressed="true">iOS · iPadOS</button><button type="button" class="an-signature__chip" data-answer="1" aria-pressed="false">Android</button><button type="button" class="an-signature__chip" data-answer="2" aria-pressed="false">macOS</button><button type="button" class="an-signature__chip" data-answer="3" aria-pressed="false">watchOS</button><button type="button" class="an-signature__chip" data-answer="4" aria-pressed="false">visionOS</button><button type="button" class="an-signature__chip" data-answer="5" aria-pressed="false">Wear OS</button><button type="button" class="an-signature__chip" data-answer="6" aria-pressed="false">tvOS</button></div><p class="an-signature__label">an-switch becomes</p><div class="an-signature__card" data-answer="0"><code class="an-signature__becomes">UISwitch</code><p class="an-signature__note">The system's own switch: its animation, its haptic, its accessibility trait, and whatever it looks like in the next release of iOS.</p></div><div class="an-signature__card" data-answer="1"><code class="an-signature__becomes">MaterialSwitch</code><p class="an-signature__note">Material 3, resolved without Gradle. It follows the device theme, including the dynamic colour a user picked from their wallpaper.</p></div><div class="an-signature__card" data-answer="2"><code class="an-signature__becomes">NSSwitch</code><p class="an-signature__note">AppKit, in a window that resizes — with a pointer that has a shape and a hover state, both of which a finger does not have.</p></div><div class="an-signature__card" data-answer="3"><code class="an-signature__becomes">Toggle</code><p class="an-signature__note">The one host that is not a view hierarchy: the tree is mirrored into a model SwiftUI redraws.</p></div><div class="an-signature__card" data-answer="4"><code class="an-signature__becomes">UISwitch</code><p class="an-signature__note">The same host as the phone, in a windowed scene. A window in space is not a screen, but it is still UIKit.</p></div><div class="an-signature__card" data-answer="5"><code class="an-signature__becomes">MaterialSwitch</code><p class="an-signature__note">The phone's host on a round screen, where the safe area is how the bezel's margin arrives.</p></div><div class="an-signature__card" data-answer="6" data-absent="true"><code class="an-signature__becomes">nothing is mounted</code><p class="an-signature__note">UISwitch is not in the tvOS SDK — a television is driven with a remote. The layout keeps the gap it had measured and the host says so once, in the log.</p></div></div></div></section><script type="module">for(let e of document.querySelectorAll(`[data-signature]`)){let t=e.querySelectorAll(`.an-signature__chip`),n=e.querySelectorAll(`.an-signature__card`),r=e=>{t.forEach(t=>t.setAttribute(`aria-pressed`,String(t.dataset.answer===e))),n.forEach(t=>{t.hidden=t.dataset.answer!==e})};t.forEach(e=>e.addEventListener(`click`,()=>r(e.dataset.answer))),r(`0`)}</script>
<div class="an-bento not-content"><article class="an-bento__panel" data-wide="true"><h3 class="an-bento__title">Real controls, not lookalikes</h3><p class="an-bento__body">Nothing is drawn to resemble a control. The switch in your template <strong>is</strong> the system’s switch, so it looks and behaves however that control does in that version of the OS, and it ages with the platform instead of with this repository.</p><ul class="an-bento__rows"><li><span class="an-bento__label">iOS · iPadOS</span><code class="an-bento__value">UISwitch</code></li><li><span class="an-bento__label">Android</span><code class="an-bento__value">MaterialSwitch</code></li><li><span class="an-bento__label">macOS</span><code class="an-bento__value">NSSwitch</code></li><li><span class="an-bento__label">watchOS</span><code class="an-bento__value">Toggle</code></li><li><span class="an-bento__label">visionOS</span><code class="an-bento__value">UISwitch</code></li><li><span class="an-bento__label">tvOS</span><code class="an-bento__value">not in the SDK</code></li></ul></article><article class="an-bento__panel"><h3 class="an-bento__title">The layout is not the platform’s</h3><p class="an-bento__body">UIKit, AppKit and Android lay out differently, and SwiftUI does not let you lay out at all — so layout leaves the platform entirely. Flexbox runs once, in a Rust core over taffy, and every host is handed absolute frames in logical points. The same template lays out identically on a phone, a TV and a watch.</p></article><article class="an-bento__panel"><h3 class="an-bento__title">Angular as it is</h3><p class="an-bento__body">Signals, <code>@if</code>, <code>@for</code>, the router with parameters, AOT templates, dependency injection. Zoneless, and not optionally: without zone.js there are no timers or XHR to patch inside the engine, which is most of what makes this painful elsewhere. No dialect, no subset.</p></article><article class="an-bento__panel"><h3 class="an-bento__title">A gap is never silent</h3><p class="an-bento__body">A prop no host reads, a style nobody recognises, an event a platform cannot deliver, a plugin missing a platform: each one warns, or stops the build. A primitive that is unsupported somewhere has to say so in writing, and scripts enforce it.</p><pre class="an-bento__output"><code>[angular-native] (pinch) does not arrive on watchOS:
MagnifyGesture is @available(watchOS, unavailable),
and two fingers do not fit on a 40 mm screen</code></pre></article></div>
<section class="an-showcase not-content"><header class="an-showcase__head"><p class="an-showcase__eyebrow">Recorded on a simulator, not mocked up</p><h2 class="an-showcase__title">Two apps out of examples/, running.</h2><p class="an-showcase__body">Both of these are ordinary Angular components — signals, @for, @if — and every control in them is the platform's own. The recordings are the iOS simulator, driven by hand: the search field is a UISearchBar, the size picker is a UISegmentedControl, the quantity is a UIStepper, and the stars are SF Symbols.</p></header><div class="an-showcase__grid"><article class="an-demo"><div class="an-demo__phone"><div class="an-demo__screen"><video class="an-demo__video" poster="/img/shots/feed-poster.jpg" muted loop playsinline preload="none" data-autoplay tabindex="-1"><source src="/video/feed.mp4" type="video/mp4"></video></div></div><div class="an-demo__text"><h3 class="an-demo__title">A gallery that reflows</h3><p class="an-demo__body">Two columns dealt out by running height, a system search field, a category strip and pull-to-refresh. There is no grid in the layout engine and none is needed: a waterfall is two flex columns, resolved once in Rust.</p><ul class="an-demo__uses"><li><code>an-search-bar</code></li><li><code>an-segmented-control</code></li><li><code>an-image</code></li><li><code>an-scroll-view</code></li></ul><a class="an-demo__link" href="/guide/lists/">How long lists work <span aria-hidden="true">→</span></a></div></article><article class="an-demo"><div class="an-demo__phone"><div class="an-demo__screen"><video class="an-demo__video" poster="/img/shots/storefront-poster.jpg" muted loop playsinline preload="none" data-autoplay tabindex="-1"><source src="/video/storefront.mp4" type="video/mp4"></video></div></div><div class="an-demo__text"><h3 class="an-demo__title">A product page you can swipe</h3><p class="an-demo__body">The carousel is the one thing here that is not a system control, because no platform ships one — so it is a pan gesture moving a transform, and letting go hands the rest to the platform’s own drawing thread. The stepper and the switch beside it are UIKit’s.</p><ul class="an-demo__uses"><li><code>an-stepper</code></li><li><code>an-switch</code></li><li><code>an-segmented-control</code></li><li><code>(pan)</code></li><li><code>[animate]</code></li></ul><a class="an-demo__link" href="/guide/gestures-and-animation/">Gestures and animation <span aria-hidden="true">→</span></a></div></article></div></section><script type="module">var e=window.matchMedia(`(prefers-reduced-motion: reduce)`),t=document.querySelectorAll(`[data-autoplay]`);if(e.matches)t.forEach(e=>e.setAttribute(`controls`,``));else if(`IntersectionObserver`in window){let e=new IntersectionObserver(e=>{for(let t of e){let e=t.target;t.isIntersecting?e.play().catch(()=>e.setAttribute(`controls`,``)):e.pause()}},{threshold:.35});t.forEach(t=>e.observe(t))}else t.forEach(e=>{e.autoplay=!0,e.play().catch(()=>e.setAttribute(`controls`,``))});</script>
<header class="an-section not-content"><p class="an-section__eyebrow">Where it runs</p><h2 class="an-section__title">Eight platforms, one bundle</h2><p class="an-section__body">The same bundle on all of them. What differs is not the code — it is which controls that platform ships, and every gap is listed with the reason for it.</p></header>
<ul class="an-platforms not-content"><li class="an-platform" data-level="full"><p class="an-platform__name">iOS · iPadOS</p><p class="an-platform__renders"><span class="an-platform__label">Renders with</span><span class="an-platform__value">UIKit</span></p><p class="an-platform__state"><span class="an-platform__dot" aria-hidden="true"></span>All 25 primitives</p></li><li class="an-platform" data-level="full"><p class="an-platform__name">Android</p><p class="an-platform__renders"><span class="an-platform__label">Renders with</span><span class="an-platform__value">android.view + Material 3</span></p><p class="an-platform__state"><span class="an-platform__dot" aria-hidden="true"></span>All 25 primitives</p></li><li class="an-platform" data-level="full"><p class="an-platform__name">macOS</p><p class="an-platform__renders"><span class="an-platform__label">Renders with</span><span class="an-platform__value">AppKit</span></p><p class="an-platform__state"><span class="an-platform__dot" aria-hidden="true"></span>All 25 primitives</p></li><li class="an-platform" data-level="partial"><p class="an-platform__name">tvOS</p><p class="an-platform__renders"><span class="an-platform__label">Renders with</span><span class="an-platform__value">UIKit + focus engine</span></p><p class="an-platform__state"><span class="an-platform__dot" aria-hidden="true"></span>20 of 25 — a TV has no switch or slider</p></li><li class="an-platform" data-level="full"><p class="an-platform__name">visionOS</p><p class="an-platform__renders"><span class="an-platform__label">Renders with</span><span class="an-platform__value">UIKit in a windowed scene</span></p><p class="an-platform__state"><span class="an-platform__dot" aria-hidden="true"></span>All 25 primitives</p></li><li class="an-platform" data-level="partial"><p class="an-platform__name">watchOS</p><p class="an-platform__renders"><span class="an-platform__label">Renders with</span><span class="an-platform__value">SwiftUI</span></p><p class="an-platform__state"><span class="an-platform__dot" aria-hidden="true"></span>17 of 25</p></li><li class="an-platform" data-level="partial"><p class="an-platform__name">Wear OS</p><p class="an-platform__renders"><span class="an-platform__label">Renders with</span><span class="an-platform__value">android.view</span></p><p class="an-platform__state"><span class="an-platform__dot" aria-hidden="true"></span>18 of 25</p></li><li class="an-platform" data-level="none"><p class="an-platform__name">HarmonyOS · Windows</p><p class="an-platform__renders"><span class="an-platform__label">Renders with</span><span class="an-platform__value">—</span></p><p class="an-platform__state"><span class="an-platform__dot" aria-hidden="true"></span>Not started</p></li></ul>
<section class="an-commands not-content"><div class="an-commands__text"><p class="an-section__eyebrow">In one minute</p><h2 class="an-section__title">Four commands on a project you already had</h2><p class="an-section__body">An Angular CLI project, unmodified, running on native views. Nothing moves into this repository and <code>ng build</code> keeps working.</p><dl class="an-commands__notes"><div><dt><code>an init</code></dt><dd>Dependencies, tsconfig and an entry point. It touches neither src/main.ts nor angular.json.</dd></div><div><dt><code>an add ios</code></dt><dd>Writes ios/Info.plist, yours from then on.</dd></div><div><dt><code>an ios</code></dt><dd>Builds, assembles the .app without Xcode and launches it in the simulator.</dd></div></dl></div><div class="an-commands__code"><div class="expressive-code"><figure class="frame is-terminal not-content"><figcaption class="header"><span class="title"></span><span class="sr-only">Terminal window</span></figcaption><pre data-language="bash"><code><div class="ec-line"><div class="code"><span style="--0:#80A665;--1:#4B7231">npx</span><span style="--0:#DBD7CAEE;--1:#393A34"> </span><span style="--0:#C98A7D;--1:#96574A">@angular/cli@latest</span><span style="--0:#DBD7CAEE;--1:#393A34"> </span><span style="--0:#C98A7D;--1:#96574A">new</span><span style="--0:#DBD7CAEE;--1:#393A34"> </span><span style="--0:#C98A7D;--1:#96574A">my-app</span><span style="--0:#DBD7CAEE;--1:#393A34"> </span><span style="--0:#8B8B8B;--1:#686868">&&</span><span style="--0:#DBD7CAEE;--1:#393A34"> </span><span style="--0:#B8A965;--1:#786713">cd</span><span style="--0:#DBD7CAEE;--1:#393A34"> </span><span style="--0:#C98A7D;--1:#96574A">my-app</span></div></div><div class="ec-line"><div class="code"><span style="--0:#80A665;--1:#4B7231">an</span><span style="--0:#DBD7CAEE;--1:#393A34"> </span><span style="--0:#C98A7D;--1:#96574A">init</span></div></div><div class="ec-line"><div class="code"><span style="--0:#80A665;--1:#4B7231">an</span><span style="--0:#DBD7CAEE;--1:#393A34"> </span><span style="--0:#C98A7D;--1:#96574A">add</span><span style="--0:#DBD7CAEE;--1:#393A34"> </span><span style="--0:#C98A7D;--1:#96574A">ios</span></div></div><div class="ec-line"><div class="code"><span style="--0:#80A665;--1:#4B7231">an</span><span style="--0:#DBD7CAEE;--1:#393A34"> </span><span style="--0:#C98A7D;--1:#96574A">ios</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button title="Copy to clipboard" data-copied="Copied!" data-code="npx @angular/cli@latest new my-app && cd my-appan initan add iosan ios"><div></div></button></div></figure></div></div></section>
<section class="an-closing not-content"><h2 class="an-closing__title">Write Angular. <em>Ship native.</em></h2><p class="an-closing__body">An ordinary ng new project, four commands, and it is running on real UIKit and real Material views.</p><a class="sl-link-button not-content primary astro-dcqstdaq" href="/guide/quick-start/">Quick start<svg aria-hidden="true" class="astro-dcqstdaq astro-hkc32dio" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M17.92 11.62a1.001 1.001 0 0 0-.21-.33l-5-5a1.003 1.003 0 1 0-1.42 1.42l3.3 3.29H7a1 1 0 0 0 0 2h7.59l-3.3 3.29a1.002 1.002 0 0 0 .325 1.639 1 1 0 0 0 1.095-.219l5-5a1 1 0 0 0 .21-.33 1 1 0 0 0 0-.76Z"/></svg></a></section></div><footer class="sl-flex astro-ddtxxk7k"><div class="meta sl-flex astro-ddtxxk7k"></div><div class="pagination-links print:hidden astro-b5raizh3" dir="ltr"></div></footer></div></div></main></div></div></div></div></body></html>