Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rolemodel/betanxt-design-system",
"version": "1.0.0",
"version": "1.2.0",
"description": "The BetaNXT design system for MUI.",
"type": "module",
"exports": {
Expand Down
77 changes: 77 additions & 0 deletions src/components/drawer/BNDialogTitle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import CloseRounded from '@mui/icons-material/CloseRounded'
import {
DialogTitle,
type DialogTitleProps,
IconButton,
Stack,
Typography,
} from '@mui/material'
import type { SxProps, Theme } from '@mui/material'

export type BNDialogTitleBgColorVariant = 'background.paper' | 'appBarPrimary.defaultFill'

export type BNDialogTitleTextColorVariant =
| 'text.primary'
| 'appBarPrimary.defaultContrast'

export interface BNDialogTitleProps extends Omit<DialogTitleProps, 'variant'> {
bgColorVariant?: BNDialogTitleBgColorVariant
textColorVariant?: BNDialogTitleTextColorVariant
variant?: 'default' | 'primary'
onClose?: () => void
closeAriaLabel?: string
}

export const BNDialogTitle = ({
bgColorVariant,
textColorVariant,
variant,
onClose,
closeAriaLabel = 'Close dialog',
title,
sx,
...rest
}: BNDialogTitleProps) => {
const preset =
variant === 'primary'
? { bg: 'appBarPrimary.defaultFill', text: 'appBarPrimary.defaultContrast' }
: variant === 'default' || !variant
? { bg: 'background.paper', text: 'text.primary' }
: undefined

const resolvedBg = (bgColorVariant ?? preset?.bg ?? 'background.paper') as string
const resolvedText = (textColorVariant ?? preset?.text ?? 'text.primary') as string

const readCssVar = (theme: Theme, path: string): string | undefined => {
return path
.split('.')
.reduce<any>((obj, key) => (obj ? obj[key] : undefined), (theme as any).vars)
}

const colorRule = (theme: Theme) => ({
backgroundColor: readCssVar(theme, `palette.${resolvedBg}`),
color: readCssVar(theme, `palette.${resolvedText}`),
})

const mergedSx: SxProps<Theme> = sx
? [colorRule, ...(Array.isArray(sx) ? sx : [sx])]
: [colorRule]

return (
<DialogTitle sx={mergedSx} {...rest}>
<Stack direction="row" alignItems="center" justifyContent="space-between" gap={1}>
<Typography variant="h4">{title}</Typography>
{onClose && (
<IconButton
aria-label={closeAriaLabel}
color="inherit"
onClick={onClose}
size="large"
>
<CloseRounded fontSize="medium" />
</IconButton>
)}
</Stack>
</DialogTitle>
)
}
16 changes: 16 additions & 0 deletions src/components/drawer/BNDrawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Drawer, type DrawerProps } from '@mui/material'

import { BNDialogTitle, type BNDialogTitleProps } from './BNDialogTitle'

export interface BNDrawerProps extends DrawerProps {
titleProps?: BNDialogTitleProps
}

export const BNDrawer = ({ titleProps, children, ...drawerProps }: BNDrawerProps) => {
return (
<Drawer {...drawerProps}>
{titleProps && <BNDialogTitle {...titleProps} />}
{children}
</Drawer>
)
}
6 changes: 6 additions & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ export { default as BNNumberField } from './BNNumberField'
export { currencyConfig } from './BNNumberField'
export type { BNNumberFieldProps, Currency } from './BNNumberField'

// Drawer Components
export { BNDrawer } from './drawer/BNDrawer'
export type { BNDrawerProps } from './drawer/BNDrawer'
export { BNDialogTitle } from './drawer/BNDialogTitle'
export type { BNDialogTitleProps } from './drawer/BNDialogTitle'

// Filter Search Components
export { default as BNFilterSelect } from './filter-search/BNFilterSelect'
export type { BNFilterSelectProps, FilterOption } from './filter-search/BNFilterSelect'
Expand Down
83 changes: 83 additions & 0 deletions src/stories/BNDrawer.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import type { Meta, StoryObj } from '@storybook/react-vite'
import React from 'react'

import {
Accordion,
AccordionDetails,
AccordionSummary,
Box,
Button,
CardActions,
Typography,
} from '@mui/material'

import { BNDrawer } from '../components/drawer/BNDrawer'

const meta = {
title: 'Custom Components/BNDrawer',
parameters: {
layout: 'fullscreen',
controls: {
exclude: ['LinkComponent'],
},
},
argTypes: {
color: {
control: 'select',
options: ['default', 'secondary'],
},
},
component: BNDrawer,
} satisfies Meta<typeof BNDrawer>

export default meta

type Story = StoryObj<typeof meta>

export const Primary: Story = {
parameters: {
layout: 'padded',
},
args: {
variant: 'temporary',
titleProps: {
title: 'Drawer Title',
variant: 'primary',
},
},
render: (args) => {
const [open, setOpen] = React.useState(false)
const toggleDrawer = (newOpen: boolean) => () => setOpen(newOpen)
return (
<>
<Button onClick={toggleDrawer(true)}>Open drawer</Button>
<BNDrawer
{...args}
open={open}
onClose={toggleDrawer(false)}
titleProps={{ ...args.titleProps, onClose: toggleDrawer(false) }}
>
<Box
sx={{ p: 3, width: '100%', maxWidth: 500, minWidth: { xs: '100%', md: 500 } }}
>
<Typography variant="h5" gutterBottom>
Drawer Content accepts any children
</Typography>
<Accordion variant="outlined">
<AccordionSummary>
<Typography variant="body2">Accordion 1</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography variant="body2">Accordion 1 content</Typography>
</AccordionDetails>
</Accordion>
</Box>
<CardActions>
<Button variant="outlined">Action</Button>
<Button variant="contained">Action</Button>
</CardActions>
</BNDrawer>
</>
)
},
}
15 changes: 15 additions & 0 deletions src/stories/CHANGELOG.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.2.0] - 2025-10-14

### Added

- BNDialogTitle: preset-based color variants with close icon; supports `variant="primary"` and explicit bg/text token overrides; integrates with BNDrawer via `titleProps` (bn-dialog-title, 2025-10-14)
- BNDrawer: wrapper component exposing `titleProps` to render BNDialogTitle and forward Drawer props (bn-drawer, 2025-10-14)

### Documentation

- Storybook: BNDrawer story demonstrating preset title styling, close handling, and content (bn-drawer-story, 2025-10-14)

### Build

- Changelog updated for new components and changes (changelog-update, 2025-10-14)

## [1.0.0] - 2025-09-24

### Added
Expand Down
Loading