npm package: @mirai/ui
Description: > React components library.
Author: JΛVI
Latest version: 2.1.94

# 💾 @mirai/ui

> React components library.

### 📦 Setup

Add the package in your project:

```
yarn add @mirai/ui
```

## Primitives

### Checkbox

This primitive returns a checkbox button based on the following properties:

- `checked:boolean` if true, the checkbox button is checked
- `children:node`
- `disabled:boolean` applying 'disabled' attribute
- `error:boolean` shows error style
- `name:string` input name (required)
- `value:string` input value
- `onChange:function` executed when input value changes

```jsx
import { Checkbox, View } from '@mirai/ui';

const MyComponent = () => (
  <View>
    <Checkbox
      name="checkbox"
      checked={false}
      disabled={false}
      value="primitive"
      onChange={() => console.log('change')}
    />
  </View>
```

**Theming variables**

```css
--mirai-ui-checkbox-background: var(--mirai-ui-base);
--mirai-ui-checkbox-background-checked: var(--mirai-ui-accent);
--mirai-ui-checkbox-background-disabled: var(--mirai-ui-content-border);
--mirai-ui-checkbox-border-color: var(--mirai-ui-content-light);
--mirai-ui-checkbox-border-radius: var(--mirai-ui-border-radius);
--mirai-ui-checkbox-size: calc(var(--mirai-ui-space-M) + var(--mirai-ui-space-XXS));
--mirai-ui-checkbox-size-mobile: var(--mirai-ui-space-L);
```

### Icon

This primitive returns a span with an icon based on a mandatory string prop `name`.

- `accent:boolean` use theme's accent color
- `accentDark:boolean` use theme's accent-dark color
- `accentLight:boolean` use theme's accent-light color
- `action:boolean` modifying font-size
- `dark:boolean` use theme's content-dark color
- `error:boolean` use theme's error color
- `headline:boolean` modifying font-size (default headline:3)
- `info:boolean` use theme's info color
- `level:number` assign the level of heading (1, 2, 3 or 4)
- `light:boolean` use theme's content-light color
- `paragraph:boolean` modifying font-size
- `small:boolean` modifying font-size
- `success:boolean` use theme's success color
- `value:func` Enum value
- `warning:boolean` use theme's warning color

```jsx
import { Icon, ICON, View } from '@mirai/ui';

const MyComponent = () => (
  <View>
    <Icon value={ICON.LEFT} />
  </View>
);
```

> ℹ️ Current available values: Left, Right, Up, Down, Check, Add, Remove, ExpandLess, ExpandMore, EyeOpen, EyeClose, Close, Error, Info, Success, Warning, List, Lock, Bed, Calendar, Person, Account.

### Input

This primitive returns an input or a textarea based on the following props:

- `disabled:boolean` applying 'disabled' attribute
- `max:number` specifies the maximum allowed value for numeric input
- `min:number` specifies the minimun allowed value for numeric input
- `multiline:boolean` if true returning textarea
- `name:string` input name
- `type:string` type attribute value
- `onChange:function` executed when input value changes
- `onEnter:function` executed when user clicks on input
- `onError:function` executed once an error event fires
- `onLeave:function` executed on click outside the input

```jsx
import { Input, View } from '@mirai/ui';

const MyComponent = () => (
  <View>
    <Input
      required
      minLength={8}
      placeholder="Input"
      value={primitive}
      test={(value) => value.includes('something')}
      onChange={() => console.log('change')}
      onError={(error) => console.log('Error:', error)}
    />
  </View>
);
```

**Theming variables**

```css
--mirai-ui-input-background: var(--mirai-ui-base);
--mirai-ui-input-color: var(--mirai-ui-content);
--mirai-ui-input-color-active: var(--mirai-ui-focus-color);
--mirai-ui-input-color-disabled: var(--mirai-ui-content-light);
--mirai-ui-input-shadow-active: var(--mirai-ui-focus-shadow);
--mirai-ui-input-shadow-active-error: 0 0 0 var(--mirai-ui-focus-width) var(--mirai-ui-error-border);
--mirai-ui-input-shadow-active-warning: 0 0 0 calc(var(--mirai-ui-focus-width) * 0.66) var(--mirai-ui-error-background);
--mirai-ui-input-shadow-active-success: 0 0 0 var(--mirai-ui-focus-width) var(--mirai-ui-success-border);
```

### Layer

This primitive returns an element that displays with relative position to other element based on the following props:

- `bottom:bool` if you want open the content below the reference component.
- `centered:bool` if you want center the content using screen as parent.
- `children:node` two children elements are accepted, the first one is the element to be displayed and the second one is the LayerContent that wraps the element to be displayed if the visible prop is true
- `fixed:bool` if you want use a fixed position instead of an absolute one, by default is `false`.
- `forceRender:bool` if you want render content children even if `visible` is _falsy_, by default is `true`.
- `left:bool` if you want open the content on the left of the reference component.
- `right:bool` if you want open the content on the right of the reference component.
- `timestamp:number` if you want to force render to recalculate the position of content, assign this property with a number (`Date.now()`).
- `top:bool` if you want open the content above the reference component.
- `visible:boolean` showing or hiding the layer
- `onPosition:boolean` called when the position of the layer is calculated or updated. It receives `orientation` argument, which is an object containing information about the layer's position with `top` and `left` properties

The position of the layer is based on the position of the element to be displayed. If the layer can show on right or left because have a gap in this direction, the layer will be shown on the right or left of the element to be displayed. If the layer can open on top or bottom because have a gap in this direction, the layer will be shown on the top or bottom of the element to be displayed

```jsx
import { Button, Calendar, Layer, LayerContent } from '@mirai/ui';

const MyComponent = () => {
  const [visible, setVisible] = useState(false);

  return (
    <Layer visible={visible}>
      <Button style={{ position: 'absolute', left: '500px', top: '100px' }} onPress={() => setVisible(!visible)}>
        {visible ? 'close' : 'open'}
      </Button>
      <LayerContent>
        <Calendar months={2} range />
      </LayerContent>
    </Layer>
  );
};
```

**Theming variables**

```css
--mirai-ui-layer-XS: -1;
--mirai-ui-layer-S: 0;
--mirai-ui-layer-M: 10;
--mirai-ui-layer-L: 100;
--mirai-ui-layer-XL: 10000;
--mirai-ui-layer-XXL: 100000;
--mirai-ui-layer-content: var(--mirai-ui-layer-XL);
```

