Options
All
  • Public
  • Public/Protected
  • All
Menu

Namespace UI

Basic user interface components designed to simplify custom styling of the application.

Most UI components are drop-in replacements for their native counterparts, as they are mostly wrappers around their native counterparts using styled-components.

For example, <input /> can be replaced with <UI.Input /> using all of the same props.

Other components (e.g., Modal, Spinner, etc.) don't typically have native counterparts but are common and generic enough to be considered a user interface component.

Index

Type aliases

ButtonProps: Omit<React.HTMLProps<HTMLButtonElement>, "size"> & { backgroundColor?: string; color?: string; size?: "small" | "medium" | "large" | string | number; type?: "button" | "reset" | "submit" }
ComboProps: React.HTMLProps<HTMLInputElement> & { inputValue?: string; placeholderComponent?: React.ReactNode; useEffect?: boolean; value?: string; onChange?: any; onInput?: any }
ComboSetState: React.Dispatch<React.SetStateAction<ComboState>>
ComboState: { inputValue?: string; value?: string }

Type declaration

  • Optional inputValue?: string
  • Optional value?: string
ErrorProps: React.HTMLProps<HTMLDivElement> & { center?: boolean; children?: VariableError | boolean | React.ReactChild | React.ReactFragment | React.ReactPortal | null; error?: VariableError }
FooterProps: React.HTMLProps<HTMLDivElement>
FormProps: Omit<React.HTMLProps<HTMLFormElement>, "onSubmit"> & { getFormData?: any; onInput?: any; onSubmit?: any }
HeaderProps: React.HTMLProps<HTMLDivElement>
IframeProps: React.HTMLProps<HTMLIFrameElement> & { mutate?: any }
InputDateTimeProps: React.HTMLProps<HTMLInputElement> & { offsetTime?: number }
InputProps: React.HTMLProps<HTMLInputElement> & { placeholderComponent?: React.ReactNode; useEffect?: boolean; onChange?: any; onInput?: any; onKeyDown?: any; onKeyPress?: any; onKeyUp?: any }
InputSetState: React.Dispatch<React.SetStateAction<InputState>>
InputState: { value: InputValue }

Type declaration

InputValue: string | number | readonly string[] | undefined
ModalButtonProps: React.HTMLProps<HTMLButtonElement> & { type?: "button" | "reset" | "submit" }
ModalCloseUnderlayProps: React.HTMLProps<HTMLButtonElement> & { type?: "button" | "reset" | "submit" }
ModalProps: React.HTMLProps<HTMLDivElement> & { backgroundColor?: string; position?: "left" | "right"; onBack?: any; onClose?: any }
RTEFormEvent: { currentTarget: RTEWrapperElement }

Type declaration

RTEFormEventHandler: (event: RTEFormEvent, setState?: RTESetState) => void

Type declaration

RTEProps: Omit<React.HTMLProps<HTMLDivElement>, "value" | "onInput" | "onChange" | "onFocus" | "onBlur"> & { buttonDisabled?: boolean; onBlur?: RTEFormEventHandler; onChange?: RTEFormEventHandler; onFocus?: RTEFormEventHandler; onInput?: RTEFormEventHandler; placeholderComponent?: React.ReactNode; scrollElementRef?: React.RefObject<null | HTMLElement>; toolbarKey?: string; toolbars?: RTEToolbars; useEffect?: boolean; value: RTEValue }
RTESetState: React.Dispatch<React.SetStateAction<RTEState>>
RTEState: { value: RTEValue }

Type declaration

RTEValue: { html: string; text: string }

Type declaration

  • html: string
  • text: string
SelectProps: React.HTMLProps<HTMLSelectElement> & { placeholderComponent?: React.ReactNode; useEffect?: boolean }
SelectSetState: React.Dispatch<React.SetStateAction<SelectState>>
SelectState: { selectedText?: string; value?: SelectValue }

Type declaration

  • Optional selectedText?: string
  • Optional value?: SelectValue
SelectValue: string | number | readonly string[] | undefined
SpinnerProps: Omit<React.HTMLProps<HTMLDivElement>, "size"> & { color?: string; inline?: boolean; size?: "tiny" | "small" | "medium" | "large"; spin?: boolean; style?: CSSProperties }
StatusIconColors: Record<string, string>
StatusIconProps: Parameters<typeof Spinner>[0] & { colors?: StatusIconColors; icons?: StatusIcons; size?: "small" | "medium" | "large"; spin?: boolean; status?: keyof StatusIconColors; title?: string }
StatusIcons<C>: Record<keyof C, React.ReactElement>

Type parameters

TextareaProps: React.HTMLProps<HTMLTextAreaElement> & { placeholderComponent?: React.ReactNode; useEffect?: boolean; onBlur?: any; onChange?: any; onInput?: any; onKeyDown?: any; onKeyPress?: any; onKeyUp?: any }
TextareaSetState: React.Dispatch<React.SetStateAction<TextareaState>>
TextareaState: { value: TextareaValue }

Type declaration

TextareaValue: string | number | readonly string[] | undefined

Variables

Button: StyledComponent<(__namedParameters: ButtonProps) => Element, DefaultTheme, {}, never> = ...

A styled button element.

This is a simple wrapper around the native button element, so you can replace <button { ...props } /> with <UI.Button { ...props } /> for better looking, easily stylable buttons for your application.

Example usage:

import React, { useState } from 'react'
import * as UI from '../../UI'

export type ExampleProps = React.HTMLProps<HTMLDivElement>

export const Example = (props: ExampleProps): React.ReactElement => {
const [ count, setCount ] = useState(0)

return (
<div { ...props }>
<p>
The button was clicked {count} times.
</p>

<UI.Button onClick={() => setCount(count => count + 1)}>
<span>
Click me
</span>
</UI.Button>
</div>
)
}
Center: StyledComponent<"div", DefaultTheme, {}, never> = ...

A styled div using flex box CSS to center its contents both horizonally and vertically.

Combo: StyledComponent<(__namedParameters: ComboProps) => Element, DefaultTheme, {}, never> = ...

A custom "combo" box. Looks like a select menu, but you can type into it like it's an input. The value prop represents the selected value, while the inputValue prop represents the value of the input. What you do with the input/selection is up to you - e.g., filtering, adding/removing options, etc.

You can replace <select { ...props } /> with <UI.Combo { ...props } /> for filterable, better looking, easily stylable select menus with inputs for your application.

Example usage:

import React, { useState } from 'react'
import * as UI from '../../UI'

export type ExampleProps = React.HTMLProps<HTMLDivElement>

export const Example = (props: ExampleProps): React.ReactElement => {
const [ value, setValue ] = useState('')
const [ inputValue, setInputValue ] = useState('')
const options = [
'',
'foo',
'bar'
]

return (
<div { ...props }>
<p>
Type into the combo box and select an option.
</p>

<UI.Combo
placeholder='Hello, World!'
name='example'
value={value}
inputValue={inputValue}
onInput={event => {
setInputValue(event.currentTarget.value)
}}
onChange={event => {
setValue(event.currentTarget.value)
}}
>
{options.map(option => inputValue && option.indexOf(inputValue) < 0 ? null : (
<option key={option} value={option}>
{option}
</option>
))}
</UI.Combo>
</div>
)
}
ComboArrow: StyledComponent<"b", DefaultTheme, {}, never> = ...

The styled arrow icon for the combo box.

ComboInput: StyledComponent<"input", DefaultTheme, {}, never> = ...

The styled input element for the combo box.

ComboOptions: StyledComponent<"ul", DefaultTheme, {}, never> = ...

The combo box's list of selectable options.

ComboPlaceholder: StyledComponent<"span", DefaultTheme, { aria-hidden: true }, "aria-hidden"> = ...

The styled placeholder element for the combo box.

Error: StyledComponent<(__namedParameters: ErrorProps) => Element, DefaultTheme, {}, never> = ...

