xref: /expo/packages/html-elements/README.md (revision e330c216)
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