### Pressable

This primitive returns pressable elements based on the following properties:

- `children:node`
- `disabled:boolean` disable attribute
- `preventDefault:boolean` if you want stop the event tunneling (default true).
- `tag:string` html tag applied to a primitive
- `onEnter:function` executed once the user hovers over the element
- `onLeave:function` executed once the user hovers away
- `onPress:function` executed on mouse click on the element

```jsx
import { Icon, Pressable, View } from '@mirai/ui';

const MyComponent = () => (
  <View>
    <Pressable onPress={() => console.log('clicked')}>
      <Icon name="Left" />
    </Pressable>
  </View>
);
```

### Radio

This primitive returns a radio button based on the following properties:

- `checked:boolean` if true, the radio button is checked
- `disabled:boolean` applying 'disabled' attribute
- `name:string` input name
- `value:string` input value
- `onChange:function` executed when input value changes

```jsx
import { Radio, View } from '@mirai/ui';

const MyComponent = () => (
  <View>
    <Radio
      name="radio"
      checked={false}
      disabled={false}
      value={primitive}
      onChange={() => console.log('change')
    />
  </View>
```

**Theming variables**

```css
--mirai-ui-radio-background: var(--mirai-ui-base);
--mirai-ui-radio-background-checked: var(--mirai-ui-accent);
--mirai-ui-radio-background-disabled: var(--mirai-ui-content-border);
--mirai-ui-radio-size: var(--mirai-ui-checkbox-size);
--mirai-ui-radio-size-mobile: var(--mirai-ui-checkbox-size-mobile);
```

### ScrollView

This primitive is used to make vertically scrollable views and receives the following props:

- `behavior:string` type of scroll animation
- `children:node`
- `height:number` height value
- `horizontal:boolean` layout direction
- `scrollEventThrottle:number` scroll timeout value
- `scrollIndicator:boolean` if true the scroll indicator is shown
- `scrollTo:number` coordinate to scroll to
- `snap:bool` if you want use the CSS feature `scroll-snap`
- `tag:string` html tag of resulting element
- `width:number` width value
- `onScroll:function` executed when user scrolls over the element

```jsx
import { ScrollView, View } from '@mirai/ui';

const MyComponent = ({ isDesktop }) => (
  <ScrollView horizontal={isDesktop} onScroll={() => console.log('scrolling')}>
    <View>Box 1</View>
    <View>Box 2</View>
  </ScrollView>
);
```

### Select

This primitive returns a select element and receives the following props:

- `disabled:boolean` applying 'disabled' attribute
- `disabledOptions:boolean[]` applying 'disabled' for an specific option
- `emptyOption:string` label for the empty default value (e.g. 'Select an option')
- `options:string[]` select options text and values
- `value:string` current value
- `onChange:function` executed when input value changes
- `onEnter` executed when select is focused
- `onError` executed when an error occurs
- `onLeave` executed when select loses

```jsx
import { Select } from '@mirai/ui';

const Example = (props) => {
  const [value, setValue] = useState('');

  const handleChange = (next, ...others) => {
    setValue(next);
  };

  return (
    <Select
      disabledOptions={[, true]}
      emptyOption="Select one option..."
      name="Select"
      options={['foo', 'bar']}
      value={value}
      onChange={handleChange}
    />
  );
};
```

### Switch

This primitive returns a _mobile_ checkbox button based on the following properties:

- `checked:boolean` if true, the checkbox button is checked
- `disabled:boolean` applying 'disabled' attribute
- `error:boolean` shows error style
- `name:string` input name (required)
- `onChange:function` executed when input value changes

```jsx
import { Switch } from '@mirai/ui';

const MyComponent = () => (
  <Switch
    name="checkbox"
    checked={false}
    disabled={false}
    onChange={() => console.log('change')}
  />
```

**Theming variables**

```css
--mirai-ui-switch-background: var(--mirai-ui-base);
--mirai-ui-switch-background-checked: var(--mirai-ui-accent);
--mirai-ui-switch-background-disabled: var(--mirai-ui-content-border);
--mirai-ui-switch-border-size: var(--mirai-ui-space-XXS);
--mirai-ui-switch-border-radius: var(--mirai-ui-space-L);
--mirai-ui-switch-size: var(--mirai-ui-space-M);
--mirai-ui-switch-size-mobile: calc(var(--mirai-ui-space-L) - var(--mirai-ui-space-XXS));
```

### Text

A primitive for displaying text. It receives the following props:

- `accent:boolean` use theme's accent color
- `accentDark:boolean` use theme's accent-dark color
- `accentLight:boolean` use theme's accent-light color
- `action:boolean` modifying font-size
- `bold:boolean` modifying font-weight
- `brand:boolean` use of the CSS variables `--mirai-ui-text-brand-*`
- `capitalize:boolean` capitalize the first word of a sentence
- `children:string`
- `dark:boolean` use theme's content-dark color
- `error:boolean` use theme's error color
- `headline:boolean` modifying font-size
- `info:boolean` use theme's info color
- `level:number` assign the level of heading (1, 2, 3 or 4)
- `light:boolean` use theme's content-light color
- `markdown:boolean` if true renders content as parsed markdown
- `medium:boolean` modifying font-weight
- `small:boolean` modifying font-size
- `success:boolean` use theme's success color
- `tag:string` html tag of resulting element
- `tiny:bool` modifying font-size
- `underline:boolean` use an underline text decoration
- `upperCase:boolean` switching text to upper case
- `warning:boolean` use theme's warning color
- `wide:boolean` specifies whether the component should have more width or not

```jsx
import { Text, View } from '@mirai/ui';

const MyComponent = ({ headerText }) => (
  <View>
    <Text bold upperCase headline>
      {headerText}
    </Text>
  </View>
);
```

### View

This primitive works as a container for displaying layout. It receives the following properties:

- `children:node`
- `fit:boolean` sets width CSS property as 'fit-content' if true
- `forceRow:boolean` forces the flex-direction as 'row' if true
- `row:boolean` sets flex-direction as 'row' or 'row-reverse' if true
- `tag:string` html tag of resulting element
- `wide:bool` modifying the button to full-width

```jsx
import { Text, View } from '@mirai/ui';

const MyComponent = ({ headerText }) => (
  <View row>
    <Text bold upperCase headline>
      {headerText}
    </Text>
    <View fit>Lorem ipsum very long text</View>
  </View>
);
```

