Utilities
Utilities are small helpers for labelling icons, hiding text visually, portalling content, merging props and resetting element styles.These components draw nothing of their own. They help you build accessible, composable UI around the other components. To set colours, radius and appearance for a part of the page, use Theme, covered in Theming.
Playground
AccessibleIcon
AccessibleIcon gives a standalone icon a name for screen readers. It hides the icon with aria-hidden and adds label as visually hidden text next to it.
import { AccessibleIcon } from '@kushagradhawan/kookie-ui';
import { HugeiconsIcon } from '@hugeicons/react';
import { CheckmarkCircle02Icon } from '@hugeicons/core-free-icons';
<AccessibleIcon label="Verified">
<HugeiconsIcon icon={CheckmarkCircle02Icon} strokeWidth={1.75} />
</AccessibleIcon>Use it only for an icon that means something on its own, such as a status mark. An icon next to a text label is decoration, and an icon-only Button takes aria-label instead.
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | The name a screen reader announces. Required | |
children | ReactElement | One icon element. Required |
VisuallyHidden
VisuallyHidden hides its content from the screen but keeps it for screen readers. Use it for a heading or label that sighted users don't need because the layout already makes it clear.
import { VisuallyHidden } from '@kushagradhawan/kookie-ui';
<Dialog.Title>
<VisuallyHidden>Search</VisuallyHidden>
</Dialog.Title>Don't hide text that everyone needs, such as an error message or the label of a form field that has no other visible label. It renders a span and accepts asChild and every attribute of the HTML span element.
Portal
Portal renders its children at the end of document.body, or inside container, outside the parent's DOM. Use it for your own overlays. Dialog, Popover, Tooltip and the menus already portal their content.
import { Box, Portal, Theme } from '@kushagradhawan/kookie-ui';
<Portal>
<Theme asChild>
<Box position="fixed" bottom="4" right="4">
<UploadStatus />
</Box>
</Theme>
</Portal>Content portalled to body leaves the Theme it was written in, so wrap it in <Theme asChild> to keep the theme's colours and radius, as Kookie's own overlays do. Portal renders nothing on the server and mounts on the client.
| Prop | Type | Default | Description |
|---|---|---|---|
container | Element | DocumentFragment | null | document.body | Where the content renders |
asChild | boolean | false | Renders the child element instead of a div |
Portal also accepts every attribute of the HTML div element.
Slot
Slot merges its props onto its only child and renders that child. It is how asChild works across Kookie, and you can use it to give your own components an asChild prop.
import { Slot, Slottable } from '@kushagradhawan/kookie-ui';
function NavItem({ asChild, icon, children, ...props }: NavItemProps) {
const Comp = asChild ? Slot : 'button';
return (
<Comp className="nav-item" {...props}>
{icon}
<Slottable>{children}</Slottable>
</Comp>
);
}When both Slot and the child set the same prop, the child wins. Class names join, styles merge with the child's values on top, refs combine, and both event handlers run, the child's first.
Slottable marks which child receives the props when the component renders other elements around it, like the icon above. Without it, Slot needs exactly one child.
Reset
Reset removes the browser's default styles from its only child: margins, fonts, list bullets, button and input styles, and the focus outline. Use it when you build a control from a native element and want to start from nothing.
import { Reset } from '@kushagradhawan/kookie-ui';
<Reset>
<ul>
{items.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</Reset>Reset adds a class to the child and renders no element of its own. It takes one React element as its child and accepts any props, which it passes to that child. Reset removes the focus outline, so add a visible focus style to any control you reset.