File tree Expand file tree Collapse file tree 9 files changed +493
-176
lines changed
Expand file tree Collapse file tree 9 files changed +493
-176
lines changed Original file line number Diff line number Diff line change 1616 "mainFile": "index.ts",
1717 "rootDir": "design/patterns/form"
1818 },
19+ "patterns/header": {
20+ "name": "patterns/header",
21+ "scope": "",
22+ "version": "",
23+ "defaultScope": "automations.design",
24+ "mainFile": "index.ts",
25+ "rootDir": "design/patterns/header",
26+ "config": {
27+ "bitdev.react/react-env@0a734828d968c74e981ef0ca77acb414e90ea08d": {},
28+ "teambit.envs/envs": {
29+ "env": "bitdev.react/react-env"
30+ }
31+ }
32+ },
1933 "ui/button": {
2034 "name": "ui/button",
2135 "scope": "automations.design",
Original file line number Diff line number Diff line change 1+ import React from 'react' ;
2+ import { Header } from './header.js' ;
3+
4+ export const BasicHeader = ( ) => {
5+ const navItems = [
6+ { label : 'Home' , href : '/' } ,
7+ { label : 'About' , href : '/about' } ,
8+ { label : 'Services' , href : '/services' } ,
9+ { label : 'Contact' , href : '/contact' } ,
10+ ] ;
11+
12+ const userMenuItems = [
13+ { label : 'Profile' , onClick : ( ) => console . log ( 'Profile clicked' ) } ,
14+ { label : 'Settings' , onClick : ( ) => console . log ( 'Settings clicked' ) } ,
15+ { label : 'Logout' , onClick : ( ) => console . log ( 'Logout clicked' ) } ,
16+ ] ;
17+
18+ return (
19+ < Header
20+ logo = { < div style = { { fontSize : '1.5rem' , fontWeight : 'bold' } } > Logo</ div > }
21+ navItems = { navItems }
22+ userMenuItems = { userMenuItems }
23+ />
24+ ) ;
25+ } ;
Original file line number Diff line number Diff line change 1+ ---
2+ description : A responsive header component with navigation and user menu
3+ labels : ['react', 'header', 'navigation', 'ui']
4+ ---
5+
6+ import { Header } from ' ./header.js' ;
7+ import { BasicHeader } from ' ./header.composition.js' ;
8+
9+ # Header Component
10+
11+ A flexible and responsive header component that includes a logo area, navigation menu, and user menu.
12+
13+ ## Usage
14+
15+ ``` jsx
16+ import { Header } from ' @your-scope/design.patterns.header' ;
17+
18+ const navItems = [
19+ { label: ' Home' , href: ' /' },
20+ { label: ' About' , href: ' /about' },
21+ { label: ' Services' , href: ' /services' },
22+ ];
23+
24+ const userMenuItems = [
25+ { label: ' Profile' , onClick : () => console .log (' Profile clicked' ) },
26+ { label: ' Settings' , onClick : () => console .log (' Settings clicked' ) },
27+ ];
28+
29+ < Header
30+ logo= {< YourLogo / > }
31+ navItems= {navItems}
32+ userMenuItems= {userMenuItems}
33+ fixed= {true }
34+ / >
35+ ```
36+
37+ ## Example
38+
39+ <BasicHeader />
Original file line number Diff line number Diff line change 1+ .header {
2+ width : 100% ;
3+ background-color : # ffffff ;
4+ box-shadow : 0 2px 4px rgba (0 , 0 , 0 , 0.1 );
5+ padding : 1rem 0 ;
6+ }
7+
8+ .fixed {
9+ position : fixed;
10+ top : 0 ;
11+ left : 0 ;
12+ z-index : 1000 ;
13+ }
14+
15+ .container {
16+ max-width : 1200px ;
17+ margin : 0 auto;
18+ padding : 0 1rem ;
19+ display : flex;
20+ align-items : center;
21+ justify-content : space-between;
22+ }
23+
24+ .logo {
25+ display : flex;
26+ align-items : center;
27+ }
28+
29+ .nav {
30+ display : flex;
31+ gap : 2rem ;
32+ margin : 0 2rem ;
33+ }
34+
35+ .navItem {
36+ color : # 333 ;
37+ text-decoration : none;
38+ font-weight : 500 ;
39+ transition : color 0.2s ease;
40+ }
41+
42+ .navItem : hover {
43+ color : # 007bff ;
44+ }
45+
46+ .userMenu {
47+ display : flex;
48+ gap : 1rem ;
49+ }
50+
51+ .userMenuItem {
52+ background : none;
53+ border : none;
54+ padding : 0.5rem 1rem ;
55+ cursor : pointer;
56+ color : # 333 ;
57+ font-weight : 500 ;
58+ transition : color 0.2s ease;
59+ }
60+
61+ .userMenuItem : hover {
62+ color : # 007bff ;
63+ }
Original file line number Diff line number Diff line change 1+ import React from 'react' ;
2+ import { render , screen } from '@testing-library/react' ;
3+ import { BasicHeader } from './header.composition.js' ;
4+
5+ describe ( 'Header component' , ( ) => {
6+ it ( 'should render navigation items correctly' , ( ) => {
7+ render ( < BasicHeader /> ) ;
8+
9+ // Check if navigation items are rendered
10+ expect ( screen . getByText ( 'Home' ) ) . toBeInTheDocument ( ) ;
11+ expect ( screen . getByText ( 'About' ) ) . toBeInTheDocument ( ) ;
12+ expect ( screen . getByText ( 'Services' ) ) . toBeInTheDocument ( ) ;
13+ expect ( screen . getByText ( 'Contact' ) ) . toBeInTheDocument ( ) ;
14+ } ) ;
15+
16+ it ( 'should render user menu items correctly' , ( ) => {
17+ render ( < BasicHeader /> ) ;
18+
19+ // Check if user menu items are rendered
20+ expect ( screen . getByText ( 'Profile' ) ) . toBeInTheDocument ( ) ;
21+ expect ( screen . getByText ( 'Settings' ) ) . toBeInTheDocument ( ) ;
22+ expect ( screen . getByText ( 'Logout' ) ) . toBeInTheDocument ( ) ;
23+ } ) ;
24+
25+ it ( 'should render logo correctly' , ( ) => {
26+ render ( < BasicHeader /> ) ;
27+
28+ // Check if logo is rendered
29+ expect ( screen . getByText ( 'Logo' ) ) . toBeInTheDocument ( ) ;
30+ } ) ;
31+ } ) ;
Original file line number Diff line number Diff line change 1+ import React from 'react' ;
2+ import styles from './header.module.css' ;
3+
4+ export type HeaderProps = {
5+ /**
6+ * The logo to display in the header
7+ */
8+ logo ?: React . ReactNode ;
9+ /**
10+ * Navigation items to display in the header
11+ */
12+ navItems ?: Array < {
13+ label : string ;
14+ href : string ;
15+ } > ;
16+ /**
17+ * User menu items to display in the header
18+ */
19+ userMenuItems ?: Array < {
20+ label : string ;
21+ onClick : ( ) => void ;
22+ } > ;
23+ /**
24+ * Whether the header is fixed at the top
25+ */
26+ fixed ?: boolean ;
27+ /**
28+ * Optional data-testid for testing
29+ */
30+ 'data-testid' ?: string ;
31+ } ;
32+
33+ export function Header ( {
34+ logo,
35+ navItems = [ ] ,
36+ userMenuItems = [ ] ,
37+ fixed = false ,
38+ 'data-testid' : testId ,
39+ } : HeaderProps ) {
40+ return (
41+ < header
42+ className = { `${ styles . header } ${ fixed ? styles . fixed : '' } ` }
43+ data-testid = { testId }
44+ >
45+ < div className = { styles . container } >
46+ { logo && (
47+ < div className = { styles . logo } >
48+ { logo }
49+ </ div >
50+ ) }
51+
52+ { navItems . length > 0 && (
53+ < nav className = { styles . nav } >
54+ { navItems . map ( ( item , index ) => (
55+ < a
56+ key = { index }
57+ href = { item . href }
58+ className = { styles . navItem }
59+ >
60+ { item . label }
61+ </ a >
62+ ) ) }
63+ </ nav >
64+ ) }
65+
66+ { userMenuItems . length > 0 && (
67+ < div className = { styles . userMenu } >
68+ { userMenuItems . map ( ( item , index ) => (
69+ < button
70+ key = { index }
71+ onClick = { item . onClick }
72+ className = { styles . userMenuItem }
73+ >
74+ { item . label }
75+ </ button >
76+ ) ) }
77+ </ div >
78+ ) }
79+ </ div >
80+ </ header >
81+ ) ;
82+ }
Original file line number Diff line number Diff line change 1+ export { Header } from './header.js' ;
2+ export type { HeaderProps } from './header.js' ;
You can’t perform that action at this time.
0 commit comments