Implementing a Reusable Bottom Sheet Component in Angular
This challenge focuses on building a flexible and reusable bottom sheet component in Angular. Bottom sheets are common UI elements that slide up from the bottom of the screen, often used for secondary actions, detailed information, or forms. Mastering this will enhance your ability to create dynamic and user-friendly interfaces in Angular applications.
Problem Description
Your task is to create a generic Angular component that can serve as a bottom sheet. This component should be easily integrated into any part of an application, allowing for dynamic content to be displayed within it and controlled programmatically.
Key Requirements:
- Component Structure: Create an Angular component (e.g.,
BottomSheetComponent) that will act as the container for the bottom sheet. - Dynamic Content: The component should accept arbitrary Angular components or templates as its content. This means the
BottomSheetComponentitself shouldn't dictate the specific UI inside it. - Opening and Closing: Implement methods to programmatically open and close the bottom sheet. This should include smooth animations for the slide-up and slide-down effect.
- Overlay: When the bottom sheet is open, an overlay should appear behind it, dimming the background and preventing interaction with the underlying content. The overlay should also trigger a close action when clicked.
- Accessibility: Ensure basic accessibility considerations, such as focus management (when opened, focus should be on the sheet; when closed, focus should return to the element that triggered it).
- Styling: Provide basic, customizable styling for the bottom sheet and its overlay.
Expected Behavior:
- When the
open()method is called, the bottom sheet should slide up from the bottom of the viewport, and the overlay should appear. - Clicking on the overlay should call the
close()method. - When the
close()method is called, the bottom sheet should slide down, and the overlay should disappear. - The content provided to the bottom sheet should be rendered within its boundaries.
Edge Cases:
- Rapid opening and closing: Ensure the component handles multiple open/close calls without errors or visual glitches.
- Content overflow: If the content within the bottom sheet exceeds the viewport height, it should be scrollable.
Examples
Example 1: Basic Usage
Imagine you have a button that, when clicked, should open a bottom sheet containing a simple form.
-
Triggering Component (e.g.,
AppComponent):- A button with text "Show Form".
- When clicked, it calls a method like
openBottomSheet()which instantiates and displays theBottomSheetComponent. - The
BottomSheetComponentwill receive aContactFormComponentas its content.
-
BottomSheetComponentOutput:- A modal-like container slides up from the bottom.
- The
ContactFormComponentis rendered inside this container. - A semi-transparent overlay covers the rest of the screen.
- Clicking the overlay closes the bottom sheet.
Example 2: Dynamic Content with Data
Consider opening a bottom sheet to display user details fetched from an API.
-
Triggering Component (e.g.,
UserProfileComponent):- A list of user names.
- Clicking a user name calls a method
viewUserDetails(userId)which opens aBottomSheetComponent. - The
BottomSheetComponentreceives aUserDetailsComponentas its content, along with theuserIdto fetch and display specific data.
-
BottomSheetComponentOutput:- Slides up to reveal the
UserDetailsComponent. - The
UserDetailsComponentdisplays the fetched information for the givenuserId. - Overlay is present.
- Slides up to reveal the
Example 3: Scrollable Content
If the bottom sheet needs to display a long list or a lot of text.
-
Triggering Component:
- A button that opens a bottom sheet.
-
BottomSheetComponentContent (e.g.,LongListComponent):- A list with 50+ items.
-
BottomSheetComponentOutput:- The bottom sheet opens.
- The
LongListComponentcontent is rendered. - The content inside the bottom sheet is scrollable vertically, indicating that the sheet itself has a fixed maximum height or handles its internal content overflow appropriately.
Constraints
- Angular version: Latest stable version (e.g., Angular 16+).
- TypeScript: Use modern TypeScript features.
- Styling: Use CSS or SCSS for styling. Assume standard browser compatibility.
- Performance: Animations should be smooth and not introduce significant lag.
- No external UI libraries for the bottom sheet functionality itself (e.g., ng-bootstrap, material components). You can use them for the content within the bottom sheet if desired, but the bottom sheet mechanism must be custom-built.
Notes
- Consider using Angular's
ComponentFactoryResolverorViewContainerReffor dynamically injecting content. - Animations can be implemented using Angular's built-in animation system or CSS transitions.
- Think about how you will manage the state of the bottom sheet (open/closed) and how the parent component will interact with it (e.g., using
@Outputevents for closing or returning data). - For accessibility, consider ARIA attributes and focus trapping.