@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,282 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Modus Color Linting Script for Angular + Tailwind v4
5
+ *
6
+ * This script checks for usage of non-Modus color patterns in Angular files,
7
+ * CSS files, and TypeScript files to ensure design system consistency.
8
+ *
9
+ * It flags common Tailwind color patterns and suggests Modus alternatives.
10
+ */
11
+
12
+ import fs from 'fs';
13
+ import path from 'path';
14
+ import { createRequire } from 'module';
15
+ const require = createRequire(import.meta.url);
16
+ const { glob } = require('glob');
17
+
18
+ // Common Tailwind color patterns to detect
19
+ const TAILWIND_COLOR_PATTERNS = [
20
+ // Tailwind color classes
21
+ /\b(red|blue|green|yellow|purple|pink|indigo|gray|slate|zinc|neutral|stone|orange|amber|lime|emerald|teal|cyan|sky|violet|fuchsia|rose)-(\d{2,3}|50)\b/g,
22
+
23
+ // Tailwind background colors
24
+ /\bbg-(red|blue|green|yellow|purple|pink|indigo|gray|slate|zinc|neutral|stone|orange|amber|lime|emerald|teal|cyan|sky|violet|fuchsia|rose)-(\d{2,3}|50)\b/g,
25
+
26
+ // Tailwind text colors
27
+ /\btext-(red|blue|green|yellow|purple|pink|indigo|gray|slate|zinc|neutral|stone|orange|amber|lime|emerald|teal|cyan|sky|violet|fuchsia|rose)-(\d{2,3}|50)\b/g,
28
+
29
+ // Tailwind border colors
30
+ /\bborder-(red|blue|green|yellow|purple|pink|indigo|gray|slate|zinc|neutral|stone|orange|amber|lime|emerald|teal|cyan|sky|violet|fuchsia|rose)-(\d{2,3}|50)\b/g,
31
+
32
+ // CSS hex colors (Modus-specific hex values that should be flagged)
33
+ /#(ff0000|00ff00|0000ff|ffff00|ff00ff|00ffff|ffffff|000000|fff|000|f1f1f6|252a2e|cbcdd6|464b52|b7b9c3|353a40|171c1e|0063a3|1e8a44|da212c|fbad26)\b/gi,
34
+
35
+ // CSS rgb/rgba colors (basic ones)
36
+ /rgb\(\s*(255,\s*0,\s*0|0,\s*255,\s*0|0,\s*0,\s*255|255,\s*255,\s*0|255,\s*0,\s*255|0,\s*255,\s*255|255,\s*255,\s*255|0,\s*0,\s*0)\s*\)/gi,
37
+
38
+ // CSS Variables (should use design system colors instead)
39
+ /var\(--modus-wc-color-[^)]*\)/g,
40
+ ];
41
+
42
+ // Design System Color Suggestions (from src/styles.css)
43
+ const DESIGN_SYSTEM_COLOR_SUGGESTIONS = {
44
+ // Background colors
45
+ red: 'bg-destructive', // Modus 2.0 standard
46
+ green: 'bg-success',
47
+ blue: 'bg-primary',
48
+ info: 'bg-primary',
49
+ yellow: 'bg-warning',
50
+ black: 'bg-background',
51
+ white: 'bg-background',
52
+ gray100: 'bg-card',
53
+ gray200: 'bg-muted',
54
+ gray300: 'bg-secondary',
55
+
56
+ // Text colors (only semantic design system colors allowed)
57
+ 'text-red': 'text-foreground', // Use primary text color instead of color-specific text
58
+ 'text-green': 'text-foreground', // Use primary text color instead of color-specific text
59
+ 'text-blue': 'text-foreground', // Use primary text color instead of color-specific text
60
+ 'text-yellow': 'text-foreground', // Use primary text color instead of color-specific text
61
+ 'text-black': 'text-foreground', // Primary text color
62
+ 'text-white': 'text-foreground', // Primary text color (theme-aware)
63
+ 'text-gray': 'text-muted-foreground', // Muted text color
64
+
65
+ // CSS Variables to Design System
66
+ 'var(--modus-wc-color-base-page)': 'bg-background',
67
+ 'var(--modus-wc-color-base-100)': 'bg-card',
68
+ 'var(--modus-wc-color-base-200)': 'bg-muted',
69
+ 'var(--modus-wc-color-base-300)': 'bg-secondary',
70
+ 'var(--modus-wc-color-base-content)': 'text-foreground',
71
+ 'var(--modus-wc-color-info)': 'bg-primary',
72
+ 'var(--modus-wc-color-success)': 'bg-success',
73
+ 'var(--modus-wc-color-error)': 'bg-destructive', // Modus 2.0 standard
74
+ 'var(--modus-wc-color-warning)': 'bg-warning',
75
+ };
76
+
77
+ // Files to check
78
+ const FILE_PATTERNS = ['src/**/*.ts', 'src/**/*.html', 'src/**/*.css', 'src/**/*.scss'];
79
+
80
+ // Files to exclude
81
+ const EXCLUDE_PATTERNS = [
82
+ 'node_modules/**',
83
+ 'dist/**',
84
+ 'build/**',
85
+ '**/*.d.ts',
86
+ 'src/styles.css', // Exclude styles.css as it contains the design system definitions
87
+ ];
88
+
89
+ async function checkFile(filePath) {
90
+ const content = fs.readFileSync(filePath, 'utf8');
91
+ const violations = [];
92
+
93
+ for (const pattern of TAILWIND_COLOR_PATTERNS) {
94
+ let match;
95
+ while ((match = pattern.exec(content)) !== null) {
96
+ const line = content.substring(0, match.index).split('\n').length;
97
+ const column = match.index - content.lastIndexOf('\n', match.index - 1);
98
+
99
+ // Get color suggestion based on context
100
+ const colorName = match[1] || extractColorFromHex(match[0]);
101
+ const isTextColor = match[0].startsWith('text-');
102
+ const isBorderColor = match[0].startsWith('border-');
103
+
104
+ let suggestion;
105
+ if (isTextColor) {
106
+ // For text colors, suggest semantic text colors
107
+ suggestion = getTextColorSuggestion(colorName);
108
+ } else if (isBorderColor) {
109
+ // For border colors, suggest border utilities
110
+ suggestion = getBorderColorSuggestion(colorName);
111
+ } else {
112
+ // For background colors, use existing mapping
113
+ suggestion = DESIGN_SYSTEM_COLOR_SUGGESTIONS[colorName] ||
114
+ DESIGN_SYSTEM_COLOR_SUGGESTIONS[match[0]] ||
115
+ 'bg-primary';
116
+ }
117
+
118
+ violations.push({
119
+ file: filePath,
120
+ line,
121
+ column,
122
+ match: match[0],
123
+ suggestion,
124
+ message: `Use design system color instead of "${match[0]}". Consider: ${suggestion}`,
125
+ });
126
+ }
127
+
128
+ // Reset regex lastIndex for next iteration
129
+ pattern.lastIndex = 0;
130
+ }
131
+
132
+ return violations;
133
+ }
134
+
135
+ function getTextColorSuggestion(colorName) {
136
+ // For text colors, suggest semantic color equivalents (using the color itself as text)
137
+ const textColorMap = {
138
+ red: 'text-destructive', // Red text → destructive color as text
139
+ green: 'text-success', // Green text → success color as text
140
+ blue: 'text-primary', // Blue text → primary color as text
141
+ info: 'text-primary', // Info text → primary color as text
142
+ yellow: 'text-warning', // Yellow text → warning color as text
143
+ black: 'text-foreground', // Black text → primary text
144
+ white: 'text-foreground', // White text → primary text (theme-aware)
145
+ gray: 'text-muted-foreground', // Gray text → muted text
146
+ gray100: 'text-card-foreground', // Light gray → card text
147
+ gray200: 'text-muted-foreground', // Medium gray → muted text
148
+ gray300: 'text-secondary-foreground', // Dark gray → secondary text
149
+ };
150
+ return textColorMap[colorName] || 'text-foreground';
151
+ }
152
+
153
+ function getBorderColorSuggestion(colorName) {
154
+ // For border colors, suggest border utilities
155
+ const borderColorMap = {
156
+ red: 'border-destructive',
157
+ green: 'border-success',
158
+ blue: 'border-primary',
159
+ yellow: 'border-warning',
160
+ black: 'border-default',
161
+ white: 'border-default',
162
+ gray: 'border-default',
163
+ };
164
+ return borderColorMap[colorName] || 'border-default';
165
+ }
166
+
167
+ function extractColorFromHex(hex) {
168
+ const colorMap = {
169
+ // Basic colors
170
+ '#ff0000': 'red',
171
+ '#00ff00': 'green',
172
+ '#0000ff': 'blue',
173
+ '#ffff00': 'yellow',
174
+ '#ffffff': 'white',
175
+ '#000000': 'black',
176
+
177
+ // Modus-specific hex values (these should be replaced with CSS variables)
178
+ '#fff': 'white', // Should use: bg-background
179
+ '#000': 'black', // Should use: bg-background [dark theme]
180
+ '#f1f1f6': 'gray100', // Should use: bg-card
181
+ '#252a2e': 'gray100', // Should use: bg-card [dark theme]
182
+ '#cbcdd6': 'gray200', // Should use: bg-muted
183
+ '#464b52': 'gray200', // Should use: bg-muted [dark theme]
184
+ '#b7b9c3': 'gray300', // Should use: bg-secondary
185
+ '#353a40': 'gray300', // Should use: bg-secondary [dark theme]
186
+ '#171c1e': 'black', // Should use: text-foreground
187
+ '#0063a3': 'blue', // Should use: bg-primary
188
+ '#1e8a44': 'green', // Should use: bg-success
189
+ '#da212c': 'red', // Should use: bg-destructive
190
+ '#fbad26': 'yellow', // Should use: bg-warning
191
+ };
192
+ return colorMap[hex.toLowerCase()] || 'info';
193
+ }
194
+
195
+ async function main() {
196
+ console.log('🎨 Checking for design system color compliance in Angular app...\n');
197
+
198
+ let allViolations = [];
199
+
200
+ try {
201
+ // Get all files to check
202
+ const allFiles = [];
203
+ for (const pattern of FILE_PATTERNS) {
204
+ const files = glob.sync(pattern, {
205
+ ignore: EXCLUDE_PATTERNS,
206
+ });
207
+ allFiles.push(...files.map(f => path.resolve(f)));
208
+ }
209
+ const files = [...new Set(allFiles)];
210
+
211
+ // Check each file
212
+ for (const file of files) {
213
+ try {
214
+ const violations = await checkFile(file);
215
+ allViolations = allViolations.concat(violations);
216
+ } catch (error) {
217
+ console.warn(`⚠️ Warning: Could not check file ${file}: ${error.message}`);
218
+ }
219
+ }
220
+
221
+ // Report results
222
+ if (allViolations.length === 0) {
223
+ console.log('✅ All files are using design system colors correctly!');
224
+ process.exit(0);
225
+ } else {
226
+ console.log(`❌ Found ${allViolations.length} color violations:\n`);
227
+
228
+ // Group violations by file
229
+ const violationsByFile = allViolations.reduce((acc, violation) => {
230
+ if (!acc[violation.file]) {
231
+ acc[violation.file] = [];
232
+ }
233
+ acc[violation.file].push(violation);
234
+ return acc;
235
+ }, {});
236
+
237
+ // Print violations
238
+ for (const [file, violations] of Object.entries(violationsByFile)) {
239
+ const relativePath = path.relative(process.cwd(), file);
240
+ console.log(`📄 ${relativePath}:`);
241
+
242
+ for (const violation of violations) {
243
+ console.log(` ${violation.line}:${violation.column} - ${violation.message}`);
244
+ }
245
+ console.log();
246
+ }
247
+
248
+ console.log('💡 Design System Color Reference (from src/styles.css):');
249
+ console.log(' Use Tailwind classes with design system colors:');
250
+ console.log(
251
+ ' ✅ Background: bg-background, bg-card, bg-muted, bg-secondary, bg-primary, bg-success, bg-destructive, bg-warning'
252
+ );
253
+ console.log(
254
+ ' ✅ Text: text-foreground, text-muted-foreground, text-card-foreground, text-secondary-foreground'
255
+ );
256
+ console.log(
257
+ ' ✅ Colored text: text-primary, text-success, text-destructive, text-warning'
258
+ );
259
+ console.log(
260
+ ' ✅ Text on colored backgrounds: text-primary-foreground, text-success-foreground, text-destructive-foreground, text-warning-foreground'
261
+ );
262
+ console.log(
263
+ ' ✅ Borders: Use border utility classes (border-default, border-thick, border-dashed)'
264
+ );
265
+ console.log(
266
+ ' ✅ Component props: color="primary", color="secondary", color="warning", color="danger" (maps to destructive)'
267
+ );
268
+ console.log(
269
+ ' 📝 Note: Use design system colors instead of CSS variables or hardcoded values'
270
+ );
271
+ console.log(' 📖 Documentation: See src/styles.css for complete color mapping');
272
+
273
+ process.exit(1);
274
+ }
275
+ } catch (error) {
276
+ console.error('💥 Error running color check:', error.message);
277
+ process.exit(1);
278
+ }
279
+ }
280
+
281
+ // Run the script
282
+ main();
@@ -0,0 +1,263 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Modus Icons Linting Script for Angular + Tailwind v4
5
+ *
6
+ * This script checks for usage of non-Modus icon patterns in Angular files
7
+ * to ensure design system consistency and proper Modus Icons usage.
8
+ *
9
+ * It flags common non-Modus icon patterns and suggests Modus alternatives.
10
+ */
11
+
12
+ import fs from 'fs';
13
+ import path from 'path';
14
+ import { createRequire } from 'module';
15
+ const require = createRequire(import.meta.url);
16
+ const { glob } = require('glob');
17
+
18
+ // Non-Modus icon patterns to detect
19
+ const NON_MODUS_ICON_PATTERNS = [
20
+ // Font Awesome icons
21
+ /\b(fa|fas|far|fab|fal|fad|fat)-[a-zA-Z0-9-]+\b/g,
22
+
23
+ // Material Icons
24
+ /\bmaterial-icons\b/g,
25
+ /\bmaterial-symbols\b/g,
26
+
27
+ // Heroicons
28
+ /\bheroicons\b/g,
29
+
30
+ // Lucide icons
31
+ /\blucide\b/g,
32
+ /\blucide-react\b/g,
33
+
34
+ // React Icons (Angular might have similar patterns)
35
+ /\bfrom ['"]react-icons\b/g,
36
+ /\bfrom ['"]@heroicons\b/g,
37
+ /\bfrom ['"]lucide-react\b/g,
38
+
39
+ // Common icon libraries
40
+ /\b@ant-design\/icons\b/g,
41
+ /\b@mui\/icons-material\b/g,
42
+ /\b@tabler\/icons\b/g,
43
+ /\b@phosphor-icons\b/g,
44
+
45
+ // SVG icon patterns (non-Modus) - only if they're not Modus
46
+ /<svg[^>]*class="[^"]*icon[^"]*"[^>]*>/g,
47
+
48
+ // Icon components (non-Modus) - exclude modus-icon
49
+ /<Icon[^>]*>/g,
50
+ /<Icons[^>]*>/g,
51
+ /<IconButton[^>]*>/g,
52
+
53
+ // Common icon imports (exclude modus-icon and modus-icons)
54
+ /import.*Icon.*from(?!.*modus)/g,
55
+ /import.*Icons.*from/g,
56
+ /import.*@heroicons/g,
57
+ /import.*@lucide/g,
58
+ /import.*react-icons/g,
59
+ /import.*@ant-design\/icons/g,
60
+ /import.*@mui\/icons-material/g,
61
+ ];
62
+
63
+ // Modus Icons patterns (these are GOOD)
64
+ const MODUS_ICON_PATTERNS = [
65
+ /<i\s+class="modus-icons"[^>]*>/g,
66
+ /class="modus-icons"/g,
67
+ /@trimble-oss\/modus-icons/g,
68
+ /modus-icons\.css/g,
69
+ /<modus-icon[^>]*>/g,
70
+ /<modus-wc-icon[^>]*>/g,
71
+ /ModusWcIcon/g,
72
+ ];
73
+
74
+ // Files to check
75
+ const FILE_PATTERNS = ['src/**/*.ts', 'src/**/*.html', 'src/**/*.css', 'src/**/*.scss'];
76
+
77
+ // Files to exclude
78
+ const EXCLUDE_PATTERNS = ['node_modules/**', 'dist/**', 'build/**', '**/*.d.ts', 'scripts/**'];
79
+
80
+ async function checkFile(filePath) {
81
+ const content = fs.readFileSync(filePath, 'utf8');
82
+ const violations = [];
83
+ const modusIconsFound = [];
84
+
85
+ // Check for Modus Icons usage (good patterns)
86
+ for (const pattern of MODUS_ICON_PATTERNS) {
87
+ let match;
88
+ while ((match = pattern.exec(content)) !== null) {
89
+ const line = content.substring(0, match.index).split('\n').length;
90
+ modusIconsFound.push({
91
+ file: filePath,
92
+ line,
93
+ match: match[0],
94
+ type: 'modus-icon',
95
+ });
96
+ }
97
+ pattern.lastIndex = 0;
98
+ }
99
+
100
+ // Check for non-Modus icon patterns (violations)
101
+ for (const pattern of NON_MODUS_ICON_PATTERNS) {
102
+ let match;
103
+ while ((match = pattern.exec(content)) !== null) {
104
+ const line = content.substring(0, match.index).split('\n').length;
105
+ const column = match.index - content.lastIndexOf('\n', match.index - 1);
106
+
107
+ // Skip if it's a legitimate Modus pattern or legitimate component/import
108
+ const matchText = match[0];
109
+ const matchIndex = match.index;
110
+
111
+ // Check if it's a TypeScript type annotation (e.g., input<IconPosition>, output<IconType>, etc.)
112
+ const beforeMatch = content.substring(Math.max(0, matchIndex - 100), matchIndex);
113
+
114
+ // Check if this is in a TypeScript generic context
115
+ const isTypeScriptType =
116
+ // Angular signals/inputs/outputs with generics: input<IconPosition>, output<IconType>
117
+ /(?:input|output|model|signal|computed|effect|event|Output|Input|Signal|Model|ReadonlySignal)\s*<\s*[^>]*Icon/i.test(
118
+ beforeMatch
119
+ ) ||
120
+ // Function return types with generics: Promise<IconType>, Observable<IconType>
121
+ /:\s*(?:Promise<|Observable<|Array<).*Icon/i.test(beforeMatch) ||
122
+ // Type declarations: type Icon = ..., interface Icon = ...
123
+ /(?:type|interface|enum)\s+\w*Icon\s*[=:{]/i.test(beforeMatch) ||
124
+ // Variable declarations with types: const x: IconType =
125
+ /(?:const|let|var)\s+\w+\s*:\s*.*Icon/i.test(beforeMatch) ||
126
+ // Generic constraints: extends Icon, T extends Icon
127
+ /(?:extends|implements)\s+.*Icon/i.test(beforeMatch) ||
128
+ // Array types: Icon[], IconType[]
129
+ /\w*Icon\w*\s*\[\]/i.test(beforeMatch) ||
130
+ // Generic angle brackets with Icon inside: <IconPosition>, <IconType>
131
+ (matchText.startsWith('<') &&
132
+ matchText.endsWith('>') &&
133
+ /[<>]\s*\w*Icon/i.test(beforeMatch + matchText));
134
+
135
+ if (
136
+ matchText.includes('modus-icon') ||
137
+ matchText.includes('ModusIcon') ||
138
+ matchText.includes('ModusWcIcon') ||
139
+ matchText.includes('modus-icons') ||
140
+ (matchText.includes('icon') && content.includes('modus-icons')) ||
141
+ // Skip legitimate component names and imports
142
+ matchText.includes('IconsPage') ||
143
+ matchText.includes('modusIcons') ||
144
+ matchText.includes('totalIconCount') ||
145
+ matchText.includes('categoryCount') ||
146
+ // Skip TypeScript type annotations
147
+ isTypeScriptType ||
148
+ // Skip legitimate import patterns
149
+ (matchText.includes('import') &&
150
+ (matchText.includes('IconsPage') ||
151
+ matchText.includes('modusIcons') ||
152
+ matchText.includes('totalIconCount') ||
153
+ matchText.includes('categoryCount') ||
154
+ (matchText.includes('from') &&
155
+ (matchText.includes('./pages/IconsPage') ||
156
+ matchText.includes('../pages/IconsPage') ||
157
+ matchText.includes('./data/modusIcons') ||
158
+ matchText.includes('../data/modusIcons') ||
159
+ matchText.includes('data/modusIcons'))))) ||
160
+ // Skip legitimate Angular component usage
161
+ (matchText.includes('<') &&
162
+ matchText.includes('>') &&
163
+ (matchText.includes('IconsPage') ||
164
+ matchText.includes('modusIcons') ||
165
+ matchText.includes('totalIconCount') ||
166
+ matchText.includes('categoryCount')))
167
+ ) {
168
+ continue;
169
+ }
170
+
171
+ violations.push({
172
+ file: filePath,
173
+ line,
174
+ column,
175
+ match: match[0],
176
+ message: `Non-Modus icon pattern detected: "${match[0]}". Use Modus Icons instead.`,
177
+ suggestion:
178
+ 'Replace with <i class="modus-icons">icon_name</i> or <modus-icon name="icon_name" />',
179
+ });
180
+ }
181
+ pattern.lastIndex = 0;
182
+ }
183
+
184
+ return { violations, modusIconsFound };
185
+ }
186
+
187
+ async function main() {
188
+ console.log('🎨 Checking for Modus Icons usage in Angular app...\n');
189
+
190
+ let allViolations = [];
191
+ let allModusIcons = [];
192
+
193
+ try {
194
+ // Get all files to check
195
+ const allFiles = [];
196
+ for (const pattern of FILE_PATTERNS) {
197
+ const files = glob.sync(pattern, {
198
+ ignore: EXCLUDE_PATTERNS,
199
+ });
200
+ allFiles.push(...files.map((f) => path.resolve(f)));
201
+ }
202
+ const files = [...new Set(allFiles)];
203
+
204
+ // Check each file
205
+ for (const file of files) {
206
+ try {
207
+ const { violations, modusIconsFound } = await checkFile(file);
208
+ allViolations = allViolations.concat(violations);
209
+ allModusIcons = allModusIcons.concat(modusIconsFound);
210
+ } catch (error) {
211
+ console.warn(`⚠️ Warning: Could not check file ${file}: ${error.message}`);
212
+ }
213
+ }
214
+
215
+ // Report results
216
+ if (allViolations.length === 0) {
217
+ console.log('✅ All files are using Modus Icons correctly!');
218
+ console.log(`📊 Found ${allModusIcons.length} proper Modus Icons usage(s)`);
219
+ process.exit(0);
220
+ } else {
221
+ console.log(`❌ Found ${allViolations.length} non-Modus icon violations:\n`);
222
+
223
+ // Group violations by file
224
+ const violationsByFile = allViolations.reduce((acc, violation) => {
225
+ if (!acc[violation.file]) {
226
+ acc[violation.file] = [];
227
+ }
228
+ acc[violation.file].push(violation);
229
+ return acc;
230
+ }, {});
231
+
232
+ // Print violations
233
+ for (const [file, violations] of Object.entries(violationsByFile)) {
234
+ const relativePath = path.relative(process.cwd(), file);
235
+ console.log(`📄 ${relativePath}:`);
236
+
237
+ for (const violation of violations) {
238
+ console.log(` ${violation.line}:${violation.column} - ${violation.message}`);
239
+ console.log(` 💡 Suggestion: ${violation.suggestion}`);
240
+ }
241
+ console.log();
242
+ }
243
+
244
+ console.log('💡 Modus Icons Reference:');
245
+ console.log(' ✅ Angular component: <modus-icon name="icon_name" size="md" />');
246
+ console.log(' ✅ Direct usage: <i class="modus-icons">icon_name</i>');
247
+ console.log(
248
+ ' ✅ Import in src/styles.css: @import "@trimble-oss/moduswebcomponents/modus-wc-styles.css";'
249
+ );
250
+ console.log(' 📚 Icon Catalog: https://modus-icons.trimble.com/field-systems/');
251
+ console.log(' 🎨 Available Icons: Check data/modusIcons.ts for complete list');
252
+ console.log(' 📖 Documentation: https://trimble-oss.github.io/modus-wc-2.0/main/');
253
+
254
+ process.exit(1);
255
+ }
256
+ } catch (error) {
257
+ console.error('💥 Error running icon check:', error.message);
258
+ process.exit(1);
259
+ }
260
+ }
261
+
262
+ // Run the script
263
+ main();