- AccordionNew
- Alert
- Alert DialogNew
- AutocompleteNew
- AvatarNew
- Badge
- Breadcrumb
- Button
- CalendarNew
- CardNew
- Checkbox
- Checkbox GroupNew
- CollapsibleNew
- ComboboxNew
- CommandNew
- Context MenuNew
- Date PickerNew
- DialogNew
- DrawerNew
- EmptyNew
- FieldNew
- FieldsetNew
- FormNew
- FrameNew
- GroupNew
- Input
- Input GroupNew
- KbdNew
- Label
- MenuNew
- MeterNew
- Number Field
- OTP FieldNew
- Pagination
- PopoverNew
- Preview CardNew
- Progress
- Radio Group
- Scroll AreaNew
- Select
- Separator
- SheetNew
- SkeletonNew
- Slider
- Spinner
- StepperNew
- Switch
- Table
- TabsNew
- Textarea
- ToastNew
- ToggleNew
- Toggle GroupNew
- ToolbarNew
- Tooltip
Icons
The Rubix icon set — 228 icons, one module per icon, and the conventions for sizing, colouring and labelling them.
The Rubix icon set: 228 React components, one per module. There is no external icon dependency — every chevron, close cross and spinner Mako draws comes from here.
Import one icon per module, exactly like components:
import { MagnifyingGlass } from "mako-ui/icons/magnifying-glass";
import { Plus } from "mako-ui/icons/plus";
import { Trash } from "mako-ui/icons/trash";One icon, one module — no barrel, nothing to navigate. The path is the kebab-case of the export, exactly like components: AddBox lives in mako-ui/icons/add-box, just as AlertDialog lives in mako-ui/components/alert-dialog.
What an icon is
Every icon is a forwardRef SVG component with the same shape:
<svg fill="currentColor" width="24" height="24" viewBox="0 0 48 48" {...props} />Props are plain SVGProps<SVGSVGElement> — className, style, onClick, aria-*, ref.
size propsize={16} fails typecheck — use a size-* class, or let the parent
component do the sizing.
Sizing
Let the surrounding Mako component size the icon. Most components already declare inner SVG sizing, so an icon dropped into a Button, MenuItem, SelectTrigger or InputGroupAddon needs no class at all:
<Button>
<Plus aria-hidden="true" />
Add item
</Button>Those rules are written as [&_svg:not([class*='size-'])]:size-4, so an explicit size-* opts out and wins. Use it only when the inherited size is genuinely wrong:
<Trash aria-hidden="true" className="size-5" />A standalone icon — outside any Mako component — inherits nothing, so its width/height attributes apply and it renders at 24px. Set size-* when you want another size.
Colour
fill="currentColor" means icons inherit text colour. Tint them with semantic text tokens, never with fill-* or a raw palette class:
<Warning aria-hidden="true" className="text-destructive" />Several components also dim inner SVGs via [&_svg:not([class*='opacity-'])]:opacity-80. Check the component before adding your own opacity class — an explicit opacity-* overrides it.
Accessibility
- Decorative or redundant (label text is adjacent):
aria-hidden="true". - Carrying the only meaning (icon-only button): keep the icon hidden and label the control.
<Button size="icon" aria-label="Delete">
<Trash aria-hidden="true" />
</Button>Outlined and *Plain
Icons come in pairs. The base name is the outlined drawing; the *Plain suffix is the solid counterpart of the same glyph. Use the pair for state — outlined at rest, filled once the thing is selected, favourited or enabled:
import { Star } from "mako-ui/icons/star";
import { StarPlain } from "mako-ui/icons/star-plain";
<Star aria-hidden="true" /> {/* outlined — unselected */}
<StarPlain aria-hidden="true" /> {/* filled — active */}Each variant is its own module, so importing Star never pulls StarPlain in. Not every glyph has both variants; check the catalog below.
Names that need care
| Name | Why |
|---|---|
Date | Shadows the JavaScript global — import as Date as DateIcon |
Label | Shadows Mako's Label component — import as Label as LabelIcon |
Point_down | The one export that is not PascalCase — spell it exactly; PointDown does not exist |
The alias goes on the named export; the subpath keeps the icon's real name:
import { Date as DateIcon } from "mako-ui/icons/date";
import { Label as LabelIcon } from "mako-ui/icons/label";Flags
The 15 Flag* icons are multi-colour brand assets: they set fill="none" on the root and paint fixed hex fills inside, so currentColor and text-* classes do not recolour them. Size them like any other icon.
They also contain static internal mask ids, so rendering several flags in one document produces duplicate DOM ids. Every mask covers the full viewBox, which makes this visually harmless — but HTML validators and duplicate-id lint rules will flag it.
Catalog
228 icons. Select one to copy its import.