UNPKG

@trimble-oss/modus-mcp-server

Version:

An MCP server providing information about Modus React form and UI components

400 lines (292 loc) 10.1 kB
# Modus Web Components 2.0 - Framework Documentation ## Table of Contents 1. [Overview](#overview) 2. [General Setup](#general-setup) 3. [React Implementation](#react-implementation) 4. [Angular Implementation](#angular-implementation) 5. [Event Handling Guide](#event-handling-guide) 6. [Component Reference](#component-reference) --- ## Overview ### Metadata - **Library Name**: @trimble-oss/moduswebcomponents - **Version**: 2.0 ### Introduction Modus Web Components 2.0 is a library of reusable UI components built with Web Components technology. These components are framework-agnostic and can be used in any web application regardless of the technology stack. The library provides a consistent design system following Trimble's Modus Design guidelines. **Key Features:** - Framework-agnostic components - TypeScript support - Multiple theming options - Accessibility compliance - Responsive design - Shadow DOM disabled by default for easier styling --- ## General Setup ### Base Installation --- ## React Implementation ### Complete Step-by-Step Installation Guide Follow these steps **in order** to properly set up Modus Web Components 2.0 in your React application: #### Step 1: Install Core Modus Web Components Package ```powershell npm install @trimble-oss/moduswebcomponents --legacy-peer-deps; ``` #### Step 2: Install React-Specific Package ```powershell npm install @trimble-oss/moduswebcomponents-react --legacy-peer-deps; ``` #### Step 3: Define Custom Elements Register the custom elements in your React application entry point (usually `main.jsx` or `index.js`): ```javascript // main.jsx or index.js import React from 'react'; import ReactDOM from 'react-dom/client'; import { defineCustomElements } from '@trimble-oss/moduswebcomponents/loader'; import App from './App.jsx'; // Define custom elements BEFORE rendering your app defineCustomElements(); ReactDOM.createRoot(document.getElementById('root')).render( <React.StrictMode> <App /> </React.StrictMode> ); ``` #### Step 4: Add CSS Imports Add the Modus CSS to your global CSS file (usually `index.css` or `main.css`): ```css /* index.css or main.css */ @import '@trimble-oss/moduswebcomponents/modus-wc-styles.css'; ``` #### Step 5: Add Modus Icons Add the Modus Icons to your application's HTML head section (usually `index.html`): ```html <!-- index.html --> <head> <!-- Preload for performance --> <link rel="preload" href="https://cdn.jsdelivr.net/npm/@trimble-oss/modus-icons@latest/dist/modus-outlined/fonts/modus-icons.css" as="style" crossorigin="anonymous" /> <!-- Actual stylesheet --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@trimble-oss/modus-icons@latest/dist/modus-outlined/fonts/modus-icons.css" /> </head> ``` #### Step 6: Verify Installation Test your setup by using a simple component: ```jsx // App.jsx import { ModusWcButton } from '@trimble-oss/moduswebcomponents-react'; function App() { return ( <div> <ModusWcButton variant="primary">Test Button</ModusWcButton> </div> ); } export default App; ``` ### Installation Summary **Complete installation requires these 5 steps:** 1. `npm install @trimble-oss/moduswebcomponents` 2. `npm install @trimble-oss/moduswebcomponents-react` 3. Call `defineCustomElements()` in your main entry file 4. Import `@trimble-oss/moduswebcomponents/modus-wc-styles.css` in your global CSS 5. Add Modus Icons CDN links to your HTML head **⚠️ Important Notes:** - Follow the steps in this **exact order** - Do not skip any steps - `defineCustomElements()` must be called before React renders your app - CSS import must be in your global CSS file - Icons are required for many components to display properly ### Basic React Usage ```jsx // React usage <ModusWcButton variant="primary">Click me</ModusWcButton> ``` ### React TypeScript Support ```typescript // TypeScript example with React import { ISelectOption, ModusWcSelectCustomEvent } from '@trimble-oss/moduswebcomponents'; // Typed component props const options: ISelectOption[] = [ { label: 'Option 1', value: '1', }, { label: 'Option 2', value: '2', }, ]; // Typed event handlers - Always use event.detail.target.value const handleEvent = (e: CustomEvent) => { // Type-safe access to event details console.log(e.detail.target.value); // Correct for all components } ``` ### React Controlled Input Pattern The controlled input pattern involves maintaining the state of the input's value within the React application or component. **Key Benefits:** - Single source of truth for input values - Real-time validation and transformation of data - Simplified form state management - Improved testability and debugging #### Basic React Controlled Input ```jsx import React, { useState } from 'react'; import { ModusWcTextInput } from '@trimble-oss/moduswebcomponents-react'; interface Props extends React.ComponentProps<typeof ModusWcTextInput> {} const MyComponent: React.FC<Props> = (props) => { const [value, setValue] = useState(''); const handleInputChange = ( e: CustomEvent<HTMLModusWcTextInputElementEventMap['inputChange']> ) => { const value = e.detail.target.value; setValue(value); }; return ( <ModusWcTextInput {...props} onInputChange={handleInputChange} value={value} /> ); }; export default MyComponent; ``` #### Alternative React Controlled Input ```jsx // React controlled input example import { useState } from 'react'; function ControlledTextInput() { const [value, setValue] = useState(''); // Handle input changes const handleChange = (event: CustomEvent) => { setValue(event.detail.target.value); // Additional logic can be added here }; return <ModusWcTextInput onInputChange={handleChange} value={value} />; } ``` ### React Component Wrapping Patterns When using Modus React Components directly, it is recommended to wrap it in corresponding React components within your application. This will abstract away from the library dependency, allowing more flexibility for you and your application in the future. #### Simple React Wrapper ```tsx import React from 'react'; import { ModusWcAvatar } from '@trimble-oss/moduswebcomponents-react'; interface Props extends React.ComponentProps<typeof ModusWcAvatar> {} const Avatar: React.FC<Props> = (props) => { return <ModusWcAvatar {...props} />; }; export default Avatar; ``` #### Complex React Wrapper ```tsx import React from 'react'; import { ModusWcTextInput } from '@trimble-oss/moduswebcomponents-react'; interface Props extends Omit<React.ComponentProps<typeof ModusWcTextInput>, 'inputChange'> { onValueChange: (value: string) => void; } const TextInput: React.FC<Props> = (props) => { const handleInputChange = ( e: CustomEvent<HTMLModusWcTextInputElementEventMap['inputChange']> ) => { const value = e.detail.target.value; props.onValueChange(value); }; return <ModusWcTextInput {...props} onInputChange={handleInputChange} />; }; export default TextInput; ``` ### Using React Component Library ```tsx import { ModusWcBadge } from '@trimble-oss/moduswebcomponents-react'; <ModusWcBadge aria-label="Badge" content="Words" />; ``` --- ## Angular Implementation ### Angular-Specific Installation ```powershell npm install @trimble-oss/moduswebcomponents @trimble-oss/moduswebcomponents-angular; ``` ### Basic Angular Usage ```typescript // Angular usage <ModusWcButton variant="primary">Click me</ModusWcButton> ``` ### Angular Controlled Input Pattern Angular uses its two-way data binding to implement controlled inputs: ```typescript // Angular controlled input example import { Component } from '@angular/core'; @Component({ selector: 'controlled-text-input', template: ` <ModusWcTextInput (inputChange)="onInputChange($event)" [value]="inputValue" > </ModusWcTextInput> `, }) export class ControlledTextInput { inputValue: string = ''; onInputChange(event: CustomEvent) { this.inputValue = event.detail.target.value; // Correct event handling // Validation or transformation logic can be added here } } ``` --- ## Event Handling Guide ### Event Handling Pattern for All Modus Components > **⚠️ UPDATED EVENT HANDLING GUIDE ⚠️** **IMPORTANT:** All Modus Web Components use the same consistent event handling pattern. Always use `event.detail.target.value` for all components, including select components. #### Universal Event Handling Pattern ```typescript // CORRECT: Use event.detail.target.value for ALL components const handleEvent = (event: CustomEvent) => { setValue(event.detail.target.value); // Works for ALL Modus components } ``` #### Component-Specific Examples ```typescript // ModusWcSelect - Use event.detail.target.value const handleSelectEvent = (e: CustomEvent) => { console.log(e.detail.target.value); // Correct for select components } // ModusWcTextInput - Use event.detail.target.value const handleInputChange = (event: CustomEvent) => { setValue(event.detail.target.value); // Correct for input components } // ModusWcCheckbox - Use event.detail.target.checked const handleCheckboxChange = (event: CustomEvent) => { setChecked(event.detail.target.checked); // Correct for checkbox } ``` --- ### HTML Usage (Framework Agnostic) ```html <!-- HTML usage --> <modus-wc-button variant="primary">Click me</modus-wc-button> ``` **Note:** In HTML, web component tags use kebab-case (modus-wc-button), but in React/Angular frameworks, use camelCase (ModusWcButton). --- ### Event Handling for All Components All components follow the same event handling pattern: ```typescript // Universal pattern for all Modus Web Components const handleComponentEvent = (event: CustomEvent) => { // For value-based components (inputs, selects, etc.) const value = event.detail.target.value; // For boolean components (checkboxes, switches, etc.) const checked = event.detail.target.checked; }; ``` ---