UMD Web Components Library
    Preparing search index...

    UMD Web Components Library

    University of Maryland Web Components Library

    Components Version

    High-level web components built from the elements library for interfaces, interactivity, layout, and data feeds. This library provides ready-to-use web components that follow the University of Maryland's design guidelines and accessibility standards. These components are designed to work seamlessly together to create consistent, branded UMD web experiences while maintaining performance and usability across all devices.

    # Using npm
    npm install @universityofmaryland/web-components-library

    # Using yarn
    yarn add @universityofmaryland/web-components-library

    The simplest way to use the components is to load all of them at once. This approach is ideal for applications that use many UMD components.

    import LoadUmdComponents from '@universityofmaryland/web-components-library';

    document.addEventListener('DOMContentLoaded', () => {
    LoadUmdComponents();
    // All components are now registered and available in the DOM
    });

    For better performance, you can import only the components you need:

    import {
    card,
    navigation,
    hero,
    } from '@universityofmaryland/web-components-library/Components';

    // Initialize specific components
    card.standard();
    navigation.header();
    hero.minimal();

    The library includes a wide range of components organized by type:

    • layout.boxLogo - Box with logo layout
    • layout.imageExpand - Expandable image layout
    • layout.modal - Modal dialog
    • layout.scrollTop - Scroll to top button
    • layout.stickyColumns - Sticky columns layout
    • accordion - Collapsible content panels
    • actions - Action buttons and links
    • alert - Alert notifications
    • card - Various card styles (standard, article, overlay)
    • carousel - Image and content carousels
    • hero - Hero sections (standard, minimal, expand, logo)
    • navigation - Navigation components (header, drawer, breadcrumb)
    • person - Person/profile components
    • quote - Quote/testimonial components
    • stat - Statistics display
    • tab - Tabbed interface
    • text - Text components
    <umd-element-card>
    <img slot="image" src="path/to/image.jpg" alt="Card image" />
    <p slot="eyebrow">Category</p>
    <h3 slot="headline">Card Title</h3>
    <p slot="text">
    Card description text goes here with details about the card content.
    </p>
    <div slot="actions">
    <a href="#">Learn More</a>
    </div>
    </umd-element-card>

    The library uses a sophisticated model system for creating and registering web components with consistent behavior, validation, and lifecycle management.

    Components are registered using the Register.webComponent() utility:

    import { Register } from 'model';

    export default Register.webComponent({
    tagName: 'umd-element-example',
    slots: slotConfiguration,
    createComponent: componentFactory,
    attributes: attributeHandlers, // Optional: reactive attribute observers
    afterConnect: lifecycleCallback, // Optional: lifecycle hooks
    });

    The library uses two types of attributes:

    Set initial component state and configuration:

    <umd-element-card data-theme="dark">
    <!-- Content -->
    </umd-element-card>

    Common configuration attributes:

    • data-theme - Color theme (light, dark)
    • data-display - Display style (grid, list, inline)
    • data-visual-open - Initial open state
    • data-size - Component size (small, medium, large)

    Trigger component behavior when changed:

    // Programmatic control
    element.setAttribute('is-visual-open', 'true');
    element.setAttribute('resize', 'true');

    Common observed attributes:

    • is-visual-open - Opens component
    • is-visual-closed - Closes component
    • resize - Triggers resize calculation
    • load - Triggers load event

    The library provides pre-built attribute handlers:

    import { Attributes } from 'model';

    // Single handler
    const resizeHandler = Attributes.handler.common.resize();

    // Combined handlers
    const multiHandler = Attributes.handler.combine([
    Attributes.handler.common.resize(),
    Attributes.handler.common.visualToggle(),
    ]);

    // Custom handler with callback
    const customHandler = Attributes.handler.common.resize((element) => {
    element.events?.recalculate();
    });

    Available handlers:

    • resize() - Handles component resizing
    • visualToggle() - Open/close animations
    • visualShowHide() - Show/hide visibility
    • accordion() - Complete accordion behavior

    Components use a slot-based content distribution system with validation:

    import { Slots } from 'model';

    const slots = {
    headline: {
    allowedElements: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
    required: true,
    },
    text: {
    allowedElements: ['div', 'p'],
    required: false,
    },
    actions: {
    allowedElements: ['div', 'nav'],
    deprecated: { replacement: 'cta' },
    },
    };

    Using slots in HTML:

    <umd-element-example>
    <h3 slot="headline">Title</h3>
    <p slot="text">Content text</p>
    <div slot="actions">
    <a href="#">Learn More</a>
    </div>
    </umd-element-example>

    Pre-built lifecycle hooks for common initialization patterns:

    import { Lifecycle } from 'model';

    // Available hooks
    afterConnect: Lifecycle.hooks.loadOnConnect, // Calls load event
    afterConnect: Lifecycle.hooks.loadAnimation, // Sets up animations
    afterConnect: Lifecycle.hooks.resizeOnConnect, // Triggers resize

    Example of a complete component implementation:

    import { Composite } from '@universityofmaryland/web-elements-library';
    import { Attributes, Slots, Register, Lifecycle } from 'model';
    import type { CreateComponentFunction, SlotConfiguration } from '../_types';

    // Define the custom element tag name
    const tagName = 'umd-custom-component';

    // Configure slots with validation
    const slots: SlotConfiguration = {
    headline: {
    allowedElements: ['h2', 'h3', 'h4'],
    required: true,
    },
    text: {
    allowedElements: ['p', 'div'],
    },
    image: {
    allowedElements: ['img', 'picture'],
    required: false,
    },
    };

    // Create the component factory function
    const createComponent: CreateComponentFunction = (element) => {
    // Extract validated slot content
    const headline = Slots.headline.default({ element });
    const text = Slots.text.default({ element });
    const image = Slots.query.elements({ element, name: 'image' });

    // Extract configuration attributes
    const isThemeDark = Attributes.isTheme.dark({ element });
    const displayStyle = element.getAttribute('data-display') || 'default';

    // Create component using the Elements library
    return Composite.customComponent.create({
    headline,
    text,
    image,
    isThemeDark,
    displayStyle,
    });
    };

    // Register the web component with all features
    export default Register.webComponent({
    tagName,
    slots,
    createComponent,
    attributes: [
    Attributes.handler.common.resize(),
    Attributes.handler.common.visualToggle(),
    ],
    afterConnect: Lifecycle.hooks.loadOnConnect,
    });

    Components dispatch custom events for state changes:

    // Listen for component events
    element.addEventListener('component:ready', (e) => {
    console.log('Component initialized');
    });

    element.addEventListener('component:resize', (e) => {
    console.log('Component resized');
    });

    element.addEventListener('component:error', (e) => {
    console.error('Component error:', e.detail);
    });

    Components automatically update when observed attributes change:

    // Triggers resize handler
    element.setAttribute('resize', 'true');

    // Triggers visual state change
    element.setAttribute('is-visual-open', 'true');

    All components use Shadow DOM for style encapsulation:

    // Access shadow root
    const shadowRoot = element.shadowRoot;

    // Query within shadow DOM
    const internalElement = shadowRoot.querySelector('.component-part');
    # Clone the repository
    git clone https://github.com/umd-digital/design-system.git
    cd design-system/packages/components

    # Install dependencies
    npm install

    # Start development server
    npm start
    # Production build
    npm run build

    # Build and publish to npm
    npm run release

    The library uses Jest with jsdom for testing web components:

    # Run all tests
    npm test

    # Run tests in watch mode
    npm run test:watch

    # Generate coverage report
    npm run test:coverage

    # Run specific test file
    npm test -- source/api/__tests__/card/standard.test.ts

    Each component test validates:

    • Component registration with customElements
    • Slot configuration and validation
    • Attribute handling (both configuration and observed)
    • Deprecation warnings
    • Event dispatching
    • Error handling

    The library is built with TypeScript and provides comprehensive type definitions:

    import type {
    ComponentRef,
    CreateComponentFunction,
    ComponentRegistration,
    SlotConfiguration,
    ThemeProps,
    VisualStateProps,
    ComponentEvents,
    } from '@universityofmaryland/web-components-library';

    Key interfaces:

    • ComponentRef - Reference returned by component factories
    • SlotConfiguration - Slot validation rules
    • CreateComponentFunction - Component factory signature
    • ComponentRegistration - Registration function type
    • AttributeHandler - Attribute observer configuration
    import { CommonSlots } from 'model/slots/common';

    const slots = {
    headline: CommonSlots.headline, // Pre-configured headline slot
    text: CommonSlots.text, // Pre-configured text slot
    actions: CommonSlots.actions, // Pre-configured actions slot
    customSlot: {
    // Custom slot definition
    allowedElements: ['div', 'section'],
    required: false,
    },
    };

    Components can be composed from other components:

    import {
    card,
    hero,
    } from '@universityofmaryland/web-components-library/Components';

    // Initialize multiple components
    card.standard();
    card.overlay();
    hero.minimal();

    // Components work together
    const heroWithCards = `
    <umd-element-hero>
    <h1 slot="headline">Welcome</h1>
    <div slot="actions">
    <umd-element-call-to-action>
    <!-- CTA Slot Options -->
    </umd-element-call-to-action>
    </div>
    </umd-element-hero>
    `;

    The UMD Web Components Library supports all modern browsers that support Web Components, including:

    • Chrome 90+
    • Firefox 88+
    • Safari 14+
    • Edge 90+

    For older browsers, consider using the Web Components polyfills.

    This library depends on:

    • @universityofmaryland/web-elements-library (^1.2.0) - For foundational UI elements
    • @universityofmaryland/web-styles-library (^1.4.2) - For styling and theming
    • TypeScript (^5.0.0) - For type safety
    • PostCSS & Tailwind CSS - For styling processing
    • Components are lazy-loaded when first used
    • Shadow DOM provides style isolation without global CSS pollution
    • Slot validation happens once during initialization
    • Attribute observers only trigger for registered attributes
    • Components dispatch events for async operations

    All components in this library are designed with accessibility in mind:

    • WCAG 2.1 AA compliant
    • Keyboard navigable interfaces with visible focus indicators
    • Screen reader friendly with proper ARIA attributes and live regions
    • Focus management for interactive elements
    • Color contrast ratios that meet accessibility standards
    • Reduced motion support via prefers-reduced-motion
    • Semantic HTML structure

    For contribution guidelines, please refer to the main repository README.

    This project is licensed under the University of Maryland license.