@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,75 @@
1
+
2
+
3
+ import { useEffect, useRef } from "react";
4
+ import { ModusWcBreadcrumbs } from "@trimble-oss/moduswebcomponents-react";
5
+
6
+ /**
7
+ * Represents a single item in the breadcrumb trail.
8
+ */
9
+ export interface BreadcrumbItem {
10
+ /** The text to display for the breadcrumb item. */
11
+ label: string;
12
+ /** The URL to navigate to when the breadcrumb item is clicked. */
13
+ url?: string;
14
+ }
15
+
16
+ /**
17
+ * Props for the ModusBreadcrumbs component.
18
+ */
19
+ export interface ModusBreadcrumbsProps {
20
+ /** The items to display in the breadcrumb trail. */
21
+ items: BreadcrumbItem[];
22
+ /** The size of the breadcrumbs. */
23
+ size?: 'sm' | 'md' | 'lg';
24
+ /** A custom CSS class to apply to the breadcrumbs. */
25
+ customClass?: string;
26
+ /** The ARIA label for the breadcrumbs. */
27
+ 'aria-label'?: string;
28
+ /** A callback function to handle breadcrumb item clicks. */
29
+ onBreadcrumbClick?: (event: CustomEvent<BreadcrumbItem>) => void;
30
+ }
31
+
32
+ /**
33
+ * Renders a Modus breadcrumbs component.
34
+ * @param {ModusBreadcrumbsProps} props - The component props.
35
+ * @param {BreadcrumbItem[]} props.items - The items to display in the breadcrumb trail.
36
+ * @param {'sm' | 'md' | 'lg'} [props.size='md'] - The size of the breadcrumbs.
37
+ * @param {string} [props.customClass] - A custom CSS class to apply to the breadcrumbs.
38
+ * @param {string} [props.aria-label] - The ARIA label for the breadcrumbs.
39
+ * @param {(event: CustomEvent<BreadcrumbItem>) => void} [props.onBreadcrumbClick] - A callback function to handle breadcrumb item clicks.
40
+ * @returns {JSX.Element} The rendered breadcrumbs component.
41
+ */
42
+ export default function ModusBreadcrumbs({
43
+ items,
44
+ size = 'md',
45
+ customClass,
46
+ 'aria-label': ariaLabel,
47
+ onBreadcrumbClick,
48
+ }: ModusBreadcrumbsProps) {
49
+ const breadcrumbsRef = useRef<HTMLModusWcBreadcrumbsElement>(null);
50
+
51
+ useEffect(() => {
52
+ const breadcrumbs = breadcrumbsRef.current;
53
+ if (!breadcrumbs || !onBreadcrumbClick) return;
54
+
55
+ const handleBreadcrumbClick = (event: Event) => {
56
+ const customEvent = event as CustomEvent<BreadcrumbItem>;
57
+ onBreadcrumbClick(customEvent);
58
+ };
59
+
60
+ breadcrumbs.addEventListener("breadcrumbClick", handleBreadcrumbClick);
61
+ return () => {
62
+ breadcrumbs.removeEventListener("breadcrumbClick", handleBreadcrumbClick);
63
+ };
64
+ }, [onBreadcrumbClick]);
65
+
66
+ return (
67
+ <ModusWcBreadcrumbs
68
+ ref={breadcrumbsRef}
69
+ items={items}
70
+ size={size}
71
+ customClass={customClass}
72
+ aria-label={ariaLabel}
73
+ />
74
+ );
75
+ }
@@ -0,0 +1,244 @@
1
+ import { ModusWcButton } from "@trimble-oss/moduswebcomponents-react";
2
+ import type { ReactNode } from "react";
3
+
4
+ /**
5
+ * Props for the ModusButton component.
6
+ */
7
+ interface ModusButtonProps {
8
+ /** The color of the button. */
9
+ color?: "primary" | "secondary" | "tertiary" | "warning" | "danger";
10
+ /** The variant of the button. */
11
+ variant?: "filled" | "outlined" | "borderless";
12
+ /** The size of the button. */
13
+ size?: "xs" | "sm" | "md" | "lg";
14
+ /** The shape of the button. */
15
+ shape?: "rectangle" | "square" | "circle";
16
+
17
+ /** Whether the button is disabled. */
18
+ disabled?: boolean;
19
+ /** Whether the button should take up the full width of its container. */
20
+ fullWidth?: boolean;
21
+ /** Whether the button is pressed. */
22
+ pressed?: boolean;
23
+ /** The type of the button. */
24
+ type?: "button" | "submit" | "reset";
25
+
26
+ /** The content to display inside the button. */
27
+ children?: ReactNode;
28
+ /** An icon to display in the button. */
29
+ icon?: string;
30
+ /** The position of the icon relative to the button text. */
31
+ iconPosition?: "left" | "right" | "only";
32
+ /** The size of the icon (Tailwind text class). */
33
+ iconSize?: string;
34
+
35
+ /** The ARIA label for the button. */
36
+ ariaLabel?: string;
37
+
38
+ /** A callback function to handle button clicks. */
39
+ onButtonClick?: () => void;
40
+
41
+ /** A custom CSS class to apply to the button. */
42
+ className?: string;
43
+ }
44
+
45
+ /**
46
+ * Renders a Modus button component with full customization support.
47
+ *
48
+ * @example
49
+ * // Basic button
50
+ * <ModusButton>Click me</ModusButton>
51
+ *
52
+ * @example
53
+ * // Icon button with custom styling
54
+ * <ModusButton
55
+ * icon="add"
56
+ * iconPosition="left"
57
+ * color="primary"
58
+ * size="lg"
59
+ * >
60
+ * Add Item
61
+ * </ModusButton>
62
+ *
63
+ * @example
64
+ * // Icon-only button with accessibility
65
+ * <ModusButton
66
+ * icon="settings"
67
+ * iconPosition="only"
68
+ * ariaLabel="Open settings"
69
+ * />
70
+ *
71
+ * @param {ModusButtonProps} props - The component props.
72
+ * @returns {JSX.Element} The rendered button component.
73
+ * @see {@link https://modus.trimble.com/components/button} - Modus Button documentation
74
+ */
75
+ export default function ModusButton({
76
+ color,
77
+ variant,
78
+ size = "md",
79
+ shape = "rectangle",
80
+ disabled = false,
81
+ fullWidth = false,
82
+ pressed = false,
83
+ type = "button",
84
+ children,
85
+ icon,
86
+ iconPosition = "left",
87
+ iconSize,
88
+ ariaLabel,
89
+ onButtonClick,
90
+ className,
91
+ }: ModusButtonProps) {
92
+ /**
93
+ * Determines the appropriate icon size class based on button size, icon position, and explicit iconSize prop.
94
+ *
95
+ * @returns {string} The Tailwind text class for the icon size
96
+ * @private
97
+ */
98
+ const getIconSizeClass = (): string => {
99
+ // If iconSize is explicitly provided, use it
100
+ if (iconSize) {
101
+ return iconSize;
102
+ }
103
+
104
+ // Automatic sizing based on button size and icon position
105
+ if (iconPosition === "only") {
106
+ // Icon-only buttons get larger icons
107
+ switch (size) {
108
+ case "xs":
109
+ return "text-sm";
110
+ case "sm":
111
+ return "text-base";
112
+ case "md":
113
+ return "text-xl";
114
+ case "lg":
115
+ return "text-2xl";
116
+ default:
117
+ return "text-xl";
118
+ }
119
+ } else {
120
+ // Icons with text scale with button size
121
+ switch (size) {
122
+ case "xs":
123
+ return "text-xs";
124
+ case "sm":
125
+ return "text-sm";
126
+ case "md":
127
+ return "text-lg";
128
+ case "lg":
129
+ return "text-xl";
130
+ default:
131
+ return "text-lg";
132
+ }
133
+ }
134
+ };
135
+
136
+ /**
137
+ * Renders an icon with proper positioning and styling based on its position.
138
+ *
139
+ * This helper function creates an icon element with appropriate margin spacing
140
+ * based on the icon's position relative to the button text. Icons positioned
141
+ * on the left get right margin, icons on the right get left margin, and
142
+ * icon-only buttons have no margin.
143
+ *
144
+ * @param {string} iconName - The name of the Modus icon to render
145
+ * @param {"left" | "right" | "only"} position - The position of the icon relative to text
146
+ * @returns {JSX.Element} The rendered icon element with appropriate styling
147
+ * @private
148
+ */
149
+ const renderIcon = (
150
+ iconName: string,
151
+ position: "left" | "right" | "only",
152
+ ) => {
153
+ const iconStyle =
154
+ position === "left"
155
+ ? { marginRight: "8px" }
156
+ : position === "right"
157
+ ? { marginLeft: "8px" }
158
+ : {};
159
+
160
+ const iconSizeClass = getIconSizeClass();
161
+
162
+ return (
163
+ <i className={`modus-icons ${iconSizeClass}`} style={iconStyle}>
164
+ {iconName}
165
+ </i>
166
+ );
167
+ };
168
+
169
+ /**
170
+ * Determines and renders the button content based on icon position.
171
+ *
172
+ * This function handles the complex logic of combining icons and text content
173
+ * based on the iconPosition prop. It supports three modes:
174
+ * - "left": Icon appears before text
175
+ * - "right": Icon appears after text
176
+ * - "only": Only the icon is displayed (text is hidden)
177
+ *
178
+ * @returns {ReactNode} The rendered content with proper icon and text arrangement
179
+ * @private
180
+ */
181
+ const renderContent = () => {
182
+ if (!icon) {
183
+ return children;
184
+ }
185
+
186
+ switch (iconPosition) {
187
+ case "left":
188
+ return (
189
+ <>
190
+ {renderIcon(icon, "left")}
191
+ {children}
192
+ </>
193
+ );
194
+ case "right":
195
+ return (
196
+ <>
197
+ {children}
198
+ {renderIcon(icon, "right")}
199
+ </>
200
+ );
201
+ case "only":
202
+ return renderIcon(icon, "only");
203
+ default:
204
+ return children;
205
+ }
206
+ };
207
+
208
+ /**
209
+ * Generates appropriate ARIA label for accessibility.
210
+ *
211
+ * This function ensures proper accessibility by generating ARIA labels
212
+ * for icon-only buttons. If no explicit ariaLabel is provided and the
213
+ * button is icon-only, it uses the text content as the aria-label.
214
+ * This ensures screen readers can properly announce the button's purpose.
215
+ *
216
+ * @returns {string | undefined} The appropriate ARIA label or undefined
217
+ * @private
218
+ */
219
+ const getAriaLabel = () => {
220
+ if (ariaLabel) return ariaLabel;
221
+ if (iconPosition === "only" && typeof children === "string") {
222
+ return children; // Use text content as aria-label for icon-only buttons
223
+ }
224
+ return undefined;
225
+ };
226
+
227
+ return (
228
+ <ModusWcButton
229
+ {...(color && { color })}
230
+ {...(variant && { variant })}
231
+ size={size}
232
+ shape={shape}
233
+ disabled={disabled}
234
+ fullWidth={fullWidth}
235
+ pressed={pressed}
236
+ type={type}
237
+ aria-label={getAriaLabel()}
238
+ onButtonClick={onButtonClick}
239
+ custom-class={className}
240
+ >
241
+ {renderContent()}
242
+ </ModusWcButton>
243
+ );
244
+ }
@@ -0,0 +1,91 @@
1
+ import { ModusWcButtonGroup } from "@trimble-oss/moduswebcomponents-react";
2
+ import type { ReactNode } from "react";
3
+
4
+ /**
5
+ * Props for the ModusButtonGroup component.
6
+ */
7
+ export interface ModusButtonGroupProps {
8
+ /** The content to display inside the button group (ModusButton components). */
9
+ children?: ReactNode;
10
+ /** Style variant applied to all buttons within the group. */
11
+ variant?: "borderless" | "filled" | "outlined";
12
+ /** Color applied to all buttons within the group. */
13
+ color?: "primary" | "secondary" | "tertiary" | "warning" | "danger";
14
+ /** Disables all buttons within the button group. */
15
+ disabled?: boolean;
16
+ /** Orientation of the button group: horizontal or vertical. */
17
+ orientation?: "horizontal" | "vertical";
18
+ /** Selection behavior - default (no selection), single (radio-like), or multiple (checkbox-like). */
19
+ selectionType?: "default" | "single" | "multiple";
20
+ /** Callback when any button in the group is clicked. */
21
+ onButtonGroupClick?: (
22
+ event: CustomEvent<{ button: HTMLElement; isSelected: boolean }>,
23
+ ) => void;
24
+ /** Callback when button selection changes. */
25
+ onButtonSelectionChange?: (
26
+ event: CustomEvent<{ selectedButtons: HTMLElement[] }>,
27
+ ) => void;
28
+ /** A custom CSS class to apply to the button group. */
29
+ customClass?: string;
30
+ /** The ARIA label for the button group. */
31
+ ariaLabel?: string;
32
+ }
33
+
34
+ /**
35
+ * Renders a Modus button group component that groups multiple buttons together.
36
+ *
37
+ * @example
38
+ * // Basic horizontal button group
39
+ * <ModusButtonGroup variant="outlined" color="primary">
40
+ * <ModusButton>Button 1</ModusButton>
41
+ * <ModusButton>Button 2</ModusButton>
42
+ * <ModusButton>Button 3</ModusButton>
43
+ * </ModusButtonGroup>
44
+ *
45
+ * @example
46
+ * // Single selection (radio-like behavior)
47
+ * <ModusButtonGroup selectionType="single" variant="outlined">
48
+ * <ModusButton>Option 1</ModusButton>
49
+ * <ModusButton pressed>Option 2</ModusButton>
50
+ * <ModusButton>Option 3</ModusButton>
51
+ * </ModusButtonGroup>
52
+ *
53
+ * @example
54
+ * // Multiple selection (checkbox-like behavior)
55
+ * <ModusButtonGroup selectionType="multiple" variant="outlined">
56
+ * <ModusButton pressed>Bold</ModusButton>
57
+ * <ModusButton>Italic</ModusButton>
58
+ * <ModusButton pressed>Underline</ModusButton>
59
+ * </ModusButtonGroup>
60
+ *
61
+ * @param {ModusButtonGroupProps} props - The component props.
62
+ * @returns {JSX.Element} The rendered button group component.
63
+ */
64
+ export default function ModusButtonGroup({
65
+ children,
66
+ variant = "outlined",
67
+ color,
68
+ disabled = false,
69
+ orientation = "horizontal",
70
+ selectionType = "default",
71
+ onButtonGroupClick,
72
+ onButtonSelectionChange,
73
+ customClass,
74
+ ariaLabel,
75
+ }: ModusButtonGroupProps) {
76
+ return (
77
+ <ModusWcButtonGroup
78
+ variant={variant}
79
+ color={color}
80
+ disabled={disabled}
81
+ orientation={orientation}
82
+ selection-type={selectionType}
83
+ onButtonGroupClick={onButtonGroupClick}
84
+ onButtonSelectionChange={onButtonSelectionChange}
85
+ custom-class={customClass}
86
+ aria-label={ariaLabel}
87
+ >
88
+ {children}
89
+ </ModusWcButtonGroup>
90
+ );
91
+ }
@@ -0,0 +1,70 @@
1
+ import type { ReactNode } from "react";
2
+ import { ModusWcCard } from "@trimble-oss/moduswebcomponents-react";
3
+
4
+ /**
5
+ * Props for the ModusCard component.
6
+ */
7
+ export interface ModusCardProps {
8
+ /** The main content of the card. */
9
+ children?: ReactNode;
10
+ /** Whether to show a background figure. */
11
+ backgroundFigure?: boolean;
12
+ /** Whether the card has a border. */
13
+ bordered?: boolean;
14
+ /** The layout of the card. */
15
+ layout?: 'vertical' | 'horizontal';
16
+ /** The padding of the card. */
17
+ padding?: 'compact' | 'comfortable';
18
+ /** A custom CSS class to apply to the card. */
19
+ customClass?: string;
20
+ /** The ARIA label for the card. */
21
+ 'aria-label'?: string;
22
+ /** The header content of the card. */
23
+ header?: ReactNode;
24
+ /** The title content of the card. */
25
+ title?: ReactNode;
26
+ /** The subtitle content of the card. */
27
+ subtitle?: ReactNode;
28
+ /** The actions content of the card. */
29
+ actions?: ReactNode;
30
+ /** The footer content of the card. */
31
+ footer?: ReactNode;
32
+ }
33
+
34
+ /**
35
+ * Renders a Modus card component.
36
+ * @param {ModusCardProps} props - The component props.
37
+ * @returns {JSX.Element} The rendered card component.
38
+ */
39
+ export default function ModusCard({
40
+ children,
41
+ backgroundFigure = false,
42
+ bordered = false,
43
+ layout = 'vertical',
44
+ padding = 'comfortable',
45
+ customClass,
46
+ 'aria-label': ariaLabel,
47
+ header,
48
+ title,
49
+ subtitle,
50
+ actions,
51
+ footer,
52
+ }: ModusCardProps) {
53
+ return (
54
+ <ModusWcCard
55
+ backgroundFigure={backgroundFigure}
56
+ bordered={bordered}
57
+ layout={layout}
58
+ padding={padding}
59
+ customClass={customClass}
60
+ aria-label={ariaLabel}
61
+ >
62
+ {header && <div slot="header">{header}</div>}
63
+ {title && <div slot="title">{title}</div>}
64
+ {subtitle && <div slot="subtitle">{subtitle}</div>}
65
+ {children}
66
+ {actions && <div slot="actions">{actions}</div>}
67
+ {footer && <div slot="footer">{footer}</div>}
68
+ </ModusWcCard>
69
+ );
70
+ }
@@ -0,0 +1,168 @@
1
+ import { useEffect, useRef } from "react";
2
+ import { ModusWcCheckbox } from "@trimble-oss/moduswebcomponents-react";
3
+
4
+ /**
5
+ * Props for the ModusCheckbox component.
6
+ */
7
+ export interface ModusCheckboxProps {
8
+ /** The value of the checkbox. */
9
+ value?: boolean;
10
+ /** Whether the checkbox is disabled. */
11
+ disabled?: boolean;
12
+ /** Whether the checkbox is in an indeterminate state. */
13
+ indeterminate?: boolean;
14
+ /** The label for the checkbox. */
15
+ label?: string;
16
+ /** The name of the checkbox. */
17
+ name?: string;
18
+ /** Whether the checkbox is required. */
19
+ required?: boolean;
20
+ /** The size of the checkbox. */
21
+ size?: "sm" | "md" | "lg";
22
+ /** The ID of the input element. */
23
+ inputId?: string;
24
+ /** The tab index of the input element. */
25
+ inputTabIndex?: number;
26
+ /** A custom CSS class to apply to the checkbox. */
27
+ customClass?: string;
28
+ /** The ARIA label for the checkbox. */
29
+ "aria-label"?: string;
30
+ /** A callback function to handle input changes. */
31
+ onInputChange?: (event: CustomEvent<InputEvent>) => void;
32
+ /** A callback function to handle input focus. */
33
+ onInputFocus?: (event: CustomEvent<FocusEvent>) => void;
34
+ /** A callback function to handle input blur. */
35
+ onInputBlur?: (event: CustomEvent<FocusEvent>) => void;
36
+ /** A callback function to handle value changes. */
37
+ onValueChange?: (event: CustomEvent<boolean>) => void;
38
+ }
39
+
40
+ /**
41
+ * Renders a Modus checkbox component with critical bug workaround.
42
+ *
43
+ * ⚠️ IMPORTANT: This component includes a workaround for a critical value inversion bug
44
+ * in the underlying ModusWcCheckbox web component. The value property returns the
45
+ * opposite of the actual checked state, which is automatically corrected.
46
+ *
47
+ * @example
48
+ * // Basic checkbox
49
+ * <ModusCheckbox label="Accept terms" />
50
+ *
51
+ * @example
52
+ * // Controlled checkbox with value change handler
53
+ * <ModusCheckbox
54
+ * label="Subscribe to newsletter"
55
+ * value={isSubscribed}
56
+ * onValueChange={(event) => setSubscribed(event.detail)}
57
+ * />
58
+ *
59
+ * @example
60
+ * // Indeterminate checkbox
61
+ * <ModusCheckbox
62
+ * label="Select all"
63
+ * indeterminate={true}
64
+ * onValueChange={handleSelectAll}
65
+ * />
66
+ *
67
+ * @param {ModusCheckboxProps} props - The component props.
68
+ * @returns {JSX.Element} The rendered checkbox component.
69
+ * @see {@link https://modus.trimble.com/components/checkbox} - Modus Checkbox documentation
70
+ * @see {@link https://github.com/trimble-oss/modus-web-components/issues} - Known issues
71
+ */
72
+ export default function ModusCheckbox({
73
+ value = false,
74
+ disabled = false,
75
+ indeterminate = false,
76
+ label,
77
+ name = "",
78
+ required = false,
79
+ size = "md",
80
+ inputId,
81
+ inputTabIndex,
82
+ customClass,
83
+ "aria-label": ariaLabel,
84
+ onInputChange,
85
+ onInputFocus,
86
+ onInputBlur,
87
+ onValueChange,
88
+ }: ModusCheckboxProps) {
89
+ const checkboxRef = useRef<HTMLModusWcCheckboxElement>(null);
90
+
91
+ useEffect(() => {
92
+ const checkbox = checkboxRef.current;
93
+ if (!checkbox) return;
94
+
95
+ const handleInputChange = (event: Event) => {
96
+ onInputChange?.(event as CustomEvent<InputEvent>);
97
+ };
98
+ const handleInputFocus = (event: Event) => {
99
+ onInputFocus?.(event as CustomEvent<FocusEvent>);
100
+ };
101
+ const handleInputBlur = (event: Event) => {
102
+ onInputBlur?.(event as CustomEvent<FocusEvent>);
103
+ };
104
+ /**
105
+ * Handles value change events with critical bug fix for value inversion.
106
+ *
107
+ * ⚠️ CRITICAL BUG WORKAROUND: The ModusWcCheckbox component has a value
108
+ * inversion bug where the `value` property returns the opposite of the
109
+ * actual checked state. This function corrects this by inverting the
110
+ * raw value before passing it to the parent component.
111
+ *
112
+ * @param {Event} event - The input change event from the web component
113
+ * @private
114
+ * @see {@link https://github.com/trimble-oss/modus-web-components/issues} - Modus Web Components issue tracker
115
+ */
116
+ const handleValueChange = (event: Event) => {
117
+ const customEvent = event as CustomEvent<InputEvent>;
118
+ // 🚨 CRITICAL: Handle the value inversion bug
119
+ // The value inversion bug is in the target.value, not the event detail
120
+ const rawValue = (customEvent.target as HTMLModusWcCheckboxElement).value;
121
+ const actualValue = !rawValue; // ✅ CORRECT: Invert the value
122
+
123
+ // Create a new event with the corrected value
124
+ const correctedEvent = new CustomEvent("valueChange", {
125
+ detail: actualValue,
126
+ bubbles: true,
127
+ cancelable: true,
128
+ });
129
+
130
+ onValueChange?.(correctedEvent);
131
+ };
132
+
133
+ if (onInputChange)
134
+ checkbox.addEventListener("inputChange", handleInputChange);
135
+ if (onInputFocus) checkbox.addEventListener("inputFocus", handleInputFocus);
136
+ if (onInputBlur) checkbox.addEventListener("inputBlur", handleInputBlur);
137
+ if (onValueChange)
138
+ checkbox.addEventListener("inputChange", handleValueChange);
139
+
140
+ return () => {
141
+ if (onInputChange)
142
+ checkbox.removeEventListener("inputChange", handleInputChange);
143
+ if (onInputFocus)
144
+ checkbox.removeEventListener("inputFocus", handleInputFocus);
145
+ if (onInputBlur)
146
+ checkbox.removeEventListener("inputBlur", handleInputBlur);
147
+ if (onValueChange)
148
+ checkbox.removeEventListener("inputChange", handleValueChange);
149
+ };
150
+ }, [onInputChange, onInputFocus, onInputBlur, onValueChange]);
151
+
152
+ return (
153
+ <ModusWcCheckbox
154
+ ref={checkboxRef}
155
+ value={value}
156
+ disabled={disabled}
157
+ indeterminate={indeterminate}
158
+ label={label}
159
+ name={name}
160
+ required={required}
161
+ size={size}
162
+ inputId={inputId}
163
+ inputTabIndex={inputTabIndex}
164
+ customClass={customClass}
165
+ aria-label={ariaLabel}
166
+ />
167
+ );
168
+ }