## Components

React components assembled with primitives.

### Action

A hyperlink component that receives the following props:

- `bold:boolean` modifying font-weight
- `children:node|string`
- `disabled:boolean` applying 'disabled' attribute
- `href:string` applying 'href' attribute & force `a` tag
- `inline:boolean` modifying the button padding size
- `large:boolean` modifying the button size
- `small:boolean` modifying the button size
- `tag:string` html tag of resulting element ('button' by default)
- `target:boolean` applying 'target' attribute (in combination with `href:string`)
- `underline:boolean` use an underline text decoration
- `wide:bool` modifying the button to full-width
- `onEnter:function` executed when the user hovers over
- `onLeave:function` executed when the user hovers away
- `onPress:function` executed on mouse click on the element

```jsx
import { Action } from '@mirai/ui';

const MyComponent = (props) => {
  const handleActionClick = () => console.log('click');

  return (
    <>
      <Action large onPress={handleActionClick} />
    </>
  );
};
```

**Theming variables**

```css
--mirai-ui-action-color: var(--mirai-ui-accent);
--mirai-ui-action-color-disabled: var(--mirai-ui-content-light);
--mirai-ui-action-font-weight: var(--mirai-ui-font-weight);
```

### Button

A button component that receives the following props:

- `busy:bool` if `true` will disable button and give feedback as something is processing.
- `children:node|string`
- `disabled:boolean` applying 'disabled' attribute
- `fixed:bool` if you want use a fixed position for your tooltip, by default is `false`.
- `large:boolean` modifying the button size
- `secondary:boolean` modifying the button appearance using a secondary _variant_.
- `rounded:boolean` if true will use the theme border-radius variable for round the corners
- `small:boolean` modifying the button size
- `squared:boolean` if true gives rectangular shape to the button (false by default)
- `tag:string` html tag of resulting element ('button' by default)
- `tooltip:string` text it will appears when hover on component.
- `transparent:bool` modifying the button appearance using a transparent _variant_.
- `wide:bool` modifying the button to full-width
- `onEnter:function` executed when the user hovers over
- `onLeave:function` executed when the user hovers away
- `onPress:function` executed on mouse click on the element

```jsx
import { Button } from '@mirai/ui';

const MyComponent = (props) => {
  const handleButtonClick = () => console.log('click');

  return (
    <>
      <Button large onPress={handleButtonClick} />
    </>
  );
};
```

**Theming variables**

```css
--mirai-ui-button-background: var(--mirai-ui-accent);
--mirai-ui-button-background-active: var(--mirai-ui-focus-color);
--mirai-ui-button-busy-motion: calc(var(--mirai-ui-motion-expand) * 10);
--mirai-ui-button-busy-width: 0%;
--mirai-ui-button-color: var(--mirai-ui-base);
--mirai-ui-button-color-active: rgba(255, 255, 255, 0.2);
--mirai-ui-button-color-disabled: var(--mirai-ui-content-border);
--mirai-ui-button-disabled-color: var(--mirai-ui-content-light);
--mirai-ui-button-font-weight: var(--mirai-ui-font-medium-weight);
--mirai-ui-button-padding-x: var(--mirai-ui-space-L);
--mirai-ui-button-height: calc(var(--mirai-ui-space-XL) - var(--mirai-ui-space-XXS));
--mirai-ui-button-large-height: var(--mirai-ui-space-XL);
--mirai-ui-button-small-height: calc(var(--mirai-ui-space-XL) - var(--mirai-ui-space-M));
--mirai-ui-button-radius: var(--mirai-ui-border-radius);
--mirai-ui-button-secondary-background: var(--mirai-ui-base);
--mirai-ui-button-secondary-background-active: var(--mirai-ui-accent-background);
--mirai-ui-button-secondary-color: var(--mirai-ui-button-background);
--mirai-ui-button-secondary-color-active: var(--mirai-ui-focus-color);
--mirai-ui-button-transparent-background-active: var(--mirai-ui-accent-background);
--mirai-ui-button-transparent-color: var(--mirai-ui-content);
--mirai-ui-button-transparent-color-active: var(--mirai-ui-focus-color);
```

### Calendar

A calendar component that receives the following props:

- `allowSameDayRange:boolean` when `range` is enabled, allows selecting a one-day range by clicking the same day twice
- `autoScroll:boolean` specifies whether the calendar should automatically scroll to the selected date or the focused month
- `captions:object` captions to be placed into calendar cells
- `disabledDates:[string]` dates to be shown as unavailable and can't be selected
- `disabledPast:boolean` past dates to be shown as unavailable and can't be selected
- `format:string` date display format (e.g. "DD/MM/YYYY")
- `from:string` date in specific format (e.g. "31/03/2022")
- `highlights:[string]` highlights a determinate group of dates
- `l10n:object` change button's text for load more dates
- `locale:string` locale value
- `months:number` number of months to be visible
- `range:boolean` Enable range selection
- `rangeMaxDays:number` Maximum days in a range
- `rangeMinDays:number` Minimum days in a range
- `to:string` date in specific format (e.g. "31/03/2022")
- `tooltips:object` tooltips to be placed into calendar cells
- `value:string|[string]` when `range` is enabled, same-day ranges are represented as `[from, to]` with both dates equal
- `onChange:function` executed when input value changes
- `onFocus:function` executed on calendar cell hover
- `onNavigation:function` executed when move to the next/previous months
- `onScroll:function` executed when user scrolls the calendars container (only available in mobile environments)

```jsx
import { Calendar } from '@mirai/ui';

const MyComponent = props => {
  const [value, setValue] = useState([]);
  const [from, to] = value;

  return (
    <Calendar
      captions={
          '2022/03/31': '10.95$',
          '2022/04/18': '510.95$',
          '2022/04/20': '10.95$',
          '2022/04/24': '9.95$',
      }
      disabledDates={['2022/04/14', '2022/04/25', '2022/04/29', '2022/04/30']}
      format="DD/MM/YYYY"
      months={2}
      from={from}
      to={to}
      tooltips={
        '2022/03/31':  { text: '' },
        '2022/04/20': { text: '10.95$' },
      }
      onChange={setValue}
    />
  );
}
```

**Theming variables**

