@mirai/ui v2.1.55
💾 @mirai/ui
React components library.
📦 Setup
Add the package in your project:
yarn add @mirai/uiPrimitives
Checkbox
This primitive returns a checkbox button based on the following properties:
checked:booleanif true, the checkbox button is checkedchildren:nodedisabled:booleanapplying 'disabled' attributeerror:booleanshows error stylename:stringinput name (required)value:stringinput valueonChange:functionexecuted 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-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:booleanuse theme's accent coloraccentDark:booleanuse theme's accent-dark coloraccentLight:booleanuse theme's accent-light coloraction:booleanmodifying font-sizedark:booleanuse theme's content-dark colorerror:booleanuse theme's error colorheadline:booleanmodifying font-size (default headline:3)info:booleanuse theme's info colorlevel:numberassign the level of heading (1, 2, 3 or 4)light:booleanuse theme's content-light colorparagraph:booleanmodifying font-sizesmall:booleanmodifying font-sizesuccess:booleanuse theme's success colorvalue:funcEnum valuewarning:booleanuse 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:booleanapplying 'disabled' attributemax:numberspecifies the maximum allowed value for numeric inputmin:numberspecifies the minimun allowed value for numeric inputmultiline:booleanif true returning textareaname:stringinput nametype:stringtype attribute valueonChange:functionexecuted when input value changesonEnter:functionexecuted when user clicks on inputonError:functionexecuted once an error event firesonLeave:functionexecuted 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-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:boolif you want open the content below the reference component.centered:boolif you want center the content using screen as parent.children:nodetwo 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 truefixed:boolif you want use a fixed position instead of an absolute one, by default isfalse.forceRender:boolif you want render content children even ifvisibleis falsy, by default istrue.left:boolif you want open the content on the left of the reference component.right:boolif you want open the content on the right of the reference component.timestamp:numberif you want to force render to recalculate the position of content, assign this property with a number (Date.now()).top:boolif you want open the content above the reference component.visible:booleanshowing or hiding the layeronPosition:booleancalled when the position of the layer is calculated or updated. It receivesorientationargument, which is an object containing information about the layer's position withtopandleftproperties
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-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:nodedisabled:booleandisable attributepreventDefault:booleanif you want stop the event tunneling (default true).tag:stringhtml tag applied to a primitiveonEnter:functionexecuted once the user hovers over the elementonLeave:functionexecuted once the user hovers awayonPress:functionexecuted 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:booleanif true, the radio button is checkeddisabled:booleanapplying 'disabled' attributename:stringinput namevalue:stringinput valueonChange:functionexecuted 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-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:stringtype of scroll animationchildren:nodeheight:numberheight valuehorizontal:booleanlayout directionscrollEventThrottle:numberscroll timeout valuescrollIndicator:booleanif true the scroll indicator is shownscrollTo:numbercoordinate to scroll tosnap:boolif you want use the CSS featurescroll-snaptag:stringhtml tag of resulting elementwidth:numberwidth valueonScroll:functionexecuted 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:booleanapplying 'disabled' attributedisabledOptions:boolean[]applying 'disabled' for an specific optionemptyOption:stringlabel for the empty default value (e.g. 'Select an option')options:string[]select options text and valuesvalue:stringcurrent valueonChange:functionexecuted when input value changesonEnterexecuted when select is focusedonErrorexecuted when an error occursonLeaveexecuted 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:booleanif true, the checkbox button is checkeddisabled:booleanapplying 'disabled' attributeerror:booleanshows error stylename:stringinput name (required)onChange:functionexecuted 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-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:booleanuse theme's accent coloraccentDark:booleanuse theme's accent-dark coloraccentLight:booleanuse theme's accent-light coloraction:booleanmodifying font-sizebold:booleanmodifying font-weightbrand:booleanuse of the CSS variables--mirai-ui-text-brand-*capitalize:booleancapitalize the first word of a sentencechildren:stringdark:booleanuse theme's content-dark colorerror:booleanuse theme's error colorheadline:booleanmodifying font-sizeinfo:booleanuse theme's info colorlevel:numberassign the level of heading (1, 2, 3 or 4)light:booleanuse theme's content-light colormarkdown:booleanif true renders content as parsed markdownmedium:booleanmodifying font-weightsmall:booleanmodifying font-sizesuccess:booleanuse theme's success colortag:stringhtml tag of resulting elementtiny:boolmodifying font-sizeunderline:booleanuse an underline text decorationupperCase:booleanswitching text to upper casewarning:booleanuse theme's warning colorwide:booleanspecifies 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:nodefit:booleansets width CSS property as 'fit-content' if trueforceRow:booleanforces the flex-direction as 'row' if truerow:booleansets flex-direction as 'row' or 'row-reverse' if truetag:stringhtml tag of resulting elementwide:boolmodifying 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:booleanmodifying font-weightchildren:node|stringdisabled:booleanapplying 'disabled' attributehref:stringapplying 'href' attribute & forceataginline:booleanmodifying the button padding sizelarge:booleanmodifying the button sizesmall:booleanmodifying the button sizetag:stringhtml tag of resulting element ('button' by default)target:booleanapplying 'target' attribute (in combination withhref:string)underline:booleanuse an underline text decorationwide:boolmodifying the button to full-widthonEnter:functionexecuted when the user hovers overonLeave:functionexecuted when the user hovers awayonPress:functionexecuted 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:booliftruewill disable button and give feedback as something is processing.children:node|stringdisabled:booleanapplying 'disabled' attributefixed:boolif you want use a fixed position for your tooltip, by default isfalse.large:booleanmodifying the button sizesecondary:booleanmodifying the button appearance using a secondary variant.rounded:booleanif true will use the theme border-radius variable for round the cornerssmall:booleanmodifying the button sizesquared:booleanif true gives rectangular shape to the button (false by default)tag:stringhtml tag of resulting element ('button' by default)tooltip:stringtext it will appears when hover on component.transparent:boolmodifying the button appearance using a transparent variant.wide:boolmodifying the button to full-widthonEnter:functionexecuted when the user hovers overonLeave:functionexecuted when the user hovers awayonPress:functionexecuted 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-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:
autoScroll:booleanspecifies whether the calendar should automatically scroll to the selected date or the focused monthcaptions:objectcaptions to be placed into calendar cellsdisabledDates:[string]dates to be shown as unavailable and can't be selecteddisabledPast:booleanpast dates to be shown as unavailable and can't be selectedformat:stringdate display format (e.g. "DD/MM/YYYY")from:stringdate in specific format (e.g. "31/03/2022")highlights:[string]highlights a determinate group of datesl10n:objectchange button's text for load more dateslocale:stringlocale valuemonths:numbernumber of months to be visiblerange:booleanEnable range selectionrangeMaxDays:numberMaximum days in a rangerangeMinDays:numberMinimum days in a rangeto:stringdate in specific format (e.g. "31/03/2022")tooltips:objecttooltips to be placed into calendar cellsvalue:string|[string]onChange:functionexecuted when input value changesonFocus:functionexecuted on calendar cell hoveronNavigation:functionexecuted when move to the next/previous monthsonScroll:functionexecuted 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-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:nodeelements to be rendered within the formdebounce:numberthe delay before triggering the onChange callback after the form values have changed (0 by default)schema:objectdefines validation schema for the form fields. Maps field names to their respective validation rulesshowErrors:booleanindicates whether to display the validation errors for the form fieldstag:stringHTML tag name to be used for rendering the form element ('form' by default)validateOnMount:booleanindicates whether to perform validation on form mountonChange:functionexecuted when any field value changesonEnter:functionwhen a form field gets focusonError:functionexecuted when one or more fields have errorsonLeave:functionexecuted when a form field loses focusonSubmit:functionexecuted 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: '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:stringdate format to be applied ('DD/MM/YYYY' by default)max:stringmaximum date value allowedmin:stringminimum date value allowedplaceholder:boolindicated whether to show placeholder with format or notvalue:stringcurrent valueonChange:functionexecuted when the value is changedonError:functionexecuted 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:boolapplying 'disabled' attributehint:stringbrief messagelabel:stringinput labelmax:numbermaximum input valuemin:numberminimum input valuename:stringinput name attribute (required)rounded:boolif you want use theroundedproperty of<Button>showRequired:booldisplays*next to the labelstep:numberto be added/subtracted from value on each button clickvalue:numberinput valueonChange:functionexecuted 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:booleanif true, the input is checkeddisabled:booleanapplying 'disabled' attributeerror:booleanshows error styleindeterminate:booleanapplying 'indeterminate' attribute (only for type checkbox)label:stringinput labelname:stringinput nameshowRequired:booldisplays*next to the labelsmall:boolmodifying font-sizetype:stringtype of input (radio or checkbox)value:numberinput valueonChange:functionexecuted 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-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:booleanapplying 'disabled' attributeerror:booleanindicating whether there is an error in the inputhint:stringtext with additional info to be displayed below the inputicon:functionicon component to be displayed before the inputlabel:stringlabel text for the phone number partlabelPrefix:stringlabel text for the country code partname:string- required prop, input nameprefixes:string[]available country codesshowRequired:booleanindicating whether the "required" indicator should be shownshowState:booleanindicating whether to show the state icons for errors, success, and warningsuccess:booleanindicating whether the input has a success statevalue:stringcurrent valuewarning:booleanindicating whether the input has a warning stateonChange:functionexecuted when input value changesonEnter:functionexecuted when input gets focusonError:functionexecuted when there are validation errors in the inputonLeave:functionexecuted 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:stringa support text (Ex. currency symbol)disabled:booleanapplying 'disabled' attributeerror:booleanindicating whether there is an error in the inputhint:stringtext with additional info to be displayed below the inputicon:stringif you want use an<Icon>within the componentlabel:stringlabel textname:string- required prop, input nameshowRequired:booleanindicating whether the "required" indicator should be shownshowState:booleanindicating whether to show the state icons for errors, success, and warningsuccess:booleanindicating whether the input has a success statewarning:booleanindicating whether the input has a warning stateonChange:functionexecuted when input value changesonEnter:functionexecuted when input gets focusonError:functionexecuted when there are validation errors in the inputonLeave:functionexecuted 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:stringa support text (Ex. currency symbol)disabled:booleanapplying 'disabled' attributeerror:booleanshows error stylehint:stringbrief messageicon:stringif you want use an<Icon>within the componentlabel:stringinput labelmarkdown:booleanif true shows a preview of your markdown textmultiline:booleanif true returning textareaname:stringinput name (required)showRequired:booldisplays*next to the labelshowState:booldisplays state of input (error, warning or success)success:boolsets success statetype:stringinput type attributewarning:boolsets warning stateonChange:functionexecuted when input value changesonEnter:functionexecuted when user clicks on inputonLeave:functionexecuted 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-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:nodeThe element which we will use as reference for display the menu.options:arrayOf(Option:shape)selected:string|numberif you want highlight one of the optionsTemplate:nodeif you don't want use the default option scaffold.title:stringshows a title for the modalvisible:booleanshowing or hiding the menuonPress:funccallback when we click on a determinate option.
Before learning how to instantiate <Menu> let's look at the properties of our shape Option:
children:nodeIf you wanna add a component in the right side of your option.disabled:booleandisables the optiondivider:booleanif you wanna show a divider in the bottom of the optionicon:stringIf you want instantiate a primitive<Icon>label:stringlabel of the optionvalue:string|numberthis property will dispatch as identificator in the callbackonPress: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-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:boolif you want use a glashmorphism effect in the overflowchildren:nodefit:boolif you want use fit width with the contentforceRender:boolif you want to load the children even if the modal is not visiblemobileBehavior:boolif you want use mobile behavioroverflow:boolwraps all modal in a semi-transparent layerportal:boolif you want use portal feature of React APIpreventDefault:boolif you want stop the event tunneling (default true)title:stringshows a title for the modalvisible:booleanif true modal is shownonBack:functionexecuted once back button is touchedonClose:functionexecuted once close button is touchedonOverflow:functionexecuted 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-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:boolrequired prop, the content of the notification (any valid React node)contrast:boolindicanting wheter the notification as tooltiperror:boolindicating whether the notification represents an error message with corresponding stylesinfo:boolindicating whether the notification represents an informational messageinline:boolindicating whether the notification should be displayed inlinelarge:boolindicating whether the notification should be displayed in a large sizesmall:boolindicating whether the notification should be displayed in a small sizesuccess:boolindicating whether the notification represents a success message with corresponding styleswarning:boolindicating whether the notification represents a warning message with corresponding styleswide:boolindicating whether the notification should be displayed in a wide formatonClose:functionexecuted 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-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:boolexpress an unspecified amount of wait time.value:numbervalue of percentagevisible:booleanif 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:boolif you want auto slide feature (default is false).behavior:stringtype of scroll animationcaptions:arrayOf:stringif you want show a determinate caption for a determinate image.counter:boolshow counterfullScreen:booleanif you want start in fullScreen mode.height:numberHeight of component (required).images:arrayOf:stringimages to show (required).index:numberIf you want show a determinate image at atart.indicator:booleanif true shows the amount of pictures viewed using a progress component.replay:booleanrestart slider when we go forwards after the last imagescrollDelay:numberdelay in milliseconds before scrolling to next imageshowButtons:booleanif true shows the buttonsthumbnails:arrayOf:stringif you want use thumbnails of images in fullScreen mode.width:numberwidth of component (required).onChange:functionexecuted when image (index) is visibleonCounter:functionshow a pressable counter
import { Slider } from '@mirai/ui';
const MyComponent = (props) => {
return <Slider height={320} images={[...]} width={480} />;
};Theming variables
--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 schemafilter:object[]array of filter items that are applied to the table data. Each filter item represents a specific filter configuration.inline:boolspecifies whether the table should be displayed inlineschema:shapethe model data schemapagination:numberthe number of rows you will paginatesearch:stringthe query string you want use for filter the datasourceselected:arrayOf(dataSource.row)if you want pre-select some rows in 1st rendersort:boolspecifies whether the table can be sorted or notstore:stringif you want use storage feature for some features of your table (ex. keep the current filters).onPress:functionexecuted once press in any rowonScroll:functionexecuted once scroll the tableonSelect:functionexecuted once select a determinate row
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 }}
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:nodeThe element which we will use as reference for display the menu.left:boolpositioning of the tooltip relative to its parent elementpressable:boolChange event dispatcher toonPressinstead ofonEnter.right:boolpositioning of the tooltip relative to its parent elementTemplate:nodeif you don't want use the default scaffold.text:stringtext it will appears when hover onchildren.timestamp:numbervalue used to force render to recalculate the position of the tooltiptop:boolChange the position to the top of reference element.visible:booleanthe 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 #edffffgetDirection
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);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:numberheight resolution of devicewidth:numberwidth resolution of deviceuserAgent:stringtype of browser's user agentchrome:boolusing chrome browserfirefox:boolusing firefox browserinApp:boolusing an application browser such as Facebook, Twitter..mobile:boolusing a mobile browsersafari:boolusing safari browsertouch:booltouch screen capabilityisLandscape:boolorientation is landscapeisPortrait:boolorientation is portraitisMobile:boolis in the mobile breakpoint (<=480)isTable:boolis in the mobile breakpoint (>480px && <=1180px)isDesktop:boolin 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)} />;
};10 months ago
11 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
10 months ago
11 months ago
9 months ago
11 months ago
11 months ago
11 months ago
9 months ago
9 months ago
8 months ago
8 months ago
8 months ago
8 months ago
9 months ago
8 months ago
9 months ago
9 months ago
9 months ago
8 months ago
6 months ago
6 months ago
6 months ago
6 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
10 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago