一键导入
create-modus-wrapper-component
Scaffold a new Modus wrapper component following established patterns with proper TypeScript interfaces, event handling, and cleanup
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Scaffold a new Modus wrapper component following established patterns with proper TypeScript interfaces, event handling, and cleanup
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Scaffold form components with proper Modus input integration, event handling, validation, and checkbox bug handling
Scaffold a new Modus wrapper component following established SolidJS patterns with proper TypeScript interfaces, event handling, and cleanup
Debug and fix common event handling problems with Modus web components
Apply the critical checkbox value inversion workaround when working with ModusCheckbox components
Create Modus modals using the callback ref pattern for programmatic control
Help with correct Modus icon usage patterns including naming conventions, sizing, and accessibility
| name | create-modus-wrapper-component |
| description | Scaffold a new Modus wrapper component following established patterns with proper TypeScript interfaces, event handling, and cleanup |
Scaffold a new Modus wrapper component following established patterns from the codebase.
Use this skill when:
All Modus wrapper components follow this structure:
@trimble-oss/moduswebcomponents-reactuseRef for component referenceuseEffect for event listeners with proper cleanupsrc/components/ModusButton.tsx - No event listeners neededsrc/components/ModusCheckbox.tsx - Shows event handling patternsrc/components/ModusDropdownMenu.tsx - Shows menu event handlingimport { useEffect, useRef } from "react";
import { ModusWc[ComponentName] } from "@trimble-oss/moduswebcomponents-react";
import type { ReactNode } from "react";
/**
* Props for the Modus[ComponentName] component.
*/
export interface Modus[ComponentName]Props {
/** Description of prop */
propName?: string;
/** A callback function to handle events. */
onEventName?: (event: CustomEvent<EventDetailType>) => void;
/** A custom CSS class to apply to the component. */
customClass?: string;
/** The ARIA label for accessibility. */
"aria-label"?: string;
}
/**
* Renders a Modus [component name] component.
*
* @example
* // Basic usage
* <Modus[ComponentName] propName="value" />
*
* @example
* // With event handler
* <Modus[ComponentName]
* propName="value"
* onEventName={(event) => console.log(event.detail)}
* />
*
* @param {Modus[ComponentName]Props} props - The component props.
* @returns {JSX.Element} The rendered component.
* @see {@link https://modus.trimble.com/components/[component]} - Modus documentation
*/
export default function Modus[ComponentName]({
propName,
onEventName,
customClass,
"aria-label": ariaLabel,
}: Modus[ComponentName]Props) {
const componentRef = useRef<HTMLModusWc[ComponentName]Element>(null);
// Set up event listeners if needed
useEffect(() => {
const component = componentRef.current;
if (!component) return;
const handleEventName = (event: Event) => {
onEventName?.(event as CustomEvent<EventDetailType>);
};
if (onEventName) {
component.addEventListener("eventName", handleEventName);
}
return () => {
if (onEventName) {
component.removeEventListener("eventName", handleEventName);
}
};
}, [onEventName]);
return (
<ModusWc[ComponentName]
ref={componentRef}
prop-name={propName}
custom-class={customClass}
aria-label={ariaLabel}
/>
);
}
For optional props that shouldn't be passed when undefined:
// ✅ CORRECT: Conditional spreading
<ModusWcComponent
{...(color && { color })}
{...(variant && { variant })}
size={size} // Required prop, always pass
/>
// ❌ WRONG: Passing undefined
<ModusWcComponent
color={color} // May be undefined
variant={variant} // May be undefined
/>
Reference: src/components/ModusButton.tsx:229-230
Always use useEffect with cleanup:
useEffect(() => {
const component = componentRef.current;
if (!component) return;
const handleEvent = (event: Event) => {
onEvent?.(event as CustomEvent<EventDetailType>);
};
if (onEvent) {
component.addEventListener("eventName", handleEvent);
}
return () => {
if (onEvent) {
component.removeEventListener("eventName", handleEvent);
}
};
}, [onEvent]);
Reference: src/components/ModusCheckbox.tsx:91-150
Use proper types for web component elements:
// ✅ CORRECT: Proper element type
const componentRef = useRef<HTMLModusWcButtonElement>(null);
const componentRef = useRef<HTMLModusWcCheckboxElement>(null);
const componentRef = useRef<HTMLModusWcDropdownMenuElement>(null);
// Pattern: HTMLModusWc[ComponentName]Element
Web components use kebab-case for props:
// React prop: customClass
// Web component prop: custom-class
<ModusWcComponent custom-class={customClass} />
// React prop: modalId
// Web component prop: modal-id
<ModusWcModal modal-id={modalId} />
Always type event handlers properly:
// ✅ CORRECT: Typed event handler
onEventName?: (event: CustomEvent<{ value: string }>) => void;
// In handler:
const handleEvent = (event: Event) => {
onEventName?.(event as CustomEvent<{ value: string }>);
};
Modus components use these common event names:
inputChange - For input value changesinputFocus - For focus eventsinputBlur - For blur eventsbuttonClick - For button clicksitemSelect - For menu/dropdown item selectionmenuVisibilityChange - For dropdown menu visibilityexpandedChange - For accordion/collapse stateCheck the Modus documentation for component-specific events.
Always include:
aria-label prop for icon-only or non-text componentsuseEffectcomponentRef.current before useAfter creating the wrapper:
src/components/index.ts (if exists)src/demos/[component]-demo/page.tsx