Actions
Components that help users take action or make choices
Buttons
Let users take action and make choices with a single tap.
Floating Action Buttons
Help people take primary actions with a prominent button that floats above the UI.
Extended FAB
Extended FABs are more prominent and provide clearer action guidance than standard FABs.
Segmented Button
Help people select options, switch views, or sort elements.
Chips
Compact elements that represent an input, attribute, or action.
Communication
Components that provide feedback or display status information
Badges
Show notifications, counts, or status information on navigation items and icons.
Progress Indicators
Express an unspecified wait time or display the length of a process.
Snackbars
Provide brief messages about app processes at the bottom of the screen.
Containment
Components that hold or organize content and other components
Cards
Display content and actions about a single subject.
Carousel
Display a collection of items that can be scrolled horizontally.
Dialogs
Provide important prompts in a user flow.
Lists
Continuous, vertical indexes of text and images.
Navigation
Components that help users move between different views and sections
Bottom App Bar
Display navigation and key actions at the bottom of mobile and tablet screens.
Navigation Bar
Let people switch between UI views on smaller devices.
Navigation Drawer
Let people switch between UI views on larger devices.
Navigation Rail
Let people switch between UI views on mid-sized devices.
Search
Let people enter a keyword or phrase to get relevant information.
Tabs
Organize content into separate views where only one view is visible at a time.
Top App Bar
Display navigation, actions, and text at the top of a screen.
Menus
Display a list of choices on a temporary surface.
Selection
Components that let users make choices or selections
Checkboxes
Let users select one or more items from a list, or turn an item on or off.
Chips
Help people enter information, make selections, filter content, or trigger actions.
Date Pickers
Let people select a date, or a range of dates.
Radio Buttons
Allow users to select one option from a set.
Sliders
Let users make selections from a range of values.
Switches
Toggle the state of a single item on or off.
Time Pickers
Help users select and set a specific time.
Text Inputs
Components that allow users to enter and edit text
Text Fields
Let users enter and edit text.
Feedback
Components that provide system feedback to users
Dialogs
Interrupt the user flow to provide critical information or request a decision.
Documentation
Components Module Documentation
The Components module provides a collection of highly optimized, fully accessible UI components built using the functional composition pattern. Each component is crafted with a focus on performance, memory efficiency, and code reusability while adhering to Material Design 3 specifications.
Overview
The Components module implements Material Design 3 principles using a lightweight, dependency-free architecture. Instead of relying on inheritance or heavy frameworks, components are constructed through functional composition, allowing for precisely tailored features with minimal overhead.
Key characteristics of our component system include:
- Functional Composition: Components are assembled from small, focused feature enhancers
- Zero Dependencies: No external dependencies, keeping bundle size minimal
- TypeScript-First: Full type safety with comprehensive interfaces
- Accessibility-Focused: ARIA support and keyboard navigation built-in
- Performance-Optimized: Minimal DOM operations and memory footprint
- Customizable: Extensive configuration options without bloat
Component Architecture
Each component follows a consistent architectural pattern:
- Factory Function: A creator function (e.g.,
createButton
) serves as the primary API - Configuration Processing: Default values are merged with user configuration
- Feature Composition: Multiple enhancers are applied in a specific order
- Public API Creation: A clean public API is exposed while hiding implementation details
Component Factory Pattern
The standard pattern used for creating components is:
const component = pipe(
createBase,
withEvents(),
withElement(config),
withSpecificFeatures(config),
withLifecycle(),
withAPI(config)
)(processedConfig);
This pipeline provides a clean separation of concerns while ensuring each component only includes the features it needs.
Core Components
Button
The Button component implements Material Design 3 button variants with ripple effects, states, and accessibility features.
Variants
- Filled: Primary action with solid background (high emphasis)
- Tonal: Secondary action with semi-filled background (medium emphasis)
- Outlined: Button with outline border (medium-low emphasis)
- Elevated: Button with slight elevation/shadow
- Text: Text-only button without background (low emphasis)
Key Features
- Touch ripple effects with configurable animation
- Accessible keyboard navigation and ARIA attributes
- Icon support with position control
- Disabled state management
- Focus, hover, and active states
Checkbox
The Checkbox component provides a Material Design 3 compliant checkbox with support for indeterminate state.
Key Features
- Checked, unchecked, and indeterminate states
- Label positioning (start/end)
- Accessible keyboard interaction
- Touch-friendly hit areas
- Form integration with name/value
Menu
The Menu component offers a dropdown menu system with support for nested submenus, keyboard navigation, and ARIA attributes.
Key Features
- Intelligent positioning with automatic flipping
- Cursor-based focus management
- Support for nested submenus
- Icons and keyboard shortcuts
- Dynamic item enabling/disabling
- Keyboard navigation and screen reader support
Slider
The Slider component implements a touch and keyboard accessible range input with support for discrete steps, custom thumb control, and accessibility features.
Key Features
- Continuous and discrete (stepped) modes
- Range slider support (dual thumbs)
- Customizable track and thumb appearance
- Keyboard accessibility with fine/coarse adjustments
- Touch and mouse input with accessible events
- Value bubble for current selection
Component APIs
Each component exposes a consistent public API with these characteristics:
- Element Access: Direct access to the root DOM element
- State Methods: Enable/disable and other state controls
- Content Methods: Update text, icons, etc.
- Event Subscription: Add/remove event listeners
- Lifecycle Control: Mount, unmount, and destroy functionality
- Method Chaining: Most methods return the component for chaining
Common API Patterns
Most components implement these common API methods:
- Element Reference:
component.element
provides access to the root DOM element - Event Handling:
component.on(event, handler)
andcomponent.off(event, handler)
- State Management:
component.enable()
andcomponent.disable()
- Destruction:
component.destroy()
for cleanup
Extending Components
The component system is designed for extension through several approaches:
Feature Composition
New features can be added to existing components through the composition pipeline:
const createCustomButton = (config) => pipe(
createButton,
withCustomFeature(config)
)(config);
Custom Components
New components can be created following the same pattern:
const createCustomComponent = (config) => {
const baseConfig = {
...defaultConfig,
...config,
componentName: 'custom'
};
return pipe(
createBase,
withEvents(),
withElement(elementConfig),
withFeature1(baseConfig),
withFeature2(baseConfig),
withLifecycle()
)(baseConfig);
};
API Extension
Existing component APIs can be extended with custom functionality:
const withCustomAPI = (component) => ({
...component,
customMethod() {
// Custom implementation
return this;
}
});
const enhancedButton = withCustomAPI(createButton(config));
Component Features
Components are built from composable features, including:
UI Features
- Text Content: Adds and manages text through
withText
- Icon Support: Adds icon capabilities through
withIcon
- Variant Styling: Applies style variants through
withVariant
- Size Variations: Adds size options through
withSize
- Ripple Effect: Adds Material Design ripple through
withRipple
Behavioral Features
- Event Handling: Adds event system through
withEvents
- Disabled State: Adds disabled functionality through
withDisabled
- Input Handling: Adds form input behavior through
withInput
- Checkable State: Adds checked state through
withCheckable
- Lifecycle Management: Adds lifecycle methods through
withLifecycle
Specialized Features
- Track/Thumb: Adds slider/switch track elements through
withTrack
- Label Management: Adds label support through
withTextLabel
- Badge Support: Adds badge capability through
withBadge
- Gesture Recognition: Adds touch gestures through
withGestures
Styling Approach
Components use a consistent styling approach with these characteristics:
- External CSS: Styles are defined in external SCSS files
- BEM Naming: Block-Element-Modifier pattern for class names
- Prefixing: All classes use the
mtrl-
prefix for namespacing - States as Modifiers: States like
--disabled
are applied as modifier classes - Minimal Specificity: Flat selector hierarchy to avoid specificity issues
Performance Considerations
The component system includes numerous performance optimizations:
Rendering Performance
- Minimal DOM Operations: Batch DOM changes and minimize reflow
- Efficient Event Handling: Use event delegation where appropriate
- Class Toggle Optimization: Efficient class manipulation with batch operations
- Lazy Initialization: Components initialize features only when needed
Memory Management
- Proper Cleanup: Components properly clean up resources on destruction
- Event Handler Management: Centralized tracking of event handlers for removal
- Avoid Closure Leaks: Careful management of closure references
- Reuse DOM Elements: Recycle elements when possible
Accessibility
All components implement accessibility best practices:
- ARIA Attributes: Proper role and state attributes
- Keyboard Navigation: Full keyboard support with expected behaviors
- Focus Management: Visible focus indicators and logical focus order
- Screen Reader Support: Meaningful text alternatives and announcements
- Touch Targets: Appropriately sized touch targets for mobile use
Examples of Component Usage
Button Component
// Create a filled button with an icon
const submitButton = createButton({
text: 'Submit',
variant: 'filled',
icon: '<svg>...</svg>',
iconPosition: 'start'
});
// Add click handler
submitButton.on('click', () => {
console.log('Button clicked');
});
// Disable during async operation
submitButton.disable();
// Re-enable when done
submitButton.enable();
// Clean up when no longer needed
submitButton.destroy();
Checkbox Component
// Create a checkbox with label
const consentCheckbox = createCheckbox({
label: 'I agree to the terms and conditions',
name: 'consent',
required: true,
labelPosition: 'end'
});
// Add change handler
consentCheckbox.on('change', (e) => {
console.log('Checkbox state:', e.checked);
});
// Toggle checked state
consentCheckbox.toggle();
// Set indeterminate state for "some selected" UI
consentCheckbox.setIndeterminate(true);
// Update label text
consentCheckbox.setLabel('I consent to all terms of service');
Menu Component
// Create a menu with items
const userMenu = createMenu({
anchor: document.getElementById('user-avatar'),
items: [
{ id: 'profile', text: 'Profile', icon: '<svg>...</svg>' },
{ id: 'settings', text: 'Settings' },
{ type: 'divider' },
{ id: 'logout', text: 'Log out' }
],
placement: 'bottom-end'
});
// Listen for selections
userMenu.on('select', (e) => {
console.log('Selected item:', e.itemId);
if (e.itemId === 'logout') {
logoutUser();
}
});
// Open the menu programmatically
userMenu.open();
// Update items dynamically
userMenu.setItems([
// New items...
]);
Slider Component
// Create a slider
const volumeSlider = createSlider({
min: 0,
max: 100,
value: 50,
step: 1,
label: 'Volume',
showValue: true
});
// Listen for value changes
volumeSlider.on('change', (e) => {
console.log('New volume:', e.value);
setSystemVolume(e.value);
});
// Update value programmatically
volumeSlider.setValue(75);
// Create a range slider
const priceRangeSlider = createSlider({
min: 0,
max: 1000,
value: 200,
secondValue: 800,
range: true,
label: 'Price Range',
valueFormatter: (value) => `${value}`
});
Best Practices
When working with the component system, consider these best practices:
- Resource Management: Always call
destroy()
when a component is no longer needed - Event Handling: Use the component's event system instead of direct DOM events
- Component Configuration: Configure components at creation time when possible
- DOM Manipulation: Avoid direct DOM manipulation of component elements
- Performance: For lists of components, use virtualization techniques
- Accessibility: Test with keyboard navigation and screen readers
- State Management: Use component state methods instead of class manipulation
Component Status and Roadmap
The current component library includes these fully implemented components:
- Button (all variants)
- Checkbox
- Menu (with nested submenus)
- Slider (including range slider)
- Switch
- TextField
- Radio Button
- List
- Card
- Dialog
- Snackbar
Upcoming components on the roadmap include:
- Tabs
- Navigation Rail
- Bottom App Bar
- Chips
- Date Picker
- Time Picker
- Segmented Button
- Navigation Drawer
- Progress Indicators
Contributing New Components
When creating new components for the library, follow these guidelines:
- Use the established functional composition pattern
- Create a clear public API with comprehensive TypeScript types
- Add thorough accessibility support
- Include documentation with usage examples
- Write tests for component features
- Optimize for performance and memory usage
- Follow the Material Design 3 specification
- Use existing features when possible
Conclusion
The Components module provides a comprehensive suite of UI components built on a foundation of functional composition. By assembling small, focused feature enhancers, each component includes precisely the functionality it needs without unnecessary overhead. This approach results in a lightweight, performant, and accessible implementation of the Material Design 3 specification.