@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,160 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Master rule providing overview and references to all Modus React rules
|
|
3
|
+
globs: ["**/*.tsx", "**/*.ts", "**/*.css"]
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Modus React Rules - Master Reference
|
|
8
|
+
|
|
9
|
+
This master rule provides an overview of all available rules and serves as an entry point for understanding the Modus React development patterns.
|
|
10
|
+
|
|
11
|
+
## Rule Structure
|
|
12
|
+
|
|
13
|
+
This project uses a **short/full rule pattern**:
|
|
14
|
+
|
|
15
|
+
- **Short Rules** (`*-short.mdc`): Always applied, concise summaries
|
|
16
|
+
- **Full Rules** (`*.mdc`): Apply intelligently, detailed patterns
|
|
17
|
+
|
|
18
|
+
See `README.md` in this directory for complete rule documentation.
|
|
19
|
+
|
|
20
|
+
## Essential Rules (Always Applied)
|
|
21
|
+
|
|
22
|
+
These short rules are always included in chat context:
|
|
23
|
+
|
|
24
|
+
### Design System
|
|
25
|
+
- `modus-color-usage-react-short.mdc` - Color system usage
|
|
26
|
+
- `modus-icons-react-short.mdc` - Icon usage patterns
|
|
27
|
+
- `modus-semantic-html-react-short.mdc` - HTML element usage
|
|
28
|
+
- `border-usage-guidelines-short.mdc` - Border utilities
|
|
29
|
+
- `modus-opacity-utilities-react-short.mdc` - Opacity utilities
|
|
30
|
+
- `modus-tailwind-usage-react-short.mdc` - Tailwind integration
|
|
31
|
+
- `modus-themes-react-short.mdc` - Theme implementation
|
|
32
|
+
|
|
33
|
+
### Component Patterns
|
|
34
|
+
- `modus-button-group-usage-react-short.mdc` - Button group patterns
|
|
35
|
+
- `modus-checkbox-value-inversion-react-short.mdc` - Checkbox bug handling
|
|
36
|
+
- `modus-modal-implementation-react-short.mdc` - Modal patterns
|
|
37
|
+
- `modus-accordion-state-management-react-short.mdc` - Accordion state
|
|
38
|
+
- `modus-select-vs-dropdown-menu-react-short.mdc` - Dropdown patterns
|
|
39
|
+
- `modus-navbar-side-navigation-react-short.mdc` - Navigation integration
|
|
40
|
+
|
|
41
|
+
### React Integration
|
|
42
|
+
- `modus-react-integration-short.mdc` - React + Modus integration
|
|
43
|
+
- `modus-react-best-practices-short.mdc` - React best practices
|
|
44
|
+
- `modus-react-key-warnings-short.mdc` - React key prop patterns
|
|
45
|
+
|
|
46
|
+
### Workflow
|
|
47
|
+
- `development-workflow-react-short.mdc` - Linting and quality checks
|
|
48
|
+
- `chrome-devtools-testing-react-short.mdc` - Browser testing
|
|
49
|
+
- `implementation-guides-react-short.mdc` - Feature development guides
|
|
50
|
+
- `modus-no-emojis-react-short.mdc` - Emoji prohibition
|
|
51
|
+
|
|
52
|
+
## Detailed Rules (Apply Intelligently)
|
|
53
|
+
|
|
54
|
+
For detailed patterns, examples, and advanced techniques, reference these full rules:
|
|
55
|
+
|
|
56
|
+
### Component-Specific Details
|
|
57
|
+
- `modus-button-group-usage-react.mdc` - Complete button group patterns
|
|
58
|
+
- `modus-checkbox-value-inversion-react.mdc` - Checkbox bug details
|
|
59
|
+
- `modus-modal-implementation-react.mdc` - Complete modal implementation
|
|
60
|
+
- `modus-accordion-state-management-react.mdc` - Accordion state management
|
|
61
|
+
- `modus-select-vs-dropdown-menu-react.mdc` - Dropdown comparison
|
|
62
|
+
- `modus-navbar-side-navigation-react.mdc` - Navigation integration details
|
|
63
|
+
|
|
64
|
+
### Design System Details
|
|
65
|
+
- `modus-color-usage-react.mdc` - Complete color system guide
|
|
66
|
+
- `modus-icons-react.mdc` - Complete icon usage guide
|
|
67
|
+
- `modus-semantic-html-react.mdc` - HTML patterns guide
|
|
68
|
+
- `border-usage-guidelines.mdc` - Complete border utilities guide
|
|
69
|
+
- `modus-opacity-utilities-react.mdc` - Complete opacity utilities guide
|
|
70
|
+
- `modus-tailwind-usage-react.mdc` - Complete Tailwind integration guide
|
|
71
|
+
- `modus-themes-react.mdc` - Complete theme implementation guide
|
|
72
|
+
|
|
73
|
+
### Integration & Best Practices
|
|
74
|
+
- `modus-react-integration.mdc` - Complete React integration guide
|
|
75
|
+
- `modus-react-best-practices.mdc` - Complete best practices guide
|
|
76
|
+
- `modus-react-key-warnings.mdc` - Complete key prop patterns guide
|
|
77
|
+
- `modus-react-essentials.mdc` - Comprehensive essentials (consolidates multiple topics)
|
|
78
|
+
|
|
79
|
+
### Workflow & Testing
|
|
80
|
+
- `development-workflow-react.mdc` - Complete workflow guide
|
|
81
|
+
- `chrome-devtools-testing-react.mdc` - Complete testing guide
|
|
82
|
+
- `implementation-guides-react.mdc` - Complete implementation guide structure
|
|
83
|
+
|
|
84
|
+
### UX Foundations
|
|
85
|
+
- `ux/ux-ui-foundations.mdc` - UI/UX foundations with Modus 2 + Tailwind
|
|
86
|
+
- `ux/gestalt-laws-detailed.mdc` - Gestalt Laws implementation guide
|
|
87
|
+
|
|
88
|
+
## Reference Files
|
|
89
|
+
|
|
90
|
+
- `modus-icon-names.mdc` - Complete list of valid Modus icon names
|
|
91
|
+
- `modus-components-reference.mdc` - Component reference guide
|
|
92
|
+
|
|
93
|
+
## Quick Start Guide
|
|
94
|
+
|
|
95
|
+
### Working with Components
|
|
96
|
+
|
|
97
|
+
1. Check component-specific short rule (always applied)
|
|
98
|
+
2. For details, reference full rule: `@modus-[component]-react`
|
|
99
|
+
3. See component reference: `@modus-components-reference`
|
|
100
|
+
|
|
101
|
+
### Working with Design System
|
|
102
|
+
|
|
103
|
+
1. Short rules provide essential patterns (always applied)
|
|
104
|
+
2. For details, reference full rule: `@modus-[topic]-react`
|
|
105
|
+
3. For icon names: `@modus-icon-names`
|
|
106
|
+
|
|
107
|
+
### Common Patterns
|
|
108
|
+
|
|
109
|
+
**Colors**: Always use design system colors (`bg-background`, `text-foreground`, etc.)
|
|
110
|
+
- Reference: `@modus-color-usage-react`
|
|
111
|
+
|
|
112
|
+
**Icons**: Use Modus icons exclusively (`<i className="modus-icons">icon-name</i>`)
|
|
113
|
+
- Reference: `@modus-icons-react`
|
|
114
|
+
- Names: `@modus-icon-names`
|
|
115
|
+
|
|
116
|
+
**Components**: Use wrapper components, not web components directly
|
|
117
|
+
- Reference: `@modus-react-integration`
|
|
118
|
+
|
|
119
|
+
**State Management**: Let Modus components manage their own state
|
|
120
|
+
- Reference: Component-specific rules
|
|
121
|
+
|
|
122
|
+
## Rule Application
|
|
123
|
+
|
|
124
|
+
Rules are applied automatically based on:
|
|
125
|
+
|
|
126
|
+
1. **Always Apply**: Short rules with `alwaysApply: true`
|
|
127
|
+
2. **File Patterns**: Rules activate when working with matching files (`globs`)
|
|
128
|
+
3. **Context Matching**: Agent applies rules based on description relevance
|
|
129
|
+
4. **Manual Reference**: Use `@rule-name` to explicitly reference a rule
|
|
130
|
+
|
|
131
|
+
## Best Practices
|
|
132
|
+
|
|
133
|
+
When working with Modus React:
|
|
134
|
+
|
|
135
|
+
1. **Follow Short Rules**: Essential patterns are always available
|
|
136
|
+
2. **Reference Full Rules**: Use `@rule-name` for detailed guidance
|
|
137
|
+
3. **Check Component Reference**: See `@modus-components-reference` for component details
|
|
138
|
+
4. **Verify Icon Names**: Check `@modus-icon-names` before using icons
|
|
139
|
+
5. **Run Linting**: Use `npm run lint:all` before committing
|
|
140
|
+
|
|
141
|
+
## Getting Help
|
|
142
|
+
|
|
143
|
+
- **Rule Documentation**: See `README.md` in this directory
|
|
144
|
+
- **Project Guide**: See `CLAUDE.md` in project root
|
|
145
|
+
- **Component Reference**: `@modus-components-reference`
|
|
146
|
+
- **Icon Names**: `@modus-icon-names`
|
|
147
|
+
|
|
148
|
+
## Rule Maintenance
|
|
149
|
+
|
|
150
|
+
When adding or updating rules:
|
|
151
|
+
|
|
152
|
+
1. Create/update short rule with `alwaysApply: true`
|
|
153
|
+
2. Create/update full rule with `alwaysApply: false`
|
|
154
|
+
3. Ensure descriptions match between short and full
|
|
155
|
+
4. Add appropriate `globs:` patterns
|
|
156
|
+
5. Update `README.md` with new rule entry
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
**Note**: This master rule is always applied to provide rule overview. For specific guidance, reference the appropriate detailed rule using `@rule-name` syntax.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Use ModusDropdownMenu instead of ModusSelect for reliable event handling
|
|
3
|
+
globs: ["**/components/ModusSelect*.tsx", "**/components/ModusDropdownMenu*.tsx", "**/demos/**/page.tsx"]
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Modus Select vs Dropdown Menu - Short
|
|
8
|
+
|
|
9
|
+
Use ModusDropdownMenu instead of ModusSelect for reliable event handling.
|
|
10
|
+
|
|
11
|
+
## Key Rules
|
|
12
|
+
|
|
13
|
+
- **Use ModusDropdownMenu, not ModusSelect** - ModusSelect has unreliable event handling in React
|
|
14
|
+
- **Reliable itemSelect events** - ModusDropdownMenu provides consistent event handling
|
|
15
|
+
- **Proper state management** - Use React state to track selected values and visibility
|
|
16
|
+
- **Programmatic control** - Use refs to control dropdown visibility
|
|
17
|
+
- **Event handling patterns** - Handle `itemSelect` events for selection changes
|
|
18
|
+
- **Test thoroughly** - Verify dropdown behavior and event handling
|
|
19
|
+
- **Use established patterns** - Follow ModusDropdownMenu component patterns
|
|
20
|
+
|
|
21
|
+
## Reference
|
|
22
|
+
|
|
23
|
+
For detailed component comparison, implementation patterns, and advanced usage, fetch the full rule: `modus-select-vs-dropdown-menu-react`
|
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Use ModusDropdownMenu instead of ModusSelect for reliable event handling
|
|
3
|
+
globs: ["**/components/ModusSelect*.tsx", "**/components/ModusDropdownMenu*.tsx", "**/demos/**/page.tsx"]
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ModusSelect vs ModusDropdownMenu in React
|
|
8
|
+
|
|
9
|
+
## 🚨 **CRITICAL: ModusSelect Reliability Issues**
|
|
10
|
+
|
|
11
|
+
**Problem**: `ModusSelect` component has unreliable event handling in React applications, especially with Chrome DevTools automation and testing.
|
|
12
|
+
|
|
13
|
+
**Root Cause**: `ModusSelect` events are inconsistent and may not fire reliably in React environments.
|
|
14
|
+
|
|
15
|
+
**Solution**: Use `ModusDropdownMenu` with `itemSelect` events, which are more reliable and consistent.
|
|
16
|
+
|
|
17
|
+
## ❌ **Common Anti-Patterns**
|
|
18
|
+
|
|
19
|
+
### ❌ **Using ModusSelect (Unreliable)**
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
// ❌ WRONG: ModusSelect with unreliable events
|
|
23
|
+
function UnreliableSelect() {
|
|
24
|
+
const [selectedValue, setSelectedValue] = useState("");
|
|
25
|
+
|
|
26
|
+
const options = [
|
|
27
|
+
{ label: "Option 1", value: "option1" },
|
|
28
|
+
{ label: "Option 2", value: "option2" },
|
|
29
|
+
{ label: "Option 3", value: "option3" },
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
const handleInputChange = (event: CustomEvent<InputEvent>) => {
|
|
33
|
+
// ❌ This event may not fire reliably in React
|
|
34
|
+
console.log("Select changed:", event.target.value);
|
|
35
|
+
setSelectedValue(event.target.value);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<ModusSelect
|
|
40
|
+
options={options}
|
|
41
|
+
value={selectedValue}
|
|
42
|
+
onInputChange={handleInputChange} // ❌ Unreliable event
|
|
43
|
+
label="Select an option"
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### ❌ **Direct Event Handling**
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
// ❌ WRONG: Direct event handling
|
|
53
|
+
function DirectEventHandling() {
|
|
54
|
+
const options = [
|
|
55
|
+
{ label: "Option 1", value: "1" },
|
|
56
|
+
{ label: "Option 2", value: "2" },
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
const handleInputChange = (event: CustomEvent<InputEvent>) => {
|
|
60
|
+
// ❌ This may not work consistently in React
|
|
61
|
+
const value = event.target.value;
|
|
62
|
+
console.log("Selected:", value);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
return <ModusSelect options={options} onInputChange={handleInputChange} />;
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## ✅ **Correct Patterns**
|
|
70
|
+
|
|
71
|
+
### ✅ **Use ModusDropdownMenu (Reliable)**
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
// ✅ CORRECT: ModusDropdownMenu with reliable events
|
|
75
|
+
function ReliableDropdown() {
|
|
76
|
+
const [selectedValue, setSelectedValue] = useState("");
|
|
77
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
78
|
+
const dropdownRef = useRef<HTMLModusWcDropdownMenuElement>(null);
|
|
79
|
+
|
|
80
|
+
const handleItemSelect = (event: CustomEvent<{ value: string }>) => {
|
|
81
|
+
// ✅ CORRECT: Reliable itemSelect event
|
|
82
|
+
const value = event.detail.value;
|
|
83
|
+
console.log("Item selected:", value);
|
|
84
|
+
setSelectedValue(value);
|
|
85
|
+
setIsOpen(false);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const toggleDropdown = () => {
|
|
89
|
+
if (dropdownRef.current) {
|
|
90
|
+
dropdownRef.current.menuVisible = !isOpen;
|
|
91
|
+
setIsOpen(!isOpen);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const menuItems = [
|
|
96
|
+
{ label: "Option 1", value: "option1" },
|
|
97
|
+
{ label: "Option 2", value: "option2" },
|
|
98
|
+
{ label: "Option 3", value: "option3" },
|
|
99
|
+
];
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<ModusDropdownMenu
|
|
103
|
+
ref={dropdownRef}
|
|
104
|
+
menuVisible={isOpen}
|
|
105
|
+
onItemSelect={handleItemSelect}
|
|
106
|
+
buttonContent={
|
|
107
|
+
<ModusWcButton onClick={toggleDropdown}>
|
|
108
|
+
{selectedValue || "Select an option"}
|
|
109
|
+
</ModusWcButton>
|
|
110
|
+
}
|
|
111
|
+
menuItems={menuItems}
|
|
112
|
+
/>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### ✅ **Reusable Dropdown Hook**
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
// ✅ CORRECT: Reusable dropdown hook
|
|
121
|
+
function useDropdown() {
|
|
122
|
+
const [selectedValue, setSelectedValue] = useState("");
|
|
123
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
124
|
+
const dropdownRef = useRef<HTMLModusWcDropdownMenuElement>(null);
|
|
125
|
+
|
|
126
|
+
const handleItemSelect = (event: CustomEvent<{ value: string }>) => {
|
|
127
|
+
const value = event.detail.value;
|
|
128
|
+
setSelectedValue(value);
|
|
129
|
+
setIsOpen(false);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const toggleDropdown = () => {
|
|
133
|
+
if (dropdownRef.current) {
|
|
134
|
+
dropdownRef.current.menuVisible = !isOpen;
|
|
135
|
+
setIsOpen(!isOpen);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const closeDropdown = () => {
|
|
140
|
+
if (dropdownRef.current) {
|
|
141
|
+
dropdownRef.current.menuVisible = false;
|
|
142
|
+
setIsOpen(false);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
selectedValue,
|
|
148
|
+
isOpen,
|
|
149
|
+
dropdownRef,
|
|
150
|
+
handleItemSelect,
|
|
151
|
+
toggleDropdown,
|
|
152
|
+
closeDropdown,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ✅ CORRECT: Use the hook
|
|
157
|
+
function DropdownComponent() {
|
|
158
|
+
const {
|
|
159
|
+
selectedValue,
|
|
160
|
+
isOpen,
|
|
161
|
+
dropdownRef,
|
|
162
|
+
handleItemSelect,
|
|
163
|
+
toggleDropdown,
|
|
164
|
+
} = useDropdown();
|
|
165
|
+
|
|
166
|
+
const menuItems = [
|
|
167
|
+
{ label: "Option 1", value: "option1" },
|
|
168
|
+
{ label: "Option 2", value: "option2" },
|
|
169
|
+
{ label: "Option 3", value: "option3" },
|
|
170
|
+
];
|
|
171
|
+
|
|
172
|
+
return (
|
|
173
|
+
<ModusDropdownMenu
|
|
174
|
+
ref={dropdownRef}
|
|
175
|
+
menuVisible={isOpen}
|
|
176
|
+
onItemSelect={handleItemSelect}
|
|
177
|
+
buttonContent={
|
|
178
|
+
<ModusWcButton onClick={toggleDropdown}>
|
|
179
|
+
{selectedValue || "Select an option"}
|
|
180
|
+
</ModusWcButton>
|
|
181
|
+
}
|
|
182
|
+
menuItems={menuItems}
|
|
183
|
+
/>
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## 🎯 **Advanced Patterns**
|
|
189
|
+
|
|
190
|
+
### ✅ **Dropdown with Search**
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
// ✅ CORRECT: Dropdown with search functionality
|
|
194
|
+
function SearchableDropdown() {
|
|
195
|
+
const [selectedValue, setSelectedValue] = useState("");
|
|
196
|
+
const [searchTerm, setSearchTerm] = useState("");
|
|
197
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
198
|
+
const dropdownRef = useRef<ModusWcDropdownMenu>(null);
|
|
199
|
+
|
|
200
|
+
const options = [
|
|
201
|
+
{ value: "apple", label: "Apple" },
|
|
202
|
+
{ value: "banana", label: "Banana" },
|
|
203
|
+
{ value: "cherry", label: "Cherry" },
|
|
204
|
+
{ value: "date", label: "Date" },
|
|
205
|
+
{ value: "elderberry", label: "Elderberry" },
|
|
206
|
+
];
|
|
207
|
+
|
|
208
|
+
const filteredOptions = options.filter((option) =>
|
|
209
|
+
option.label.toLowerCase().includes(searchTerm.toLowerCase())
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
const handleItemSelect = (event: CustomEvent) => {
|
|
213
|
+
const value = event.detail;
|
|
214
|
+
setSelectedValue(value);
|
|
215
|
+
setIsOpen(false);
|
|
216
|
+
setSearchTerm("");
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const toggleDropdown = () => {
|
|
220
|
+
if (dropdownRef.current) {
|
|
221
|
+
const dropdown = dropdownRef.current.querySelector(
|
|
222
|
+
"modus-dropdown-menu"
|
|
223
|
+
) as any;
|
|
224
|
+
if (dropdown) {
|
|
225
|
+
if (isOpen) {
|
|
226
|
+
dropdown.close();
|
|
227
|
+
} else {
|
|
228
|
+
dropdown.open();
|
|
229
|
+
}
|
|
230
|
+
setIsOpen(!isOpen);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
return (
|
|
236
|
+
<div className="space-y-2">
|
|
237
|
+
<ModusWcButton onClick={toggleDropdown}>
|
|
238
|
+
{selectedValue || "Select an option"}
|
|
239
|
+
</ModusWcButton>
|
|
240
|
+
|
|
241
|
+
<ModusWcDropdownMenu ref={dropdownRef} onItemSelect={handleItemSelect}>
|
|
242
|
+
<div className="p-2">
|
|
243
|
+
<input
|
|
244
|
+
type="text"
|
|
245
|
+
placeholder="Search options..."
|
|
246
|
+
value={searchTerm}
|
|
247
|
+
onChange={(e) => setSearchTerm(e.target.value)}
|
|
248
|
+
className="w-full px-3 py-2 border border-input rounded bg-input text-foreground"
|
|
249
|
+
/>
|
|
250
|
+
</div>
|
|
251
|
+
|
|
252
|
+
{filteredOptions.map((option) => (
|
|
253
|
+
<ModusWcDropdownMenuItem key={option.value} value={option.value}>
|
|
254
|
+
{option.label}
|
|
255
|
+
</ModusWcDropdownMenuItem>
|
|
256
|
+
))}
|
|
257
|
+
</ModusWcDropdownMenu>
|
|
258
|
+
</div>
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### ✅ **Multi-Select Dropdown**
|
|
264
|
+
|
|
265
|
+
```tsx
|
|
266
|
+
// ✅ CORRECT: Multi-select dropdown
|
|
267
|
+
function MultiSelectDropdown() {
|
|
268
|
+
const [selectedValues, setSelectedValues] = useState<string[]>([]);
|
|
269
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
270
|
+
const dropdownRef = useRef<ModusWcDropdownMenu>(null);
|
|
271
|
+
|
|
272
|
+
const options = [
|
|
273
|
+
{ value: "option1", label: "Option 1" },
|
|
274
|
+
{ value: "option2", label: "Option 2" },
|
|
275
|
+
{ value: "option3", label: "Option 3" },
|
|
276
|
+
{ value: "option4", label: "Option 4" },
|
|
277
|
+
];
|
|
278
|
+
|
|
279
|
+
const handleItemSelect = (event: CustomEvent) => {
|
|
280
|
+
const value = event.detail;
|
|
281
|
+
setSelectedValues((prev) => {
|
|
282
|
+
if (prev.includes(value)) {
|
|
283
|
+
return prev.filter((v) => v !== value);
|
|
284
|
+
} else {
|
|
285
|
+
return [...prev, value];
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
const toggleDropdown = () => {
|
|
291
|
+
if (dropdownRef.current) {
|
|
292
|
+
const dropdown = dropdownRef.current.querySelector(
|
|
293
|
+
"modus-dropdown-menu"
|
|
294
|
+
) as any;
|
|
295
|
+
if (dropdown) {
|
|
296
|
+
if (isOpen) {
|
|
297
|
+
dropdown.close();
|
|
298
|
+
} else {
|
|
299
|
+
dropdown.open();
|
|
300
|
+
}
|
|
301
|
+
setIsOpen(!isOpen);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
return (
|
|
307
|
+
<div className="space-y-2">
|
|
308
|
+
<ModusWcButton onClick={toggleDropdown}>
|
|
309
|
+
{selectedValues.length > 0
|
|
310
|
+
? `${selectedValues.length} selected`
|
|
311
|
+
: "Select options"}
|
|
312
|
+
</ModusWcButton>
|
|
313
|
+
|
|
314
|
+
<ModusWcDropdownMenu ref={dropdownRef} onItemSelect={handleItemSelect}>
|
|
315
|
+
{options.map((option) => (
|
|
316
|
+
<ModusWcDropdownMenuItem
|
|
317
|
+
key={option.value}
|
|
318
|
+
value={option.value}
|
|
319
|
+
className={
|
|
320
|
+
selectedValues.includes(option.value)
|
|
321
|
+
? "bg-primary text-primary-foreground"
|
|
322
|
+
: ""
|
|
323
|
+
}
|
|
324
|
+
>
|
|
325
|
+
{option.label}
|
|
326
|
+
</ModusWcDropdownMenuItem>
|
|
327
|
+
))}
|
|
328
|
+
</ModusWcDropdownMenu>
|
|
329
|
+
</div>
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## 🔧 **Testing Patterns**
|
|
335
|
+
|
|
336
|
+
### ✅ **Test Dropdown Reliability**
|
|
337
|
+
|
|
338
|
+
```tsx
|
|
339
|
+
// ✅ CORRECT: Test dropdown reliability
|
|
340
|
+
function DropdownTest() {
|
|
341
|
+
const [testResults, setTestResults] = useState<string[]>([]);
|
|
342
|
+
const dropdownRef = useRef<ModusWcDropdownMenu>(null);
|
|
343
|
+
|
|
344
|
+
const testDropdown = () => {
|
|
345
|
+
if (dropdownRef.current) {
|
|
346
|
+
const dropdown = dropdownRef.current.querySelector(
|
|
347
|
+
"modus-dropdown-menu"
|
|
348
|
+
) as any;
|
|
349
|
+
if (dropdown) {
|
|
350
|
+
dropdown.open();
|
|
351
|
+
setTestResults((prev) => [...prev, "Dropdown opened"]);
|
|
352
|
+
|
|
353
|
+
setTimeout(() => {
|
|
354
|
+
dropdown.close();
|
|
355
|
+
setTestResults((prev) => [...prev, "Dropdown closed"]);
|
|
356
|
+
}, 1000);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
const handleItemSelect = (event: CustomEvent) => {
|
|
362
|
+
const value = event.detail;
|
|
363
|
+
setTestResults((prev) => [...prev, `Item selected: ${value}`]);
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
return (
|
|
367
|
+
<div className="space-y-4">
|
|
368
|
+
<ModusWcButton onClick={testDropdown}>Test Dropdown</ModusWcButton>
|
|
369
|
+
|
|
370
|
+
<ModusWcDropdownMenu ref={dropdownRef} onItemSelect={handleItemSelect}>
|
|
371
|
+
<ModusWcDropdownMenuItem value="test1">
|
|
372
|
+
Test Option 1
|
|
373
|
+
</ModusWcDropdownMenuItem>
|
|
374
|
+
<ModusWcDropdownMenuItem value="test2">
|
|
375
|
+
Test Option 2
|
|
376
|
+
</ModusWcDropdownMenuItem>
|
|
377
|
+
</ModusWcDropdownMenu>
|
|
378
|
+
|
|
379
|
+
<div>
|
|
380
|
+
<h3>Test Results:</h3>
|
|
381
|
+
{testResults.map((result, index) => (
|
|
382
|
+
<div key={index}>{result}</div>
|
|
383
|
+
))}
|
|
384
|
+
</div>
|
|
385
|
+
</div>
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
## 🚫 **What NOT to Do**
|
|
391
|
+
|
|
392
|
+
### ❌ **Don't Use ModusSelect**
|
|
393
|
+
|
|
394
|
+
```tsx
|
|
395
|
+
// ❌ WRONG: Don't use ModusSelect
|
|
396
|
+
const options = [{ label: "Option 1", value: "1" }];
|
|
397
|
+
<ModusSelect options={options} onInputChange={handleChange} />;
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### ❌ **Don't Rely on ModusSelect Events**
|
|
401
|
+
|
|
402
|
+
```tsx
|
|
403
|
+
// ❌ WRONG: Don't rely on ModusSelect events
|
|
404
|
+
const handleInputChange = (event: CustomEvent<InputEvent>) => {
|
|
405
|
+
// This may not fire reliably in React
|
|
406
|
+
setValue(event.target.value);
|
|
407
|
+
};
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### ❌ **Don't Mix Select and Dropdown**
|
|
411
|
+
|
|
412
|
+
```tsx
|
|
413
|
+
// ❌ WRONG: Don't mix select and dropdown
|
|
414
|
+
<div>
|
|
415
|
+
<ModusSelect options={options} onInputChange={handleSelect} />
|
|
416
|
+
{/* ❌ Unreliable */}
|
|
417
|
+
|
|
418
|
+
<ModusDropdownMenu menuItems={menuItems} onItemSelect={handleDropdown} />
|
|
419
|
+
{/* ✅ Reliable */}
|
|
420
|
+
</div>
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
## 🎯 **Key Takeaways**
|
|
424
|
+
|
|
425
|
+
1. **Use ModusDropdownMenu**: Always use `ModusDropdownMenu` instead of `ModusSelect`
|
|
426
|
+
2. **Reliable Events**: `itemSelect` events are more reliable than `inputChange` events
|
|
427
|
+
3. **Programmatic Control**: Use `menuVisible` property for programmatic control
|
|
428
|
+
4. **Event Handling**: Use proper event handling patterns with refs
|
|
429
|
+
5. **Testing**: Test dropdown functionality thoroughly
|
|
430
|
+
|
|
431
|
+
## 🔍 **Dropdown Implementation Checklist**
|
|
432
|
+
|
|
433
|
+
- [ ] ✅ **Use ModusDropdownMenu**: Never use ModusSelect
|
|
434
|
+
- [ ] ✅ **Event Handling**: Use itemSelect events for reliability
|
|
435
|
+
- [ ] ✅ **Programmatic Control**: Use menuVisible property for control
|
|
436
|
+
- [ ] ✅ **State Management**: Proper state management with React
|
|
437
|
+
- [ ] ✅ **Testing**: Test dropdown functionality and events
|
|
438
|
+
- [ ] ✅ **Accessibility**: Ensure proper accessibility with dropdown
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
**Remember: ModusSelect has unreliable event handling in React applications. Always use ModusDropdownMenu with itemSelect events for reliable dropdown functionality. Use menuVisible property for programmatic control and proper event handling patterns.**
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Use div elements exclusively to avoid Tailwind CSS conflicts
|
|
3
|
+
globs: ["**/*.tsx"]
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Modus Semantic HTML - Short
|
|
8
|
+
|
|
9
|
+
Use div elements exclusively to avoid Tailwind CSS conflicts.
|
|
10
|
+
|
|
11
|
+
## Key Rules
|
|
12
|
+
|
|
13
|
+
- **Use div elements only** - All content must use `<div>` elements
|
|
14
|
+
- **No semantic HTML elements** - Never use `h1`, `p`, `section`, `header`, `footer`, `nav`, `main`, `aside`, `article`, `span`
|
|
15
|
+
- **Use Tailwind classes for styling** - Apply typography and layout with Tailwind classes
|
|
16
|
+
- **Icon exception** - Only `<i>` elements allowed for Modus icons
|
|
17
|
+
- **Consistent structure** - Maintain consistent div-based component structure
|
|
18
|
+
- **Accessibility with divs** - Ensure proper accessibility with div elements
|
|
19
|
+
- **Test rendering** - Verify components render correctly in all themes
|
|
20
|
+
|
|
21
|
+
## Reference
|
|
22
|
+
|
|
23
|
+
For detailed HTML patterns, accessibility guidelines, and advanced div usage, fetch the full rule: `modus-semantic-html-react`
|