@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,75 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef } from "react";
|
|
4
|
+
import { ModusWcBreadcrumbs } from "@trimble-oss/moduswebcomponents-react";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Represents a single item in the breadcrumb trail.
|
|
8
|
+
*/
|
|
9
|
+
export interface BreadcrumbItem {
|
|
10
|
+
/** The text to display for the breadcrumb item. */
|
|
11
|
+
label: string;
|
|
12
|
+
/** The URL to navigate to when the breadcrumb item is clicked. */
|
|
13
|
+
url?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Props for the ModusBreadcrumbs component.
|
|
18
|
+
*/
|
|
19
|
+
export interface ModusBreadcrumbsProps {
|
|
20
|
+
/** The items to display in the breadcrumb trail. */
|
|
21
|
+
items: BreadcrumbItem[];
|
|
22
|
+
/** The size of the breadcrumbs. */
|
|
23
|
+
size?: 'sm' | 'md' | 'lg';
|
|
24
|
+
/** A custom CSS class to apply to the breadcrumbs. */
|
|
25
|
+
customClass?: string;
|
|
26
|
+
/** The ARIA label for the breadcrumbs. */
|
|
27
|
+
'aria-label'?: string;
|
|
28
|
+
/** A callback function to handle breadcrumb item clicks. */
|
|
29
|
+
onBreadcrumbClick?: (event: CustomEvent<BreadcrumbItem>) => void;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Renders a Modus breadcrumbs component.
|
|
34
|
+
* @param {ModusBreadcrumbsProps} props - The component props.
|
|
35
|
+
* @param {BreadcrumbItem[]} props.items - The items to display in the breadcrumb trail.
|
|
36
|
+
* @param {'sm' | 'md' | 'lg'} [props.size='md'] - The size of the breadcrumbs.
|
|
37
|
+
* @param {string} [props.customClass] - A custom CSS class to apply to the breadcrumbs.
|
|
38
|
+
* @param {string} [props.aria-label] - The ARIA label for the breadcrumbs.
|
|
39
|
+
* @param {(event: CustomEvent<BreadcrumbItem>) => void} [props.onBreadcrumbClick] - A callback function to handle breadcrumb item clicks.
|
|
40
|
+
* @returns {JSX.Element} The rendered breadcrumbs component.
|
|
41
|
+
*/
|
|
42
|
+
export default function ModusBreadcrumbs({
|
|
43
|
+
items,
|
|
44
|
+
size = 'md',
|
|
45
|
+
customClass,
|
|
46
|
+
'aria-label': ariaLabel,
|
|
47
|
+
onBreadcrumbClick,
|
|
48
|
+
}: ModusBreadcrumbsProps) {
|
|
49
|
+
const breadcrumbsRef = useRef<HTMLModusWcBreadcrumbsElement>(null);
|
|
50
|
+
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
const breadcrumbs = breadcrumbsRef.current;
|
|
53
|
+
if (!breadcrumbs || !onBreadcrumbClick) return;
|
|
54
|
+
|
|
55
|
+
const handleBreadcrumbClick = (event: Event) => {
|
|
56
|
+
const customEvent = event as CustomEvent<BreadcrumbItem>;
|
|
57
|
+
onBreadcrumbClick(customEvent);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
breadcrumbs.addEventListener("breadcrumbClick", handleBreadcrumbClick);
|
|
61
|
+
return () => {
|
|
62
|
+
breadcrumbs.removeEventListener("breadcrumbClick", handleBreadcrumbClick);
|
|
63
|
+
};
|
|
64
|
+
}, [onBreadcrumbClick]);
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<ModusWcBreadcrumbs
|
|
68
|
+
ref={breadcrumbsRef}
|
|
69
|
+
items={items}
|
|
70
|
+
size={size}
|
|
71
|
+
customClass={customClass}
|
|
72
|
+
aria-label={ariaLabel}
|
|
73
|
+
/>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { ModusWcButton } from "@trimble-oss/moduswebcomponents-react";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Props for the ModusButton component.
|
|
6
|
+
*/
|
|
7
|
+
interface ModusButtonProps {
|
|
8
|
+
/** The color of the button. */
|
|
9
|
+
color?: "primary" | "secondary" | "tertiary" | "warning" | "danger";
|
|
10
|
+
/** The variant of the button. */
|
|
11
|
+
variant?: "filled" | "outlined" | "borderless";
|
|
12
|
+
/** The size of the button. */
|
|
13
|
+
size?: "xs" | "sm" | "md" | "lg";
|
|
14
|
+
/** The shape of the button. */
|
|
15
|
+
shape?: "rectangle" | "square" | "circle";
|
|
16
|
+
|
|
17
|
+
/** Whether the button is disabled. */
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
/** Whether the button should take up the full width of its container. */
|
|
20
|
+
fullWidth?: boolean;
|
|
21
|
+
/** Whether the button is pressed. */
|
|
22
|
+
pressed?: boolean;
|
|
23
|
+
/** The type of the button. */
|
|
24
|
+
type?: "button" | "submit" | "reset";
|
|
25
|
+
|
|
26
|
+
/** The content to display inside the button. */
|
|
27
|
+
children?: ReactNode;
|
|
28
|
+
/** An icon to display in the button. */
|
|
29
|
+
icon?: string;
|
|
30
|
+
/** The position of the icon relative to the button text. */
|
|
31
|
+
iconPosition?: "left" | "right" | "only";
|
|
32
|
+
/** The size of the icon (Tailwind text class). */
|
|
33
|
+
iconSize?: string;
|
|
34
|
+
|
|
35
|
+
/** The ARIA label for the button. */
|
|
36
|
+
ariaLabel?: string;
|
|
37
|
+
|
|
38
|
+
/** A callback function to handle button clicks. */
|
|
39
|
+
onButtonClick?: () => void;
|
|
40
|
+
|
|
41
|
+
/** A custom CSS class to apply to the button. */
|
|
42
|
+
className?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Renders a Modus button component with full customization support.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* // Basic button
|
|
50
|
+
* <ModusButton>Click me</ModusButton>
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* // Icon button with custom styling
|
|
54
|
+
* <ModusButton
|
|
55
|
+
* icon="add"
|
|
56
|
+
* iconPosition="left"
|
|
57
|
+
* color="primary"
|
|
58
|
+
* size="lg"
|
|
59
|
+
* >
|
|
60
|
+
* Add Item
|
|
61
|
+
* </ModusButton>
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* // Icon-only button with accessibility
|
|
65
|
+
* <ModusButton
|
|
66
|
+
* icon="settings"
|
|
67
|
+
* iconPosition="only"
|
|
68
|
+
* ariaLabel="Open settings"
|
|
69
|
+
* />
|
|
70
|
+
*
|
|
71
|
+
* @param {ModusButtonProps} props - The component props.
|
|
72
|
+
* @returns {JSX.Element} The rendered button component.
|
|
73
|
+
* @see {@link https://modus.trimble.com/components/button} - Modus Button documentation
|
|
74
|
+
*/
|
|
75
|
+
export default function ModusButton({
|
|
76
|
+
color,
|
|
77
|
+
variant,
|
|
78
|
+
size = "md",
|
|
79
|
+
shape = "rectangle",
|
|
80
|
+
disabled = false,
|
|
81
|
+
fullWidth = false,
|
|
82
|
+
pressed = false,
|
|
83
|
+
type = "button",
|
|
84
|
+
children,
|
|
85
|
+
icon,
|
|
86
|
+
iconPosition = "left",
|
|
87
|
+
iconSize,
|
|
88
|
+
ariaLabel,
|
|
89
|
+
onButtonClick,
|
|
90
|
+
className,
|
|
91
|
+
}: ModusButtonProps) {
|
|
92
|
+
/**
|
|
93
|
+
* Determines the appropriate icon size class based on button size, icon position, and explicit iconSize prop.
|
|
94
|
+
*
|
|
95
|
+
* @returns {string} The Tailwind text class for the icon size
|
|
96
|
+
* @private
|
|
97
|
+
*/
|
|
98
|
+
const getIconSizeClass = (): string => {
|
|
99
|
+
// If iconSize is explicitly provided, use it
|
|
100
|
+
if (iconSize) {
|
|
101
|
+
return iconSize;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Automatic sizing based on button size and icon position
|
|
105
|
+
if (iconPosition === "only") {
|
|
106
|
+
// Icon-only buttons get larger icons
|
|
107
|
+
switch (size) {
|
|
108
|
+
case "xs":
|
|
109
|
+
return "text-sm";
|
|
110
|
+
case "sm":
|
|
111
|
+
return "text-base";
|
|
112
|
+
case "md":
|
|
113
|
+
return "text-xl";
|
|
114
|
+
case "lg":
|
|
115
|
+
return "text-2xl";
|
|
116
|
+
default:
|
|
117
|
+
return "text-xl";
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
// Icons with text scale with button size
|
|
121
|
+
switch (size) {
|
|
122
|
+
case "xs":
|
|
123
|
+
return "text-xs";
|
|
124
|
+
case "sm":
|
|
125
|
+
return "text-sm";
|
|
126
|
+
case "md":
|
|
127
|
+
return "text-lg";
|
|
128
|
+
case "lg":
|
|
129
|
+
return "text-xl";
|
|
130
|
+
default:
|
|
131
|
+
return "text-lg";
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Renders an icon with proper positioning and styling based on its position.
|
|
138
|
+
*
|
|
139
|
+
* This helper function creates an icon element with appropriate margin spacing
|
|
140
|
+
* based on the icon's position relative to the button text. Icons positioned
|
|
141
|
+
* on the left get right margin, icons on the right get left margin, and
|
|
142
|
+
* icon-only buttons have no margin.
|
|
143
|
+
*
|
|
144
|
+
* @param {string} iconName - The name of the Modus icon to render
|
|
145
|
+
* @param {"left" | "right" | "only"} position - The position of the icon relative to text
|
|
146
|
+
* @returns {JSX.Element} The rendered icon element with appropriate styling
|
|
147
|
+
* @private
|
|
148
|
+
*/
|
|
149
|
+
const renderIcon = (
|
|
150
|
+
iconName: string,
|
|
151
|
+
position: "left" | "right" | "only",
|
|
152
|
+
) => {
|
|
153
|
+
const iconStyle =
|
|
154
|
+
position === "left"
|
|
155
|
+
? { marginRight: "8px" }
|
|
156
|
+
: position === "right"
|
|
157
|
+
? { marginLeft: "8px" }
|
|
158
|
+
: {};
|
|
159
|
+
|
|
160
|
+
const iconSizeClass = getIconSizeClass();
|
|
161
|
+
|
|
162
|
+
return (
|
|
163
|
+
<i className={`modus-icons ${iconSizeClass}`} style={iconStyle}>
|
|
164
|
+
{iconName}
|
|
165
|
+
</i>
|
|
166
|
+
);
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Determines and renders the button content based on icon position.
|
|
171
|
+
*
|
|
172
|
+
* This function handles the complex logic of combining icons and text content
|
|
173
|
+
* based on the iconPosition prop. It supports three modes:
|
|
174
|
+
* - "left": Icon appears before text
|
|
175
|
+
* - "right": Icon appears after text
|
|
176
|
+
* - "only": Only the icon is displayed (text is hidden)
|
|
177
|
+
*
|
|
178
|
+
* @returns {ReactNode} The rendered content with proper icon and text arrangement
|
|
179
|
+
* @private
|
|
180
|
+
*/
|
|
181
|
+
const renderContent = () => {
|
|
182
|
+
if (!icon) {
|
|
183
|
+
return children;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
switch (iconPosition) {
|
|
187
|
+
case "left":
|
|
188
|
+
return (
|
|
189
|
+
<>
|
|
190
|
+
{renderIcon(icon, "left")}
|
|
191
|
+
{children}
|
|
192
|
+
</>
|
|
193
|
+
);
|
|
194
|
+
case "right":
|
|
195
|
+
return (
|
|
196
|
+
<>
|
|
197
|
+
{children}
|
|
198
|
+
{renderIcon(icon, "right")}
|
|
199
|
+
</>
|
|
200
|
+
);
|
|
201
|
+
case "only":
|
|
202
|
+
return renderIcon(icon, "only");
|
|
203
|
+
default:
|
|
204
|
+
return children;
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Generates appropriate ARIA label for accessibility.
|
|
210
|
+
*
|
|
211
|
+
* This function ensures proper accessibility by generating ARIA labels
|
|
212
|
+
* for icon-only buttons. If no explicit ariaLabel is provided and the
|
|
213
|
+
* button is icon-only, it uses the text content as the aria-label.
|
|
214
|
+
* This ensures screen readers can properly announce the button's purpose.
|
|
215
|
+
*
|
|
216
|
+
* @returns {string | undefined} The appropriate ARIA label or undefined
|
|
217
|
+
* @private
|
|
218
|
+
*/
|
|
219
|
+
const getAriaLabel = () => {
|
|
220
|
+
if (ariaLabel) return ariaLabel;
|
|
221
|
+
if (iconPosition === "only" && typeof children === "string") {
|
|
222
|
+
return children; // Use text content as aria-label for icon-only buttons
|
|
223
|
+
}
|
|
224
|
+
return undefined;
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
return (
|
|
228
|
+
<ModusWcButton
|
|
229
|
+
{...(color && { color })}
|
|
230
|
+
{...(variant && { variant })}
|
|
231
|
+
size={size}
|
|
232
|
+
shape={shape}
|
|
233
|
+
disabled={disabled}
|
|
234
|
+
fullWidth={fullWidth}
|
|
235
|
+
pressed={pressed}
|
|
236
|
+
type={type}
|
|
237
|
+
aria-label={getAriaLabel()}
|
|
238
|
+
onButtonClick={onButtonClick}
|
|
239
|
+
custom-class={className}
|
|
240
|
+
>
|
|
241
|
+
{renderContent()}
|
|
242
|
+
</ModusWcButton>
|
|
243
|
+
);
|
|
244
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { ModusWcButtonGroup } from "@trimble-oss/moduswebcomponents-react";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Props for the ModusButtonGroup component.
|
|
6
|
+
*/
|
|
7
|
+
export interface ModusButtonGroupProps {
|
|
8
|
+
/** The content to display inside the button group (ModusButton components). */
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
/** Style variant applied to all buttons within the group. */
|
|
11
|
+
variant?: "borderless" | "filled" | "outlined";
|
|
12
|
+
/** Color applied to all buttons within the group. */
|
|
13
|
+
color?: "primary" | "secondary" | "tertiary" | "warning" | "danger";
|
|
14
|
+
/** Disables all buttons within the button group. */
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
/** Orientation of the button group: horizontal or vertical. */
|
|
17
|
+
orientation?: "horizontal" | "vertical";
|
|
18
|
+
/** Selection behavior - default (no selection), single (radio-like), or multiple (checkbox-like). */
|
|
19
|
+
selectionType?: "default" | "single" | "multiple";
|
|
20
|
+
/** Callback when any button in the group is clicked. */
|
|
21
|
+
onButtonGroupClick?: (
|
|
22
|
+
event: CustomEvent<{ button: HTMLElement; isSelected: boolean }>,
|
|
23
|
+
) => void;
|
|
24
|
+
/** Callback when button selection changes. */
|
|
25
|
+
onButtonSelectionChange?: (
|
|
26
|
+
event: CustomEvent<{ selectedButtons: HTMLElement[] }>,
|
|
27
|
+
) => void;
|
|
28
|
+
/** A custom CSS class to apply to the button group. */
|
|
29
|
+
customClass?: string;
|
|
30
|
+
/** The ARIA label for the button group. */
|
|
31
|
+
ariaLabel?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Renders a Modus button group component that groups multiple buttons together.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* // Basic horizontal button group
|
|
39
|
+
* <ModusButtonGroup variant="outlined" color="primary">
|
|
40
|
+
* <ModusButton>Button 1</ModusButton>
|
|
41
|
+
* <ModusButton>Button 2</ModusButton>
|
|
42
|
+
* <ModusButton>Button 3</ModusButton>
|
|
43
|
+
* </ModusButtonGroup>
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* // Single selection (radio-like behavior)
|
|
47
|
+
* <ModusButtonGroup selectionType="single" variant="outlined">
|
|
48
|
+
* <ModusButton>Option 1</ModusButton>
|
|
49
|
+
* <ModusButton pressed>Option 2</ModusButton>
|
|
50
|
+
* <ModusButton>Option 3</ModusButton>
|
|
51
|
+
* </ModusButtonGroup>
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* // Multiple selection (checkbox-like behavior)
|
|
55
|
+
* <ModusButtonGroup selectionType="multiple" variant="outlined">
|
|
56
|
+
* <ModusButton pressed>Bold</ModusButton>
|
|
57
|
+
* <ModusButton>Italic</ModusButton>
|
|
58
|
+
* <ModusButton pressed>Underline</ModusButton>
|
|
59
|
+
* </ModusButtonGroup>
|
|
60
|
+
*
|
|
61
|
+
* @param {ModusButtonGroupProps} props - The component props.
|
|
62
|
+
* @returns {JSX.Element} The rendered button group component.
|
|
63
|
+
*/
|
|
64
|
+
export default function ModusButtonGroup({
|
|
65
|
+
children,
|
|
66
|
+
variant = "outlined",
|
|
67
|
+
color,
|
|
68
|
+
disabled = false,
|
|
69
|
+
orientation = "horizontal",
|
|
70
|
+
selectionType = "default",
|
|
71
|
+
onButtonGroupClick,
|
|
72
|
+
onButtonSelectionChange,
|
|
73
|
+
customClass,
|
|
74
|
+
ariaLabel,
|
|
75
|
+
}: ModusButtonGroupProps) {
|
|
76
|
+
return (
|
|
77
|
+
<ModusWcButtonGroup
|
|
78
|
+
variant={variant}
|
|
79
|
+
color={color}
|
|
80
|
+
disabled={disabled}
|
|
81
|
+
orientation={orientation}
|
|
82
|
+
selection-type={selectionType}
|
|
83
|
+
onButtonGroupClick={onButtonGroupClick}
|
|
84
|
+
onButtonSelectionChange={onButtonSelectionChange}
|
|
85
|
+
custom-class={customClass}
|
|
86
|
+
aria-label={ariaLabel}
|
|
87
|
+
>
|
|
88
|
+
{children}
|
|
89
|
+
</ModusWcButtonGroup>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { ModusWcCard } from "@trimble-oss/moduswebcomponents-react";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Props for the ModusCard component.
|
|
6
|
+
*/
|
|
7
|
+
export interface ModusCardProps {
|
|
8
|
+
/** The main content of the card. */
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
/** Whether to show a background figure. */
|
|
11
|
+
backgroundFigure?: boolean;
|
|
12
|
+
/** Whether the card has a border. */
|
|
13
|
+
bordered?: boolean;
|
|
14
|
+
/** The layout of the card. */
|
|
15
|
+
layout?: 'vertical' | 'horizontal';
|
|
16
|
+
/** The padding of the card. */
|
|
17
|
+
padding?: 'compact' | 'comfortable';
|
|
18
|
+
/** A custom CSS class to apply to the card. */
|
|
19
|
+
customClass?: string;
|
|
20
|
+
/** The ARIA label for the card. */
|
|
21
|
+
'aria-label'?: string;
|
|
22
|
+
/** The header content of the card. */
|
|
23
|
+
header?: ReactNode;
|
|
24
|
+
/** The title content of the card. */
|
|
25
|
+
title?: ReactNode;
|
|
26
|
+
/** The subtitle content of the card. */
|
|
27
|
+
subtitle?: ReactNode;
|
|
28
|
+
/** The actions content of the card. */
|
|
29
|
+
actions?: ReactNode;
|
|
30
|
+
/** The footer content of the card. */
|
|
31
|
+
footer?: ReactNode;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Renders a Modus card component.
|
|
36
|
+
* @param {ModusCardProps} props - The component props.
|
|
37
|
+
* @returns {JSX.Element} The rendered card component.
|
|
38
|
+
*/
|
|
39
|
+
export default function ModusCard({
|
|
40
|
+
children,
|
|
41
|
+
backgroundFigure = false,
|
|
42
|
+
bordered = false,
|
|
43
|
+
layout = 'vertical',
|
|
44
|
+
padding = 'comfortable',
|
|
45
|
+
customClass,
|
|
46
|
+
'aria-label': ariaLabel,
|
|
47
|
+
header,
|
|
48
|
+
title,
|
|
49
|
+
subtitle,
|
|
50
|
+
actions,
|
|
51
|
+
footer,
|
|
52
|
+
}: ModusCardProps) {
|
|
53
|
+
return (
|
|
54
|
+
<ModusWcCard
|
|
55
|
+
backgroundFigure={backgroundFigure}
|
|
56
|
+
bordered={bordered}
|
|
57
|
+
layout={layout}
|
|
58
|
+
padding={padding}
|
|
59
|
+
customClass={customClass}
|
|
60
|
+
aria-label={ariaLabel}
|
|
61
|
+
>
|
|
62
|
+
{header && <div slot="header">{header}</div>}
|
|
63
|
+
{title && <div slot="title">{title}</div>}
|
|
64
|
+
{subtitle && <div slot="subtitle">{subtitle}</div>}
|
|
65
|
+
{children}
|
|
66
|
+
{actions && <div slot="actions">{actions}</div>}
|
|
67
|
+
{footer && <div slot="footer">{footer}</div>}
|
|
68
|
+
</ModusWcCard>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
import { ModusWcCheckbox } from "@trimble-oss/moduswebcomponents-react";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Props for the ModusCheckbox component.
|
|
6
|
+
*/
|
|
7
|
+
export interface ModusCheckboxProps {
|
|
8
|
+
/** The value of the checkbox. */
|
|
9
|
+
value?: boolean;
|
|
10
|
+
/** Whether the checkbox is disabled. */
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
/** Whether the checkbox is in an indeterminate state. */
|
|
13
|
+
indeterminate?: boolean;
|
|
14
|
+
/** The label for the checkbox. */
|
|
15
|
+
label?: string;
|
|
16
|
+
/** The name of the checkbox. */
|
|
17
|
+
name?: string;
|
|
18
|
+
/** Whether the checkbox is required. */
|
|
19
|
+
required?: boolean;
|
|
20
|
+
/** The size of the checkbox. */
|
|
21
|
+
size?: "sm" | "md" | "lg";
|
|
22
|
+
/** The ID of the input element. */
|
|
23
|
+
inputId?: string;
|
|
24
|
+
/** The tab index of the input element. */
|
|
25
|
+
inputTabIndex?: number;
|
|
26
|
+
/** A custom CSS class to apply to the checkbox. */
|
|
27
|
+
customClass?: string;
|
|
28
|
+
/** The ARIA label for the checkbox. */
|
|
29
|
+
"aria-label"?: string;
|
|
30
|
+
/** A callback function to handle input changes. */
|
|
31
|
+
onInputChange?: (event: CustomEvent<InputEvent>) => void;
|
|
32
|
+
/** A callback function to handle input focus. */
|
|
33
|
+
onInputFocus?: (event: CustomEvent<FocusEvent>) => void;
|
|
34
|
+
/** A callback function to handle input blur. */
|
|
35
|
+
onInputBlur?: (event: CustomEvent<FocusEvent>) => void;
|
|
36
|
+
/** A callback function to handle value changes. */
|
|
37
|
+
onValueChange?: (event: CustomEvent<boolean>) => void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Renders a Modus checkbox component with critical bug workaround.
|
|
42
|
+
*
|
|
43
|
+
* ⚠️ IMPORTANT: This component includes a workaround for a critical value inversion bug
|
|
44
|
+
* in the underlying ModusWcCheckbox web component. The value property returns the
|
|
45
|
+
* opposite of the actual checked state, which is automatically corrected.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* // Basic checkbox
|
|
49
|
+
* <ModusCheckbox label="Accept terms" />
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* // Controlled checkbox with value change handler
|
|
53
|
+
* <ModusCheckbox
|
|
54
|
+
* label="Subscribe to newsletter"
|
|
55
|
+
* value={isSubscribed}
|
|
56
|
+
* onValueChange={(event) => setSubscribed(event.detail)}
|
|
57
|
+
* />
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* // Indeterminate checkbox
|
|
61
|
+
* <ModusCheckbox
|
|
62
|
+
* label="Select all"
|
|
63
|
+
* indeterminate={true}
|
|
64
|
+
* onValueChange={handleSelectAll}
|
|
65
|
+
* />
|
|
66
|
+
*
|
|
67
|
+
* @param {ModusCheckboxProps} props - The component props.
|
|
68
|
+
* @returns {JSX.Element} The rendered checkbox component.
|
|
69
|
+
* @see {@link https://modus.trimble.com/components/checkbox} - Modus Checkbox documentation
|
|
70
|
+
* @see {@link https://github.com/trimble-oss/modus-web-components/issues} - Known issues
|
|
71
|
+
*/
|
|
72
|
+
export default function ModusCheckbox({
|
|
73
|
+
value = false,
|
|
74
|
+
disabled = false,
|
|
75
|
+
indeterminate = false,
|
|
76
|
+
label,
|
|
77
|
+
name = "",
|
|
78
|
+
required = false,
|
|
79
|
+
size = "md",
|
|
80
|
+
inputId,
|
|
81
|
+
inputTabIndex,
|
|
82
|
+
customClass,
|
|
83
|
+
"aria-label": ariaLabel,
|
|
84
|
+
onInputChange,
|
|
85
|
+
onInputFocus,
|
|
86
|
+
onInputBlur,
|
|
87
|
+
onValueChange,
|
|
88
|
+
}: ModusCheckboxProps) {
|
|
89
|
+
const checkboxRef = useRef<HTMLModusWcCheckboxElement>(null);
|
|
90
|
+
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
const checkbox = checkboxRef.current;
|
|
93
|
+
if (!checkbox) return;
|
|
94
|
+
|
|
95
|
+
const handleInputChange = (event: Event) => {
|
|
96
|
+
onInputChange?.(event as CustomEvent<InputEvent>);
|
|
97
|
+
};
|
|
98
|
+
const handleInputFocus = (event: Event) => {
|
|
99
|
+
onInputFocus?.(event as CustomEvent<FocusEvent>);
|
|
100
|
+
};
|
|
101
|
+
const handleInputBlur = (event: Event) => {
|
|
102
|
+
onInputBlur?.(event as CustomEvent<FocusEvent>);
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Handles value change events with critical bug fix for value inversion.
|
|
106
|
+
*
|
|
107
|
+
* ⚠️ CRITICAL BUG WORKAROUND: The ModusWcCheckbox component has a value
|
|
108
|
+
* inversion bug where the `value` property returns the opposite of the
|
|
109
|
+
* actual checked state. This function corrects this by inverting the
|
|
110
|
+
* raw value before passing it to the parent component.
|
|
111
|
+
*
|
|
112
|
+
* @param {Event} event - The input change event from the web component
|
|
113
|
+
* @private
|
|
114
|
+
* @see {@link https://github.com/trimble-oss/modus-web-components/issues} - Modus Web Components issue tracker
|
|
115
|
+
*/
|
|
116
|
+
const handleValueChange = (event: Event) => {
|
|
117
|
+
const customEvent = event as CustomEvent<InputEvent>;
|
|
118
|
+
// 🚨 CRITICAL: Handle the value inversion bug
|
|
119
|
+
// The value inversion bug is in the target.value, not the event detail
|
|
120
|
+
const rawValue = (customEvent.target as HTMLModusWcCheckboxElement).value;
|
|
121
|
+
const actualValue = !rawValue; // ✅ CORRECT: Invert the value
|
|
122
|
+
|
|
123
|
+
// Create a new event with the corrected value
|
|
124
|
+
const correctedEvent = new CustomEvent("valueChange", {
|
|
125
|
+
detail: actualValue,
|
|
126
|
+
bubbles: true,
|
|
127
|
+
cancelable: true,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
onValueChange?.(correctedEvent);
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
if (onInputChange)
|
|
134
|
+
checkbox.addEventListener("inputChange", handleInputChange);
|
|
135
|
+
if (onInputFocus) checkbox.addEventListener("inputFocus", handleInputFocus);
|
|
136
|
+
if (onInputBlur) checkbox.addEventListener("inputBlur", handleInputBlur);
|
|
137
|
+
if (onValueChange)
|
|
138
|
+
checkbox.addEventListener("inputChange", handleValueChange);
|
|
139
|
+
|
|
140
|
+
return () => {
|
|
141
|
+
if (onInputChange)
|
|
142
|
+
checkbox.removeEventListener("inputChange", handleInputChange);
|
|
143
|
+
if (onInputFocus)
|
|
144
|
+
checkbox.removeEventListener("inputFocus", handleInputFocus);
|
|
145
|
+
if (onInputBlur)
|
|
146
|
+
checkbox.removeEventListener("inputBlur", handleInputBlur);
|
|
147
|
+
if (onValueChange)
|
|
148
|
+
checkbox.removeEventListener("inputChange", handleValueChange);
|
|
149
|
+
};
|
|
150
|
+
}, [onInputChange, onInputFocus, onInputBlur, onValueChange]);
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<ModusWcCheckbox
|
|
154
|
+
ref={checkboxRef}
|
|
155
|
+
value={value}
|
|
156
|
+
disabled={disabled}
|
|
157
|
+
indeterminate={indeterminate}
|
|
158
|
+
label={label}
|
|
159
|
+
name={name}
|
|
160
|
+
required={required}
|
|
161
|
+
size={size}
|
|
162
|
+
inputId={inputId}
|
|
163
|
+
inputTabIndex={inputTabIndex}
|
|
164
|
+
customClass={customClass}
|
|
165
|
+
aria-label={ariaLabel}
|
|
166
|
+
/>
|
|
167
|
+
);
|
|
168
|
+
}
|