Add IconButton, Divider, and Link atom components
IconButton: - Wraps MUI IconButton with FA theme (focus ring, brand hover colours) - 3 sizes reusing Button height tokens: small 32px, medium 40px, large 48px - 5 stories: Default, Sizes, Colours, States, CommonUseCases Divider: - Wraps MUI Divider with FA border token - Horizontal/vertical, fullWidth/inset/middle variants, text support - 6 stories: Default, Variants, Vertical, WithText, InContent, NavigationList Link: - Wraps MUI Link with FA brand colour (copper brand.600, 4.8:1 contrast) - Underline on hover by default, focus-visible ring, fontWeight 500 - 7 stories: Default, UnderlineVariants, ColourVariants, Inline, Navigation, FooterLinks, OnDifferentBackgrounds Theme: Added MuiIconButton, MuiDivider, MuiLink overrides Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
113
src/components/atoms/Divider/Divider.stories.tsx
Normal file
113
src/components/atoms/Divider/Divider.stories.tsx
Normal file
@@ -0,0 +1,113 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { Divider } from './Divider';
|
||||
import Box from '@mui/material/Box';
|
||||
|
||||
const meta: Meta<typeof Divider> = {
|
||||
title: 'Atoms/Divider',
|
||||
component: Divider,
|
||||
tags: ['autodocs'],
|
||||
argTypes: {
|
||||
orientation: { control: 'select', options: ['horizontal', 'vertical'] },
|
||||
variant: { control: 'select', options: ['fullWidth', 'inset', 'middle'] },
|
||||
light: { control: 'boolean' },
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof Divider>;
|
||||
|
||||
// ─── Default ────────────────────────────────────────────────────────────────
|
||||
|
||||
export const Default: Story = {
|
||||
decorators: [(Story) => <Box sx={{ width: 400 }}><Story /></Box>],
|
||||
};
|
||||
|
||||
// ─── Variants ───────────────────────────────────────────────────────────────
|
||||
|
||||
/** fullWidth, inset, and middle variants */
|
||||
export const Variants: Story = {
|
||||
render: () => (
|
||||
<Box sx={{ width: 400, display: 'flex', flexDirection: 'column', gap: 2 }}>
|
||||
<Box>
|
||||
<Box sx={{ fontSize: 12, color: 'text.secondary', mb: 1 }}>fullWidth (default)</Box>
|
||||
<Divider />
|
||||
</Box>
|
||||
<Box>
|
||||
<Box sx={{ fontSize: 12, color: 'text.secondary', mb: 1 }}>inset</Box>
|
||||
<Divider variant="inset" />
|
||||
</Box>
|
||||
<Box>
|
||||
<Box sx={{ fontSize: 12, color: 'text.secondary', mb: 1 }}>middle</Box>
|
||||
<Divider variant="middle" />
|
||||
</Box>
|
||||
</Box>
|
||||
),
|
||||
};
|
||||
|
||||
// ─── Vertical ───────────────────────────────────────────────────────────────
|
||||
|
||||
/** Vertical divider inside a flex container */
|
||||
export const Vertical: Story = {
|
||||
render: () => (
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2, height: 40 }}>
|
||||
<Box>Left</Box>
|
||||
<Divider orientation="vertical" flexItem />
|
||||
<Box>Right</Box>
|
||||
</Box>
|
||||
),
|
||||
};
|
||||
|
||||
// ─── With Text ──────────────────────────────────────────────────────────────
|
||||
|
||||
/** Divider with centered text (MUI "textAlign" support) */
|
||||
export const WithText: Story = {
|
||||
name: 'With Text',
|
||||
render: () => (
|
||||
<Box sx={{ width: 400, display: 'flex', flexDirection: 'column', gap: 3 }}>
|
||||
<Divider>OR</Divider>
|
||||
<Divider textAlign="left">Section</Divider>
|
||||
<Divider textAlign="right">End</Divider>
|
||||
</Box>
|
||||
),
|
||||
};
|
||||
|
||||
// ─── In Content ─────────────────────────────────────────────────────────────
|
||||
|
||||
/** Dividers separating content sections */
|
||||
export const InContent: Story = {
|
||||
name: 'In Content',
|
||||
render: () => (
|
||||
<Box sx={{ width: 400, p: 3, border: '1px solid', borderColor: 'divider', borderRadius: 1 }}>
|
||||
<Box sx={{ fontWeight: 600, mb: 1 }}>Service Details</Box>
|
||||
<Box sx={{ fontSize: 14, color: 'text.secondary', mb: 2 }}>
|
||||
Chapel service with traditional ceremony
|
||||
</Box>
|
||||
<Divider />
|
||||
<Box sx={{ fontWeight: 600, mt: 2, mb: 1 }}>Venue</Box>
|
||||
<Box sx={{ fontSize: 14, color: 'text.secondary', mb: 2 }}>
|
||||
West Chapel, Strathfield
|
||||
</Box>
|
||||
<Divider />
|
||||
<Box sx={{ fontWeight: 600, mt: 2, mb: 1 }}>Total</Box>
|
||||
<Box sx={{ fontSize: 14, color: 'text.primary' }}>$2,400</Box>
|
||||
</Box>
|
||||
),
|
||||
};
|
||||
|
||||
// ─── Navigation List ────────────────────────────────────────────────────────
|
||||
|
||||
/** Dividers between navigation items (footer pattern) */
|
||||
export const NavigationList: Story = {
|
||||
name: 'Navigation List',
|
||||
render: () => (
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5, height: 20 }}>
|
||||
<Box sx={{ fontSize: 14, color: 'text.secondary' }}>FAQ</Box>
|
||||
<Divider orientation="vertical" flexItem />
|
||||
<Box sx={{ fontSize: 14, color: 'text.secondary' }}>Contact Us</Box>
|
||||
<Divider orientation="vertical" flexItem />
|
||||
<Box sx={{ fontSize: 14, color: 'text.secondary' }}>Privacy</Box>
|
||||
<Divider orientation="vertical" flexItem />
|
||||
<Box sx={{ fontSize: 14, color: 'text.secondary' }}>Terms</Box>
|
||||
</Box>
|
||||
),
|
||||
};
|
||||
41
src/components/atoms/Divider/Divider.tsx
Normal file
41
src/components/atoms/Divider/Divider.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import React from 'react';
|
||||
import MuiDivider from '@mui/material/Divider';
|
||||
import type { DividerProps as MuiDividerProps } from '@mui/material/Divider';
|
||||
|
||||
// ─── Types ───────────────────────────────────────────────────────────────────
|
||||
|
||||
/** Props for the FA Divider component */
|
||||
export interface DividerProps extends MuiDividerProps {}
|
||||
|
||||
// ─── Component ───────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Visual separator for the FA design system.
|
||||
*
|
||||
* Thin line for separating content sections, navigation groups, or
|
||||
* list items. Wraps MUI Divider with FA border tokens.
|
||||
*
|
||||
* Orientations:
|
||||
* - `horizontal` (default) — full-width horizontal line
|
||||
* - `vertical` — full-height vertical line (use inside flex containers)
|
||||
*
|
||||
* Variants:
|
||||
* - `fullWidth` (default) — spans the full container
|
||||
* - `inset` — indented from the left (for list item separators)
|
||||
* - `middle` — indented from both sides
|
||||
*
|
||||
* Usage:
|
||||
* ```tsx
|
||||
* <Divider />
|
||||
* <Divider orientation="vertical" flexItem />
|
||||
* <Divider variant="inset" />
|
||||
* ```
|
||||
*/
|
||||
export const Divider = React.forwardRef<HTMLHRElement, DividerProps>(
|
||||
(props, ref) => {
|
||||
return <MuiDivider ref={ref} {...props} />;
|
||||
},
|
||||
);
|
||||
|
||||
Divider.displayName = 'Divider';
|
||||
export default Divider;
|
||||
2
src/components/atoms/Divider/index.ts
Normal file
2
src/components/atoms/Divider/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { Divider, default } from './Divider';
|
||||
export type { DividerProps } from './Divider';
|
||||
Reference in New Issue
Block a user