Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@expo/html-elements

Package Overview
Dependencies
Maintainers
20
Versions
79
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@expo/html-elements

Universal semantic HTML React components for iOS, Android, web, and desktop

  • 0.2.2
  • Source
  • npm
  • Socket score

Version published
Maintainers
20
Created
Source

@expo/html-elements

Product: demo

Supports Expo iOS Supports Expo Android Supports Expo Web Circle CI

Simple, light-weight, and well tested, universal semantic HTML elements as React components for iOS, Android, web, and desktop apps!

We 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.

What you get

  • 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.
    • This package takes full advantage of react-native-web a11y rules whenever possible.
    • For example, the H1 component will render an <h1 /> on web, a UILabel on iOS, and a TextView on Android.
  • Every component can accept styles from the StyleSheet API.
  • TypeScript works for iOS, Android, and web, no more having to create monkey patches to use href on a Text element.
  • Every component is tested render tested universally for iOS, Android, and Web using the package jest-expo-enzyme. Each element is also E2E tested on iOS with Detox, and web with jest-expo-puppeteer.
  • This package is completely side-effect free!

Setup

Install:

yarn add @expo/html-elements

Import and use the package:

import { H1 } from '@expo/html-elements';

Components

Here 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.

HTML@expo/html-elements
<a /><A />
<article /><Article />
<aside /><Aside />
<b /><B />
<blockquote /><BlockQuote />
<br /><BR />
<caption /><Caption />
<code /><Code />
<del /><Del />
<em /><EM />
<footer /><Footer />
<h1 /><H1 />
<h2 /><H2 />
<h3 /><H3 />
<h4 /><H4 />
<h5 /><H5 />
<h6 /><H6 />
<header /><Header />
<hr /><HR />
<i /><I />
<main /><Main />
<mark /><Mark />
<nav /><Nav />
<p /><P />
<pre /><Pre />
<q /><Q />
<s /><S />
<section /><Section />
<strong /><Strong />
<table /><Table />
<tbody /><TBody />
<td /><TD />
<tfoot /><TFoot />
<th /><TH />
<thead /><THead />
<time /><Time />
<tr /><TR />
<ul /><UL />
<li /><LI />
<details />⏱ Pending
<summary />⏱ Pending
<progress />⏱ Pending
<select />⏱ Pending
<picture />⏱ Pending
<figure />⏱ Pending
<figcaption />⏱ Pending
<form />⏱ Pending
<label />⏱ Pending

External

Other features not implemented in this package can be found in different parts of the Expo ecosystem.

HTMLUniversalPackage
<audio />Audioexpo-av
<button /><Button />react-native
<input type="text" /><TextInput />react-native
<input type="file" />ImagePickerexpo-image-picker
<input type="file" />DocumentPickerexpo-document-picker
<canvas /><GLView />expo-gl & Expo Canvas
<iframe /><WebView /><WebView />. @react-native-community/web-view is not maintained by Expo and doesn't have web support
<link />NoneEject the index.html with npx expo customize and link resources directly with <link />
<noscript />NoneEject the index.html with npx expo customize and use <noscript /> directly as HTML
<div /><View />react-native
<img /><Image />react-native
<span /><Text />react-native
<video /><Video />expo-av
style="backdrop-filter"<BlurView />expo-blur
style="linear-gradient()"<LinearGradient />expo-linear-gradient

Headings

Header elements will use the expected font size and margins from web universally. You can see how the native CSS units (rem, and em) are transformed in css/units.

import { H1, H2, H3, H4, H5, H6 } from '@expo/html-elements';

<H1/>

import { H1 } from '@expo/html-elements';
export default () => <H1>Example<H1/>
PlatformOutput
Web<h1 aria-level="1" dir="auto" role="heading" />
Native<Text accessibilityRole="header" style={[Custom]} />

<H2/>

import { H2 } from '@expo/html-elements';
export default () => <H2>Example<H2/>
PlatformOutput
Web<h2 aria-level="2" dir="auto" role="heading" />
Native<Text accessibilityRole="header" style={[Custom]} />

<H3/>

import { H3 } from '@expo/html-elements';
export default () => <H3>Example<H3/>
PlatformOutput
Web<h3 aria-level="3" dir="auto" role="heading" />
Native<Text accessibilityRole="header" style={[Custom]} />

<H4/>

import { H4 } from '@expo/html-elements';
export default () => <H4>Example<H4/>
PlatformOutput
Web<h4 aria-level="4" dir="auto" role="heading" />
Native<Text accessibilityRole="header" style={[Custom]} />

<H5/>

import { H5 } from '@expo/html-elements';
export default () => <H5>Example<H5/>
PlatformOutput
Web<h5 aria-level="5" dir="auto" role="heading" />
Native<Text accessibilityRole="header" style={[Custom]} />

<H6/>

import { H6 } from '@expo/html-elements';
export default () => <H6>Example<H6/>
PlatformOutput
Web<h6 aria-level="6" dir="auto" role="heading" />
Native<Text accessibilityRole="header" style={[Custom]} />

<A/>

You 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.

  • The CSS style is fully normalized to match <Text />
  • For pseudo-class effects like hover and focus states check out the package react-native-web-hooks | tutorial
import { A } from '@expo/html-elements';

export default () => <A href="#" target="_blank" />;
}
PlatformOutput
Web<a data-focusable="{true}" dir="auto" href="#" role="link" target="_blank" />
Native<Text accessibilityRole="link" onPress={[Function]} />

Layout

You can use layout elements like Header, Main, Footer, Section, Nav, etc. as a drop-in replacement for Views in your existing app.

Default Layout style

All layout HTML elements inherit the shared style of <View /> to accommodate the Yoga layout engine which we use on native for iOS, and Android.

  • display is always flex. This is because Yoga only implements display: flex.
  • flex-direction is always column instead of row.
Why use Layout elements

Consider 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:

Some 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.

<Nav/>

import { Nav } from '@expo/html-elements';

export default () => <Nav />;
PlatformOutput
Web<nav style="display:flex" />
Native<View />

<Header/>

Renders a <header /> on web with ARIA set to banner and a View with ARIA set to header on mobile.

import { Header } from '@expo/html-elements';

export default () => <Header />;
PlatformOutput
Web<header role="banner" />
Native<View />
iOSUIView uses UIAccessibilityTraitHeader.
AndroidView will use the proper AccessibilityNodeInfoCompat.CollectionItemInfoCompat docs

<Main/>

Renders a <main /> on web with ARIA role set to main and a View with no ARIA set on mobile.

import { Main } from '@expo/html-elements';

export default () => (
    <Main>
      <P>Some content in the main element</P>
    </Main>
  );
)
PlatformOutput
Web<main role="main" style="display:flex" />
Native<View />

<Section/>

Renders a <section /> on web with ARIA set to region and a View with ARIA set to summary on mobile.

import { Section } from '@expo/html-elements';

export default () => <Section />;
PlatformOutput
Web<section role="region" style="display:flex" />
Native<View accessibilityRole="summary" />

<Article/>

Renders an <article /> on web and a View everywhere else.

import { Article } from '@expo/html-elements';

export default () => <Article />;
PlatformOutput
Web<article role="article" />
Native<View />

<Aside/>

import { Aside } from '@expo/html-elements';

export default () => <Aside />;
PlatformOutput
Web<aside role="complementary" />
Native<View />

Renders an <footer /> on web and a View everywhere else.

import { Footer } from '@expo/html-elements';

export default () => <Footer />;
PlatformOutput
Web<footer role="contentinfo" />
Native<View />

Text

Text elements currently use Text universally rendering either a div or span to emulate Yoga style properly.

  • Style is modified to match web.
  • All font styles are reset (minus Code, and Pre).
  • All elements accept styles from StyleSheet API.
import { P, B, S, I, BR, Code } from '@expo/html-elements';

export default () => (
  <>
    <P>
      Hello<B>World (in bold)</B>
    </P>
    <S>strike text</S>
    <BR />
    <I>Italic</I>
    <Code>const foo = true</Code>
  </>
);

<P/>

Standard paragraph element.

PlatformOutput
Universal<Text style={{ fontSize: 14, marginVertical: '1em' }} />

<B/>

Bold text text.

PlatformOutput
Universal<Text style={{ fontWeight: 'bold' }} />

<Strong/>

Alternate bold text.

PlatformOutput
Universal<Text style={{ fontWeight: 'bold' }} />

<S/>

Strike through text.

PlatformOutput
Universal<Text style={{ textDecorationLine: 'line-through' }} />

<Del/>

Alternate strike through text.

PlatformOutput
Universal<Text style={{ textDecorationLine: 'line-through' }} />

<I/>

Italic text.

PlatformOutput
Universal<Text style={{ fontStyle: 'italic' }} />

<EM/>

Alternate italic text.

PlatformOutput
Universal<Text style={{ fontStyle: 'italic' }} />

