English · Русский
UI component library for React with TypeScript and Tailwind CSS v4: buttons, form fields, popovers, dialogs, notifications and more. Built on pbstyles tokens, with light and dark themes out of the box.
🌐 Website · 📖 Documentation · 🎨 Figma community · 🖼 Behance · 📦 npm · 📝 Releases
- Features
- Installation
- Quick start
- Components
- Hooks
- Providers
- Dark theme
- Links in Next.js
- Development
- Related projects
- Contributing
- Author
- License
- Typed. Written in TypeScript, props and types are exported from the package.
- Tailwind v4 inside. Styles are prefixed with
pbc:, so they do not clash with your own Tailwind classes. - Light and dark themes. Follows
prefers-color-schemeor is switched manually withdata-theme. - Accessible. Native elements, keyboard support and aria attributes.
- Controlled and uncontrolled. Form components work in both modes.
- Figma file. The same components are available in a Figma community file.
npm install @prosazhin/pbcomponents
# or
yarn add @prosazhin/pbcomponentsRequires React 19.
Styles are bundled and imported together with the package. Wrap the app in PBCProvider to enable notifications and
dialogs, then use the components:
import { Button, PBCProvider } from '@prosazhin/pbcomponents';
const App = () => (
<PBCProvider>
<Button size='m' color='primary' theme='filled' onClick={() => {}}>
Button
</Button>
</PBCProvider>
);Each component page on the website has a live preview and the full API.
| Component | Docs |
|---|---|
Button |
Open |
ButtonGroup |
Open |
Badge |
Open |
Tag |
Open |
Alert |
Open |
Progress |
Open |
Pagination |
Open |
Headline |
Open |
Container |
Open |
| Component | Docs |
|---|---|
Input |
Open |
Textarea |
Open |
Select |
Open |
Search |
Open |
Field |
Open |
Checkbox |
Open |
CheckboxGroup |
Open |
Toggle |
Open |
Radio |
Open |
RadioGroup |
Open |
InlineRadio |
Open |
InlineRadioGroup |
Open |
| Component | Docs |
|---|---|
Tabs |
Open |
Tab |
Open |
Collapse |
Open |
CollapseGroup |
Open |
| Component | Docs |
|---|---|
Popover |
Open |
PopoverItem |
Open |
ConfirmPopover |
Open |
Tooltip |
Open |
Dialog |
Open |
ConfirmDialog |
Open |
Notification |
Open |
| Component | Docs |
|---|---|
PBCProvider |
Open |
DialogProvider |
Open |
NotificationsProvider |
Open |
| Component | Docs |
|---|---|
Text |
Open |
Icon |
Open |
Content |
Open |
| Hook | Docs |
|---|---|
useClickOutside |
Open |
useControllableState |
Open |
useCountdown |
Open |
useHoverControllable |
Open |
useKeydown |
Open |
useMergeRefs |
Open |
usePopover |
Open |
useScreenSize |
Open |
useDialog |
Open |
useShowDialog |
Open |
useNotifications |
Open |
PBCProvider is a wrapper for the notifications and dialog providers, so they do not have to be set up separately.
import { PBCProvider } from '@prosazhin/pbcomponents';
const App = () => (
<PBCProvider
notifications={{
top: 48,
onError: (error, context) => console.error('Notification callback error', error, context),
}}
>
{children}
</PBCProvider>
);import { Button, useNotifications } from '@prosazhin/pbcomponents';
const Component = () => {
const { showNotification } = useNotifications();
return <Button onClick={() => showNotification({ headline: 'Headline', children: 'Description' })}>Show</Button>;
};import { Button, Dialog, useDialog, useShowDialog } from '@prosazhin/pbcomponents';
const DIALOG_ID = 'my-dialog';
const Component = () => {
const { closeDialog } = useDialog();
const showDialog = useShowDialog(() => (
<Dialog id={DIALOG_ID}>
<div>Dialog content</div>
<Button color='primary' theme='filled' onClick={() => closeDialog(DIALOG_ID)}>
Close
</Button>
</Dialog>
));
return <Button onClick={showDialog}>Open dialog</Button>;
};Colors come from pbstyles tokens. Without any setup the theme follows the system
prefers-color-scheme. To control it manually, set data-theme on <html> or on any container:
<html data-theme="dark">
<div data-theme="light">This block is always light</div>
</html>Components that render as a link when href is set (Button, Tab, Popover.Item, Tag) accept a linkComponent
prop to use a custom link, e.g. next/link:
import NextLink from 'next/link';
<Button href='/about' linkComponent={NextLink}>
About
</Button>;The repository is an npm workspaces monorepo: the library in
workspaces/pbcomponents and a local
Storybook playground in workspaces/storybook.
npm install
npm run dev # library watch build + Storybook
npm run build # build the library
npm run lint
npm test- pbstyles — design tokens and styles the components are built on.
- mixin-dictionary — tokens to CSS variables and LESS/SCSS mixins.
- tailwind-dictionary — tokens to a Tailwind CSS theme.
Bug reports and ideas are welcome in issues.
Evgenii Sazhin, frontend developer & designer — prosazhin.dev · GitHub · Telegram · LinkedIn
If the library is useful to you, give it a ⭐ on GitHub.
MIT © Evgenii Sazhin