@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,445 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Essential state management patterns for Modus Accordion components in React
|
|
3
|
+
globs: ["**/components/ModusAccordion*.tsx", "**/demos/**/page.tsx"]
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Modus Accordion State Management in React
|
|
8
|
+
|
|
9
|
+
## 🚨 **IMPORTANT: Accordion State Management Guidelines**
|
|
10
|
+
|
|
11
|
+
**Key Principle**: Modus Web Components (`ModusWcAccordion`, `ModusWcCollapse`) are designed to manage their own state, but they DO support controlled state when needed.
|
|
12
|
+
|
|
13
|
+
**Best Practice**: Use the `expanded` attribute on `ModusWcCollapse` components for initial state or programmatic control, but avoid trying to synchronize React state with Modus state in real-time.
|
|
14
|
+
|
|
15
|
+
## ❌ **Common Anti-Patterns**
|
|
16
|
+
|
|
17
|
+
### ❌ **Real-time State Synchronization**
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
// ❌ WRONG: Trying to sync React state with Modus state in real-time
|
|
21
|
+
function AccordionComponent() {
|
|
22
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<ModusWcAccordion
|
|
26
|
+
onExpandedChange={(e) => setIsExpanded(e.detail.expanded)} // ❌ Creates state loop
|
|
27
|
+
>
|
|
28
|
+
<ModusWcCollapse expanded={isExpanded}>
|
|
29
|
+
{" "}
|
|
30
|
+
{/* ❌ This causes conflicts */}
|
|
31
|
+
<div slot="content">Content</div>
|
|
32
|
+
</ModusWcCollapse>
|
|
33
|
+
</ModusWcAccordion>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### ❌ **Complex State Synchronization**
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
// ❌ WRONG: Complex state synchronization that can cause loops
|
|
42
|
+
function MyComponent() {
|
|
43
|
+
const [accordionStates, setAccordionStates] = useState({
|
|
44
|
+
accordion1: false,
|
|
45
|
+
accordion2: true,
|
|
46
|
+
accordion3: false,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const toggleAccordion = (id: string) => {
|
|
50
|
+
setAccordionStates((prev) => ({
|
|
51
|
+
...prev,
|
|
52
|
+
[id]: !prev[id],
|
|
53
|
+
}));
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<div>
|
|
58
|
+
{Object.entries(accordionStates).map(([id, isExpanded]) => (
|
|
59
|
+
<ModusWcAccordion
|
|
60
|
+
key={id}
|
|
61
|
+
onExpandedChange={() => toggleAccordion(id)} // ❌ Creates state loops
|
|
62
|
+
>
|
|
63
|
+
<ModusWcCollapse expanded={isExpanded}>
|
|
64
|
+
{" "}
|
|
65
|
+
{/* ❌ This can cause conflicts */}
|
|
66
|
+
<div slot="content">Content for {id}</div>
|
|
67
|
+
</ModusWcCollapse>
|
|
68
|
+
</ModusWcAccordion>
|
|
69
|
+
))}
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## ✅ **Correct Patterns**
|
|
76
|
+
|
|
77
|
+
### ✅ **Let Modus Components Manage Their Own State**
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
// ✅ CORRECT: Let Modus accordion manage its own state
|
|
81
|
+
function AccordionComponent() {
|
|
82
|
+
return (
|
|
83
|
+
<ModusWcAccordion>
|
|
84
|
+
<ModusWcCollapse
|
|
85
|
+
collapse-id="item1"
|
|
86
|
+
options={{
|
|
87
|
+
title: "Item One",
|
|
88
|
+
description: "First accordion item",
|
|
89
|
+
icon: "star",
|
|
90
|
+
}}
|
|
91
|
+
>
|
|
92
|
+
<div slot="content">Content for item one.</div>
|
|
93
|
+
</ModusWcCollapse>
|
|
94
|
+
</ModusWcAccordion>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### ✅ **Initial State Control (Recommended)**
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
// ✅ CORRECT: Set initial state without real-time synchronization
|
|
103
|
+
function AccordionComponent() {
|
|
104
|
+
return (
|
|
105
|
+
<ModusWcAccordion>
|
|
106
|
+
<ModusWcCollapse
|
|
107
|
+
collapse-id="item1"
|
|
108
|
+
expanded={true} // ✅ CORRECT: Initial state is fine
|
|
109
|
+
options={{
|
|
110
|
+
title: "Initially Open",
|
|
111
|
+
description: "This item starts expanded",
|
|
112
|
+
}}
|
|
113
|
+
>
|
|
114
|
+
<div slot="content">Content for item one.</div>
|
|
115
|
+
</ModusWcCollapse>
|
|
116
|
+
</ModusWcAccordion>
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### ✅ **Listen to Events for Tracking (Not Control)**
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
// ✅ CORRECT: Listen to events for tracking, don't control state
|
|
125
|
+
function AccordionComponent() {
|
|
126
|
+
const [trackingData, setTrackingData] = useState({
|
|
127
|
+
accordionOpened: false,
|
|
128
|
+
openCount: 0,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const handleAccordionChange = (
|
|
132
|
+
event: CustomEvent<{ expanded: boolean; index: number }>
|
|
133
|
+
) => {
|
|
134
|
+
const { expanded, index } = event.detail;
|
|
135
|
+
|
|
136
|
+
// ✅ CORRECT: Use for tracking/analytics, not state control
|
|
137
|
+
setTrackingData((prev) => ({
|
|
138
|
+
accordionOpened: expanded,
|
|
139
|
+
openCount: expanded ? prev.openCount + 1 : prev.openCount,
|
|
140
|
+
}));
|
|
141
|
+
|
|
142
|
+
// ✅ CORRECT: Log for analytics
|
|
143
|
+
console.log(
|
|
144
|
+
`Accordion item ${index} is now ${expanded ? "open" : "closed"}`
|
|
145
|
+
);
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
return (
|
|
149
|
+
<ModusWcAccordion onExpandedChange={handleAccordionChange}>
|
|
150
|
+
<ModusWcCollapse
|
|
151
|
+
collapse-id="item1"
|
|
152
|
+
options={{
|
|
153
|
+
title: "Item One",
|
|
154
|
+
description: "First accordion item",
|
|
155
|
+
}}
|
|
156
|
+
>
|
|
157
|
+
<div slot="content">Content for item one.</div>
|
|
158
|
+
</ModusWcCollapse>
|
|
159
|
+
</ModusWcAccordion>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### ✅ **Programmatic Control When Needed**
|
|
165
|
+
|
|
166
|
+
```tsx
|
|
167
|
+
// ✅ CORRECT: Use refs for programmatic control
|
|
168
|
+
function AccordionComponent() {
|
|
169
|
+
const collapseRef = useRef<ModusWcCollapse>(null);
|
|
170
|
+
|
|
171
|
+
const openAccordion = () => {
|
|
172
|
+
// ✅ CORRECT: Use ref to control collapse programmatically
|
|
173
|
+
if (collapseRef.current) {
|
|
174
|
+
collapseRef.current.expanded = true;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const closeAccordion = () => {
|
|
179
|
+
// ✅ CORRECT: Use ref to control collapse programmatically
|
|
180
|
+
if (collapseRef.current) {
|
|
181
|
+
collapseRef.current.expanded = false;
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
return (
|
|
186
|
+
<div>
|
|
187
|
+
<button onClick={openAccordion}>Open Accordion</button>
|
|
188
|
+
<button onClick={closeAccordion}>Close Accordion</button>
|
|
189
|
+
|
|
190
|
+
<ModusWcAccordion>
|
|
191
|
+
<ModusWcCollapse
|
|
192
|
+
ref={collapseRef}
|
|
193
|
+
collapse-id="item1"
|
|
194
|
+
options={{
|
|
195
|
+
title: "Controllable Item",
|
|
196
|
+
description: "This can be controlled programmatically",
|
|
197
|
+
}}
|
|
198
|
+
>
|
|
199
|
+
<div slot="content">Content for controllable item.</div>
|
|
200
|
+
</ModusWcCollapse>
|
|
201
|
+
</ModusWcAccordion>
|
|
202
|
+
</div>
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## 🎯 **Best Practices**
|
|
208
|
+
|
|
209
|
+
### ✅ **State Management Strategy**
|
|
210
|
+
|
|
211
|
+
1. **Let Modus Components Own Their State**
|
|
212
|
+
|
|
213
|
+
- Don't try to control `expanded` from React
|
|
214
|
+
- Use events to track state changes
|
|
215
|
+
- Use refs for programmatic control when needed
|
|
216
|
+
|
|
217
|
+
2. **Event-Driven Architecture**
|
|
218
|
+
|
|
219
|
+
```tsx
|
|
220
|
+
// ✅ CORRECT: Event-driven approach
|
|
221
|
+
function MyComponent() {
|
|
222
|
+
const handleAccordionChange = (event: CustomEvent) => {
|
|
223
|
+
// Handle the event for tracking, analytics, or side effects
|
|
224
|
+
// Don't try to control the accordion state
|
|
225
|
+
console.log("Accordion expanded:", event.detail);
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
return (
|
|
229
|
+
<ModusWcAccordion onExpandedChange={handleAccordionChange}>
|
|
230
|
+
<div slot="header">Header</div>
|
|
231
|
+
<div slot="body">Body</div>
|
|
232
|
+
</ModusWcAccordion>
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
3. **Use Refs for Programmatic Control**
|
|
238
|
+
|
|
239
|
+
```tsx
|
|
240
|
+
// ✅ CORRECT: Ref-based control
|
|
241
|
+
const accordionRef = useRef<ModusWcAccordion>(null);
|
|
242
|
+
|
|
243
|
+
const toggleAccordion = () => {
|
|
244
|
+
if (accordionRef.current) {
|
|
245
|
+
accordionRef.current.expanded = !accordionRef.current.expanded;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### ✅ **Multiple Accordions Pattern**
|
|
251
|
+
|
|
252
|
+
```tsx
|
|
253
|
+
// ✅ CORRECT: Multiple accordions with independent state
|
|
254
|
+
function MultipleAccordions() {
|
|
255
|
+
const accordionRefs = useRef<(ModusWcAccordion | null)[]>([]);
|
|
256
|
+
|
|
257
|
+
const openAllAccordions = () => {
|
|
258
|
+
accordionRefs.current.forEach((ref) => {
|
|
259
|
+
if (ref) ref.expanded = true;
|
|
260
|
+
});
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const closeAllAccordions = () => {
|
|
264
|
+
accordionRefs.current.forEach((ref) => {
|
|
265
|
+
if (ref) ref.expanded = false;
|
|
266
|
+
});
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
return (
|
|
270
|
+
<div>
|
|
271
|
+
<button onClick={openAllAccordions}>Open All</button>
|
|
272
|
+
<button onClick={closeAllAccordions}>Close All</button>
|
|
273
|
+
|
|
274
|
+
{accordionData.map((item, index) => (
|
|
275
|
+
<ModusWcAccordion
|
|
276
|
+
key={item.id}
|
|
277
|
+
ref={(el) => (accordionRefs.current[index] = el)}
|
|
278
|
+
>
|
|
279
|
+
<div slot="header">{item.title}</div>
|
|
280
|
+
<div slot="body">{item.content}</div>
|
|
281
|
+
</ModusWcAccordion>
|
|
282
|
+
))}
|
|
283
|
+
</div>
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## 🔧 **Advanced Patterns**
|
|
289
|
+
|
|
290
|
+
### ✅ **Accordion with External State Tracking**
|
|
291
|
+
|
|
292
|
+
```tsx
|
|
293
|
+
// ✅ CORRECT: Track accordion state without controlling it
|
|
294
|
+
function AccordionWithTracking() {
|
|
295
|
+
const [accordionStates, setAccordionStates] = useState<
|
|
296
|
+
Record<string, boolean>
|
|
297
|
+
>({});
|
|
298
|
+
|
|
299
|
+
const handleAccordionChange = (id: string) => (event: CustomEvent) => {
|
|
300
|
+
const isExpanded = event.detail;
|
|
301
|
+
|
|
302
|
+
// ✅ CORRECT: Track state for analytics/UI updates
|
|
303
|
+
setAccordionStates((prev) => ({
|
|
304
|
+
...prev,
|
|
305
|
+
[id]: isExpanded,
|
|
306
|
+
}));
|
|
307
|
+
|
|
308
|
+
// ✅ CORRECT: Use for conditional rendering or analytics
|
|
309
|
+
if (isExpanded) {
|
|
310
|
+
console.log(`Accordion ${id} opened`);
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
return (
|
|
315
|
+
<div>
|
|
316
|
+
{accordionData.map((item) => (
|
|
317
|
+
<ModusWcAccordion
|
|
318
|
+
key={item.id}
|
|
319
|
+
onExpandedChange={handleAccordionChange(item.id)}
|
|
320
|
+
>
|
|
321
|
+
<div slot="header">
|
|
322
|
+
{item.title}
|
|
323
|
+
{accordionStates[item.id] && <span> (Open)</span>}
|
|
324
|
+
</div>
|
|
325
|
+
<div slot="body">{item.content}</div>
|
|
326
|
+
</ModusWcAccordion>
|
|
327
|
+
))}
|
|
328
|
+
</div>
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### ✅ **Accordion with Conditional Content**
|
|
334
|
+
|
|
335
|
+
```tsx
|
|
336
|
+
// ✅ CORRECT: Use events to show/hide related content
|
|
337
|
+
function AccordionWithConditionalContent() {
|
|
338
|
+
const [activeAccordion, setActiveAccordion] = useState<string | null>(null);
|
|
339
|
+
|
|
340
|
+
const handleAccordionChange = (id: string) => (event: CustomEvent) => {
|
|
341
|
+
const isExpanded = event.detail;
|
|
342
|
+
setActiveAccordion(isExpanded ? id : null);
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
return (
|
|
346
|
+
<div>
|
|
347
|
+
{accordionData.map((item) => (
|
|
348
|
+
<div key={item.id}>
|
|
349
|
+
<ModusWcAccordion onExpandedChange={handleAccordionChange(item.id)}>
|
|
350
|
+
<div slot="header">{item.title}</div>
|
|
351
|
+
<div slot="body">{item.content}</div>
|
|
352
|
+
</ModusWcAccordion>
|
|
353
|
+
|
|
354
|
+
{/* ✅ CORRECT: Show additional content based on accordion state */}
|
|
355
|
+
{activeAccordion === item.id && (
|
|
356
|
+
<div className="mt-4 p-4 bg-muted rounded">
|
|
357
|
+
Additional content for {item.title}
|
|
358
|
+
</div>
|
|
359
|
+
)}
|
|
360
|
+
</div>
|
|
361
|
+
))}
|
|
362
|
+
</div>
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## 🚫 **What NOT to Do**
|
|
368
|
+
|
|
369
|
+
### ❌ **Don't Control State from React**
|
|
370
|
+
|
|
371
|
+
```tsx
|
|
372
|
+
// ❌ WRONG: Don't do this
|
|
373
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
374
|
+
|
|
375
|
+
<ModusWcAccordion
|
|
376
|
+
expanded={isExpanded} // ❌ This causes conflicts
|
|
377
|
+
onExpandedChange={(e) => setIsExpanded(e.detail)} // ❌ Creates loops
|
|
378
|
+
>
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### ❌ **Don't Use React State for Accordion Logic**
|
|
382
|
+
|
|
383
|
+
```tsx
|
|
384
|
+
// ❌ WRONG: Don't manage accordion state in React
|
|
385
|
+
const [accordionState, setAccordionState] = useState({
|
|
386
|
+
accordion1: false,
|
|
387
|
+
accordion2: true,
|
|
388
|
+
});
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### ❌ **Don't Try to Sync React and Modus State**
|
|
392
|
+
|
|
393
|
+
```tsx
|
|
394
|
+
// ❌ WRONG: Don't try to sync states
|
|
395
|
+
useEffect(() => {
|
|
396
|
+
// This will cause infinite loops
|
|
397
|
+
if (reactState !== modusState) {
|
|
398
|
+
setReactState(modusState);
|
|
399
|
+
}
|
|
400
|
+
}, [reactState, modusState]);
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
## 🎯 **Key Takeaways**
|
|
404
|
+
|
|
405
|
+
1. **Initial State is Fine**: Setting `expanded={true}` for initial state is perfectly acceptable
|
|
406
|
+
2. **Avoid Real-time Sync**: Don't try to synchronize React state with Modus state in real-time
|
|
407
|
+
3. **Use Events for Tracking**: Listen to `onExpandedChange` for analytics and side effects
|
|
408
|
+
4. **Use Refs for Control**: When you need programmatic control, use refs on `ModusWcCollapse`
|
|
409
|
+
5. **Trust the Component**: Modus Web Components handle their own state changes after initial render
|
|
410
|
+
6. **Proper Structure**: Use `ModusWcAccordion` with `ModusWcCollapse` components and `options` for headers
|
|
411
|
+
|
|
412
|
+
## 🔍 **Testing Accordion State**
|
|
413
|
+
|
|
414
|
+
```tsx
|
|
415
|
+
// ✅ CORRECT: Test accordion behavior
|
|
416
|
+
function TestAccordion() {
|
|
417
|
+
const accordionRef = useRef<ModusWcAccordion>(null);
|
|
418
|
+
|
|
419
|
+
const testAccordion = () => {
|
|
420
|
+
if (accordionRef.current) {
|
|
421
|
+
// Test opening
|
|
422
|
+
accordionRef.current.expanded = true;
|
|
423
|
+
|
|
424
|
+
setTimeout(() => {
|
|
425
|
+
// Test closing
|
|
426
|
+
accordionRef.current!.expanded = false;
|
|
427
|
+
}, 1000);
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
return (
|
|
432
|
+
<div>
|
|
433
|
+
<button onClick={testAccordion}>Test Accordion</button>
|
|
434
|
+
<ModusWcAccordion ref={accordionRef}>
|
|
435
|
+
<div slot="header">Test Header</div>
|
|
436
|
+
<div slot="body">Test Body</div>
|
|
437
|
+
</ModusWcAccordion>
|
|
438
|
+
</div>
|
|
439
|
+
);
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
**Remember: Modus accordion components support controlled initial state but avoid real-time synchronization. Use `expanded` for initial state, `onExpandedChange` for tracking, and refs for programmatic control. This approach prevents conflicts and ensures reliable behavior.**
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Critical pattern for ModusButton inside ModusButtonGroup
|
|
3
|
+
globs: ["**/components/ModusButton*.tsx", "**/demos/**/page.tsx"]
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Modus Button Group Usage - Short
|
|
8
|
+
|
|
9
|
+
Critical pattern to avoid styling conflicts in button groups.
|
|
10
|
+
|
|
11
|
+
## Key Rules
|
|
12
|
+
|
|
13
|
+
- **No defaults for variant/color in ModusButton** - Defaults override button group settings
|
|
14
|
+
- **Use conditional prop spreading** - `{...(variant && { variant })}` to only pass when defined
|
|
15
|
+
- **Group controls styling** - ModusButtonGroup applies variant/color to all child buttons
|
|
16
|
+
- **Don't set variant/color on buttons inside groups** - Let the group control them
|
|
17
|
+
- **Explicitly set props for standalone buttons** - When not in a group, set variant and color
|
|
18
|
+
- **Group uses setAttribute after load** - DOM manipulation requires no conflicting React props
|
|
19
|
+
- **Test all three variants** - Outlined, filled, and borderless should look distinct
|
|
20
|
+
|
|
21
|
+
## Reference
|
|
22
|
+
|
|
23
|
+
For detailed patterns, web component internals, and testing checklist, fetch the full rule: `modus-button-group-usage-react`
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Critical pattern for ModusButton inside ModusButtonGroup
|
|
3
|
+
globs: ["**/components/ModusButton*.tsx", "**/demos/**/page.tsx"]
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Modus Button Group Usage
|
|
8
|
+
|
|
9
|
+
Critical patterns for using ModusButton components inside ModusButtonGroup.
|
|
10
|
+
|
|
11
|
+
## The Problem
|
|
12
|
+
|
|
13
|
+
When `ModusButton` has default values for `variant` and `color`, these explicit values **override** the `ModusButtonGroup`'s settings. This causes all buttons to look the same regardless of the group's variant prop.
|
|
14
|
+
|
|
15
|
+
## Root Cause
|
|
16
|
+
|
|
17
|
+
The `modus-wc-button-group` web component uses `setAttribute()` to apply its `variant` and `color` to child buttons **after** they load. If React buttons have explicit defaults, they override the group's settings.
|
|
18
|
+
|
|
19
|
+
## Correct Pattern
|
|
20
|
+
|
|
21
|
+
### ModusButton Component
|
|
22
|
+
|
|
23
|
+
Do NOT set defaults for `variant` or `color` in the ModusButton wrapper:
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
// CORRECT - No defaults, allows inheritance from button group
|
|
27
|
+
export default function ModusButton({
|
|
28
|
+
color, // undefined by default
|
|
29
|
+
variant, // undefined by default
|
|
30
|
+
size = "md",
|
|
31
|
+
// ...other props
|
|
32
|
+
}: ModusButtonProps) {
|
|
33
|
+
return (
|
|
34
|
+
<ModusWcButton
|
|
35
|
+
{...(color && { color })} // Only pass if defined
|
|
36
|
+
{...(variant && { variant })} // Only pass if defined
|
|
37
|
+
size={size}
|
|
38
|
+
// ...other props
|
|
39
|
+
>
|
|
40
|
+
{children}
|
|
41
|
+
</ModusWcButton>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
// WRONG - Defaults override button group settings
|
|
48
|
+
export default function ModusButton({
|
|
49
|
+
color = "primary", // BAD: Will override group's color
|
|
50
|
+
variant = "filled", // BAD: Will override group's variant
|
|
51
|
+
// ...
|
|
52
|
+
}: ModusButtonProps) {
|
|
53
|
+
// ...
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Using ModusButton Standalone
|
|
58
|
+
|
|
59
|
+
When using `ModusButton` outside a button group, explicitly set the props you need:
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
// Standalone button - explicitly set variant and color
|
|
63
|
+
<ModusButton variant="filled" color="primary">
|
|
64
|
+
Click Me
|
|
65
|
+
</ModusButton>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Using ModusButton in a Button Group
|
|
69
|
+
|
|
70
|
+
When inside a `ModusButtonGroup`, do NOT set variant/color on individual buttons:
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
// CORRECT - Group controls all button styling
|
|
74
|
+
<ModusButtonGroup variant="outlined" color="primary">
|
|
75
|
+
<ModusButton>Button 1</ModusButton>
|
|
76
|
+
<ModusButton>Button 2</ModusButton>
|
|
77
|
+
<ModusButton>Button 3</ModusButton>
|
|
78
|
+
</ModusButtonGroup>
|
|
79
|
+
|
|
80
|
+
// WRONG - Individual button props override group settings
|
|
81
|
+
<ModusButtonGroup variant="outlined" color="primary">
|
|
82
|
+
<ModusButton variant="filled">Button 1</ModusButton> // BAD
|
|
83
|
+
<ModusButton color="danger">Button 2</ModusButton> // BAD
|
|
84
|
+
</ModusButtonGroup>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## How ModusButtonGroup Works
|
|
88
|
+
|
|
89
|
+
The web component applies styling to children via DOM manipulation:
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
// Inside modus-wc-button-group.tsx
|
|
93
|
+
private syncButtonStates(): void {
|
|
94
|
+
this.buttonElements = this.el.querySelectorAll('modus-wc-button');
|
|
95
|
+
this.setButtonAttribute('variant', this.variant);
|
|
96
|
+
this.setButtonAttribute('color', this.color || null);
|
|
97
|
+
this.setButtonAttribute('disabled', this.disabled ? 'true' : null);
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
This only works if child buttons don't have explicit values that override the setAttribute calls.
|
|
102
|
+
|
|
103
|
+
## Quick Reference
|
|
104
|
+
|
|
105
|
+
| Context | variant | color | Notes |
|
|
106
|
+
| ------------------------------ | ---------------------- | ---------------------- | -------------------------------- |
|
|
107
|
+
| Standalone button | Set explicitly | Set explicitly | Button controls its own style |
|
|
108
|
+
| Inside button group | Do NOT set | Do NOT set | Group controls all button styles |
|
|
109
|
+
| Mixed (some grouped, some not) | Set only on standalone | Set only on standalone | Follow context rules |
|
|
110
|
+
|
|
111
|
+
## Testing Checklist
|
|
112
|
+
|
|
113
|
+
- [ ] Outlined variant shows bordered buttons with transparent background
|
|
114
|
+
- [ ] Filled variant shows solid colored buttons
|
|
115
|
+
- [ ] Borderless variant shows text-only buttons without borders
|
|
116
|
+
- [ ] Color prop applies consistently to all buttons in group
|
|
117
|
+
- [ ] Individual buttons don't override group styling
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Critical bug fix for ModusWcCheckbox value property inversion
|
|
3
|
+
globs: ["**/components/ModusCheckbox*.tsx", "**/demos/**/page.tsx"]
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Modus Checkbox Value Inversion - Short
|
|
8
|
+
|
|
9
|
+
Critical bug fix for ModusWcCheckbox value property inversion.
|
|
10
|
+
|
|
11
|
+
## Key Rules
|
|
12
|
+
|
|
13
|
+
- **Always invert checkbox value property** - `const actualChecked = !value` from `inputChange` event
|
|
14
|
+
- **Use wrapper components** - Create React wrapper to handle inversion automatically
|
|
15
|
+
- **Never trust the raw value** - The `value` property is inverted (false when checked, true when unchecked)
|
|
16
|
+
- **Handle in event handlers** - Invert value in `onInputChange` event handler
|
|
17
|
+
- **Use utility functions** - Create helper functions for value inversion
|
|
18
|
+
- **Test thoroughly** - Verify checkbox behavior matches expected state
|
|
19
|
+
- **Document the bug** - Make team aware of this critical issue
|
|
20
|
+
|
|
21
|
+
## Reference
|
|
22
|
+
|
|
23
|
+
For detailed bug explanation, wrapper component patterns, and utility functions, fetch the full rule: `modus-checkbox-value-inversion-react`
|