Material Design Components in CSS, JS and HTML providing a comprehensive implementation of Google's Material Design specification for web applications.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Interactive form controls with Material Design styling and behavior including buttons, text fields, checkboxes, radio buttons, switches, and sliders. All form components provide both visual styling and programmatic APIs for dynamic interaction.
Enhanced button with ripple effects and state management.
/**
* Material Design button component
* CSS Class: mdl-js-button
* Widget: true
*/
interface MaterialButton {
/** Disable the button, preventing interaction and adding disabled styling */
disable(): void;
/** Enable the button, restoring interaction and removing disabled styling */
enable(): void;
}HTML Structure:
<!-- Basic button -->
<button class="mdl-button mdl-js-button">
Button
</button>
<!-- Raised button with ripple effect -->
<button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect">
Raised Button
</button>
<!-- FAB (Floating Action Button) -->
<button class="mdl-button mdl-js-button mdl-button--fab mdl-button--colored">
<i class="material-icons">add</i>
</button>Usage Examples:
// Access button instance
const button = document.querySelector('.mdl-js-button').MaterialButton;
// Disable button programmatically
button.disable();
// Enable button programmatically
button.enable();
// Toggle button state based on form validation
function updateButtonState(isValid) {
if (isValid) {
button.enable();
} else {
button.disable();
}
}Enhanced text input with floating labels, validation, and state management.
/**
* Material Design text field component
* CSS Class: mdl-js-textfield
* Widget: true
*/
interface MaterialTextfield {
/** Check and update disabled state based on input element */
checkDisabled(): void;
/** Check and update focus state, managing floating label */
checkFocus(): void;
/** Check and update validity state, showing/hiding error messages */
checkValidity(): void;
/** Check and update dirty state (whether user has entered content) */
checkDirty(): void;
/** Disable the textfield, preventing interaction */
disable(): void;
/** Enable the textfield, restoring interaction */
enable(): void;
/**
* Update textfield value and refresh all states
* @param value - New value to set
*/
change(value: string): void;
}HTML Structure:
<!-- Basic textfield with floating label -->
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="text" id="sample1">
<label class="mdl-textfield__label" for="sample1">Text...</label>
</div>
<!-- Textfield with error message -->
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="email" id="sample2" required>
<label class="mdl-textfield__label" for="sample2">Email...</label>
<span class="mdl-textfield__error">Input is not an email address!</span>
</div>
<!-- Multiline textfield -->
<div class="mdl-textfield mdl-js-textfield">
<textarea class="mdl-textfield__input" type="text" rows="3" id="sample5"></textarea>
<label class="mdl-textfield__label" for="sample5">Text lines...</label>
</div>Usage Examples:
// Access textfield instance
const textfield = document.querySelector('.mdl-js-textfield').MaterialTextfield;
// Update value programmatically
textfield.change('New value');
// Check validity after programmatic changes
textfield.checkValidity();
// Disable/enable based on conditions
if (userCannotEdit) {
textfield.disable();
} else {
textfield.enable();
}
// Validate on blur
const input = document.querySelector('.mdl-textfield__input');
input.addEventListener('blur', () => {
textfield.checkValidity();
textfield.checkDirty();
});Enhanced checkbox with Material Design styling and state management.
/**
* Material Design checkbox component
* CSS Class: mdl-js-checkbox
* Widget: true
*/
interface MaterialCheckbox {
/** Check and update toggle state based on input element */
checkToggleState(): void;
/** Check and update disabled state */
checkDisabled(): void;
/** Disable the checkbox, preventing interaction */
disable(): void;
/** Enable the checkbox, restoring interaction */
enable(): void;
/** Check the checkbox programmatically */
check(): void;
/** Uncheck the checkbox programmatically */
uncheck(): void;
}HTML Structure:
<!-- Basic checkbox -->
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="checkbox-1">
<input type="checkbox" id="checkbox-1" class="mdl-checkbox__input">
<span class="mdl-checkbox__label">Check me out</span>
</label>
<!-- Disabled checkbox -->
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="checkbox-2">
<input type="checkbox" id="checkbox-2" class="mdl-checkbox__input" disabled>
<span class="mdl-checkbox__label">Disabled</span>
</label>Usage Examples:
// Access checkbox instance
const checkbox = document.querySelector('.mdl-js-checkbox').MaterialCheckbox;
// Check/uncheck programmatically
checkbox.check();
checkbox.uncheck();
// Toggle based on condition
if (shouldBeChecked) {
checkbox.check();
} else {
checkbox.uncheck();
}
// Disable during async operations
async function performAsyncAction() {
checkbox.disable();
try {
await someAsyncOperation();
} finally {
checkbox.enable();
}
}Enhanced radio button with Material Design styling and state management.
/**
* Material Design radio button component
* CSS Class: mdl-js-radio
* Widget: true
*/
interface MaterialRadio {
/** Check and update toggle state based on input element */
checkToggleState(): void;
/** Check and update disabled state */
checkDisabled(): void;
/** Disable the radio button, preventing interaction */
disable(): void;
/** Enable the radio button, restoring interaction */
enable(): void;
/** Check the radio button programmatically */
check(): void;
/** Uncheck the radio button programmatically */
uncheck(): void;
}HTML Structure:
<!-- Radio button group -->
<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="option-1">
<input type="radio" id="option-1" class="mdl-radio__button" name="options" value="1">
<span class="mdl-radio__label">First</span>
</label>
<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="option-2">
<input type="radio" id="option-2" class="mdl-radio__button" name="options" value="2">
<span class="mdl-radio__label">Second</span>
</label>Toggle switch component for binary state selection.
/**
* Material Design switch component
* CSS Class: mdl-js-switch
* Widget: true
*/
interface MaterialSwitch {
/** Check and update toggle state based on input element */
checkToggleState(): void;
/** Check and update disabled state */
checkDisabled(): void;
/** Disable the switch, preventing interaction */
disable(): void;
/** Enable the switch, restoring interaction */
enable(): void;
/** Turn the switch on programmatically */
on(): void;
/** Turn the switch off programmatically */
off(): void;
}HTML Structure:
<!-- Basic switch -->
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect" for="switch-1">
<input type="checkbox" id="switch-1" class="mdl-switch__input">
<span class="mdl-switch__label">Enable notifications</span>
</label>Icon that toggles between states when clicked.
/**
* Material Design icon toggle component
* CSS Class: mdl-js-icon-toggle
* Widget: true
*/
interface MaterialIconToggle {
/** Check and update toggle state based on input element */
checkToggleState(): void;
/** Check and update disabled state */
checkDisabled(): void;
/** Disable the icon toggle, preventing interaction */
disable(): void;
/** Enable the icon toggle, restoring interaction */
enable(): void;
/** Check the icon toggle programmatically */
check(): void;
/** Uncheck the icon toggle programmatically */
uncheck(): void;
}HTML Structure:
<!-- Icon toggle for favorites -->
<label class="mdl-icon-toggle mdl-js-icon-toggle mdl-js-ripple-effect" for="icon-toggle-1">
<input type="checkbox" id="icon-toggle-1" class="mdl-icon-toggle__input">
<i class="mdl-icon-toggle__label material-icons">favorite_border</i>
</label>Range slider input component for selecting numeric values.
/**
* Material Design slider component
* CSS Class: mdl-js-slider
* Widget: true
*/
interface MaterialSlider {
/** Disable the slider, preventing interaction */
disable(): void;
/** Enable the slider, restoring interaction */
enable(): void;
/**
* Update slider value programmatically
* @param value - New value to set (within min/max range)
*/
change(value: number): void;
}
// Note: MaterialSlider includes special handling for Internet Explorer compatibility
// and automatically creates background container elements for visual stylingHTML Structure:
<!-- Basic slider -->
<p style="width: 300px">
<input class="mdl-slider mdl-js-slider" type="range"
min="0" max="100" value="0" tabindex="0">
</p>
<!-- Slider with initial value -->
<p style="width: 300px">
<input class="mdl-slider mdl-js-slider" type="range"
min="0" max="100" value="25" tabindex="0">
</p>Usage Examples:
// Access slider instance
const slider = document.querySelector('.mdl-js-slider').MaterialSlider;
// Update value programmatically
slider.change(75);
// Disable during loading
slider.disable();
// ... perform async operation
slider.enable();
// React to value changes
const sliderInput = document.querySelector('.mdl-js-slider');
sliderInput.addEventListener('input', (event) => {
console.log('Slider value:', event.target.value);
updateDisplay(event.target.value);
});// Integrate with form validation
function validateForm() {
const textfields = document.querySelectorAll('.mdl-js-textfield');
let isValid = true;
textfields.forEach(field => {
const textfield = field.MaterialTextfield;
textfield.checkValidity();
const input = field.querySelector('.mdl-textfield__input');
if (!input.validity.valid) {
isValid = false;
}
});
const submitButton = document.querySelector('#submit-button').MaterialButton;
if (isValid) {
submitButton.enable();
} else {
submitButton.disable();
}
return isValid;
}
// Real-time validation
document.addEventListener('input', (event) => {
if (event.target.matches('.mdl-textfield__input')) {
const textfield = event.target.closest('.mdl-js-textfield').MaterialTextfield;
textfield.checkValidity();
textfield.checkDirty();
validateForm();
}
});// MaterialTextfield constants
interface TextfieldConstants {
/** Value indicating no maximum rows limit */
NO_MAX_ROWS: -1;
/** Attribute name for maxrows configuration */
MAX_ROWS_ATTRIBUTE: 'maxrows';
}
// MaterialCheckbox constants
interface CheckboxConstants {
/** Small timeout value for animation timing */
TINY_TIMEOUT: 0.001;
}Form components may encounter various error conditions:
// Handle component access errors
function safeComponentAccess(element, componentName) {
try {
const component = element[componentName];
if (!component) {
console.warn(`Component ${componentName} not found on element`);
// Try to upgrade the element
componentHandler.upgradeElement(element);
return element[componentName];
}
return component;
} catch (error) {
console.error(`Error accessing ${componentName}:`, error);
return null;
}
}
// Validate input values
function safeSliderChange(slider, value) {
const input = slider.element_.querySelector('input');
const min = parseFloat(input.min) || 0;
const max = parseFloat(input.max) || 100;
if (value < min || value > max) {
console.warn(`Slider value ${value} outside range [${min}, ${max}]`);
value = Math.max(min, Math.min(max, value));
}
slider.change(value);
}