@julianoczkowski/create-trimble-app 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (450) hide show
  1. package/README.md +191 -0
  2. package/bin/create-trimble-app.js +9 -0
  3. package/package.json +67 -0
  4. package/src/cli.js +134 -0
  5. package/src/frameworks.js +28 -0
  6. package/src/scaffold.js +209 -0
  7. package/src/utils/file.js +47 -0
  8. package/src/utils/git.js +140 -0
  9. package/src/utils/install.js +25 -0
  10. package/src/utils/logger.js +124 -0
  11. package/templates/angular/.cursor/commands/remove-dev-content.md +394 -0
  12. package/templates/angular/.cursor/mcp.json +13 -0
  13. package/templates/angular/.cursor/rules/modus-angular-20.mdc +82 -0
  14. package/templates/angular/.cursor/rules/modus-angular-accordion-state-management-short.mdc +45 -0
  15. package/templates/angular/.cursor/rules/modus-angular-accordion-state-management.mdc +322 -0
  16. package/templates/angular/.cursor/rules/modus-angular-best-practices.mdc +472 -0
  17. package/templates/angular/.cursor/rules/modus-angular-border-usage-short.mdc +48 -0
  18. package/templates/angular/.cursor/rules/modus-angular-border-usage.mdc +286 -0
  19. package/templates/angular/.cursor/rules/modus-angular-button-group-usage-short.mdc +47 -0
  20. package/templates/angular/.cursor/rules/modus-angular-button-group-usage.mdc +263 -0
  21. package/templates/angular/.cursor/rules/modus-angular-checkbox-value-inversion-short.mdc +36 -0
  22. package/templates/angular/.cursor/rules/modus-angular-checkbox-value-inversion.mdc +92 -0
  23. package/templates/angular/.cursor/rules/modus-angular-chrome-devtools-testing-short.mdc +34 -0
  24. package/templates/angular/.cursor/rules/modus-angular-chrome-devtools-testing.mdc +185 -0
  25. package/templates/angular/.cursor/rules/modus-angular-color-usage-short.mdc +56 -0
  26. package/templates/angular/.cursor/rules/modus-angular-color-usage.mdc +208 -0
  27. package/templates/angular/.cursor/rules/modus-angular-components-reference.mdc +114 -0
  28. package/templates/angular/.cursor/rules/modus-angular-design-system.mdc +273 -0
  29. package/templates/angular/.cursor/rules/modus-angular-development-workflow-short.mdc +43 -0
  30. package/templates/angular/.cursor/rules/modus-angular-development-workflow.mdc +145 -0
  31. package/templates/angular/.cursor/rules/modus-angular-essentials.mdc +272 -0
  32. package/templates/angular/.cursor/rules/modus-angular-forms-validation-short.mdc +56 -0
  33. package/templates/angular/.cursor/rules/modus-angular-forms-validation.mdc +124 -0
  34. package/templates/angular/.cursor/rules/modus-angular-icon-names.mdc +70 -0
  35. package/templates/angular/.cursor/rules/modus-angular-icons-short.mdc +40 -0
  36. package/templates/angular/.cursor/rules/modus-angular-icons.mdc +137 -0
  37. package/templates/angular/.cursor/rules/modus-angular-implementation-guides-short.mdc +36 -0
  38. package/templates/angular/.cursor/rules/modus-angular-implementation-guides.mdc +301 -0
  39. package/templates/angular/.cursor/rules/modus-angular-integration-short.mdc +60 -0
  40. package/templates/angular/.cursor/rules/modus-angular-integration.mdc +1096 -0
  41. package/templates/angular/.cursor/rules/modus-angular-master.mdc +164 -0
  42. package/templates/angular/.cursor/rules/modus-angular-modal-usage-short.mdc +51 -0
  43. package/templates/angular/.cursor/rules/modus-angular-modal-usage.mdc +115 -0
  44. package/templates/angular/.cursor/rules/modus-angular-navbar-usage-short.mdc +49 -0
  45. package/templates/angular/.cursor/rules/modus-angular-navbar-usage.mdc +146 -0
  46. package/templates/angular/.cursor/rules/modus-angular-no-emojis.mdc +66 -0
  47. package/templates/angular/.cursor/rules/modus-angular-opacity-utilities-short.mdc +43 -0
  48. package/templates/angular/.cursor/rules/modus-angular-opacity-utilities.mdc +160 -0
  49. package/templates/angular/.cursor/rules/modus-angular-select-vs-dropdown-menu-short.mdc +51 -0
  50. package/templates/angular/.cursor/rules/modus-angular-select-vs-dropdown-menu.mdc +83 -0
  51. package/templates/angular/.cursor/rules/modus-angular-semantic-html-short.mdc +36 -0
  52. package/templates/angular/.cursor/rules/modus-angular-semantic-html.mdc +81 -0
  53. package/templates/angular/.cursor/rules/modus-angular-side-navigation-usage-short.mdc +50 -0
  54. package/templates/angular/.cursor/rules/modus-angular-side-navigation-usage.mdc +136 -0
  55. package/templates/angular/.cursor/rules/modus-angular-table-usage-short.mdc +52 -0
  56. package/templates/angular/.cursor/rules/modus-angular-table-usage.mdc +151 -0
  57. package/templates/angular/.cursor/rules/modus-angular-tailwind-usage-short.mdc +44 -0
  58. package/templates/angular/.cursor/rules/modus-angular-tailwind-usage.mdc +242 -0
  59. package/templates/angular/.cursor/rules/modus-angular-themes-short.mdc +54 -0
  60. package/templates/angular/.cursor/rules/modus-angular-themes.mdc +222 -0
  61. package/templates/angular/.cursor/rules/modus-angular-utility-panel-usage-short.mdc +52 -0
  62. package/templates/angular/.cursor/rules/modus-angular-utility-panel-usage.mdc +130 -0
  63. package/templates/angular/.cursor/rules/ux/gestalt-laws-detailed.mdc +514 -0
  64. package/templates/angular/.cursor/rules/ux/ux-ui-foundations.mdc +235 -0
  65. package/templates/angular/.cursor/skills/run-lint-checks/SKILL.md +169 -0
  66. package/templates/angular/.editorconfig +17 -0
  67. package/templates/angular/.github/dependabot.yml +19 -0
  68. package/templates/angular/.github/workflows/a11y-check.yml +135 -0
  69. package/templates/angular/.github/workflows/ci.yml +44 -0
  70. package/templates/angular/.husky/pre-commit +32 -0
  71. package/templates/angular/.postcssrc.json +5 -0
  72. package/templates/angular/.vscode/extensions.json +4 -0
  73. package/templates/angular/.vscode/launch.json +20 -0
  74. package/templates/angular/.vscode/tasks.json +42 -0
  75. package/templates/angular/CLAUDE.md +148 -0
  76. package/templates/angular/README.md +92 -0
  77. package/templates/angular/amplify.yml +25 -0
  78. package/templates/angular/angular.json +106 -0
  79. package/templates/angular/data/modusIcons.ts +861 -0
  80. package/templates/angular/package-lock.json +11030 -0
  81. package/templates/angular/package.json +66 -0
  82. package/templates/angular/public/angular-icon.svg +12 -0
  83. package/templates/angular/public/favicon.ico +0 -0
  84. package/templates/angular/public/modus-icons.css +49 -0
  85. package/templates/angular/public/vite.svg +1 -0
  86. package/templates/angular/scripts/README.md +410 -0
  87. package/templates/angular/scripts/check-border-violations.js +352 -0
  88. package/templates/angular/scripts/check-icon-names.js +402 -0
  89. package/templates/angular/scripts/check-inline-styles.js +292 -0
  90. package/templates/angular/scripts/check-modus-colors.js +282 -0
  91. package/templates/angular/scripts/check-modus-icons.js +263 -0
  92. package/templates/angular/scripts/check-opacity-utilities.js +426 -0
  93. package/templates/angular/scripts/check-semantic-html.js +452 -0
  94. package/templates/angular/scripts/check-typescript.js +109 -0
  95. package/templates/angular/src/app/app.config.ts +29 -0
  96. package/templates/angular/src/app/app.css +0 -0
  97. package/templates/angular/src/app/app.html +4 -0
  98. package/templates/angular/src/app/app.routes.ts +351 -0
  99. package/templates/angular/src/app/app.spec.ts +27 -0
  100. package/templates/angular/src/app/app.ts +47 -0
  101. package/templates/angular/src/app/components/README.md +77 -0
  102. package/templates/angular/src/app/components/index.ts +53 -0
  103. package/templates/angular/src/app/components/modus-accordion.component.ts +50 -0
  104. package/templates/angular/src/app/components/modus-alert.component.ts +133 -0
  105. package/templates/angular/src/app/components/modus-autocomplete.component.ts +262 -0
  106. package/templates/angular/src/app/components/modus-avatar.component.ts +75 -0
  107. package/templates/angular/src/app/components/modus-badge.component.ts +84 -0
  108. package/templates/angular/src/app/components/modus-breadcrumbs.component.ts +65 -0
  109. package/templates/angular/src/app/components/modus-button-group.component.ts +82 -0
  110. package/templates/angular/src/app/components/modus-button.component.ts +292 -0
  111. package/templates/angular/src/app/components/modus-card.component.ts +73 -0
  112. package/templates/angular/src/app/components/modus-checkbox.component.ts +117 -0
  113. package/templates/angular/src/app/components/modus-chip.component.ts +97 -0
  114. package/templates/angular/src/app/components/modus-collapse.component.ts +118 -0
  115. package/templates/angular/src/app/components/modus-date.component.ts +165 -0
  116. package/templates/angular/src/app/components/modus-dropdown-menu.component.ts +108 -0
  117. package/templates/angular/src/app/components/modus-file-dropzone.component.ts +121 -0
  118. package/templates/angular/src/app/components/modus-handle.component.ts +96 -0
  119. package/templates/angular/src/app/components/modus-icon.component.ts +81 -0
  120. package/templates/angular/src/app/components/modus-input-feedback.component.ts +54 -0
  121. package/templates/angular/src/app/components/modus-input-label.component.ts +62 -0
  122. package/templates/angular/src/app/components/modus-loader.component.ts +48 -0
  123. package/templates/angular/src/app/components/modus-logo.component.ts +115 -0
  124. package/templates/angular/src/app/components/modus-menu-item.component.ts +116 -0
  125. package/templates/angular/src/app/components/modus-menu.component.ts +58 -0
  126. package/templates/angular/src/app/components/modus-modal.component.ts +70 -0
  127. package/templates/angular/src/app/components/modus-navbar.component.ts +303 -0
  128. package/templates/angular/src/app/components/modus-number-input.component.ts +174 -0
  129. package/templates/angular/src/app/components/modus-pagination.component.ts +74 -0
  130. package/templates/angular/src/app/components/modus-panel.component.ts +61 -0
  131. package/templates/angular/src/app/components/modus-progress.component.ts +62 -0
  132. package/templates/angular/src/app/components/modus-radio.component.ts +102 -0
  133. package/templates/angular/src/app/components/modus-rating.component.ts +80 -0
  134. package/templates/angular/src/app/components/modus-select.component.ts +131 -0
  135. package/templates/angular/src/app/components/modus-side-navigation.component.ts +90 -0
  136. package/templates/angular/src/app/components/modus-skeleton.component.ts +54 -0
  137. package/templates/angular/src/app/components/modus-slider.component.ts +132 -0
  138. package/templates/angular/src/app/components/modus-stepper.component.ts +65 -0
  139. package/templates/angular/src/app/components/modus-switch.component.ts +118 -0
  140. package/templates/angular/src/app/components/modus-table.component.ts +204 -0
  141. package/templates/angular/src/app/components/modus-tabs.component.ts +82 -0
  142. package/templates/angular/src/app/components/modus-text-input.component.ts +221 -0
  143. package/templates/angular/src/app/components/modus-textarea.component.ts +168 -0
  144. package/templates/angular/src/app/components/modus-theme-switcher.component.ts +45 -0
  145. package/templates/angular/src/app/components/modus-time-input.component.ts +172 -0
  146. package/templates/angular/src/app/components/modus-toast.component.ts +63 -0
  147. package/templates/angular/src/app/components/modus-toolbar.component.ts +43 -0
  148. package/templates/angular/src/app/components/modus-tooltip.component.ts +83 -0
  149. package/templates/angular/src/app/components/modus-typography.component.ts +79 -0
  150. package/templates/angular/src/app/components/modus-utility-panel.component.ts +275 -0
  151. package/templates/angular/src/app/components/theme-demo.component.ts +1242 -0
  152. package/templates/angular/src/app/data/component-demos.ts +360 -0
  153. package/templates/angular/src/app/data/modus-icons.ts +806 -0
  154. package/templates/angular/src/app/demos/accordion/accordion-demo.component.ts +212 -0
  155. package/templates/angular/src/app/demos/alert/alert-demo.component.ts +108 -0
  156. package/templates/angular/src/app/demos/autocomplete/autocomplete-demo.component.ts +174 -0
  157. package/templates/angular/src/app/demos/avatar/avatar-demo.component.ts +149 -0
  158. package/templates/angular/src/app/demos/badge/badge-demo.component.ts +148 -0
  159. package/templates/angular/src/app/demos/breadcrumbs/breadcrumbs-demo.component.ts +96 -0
  160. package/templates/angular/src/app/demos/button/button-demo.component.ts +256 -0
  161. package/templates/angular/src/app/demos/button-group/button-group-demo.component.ts +215 -0
  162. package/templates/angular/src/app/demos/card/card-demo.component.ts +180 -0
  163. package/templates/angular/src/app/demos/checkbox/checkbox-demo.component.ts +71 -0
  164. package/templates/angular/src/app/demos/chip/chip-demo.component.ts +183 -0
  165. package/templates/angular/src/app/demos/date/date-demo.component.ts +193 -0
  166. package/templates/angular/src/app/demos/dropdown/dropdown-demo.component.ts +196 -0
  167. package/templates/angular/src/app/demos/file-dropzone/file-dropzone-demo.component.ts +176 -0
  168. package/templates/angular/src/app/demos/handle/handle-demo.component.ts +265 -0
  169. package/templates/angular/src/app/demos/icon/icon-demo.component.ts +65 -0
  170. package/templates/angular/src/app/demos/input-feedback/input-feedback-demo.component.ts +189 -0
  171. package/templates/angular/src/app/demos/input-label/input-label-demo.component.ts +330 -0
  172. package/templates/angular/src/app/demos/loader/loader-demo.component.ts +143 -0
  173. package/templates/angular/src/app/demos/logo/logo-demo.component.ts +191 -0
  174. package/templates/angular/src/app/demos/menu/menu-demo.component.ts +72 -0
  175. package/templates/angular/src/app/demos/modal/modal-demo.component.ts +278 -0
  176. package/templates/angular/src/app/demos/navbar/navbar-demo.component.ts +135 -0
  177. package/templates/angular/src/app/demos/number-input/number-input-demo.component.ts +175 -0
  178. package/templates/angular/src/app/demos/pagination/pagination-demo.component.ts +134 -0
  179. package/templates/angular/src/app/demos/panel/panel-demo.component.ts +235 -0
  180. package/templates/angular/src/app/demos/progress/progress-demo.component.ts +169 -0
  181. package/templates/angular/src/app/demos/radio/radio-demo.component.ts +161 -0
  182. package/templates/angular/src/app/demos/rating/rating-demo.component.ts +97 -0
  183. package/templates/angular/src/app/demos/select/select-demo.component.ts +107 -0
  184. package/templates/angular/src/app/demos/shared/demo-example-clean.component.ts +41 -0
  185. package/templates/angular/src/app/demos/shared/demo-example.component.ts +42 -0
  186. package/templates/angular/src/app/demos/shared/demo-page.component.ts +97 -0
  187. package/templates/angular/src/app/demos/shared/index.ts +3 -0
  188. package/templates/angular/src/app/demos/side-navigation/side-navigation-demo.component.ts +524 -0
  189. package/templates/angular/src/app/demos/skeleton/skeleton-demo.component.ts +112 -0
  190. package/templates/angular/src/app/demos/slider/slider-demo.component.ts +76 -0
  191. package/templates/angular/src/app/demos/stepper/stepper-demo.component.ts +79 -0
  192. package/templates/angular/src/app/demos/switch/switch-demo.component.ts +113 -0
  193. package/templates/angular/src/app/demos/table/table-demo.component.ts +405 -0
  194. package/templates/angular/src/app/demos/tabs/tabs-demo.component.ts +318 -0
  195. package/templates/angular/src/app/demos/text-input/text-input-demo.component.ts +160 -0
  196. package/templates/angular/src/app/demos/textarea/textarea-demo.component.ts +95 -0
  197. package/templates/angular/src/app/demos/theme-switcher/theme-switcher-demo.component.ts +38 -0
  198. package/templates/angular/src/app/demos/time-input/time-input-demo.component.ts +130 -0
  199. package/templates/angular/src/app/demos/toast/toast-demo.component.ts +258 -0
  200. package/templates/angular/src/app/demos/toolbar/toolbar-demo.component.ts +54 -0
  201. package/templates/angular/src/app/demos/tooltip/tooltip-demo.component.ts +163 -0
  202. package/templates/angular/src/app/demos/utility-panel/utility-panel-demo.component.ts +197 -0
  203. package/templates/angular/src/app/dev/dev-config.ts +119 -0
  204. package/templates/angular/src/app/dev/dev-panel/dev-panel.component.ts +215 -0
  205. package/templates/angular/src/app/dev/dev-panel.service.ts +63 -0
  206. package/templates/angular/src/app/dev/index.ts +8 -0
  207. package/templates/angular/src/app/dev/theme-switcher-dropdown/theme-switcher-dropdown.component.ts +134 -0
  208. package/templates/angular/src/app/dev-pages/color-palette/color-palette.component.ts +229 -0
  209. package/templates/angular/src/app/dev-pages/components-gallery/components-gallery.component.ts +486 -0
  210. package/templates/angular/src/app/dev-pages/icons/icons.component.ts +149 -0
  211. package/templates/angular/src/app/pages/home/home.component.ts +251 -0
  212. package/templates/angular/src/app/services/README.md +57 -0
  213. package/templates/angular/src/app/services/theme.service.ts +163 -0
  214. package/templates/angular/src/environments/environment.development.ts +8 -0
  215. package/templates/angular/src/environments/environment.ts +8 -0
  216. package/templates/angular/src/index.html +14 -0
  217. package/templates/angular/src/main.ts +6 -0
  218. package/templates/angular/src/styles.css +1328 -0
  219. package/templates/angular/tsconfig.app.json +15 -0
  220. package/templates/angular/tsconfig.json +35 -0
  221. package/templates/angular/tsconfig.spec.json +14 -0
  222. package/templates/config.json +23 -0
  223. package/templates/react/.cursor/commands/remove-dev-content.md +311 -0
  224. package/templates/react/.cursor/mcp.json +13 -0
  225. package/templates/react/.cursor/rules/README.md +240 -0
  226. package/templates/react/.cursor/rules/border-usage-guidelines-short.mdc +22 -0
  227. package/templates/react/.cursor/rules/border-usage-guidelines.mdc +380 -0
  228. package/templates/react/.cursor/rules/chrome-devtools-testing-react-short.mdc +23 -0
  229. package/templates/react/.cursor/rules/development-workflow-react-short.mdc +23 -0
  230. package/templates/react/.cursor/rules/development-workflow-react.mdc +292 -0
  231. package/templates/react/.cursor/rules/implementation-guides-react-short.mdc +23 -0
  232. package/templates/react/.cursor/rules/implementation-guides-react.mdc +446 -0
  233. package/templates/react/.cursor/rules/modus-accordion-state-management-react-short.mdc +23 -0
  234. package/templates/react/.cursor/rules/modus-accordion-state-management-react.mdc +445 -0
  235. package/templates/react/.cursor/rules/modus-button-group-usage-react-short.mdc +23 -0
  236. package/templates/react/.cursor/rules/modus-button-group-usage-react.mdc +117 -0
  237. package/templates/react/.cursor/rules/modus-checkbox-value-inversion-react-short.mdc +23 -0
  238. package/templates/react/.cursor/rules/modus-checkbox-value-inversion-react.mdc +492 -0
  239. package/templates/react/.cursor/rules/modus-color-usage-react-short.mdc +23 -0
  240. package/templates/react/.cursor/rules/modus-color-usage-react.mdc +420 -0
  241. package/templates/react/.cursor/rules/modus-components-reference.mdc +366 -0
  242. package/templates/react/.cursor/rules/modus-icon-names.mdc +63 -0
  243. package/templates/react/.cursor/rules/modus-icons-react-short.mdc +24 -0
  244. package/templates/react/.cursor/rules/modus-icons-react.mdc +402 -0
  245. package/templates/react/.cursor/rules/modus-modal-implementation-react-short.mdc +23 -0
  246. package/templates/react/.cursor/rules/modus-modal-implementation-react.mdc +831 -0
  247. package/templates/react/.cursor/rules/modus-navbar-side-navigation-react-short.mdc +23 -0
  248. package/templates/react/.cursor/rules/modus-navbar-side-navigation-react.mdc +247 -0
  249. package/templates/react/.cursor/rules/modus-no-emojis-react-short.mdc +23 -0
  250. package/templates/react/.cursor/rules/modus-opacity-utilities-react-short.mdc +70 -0
  251. package/templates/react/.cursor/rules/modus-opacity-utilities-react.mdc +208 -0
  252. package/templates/react/.cursor/rules/modus-react-best-practices-short.mdc +23 -0
  253. package/templates/react/.cursor/rules/modus-react-best-practices.mdc +508 -0
  254. package/templates/react/.cursor/rules/modus-react-essentials.mdc +209 -0
  255. package/templates/react/.cursor/rules/modus-react-integration-short.mdc +23 -0
  256. package/templates/react/.cursor/rules/modus-react-integration.mdc +509 -0
  257. package/templates/react/.cursor/rules/modus-react-key-warnings-short.mdc +23 -0
  258. package/templates/react/.cursor/rules/modus-react-key-warnings.mdc +805 -0
  259. package/templates/react/.cursor/rules/modus-react-master.mdc +160 -0
  260. package/templates/react/.cursor/rules/modus-select-vs-dropdown-menu-react-short.mdc +23 -0
  261. package/templates/react/.cursor/rules/modus-select-vs-dropdown-menu-react.mdc +442 -0
  262. package/templates/react/.cursor/rules/modus-semantic-html-react-short.mdc +23 -0
  263. package/templates/react/.cursor/rules/modus-semantic-html-react.mdc +427 -0
  264. package/templates/react/.cursor/rules/modus-tailwind-usage-react-short.mdc +23 -0
  265. package/templates/react/.cursor/rules/modus-tailwind-usage-react.mdc +642 -0
  266. package/templates/react/.cursor/rules/modus-themes-react-short.mdc +23 -0
  267. package/templates/react/.cursor/rules/modus-themes-react.mdc +506 -0
  268. package/templates/react/.cursor/rules/ux/gestalt-laws-detailed.mdc +456 -0
  269. package/templates/react/.cursor/rules/ux/ux-ui-foundations.mdc +211 -0
  270. package/templates/react/.cursor/skills/create-modus-form-component/SKILL.md +518 -0
  271. package/templates/react/.cursor/skills/create-modus-wrapper-component/SKILL.md +252 -0
  272. package/templates/react/.cursor/skills/fix-modus-component-event-issues/SKILL.md +345 -0
  273. package/templates/react/.cursor/skills/handle-modus-checkbox-value-bug/SKILL.md +202 -0
  274. package/templates/react/.cursor/skills/implement-modus-modal-with-refs/SKILL.md +386 -0
  275. package/templates/react/.cursor/skills/integrate-modus-icons/SKILL.md +300 -0
  276. package/templates/react/.cursor/skills/run-lint-checks/SKILL.md +235 -0
  277. package/templates/react/.cursor/skills/set-up-modus-event-listeners/SKILL.md +284 -0
  278. package/templates/react/.cursor/skills/style-modus-components-with-tailwind/SKILL.md +382 -0
  279. package/templates/react/.env.development +3 -0
  280. package/templates/react/.env.production +3 -0
  281. package/templates/react/.github/CODEOWNERS +28 -0
  282. package/templates/react/.github/ISSUE_TEMPLATE/bug_report.yml +176 -0
  283. package/templates/react/.github/ISSUE_TEMPLATE/config.yml +20 -0
  284. package/templates/react/.github/ISSUE_TEMPLATE/documentation.yml +115 -0
  285. package/templates/react/.github/ISSUE_TEMPLATE/feature_request.yml +171 -0
  286. package/templates/react/.github/ISSUE_TEMPLATE/question.yml +139 -0
  287. package/templates/react/.github/copilot-instructions.md +80 -0
  288. package/templates/react/.github/instructions/components.instructions.md +82 -0
  289. package/templates/react/.github/instructions/demos.instructions.md +82 -0
  290. package/templates/react/.github/instructions/pages.instructions.md +76 -0
  291. package/templates/react/.github/instructions/styles.instructions.md +77 -0
  292. package/templates/react/.github/instructions/typescript.instructions.md +101 -0
  293. package/templates/react/.github/pull_request_template.md +188 -0
  294. package/templates/react/.github/workflows/ci.yml +43 -0
  295. package/templates/react/.github/workflows/claude-code-review.yml +44 -0
  296. package/templates/react/.github/workflows/claude.yml +50 -0
  297. package/templates/react/.husky/pre-commit +28 -0
  298. package/templates/react/.vscode/extensions.json +8 -0
  299. package/templates/react/CLAUDE.md +119 -0
  300. package/templates/react/CODE_OF_CONDUCT.md +79 -0
  301. package/templates/react/CONTRIBUTING.md +65 -0
  302. package/templates/react/LICENSE +21 -0
  303. package/templates/react/README.md +728 -0
  304. package/templates/react/SECURITY.md +50 -0
  305. package/templates/react/eslint.config.js +23 -0
  306. package/templates/react/index.html +13 -0
  307. package/templates/react/package-lock.json +5209 -0
  308. package/templates/react/package.json +49 -0
  309. package/templates/react/postcss.config.js +6 -0
  310. package/templates/react/public/react.svg +1 -0
  311. package/templates/react/public/vite.svg +1 -0
  312. package/templates/react/readme_assets/getting_started_header.png +0 -0
  313. package/templates/react/readme_assets/hero.png +0 -0
  314. package/templates/react/readme_assets/modus_comp.png +0 -0
  315. package/templates/react/readme_assets/modus_figma_mcp.png +0 -0
  316. package/templates/react/readme_assets/teaser_comp.gif +0 -0
  317. package/templates/react/scripts/README.md +343 -0
  318. package/templates/react/scripts/check-border-violations.js +483 -0
  319. package/templates/react/scripts/check-icon-names.js +486 -0
  320. package/templates/react/scripts/check-inline-styles.js +364 -0
  321. package/templates/react/scripts/check-modus-colors.js +247 -0
  322. package/templates/react/scripts/check-modus-icons.js +256 -0
  323. package/templates/react/scripts/check-opacity-utilities.js +481 -0
  324. package/templates/react/scripts/check-semantic-html.js +476 -0
  325. package/templates/react/scripts/check-typescript.js +109 -0
  326. package/templates/react/src/App.css +42 -0
  327. package/templates/react/src/App.tsx +54 -0
  328. package/templates/react/src/assets/react.svg +1 -0
  329. package/templates/react/src/components/DemoExample.tsx +61 -0
  330. package/templates/react/src/components/DemoPage.tsx +81 -0
  331. package/templates/react/src/components/ModusAccordion.tsx +89 -0
  332. package/templates/react/src/components/ModusAlert.tsx +85 -0
  333. package/templates/react/src/components/ModusAutocomplete.tsx +207 -0
  334. package/templates/react/src/components/ModusAvatar.tsx +50 -0
  335. package/templates/react/src/components/ModusBadge.tsx +82 -0
  336. package/templates/react/src/components/ModusBreadcrumbs.tsx +75 -0
  337. package/templates/react/src/components/ModusButton.tsx +244 -0
  338. package/templates/react/src/components/ModusButtonGroup.tsx +91 -0
  339. package/templates/react/src/components/ModusCard.tsx +70 -0
  340. package/templates/react/src/components/ModusCheckbox.tsx +168 -0
  341. package/templates/react/src/components/ModusChip.tsx +93 -0
  342. package/templates/react/src/components/ModusDate.tsx +154 -0
  343. package/templates/react/src/components/ModusDropdownMenu.tsx +148 -0
  344. package/templates/react/src/components/ModusFileDropzone.tsx +140 -0
  345. package/templates/react/src/components/ModusHandle.tsx +101 -0
  346. package/templates/react/src/components/ModusIcon.tsx +49 -0
  347. package/templates/react/src/components/ModusInputFeedback.tsx +52 -0
  348. package/templates/react/src/components/ModusInputLabel.tsx +50 -0
  349. package/templates/react/src/components/ModusLoader.tsx +42 -0
  350. package/templates/react/src/components/ModusLogo.tsx +102 -0
  351. package/templates/react/src/components/ModusMenu.tsx +119 -0
  352. package/templates/react/src/components/ModusMenuItem.tsx +86 -0
  353. package/templates/react/src/components/ModusModal.tsx +145 -0
  354. package/templates/react/src/components/ModusNavbar.tsx +504 -0
  355. package/templates/react/src/components/ModusNumberInput.tsx +230 -0
  356. package/templates/react/src/components/ModusPagination.tsx +94 -0
  357. package/templates/react/src/components/ModusPanel.tsx +92 -0
  358. package/templates/react/src/components/ModusProgress.tsx +70 -0
  359. package/templates/react/src/components/ModusProvider.tsx +18 -0
  360. package/templates/react/src/components/ModusRadio.tsx +114 -0
  361. package/templates/react/src/components/ModusRating.tsx +108 -0
  362. package/templates/react/src/components/ModusSelect.tsx +171 -0
  363. package/templates/react/src/components/ModusSideNavigation.tsx +149 -0
  364. package/templates/react/src/components/ModusSkeleton.tsx +42 -0
  365. package/templates/react/src/components/ModusSlider.tsx +128 -0
  366. package/templates/react/src/components/ModusStepper.tsx +85 -0
  367. package/templates/react/src/components/ModusSwitch.tsx +130 -0
  368. package/templates/react/src/components/ModusTable.tsx +309 -0
  369. package/templates/react/src/components/ModusTabs.tsx +114 -0
  370. package/templates/react/src/components/ModusTextInput.tsx +179 -0
  371. package/templates/react/src/components/ModusTextarea.tsx +164 -0
  372. package/templates/react/src/components/ModusThemeSwitcher.tsx +58 -0
  373. package/templates/react/src/components/ModusTimeInput.tsx +176 -0
  374. package/templates/react/src/components/ModusToast.tsx +207 -0
  375. package/templates/react/src/components/ModusToolbar.tsx +70 -0
  376. package/templates/react/src/components/ModusTooltip.tsx +97 -0
  377. package/templates/react/src/components/ModusUtilityPanel.tsx +198 -0
  378. package/templates/react/src/components/ThemeSwitcherDropdown.tsx +117 -0
  379. package/templates/react/src/components/ThemeToggleSimple.tsx +157 -0
  380. package/templates/react/src/config/routes.ts +196 -0
  381. package/templates/react/src/contexts/ThemeContext.tsx +81 -0
  382. package/templates/react/src/contexts/ThemeContextData.tsx +89 -0
  383. package/templates/react/src/data/modusIcons.ts +865 -0
  384. package/templates/react/src/demos/accordion-demo/page.tsx +236 -0
  385. package/templates/react/src/demos/alert-demo/page.tsx +94 -0
  386. package/templates/react/src/demos/autocomplete-demo/page.tsx +166 -0
  387. package/templates/react/src/demos/avatar-demo/page.tsx +135 -0
  388. package/templates/react/src/demos/badge-demo/page.tsx +174 -0
  389. package/templates/react/src/demos/breadcrumbs-demo/page.tsx +88 -0
  390. package/templates/react/src/demos/button-demo/page.tsx +261 -0
  391. package/templates/react/src/demos/button-group-demo/page.tsx +231 -0
  392. package/templates/react/src/demos/card-demo/page.tsx +241 -0
  393. package/templates/react/src/demos/checkbox-demo/page.tsx +79 -0
  394. package/templates/react/src/demos/chip-demo/page.tsx +197 -0
  395. package/templates/react/src/demos/date-demo/page.tsx +179 -0
  396. package/templates/react/src/demos/dropdown-demo/page.tsx +150 -0
  397. package/templates/react/src/demos/file-dropzone-demo/page.tsx +186 -0
  398. package/templates/react/src/demos/handle-demo/page.tsx +313 -0
  399. package/templates/react/src/demos/icon-demo/page.tsx +72 -0
  400. package/templates/react/src/demos/input-feedback-demo/page.tsx +202 -0
  401. package/templates/react/src/demos/input-label-demo/page.tsx +392 -0
  402. package/templates/react/src/demos/loader-demo/page.tsx +138 -0
  403. package/templates/react/src/demos/logo-demo/page.tsx +292 -0
  404. package/templates/react/src/demos/menu-demo/page.tsx +70 -0
  405. package/templates/react/src/demos/modal-demo/page.tsx +332 -0
  406. package/templates/react/src/demos/navbar-demo/page.tsx +141 -0
  407. package/templates/react/src/demos/number-input-demo/page.tsx +180 -0
  408. package/templates/react/src/demos/pagination-demo/page.tsx +147 -0
  409. package/templates/react/src/demos/panel-demo/page.tsx +376 -0
  410. package/templates/react/src/demos/progress-demo/page.tsx +185 -0
  411. package/templates/react/src/demos/radio-demo/page.tsx +242 -0
  412. package/templates/react/src/demos/rating-demo/page.tsx +97 -0
  413. package/templates/react/src/demos/select-demo/page.tsx +111 -0
  414. package/templates/react/src/demos/side-navigation-demo/page.tsx +775 -0
  415. package/templates/react/src/demos/skeleton-demo/page.tsx +107 -0
  416. package/templates/react/src/demos/slider-demo/page.tsx +78 -0
  417. package/templates/react/src/demos/stepper-demo/page.tsx +86 -0
  418. package/templates/react/src/demos/switch-demo/page.tsx +146 -0
  419. package/templates/react/src/demos/table-demo/page.tsx +489 -0
  420. package/templates/react/src/demos/tabs-demo/page.tsx +187 -0
  421. package/templates/react/src/demos/text-input-demo/page.tsx +151 -0
  422. package/templates/react/src/demos/textarea-demo/page.tsx +73 -0
  423. package/templates/react/src/demos/theme-switcher-demo/page.tsx +26 -0
  424. package/templates/react/src/demos/time-input-demo/page.tsx +148 -0
  425. package/templates/react/src/demos/toast-demo/page.tsx +302 -0
  426. package/templates/react/src/demos/toolbar-demo/page.tsx +49 -0
  427. package/templates/react/src/demos/tooltip-demo/page.tsx +209 -0
  428. package/templates/react/src/demos/typography-test/page.tsx +28 -0
  429. package/templates/react/src/demos/utility-panel-demo/page.tsx +197 -0
  430. package/templates/react/src/dev/DevPanel.tsx +219 -0
  431. package/templates/react/src/dev/DevPanelContext.ts +14 -0
  432. package/templates/react/src/dev/DevPanelProvider.tsx +63 -0
  433. package/templates/react/src/dev/DevRoutes.tsx +98 -0
  434. package/templates/react/src/dev/config.ts +127 -0
  435. package/templates/react/src/dev/index.ts +8 -0
  436. package/templates/react/src/dev/useDevPanel.ts +17 -0
  437. package/templates/react/src/dev-pages/ColorPalettePage.tsx +347 -0
  438. package/templates/react/src/dev-pages/ComponentsGalleryPage.tsx +489 -0
  439. package/templates/react/src/dev-pages/IconsPage.tsx +137 -0
  440. package/templates/react/src/dev-pages/index.ts +3 -0
  441. package/templates/react/src/hooks/useTheme.ts +15 -0
  442. package/templates/react/src/index.css +635 -0
  443. package/templates/react/src/main.tsx +14 -0
  444. package/templates/react/src/pages/HomePage.tsx +283 -0
  445. package/templates/react/src/vite-env.d.ts +9 -0
  446. package/templates/react/tailwind.config.js +58 -0
  447. package/templates/react/tsconfig.app.json +27 -0
  448. package/templates/react/tsconfig.json +7 -0
  449. package/templates/react/tsconfig.node.json +25 -0
  450. package/templates/react/vite.config.ts +18 -0
@@ -0,0 +1,252 @@
1
+ ---
2
+ name: create-modus-wrapper-component
3
+ description: Scaffold a new Modus wrapper component following established patterns with proper TypeScript interfaces, event handling, and cleanup
4
+ ---
5
+
6
+ # Create Modus Wrapper Component
7
+
8
+ Scaffold a new Modus wrapper component following established patterns from the codebase.
9
+
10
+ ## When to Use
11
+
12
+ Use this skill when:
13
+ - Creating a new wrapper component for a Modus web component
14
+ - You need to integrate a Modus component that doesn't have a wrapper yet
15
+ - You want to ensure proper event handling and TypeScript types
16
+
17
+ ## Pattern Overview
18
+
19
+ All Modus wrapper components follow this structure:
20
+
21
+ 1. **Import the web component** from `@trimble-oss/moduswebcomponents-react`
22
+ 2. **Define TypeScript props interface** with JSDoc comments
23
+ 3. **Use `useRef`** for component reference
24
+ 4. **Use `useEffect`** for event listeners with proper cleanup
25
+ 5. **Forward props** to the web component with conditional spreading
26
+ 6. **Handle events** via event listeners, not React props
27
+
28
+ ## Reference Examples
29
+
30
+ - **Simple wrapper**: `src/components/ModusButton.tsx` - No event listeners needed
31
+ - **With event listeners**: `src/components/ModusCheckbox.tsx` - Shows event handling pattern
32
+ - **With dropdown**: `src/components/ModusDropdownMenu.tsx` - Shows menu event handling
33
+
34
+ ## Implementation Template
35
+
36
+ ```tsx
37
+ import { useEffect, useRef } from "react";
38
+ import { ModusWc[ComponentName] } from "@trimble-oss/moduswebcomponents-react";
39
+ import type { ReactNode } from "react";
40
+
41
+ /**
42
+ * Props for the Modus[ComponentName] component.
43
+ */
44
+ export interface Modus[ComponentName]Props {
45
+ /** Description of prop */
46
+ propName?: string;
47
+
48
+ /** A callback function to handle events. */
49
+ onEventName?: (event: CustomEvent<EventDetailType>) => void;
50
+
51
+ /** A custom CSS class to apply to the component. */
52
+ customClass?: string;
53
+
54
+ /** The ARIA label for accessibility. */
55
+ "aria-label"?: string;
56
+ }
57
+
58
+ /**
59
+ * Renders a Modus [component name] component.
60
+ *
61
+ * @example
62
+ * // Basic usage
63
+ * <Modus[ComponentName] propName="value" />
64
+ *
65
+ * @example
66
+ * // With event handler
67
+ * <Modus[ComponentName]
68
+ * propName="value"
69
+ * onEventName={(event) => console.log(event.detail)}
70
+ * />
71
+ *
72
+ * @param {Modus[ComponentName]Props} props - The component props.
73
+ * @returns {JSX.Element} The rendered component.
74
+ * @see {@link https://modus.trimble.com/components/[component]} - Modus documentation
75
+ */
76
+ export default function Modus[ComponentName]({
77
+ propName,
78
+ onEventName,
79
+ customClass,
80
+ "aria-label": ariaLabel,
81
+ }: Modus[ComponentName]Props) {
82
+ const componentRef = useRef<HTMLModusWc[ComponentName]Element>(null);
83
+
84
+ // Set up event listeners if needed
85
+ useEffect(() => {
86
+ const component = componentRef.current;
87
+ if (!component) return;
88
+
89
+ const handleEventName = (event: Event) => {
90
+ onEventName?.(event as CustomEvent<EventDetailType>);
91
+ };
92
+
93
+ if (onEventName) {
94
+ component.addEventListener("eventName", handleEventName);
95
+ }
96
+
97
+ return () => {
98
+ if (onEventName) {
99
+ component.removeEventListener("eventName", handleEventName);
100
+ }
101
+ };
102
+ }, [onEventName]);
103
+
104
+ return (
105
+ <ModusWc[ComponentName]
106
+ ref={componentRef}
107
+ prop-name={propName}
108
+ custom-class={customClass}
109
+ aria-label={ariaLabel}
110
+ />
111
+ );
112
+ }
113
+ ```
114
+
115
+ ## Key Patterns
116
+
117
+ ### 1. Conditional Prop Spreading
118
+
119
+ For optional props that shouldn't be passed when undefined:
120
+
121
+ ```tsx
122
+ // ✅ CORRECT: Conditional spreading
123
+ <ModusWcComponent
124
+ {...(color && { color })}
125
+ {...(variant && { variant })}
126
+ size={size} // Required prop, always pass
127
+ />
128
+
129
+ // ❌ WRONG: Passing undefined
130
+ <ModusWcComponent
131
+ color={color} // May be undefined
132
+ variant={variant} // May be undefined
133
+ />
134
+ ```
135
+
136
+ Reference: `src/components/ModusButton.tsx:229-230`
137
+
138
+ ### 2. Event Listener Setup
139
+
140
+ Always use `useEffect` with cleanup:
141
+
142
+ ```tsx
143
+ useEffect(() => {
144
+ const component = componentRef.current;
145
+ if (!component) return;
146
+
147
+ const handleEvent = (event: Event) => {
148
+ onEvent?.(event as CustomEvent<EventDetailType>);
149
+ };
150
+
151
+ if (onEvent) {
152
+ component.addEventListener("eventName", handleEvent);
153
+ }
154
+
155
+ return () => {
156
+ if (onEvent) {
157
+ component.removeEventListener("eventName", handleEvent);
158
+ }
159
+ };
160
+ }, [onEvent]);
161
+ ```
162
+
163
+ Reference: `src/components/ModusCheckbox.tsx:91-150`
164
+
165
+ ### 3. TypeScript Types
166
+
167
+ Use proper types for web component elements:
168
+
169
+ ```tsx
170
+ // ✅ CORRECT: Proper element type
171
+ const componentRef = useRef<HTMLModusWcButtonElement>(null);
172
+ const componentRef = useRef<HTMLModusWcCheckboxElement>(null);
173
+ const componentRef = useRef<HTMLModusWcDropdownMenuElement>(null);
174
+
175
+ // Pattern: HTMLModusWc[ComponentName]Element
176
+ ```
177
+
178
+ ### 4. Prop Naming
179
+
180
+ Web components use kebab-case for props:
181
+
182
+ ```tsx
183
+ // React prop: customClass
184
+ // Web component prop: custom-class
185
+ <ModusWcComponent custom-class={customClass} />
186
+
187
+ // React prop: modalId
188
+ // Web component prop: modal-id
189
+ <ModusWcModal modal-id={modalId} />
190
+ ```
191
+
192
+ ### 5. Event Handler Types
193
+
194
+ Always type event handlers properly:
195
+
196
+ ```tsx
197
+ // ✅ CORRECT: Typed event handler
198
+ onEventName?: (event: CustomEvent<{ value: string }>) => void;
199
+
200
+ // In handler:
201
+ const handleEvent = (event: Event) => {
202
+ onEventName?.(event as CustomEvent<{ value: string }>);
203
+ };
204
+ ```
205
+
206
+ ## Common Event Names
207
+
208
+ Modus components use these common event names:
209
+
210
+ - `inputChange` - For input value changes
211
+ - `inputFocus` - For focus events
212
+ - `inputBlur` - For blur events
213
+ - `buttonClick` - For button clicks
214
+ - `itemSelect` - For menu/dropdown item selection
215
+ - `menuVisibilityChange` - For dropdown menu visibility
216
+ - `expandedChange` - For accordion/collapse state
217
+
218
+ Check the Modus documentation for component-specific events.
219
+
220
+ ## Accessibility
221
+
222
+ Always include:
223
+
224
+ - `aria-label` prop for icon-only or non-text components
225
+ - Proper ARIA attributes passed to web component
226
+ - Keyboard navigation support (usually handled by web component)
227
+
228
+ ## Testing Checklist
229
+
230
+ - [ ] Component renders without errors
231
+ - [ ] Props are forwarded correctly to web component
232
+ - [ ] Event listeners are set up and cleaned up properly
233
+ - [ ] TypeScript types are correct
234
+ - [ ] Accessibility attributes are included
235
+ - [ ] Conditional props don't pass undefined values
236
+
237
+ ## Common Mistakes to Avoid
238
+
239
+ 1. **Missing cleanup**: Always return cleanup function from `useEffect`
240
+ 2. **Wrong event names**: Check Modus docs for exact event names
241
+ 3. **Passing undefined**: Use conditional spreading for optional props
242
+ 4. **Wrong prop names**: Web components use kebab-case, React uses camelCase
243
+ 5. **Missing null checks**: Always check `componentRef.current` before use
244
+
245
+ ## Next Steps
246
+
247
+ After creating the wrapper:
248
+
249
+ 1. Export it from `src/components/index.ts` (if exists)
250
+ 2. Create a demo page in `src/demos/[component]-demo/page.tsx`
251
+ 3. Add to component reference documentation
252
+ 4. Test all props and events
@@ -0,0 +1,345 @@
1
+ ---
2
+ name: fix-modus-component-event-issues
3
+ description: Debug and fix common event handling problems with Modus web components
4
+ ---
5
+
6
+ # Fix Modus Component Event Issues
7
+
8
+ Debug and fix common event handling problems with Modus web components.
9
+
10
+ ## When to Use
11
+
12
+ Use this skill when:
13
+ - Events aren't firing on Modus components
14
+ - Components aren't responding to user interactions
15
+ - Event handlers aren't being called
16
+ - You suspect event listener setup issues
17
+
18
+ ## Common Issues and Solutions
19
+
20
+ ### Issue 1: Events Not Firing
21
+
22
+ **Symptoms**: Click handlers, change handlers, or other events don't fire.
23
+
24
+ **Causes**:
25
+ 1. Missing event listener setup
26
+ 2. Wrong event name
27
+ 3. Component ref not set up
28
+ 4. Handler not passed as prop
29
+
30
+ **Solution**:
31
+
32
+ ```tsx
33
+ // ✅ CORRECT: Proper event listener setup
34
+ useEffect(() => {
35
+ const component = componentRef.current;
36
+ if (!component) return;
37
+
38
+ const handleEvent = (event: Event) => {
39
+ onEvent?.(event as CustomEvent<EventDetailType>);
40
+ };
41
+
42
+ if (onEvent) {
43
+ component.addEventListener("eventName", handleEvent);
44
+ }
45
+
46
+ return () => {
47
+ if (onEvent) {
48
+ component.removeEventListener("eventName", handleEvent);
49
+ }
50
+ };
51
+ }, [onEvent]); // ✅ Include handler in dependencies
52
+ ```
53
+
54
+ **Checklist**:
55
+ - [ ] Component ref is created: `const componentRef = useRef<HTMLModusWcComponentElement>(null)`
56
+ - [ ] Ref is passed to web component: `<ModusWcComponent ref={componentRef} />`
57
+ - [ ] Event listener is added in `useEffect`
58
+ - [ ] Event name matches Modus documentation
59
+ - [ ] Handler is included in dependency array
60
+ - [ ] Cleanup function removes listener
61
+
62
+ ### Issue 2: Missing Cleanup
63
+
64
+ **Symptoms**: Memory leaks, events firing multiple times, component errors after unmount.
65
+
66
+ **Solution**:
67
+
68
+ ```tsx
69
+ useEffect(() => {
70
+ const component = componentRef.current;
71
+ if (!component) return;
72
+
73
+ const handleEvent = (event: Event) => {
74
+ onEvent?.(event as CustomEvent<EventDetailType>);
75
+ };
76
+
77
+ component.addEventListener("eventName", handleEvent);
78
+
79
+ // ✅ CRITICAL: Always return cleanup function
80
+ return () => {
81
+ component.removeEventListener("eventName", handleEvent);
82
+ };
83
+ }, [onEvent]);
84
+ ```
85
+
86
+ ### Issue 3: Wrong Event Names
87
+
88
+ **Symptoms**: Events never fire, wrong event type received.
89
+
90
+ **Common Event Names**:
91
+
92
+ | Component | Event Name | Detail Type |
93
+ |-----------|------------|-------------|
94
+ | Checkbox | `inputChange` | `InputEvent` |
95
+ | TextInput | `inputChange` | `InputEvent` |
96
+ | DropdownMenu | `itemSelect` | `{ value: string }` |
97
+ | DropdownMenu | `menuVisibilityChange` | `{ isVisible: boolean }` |
98
+ | Navbar | `searchClick` | `MouseEvent \| KeyboardEvent` |
99
+ | Accordion | `expandedChange` | `{ expanded: boolean; index: number }` |
100
+
101
+ **Solution**: Check Modus documentation for exact event names. They're case-sensitive.
102
+
103
+ ### Issue 4: Missing Ref
104
+
105
+ **Symptoms**: `Cannot read property 'addEventListener' of null`, events don't attach.
106
+
107
+ **Solution**:
108
+
109
+ ```tsx
110
+ // ✅ CORRECT: Ref setup
111
+ const componentRef = useRef<HTMLModusWcComponentElement>(null);
112
+
113
+ useEffect(() => {
114
+ const component = componentRef.current;
115
+ if (!component) return; // ✅ Check before use
116
+
117
+ // Set up listeners
118
+ }, []);
119
+
120
+ return (
121
+ <ModusWcComponent ref={componentRef} /> // ✅ Pass ref
122
+ );
123
+ ```
124
+
125
+ ### Issue 5: Handler Not in Dependencies
126
+
127
+ **Symptoms**: Stale closures, handlers use old values.
128
+
129
+ **Solution**:
130
+
131
+ ```tsx
132
+ useEffect(() => {
133
+ const component = componentRef.current;
134
+ if (!component) return;
135
+
136
+ const handleEvent = (event: Event) => {
137
+ onEvent?.(event as CustomEvent<EventDetailType>);
138
+ };
139
+
140
+ if (onEvent) {
141
+ component.addEventListener("eventName", handleEvent);
142
+ }
143
+
144
+ return () => {
145
+ if (onEvent) {
146
+ component.removeEventListener("eventName", handleEvent);
147
+ }
148
+ };
149
+ }, [onEvent]); // ✅ Include handler in dependencies
150
+ ```
151
+
152
+ ### Issue 6: Wrong Event Target
153
+
154
+ **Symptoms**: Can't access component properties, wrong value extracted.
155
+
156
+ **Solution**:
157
+
158
+ ```tsx
159
+ // ✅ CORRECT: Cast to proper element type
160
+ const handleInputChange = (event: Event) => {
161
+ const customEvent = event as CustomEvent<InputEvent>;
162
+ const value = (customEvent.target as HTMLModusWcTextInputElement).value;
163
+ onInputChange?.(value);
164
+ };
165
+
166
+ // ❌ WRONG: Don't use event.detail for input values
167
+ const handleInputChange = (event: Event) => {
168
+ const value = event.detail; // Wrong for input components!
169
+ };
170
+ ```
171
+
172
+ ### Issue 7: Multiple Event Listeners
173
+
174
+ **Symptoms**: Events fire multiple times, duplicate handlers.
175
+
176
+ **Solution**:
177
+
178
+ ```tsx
179
+ // ✅ CORRECT: Conditional attachment
180
+ if (onEvent) {
181
+ component.addEventListener("eventName", handleEvent);
182
+ }
183
+
184
+ // ✅ CORRECT: Remove in cleanup
185
+ return () => {
186
+ if (onEvent) {
187
+ component.removeEventListener("eventName", handleEvent);
188
+ }
189
+ };
190
+ ```
191
+
192
+ ## Debugging Checklist
193
+
194
+ When events aren't working, check:
195
+
196
+ 1. **Ref Setup**
197
+ - [ ] `useRef` is created with correct type
198
+ - [ ] Ref is passed to web component
199
+ - [ ] Ref is checked before use (`if (!component) return`)
200
+
201
+ 2. **Event Listener Setup**
202
+ - [ ] Listener is added in `useEffect`
203
+ - [ ] Event name matches Modus documentation
204
+ - [ ] Handler function is defined
205
+ - [ ] Handler is conditionally attached (if prop exists)
206
+
207
+ 3. **Cleanup**
208
+ - [ ] Cleanup function is returned from `useEffect`
209
+ - [ ] Listener is removed in cleanup
210
+ - [ ] Same handler reference is used for add/remove
211
+
212
+ 4. **Dependencies**
213
+ - [ ] Handler props are in dependency array
214
+ - [ ] No missing dependencies causing stale closures
215
+
216
+ 5. **Event Handling**
217
+ - [ ] Event is cast to correct `CustomEvent` type
218
+ - [ ] Value is extracted correctly (`target.value` vs `detail`)
219
+ - [ ] Handler is called with correct parameters
220
+
221
+ ## Debugging Tools
222
+
223
+ ### Console Logging
224
+
225
+ ```tsx
226
+ useEffect(() => {
227
+ const component = componentRef.current;
228
+ if (!component) {
229
+ console.error("Component ref is null");
230
+ return;
231
+ }
232
+
233
+ console.log("Setting up event listener for:", component);
234
+
235
+ const handleEvent = (event: Event) => {
236
+ console.log("Event fired:", event);
237
+ console.log("Event type:", event.type);
238
+ console.log("Event target:", event.target);
239
+ onEvent?.(event as CustomEvent<EventDetailType>);
240
+ };
241
+
242
+ component.addEventListener("eventName", handleEvent);
243
+ console.log("Event listener attached");
244
+
245
+ return () => {
246
+ console.log("Cleaning up event listener");
247
+ component.removeEventListener("eventName", handleEvent);
248
+ };
249
+ }, [onEvent]);
250
+ ```
251
+
252
+ ### React DevTools
253
+
254
+ - Check if component ref is set
255
+ - Verify component is mounted
256
+ - Check if handlers are defined
257
+
258
+ ### Browser DevTools
259
+
260
+ - Check Event Listeners panel for attached listeners
261
+ - Verify event names match
262
+ - Check for errors in console
263
+
264
+ ## Common Patterns to Verify
265
+
266
+ ### Pattern 1: Basic Event Setup
267
+
268
+ ```tsx
269
+ // ✅ Verify this pattern
270
+ const componentRef = useRef<HTMLModusWcComponentElement>(null);
271
+
272
+ useEffect(() => {
273
+ const component = componentRef.current;
274
+ if (!component) return;
275
+
276
+ const handleEvent = (event: Event) => {
277
+ onEvent?.(event as CustomEvent<EventDetailType>);
278
+ };
279
+
280
+ if (onEvent) {
281
+ component.addEventListener("eventName", handleEvent);
282
+ }
283
+
284
+ return () => {
285
+ if (onEvent) {
286
+ component.removeEventListener("eventName", handleEvent);
287
+ }
288
+ };
289
+ }, [onEvent]);
290
+
291
+ return <ModusWcComponent ref={componentRef} />;
292
+ ```
293
+
294
+ ### Pattern 2: Multiple Events
295
+
296
+ ```tsx
297
+ // ✅ Verify all events are set up
298
+ useEffect(() => {
299
+ const component = componentRef.current;
300
+ if (!component) return;
301
+
302
+ const handleEvent1 = (event: Event) => {
303
+ onEvent1?.(event as CustomEvent<Type1>);
304
+ };
305
+ const handleEvent2 = (event: Event) => {
306
+ onEvent2?.(event as CustomEvent<Type2>);
307
+ };
308
+
309
+ if (onEvent1) component.addEventListener("event1", handleEvent1);
310
+ if (onEvent2) component.addEventListener("event2", handleEvent2);
311
+
312
+ return () => {
313
+ if (onEvent1) component.removeEventListener("event1", handleEvent1);
314
+ if (onEvent2) component.removeEventListener("event2", handleEvent2);
315
+ };
316
+ }, [onEvent1, onEvent2]); // ✅ All handlers in dependencies
317
+ ```
318
+
319
+ ## Quick Fixes
320
+
321
+ ### Fix: Events Not Firing
322
+
323
+ 1. Check if ref is set: `console.log(componentRef.current)`
324
+ 2. Verify event name: Check Modus docs
325
+ 3. Add console.log in handler to verify it's called
326
+ 4. Check if handler prop is passed
327
+
328
+ ### Fix: Events Firing Multiple Times
329
+
330
+ 1. Check if cleanup is removing listeners
331
+ 2. Verify handler isn't recreated on each render
332
+ 3. Check dependency array includes handler
333
+
334
+ ### Fix: Wrong Values
335
+
336
+ 1. Verify event type casting
337
+ 2. Check if using `target.value` vs `detail`
338
+ 3. For checkboxes, verify value inversion is handled
339
+
340
+ ## Related Files
341
+
342
+ - `src/components/ModusCheckbox.tsx` - Event handling example
343
+ - `src/components/ModusDropdownMenu.tsx` - Multiple events example
344
+ - `src/components/ModusNavbar.tsx` - Complex event handling
345
+ - `.cursor/rules/modus-react-integration.mdc` - Integration patterns