1<h1 align="center">@expo/html-elements</h1> 2 3<img alt="Product: demo" src="https://dev-to-uploads.s3.amazonaws.com/i/xoc3yx7qfqf6e1w6mm2e.png" /> 4 5<p align="center"> 6 <!-- iOS --> 7 <img alt="Supports Expo iOS" longdesc="Supports Expo iOS" src="https://img.shields.io/badge/iOS-4630EB.svg?style=flat-square&logo=APPLE&labelColor=999999&logoColor=fff" /> 8 <!-- Android --> 9 <img alt="Supports Expo Android" longdesc="Supports Expo Android" src="https://img.shields.io/badge/Android-4630EB.svg?style=flat-square&logo=ANDROID&labelColor=A4C639&logoColor=fff" /> 10 <!-- Web --> 11 <img alt="Supports Expo Web" longdesc="Supports Expo Web" src="https://img.shields.io/badge/web-4630EB.svg?style=flat-square&logo=GOOGLE-CHROME&labelColor=4285F4&logoColor=fff" /> 12 <a aria-label="Circle CI" href="https://circleci.com/gh/expo/expo/tree/main"> 13 <img alt="Circle CI" src="https://flat.badgen.net/circleci/github/expo/expo?label=Circle%20CI&labelColor=555555&icon=circleci"> 14 </a> 15</p> 16 17Simple, light-weight, and well tested, universal semantic HTML elements as React components for iOS, Android, web, and desktop apps! 18 19We at Expo recommend using platform agnostic primitives like `View`, `Image`, and `Text` whenever possible but sometimes that's not easy. Some primitives like Tables, and Footers are native to web only and currently have no way of easily accessing. This package aims to solve that while still being an optimal UI package for iOS, and Android. 20 21### What you get 22 23- Using `@expo/html-elements` will optimize your website for SEO and accessibility. Meaning your websites are indexed more accurately and your native apps better accommodate physically impaired users. 24 - This package takes full advantage of [`react-native-web` a11y rules](https://github.com/necolas/react-native-web/blob/master/packages/docs/src/guides/accessibility.stories.mdx) whenever possible. 25 - For example, the `H1` component will render an `<h1 />` on web, a `UILabel` on iOS, and a `TextView` on Android. 26- Every component can accept styles from the `StyleSheet` API. 27- TypeScript works for iOS, Android, and web, no more having to create monkey patches to use `href` on a `Text` element. 28- Every component is tested render **tested universally** for iOS, Android, and Web using the package [`jest-expo-enzyme`](https://www.npmjs.com/package/jest-expo-enzyme). Each element is also **E2E tested** on iOS with Detox, and web with [`jest-expo-puppeteer`](https://www.npmjs.com/package/jest-expo-puppeteer). 29- This package is completely side-effect free! 30 31## Setup 32 33Install: 34 35```sh 36yarn add @expo/html-elements 37``` 38 39Import and use the package: 40 41```tsx 42import { H1 } from '@expo/html-elements'; 43``` 44 45# Components 46 47Here is a list of all the currently supported elements and the web feature they map to. Not all HTML elements are supported. There are some HTML elements that mostly overlap with some universal modules, you should always try to use the universal modules whenever possible. All supported components are a capitalized variation of the semantic HTML they implement/emulate. 48 49| HTML | `@expo/html-elements` | 50| ----------------------------------- | :-----------------------------: | 51| [`<a />`][html-a] | [`<A />`](#a) | 52| [`<article />`][html-article] | [`<Article />`](#article) | 53| [`<aside />`][html-aside] | [`<Aside />`](#aside) | 54| [`<b />`][html-b] | [`<B />`](#b) | 55| [`<blockquote />`][html-blockquote] | [`<BlockQuote />`](#blockquote) | 56| [`<br />`][html-br] | [`<BR />`](#br) | 57| [`<caption />`][html-caption] | [`<Caption />`](#caption) | 58| [`<code />`][html-code] | [`<Code />`](#code) | 59| [`<del />`][html-del] | [`<Del />`](#del) | 60| [`<em />`][html-em] | [`<EM />`](#em) | 61| [`<footer />`][html-footer] | [`<Footer />`](#footer) | 62| [`<h1 />`][html-h1] | [`<H1 />`](#h1) | 63| [`<h2 />`][html-h2] | [`<H2 />`](#h2) | 64| [`<h3 />`][html-h3] | [`<H3 />`](#h3) | 65| [`<h4 />`][html-h4] | [`<H4 />`](#h4) | 66| [`<h5 />`][html-h5] | [`<H5 />`](#h5) | 67| [`<h6 />`][html-h6] | [`<H6 />`](#h6) | 68| [`<header />`][html-header] | [`<Header />`](#header) | 69| [`<hr />`][html-hr] | [`<HR />`](#hr) | 70| [`<i />`][html-i] | [`<I />`](#i) | 71| [`<main />`][html-main] | [`<Main />`](#main) | 72| [`<mark />`][html-mark] | [`<Mark />`](#mark) | 73| [`<nav />`][html-nav] | [`<Nav />`](#nav) | 74| [`<p />`][html-p] | [`<P />`](#p) | 75| [`<pre />`][html-pre] | [`<Pre />`](#pre) | 76| [`<q />`][html-q] | [`<Q />`](#q) | 77| [`<s />`][html-s] | [`<S />`](#s) | 78| [`<section />`][html-section] | [`<Section />`](#section) | 79| [`<strong />`][html-strong] | [`<Strong />`](#strong) | 80| [`<table />`][html-table] | [`<Table />`](#table) | 81| [`<tbody />`][html-tbody] | [`<TBody />`](#tbody) | 82| [`<td />`][html-td] | [`<TD />`](#td) | 83| [`<tfoot />`][html-tfoot] | [`<TFoot />`](#tfoot) | 84| [`<th />`][html-th] | [`<TH />`](#th) | 85| [`<thead />`][html-thead] | [`<THead />`](#thead) | 86| [`<time />`][html-time] | [`<Time />`](#time) | 87| [`<tr />`][html-tr] | [`<TR />`](#tr) | 88| [`<ul />`][html-ul] | [`<UL />`](#ul) | 89| [`<li />`][html-li] | [`<LI />`](#li) | 90| [`<details />`][html-details] | ⏱ Pending | 91| [`<summary />`][html-summary] | ⏱ Pending | 92| [`<progress />`][html-progress] | ⏱ Pending | 93| [`<select />`][html-select] | ⏱ Pending | 94| [`<picture />`][html-picture] | ⏱ Pending | 95| [`<figure />`][html-figure] | ⏱ Pending | 96| [`<figcaption />`][html-figcaption] | ⏱ Pending | 97| [`<form />`][html-form] | ⏱ Pending | 98| [`<label />`][html-label] | ⏱ Pending | 99 100## External 101 102Other features not implemented in this package can be found in different parts of the Expo ecosystem. 103 104| HTML | Universal | Package | 105| ------------------------------- | :------------------: | :--------------------------------------------------------------------------------------------------------------------: | 106| `<audio />` | `Audio` | [`expo-av`][ex-audio] | 107| `<button />` | `<Button />` | `react-native` | 108| `<input type="text" />` | `<TextInput />` | `react-native` | 109| `<input type="file" />` | `ImagePicker` | [`expo-image-picker`][ex-ipick] | 110| `<input type="file" />` | `DocumentPicker` | [`expo-document-picker`][ex-dpick] | 111| `<canvas />` | `<GLView />` | [`expo-gl`][ex-gl] & [Expo Canvas][ex-canvas] | 112| `<iframe />` | `<WebView />` | [`<WebView />`][ex-webview]. `@react-native-community/web-view` is not maintained by Expo and doesn't have web support | 113| [`<link />`][html-link] | None | Eject the `index.html` with `npx expo customize` and link resources directly with `<link />` | 114| [`<noscript />`][html-noscript] | None | Eject the `index.html` with `npx expo customize` and use `<noscript />` directly as HTML | 115| `<div />` | `<View />` | `react-native` | 116| `<img />` | `<Image />` | `react-native` | 117| `<span />` | `<Text />` | `react-native` | 118| `<video />` | `<Video />` | [`expo-av`][ex-vid] | 119| `style="backdrop-filter"` | `<BlurView />` | [`expo-blur`][ex-blur] | 120| `style="linear-gradient()"` | `<LinearGradient />` | [`expo-linear-gradient`][ex-gradient] | 121 122[ex-gradient]: https://docs.expo.dev/versions/latest/sdk/linear-gradient/ 123[ex-webview]: https://docs.expo.dev/versions/latest/sdk/webview/ 124[ex-audio]: https://docs.expo.dev/versions/latest/sdk/audio 125[ex-gl]: https://docs.expo.dev/versions/latest/sdk/gl-view 126[ex-canvas]: https://github.com/expo/expo-2d-context 127[html-noscript]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/noscript 128[html-link]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link 129[ex-blur]: https://docs.expo.dev/versions/latest/sdk/blur-view/ 130[ex-vid]: https://docs.expo.dev/versions/latest/sdk/video/ 131[ex-ipick]: https://docs.expo.dev/versions/latest/sdk/imagepicker/ 132[ex-dpick]: https://docs.expo.dev/versions/latest/sdk/document-picker/ 133 134## Headings 135 136Header elements will use the expected [font size and margins from web](http://trac.webkit.org/browser/trunk/Source/WebCore/css/html.css) universally. You can see how the native CSS units (rem, and em) are transformed in [css/units](src/css/units.ts). 137 138```tsx 139import { H1, H2, H3, H4, H5, H6 } from '@expo/html-elements'; 140``` 141 142### `<H1/>` 143 144```tsx 145import { H1 } from '@expo/html-elements'; 146export default () => <H1>Example<H1/> 147``` 148 149| Platform | Output | 150| -------- | ------------------------------------------------------ | 151| Web | `<h1 aria-level="1" dir="auto" role="heading" />` | 152| Native | `<Text accessibilityRole="header" style={[Custom]} />` | 153 154### `<H2/>` 155 156```tsx 157import { H2 } from '@expo/html-elements'; 158export default () => <H2>Example<H2/> 159``` 160 161| Platform | Output | 162| -------- | ------------------------------------------------------ | 163| Web | `<h2 aria-level="2" dir="auto" role="heading" />` | 164| Native | `<Text accessibilityRole="header" style={[Custom]} />` | 165 166### `<H3/>` 167 168```tsx 169import { H3 } from '@expo/html-elements'; 170export default () => <H3>Example<H3/> 171``` 172 173| Platform | Output | 174| -------- | ------------------------------------------------------ | 175| Web | `<h3 aria-level="3" dir="auto" role="heading" />` | 176| Native | `<Text accessibilityRole="header" style={[Custom]} />` | 177 178### `<H4/>` 179 180```tsx 181import { H4 } from '@expo/html-elements'; 182export default () => <H4>Example<H4/> 183``` 184 185| Platform | Output | 186| -------- | ------------------------------------------------------ | 187| Web | `<h4 aria-level="4" dir="auto" role="heading" />` | 188| Native | `<Text accessibilityRole="header" style={[Custom]} />` | 189 190### `<H5/>` 191 192```tsx 193import { H5 } from '@expo/html-elements'; 194export default () => <H5>Example<H5/> 195``` 196 197| Platform | Output | 198| -------- | ------------------------------------------------------ | 199| Web | `<h5 aria-level="5" dir="auto" role="heading" />` | 200| Native | `<Text accessibilityRole="header" style={[Custom]} />` | 201 202### `<H6/>` 203 204```tsx 205import { H6 } from '@expo/html-elements'; 206export default () => <H6>Example<H6/> 207``` 208 209| Platform | Output | 210| -------- | ------------------------------------------------------ | 211| Web | `<h6 aria-level="6" dir="auto" role="heading" />` | 212| Native | `<Text accessibilityRole="header" style={[Custom]} />` | 213 214## Link 215 216### `<A/>` 217 218You can use the anchor element with href prop to open links. On native this will attempt to use the `Linking` API to open the `href`. 219 220- The CSS style is fully normalized to match `<Text />` 221- For pseudo-class effects like hover and focus states check out the package [`react-native-web-hooks`](https://www.npmjs.com/package/react-native-web-hooks) | [tutorial](https://blog.expo.dev/css-pseudo-class-effects-in-expo-for-web-56649f88eb6b) 222 223```tsx 224import { A } from '@expo/html-elements'; 225 226export default () => <A href="#" target="_blank" />; 227} 228``` 229 230| Platform | Output | 231| -------- | ------------------------------------------------------------------------------- | 232| Web | `<a data-focusable="{true}" dir="auto" href="#" role="link" target="_blank" />` | 233| Native | `<Text accessibilityRole="link" onPress={[Function]} />` | 234 235## Layout 236 237You can use layout elements like Header, Main, Footer, Section, Nav, etc. as a drop-in replacement for `View`s in your existing app. 238 239#### Default Layout style 240 241All layout HTML elements inherit the shared style of `<View />` to accommodate the [Yoga layout engine][yoga] which we use on native for iOS, and Android. 242 243- `display` is always `flex`. This is because [Yoga][yoga] only implements `display: flex`. 244- `flex-direction` is always `column` instead of `row`. 245 246#### Why use Layout elements 247 248Consider the following: in your app you have a basic element at the top which wraps the buttons and title. A screen reader doesn't understand that this is a header, and mostly neither does a web crawler. But if you replace the encasing view with a `<Header />` the following happens: 249 250- **iOS**: `UIView` uses [`UIAccessibilityTraitHeader`](https://developer.apple.com/documentation/uikit/uiaccessibilitytraitheader?language=objc). 251- **Android**: `View` will use the proper [`AccessibilityNodeInfoCompat.CollectionItemInfoCompat`](https://github.com/facebook/react-native/blob/7428271995adf21b2b31b188ed83b785ce1e9189/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java#L370-L372) | [docs](https://developer.android.com/reference/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.CollectionItemInfoCompat). 252- **web**: render an HTML 5 [`<header />`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/header) with the ARIA `role` set to [`"banner"`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Banner_role). 253 254Some elements like `Footer` and `Main` have no iOS, or Android enhancements, but they'll still improve web. Using the proper HTML 5 elements will make your layout compliant with the [HTML5 outline algorithm](https://html.spec.whatwg.org/multipage/sections.html#outlines). 255 256### `<Nav/>` 257 258```tsx 259import { Nav } from '@expo/html-elements'; 260 261export default () => <Nav />; 262``` 263 264| Platform | Output | 265| -------- | ------------------------------ | 266| Web | `<nav style="display:flex" />` | 267| Native | `<View />` | 268 269### `<Header/>` 270 271Renders a `<header />` on web with ARIA set to [`banner`][aria-banner] and a `View` with ARIA set to `header` on mobile. 272 273```tsx 274import { Header } from '@expo/html-elements'; 275 276export default () => <Header />; 277``` 278 279| Platform | Output | 280| -------- | ------------------------------------------------------------------------------------------------------------------- | 281| Web | [`<header role="banner" />`][html-header] | 282| Native | `<View />` | 283| iOS | `UIView` uses [`UIAccessibilityTraitHeader`][uiatheader]. | 284| Android | `View` will use the proper [`AccessibilityNodeInfoCompat.CollectionItemInfoCompat`][anicompat] [docs][anicompatdoc] | 285 286[uiatheader]: https://developer.apple.com/documentation/uikit/uiaccessibilitytraitheader?language=objc 287[anicompat]: https://github.com/facebook/react-native/blob/7428271995adf21b2b31b188ed83b785ce1e9189/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java#L370-L372 288[anicompatdoc]: https://developer.android.com/reference/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.CollectionItemInfoCompat 289 290### `<Main/>` 291 292Renders a `<main />` on web with ARIA `role` set to `main` and a `View` with no ARIA set on mobile. 293 294```tsx 295import { Main } from '@expo/html-elements'; 296 297export default () => ( 298 <Main> 299 <P>Some content in the main element</P> 300 </Main> 301 ); 302) 303``` 304 305| Platform | Output | 306| -------- | ------------------------------------------- | 307| Web | `<main role="main" style="display:flex" />` | 308| Native | `<View />` | 309 310### `<Section/>` 311 312Renders a `<section />` on web with ARIA set to `region` and a `View` with ARIA set to `summary` on mobile. 313 314```tsx 315import { Section } from '@expo/html-elements'; 316 317export default () => <Section />; 318``` 319 320| Platform | Output | 321| -------- | ------------------------------------------------ | 322| Web | `<section role="region" style="display:flex" />` | 323| Native | `<View accessibilityRole="summary" />` | 324 325### `<Article/>` 326 327Renders an `<article />` on web and a `View` everywhere else. 328 329```tsx 330import { Article } from '@expo/html-elements'; 331 332export default () => <Article />; 333``` 334 335| Platform | Output | 336| -------- | ---------------------------- | 337| Web | `<article role="article" />` | 338| Native | `<View />` | 339 340### `<Aside/>` 341 342```tsx 343import { Aside } from '@expo/html-elements'; 344 345export default () => <Aside />; 346``` 347 348| Platform | Output | 349| -------- | -------------------------------- | 350| Web | `<aside role="complementary" />` | 351| Native | `<View />` | 352 353### `<Footer/>` 354 355Renders an `<footer />` on web and a `View` everywhere else. 356 357```tsx 358import { Footer } from '@expo/html-elements'; 359 360export default () => <Footer />; 361``` 362 363| Platform | Output | 364| -------- | ------------------------------- | 365| Web | `<footer role="contentinfo" />` | 366| Native | `<View />` | 367 368## Text 369 370Text elements currently use `Text` universally rendering either a `div` or `span` to emulate Yoga style properly. 371 372- Style is modified to match web. 373- All font styles are reset (minus `Code`, and `Pre`). 374- All elements accept styles from `StyleSheet` API. 375 376```tsx 377import { P, B, S, I, BR, Code } from '@expo/html-elements'; 378 379export default () => ( 380 <> 381 <P> 382 Hello<B>World (in bold)</B> 383 </P> 384 <S>strike text</S> 385 <BR /> 386 <I>Italic</I> 387 <Code>const foo = true</Code> 388 </> 389); 390``` 391 392### `<P/>` 393 394Standard paragraph element. 395 396| Platform | Output | 397| --------- | ---------------------------------------------------------- | 398| Universal | `<Text style={{ fontSize: 14, marginVertical: '1em' }} />` | 399 400### `<B/>` 401 402Bold text text. 403 404| Platform | Output | 405| --------- | ----------------------------------------- | 406| Universal | `<Text style={{ fontWeight: 'bold' }} />` | 407 408### `<Strong/>` 409 410Alternate bold text. 411 412| Platform | Output | 413| --------- | ----------------------------------------- | 414| Universal | `<Text style={{ fontWeight: 'bold' }} />` | 415 416### `<S/>` 417 418Strike through text. 419 420| Platform | Output | 421| --------- | --------------------------------------------------------- | 422| Universal | `<Text style={{ textDecorationLine: 'line-through' }} />` | 423 424### `<Del/>` 425 426Alternate strike through text. 427 428| Platform | Output | 429| --------- | --------------------------------------------------------- | 430| Universal | `<Text style={{ textDecorationLine: 'line-through' }} />` | 431 432### `<I/>` 433 434Italic text. 435 436| Platform | Output | 437| --------- | ------------------------------------------ | 438| Universal | `<Text style={{ fontStyle: 'italic' }} />` | 439 440### `<EM/>` 441 442Alternate italic text. 443 444| Platform | Output | 445| --------- | ------------------------------------------ | 446| Universal | `<Text style={{ fontStyle: 'italic' }} />` | 447 448### `<Code/>` 449 450Inline code block with `fontFamily: 'Courier'` on iOS and Web, `fontFamily: 'monospace'` on Android. 451 452| Platform | Output | 453| --------- | --------------------------- | 454| Universal | `<Text style={[Custom]} />` | 455 456### `<Pre/>` 457 458Render a preformatted code block with `fontFamily: 'Courier'` on iOS and Web, `fontFamily: 'monospace'` on Android. 459 460```jsx 461<Pre>{` 462body { 463 color: red; 464} 465`}</Pre> 466 467// Or pass views 468 469<Pre> 470 <Code>{`const val = true`}</Code> 471</Pre> 472``` 473 474| Platform | Output | 475| --------- | ----------------------------------------- | 476| Universal | `<Text style={[Custom]} />` \| `<View />` | 477 478### `<Mark/>` 479 480Highlight text. 481 482| Platform | Output | 483| --------- | ---------------------------------------------------------------- | 484| Universal | `<Text style={{ backgroundColor: 'yellow', color: 'black' }} />` | 485 486### `<Q/>` 487 488Quoted text. 489 490| Platform | Output | 491| --------- | -------------------------------------------------- | 492| Universal | `<Text style={[Custom]}>"{props.children}"</Text>` | 493 494### `<BlockQuote/>` 495 496| Platform | Output | 497| --------- | --------------------------- | 498| Universal | `<View style={[Custom]} />` | 499 500### `<Time/>` 501 502- `dateTime` prop is supported on web and stripped on native. 503 504| Platform | Output | 505| --------- | --------------------------- | 506| Universal | `<Text style={[Custom]} />` | 507 508## Lists 509 510Lists can be used to create basic bulleted or numbered lists. You should try and use universal `FlatList` or `SectionList` components for long scrolling lists instead of these. 511 512### `<UL/>` 513 514Create an unordered (bulleted) list `<ul />` on web, and emulates the style with a `<View />` on native. 515 516- [x] Resets font styles everywhere. 517- [ ] Supports i18n by reversing format on iOS and Android 518- [ ] Supports custom bullets 519 520```tsx 521import { UL, LI } from '@expo/html-elements'; 522 523export default () => ( 524 <UL> 525 <LI>oranges</LI> 526 <LI>apples</LI> 527 <UL> 528 <LI>green</LI> 529 <LI>red</LI> 530 </UL> 531 </UL> 532); 533``` 534 535| Platform | Output | 536| -------- | --------------------------- | 537| Web | `<ul />` | 538| Native | `<View style={[Custom]} />` | 539 540### `<LI/>` 541 542Create a standard list item `<li />` on web and a native view on mobile which can render text or views inside it. 543 544| Platform | Output | 545| -------- | ---------------------------------------------------------- | 546| Web | `<li />` | 547| Native | `<Text style={[Custom]} />` \| `<View style={[Custom]} />` | 548 549## Rules 550 551### `<HR/>` 552 553Renders a `<View>` everywhere. Style is modified to match web. 554 555```tsx 556import { HR } from '@expo/html-elements'; 557 558export default () => <HR />; 559``` 560 561| Platform | Output | 562| -------- | --------------------------- | 563| Web | `<hr />` | 564| Native | `<View style={[Custom]} />` | 565 566### `<BR/>` 567 568Create a line break. 569 570| Platform | Output | 571| -------- | ---------------------------------------- | 572| Web | `<br />` | 573| Native | `<View style={{height: 8, width: 0}} />` | 574 575## Tables 576 577Create tables universally. 578 579- Each element renders to the expected type on web. 580- `padding` is removed from all table elements. 581- Text **can only** be rendered in `TH` and `TD` on mobile. 582- `colSpan` and `rowSpan` are currently web-only (PRs welcome). 583 584```tsx 585import { Table, THead, TH, TBody, TFoot, TR, TD, Caption } from '@expo/html-elements'; 586import { Text } from 'react-native'; 587 588export default () => ( 589 <Table> 590 <Caption>Caption</Caption> 591 <THead> 592 <TR> 593 <TH colSpan="2">The table header</TH> 594 </TR> 595 </THead> 596 <TBody> 597 <TR> 598 <TD>The table body</TD> 599 <TD>with two columns</TD> 600 </TR> 601 </TBody> 602 <TFoot> 603 <TR> 604 <TD> 605 <Text>This is the table footer</Text> 606 </TD> 607 </TR> 608 </TFoot> 609 </Table> 610); 611``` 612 613#### Table example output web 614 615```html 616<table> 617 <caption> 618 Caption 619 </caption> 620 <thead> 621 <tr> 622 <th colspan="2">The table header</th> 623 </tr> 624 </thead> 625 <tbody> 626 <tr> 627 <td>The table body</td> 628 <td>with two columns</td> 629 </tr> 630 </tbody> 631 <tfoot> 632 <tr> 633 <td><div>The table body</div></td> 634 </tr> 635 </tfoot> 636</table> 637``` 638 639### `<Table/>` 640 641Base element for creating a Table. 642 643| Platform | Output | 644| -------- | --------------------------- | 645| Web | `<table />` | 646| Native | `<View style={[Custom]} />` | 647 648### `<THead/>` 649 650Header element in a Table. 651 652| Platform | Output | 653| -------- | --------------------------- | 654| Web | `<thead />` | 655| Native | `<View style={[Custom]} />` | 656 657### `<TBody/>` 658 659Body element in a Table. 660 661| Platform | Output | 662| -------- | --------------------------- | 663| Web | `<tbody />` | 664| Native | `<View style={[Custom]} />` | 665 666### `<TFoot/>` 667 668Footer element in a Table. 669 670| Platform | Output | 671| -------- | --------------------------- | 672| Web | `<tfoot />` | 673| Native | `<View style={[Custom]} />` | 674 675### `<TH/>` 676 677Used to display text in the Header. 678 679- `colSpan` and `rowSpan` are currently web-only. 680 681| Platform | Output | 682| -------- | --------------------------- | 683| Web | `<th />` | 684| Native | `<Text style={[Custom]} />` | 685 686### `<TR/>` 687 688Used to create a Row in a Table. 689 690| Platform | Output | 691| -------- | --------------------------- | 692| Web | `<tr />` | 693| Native | `<View style={[Custom]} />` | 694 695### `<TD/>` 696 697Create a cell in a Table. 698 699- `colSpan` and `rowSpan` are currently web-only. 700 701| Platform | Output | 702| -------- | --------------------------- | 703| Web | `<td />` | 704| Native | `<View style={[Custom]} />` | 705 706### `<Caption/>` 707 708Used to caption your table. Excepts text as a child. 709 710| Platform | Output | 711| -------- | --------------------------- | 712| Web | `<caption />` | 713| Native | `<Text style={[Custom]} />` | 714 715## TODO 716 717- Improve relative imports for better tree-shaking. 718 719## Contributing 720 721Contributions are very welcome! Please refer to guidelines described in the [contributing guide](https://github.com/expo/expo#contributing). 722 723[yoga]: https://yogalayout.com/ 724 725<!-- HTML element links --> 726 727[html-a]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a 728[html-article]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/article 729[html-aside]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/aside 730[html-b]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/b 731[html-blockquote]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote 732[html-br]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/br 733[html-caption]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption 734[html-code]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/code 735[html-del]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/del 736[html-em]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/em 737[html-footer]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/footer 738[html-form]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form 739[html-h1]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h1 740[html-h2]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h2 741[html-h3]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h3 742[html-h4]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h4 743[html-h5]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h5 744[html-h6]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h6 745[html-header]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/header 746[html-hr]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hr 747[html-i]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/i 748[html-main]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/main 749[html-mark]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark 750[html-nav]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/nav 751[html-ol]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ol 752[html-p]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/p 753[html-pre]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre 754[html-q]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q 755[html-s]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/s 756[html-section]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/section 757[html-small]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/small 758[html-strong]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/strong 759[html-table]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table 760[html-tbody]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tbody 761[html-td]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td 762[html-tfoot]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tfoot 763[html-th]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/th 764[html-thead]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/thead 765[html-time]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/time 766[html-tr]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tr 767[html-ul]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ul 768[html-li]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/li 769[html-label]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label 770[html-details]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details 771[html-summary]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary 772[html-progress]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress 773[html-select]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select 774[html-picture]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture 775[html-figure]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure 776[html-figcaption]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figcaption 777[aria-banner]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Banner_role 778