@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,108 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef } from "react";
|
|
4
|
+
import { ModusWcRating } from "@trimble-oss/moduswebcomponents-react";
|
|
5
|
+
|
|
6
|
+
type RatingVariant = "star" | "heart" | "smiley" | "thumb";
|
|
7
|
+
type RatingSize = "sm" | "md" | "lg";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Represents the detail of a rating change event.
|
|
11
|
+
*/
|
|
12
|
+
export interface RatingChangeDetail {
|
|
13
|
+
/** The new rating value. */
|
|
14
|
+
newRating: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Props for the ModusRating component.
|
|
19
|
+
*/
|
|
20
|
+
export interface ModusRatingProps {
|
|
21
|
+
/** The variant of the rating component. */
|
|
22
|
+
variant?: RatingVariant;
|
|
23
|
+
/** The total number of rating items. */
|
|
24
|
+
count?: number;
|
|
25
|
+
/** The current rating value. */
|
|
26
|
+
value?: number;
|
|
27
|
+
/** Whether to allow half ratings. */
|
|
28
|
+
allowHalf?: boolean;
|
|
29
|
+
/** The size of the rating items. */
|
|
30
|
+
size?: RatingSize;
|
|
31
|
+
/** Whether the rating component is disabled. */
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
/** A custom CSS class to apply to the rating component. */
|
|
34
|
+
customClass?: string;
|
|
35
|
+
/** The ARIA label for the rating component. */
|
|
36
|
+
'aria-label'?: string;
|
|
37
|
+
/** A function to get the ARIA label text for a given rating value. */
|
|
38
|
+
getAriaLabelText?: (ratingValue: number) => string;
|
|
39
|
+
/** A callback function to handle rating changes. */
|
|
40
|
+
onRatingChange?: (event: CustomEvent<RatingChangeDetail>) => void;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Renders a Modus rating component.
|
|
45
|
+
* @param {ModusRatingProps} props - The component props.
|
|
46
|
+
* @returns {JSX.Element} The rendered rating component.
|
|
47
|
+
*/
|
|
48
|
+
export default function ModusRating({
|
|
49
|
+
variant = 'smiley',
|
|
50
|
+
count = 5,
|
|
51
|
+
value = 0,
|
|
52
|
+
allowHalf = false,
|
|
53
|
+
size = 'md',
|
|
54
|
+
disabled = false,
|
|
55
|
+
customClass,
|
|
56
|
+
'aria-label': ariaLabel,
|
|
57
|
+
getAriaLabelText,
|
|
58
|
+
onRatingChange,
|
|
59
|
+
}: ModusRatingProps) {
|
|
60
|
+
const ratingRef = useRef<HTMLModusWcRatingElement>(null);
|
|
61
|
+
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
const rating = ratingRef.current;
|
|
64
|
+
if (!rating) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (getAriaLabelText) {
|
|
69
|
+
rating.getAriaLabelText = getAriaLabelText;
|
|
70
|
+
return () => {
|
|
71
|
+
rating.getAriaLabelText = undefined;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return;
|
|
76
|
+
}, [getAriaLabelText]);
|
|
77
|
+
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
const rating = ratingRef.current;
|
|
80
|
+
if (!rating || !onRatingChange) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const handleRatingChange = (event: Event) => {
|
|
85
|
+
onRatingChange(event as CustomEvent<RatingChangeDetail>);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
rating.addEventListener("ratingChange", handleRatingChange);
|
|
89
|
+
|
|
90
|
+
return () => {
|
|
91
|
+
rating.removeEventListener("ratingChange", handleRatingChange);
|
|
92
|
+
};
|
|
93
|
+
}, [onRatingChange]);
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<ModusWcRating
|
|
97
|
+
ref={ratingRef}
|
|
98
|
+
variant={variant}
|
|
99
|
+
count={count}
|
|
100
|
+
value={value}
|
|
101
|
+
allowHalf={allowHalf}
|
|
102
|
+
size={size}
|
|
103
|
+
disabled={disabled}
|
|
104
|
+
customClass={customClass}
|
|
105
|
+
aria-label={ariaLabel}
|
|
106
|
+
/>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef } from "react";
|
|
4
|
+
import { ModusWcSelect } from "@trimble-oss/moduswebcomponents-react";
|
|
5
|
+
|
|
6
|
+
type SelectSize = "sm" | "md" | "lg";
|
|
7
|
+
type FeedbackLevel = "error" | "info" | "success" | "warning";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Represents an option in a select component.
|
|
11
|
+
*/
|
|
12
|
+
export interface ModusSelectOption {
|
|
13
|
+
/** The text to display for the option. */
|
|
14
|
+
label: string;
|
|
15
|
+
/** The value of the option. */
|
|
16
|
+
value: string;
|
|
17
|
+
/** Whether the option is disabled. */
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Represents feedback for a select component.
|
|
23
|
+
*/
|
|
24
|
+
export interface ModusSelectFeedback {
|
|
25
|
+
/** The severity level of the feedback. */
|
|
26
|
+
level: FeedbackLevel;
|
|
27
|
+
/** The message to display as feedback. */
|
|
28
|
+
message?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Props for the ModusSelect component.
|
|
33
|
+
*/
|
|
34
|
+
export interface ModusSelectProps {
|
|
35
|
+
/** The options to display in the select component. */
|
|
36
|
+
options: ModusSelectOption[];
|
|
37
|
+
/** The value of the select component. */
|
|
38
|
+
value?: string;
|
|
39
|
+
/** The label for the select component. */
|
|
40
|
+
label?: string;
|
|
41
|
+
/** The name of the select component. */
|
|
42
|
+
name?: string;
|
|
43
|
+
/** The size of the select component. */
|
|
44
|
+
size?: SelectSize;
|
|
45
|
+
/** Whether the select component is required. */
|
|
46
|
+
required?: boolean;
|
|
47
|
+
/** Whether the select component is disabled. */
|
|
48
|
+
disabled?: boolean;
|
|
49
|
+
/** Whether the select component has a border. */
|
|
50
|
+
bordered?: boolean;
|
|
51
|
+
/** The ID of the input element. */
|
|
52
|
+
inputId?: string;
|
|
53
|
+
/** The tab index of the input element. */
|
|
54
|
+
inputTabIndex?: number;
|
|
55
|
+
/** A custom CSS class to apply to the select component. */
|
|
56
|
+
customClass?: string;
|
|
57
|
+
/** Feedback to display for the select component. */
|
|
58
|
+
feedback?: ModusSelectFeedback;
|
|
59
|
+
/** The ARIA label for the select component. */
|
|
60
|
+
'aria-label'?: string;
|
|
61
|
+
/** A callback function to handle input changes. */
|
|
62
|
+
onInputChange?: (event: CustomEvent<InputEvent>) => void;
|
|
63
|
+
/** A callback function to handle input focus. */
|
|
64
|
+
onInputFocus?: (event: CustomEvent<FocusEvent>) => void;
|
|
65
|
+
/** A callback function to handle input blur. */
|
|
66
|
+
onInputBlur?: (event: CustomEvent<FocusEvent>) => void;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Renders a Modus select component.
|
|
71
|
+
* @param {ModusSelectProps} props - The component props.
|
|
72
|
+
* @returns {JSX.Element} The rendered select component.
|
|
73
|
+
*/
|
|
74
|
+
export default function ModusSelect({
|
|
75
|
+
options,
|
|
76
|
+
value = '',
|
|
77
|
+
label,
|
|
78
|
+
name,
|
|
79
|
+
size = 'md',
|
|
80
|
+
required = false,
|
|
81
|
+
disabled = false,
|
|
82
|
+
bordered = true,
|
|
83
|
+
inputId,
|
|
84
|
+
inputTabIndex,
|
|
85
|
+
customClass,
|
|
86
|
+
feedback,
|
|
87
|
+
'aria-label': ariaLabel,
|
|
88
|
+
onInputChange,
|
|
89
|
+
onInputFocus,
|
|
90
|
+
onInputBlur,
|
|
91
|
+
}: ModusSelectProps) {
|
|
92
|
+
const selectRef = useRef<HTMLModusWcSelectElement>(null);
|
|
93
|
+
|
|
94
|
+
// Sync options array with the web component
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
const select = selectRef.current;
|
|
97
|
+
if (!select) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Assign a new array to trigger re-render within the component
|
|
102
|
+
select.options = [...options];
|
|
103
|
+
}, [options]);
|
|
104
|
+
|
|
105
|
+
// Sync feedback (object set via property, not attribute)
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
const select = selectRef.current;
|
|
108
|
+
if (!select) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
select.feedback = feedback;
|
|
113
|
+
}, [feedback]);
|
|
114
|
+
|
|
115
|
+
// Wire up events
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
const select = selectRef.current;
|
|
118
|
+
if (!select) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const handleInputChange = (event: Event) => {
|
|
123
|
+
onInputChange?.(event as CustomEvent<InputEvent>);
|
|
124
|
+
};
|
|
125
|
+
const handleInputFocus = (event: Event) => {
|
|
126
|
+
onInputFocus?.(event as CustomEvent<FocusEvent>);
|
|
127
|
+
};
|
|
128
|
+
const handleInputBlur = (event: Event) => {
|
|
129
|
+
onInputBlur?.(event as CustomEvent<FocusEvent>);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
if (onInputChange) {
|
|
133
|
+
select.addEventListener("inputChange", handleInputChange);
|
|
134
|
+
}
|
|
135
|
+
if (onInputFocus) {
|
|
136
|
+
select.addEventListener("inputFocus", handleInputFocus);
|
|
137
|
+
}
|
|
138
|
+
if (onInputBlur) {
|
|
139
|
+
select.addEventListener("inputBlur", handleInputBlur);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return () => {
|
|
143
|
+
if (onInputChange) {
|
|
144
|
+
select.removeEventListener("inputChange", handleInputChange);
|
|
145
|
+
}
|
|
146
|
+
if (onInputFocus) {
|
|
147
|
+
select.removeEventListener("inputFocus", handleInputFocus);
|
|
148
|
+
}
|
|
149
|
+
if (onInputBlur) {
|
|
150
|
+
select.removeEventListener("inputBlur", handleInputBlur);
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
}, [onInputChange, onInputFocus, onInputBlur]);
|
|
154
|
+
|
|
155
|
+
return (
|
|
156
|
+
<ModusWcSelect
|
|
157
|
+
ref={selectRef}
|
|
158
|
+
value={value}
|
|
159
|
+
label={label}
|
|
160
|
+
name={name}
|
|
161
|
+
size={size}
|
|
162
|
+
required={required}
|
|
163
|
+
disabled={disabled}
|
|
164
|
+
bordered={bordered}
|
|
165
|
+
inputId={inputId}
|
|
166
|
+
inputTabIndex={inputTabIndex}
|
|
167
|
+
customClass={customClass}
|
|
168
|
+
aria-label={ariaLabel}
|
|
169
|
+
/>
|
|
170
|
+
);
|
|
171
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
+
import { ModusWcSideNavigation } from "@trimble-oss/moduswebcomponents-react";
|
|
3
|
+
import ModusMenu from "./ModusMenu";
|
|
4
|
+
import type { MenuItem } from "./ModusMenu";
|
|
5
|
+
|
|
6
|
+
type SideNavSize = "sm" | "md" | "lg";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Props for the ModusSideNavigation component.
|
|
10
|
+
*/
|
|
11
|
+
export interface ModusSideNavigationProps {
|
|
12
|
+
/** The items to display in the side navigation. */
|
|
13
|
+
items: MenuItem[];
|
|
14
|
+
/** Whether the side navigation is expanded. */
|
|
15
|
+
expanded?: boolean;
|
|
16
|
+
/** The default expanded state of the side navigation. */
|
|
17
|
+
defaultExpanded?: boolean;
|
|
18
|
+
/** Whether to collapse the side navigation when clicking outside of it. */
|
|
19
|
+
collapseOnClickOutside?: boolean;
|
|
20
|
+
/** The maximum width of the side navigation. */
|
|
21
|
+
maxWidth?: string;
|
|
22
|
+
/** The size of the side navigation. */
|
|
23
|
+
size?: SideNavSize;
|
|
24
|
+
/** A custom CSS class to apply to the side navigation. */
|
|
25
|
+
customClass?: string;
|
|
26
|
+
/** Whether to automatically collapse the side navigation when an item is selected. */
|
|
27
|
+
autoCollapseOnSelect?: boolean;
|
|
28
|
+
/** A callback function to handle expanded state changes. */
|
|
29
|
+
onExpandedChange?: (expanded: boolean) => void;
|
|
30
|
+
/** A callback function to handle item selection. */
|
|
31
|
+
onItemSelect?: (item: MenuItem) => void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Renders a Modus side navigation component.
|
|
36
|
+
* @param {ModusSideNavigationProps} props - The component props.
|
|
37
|
+
* @returns {JSX.Element} The rendered side navigation component.
|
|
38
|
+
*/
|
|
39
|
+
export default function ModusSideNavigation({
|
|
40
|
+
items,
|
|
41
|
+
expanded,
|
|
42
|
+
defaultExpanded = false,
|
|
43
|
+
collapseOnClickOutside = true,
|
|
44
|
+
maxWidth = '256px',
|
|
45
|
+
size = 'md',
|
|
46
|
+
customClass,
|
|
47
|
+
autoCollapseOnSelect = true,
|
|
48
|
+
onExpandedChange,
|
|
49
|
+
onItemSelect,
|
|
50
|
+
}: ModusSideNavigationProps) {
|
|
51
|
+
const navRef = useRef<HTMLModusWcSideNavigationElement>(null);
|
|
52
|
+
const isControlled = expanded !== undefined;
|
|
53
|
+
const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);
|
|
54
|
+
|
|
55
|
+
const currentExpanded = useMemo(
|
|
56
|
+
() => (isControlled ? Boolean(expanded) : internalExpanded),
|
|
57
|
+
[expanded, internalExpanded, isControlled]
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
// Synchronize expanded state to the web component
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
const nav = navRef.current;
|
|
63
|
+
if (nav && nav.expanded !== currentExpanded) {
|
|
64
|
+
nav.expanded = currentExpanded;
|
|
65
|
+
}
|
|
66
|
+
}, [currentExpanded]);
|
|
67
|
+
|
|
68
|
+
// Keep collapse-on-click-outside and max-width up to date
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
const nav = navRef.current;
|
|
71
|
+
if (!nav) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
nav.collapseOnClickOutside = collapseOnClickOutside;
|
|
76
|
+
nav.maxWidth = maxWidth;
|
|
77
|
+
if (customClass) {
|
|
78
|
+
nav.customClass = customClass;
|
|
79
|
+
} else {
|
|
80
|
+
nav.customClass = undefined;
|
|
81
|
+
}
|
|
82
|
+
}, [collapseOnClickOutside, maxWidth, customClass]);
|
|
83
|
+
|
|
84
|
+
// Handle expanded change events from the component
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
const nav = navRef.current;
|
|
87
|
+
if (!nav) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const handleExpandedChange = (event: Event) => {
|
|
92
|
+
const customEvent = event as CustomEvent<boolean>;
|
|
93
|
+
const newExpanded = customEvent.detail;
|
|
94
|
+
|
|
95
|
+
if (!isControlled) {
|
|
96
|
+
setInternalExpanded(newExpanded);
|
|
97
|
+
}
|
|
98
|
+
onExpandedChange?.(newExpanded);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
nav.addEventListener("expandedChange", handleExpandedChange);
|
|
102
|
+
|
|
103
|
+
return () => {
|
|
104
|
+
nav.removeEventListener("expandedChange", handleExpandedChange);
|
|
105
|
+
};
|
|
106
|
+
}, [isControlled, onExpandedChange]);
|
|
107
|
+
|
|
108
|
+
const collapseNavigation = useCallback(() => {
|
|
109
|
+
const nav = navRef.current;
|
|
110
|
+
if (!nav) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
nav.expanded = false;
|
|
114
|
+
if (!isControlled) {
|
|
115
|
+
setInternalExpanded(false);
|
|
116
|
+
}
|
|
117
|
+
onExpandedChange?.(false);
|
|
118
|
+
}, [isControlled, onExpandedChange]);
|
|
119
|
+
|
|
120
|
+
const handleItemSelect = useCallback(
|
|
121
|
+
(item: MenuItem) => {
|
|
122
|
+
onItemSelect?.(item);
|
|
123
|
+
if (autoCollapseOnSelect) {
|
|
124
|
+
collapseNavigation();
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
[autoCollapseOnSelect, collapseNavigation, onItemSelect]
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<ModusWcSideNavigation
|
|
132
|
+
ref={navRef}
|
|
133
|
+
custom-class={customClass}
|
|
134
|
+
collapseOnClickOutside={collapseOnClickOutside}
|
|
135
|
+
expanded={currentExpanded}
|
|
136
|
+
maxWidth={maxWidth}
|
|
137
|
+
>
|
|
138
|
+
<ModusMenu
|
|
139
|
+
items={items}
|
|
140
|
+
size={size}
|
|
141
|
+
orientation="vertical"
|
|
142
|
+
bordered={false}
|
|
143
|
+
onItemSelect={handleItemSelect}
|
|
144
|
+
/>
|
|
145
|
+
</ModusWcSideNavigation>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export type { MenuItem as ModusSideNavigationItem };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ModusWcSkeleton } from "@trimble-oss/moduswebcomponents-react";
|
|
2
|
+
|
|
3
|
+
type SkeletonShape = "circle" | "rectangle";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Props for the ModusSkeleton component.
|
|
7
|
+
*/
|
|
8
|
+
export interface ModusSkeletonProps {
|
|
9
|
+
/** The height of the skeleton. */
|
|
10
|
+
height?: string;
|
|
11
|
+
/** The width of the skeleton. */
|
|
12
|
+
width?: string;
|
|
13
|
+
/** The shape of the skeleton. */
|
|
14
|
+
shape?: SkeletonShape;
|
|
15
|
+
/** A custom CSS class to apply to the skeleton. */
|
|
16
|
+
customClass?: string;
|
|
17
|
+
/** The ARIA label for the skeleton. */
|
|
18
|
+
ariaLabel?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Renders a Modus skeleton component.
|
|
23
|
+
* @param {ModusSkeletonProps} props - The component props.
|
|
24
|
+
* @returns {JSX.Element} The rendered skeleton component.
|
|
25
|
+
*/
|
|
26
|
+
export default function ModusSkeleton({
|
|
27
|
+
height = "var(--modus-wc-line-height-md)",
|
|
28
|
+
width = "100%",
|
|
29
|
+
shape = "rectangle",
|
|
30
|
+
customClass,
|
|
31
|
+
ariaLabel = "Loading placeholder",
|
|
32
|
+
}: ModusSkeletonProps) {
|
|
33
|
+
return (
|
|
34
|
+
<ModusWcSkeleton
|
|
35
|
+
height={height}
|
|
36
|
+
width={width}
|
|
37
|
+
shape={shape}
|
|
38
|
+
custom-class={customClass}
|
|
39
|
+
aria-label={ariaLabel}
|
|
40
|
+
/>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef } from "react";
|
|
4
|
+
import { ModusWcSlider } from "@trimble-oss/moduswebcomponents-react";
|
|
5
|
+
|
|
6
|
+
type SliderSize = "sm" | "md" | "lg";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Props for the ModusSlider component.
|
|
10
|
+
*/
|
|
11
|
+
export interface ModusSliderProps {
|
|
12
|
+
/** The current value of the slider. */
|
|
13
|
+
value?: number;
|
|
14
|
+
/** The minimum value of the slider. */
|
|
15
|
+
min?: number;
|
|
16
|
+
/** The maximum value of the slider. */
|
|
17
|
+
max?: number;
|
|
18
|
+
/** The step interval for the slider. */
|
|
19
|
+
step?: number;
|
|
20
|
+
/** The label for the slider. */
|
|
21
|
+
label?: string;
|
|
22
|
+
/** The name of the slider. */
|
|
23
|
+
name?: string;
|
|
24
|
+
/** The size of the slider. */
|
|
25
|
+
size?: SliderSize;
|
|
26
|
+
/** Whether the slider is required. */
|
|
27
|
+
required?: boolean;
|
|
28
|
+
/** Whether the slider is disabled. */
|
|
29
|
+
disabled?: boolean;
|
|
30
|
+
/** The ID of the input element. */
|
|
31
|
+
inputId?: string;
|
|
32
|
+
/** The tab index of the input element. */
|
|
33
|
+
inputTabIndex?: number;
|
|
34
|
+
/** A custom CSS class to apply to the slider. */
|
|
35
|
+
customClass?: string;
|
|
36
|
+
/** The ARIA label for the slider. */
|
|
37
|
+
'aria-label'?: string;
|
|
38
|
+
/** A callback function to handle input changes. */
|
|
39
|
+
onInputChange?: (event: CustomEvent<InputEvent>) => void;
|
|
40
|
+
/** A callback function to handle input focus. */
|
|
41
|
+
onInputFocus?: (event: CustomEvent<FocusEvent>) => void;
|
|
42
|
+
/** A callback function to handle input blur. */
|
|
43
|
+
onInputBlur?: (event: CustomEvent<FocusEvent>) => void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Renders a Modus slider component.
|
|
48
|
+
* @param {ModusSliderProps} props - The component props.
|
|
49
|
+
* @returns {JSX.Element} The rendered slider component.
|
|
50
|
+
*/
|
|
51
|
+
export default function ModusSlider({
|
|
52
|
+
value = 0,
|
|
53
|
+
min = 0,
|
|
54
|
+
max = 100,
|
|
55
|
+
step = 1,
|
|
56
|
+
label,
|
|
57
|
+
name,
|
|
58
|
+
size = 'md',
|
|
59
|
+
required = false,
|
|
60
|
+
disabled = false,
|
|
61
|
+
inputId,
|
|
62
|
+
inputTabIndex,
|
|
63
|
+
customClass,
|
|
64
|
+
'aria-label': ariaLabel,
|
|
65
|
+
onInputChange,
|
|
66
|
+
onInputFocus,
|
|
67
|
+
onInputBlur,
|
|
68
|
+
}: ModusSliderProps) {
|
|
69
|
+
const sliderRef = useRef<HTMLModusWcSliderElement>(null);
|
|
70
|
+
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
const slider = sliderRef.current;
|
|
73
|
+
if (!slider) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const handleInputChange = (event: Event) => {
|
|
78
|
+
onInputChange?.(event as CustomEvent<InputEvent>);
|
|
79
|
+
};
|
|
80
|
+
const handleInputFocus = (event: Event) => {
|
|
81
|
+
onInputFocus?.(event as CustomEvent<FocusEvent>);
|
|
82
|
+
};
|
|
83
|
+
const handleInputBlur = (event: Event) => {
|
|
84
|
+
onInputBlur?.(event as CustomEvent<FocusEvent>);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
if (onInputChange) {
|
|
88
|
+
slider.addEventListener("inputChange", handleInputChange);
|
|
89
|
+
}
|
|
90
|
+
if (onInputFocus) {
|
|
91
|
+
slider.addEventListener("inputFocus", handleInputFocus);
|
|
92
|
+
}
|
|
93
|
+
if (onInputBlur) {
|
|
94
|
+
slider.addEventListener("inputBlur", handleInputBlur);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return () => {
|
|
98
|
+
if (onInputChange) {
|
|
99
|
+
slider.removeEventListener("inputChange", handleInputChange);
|
|
100
|
+
}
|
|
101
|
+
if (onInputFocus) {
|
|
102
|
+
slider.removeEventListener("inputFocus", handleInputFocus);
|
|
103
|
+
}
|
|
104
|
+
if (onInputBlur) {
|
|
105
|
+
slider.removeEventListener("inputBlur", handleInputBlur);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}, [onInputBlur, onInputChange, onInputFocus]);
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<ModusWcSlider
|
|
112
|
+
ref={sliderRef}
|
|
113
|
+
value={value}
|
|
114
|
+
min={min}
|
|
115
|
+
max={max}
|
|
116
|
+
step={step}
|
|
117
|
+
label={label}
|
|
118
|
+
name={name}
|
|
119
|
+
size={size}
|
|
120
|
+
required={required}
|
|
121
|
+
disabled={disabled}
|
|
122
|
+
inputId={inputId}
|
|
123
|
+
inputTabIndex={inputTabIndex}
|
|
124
|
+
custom-class={customClass}
|
|
125
|
+
aria-label={ariaLabel}
|
|
126
|
+
/>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef } from "react";
|
|
4
|
+
import { ModusWcStepper } from "@trimble-oss/moduswebcomponents-react";
|
|
5
|
+
|
|
6
|
+
export type StepperColor =
|
|
7
|
+
| "primary"
|
|
8
|
+
| "secondary"
|
|
9
|
+
| "accent"
|
|
10
|
+
| "info"
|
|
11
|
+
| "success"
|
|
12
|
+
| "warning"
|
|
13
|
+
| "error"
|
|
14
|
+
| "neutral";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Represents a single step in a stepper component.
|
|
18
|
+
*/
|
|
19
|
+
export interface ModusStepperItem {
|
|
20
|
+
/** The label for the step. */
|
|
21
|
+
label?: string;
|
|
22
|
+
/** The color of the step. */
|
|
23
|
+
color?: StepperColor;
|
|
24
|
+
/** The content of the step. */
|
|
25
|
+
content?: string;
|
|
26
|
+
/** A custom CSS class to apply to the step. */
|
|
27
|
+
customClass?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Props for the ModusStepper component.
|
|
32
|
+
*/
|
|
33
|
+
export interface ModusStepperProps {
|
|
34
|
+
/** The steps to display in the stepper. */
|
|
35
|
+
steps: ModusStepperItem[];
|
|
36
|
+
/** The orientation of the stepper. */
|
|
37
|
+
orientation?: 'horizontal' | 'vertical';
|
|
38
|
+
/** A custom CSS class to apply to the stepper. */
|
|
39
|
+
customClass?: string;
|
|
40
|
+
/** The ARIA label for the stepper. */
|
|
41
|
+
ariaLabel?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Renders a Modus stepper component.
|
|
46
|
+
* @param {ModusStepperProps} props - The component props.
|
|
47
|
+
* @returns {JSX.Element} The rendered stepper component.
|
|
48
|
+
*/
|
|
49
|
+
export default function ModusStepper({
|
|
50
|
+
steps,
|
|
51
|
+
orientation = 'horizontal',
|
|
52
|
+
customClass,
|
|
53
|
+
ariaLabel = 'Workflow progress',
|
|
54
|
+
}: ModusStepperProps) {
|
|
55
|
+
const stepperRef = useRef<HTMLModusWcStepperElement>(null);
|
|
56
|
+
|
|
57
|
+
// Keep steps array in sync (assign new array for stencil change detection)
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
const stepper = stepperRef.current;
|
|
60
|
+
if (!stepper) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
stepper.steps = steps.map((step) => ({ ...step }));
|
|
65
|
+
}, [steps]);
|
|
66
|
+
|
|
67
|
+
// Keep custom class up to date
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
const stepper = stepperRef.current;
|
|
70
|
+
if (!stepper) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
stepper.customClass = customClass;
|
|
75
|
+
}, [customClass]);
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<ModusWcStepper
|
|
79
|
+
ref={stepperRef}
|
|
80
|
+
orientation={orientation}
|
|
81
|
+
aria-label={ariaLabel}
|
|
82
|
+
custom-class={customClass}
|
|
83
|
+
/>
|
|
84
|
+
);
|
|
85
|
+
}
|