Displays a readable error message from some Error.

You can pass the error as a property or as children.

If there is no error, the element will be hidden using display: none.

Example usage:

import React, { useState } from 'react'
import * as UI from '../../UI'

export type ExampleProps = React.HTMLProps<HTMLDivElement>

export const Example = (props: ExampleProps): React.ReactElement => {
const [ error, setError ] = useState<null | Error>(null)

return (
<div { ...props }>
<p>
Click the button to produce an error.
</p>

<UI.Button onClick={() => setError(new Error(`This is an error!`))}>
<span>
Click me
</span>
</UI.Button>

<p>
<UI.Error>
{error}
</UI.Error>
</p>
</div>
)
}
Footer: StyledComponent<(__namedParameters: FooterProps) => Element, DefaultTheme, {}, never> = ...

A styled footer element.

This is a simple wrapper around the native footer element, so you can replace <footer { ...props } /> with <UI.Footer { ...props } /> for better looking, easily stylable footers for your application.

Example usage:

import React from 'react'
import * as UI from '../../UI'

export type ExampleProps = React.HTMLProps<HTMLDivElement>

export const Example = (props: ExampleProps): React.ReactElement => {
return (
<div { ...props }>
<UI.Footer>
<span>
Hello, World!
</span>
</UI.Footer>
</div>
)
}
H1: StyledComponent<"h1", DefaultTheme, {}, never> = ...
H2: StyledComponent<"h2", DefaultTheme, {}, never> = ...
H3: StyledComponent<"h3", DefaultTheme, {}, never> = ...
H4: StyledComponent<"h4", DefaultTheme, {}, never> = ...
Header: StyledComponent<(__namedParameters: UI.HeaderProps) => Element, DefaultTheme, {}, never> = ...

A styled header element.

This is a simple wrapper around the native header element, so you can replace <header { ...props } /> with <UI.Header { ...props } /> for better looking, easily stylable headers for your application.

Example usage:

import React from 'react'
import * as UI from '../../UI'

export type ExampleProps = React.HTMLProps<HTMLDivElement>

export const Example = (props: ExampleProps): React.ReactElement => {
return (
<div { ...props }>
<UI.Header>
<span>
Hello, World!
</span>
</UI.Header>
</div>
)
}
Iframe: StyledComponent<(__namedParameters: IframeProps) => Element, DefaultTheme, {}, never> = ...

A styled iframe element which attempts to adjust its height depending on its contents.

You may also optionally mutate its contents for the same domain.

Example usage:

import React from 'react'
import * as UI from '../../UI'

export type ExampleProps = React.HTMLProps<HTMLDivElement>

const mutateAnchor = (anchor: HTMLAnchorElement) => {
anchor.setAttribute(`target`, `_blank`)
anchor.setAttribute(`rel`, `noopener noreferrer`)
}

export const Example = (props: ExampleProps): React.ReactElement => {
return (
<div { ...props }>
<p>
The link in the iframe below is mutated upon render to open in a new window.
</p>

<UI.Iframe
title='Hello, World!'
srcDoc={`
<!DOCTYPE html>
<html>
<body>
<a href='https://www.molecule.dev'>
Molecule.dev
</a>
</body>
</html>
`}
mutate={element => {
const iframe = element?.firstElementChild as HTMLIFrameElement
const body = iframe?.contentWindow?.document?.body
const anchors = body?.querySelectorAll(`a`)

if (anchors?.length) {
for (let i = 0; i < anchors.length; i++) {
mutateAnchor(anchors[i])
}
}
}}
/>
</div>
)
}
Input: StyledComponent<(__namedParameters: InputProps) => Element, DefaultTheme, {}, never> = ...

A styled input element.

This is a simple wrapper around the native input element, so you can replace <input { ...props } /> with <UI.Input { ...props } /> for better looking, easily stylable inputs for your application.

Example usage:

import React, { useState } from 'react'
import * as UI from '../../UI'

export type ExampleProps = React.HTMLProps<HTMLDivElement>