<Code/>

Inline code block with fontFamily: 'Courier' on iOS and Web, fontFamily: 'monospace' on Android.

PlatformOutput
Universal<Text style={[Custom]} />

<Pre/>

Render a preformatted code block with fontFamily: 'Courier' on iOS and Web, fontFamily: 'monospace' on Android.

<Pre>{`
body {
  color: red;
}
`}</Pre>

// Or pass views

<Pre>
  <Code>{`const val = true`}</Code>
</Pre>
PlatformOutput
Universal<Text style={[Custom]} /> | <View />

<Mark/>

Highlight text.

PlatformOutput
Universal<Text style={{ backgroundColor: 'yellow', color: 'black' }} />

<Q/>

Quoted text.

PlatformOutput
Universal<Text style={[Custom]}>"{props.children}"</Text>

<BlockQuote/>

PlatformOutput
Universal<View style={[Custom]} />

<Time/>

  • dateTime prop is supported on web and stripped on native.
PlatformOutput
Universal<Text style={[Custom]} />

Lists

Lists 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.

<UL/>

Create an unordered (bulleted) list <ul /> on web, and emulates the style with a <View /> on native.

  • Resets font styles everywhere.
  • Supports i18n by reversing format on iOS and Android
  • Supports custom bullets
import { UL, LI } from '@expo/html-elements';

export default () => (
  <UL>
    <LI>oranges</LI>
    <LI>apples</LI>
    <UL>
      <LI>green</LI>
      <LI>red</LI>
    </UL>
  </UL>
);
PlatformOutput
Web<ul />
Native<View style={[Custom]} />

<LI/>

Create a standard list item <li /> on web and a native view on mobile which can render text or views inside it.

PlatformOutput
Web<li />
Native<Text style={[Custom]} /> | <View style={[Custom]} />

Rules

<HR/>

Renders a <View> everywhere. Style is modified to match web.

import { HR } from '@expo/html-elements';

export default () => <HR />;
PlatformOutput
Web<hr />
Native<View style={[Custom]} />

<BR/>

Create a line break.

PlatformOutput
Web<br />
Native<View style={{height: 8, width: 0}} />

Tables

Create tables universally.

  • Each element renders to the expected type on web.
  • padding is removed from all table elements.
  • Text can only be rendered in TH and TD on mobile.
  • colSpan and rowSpan are currently web-only (PRs welcome).
import { Table, THead, TH, TBody, TFoot, TR, TD, Caption } from '@expo/html-elements';
import { Text } from 'react-native';

export default () => (
  <Table>
    <Caption>Caption</Caption>
    <THead>
      <TR>
        <TH colSpan="2">The table header</TH>
      </TR>
    </THead>
    <TBody>
      <TR>
        <TD>The table body</TD>
        <TD>with two columns</TD>
      </TR>
    </TBody>
    <TFoot>
      <TR>
        <TD>
          <Text>This is the table footer</Text>
        </TD>
      </TR>
    </TFoot>
  </Table>
);
Table example output web
<table>
  <caption>
    Caption
  </caption>
  <thead>
    <tr>
      <th colspan="2">The table header</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>The table body</td>
      <td>with two columns</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td><div>The table body</div></td>
    </tr>
  </tfoot>
</table>

<Table/>

Base element for creating a Table.

PlatformOutput
Web<table />
Native<View style={[Custom]} />

<THead/>

Header element in a Table.

PlatformOutput
Web<thead />
Native<View style={[Custom]} />

<TBody/>

Body element in a Table.

PlatformOutput
Web<tbody />
Native<View style={[Custom]} />

<TFoot/>

Footer element in a Table.

PlatformOutput
Web<tfoot />
Native<View style={[Custom]} />

<TH/>

Used to display text in the Header.

  • colSpan and rowSpan are currently web-only.
PlatformOutput
Web<th />
Native<Text style={[Custom]} />

<TR/>

Used to create a Row in a Table.

PlatformOutput
Web<tr />
Native<View style={[Custom]} />

<TD/>

Create a cell in a Table.

  • colSpan and rowSpan are currently web-only.
PlatformOutput
Web<td />
Native<View style={[Custom]} />

<Caption/>

Used to caption your table. Excepts text as a child.

PlatformOutput
Web<caption />
Native<Text style={[Custom]} />

TODO

  • Improve relative imports for better tree-shaking.

Contributing

Contributions are very welcome! Please refer to guidelines described in the contributing guide.

Keywords

FAQs

Package last updated on 30 Oct 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc