Repository navigation
LayoutHeaderPanel
The LayoutHeaderPanel component is a slide-out panel that displays user profile information and preferences. It appears from the right side of the screen when the user clicks the profile button in the header.
This component does not accept any props. It manages its own state through context hooks.
import { LayoutHeaderPanel } from "@/components/Layout/LayoutHeaderPanel";
// Typically used within LayoutHeader
<Header>
<LayoutHeaderPanel />
</Header>;- Slides in from the right side of the screen
- Smooth transition animation
- Overlay for focus management
- Close Button: IconButton with X icon in the header
- Outside Click: Click anywhere outside the panel to close
- Keyboard: ESC key support (via Carbon)
The panel displays the HeaderPanelProfile component, which includes:
- User information
- Avatar display
- Client/district selection
- Logout option
<HeaderPanel expanded={isHeaderPanelOpen}>
<div className="right-title-section">
<h4>My Profile</h4>
<IconButton onClick={closeHeaderPanel}>
<Close />
</IconButton>
</div>
<HeaderPanelProfile />
</HeaderPanel>const { isHeaderPanelOpen, closeHeaderPanel } = useLayout();-
isHeaderPanelOpen: Boolean controlling panel visibility -
closeHeaderPanel: Function to close the panel
Uses the useOutsideClick hook to detect clicks outside the panel:
const panelRef = useRef<HTMLDivElement>(null);
useOutsideClick(panelRef, closeHeaderPanel, isHeaderPanelOpen);The component returns null when closed to avoid rendering unnecessary DOM elements:
if (!isHeaderPanelOpen) return null;.profile-panel {
max-inline-size: 25rem !important;
inline-size: auto;
background-color: var(--#{vars.$bcgov-prefix}-layer-02);
color: var(--#{vars.$bcgov-prefix}-text-primary);
transition: width 0.11s cubic-bezier(0.2, 0, 1, 0.9);
will-change: width;
border-left: 0.063rem solid var(--#{vars.$bcgov-prefix}-border-subtle-01);
display: flex;
flex-direction: column;
}.right-title-section {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
}@include breakpoint-down(md) {
.profile-panel {
max-inline-size: 20rem !important;
}
}-
Background:
var(--bcgov-layer-02)(BC Government design token) -
Text color:
var(--bcgov-text-primary)(BC Government design token) -
Border:
var(--bcgov-border-subtle-01)(BC Government design token) - Max width: 25rem (desktop), 20rem (mobile)
The panel uses Carbon's built-in slide animation:
- Duration: 0.11s
- Easing:
cubic-bezier(0.2, 0, 1, 0.9) - Property:
width - Performance: Uses
will-change: width
aria-label="User Profile Tab"data-testid="header-panel"- Close button is keyboard accessible
- Panel can be closed with ESC key (Carbon default)
- Focus is properly managed when opening/closing
- Ref attached for outside click detection
- Focus trap within panel when open
- Returns focus to trigger button on close
<IconButton
kind="ghost"
label="Close"
onClick={closeHeaderPanel}
align="bottom"
>
<Close />
</IconButton>- Kind: Ghost (transparent background)
- Label: "Close" (for accessibility)
- Align: Bottom (tooltip alignment)
- Icon: Close (X icon from Carbon)
The component uses useOutsideClick to close the panel:
useOutsideClick(
panelRef, // Reference to panel element
closeHeaderPanel, // Callback to execute
isHeaderPanelOpen, // Only active when panel is open
);- LayoutProvider: For panel state management
- AuthProvider: Required by HeaderPanelProfile
- PreferenceProvider: Required by HeaderPanelProfile
- useOutsideClick: Detects clicks outside the panel
- HeaderPanelProfile: Main profile content
-
HeaderPanel: Slide-out panel container -
IconButton: Close button -
Close: Close icon
import { Header, HeaderContainer } from "@carbon/react";
import { LayoutProvider } from "@/context/layout/LayoutProvider";
import { LayoutHeaderPanel } from "@/components/Layout/LayoutHeaderPanel";
function AppHeader() {
return (
<LayoutProvider>
<HeaderContainer
render={() => (
<Header>
{/* Other header elements */}
<LayoutHeaderPanel />
</Header>
)}
/>
</LayoutProvider>
);
}- User clicks profile button in header
- Panel slides in from the right
- User views profile information and preferences
- User can:
- Select client/district
- View user information
- Log out
- Panel closes when:
- User clicks close button
- User clicks outside panel
- User presses ESC key
- LayoutHeader: Parent header component
- LayoutHeaderGlobalBar: Contains the profile button that opens the panel
- HeaderPanelProfile: Profile content displayed in the panel
- Single Instance: Use only one panel per application
- Context Provider: Ensure LayoutProvider is available
- Outside Click: Don't add multiple outside click handlers
- Performance: Panel unmounts when closed to save resources
- Accessibility: Maintain focus management and keyboard support
- The panel slides in from the right side on all screen sizes
- Width adjusts for mobile devices (20rem vs 25rem)
- The panel is removed from DOM when closed (not just hidden)
- Uses Carbon Design System patterns for consistency
- Border provides visual separation from main content
This wiki documents NR Waste Plus for users and developers. Verify security and deployment guidance against the current application configuration before applying it elsewhere.
- Report an issue or ask a question in the GitHub repository.
- Follow the Contributing Guidelines to propose an update.
- Read the Code of Conduct.
Collection indexes support human browsing and machine retrieval. Keep both current when adding or moving wiki pages.
NR Waste Plus Wiki | GitHub Repository