export const Example = (props: ExampleProps): React.ReactElement => {
const [ value, setValue ] = useState('')

return (
<div { ...props }>
<p>
Type something into the input.
</p>

<UI.Input
placeholder='Hello, World!'
name='example'
value={value}
onInput={event => {
setValue(event.currentTarget.value)
}}
/>
</div>
)
}
InputPlaceholder: StyledComponent<"span", DefaultTheme, { aria-hidden: true }, "aria-hidden"> = ...

The input's styled placeholder element.

Modal: StyledComponent<(__namedParameters: ModalProps) => Element, DefaultTheme, {}, never> = ...

A custom modal component, defaults to a center position with 'left' or 'right' options.

If onClose and/or onBack handlers are provided, the corresponding buttons will be added within the ModalHeader, plus the ModalUnderlay.

Example usage:

import React, { useState } from 'react'
import * as UI from '../../UI'

export type ExampleProps = React.HTMLProps<HTMLDivElement>

export const Example = (props: ExampleProps): React.ReactElement => {
const [ visible, setVisible ] = useState(false)

return (
<div { ...props }>
<p>
Click the button to show the modal.
</p>

<UI.Button onClick={() => setVisible(true)}>
<span>
Click me
</span>
</UI.Button>

{visible && (
<UI.Modal onClose={() => setVisible(false)}>
<p>
This is a centered modal.
</p>

<p>
Click the X at the top right to close it.
</p>
</UI.Modal>
)}
</div>
)
}
ModalButton: StyledComponent<(__namedParameters: ModalButtonProps) => Element, DefaultTheme, {}, never> = ...

A button icon which can be rendered with an onClick handler, usually within a ModalHeader.

ModalHeader: StyledComponent<(__namedParameters: UI.HeaderProps) => Element, DefaultTheme, {}, never> = ...
ModalUnderlay: StyledComponent<(__namedParameters: ModalCloseUnderlayProps) => ReactElement<any, string | JSXElementConstructor<any>>, DefaultTheme, {}, never> = ...

A full-sized, semi-transparent underlay which can be rendered before your Modal with an onClick handler, usually to close the modal.

P: StyledComponent<"p", DefaultTheme, {}, never> = ...
RTE: StyledComponent<(__namedParameters: RTEProps) => Element, DefaultTheme, {}, never> = ...

A custom rich text editor using Quill.

Aims to be similar in function to the native textarea element, but the value is an object containing both text and html instead of a string.

Example usage:

import React, { useState } from 'react'
import * as UI from '../../UI'

export type ExampleProps = React.HTMLProps<HTMLDivElement>

export const Example = (props: ExampleProps): React.ReactElement => {
const [ value, setValue ] = useState({
html: `<p><br></p>`,
text: `\n`
})

return (
<div { ...props }>
<p>
Type something into the rich text editor and see console logs for value changes.
</p>

<UI.RTE
placeholder='Hello, World!'
name='example'
value={value}
onInput={event => {
console.log(event.currentTarget.value)
setValue(event.currentTarget.value)
}}
/>
</div>
)
}
see

https://www.npmjs.com/package/quill

RTEPlaceholder: StyledComponent<"span", DefaultTheme, { aria-hidden: true }, "aria-hidden"> = ...
Section: StyledComponent<(__namedParameters: any) => Element, DefaultTheme, {}, never> = ...
Select: StyledComponent<(__namedParameters: SelectProps) => ReactElement<any, string | JSXElementConstructor<any>>, DefaultTheme, {}, never> = ...

A styled select element, normalized to look the same for every major browser.

You can replace <select { ...props } /> with <UI.Select { ...props } /> for filterable, better looking, easily stylable select menus for your application.

Example usage:

import React, { useState } from 'react'
import * as UI from '../../UI'

export type ExampleProps = React.HTMLProps<HTMLDivElement>