```css
--mirai-ui-calendar-caption-color: var(--mirai-ui-content-light);
--mirai-ui-calendar-cell: var(--mirai-ui-space-XL);
--mirai-ui-calendar-cell-border-radius: var(--mirai-ui-border-radius);
--mirai-ui-calendar-color-active: var(--mirai-ui-accent);
--mirai-ui-calendar-padding: var(--mirai-ui-space-XS);
--mirai-ui-calendar-range-background: var(--mirai-ui-content-background);
--mirai-ui-calendar-selected-background: var(--mirai-ui-accent);
--mirai-ui-calendar-selected-color: var(--mirai-ui-base);
--mirai-ui-calendar-weekday-color: var(--mirai-ui-content-light);
```

### Form

Component that unites various inputs of different types into a single form. It receives the following props:

- `children:node` elements to be rendered within the form
- `debounce:number` the delay before triggering the onChange callback after the form values have changed (0 by default)
- `schema:object` defines validation schema for the form fields. Maps field names to their respective validation rules
- `showErrors:boolean` indicates whether to display the validation errors for the form fields
- `tag:string` HTML tag name to be used for rendering the form element ('form' by default)
- `validateOnMount:boolean` indicates whether to perform validation on form mount
- `onChange:function` executed when any field value changes
- `onEnter:function` when a form field gets focus
- `onError:function` executed when one or more fields have errors
- `onLeave:function` executed when a form field loses focus
- `onSubmit:function` executed when the form is submitted

```jsx
import { Button, Form, InputDate, InputText } from '@mirai/ui';

const Example = (props) => {
  const [condition, setCondition] = useState(false);
  const [form, setForm] = useState({
    email: 'javi@mirai.com',
    dateOfBirth: '04/10/1980',
  });
  const [error, setError] = useState({});

  const handleChange = (next, ...others) => setForm(next);

  const handleEnter = (...others) => console.log('<Form>::onEnter', ...others);

  const handleError = (next, ...others) => setError(next);

  const handleLeave = (...others) => console.log('<Form>::onLeave', ...others);

  const handleSubmit = (...others) => console.log('<Form>::onSubmit', ...others);

  return (
    <Form
      {...props}
      onChange={handleChange}
      onEnter={handleEnter}
      onError={handleError}
      onLeave={handleLeave}
      onSubmit={handleSubmit}
    >
      <InputText
        name="email"
        error={!!error.email}
        test={(value) => value.includes('@mirai.com')}
        label="Email"
        hint="Should contains @mirai.com"
        required
        type="email"
        value={form.email}
      />
      <InputDate
        name="dateOfBirth"
        error={!!error.dateOfBirth}
        label="Your birthdate"
        max="31/12/2022"
        min="10/04/1980"
        required
        type="inputDate"
        value={form.dateOfBirth}
      />

      <Button disabled={Object.keys(error).length !== 0} type="submit" wide>
        Submit
      </Button>
    </Form>
  );
};
```

### InputDate

Input date component that receives the following props:

- `format:string` date format to be applied ('DD/MM/YYYY' by default)
- `max:string` maximum date value allowed
- `min:string` minimum date value allowed
- `placeholder:bool` indicated whether to show placeholder with format or not
- `value:string` current value
- `onChange:function` executed when the value is changed
- `onError:function` executed when there's an error

```jsx
import { InputDate } from '@mirai/ui';

const Example = ({ value: propValue, ...props }) => {
  const [value, setValue] = useState(propValue);

  const handleChange = (next, ...others) => {
    setValue(next);
  };

  const handleError = (...others) => console.log('<InputDate>::onError', ...others);

  return (
    <InputDate
      format="MM/DD/YYYY"
      min="03/20/2023"
      max="03/20/2028"
      value={value}
      onChange={handleChange}
      onError={handleError}
    />
  );
};
```

### InputList

A custom select input component that receives the following props:

- `caption:string` a support text (Ex. currency symbol)
- `disabled:boolean` applying 'disabled' attribute
- `emptyOption:string` label used to clear current selection in single mode (shown only when a value is selected and input is not required)
- `error:boolean` indicating whether there is an error in the input
- `hint:string` text with additional info to be displayed below the input
- `icon:string` if you want use an `<Icon>` within the component
- `multiple:bool` if you want select more than one option
- `label:string` label text
- `maxVisibleOptions:number` maximum number of visible options before the menu becomes scrollable. Default value is `5`
- `name:string` - required prop, input name
- `showRequired:boolean` indicating whether the "required" indicator should be shown
- `showState:boolean` indicating whether to show the state icons for errors, success, and warning
- `success:boolean` indicating whether the input has a success state
- `warning:boolean` indicating whether the input has a warning state
- `onChange:function` executed when input value changes
- `onEnter:function` executed when input gets focus
- `onError:function` executed when there are validation errors in the input
- `onLeave:function` executed when input loses focus

```jsx
import { InputList } from '@mirai/ui';

const Example = (props) => {
  const [value, setValue] = useState(2);

  const handleChange = (next, ...others) => {
    setValue(next);
  };

  const handleEnter = (...others) => console.log('<InputList>::onEnter', ...others);
  const handleLeave = (...others) => console.log('<InputList>::onLeave', ...others);

  return (
    <InputList
      emptyOption="Select one option..."
      hint="hint"
      label="label"
      maxVisibleOptions={6}
      name="name"
      options={[
        { name: 'One', description: 'Number one', value: 1 },
        { name: 'Two', description: 'Number two', value: 2 },
        { name: 'Three', description: 'Number three', value: 3 },
        { name: 'Four', description: 'Number four', value: 4 },
      ]}
      value={value}
      onChange={handleChange}
      onEnter={handleEnter}
      onLeave={handleLeave}
    />
  );
};
```

### InputNumber

Input number component controlling the value with 2 buttons. Receives the following props:

- `disabled:bool` applying 'disabled' attribute
- `hint:string` brief message
- `label:string` input label
- `max:number` maximum input value
- `min:number` minimum input value
- `name:string` input name attribute (required)
- `rounded:bool` if you want use the `rounded` property of `<Button>`
- `showRequired:bool` displays `*` next to the label
- `step:number` to be added/subtracted from value on each button click
- `value:number` input value
- `onChange:function` executed when input value changes

```jsx
import { InputNumber } from '@mirai/ui';

const MyComponent = (props) => {
  const [number, setNumber] = useState(1);

  return <InputNumber min={1} name="candies" label="Candies" value={number} onChange={(next) => setNumber(next)} />;
};
```

