Foundational UI building blocks for the UMD Design System, providing atomic elements that combine to create complex, accessible, and brand-compliant University of Maryland digital experiences.
The UMD Web Elements Library provides the essential building blocks used to construct the UMD Web Components Library. Think of elements as atoms in a design system - they are the smallest, indivisible units that maintain meaning and functionality. These elements handle core UI patterns like buttons, images, text layouts, and containers while remaining unopinionated about their final appearance, relying on the Styles Library for visual presentation.
# Using npm
npm install @universityofmaryland/web-elements-library
# Using yarn
yarn add @universityofmaryland/web-elements-library
Elements are styled by the Styles package:
npm install @universityofmaryland/web-styles-library
import { Composite, Atomic } from '@universityofmaryland/web-elements-library';
// Create a card element
const card = Composite.card.block({
headline: document.createElement('h3'),
text: document.createElement('p'),
image: document.querySelector('img'),
isThemeDark: true,
});
// Add to DOM
document.querySelector('.container').appendChild(card.element);
// Apply associated styles
const style = document.createElement('style');
style.textContent = card.styles;
document.head.appendChild(style);
The most basic building blocks:
Combinations of atomic elements forming UI patterns:
All elements return a consistent interface:
interface ElementModel {
element: HTMLElement | DocumentFragment;
styles: string;
events?: {
load?: () => void;
resize?: () => void;
destroy?: () => void;
};
}
Elements rely entirely on the Styles package for visual presentation:
import { Composite } from '@universityofmaryland/web-elements-library';
// Styles are automatically included in the element.styles property
Components are built using Elements:
Feed layouts use Elements for content display:
// Feeds internally use card and grid elements
import { card } from '@universityofmaryland/web-elements-library/Composite';
import { Atomic } from '@universityofmaryland/web-elements-library';
// Text-based action
const textAction = Atomic.actions.text({
text: 'Learn More',
url: '/learn-more',
isStyled: true,
});
// Icon action
const iconAction = Atomic.actions.icon({
icon: 'arrow-right',
url: '#',
ariaLabel: 'Next page',
});
import { Composite } from '@universityofmaryland/web-elements-library';
// Block card
const blockCard = Composite.card.block({
headline: document.querySelector('h3'),
text: document.querySelector('p'),
image: document.querySelector('img'),
actions: document.querySelector('.actions'),
isThemeDark: false,
});
// Overlay card
const overlayCard = Composite.card.overlay({
headline: headlineElement,
text: textElement,
image: imageElement,
isTypeColor: true,
isThemeDark: true,
});
The hero category offers multiple variations for impactful layouts:
const hero = Composite.hero.standard({
headline: document.createElement('h1'),
eyebrow: document.createElement('span'),
text: document.createElement('p'),
actions: document.createElement('div'),
image: imageElement,
includesAnimation: true,
isThemeDark: true,
});
const minimalHero = Composite.hero.minimal({
headline: document.createElement('h1'),
text: document.createElement('p'),
eyebrow: document.createElement('span'),
});
const overlayHero = Composite.hero.overlay({
headline: headlineElement,
text: textElement,
image: imageElement,
hasBorder: true,
isTransparent: false,
isSticky: true,
isTextCenter: true,
});
Grid Hero - Content blocks in grid layout:
const gridHero = Composite.hero.custom.grid({
headline: headlineElement,
blocks: [block1, block2, block3, block4],
image: backgroundImage,
isThemeDark: true,
});
Expand Hero - With expandable content:
const expandHero = Composite.hero.custom.expand({
headline: headlineElement,
text: textElement,
expandedContent: hiddenContent,
includesAnimation: true,
});
import { Composite } from '@universityofmaryland/web-elements-library';
// Sticky columns
const stickyLayout = Composite.layout.stickyColumns({
leftColumn: sidebarContent,
rightColumn: mainContent,
stickyOffset: 100,
});
// Image expand layout
const imageExpand = Composite.layout.image.expand({
image: imageElement,
caption: 'Image caption',
isExpanded: false,
});
Full TypeScript definitions for type safety:
import type {
ElementModel,
HeroStandardProps,
CardBlockProps,
ThemeProps,
} from '@universityofmaryland/web-elements-library';
const heroProps: HeroStandardProps = {
headline: document.createElement('h1'),
isThemeDark: true,
includesAnimation: false,
};
All elements follow WCAG 2.1 AA standards:
# Run tests
npm test
# Watch mode
npm run test:watch
# Coverage report
npm run test:coverage
# Test specific category
npm test -- composite/hero
See the main repository for contribution guidelines.
University of Maryland