npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@mirai/ui

v2.1.9

Published

> React components library.

Downloads

1,157

Readme

💾 @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
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

--mirai-ui-checkbox-base: var(--mirai-ui-base);
--mirai-ui-checkbox-border-color: var(--mirai-ui-content-light);
--mirai-ui-checkbox-border-radius: var(--mirai-ui-border-radius);
--mirai-ui-checkbox-checked: var(--mirai-ui-accent);
--mirai-ui-checkbox-disabled: var(--mirai-ui-content-border);
--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
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
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

--mirai-ui-input-background: var(--mirai-ui-base);
--mirai-ui-input-color: var(--mirai-ui-content);
--mirai-ui-input-disabled: var(--mirai-ui-content-light);

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

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

--mirai-ui-layer-content: var(--mirai-ui-layer-XL);
--mirai-ui-layer-XS: -1;
--mirai-ui-layer-S: 0;
--mirai-ui-layer-M: 1;
--mirai-ui-layer-L: 10;
--mirai-ui-layer-XL: 100;

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

--mirai-ui-radio-base: var(--mirai-ui-base);
--mirai-ui-radio-border: var(--mirai-ui-content-light);
--mirai-ui-radio-checked: var(--mirai-ui-accent);
--mirai-ui-radio-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
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
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
import { Switch } from '@mirai/ui';

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

Theming variables

--mirai-ui-switch-base: var(--mirai-ui-base);
--mirai-ui-switch-border-color: var(--mirai-ui-content-light);
--mirai-ui-switch-border-size: var(--mirai-ui-space-XXS);
--mirai-ui-switch-border-radius: var(--mirai-ui-space-L);
--mirai-ui-switch-checked: var(--mirai-ui-accent);
--mirai-ui-switch-disabled: var(--mirai-ui-content-border);
--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
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
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
import { Action } from '@mirai/ui';

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

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

Theming variables

--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
import { Button } from '@mirai/ui';

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

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

Theming variables

--mirai-ui-button-background: var(--mirai-ui-accent);
--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-disabled-background: var(--mirai-ui-content-border);
--mirai-ui-button-disabled-color: var(--mirai-ui-content-light);
--mirai-ui-button-focus-color: var(--mirai-ui-focus-color);
--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-focus-color: var(--mirai-ui-button-focus-color);
--mirai-ui-button-secondary-focus-color-shadow: var(--mirai-ui-focus-color-shadow);
--mirai-ui-button-transparent-background-active: var(--mirai-ui-accent-background);
--mirai-ui-button-transparent-color: var(--mirai-ui-content);

Calendar

A calendar component that receives the following props:

  • 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
  • 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]
  • 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)
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

--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-highlight-color: 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);
--mirai-ui-calendar-week-margin: 2px;

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
import { Button, Form, InputDate, InputText } from '@mirai/ui';

const Example = (props) => {
  const [condition, setCondition] = useState(false);
  const [form, setForm] = useState({
    email: '[email protected]',
    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
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}
    />
  );
};

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

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

--mirai-ui-input-option-disabled: var(--mirai-ui-content-light);
--mirai-ui-input-option-gap-x: var(--mirai-ui-space-XS);
--mirai-ui-input-option-gap-y: 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
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
  • 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
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
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

--mirai-ui-input-text-border: solid var(--mirai-ui-border-width) var(--mirai-ui-content-border);
--mirai-ui-input-text-disabled: var(--mirai-ui-content-border);
--mirai-ui-input-text-error: var(--mirai-ui-error);
--mirai-ui-input-text-focus: var(--mirai-ui-content);
--mirai-ui-input-text-gap: var(--mirai-ui-space-M);
--mirai-ui-input-text-icon: var(--mirai-ui-font-size-headline-3);
--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.
  • options:arrayOf(Option:shape)
  • 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
import { Button, Icon, Menu } from '@mirai/ui';

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

  <Menu
    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

--mirai-ui-menu-base: 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-shadow: var(--mirai-ui-shadow);
--mirai-ui-menu-option-disabled: var(--mirai-ui-content-border);
--mirai-ui-menu-option-hover-background: var(--mirai-ui-content-background);
--mirai-ui-menu-option-hover-color: var(--mirai-ui-content);
--mirai-ui-menu-option-padding: var(--mirai-ui-space-M);

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
  • 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
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

--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-L);
--mirai-ui-modal-overflow: 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
import { Notification } from '@mirai/ui';

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

Theming variables

--mirai-ui-notification-border-radius: var(--mirai-ui-border-radius);
--mirai-ui-notification-padding: var(--mirai-ui-space-S);
--mirai-ui-notification-padding-large: var(--mirai-ui-space-M);
--mirai-ui-notification-padding-small: 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
import { Progress } from '@mirai/ui';

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

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

Theming variables

--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
  • 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
import { Slider } from '@mirai/ui';

const MyComponent = (props) => {

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

Theming variables

--mirai-ui-slider-button: var(--mirai-ui-base);
--mirai-ui-slider-button-icon: 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
  • 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
import { InputText, Table } from '@mirai/ui';

const dataSource = [
  { username: 'jose', email: '[email protected]', year: 2012 },
  { username: 'mario/1', email: '[email protected]', year: 2005 },
  { username: 'carlos', email: '[email protected]', year: 2012 },
  { username: 'svet', email: '[email protected]', year: 2021, action: <Button>View</Button> },
  { username: 'javi', email: '[email protected]', year: 2022, twitter: 'soyjavi' },
  { username: 'victor', email: '[email protected]', year: 2021 },
  {
    username: 'mario/2',
    email: '[email protected]',
    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 }}
      search={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

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

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

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:

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:

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:

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

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

List of Theming variables

/* 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);
--mirai-ui-focus-shadow-error: 0 0 0 var(--mirai-ui-focus-width) var(--mirai-ui-error-border);

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:

  • height:number height resolution of device
  • width:number width resolution of device
  • 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
  • isLandscape:bool orientation is landscape
  • isPortrait:bool orientation is portrait
  • 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:

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

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