**Theming variables**

```css
--mirai-ui-input-number-value-width: var(--mirai-ui-space-XL);
```

### InputOption

This component is used to display a radio button or checkbox base on a mandatory string prop `type`. It receives the following props:

- `checked:boolean` if true, the input is checked
- `disabled:boolean` applying 'disabled' attribute
- `error:boolean` shows error style
- `indeterminate:boolean` applying 'indeterminate' attribute (only for type checkbox)
- `label:string` input label
- `name:string` input name
- `showRequired:bool` displays `*` next to the label
- `small:bool` modifying font-size
- `type:string` type of input (radio or checkbox)
- `value:number` input value
- `onChange:function` executed when input value changes

```jsx
import { InputOption, View } from '@mirai/ui';

const MyComponent = () => {
  const [value, setValue] = useState('');
  const [checked, setChecked] = useState(false);
  return (
    <View>
      <InputOption
        type="radio"
        label="Option 1"
        name="option"
        checked={value === 'radio1'}
        disabled={false}
        value="radio1"
        onChange={() => useState('radio1')}
      />
      <InputOption
        type="radio"
        label="Option 2"
        name="option"
        checked={value === 'radio2'}
        disabled={false}
        value="radio2"
        onChange={() => useState('radio2')}
      />
    </View>
    <View>
      <InputOption
        type="checkbox"
        label="Option 3"
        name="optionCheckbox"
        checked={checked}
        disabled={false}
        onChange={() => useChecked(!checked)}
      />
    </View>
  );
};
```

**Theming variables**

```css
--mirai-ui-input-option-gap: var(--mirai-ui-space-XS);
--mirai-ui-input-option-margin-bottom: var(--mirai-ui-space-M);
```

### InputPhone

Input element for phone numbers that receives the following props:

- `disabled:boolean` applying 'disabled' attribute
- `error:boolean` indicating whether there is an error in the input
- `hint:string` text with additional info to be displayed below the input
- `icon:function` icon component to be displayed before the input
- `label:string` label text for the phone number part
- `labelPrefix:string` label text for the country code part
- `name:string` - required prop, input name
- `prefixes:string[]` available country codes
- `showRequired:boolean` indicating whether the "required" indicator should be shown
- `showState:boolean` indicating whether to show the state icons for errors, success, and warning
- `success:boolean` indicating whether the input has a success state
- `value:string` current value
- `warning:boolean` indicating whether the input has a warning state
- `onChange:function` executed when input value changes
- `onEnter:function` executed when input gets focus
- `onError:function` executed when there are validation errors in the input
- `onLeave:function` executed when input loses focus

```jsx
import { InputPhone } from '@mirai/ui';

export const Story = (props) => {
  const [value, setValue] = useState('+34 123456789');

  const handleChange = (next, ...others) => {
    setValue(next);
  };

  const handleError = (...others) => console.log('<InputSelect>::onError', ...others);

  return (
    <InputPhone
      hint="hint"
      label="Phone Number"
      labelPrefix="Code"
      name="name"
      prefixes={['+34', '+44', '+001', '+999', '+39', '+56']}
      required
      value={value}
      onChange={handleChange}
      onError={handleError}
    />
  );
};
```

### InputSelect

A select input component that receives the following props:

- `caption:string` a support text (Ex. currency symbol)
- `disabled:boolean` applying 'disabled' attribute
- `error:boolean` indicating whether there is an error in the input
- `hint:string` text with additional info to be displayed below the input
- `icon:string` if you want use an `<Icon>` within the component
- `label:string` label text
- `name:string` - required prop, input name
- `showRequired:boolean` indicating whether the "required" indicator should be shown
- `showState:boolean` indicating whether to show the state icons for errors, success, and warning
- `success:boolean` indicating whether the input has a success state
- `warning:boolean` indicating whether the input has a warning state
- `onChange:function` executed when input value changes
- `onEnter:function` executed when input gets focus
- `onError:function` executed when there are validation errors in the input
- `onLeave:function` executed when input loses focus

```jsx
import { InputSelect } from '@mirai/ui';

const Example = (props) => {
  const [value, setValue] = useState('two');

  const handleChange = (next, ...others) => {
    setValue(next);
  };

  const handleEnter = (...others) => console.log('<InputSelect>::onEnter', ...others);
  const handleLeave = (...others) => console.log('<InputSelect>::onLeave', ...others);

  return (
    <InputSelect
      hint="hint"
      label="label"
      name="name"
      options={['one', 'two', 'three', 'four', 'five']}
      value={value}
      onChange={handleChange}
      onEnter={handleEnter}
      onLeave={handleLeave}
    />
  );
};
```

### InputText

Text input component receiving the following props:

- `caption:string` a support text (Ex. currency symbol)
- `disabled:boolean` applying 'disabled' attribute
- `error:boolean` shows error style
- `hint:string` brief message
- `icon:string` if you want use an `<Icon>` within the component
- `label:string` input label
- `markdown:boolean` if true shows a preview of your markdown text
- `multiline:boolean` if true returning textarea
- `name:string` input name (required)
- `showRequired:bool` displays `*` next to the label
- `showState:bool` displays state of input (error, warning or success)
- `success:bool` sets success state
- `type:string` input type attribute
- `warning:bool` sets warning state
- `onChange:function` executed when input value changes
- `onEnter:function` executed when user clicks on input
- `onLeave:function` executed on click outside the input

```jsx
import { InputText } from '@mirai/ui';

const MyComponent = (props) => {
  const [text, setText] = useState();

  return (
    <InputText
      name="text"
      hint="hint"
      label="My epic input"
      placeholder="Some epic text"
      type="text"
      value={text}
      onChange={(next) => setText(next)}
    />
  );
};
```

**Theming variables**

```css
--mirai-ui-input-text-border: solid var(--mirai-ui-border-width) var(--mirai-ui-content-border);
--mirai-ui-input-text-color-active: var(--mirai-ui-content);
--mirai-ui-input-text-color-disabled: var(--mirai-ui-content-border);
--mirai-ui-input-text-icon-size: var(--mirai-ui-font-size-headline-3);
--mirai-ui-input-text-margin-bottom: var(--mirai-ui-space-M);
--mirai-ui-input-text-padding-x: var(--mirai-ui-space-M);
--mirai-ui-input-text-padding-y: var(--mirai-ui-space-XS);
--mirai-ui-input-text-radius: var(--mirai-ui-border-radius);
```

