Material Design CSS framework with interactive JavaScript components for building responsive web applications
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Core utilities, helper functions, and the global M object providing framework-wide functionality including auto-initialization, form utilities, animation helpers, and development tools.
Central namespace containing all Materialize functionality and utilities.
/**
* Global Materialize object containing all framework functionality
*/
declare const M: {
/** Framework version string */
version: string; // "1.0.0"
/** jQuery availability indicator */
jQueryLoaded: boolean;
/** Tab key press state tracking */
tabPressed: boolean;
/** General key down state tracking */
keyDown: boolean;
/** Key code constants */
keys: {
TAB: 9;
ENTER: 13;
ESC: 27;
ARROW_UP: 38;
ARROW_DOWN: 40;
};
/** Auto-initialize all components within context */
AutoInit(context?: Element): void;
/** Update text field labels after dynamic content changes */
updateTextFields(): void;
/** Validate individual form field */
validate_field(field: Element): boolean;
/** Auto-resize textarea to fit content */
textareaAutoResize(textarea: Element): void;
/** Show toast notification */
toast(options: ToastOptions | { html: string }): Toast;
/** Generate unique random ID */
guid(): string;
/** Escape hash string special characters */
escapeHash(hash: string): string;
/** Check if element or parent has fixed positioning */
elementOrParentIsFixed(element: Element): boolean;
/** Check if bounding box is within container */
checkWithinContainer(container: Element, bounding: BoundingBox, offset: number): Edges;
/** Check possible alignments for positioning */
checkPossibleAlignments(el: Element, container: Element, bounding: BoundingBox, offset: number): AlignmentInfo;
/** Get overflow parent element */
getOverflowParent(element: Element): Element | null;
/** Extract ID from trigger element */
getIdFromTrigger(trigger: Element): string;
/** Cross-browser document scroll top */
getDocumentScrollTop(): number;
/** Cross-browser document scroll left */
getDocumentScrollLeft(): number;
/** Throttle function execution */
throttle(func: Function, wait: number, options?: ThrottleOptions): Function;
/** Initialize jQuery wrapper for component */
initializeJqueryWrapper(plugin: any, pluginName: string, classRef: string): void;
/** Generate selector string for jQuery object */
objectSelectorString(obj: any): string;
// Component classes
Autocomplete: typeof Autocomplete;
Carousel: typeof Carousel;
CharacterCounter: typeof CharacterCounter;
Chips: typeof Chips;
Collapsible: typeof Collapsible;
Datepicker: typeof Datepicker;
Dropdown: typeof Dropdown;
FloatingActionButton: typeof FloatingActionButton;
FormSelect: typeof FormSelect;
Materialbox: typeof Materialbox;
Modal: typeof Modal;
Parallax: typeof Parallax;
Pushpin: typeof Pushpin;
Range: typeof Range;
ScrollSpy: typeof ScrollSpy;
Sidenav: typeof Sidenav;
Slider: typeof Slider;
Tabs: typeof Tabs;
TapTarget: typeof TapTarget;
Timepicker: typeof Timepicker;
Toast: typeof Toast;
Tooltip: typeof Tooltip;
};Automatic component initialization system that scans the DOM and initializes components based on CSS classes.
/**
* Auto-initialize all components within context
* @param context - DOM element to search within (default: document.body)
*/
M.AutoInit(context?: Element): void;Usage Examples:
// Initialize all components on page load
document.addEventListener('DOMContentLoaded', function() {
M.AutoInit();
});
// Initialize components in specific container
const container = document.getElementById('dynamic-content');
M.AutoInit(container);
// Components that auto-initialize:
const autoInitComponents = {
'Autocomplete': '.autocomplete:not(.no-autoinit)',
'Carousel': '.carousel:not(.no-autoinit)',
'Chips': '.chips:not(.no-autoinit)',
'Collapsible': '.collapsible:not(.no-autoinit)',
'Datepicker': '.datepicker:not(.no-autoinit)',
'Dropdown': '.dropdown-trigger:not(.no-autoinit)',
'Materialbox': '.materialboxed:not(.no-autoinit)',
'Modal': '.modal:not(.no-autoinit)',
'Parallax': '.parallax:not(.no-autoinit)',
'Pushpin': '.pushpin:not(.no-autoinit)',
'ScrollSpy': '.scrollspy:not(.no-autoinit)',
'FormSelect': 'select:not(.no-autoinit)',
'Sidenav': '.sidenav:not(.no-autoinit)',
'Tabs': '.tabs:not(.no-autoinit)',
'TapTarget': '.tap-target:not(.no-autoinit)',
'Timepicker': '.timepicker:not(.no-autoinit)',
'Tooltip': '.tooltipped:not(.no-autoinit)',
'FloatingActionButton': '.fixed-action-btn:not(.no-autoinit)'
};Helper functions for form handling and validation.
/**
* Update all text field labels and styling
* Call after dynamically adding form elements
*/
M.updateTextFields(): void;
/**
* Validate individual form field
* @param field - Form field element to validate
* @returns Boolean indicating if field is valid
*/
M.validate_field(field: Element): boolean;
/**
* Auto-resize textarea element to fit content
* @param textarea - Textarea element to resize
*/
M.textareaAutoResize(textarea: Element): void;Usage Examples:
// Update text fields after AJAX content load
fetch('/api/form-data')
.then(response => response.json())
.then(data => {
// Populate form fields
document.getElementById('name').value = data.name;
document.getElementById('email').value = data.email;
// Update labels
M.updateTextFields();
});
// Validate form on submission
document.getElementById('myForm').addEventListener('submit', function(e) {
e.preventDefault();
const inputs = this.querySelectorAll('input[type="text"], input[type="email"]');
let isValid = true;
inputs.forEach(input => {
if (!M.validate_field(input)) {
isValid = false;
}
});
if (isValid) {
// Submit form
this.submit();
}
});
// Auto-resize textareas
document.querySelectorAll('textarea').forEach(textarea => {
M.textareaAutoResize(textarea);
});Global toast notification system for user feedback.
/**
* Show toast notification
* @param options - Toast configuration options
* @returns Toast instance
*/
M.toast(options: ToastOptions | { html: string }): Toast;
interface ToastOptions {
/** Toast message HTML content */
html: string;
/** Display duration in milliseconds */
displayLength?: number; // default: 4000
/** Enter animation duration */
inDuration?: number; // default: 300
/** Exit animation duration */
outDuration?: number; // default: 375
/** Additional CSS classes */
classes?: string;
/** Callback when toast is dismissed */
completeCallback?: () => void;
/** Percentage of drag distance to activate dismissal */
activationPercent?: number; // default: 0.8
}Usage Examples:
// Simple toast
M.toast({html: 'Hello World!'});
// Styled toast
M.toast({
html: 'Success! Data saved.',
classes: 'green rounded',
displayLength: 2000
});
// Toast with callback
M.toast({
html: 'Processing...',
completeCallback: () => console.log('Toast dismissed')
});
// Toast with action button
M.toast({
html: `<span>Email sent</span><button class="btn-flat toast-action">Undo</button>`,
classes: 'rounded'
});Helper functions for animation and performance optimization.
/**
* Throttle function execution to improve performance
* @param func - Function to throttle
* @param wait - Milliseconds to wait between calls
* @param options - Throttle options
* @returns Throttled function
*/
M.throttle(func: Function, wait: number, options?: ThrottleOptions): Function;
interface ThrottleOptions {
/** Execute on leading edge */
leading?: boolean; // default: true
/** Execute on trailing edge */
trailing?: boolean; // default: true
}
/**
* Generate unique random ID
* @returns UUID-style string
*/
M.guid(): string;Usage Examples:
// Throttle scroll handler for performance
const handleScroll = M.throttle(function() {
console.log('Scroll event:', window.scrollY);
}, 100);
window.addEventListener('scroll', handleScroll);
// Throttle resize handler
const handleResize = M.throttle(function() {
// Expensive resize operations
recalculateLayout();
}, 250, { leading: false });
window.addEventListener('resize', handleResize);
// Generate unique IDs
const uniqueId = M.guid(); // e.g., "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"Helper functions for DOM element manipulation and positioning.
/**
* Check if element or any parent has fixed positioning
* @param element - Element to check
* @returns Boolean indicating fixed positioning
*/
M.elementOrParentIsFixed(element: Element): boolean;
/**
* Escape hash string special characters for CSS selectors
* @param hash - Hash string to escape
* @returns Escaped hash string
*/
M.escapeHash(hash: string): string;
/**
* Extract ID from trigger element (data-target or href)
* @param trigger - Trigger element
* @returns Target ID string
*/
M.getIdFromTrigger(trigger: Element): string;
/**
* Get cross-browser document scroll position
* @returns Scroll top position in pixels
*/
M.getDocumentScrollTop(): number;
/**
* Get cross-browser document scroll position
* @returns Scroll left position in pixels
*/
M.getDocumentScrollLeft(): number;
/**
* Get overflow parent of element
* @param element - Element to find overflow parent for
* @returns Overflow parent element or null
*/
M.getOverflowParent(element: Element): Element | null;Usage Examples:
// Check for fixed positioning
const isFixed = M.elementOrParentIsFixed(document.getElementById('myElement'));
if (isFixed) {
// Handle fixed positioning
}
// Escape hash for selector
const hash = '#my:special.id';
const escaped = M.escapeHash(hash); // '#my\\:special\\.id'
document.querySelector(escaped);
// Get target ID from trigger
const trigger = document.querySelector('[data-target="modal1"]');
const targetId = M.getIdFromTrigger(trigger); // 'modal1'
// Cross-browser scroll position
const scrollTop = M.getDocumentScrollTop();
const scrollLeft = M.getDocumentScrollLeft();
// Find overflow parent
const overflowParent = M.getOverflowParent(myElement);Advanced positioning and alignment helper functions.
/**
* Check if bounding box is within container boundaries
* @param container - Container element
* @param bounding - Bounding box to check
* @param offset - Offset from edges
* @returns Object indicating which edges are exceeded
*/
M.checkWithinContainer(container: Element, bounding: BoundingBox, offset: number): Edges;
/**
* Check possible alignments for positioning
* @param el - Element to position
* @param container - Container element
* @param bounding - Bounding box
* @param offset - Offset value
* @returns Alignment possibilities and space information
*/
M.checkPossibleAlignments(el: Element, container: Element, bounding: BoundingBox, offset: number): AlignmentInfo;
interface BoundingBox {
left: number;
top: number;
width: number;
height: number;
}
interface Edges {
top: boolean;
right: boolean;
bottom: boolean;
left: boolean;
}
interface AlignmentInfo {
top: boolean;
right: boolean;
bottom: boolean;
left: boolean;
spaceOnTop: number | null;
spaceOnRight: number | null;
spaceOnBottom: number | null;
spaceOnLeft: number | null;
}Automatic jQuery wrapper generation for seamless integration.
/**
* Initialize jQuery wrapper for component
* @param plugin - Component class
* @param pluginName - jQuery plugin name
* @param classRef - Class reference name
*/
M.initializeJqueryWrapper(plugin: any, pluginName: string, classRef: string): void;
/**
* Generate selector string for jQuery object
* @param obj - jQuery object
* @returns Selector string
*/
M.objectSelectorString(obj: any): string;jQuery Usage Patterns:
// When jQuery is loaded, components get jQuery wrappers
$(document).ready(function(){
// jQuery-style initialization
$('.modal').modal({
dismissible: false,
opacity: 0.5
});
// Method calling
$('.modal').modal('open');
// Getter methods
const isOpen = $('.modal').modal('isOpen');
// Chaining
$('.dropdown-trigger').dropdown().addClass('active');
});// Get component instances
const modalInstance = M.Modal.getInstance(document.getElementById('modal1'));
const dropdownInstance = M.Dropdown.getInstance(document.querySelector('.dropdown-trigger'));
// Check instance existence
if (modalInstance) {
console.log('Modal is initialized');
console.log('Modal is open:', modalInstance.isOpen);
}
// List all instances of a component type
const allModals = document.querySelectorAll('.modal');
allModals.forEach(modal => {
const instance = M.Modal.getInstance(modal);
if (instance) {
console.log('Modal instance found:', instance);
}
});// Throttle expensive operations
const expensiveOperation = M.throttle(function() {
// Expensive DOM calculations
recalculatePositions();
}, 16); // ~60fps
// Debounce user input
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
const debouncedSearch = debounce(function(query) {
performSearch(query);
}, 300);// Safe component initialization
function safeInit() {
try {
// Auto-initialize components
M.AutoInit();
} catch (error) {
console.error('Component initialization failed:', error);
// Initialize components individually
const components = [
{ selector: '.modal', init: M.Modal.init },
{ selector: '.dropdown-trigger', init: M.Dropdown.init },
{ selector: '.sidenav', init: M.Sidenav.init }
];
components.forEach(({ selector, init }) => {
try {
const elems = document.querySelectorAll(selector);
if (elems.length > 0) {
init(elems);
}
} catch (err) {
console.warn(`Failed to initialize ${selector}:`, err);
}
});
}
}
// Check for component availability
function checkComponentSupport() {
const requiredComponents = ['Modal', 'Dropdown', 'Sidenav'];
const missing = requiredComponents.filter(component => !M[component]);
if (missing.length > 0) {
console.warn('Missing components:', missing);
return false;
}
return true;
}Material Design ripple effect system for adding visual feedback to interactive elements. Waves is automatically initialized but can be manually controlled for custom implementations.
/**
* Waves ripple effect system for Material Design interactions
*/
declare const Waves: {
/**
* Display ripple effect with optional configuration
* @param options - Animation configuration options
*/
displayEffect(options?: WaveOptions): void;
/**
* Attach waves effect to specific element
* @param element - Element to attach waves effect to
*/
attach(element: Element): void;
/** Effect duration in milliseconds */
duration: number; // default: 750
};
interface WaveOptions {
/** Animation duration in milliseconds */
duration?: number; // default: 750
}Usage Examples:
<!-- Elements with automatic waves effect -->
<button class="btn waves-effect">Button</button>
<a class="btn-floating waves-effect waves-light red">
<i class="material-icons">add</i>
</a>
<!-- Different wave colors -->
<button class="btn blue waves-effect waves-light">Light Waves</button>
<button class="btn blue waves-effect waves-dark">Dark Waves</button>
<!-- Waves on other elements -->
<div class="card waves-effect">
<div class="card-content">
<span class="card-title">Clickable Card</span>
</div>
</div>
<!-- Input elements (automatically wrapped) -->
<input type="button" class="btn waves-effect" value="Input Button">// Manual waves initialization (usually not needed)
Waves.displayEffect({
duration: 500
});
// Attach waves to dynamically created elements
const newButton = document.createElement('button');
newButton.className = 'btn waves-effect';
newButton.textContent = 'Dynamic Button';
document.body.appendChild(newButton);
// Manually attach waves effect
Waves.attach(newButton);
// Custom duration for all waves
Waves.displayEffect({
duration: 1000
});CSS Classes:
.waves-effect - Base class required for waves functionality.waves-light - Light-colored ripple effect (for dark backgrounds).waves-dark - Dark-colored ripple effect (for light backgrounds).waves-red, .waves-yellow, .waves-orange, .waves-purple, .waves-green, .waves-teal - Colored ripple effectsFeatures:
// Dynamic component management
class ComponentManager {
constructor() {
this.instances = new Map();
}
init(selector, ComponentClass, options = {}) {
const elements = document.querySelectorAll(selector);
elements.forEach(el => {
const instance = new ComponentClass(el, options);
this.instances.set(el, instance);
});
}
destroy(selector) {
const elements = document.querySelectorAll(selector);
elements.forEach(el => {
const instance = this.instances.get(el);
if (instance && instance.destroy) {
instance.destroy();
this.instances.delete(el);
}
});
}
reinit(selector, ComponentClass, options = {}) {
this.destroy(selector);
this.init(selector, ComponentClass, options);
}
}
// Usage
const manager = new ComponentManager();
manager.init('.modal', M.Modal, { dismissible: false });
manager.reinit('.modal', M.Modal, { dismissible: true });