export const Example = (props: ExampleProps): React.ReactElement => {
const [ value, setValue ] = useState('')
const options = [
'',
'foo',
'bar'
]

return (
<div { ...props }>
<p>
Select an option.
</p>

<UI.Select
style={{ width: 200 }}
placeholder='Hello, World!'
name='example'
value={value}
onChange={event => {
setValue(event.currentTarget.value)
}}
>
{options.map(option => (
<option key={option} value={option}>
{option}
</option>
))}
</UI.Select>
</div>
)
}
SelectArrow: StyledComponent<"b", DefaultTheme, {}, never> = ...

The styled arrow icon for the select menu.

SelectPlaceholder: StyledComponent<"span", DefaultTheme, { aria-hidden: true }, "aria-hidden"> = ...

The styled placeholder element for the select menu.

SelectSelectedText: StyledComponent<"span", DefaultTheme, {}, never> = ...

To achieve the same style across browsers, the selected option's text is rendered on top of the select element.

Spinner: StyledComponent<(__namedParameters: SpinnerProps) => Element, DefaultTheme, {}, never> = ...

A spinning icon to indicate loading/pending state.

Provide spin as false stop the spinning.

Example usage:

import React from 'react'
import * as UI from '../../UI'

export type ExampleProps = React.HTMLProps<HTMLDivElement>

export const Example = (props: ExampleProps): React.ReactElement => {
return (
<div { ...props }>
<UI.Spinner />
</div>
)
}
StatusIcon: StyledComponent<(__namedParameters: StatusIconProps) => null | Element, DefaultTheme, {}, never> = ...

An icon to represent the state of some promise.

Designed to be paired with the usePromise hook.

Example usage:

import React from 'react'
import { usePromise } from '../../hooks/usePromise'
import * as UI from '../../UI'

export type ExampleProps = React.HTMLProps<HTMLDivElement>

export const Example = (props: ExampleProps): React.ReactElement => {
const [ randomNumberRequest, requestRandomNumber ] = usePromise(async () => {
await new Promise(resolve => setTimeout(resolve, 1000))

if (Math.random() < 0.5) {
return Math.random()
} else {
throw new Error(`Try again!`)
}
})

const isPending = randomNumberRequest.status === 'pending'

return (
<div style={{ textAlign: `center` }} { ...props }>
<p>
Click the button to asynchronously set a random number. It has a 50% chance of throwing an error.
</p>

<p>
Current random number: {randomNumberRequest.value || `?`}
</p>

<UI.Button onClick={() => requestRandomNumber()} disabled={isPending}>
<span>
{isPending
? `Wait a second...`
: `Get a random number`
}
</span>
</UI.Button>

<UI.StatusIcon status={randomNumberRequest.status} />

<UI.Error>
{randomNumberRequest.error}
</UI.Error>
</div>
)
}
Text: StyledComponent<"span", DefaultTheme, { color?: string }, never> = ...

A styled span element to quickly color some text using the current theme.

This is a simple wrapper around the native span element, so you can replace <span { ...props } /> with <UI.Text color='primary' { ...props } /> for better looking, easily stylable inline text for your application.

Example usage:

import React from 'react'
import * as UI from '../../UI'

export type ExampleProps = React.HTMLProps<HTMLDivElement>

export const Example = (props: ExampleProps): React.ReactElement => {
return (
<div { ...props }>
Hello, <UI.Text color='primary'>World</UI.Text>!
</div>
)
}
Textarea: StyledComponent<(__namedParameters: TextareaProps) => Element, DefaultTheme, {}, never> = ...

A styled textarea element.

This is a simple wrapper around the native textarea element, so you can replace <textarea { ...props } /> with <UI.Textarea { ...props } /> for better looking, easily stylable textareas for your application.

Example usage:

import React, { useState } from 'react'
import * as UI from '../../UI'

export type ExampleProps = React.HTMLProps<HTMLDivElement>