### Menu

This component helps you to create a menu over a determinate component receiving the following props:

- `children:node` The element which we will use as reference for display the menu.
- `header:node` Optional static content rendered above options (outside the scrollable options area).
- `options:arrayOf(Option:shape)`
- `selected:string|number` if you want highlight one of the options
- `Template:node` if you don't want use the default option scaffold.
- `title:string` shows a title for the modal
- `visible:boolean` showing or hiding the menu
- `onPress:func` callback when we click on a determinate _option_.

Before learning how to instantiate `<Menu>` let's look at the properties of our _shape_ `Option`:

- `children:node` If you wanna add a component in the right side of your option.
- `disabled:boolean` disables the option
- `divider:boolean` if you wanna show a divider in the bottom of the option
- `icon:string` If you want instantiate a primitive `<Icon>`
- `label:string` label of the option
- `value:string|number` this property will dispatch as identificator in the callback `onPress:func`

```jsx
import { Button, Icon, Menu } from '@mirai/ui';

const MyComponent = () => {
  const [visible, setVisible] = useState(false);

  <Menu
    header={<View>Search...</View>}
    options={[
      { icon: 'EyeOpen', label: 'Show results', value: 1 },
      { icon: 'Add', label: 'Add item', disabled: true, value: 2 },
      { icon: 'Remove', label: 'Remove item', divider: true, value: 'three' },
      { label: 'Using child', children: <Button small>Add</Button>, value: 'four' },
    ]}
    visible={visible}
    onPress={(value, event) => console.log('<Menu>::onPress', value, event)}
  >
    <Button squared secondary onPress={() => setVisible(!visible)}>
      <Icon name="Add" />
    </Button>
  </Menu>;
};
```

**Theming variables**

```css
--mirai-ui-menu-background: var(--mirai-ui-base);
--mirai-ui-menu-border-radius: var(--mirai-ui-border-radius);
--mirai-ui-menu-min-width: calc(var(--mirai-ui-breakpoint-S) / 2);
--mirai-ui-menu-option-background-active: var(--mirai-ui-content-background);
--mirai-ui-menu-option-color-active: var(--mirai-ui-content);
--mirai-ui-menu-option-color-disabled: var(--mirai-ui-content-border);
--mirai-ui-menu-option-selected-background: var(--mirai-ui-accent);
--mirai-ui-menu-option-selected-color: var(--mirai-ui-base);
--mirai-ui-menu-shadow: var(--mirai-ui-shadow);
```

### Modal

A modal component receiving the following props:

- `blur:bool` if you want use a _glashmorphism_ effect in the overflow
- `children:node`
- `fit:bool` if you want use fit width with the content
- `forceRender:bool` if you want to load the children even if the modal is not visible
- `mobileBehavior:bool` if you want use mobile behavior
- `overflow:bool` wraps all modal in a semi-transparent layer
- `portal:bool` if you want use _portal feature_ of React API
- `preventDefault:bool` if you want stop the event tunneling (default true)
- `title:string` shows a title for the modal
- `visible:boolean` if true modal is shown
- `onBack:function` executed once back button is touched
- `onClose:function` executed once close button is touched
- `onOverflow:function` executed once overflow is touched

```jsx
import { Modal, View } from '@mirai/ui';

const MyComponent = (props) => {
  const [visible, setVisible] = useState(false);

  return (
    <Modal visible={visible} onClose={() => setVisible(false)}>
      <View>Some modal text</View>
    </Modal>
  );
};
```

**Theming variables**

```css
--mirai-ui-modal-background: var(--mirai-ui-base);
--mirai-ui-modal-border-radius: calc(var(--mirai-ui-border-radius) * 2);
--mirai-ui-modal-header-padding: var(--mirai-ui-space-M);
--mirai-ui-modal-icon: var(--mirai-ui-font-size-headline-2);
--mirai-ui-modal-layer: var(--mirai-ui-layer-XL);
--mirai-ui-modal-overflow-background: rgba(72, 72, 72, 0.2);
--mirai-ui-modal-shadow: var(--mirai-ui-shadow);
```

### Notification

A component that displays a notification message with optional icons and close button and receives the following props:

- `children:bool` required prop, the content of the notification (any valid React node)
- `contrast:bool` indicanting wheter the notification as tooltip
- `error:bool` indicating whether the notification represents an error message with corresponding styles
- `info:bool` indicating whether the notification represents an informational message
- `inline:bool` indicating whether the notification should be displayed inline
- `large:bool` indicating whether the notification should be displayed in a large size
- `small:bool` indicating whether the notification should be displayed in a small size
- `success:bool` indicating whether the notification represents a success message with corresponding styles
- `warning:bool` indicating whether the notification represents a warning message with corresponding styles
- `wide:bool` indicating whether the notification should be displayed in a wide format
- `onClose:function` executed when the close button is clicked

```jsx
import { Notification } from '@mirai/ui';

const Example = (props) => (
  <Notification error large wide onClose={() => console.log('Closing...')}>
    Something went wrong...
  </Notification>
);
```

**Theming variables**

```css
--mirai-ui-notification-border-radius: var(--mirai-ui-border-radius);
--mirai-ui-notification-padding: var(--mirai-ui-space-S);
--mirai-ui-notification-large-padding: var(--mirai-ui-space-M);
--mirai-ui-notification-small-padding: var(--mirai-ui-space-XS);
```

### Progress

A progress component receiving the following props:

- `indeterminate:bool` express an unspecified amount of wait time.
- `value:number` value of percentage
- `visible:boolean` if true progress is shown

```jsx
import { Progress } from '@mirai/ui';

const MyComponent = (props) => {
  const [visible, setVisible] = useState(false);

  return <Progress indeterminate visible={visible} />;
};
```

**Theming variables**

```css
--mirai-ui-progress-background: var(--mirai-ui-content-background);
--mirai-ui-progress-color: var(--mirai-ui-accent);
--mirai-ui-progress-height: var(--mirai-ui-space-XS);
--mirai-ui-progress-motion: calc(var(--mirai-ui-motion-expand) * 3);
```

### Slider

A Slider component receiving the following props:

- `auto:bool` if you want auto slide feature (default is false).
- `behavior:string` type of scroll animation
- `captions:arrayOf:string` if you want show a determinate caption for a determinate image.
- `counter:bool` show counter
- `fullScreen:boolean` if you want start in fullScreen mode.
- `height:number` Height of component (required).
- `images:arrayOf:string` images to show (required).
- `index:number` If you want show a determinate image at atart.
- `indicator:boolean` if true shows the amount of pictures viewed using a progress component.
- `replay:boolean` restart slider when we go forwards after the last image
- `scrollDelay:number` delay in milliseconds before scrolling to next image
- `showButtons:boolean` if true shows the buttons
- `thumbnails:arrayOf:string` if you want use thumbnails of images in fullScreen mode.
- `width:number` width of component (required).
- `onChange:function` executed when image (index) is visible
- `onCounter:function` show a pressable counter

```jsx
import { Slider } from '@mirai/ui';

const MyComponent = (props) => {

  return <Slider height={320} images={[...]} width={480} />;
};
```

**Theming variables**

```css
--mirai-ui-slider-button-background: var(--mirai-ui-base);
--mirai-ui-slider-icon-color: var(--mirai-ui-content);
--mirai-ui-slider-overlay: rgba(0, 0, 0, 0.66);
--mirai-ui-slider-overlay-color: var(--mirai-ui-base);
--mirai-ui-slider-border-radius: var(--mirai-ui-border-radius);
```

### Table

This component helps you to create a pure html table receiving the following props:

- `dataSource:arrayOf(shape)` datasource of your model data schema
- `filter:object[]` array of filter items that are applied to the table data. Each filter item represents a specific filter configuration.
- `inline:bool` specifies whether the table should be displayed inline
- `schema:shape` the model data schema
- `pagination:number` the number of rows you will paginate
- `search:string` the query string you want use for filter the datasource
- `selected:arrayOf(dataSource.row)` if you want pre-select some rows in 1st render
- `showEmpty:bool` when true, shows an empty-state row if there are no filtered results
- `sort:bool` specifies whether the table can be sorted or not
- `store:string` if you want use storage feature for some features of your table (ex. keep the current filters).
- `onPress:function` executed once press in any row
- `onScroll:function` executed once scroll the table
- `onSelect:function` executed once select a determinate row

```jsx
import { InputText, Table } from '@mirai/ui';

const dataSource = [
  { username: 'jose', email: 'jose@mirai.com', year: 2012 },
  { username: 'mario/1', email: 'mario.1@mirai.com', year: 2005 },
  { username: 'carlos', email: 'carlos@mirai.com', year: 2012 },
  { username: 'svet', email: 'svet@mirai.com', year: 2021, action: <Button>View</Button> },
  { username: 'javi', email: 'hi@soyjavi.com', year: 2022, twitter: 'soyjavi' },
  { username: 'victor', email: 'victor@mirai.com', year: 2021 },
  {
    username: 'mario/2',
    email: 'mario.2@mirai.com',
    year: 2022,
    tags: ['en', 'jp'].map((language) => <Text>{language}</Text>),
    languages: ['en', 'jp'],
  },
];

const schema = {
  username: { label: 'User Name', type: 'text' },
  email: { label: 'Email' },
  year: { label: 'Year', type: 'number' },
  twitter: { label: 'Twitter' },
  action: { label: 'Action', type: 'component' },
  tags: { label: 'Tags', type: 'component', bind: 'languages' },
  languages: { label: 'Languages', type: 'hidden' },
};

const MyComponent = () => {
  const [visible, setVisible] = useState(false);

  <>
    <InputText name="search" type="search" label="Search..." value={search} onChange={setSearch} />

    <Table
      {...{ dataSource, schema, search }}
      selected={[dataSource[4]]}
      onPress={(row) => console.log('::onPress::', row)}
      onSelect={(row) => console.log('::onSelect::', row)}
      onScroll={(event) => console.log('::onScroll::', event)}
      className={style.scrollview}
    />
  </>;
};
```

**Theming variables**

```css
--mirai-ui-table-background: var(--mirai-ui-base);
--mirai-ui-table-border-color: var(--mirai-ui-content-border);
--mirai-ui-table-border-radius: var(--mirai-ui-space-XS);
--mirai-ui-table-color: var(--mirai-ui-content);
--mirai-ui-table-color-disabled: var(--mirai-ui-content-border);
--mirai-ui-table-padding-x: var(--mirai-ui-space-M);
--mirai-ui-table-padding-y: var(--mirai-ui-space-M);
--mirai-ui-table-selected-background: var(--mirai-ui-content-background);
--mirai-ui-table-selected-color: var(--mirai-ui-content);
```

### Tooltip

This component helps you to create a tooltip over a determinate component receiving the following props:

- `children:node` The element which we will use as reference for display the menu.
- `left:bool` positioning of the tooltip relative to its parent element
- `pressable:bool` Change event dispatcher to `onPress` instead of ` onEnter`.
- `right:bool` positioning of the tooltip relative to its parent element
- `Template:node` if you don't want use the default scaffold.
- `text:string` text it will appears when hover on `children`.
- `timestamp:number` value used to force render to recalculate the position of the tooltip
- `top:bool` Change the position to the top of reference element.
- `visible:boolean` the default state of visibility of the instance.

```jsx
import { Text, Tooltip } from '@mirai/ui';

const MyComponent = () => {
  const [visible, setVisible] = useState(false);

  <Tooltip text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. ">
    <Text bold>hover me</Text>
  </Tooltip>;
};
```

**Theming variables**

```css
--mirai-ui-tooltip-background: var(--mirai-ui-content-dark);
--mirai-ui-tooltip-border-radius: var(--mirai-ui-border-radius);
--mirai-ui-tooltip-color: var(--mirai-ui-base);
--mirai-ui-tooltip-space: var(--mirai-ui-space-XS);
--mirai-ui-tooltip-max-width: calc(var(--mirai-ui-space-XXL) * 4);
```

## Theme

Styles can be customised by using Theme utility.

### get()

This method returns current theme settings (variables with values). This method receives as an optional parameter a string with a prefix (domain) to specify the scope ('--mirai-ui-' by default);

### setVariable(variable, value, domain)

This method sets a value of the variable passed as a parameter.

