@brkz-inc/patterns
v2.0.0
Published
BRKZ higher-level UI patterns — compositions of @brkz-inc/ui components
Readme
@brkz-inc/patterns
Higher-level UI patterns for the BRKZ design system. These are composable, reusable layouts built from @brkz-inc/ui components.
Difference from @brkz-inc/ui
| @brkz-inc/ui | @brkz-inc/patterns |
|------------|------------------|
| Atomic components (Button, Input) | Composed patterns (ListingPageShell, DetailPageShell) |
| Single concern | Multiple components combined |
| No layout opinions | Layout-aware |
Recently removed
Several unadopted patterns were replaced with battle-tested equivalents:
PatternSidebar→ removed. UseSidebarfrom@brkz-inc/ui(a richer compound API + theuseSidebar().registerDetailShell()coordination context).PageLayout/PageHeader/FilterBar→ removed. UseListingPageShell/DetailPageShellinstead — the shells own their headers (title, filters, back affordance) and freeform header slots. (Header, the global app top-bar, is unrelated and stays.)
Available Patterns
EmptyState
Shown when a list or page has no data.
import { EmptyState } from '@brkz-inc/patterns'
<EmptyState
icon={<FileX />}
title="No orders found"
description="Try adjusting your filters."
action={<Button>Create order</Button>}
/>ConfirmDialog
Standardized confirmation dialog for destructive actions.
import { ConfirmDialog } from '@brkz-inc/patterns'
<ConfirmDialog
open={isOpen}
onOpenChange={setIsOpen}
title="Delete order?"
description="This cannot be undone."
destructive
confirmLabel="Yes, delete"
onConfirm={handleDelete}
/>ListingPageShell
List / table / grid page shell — sibling to DetailPageShell. A Card-based
header chrome (collapsible filter header on mobile, or a static title card) plus a
scrolling body. LISTING_SEARCH_WRAPPER_CLASS is exported alongside for
consistent search-input sizing. StatusFilterTabs (re-exported from
@brkz-inc/ui) is the quick-filter tab row commonly placed in the header.
import { ListingPageShell, LISTING_SEARCH_WRAPPER_CLASS } from '@brkz-inc/patterns'
<ListingPageShell
headerTitle="Suppliers"
header={
<div className="flex items-center gap-3">
<div className={LISTING_SEARCH_WRAPPER_CLASS}>
<SearchInput placeholder="Search…" />
</div>
<ListingViewToggle value={view} onValueChange={setView} className="ms-auto" />
</div>
}
>
{/* list / table / grid */}
</ListingPageShell>DetailPageShell
Unified record-detail shell: back affordance + title on the left, three freeform
header slots on the right (headerTitleAdornment, headerMeta, headerActions),
an optional alerts row, and children rendered inside a single outer Card.
On mount it calls useSidebar().registerDetailShell() from @brkz-inc/ui, so
rendering the shell auto-collapses the surrounding sidebar (and reopens it on
unmount). sticky (default true) pins the header and makes the body the only
scroller; sticky={false} lets the whole page scroll. There is no wrap prop —
the single outer Card is always present.
import { DetailPageShell } from '@brkz-inc/patterns'
<DetailPageShell
onBack={() => navigate(-1)}
title="Supplier · Acme Industrial"
headerTitleAdornment={<Badge variant="success">Active</Badge>}
headerActions={<Button>Approve</Button>}
>
{/* detail body */}
</DetailPageShell>Must be rendered inside a
SidebarProvider(from@brkz-inc/ui) so theregisterDetailShellcoordination context resolves.
AuthLayout + AuthSection
Split-screen authentication shell. AuthLayout is the page frame (branded hero
on the left, centered card on the right); AuthSection is the titled content
block inside it, with an optional inline back affordance (onBack). badge /
heroTitle are app-supplied (i18n-agnostic); legalNotice defaults to the BRKZ
corporate notice (pass null to hide). The opt-in mirrorHero prop horizontally
flips the hero image in RTL only (default off) for apps whose hero composition
should face back into a mirrored (Arabic) layout.
import { AuthLayout, AuthSection } from '@brkz-inc/patterns'
<AuthLayout badge="BRKZ Finance" heroTitle="Secure access…" bgImg={heroUrl}>
<AuthSection title="Sign in" description="Enter your phone number." onBack={goBack}>
{/* fields */}
</AuthSection>
</AuthLayout>OTPScreen
Verification-code step composed inside an AuthSection. A length-slot OTP input
auto-submits on completion; the resend control is gated by a resendSeconds
countdown (useCountDown); the phone is masked via maskPhoneNumber. All copy is
overridable through labels (i18n seam); countryCode is consumer-derived
(country-code parsing stays app-side).
import { OTPScreen } from '@brkz-inc/patterns'
<OTPScreen
phoneNumber={phone}
countryCode={getCountryCodeFromPhone(phone)}
loading={isVerifying}
error={error}
clearError={clearError}
onSubmit={verify}
resendOTP={resend}
goBack={goBack}
/>Adding new patterns
- Create
src/pattern-name/PatternName.tsx - Export from
src/index.ts - Add a Storybook story in
apps/docs/src/stories/patterns/ - Run
pnpm changeset
