import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Alert, Button, Grid, useTheme } from 'core'
export const meta = {
title: 'Alert',
description: 'Show a message that stays in the page, with an optional title, icon and close button.',
sidebar: 'components',
group: 'Components',
index: 54
}
## Alert
Show a message that stays in the page, with an optional title, icon and close button.
Your trial ends in 3 days. Pick a plan to keep your projects.Invoice 2041 is paid.You used 92% of your 10 GB.Your bank refused the payment. Update the card to retry.
`}
/>
New features are on the way.New features are on the way.New features are on the way.New features are on the way.
`}
/>
{
const [open, setOpen] = React.useState(true)
return open ? (
setOpen(false)}>
Reload the page to get the latest changes.
) : (
)
}
`}
/>
{
const theme = useTheme()
const icon = (
)
return (
Leave now and the last 4 edits are lost.
)
}
`}
/>
Alert.Props
| Attribute | Description | Type | Accepted values | Default |
| -------------- | --------------------------------------------- | ----------------------------------------------------------------------------- | --------------- | --------- |
| **type** | color of the alert | `'default' \| 'primary' \| 'secondary' \| 'success' \| 'warning' \| 'error' \| 'info'` | - | `default` |
| **title** | bold first line | `ReactNode` | - | - |
| **icon** | element before the text | `ReactNode` | - | - |
| **filled** | solid color | `boolean` | - | `false` |
| **light** | tinted background | `boolean` | - | `false` |
| **subtle** | text only, no border | `boolean` | - | `false` |
| **onClose** | shows a close button and calls it on click | `() => void` | - | - |
| **closeLabel** | accessible name of the close button | `string` | - | `Close` |
| **role** | defaults to `alert` for errors and warnings, `status` otherwise | `string` | - | - |
| ... | native props | `HTMLAttributes` | - | - |
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Avatar, Grid, Text, Tag, Card } from 'core'
export const meta = {
title: 'Avatar',
description:
'Avatars represent a user or a team. Stacked avatars represent a group of people.',
sidebar: 'components',
group: 'Components',
index: 1
}
## Avatar
Avatars represent a user or a team. Stacked avatars represent a group of people.
`}
/>
`}
/>
`}
/>
{[
['AL', 'Ada Lovelace', 'Owner'],
['GH', 'Grace Hopper', 'Editor'],
['LT', 'Linus Torvalds', 'Viewer']
].map(([text, name, role]) => (
{name}{role}
))}
`}
/>
Avatar.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------ | ---------------------------------- | ------------------- | ---------------------------------------- | ------- |
| **src** | image src | `string` | - | - |
| **stacked** | stacked display group | `boolean` | - | `false` |
| **text** | display text when image is missing | `string` | - | - |
| **isSquare** | avatar shape | `boolean` | - | `false` |
| ... | native props | `ImgHTMLAttributes` | `'alt', 'crossOrigin', 'className', ...` | - |
Avatar.Group.Props
| Attribute | Description | Type | Accepted values | Default |
| --------- | ------------------ | ---------------- | -------------------------------- | ------- |
| **count** | show total members | `number` | - | - |
| ... | native props | `HTMLAttributes` | `'id', 'name', 'className', ...` | - |
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Badge, Grid, Avatar, Button, Link, useTheme } from 'core'
export const meta = {
title: 'Badge',
description: 'Display an indicator that requires attention.',
sidebar: 'components',
group: 'Components',
index: 2
}
## Badge
Display an indicator that requires attention.
Default
`}
/>
DefaultPrimarySecondarySuccessWarningErrorInfo
`}
/>
For more colors, please refer to the{' '}
color section
.
>
}
scope={{ Grid, Badge, useTheme }}
code={`
() => {
const theme = useTheme()
return (
Success Light
AlertPurpleViolet
)
}
`}
/>
Recording
Live
`}
/>
10
10
99+
Bolio UI
Share Link
`}
/>
Badge.Props
| Attribute | Description | Type | Accepted values | Default |
| --------- | --------------------------- | ---------------- | ------------------------------- | --------- |
| **type** | badge type | `BadgeTypes` | [BadgeTypes](#badgetypes) | `default` |
| **dot** | show dot and ignore content | `boolean` | - | `false` |
| **pulse** | animated ring for live status | `boolean` | - | `false` |
| **ghost** | outline variant: opposite color | `boolean` | - | `false` |
| **light** | light variant: tinted background | `boolean` | - | `false` |
| **subtle**| subtle variant: no background | `boolean` | - | `false` |
| ... | native props | `HTMLAttributes` | `'alt', 'id', 'className', ...` | - |
Badge.Anchor.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------- | ---------------------- | ----------------- | ----------------------------------- | ---------- |
| **placement** | fixe position of Badge | `AnchorPlacement` | [AnchorPlacement](#anchorplacement) | `topRight` |
| ... | native props | `HTMLAttributes` | `'alt', 'id', 'className', ...` | - |
BadgeTypes
```ts
type BadgeTypes =
| 'default'
| 'primary'
| 'secondary'
| 'success'
| 'warning'
| 'error'
| 'info'
```
AnchorPlacement
```ts
type AnchorPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight'
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Breadcrumbs, Grid } from 'core'
import { useRouter } from 'next/navigation'
import { Home, Settings } from '@bolio-ui/icons'
export const meta = {
title: 'Breadcrumbs',
description: 'Show where users are in the application.',
sidebar: 'components',
group: 'Components',
index: 3
}
## Breadcrumbs
Show where users are in the application.
HomeSettingsGeneral
`}
/>
HomeCategoriesAddHome:PagesDefaultIndex
`}
/>
Settings
General
`}
/>
{
const router = useRouter()
const go = (url) => (event) => {
event.preventDefault()
router.push(url)
}
return (
HomeSettingsGeneral
)
}
`}
/>
Breadcrumbs.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------- | ---------------- | ---------------- | ------------------------ | ------- |
| **separator** | separator string | `string` | - | `/` |
| ... | native props | `HTMLAttributes` | `'id', 'className', ...` | - |
Breadcrumbs.Item.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------ | ------------------ | ----------------------------- | ------------------------ | ------- |
| **href** | link address | `string` | - | - |
| **nextLink** | render as a link even without `href` | `boolean` | - | `false` |
| **onClick** | click event | `(event: MouseEvent) => void` | - | - |
| ... | native props | `AnchorHTMLAttributes` | `'id', 'className', ...` | - |
Breadcrumbs.Separator.Props
| Attribute | Description | Type | Accepted values | Default |
| --------- | ------------ | ---------------- | ------------------------ | ------- |
| ... | native props | `HTMLAttributes` | `'id', 'className', ...` | - |
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { ButtonDropdown, Grid } from 'core'
import { Playground, Attributes } from 'src/components'
import { Plus, Copy, FileText } from '@bolio-ui/icons'
export const meta = {
title: 'Button Dropdown',
description: 'Display related but alternate actions for a button.',
sidebar: 'components',
group: 'Components',
index: 5
}
## Button Dropdown
Display related but alternate actions for a button.
Default ButtonSecondary ButtonTertiary Button
`}
/>
Default ButtonSecondary ButtonTertiary Button
`}
/>
Default ButtonSecondary ButtonTertiary Button
`}
/>
Primary ButtonSecondary ButtonTertiary ButtonSecondary ButtonSecondary ButtonTertiary ButtonSuccess ButtonSecondary ButtonTertiary ButtonWarning ButtonSecondary ButtonTertiary ButtonError ButtonSecondary ButtonTertiary ButtonInfo ButtonSecondary ButtonTertiary Button
`}
/>
CheckBlockLockDestroy
`}
/>
}>
Check UserBlock UserLock UserDestroy User
`}
/>
}>Copy Markdown
}>View as Markdown
`}
/>
StartSecondary ButtonCenterSecondary ButtonEndSecondary Button
`}
/>
ButtonDropdown.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------ | --------------------------- | ------------------------------ | ------------------------------------------- | -------------------- |
| **type** | button type | `ButtonDropdownTypes` | [ButtonDropdownTypes](#buttondropdowntypes) | `default` |
| **loading** | display loading indicator | `boolean` | - | `false` |
| **auto** | autoscale width | `boolean` | - | `false` |
| **align** | main button label alignment | `'start' \| 'center' \| 'end'` | - | `center` |
| **disabled** | disable button | `boolean` | - | `false` |
| **icon** | custom right icon | `ReactNode` | - | `ButtonDropdownIcon` |
| ... | native props | `HTMLAttributes` | `'autoFocus', 'name', 'className', ...` | - |
ButtonDropdown.Item.Props
| Attribute | Description | Type | Accepted values | Default |
| ----------- | --------------------- | ---------------------- | ------------------------------------------- | --------- |
| **type** | button type | `ButtonDropdownTypes` | [ButtonDropdownTypes](#buttondropdowntypes) | `default` |
| **main** | the main action | `boolean` | - | `false` |
| **icon** | icon before the label | `ReactNode` | - | - |
| **onClick** | event handler | `MouseEventHandler` | - | - |
| ... | native props | `ButtonHTMLAttributes` | `'id', 'name', 'className', ...` | - |
ButtonDropdownTypes
```ts
type ButtonDropdownTypes =
| 'default'
| 'primary'
| 'secondary'
| 'success'
| 'warning'
| 'error'
| 'info'
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Button, Grid, ButtonGroup } from 'core'
import { Bold, Italic, Underline } from '@bolio-ui/icons'
export const meta = {
title: 'Button Group',
description: 'A set of related buttons.',
sidebar: 'components',
group: 'Components',
index: 6
}
## Button Group
A set of related buttons.
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
{
const [on, setOn] = React.useState({ bold: true, italic: false, underline: false })
const toggle = (key) => () => setOn((last) => ({ ...last, [key]: !last[key] }))
const style = (key) => (on[key] ? 'primary' : 'default')
return (
} aria-label="Bold" aria-pressed={on.bold} type={style('bold')} onClick={toggle('bold')} />
} aria-label="Italic" aria-pressed={on.italic} type={style('italic')} onClick={toggle('italic')} />
} aria-label="Underline" aria-pressed={on.underline} type={style('underline')} onClick={toggle('underline')} />
)
}
`}
/>
ButtonGroup.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------ | --------------------------- | ---------------------- | --------------------------- | --------- |
| **type** | button type | `ButtonTypes` | [ButtonTypes](#buttontypes) | `default` |
| **ghost** | the opposite color | `boolean` | - | `false` |
| **vertical** | show all buttons vertically | `boolean` | - | `false` |
| **disabled** | disable all buttons | `boolean` | - | `false` |
| ... | native props | `ButtonHTMLAttributes` | `'id', 'className', ...` | - |
ButtonTypes
```ts
type ButtonTypes =
| 'default'
| 'secondary'
| 'success'
| 'warning'
| 'error'
| 'abort'
| 'secondary-light'
| 'success-light'
| 'warning-light'
| 'error-light'
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Button, Grid, Row, Code } from 'core'
import { Zap, ZapOff, AlertCircle, XSquare } from '@bolio-ui/icons'
export const meta = {
title: 'Button',
description: 'A set of related buttons.',
sidebar: 'components',
group: 'Components',
index: 4
}
## Button
Used to trigger an operation.
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
} auto scale={2 / 3} />
} auto scale={2 / 3} px={0.6} />
} auto>
Button
} type="success" scale={0.85}>
Button
} type="warning" scale={0.85}>
Button
} type="secondary">
Button
} type="error" ghost>
Remove Button
} disabled>
Remove Button
`}
/>
{
const [state, setState] = React.useState('idle')
const save = () => {
setState('saving')
setTimeout(() => setState('saved'), 1500)
}
return (
)
}
`}
/>
Button.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------- | ----------------------------------------- | ----------------------------------------------- | --------------------------- | --------- |
| **type** | button type | `ButtonTypes` | [ButtonTypes](#buttontypes) | `default` |
| **ghost** | the opposite color | `boolean` | - | `false` |
| **subtle** | no background, only the type's color | `boolean` | - | `false` |
| **rounded** | rounded button | `boolean` | - | `false` |
| **loading** | display loading indicator | `boolean` | - | `false` |
| **shadow** | display shadow | `boolean` | - | `false` |
| **auto** | autoscale width | `boolean` | - | `false` |
| **effect** | display animation | `boolean` | - | `true` |
| **spotlight** | glow that follows the pointer on hover | `boolean` | - | `false` |
| **disabled** | disable button | `boolean` | - | `false` |
| **onClick** | click handler | `MouseEventHandler` | - | - |
| **icon** | show icon in button | `ReactNode` | - | - |
| **iconRight** | show icon on the other side of the button | `ReactNode` | - | - |
| **htmlType** | native type of button element | `ButtonHTMLAttributes.type` | - | `button` |
| **ref** | forwardRef | Ref<HTMLButtonElement | null> | - | - |
| ... | native props | `ButtonHTMLAttributes` | `'id', 'className', ...` | - |
ButtonTypes
```ts
type ButtonTypes =
| 'default'
| 'primary'
| 'secondary'
| 'success'
| 'warning'
| 'error'
| 'info'
| 'abort'
| 'primary-light'
| 'secondary-light'
| 'success-light'
| 'warning-light'
| 'error-light'
| 'info-light'
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Calendar, Grid } from 'core'
export const meta = {
title: 'Calendar',
description: 'A month grid to pick a day with the mouse or the keyboard.',
sidebar: 'components',
group: 'Components',
index: 43
}
## Calendar
A month grid to pick a day with the mouse or the keyboard. `DatePicker` uses it, and you can use it alone when the calendar should always be visible.
In Next.js 16 with `cacheComponents` on, wrap a `Calendar` that is always visible in ``. It reads today's date while it renders, and Next does not prerender that. A `DatePicker` does not need it, because its calendar opens on a click.
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
date.getDay() === 0 || date.getDay() === 6} />
`}
/>
`}
/>
`}
/>
Calendar.Props
| Attribute | Description | Type | Accepted values | Default |
| --------------------- | --------------------------------------------------------- | ------------------------------------------- | ------------------------------- | ---------------- |
| **value** | selected day, days or range, to control the component | `Date` / `null`, `Date[]` or `[Date, Date]` | - | - |
| **onChange** | called with what the user picked, in the shape of `value` | `(value) => void` | - | - |
| **min** | first day that can be picked | `Date` | - | - |
| **max** | last day that can be picked | `Date` | - | - |
| **locale** | language of the month and weekday names | `string` | any `Intl` locale | `en-US` |
| **weekStartsOn** | first day of the week, 0 is Sunday | `number` | `0` to `6` | `0` |
| **mode** | how many days can be picked | `string` | `'single', 'multiple', 'range'` | `single` |
| **maxSelected** | most days in `multiple` mode | `number` | - | - |
| **shouldDisableDate** | disable the days where it returns `true` | `(date: Date) => boolean` | - | - |
| **showOutsideDays** | show days of the neighbor months | `boolean` | - | `false` |
| **numberOfMonths** | months shown side by side; hides the neighbor days if more than one | `number` | - | `1` |
| **showWeekNumbers** | show the ISO week of each row | `boolean` | - | `false` |
| **month** | visible month, to control it | `Date` | - | - |
| **defaultMonth** | visible month at the start | `Date` | - | the selected day |
| **onMonthChange** | called with the first day of the new month | `(month: Date) => void` | - | - |
| **weekLabel** | name of the week number column | `string` | - | `Week` |
| **autoFocus** | move the focus to the day when it is shown | `boolean` | - | `false` |
| **previousLabel** | name of the previous month button | `string` | - | `Previous month` |
| **nextLabel** | name of the next month button | `string` | - | `Next month` |
| ... | native props | `HTMLAttributes` | `'id', 'className', ...` | - |
Ref
The `ref` points at the root element.
Accessibility
The days are a `grid` named by the month, with a single tab stop on the focused day. The selected day has `aria-selected` and today has `aria-current="date"`.
| Key | Action |
| ------------------------- | ----------------------------------------------- |
| Arrow keys | Move by one day, or one week |
| Home and End | Go to the first and to the last day of the week |
| Page Up and Page Down | Go to the previous and to the next month |
| Shift and Page Up or Down | Go to the previous and to the next year |
| Enter and Space | Pick the day |
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Capacity, Grid, Card, Text, useTheme } from 'core'
export const meta = {
title: 'Capacity',
description: 'Display an capacity indicator.',
sidebar: 'components',
group: 'Components',
index: 7
}
## Capacity
Display an capacity indicator.
`}
/>
{
const theme = useTheme()
return (
)
}
`}
/>
{[
['Projects', 3, 10],
['Members', 7, 10],
['Storage (GB)', 9.4, 10]
].map(([label, value, limit]) => (
{label}{value} of {limit}
))}
`}
/>
Capacity.Props
| Attribute | Description | Type | Accepted values | Default |
| --------- | ---------------- | ---------------- | ------------------ | ------- |
| **value** | value number | `number` | - | 0 |
| **limit** | max value | `number` | - | 100 |
| **color** | css color string | `string` | - | - |
| ... | native props | `HTMLAttributes` | `'className', ...` | - |
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Card, Link, Image, Text, Divider, Code, Grid, Avatar, Button } from 'core'
export const meta = {
title: 'Card',
description: 'A common container component.',
sidebar: 'components',
group: 'Components',
index: 8
}
## Card
A common container component.
A default card.
`}
/>
A hoverable default card.A hoverable primary card.A hoverable secondary card.
`}
/>
A bordered default card.A bordered primary card.A bordered secondary card.
`}
/>
A shadow default card.A shadow primary card.A shadow secondary card.
`}
/>
{
const types = ['default', 'primary', 'secondary', 'success', 'warning', 'error', 'info', 'dark', 'lite']
return (
{types.map((type) => (
{type}
{type}
))}
)
}
`}
/>
Bolio UI
More creative and fun with amazing features for React.
Visit source code on GitHub.
Bolio UI
More creative and fun with amazing features for React.
Visit source code on GitHub.
`}
/>
Bolio UI
More creative and fun with amazing features for React.
Visit source code on GitHub.
`}
/>
A Simple Component
React components implement a render() method that takes
input data and returns what to display. This example uses an
XML-like syntax called JSX. Input data that is passed into the
component can be accessed by render() via{' '}
this.props.
`}
/>
DefaultMove the pointer over the card.PrimaryThe glow follows the card color.DarkWorks on solid backgrounds too.
`}
/>
FrostedThe gradient shows through the card.Frosted darkSame effect with a dark tint.
`}
/>
alert('Opened')}>
Open projectClick, or focus with Tab.With spotlightCombine variants freely.
`}
/>
Revenue$48,200+12.4% this monthActive users3,842+4.1% this weekChurn1.8%+0.3% this month
`}
/>
Free$01 projectCommunity supportPro$12Unlimited projectsPriority support
`}
/>
Ada Lovelaceada@example.com
`}
/>
Card.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------- | ------------------- | --------------------- | ----------------------- | --------- |
| **hoverable** | add effect on hover | `boolean` | - | `false` |
| **shadow** | show shadow | `boolean` | - | `false` |
| **type** | card type | [CardType](#cardtype) | - | `default` |
| **filled** | filled variant, solid background | `boolean` | - | `false` |
| **ghost** | outline variant, always shows a border | `boolean` | - | `false` |
| **subtle** | subtle variant, no background | `boolean` | - | `false` |
| **spotlight** | glow that follows the pointer on hover | `boolean` | - | `false` |
| **glass** | translucent background with blur | `boolean` | - | `false` |
| **interactive** | pointer cursor, lift on hover and focus ring | `boolean` | - | `false` |
| ... | native props | `HTMLAttributes` | `'id', className', ...` | - |
Card.Content.Props
| Attribute | Description | Type | Accepted values | Default |
| --------- | ------------ | ---------------- | ----------------------- | ------- |
| ... | native props | `HTMLAttributes` | `'id', className', ...` | - |
Card.Footer.Props
| Attribute | Description | Type | Accepted values | Default |
| --------------------- | ----------------------------- | ---------------- | ----------------------- | ------- |
| **disableAutoMargin** | cancel automatic margin value | `boolean` | - | `false` |
| ... | native props | `HTMLAttributes` | `'id', className', ...` | - |
CardType
```ts
type CardType =
| 'default'
| 'primary'
| 'secondary'
| 'success'
| 'warning'
| 'error'
| 'info'
| 'dark'
| 'lite'
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Carousel, Card, Text, Avatar, Button, Grid, Image, useTheme } from 'core'
export const meta = {
title: 'Carousel',
description:
'A row of slides that scrolls and snaps, with buttons and dots to move between them.',
sidebar: 'components',
group: 'Components',
index: 64
}
## Carousel
A row of slides that scrolls and snaps into place. It is plain scrolling with
`scroll-snap`, so touch, trackpad and keyboard work as the browser does them,
and the buttons and dots move the same scroll.
{[
['Themes', 'Dark and light, and your brand color in one line.'],
['Accessible', 'Keyboard and screen reader support in every component.'],
['Typed', 'Props and refs are typed for TypeScript.']
].map(([title, text]) => (
{title}{text}
))}
`}
/>
{['Free', 'Starter', 'Pro', 'Team', 'Business'].map((name, index) => (
{name}{'$' + index * 12 + ' a month'}
))}
`}
/>
{
const theme = useTheme()
const photos = [
['/img/jpg/docs/lake-sunrise.jpg', 'A mountain lake at sunrise', 'Lake at sunrise'],
['/img/jpg/docs/forest-lake.jpg', 'A forest lake under the clouds', 'Forest lake'],
['/img/jpg/docs/autumn-canyon.jpg', 'A river in a canyon in autumn', 'Autumn canyon'],
['/img/jpg/docs/mountain-reflection.jpg', 'Snowy mountains reflected in a lake', 'Mountain reflection'],
['/img/jpg/docs/moonlit-peaks.jpg', 'Snowy mountains under the moon', 'Moonlit peaks']
]
return (
{photos.map(([src, alt, caption]) => (
{caption}
))}
)
}
`}
/>
{
const theme = useTheme()
const photos = [
['/img/jpg/docs/lake-sunrise.jpg', 'A mountain lake at sunrise'],
['/img/jpg/docs/forest-lake.jpg', 'A forest lake under the clouds'],
['/img/jpg/docs/autumn-canyon.jpg', 'A river in a canyon in autumn'],
['/img/jpg/docs/mountain-reflection.jpg', 'Snowy mountains reflected in a lake'],
['/img/jpg/docs/moonlit-peaks.jpg', 'Snowy mountains under the moon']
]
return (
{photos.map(([src, alt]) => (
))}
)
}
`}
/>
{
const theme = useTheme()
const places = [
['/img/jpg/docs/lake-sunrise.jpg', 'A mountain lake at sunrise', 'Lake at sunrise', 'From $420'],
['/img/jpg/docs/forest-lake.jpg', 'A forest lake under the clouds', 'Forest lake', 'From $380'],
['/img/jpg/docs/autumn-canyon.jpg', 'A river in a canyon in autumn', 'Autumn canyon', 'From $510'],
['/img/jpg/docs/mountain-reflection.jpg', 'Snowy mountains reflected in a lake', 'Mountain reflection', 'From $460']
]
return (
{places.map(([src, alt, name, price]) => (
{name}{price}
))}
)
}
`}
/>
{
const [index, setIndex] = React.useState(0)
return (
{['Create an account', 'Invite your team', 'Deploy', 'Share the link'].map((step) => (
{step}
))}
Slide {index + 1} of 4
)
}
`}
/>
{[
['AL', 'Ada Lovelace', 'We shipped our dashboard in a week.'],
['GH', 'Grace Hopper', 'The best defaults I have used.'],
['LT', 'Linus Torvalds', 'Easy to theme, and the docs are clear.']
].map(([text, name, quote]) => (
{quote}
{name}
))}
`}
/>
Carousel.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------------ | ----------------------------------------------------------------- | --------------------------------------------- | ------------------------- | ------------------- |
| **slidesToShow** | slides in view at once | `number` | - | `1` |
| **gap** | space between the slides | `string` | any CSS length | `1rem` |
| **controls** | show the previous and next buttons | `boolean` | - | `true` |
| **indicators** | show a dot for each position | `boolean` | - | `true` |
| **value** | index of the first slide in view, to control it | `number` | - | - |
| **initialValue** | index of the first slide in view on the first render | `number` | - | `0` |
| **onChange** | called with the index of the slide the scroll rests on | `(index: number) => void` | - | - |
| **previousLabel** | name of the previous button | `string` | - | `Previous slide` |
| **nextLabel** | name of the next button | `string` | - | `Next slide` |
| **slideLabel** | name of each slide for screen readers | `(index: number, count: number) => string` | - | `1 of 5` |
| **indicatorLabel** | name of each dot | `(index: number) => string` | - | `Go to slide 1` |
| ... | native props, passed to the root `div` | `HTMLAttributes` | `'aria-label', 'id', ...` | - |
Behavior
- • **Scroll**: swiping, the trackpad, the arrow keys on the focused list and the buttons all move the same scroll. `onChange` is called once the scroll stops, not on every pixel.
- • **Motion**: the scroll is smooth, unless the user asked for less motion in the system.
- • **Ends**: the buttons are disabled on the first and the last position. There is no loop.
- • **Controls**: when every slide fits, the buttons and dots are not shown.
Ref
The `ref` points at the root `div`.
Accessibility
The root is a `region` with `aria-roledescription="carousel"`, and each slide is a `group` named by its position, like "2 of 5". Name the carousel with `aria-label`. The scrolling list can be focused, so the keyboard can scroll it, and the buttons and dots are real buttons with names you can translate. The dot of the current position has `aria-current`.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Checkbox, Grid, Code, Button } from 'core'
export const meta = {
title: 'Checkbox',
description: 'Displays a boolean value.',
sidebar: 'components',
group: 'Components',
index: 9
}
## Checkbox
Displays a boolean value.
Check option
`}
/>
scale-0.25
scale-0.5
scale-0.75
`}
/>
Checkbox Default
Checkbox Primary
Checkbox Secondary
Checkbox Success
Checkbox Warning
Checkbox Error
Checkbox Info
`}
/>
Checkbox option
Checkbox option disabled
`}
/>
{
const handler = value => {
console.log(value)
}
return (
Checkbox option 1Checkbox option 2Checkbox option 3Checkbox option 4
)
}
`}
/>
{
const [accepted, setAccepted] = React.useState(false)
return (
setAccepted(event.target.checked)}>
I accept the terms of use
)
}
`}
/>
Checkbox.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------------ | ------------------------------------------- | ---------------------------------------------- | ------------------------------- | --------- |
| **checked** | checked or not | `boolean` | - | - |
| **initialChecked** | checked or not on initial | `boolean` | - | `false` |
| **onChange** | change event handler | `CheckboxEvent` | - | - |
| **value** | unique identification value (only in group) | `string` | - | - |
| **disabled** | disable checkbox | `boolean` | - | `false` |
| **type** | current type | `CheckboxTypes` | [CheckboxTypes](#checkboxtypes) | `default` |
| **ref** | forwardRef | Ref<HTMLInputElement | null> | - | - |
| ... | native props | `LabelHTMLAttributes` | `'form' ...` | - |
Checkbox.Group.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------ | ---------------------- | ---------------------------- | --------------- | ------- |
| **value** | checked children | `Array` | - | `[]` |
| **disabled** | disable checkbox group | `boolean` | - | `false` |
| **onChange** | change event handler | `(values: string[]) => void` | - | - |
| ... | native props | `HTMLAttributes` | `'id', ...` | - |
CheckboxTypes
```ts
type CheckboxTypes =
| 'default'
| 'primary'
| 'secondary'
| 'success'
| 'warning'
| 'error'
| 'info'
```
CheckboxEvent
```ts
interface CheckboxEventTarget {
checked: boolean
}
export interface CheckboxEvent {
target: CheckboxEventTarget
stopPropagation: () => void
preventDefault: () => void
nativeEvent: React.ChangeEvent
}
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Chip, Card, Text, Grid } from 'core'
export const meta = {
title: 'Chip',
description: 'Pick options from a row of pills, one or several at a time.',
sidebar: 'components',
group: 'Components',
index: 55
}
## Chip
Pick options from a row of pills, one or several at a time.
Free shipping
`}
/>
{
const [stack, setStack] = React.useState(['react'])
return (
<>
ReactVueSvelteSolid
{stack.length ? stack.length + ' selected: ' + stack.join(', ') : 'Pick at least one framework.'}
>
)
}
`}
/>
{
const [size, setSize] = React.useState(['m'])
return (
SMLXL, sold out
)
}
`}
/>
{
const posts = [
['Ship a Tour in an afternoon', 'product'],
['Why we dropped styled-jsx', 'engineering'],
['Dark mode without gray mush', 'design'],
['Splitting a layout with CSS grid', 'engineering'],
['Reading an empty state', 'design']
]
const [topics, setTopics] = React.useState([])
const shown = topics.length ? posts.filter(([, topic]) => topics.includes(topic)) : posts
return (
<>
ProductEngineeringDesign
>
)
}
`}
/>
Chip.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------------ | -------------------------------------------------------- | ----------------------------------------------------------------- | --------------- | --------- |
| **value** | value the chip adds to or takes from its `Chip.Group` | `string` | - | - |
| **checked** | checked state, to control the chip | `boolean` | - | - |
| **initialChecked** | checked state at the start | `boolean` | - | `false` |
| **onChange** | called with the new state when the chip is alone | `(checked: boolean) => void` | - | - |
| **type** | color of a checked chip | `'primary' \| 'secondary' \| 'success' \| 'warning' \| 'error' \| 'info'` | - | `primary` |
| **disabled** | block the chip | `boolean` | - | `false` |
| ... | native props of the input | `InputHTMLAttributes` | - | - |
Chip.Group.Props
| Attribute | Description | Type | Accepted values | Default |
| ---------------- | ------------------------------------------- | ----------------------------- | --------------- | ------- |
| **value** | values of the checked chips, to control it | `string[]` | - | - |
| **initialValue** | values checked at the start | `string[]` | - | `[]` |
| **onChange** | called with the values of the checked chips | `(value: string[]) => void` | - | - |
| **multiple** | allow several checked chips | `boolean` | - | `false` |
| **disabled** | block every chip of the group | `boolean` | - | `false` |
| ... | native props | `HTMLAttributes` | - | - |
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Code, Text, Grid } from 'core'
import { Playground, Attributes, ParsedCodes } from 'src/components'
import WaitTime from 'core/MdxWidgets/ParsedCodes/WaitTime'
export const meta = {
title: 'Code',
description: 'Show source code in a standardized way.',
sidebar: 'components',
group: 'Components',
index: 10
}
## Code
Show source code in a standardized way. Want to display shell code snippets? try [Snippet](/docs/components/snippet).
Run npm i @bolio-ui/core to install.
Or run yarn add @bolio-ui/core to install.
`}
/>
`}
/>
{'yarn add @bolio-ui/core'}
`}
/>
`}
/>
{
const [active, setActive] = React.useState(0)
const codes = [
"import { Button } from '@bolio-ui/core'",
"import { Text } from '@bolio-ui/core'"
]
return (
{codes[active]}
)
}
`}
/>
`}
/>
Code.Props
| Attribute | Description | Type | Accepted values | Default |
| --------------- | ------------------------------------------- | ------------------------- | ------------------ | ------- |
| **block** | show code in `pre` | `boolean` | - | `false` |
| **name** | text displayed at the top of the code block | `string` | - | - |
| **classic** | display with classic style | `boolean` | - | `false` |
| **tabs** | names of the tabs, in place of `name` | `string[]` | - | `[]` |
| **activeTab** | index of the active tab | `number` | - | `0` |
| **onTabChange** | called with the index of the chosen tab | `(index: number) => void` | - | - |
| ... | native props | `HTMLAttributes` | `'className', ...` | - |
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Row, Col, Card, Text } from 'core'
export const meta = {
title: 'Col',
description: 'A column inside a Row, sized in twelfths.',
sidebar: 'components',
group: 'Components',
index: 47
}
## Col
A column inside a Row, sized in twelfths of the row.
span 4
span 8
`}
/>
span 4, offset 4
`}
/>
SettingsProfileBillingTeam
ProfileUpdate your name, photo and the email we use to contact you.
`}
/>
Col.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------- | ------------------------------------------ | ----------------------------- | ----------------------------- | ------- |
| **span** | how many twelfths of the row it takes | `number` | `1` to `12` | `12` |
| **offset** | how many twelfths to leave before it | `number` | `0` to `11` | `0` |
| **component** | the element to render | `keyof JSX.IntrinsicElements` | `'div', 'li', 'section', ...` | `div` |
| ... | native props | `HTMLAttributes` | `'id', 'className', ...` | - |
Ref
The `ref` points at the root element.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Collapse, Grid, Text } from 'core'
export const meta = {
title: 'Collapse',
description:
'Display large amounts of text in collapsible sections. Commonly referred to as an accordion.',
sidebar: 'components',
group: 'Components',
index: 11
}
## Collapse
Display large amounts of text in collapsible sections. Commonly referred to as an accordion.
Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt mollit
anim id est laborum.
Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt mollit
anim id est laborum.
`}
/>
Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt mollit
anim id est laborum.
Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt mollit
anim id est laborum.
`}
/>
Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt mollit
anim id est laborum.
More description about Lorem ipsum 2
>
}
>
Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt mollit
anim id est laborum.
`}
/>
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est
laborum
`}
/>
{
const [visible, setVisible] = React.useState(true)
return (
The section is {visible ? 'open' : 'closed'}.Nobody sees this.
)
}
`}
/>
Collapse.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------------- | ---------------- | ---------------- | -------------------------------- | ------- |
| **title**(required) | collapse title | `string` | - | - |
| **subtitle** | description | `string` | - | - |
| **initialVisible** | initial expanded | `boolean` | - | `false` |
| **visible** | expanded, to control it | `boolean` | - | - |
| **onVisibleChange** | called with the next state when the header is clicked | `(visible: boolean) => void` | - | - |
| **disabled** | the section cannot be toggled | `boolean` | - | `false` |
| **shadow** | show shadow card | `boolean` | - | `false` |
| ... | native props | `HTMLAttributes` | `'id', 'name', 'className', ...` | - |
Collapse.Group.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------- | -------------- | ---------------- | -------------------------------- | ------- |
| **accordion** | accordion mode | `boolean` | - | `true` |
| ... | native props | `HTMLAttributes` | `'id', 'name', 'className', ...` | - |
Accessibility
The title is a heading with a real button inside, so a screen reader announces it as a heading and as a button that is expanded or collapsed, and `aria-controls` points at the content. Enter and Space toggle a section. In a `Collapse.Group`, the Up and Down arrows move focus between the titles, wrapping at the ends, and Home and End go to the first and the last. Disabled sections are skipped.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { ColorInput, Grid, useTheme } from 'core'
export const meta = {
title: 'Color Input',
description:
'A field for a hex color, with a swatch that opens a color picker in a popover.',
sidebar: 'components',
group: 'Components',
index: 66
}
## Color Input
A field for a hex color. The swatch on the left shows the color and opens a
Color Picker in a popover. You can
also type the code.
Brand color
`}
/>
`}
/>
{
const theme = useTheme()
const [primary, setPrimary] = React.useState('#2563eb')
const [secondary, setSecondary] = React.useState('#7c3aed')
return (
PrimarySecondary
)
}
`}
/>
`}
/>
`}
/>
ColorInput.Props
| Attribute | Description | Type | Accepted values | Default |
| ----------------- | -------------------------------------------------------- | ----------------------- | -------------------------------------------------------------------------- | -------------- |
| **value** | the color, to control the component | `string` | `'#rrggbb'`, `'#rgb'` | - |
| **initialValue** | the color on the first render | `string` | `'#rrggbb'`, `'#rgb'` | `#000000` |
| **onChange** | called with the color as `#rrggbb` in lowercase | `(hex: string) => void` | - | - |
| **swatches** | colors to pick with one click in the popover | `string[]` | - | - |
| **placeholder** | text shown when the field is empty | `string` | - | `#000000` |
| **pickerLabel** | name of the swatch button and of the dialog | `string` | - | `Choose color` |
| **disabled** | disable the component | `boolean` | - | `false` |
| **type** | color of the field | `NormalTypes` | `'default', 'primary', 'secondary', 'success', 'warning', 'error', 'info'` | `default` |
| **rounded** | round the corners | `boolean` | - | `false` |
| **filled** | filled variant | `boolean` | - | `false` |
| **light** | light variant | `boolean` | - | `false` |
| **ghost** | outline variant | `boolean` | - | `false` |
| **subtle** | subtle variant | `boolean` | - | `false` |
| ... | native props, passed to the input | `InputHTMLAttributes` | `'aria-label', 'name', ...` | - |
Typing
The color changes as soon as the text holds six digits, with or without the `#`. A short code like `#abc` is read when the field loses the focus, and becomes `#aabbcc`. Any other text is dropped on blur, and the field goes back to the current color. The field always holds a color, so it cannot be left empty.
Ref
The `ref` points at the `input`.
Accessibility
The field is named by its label, or by `aria-label`. The swatch is a button with `aria-haspopup="dialog"` and `aria-expanded`, named by `pickerLabel`. The picker opens in a dialog with the focus on its square. Escape closes it and puts the focus back on the swatch. The code is also a text in the field, so the color is not conveyed by the swatch alone. See Color Picker for the keys.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { ColorPicker, Grid, Text, Button, useTheme } from 'core'
export const meta = {
title: 'Color Picker',
description:
'A panel to pick a color by saturation, brightness and hue, with a hex field and optional swatches.',
sidebar: 'components',
group: 'Components',
index: 65
}
## Color Picker
A panel to pick a color. Drag in the square for the saturation and the
brightness, use the bar for the hue, or type the hex code. For a field that
opens this panel in a popover, see Color Input.
`}
/>
`}
/>
{
const theme = useTheme()
const [color, setColor] = React.useState('#f59e0b')
return (
{color}
)
}
`}
/>
`}
/>
ColorPicker.Props
| Attribute | Description | Type | Accepted values | Default |
| ---------------- | ------------------------------------------------------------ | ----------------------- | ------------------------- | ----------------------------- |
| **value** | the color, to control the component | `string` | `'#rrggbb'`, `'#rgb'` | - |
| **initialValue** | the color on the first render | `string` | `'#rrggbb'`, `'#rgb'` | `#000000` |
| **onChange** | called with the color as `#rrggbb` in lowercase | `(hex: string) => void` | - | - |
| **swatches** | colors to pick with one click | `string[]` | - | - |
| **hexInput** | show the field for the hex code | `boolean` | - | `true` |
| **disabled** | disable the component | `boolean` | - | `false` |
| **panelLabel** | name of the square, for screen readers | `string` | - | `Saturation and brightness` |
| **hueLabel** | name of the hue bar | `string` | - | `Hue` |
| **hexLabel** | name of the hex field | `string` | - | `Hex color` |
| ... | native props, passed to the root `div` | `HTMLAttributes` | `'aria-label', 'id', ...` | - |
Hex field
The field changes the color as soon as it holds six digits, with or without the `#`. A short code like `#abc` is read when the field loses the focus, and becomes `#aabbcc`. Any other text is dropped on blur, and the field goes back to the current color.
Ref
The `ref` points at the root `div`.
Accessibility
The square is a `slider` named by `panelLabel`, whose value reads like "40% saturation, 80% brightness". With the focus on it, Left and Right change the saturation and Up and Down the brightness, by 1%, or by 10% with Shift. The hue bar is a native range input, and the swatches are buttons named by their code, with `aria-pressed` on the one in use. The color is never conveyed by the swatch alone, because the hex code is also a text.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Combobox, Grid, Code } from 'core'
export const meta = {
title: 'Combobox',
description:
'An input that filters a list of options while you type and lets you pick one.',
sidebar: 'components',
group: 'Components',
index: 42
}
## Combobox
An input that filters a list of options while you type and lets you pick one.
Use it when the list is long enough that a `Select` is hard to scan.
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
Combobox.Props
| Attribute | Description | Type | Accepted values | Default |
| ----------------- | ---------------------------------------------------------- | --------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------- |
| **options** | the options to choose from | `ComboboxOption[]` | [ComboboxOption](#comboboxoption) | - |
| **value** | selected value, to control the component | `string` / `null` | - | - |
| **initialValue** | selected value at the start | `string` / `null` | - | `null` |
| **onChange** | called with the chosen value, or `null` when it is cleared | (value: string | null) => void | - | - |
| **onInputChange** | called with the text while the user types | `(text: string) => void` | - | - |
| **filter** | decides which options match the text | `(option, text) => boolean` | - | contains, case insensitive |
| **placeholder** | text shown when the input is empty | `string` | - | - |
| **emptyText** | text shown when no option matches | `string` | - | `No results` |
| **disabled** | disable the component | `boolean` | - | `false` |
| **rounded** | round the corners | `boolean` | - | `false` |
| **filled** | filled variant | `boolean` | - | `false` |
| **light** | light variant | `boolean` | - | `false` |
| **ghost** | outline variant | `boolean` | - | `false` |
| **subtle** | subtle variant | `boolean` | - | `false` |
| **type** | color of the field | `NormalTypes` | `'default', 'primary', 'secondary', 'success', 'warning', 'error', 'info'` | `default` |
| **rounded** | round the corners | `boolean` | - | `false` |
| **filled** | filled variant | `boolean` | - | `false` |
| **light** | light variant | `boolean` | - | `false` |
| **ghost** | outline variant | `boolean` | - | `false` |
| **subtle** | subtle variant | `boolean` | - | `false` |
| ... | native props, passed to the input | `InputHTMLAttributes` | `'aria-label', 'name', 'id', ...` | - |
ComboboxOption
```ts
type ComboboxOption = {
value: string
label?: string // shown in the list and in the input, `value` when missing
disabled?: boolean
}
```
Ref
The `ref` points at the `input`.
Accessibility
The input has `role="combobox"` and points at the active option with `aria-activedescendant`. The list is a `listbox` of `option` elements.
| Key | Action |
| ----------------- | ---------------------------------------------------- |
| Arrow Down and Up | Open the list, and move between the options |
| Enter | Choose the active option |
| Escape | Close the list |
| Tab | Close the list and restore the text of the selection |
A screen reader hears how many options match while the user types. Give the input a name with `aria-label` or `aria-labelledby`.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Command, Button, Keyboard, useKeyboard, KeyCode, KeyMod, Grid, Text } from 'core'
import { useState } from 'react'
import { Home, Settings, Search, Plus, UserPlus, CreditCard, LogOut } from '@bolio-ui/icons'
export const meta = {
title: 'Command',
description: 'A searchable list of actions, opened with a shortcut.',
sidebar: 'components',
group: 'Components',
index: 57
}
## Command
A searchable list of actions, opened with a shortcut.
{
const [open, setOpen] = useState(false)
const items = [
{ value: 'home', label: 'Go to home', icon: , onSelect: () => console.log('home') },
{ value: 'settings', label: 'Open settings', icon: , hint: 'G S', onSelect: () => console.log('settings') },
{ value: 'theme', label: 'Switch theme', hint: 'T', onSelect: () => console.log('theme') }
]
return (
<>
setOpen(false)} items={items} />
>
)
}
`}
/>
{
const [open, setOpen] = useState(false)
useKeyboard(
(event) => {
event.preventDefault()
setOpen(true)
},
[KeyCode.KEY_K, KeyMod.CtrlCmd]
)
const items = [
{ value: 'new', label: 'New project', onSelect: () => console.log('new') },
{ value: 'invite', label: 'Invite a teammate', onSelect: () => console.log('invite') }
]
return (
<>
K setOpen(false)} items={items} />
>
)
}
`}
/>
{
const [open, setOpen] = useState(false)
const [last, setLast] = useState('nothing yet')
const run = (name) => () => setLast(name)
const items = [
{ value: 'new', label: 'Create project', icon: , hint: 'N', onSelect: run('created a project') },
{ value: 'invite', label: 'Invite a teammate', icon: , onSelect: run('opened the invite form') },
{ value: 'billing', label: 'Go to billing', icon: , hint: 'G B', onSelect: run('went to billing') },
{ value: 'settings', label: 'Open settings', icon: , hint: 'G S', onSelect: run('opened settings') },
{ value: 'signout', label: 'Sign out', icon: , onSelect: run('signed out') }
]
return (
<>
} onClick={() => setOpen(true)}>Search or run a command
Last action: {last} setOpen(false)} items={items} />
>
)
}
`}
/>
Command.Props
| Attribute | Description | Type | Accepted values | Default |
| --------------- | ----------------------------------- | -------------------- | --------------- | ------------------------------ |
| **visible** | show the palette | `boolean` | - | - |
| **onClose** | called on Esc, backdrop or selection | `() => void` | - | - |
| **items** | actions to list | `CommandItem[]` | - | - |
| **placeholder** | placeholder of the search field | `string` | - | `Type a command or search` |
| **emptyText** | shown when nothing matches | `string` | - | `No results. Try another word.` |
CommandItem
```ts
interface CommandItem {
value: string
label: string
icon?: React.ReactNode
hint?: React.ReactNode
onSelect?: () => void
}
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Container, Card, Text, Button, Grid } from 'core'
export const meta = {
title: 'Container',
description: 'Limit the width of the page and center its content.',
sidebar: 'components',
group: 'Components',
index: 45
}
## Container
Limit the width of the page and center its content. Put a `Row` inside it to build the layout. See the page structure guide.
The content of the page.
`}
/>
This one has no maximum width.
`}
/>
Build your interface fasterAccessible components, themes that follow your brand and docs you can copy from.
`}
/>
Container.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------- | --------------------------------------------------------------- | --------------------- | --------------------------------------------- | ------- |
| **fluid** | remove the maximum width | `boolean` | - | `false` |
| **justify** | horizontal alignment, when the Container is a flex box | `string` | `start`, `end`, `center`, `space-around`, `space-between` | `start` |
| **align** | vertical alignment, when the Container is a flex box | `string` | `top`, `middle`, `bottom` | `top` |
| **component** | the element to render | `keyof JSX.IntrinsicElements` | `'div', 'main', 'section', ...` | `div` |
| ... | native props | `HTMLAttributes` | `'id', 'className', ...` | - |
`justify` and `align` only have an effect when you make the Container a flex box, for example with `style={{ display: 'flex' }}`.
Ref
The `ref` points at the root element.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { ContextMenu, Menu, Card, Text, Grid } from 'core'
export const meta = {
title: 'Context Menu',
description:
'A menu of actions that opens at the pointer when the user right clicks an area.',
sidebar: 'components',
group: 'Components',
index: 67
}
## Context Menu
A menu of actions that opens at the pointer when the user right clicks an area.
It is a Menu placed at the cursor, so it has
the same items, submenus and keys.
CopyPasteDelete
>
}
>
Right click anywhere in this card
`}
/>
{
const [last, setLast] = React.useState('Right click a file.')
const files = ['Contract.pdf', 'Invoice.pdf', 'Photo.png']
return (
{files.map((file) => (
setLast('Opened ' + file)}>Open setLast('Renamed ' + file)}>Rename setLast('Emailed ' + file)}>Email setLast('Copied the link to ' + file)}>Copy link setLast('Deleted ' + file)}>Delete
>
}
>
{file}
))}
{last}
)
}
`}
/>
Never shown}>
The menu of the browser opens here
`}
/>
ContextMenu.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------------- | --------------------------------------------------------------- | ---------------------------- | ---------------------------------------- | ------- |
| **content** | the items of the menu | `ReactNode` | `Menu.Item`, `Menu.Sub`, `Menu.Divider`, ... | - |
| **disabled** | leave the right click to the browser | `boolean` | - | `false` |
| **onVisibleChange** | called with `true` when the menu opens and `false` when it closes | `(visible: boolean) => void` | - | - |
| ... | native props, passed to the area `div` | `HTMLAttributes` | `'tabIndex', 'id', 'style', ...` | - |
Behavior
- • **Position**: the menu opens at the pointer and flips to the other side when there is no room.
- • **Another right click** moves the menu to the new point.
- • **Closing**: choosing an item, Escape, a click outside and a scroll of the page all close it. The focus goes back to the area.
- • **Items** are the ones of Menu, with the same keys: arrows, Home, End, Enter, Space and the first letters.
- • **onContextMenu**: a handler you pass to the area runs first, and calling `preventDefault` there keeps the menu closed.
Ref
The `ref` points at the area `div`.
Accessibility
The right click is not the only way in. The keyboard opens a context menu with Shift and F10, or with the menu key, on a focused element, and the browser sends the same event with the position of that element. For that, the area, or something inside it, has to be focusable: use `tabIndex={0}` on the area when it has nothing focusable. The menu is a `menu` with `menuitem` children, as in Menu. Touch screens have no right click, so keep a visible way to reach the same actions, like a button with a Menu.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { DatePicker, Grid, Code } from 'core'
export const meta = {
title: 'DatePicker',
description: 'An input to type a date, with a calendar to pick it.',
sidebar: 'components',
group: 'Components',
index: 44
}
## DatePicker
An input to type a date, with a calendar to pick it. The text is a date in the `YYYY-MM-DD` format, which is the same in every country.
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
DatePicker.Props
| Attribute | Description | Type | Accepted values | Default |
| ----------------- | -------------------------------------------------------- | ------------------------------------------------ | -------------------------------------------------------------------------- | ------------- |
| **value** | selected date, to control the component | `Date` / `null` | - | - |
| **initialValue** | date at the start | `Date` / `null` | - | `null` |
| **onChange** | called with the date, or `null` when the text is emptied | (date: Date | null) => void | - | - |
| **min** | first date that can be picked | `Date` | - | - |
| **max** | last date that can be picked | `Date` | - | - |
| **locale** | language of the calendar | `string` | any `Intl` locale | `en-US` |
| **weekStartsOn** | first day of the week in the calendar, 0 is Sunday | `number` | `0` to `6` | `0` |
| **placeholder** | text shown when the input is empty | `string` | - | `YYYY-MM-DD` |
| **calendarLabel** | name of the calendar button and of its dialog | `string` | - | `Choose date` |
| **disabled** | disable the component | `boolean` | - | `false` |
| **rounded** | round the corners | `boolean` | - | `false` |
| **filled** | filled variant | `boolean` | - | `false` |
| **light** | light variant | `boolean` | - | `false` |
| **ghost** | outline variant | `boolean` | - | `false` |
| **subtle** | subtle variant | `boolean` | - | `false` |
| **type** | color of the field | `NormalTypes` | `'default', 'primary', 'secondary', 'success', 'warning', 'error', 'info'` | `default` |
| **rounded** | round the corners | `boolean` | - | `false` |
| **filled** | filled variant | `boolean` | - | `false` |
| **light** | light variant | `boolean` | - | `false` |
| **ghost** | outline variant | `boolean` | - | `false` |
| **subtle** | subtle variant | `boolean` | - | `false` |
| ... | native props, passed to the input | `InputHTMLAttributes` | `'aria-label', 'name', ...` | - |
Typing
The value changes only for a real date inside `min` and `max`. `2026-02-31` is not accepted. When the input loses the focus, it goes back to the last valid date. An empty text clears the value.
Ref
The `ref` points at the `input`.
Accessibility
The calendar button has `aria-haspopup="dialog"` and `aria-expanded`. The calendar opens in a dialog with the focus on the day of the current value. Escape closes it and puts the focus back on the button, and picking a day puts the focus on the input. See Calendar for the keys.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { DateRangePicker, Grid, Text, Code } from 'core'
export const meta = {
title: 'DateRangePicker',
description:
'Two inputs to type a start and an end date, with one calendar to pick the range.',
sidebar: 'components',
group: 'Components',
index: 60
}
## DateRangePicker
Two inputs to type a start and an end date, with a calendar of two months to pick the
range. When there is not room for two months, for example on a phone, it shows one. The text is a date in the `YYYY-MM-DD` format, which is the same in every country.
`}
/>
`}
/>
{
const [range, setRange] = React.useState([null, null])
const format = (date) => (date ? date.toDateString() : '...')
return (
From {format(range[0])} to {format(range[1])}.
)
}
`}
/>
`}
/>
`}
/>
`}
/>
DateRangePicker.Props
| Attribute | Description | Type | Accepted values | Default |
| -------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------- |
| **value** | selected range, to control the component | [Date | null, Date | null] | - | - |
| **initialValue** | range at the start | [Date | null, Date | null] | - | `[null, null]` |
| **onChange** | called with `[start, end]`, with `end` as `null` while the range is picked | (range: [Date | null, Date | null]) => void | - | - |
| **min** | first date that can be picked | `Date` | - | - |
| **max** | last date that can be picked | `Date` | - | - |
| **locale** | language of the calendar | `string` | any `Intl` locale | `en-US` |
| **weekStartsOn** | first day of the week in the calendar, 0 is Sunday | `number` | `0` to `6` | `0` |
| **startPlaceholder** | text shown when the start input is empty | `string` | - | `YYYY-MM-DD` |
| **endPlaceholder** | text shown when the end input is empty | `string` | - | `YYYY-MM-DD` |
| **startLabel** | name of the start input | `string` | - | `Start date` |
| **endLabel** | name of the end input | `string` | - | `End date` |
| **calendarLabel** | name of the calendar button and of its dialog | `string` | - | `Choose dates` |
| **disabled** | disable the component | `boolean` | - | `false` |
| **type** | color of the field | `NormalTypes` | `'default', 'primary', 'secondary', 'success', 'warning', 'error', 'info'` | `default` |
| **rounded** | round the corners | `boolean` | - | `false` |
| **filled** | filled variant | `boolean` | - | `false` |
| **light** | light variant | `boolean` | - | `false` |
| **ghost** | outline variant | `boolean` | - | `false` |
| **subtle** | subtle variant | `boolean` | - | `false` |
| ... | native props, passed to the group `div` | `HTMLAttributes` | `'aria-label', 'id', ...` | - |
Typing
Each input changes the range only for a real date inside `min` and `max`. The end cannot come before the start, so that text is not accepted. When an input loses the focus, it goes back to the last valid date. An empty text clears that edge of the range.
Ref
The `ref` points at the group `div`.
Accessibility
The group is named by `aria-label`, and each input has its own name, `Start date` and `End date`, which you can translate with `startLabel` and `endLabel`. The calendar button has `aria-haspopup="dialog"` and `aria-expanded`. The calendar opens in a dialog that shows two months side by side, or one month when there is not room, with the focus on the day of the start. Escape closes it and puts the focus back on the button, and picking the end puts the focus on the end input. See Calendar for the keys.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Description, Code, Grid, Card, Badge } from 'core'
export const meta = {
title: 'Description',
description: 'Display brief information with a title and description.',
sidebar: 'components',
group: 'Components',
index: 12
}
## Description
Display brief information with a title and description.
`}
/>
code about this section.
}
/>
`}
/>
Pro} />
`}
/>
Description.Props
| Attribute | Description | Type | Accepted values | Default |
| ----------- | ------------ | ---------------------- | --------------- | ------- |
| **title** | title text | `ReactNode` / `string` | - | - |
| **content** | title text | `ReactNode` / `string` | - | - |
| ... | native props | `HTMLAttributes` | - | - |
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Display, Code, Snippet, Image, Grid } from 'core'
export const meta = {
title: 'Display',
description:
'To display important information or images in a central alignment.',
sidebar: 'components',
group: 'Components',
index: 13
}
## Display
To display important information or images in a central alignment.
`}
/>
{
const codes = \`{
"build": {
"env": {
"VARIABLE": "ENV_SECRET"
}
}
}\`
return (
{codes}
)
}
`}
/>
`}
/>
Browse bolio-ui.com.br for more information.}>
`}
/>
Display.Props
| Attribute | Description | Type | Accepted values | Default |
| ----------- | ----------------------------- | ---------------------- | --------------- | ------- |
| **caption** | description for display block | `ReactNode` / `string` | - | - |
| **shadow** | show shadow | `boolean` | - | `false` |
| ... | native props | `HTMLAttributes` | - | - |
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Layout, Playground, Attributes } from 'src/components'
import { Divider, Text, Grid } from 'core'
export const meta = {
title: 'Divider',
description: 'A divider line separates different content.',
sidebar: 'components',
group: 'Components',
index: 14
}
## Divider
A divider line separates different content.
React makes it painless to create interactive UIs. Design simple views
for each state in your application, and React will efficiently update
and render just the right components when your data changes.
Declarative views make your code more predictable and easier to debug.
`}
/>
React makes it painless to create interactive UIs. Design simple views
for each state in your application, and React will efficiently update
and render just the right components when your data changes.
A Simple Component
React components implement a render() method that takes input data and
returns what to display. This example uses an XML-like syntax called
JSX. Input data that is passed into the component can be accessed by
render() via this.props.
A Stateful Component
In addition to taking input data (accessed via this.props), a component
can maintain internal state data (accessed via this.state). When a
component’s state data changes, the rendered markup will be updated by
re-invoking render().
`}
/>
React makes it painless to create interactive UIs. Design simple views
for each state in your application, and React will efficiently update
and render just the right components when your data changes.
A Simple Component
React components implement a render() method that takes input data and
returns what to display. This example uses an XML-like syntax called
JSX. Input data that is passed into the component can be accessed by
render() via this.props.
A Stateful Component
In addition to taking input data (accessed via this.props), a component
can maintain internal state data (accessed via this.state). When a
component’s state data changes, the rendered markup will be updated by
re-invoking render().
`}
/>
React makes it painless to create interactive UIs. Design simple views
for each state in your application, and React will efficiently update
and render just the right components when your data changes.
A Simple Component
React components implement a render() method that takes input data and
returns what to display. This example uses an XML-like syntax called
JSX. Input data that is passed into the component can be accessed by
render() via this.props.
A Stateful Component
In addition to taking input data (accessed via this.props), a component
can maintain internal state data (accessed via this.state). When a
component’s state data changes, the rendered markup will be updated by
re-invoking render().
`}
/>
Divider.Props
| Attribute | Description | Type | Accepted values | Default |
| --------- | ----------------- | ----------------------------- | -------------------------------- | --------- |
| **type** | type of divier | [DividerTypes](#dividertypes) | - | `default` |
| **align** | alignment of text | [DividerAlign](#divideralign) | - | `center` |
| ... | native props | `HTMLAttributes` | `'id', 'name', 'className', ...` | - |
DividerTypes
```ts
type DividerTypes =
| 'default'
| 'primary'
| 'secondary'
| 'success'
| 'warning'
| 'error'
| 'info'
| 'dark'
| 'lite'
```
DividerAlign
```ts
type DividerAlign = 'center' | 'start' | 'left' | 'end' | 'right'
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Dot, Grid, Card } from 'core'
export const meta = {
title: 'Dot',
description: 'Display an indicator of standardization status.',
sidebar: 'components',
group: 'Components',
index: 15
}
## Dot
Display an indicator of standardization status.
`}
/>
CanceledPrimarySecondaryReadyWarningErrorInfo
`}
/>
{[
['success', 'API', 'Operational'],
['warning', 'Webhooks', 'Delayed by 4 minutes'],
['error', 'Payments', 'Down since 09:12']
].map(([type, name, state]) => (
{name}: {state}
))}
`}
/>
Dot.Props
| Attribute | Description | Type | Accepted values | Default |
| --------- | ------------ | ---------------- | --------------------- | --------- |
| **type** | dot type | `DotTypes` | [DotTypes](#dottypes) | `default` |
| ... | native props | `HTMLAttributes` | - | - |
DotTypes
```ts
type DotTypes =
| 'default'
| 'primary'
| 'secondary'
| 'success'
| 'warning'
| 'error'
| 'info'
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Drawer, Button, Grid, Input, Spacer } from 'core'
export const meta = {
title: 'Drawer',
description: 'An interactive element fixed to the edge of the screen.',
sidebar: 'components',
group: 'Components',
index: 16
}
## Drawer
An interactive element fixed to the edge of the screen.
{
const [state, setState] = React.useState(false)
return (
setState(false)}
placement="right"
>
DrawerExample of a drawer
{posted !== null && Posted, {posted} {posted === 1 ? 'person' : 'people'} notified.}
)
}
`}
/>
Mention.Props
| Attribute | Description | Type | Accepted values | Default |
| ---------------- | ---------------------------------------------------------------- | ----------------------------------------------------- | --------------- | ------------ |
| **options** | what can be mentioned. `value` is inserted, `label` is shown | `{ value: string; label?: string; disabled?: boolean }[]` | - | - |
| **trigger** | character that opens the list | `string` | - | `@` |
| **value** | text of the field, to control it | `string` | - | - |
| **initialValue** | text at the start | `string` | - | `''` |
| **onChange** | called with the new text | `(text: string) => void` | - | - |
| **onSelect** | called with the option that was inserted | `(option: MentionOption) => void` | - | - |
| **rows** | height of the field | `number` | - | `3` |
| **placeholder** | hint while the field is empty | `string` | - | - |
| **emptyText** | shown when nothing matches | `string` | - | `No results` |
| **disabled** | block the field | `boolean` | - | `false` |
| ... | native props of the textarea | `TextareaHTMLAttributes` | - | - |
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Menu, Button, Grid } from 'core'
export const meta = {
title: 'Menu',
description:
'A list of actions that opens from a button, with submenus, checkbox and radio items and keyboard support.',
sidebar: 'components',
group: 'Components',
index: 49
}
## Menu
A list of actions that opens from a button. Use it for commands, like editing
or sharing something. To pick a value for a form, use `Select` or `Combobox`.
`}
/>
`}
/>
`}
/>
{
const [grid, setGrid] = React.useState(true)
const [ruler, setRuler] = React.useState(false)
const [sort, setSort] = React.useState('name')
return (
)
}
`}
/>
{
const [visible, setVisible] = React.useState(false)
return (
)
}
`}
/>
Menu.Props
| Attribute | Description | Type | Accepted values | Default |
| --------------------- | ---------------------------------------------------- | ------------------------------ | --------------------------------- | ------- |
| **trigger** | the element that opens the menu, usually a `Button` | `ReactElement` | - | - |
| **visible** | open state, to control the menu | `boolean` | - | - |
| **initialVisible** | open state at the start | `boolean` | - | `false` |
| **onVisibleChange** | called when the menu wants to open or close | `(visible: boolean) => void` | - | - |
| **getPopupContainer** | element that receives the menu, `document.body` when missing | `() => HTMLElement` | - | - |
| ... | native props, passed to the element around the trigger | `HTMLAttributes` | `'id', 'className', ...` | - |
Menu.Item.Props
| Attribute | Description | Type | Accepted values | Default |
| -------------------- | ----------------------------------------------- | -------------------------- | ------------------------ | --------- |
| **onClick** | called when the item is chosen, by click or key | `(event) => void` | - | - |
| **icon** | shown before the label | `ReactNode` | - | - |
| **shortcut** | shown after the label, only for the eye | `string` | - | - |
| **type** | color of the item | `string` | `'default', 'error'` | `default` |
| **disabled** | the item cannot be chosen or focused | `boolean` | - | `false` |
| **disableAutoClose** | keep the menu open after the item is chosen | `boolean` | - | `false` |
| ... | native props | `HTMLAttributes` | `'aria-keyshortcuts', ...` | - |
Menu.CheckboxItem.Props
Accepts the props of `Menu.Item`, except `onClick`, plus:
| Attribute | Description | Type | Accepted values | Default |
| -------------------- | ------------------------------------------- | ----------------------------- | --------------- | ------- |
| **checked** | whether the option is on | `boolean` | - | `false` |
| **onChange** | called with the new state | `(checked: boolean) => void` | - | - |
| **disableAutoClose** | keep the menu open after the item is chosen | `boolean` | - | `true` |
Menu.RadioGroup.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------ | ---------------------------------------------- | ------------------------- | ------------------------ | ------- |
| **value** | the value of the checked item | `string` | - | - |
| **onChange** | called with the value of the chosen item | `(value: string) => void` | - | - |
| ... | native props, name the group with `aria-label` | `HTMLAttributes` | `'aria-label', ...` | - |
Menu.RadioItem.Props
Accepts the props of `Menu.Item`, except `onClick`, plus:
| Attribute | Description | Type | Accepted values | Default |
| -------------------- | ------------------------------------------- | --------- | --------------- | ------- |
| **value** | the value this item checks in its group | `string` | - | - |
| **disableAutoClose** | keep the menu open after the item is chosen | `boolean` | - | `true` |
Menu.Sub.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------ | ----------------------------------- | ---------------- | --------------- | ------- |
| **label** | text of the item that opens it | `ReactNode` | - | - |
| **icon** | shown before the label | `ReactNode` | - | - |
| **disabled** | the submenu cannot be opened | `boolean` | - | `false` |
| ... | native props, passed to the item | `HTMLAttributes` | - | - |
Menu.Label and Menu.Divider
Both accept native props. `Menu.Label` is a title for the items below it, and `Menu.Divider` is a line between groups.
Ref
The `ref` of `Menu` points at the element around the trigger. The `ref` of each item, of `Menu.Label` and of `Menu.Divider` points at its own element, and the `ref` of `Menu.Sub` at the item that opens it.
Accessibility
The trigger gets `aria-haspopup="menu"` and `aria-expanded`. The list is a `menu`, named by the trigger, with `menuitem`, `menuitemcheckbox` and `menuitemradio` items. A radio group is a `group`; name it with `aria-label`. The `shortcut` is only visual: to announce it, pass `aria-keyshortcuts`, like `aria-keyshortcuts="Meta+E"`.
| Key | Action |
| --------------------- | ---------------------------------------------------------- |
| Arrow Down and Up | On the trigger, open on the first or the last item. In the menu, move between the items |
| Enter and Space | Choose the focused item, or open its submenu |
| Home and End | Go to the first or the last item |
| Arrow Right | Open the submenu of the focused item |
| Arrow Left | Close the submenu and go back to its item |
| Escape | Close the submenu, or the menu and focus the trigger |
| Tab | Close the menu and focus the trigger |
| Letters | Go to the next item that starts with what was typed |
Disabled items are skipped by the keyboard.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Modal, Button, Code, useModal, Grid, Text } from 'core'
import { useState } from 'react'
export const meta = {
title: 'Modal',
description:
'Display popup content that requires attention or provides additional information.',
sidebar: 'components',
group: 'Components',
index: 24
}
## Modal
Display popup content that requires attention or provides additional information.
If you just need to prompt for a text message, try component [Toast](/docs/hooks/use-toast).
The Modal contain an additional Hooks, see subsection [useModal](/docs/hooks/use-modal) for details.
{
const [state, setState] = useState(false)
const handler = () => setState(true)
const closeHandler = (event) => {
setState(false)
console.log('closed')
}
return (
setState(false)}>
ModalExample of a modal
)
}
`}
/>
{
const { visible, setVisible, bindings } = useModal()
return (
ModalExample of a modal
Demo content for the modal.
setVisible(false)}>
Cancel
Accepted
)
}
`}
/>
{
const { visible, setVisible, bindings } = useModal()
return (
ModalModal with a very large content
React has been designed from the start for gradual adoption, and
you can use as little or as much React as you need. Whether you
want to get a taste of React, add some interactivity to a simple
HTML page, or start a complex React-powered app, the links in this
section will help you get started.
React has been designed from the start for gradual adoption, and
you can use as little or as much React as you need. Whether you
want to get a taste of React, add some interactivity to a simple
HTML page, or start a complex React-powered app, the links in this
section will help you get started.
React has been designed from the start for gradual adoption, and
you can use as little or as much React as you need. Whether you
want to get a taste of React, add some interactivity to a simple
HTML page, or start a complex React-powered app, the links in this
section will help you get started.
React has been designed from the start for gradual adoption, and
you can use as little or as much React as you need. Whether you
want to get a taste of React, add some interactivity to a simple
HTML page, or start a complex React-powered app, the links in this
section will help you get started.
React has been designed from the start for gradual adoption, and
you can use as little or as much React as you need. Whether you
want to get a taste of React, add some interactivity to a simple
HTML page, or start a complex React-powered app, the links in this
section will help you get started.
React has been designed from the start for gradual adoption, and
you can use as little or as much React as you need. Whether you
want to get a taste of React, add some interactivity to a simple
HTML page, or start a complex React-powered app, the links in this
section will help you get started.
React has been designed from the start for gradual adoption, and
you can use as little or as much React as you need. Whether you
want to get a taste of React, add some interactivity to a simple
HTML page, or start a complex React-powered app, the links in this
section will help you get started.
{unread ? unread + ' unread' : 'You are all caught up'}Ana commented on Pricing.mdRui invited you to BillingYour export is ready
)
return (
}>Notifications
)
}
`}
/>
Popover.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------------------- | ---------------------------------------------- | ----------------------------- | ------------------- | -------- |
| **content** | content of pop-up | `ReactNode` `() => ReactNode` | - | - |
| **visible** | visible or not | `boolean` | - | `false` |
| **initialVisible** | visible on initial | `boolean` | - | `false` |
| **hideArrow** | hide arrow icon | `boolean` | - | `false` |
| **placement** | position of the popover relative to the target | [Placement](#placement) | - | `bottom` |
| **trigger** | tooltip trigger mode | `'click' / 'hover'` | - | `click` |
| **enterDelay**(ms) | delay before popover is shown | `number` | - | `100` |
| **leaveDelay**(ms) | delay before popover is hidden | `number` | - | `0` |
| **offset**(px) | distance between pop-up and target | `number` | - | `12` |
| **portalClassName** | className of pop-up box | `string` | - | - |
| **onVisibleChange** | call when visibility of the popover is changed | `(visible: boolean) => void` | - | - |
| **disableItemsAutoClose** | prevent close Popover when Items clicked | `boolean` | - | - |
| ... | native props | `HTMLAttributes` | `'id', 'name', ...` | - |
Popover.Item
| Attribute | Description | Type | Accepted values | Default |
| -------------------- | ---------------------------------- | --------- | --------------- | ------- |
| **line** | show a line | `boolean` | - | `false` |
| **title** | show text with title style | `boolean` | - | `false` |
| **disableAutoClose** | prevent close Popover when clicked | `boolean` | - | `false` |
Placement
```ts
type Placement = 'top'
| 'topStart',
| 'topEnd',
| 'left',
| 'leftStart',
| 'leftEnd',
| 'bottom',
| 'bottomStart',
| 'bottomEnd',
| 'right',
| 'rightStart',
| 'rightEnd',
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Progress, Grid, useTheme, Button, Text } from 'core'
import { useState } from 'react'
export const meta = {
title: 'Progress',
description: 'Display progress relative to a limit or related to a task.',
sidebar: 'components',
group: 'Components',
index: 28
}
## Progress
Display progress relative to a limit or related to a task.
`}
/>
`}
/>
{
const theme = useTheme()
const [value, setValue] = useState(20)
const colors = {
20: theme.palette.error,
40: theme.palette.warning,
60: theme.palette.success,
80: '#000'
}
return (
)
}`}
/>
`}
/>
`}
/>
`}
/>
{
const [value, setValue] = React.useState(0)
const upload = () => {
setValue(10)
const timer = setInterval(() => {
setValue((last) => {
if (last >= 100) {
clearInterval(timer)
return 100
}
return last + 10
})
}, 300)
}
const label = value === 100 ? 'Upload complete' : value ? 'Uploading report.pdf, ' + value + '%' : 'report.pdf is ready to upload'
return (
{label}
)
}
`}
/>
Progress.Props
| Attribute | Description | Type | Accepted values | Default |
| --------------- | ---------------------- | --------------------------- | ------------------------------- | --------- |
| **value** | current value | `number` | - | 0 |
| **max** | max value | `number` | - | 100 |
| **fixedTop** | fix progress to top | `boolean` | - | `false` |
| **fixedBottom** | fix progress to bottom | `boolean` | - | `false` |
| **segments** | split the bar in blocks | `number` | - | - |
| **circular** | show a ring instead of a bar | `boolean` | - | `false` |
| **colors** | custom colors | `{ [key: number]: string }` | - | - |
| **type** | predefined state types | `ProgressTypes` | [ProgressTypes](#progresstypes) | `default` |
| ... | native props | `ProgressHTMLAttributes` | `'aria-busy', ...` | - |
ProgressTypes
```ts
type ProgressTypes =
| 'default'
| 'primary'
| 'secondary'
| 'success'
| 'warning'
| 'error'
| 'info'
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Radio, Grid, Code, Button } from 'core'
import { useState } from 'react'
export const meta = {
title: 'Radio',
description: 'Provides single user input from a selection of options.',
sidebar: 'components',
group: 'Components',
index: 29
}
## Radio
Provides single user input from a selection of options.
Option 1
`}
/>
{
const [state, setState] = useState('1')
const handler = (val) => {
setState(val)
console.log(val)
}
return (
Option 1Option 2
)
}
`}
/>
Default
Primary
Secondary
Success
Warning
Error
Info
`}
/>
console.log(val)}>
Option 1
Example description for Option 1
`}
/>
Option 1Option 2
`}
/>
Option 1Description for Option1
Option 2Description for Option2
`}
/>
{
const plans = {
free: ['Free', '$0 a month', '1 project'],
pro: ['Pro', '$12 a month', 'Unlimited projects'],
team: ['Team', '$36 a month', 'Up to 10 members']
}
const [plan, setPlan] = React.useState('pro')
return (
{Object.entries(plans).map(([key, [name, price, hint]]) => (
{name}
{price}. {hint}.
))}
)
}
`}
/>
Radio.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------ | ----------------------------- | ---------------------------------------------- | ------------------------- | --------- |
| **checked** | selected or not (in single) | `boolean` | - | `false` |
| **value** | unique ident value (in group) | `string` | - | - |
| **id** | native attr | `string` | - | - |
| **disabled** | disable current radio | `boolean` | - | `false` |
| **type** | current type | `RadioTypes` | [RadioTypes](#radiotypes) | `default` |
| **onChange** | change event | `(e: RadioEvent) => void` | - | - |
| **ref** | forwardRef | Ref<HTMLInputElement | null> | - | - |
| ... | native props | `InputHTMLAttributes` | `'id', 'className', ...` | - |
Radio.Group.Props
| Attribute | Description | Type | Accepted values | Default |
| ---------------- | -------------------- | ------------------------- | ------------------------ | ------- |
| **initialValue** | initial value | `string` | - | - |
| **value** | selected child radio | `string` | - | - |
| **useRow** | horizontal layout | `boolean` | - | `false` |
| **disabled** | disable all radios | `boolean` | - | `false` |
| **onChange** | change event | `(value: string) => void` | - | - |
| ... | native props | `HTMLAttributes` | `'id', 'className', ...` | - |
Radio.Description.Props
| Attribute | Description | Type | Accepted values | Default |
| --------- | ------------ | ---------------- | ------------------------ | ------- |
| ... | native props | `HTMLAttributes` | `'id', 'className', ...` | - |
RadioTypes
```ts
type RadioTypes =
| 'default'
| 'primary'
| 'secondary'
| 'success'
| 'warning'
| 'error'
| 'info'
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Rating, Grid } from 'core'
import { useState } from 'react'
import { Umbrella, Zap } from '@bolio-ui/icons'
export const meta = {
title: 'Rating',
description: 'Pick or show a score with stars or any other icon.',
sidebar: 'components',
group: 'Components',
index: 30
}
## Rating
Pick or show a score with stars or any other icon. The value only changes when the user clicks or uses the arrow keys, and hovering shows a preview.
{
const [value, setValue] = useState(3)
return (
Selection: {value}
)
}
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
} />
} highlightSelectedOnly />
`}
/>
Rating.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------------------- | --------------------------------------------------- | ------------------------------------------ | --------------------------- | --------- |
| **value** | current score, to control the component | `number` | `0` to `count` | - |
| **initialValue** | score at the start | `number` | `0` to `count` | `0` |
| **onChange** | called with the score the user picked | `(value: number) => void` | - | - |
| **onHoverChange** | called with the previewed score, or `null` on leave | `(value: number \| null) => void` | - | - |
| **count** | amount of icons | `number` | - | `5` |
| **precision** | step of the score | `RatingPrecision` | `1`, `0.5` | `1` |
| **type** | color of the icons | `RatingTypes` | [RatingTypes](#ratingtypes) | `default` |
| **variant** | look of the empty icons | `RatingVariants` | `'outline', 'filled'` | `outline` |
| **icon** | icon of the filled state | `React.ReactNode` | - | star |
| **emptyIcon** | icon of the empty state | `React.ReactNode` | - | `icon` |
| **readOnly** | show the score without picking | `boolean` | - | `false` |
| **disabled** | block the component | `boolean` | - | `false` |
| **clearable** | a click on the current score clears it | `boolean` | - | `false` |
| **highlightSelectedOnly** | light only the icon of the score | `boolean` | - | `false` |
| **getLabel** | accessible name of each score | `(value: number, count: number) => string` | - | `3 of 5` |
| ... | native props | `HTMLAttributes` | - | - |
RatingTypes
```ts
type RatingTypes =
'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info'
```
Accessibility
The component is a group of native radio buttons, so the arrow keys move the score and Tab leaves the group. Give it an `aria-label`. With `readOnly` or `disabled` it becomes an image named by `getLabel`.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Row, Col, Card, Text } from 'core'
export const meta = {
title: 'Row',
description: 'A flex row that holds columns.',
sidebar: 'components',
group: 'Components',
index: 46
}
## Row
A flex row that holds columns. Each `Col` takes a number of twelfths of the row, so the spans in a row should add up to 12 or less.
span 4
span 4
span 4
`}
/>
span 3
span 3
`}
/>
short
a taller cell
`}
/>
gap 2
gap 2
`}
/>
Row.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------- | -------------------------------------------------------- | ----------------------------- | ---------------------------------------------------------- | ------- |
| **justify** | horizontal alignment of the columns | `string` | `start`, `end`, `center`, `space-around`, `space-between` | `start` |
| **align** | vertical alignment of the columns | `string` | `top`, `middle`, `bottom` | `top` |
| **gap** | space around the content of the columns, in theme gaps | `number` | - | `0` |
| **component** | the element to render | `keyof JSX.IntrinsicElements` | `'div', 'ul', 'section', ...` | `div` |
| ... | native props | `HTMLAttributes` | `'id', 'className', ...` | - |
The row does not wrap. If the spans add up to more than 12, the columns get narrower instead of going to the next line. Use a new `Row` for the next line, or use `Grid`, which wraps.
Ref
The `ref` points at the root element.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Section, Container, Text, Button, useTheme } from 'core'
export const meta = {
title: 'Section',
description: 'A band of the page, with an optional background.',
sidebar: 'components',
group: 'Components',
index: 48
}
## Section
A band of the page that groups related content, with an optional background. It renders a `section` element. Put a `Container` inside it to limit the width of the content.
A section of the page.
`}
/>
{
const theme = useTheme()
return (
A band with a background.
)
}
`}
/>
{
const theme = useTheme()
return (
<>
Everything you need to shipForms, tables and dialogs that work with your theme from the first line.Start with the free planNo card needed. Upgrade when your team grows.
>
)
}
`}
/>
Section.Props
| Attribute | Description | Type | Accepted values | Default |
| --------- | ------------------------------ | ---------------- | ------------------------ | ------------- |
| **bg** | background color | `string` | any CSS color | `transparent` |
| ... | native props | `HTMLAttributes` | `'id', 'className', ...` | - |
Ref
The `ref` points at the `section` element.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { SegmentedControl, Grid, Text } from 'core'
export const meta = {
title: 'Segmented Control',
description:
'A row of options where exactly one is selected, for switching a view or a setting in place.',
sidebar: 'components',
group: 'Components',
index: 58
}
## Segmented Control
A row of options where exactly one is selected. Use it to switch a view or a
setting in place, like a period or a layout.
DayWeekMonth
`}
/>
{
const [view, setView] = React.useState('list')
return (
ListGridBoardShowing the {view} view.
)
}
`}
/>
MonthlyYearly
`}
/>
ListGridBoardListGrid
`}
/>
SegmentedControl.Props
| Attribute | Description | Type | Accepted values | Default |
| ---------------- | -------------------------------------------- | ----------------------------------- | ------------------------- | ------- |
| **value** | selected item, to control it | `string` | `number` | - | - |
| **initialValue** | item selected on the first render | `string` | `number` | - | - |
| **onChange** | called with the `value` of the chosen item | `(value: string \| number) => void` | - | - |
| **disabled** | disables every item | `boolean` | - | `false` |
| **fullWidth** | fills the width of the container | `boolean` | - | `false` |
| ... | native props, passed to the `div` | `HTMLAttributes` | `'aria-label', 'id', ...` | - |
SegmentedControl.Item.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------ | -------------------------------------------- | ------------------------ | --------------- | ------- |
| **value** | identifies the item in `value` and `onChange` | `string` | `number` | - | - |
| **disabled** | the item cannot be chosen | `boolean` | - | `false` |
| ... | native props, passed to the radio `input` | `InputHTMLAttributes` | `'id', ...` | - |
Ref
The `ref` of `SegmentedControl` points at the `div`, and the `ref` of each item at its radio `input`.
Accessibility
The group is a `radiogroup` and each item is a native radio, so a screen reader announces the name of the group, the option and its position. Name the group with `aria-label`. Tab moves focus into the group on the selected item, and the arrow keys move between the items and select the one in focus. The selected item is not shown by color alone: it also gets a raised background.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Select, Grid, Code, Modal, useModal, Button, Text } from 'core'
export const meta = {
title: 'Select',
description: 'Display a dropdown list of items.',
sidebar: 'components',
group: 'Components',
index: 31
}
## Select
Display a dropdown list of items.
The Select contain an additional Hooks, see subsection [useModal](/docs/hooks/use-modal) for details.
{
const handler = (val) => console.log(val)
return (
)
}
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
{
const { visible, setVisible, bindings } = useModal()
return (
Modal
Scroll through the content to see the changes.
Scroll through the content to see the changes.
setVisible(false)}>Cancel
)
}`}
/>
{
const [status, setStatus] = React.useState('open')
const [sort, setSort] = React.useState('recent')
return (
Showing {status} issues, {sort}.
)
}
`}
/>
Select.Props
| Attribute | Description | Type | Accepted values | Default |
| --------------------------- | -------------------------------------------------------- | --------------------------------------------------- | --------------------------- | --------------- |
| **value** | selected value | `string`, `string[]` | - | - |
| **initialValue** | initial value | `string`, `string[]` | - | - |
| **placeholder** | placeholder string | `string` | - | - |
| **width** | css width value of select | `string` | - | `initial` |
| **type** | current type | `SelectTypes` | [SelectTypes](#selecttypes) | `default` |
| **icon** | icon component | `ComponentType` | - | `SVG Component` |
| **pure** | remove icon component | `boolean` | - | `false` |
| **multiple** | support multiple selection | `boolean` | - | `false` |
| **clearable** | add clear icon on multiple selection (ignored otherwise) | `boolean` | - | `true` |
| **disabled** | disable current radio | `boolean` | - | `false` |
| **rounded** | round the corners | `boolean` | - | `false` |
| **filled** | filled variant | `boolean` | - | `false` |
| **light** | light variant | `boolean` | - | `false` |
| **ghost** | outline variant | `boolean` | - | `false` |
| **subtle** | subtle variant | `boolean` | - | `false` |
| **rounded** | round the corners | `boolean` | - | `false` |
| **filled** | filled variant | `boolean` | - | `false` |
| **light** | light variant | `boolean` | - | `false` |
| **ghost** | outline variant | `boolean` | - | `false` |
| **subtle** | subtle variant | `boolean` | - | `false` |
| **onChange** | selected value | (val: string | string[]) => void | - | - |
| **dropdownClassName** | className of dropdown menu | `string` | - | - |
| **dropdownStyle** | style of dropdown menu | `object` | - | - |
| **disableMatchWidth** | disable Option from follow Select width | `boolean` | - | `false` |
| **getPopupContainer** | dropdown render parent element, the default is `body` | `() => HTMLElement` | - | - |
| **onDropdownVisibleChange** | dropdown change events | `(visible: boolean) => void` | - | - |
| **ref** | forwardRef | `SelectRef` | [SelectRef](#selectref) | - |
| ... | native props | `HTMLAttributes` | `'name', 'alt', ...` | - |
Select.Option.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------------- | ---------------------- | ---------------- | ------------------- | ------- |
| **value**(required) | unique ident value | `string` | - | - |
| **disabled** | disable current option | `boolean` | - | `false` |
| **divider** | display a line | `boolean` | - | `false` |
| **label** | display a group title | `boolean` | - | `false` |
| ... | native props | `HTMLAttributes` | `'name', 'id', ...` | - |
SelectRef
```ts
type SelectRef = {
focus: () => void
blur: () => void
scrollTo?: (options?: ScrollToOptions) => void
}
```
SelectTypes
```ts
type SelectTypes =
'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info'
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Skeleton, Grid, Text, Button } from 'core'
export const meta = {
title: 'Skeleton',
description:
'A placeholder in the shape of the content while it loads, so the layout does not jump.',
sidebar: 'components',
group: 'Components',
index: 50
}
## Skeleton
A placeholder in the shape of the content while it loads, so the layout does
not jump when the content arrives.
`}
/>
`}
/>
`}
/>
{
const [loading, setLoading] = React.useState(true)
return (
The content shows up here once it has loaded.
)
}
`}
/>
Skeleton.Props
| Attribute | Description | Type | Accepted values | Default |
| ----------- | ------------------------------------------------------------- | ------------------ | -------------------------- | ------- |
| **width** | width of the placeholder; a number is a multiple of the theme unit | `string` / `number` | `'60%'`, `'48px'`, ... | `100%`, `2.5em` for a circle |
| **height** | height of each line; a number is a multiple of the theme unit | `string` / `number` | `'120px'`, ... | `1em`, the width for a circle |
| **lines** | number of lines; the last one is shorter | `number` | - | `1` |
| **circle** | round shape, for avatars | `boolean` | - | `false` |
| **loading** | with children, shows the placeholder while `true` | `boolean` | - | `true` |
| ... | native props, passed to the root element | `HTMLAttributes` | `'id', 'className', ...` | - |
Ref
The `ref` points at the root element of the placeholder. With children and `loading={false}`, the children render alone and the `ref` is not used.
Accessibility
The placeholder has `aria-hidden`, so screen readers skip it. When it wraps content, the wrapper has `aria-busy="true"` while loading. With `prefers-reduced-motion`, the shimmer stops and the shapes stay still.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Slider, Grid, Text } from 'core'
import { useState } from 'react'
export const meta = {
title: 'Slider',
description: 'Display the current value and an inputable range.',
sidebar: 'components',
group: 'Components',
index: 32
}
## Slider
Display the current value and an inputable range.
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
{
const [value, setValue] = useState()
const handler = (val) => {
console.log(val)
setValue(val)
}
return (
)
}
`}
/>
{
const [budget, setBudget] = React.useState(500)
return (
Monthly budget: {'$' + budget}
)
}
`}
/>
Slider.Props
| Attribute | Description | Type | Accepted values | Default |
| ---------------- | -------------------------------------------------- | ----------------------- | -------------------------------- | --------- |
| **initialValue** | initial value | `number` | - | 0 |
| **value** | slider value | `number` | - | 0 |
| **type** | current type | `SliderTypes` | [SliderTypes](#slidertypes) | `default` |
| **step** | the granularity the slider can step through values | `number` | - | 1 |
| **max** | the maximum value of slider | `number` | - | 100 |
| **min** | the minimum value of slider | `number` | - | 0 |
| **disabled** | disable slider interaction | `boolean` | `false` |
| **showMarkers** | show each marker | `boolean` | - | `false` |
| **hideValue** | hide slider value | `boolean` | - | `false` |
| **onChange** | called when the value of silder changes | `(val: number) => void` | - | - |
| ... | native props | `HTMLAttributes` | `'id', 'name', 'className', ...` | - |
SliderTypes
```ts
type SliderTypes =
| 'default'
| 'primary'
| 'secondary'
| 'success'
| 'warning'
| 'error'
| 'info'
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Snippet, Grid, Code } from 'core'
export const meta = {
title: 'Snippet',
description: 'Display a snippet of copyable code for the command line.',
sidebar: 'components',
group: 'Components',
index: 33
}
## Snippet
Display a snippet of copyable code for the command line.
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
Snippet.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------- | ----------------------- | ------------------- | -------------------------------- | ---------------------- |
| **text** | code snippet | `string` `string[]` | - | - |
| **type** | snippet types | `SnippetTypes` | [SnippetTypes](#snippettypes) | `default` |
| **filled** | filled variant | `boolean` | - | `false` |
| **light** | light variant | `boolean` | - | `false` |
| **ghost** | outline variant | `boolean` | - | `false` |
| **subtle** | subtle variant | `boolean` | - | `false` |
| **width** | set CSS string | `string` | - | `initial` |
| **copy** | function of copy button | `CopyTypes` | [CopyTypes](#copytypes) | `default` |
| **symbol** | symbol snippet | `string` | - | `$` |
| **toastText** | toast text | `string` | - | `Copied to clipboard!` |
| **toastType** | toast type | `ToastTypes` | [ToastTypes](#toasttypes) | `success` |
| ... | native props | `HTMLAttributes` | `'id', 'name', 'className', ...` | - |
SnippetTypes
```ts
type SnippetTypes =
| 'default'
| 'primary'
| 'secondary'
| 'success'
| 'warning'
| 'error'
| 'info'
```
CopyTypes
```ts
type CopyTypes = 'default' | 'silent' | 'prevent'
```
ToastTypes
```ts
type ToastTypes =
| 'default'
| 'primary'
| 'secondary'
| 'success'
| 'warning'
| 'error'
| 'info'
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Spacer, Grid, Input, Button, useTheme } from 'core'
export const meta = {
title: 'Spacer',
description: 'Provide empty space.',
sidebar: 'components',
group: 'Components',
index: 34
}
## Spacer
Provide empty space.
{
const theme = useTheme()
const block = (color) => ({ background: color, borderRadius: theme.layout.radius })
return (
)
}
`}
/>
{
const theme = useTheme()
const block = { background: theme.palette.accents_3, borderRadius: theme.layout.radius }
return (
)
}
`}
/>
Email
Password
`}
/>
Spacer.Props
| Attribute | Description | Type | Accepted values | Default |
| ---------- | -------------- | ------------------ | ------------------------ | ------- |
| **w** | x-axis spacing | `number` / `float` | - | 1 |
| **h** | y-axis spacing | `number` / `float` | - | 1 |
| **inline** | inline space | `boolean` | - | `false` |
| ... | native props | `HTMLAttributes` | `'id', 'className', ...` | - |
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Spinner, Grid, Card, Button, Text } from 'core'
export const meta = {
title: 'Spinner',
description: 'Indicate an action running in the background.',
sidebar: 'components',
group: 'Components',
index: 35
}
## Spinner
Indicate an action running in the background.
As an indicator of load waiting, see also component [Loading](/docs/components/loading).
`}
/>
{
const [loading, setLoading] = React.useState(false)
const refresh = () => {
setLoading(true)
setTimeout(() => setLoading(false), 1500)
}
return (
Recent invoices
{loading ? : 3 invoices are waiting for payment.}
)
}
`}
/>
Saving your changes
`}
/>
Spinner.Props
| Attribute | Description | Type | Accepted values | Default |
| --------- | ------------ | ---------------- | ------------------------ | ------- |
| ... | native props | `HTMLAttributes` | `'id', 'className', ...` | - |
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Splitter, Text, useTheme } from 'core'
export const meta = {
title: 'Splitter',
description:
'Panels that share a space, with a line between them that the user drags to resize them.',
sidebar: 'components',
group: 'Components',
index: 68
}
## Splitter
Panels that share a space, with a line between them that the user drags, or moves
with the arrow keys, to give more room to one of them. The Splitter fills its
container, so the container needs a height.
{
const theme = useTheme()
return (
)
}
`}
/>
Splitter.Props
| Attribute | Description | Type | Accepted values | Default |
| ---------------- | ----------------------------------------------------------------------- | ------------------------------ | ------------------------- | ------------ |
| **direction** | `horizontal` puts the panels side by side, `vertical` stacks them | `string` | `'horizontal', 'vertical'` | `horizontal` |
| **onResize** | called with the size of every panel, in percent, when one of them changes | `(sizes: number[]) => void` | - | - |
| **handleLabel** | name of the lines, for screen readers | `string` | - | `Resize` |
| ... | native props, passed to the root `div` | `HTMLAttributes` | `'id', 'style', ...` | - |
Splitter.Panel.Props
| Attribute | Description | Type | Accepted values | Default |
| --------------- | ------------------------------------------------------------------------------------ | -------- | --------------- | ------- |
| **defaultSize** | percent of the space the panels share; the panels without one split what is left | `number` | `0` to `100` | - |
| **minSize** | smallest size the panel can have, in percent | `number` | `0` to `100` | `0` |
| **maxSize** | largest size the panel can have, in percent | `number` | `0` to `100` | `100` |
| ... | native props, passed to the panel `div` | `HTMLAttributes` | `'className', 'style', ...` | - |
Behavior
- • **Sizes** are percents of the space the panels share, without the lines, so the panels stay in proportion when the container is resized.
- • **A line** moves the panel before it and the one after it, by the same amount, as far as the limits of both allow.
- • **Overflow**: each panel scrolls its own content.
- • **Panels that come or go** start the sizes again from the `defaultSize` values.
Ref
The `ref` of `Splitter` points at the root `div`, and the `ref` of a panel at its `div`.
Accessibility
Each line is a `separator` that can be focused, with `aria-valuenow`, `aria-valuemin` and `aria-valuemax` for the size of the panel before it, and `aria-controls` pointing at that panel. The arrow keys that go along the splitter move it by 1%, or by 10% with Shift: Left and Right when the panels are side by side, Up and Down when they are stacked. Home and End go to the smallest and the largest size the limits allow. Name the lines with `handleLabel`.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Stat, Grid, Card, Progress, SegmentedControl } from 'core'
export const meta = {
title: 'Stat',
description: 'Show a number with its label and trend.',
sidebar: 'components',
group: 'Components',
index: 53
}
## Stat
Show a number with its label and trend.
`}
/>
}
/>
`}
/>
{
const periods = {
week: [
['Revenue', '$11,300', '+3.2% vs last week'],
['Active users', '2,914', '+1.1% vs last week'],
['Churn', '0.4%', '-0.1% vs last week']
],
month: [
['Revenue', '$48,200', '+12.4% vs last month'],
['Active users', '3,842', '+4.1% vs last month'],
['Churn', '1.8%', '-0.3% vs last month']
],
year: [
['Revenue', '$512,900', '+31.0% vs last year'],
['Active users', '3,842', '+58.2% vs last year'],
['Churn', '6.2%', '-1.4% vs last year']
]
}
const [period, setPeriod] = React.useState('month')
return (
WeekMonthYear
{periods[period].map(([label, value, change]) => (
))}
)
}
`}
/>
Stat.Props
| Attribute | Description | Type | Accepted values | Default |
| ---------- | ------------------------------------------ | ---------------- | --------------- | ------- |
| **label** | what the number measures | `ReactNode` | - | - |
| **value** | the number | `ReactNode` | - | - |
| **change** | trend text, a leading `-` is shown as drop | `string` | - | - |
| **extra** | chart or icon on the right | `ReactNode` | - | - |
| ... | native props | `HTMLAttributes` | - | - |
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Stepper, Button, Grid } from 'core'
export const meta = {
title: 'Stepper',
description:
'Shows the steps of a flow and which one the user is on, like a checkout or a signup.',
sidebar: 'components',
group: 'Components',
index: 51
}
## Stepper
Shows the steps of a flow and which one the user is on, like a checkout or a
signup. The steps before `active` are completed.
`}
/>
{
const [active, setActive] = React.useState(0)
return (
{' '}
)
}
`}
/>
`}
/>
`}
/>
Stepper.Props
| Attribute | Description | Type | Accepted values | Default |
| --------------- | --------------------------------------------------- | ------------------------- | ---------------------------- | ------------ |
| **active** | index of the current step, from `0` | `number` | - | - |
| **onStepClick** | called with the index of the clicked step; turns the steps into buttons | `(index: number) => void` | - | - |
| **orientation** | direction of the steps | `string` | `'horizontal', 'vertical'` | `horizontal` |
| ... | native props, passed to the `ol` | `OlHTMLAttributes` | `'aria-label', 'id', ...` | - |
Stepper.Step.Props
| Attribute | Description | Type | Accepted values | Default |
| --------------- | ------------------------------------------------------ | ---------------- | --------------- | ------- |
| **label** | name of the step | `ReactNode` | - | - |
| **description** | text below the label | `ReactNode` | - | - |
| **icon** | replaces the number, the check and the error mark | `ReactNode` | - | - |
| **error** | the step failed | `boolean` | - | `false` |
| **disabled** | the step cannot be clicked, with `onStepClick` | `boolean` | - | `false` |
| ... | native props, passed to the `li` | `LiHTMLAttributes` | - | - |
Ref
The `ref` of `Stepper` points at the `ol`, and the `ref` of each step at its `li`.
Accessibility
The steps are an ordered list, so a screen reader hears how many there are and the position of each. Name the list with `aria-label`. The current step has `aria-current="step"`, and completed and failed steps say so in text, not only in color. With `onStepClick`, each step is a real button, reached with Tab.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, PlaygroundTitle, Attributes } from 'src/components'
import { Table, Spacer, Code, Text, Button, Dot, Grid } from 'core'
import { useState } from 'react'
export const meta = {
title: 'Table',
description: 'Display tabular data in format.',
sidebar: 'components',
group: 'Components',
index: 42
}
## Table
Display tabular data in format.
{
const data = [
{ property: 'type', description: 'Content type', type: 'secondary | warning', default: '-' },
{ property: 'Component', description: 'DOM element to use', type: 'string', default: '-' },
{ property: 'bold', description: 'Bold style', type: 'boolean', default: 'true' },
]
return (
)
}
`}
/>
Table.Props
| Attribute | Description | Type | Accepted values | Default |
| ---------------- | -------------------------------------------- | ----------------------------------------------------- | ------------------ | ------- |
| **data** | data source | `Array` | - | - |
| **initialData** | inital datas | `Array` | - | `[]` |
| **emptyText** | displayed text when table's content is empty | `string` | - | - |
| **hover** | table's hover effect | `boolean` | - | `true` |
| **onRow** | callback row's content by click | [TableOnRowClick](#tableonrowclick) | - | - |
| **onCell** | callback cell's content by click | [TableOnCellClick](#tableoncellclick) | - | - |
| **onChange** | data change event | `(data: T) => void` | - | - |
| **pagination** | split the rows in pages | [TablePagination](#tablepagination) | - | - |
| **rowClassName** | set className to each row | [TableRowClassNameHandler](#tablerowclassnamehandler) | - | - |
| **sort** | the column the rows are sorted by, to control it | [TableSort](#tablesort) / `null` | - | - |
| **initialSort** | sort on the first render | [TableSort](#tablesort) / `null` | - | `null` |
| **onSortChange** | called with the new sort, or `null` when it is cleared | `(sort: TableSort \| null) => void` | - | - |
| **selectable** | a checkbox on each row, and one in the header | `boolean` | - | `false` |
| **rowKey** | what identifies a row: a prop, or a function. The position in `data` when missing | `keyof T` / `(row: T) => string \| number` | - | - |
| **selectedKeys** | keys of the selected rows, to control them | `Array` | - | - |
| **initialSelectedKeys** | keys of the rows selected on the first render | `Array` | - | `[]` |
| **onSelectionChange** | called with the keys and the rows selected | `(keys, rows: T[]) => void` | - | - |
| **selectRowLabel** | name of the checkbox of a row, for screen readers | `string` | - | `Select row` |
| **selectAllLabel** | name of the checkbox in the header | `string` | - | `Select all rows` |
| ... | native props | `TableHTMLAttributes` | `'id', 'name' ...` | - |
Table.Column.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------------ | -------------------------------------- | --------------------------------------- | --------------- | ------- |
| **prop**(required) | table-column's prop | `string` | - | - |
| **label** | table-column's label | `string` | - | - |
| **width** | width number (px) | `number` | - | - |
| **className** | set className to each column | `string` | - | - |
| **sortable** | the header becomes a button that sorts the rows | `boolean` | - | `false` |
| **sorter** | how two rows compare, when the default order does not fit | `(a: T, b: T) => number` | - | - |
| **render** | render returns elements in all columns | [TableColumnRender](#tablecolumnrender) | - | - |
TableSort
```ts
type TableSort = { prop: string; direction: 'asc' | 'desc' }
```
Sorting and selection
- • **Order**: numbers are compared by value, and any other value as text, where `item 2` comes before `item 10`. Use `sorter` on a column for anything else. The header has `aria-sort`, and the sorted column shows an arrow.
- • **Server rows**: with `pagination.total`, the rows are the ones of the server, so the table does not sort them. It only calls `onSortChange`, and you send the new order with the data.
- • **Selection keys**: the selection is kept by key, so it survives a sort and a change of page. `onSelectionChange` receives the rows that are in `data`, which are only the current page when the rows are on the server.
- • **Select all**: the checkbox in the header selects the rows in view, the current page. It is checked when all of them are selected, and in between when only some are.
TablePagination
| Attribute | Description | Type | Accepted values | Default |
| ---------------- | ---------------------------------------------- | ------------------------ | --------------- | ------- |
| **pageSize** | rows in each page | `number` | - | - |
| **page** | current page, to control it | `number` | - | `1` |
| **onPageChange** | called with the page the user picked | `(page: number) => void` | - | - |
| **total** | all the rows on the server, `data` is the page | `number` | - | - |
TableOnRowClick
```ts
type TableOnRowClick = (rowData: T, rowIndex: number) => void
```
TableOnCellClick
```ts
type TableOnCellClick = (
value: T[keyof T],
rowIndex: number,
colunmIndex: number
) => void
```
TableRowClassNameHandler
```ts
type TableRowClassNameHandler = (rowData: T, rowIndex: number) => string
```
TableColumnRender
```ts
type TableColumnRender = (
value: T[keyof T],
rowData: T,
rowIndex: number
) => JSX.Element | void
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Tabs, Grid, Text, Button, Code, useTabs, Input, Spacer } from 'core'
import { useState } from 'react'
import { Instagram, Facebook } from '@bolio-ui/icons'
export const meta = {
title: 'Tabs',
description: 'Display tab content.',
sidebar: 'components',
group: 'Components',
index: 36
}
## Tabs
Display tab content.
The Tabs contain an additional Hooks, see subsection [useTabs](/docs/hooks/use-tabs) for details.
React makes it painless to create interactive UIs. Design simple views
for each state in your application, and React will efficiently update
and render just the right components when your data changes.
Build encapsulated components that manage their own state, then
compose them to make complex UIs.
`}
/>
React makes it painless to create interactive UIs. Design simple views
for each state in your application, and React will efficiently update
and render just the right components when your data changes.
`}
/>
A summary of the project.
Everything that changed this week.
Names, members and billing.
`}
/>
React makes it painless to create interactive UIs. Design simple
views for each state in your application, and React will efficiently
update and render just the right components when your data changes.
Build encapsulated components that manage their own state, then
compose them to make complex UIs.
`}
/>
React makes it painless to create interactive UIs. Design simple
views for each state in your application, and React will efficiently
update and render just the right components when your data changes.
Build encapsulated components that manage their own state, then
compose them to make complex UIs.
`}
/>
Instagram
>
}
value="1"
>
Hello, this is my profile. Facebook
>
}
value="2"
>
Hi, this is my page.
`}
/>
Hello!Cool stuff.Good people.Amazing.Very low.Clear.Extraordinary person.Easy to tweak.Charts.Privacy focused.
`}
/>
{
const [value, setValue] = useState('1')
const switchHandler = () => setValue('2')
const changeHandler = val => setValue(val)
return (
React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes.Build encapsulated components that manage their own state, then compose them to make complex UIs.
)
}
`}
/>
Name
You are on the Pro plan. The next charge of $12 is on Nov 3.3 members have access to this workspace.
`}
/>
Tabs.Props
| Attribute | Description | Type | Accepted values | Default |
| -------------------- | --------------------------------------- | ----------------------- | ------------------------------- | ------- |
| **initialValue** | initial value | `string` | - | - |
| **value** | current selected value | `string` | - | - |
| **hideDivider** | hide default divider | `boolean` | - | `false` |
| **hideBorder** | hide border on active | `boolean` | - | `false` |
| **slide** | sliding indicator under the active tab | `boolean` | - | `false` |
| **leftSpace** | space area on the left side | `CSSProperties` | - | `12px` |
| **onChange** | change event | `(val: string) => void` | - | - |
| **align** | horizontal alignment of each child item | `justifyContent` | - | `left` |
| **activeClassName** | className of active child item | `string` | - | - |
| **activeStyles** | style of active child item | `object` | - | - |
| **hoverHeightRatio** | height percentage of highlight block | `number` | - | 0.7 |
| **hoverWidthRatio** | width percentage of highlight block | `number` | - | 1.15 |
| ... | native props | `HTMLAttributes` | `'alt', 'id', 'className', ...` | - |
Tabs.Item.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------------- | ------------------- | --------- | --------------- | ------- |
| **label**(required) | display tab's label | `string` | - | - |
| **value**(required) | unique ident value | `string` | - | - |
| **disabled** | disable current tab | `boolean` | - | `false` |
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Tag, Grid, Text } from 'core'
export const meta = {
title: 'Tag',
description: 'Display a unique keyword, optionally as a part of a set.',
sidebar: 'components',
group: 'Components',
index: 37
}
## Tag
Display a unique keyword, optionally as a part of a set.
Status: Unstable
`}
/>
DefaultPrimarySecondarySuccessWarningErrorDarkLite
`}
/>
DefaultPrimarySecondarySuccessWarningErrorDarkLite
`}
/>
Designing accessible forms
PublishedAccessibilityForms5 min read
`}
/>
Tag.Props
| Attribute | Description | Type | Accepted values | Default |
| ---------- | --------------------------- | --------------------- | ------------------------ | --------- |
| **type** | tag type | [TagTypes](#tagtypes) | - | `default` |
| **invert** | filled variant: invert color and background | `boolean` | - | `false` |
| **light** | light variant: tinted background | `boolean` | - | `false` |
| **subtle** | subtle variant: no background | `boolean` | - | `false` |
| ... | native props | `HTMLAttributes` | `'id', 'className', ...` | - |
TagTypes
```ts
type TagTypes =
| 'default'
| 'secondary'
| 'success'
| 'warning'
| 'error'
| 'dark'
| 'lite'
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { TagsInput, Grid, Text } from 'core'
export const meta = {
title: 'Tags Input',
description:
'A field where each entry becomes a tag, for lists like skills, topics or email addresses.',
sidebar: 'components',
group: 'Components',
index: 59
}
## Tags Input
A field where each entry becomes a tag. Enter or a comma ends a tag, and the
remove button or Backspace takes it out.
Topics
`}
/>
{
const [tags, setTags] = React.useState(['design'])
return (
{tags.length} tags: {tags.join(', ')}
)
}
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
TagsInput.Props
| Attribute | Description | Type | Accepted values | Default |
| ------------------- | -------------------------------------------------------- | ---------------------------- | --------------------------------------------------------------------- | --------- |
| **value** | tags, to control the field | `string[]` | - | - |
| **initialValue** | tags on the first render | `string[]` | - | `[]` |
| **onChange** | called with the whole list when a tag is added or removed | `(tags: string[]) => void` | - | - |
| **max** | most tags the field holds; the next ones are ignored | `number` | - | - |
| **allowDuplicates** | accepts a tag that is already in the list | `boolean` | - | `false` |
| **type** | color of the field | `string` | `'default', 'primary', 'secondary', 'success', 'warning', 'error', 'info'` | `default` |
| **rounded** | rounded corners | `boolean` | - | `false` |
| **filled** | filled surface | `boolean` | - | `false` |
| **light** | light surface | `boolean` | - | `false` |
| **ghost** | ghost surface | `boolean` | - | `false` |
| **subtle** | subtle surface | `boolean` | - | `false` |
| **disabled** | locks the field | `boolean` | - | `false` |
| **readOnly** | shows the tags without changing them | `boolean` | - | `false` |
| **error** | marks the field as invalid | `boolean` | - | `false` |
| **errorMessage** | text shown below the field with `error` | `string` | - | - |
| ... | native props, passed to the `input` | `InputHTMLAttributes` | `'placeholder', 'aria-label', 'id', ...` | - |
Adding and removing tags
- • **Enter** turns the text into a tag. With an empty field, Enter works as usual, so a form can still submit.
- • **A comma** ends a tag, typed or pasted, so `a, b, c` becomes three tags.
- • **Leaving the field** adds the text that is still in it.
- • **Backspace** on an empty field removes the last tag, and each tag also has a remove button.
- • Spaces around a tag are trimmed, and empty tags are ignored.
Ref
The `ref` points at the `input`.
Accessibility
The field is a native text input, so a label passed as children, or `aria-label`, names it. Each remove button is named after its tag, like "Remove React", and sits in the tab order. `error` sets `aria-invalid` and links the message with `aria-describedby`.
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Text, Grid } from 'core'
export const meta = {
title: 'Text',
description: 'Display text using well-defined typographic styles.',
sidebar: 'components',
group: 'Components',
index: 38
}
## Text
Display text using well-defined typographic styles.
Hello my friend, have fun with Bolio UI 🥷🏼
`}
/>
Make your development more creative and with amazing tools for React.
Make your development more creative and with amazing tools for React.
`}
/>
React makes it painless to create interactive UIs. Design simple views
for each state in your application, and React will efficiently update
and render just the right components when your data changes.
React makes it painless to create interactive UIs. Design simple views
for each state in your application, and React will efficiently update
and render just the right components when your data changes.
`}
/>
Build encapsulated components that manage their own state, then compose
them to make complex UIs.
`}
/>
Text colored
Text colored
Text colored
Text colored
Text colored
Text colored
Text colored
`}
/>
Font Size: 12px;
Font Size: 14px;Font Size: 1rem;
Font Size Scale: 1.25;
`}
/>
Build encapsulated components that manage their own state, then compose
them to make complex UIs.
Since component logic is written in JavaScript instead of templates,
you can easily pass rich data through your app and keep state out of
the DOM.
We don’t make assumptions about the rest of your technology stack, so
you can develop new features in React without rewriting existing code.
`}
/>
Text.Props
| Attribute | Description | Type | Accepted values | Default |
| -------------- | -------------- | ---------------- | ------------------------ | --------- |
| **p** | component name | `boolean` | - | `true` |
| **h1 - h6** | component name | `boolean` | - | `false` |
| **small** | component name | `boolean` | - | `false` |
| **span** | component name | `boolean` | - | `false` |
| **del** | component name | `boolean` | - | `false` |
| **i** | component name | `boolean` | - | `false` |
| **em** | component name | `boolean` | - | `false` |
| **b** | component name | `boolean` | - | `false` |
| **blockquote** | component name | `boolean` | - | `false` |
| **type** | text type | `TextTypes` | [TextTypes](#texttypes) | `default` |
| ... | native props | `HTMLAttributes` | `'id', 'className', ...` | - |
TextTypes
```ts
type TextTypes =
| 'default'
| 'primary'
| 'secondary'
| 'success'
| 'warning'
| 'error'
| 'info'
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Textarea, Grid, useInput, Button, Code } from 'core'
import { useState } from 'react'
export const meta = {
title: 'Textarea',
description: 'Retrieve multi-line user input.',
sidebar: 'components',
group: 'Components',
index: 39
}
## Textarea
Retrieve multi-line user input.
`}
/>
`}
/>
`}
/>
`}
/>
`}
/>
{
const [value, setValue] = useState()
const handler = (e) => {
setValue(e.target.value)
console.log(e.target.value)
}
return (
)
}
`}
/>
{
const { setState, reset, bindings } = useInput(
'This documentation always reflects the latest stable version of React. Since React 16, you can find older versions of the documentation on a separate page. Note that documentation for past versions is snapshotted at the time of the release, and isn’t being continuously updated.'
)
return (
)
}
`}
/>
{
const ref = React.useRef(null)
const setChange = () => {
ref && (ref.current.value = Math.random().toString(32))
}
return (
)
}
`}
/>
Textarea.Props
| Attribute | Description | Type | Accepted values | Default |
| ---------------- | --------------- | -------------------------------- | -------------------------------- | --------- |
| **value** | textarea value | `string` | - | - |
| **initialValue** | textarea value | `string` | - | - |
| **placeholder** | placeholder | `string` | - | - |
| **type** | current type | `TextareaTypes` | [TextareaTypes](#textareatypes) | `default` |
| **readOnly** | native attr | `boolean` | - | `false` |
| **disabled** | disable input | `boolean` | - | `false` |
| **rounded** | round corners | `boolean` | - | `false` |
| **filled** | filled variant | `boolean` | - | `false` |
| **light** | light variant | `boolean` | - | `false` |
| **ghost** | outline variant | `boolean` | - | `false` |
| **subtle** | subtle variant | `boolean` | - | `false` |
| **onChange** | change event | `(e: React.ChangeEvent) => void` | - | - |
| **resize** | CSS attribute | `CSSResize` | [CSSResize](#cssresize) | `none` |
| ... | native props | `TextareaHTMLAttributes` | `'form', 'id', 'className', ...` | - |
useInput
```ts
type useInput = (initialValue: string) => {
state: string
setState: Dispatch>
currentRef: MutableRefObject
reset: () => void
bindings: {
value: string
onChange: (event: React.ChangeEvent) => void
}
}
```
TextareaTypes
```ts
type TextareaTypes =
'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info'
```
CSSResize
```ts
type CSSResize =
'none' | 'both' | 'horizontal' | 'vertical' | 'initial' | 'inherit'
```
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Timeline } from 'core'
import { GitCommit, Check, Package, Truck, MapPin, MessageSquare, UserPlus, FileText } from '@bolio-ui/icons'
export const meta = {
title: 'Timeline',
description: 'List events in order, such as a changelog or an activity feed.',
sidebar: 'components',
group: 'Components',
index: 55
}
## Timeline
List events in order, such as a changelog or an activity feed.
We received your order and are preparing it.
The package left the warehouse.
`}
/>
} title="v2.1.0" time="Oct 2">
Added spotlight to Card and Button.
} title="v2.0.1" time="Sep 21">
Fixed ButtonGroup ghost borders.
} title="v2.0.0" time="Sep 1">
First stable release.
`}
/>
} title="Order packed" time="Mon, 09:41">
Your 2 items are ready at the warehouse.
} title="On the way" time="Tue, 14:05">
The carrier picked up the package in Lisbon.
} title="Out for delivery" time="Thu, 08:30">
Arrives today between 10:00 and 13:00.
} title="Delivered" time="Thu, 10:12" />
`}
/>
} title="Ana commented" time="2 min ago">
“The new pricing table looks good to ship.”
} title="Rui edited Pricing.md" time="1 hour ago" />
} title="Marta joined the team" time="Yesterday" />
`}
/>
Timeline.Props
| Attribute | Description | Type | Accepted values | Default |
| --------- | ------------ | --------------- | --------------- | ------- |
| ... | native props | `HTMLAttributes` | - | - |
Timeline.Item.Props
| Attribute | Description | Type | Accepted values | Default |
| --------- | ---------------------------- | ---------------- | --------------- | ------- |
| **title** | event title | `ReactNode` | - | - |
| **time** | date or time beside the title | `ReactNode` | - | - |
| **icon** | replaces the default dot | `ReactNode` | - | - |
| ... | native props | `HTMLAttributes` | - | - |
export default Docs.withMeta(meta)
---
import Docs from 'src/templates/Docs'
import { Playground, Attributes } from 'src/components'
import { Toggle, Grid, Card, Text } from 'core'
import { Sun, Moon } from '@bolio-ui/icons'
export const meta = {
title: 'Toggle',
description: 'Displays a boolean value.',
sidebar: 'components',
group: 'Components',
index: 40
}
## Toggle
Displays a boolean value.
`}
/>
`}
/>
} checkedIcon={} />
} checkedIcon={} />
`}
/>