cover-image

Mirotone React

About

Mirotone React is a component library for the Mirotone Design System, offering a range of components and utilities to speed up development for Miro. It draws inspiration from Mirotone CSS and Miro UI Components.

Links

Technologies

  • React
  • Mirotone CSS
  • Storybook
  • Radix UI
  • Vite
  • TypeScript

Features

20+ pre-built components

Mirotone React comes with all the basic building blocks to build out a beautiful user interface. It includes all the essentials such as buttons, headings, paragraphs, grids, icons, spinners, form inputs and so much more.

Here is a basic example of how the components can be used:

App.tsx
1import { Button, ButtonProps, Input, InputProps, tokens } from 'mirotone-react';
2import { useCallback, useRef, useState } from 'react';
3
4const buttonProps: ButtonProps = {
5  size: 'large',
6  variant: 'danger',
7};
8
9const inputProps: InputProps = {
10  size: 'small',
11};
12
13function App() {
14  const [value, setValue] = useState('');
15  const buttonRef = useRef<HTMLButtonElement>(null);
16  const inputRef = useRef<HTMLInputElement>(null);
17
18  const buttonClickHandler = useCallback(() => {
19    if (inputRef.current) {
20      inputRef.current.focus();
21    }
22  }, []);
23
24  return (
25    <>
26      <Input
27        {...inputProps}
28        ref={inputRef}
29        value={value}
30        onChange={setValue}
31        style={{ color: tokens.color.red[800] }}
32      />
33      <Button
34        {...buttonProps}
35        ref={buttonRef}
36        style={{ borderRadius: tokens.borderRadius.small }}
37        onClick={buttonClickHandler}
38      >
39        Click to focus input
40      </Button>
41    </>
42  );
43}
44
45export default App;

150+ icons

Mirotone React offers a 1 to 1 mapping of all the icons available on Mirotone. To select an icon, simply use the <Icon /> React component and send through the name prop. which gives you access to over 150 icon tokens.

All icon tokens can be found in the docs. Here is a basic example of how to use an icon with Mirotone React:

1import { Icon } from 'mirotone-react';
2
3const ShapeIcon = () => <Icon name="shapes" />;

Type safe tokens

Mirotone React promotes consistency in UI. To do so, it provides a fully typed tokens object that gives you access to font sizes and weights, Miro's color palette, spacing and border-radius values.

Here is a basic example of how to import tokens in your app:

1import { tokens } from 'mirotone-react';

The object contains the following options:

tokens.color - Color docs

tokens.typography - Typography docs

tokens.space - Spacing docs

tokens.borderRadius - Border radius docs

Composition first

Mirotone React is designed for the user to compose their UI how they want. This flexibility allows the user to use Mirotone React similarly to lego blocks. The Recipes section on the docs demonstrates how many small components can be glued together to make a composed component.

Here is an example of how an app card is composed:

1<AppCard>
2  <AppCardTitle>
3    App card title
4  </AppCardTitle>
5  <AppCardDescription>
6    App card description
7  </AppCardDescription>
8  <AppCardBody>
9    <AppCardTags>
10      <Tag>
11        Tag
12      </Tag>
13      <Tag backgroundColor="var(--yellow700)">
14        Another tag
15      </Tag>
16      <Tag textColor="var(--green700)">
17        Just one more
18      </Tag>
19      <Tag>
20        JIRA-1234
21      </Tag>
22      <Tag icon="link">
23        A tag with icon
24      </Tag>
25    </AppCardTags>
26    <Logo />
27  </AppCardBody>
28</AppCard>

Flexible styling

Mirotone React exposes standard HTML DOM props for all of its components. This includes the className and ref props so that third-party styling solutions can modify Mirotone React components. Here are some examples of how third-party styling solutions can be applied:

CSS styling

index.css
1.text {
2  color: var(--blue600);
3  font-weight: bold;
4  text-decoration: underline;
5  font-size: 1.875rem;
6  line-height: 2.25rem;
7}
App.tsx
1import styles from './index.module.css';
2
3import { Text } from 'mirotone-react';
4
5const App = () => <Text className={styles.text}>CSS text</Text>;
6
7export default App;

Emotion CSS

App.tsx
1import { css } from '@emotion/css';
2
3import { Text, tokens } from 'mirotone-react';
4
5const App = () => (
6  <Text
7    className={css`
8      color: ${tokens.color.blue[600]};
9      font-weight: bold;
10      text-decoration: underline;
11      font-size: 1.875rem;
12      line-height: 2.25rem;
13    `}
14  >
15    Emotion css prop
16  </Text>
17);
18
19export default App;

Emotion styled

App.tsx
1import styled from '@emotion/styled';
2
3import { Text, tokens } from 'mirotone-react';
4
5const StyledText = styled(Text)({
6  color: tokens.color.blue[600],
7  fontWeight: 'bold',
8  textDecoration: 'underline',
9  fontSize: '1.875rem',
10  lineHeight: '2.25rem',
11});
12
13const App = () => <StyledText>Emotion styled component</StyledText>;
14
15export default App;

Tailwind CSS

index.css
1@tailwind base;
2@tailwind components;
3@tailwind utilities;
App.tsx
1import './index.css';
2
3import { Text } from 'mirotone-react';
4
5const App = () => <Text className='text-3xl font-bold underline text-blue-500'>Tailwind text</Text>;
6
7export default App;