```jsx
import { Button, Text, Theme } from '../../src';

export default () => {
  const [theme, setTheme] = useState(Theme.get());

  const handlePress = () => {
    Theme.setVariable('base', '#222');
    Theme.setVariable('content', '#fff');
    Theme.setVariable('font', 'courier');
    Theme.setVariable('accent', '#f0f');
    setTheme(Theme.get());
  };

  const { accent, spaceXL } = Theme.get();

  return (
    <>
      <Button style={{ marginTop: spaceXL, color: accent }} onPress={handlePress}>
        Change Theme
      </Button>
    </>
  );
};
```

### shadeColors

This method helps you to create a color palette for the `accent` color of your theme. For example if in our theme we have `--mirai-ui-accent: #3978c5`:

```js
Theme.shadeColors()
>> ACCENT:400 #61a0ed
   ACCENT:300 #89c8ff
   ACCENT:200 #edffff
```

### getDirection

This method helps you to know which is the current direction of your theme. Let's see how we can use it:

```js
Theme.getDirection();
>> 0 (DIRECTION_TYPE.LEFT)
>> 1 (DIRECTION_TYPE.RIGHT)
```

### setDirection

This method helps you to set direction variables of your theme. This is pretty useful when you have different languages and your texts should be written in different directions. Let's see how we can use it:

```js
import { DIRECTION_TYPE } from '@mirai/ui';

Theme.setDirection(DIRECTION_TYPE.RIGHT);
>> 1 (DIRECTION_TYPE.RIGHT)
```

### List of Theming variables

```css
/* typography */
--mirai-ui-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif,
  'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
--mirai-ui-input-font: var(--mirai-ui-font);
--mirai-ui-font-weight: 400;
--mirai-ui-font-bold: var(--mirai-ui-font);
--mirai-ui-font-bold-weight: 700;
--mirai-ui-font-size-headline-1: 32px;
--mirai-ui-line-height-headline-1: 40px;
--mirai-ui-font-size-headline-2: 24px;
--mirai-ui-line-height-headline-2: 32px;
--mirai-ui-font-size-headline-3: 20px;
--mirai-ui-line-height-headline-3: 24px;
--mirai-ui-font-size-paragraph: 16px;
--mirai-ui-line-height-paragraph: 20px;
--mirai-ui-font-size-action: 14px;
--mirai-ui-line-height-action: 18px;
--mirai-ui-font-size-small: 12px;
--mirai-ui-line-height-small: 16px;
--mirai-ui-font-size-tiny: 10px;
--mirai-ui-line-height-tiny: 12px;
--mirai-ui-text-direction: ltr;
--mirai-ui-text-align: left;

/* palette */
--mirai-ui-base: #ffffff;

--mirai-ui-content: #484848;
--mirai-ui-content-background: #f6f6f6;
--mirai-ui-content-border: #dedede;
--mirai-ui-content-light: #6e6e6e;
--mirai-ui-content-dark: #202020;

--mirai-ui-accent: #3978c5;
--mirai-ui-accent-background: #e9f1fc;
--mirai-ui-accent-border: #b0c9e8;
--mirai-ui-accent-light: #88aedc;
--mirai-ui-accent-dark: #224876;

--mirai-ui-error: #d32f2f;
--mirai-ui-error-background: #fdeded;
--mirai-ui-error-border: #fad6d6;

--mirai-ui-warning: #663c00;
--mirai-ui-warning-background: #fff4e5;
--mirai-ui-warning-border: #ffe5c2;

--mirai-ui-success: #1e4620;
--mirai-ui-success-background: #edf7ed;
--mirai-ui-success-border: #d5ecd5;

--mirai-ui-info: #014361;
--mirai-ui-info-background: #e6f5fd;
--mirai-ui-info-border: #c6e8fa;

/* spacing */
--mirai-ui-space-XXS: 4px;
--mirai-ui-space-XS: 8px;
--mirai-ui-space-S: 12px;
--mirai-ui-space-M: 16px;
--mirai-ui-space-L: 24px;
--mirai-ui-space-XL: 48px;
--mirai-ui-space-XXL: 64px;

/* breakpoints */
--mirai-ui-breakpoint-S: 480px;
--mirai-ui-breakpoint-M: 1180px;
--mirai-ui-breakpoint-content: 1280px;

/* motion */
--mirai-ui-motion-collapse: 200ms;
--mirai-ui-motion-expand: 300ms;
--mirai-ui-motion-easing: cubic-bezier(0.1, 0.1, 0.25, 0.9);

/* input */
--mirai-ui-input-font-size: var(--mirai-ui-font-size-paragraph);
--mirai-ui-input-min-height: var(--mirai-ui-space-XL);

/* border */
--mirai-ui-border-radius: 4px;
--mirai-ui-border-width: 1px;

/* shadow */
--mirai-ui-shadow: 0 0 var(--mirai-ui-space-S) rgba(0, 0, 0, 0.1);

/* focus */
--mirai-ui-focus-color: var(--mirai-ui-accent-dark);
--mirai-ui-focus-color-shadow: var(--mirai-ui-accent-border);
--mirai-ui-focus-width: var(--mirai-ui-space-XXS);
--mirai-ui-focus-shadow: 0 0 0 var(--mirai-ui-focus-width) var(--mirai-ui-focus-color-shadow);
```

## Hooks

a repository of hooks which will help you create simpler solutions.

### useDevice

This _hook_ can help you know what type of device your application or component is running on. Lets see the properties that this _hook_ is going to expose for you:

<!-- screen -->

- `height:number` height resolution of device
- `width:number` width resolution of device
<!-- navigator -->
- `userAgent:string` type of browser's user agent
- `chrome:bool` using chrome browser
- `firefox:bool` using firefox browser
- `inApp:bool` using an application browser such as Facebook, Twitter..
- `mobile:bool` using a mobile browser
- `safari:bool` using safari browser
- `touch:bool` touch screen capability
<!--  orientation -->
- `isLandscape:bool` orientation is landscape
- `isPortrait:bool` orientation is portrait
<!-- type -->
- `isMobile:bool` is in the mobile breakpoint (<=480)
- `isTable:bool` is in the mobile breakpoint (>480px && <=1180px)
- `isDesktop:bool` in in the desktop breakpoint (>1180px)

Let's see a simple use of the hook:

```jsx
const component = () => {
  const { isPortrait, isDesktop } = useDevice();

  return <div classname={styles(style.container, isPortrait && isDesktop && style.mobileApp)} />;
};
```