@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,93 @@
1
+ import { useEffect, useRef } from "react";
2
+ import type { ReactNode } from "react";
3
+ import { ModusWcChip } from "@trimble-oss/moduswebcomponents-react";
4
+
5
+ /**
6
+ * Props for the ModusChip component.
7
+ */
8
+ export interface ModusChipProps {
9
+ /** The content to display inside the chip. */
10
+ children?: ReactNode;
11
+ /** Whether the chip is active. */
12
+ active?: boolean;
13
+ /** Whether the chip is disabled. */
14
+ disabled?: boolean;
15
+ /** Whether the chip has an error. */
16
+ hasError?: boolean;
17
+ /** The label for the chip. */
18
+ label?: string;
19
+ /** Whether to show the remove button. */
20
+ showRemove?: boolean;
21
+ /** The size of the chip. */
22
+ size?: 'sm' | 'md' | 'lg';
23
+ /** The variant of the chip. */
24
+ variant?: 'filled' | 'outline';
25
+ /** A custom CSS class to apply to the chip. */
26
+ customClass?: string;
27
+ /** The ARIA label for the chip. */
28
+ 'aria-label'?: string;
29
+ /** A callback function to handle chip clicks. */
30
+ onChipClick?: (event: CustomEvent<MouseEvent | KeyboardEvent>) => void;
31
+ /** A callback function to handle chip removal. */
32
+ onChipRemove?: (event: CustomEvent<MouseEvent | KeyboardEvent>) => void;
33
+ }
34
+
35
+ /**
36
+ * Renders a Modus chip component.
37
+ * @param {ModusChipProps} props - The component props.
38
+ * @returns {JSX.Element} The rendered chip component.
39
+ */
40
+ export default function ModusChip({
41
+ children,
42
+ active = false,
43
+ disabled = false,
44
+ hasError = false,
45
+ label = '',
46
+ showRemove = false,
47
+ size = 'md',
48
+ variant = 'filled',
49
+ customClass,
50
+ 'aria-label': ariaLabel,
51
+ onChipClick,
52
+ onChipRemove,
53
+ }: ModusChipProps) {
54
+ const chipRef = useRef<HTMLModusWcChipElement>(null);
55
+
56
+ useEffect(() => {
57
+ const chip = chipRef.current;
58
+ if (!chip) return;
59
+
60
+ const handleChipClick = (event: Event) => {
61
+ onChipClick?.(event as CustomEvent<MouseEvent | KeyboardEvent>);
62
+ };
63
+ const handleChipRemove = (event: Event) => {
64
+ onChipRemove?.(event as CustomEvent<MouseEvent | KeyboardEvent>);
65
+ };
66
+
67
+ if (onChipClick) chip.addEventListener("chipClick", handleChipClick);
68
+ if (onChipRemove) chip.addEventListener("chipRemove", handleChipRemove);
69
+
70
+ return () => {
71
+ if (onChipClick) chip.removeEventListener("chipClick", handleChipClick);
72
+ if (onChipRemove)
73
+ chip.removeEventListener("chipRemove", handleChipRemove);
74
+ };
75
+ }, [onChipClick, onChipRemove]);
76
+
77
+ return (
78
+ <ModusWcChip
79
+ ref={chipRef}
80
+ active={active}
81
+ disabled={disabled}
82
+ hasError={hasError}
83
+ label={label}
84
+ showRemove={showRemove}
85
+ size={size}
86
+ variant={variant}
87
+ customClass={customClass}
88
+ aria-label={ariaLabel}
89
+ >
90
+ {children}
91
+ </ModusWcChip>
92
+ );
93
+ }
@@ -0,0 +1,154 @@
1
+ import { useEffect, useRef } from "react";
2
+ import { ModusWcDate } from "@trimble-oss/moduswebcomponents-react";
3
+
4
+ /**
5
+ * Represents feedback for an input component.
6
+ */
7
+ export interface InputFeedbackProp {
8
+ /** The severity level of the feedback. */
9
+ level: "error" | "info" | "success" | "warning";
10
+ /** The message to display as feedback. */
11
+ message?: string;
12
+ }
13
+
14
+ /** Date format options. */
15
+ export type DateFormat =
16
+ | "yyyy-mm-dd"
17
+ | "dd-mm-yyyy"
18
+ | "yyyy/mm/dd"
19
+ | "dd/mm/yyyy"
20
+ | "MMM DD, YYYY";
21
+
22
+ /** Week start day options. */
23
+ export type WeekStartDay = "sunday" | "monday";
24
+
25
+ /**
26
+ * Props for the ModusDate component.
27
+ */
28
+ export interface ModusDateProps {
29
+ /** The value of the date input (Format: YYYY-MM-DD). */
30
+ value?: string;
31
+ /** Whether the date input has a border. */
32
+ bordered?: boolean;
33
+ /** Whether the date input is disabled. */
34
+ disabled?: boolean;
35
+ /** Feedback to display for the date input. */
36
+ feedback?: InputFeedbackProp;
37
+ /** Date format pattern. */
38
+ format?: DateFormat;
39
+ /** The ID of the input element. */
40
+ inputId?: string;
41
+ /** The tab index of the input element. */
42
+ inputTabIndex?: number;
43
+ /** The label for the date input. */
44
+ label?: string;
45
+ /** The maximum allowed date (Format: YYYY-MM-DD). */
46
+ max?: string;
47
+ /** The minimum allowed date (Format: YYYY-MM-DD). */
48
+ min?: string;
49
+ /** The name of the input element. */
50
+ name?: string;
51
+ /** Whether the date input is read-only. */
52
+ readOnly?: boolean;
53
+ /** Whether the date input is required. */
54
+ required?: boolean;
55
+ /** The size of the date input. */
56
+ size?: "sm" | "md" | "lg";
57
+ /** First day of the week for the calendar view. */
58
+ weekStartDay?: WeekStartDay;
59
+ /** A custom CSS class to apply to the date input. */
60
+ customClass?: string;
61
+ /** The ARIA label for the date input. */
62
+ "aria-label"?: string;
63
+ /** A callback function to handle input changes. */
64
+ onInputChange?: (event: CustomEvent<InputEvent>) => void;
65
+ /** A callback function to handle input focus. */
66
+ onInputFocus?: (event: CustomEvent<FocusEvent>) => void;
67
+ /** A callback function to handle input blur. */
68
+ onInputBlur?: (event: CustomEvent<FocusEvent>) => void;
69
+ }
70
+
71
+ /**
72
+ * Renders a Modus date input component.
73
+ * @param {ModusDateProps} props - The component props.
74
+ * @returns {JSX.Element} The rendered date input component.
75
+ */
76
+ export default function ModusDate({
77
+ value = "",
78
+ bordered = true,
79
+ disabled = false,
80
+ feedback,
81
+ format,
82
+ inputId,
83
+ inputTabIndex,
84
+ label,
85
+ max,
86
+ min,
87
+ name = "",
88
+ readOnly = false,
89
+ required = false,
90
+ size = "md",
91
+ weekStartDay,
92
+ customClass,
93
+ "aria-label": ariaLabel,
94
+ onInputChange,
95
+ onInputFocus,
96
+ onInputBlur,
97
+ }: ModusDateProps) {
98
+ const dateRef = useRef<HTMLModusWcDateElement>(null);
99
+
100
+ useEffect(() => {
101
+ const date = dateRef.current;
102
+ if (!date) return;
103
+
104
+ const handleInputChange = (event: Event) => {
105
+ onInputChange?.(event as CustomEvent<InputEvent>);
106
+ };
107
+ const handleInputFocus = (event: Event) => {
108
+ onInputFocus?.(event as CustomEvent<FocusEvent>);
109
+ };
110
+ const handleInputBlur = (event: Event) => {
111
+ onInputBlur?.(event as CustomEvent<FocusEvent>);
112
+ };
113
+
114
+ if (onInputChange) date.addEventListener("inputChange", handleInputChange);
115
+ if (onInputFocus) date.addEventListener("inputFocus", handleInputFocus);
116
+ if (onInputBlur) date.addEventListener("inputBlur", handleInputBlur);
117
+
118
+ return () => {
119
+ if (onInputChange)
120
+ date.removeEventListener("inputChange", handleInputChange);
121
+ if (onInputFocus)
122
+ date.removeEventListener("inputFocus", handleInputFocus);
123
+ if (onInputBlur) date.removeEventListener("inputBlur", handleInputBlur);
124
+ };
125
+ }, [onInputChange, onInputFocus, onInputBlur]);
126
+
127
+ // Note: format and weekStartDay are passed as attributes since they may not be
128
+ // exposed as typed props in the React bindings but are supported by the web component
129
+ const additionalProps: Record<string, unknown> = {};
130
+ if (format) additionalProps.format = format;
131
+ if (weekStartDay) additionalProps.weekStartDay = weekStartDay;
132
+
133
+ return (
134
+ <ModusWcDate
135
+ ref={dateRef}
136
+ value={value}
137
+ bordered={bordered}
138
+ disabled={disabled}
139
+ feedback={feedback}
140
+ inputId={inputId}
141
+ inputTabIndex={inputTabIndex}
142
+ label={label}
143
+ max={max}
144
+ min={min}
145
+ name={name}
146
+ readOnly={readOnly}
147
+ required={required}
148
+ size={size}
149
+ customClass={customClass}
150
+ aria-label={ariaLabel}
151
+ {...additionalProps}
152
+ />
153
+ );
154
+ }
@@ -0,0 +1,148 @@
1
+ import { useEffect, useRef } from "react";
2
+ import type { ReactNode } from "react";
3
+ import { ModusWcDropdownMenu } from "@trimble-oss/moduswebcomponents-react";
4
+ import ModusMenuItem from "./ModusMenuItem";
5
+ import type { MenuItem } from "./ModusMenu";
6
+
7
+ /**
8
+ * Props for the ModusDropdownMenu component.
9
+ */
10
+ export interface ModusDropdownMenuProps {
11
+ /** The content to display inside the dropdown menu. */
12
+ children?: ReactNode;
13
+ /** The items to display in the dropdown menu. */
14
+ menuItems?: MenuItem[];
15
+ /** The color of the dropdown button. */
16
+ buttonColor?: 'primary' | 'secondary' | 'tertiary' | 'warning' | 'danger';
17
+ /** The size of the dropdown button. */
18
+ buttonSize?: 'xs' | 'sm' | 'md' | 'lg';
19
+ /** The variant of the dropdown button. */
20
+ buttonVariant?: 'filled' | 'outlined' | 'borderless';
21
+ /** A custom CSS class to apply to the dropdown menu. */
22
+ customClass?: string;
23
+ /** Whether the dropdown menu is disabled. */
24
+ disabled?: boolean;
25
+ /** Whether the dropdown menu has a border. */
26
+ menuBordered?: boolean;
27
+ /** The offset of the dropdown menu from the button. */
28
+ menuOffset?: number;
29
+ /** The placement of the dropdown menu. */
30
+ menuPlacement?:
31
+ | 'top'
32
+ | 'top-start'
33
+ | 'top-end'
34
+ | 'bottom'
35
+ | 'bottom-start'
36
+ | 'bottom-end'
37
+ | 'left'
38
+ | 'left-start'
39
+ | 'left-end'
40
+ | 'right'
41
+ | 'right-start'
42
+ | 'right-end';
43
+ /** The size of the dropdown menu. */
44
+ menuSize?: 'sm' | 'md' | 'lg';
45
+ /** Whether the dropdown menu is visible. */
46
+ menuVisible?: boolean;
47
+ /** The content to display inside the dropdown button. */
48
+ buttonContent?: ReactNode;
49
+ /** A callback function to handle menu visibility changes. */
50
+ onMenuVisibilityChange?: (event: CustomEvent<{ isVisible: boolean }>) => void;
51
+ /** A callback function to handle item selection. */
52
+ onItemSelect?: (event: CustomEvent<{ value: string }>) => void;
53
+ }
54
+
55
+ /**
56
+ * Renders a Modus dropdown menu component.
57
+ * @param {ModusDropdownMenuProps} props - The component props.
58
+ * @returns {JSX.Element} The rendered dropdown menu component.
59
+ */
60
+ export default function ModusDropdownMenu({
61
+ children,
62
+ menuItems,
63
+ buttonColor = 'primary',
64
+ buttonSize = 'md',
65
+ buttonVariant = 'filled',
66
+ customClass,
67
+ disabled = false,
68
+ menuBordered = true,
69
+ menuOffset = 10,
70
+ menuPlacement = 'bottom-start',
71
+ menuSize = 'md',
72
+ menuVisible = false,
73
+ buttonContent,
74
+ onMenuVisibilityChange,
75
+ onItemSelect,
76
+ }: ModusDropdownMenuProps) {
77
+ const dropdownRef = useRef<HTMLModusWcDropdownMenuElement>(null);
78
+
79
+ useEffect(() => {
80
+ const dropdown = dropdownRef.current;
81
+ if (!dropdown) return;
82
+
83
+ const handleMenuVisibilityChange = (event: Event) => {
84
+ onMenuVisibilityChange?.(event as CustomEvent<{ isVisible: boolean }>);
85
+ };
86
+ const handleItemSelect = (event: Event) => {
87
+ onItemSelect?.(event as CustomEvent<{ value: string }>);
88
+
89
+ // Close the menu after item selection
90
+ const dropdown = dropdownRef.current;
91
+ if (dropdown) {
92
+ dropdown.menuVisible = false;
93
+ }
94
+ };
95
+
96
+ if (onMenuVisibilityChange)
97
+ dropdown.addEventListener(
98
+ "menuVisibilityChange",
99
+ handleMenuVisibilityChange
100
+ );
101
+ if (onItemSelect) dropdown.addEventListener("itemSelect", handleItemSelect);
102
+
103
+ return () => {
104
+ if (onMenuVisibilityChange)
105
+ dropdown.removeEventListener(
106
+ "menuVisibilityChange",
107
+ handleMenuVisibilityChange
108
+ );
109
+ if (onItemSelect)
110
+ dropdown.removeEventListener("itemSelect", handleItemSelect);
111
+ };
112
+ }, [onMenuVisibilityChange, onItemSelect]);
113
+
114
+ return (
115
+ <ModusWcDropdownMenu
116
+ ref={dropdownRef}
117
+ buttonColor={buttonColor}
118
+ buttonSize={buttonSize}
119
+ buttonVariant={buttonVariant}
120
+ customClass={customClass}
121
+ disabled={disabled}
122
+ menuBordered={menuBordered}
123
+ menuOffset={menuOffset}
124
+ menuPlacement={menuPlacement}
125
+ menuSize={menuSize}
126
+ menuVisible={menuVisible}
127
+ >
128
+ {buttonContent && <div slot="button">{buttonContent}</div>}
129
+ <div slot="menu">
130
+ {menuItems
131
+ ? menuItems.map((item) => (
132
+ <ModusMenuItem
133
+ key={item.value}
134
+ label={item.label}
135
+ value={item.value}
136
+ subLabel={item.subLabel}
137
+ startIcon={item.startIcon}
138
+ selected={item.selected}
139
+ disabled={item.disabled}
140
+ bordered={item.bordered}
141
+ onItemSelect={onItemSelect}
142
+ />
143
+ ))
144
+ : children}
145
+ </div>
146
+ </ModusWcDropdownMenu>
147
+ );
148
+ }
@@ -0,0 +1,140 @@
1
+ import { ModusWcFileDropzone } from "@trimble-oss/moduswebcomponents-react";
2
+ import { forwardRef, useImperativeHandle, useRef } from "react";
3
+ import type { ReactNode } from "react";
4
+
5
+ /**
6
+ * Props for the ModusFileDropzone component.
7
+ */
8
+ export interface ModusFileDropzoneProps {
9
+ /** Accepted file types (e.g., '.jpg,.png' or 'image/*'). */
10
+ acceptFileTypes?: string;
11
+ /** Custom CSS class to apply to the dropzone element. */
12
+ customClass?: string;
13
+ /** Disables the file input and dropzone interaction. */
14
+ disabled?: boolean;
15
+ /** Custom instructions shown when files are dragged over the dropzone. */
16
+ fileDraggedOverInstructions?: string;
17
+ /** Show state icon (upload, success, error) in the dropzone. */
18
+ includeStateIcon?: boolean;
19
+ /** Custom instructions shown as the default dropzone message. */
20
+ instructions?: string;
21
+ /** Custom error message when an invalid file type is selected. */
22
+ invalidFileTypeMessage?: string;
23
+ /** Maximum number of files allowed; shows error if exceeded. */
24
+ maxFileCount?: number;
25
+ /** Maximum allowed length of filename (excluding extension); shows error if exceeded. */
26
+ maxFileNameLength?: number;
27
+ /** Maximum total file size in bytes; shows error if exceeded. */
28
+ maxTotalFileSizeBytes?: number;
29
+ /** Allow multiple file selection. */
30
+ multiple?: boolean;
31
+ /** Success message displayed when files are uploaded successfully. */
32
+ successMessage?: string;
33
+ /** Callback when files are selected (via drag-and-drop or file browser). */
34
+ onFileSelect?: (event: CustomEvent<FileList>) => void;
35
+ /** The ARIA label for the dropzone. */
36
+ ariaLabel?: string;
37
+ /** Custom content slot for progress indicators or additional instructions. */
38
+ children?: ReactNode;
39
+ }
40
+
41
+ /**
42
+ * Handle interface for ModusFileDropzone ref methods.
43
+ */
44
+ export interface ModusFileDropzoneHandle {
45
+ /** Resets the dropzone to its initial state, clearing all error and success states. */
46
+ reset: () => Promise<void>;
47
+ }
48
+
49
+ /**
50
+ * Renders a Modus file dropzone component for drag-and-drop file uploads.
51
+ *
52
+ * @example
53
+ * // Basic file dropzone
54
+ * <ModusFileDropzone
55
+ * acceptFileTypes=".doc, .docx, .pdf"
56
+ * instructions="Drag files here or browse to upload"
57
+ * />
58
+ *
59
+ * @example
60
+ * // Multiple files with validation
61
+ * <ModusFileDropzone
62
+ * acceptFileTypes="image/*"
63
+ * multiple
64
+ * maxFileCount={3}
65
+ * maxTotalFileSizeBytes={10485760}
66
+ * instructions="Upload images (max 3 files, 10MB total)"
67
+ * onFileSelect={(e) => console.log('Files:', e.detail)}
68
+ * />
69
+ *
70
+ * @example
71
+ * // With ref for programmatic reset
72
+ * const dropzoneRef = useRef<ModusFileDropzoneHandle>(null);
73
+ * <ModusFileDropzone ref={dropzoneRef} />
74
+ * // Later: dropzoneRef.current?.reset();
75
+ *
76
+ * @param {ModusFileDropzoneProps} props - The component props.
77
+ * @param {React.Ref<ModusFileDropzoneHandle>} ref - The ref for accessing reset method.
78
+ * @returns {JSX.Element} The rendered file dropzone component.
79
+ */
80
+ const ModusFileDropzone = forwardRef<
81
+ ModusFileDropzoneHandle,
82
+ ModusFileDropzoneProps
83
+ >(
84
+ (
85
+ {
86
+ acceptFileTypes,
87
+ customClass,
88
+ disabled,
89
+ fileDraggedOverInstructions,
90
+ includeStateIcon = true,
91
+ instructions,
92
+ invalidFileTypeMessage,
93
+ maxFileCount,
94
+ maxFileNameLength,
95
+ maxTotalFileSizeBytes,
96
+ multiple,
97
+ successMessage,
98
+ onFileSelect,
99
+ ariaLabel,
100
+ children,
101
+ },
102
+ ref,
103
+ ) => {
104
+ const dropzoneRef = useRef<HTMLModusWcFileDropzoneElement>(null);
105
+
106
+ useImperativeHandle(ref, () => ({
107
+ reset: async () => {
108
+ if (dropzoneRef.current) {
109
+ await dropzoneRef.current.reset();
110
+ }
111
+ },
112
+ }));
113
+
114
+ return (
115
+ <ModusWcFileDropzone
116
+ ref={dropzoneRef}
117
+ accept-file-types={acceptFileTypes}
118
+ custom-class={customClass}
119
+ disabled={disabled}
120
+ file-dragged-over-instructions={fileDraggedOverInstructions}
121
+ include-state-icon={includeStateIcon}
122
+ instructions={instructions}
123
+ invalid-file-type-message={invalidFileTypeMessage}
124
+ max-file-count={maxFileCount}
125
+ max-file-name-length={maxFileNameLength}
126
+ max-total-file-size-bytes={maxTotalFileSizeBytes}
127
+ multiple={multiple}
128
+ success-message={successMessage}
129
+ onFileSelect={onFileSelect}
130
+ aria-label={ariaLabel}
131
+ >
132
+ {children && <div slot="dropzone">{children}</div>}
133
+ </ModusWcFileDropzone>
134
+ );
135
+ },
136
+ );
137
+
138
+ ModusFileDropzone.displayName = "ModusFileDropzone";
139
+
140
+ export default ModusFileDropzone;
@@ -0,0 +1,101 @@
1
+ import { ModusWcHandle } from "@trimble-oss/moduswebcomponents-react";
2
+
3
+ /**
4
+ * Props for the ModusHandle component.
5
+ */
6
+ export interface ModusHandleProps {
7
+ /** Custom CSS class to apply to the handle element. */
8
+ customClass?: string;
9
+ /** Initial split percentage (1-100) for the left/top panel. */
10
+ defaultSplit?: number;
11
+ /** Spacing/density of the handle container. */
12
+ density?: "compact" | "comfortable" | "relaxed";
13
+ /** CSS selector or HTMLElement reference for the left/top panel to resize. */
14
+ leftTarget?: string;
15
+ /** Orientation of the handle (horizontal resizes left/right, vertical resizes top/bottom). */
16
+ orientation?: "horizontal" | "vertical";
17
+ /** CSS selector or HTMLElement reference for the right/bottom panel to resize. */
18
+ rightTarget?: string;
19
+ /** Size of the handle bar. */
20
+ size?: "default" | "lg" | "xl" | "2xl";
21
+ /** Type of handle to display - simple bar or button with drag icon. */
22
+ type?: "bar" | "button";
23
+ /** Color of the button (only applies when type="button"). */
24
+ buttonColor?: "primary" | "secondary" | "tertiary" | "warning" | "danger";
25
+ /** Size of the button (only applies when type="button"). */
26
+ buttonSize?: "xs" | "sm" | "md" | "lg";
27
+ /** Variant of the button (only applies when type="button"). */
28
+ buttonVariant?: "borderless" | "filled" | "outlined";
29
+ /** The ARIA label for the handle. */
30
+ ariaLabel?: string;
31
+ }
32
+
33
+ /**
34
+ * Renders a Modus handle component for resizing adjacent elements.
35
+ *
36
+ * @example
37
+ * // Basic horizontal handle
38
+ * <div className="flex h-[300px]">
39
+ * <div id="left-panel" className="w-[200px]">Left</div>
40
+ * <ModusHandle
41
+ * orientation="horizontal"
42
+ * leftTarget="#left-panel"
43
+ * rightTarget="#right-panel"
44
+ * />
45
+ * <div id="right-panel" className="flex-1">Right</div>
46
+ * </div>
47
+ *
48
+ * @example
49
+ * // Button type handle
50
+ * <ModusHandle
51
+ * type="button"
52
+ * orientation="horizontal"
53
+ * buttonColor="primary"
54
+ * buttonVariant="outlined"
55
+ * leftTarget="#panel-a"
56
+ * rightTarget="#panel-b"
57
+ * />
58
+ *
59
+ * @example
60
+ * // With custom split percentage
61
+ * <ModusHandle
62
+ * orientation="horizontal"
63
+ * defaultSplit={30}
64
+ * leftTarget="#left"
65
+ * rightTarget="#right"
66
+ * />
67
+ *
68
+ * @param {ModusHandleProps} props - The component props.
69
+ * @returns {JSX.Element} The rendered handle component.
70
+ */
71
+ export default function ModusHandle({
72
+ customClass,
73
+ defaultSplit = 50,
74
+ density = "comfortable",
75
+ leftTarget,
76
+ orientation = "horizontal",
77
+ rightTarget,
78
+ size = "default",
79
+ type = "bar",
80
+ buttonColor = "tertiary",
81
+ buttonSize = "md",
82
+ buttonVariant = "filled",
83
+ ariaLabel,
84
+ }: ModusHandleProps) {
85
+ return (
86
+ <ModusWcHandle
87
+ custom-class={customClass}
88
+ default-split={defaultSplit}
89
+ density={density}
90
+ left-target={leftTarget}
91
+ orientation={orientation}
92
+ right-target={rightTarget}
93
+ size={size}
94
+ type={type}
95
+ button-color={buttonColor}
96
+ button-size={buttonSize}
97
+ button-variant={buttonVariant}
98
+ aria-label={ariaLabel}
99
+ />
100
+ );
101
+ }
@@ -0,0 +1,49 @@
1
+
2
+
3
+ import { ModusWcIcon } from "@trimble-oss/moduswebcomponents-react";
4
+
5
+ /**
6
+ * Props for the ModusIcon component.
7
+ */
8
+ interface ModusIconProps {
9
+ /** The name of the icon to display. */
10
+ name: string;
11
+ /** The size of the icon. */
12
+ size?: 'xs' | 'sm' | 'md' | 'lg';
13
+ /** Whether the icon is decorative. */
14
+ decorative?: boolean;
15
+ /** A custom CSS class to apply to the icon. */
16
+ customClass?: string;
17
+ /** The ARIA label for the icon. */
18
+ ariaLabel?: string;
19
+ /** The color of the icon. */
20
+ color?: string;
21
+ }
22
+
23
+ /**
24
+ * Renders a Modus icon component.
25
+ * @param {ModusIconProps} props - The component props.
26
+ * @returns {JSX.Element} The rendered icon component.
27
+ */
28
+ export default function ModusIcon({
29
+ name,
30
+ size = 'md',
31
+ decorative = true,
32
+ customClass = '',
33
+ ariaLabel,
34
+ color,
35
+ }: ModusIconProps) {
36
+ // If decorative is false and no ariaLabel is provided, generate one
37
+ const finalAriaLabel = !decorative && !ariaLabel ? `${name} icon` : ariaLabel;
38
+
39
+ return (
40
+ <ModusWcIcon
41
+ name={name}
42
+ size={size}
43
+ decorative={decorative}
44
+ custom-class={customClass}
45
+ aria-label={finalAriaLabel}
46
+ style={color ? { color } : undefined}
47
+ />
48
+ );
49
+ }