@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,524 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ChangeDetectionStrategy,
|
|
3
|
+
Component,
|
|
4
|
+
signal,
|
|
5
|
+
ElementRef,
|
|
6
|
+
AfterViewInit,
|
|
7
|
+
} from '@angular/core';
|
|
8
|
+
import { CommonModule } from '@angular/common';
|
|
9
|
+
import { DemoPageComponent } from '../shared/demo-page.component';
|
|
10
|
+
import { DemoExampleComponent } from '../shared/demo-example.component';
|
|
11
|
+
import { ModusSideNavigationComponent } from '../../components/modus-side-navigation.component';
|
|
12
|
+
import { ModusMenuComponent } from '../../components/modus-menu.component';
|
|
13
|
+
import { ModusMenuItemComponent } from '../../components/modus-menu-item.component';
|
|
14
|
+
import { ModusIconComponent } from '../../components/modus-icon.component';
|
|
15
|
+
import { ModusNavbarComponent } from '../../components/modus-navbar.component';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Demo page showcasing the Modus Side Navigation component.
|
|
19
|
+
*
|
|
20
|
+
* Demonstrates side navigation features including:
|
|
21
|
+
* - Navbar integration (recommended pattern)
|
|
22
|
+
* - Icons that remain visible when collapsed
|
|
23
|
+
* - Push mode layout
|
|
24
|
+
* - State management with signals
|
|
25
|
+
* - Interactive examples with state management
|
|
26
|
+
*/
|
|
27
|
+
@Component({
|
|
28
|
+
selector: 'app-side-navigation-demo-page',
|
|
29
|
+
standalone: true,
|
|
30
|
+
imports: [
|
|
31
|
+
CommonModule,
|
|
32
|
+
DemoPageComponent,
|
|
33
|
+
DemoExampleComponent,
|
|
34
|
+
ModusSideNavigationComponent,
|
|
35
|
+
ModusMenuComponent,
|
|
36
|
+
ModusMenuItemComponent,
|
|
37
|
+
ModusIconComponent,
|
|
38
|
+
ModusNavbarComponent,
|
|
39
|
+
],
|
|
40
|
+
styles: [],
|
|
41
|
+
template: `
|
|
42
|
+
<demo-page
|
|
43
|
+
title="Modus Side Navigation"
|
|
44
|
+
description="A collapsible vertical navigation component that provides contextual menu options for application navigation. The component collapses to show icons only (4rem width) and expands to show full menu items with labels. Icons remain visible and properly positioned in both states."
|
|
45
|
+
>
|
|
46
|
+
<!-- Navbar Integration Example -->
|
|
47
|
+
<demo-example
|
|
48
|
+
title="Navbar Integration (Recommended Pattern)"
|
|
49
|
+
description="Side navigation controlled by the navbar's main menu button (hamburger menu). This is the standard Modus pattern used in applications."
|
|
50
|
+
>
|
|
51
|
+
<div class="layout-with-navbar h-[600px] flex flex-col" data-example="basic">
|
|
52
|
+
<modus-navbar
|
|
53
|
+
[userCard]="userCardInfo()"
|
|
54
|
+
[visibility]="{ mainMenu: true, user: true }"
|
|
55
|
+
class="navbar"
|
|
56
|
+
/>
|
|
57
|
+
|
|
58
|
+
<div class="main-content-row flex flex-1 overflow-hidden">
|
|
59
|
+
<modus-side-navigation
|
|
60
|
+
[expanded]="false"
|
|
61
|
+
[collapseOnClickOutside]="true"
|
|
62
|
+
[maxWidth]="'256px'"
|
|
63
|
+
mode="push"
|
|
64
|
+
[targetContent]="'#basic-panel-content'"
|
|
65
|
+
class="side-navigation h-full"
|
|
66
|
+
>
|
|
67
|
+
<modus-menu size="lg">
|
|
68
|
+
<modus-menu-item label="Home" value="home" [selected]="true">
|
|
69
|
+
<modus-icon slot="start-icon" name="home" [decorative]="true"></modus-icon>
|
|
70
|
+
</modus-menu-item>
|
|
71
|
+
<modus-menu-item label="Profile" value="profile">
|
|
72
|
+
<modus-icon slot="start-icon" name="person" [decorative]="true"></modus-icon>
|
|
73
|
+
</modus-menu-item>
|
|
74
|
+
<modus-menu-item label="Settings" value="settings">
|
|
75
|
+
<modus-icon slot="start-icon" name="settings" [decorative]="true"></modus-icon>
|
|
76
|
+
</modus-menu-item>
|
|
77
|
+
</modus-menu>
|
|
78
|
+
</modus-side-navigation>
|
|
79
|
+
|
|
80
|
+
<div id="basic-panel-content" class="panel-content flex-1 p-6">
|
|
81
|
+
<div class="text-lg font-semibold text-foreground mb-4">Main Content Area</div>
|
|
82
|
+
<p class="text-base text-foreground mb-4">
|
|
83
|
+
The side navigation of an application provides context through accessible menu
|
|
84
|
+
options and positions a consistent component to connect to various pages in the
|
|
85
|
+
application.
|
|
86
|
+
</p>
|
|
87
|
+
<p class="text-base text-foreground">
|
|
88
|
+
The side navigation is a collapsible side content of the site's pages. It is located
|
|
89
|
+
alongside the page's primary content. The component is designed to add side content
|
|
90
|
+
to a fullscreen application. It is activated through the "hamburger" menu in the
|
|
91
|
+
Navbar.
|
|
92
|
+
</p>
|
|
93
|
+
<div class="mt-4 p-4 rounded-lg bg-card border-default">
|
|
94
|
+
<div class="text-sm font-medium text-card-foreground mb-1">Navigation State:</div>
|
|
95
|
+
<div class="text-sm text-muted-foreground">
|
|
96
|
+
{{ navbarMenuExpanded() ? 'Expanded' : 'Collapsed' }}
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
</demo-example>
|
|
103
|
+
|
|
104
|
+
<!-- Sub-Menu Example -->
|
|
105
|
+
<demo-example
|
|
106
|
+
title="Side Navigation with Sub-Menus"
|
|
107
|
+
description="Advanced side navigation with collapsible sub-menus and nested menu items. Demonstrates hierarchical navigation with expand/collapse functionality."
|
|
108
|
+
>
|
|
109
|
+
<div class="layout-with-navbar-submenu h-[700px] flex flex-col" data-example="submenu">
|
|
110
|
+
<modus-navbar
|
|
111
|
+
[userCard]="subMenuUserCardInfo()"
|
|
112
|
+
[visibility]="{ mainMenu: true, user: true }"
|
|
113
|
+
class="navbar"
|
|
114
|
+
/>
|
|
115
|
+
|
|
116
|
+
<div class="main-content-row flex flex-1 overflow-hidden">
|
|
117
|
+
<modus-side-navigation
|
|
118
|
+
[expanded]="false"
|
|
119
|
+
[collapseOnClickOutside]="true"
|
|
120
|
+
[maxWidth]="'256px'"
|
|
121
|
+
mode="push"
|
|
122
|
+
[targetContent]="'#submenu-panel-content'"
|
|
123
|
+
class="side-navigation h-full"
|
|
124
|
+
>
|
|
125
|
+
<modus-menu ariaLabel="Custom menu" customClass="side-nav-menu-width">
|
|
126
|
+
<!-- Charts Menu with Sub-items -->
|
|
127
|
+
<li>
|
|
128
|
+
<div class="side-nav-flex-row" (click)="handleCollapseToggle($event)">
|
|
129
|
+
<modus-icon
|
|
130
|
+
name="bar_graph"
|
|
131
|
+
[decorative]="true"
|
|
132
|
+
class="side-nav-collapse-icon side-nav-icon-left"
|
|
133
|
+
></modus-icon>
|
|
134
|
+
<div class="side-nav-dropdown-menu">Charts</div>
|
|
135
|
+
<div class="side-nav-justify-end">
|
|
136
|
+
<modus-icon
|
|
137
|
+
name="expand_more"
|
|
138
|
+
[decorative]="true"
|
|
139
|
+
class="side-nav-collapse-icon side-nav-dropdown-toggle"
|
|
140
|
+
></modus-icon>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
</li>
|
|
144
|
+
<li class="side-nav-children-container side-nav-hidden" aria-hidden="true">
|
|
145
|
+
<ul>
|
|
146
|
+
<li>
|
|
147
|
+
<div
|
|
148
|
+
class="side-nav-flex-row side-nav-nested-row"
|
|
149
|
+
(click)="selectMenuItem('bar-chart')"
|
|
150
|
+
>
|
|
151
|
+
<div>Bar Chart</div>
|
|
152
|
+
</div>
|
|
153
|
+
</li>
|
|
154
|
+
<li>
|
|
155
|
+
<div
|
|
156
|
+
class="side-nav-flex-row side-nav-nested-row"
|
|
157
|
+
(click)="selectMenuItem('line-chart')"
|
|
158
|
+
>
|
|
159
|
+
<div>Line Chart</div>
|
|
160
|
+
</div>
|
|
161
|
+
</li>
|
|
162
|
+
<li>
|
|
163
|
+
<div
|
|
164
|
+
class="side-nav-flex-row side-nav-nested-row"
|
|
165
|
+
(click)="selectMenuItem('pie-chart')"
|
|
166
|
+
>
|
|
167
|
+
<div>Pie Chart</div>
|
|
168
|
+
</div>
|
|
169
|
+
</li>
|
|
170
|
+
</ul>
|
|
171
|
+
</li>
|
|
172
|
+
|
|
173
|
+
<!-- Calendar Menu (no sub-items) -->
|
|
174
|
+
<li>
|
|
175
|
+
<div class="side-nav-flex-row" (click)="selectMenuItem('calendar')">
|
|
176
|
+
<modus-icon
|
|
177
|
+
name="calendar"
|
|
178
|
+
[decorative]="true"
|
|
179
|
+
class="side-nav-collapse-icon side-nav-icon-left"
|
|
180
|
+
></modus-icon>
|
|
181
|
+
<div class="side-nav-dropdown-menu">Calendar</div>
|
|
182
|
+
</div>
|
|
183
|
+
</li>
|
|
184
|
+
|
|
185
|
+
<!-- Maps Menu with Sub-items -->
|
|
186
|
+
<div class="side-nav-menu-item-container">
|
|
187
|
+
<div class="side-nav-flex-row" (click)="toggleSubMenu('maps', $event)">
|
|
188
|
+
<modus-icon
|
|
189
|
+
name="compass"
|
|
190
|
+
[decorative]="true"
|
|
191
|
+
class="side-nav-collapse-icon side-nav-icon-left"
|
|
192
|
+
></modus-icon>
|
|
193
|
+
<div class="side-nav-dropdown-menu">Maps</div>
|
|
194
|
+
<div class="side-nav-justify-end">
|
|
195
|
+
<modus-icon
|
|
196
|
+
[name]="subMenuStates()['maps'] ? 'expand_less' : 'expand_more'"
|
|
197
|
+
[decorative]="true"
|
|
198
|
+
class="side-nav-collapse-icon side-nav-dropdown-toggle"
|
|
199
|
+
>
|
|
200
|
+
</modus-icon>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
<div
|
|
204
|
+
class="side-nav-children-container"
|
|
205
|
+
[class.hidden]="!subMenuStates()['maps']"
|
|
206
|
+
[attr.aria-hidden]="!subMenuStates()['maps']"
|
|
207
|
+
>
|
|
208
|
+
<div
|
|
209
|
+
class="side-nav-submenu-item side-nav-nested-row"
|
|
210
|
+
(click)="selectMenuItem('map-1')"
|
|
211
|
+
>
|
|
212
|
+
<div>Map 1</div>
|
|
213
|
+
</div>
|
|
214
|
+
<div
|
|
215
|
+
class="side-nav-submenu-item side-nav-nested-row"
|
|
216
|
+
(click)="toggleSubMenu('map-2', $event)"
|
|
217
|
+
>
|
|
218
|
+
<div>Map 2</div>
|
|
219
|
+
<div class="side-nav-justify-end">
|
|
220
|
+
<modus-icon
|
|
221
|
+
[name]="subMenuStates()['map-2'] ? 'expand_less' : 'expand_more'"
|
|
222
|
+
[decorative]="true"
|
|
223
|
+
class="side-nav-collapse-icon side-nav-dropdown-toggle"
|
|
224
|
+
>
|
|
225
|
+
</modus-icon>
|
|
226
|
+
</div>
|
|
227
|
+
</div>
|
|
228
|
+
<div
|
|
229
|
+
class="side-nav-children-container side-nav-nested-submenu"
|
|
230
|
+
[class.hidden]="!subMenuStates()['map-2']"
|
|
231
|
+
[attr.aria-hidden]="!subMenuStates()['map-2']"
|
|
232
|
+
>
|
|
233
|
+
<div
|
|
234
|
+
class="side-nav-submenu-item side-nav-deeply-nested-row"
|
|
235
|
+
(click)="selectMenuItem('map-2-1')"
|
|
236
|
+
>
|
|
237
|
+
<div>Map 1</div>
|
|
238
|
+
</div>
|
|
239
|
+
<div
|
|
240
|
+
class="side-nav-submenu-item side-nav-deeply-nested-row"
|
|
241
|
+
(click)="selectMenuItem('map-2-2')"
|
|
242
|
+
>
|
|
243
|
+
<div>Map 2</div>
|
|
244
|
+
</div>
|
|
245
|
+
</div>
|
|
246
|
+
<div
|
|
247
|
+
class="side-nav-submenu-item side-nav-nested-row"
|
|
248
|
+
(click)="selectMenuItem('map-3')"
|
|
249
|
+
>
|
|
250
|
+
<div>Map 3</div>
|
|
251
|
+
</div>
|
|
252
|
+
</div>
|
|
253
|
+
</div>
|
|
254
|
+
</modus-menu>
|
|
255
|
+
</modus-side-navigation>
|
|
256
|
+
|
|
257
|
+
<div id="submenu-panel-content" class="panel-content flex-1 p-6">
|
|
258
|
+
<div class="text-lg font-semibold text-foreground mb-4">Sub-Menu Navigation</div>
|
|
259
|
+
<p class="text-base text-foreground mb-4">
|
|
260
|
+
This example demonstrates hierarchical navigation with collapsible sub-menus. Click
|
|
261
|
+
on menu items with arrows to expand/collapse sub-menus. The navigation maintains
|
|
262
|
+
state and properly handles nested menu structures.
|
|
263
|
+
</p>
|
|
264
|
+
<div class="mt-4 p-4 rounded-lg bg-card border-default">
|
|
265
|
+
<div class="text-sm font-medium text-card-foreground mb-2">Current Selection:</div>
|
|
266
|
+
<div class="text-sm text-muted-foreground">
|
|
267
|
+
{{ selectedSubMenuItem() || 'No item selected' }}
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
<div class="mt-4 p-4 rounded-lg bg-muted">
|
|
271
|
+
<div class="text-sm font-medium text-foreground mb-2">Sub-Menu States:</div>
|
|
272
|
+
<div class="text-xs text-muted-foreground">
|
|
273
|
+
<div>Charts: {{ subMenuStates()['charts'] ? 'Expanded' : 'Collapsed' }}</div>
|
|
274
|
+
<div>Maps: {{ subMenuStates()['maps'] ? 'Expanded' : 'Collapsed' }}</div>
|
|
275
|
+
<div>Map 2: {{ subMenuStates()['map-2'] ? 'Expanded' : 'Collapsed' }}</div>
|
|
276
|
+
</div>
|
|
277
|
+
</div>
|
|
278
|
+
</div>
|
|
279
|
+
</div>
|
|
280
|
+
</div>
|
|
281
|
+
</demo-example>
|
|
282
|
+
</demo-page>
|
|
283
|
+
`,
|
|
284
|
+
})
|
|
285
|
+
export class SideNavigationDemoPageComponent implements AfterViewInit {
|
|
286
|
+
// State for first example (Navbar Integration)
|
|
287
|
+
readonly navbarMenuExpanded = signal<boolean>(false);
|
|
288
|
+
readonly userCardInfo = signal({
|
|
289
|
+
name: 'John Doe',
|
|
290
|
+
email: 'john.doe@example.com',
|
|
291
|
+
avatarSrc: '',
|
|
292
|
+
avatarAlt: 'User Avatar',
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
// State for second example (Sub-Menu)
|
|
296
|
+
readonly subMenuNavbarExpanded = signal<boolean>(false);
|
|
297
|
+
readonly subMenuUserCardInfo = signal({
|
|
298
|
+
name: 'Jane Smith',
|
|
299
|
+
email: 'jane.smith@example.com',
|
|
300
|
+
avatarSrc: '',
|
|
301
|
+
avatarAlt: 'User Avatar',
|
|
302
|
+
});
|
|
303
|
+
readonly subMenuStates = signal<Record<string, boolean>>({
|
|
304
|
+
charts: false,
|
|
305
|
+
maps: false,
|
|
306
|
+
'map-2': false,
|
|
307
|
+
});
|
|
308
|
+
readonly selectedSubMenuItem = signal<string | null>(null);
|
|
309
|
+
|
|
310
|
+
constructor(private elementRef: ElementRef) {}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Handles navbar main menu open state changes
|
|
314
|
+
* This is triggered when the hamburger menu button is clicked
|
|
315
|
+
*/
|
|
316
|
+
handleNavbarMenuOpenChange(isOpen: boolean): void {
|
|
317
|
+
console.log(
|
|
318
|
+
'Navbar main menu open change - received:',
|
|
319
|
+
isOpen,
|
|
320
|
+
'current state:',
|
|
321
|
+
this.navbarMenuExpanded()
|
|
322
|
+
);
|
|
323
|
+
// The navbar component should handle the toggle internally, but let's ensure we set the state
|
|
324
|
+
this.navbarMenuExpanded.set(isOpen);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
ngAfterViewInit(): void {
|
|
328
|
+
// Implement the same pattern as the Storybook example
|
|
329
|
+
this.setupNavbarSideNavigationIntegration();
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Sets up the navbar-side navigation integration using the Storybook pattern
|
|
334
|
+
*/
|
|
335
|
+
private setupNavbarSideNavigationIntegration(): void {
|
|
336
|
+
// Setup for first example (basic navbar integration)
|
|
337
|
+
const basicContainers = this.elementRef.nativeElement.querySelectorAll('.layout-with-navbar');
|
|
338
|
+
basicContainers.forEach((container: any) => {
|
|
339
|
+
this.setupContainerIntegration(container, 'basic');
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
// Setup for second example (sub-menu integration)
|
|
343
|
+
const subMenuContainers = this.elementRef.nativeElement.querySelectorAll(
|
|
344
|
+
'.layout-with-navbar-submenu'
|
|
345
|
+
);
|
|
346
|
+
subMenuContainers.forEach((container: any) => {
|
|
347
|
+
this.setupContainerIntegration(container, 'submenu');
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
console.log(
|
|
351
|
+
`Navbar-side navigation integration setup complete for ${
|
|
352
|
+
basicContainers.length + subMenuContainers.length
|
|
353
|
+
} containers`
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Sets up integration for a specific container
|
|
359
|
+
*/
|
|
360
|
+
private setupContainerIntegration(container: any, type: 'basic' | 'submenu'): void {
|
|
361
|
+
const exampleType = container.getAttribute('data-example');
|
|
362
|
+
console.log(
|
|
363
|
+
`Setting up ${type} container integration for:`,
|
|
364
|
+
container.className,
|
|
365
|
+
'data-example:',
|
|
366
|
+
exampleType
|
|
367
|
+
);
|
|
368
|
+
|
|
369
|
+
// Listen for navbar main menu open change events
|
|
370
|
+
container.addEventListener('mainMenuOpenChange', (event: any) => {
|
|
371
|
+
console.log(`🔥 ${type} (${exampleType}) navbar main menu open change event:`, event.detail);
|
|
372
|
+
|
|
373
|
+
// Find the side navigation element in this specific container
|
|
374
|
+
const sideNav = container.querySelector('modus-wc-side-navigation');
|
|
375
|
+
|
|
376
|
+
if (sideNav) {
|
|
377
|
+
// Directly set the expanded property on the web component
|
|
378
|
+
sideNav.expanded = event.detail;
|
|
379
|
+
console.log(`✅ Set ${type} (${exampleType}) side navigation expanded to:`, event.detail);
|
|
380
|
+
|
|
381
|
+
// Update the appropriate signal for UI consistency - ONLY for the correct example
|
|
382
|
+
if (type === 'basic' && exampleType === 'basic') {
|
|
383
|
+
console.log('📊 Updating navbarMenuExpanded signal to:', event.detail);
|
|
384
|
+
this.navbarMenuExpanded.set(event.detail);
|
|
385
|
+
} else if (type === 'submenu' && exampleType === 'submenu') {
|
|
386
|
+
console.log('📊 Updating subMenuNavbarExpanded signal to:', event.detail);
|
|
387
|
+
this.subMenuNavbarExpanded.set(event.detail);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// Collapse all sub-menus when side navigation collapses (only for submenu example)
|
|
391
|
+
if (!event.detail && exampleType === 'submenu') {
|
|
392
|
+
this.collapseAllSubMenus();
|
|
393
|
+
}
|
|
394
|
+
} else {
|
|
395
|
+
console.error(`❌ No side navigation found in ${type} container`);
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
// Also listen for expandedChange events from the side navigation itself
|
|
400
|
+
const sideNavs = container.querySelectorAll('modus-wc-side-navigation');
|
|
401
|
+
sideNavs.forEach((sideNav: any) => {
|
|
402
|
+
sideNav.addEventListener('expandedChange', (event: any) => {
|
|
403
|
+
console.log(`${type} (${exampleType}) side navigation expanded change:`, event.detail);
|
|
404
|
+
|
|
405
|
+
// Update the appropriate signal - ONLY for the correct example
|
|
406
|
+
if (type === 'basic' && exampleType === 'basic') {
|
|
407
|
+
this.navbarMenuExpanded.set(event.detail);
|
|
408
|
+
} else if (type === 'submenu' && exampleType === 'submenu') {
|
|
409
|
+
this.subMenuNavbarExpanded.set(event.detail);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Collapse all sub-menus when side navigation collapses (only for submenu example)
|
|
413
|
+
if (!event.detail && exampleType === 'submenu') {
|
|
414
|
+
this.collapseAllSubMenus();
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Also handle Storybook-style sub-menu collapse (only for submenu example)
|
|
418
|
+
if (exampleType === 'submenu') {
|
|
419
|
+
this.handleExpandChange(event);
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Toggles the expanded state of a sub-menu
|
|
427
|
+
*/
|
|
428
|
+
toggleSubMenu(menuKey: string, event: Event): void {
|
|
429
|
+
event.stopPropagation();
|
|
430
|
+
console.log('Toggling sub-menu:', menuKey);
|
|
431
|
+
|
|
432
|
+
const currentStates = this.subMenuStates();
|
|
433
|
+
const newStates = {
|
|
434
|
+
...currentStates,
|
|
435
|
+
[menuKey]: !currentStates[menuKey],
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
this.subMenuStates.set(newStates);
|
|
439
|
+
console.log('Sub-menu states updated:', newStates);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Selects a menu item and updates the current selection
|
|
444
|
+
*/
|
|
445
|
+
selectMenuItem(itemKey: string): void {
|
|
446
|
+
console.log('Selected menu item:', itemKey);
|
|
447
|
+
this.selectedSubMenuItem.set(itemKey);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Handles collapse toggle for sub-menus (Storybook pattern)
|
|
452
|
+
*/
|
|
453
|
+
handleCollapseToggle(event: Event): void {
|
|
454
|
+
const clickedEl = event.currentTarget as HTMLElement;
|
|
455
|
+
const parentLi = clickedEl.closest('li');
|
|
456
|
+
if (!parentLi) return;
|
|
457
|
+
|
|
458
|
+
// Find the icon element that needs to be toggled using the dropdown-toggle class
|
|
459
|
+
const iconEl = clickedEl.querySelector('.side-nav-dropdown-toggle') as any;
|
|
460
|
+
if (!iconEl) return;
|
|
461
|
+
|
|
462
|
+
// Find the parent side nav element (check both container types)
|
|
463
|
+
const parentContainer = clickedEl.closest('.layout-with-navbar, .layout-with-navbar-submenu');
|
|
464
|
+
const sideNav = parentContainer?.querySelector('modus-wc-side-navigation') as any;
|
|
465
|
+
|
|
466
|
+
// Toggle between expand_more and expand_less icons only if side nav is expanded
|
|
467
|
+
const isExpanded = iconEl.getAttribute('name') === 'expand_more';
|
|
468
|
+
if (sideNav?.expanded) {
|
|
469
|
+
iconEl.setAttribute('name', isExpanded ? 'expand_less' : 'expand_more');
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// Find and toggle children visibility
|
|
473
|
+
const childContainer = parentLi.nextElementSibling?.classList.contains(
|
|
474
|
+
'side-nav-children-container'
|
|
475
|
+
)
|
|
476
|
+
? parentLi.nextElementSibling
|
|
477
|
+
: null;
|
|
478
|
+
|
|
479
|
+
if (childContainer && sideNav?.expanded) {
|
|
480
|
+
childContainer.classList.toggle('side-nav-hidden');
|
|
481
|
+
childContainer.setAttribute('aria-hidden', !isExpanded ? 'true' : 'false');
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Handles expand change events (Storybook pattern)
|
|
487
|
+
*/
|
|
488
|
+
handleExpandChange(event: CustomEvent<boolean>): void {
|
|
489
|
+
if (!event.detail) {
|
|
490
|
+
const eventSource = event.target as HTMLElement;
|
|
491
|
+
const container = eventSource?.closest('.layout-with-navbar, .layout-with-navbar-submenu');
|
|
492
|
+
|
|
493
|
+
if (container) {
|
|
494
|
+
// Collapse all child containers if the side navigation is collapsed
|
|
495
|
+
const childrenContainers = container.querySelectorAll('.side-nav-children-container');
|
|
496
|
+
childrenContainers.forEach((container) => {
|
|
497
|
+
container.classList.add('side-nav-hidden');
|
|
498
|
+
container.setAttribute('aria-hidden', 'true');
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
// Reset all collapse icons to expand_more
|
|
502
|
+
const collapseIcons = container.querySelectorAll('.side-nav-dropdown-toggle');
|
|
503
|
+
collapseIcons.forEach((icon: any) => {
|
|
504
|
+
if (icon.getAttribute('name') === 'expand_less') {
|
|
505
|
+
icon.setAttribute('name', 'expand_more');
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Collapses all sub-menus (called when side navigation collapses)
|
|
514
|
+
*/
|
|
515
|
+
private collapseAllSubMenus(): void {
|
|
516
|
+
console.log('Collapsing all sub-menus');
|
|
517
|
+
this.subMenuStates.set({
|
|
518
|
+
charts: false,
|
|
519
|
+
maps: false,
|
|
520
|
+
'regional-maps': false,
|
|
521
|
+
reports: false,
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { DemoPageComponent } from '../shared/demo-page.component';
|
|
4
|
+
import { DemoExampleComponent } from '../shared/demo-example.component';
|
|
5
|
+
import { ModusSkeletonComponent } from '../../components/modus-skeleton.component';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Demo page showcasing the Modus Skeleton component.
|
|
9
|
+
*
|
|
10
|
+
* Demonstrates skeleton loading features including:
|
|
11
|
+
* - Basic skeleton
|
|
12
|
+
* - Different shapes
|
|
13
|
+
* - Custom sizes
|
|
14
|
+
* - Real-world examples
|
|
15
|
+
*/
|
|
16
|
+
@Component({
|
|
17
|
+
selector: 'app-skeleton-demo-page',
|
|
18
|
+
standalone: true,
|
|
19
|
+
imports: [CommonModule, DemoPageComponent, DemoExampleComponent, ModusSkeletonComponent],
|
|
20
|
+
template: `
|
|
21
|
+
<demo-page
|
|
22
|
+
title="Modus Skeleton"
|
|
23
|
+
description="Skeleton components provide loading placeholders that mimic the shape of content being loaded. Use skeletons to improve perceived performance and provide visual feedback during data loading."
|
|
24
|
+
>
|
|
25
|
+
<demo-example
|
|
26
|
+
title="Basic Skeleton"
|
|
27
|
+
description="Simple skeleton with default rectangle shape."
|
|
28
|
+
>
|
|
29
|
+
<div class="flex flex-col gap-6">
|
|
30
|
+
<modus-skeleton />
|
|
31
|
+
<modus-skeleton />
|
|
32
|
+
<modus-skeleton />
|
|
33
|
+
</div>
|
|
34
|
+
</demo-example>
|
|
35
|
+
|
|
36
|
+
<demo-example
|
|
37
|
+
title="Skeleton Shapes"
|
|
38
|
+
description="Skeletons in different shapes."
|
|
39
|
+
>
|
|
40
|
+
<div class="flex flex-wrap gap-6 items-center">
|
|
41
|
+
<div class="flex flex-col gap-2 items-center">
|
|
42
|
+
<modus-skeleton shape="rectangle" width="200px" height="20px" />
|
|
43
|
+
<p class="text-sm text-muted-foreground">Rectangle</p>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<div class="flex flex-col gap-2 items-center">
|
|
47
|
+
<modus-skeleton shape="circle" width="64px" height="64px" />
|
|
48
|
+
<p class="text-sm text-muted-foreground">Circle</p>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</demo-example>
|
|
52
|
+
|
|
53
|
+
<demo-example
|
|
54
|
+
title="Custom Sizes"
|
|
55
|
+
description="Skeletons with custom width and height."
|
|
56
|
+
>
|
|
57
|
+
<div class="flex flex-col gap-6">
|
|
58
|
+
<div class="flex flex-col gap-2">
|
|
59
|
+
<p class="text-sm text-muted-foreground">Small</p>
|
|
60
|
+
<modus-skeleton width="100px" height="12px" />
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<div class="flex flex-col gap-2">
|
|
64
|
+
<p class="text-sm text-muted-foreground">Medium</p>
|
|
65
|
+
<modus-skeleton width="200px" height="16px" />
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
<div class="flex flex-col gap-2">
|
|
69
|
+
<p class="text-sm text-muted-foreground">Large</p>
|
|
70
|
+
<modus-skeleton width="300px" height="24px" />
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</demo-example>
|
|
74
|
+
|
|
75
|
+
<demo-example
|
|
76
|
+
title="Real-World Example"
|
|
77
|
+
description="Skeleton loading states for common UI patterns."
|
|
78
|
+
>
|
|
79
|
+
<div class="flex flex-col gap-6">
|
|
80
|
+
<!-- Card skeleton -->
|
|
81
|
+
<div class="p-6 rounded-lg bg-card border-default">
|
|
82
|
+
<div class="flex gap-4">
|
|
83
|
+
<modus-skeleton shape="circle" width="64px" height="64px" />
|
|
84
|
+
<div class="flex flex-col gap-2 flex-1">
|
|
85
|
+
<modus-skeleton width="60%" height="20px" />
|
|
86
|
+
<modus-skeleton width="40%" height="16px" />
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<!-- List skeleton -->
|
|
92
|
+
<div class="flex flex-col gap-3">
|
|
93
|
+
<modus-skeleton width="100%" height="16px" />
|
|
94
|
+
<modus-skeleton width="90%" height="16px" />
|
|
95
|
+
<modus-skeleton width="95%" height="16px" />
|
|
96
|
+
<modus-skeleton width="85%" height="16px" />
|
|
97
|
+
</div>
|
|
98
|
+
|
|
99
|
+
<!-- Form skeleton -->
|
|
100
|
+
<div class="flex flex-col gap-4">
|
|
101
|
+
<modus-skeleton width="120px" height="14px" />
|
|
102
|
+
<modus-skeleton width="100%" height="40px" />
|
|
103
|
+
<modus-skeleton width="100px" height="14px" />
|
|
104
|
+
<modus-skeleton width="100%" height="40px" />
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
</demo-example>
|
|
108
|
+
</demo-page>
|
|
109
|
+
`,
|
|
110
|
+
})
|
|
111
|
+
export class SkeletonDemoPageComponent {}
|
|
112
|
+
|