export const Example = (props: ExampleProps): React.ReactElement => {
const [ value, setValue ] = useState('')

return (
<div { ...props }>
<p>
Type something into the textarea.
</p>

<UI.Textarea
placeholder='Hello, World!'
name='example'
value={value}
onInput={event => {
setValue(event.currentTarget.value)
}}
/>
</div>
)
}
TextareaPlaceholder: StyledComponent<"span", DefaultTheme, { aria-hidden: true }, "aria-hidden"> = ...

The styled placeholder element for the textarea.

Tip: StyledComponent<"div", DefaultTheme, {}, never> = ...

Example usage:

<UI.Tip color='green'>
<LightBulbIcon size={20} />

<span>
Some tip here.
</span>
</UI.Tip>
UL: StyledComponent<"ul", DefaultTheme, { visible?: boolean }, never> = ...
defaultStatusIconColors: StatusIconColors = ...
defaultStatusIcons: StatusIcons = ...
defaultToolbars: RTEToolbars = ...

Functions

  • Form(__namedParameters: FormProps): ReactElement<any, string | JSXElementConstructor<any>>
  • A wrapper around the native form element with some helpful additions.

    Intercepts onSubmit and onInput to pass an extra formData parameter which is a JSON object containing the state of the form data, which can be as complex (deep) or as simple as you need it to be.

    By default, the form data is determined from elements with a name attribute, where name can be a "deep" string. For example, consider the following:

    return (
    <UI.Form onSubmit={(event, formData) => logger.info(formData)}>
    <UI.Input
    name='foo.bar.baz'
    value='Hello, World!'
    />

    <UI.Button type='submit'>
    <span>
    Submit
    </span>
    </UI.Button>
    </UI.Form>
    )

    // Submitting the form would log the following:
    const formData: JSONObject = {
    foo: {
    bar: {
    baz: 'Hello, World!"
    }
    }
    }

    You can also use a data-json attribute to specify JSON values, if necessary:

    const [ value, setValue ] = useState('')

    return (
    <UI.Form onSubmit={(event, formData) => logger.info(formData)}>
    <UI.Input
    name='foo'
    value={value}
    onInput={event => setValue(event.currentTarget.value)}
    data-json={JSON.stringify({ bar: { baz: value } })}
    />

    <UI.Button type='submit'>
    <span>
    Submit
    </span>
    </UI.Button>
    </UI.Form>
    )

    If you're managing the state of the form elsewhere, then you probably don't need any of this, but wrapping your inputs in a form is generally a good idea to avoid any confusion, even if the form submission functionality goes unused.

    Parameters

    Returns ReactElement<any, string | JSXElementConstructor<any>>

  • InputDateTime(__namedParameters: InputDateTimeProps): ReactElement<any, string | JSXElementConstructor<any>>
  • Two input elements designed to normalize datetime inputs across different browsers.

    Parameters

    Returns ReactElement<any, string | JSXElementConstructor<any>>

  • getDeepObject(keyPath: string, value: JSONObject, deepObject?: JSONObject): JSONObject
  • Assigns the value to a potentially deep key.

    The keyPath can be just one - e.g., foo - or it can be deep - e.g., foo.bar.baz.

    Parameters

    • keyPath: string
    • value: JSONObject
    • deepObject: JSONObject = {}

    Returns JSONObject

  • getFormData(form: HTMLFormElement, selector?: string): JSONObject
  • Gets form data with some helpful additions/shortcuts.

    By default, all elements with a name attribute are used (i.e., the selector argument defaults to [name]), regardless of being a valid form element.

    Any elements with a data-json attribute will have this attribute parsed as JSON and used as its value.

    If an element does not have a value attribute but has innerText, the innerText is used as its value.

    The value attribute of checkboxes will be used if checked, empty string if not.

    The value attribute of radio buttons will be set only if the radio button is selected.

    You can include periods within elements names to create "deep" form data which matches the original object. For example, <UI.Input name='foo.bar.baz' value={foo.bar.baz} /> will result in form data which looks like { foo: { bar: { baz } } }.

    Parameters

    • form: HTMLFormElement
    • selector: string = ...

    Returns JSONObject

Generated using TypeDoc