story-ui-lib
v1.1.7
Published
A modern, reusable component library built with React, TypeScript, and Mantine — designed to complement the Modern design system.
Maintainers
Readme
Story UI
A modern, reusable component library built with React, TypeScript, and Mantine — designed to complement the Modern design system.
✨ Overview
Story UI provides a comprehensive set of accessible, themeable, and production-ready UI components, hooks, and utilities for building modern React applications. All components are fully typed with TypeScript and designed for easy customization.
- Modern design: Consistent, beautiful, and accessible UI out of the box
- TypeScript support: All components and hooks are fully typed
- Customizable: Built on Mantine, supports theming and dark mode
- Accessible: Follows accessibility best practices
- Ready to use: Includes hooks, utilities, and Storybook documentation
📚 Table of Contents
- 📦 Installation
- 🚀 Quick Start
- ⚡ Usage
- 🧩 Components
- 🔘 Button
- 🗂️ Card
- 📋 DataTable
- 📈 MetricCard
- 📊 Chart
- 📑 Tabs
- 🪜 Steps
- 🔔 Toast
- 🪟 Modal
- 📥 Drawer
- 💬 Popover
- 💡 Tooltip
- 🔤 Input
- 🔽 Select
- 🚨 Alert
- 🏷️ Badge
- 💸 CostCard
- ⬇️ ExportButton
- ⚡ SpeedDial
- 🔔 NotificationsCenter
- 📊 ProgressBar
- 🌀 CircularProgress
- 📭 EmptyState
- 🔎 FilterBar
- 🔍 SearchBar
- 📅 DateRangePicker
- 📊 KPIGrid
- 👤 UserProfileMenu
- 📊 DashboardGrid
- 🔝 Header
- 🔚 Footer
- 🗂️ Accordion
- ⏳ OverlayLoader
- 🗺️ MapWidget
- 📝 Custom Hooks
- 🛠️ Utilities
- 🎨 Theming & Customization
- 🔗 Storybook & Playground
- 📦 Peer Dependencies
- ❓ FAQ & Troubleshooting
- 🤝 Contributing
- 🪪 License
- 📝 Changelog
📦 Installation
npm install story-ui-lib🚀 Quick Start
import { MantineProvider } from '@mantine/core';
import { Notifications } from '@mantine/notifications';
import '@mantine/core/styles.css';
import '@mantine/notifications/styles.css';
import { Button } from 'story-ui-lib';
function App() {
return (
<MantineProvider>
<Notifications />
<Button>Get Started</Button>
</MantineProvider>
);
}⚡ Usage
import { Button, Card, MetricCard, Toast } from 'story-ui-lib';
function MyComponent() {
const handleClick = () => {
Toast.success({
title: 'Success!',
message: 'Action completed successfully'
});
};
return (
<Card title="Dashboard">
<MetricCard
title="Active Users"
value="8,549"
changeType="positive"
subtitle="12% increase"
icon="👥"
color="#6366f1"
/>
<Button onClick={handleClick}>Show Toast</Button>
</Card>
);
}🧩 Components
🔘 Button
Description: A button component with enhanced styling and consistent design tokens. Supports multiple variants, sizes, and states with smooth animations.
Import:
import { Button } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |--------------|----------------------------------------------------------------------|----------|-----------|---------------------------------------------| | size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | No | 'md' | Button size | | variant | 'filled' | 'light' | 'outline' | 'subtle' | 'transparent' | 'gradient' | No | 'filled' | Visual style variant | | color | 'blue' | 'green' | 'red' | 'yellow' | 'purple' | 'gray' | 'orange' | 'teal' | 'dark' | No | 'violet' | Color theme | | fullWidth | boolean | No | false | Makes button full width | | loading | boolean | No | false | Shows loading spinner | | disabled | boolean | No | false | Disables the button | | elevated | boolean | No | false | Adds elevation shadow on hover | | onMouseEnter | (event: MouseEvent) => void | No | | Mouse enter event handler | | onMouseLeave | (event: MouseEvent) => void | No | | Mouse leave event handler | | onClick | (event: MouseEvent) => void | No | | Click event handler |
Example:
<Button variant="filled" size="md" elevated>
Primary Action
</Button>🗂️ Card
Description: A versatile container component with consistent styling and optional interactions.
Import:
import { Card } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |--------------|---------------------|----------|---------|---------------------------------------------| | title | string | No | | Card title | | children | ReactNode | Yes | | Card content | | withBorder | boolean | No | true | Show border | | withShadow | boolean | No | true | Show shadow | | padding | string | number | No | 'lg' | Padding size | | headerAction | ReactNode | No | | Action element in header | | hoverable | boolean | No | false | Adds hover effect |
Example:
<Card title="Card Title" withBorder withShadow hoverable headerAction={<Button size="xs">Action</Button>}>
Card content goes here
</Card>📋 DataTable
Description: Advanced table component with sorting and custom cell rendering.
Import:
import { DataTable } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |--------------|---------------------|----------|-------------------|---------------------------------------------| | columns | DataTableColumn[] | Yes | | Table columns (see below) | | data | any[] | Yes | | Table data | | loading | boolean | No | false | Show loading state | | emptyMessage | string | No | 'No data available'| Message when no data | | hoverable | boolean | No | true | Highlight rows on hover | | striped | boolean | No | false | Show striped rows | | bordered | boolean | No | true | Show border | | sortable | boolean | No | false | Enable sorting |
DataTableColumn: | Prop | Type | Required | Description | |-----------|-------------------------------------------|----------|---------------------------------------------| | key | string | Yes | Unique column key | | label | string | Yes | Column label | | width | string | number | No | Column width | | render | (value: any, row: any) => ReactNode | No | Custom cell renderer | | sortable | boolean | No | Enable sorting for this column | | align | 'left' | 'center' | 'right' | No | Text alignment |
Example:
const columns = [
{ key: 'name', label: 'Name', sortable: true },
{ key: 'status', label: 'Status', render: (value) => <Badge>{value}</Badge> }
];
<DataTable columns={columns} data={data} sortable hoverable striped />📈 MetricCard
Description: Specialized card for displaying metrics with optional change indicators.
Import:
import { MetricCard } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-------------|--------------------------------------|----------|--------------|---------------------------------------------| | title | string | Yes | | Metric label/title | | value | string | number | Yes | | Value to display | | changeType | 'positive' | 'negative' | 'neutral'| No | 'neutral' | Change indicator type | | subtitle | string | No | | Subtitle or description | | progress | number | No | | Progress percentage (0-100) | | icon | ReactNode | No | | Icon to display | | trend | 'up' | 'down' | 'flat' | No | | Trend indicator | | color | string | No | '#6366f1' | Color for icon/progress | | size | 'sm' | 'md' | 'lg' | No | 'md' | Card size |
Example:
<MetricCard title="Revenue" value="$125,000" changeType="positive" subtitle="15% increase" progress={75} color="#10b981" />📊 Chart
Description: Flexible chart component supporting bar, line, pie, donut, and area charts.
Import:
import { Chart } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|---------------------------------------------------|----------|--------------|---------------------------------------------| | type | 'bar' | 'line' | 'pie' | 'donut' | 'area' | Yes | | Chart type | | data | any[] | Yes | | Chart data | | dataKey | string | Yes | | Data key for values | | xKey | string | No | 'name' | Data key for x-axis | | title | string | No | | Chart title | | height | number | No | 300 | Chart height (px) | | colors | string[] | No | default set | Chart colors | | loading | boolean | No | false | Show loading state | | showGrid | boolean | No | true | Show grid lines | | curved | boolean | No | false | Use curved lines (for line/area) | | gradient | boolean | No | false | Use gradient fill (for area) |
Example:
<Chart type="bar" data={data} dataKey="value" xKey="label" title="Sales" />📑 Tabs
Description: Tabbed interface component for organizing content into multiple views.
Import:
import { Tabs } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-------------|----------------------------------------------|----------|--------------|---------------------------------------------| | items | TabItem[] | Yes | | Array of tab items (see below) | | variant | 'default' | 'outline' | 'pills' | No | 'default' | Visual style variant | | orientation | 'horizontal' | 'vertical' | No | 'horizontal' | Tab orientation |
TabItem: | Prop | Type | Required | Description | |-----------|--------------|----------|-----------------------------| | value | string | Yes | Unique tab value | | label | string | Yes | Tab label | | icon | ReactNode | No | Optional icon | | content | ReactNode | Yes | Tab content | | disabled | boolean | No | Disable this tab |
Example:
const tabItems = [
{ value: 'home', label: 'Home', content: <div>Home</div> },
{ value: 'settings', label: 'Settings', content: <div>Settings</div> }
];
<Tabs items={tabItems} defaultValue="home" />🪜 Steps
Description: Step-by-step progress indicator with customizable content for each step.
Import:
import { Steps } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|----------------------------------------------|----------|-----------|---------------------------------------------| | steps | StepItem[] | Yes | | Array of step items (see below) | | current | number | Yes | | Current step index (0-based) | | onChange | (step: number) => void | No | | Callback when step changes | | size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | No | 'md' | Stepper size |
StepItem: | Prop | Type | Required | Description | |-------------|--------------|----------|-----------------------------| | label | string | Yes | Step label | | description | string | No | Step description | | icon | ReactNode | No | Optional icon | | content | ReactNode | No | Step content |
Example:
const steps = [
{ label: 'Setup', description: 'Configure', content: <div>Setup</div> },
{ label: 'Deploy', description: 'Deploy app', content: <div>Deploy</div> }
];
<Steps steps={steps} current={0} />🔔 Toast
Description: Notification system with multiple variants and auto-dismiss. Use as a function, not a React component.
Import:
import { Toast } from 'story-ui-lib';Toast Methods:
Toast.success(options)Toast.error(options)Toast.warning(options)Toast.info(options)
ToastOptions: | Prop | Type | Required | Default | Description | |-----------------|-----------------------------|----------|-----------|---------------------------------------------| | title | string | No | | Toast title | | message | string | Yes | | Toast message | | autoClose | number | boolean | No | 4000 | Auto close delay (ms) or false for sticky | | icon | ReactNode | No | | Custom icon | | withCloseButton | boolean | No | true | Show close button |
Example:
Toast.success({ title: 'Success', message: 'Operation completed' });
Toast.error({ title: 'Error', message: 'Something went wrong' });🪟 Modal
Description: Flexible modal dialog with customizable content and actions.
Import:
import { Modal } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |--------------------|--------------------------------------|----------|-----------|---------------------------------------------| | children | ReactNode | Yes | | Modal content | | size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | No | 'md' | Modal size | | opened | boolean | Yes | | Whether modal is open | | onClose | () => void | Yes | | Callback when closed | | title | string | No | | Modal title | | withCloseButton | boolean | No | true | Show close button | | closeOnClickOutside| boolean | No | true | Close on overlay click | | closeOnEscape | boolean | No | true | Close on escape key | | footer | ReactNode | No | | Custom footer content | | loading | boolean | No | false | Show loading state |
Example:
<Modal opened={opened} onClose={handleClose} title="Confirm Action" size="md">
Are you sure you want to proceed?
</Modal>📥 Drawer
Description: Sliding panel component for detailed views and forms.
Import:
import { Drawer } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|----------------------------------------------|----------|-----------|---------------------------------------------| | children | ReactNode | Yes | | Drawer content | | title | string | No | | Drawer title | | onClose | () => void | Yes | | Callback when closed | | size | string | number | No | 'md' | Drawer size | | position | 'left' | 'right' | 'top' | 'bottom' | No | 'right' | Drawer position | | opened | boolean | Yes | | Whether drawer is open |
Example:
<Drawer opened={opened} onClose={handleClose} title="User Details" position="right" size="lg">
<UserForm />
</Drawer>💬 Popover
Description: Floating content container triggered by user interaction.
Import:
import { Popover } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|----------------------------------------------|----------|-----------|---------------------------------------------| | trigger | ReactNode | Yes | | Element that triggers the popover | | content | ReactNode | Yes | | Popover content | | title | string | No | | Popover title | | withArrow | boolean | No | true | Show arrow pointing to target | | position | 'top' | 'bottom' | 'left' | 'right' | No | 'bottom' | Popover position |
Example:
<Popover
trigger={<Button>Show Info</Button>}
title="Additional Information"
content={<div>Detailed explanation here</div>}
position="top"
withArrow
/>💡 Tooltip
Description: Tooltip for providing helpful information on hover or focus, with accessibility support.
Import:
import { Tooltip } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-------------|----------------------------------------------------------------------|----------|-----------|---------------------------------------------| | label | ReactNode | Yes | | Tooltip content | | children | ReactElement | Yes | | Element that triggers the tooltip | | position | 'top' | 'right' | 'bottom' | 'left' | 'top-start' | 'top-end' | 'right-start' | 'right-end' | 'bottom-start' | 'bottom-end' | 'left-start' | 'left-end' | No | 'top' | Tooltip position | | disabled | boolean | No | false | Disable the tooltip | | color | 'dark' | 'gray' | 'red' | 'pink' | 'grape' | 'violet' | 'indigo' | 'blue' | 'cyan' | 'green' | 'lime' | 'yellow' | 'orange' | 'teal' | No | 'dark' | Tooltip color theme | | withArrow | boolean | No | true | Show arrow | | arrowSize | number | No | 6 | Arrow size (px) | | openDelay | number | No | 500 | Delay before showing (ms) | | closeDelay | number | No | 100 | Delay before hiding (ms) |
Example:
<Tooltip label="Click to save your changes">
<Button>Save</Button>
</Tooltip>🔤 Input
Description: Input component with enhanced styling, focus states, and validation support.
Import:
import { Input } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |--------------|----------------------------------------------|----------|-----------|---------------------------------------------| | size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | No | 'md' | Input size | | variant | 'default' | 'filled' | 'unstyled' | No | 'default' | Visual style variant | | error | boolean | string | No | | Error state or message | | disabled | boolean | No | false | Disable the input | | required | boolean | No | false | Mark as required | | enhancedFocus| boolean | No | true | Enhanced focus styling | | ... | All Mantine TextInputProps except 'size' | No | | All other Mantine input props |
Example:
<Input label="Email" placeholder="Enter your email" />
<Input label="Password" type="password" required />
<Input label="Search" variant="filled" error="Invalid input" />🔽 Select
Description: Dropdown select component with search, clear, and validation support.
Import:
import { Select } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|----------------------------------------------|----------|-----------|---------------------------------------------| | options | { value: string, label: string, disabled?: boolean }[] | Yes | | Select options | | size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | No | 'md' | Select size | | variant | 'default' | 'filled' | 'unstyled' | No | 'default' | Visual style variant | | error | boolean | string | No | | Error state or message | | disabled | boolean | No | false | Disable the select | | required | boolean | No | false | Mark as required | | clearable | boolean | No | false | Allow clearing selection | | searchable| boolean | No | false | Enable search | | ... | All Mantine SelectProps except 'data' and 'size' | No | | All other Mantine select props |
Example:
const options = [
{ value: 'apple', label: 'Apple' },
{ value: 'banana', label: 'Banana' }
];
<Select options={options} label="Fruit" placeholder="Pick one" />🚨 Alert
Description: Alert component for displaying important messages and notifications.
Import:
import { Alert } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|----------------------------------------------|----------|-----------|---------------------------------------------| | children | ReactNode | Yes | | Alert content | | variant | 'light' | 'filled' | 'outline' | No | 'light' | Visual style variant | | type | 'info' | 'success' | 'warning' | 'error' | No | 'info' | Alert type | | withIcon | boolean | No | true | Show icon | | ... | All Mantine AlertProps except 'icon' | No | | All other Mantine alert props |
Example:
<Alert type="success" variant="filled">Operation completed successfully!</Alert>🏷️ Badge
Description: Badge for displaying status indicators, labels, and small pieces of information.
Import:
import { Badge } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|----------------------------------------------|----------|-----------|---------------------------------------------| | children | ReactNode | Yes | | Badge content | | size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | No | 'sm' | Badge size | | variant | 'filled' | 'light' | 'outline' | 'dot' | 'gradient' | No | 'light' | Visual style variant | | color | 'blue' | 'green' | 'red' | 'yellow' | 'purple' | 'gray' | 'orange' | 'teal' | No | 'blue' | Badge color theme | | fullWidth | boolean | No | false | Makes badge full width | | animated | boolean | No | false | Adds subtle animation on hover | | ... | All Mantine BadgeProps except 'size' and 'variant' | No | | All other Mantine badge props |
Example:
<Badge variant="filled" color="green">Success</Badge>
<Badge size="lg" variant="outline">Large Outline</Badge>💸 CostCard
Description: Card for displaying cost metrics and related information, with flexible number formatting.
Import:
import { CostCard } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-------------|----------------------------------------------|----------|-----------|---------------------------------------------| | label | string | Yes | | Card label/title | | value | number | Yes | | Numerical value to display | | colorScheme | 'dark' | 'light' | Yes | | Color scheme for the card | | date | dayjs.Dayjs | No | | Optional date for cost type cards | | icon | ReactNode | Yes | | Icon to display in the avatar | | color | string | Yes | | Color theme for the card | | type | 'cost' | 'diff' | 'diff-absolute' | Yes | | Type of card (determines formatting) | | footer | string | No | | Optional footer text | | maxDigits | number | No | 2 | Maximum fraction digits for formatting | | currency | string | No | 'USD' | Currency code for cost values |
Example:
<CostCard label="Cloud Spend" value={12345.67} colorScheme="light" icon={<CloudIcon />} color="#6366f1" type="cost" date={dayjs()} />⬇️ ExportButton
Description: A button for exporting data in multiple formats (CSV, PDF, TXT, etc.), with dropdown support for multiple export options.
Import:
import { ExportButton } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |----------|------|----------|---------|-------------| | label | string | No | 'Export' | Button label | | icon | ReactNode | No | Download icon | Button icon | | loading | boolean | No | false | Loading state | | formats | ExportFormat[] | No | | List of export formats (label, icon, onClick) | | onClick | () => void | No | | Click handler for single export | | ...ButtonProps | | | | All Mantine Button props |
Example:
<ExportButton label="Export Data" formats={[{ label: 'CSV', onClick: () => alert('Export CSV') }]} />⚡ SpeedDial
Description: A floating action button that expands to show multiple quick actions, similar to Material Design's SpeedDial.
Import:
import { SpeedDial } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | actions | SpeedDialAction[] | Yes | | List of actions (icon, label, onClick) | | position | object | No | { bottom: 32, right: 32 } | Position on screen | | mainIcon | ReactNode | No | Plus icon | Main button icon | | mainColor | string | No | 'blue' | Main button color | | open | boolean | No | | Controlled open state | | onOpenChange | (open: boolean) => void | No | | Open state handler | | style | React.CSSProperties | No | | Custom style |
Example:
<SpeedDial actions={[{ icon: <IconEdit />, label: 'Edit', onClick: () => {} }]} />🔔 NotificationsCenter
Description: A notification center for displaying a list of notifications, with support for marking as read, clearing, and dropdown mode.
Import:
import { NotificationsCenter } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |--------------|------|----------|---------|-------------| | notifications| NotificationItem[] | Yes | | List of notifications | | onMarkRead | (id: string) => void | No | | Mark as read handler | | onClear | (id: string) => void | No | | Clear notification handler | | onClearAll | () => void | No | | Clear all handler | | renderItem | (item: NotificationItem) => ReactNode | No | | Custom render function | | dropdownMode | boolean | No | false | Show as dropdown | | style | React.CSSProperties | No | | Custom style |
Example:
<NotificationsCenter notifications={[{ id: '1', title: 'New message', timestamp: new Date() }]} />📊 ProgressBar
Description: A horizontal progress bar with optional label, percentage, and animation.
Import:
import { ProgressBar } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | value | number | Yes | | Progress value (0-100) | | label | string | No | | Label above the bar | | color | string | No | 'blue' | Bar color | | showPercentage | boolean | No | true | Show percentage text | | striped | boolean | No | false | Striped style | | animated | boolean | No | false | Animated stripes | | height | number | No | 16 | Bar height | | style | React.CSSProperties | No | | Custom style |
Example:
<ProgressBar value={60} label="Loading..." />🌀 CircularProgress
Description: A circular progress indicator with optional label and percentage.
Import:
import { CircularProgress } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | value | number | Yes | | Progress value (0-100) | | label | string | No | | Label below the circle | | color | string | No | 'blue' | Progress color | | size | number | No | 80 | Circle size (px) | | thickness | number | No | 8 | Stroke thickness | | showPercentage | boolean | No | true | Show percentage text | | style | React.CSSProperties | No | | Custom style |
Example:
<CircularProgress value={75} label="Complete" />📭 EmptyState
Description: A placeholder for empty or zero-state screens, with optional icon, description, and action.
Import:
import { EmptyState } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | title | string | No | 'No Data' | Title text | | description | string | No | 'There is nothing to display here yet.' | Description text | | icon | ReactNode | No | | Icon above title | | action | ReactNode | No | | Action button | | children | ReactNode | No | | Custom content | | style | React.CSSProperties | No | | Custom style |
Example:
<EmptyState title="No Results" description="Try adjusting your filters." />🔎 FilterBar
Description: A horizontal bar for filter controls, typically used above tables or lists.
Import:
import { FilterBar } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | children | ReactNode | Yes | | Filter controls | | gap | number | string | No | 'md' | Gap between children | | style | React.CSSProperties | No | | Custom style | | ...GroupProps | | | | All Mantine Group props |
Example:
<FilterBar><Input /><Select /></FilterBar>🔍 SearchBar
Description: A search input with a search icon and optional custom right section.
Import:
import { SearchBar } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | value | string | Yes | | Input value | | onChange | (value: string) => void | Yes | | Change handler | | onSearch | () => void | No | | Search button handler | | placeholder | string | No | 'Search...' | Placeholder text | | rightSection | ReactNode | No | | Custom right section | | ...TextInputProps | | | | All Mantine TextInput props |
Example:
<SearchBar value={search} onChange={setSearch} onSearch={() => {}} />📅 DateRangePicker
Description: A date range picker with preset ranges and support for custom date selection.
Import:
import { DateRangePicker } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | value | [Date | null, Date | null] | Yes | | Selected date range | | onChange | (value: [Date | null, Date | null]) => void | Yes | | Change handler | | preset | string | No | | Preset key | | onPresetChange | (preset: string) => void | No | | Preset change handler | | ...DatePickerInputProps | | | | All Mantine DatePickerInput props |
Example:
<DateRangePicker value={[null, null]} onChange={() => {}} />📊 KPIGrid
Description: A responsive grid for displaying key performance indicators (KPIs) with icons, trends, and subtitles.
Import:
import { KPIGrid } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | items | KPIItem[] | Yes | | List of KPI items | | columns | number | No | 4 | Number of columns | | minWidth | number | No | 220 | Minimum column width | | style | React.CSSProperties | No | | Custom style | | colorScheme | 'light' | 'dark' | No | 'light' | Color scheme |
Example:
<KPIGrid items={[{ title: 'Revenue', value: '$10K' }]} />👤 UserProfileMenu
Description: A user avatar menu with dropdown actions for profile, settings, and logout.
Import:
import { UserProfileMenu } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | name | string | Yes | | User name | | email | string | No | | User email | | avatarUrl | string | No | | Avatar image URL | | menuItems | UserProfileMenuItem[] | No | | Custom menu items | | dropdownMode | boolean | No | true | Show as dropdown | | style | React.CSSProperties | No | | Custom style |
Example:
<UserProfileMenu name="Jane Doe" email="[email protected]" />📊 DashboardGrid
Description: A responsive, draggable grid layout for dashboard widgets.
Import:
import { DashboardGrid } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | widgets | DashboardWidget[] | Yes | | List of widgets | | cols | object | No | | Columns per breakpoint | | rowHeight | number | No | 80 | Row height | | breakpoints | object | No | | Breakpoints | | margin | [number, number] | No | [16, 16] | Grid margin | | onLayoutChange | (layout: Layout[]) => void | No | | Layout change handler | | style | React.CSSProperties | No | | Custom style |
Example:
<DashboardGrid widgets={[{ id: 'w1', content: <div>Widget</div>, layout: { x: 0, y: 0, w: 4, h: 2 } }]} />🔝 Header
Description: A customizable app header with support for logo, title, and left/center/right content.
Import:
import { Header } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | left | ReactNode | No | | Left content | | center | ReactNode | No | | Center content | | right | ReactNode | No | | Right content | | logo | ReactNode | No | | Logo element | | title | string | No | | Title text | | sticky | boolean | No | false | Sticky header | | height | number | No | 64 | Header height | | background| string | No | | Background color | | style | React.CSSProperties | No | | Custom style |
Example:
<Header title="Dashboard" left={<Logo />} right={<UserProfileMenu name="Jane" />} />🔚 Footer
Description: A customizable app footer with left/center/right content and copyright.
Import:
import { Footer } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | left | ReactNode | No | | Left content | | center | ReactNode | No | | Center content | | right | ReactNode | No | | Right content | | copyright | string | No | | Copyright text | | sticky | boolean | No | false | Sticky footer | | height | number | No | 56 | Footer height | | background| string | No | | Background color | | style | React.CSSProperties | No | | Custom style |
Example:
<Footer left={<Logo />} right={<Text>Links</Text>} copyright="© 2024" />🗂️ Accordion
Description: A flexible accordion component for collapsible panels, supporting nested panels and custom headers.
Import:
import { Accordion } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | panels | AccordionPanel[] | Yes | | List of panels | | multiple | boolean | No | false | Allow multiple open | | defaultValue | string | string[] | null | No | Default open panel(s) | | iconPosition | 'left' | 'right' | No | 'left' | Icon position | | renderHeader | (panel, expanded) => ReactNode | No | | Custom header | | renderContent| (panel) => ReactNode | No | | Custom content | | className | string | No | | Custom class | | style | React.CSSProperties | No | | Custom style | | variant | string | No | | Mantine variant | | chevronPosition | 'left' | 'right' | No | | Chevron position |
Example:
<Accordion panels={[{ label: 'Panel 1', value: 'p1', content: <div>Content</div> }]} />⏳ OverlayLoader
Description: A fullscreen or container overlay loader with optional label.
Import:
import { OverlayLoader } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | label | string | No | | Loader label | | fullscreen| boolean | No | false | Fullscreen overlay | | loader | ReactNode | No | | Custom loader | | style | React.CSSProperties | No | | Custom style |
Example:
<OverlayLoader label="Loading..." fullscreen />🗺️ MapWidget
Description: A map widget for displaying locations and markers using Leaflet.
Import:
import { MapWidget } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | center | [number, number] | No | [37.7749, -122.4194] | Map center | | zoom | number | No | 10 | Zoom level | | markers | MapMarker[] | No | [] | List of markers | | style | React.CSSProperties | No | | Custom style | | children | ReactNode | No | | Custom overlays |
Example:
<MapWidget markers={[{ position: [40.7128, -74.006], popup: 'NYC' }]} />🟢 StatusIndicator
Description: A visual indicator for status with icon, color, and optional label.
Import:
import { StatusIndicator } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-------------|-----------------------------------------------------------|----------|-----------|---------------------------------------------| | status | 'success' | 'error' | 'warning' | 'info' | 'pending' | 'neutral' | Yes | | Status type | | size | 'xs' | 'sm' | 'md' | 'lg' | No | 'md' | Indicator size | | label | string | No | | Optional label text | | showIcon | boolean | No | false | Show status icon | | customIcon | ReactNode | No | | Custom icon override | | variant | 'filled' | 'light' | 'outline' | 'subtle' | No | 'filled' | Visual style variant |
Example:
<StatusIndicator status="success" label="Success" showIcon />🟣 ConfigPreviewCard
Description: Preview card for configuration sections, with title, description, and custom sections.
Import:
import { ConfigPreviewCard } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |-------------|-----------------------|----------|-----------|---------------------------------------------| | data | any | Yes | | Data object for dynamic content | | sections | ConfigPreviewSection[]| Yes | | Array of preview sections | | title | string | No | 'Preview' | Card title | | description | string | No | | Card description |
Example:
<ConfigPreviewCard
data={{}}
sections={[
{ key: '1', label: 'Section 1', content: 'Content 1' },
{ key: '2', label: 'Section 2', content: 'Content 2' },
]}
title="Preview"
description="This is a preview card."
/>🟠 FormStepperNavigation
Description: Navigation controls for multi-step forms, with Continue, Submit, and Cancel actions.
Import:
import { FormStepperNavigation } from 'story-ui-lib';Props: | Prop | Type | Required | Default | Description | |----------------|-----------------|----------|-----------------|---------------------------------------------| | activeStep | string | Yes | | Current step key | | canProceedToNext | boolean | Yes | | Can proceed to next step | | isSubmitting | boolean | Yes | | Show loading state | | onContinue | () => void | Yes | | Continue handler | | onSubmit | () => void | Yes | | Submit handler | | onCancel | () => void | Yes | | Cancel handler | | continueLabel | string | No | 'Continue' | Continue button label | | submitLabel | string | No | 'Create Alert' | Submit button label | | cancelLabel | string | No | 'Cancel' | Cancel button label | | submitIcon | ReactNode | No | Bell icon | Icon for submit button |
Example:
<FormStepperNavigation
activeStep="What"
canProceedToNext={true}
isSubmitting={false}
onContinue={() => {}}
onSubmit={() => {}}
onCancel={() => {}}
/>🟡 MultiStepForm
Description: Dynamic multi-step form with tab navigation, using Mantine's useForm.
Import:
import { MultiStepForm } from 'story-ui-lib';
import { useForm } from '@mantine/form';Props: | Prop | Type | Required | Default | Description | |-------------|-------------------------|----------|-----------|---------------------------------------------| | activeStep | string | Yes | | Current step key | | setActiveStep | (step: string) => void| Yes | | Set active step handler | | form | UseFormReturnType | Yes | | Mantine form object | | steps | MultiStepFormStepConfig[]| Yes | | Array of step configs | | stepsAllowed| string[] | Yes | | List of step keys that are allowed to be navigated to |
Field Types:
- "input": Standard text input
- "select": Dropdown select
- "multiselect": Multi-value select (new)
- "custom": Custom render
Example with multiselect:
import { useForm } from '@mantine/form';
const [activeStep, setActiveStep] = useState('step1');
const form = useForm({ initialValues: { name: '', tags: [] } });
const steps = [
{ key: 'step1', label: 'Step 1', fields: [{ name: 'name', label: 'Name', type: 'input' }] },
{ key: 'step2', label: 'Tags', fields: [{ name: 'tags', label: 'Tags', type: 'multiselect', options: [ { value: 'a', label: 'A' }, { value: 'b', label: 'B' } ] }] },
];
const stepsAllowed = ['step1', 'step2'];
<MultiStepForm
activeStep={activeStep}
setActiveStep={setActiveStep}
form={form}
steps={steps}
stepsAllowed={stepsAllowed}
/>🟤 ThresholdInput
Description: Input for threshold values with color, icon, and optional suggestion button.
Import:
import { ThresholdInput } from 'story-ui-lib';
import { IconAlertCircle } from '@tabler/icons-react';Props: | Prop | Type | Required | Default | Description | |----------------|-----------------|----------|-----------|---------------------------------------------| | label | string | Yes | | Threshold label | | color | 'red' | 'orange' | 'yellow' | 'green' | 'blue' | Yes | | Color theme | | icon | (props) => JSX.Element | Yes | | Icon to display | | description | string | No | | Description text | | suggestedValue | number | No | | Suggested value for auto-fill | | onSuggest | (value: number) => void | No | | Suggest button handler | | showSuggest | boolean | No | true | Show suggest button | | ...NumberInputProps | | No | | All Mantine NumberInput props |
Example:
import { IconAlertCircle } from '@tabler/icons-react';
<ThresholdInput
label="Critical Threshold"
color="yellow"
icon={(props) => <IconAlertCircle {...props} color="#CA8A04" />}
value={10}
onChange={() => {}}
/>🟠 ThresholdsInputGroup
Description: Group of threshold inputs for multiple levels, each with its own color and icon.
Import:
import { ThresholdsInputGroup } from 'story-ui-lib';
import { IconAlertCircle } from '@tabler/icons-react';Props: | Prop | Type | Required | Default | Description | |-------------|-----------------|----------|-----------|---------------------------------------------| | thresholds | ThresholdConfig[]| Yes | | Array of threshold configs |
Example:
import { IconAlertCircle } from '@tabler/icons-react';
const [value, setValue] = useState(10);
<ThresholdsInputGroup
thresholds={[
{
label: "Critical",
color: "yellow",
icon: (props) => <IconAlertCircle {...props} color="#CA8A04" />,
value,
onChange: setValue,
},
]}
/>📝 Custom Hooks
💾 useLocalStorage
Description: Persistent state management using localStorage. Returns a stateful value and a setter function.
Import:
import { useLocalStorage } from 'story-ui-lib';API:
const [value, setValue] = useLocalStorage(key, initialValue);
| Argument | Type | Required | Description | |---------------|----------|----------|-----------------------------------| | key | string | Yes | Storage key | | initialValue | any | Yes | Initial value |
Returns: [value, setValue] — value is the current state, setValue updates it and persists to localStorage.
Example:
const [theme, setTheme] = useLocalStorage('theme', 'light');
<Button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Current theme: {theme}
</Button>🔢 usePagination
Description: Complete pagination state management for lists and tables.
Import:
import { usePagination } from 'story-ui-lib';API:
const pagination = usePagination(totalItems, initialPageSize = 10);
| Argument | Type | Required | Description | |------------------|---------|----------|-----------------------------------| | totalItems | number | Yes | Total number of items | | initialPageSize | number | No | Initial page size (default: 10) |
Returns:
currentPage: number — Current page numberpageSize: number — Items per pagetotalItems: number — Total itemssetPage(page): function — Set current pagesetPageSize(size): function — Set page sizenextPage(): function — Go to next pageprevPage(): function — Go to previous pagegoToFirstPage(): function — Go to first pagegoToLastPage(): function — Go to last page
Example:
const pagination = usePagination(items.length, 10);
<DataTable data={items.slice(
(pagination.currentPage - 1) * pagination.pageSize,
pagination.currentPage * pagination.pageSize
)} />
<Button onClick={pagination.nextPage}>Next</Button>📋 useCopyToClipboard
Description: Easy clipboard operations with feedback. Returns a boolean and a function to copy text.
Import:
import { useCopyToClipboard } from 'story-ui-lib';API:
const [isCopied, copyToClipboard] = useCopyToClipboard();
| Return value | Type | Description | |--------------|----------------------------|-----------------------------------| | isCopied | boolean | True if text was just copied | | copyToClipboard | (text: string) => Promise | Copies text to clipboard |
Example:
const [isCopied, copyToClipboard] = useCopyToClipboard();
<Button onClick={() => copyToClipboard('Hello!')}>
{isCopied ? 'Copied!' : 'Copy' }
</Button>🛠️ Utilities
🔣 Formatters
Description: Utility functions for formatting currency, dates, percentages, and numbers.
Import:
import { formatCurrency, formatDate, formatPercentage, formatNumber } from 'story-ui-lib';| Function | Signature | Description | |--------------------|------------------------------------------------------------------|-----------------------------------| | formatCurrency | (value: number, currency = 'USD', locale = 'en-US') => string | Format as currency | | formatDate | (date: Date | string | dayjs.Dayjs, format = 'MMM DD, YYYY') => string | Format date string | | formatPercentage | (value: number, decimals = 1) => string | Format as percentage | | formatNumber | (value: number, locale = 'en-US', notation = 'standard' | 'compact') => string | Format as number |
Example:
formatCurrency(1234.56); // "$1,234.56"
formatDate(new Date()); // "Dec 10, 2024"
formatPercentage(15.7); // "15.7%"
formatNumber(12345, 'en-US', 'compact'); // "12.3K"🎨 Status Helpers
Description: Consistent status color and variant mapping for UI elements.
Import:
import { getStatusColor, getStatusVariant } from 'story-ui-lib';| Function | Signature | Description | |------------------|----------------------------------|-----------------------------------| | getStatusColor | (status: 'success' | 'warning' | 'error' | 'info' | 'neutral') => string | Get color for status | | getStatusVariant | (status: 'success' | 'warning' | 'error' | 'info' | 'neutral') => 'filled' | 'light' | 'outline' | Get variant for status |
Example:
const color = getStatusColor('success'); // "#10b981"
const variant = getStatusVariant('error'); // "light"🎨 Theming & Customization
Story UI leverages Mantine's theming system. You can customize colors, fonts, and more by passing a custom theme to MantineProvider:
import { MantineProvider, createTheme } from '@mantine/core';
const theme = createTheme({
primaryColor: 'violet',
fontFamily: 'Inter, sans-serif',
// ...other theme overrides
});
function App() {
return (
<MantineProvider theme={theme}>
{/* ... */}
</MantineProvider>
);
}🔗 Storybook & Playground
- 📖 Storybook Documentation
- 🧪 Playground App (see
packages/playground-app)
📦 Peer Dependencies
Story UI requires the following peer dependencies in your project:
- React (>=18)
- @mantine/core (>=7)
- @mantine/notifications (>=7)
- @tabler/icons-react (>=2)
Install them if not already present:
npm install react @mantine/core @mantine/notifications @tabler/icons-react❓ FAQ & Troubleshooting
Q: My styles are missing or broken!
- Make sure you import Mantine and notification styles in your root file:
import '@mantine/core/styles.css'; import '@mantine/notifications/styles.css';
Q: Components throw errors about missing providers?
- Wrap your app with
MantineProviderand add<Notifications />at the root.
Q: Is TypeScript required?
- No, but all components are fully typed and provide the best experience with TypeScript.
Q: Are components accessible?
- Yes, all components follow accessibility best practices and use semantic HTML.
--
