@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.
- package/README.md +191 -0
- package/bin/create-trimble-app.js +9 -0
- package/package.json +67 -0
- package/src/cli.js +134 -0
- package/src/frameworks.js +28 -0
- package/src/scaffold.js +209 -0
- package/src/utils/file.js +47 -0
- package/src/utils/git.js +140 -0
- package/src/utils/install.js +25 -0
- package/src/utils/logger.js +124 -0
- package/templates/angular/.cursor/commands/remove-dev-content.md +394 -0
- package/templates/angular/.cursor/mcp.json +13 -0
- package/templates/angular/.cursor/rules/modus-angular-20.mdc +82 -0
- package/templates/angular/.cursor/rules/modus-angular-accordion-state-management-short.mdc +45 -0
- package/templates/angular/.cursor/rules/modus-angular-accordion-state-management.mdc +322 -0
- package/templates/angular/.cursor/rules/modus-angular-best-practices.mdc +472 -0
- package/templates/angular/.cursor/rules/modus-angular-border-usage-short.mdc +48 -0
- package/templates/angular/.cursor/rules/modus-angular-border-usage.mdc +286 -0
- package/templates/angular/.cursor/rules/modus-angular-button-group-usage-short.mdc +47 -0
- package/templates/angular/.cursor/rules/modus-angular-button-group-usage.mdc +263 -0
- package/templates/angular/.cursor/rules/modus-angular-checkbox-value-inversion-short.mdc +36 -0
- package/templates/angular/.cursor/rules/modus-angular-checkbox-value-inversion.mdc +92 -0
- package/templates/angular/.cursor/rules/modus-angular-chrome-devtools-testing-short.mdc +34 -0
- package/templates/angular/.cursor/rules/modus-angular-chrome-devtools-testing.mdc +185 -0
- package/templates/angular/.cursor/rules/modus-angular-color-usage-short.mdc +56 -0
- package/templates/angular/.cursor/rules/modus-angular-color-usage.mdc +208 -0
- package/templates/angular/.cursor/rules/modus-angular-components-reference.mdc +114 -0
- package/templates/angular/.cursor/rules/modus-angular-design-system.mdc +273 -0
- package/templates/angular/.cursor/rules/modus-angular-development-workflow-short.mdc +43 -0
- package/templates/angular/.cursor/rules/modus-angular-development-workflow.mdc +145 -0
- package/templates/angular/.cursor/rules/modus-angular-essentials.mdc +272 -0
- package/templates/angular/.cursor/rules/modus-angular-forms-validation-short.mdc +56 -0
- package/templates/angular/.cursor/rules/modus-angular-forms-validation.mdc +124 -0
- package/templates/angular/.cursor/rules/modus-angular-icon-names.mdc +70 -0
- package/templates/angular/.cursor/rules/modus-angular-icons-short.mdc +40 -0
- package/templates/angular/.cursor/rules/modus-angular-icons.mdc +137 -0
- package/templates/angular/.cursor/rules/modus-angular-implementation-guides-short.mdc +36 -0
- package/templates/angular/.cursor/rules/modus-angular-implementation-guides.mdc +301 -0
- package/templates/angular/.cursor/rules/modus-angular-integration-short.mdc +60 -0
- package/templates/angular/.cursor/rules/modus-angular-integration.mdc +1096 -0
- package/templates/angular/.cursor/rules/modus-angular-master.mdc +164 -0
- package/templates/angular/.cursor/rules/modus-angular-modal-usage-short.mdc +51 -0
- package/templates/angular/.cursor/rules/modus-angular-modal-usage.mdc +115 -0
- package/templates/angular/.cursor/rules/modus-angular-navbar-usage-short.mdc +49 -0
- package/templates/angular/.cursor/rules/modus-angular-navbar-usage.mdc +146 -0
- package/templates/angular/.cursor/rules/modus-angular-no-emojis.mdc +66 -0
- package/templates/angular/.cursor/rules/modus-angular-opacity-utilities-short.mdc +43 -0
- package/templates/angular/.cursor/rules/modus-angular-opacity-utilities.mdc +160 -0
- package/templates/angular/.cursor/rules/modus-angular-select-vs-dropdown-menu-short.mdc +51 -0
- package/templates/angular/.cursor/rules/modus-angular-select-vs-dropdown-menu.mdc +83 -0
- package/templates/angular/.cursor/rules/modus-angular-semantic-html-short.mdc +36 -0
- package/templates/angular/.cursor/rules/modus-angular-semantic-html.mdc +81 -0
- package/templates/angular/.cursor/rules/modus-angular-side-navigation-usage-short.mdc +50 -0
- package/templates/angular/.cursor/rules/modus-angular-side-navigation-usage.mdc +136 -0
- package/templates/angular/.cursor/rules/modus-angular-table-usage-short.mdc +52 -0
- package/templates/angular/.cursor/rules/modus-angular-table-usage.mdc +151 -0
- package/templates/angular/.cursor/rules/modus-angular-tailwind-usage-short.mdc +44 -0
- package/templates/angular/.cursor/rules/modus-angular-tailwind-usage.mdc +242 -0
- package/templates/angular/.cursor/rules/modus-angular-themes-short.mdc +54 -0
- package/templates/angular/.cursor/rules/modus-angular-themes.mdc +222 -0
- package/templates/angular/.cursor/rules/modus-angular-utility-panel-usage-short.mdc +52 -0
- package/templates/angular/.cursor/rules/modus-angular-utility-panel-usage.mdc +130 -0
- package/templates/angular/.cursor/rules/ux/gestalt-laws-detailed.mdc +514 -0
- package/templates/angular/.cursor/rules/ux/ux-ui-foundations.mdc +235 -0
- package/templates/angular/.cursor/skills/run-lint-checks/SKILL.md +169 -0
- package/templates/angular/.editorconfig +17 -0
- package/templates/angular/.github/dependabot.yml +19 -0
- package/templates/angular/.github/workflows/a11y-check.yml +135 -0
- package/templates/angular/.github/workflows/ci.yml +44 -0
- package/templates/angular/.husky/pre-commit +32 -0
- package/templates/angular/.postcssrc.json +5 -0
- package/templates/angular/.vscode/extensions.json +4 -0
- package/templates/angular/.vscode/launch.json +20 -0
- package/templates/angular/.vscode/tasks.json +42 -0
- package/templates/angular/CLAUDE.md +148 -0
- package/templates/angular/README.md +92 -0
- package/templates/angular/amplify.yml +25 -0
- package/templates/angular/angular.json +106 -0
- package/templates/angular/data/modusIcons.ts +861 -0
- package/templates/angular/package-lock.json +11030 -0
- package/templates/angular/package.json +66 -0
- package/templates/angular/public/angular-icon.svg +12 -0
- package/templates/angular/public/favicon.ico +0 -0
- package/templates/angular/public/modus-icons.css +49 -0
- package/templates/angular/public/vite.svg +1 -0
- package/templates/angular/scripts/README.md +410 -0
- package/templates/angular/scripts/check-border-violations.js +352 -0
- package/templates/angular/scripts/check-icon-names.js +402 -0
- package/templates/angular/scripts/check-inline-styles.js +292 -0
- package/templates/angular/scripts/check-modus-colors.js +282 -0
- package/templates/angular/scripts/check-modus-icons.js +263 -0
- package/templates/angular/scripts/check-opacity-utilities.js +426 -0
- package/templates/angular/scripts/check-semantic-html.js +452 -0
- package/templates/angular/scripts/check-typescript.js +109 -0
- package/templates/angular/src/app/app.config.ts +29 -0
- package/templates/angular/src/app/app.css +0 -0
- package/templates/angular/src/app/app.html +4 -0
- package/templates/angular/src/app/app.routes.ts +351 -0
- package/templates/angular/src/app/app.spec.ts +27 -0
- package/templates/angular/src/app/app.ts +47 -0
- package/templates/angular/src/app/components/README.md +77 -0
- package/templates/angular/src/app/components/index.ts +53 -0
- package/templates/angular/src/app/components/modus-accordion.component.ts +50 -0
- package/templates/angular/src/app/components/modus-alert.component.ts +133 -0
- package/templates/angular/src/app/components/modus-autocomplete.component.ts +262 -0
- package/templates/angular/src/app/components/modus-avatar.component.ts +75 -0
- package/templates/angular/src/app/components/modus-badge.component.ts +84 -0
- package/templates/angular/src/app/components/modus-breadcrumbs.component.ts +65 -0
- package/templates/angular/src/app/components/modus-button-group.component.ts +82 -0
- package/templates/angular/src/app/components/modus-button.component.ts +292 -0
- package/templates/angular/src/app/components/modus-card.component.ts +73 -0
- package/templates/angular/src/app/components/modus-checkbox.component.ts +117 -0
- package/templates/angular/src/app/components/modus-chip.component.ts +97 -0
- package/templates/angular/src/app/components/modus-collapse.component.ts +118 -0
- package/templates/angular/src/app/components/modus-date.component.ts +165 -0
- package/templates/angular/src/app/components/modus-dropdown-menu.component.ts +108 -0
- package/templates/angular/src/app/components/modus-file-dropzone.component.ts +121 -0
- package/templates/angular/src/app/components/modus-handle.component.ts +96 -0
- package/templates/angular/src/app/components/modus-icon.component.ts +81 -0
- package/templates/angular/src/app/components/modus-input-feedback.component.ts +54 -0
- package/templates/angular/src/app/components/modus-input-label.component.ts +62 -0
- package/templates/angular/src/app/components/modus-loader.component.ts +48 -0
- package/templates/angular/src/app/components/modus-logo.component.ts +115 -0
- package/templates/angular/src/app/components/modus-menu-item.component.ts +116 -0
- package/templates/angular/src/app/components/modus-menu.component.ts +58 -0
- package/templates/angular/src/app/components/modus-modal.component.ts +70 -0
- package/templates/angular/src/app/components/modus-navbar.component.ts +303 -0
- package/templates/angular/src/app/components/modus-number-input.component.ts +174 -0
- package/templates/angular/src/app/components/modus-pagination.component.ts +74 -0
- package/templates/angular/src/app/components/modus-panel.component.ts +61 -0
- package/templates/angular/src/app/components/modus-progress.component.ts +62 -0
- package/templates/angular/src/app/components/modus-radio.component.ts +102 -0
- package/templates/angular/src/app/components/modus-rating.component.ts +80 -0
- package/templates/angular/src/app/components/modus-select.component.ts +131 -0
- package/templates/angular/src/app/components/modus-side-navigation.component.ts +90 -0
- package/templates/angular/src/app/components/modus-skeleton.component.ts +54 -0
- package/templates/angular/src/app/components/modus-slider.component.ts +132 -0
- package/templates/angular/src/app/components/modus-stepper.component.ts +65 -0
- package/templates/angular/src/app/components/modus-switch.component.ts +118 -0
- package/templates/angular/src/app/components/modus-table.component.ts +204 -0
- package/templates/angular/src/app/components/modus-tabs.component.ts +82 -0
- package/templates/angular/src/app/components/modus-text-input.component.ts +221 -0
- package/templates/angular/src/app/components/modus-textarea.component.ts +168 -0
- package/templates/angular/src/app/components/modus-theme-switcher.component.ts +45 -0
- package/templates/angular/src/app/components/modus-time-input.component.ts +172 -0
- package/templates/angular/src/app/components/modus-toast.component.ts +63 -0
- package/templates/angular/src/app/components/modus-toolbar.component.ts +43 -0
- package/templates/angular/src/app/components/modus-tooltip.component.ts +83 -0
- package/templates/angular/src/app/components/modus-typography.component.ts +79 -0
- package/templates/angular/src/app/components/modus-utility-panel.component.ts +275 -0
- package/templates/angular/src/app/components/theme-demo.component.ts +1242 -0
- package/templates/angular/src/app/data/component-demos.ts +360 -0
- package/templates/angular/src/app/data/modus-icons.ts +806 -0
- package/templates/angular/src/app/demos/accordion/accordion-demo.component.ts +212 -0
- package/templates/angular/src/app/demos/alert/alert-demo.component.ts +108 -0
- package/templates/angular/src/app/demos/autocomplete/autocomplete-demo.component.ts +174 -0
- package/templates/angular/src/app/demos/avatar/avatar-demo.component.ts +149 -0
- package/templates/angular/src/app/demos/badge/badge-demo.component.ts +148 -0
- package/templates/angular/src/app/demos/breadcrumbs/breadcrumbs-demo.component.ts +96 -0
- package/templates/angular/src/app/demos/button/button-demo.component.ts +256 -0
- package/templates/angular/src/app/demos/button-group/button-group-demo.component.ts +215 -0
- package/templates/angular/src/app/demos/card/card-demo.component.ts +180 -0
- package/templates/angular/src/app/demos/checkbox/checkbox-demo.component.ts +71 -0
- package/templates/angular/src/app/demos/chip/chip-demo.component.ts +183 -0
- package/templates/angular/src/app/demos/date/date-demo.component.ts +193 -0
- package/templates/angular/src/app/demos/dropdown/dropdown-demo.component.ts +196 -0
- package/templates/angular/src/app/demos/file-dropzone/file-dropzone-demo.component.ts +176 -0
- package/templates/angular/src/app/demos/handle/handle-demo.component.ts +265 -0
- package/templates/angular/src/app/demos/icon/icon-demo.component.ts +65 -0
- package/templates/angular/src/app/demos/input-feedback/input-feedback-demo.component.ts +189 -0
- package/templates/angular/src/app/demos/input-label/input-label-demo.component.ts +330 -0
- package/templates/angular/src/app/demos/loader/loader-demo.component.ts +143 -0
- package/templates/angular/src/app/demos/logo/logo-demo.component.ts +191 -0
- package/templates/angular/src/app/demos/menu/menu-demo.component.ts +72 -0
- package/templates/angular/src/app/demos/modal/modal-demo.component.ts +278 -0
- package/templates/angular/src/app/demos/navbar/navbar-demo.component.ts +135 -0
- package/templates/angular/src/app/demos/number-input/number-input-demo.component.ts +175 -0
- package/templates/angular/src/app/demos/pagination/pagination-demo.component.ts +134 -0
- package/templates/angular/src/app/demos/panel/panel-demo.component.ts +235 -0
- package/templates/angular/src/app/demos/progress/progress-demo.component.ts +169 -0
- package/templates/angular/src/app/demos/radio/radio-demo.component.ts +161 -0
- package/templates/angular/src/app/demos/rating/rating-demo.component.ts +97 -0
- package/templates/angular/src/app/demos/select/select-demo.component.ts +107 -0
- package/templates/angular/src/app/demos/shared/demo-example-clean.component.ts +41 -0
- package/templates/angular/src/app/demos/shared/demo-example.component.ts +42 -0
- package/templates/angular/src/app/demos/shared/demo-page.component.ts +97 -0
- package/templates/angular/src/app/demos/shared/index.ts +3 -0
- package/templates/angular/src/app/demos/side-navigation/side-navigation-demo.component.ts +524 -0
- package/templates/angular/src/app/demos/skeleton/skeleton-demo.component.ts +112 -0
- package/templates/angular/src/app/demos/slider/slider-demo.component.ts +76 -0
- package/templates/angular/src/app/demos/stepper/stepper-demo.component.ts +79 -0
- package/templates/angular/src/app/demos/switch/switch-demo.component.ts +113 -0
- package/templates/angular/src/app/demos/table/table-demo.component.ts +405 -0
- package/templates/angular/src/app/demos/tabs/tabs-demo.component.ts +318 -0
- package/templates/angular/src/app/demos/text-input/text-input-demo.component.ts +160 -0
- package/templates/angular/src/app/demos/textarea/textarea-demo.component.ts +95 -0
- package/templates/angular/src/app/demos/theme-switcher/theme-switcher-demo.component.ts +38 -0
- package/templates/angular/src/app/demos/time-input/time-input-demo.component.ts +130 -0
- package/templates/angular/src/app/demos/toast/toast-demo.component.ts +258 -0
- package/templates/angular/src/app/demos/toolbar/toolbar-demo.component.ts +54 -0
- package/templates/angular/src/app/demos/tooltip/tooltip-demo.component.ts +163 -0
- package/templates/angular/src/app/demos/utility-panel/utility-panel-demo.component.ts +197 -0
- package/templates/angular/src/app/dev/dev-config.ts +119 -0
- package/templates/angular/src/app/dev/dev-panel/dev-panel.component.ts +215 -0
- package/templates/angular/src/app/dev/dev-panel.service.ts +63 -0
- package/templates/angular/src/app/dev/index.ts +8 -0
- package/templates/angular/src/app/dev/theme-switcher-dropdown/theme-switcher-dropdown.component.ts +134 -0
- package/templates/angular/src/app/dev-pages/color-palette/color-palette.component.ts +229 -0
- package/templates/angular/src/app/dev-pages/components-gallery/components-gallery.component.ts +486 -0
- package/templates/angular/src/app/dev-pages/icons/icons.component.ts +149 -0
- package/templates/angular/src/app/pages/home/home.component.ts +251 -0
- package/templates/angular/src/app/services/README.md +57 -0
- package/templates/angular/src/app/services/theme.service.ts +163 -0
- package/templates/angular/src/environments/environment.development.ts +8 -0
- package/templates/angular/src/environments/environment.ts +8 -0
- package/templates/angular/src/index.html +14 -0
- package/templates/angular/src/main.ts +6 -0
- package/templates/angular/src/styles.css +1328 -0
- package/templates/angular/tsconfig.app.json +15 -0
- package/templates/angular/tsconfig.json +35 -0
- package/templates/angular/tsconfig.spec.json +14 -0
- package/templates/config.json +23 -0
- package/templates/react/.cursor/commands/remove-dev-content.md +311 -0
- package/templates/react/.cursor/mcp.json +13 -0
- package/templates/react/.cursor/rules/README.md +240 -0
- package/templates/react/.cursor/rules/border-usage-guidelines-short.mdc +22 -0
- package/templates/react/.cursor/rules/border-usage-guidelines.mdc +380 -0
- package/templates/react/.cursor/rules/chrome-devtools-testing-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/development-workflow-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/development-workflow-react.mdc +292 -0
- package/templates/react/.cursor/rules/implementation-guides-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/implementation-guides-react.mdc +446 -0
- package/templates/react/.cursor/rules/modus-accordion-state-management-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-accordion-state-management-react.mdc +445 -0
- package/templates/react/.cursor/rules/modus-button-group-usage-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-button-group-usage-react.mdc +117 -0
- package/templates/react/.cursor/rules/modus-checkbox-value-inversion-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-checkbox-value-inversion-react.mdc +492 -0
- package/templates/react/.cursor/rules/modus-color-usage-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-color-usage-react.mdc +420 -0
- package/templates/react/.cursor/rules/modus-components-reference.mdc +366 -0
- package/templates/react/.cursor/rules/modus-icon-names.mdc +63 -0
- package/templates/react/.cursor/rules/modus-icons-react-short.mdc +24 -0
- package/templates/react/.cursor/rules/modus-icons-react.mdc +402 -0
- package/templates/react/.cursor/rules/modus-modal-implementation-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-modal-implementation-react.mdc +831 -0
- package/templates/react/.cursor/rules/modus-navbar-side-navigation-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-navbar-side-navigation-react.mdc +247 -0
- package/templates/react/.cursor/rules/modus-no-emojis-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-opacity-utilities-react-short.mdc +70 -0
- package/templates/react/.cursor/rules/modus-opacity-utilities-react.mdc +208 -0
- package/templates/react/.cursor/rules/modus-react-best-practices-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-react-best-practices.mdc +508 -0
- package/templates/react/.cursor/rules/modus-react-essentials.mdc +209 -0
- package/templates/react/.cursor/rules/modus-react-integration-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-react-integration.mdc +509 -0
- package/templates/react/.cursor/rules/modus-react-key-warnings-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-react-key-warnings.mdc +805 -0
- package/templates/react/.cursor/rules/modus-react-master.mdc +160 -0
- package/templates/react/.cursor/rules/modus-select-vs-dropdown-menu-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-select-vs-dropdown-menu-react.mdc +442 -0
- package/templates/react/.cursor/rules/modus-semantic-html-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-semantic-html-react.mdc +427 -0
- package/templates/react/.cursor/rules/modus-tailwind-usage-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-tailwind-usage-react.mdc +642 -0
- package/templates/react/.cursor/rules/modus-themes-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-themes-react.mdc +506 -0
- package/templates/react/.cursor/rules/ux/gestalt-laws-detailed.mdc +456 -0
- package/templates/react/.cursor/rules/ux/ux-ui-foundations.mdc +211 -0
- package/templates/react/.cursor/skills/create-modus-form-component/SKILL.md +518 -0
- package/templates/react/.cursor/skills/create-modus-wrapper-component/SKILL.md +252 -0
- package/templates/react/.cursor/skills/fix-modus-component-event-issues/SKILL.md +345 -0
- package/templates/react/.cursor/skills/handle-modus-checkbox-value-bug/SKILL.md +202 -0
- package/templates/react/.cursor/skills/implement-modus-modal-with-refs/SKILL.md +386 -0
- package/templates/react/.cursor/skills/integrate-modus-icons/SKILL.md +300 -0
- package/templates/react/.cursor/skills/run-lint-checks/SKILL.md +235 -0
- package/templates/react/.cursor/skills/set-up-modus-event-listeners/SKILL.md +284 -0
- package/templates/react/.cursor/skills/style-modus-components-with-tailwind/SKILL.md +382 -0
- package/templates/react/.env.development +3 -0
- package/templates/react/.env.production +3 -0
- package/templates/react/.github/CODEOWNERS +28 -0
- package/templates/react/.github/ISSUE_TEMPLATE/bug_report.yml +176 -0
- package/templates/react/.github/ISSUE_TEMPLATE/config.yml +20 -0
- package/templates/react/.github/ISSUE_TEMPLATE/documentation.yml +115 -0
- package/templates/react/.github/ISSUE_TEMPLATE/feature_request.yml +171 -0
- package/templates/react/.github/ISSUE_TEMPLATE/question.yml +139 -0
- package/templates/react/.github/copilot-instructions.md +80 -0
- package/templates/react/.github/instructions/components.instructions.md +82 -0
- package/templates/react/.github/instructions/demos.instructions.md +82 -0
- package/templates/react/.github/instructions/pages.instructions.md +76 -0
- package/templates/react/.github/instructions/styles.instructions.md +77 -0
- package/templates/react/.github/instructions/typescript.instructions.md +101 -0
- package/templates/react/.github/pull_request_template.md +188 -0
- package/templates/react/.github/workflows/ci.yml +43 -0
- package/templates/react/.github/workflows/claude-code-review.yml +44 -0
- package/templates/react/.github/workflows/claude.yml +50 -0
- package/templates/react/.husky/pre-commit +28 -0
- package/templates/react/.vscode/extensions.json +8 -0
- package/templates/react/CLAUDE.md +119 -0
- package/templates/react/CODE_OF_CONDUCT.md +79 -0
- package/templates/react/CONTRIBUTING.md +65 -0
- package/templates/react/LICENSE +21 -0
- package/templates/react/README.md +728 -0
- package/templates/react/SECURITY.md +50 -0
- package/templates/react/eslint.config.js +23 -0
- package/templates/react/index.html +13 -0
- package/templates/react/package-lock.json +5209 -0
- package/templates/react/package.json +49 -0
- package/templates/react/postcss.config.js +6 -0
- package/templates/react/public/react.svg +1 -0
- package/templates/react/public/vite.svg +1 -0
- package/templates/react/readme_assets/getting_started_header.png +0 -0
- package/templates/react/readme_assets/hero.png +0 -0
- package/templates/react/readme_assets/modus_comp.png +0 -0
- package/templates/react/readme_assets/modus_figma_mcp.png +0 -0
- package/templates/react/readme_assets/teaser_comp.gif +0 -0
- package/templates/react/scripts/README.md +343 -0
- package/templates/react/scripts/check-border-violations.js +483 -0
- package/templates/react/scripts/check-icon-names.js +486 -0
- package/templates/react/scripts/check-inline-styles.js +364 -0
- package/templates/react/scripts/check-modus-colors.js +247 -0
- package/templates/react/scripts/check-modus-icons.js +256 -0
- package/templates/react/scripts/check-opacity-utilities.js +481 -0
- package/templates/react/scripts/check-semantic-html.js +476 -0
- package/templates/react/scripts/check-typescript.js +109 -0
- package/templates/react/src/App.css +42 -0
- package/templates/react/src/App.tsx +54 -0
- package/templates/react/src/assets/react.svg +1 -0
- package/templates/react/src/components/DemoExample.tsx +61 -0
- package/templates/react/src/components/DemoPage.tsx +81 -0
- package/templates/react/src/components/ModusAccordion.tsx +89 -0
- package/templates/react/src/components/ModusAlert.tsx +85 -0
- package/templates/react/src/components/ModusAutocomplete.tsx +207 -0
- package/templates/react/src/components/ModusAvatar.tsx +50 -0
- package/templates/react/src/components/ModusBadge.tsx +82 -0
- package/templates/react/src/components/ModusBreadcrumbs.tsx +75 -0
- package/templates/react/src/components/ModusButton.tsx +244 -0
- package/templates/react/src/components/ModusButtonGroup.tsx +91 -0
- package/templates/react/src/components/ModusCard.tsx +70 -0
- package/templates/react/src/components/ModusCheckbox.tsx +168 -0
- package/templates/react/src/components/ModusChip.tsx +93 -0
- package/templates/react/src/components/ModusDate.tsx +154 -0
- package/templates/react/src/components/ModusDropdownMenu.tsx +148 -0
- package/templates/react/src/components/ModusFileDropzone.tsx +140 -0
- package/templates/react/src/components/ModusHandle.tsx +101 -0
- package/templates/react/src/components/ModusIcon.tsx +49 -0
- package/templates/react/src/components/ModusInputFeedback.tsx +52 -0
- package/templates/react/src/components/ModusInputLabel.tsx +50 -0
- package/templates/react/src/components/ModusLoader.tsx +42 -0
- package/templates/react/src/components/ModusLogo.tsx +102 -0
- package/templates/react/src/components/ModusMenu.tsx +119 -0
- package/templates/react/src/components/ModusMenuItem.tsx +86 -0
- package/templates/react/src/components/ModusModal.tsx +145 -0
- package/templates/react/src/components/ModusNavbar.tsx +504 -0
- package/templates/react/src/components/ModusNumberInput.tsx +230 -0
- package/templates/react/src/components/ModusPagination.tsx +94 -0
- package/templates/react/src/components/ModusPanel.tsx +92 -0
- package/templates/react/src/components/ModusProgress.tsx +70 -0
- package/templates/react/src/components/ModusProvider.tsx +18 -0
- package/templates/react/src/components/ModusRadio.tsx +114 -0
- package/templates/react/src/components/ModusRating.tsx +108 -0
- package/templates/react/src/components/ModusSelect.tsx +171 -0
- package/templates/react/src/components/ModusSideNavigation.tsx +149 -0
- package/templates/react/src/components/ModusSkeleton.tsx +42 -0
- package/templates/react/src/components/ModusSlider.tsx +128 -0
- package/templates/react/src/components/ModusStepper.tsx +85 -0
- package/templates/react/src/components/ModusSwitch.tsx +130 -0
- package/templates/react/src/components/ModusTable.tsx +309 -0
- package/templates/react/src/components/ModusTabs.tsx +114 -0
- package/templates/react/src/components/ModusTextInput.tsx +179 -0
- package/templates/react/src/components/ModusTextarea.tsx +164 -0
- package/templates/react/src/components/ModusThemeSwitcher.tsx +58 -0
- package/templates/react/src/components/ModusTimeInput.tsx +176 -0
- package/templates/react/src/components/ModusToast.tsx +207 -0
- package/templates/react/src/components/ModusToolbar.tsx +70 -0
- package/templates/react/src/components/ModusTooltip.tsx +97 -0
- package/templates/react/src/components/ModusUtilityPanel.tsx +198 -0
- package/templates/react/src/components/ThemeSwitcherDropdown.tsx +117 -0
- package/templates/react/src/components/ThemeToggleSimple.tsx +157 -0
- package/templates/react/src/config/routes.ts +196 -0
- package/templates/react/src/contexts/ThemeContext.tsx +81 -0
- package/templates/react/src/contexts/ThemeContextData.tsx +89 -0
- package/templates/react/src/data/modusIcons.ts +865 -0
- package/templates/react/src/demos/accordion-demo/page.tsx +236 -0
- package/templates/react/src/demos/alert-demo/page.tsx +94 -0
- package/templates/react/src/demos/autocomplete-demo/page.tsx +166 -0
- package/templates/react/src/demos/avatar-demo/page.tsx +135 -0
- package/templates/react/src/demos/badge-demo/page.tsx +174 -0
- package/templates/react/src/demos/breadcrumbs-demo/page.tsx +88 -0
- package/templates/react/src/demos/button-demo/page.tsx +261 -0
- package/templates/react/src/demos/button-group-demo/page.tsx +231 -0
- package/templates/react/src/demos/card-demo/page.tsx +241 -0
- package/templates/react/src/demos/checkbox-demo/page.tsx +79 -0
- package/templates/react/src/demos/chip-demo/page.tsx +197 -0
- package/templates/react/src/demos/date-demo/page.tsx +179 -0
- package/templates/react/src/demos/dropdown-demo/page.tsx +150 -0
- package/templates/react/src/demos/file-dropzone-demo/page.tsx +186 -0
- package/templates/react/src/demos/handle-demo/page.tsx +313 -0
- package/templates/react/src/demos/icon-demo/page.tsx +72 -0
- package/templates/react/src/demos/input-feedback-demo/page.tsx +202 -0
- package/templates/react/src/demos/input-label-demo/page.tsx +392 -0
- package/templates/react/src/demos/loader-demo/page.tsx +138 -0
- package/templates/react/src/demos/logo-demo/page.tsx +292 -0
- package/templates/react/src/demos/menu-demo/page.tsx +70 -0
- package/templates/react/src/demos/modal-demo/page.tsx +332 -0
- package/templates/react/src/demos/navbar-demo/page.tsx +141 -0
- package/templates/react/src/demos/number-input-demo/page.tsx +180 -0
- package/templates/react/src/demos/pagination-demo/page.tsx +147 -0
- package/templates/react/src/demos/panel-demo/page.tsx +376 -0
- package/templates/react/src/demos/progress-demo/page.tsx +185 -0
- package/templates/react/src/demos/radio-demo/page.tsx +242 -0
- package/templates/react/src/demos/rating-demo/page.tsx +97 -0
- package/templates/react/src/demos/select-demo/page.tsx +111 -0
- package/templates/react/src/demos/side-navigation-demo/page.tsx +775 -0
- package/templates/react/src/demos/skeleton-demo/page.tsx +107 -0
- package/templates/react/src/demos/slider-demo/page.tsx +78 -0
- package/templates/react/src/demos/stepper-demo/page.tsx +86 -0
- package/templates/react/src/demos/switch-demo/page.tsx +146 -0
- package/templates/react/src/demos/table-demo/page.tsx +489 -0
- package/templates/react/src/demos/tabs-demo/page.tsx +187 -0
- package/templates/react/src/demos/text-input-demo/page.tsx +151 -0
- package/templates/react/src/demos/textarea-demo/page.tsx +73 -0
- package/templates/react/src/demos/theme-switcher-demo/page.tsx +26 -0
- package/templates/react/src/demos/time-input-demo/page.tsx +148 -0
- package/templates/react/src/demos/toast-demo/page.tsx +302 -0
- package/templates/react/src/demos/toolbar-demo/page.tsx +49 -0
- package/templates/react/src/demos/tooltip-demo/page.tsx +209 -0
- package/templates/react/src/demos/typography-test/page.tsx +28 -0
- package/templates/react/src/demos/utility-panel-demo/page.tsx +197 -0
- package/templates/react/src/dev/DevPanel.tsx +219 -0
- package/templates/react/src/dev/DevPanelContext.ts +14 -0
- package/templates/react/src/dev/DevPanelProvider.tsx +63 -0
- package/templates/react/src/dev/DevRoutes.tsx +98 -0
- package/templates/react/src/dev/config.ts +127 -0
- package/templates/react/src/dev/index.ts +8 -0
- package/templates/react/src/dev/useDevPanel.ts +17 -0
- package/templates/react/src/dev-pages/ColorPalettePage.tsx +347 -0
- package/templates/react/src/dev-pages/ComponentsGalleryPage.tsx +489 -0
- package/templates/react/src/dev-pages/IconsPage.tsx +137 -0
- package/templates/react/src/dev-pages/index.ts +3 -0
- package/templates/react/src/hooks/useTheme.ts +15 -0
- package/templates/react/src/index.css +635 -0
- package/templates/react/src/main.tsx +14 -0
- package/templates/react/src/pages/HomePage.tsx +283 -0
- package/templates/react/src/vite-env.d.ts +9 -0
- package/templates/react/tailwind.config.js +58 -0
- package/templates/react/tsconfig.app.json +27 -0
- package/templates/react/tsconfig.json +7 -0
- package/templates/react/tsconfig.node.json +25 -0
- 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();
|