This is page 7 of 7. Use http://codebase.md/push-based/angular-toolkit-mcp?page={x} to view the full context. # Directory Structure ``` ├── .aiignore ├── .cursor │ ├── flows │ │ ├── component-refactoring │ │ │ ├── 01-review-component.mdc │ │ │ ├── 02-refactor-component.mdc │ │ │ ├── 03-validate-component.mdc │ │ │ └── angular-20.md │ │ ├── ds-refactoring-flow │ │ │ ├── 01-find-violations.mdc │ │ │ ├── 01b-find-all-violations.mdc │ │ │ ├── 02-plan-refactoring.mdc │ │ │ ├── 02b-plan-refactoring-for-all-violations.mdc │ │ │ ├── 03-fix-violations.mdc │ │ │ ├── 03-non-viable-cases.mdc │ │ │ ├── 04-validate-changes.mdc │ │ │ ├── 05-prepare-report.mdc │ │ │ └── clean-global-styles.mdc │ │ └── README.md │ └── mcp.json.example ├── .github │ └── workflows │ └── ci.yml ├── .gitignore ├── .nvmrc ├── .prettierignore ├── .prettierrc ├── assets │ ├── entain-logo.png │ └── entain.png ├── CONTRIBUTING.MD ├── docs │ ├── architecture-internal-design.md │ ├── component-refactoring-flow.md │ ├── contracts.md │ ├── ds-refactoring-flow.md │ ├── getting-started.md │ ├── README.md │ ├── tools.md │ └── writing-custom-tools.md ├── eslint.config.mjs ├── jest.config.ts ├── jest.preset.mjs ├── LICENSE ├── nx.json ├── package-lock.json ├── package.json ├── packages │ ├── .gitkeep │ ├── angular-mcp │ │ ├── eslint.config.mjs │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── assets │ │ │ │ └── .gitkeep │ │ │ └── main.ts │ │ ├── tsconfig.app.json │ │ ├── tsconfig.json │ │ ├── vitest.config.mts │ │ └── webpack.config.cjs │ ├── angular-mcp-server │ │ ├── eslint.config.mjs │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── index.ts │ │ │ └── lib │ │ │ ├── angular-mcp-server.ts │ │ │ ├── prompts │ │ │ │ └── prompt-registry.ts │ │ │ ├── tools │ │ │ │ ├── ds │ │ │ │ │ ├── component │ │ │ │ │ │ ├── get-deprecated-css-classes.tool.ts │ │ │ │ │ │ ├── get-ds-component-data.tool.ts │ │ │ │ │ │ ├── list-ds-components.tool.ts │ │ │ │ │ │ └── utils │ │ │ │ │ │ ├── deprecated-css-helpers.ts │ │ │ │ │ │ ├── doc-helpers.ts │ │ │ │ │ │ ├── metadata-helpers.ts │ │ │ │ │ │ └── paths-helpers.ts │ │ │ │ │ ├── component-contract │ │ │ │ │ │ ├── builder │ │ │ │ │ │ │ ├── build-component-contract.tool.ts │ │ │ │ │ │ │ ├── models │ │ │ │ │ │ │ │ ├── schema.ts │ │ │ │ │ │ │ │ └── types.ts │ │ │ │ │ │ │ ├── spec │ │ │ │ │ │ │ │ ├── css-match.spec.ts │ │ │ │ │ │ │ │ ├── dom-slots.extractor.spec.ts │ │ │ │ │ │ │ │ ├── element-helpers.spec.ts │ │ │ │ │ │ │ │ ├── inline-styles.collector.spec.ts │ │ │ │ │ │ │ │ ├── meta.generator.spec.ts │ │ │ │ │ │ │ │ ├── public-api.extractor.spec.ts │ │ │ │ │ │ │ │ ├── styles.collector.spec.ts │ │ │ │ │ │ │ │ └── typescript-analyzer.spec.ts │ │ │ │ │ │ │ └── utils │ │ │ │ │ │ │ ├── build-contract.ts │ │ │ │ │ │ │ ├── css-match.ts │ │ │ │ │ │ │ ├── dom-slots.extractor.ts │ │ │ │ │ │ │ ├── element-helpers.ts │ │ │ │ │ │ │ ├── inline-styles.collector.ts │ │ │ │ │ │ │ ├── meta.generator.ts │ │ │ │ │ │ │ ├── public-api.extractor.ts │ │ │ │ │ │ │ ├── styles.collector.ts │ │ │ │ │ │ │ └── typescript-analyzer.ts │ │ │ │ │ │ ├── diff │ │ │ │ │ │ │ ├── diff-component-contract.tool.ts │ │ │ │ │ │ │ ├── models │ │ │ │ │ │ │ │ └── schema.ts │ │ │ │ │ │ │ ├── spec │ │ │ │ │ │ │ │ ├── diff-utils.spec.ts │ │ │ │ │ │ │ │ └── dom-path-utils.spec.ts │ │ │ │ │ │ │ └── utils │ │ │ │ │ │ │ ├── diff-utils.ts │ │ │ │ │ │ │ └── dom-path-utils.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── list │ │ │ │ │ │ │ ├── list-component-contracts.tool.ts │ │ │ │ │ │ │ ├── models │ │ │ │ │ │ │ │ ├── schema.ts │ │ │ │ │ │ │ │ └── types.ts │ │ │ │ │ │ │ ├── spec │ │ │ │ │ │ │ │ └── contract-list-utils.spec.ts │ │ │ │ │ │ │ └── utils │ │ │ │ │ │ │ └── contract-list-utils.ts │ │ │ │ │ │ └── shared │ │ │ │ │ │ ├── models │ │ │ │ │ │ │ └── types.ts │ │ │ │ │ │ ├── spec │ │ │ │ │ │ │ └── contract-file-ops.spec.ts │ │ │ │ │ │ └── utils │ │ │ │ │ │ └── contract-file-ops.ts │ │ │ │ │ ├── component-usage-graph │ │ │ │ │ │ ├── build-component-usage-graph.tool.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── models │ │ │ │ │ │ │ ├── config.ts │ │ │ │ │ │ │ ├── schema.ts │ │ │ │ │ │ │ └── types.ts │ │ │ │ │ │ └── utils │ │ │ │ │ │ ├── angular-parser.ts │ │ │ │ │ │ ├── component-helpers.ts │ │ │ │ │ │ ├── component-usage-graph-builder.ts │ │ │ │ │ │ ├── path-resolver.ts │ │ │ │ │ │ └── unified-ast-analyzer.ts │ │ │ │ │ ├── ds.tools.ts │ │ │ │ │ ├── project │ │ │ │ │ │ ├── get-project-dependencies.tool.ts │ │ │ │ │ │ ├── report-deprecated-css.tool.ts │ │ │ │ │ │ └── utils │ │ │ │ │ │ ├── dependencies-helpers.ts │ │ │ │ │ │ └── styles-report-helpers.ts │ │ │ │ │ ├── report-violations │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── models │ │ │ │ │ │ │ ├── schema.ts │ │ │ │ │ │ │ └── types.ts │ │ │ │ │ │ ├── report-all-violations.tool.ts │ │ │ │ │ │ └── report-violations.tool.ts │ │ │ │ │ ├── shared │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── models │ │ │ │ │ │ │ ├── input-schemas.model.ts │ │ │ │ │ │ │ └── schema-helpers.ts │ │ │ │ │ │ ├── utils │ │ │ │ │ │ │ ├── component-validation.ts │ │ │ │ │ │ │ ├── cross-platform-path.ts │ │ │ │ │ │ │ ├── handler-helpers.ts │ │ │ │ │ │ │ ├── output.utils.ts │ │ │ │ │ │ │ └── regex-helpers.ts │ │ │ │ │ │ └── violation-analysis │ │ │ │ │ │ ├── base-analyzer.ts │ │ │ │ │ │ ├── coverage-analyzer.ts │ │ │ │ │ │ ├── formatters.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── types.ts │ │ │ │ │ └── tools.ts │ │ │ │ ├── schema.ts │ │ │ │ ├── tools.ts │ │ │ │ ├── types.ts │ │ │ │ └── utils.ts │ │ │ └── validation │ │ │ ├── angular-mcp-server-options.schema.ts │ │ │ ├── ds-components-file-loader.validation.ts │ │ │ ├── ds-components-file.validation.ts │ │ │ ├── ds-components.schema.ts │ │ │ └── file-existence.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.tsbuildinfo │ │ └── vitest.config.mts │ ├── minimal-repo │ │ └── packages │ │ ├── application │ │ │ ├── angular.json │ │ │ ├── code-pushup.config.ts │ │ │ ├── src │ │ │ │ ├── app │ │ │ │ │ ├── app.component.ts │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.routes.ts │ │ │ │ │ ├── components │ │ │ │ │ │ ├── refactoring-tests │ │ │ │ │ │ │ ├── bad-alert-tooltip-input.component.ts │ │ │ │ │ │ │ ├── bad-alert.component.ts │ │ │ │ │ │ │ ├── bad-button-dropdown.component.ts │ │ │ │ │ │ │ ├── bad-document.component.ts │ │ │ │ │ │ │ ├── bad-global-this.component.ts │ │ │ │ │ │ │ ├── bad-mixed-external-assets.component.css │ │ │ │ │ │ │ ├── bad-mixed-external-assets.component.html │ │ │ │ │ │ │ ├── bad-mixed-external-assets.component.ts │ │ │ │ │ │ │ ├── bad-mixed-not-standalone.component.ts │ │ │ │ │ │ │ ├── bad-mixed.component.ts │ │ │ │ │ │ │ ├── bad-mixed.module.ts │ │ │ │ │ │ │ ├── bad-modal-progress.component.ts │ │ │ │ │ │ │ ├── bad-this-window-document.component.ts │ │ │ │ │ │ │ ├── bad-window.component.ts │ │ │ │ │ │ │ ├── complex-components │ │ │ │ │ │ │ │ ├── first-case │ │ │ │ │ │ │ │ │ ├── dashboard-demo.component.html │ │ │ │ │ │ │ │ │ ├── dashboard-demo.component.scss │ │ │ │ │ │ │ │ │ ├── dashboard-demo.component.ts │ │ │ │ │ │ │ │ │ ├── dashboard-header.component.html │ │ │ │ │ │ │ │ │ ├── dashboard-header.component.scss │ │ │ │ │ │ │ │ │ └── dashboard-header.component.ts │ │ │ │ │ │ │ │ ├── second-case │ │ │ │ │ │ │ │ │ ├── complex-badge-widget.component.scss │ │ │ │ │ │ │ │ │ ├── complex-badge-widget.component.ts │ │ │ │ │ │ │ │ │ └── complex-widget-demo.component.ts │ │ │ │ │ │ │ │ └── third-case │ │ │ │ │ │ │ │ ├── product-card.component.scss │ │ │ │ │ │ │ │ ├── product-card.component.ts │ │ │ │ │ │ │ │ └── product-showcase.component.ts │ │ │ │ │ │ │ ├── group-1 │ │ │ │ │ │ │ │ ├── bad-mixed-1.component.ts │ │ │ │ │ │ │ │ ├── bad-mixed-1.module.ts │ │ │ │ │ │ │ │ ├── bad-mixed-external-assets-1.component.css │ │ │ │ │ │ │ │ ├── bad-mixed-external-assets-1.component.html │ │ │ │ │ │ │ │ ├── bad-mixed-external-assets-1.component.ts │ │ │ │ │ │ │ │ └── bad-mixed-not-standalone-1.component.ts │ │ │ │ │ │ │ ├── group-2 │ │ │ │ │ │ │ │ ├── bad-mixed-2.component.ts │ │ │ │ │ │ │ │ ├── bad-mixed-2.module.ts │ │ │ │ │ │ │ │ ├── bad-mixed-external-assets-2.component.css │ │ │ │ │ │ │ │ ├── bad-mixed-external-assets-2.component.html │ │ │ │ │ │ │ │ ├── bad-mixed-external-assets-2.component.ts │ │ │ │ │ │ │ │ └── bad-mixed-not-standalone-2.component.ts │ │ │ │ │ │ │ ├── group-3 │ │ │ │ │ │ │ │ ├── bad-mixed-3.component.spec.ts │ │ │ │ │ │ │ │ ├── bad-mixed-3.component.ts │ │ │ │ │ │ │ │ ├── bad-mixed-3.module.ts │ │ │ │ │ │ │ │ ├── bad-mixed-external-assets-3.component.css │ │ │ │ │ │ │ │ ├── bad-mixed-external-assets-3.component.html │ │ │ │ │ │ │ │ ├── bad-mixed-external-assets-3.component.ts │ │ │ │ │ │ │ │ ├── bad-mixed-not-standalone-3.component.ts │ │ │ │ │ │ │ │ └── lazy-loader-3.component.ts │ │ │ │ │ │ │ └── group-4 │ │ │ │ │ │ │ ├── multi-violation-test.component.html │ │ │ │ │ │ │ ├── multi-violation-test.component.scss │ │ │ │ │ │ │ └── multi-violation-test.component.ts │ │ │ │ │ │ └── validation-tests │ │ │ │ │ │ ├── circular-dependency.component.ts │ │ │ │ │ │ ├── external-files-missing.component.ts │ │ │ │ │ │ ├── invalid-lifecycle.component.ts │ │ │ │ │ │ ├── invalid-pipe-usage.component.ts │ │ │ │ │ │ ├── invalid-template-syntax.component.ts │ │ │ │ │ │ ├── missing-imports.component.ts │ │ │ │ │ │ ├── missing-method.component.ts │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ ├── standalone-module-conflict.component.ts │ │ │ │ │ │ ├── standalone-module-conflict.module.ts │ │ │ │ │ │ ├── template-reference-error.component.ts │ │ │ │ │ │ ├── type-mismatch.component.ts │ │ │ │ │ │ ├── valid.component.ts │ │ │ │ │ │ ├── wrong-decorator-usage.component.ts │ │ │ │ │ │ └── wrong-property-binding.component.ts │ │ │ │ │ └── styles │ │ │ │ │ ├── bad-global-styles.scss │ │ │ │ │ ├── base │ │ │ │ │ │ ├── _reset.scss │ │ │ │ │ │ └── base.scss │ │ │ │ │ ├── components │ │ │ │ │ │ └── components.scss │ │ │ │ │ ├── extended-deprecated-styles.scss │ │ │ │ │ ├── layout │ │ │ │ │ │ └── layout.scss │ │ │ │ │ ├── new-styles-1.scss │ │ │ │ │ ├── new-styles-10.scss │ │ │ │ │ ├── new-styles-2.scss │ │ │ │ │ ├── new-styles-3.scss │ │ │ │ │ ├── new-styles-4.scss │ │ │ │ │ ├── new-styles-5.scss │ │ │ │ │ ├── new-styles-6.scss │ │ │ │ │ ├── new-styles-7.scss │ │ │ │ │ ├── new-styles-8.scss │ │ │ │ │ ├── new-styles-9.scss │ │ │ │ │ ├── themes │ │ │ │ │ │ └── themes.scss │ │ │ │ │ └── utilities │ │ │ │ │ └── utilities.scss │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ └── styles.css │ │ │ ├── tsconfig.app.json │ │ │ ├── tsconfig.json │ │ │ └── tsconfig.spec.json │ │ └── design-system │ │ ├── component-options.mjs │ │ ├── storybook │ │ │ └── card │ │ │ └── card-tabs │ │ │ └── overview.mdx │ │ ├── storybook-host-app │ │ │ └── src │ │ │ └── components │ │ │ ├── badge │ │ │ │ ├── badge-tabs │ │ │ │ │ ├── api.mdx │ │ │ │ │ ├── examples.mdx │ │ │ │ │ └── overview.mdx │ │ │ │ ├── badge.component.mdx │ │ │ │ └── badge.component.stories.ts │ │ │ ├── modal │ │ │ │ ├── demo-cdk-dialog-cmp.component.ts │ │ │ │ ├── demo-modal-cmp.component.ts │ │ │ │ ├── modal-tabs │ │ │ │ │ ├── api.mdx │ │ │ │ │ ├── examples.mdx │ │ │ │ │ └── overview.mdx │ │ │ │ ├── modal.component.mdx │ │ │ │ └── modal.component.stories.ts │ │ │ └── segmented-control │ │ │ ├── segmented-control-tabs │ │ │ │ ├── api.mdx │ │ │ │ ├── examples.mdx │ │ │ │ └── overview.mdx │ │ │ ├── segmented-control.component.mdx │ │ │ └── segmented-control.component.stories.ts │ │ └── ui │ │ ├── badge │ │ │ ├── package.json │ │ │ ├── project.json │ │ │ └── src │ │ │ └── badge.component.ts │ │ ├── modal │ │ │ ├── package.json │ │ │ ├── project.json │ │ │ └── src │ │ │ ├── modal-content.component.ts │ │ │ ├── modal-header │ │ │ │ └── modal-header.component.ts │ │ │ ├── modal-header-drag │ │ │ │ └── modal-header-drag.component.ts │ │ │ └── modal.component.ts │ │ ├── rx-host-listener │ │ │ ├── package.json │ │ │ ├── project.json │ │ │ └── src │ │ │ └── rx-host-listener.ts │ │ └── segmented-control │ │ ├── package.json │ │ ├── project.json │ │ └── src │ │ ├── segmented-control.component.html │ │ ├── segmented-control.component.ts │ │ ├── segmented-control.token.ts │ │ └── segmented-option.component.ts │ └── shared │ ├── angular-ast-utils │ │ ├── .spec.swcrc │ │ ├── ai │ │ │ ├── API.md │ │ │ ├── EXAMPLES.md │ │ │ └── FUNCTIONS.md │ │ ├── docs │ │ │ └── angular-component-tree.md │ │ ├── eslint.config.mjs │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── index.ts │ │ │ └── lib │ │ │ ├── constants.ts │ │ │ ├── decorator-config.visitor.inline-styles.spec.ts │ │ │ ├── decorator-config.visitor.spec.ts │ │ │ ├── decorator-config.visitor.ts │ │ │ ├── parse-component.ts │ │ │ ├── schema.ts │ │ │ ├── styles │ │ │ │ └── utils.ts │ │ │ ├── template │ │ │ │ ├── noop-tmpl-visitor.ts │ │ │ │ ├── template.walk.ts │ │ │ │ ├── utils.spec.ts │ │ │ │ ├── utils.ts │ │ │ │ └── utils.unit.test.ts │ │ │ ├── ts.walk.ts │ │ │ ├── types.ts │ │ │ └── utils.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ └── vitest.config.mts │ ├── DEPENDENCIES.md │ ├── ds-component-coverage │ │ ├── .spec.swcrc │ │ ├── ai │ │ │ ├── API.md │ │ │ ├── EXAMPLES.md │ │ │ └── FUNCTIONS.md │ │ ├── docs │ │ │ ├── examples │ │ │ │ ├── report.json │ │ │ │ └── report.md │ │ │ ├── images │ │ │ │ └── report-overview.png │ │ │ └── README.md │ │ ├── jest.config.ts │ │ ├── mocks │ │ │ └── fixtures │ │ │ └── e2e │ │ │ ├── asset-location │ │ │ │ ├── code-pushup.config.ts │ │ │ │ ├── inl-styl-inl-tmpl │ │ │ │ │ └── inl-styl-inl-tmpl.component.ts │ │ │ │ ├── inl-styl-url-tmpl │ │ │ │ │ ├── inl-styl-url-tmpl.component.html │ │ │ │ │ └── inl-styl-url-tmpl.component.ts │ │ │ │ ├── multi-url-styl-inl-tmpl │ │ │ │ │ ├── multi-url-styl-inl-tmpl-1.component.css │ │ │ │ │ ├── multi-url-styl-inl-tmpl-2.component.css │ │ │ │ │ └── multi-url-styl-inl-tmpl.component.ts │ │ │ │ ├── url-styl-inl-tmpl │ │ │ │ │ ├── url-styl-inl-tmpl.component.css │ │ │ │ │ └── url-styl-inl-tmpl.component.ts │ │ │ │ ├── url-styl-single-inl-tmpl │ │ │ │ │ ├── url-styl-inl-tmpl.component.ts │ │ │ │ │ └── url-styl-single-inl-tmpl.component.css │ │ │ │ └── url-styl-url-tmpl │ │ │ │ ├── inl-styl-url-tmpl.component.css │ │ │ │ ├── inl-styl-url-tmpl.component.html │ │ │ │ └── inl-styl-url-tmpl.component.ts │ │ │ ├── demo │ │ │ │ ├── code-pushup.config.ts │ │ │ │ ├── prompt.md │ │ │ │ └── src │ │ │ │ ├── bad-button-dropdown.component.ts │ │ │ │ ├── bad-modal-progress.component.ts │ │ │ │ ├── mixed-external-assets.component.css │ │ │ │ ├── mixed-external-assets.component.html │ │ │ │ ├── mixed-external-assets.component.ts │ │ │ │ └── sub-folder-1 │ │ │ │ ├── bad-alert.component.ts │ │ │ │ ├── button.component.ts │ │ │ │ └── sub-folder-2 │ │ │ │ ├── bad-alert-tooltip-input.component.ts │ │ │ │ └── bad-mixed.component.ts │ │ │ ├── line-number │ │ │ │ ├── code-pushup.config.ts │ │ │ │ ├── inl-styl-single.component.ts │ │ │ │ ├── inl-styl-span.component.ts │ │ │ │ ├── inl-tmpl-single.component.ts │ │ │ │ ├── inl-tmpl-span.component.ts │ │ │ │ ├── url-style │ │ │ │ │ ├── url-styl-single.component.css │ │ │ │ │ ├── url-styl-single.component.ts │ │ │ │ │ ├── url-styl-span.component.css │ │ │ │ │ └── url-styl-span.component.ts │ │ │ │ └── url-tmpl │ │ │ │ ├── url-tmpl-single.component.html │ │ │ │ ├── url-tmpl-single.component.ts │ │ │ │ ├── url-tmpl-span.component.html │ │ │ │ └── url-tmpl-span.component.ts │ │ │ ├── style-format │ │ │ │ ├── code-pushup.config.ts │ │ │ │ ├── inl-css.component.ts │ │ │ │ ├── inl-scss.component.ts │ │ │ │ ├── styles.css │ │ │ │ ├── styles.scss │ │ │ │ ├── url-css.component.ts │ │ │ │ └── url-scss.component.ts │ │ │ └── template-syntax │ │ │ ├── class-attribute.component.ts │ │ │ ├── class-binding.component.ts │ │ │ ├── code-pushup.config.ts │ │ │ └── ng-class-binding.component.ts │ │ ├── package.json │ │ ├── src │ │ │ ├── core.config.ts │ │ │ ├── index.ts │ │ │ └── lib │ │ │ ├── constants.ts │ │ │ ├── ds-component-coverage.plugin.ts │ │ │ ├── runner │ │ │ │ ├── audits │ │ │ │ │ └── ds-coverage │ │ │ │ │ ├── class-definition.utils.ts │ │ │ │ │ ├── class-definition.visitor.ts │ │ │ │ │ ├── class-definition.visitor.unit.test.ts │ │ │ │ │ ├── class-usage.utils.ts │ │ │ │ │ ├── class-usage.visitor.spec.ts │ │ │ │ │ ├── class-usage.visitor.ts │ │ │ │ │ ├── constants.ts │ │ │ │ │ ├── ds-coverage.audit.ts │ │ │ │ │ ├── schema.ts │ │ │ │ │ └── utils.ts │ │ │ │ ├── create-runner.ts │ │ │ │ └── schema.ts │ │ │ └── utils.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ └── vitest.config.mts │ ├── LLMS.md │ ├── models │ │ ├── ai │ │ │ ├── API.md │ │ │ ├── EXAMPLES.md │ │ │ └── FUNCTIONS.md │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── index.ts │ │ │ └── lib │ │ │ ├── cli.ts │ │ │ ├── diagnostics.ts │ │ │ └── mcp.ts │ │ ├── tsconfig.json │ │ └── tsconfig.lib.json │ ├── styles-ast-utils │ │ ├── .spec.swcrc │ │ ├── ai │ │ │ ├── API.md │ │ │ ├── EXAMPLES.md │ │ │ └── FUNCTIONS.md │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── index.ts │ │ │ └── lib │ │ │ ├── postcss-safe-parser.d.ts │ │ │ ├── styles-ast-utils.spec.ts │ │ │ ├── styles-ast-utils.ts │ │ │ ├── stylesheet.parse.ts │ │ │ ├── stylesheet.parse.unit.test.ts │ │ │ ├── stylesheet.visitor.ts │ │ │ ├── stylesheet.walk.ts │ │ │ ├── types.ts │ │ │ ├── utils.ts │ │ │ └── utils.unit.test.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ └── vitest.config.mts │ ├── typescript-ast-utils │ │ ├── .spec.swcrc │ │ ├── ai │ │ │ ├── API.md │ │ │ ├── EXAMPLES.md │ │ │ └── FUNCTIONS.md │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── index.ts │ │ │ └── lib │ │ │ ├── constants.ts │ │ │ └── utils.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ └── vitest.config.mts │ └── utils │ ├── .spec.swcrc │ ├── ai │ │ ├── API.md │ │ ├── EXAMPLES.md │ │ └── FUNCTIONS.md │ ├── package.json │ ├── README.md │ ├── src │ │ ├── index.ts │ │ └── lib │ │ ├── execute-process.ts │ │ ├── execute-process.unit.test.ts │ │ ├── file │ │ │ ├── default-export-loader.spec.ts │ │ │ ├── default-export-loader.ts │ │ │ ├── file.resolver.ts │ │ │ └── find-in-file.ts │ │ ├── format-command-log.integration.test.ts │ │ ├── format-command-log.ts │ │ ├── logging.ts │ │ └── utils.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ ├── tsconfig.spec.json │ ├── vite.config.ts │ └── vitest.config.mts ├── README.md ├── testing │ ├── setup │ │ ├── eslint.config.mjs │ │ ├── eslint.next.config.mjs │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── index.d.ts │ │ │ ├── index.mjs │ │ │ └── memfs.constants.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ ├── vitest.config.mts │ │ └── vitest.integration.config.mts │ ├── utils │ │ ├── eslint.config.mjs │ │ ├── eslint.next.config.mjs │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── index.ts │ │ │ └── lib │ │ │ ├── constants.ts │ │ │ ├── e2e-setup.ts │ │ │ ├── execute-process-helper.mock.ts │ │ │ ├── execute-process.mock.mjs │ │ │ ├── os-agnostic-paths.ts │ │ │ ├── os-agnostic-paths.unit.test.ts │ │ │ ├── source-file-from.code.ts │ │ │ └── string.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ ├── vite.config.ts │ │ ├── vitest.config.mts │ │ └── vitest.integration.config.mts │ └── vitest-setup │ ├── eslint.config.mjs │ ├── eslint.next.config.mjs │ ├── package.json │ ├── README.md │ ├── src │ │ ├── index.ts │ │ └── lib │ │ ├── configuration.ts │ │ └── fs-memfs.setup-file.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ ├── tsconfig.spec.json │ ├── vite.config.ts │ ├── vitest.config.mts │ └── vitest.integration.config.mts ├── tools │ ├── nx-advanced-profile.bin.js │ ├── nx-advanced-profile.js │ ├── nx-advanced-profile.postinstall.js │ └── perf_hooks.patch.js ├── tsconfig.base.json ├── tsconfig.json └── vitest.workspace.ts ``` # Files -------------------------------------------------------------------------------- /packages/shared/angular-ast-utils/src/lib/template/utils.spec.ts: -------------------------------------------------------------------------------- ```typescript import { extractClassNamesFromNgClassAST, ngClassContainsClass, ngClassesIncludeClassName, } from './utils'; import type { ASTWithSource, TmplAstElement, } from '@angular/compiler' with { 'resolution-mode': 'import' }; let parseTemplate: typeof import('@angular/compiler').parseTemplate; beforeAll(async () => { parseTemplate = (await import('@angular/compiler')).parseTemplate; }); function parseNgClassExpression(expression: string): ASTWithSource { const template = `<div [ngClass]="${expression}"></div>`; const result = parseTemplate(template, 'test.html'); const element = result.nodes[0] as TmplAstElement; const ngClassInput = element.inputs.find((input) => input.name === 'ngClass'); return ngClassInput?.value as ASTWithSource; } describe('extractClassNamesFromNgClassAST', () => { it('should extract classes from array literals', () => { const expression = "['btn', 'btn-primary', someVariable]"; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'btn', 'btn-primary', 'other', ]); expect(result).toEqual(['btn', 'btn-primary']); }); it('should extract classes from object literals', () => { const expression = "{ 'btn': true, 'btn-primary': isActive, 'other-class': false }"; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'btn', 'btn-primary', 'other-class', ]); expect(result).toEqual(['btn', 'btn-primary', 'other-class']); }); it('should extract classes from string literals', () => { const expression = "'btn btn-primary active'"; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'btn', 'btn-primary', 'active', ]); expect(result).toEqual(['btn', 'btn-primary', 'active']); }); it('should extract classes from ternary expressions without false positives from conditions', () => { const expression = "option?.logo?.toLowerCase() === 'card' ? 'card-special' : 'card-normal'"; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'card', 'card-special', 'card-normal', ]); expect(result).toEqual(['card-special', 'card-normal']); }); it('should not extract classes from binary comparison expressions', () => { const expression = "someValue === 'card' && otherValue !== 'btn'"; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'card', 'btn', ]); expect(result).toEqual([]); }); it('should handle complex nested expressions', () => { const expression = "[option?.logo?.toLowerCase() === 'card' ? 'card-active' : '', 'base-class']"; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'card', 'card-active', 'base-class', ]); expect(result).toEqual(['card-active', 'base-class']); }); it('should handle object with conditional values', () => { const expression = "{ 'card': option?.logo?.toLowerCase() === 'card', 'btn': isButton }"; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'card', 'btn', ]); expect(result).toEqual(['card', 'btn']); }); it('should handle spaced class names in object keys', () => { const expression = "{ 'card special': true, 'btn primary': false }"; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'card', 'special', 'btn', 'primary', ]); expect(result).toEqual(['card', 'special', 'btn', 'primary']); }); it('should return empty array for non-matching classes', () => { const expression = "['other', 'different']"; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'card', 'btn', ]); expect(result).toEqual([]); }); it('should remove duplicates', () => { const expression = "['card', 'card', 'btn']"; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'card', 'btn', ]); expect(result).toEqual(['card', 'btn']); }); }); describe('ngClassContainsClass', () => { it('should return true when class is found in AST', () => { const expression = "['btn', 'btn-primary']"; const astWithSource = parseNgClassExpression(expression); expect(ngClassContainsClass(astWithSource, 'btn')).toBe(true); expect(ngClassContainsClass(astWithSource, 'btn-primary')).toBe(true); }); it('should return false when class is not found in AST', () => { const expression = "['other', 'different']"; const astWithSource = parseNgClassExpression(expression); expect(ngClassContainsClass(astWithSource, 'btn')).toBe(false); }); it('should return false for classes in comparisons', () => { const expression = "option?.logo?.toLowerCase() === 'card' ? 'active' : 'inactive'"; const astWithSource = parseNgClassExpression(expression); // Should not find 'card' since it's in a comparison, not a class assignment expect(ngClassContainsClass(astWithSource, 'card')).toBe(false); expect(ngClassContainsClass(astWithSource, 'active')).toBe(true); }); }); describe('AST-based ngClass parsing integration tests', () => { it('should handle the original problem case correctly', () => { const expression = "[option?.logo?.toLowerCase(), option?.logo?.toLowerCase() == 'card' ? mergedCardLogoClass : '']"; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, ['card']); // Should NOT find 'card' from the comparison expect(result).toEqual([]); }); it('should find card when actually used as a class', () => { const expression = "['card', 'other-class']"; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, ['card']); expect(result).toEqual(['card']); }); it('should handle complex real-world scenarios', () => { const expression = "{ 'card': isCard, 'btn': isButton, 'active': option?.logo?.toLowerCase() === 'card' }"; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'card', 'btn', ]); expect(result).toEqual(['card', 'btn']); }); }); describe('AST-based class binding parsing', () => { function parseClassExpression(expression: string): ASTWithSource { const template = `<div [class]="${expression}"></div>`; const result = parseTemplate(template, 'test.html'); const element = result.nodes[0] as TmplAstElement; const classInput = element.inputs.find((input) => input.name === 'class'); return classInput?.value as ASTWithSource; } it('should work the same for [class] bindings with false positive avoidance', () => { const expression = "option?.logo?.toLowerCase() == 'card' ? 'card-special' : 'other'"; const astWithSource = parseClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'card', 'card-special', ]); expect(result).toEqual(['card-special']); }); it('should handle simple string literals in [class] bindings', () => { const expression = "'card btn-primary'"; const astWithSource = parseClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'card', 'btn-primary', 'other', ]); expect(result).toEqual(['card', 'btn-primary']); }); it('should handle ternary expressions in [class] bindings', () => { const expression = "isActive ? 'card active' : 'card inactive'"; const astWithSource = parseClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'card', 'active', 'inactive', ]); expect(result).toEqual(['card', 'active', 'inactive']); }); }); describe('AST-based interpolated class parsing', () => { function parseInterpolatedClassExpression(classValue: string): ASTWithSource { const template = `<div class="${classValue}"></div>`; const result = parseTemplate(template, 'test.html'); const element = result.nodes[0] as TmplAstElement; const classInput = element.inputs.find((input) => input.name === 'class'); return classInput?.value as ASTWithSource; } it('should extract classes from interpolated class attributes', () => { const classValue = 'count count-{{ size() }} other-class'; const astWithSource = parseInterpolatedClassExpression(classValue); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'count', 'other-class', 'different', ]); expect(result).toEqual(['count', 'other-class']); }); it('should handle interpolation with multiple dynamic parts', () => { const classValue = 'prefix {{ type }} middle {{ state }} suffix'; const astWithSource = parseInterpolatedClassExpression(classValue); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'prefix', 'middle', 'suffix', ]); expect(result).toEqual(['prefix', 'middle', 'suffix']); }); it('should handle interpolation with only static classes', () => { const classValue = 'btn btn-primary active'; const astWithSource = parseInterpolatedClassExpression(classValue); // Static class attributes without interpolation don't create class inputs // They are handled as static attributes, not dynamic bindings expect(astWithSource).toBeUndefined(); }); it('should avoid false positives from dynamic expressions in interpolation', () => { const classValue = "base-class {{ condition ? 'card' : 'other' }}"; const astWithSource = parseInterpolatedClassExpression(classValue); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'base-class', 'card', 'other', ]); expect(result).toEqual(['base-class']); }); it('should handle the exact failing test case', () => { const classValue = 'count count-{{ size() }} other-class'; const astWithSource = parseInterpolatedClassExpression(classValue); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'count', ]); expect(result).toEqual(['count']); }); }); describe('Real-world ngClass patterns from monorepo', () => { it('should handle complex object-style ngClass with multiple conditions', () => { // Based on promo filter popup component const expression = `{ 'disabled': selectedFilterIndexes?.totalCount === 0, 'pill-with-badge-v2': isOfferPageEnhanced, 'ml-2': true, 'promo-filter-apply': isOfferPageEnhanced }`; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'disabled', 'pill-with-badge-v2', 'ml-2', 'promo-filter-apply', 'btn-primary', ]); expect(result).toEqual([ 'disabled', 'pill-with-badge-v2', 'ml-2', 'promo-filter-apply', ]); }); it('should handle dark mode conditional classes', () => { const expression = `{ 'bg-body-10': !darkModeService.isEnabled, 'dark-mode-background': darkModeService.isEnabled }`; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'bg-body-10', 'dark-mode-background', 'other-class', ]); expect(result).toEqual(['bg-body-10', 'dark-mode-background']); }); it('should handle simple boolean-based ngClass', () => { const expression = `{ 'offers-navigation-enable-v1': subNavigationV1Enabled }`; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'offers-navigation-enable-v1', 'other-class', ]); expect(result).toEqual(['offers-navigation-enable-v1']); }); it('should handle responsive class conditions', () => { const expression = `{ 'mobile-card-middle': isMobile, 'btn-sm': isSmallScreen, 'form-width-75': !isMobile }`; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'mobile-card-middle', 'btn-sm', 'form-width-75', ]); expect(result).toEqual(['mobile-card-middle', 'btn-sm', 'form-width-75']); }); it('should handle property-based class binding', () => { const expression = `filterByProduct?.messages?.producticonclass`; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'icon-class', 'ui-icon', ]); expect(result).toEqual([]); }); it('should avoid false positives in complex comparison expressions', () => { const expression = `{ 'disabled': filtersByOffer?.count === 0, 'badge-counter': selectedFilterIndexes?.totalCount > 0, 'active': selectedFilters && selectedFilters.length > 0 }`; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'disabled', 'badge-counter', 'active', 'count', 'selectedFilters', ]); expect(result).toEqual(['disabled', 'badge-counter', 'active']); }); it('should handle mixed static and conditional classes', () => { const expression = `[ 'navbar', 'navbar-expand-sm', condition ? 'sub-nav-wrapper' : '', menuContainer?.class ]`; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'navbar', 'navbar-expand-sm', 'sub-nav-wrapper', 'other-class', ]); expect(result).toEqual(['navbar', 'navbar-expand-sm', 'sub-nav-wrapper']); }); it('should handle the exact problematic pattern from the original issue', () => { // The exact pattern that was causing false positives const expression = `[ option?.logo?.toLowerCase(), option?.logo?.toLowerCase() == 'card' ? mergedCardLogoClass : '', 'base-class' ]`; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'card', 'base-class', 'other', ]); expect(result).toEqual(['base-class']); }); it('should handle nested object with spaced class names', () => { // Based on filter popup patterns const expression = `{ 'filter-product-icon ui-icon': true, 'ui-icon-size-lg': iconSize === 'large', 'status-pills transparent': hasTransparentStyle }`; const astWithSource = parseNgClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'filter-product-icon', 'ui-icon', 'ui-icon-size-lg', 'status-pills', 'transparent', 'large', ]); expect(result).toEqual([ 'filter-product-icon', 'ui-icon', 'ui-icon-size-lg', 'status-pills', 'transparent', ]); }); }); describe('Real-world [class] binding patterns', () => { // Helper function to extract AST from [class] expression function parseClassExpression(expression: string): ASTWithSource { const template = `<div [class]="${expression}"></div>`; const result = parseTemplate(template, 'test.html'); const element = result.nodes[0] as TmplAstElement; const classInput = element.inputs.find((input) => input.name === 'class'); return classInput?.value as ASTWithSource; } it('should handle conditional class strings', () => { const expression = `isActive ? 'nav-item active' : 'nav-item'`; const astWithSource = parseClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'nav-item', 'active', 'inactive', ]); expect(result).toEqual(['nav-item', 'active']); }); it('should handle complex ternary with comparison false positive potential', () => { const expression = `userType === 'admin' ? 'admin-panel active' : userType === 'user' ? 'user-panel' : 'guest-panel'`; const astWithSource = parseClassExpression(expression); const result = extractClassNamesFromNgClassAST(astWithSource.ast, [ 'admin', 'admin-panel', 'active', 'user', 'user-panel', 'guest-panel', ]); expect(result).toEqual([ 'admin-panel', 'active', 'user-panel', 'guest-panel', ]); }); }); describe('Backward compatibility - ngClassesIncludeClassName', () => { it('should work with object expressions', () => { const expression = `{ 'btn': true, 'btn-primary': isActive }`; expect(ngClassesIncludeClassName(expression, 'btn')).toBe(true); expect(ngClassesIncludeClassName(expression, 'btn-primary')).toBe(true); expect(ngClassesIncludeClassName(expression, 'btn-secondary')).toBe(false); }); it('should work with array expressions', () => { const expression = `['btn', 'btn-primary', condition ? 'active' : '']`; expect(ngClassesIncludeClassName(expression, 'btn')).toBe(true); expect(ngClassesIncludeClassName(expression, 'btn-primary')).toBe(true); expect(ngClassesIncludeClassName(expression, 'active')).toBe(true); expect(ngClassesIncludeClassName(expression, 'inactive')).toBe(false); }); it('should work with string expressions', () => { const expression = `'btn btn-primary active'`; expect(ngClassesIncludeClassName(expression, 'btn')).toBe(true); expect(ngClassesIncludeClassName(expression, 'btn-primary')).toBe(true); expect(ngClassesIncludeClassName(expression, 'active')).toBe(true); expect(ngClassesIncludeClassName(expression, 'inactive')).toBe(false); }); it('should handle basic string matching', () => { const expression = `{ 'btn': option?.logo?.toLowerCase() === 'card', 'active': true }`; expect(ngClassesIncludeClassName(expression, 'btn')).toBe(true); expect(ngClassesIncludeClassName(expression, 'active')).toBe(true); }); it('should handle missing classes', () => { const expression = `{ 'other': true }`; expect(ngClassesIncludeClassName(expression, 'btn')).toBe(false); }); }); ``` -------------------------------------------------------------------------------- /packages/minimal-repo/packages/design-system/storybook-host-app/src/components/badge/badge.component.stories.ts: -------------------------------------------------------------------------------- ```typescript import { generateStatusBadges } from '@design-system/shared-storybook-utils'; import { DemoIconComponent } from '@design-system/storybook-demo-cmp-lib'; import { DS_BADGE_SIZE_ARRAY, DS_BADGE_VARIANT_ARRAY, DsBadge, } from '@frontend/ui/badge'; import { DsNotificationBubble } from '@frontend/ui/notification-bubble'; import { DsComplexityRatingComponent, getVariantInfo, } from '@frontend/ui/utils'; import { Meta, StoryObj, moduleMetadata } from '@storybook/angular'; import { allThemes } from '../../modes'; type DsBadgeStoryType = DsBadge & { label: string }; const meta: Meta<DsBadgeStoryType> = { title: 'Components/Badge', component: DsBadge, parameters: { status: generateStatusBadges('UX-2308', ['stable']), }, excludeStories: /.*Data$/, argTypes: { label: { type: 'string', table: { defaultValue: { summary: 'Label' } }, control: 'text', description: 'The text of the badge', }, size: { options: DS_BADGE_SIZE_ARRAY, table: { defaultValue: { summary: 'medium' }, category: 'Styling' }, control: { type: 'select' }, description: 'The size of the badge', }, variant: { options: DS_BADGE_VARIANT_ARRAY, table: { defaultValue: { summary: 'primary' }, category: 'Styling' }, control: { type: 'select' }, description: 'The variant of the badge', }, inverse: { type: 'boolean', table: { defaultValue: { summary: 'false' }, category: 'Styling' }, control: { type: 'boolean' }, description: 'The inverse state of the badge', }, disabled: { type: 'boolean', table: { defaultValue: { summary: 'false' }, }, control: { type: 'boolean' }, description: 'The disabled state of the badges', }, }, args: { label: 'Label', size: 'medium', variant: 'primary', disabled: false, inverse: false, }, decorators: [ moduleMetadata({ imports: [DemoIconComponent, DsNotificationBubble] }), ], }; export default meta; type Story = StoryObj<DsBadgeStoryType>; export const Default: Story = { parameters: { name: 'Default', design: { name: 'Whitelabel', type: 'figma', url: 'https://www.figma.com/file/NgrOt8MGJhe0obKFBQgqdT/Component-Tokens-(POC)?type=design&node-id=16640-68740&&mode=design&t=fS1qO73SS8lGciLj-4', }, }, name: 'Default', args: { ...meta.args, }, render: (badge) => ({ template: ` <ds-badge variant="${badge.variant}" size="${badge.size}" disabled="${badge.disabled}" [inverse]="${badge.inverse}"> ${badge.label} </ds-badge> `, }), }; export const WithIcon: Story = { parameters: { name: 'Default', design: { name: 'Whitelabel', type: 'figma', url: 'https://www.figma.com/file/NgrOt8MGJhe0obKFBQgqdT/Component-Tokens-(POC)?type=design&node-id=16640-68740&&mode=design&t=fS1qO73SS8lGciLj-4', }, }, args: { ...Default.args, }, argTypes: { ...Default.argTypes, size: { options: ['medium', 'xsmall'], }, }, decorators: [moduleMetadata({ imports: [DsBadge] })], render: (badge) => ({ template: ` <ds-badge variant="${badge.variant}" size="${badge.size}" disabled="${badge.disabled}" [inverse]="${badge.inverse}"> ${badge.label} <ds-demo-icon slot="start"/> </ds-badge> `, }), }; export const WithIconOnly: Story = { parameters: { name: 'Default', design: { name: 'Whitelabel', type: 'figma', url: 'https://www.figma.com/file/NgrOt8MGJhe0obKFBQgqdT/Component-Tokens-(POC)?type=design&node-id=16640-68740&&mode=design&t=fS1qO73SS8lGciLj-4', }, }, args: { ...Default.args, label: '', }, argTypes: { ...Default.argTypes, size: { options: ['medium', 'xsmall'], }, }, decorators: [moduleMetadata({ imports: [DsBadge] })], render: (badge) => ({ template: ` <ds-badge variant="${badge.variant}" size="${badge.size}" disabled="${badge.disabled}" [inverse]="${badge.inverse}"> ${badge.label} <ds-demo-icon slot="start"/> </ds-badge> `, }), }; export const WithNotificationBubble: Story = { parameters: { name: 'Default', design: { name: 'Whitelabel', type: 'figma', url: 'https://www.figma.com/file/NgrOt8MGJhe0obKFBQgqdT/Component-Tokens-(POC)?type=design&node-id=16640-68740&&mode=design&t=fS1qO73SS8lGciLj-4', }, }, args: { ...Default.args, }, argTypes: { ...Default.argTypes, size: { options: ['medium'], }, }, decorators: [moduleMetadata({ imports: [DsBadge] })], render: (badge) => ({ template: ` <ds-badge variant="${badge.variant}" size="${badge.size}" disabled="${badge.disabled}" [inverse]="${badge.inverse}"> ${badge.label} <ds-notification-bubble slot="start" variant="neutral" disabled="false" size="small" inverse="false">0</ds-notification-bubble> </ds-badge> `, }), }; export const variantInfo = { ...getVariantInfo(meta), tags: ['docs-template'], }; export const ComplexityLevel: Story = { tags: ['docs-template'], render: () => ({ moduleMetadata: { imports: [DsComplexityRatingComponent], }, template: ` <ds-complexity-rating [totalVariants]="variantInfo.totalCombinations" [variantOptions]="variantInfo.variantOptions" [sizeOptions]="variantInfo.sizeOptions" ></ds-complexity-rating> `, props: { variantInfo, }, }), }; export const WithSuccess: Story = { parameters: { name: 'Default', design: { name: 'Whitelabel', type: 'figma', url: 'https://www.figma.com/file/NgrOt8MGJhe0obKFBQgqdT/Component-Tokens-(POC)?type=design&node-id=16640-68740&&mode=design&t=fS1qO73SS8lGciLj-4', }, }, args: { ...Default.args, }, decorators: [moduleMetadata({})], render: (badge) => ({ template: ` <ds-badge variant="${badge.variant}" size="${badge.size}" disabled="${badge.disabled}" [inverse]="${badge.inverse}"> ${badge.label} <ds-demo-icon iconName="success" slot="end" /> </ds-badge> `, }), }; export const WithIconAndSuccess: Story = { parameters: { name: 'Default', design: { name: 'Whitelabel', type: 'figma', url: 'https://www.figma.com/file/NgrOt8MGJhe0obKFBQgqdT/Component-Tokens-(POC)?type=design&node-id=16640-68740&&mode=design&t=fS1qO73SS8lGciLj-4', }, }, args: { ...WithIcon.args, }, decorators: [moduleMetadata({})], render: (badge) => ({ template: ` <ds-badge variant="${badge.variant}" size="${badge.size}" disabled="${badge.disabled}" [inverse]="${badge.inverse}"> ${badge.label} <ds-demo-icon slot="start"/> <ds-demo-icon iconName="success" slot="end" /> </ds-badge> `, }), }; export const LargeExamples: Story = { tags: ['docs-template'], render: (args) => ({ props: args, template: ` <div style="display: grid; grid-template-columns: 1fr repeat(3, 1fr); grid-row-gap: 1em; grid-column-gap: 1em; text-align: left; align-items: center;"> ${renderHeaderRow( 'Primary', 'Primary', 'Primary Strong', 'Primary Subtle', )} ${renderPrimaryRows('medium')} <div style="grid-column: 1 / -1;"> <hr style="width: 100%; border: 1px solid #ddd; margin: 20px 0;"> </div> ${renderHeaderRow( 'Secondary', 'Secondary', 'Secondary Strong', 'Secondary Subtle', )} ${renderSecondaryRows('medium')} <div style="grid-column: 1 / -1;"> <hr style="width: 100%; border: 1px solid #ddd; margin: 20px 0;"> </div> ${renderHeaderRow( 'Green', 'Green', 'Green Strong', 'Green Subtle', )} ${renderGreenRows('medium')} <div style="grid-column: 1 / -1;"> <hr style="width: 100%; border: 1px solid #ddd; margin: 20px 0;"> </div> ${renderHeaderRow('Blue', 'Blue', 'Blue Strong', 'Blue Subtle')} ${renderBlueRows('medium')} <div style="grid-column: 1 / -1;"> <hr style="width: 100%; border: 1px solid #ddd; margin: 20px 0;"> </div> ${renderHeaderRow('Red', 'Red', 'Red Strong', 'Red Subtle')} ${renderRedRows('medium')} <div style="grid-column: 1 / -1;"> <hr style="width: 100%; border: 1px solid #ddd; margin: 20px 0;"> </div> ${renderHeaderRow( 'Neutral', 'Neutral', 'Neutral Strong', 'Neutral Subtle', )} ${renderNeutralRows('medium')} <div style="grid-column: 1 / -1;"> <hr style="width: 100%; border: 1px solid #ddd; margin: 20px 0;"> </div> ${renderHeaderRow( 'Purple', 'Purple', 'Purple Strong', 'Purple Subtle', )} ${renderPurpleRows('medium')} <div style="grid-column: 1 / -1;"> <hr style="width: 100%; border: 1px solid #ddd; margin: 20px 0;"> </div> ${renderHeaderRow( 'Yellow', 'Yellow', 'Yellow Strong', 'Yellow Subtle', )} ${renderYellowRows('medium')} <div style="grid-column: 1 / -1;"> <hr style="width: 100%; border: 1px solid #ddd; margin: 20px 0;"> </div> ${renderHeaderRow( 'Orange', 'Orange', 'Orange Strong', 'Orange Subtle', )} ${renderOrangeRows('medium')} <div style="grid-column: 1 / -1;"> <hr style="width: 100%; border: 1px solid #ddd; margin: 20px 0;"> </div> </div> `, }), }; function renderHeaderRow(title = '', col1 = '', col2 = '', col3 = '') { return ` <div style="grid-column: 1 / span 1; text-align: left; margin-top: 20px;"> <strong>${title}</strong> </div> <div style="grid-column: 2 / span 1; text-align: left; margin-top: 20px;"> <strong>${col1}</strong> </div> <div style="grid-column: 3 / span 1; text-align: left; margin-top: 20px;"> <strong>${col2}</strong> </div> <div style="grid-column: 4 / span 1; text-align: left; margin-top: 20px;"> <strong>${col3}</strong> </div> `; } function renderPrimaryRows(size: string) { return ` ${renderRow('No Icon, No Success', size)} ${renderRow('Icon', size, { showIcon: true })} ${renderRow('Icon Only', size, { showIcon: true, showIconOnly: true })} ${renderRow('Notification Bubble', size, { showNotificationBubble: true, })} ${renderRow('Success', size, { showSuccess: true })} ${renderRow('Icon + Success', size, { showIcon: true, showSuccess: true, })} `; } function renderSecondaryRows(size: string) { return ` ${renderRow('No Icon, No Success', size, { variantPrefix: 'secondary', })} ${renderRow('Icon', size, { showIcon: true, variantPrefix: 'secondary', })} ${renderRow('Icon Only', size, { showIcon: true, showIconOnly: true, variantPrefix: 'secondary', })} ${renderRow('Notification Bubble', size, { showNotificationBubble: true, variantPrefix: 'secondary', })} ${renderRow('Success', size, { showSuccess: true, variantPrefix: 'secondary', })} ${renderRow('Icon + Success', size, { showIcon: true, showSuccess: true, variantPrefix: 'secondary', })} `; } function renderGreenRows(size: string) { return ` ${renderRow('No Icon, No Success', size, { variantPrefix: 'green' })} ${renderRow('Icon', size, { showIcon: true, variantPrefix: 'green' })} ${renderRow('Icon Only', size, { showIcon: true, showIconOnly: true, variantPrefix: 'green', })} ${renderRow('Notification Bubble', size, { showNotificationBubble: true, variantPrefix: 'green', })} ${renderRow('Success', size, { showSuccess: true, variantPrefix: 'green', })} ${renderRow('Icon + Success', size, { showIcon: true, showSuccess: true, variantPrefix: 'green', })} `; } function renderBlueRows(size: string) { return ` ${renderRow('No Icon, No Success', size, { variantPrefix: 'blue' })} ${renderRow('Icon', size, { showIcon: true, variantPrefix: 'blue' })} ${renderRow('Icon Only', size, { showIcon: true, showIconOnly: true, variantPrefix: 'blue', })} ${renderRow('Notification Bubble', size, { showNotificationBubble: true, variantPrefix: 'blue', })} ${renderRow('Success', size, { showSuccess: true, variantPrefix: 'blue', })} ${renderRow('Icon + Success', size, { showIcon: true, showSuccess: true, variantPrefix: 'blue', })} `; } function renderRedRows(size: string) { return ` ${renderRow('No Icon, No Success', size, { variantPrefix: 'red' })} ${renderRow('Icon', size, { showIcon: true, variantPrefix: 'red' })} ${renderRow('Icon Only', size, { showIcon: true, showIconOnly: true, variantPrefix: 'red', })} ${renderRow('Notification Bubble', size, { showNotificationBubble: true, variantPrefix: 'red', })} ${renderRow('Success', size, { showSuccess: true, variantPrefix: 'red', })} ${renderRow('Icon + Success', size, { showIcon: true, showSuccess: true, variantPrefix: 'red', })} `; } function renderNeutralRows(size: string) { return ` ${renderRow('No Icon, No Success', size, { variantPrefix: 'neutral' })} ${renderRow('Icon', size, { showIcon: true, variantPrefix: 'neutral' })} ${renderRow('Icon Only', size, { showIcon: true, showIconOnly: true, variantPrefix: 'neutral', })} ${renderRow('Notification Bubble', size, { showNotificationBubble: true, variantPrefix: 'neutral', })} ${renderRow('Success', size, { showSuccess: true, variantPrefix: 'neutral', })} ${renderRow('Icon + Success', size, { showIcon: true, showSuccess: true, variantPrefix: 'neutral', })} `; } function renderPurpleRows(size: string) { return ` ${renderRow('No Icon, No Success', size, { variantPrefix: 'purple' })} ${renderRow('Icon', size, { showIcon: true, variantPrefix: 'purple' })} ${renderRow('Icon Only', size, { showIcon: true, showIconOnly: true, variantPrefix: 'purple', })} ${renderRow('Notification Bubble', size, { showNotificationBubble: true, variantPrefix: 'purple', })} ${renderRow('Success', size, { showSuccess: true, variantPrefix: 'purple', })} ${renderRow('Icon + Success', size, { showIcon: true, showSuccess: true, variantPrefix: 'purple', })} `; } function renderYellowRows(size: string) { return ` ${renderRow('No Icon, No Success', size, { variantPrefix: 'yellow' })} ${renderRow('Icon', size, { showIcon: true, variantPrefix: 'yellow' })} ${renderRow('Icon Only', size, { showIcon: true, showIconOnly: true, variantPrefix: 'yellow', })} ${renderRow('Notification Bubble', size, { showNotificationBubble: true, variantPrefix: 'yellow', })} ${renderRow('Success', size, { showSuccess: true, variantPrefix: 'yellow', })} ${renderRow('Icon + Success', size, { showIcon: true, showSuccess: true, variantPrefix: 'yellow', })} `; } function renderOrangeRows(size: string) { return ` ${renderRow('No Icon, No Success', size, { variantPrefix: 'orange' })} ${renderRow('Icon', size, { showIcon: true, variantPrefix: 'orange' })} ${renderRow('Icon Only', size, { showIcon: true, showIconOnly: true, variantPrefix: 'orange', })} ${renderRow('Notification Bubble', size, { showNotificationBubble: true, variantPrefix: 'orange', })} ${renderRow('Success', size, { showSuccess: true, variantPrefix: 'orange', })} ${renderRow('Icon + Success', size, { showIcon: true, showSuccess: true, variantPrefix: 'orange', })} `; } function renderRow( name: string, size: string, { showSuccess = false, showIcon = false, showIconOnly = false, showNotificationBubble = false, variantPrefix = 'primary', } = {}, ) { return ` <span style="grid-column: 1 / span 1; align-self: center;">${name}</span> ${renderBadge( `${variantPrefix}`, size, showIcon, showIconOnly, showNotificationBubble, showSuccess, )} ${renderBadge( `${variantPrefix}-strong`, size, showIcon, showIconOnly, showNotificationBubble, showSuccess, )} ${renderBadge( `${variantPrefix}-subtle`, size, showIcon, showIconOnly, showNotificationBubble, showSuccess, )} `; } function renderBadge( variant: string, size: string, showIcon: boolean, showIconOnly: boolean, showNotificationBubble: boolean, showSuccess: boolean, ) { return ` <div style="grid-column: span 1;"> <ds-badge variant="${variant}" size="${size}"> ${showIconOnly ? '' : 'Label'} ${showIcon ? '<ds-demo-icon slot="start"/>' : ''} ${ showNotificationBubble ? '<ds-notification-bubble slot="start" variant="neutral" disabled="false" size="small" inverse="false">0</ds-notification-bubble>' : '' } ${ showSuccess ? '<ds-demo-icon iconName="success" slot="end"/>' : '' } </ds-badge> </div> `; } export const ChromaticTestStory: Story = { tags: ['docs-template'], parameters: { chromatic: { modes: allThemes, disableSnapshot: false, }, }, render: (args) => ({ props: args, template: ` <div style="display: grid; grid-template-columns: repeat(7, 1fr); grid-row-gap: 1em; grid-column-gap: 1em; align-items: center; justify-items: center;"> ${renderHeaderRow()} ${renderRow('Xsmall', 'xsmall')} <div style="grid-column: span 7"></div> ${renderRow('Medium', 'medium')} ${renderRow('Medium, Icon', 'medium', { showIcon: true })} ${renderRow('Medium, IconOnly', 'medium', { showIcon: true, showIconOnly: true, })} ${renderRow('Medium, NotificationBubble', 'medium', { showNotificationBubble: true, })} ${renderRow('Medium, Success', 'medium', { showSuccess: true })} ${renderRow('Medium, Icon + Success', 'medium', { showIcon: true, showSuccess: true, })} <div style="grid-column: span 7"></div> ${renderRow('Large', 'medium')} ${renderRow('Large, Icon', 'medium', { showIcon: true })} ${renderRow('Large, IconOnly', 'medium', { showIcon: true, showIconOnly: true, })} ${renderRow('Large, NotificationBubble', 'medium', { showNotificationBubble: true, })} ${renderRow('Large, Success', 'medium', { showSuccess: true })} ${renderRow('Large, Icon + Success', 'medium', { showIcon: true, showSuccess: true, })} </div> `, }), }; ``` -------------------------------------------------------------------------------- /packages/shared/ds-component-coverage/docs/examples/report.md: -------------------------------------------------------------------------------- ```markdown # Code PushUp Report | 🏷 Category | ⭐ Score | 🛡 Audits | | :------------------------------------------------ | :-------: | :-------: | | [Design System Coverage](#design-system-coverage) | 🔴 **38** | 13 | ## 🏷 Categories ### Design System Coverage Usage of design system components 🔴 Score: **38** - 🟥 [Usage coverage for DSButton component](#usage-coverage-for-dsbutton-component-angular-design-system-coverage) (_Angular Design System Coverage_) - **7 classes found** - 🟥 [Usage coverage for DSAlert component](#usage-coverage-for-dsalert-component-angular-design-system-coverage) (_Angular Design System Coverage_) - **6 classes found** - 🟥 [Usage coverage for DSTooltip component](#usage-coverage-for-dstooltip-component-angular-design-system-coverage) (_Angular Design System Coverage_) - **5 classes found** - 🟥 [Usage coverage for DSBreadcrumb component](#usage-coverage-for-dsbreadcrumb-component-angular-design-system-coverage) (_Angular Design System Coverage_) - **4 classes found** - 🟥 [Usage coverage for DSDropdown component](#usage-coverage-for-dsdropdown-component-angular-design-system-coverage) (_Angular Design System Coverage_) - **4 classes found** - 🟥 [Usage coverage for DSModal component](#usage-coverage-for-dsmodal-component-angular-design-system-coverage) (_Angular Design System Coverage_) - **4 classes found** - 🟥 [Usage coverage for DSProgressBar component](#usage-coverage-for-dsprogressbar-component-angular-design-system-coverage) (_Angular Design System Coverage_) - **4 classes found** - 🟥 [Usage coverage for DSInput component](#usage-coverage-for-dsinput-component-angular-design-system-coverage) (_Angular Design System Coverage_) - **1 class found** - 🟩 [Usage coverage for DSAccordion component](#usage-coverage-for-dsaccordion-component-angular-design-system-coverage) (_Angular Design System Coverage_) - **0 classes found** - 🟩 [Usage coverage for DSCard component](#usage-coverage-for-dscard-component-angular-design-system-coverage) (_Angular Design System Coverage_) - **0 classes found** - 🟩 [Usage coverage for DSNavbar component](#usage-coverage-for-dsnavbar-component-angular-design-system-coverage) (_Angular Design System Coverage_) - **0 classes found** - 🟩 [Usage coverage for DSSlider component](#usage-coverage-for-dsslider-component-angular-design-system-coverage) (_Angular Design System Coverage_) - **0 classes found** - 🟩 [Usage coverage for DSTabsModule component](#usage-coverage-for-dstabsmodule-component-angular-design-system-coverage) (_Angular Design System Coverage_) - **0 classes found** ## 🛡️ Audits ### Usage coverage for DSButton component (Angular Design System Coverage) <details> <summary>🟥 <b>7 classes found</b> (score: 0)</summary> #### Issues | Severity | Message | Source file | Line(s) | | :--------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----: | | 🚨 _error_ | ✏️🔲 Element <code>button</code> in attribute <code>class</code> uses deprecated class <code>btn</code>. Use <code>DSButton</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-button--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-button-dropdown.component.ts`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-button-dropdown.component.ts) | 6 | | 🚨 _error_ | ✏️🔲 Element <code>button</code> in attribute <code>class</code> uses deprecated class <code>btn-primary</code>. Use <code>DSButton</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-button--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-button-dropdown.component.ts`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-button-dropdown.component.ts) | 6 | | 🚨 _error_ | ✏️🔲 Element <code>button</code> in attribute <code>class</code> uses deprecated class <code>btn</code>. Use <code>DSButton</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-button--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts) | 10 | | 🚨 _error_ | ✏️🔲 Element <code>button</code> in attribute <code>class</code> uses deprecated class <code>btn-primary</code>. Use <code>DSButton</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-button--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts) | 10 | | 🚨 _error_ | 🔗🎨 ️ The selector's class <code>btn</code> is deprecated. Use <code>DSButton</code> and delete the styles. <a href="https://storybook.company.com/latest/?path=/docs/components-button--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css) | 7-14 | | 🚨 _error_ | 🔗🔲 Element <code>button</code> in attribute <code>class</code> uses deprecated class <code>btn</code>. Use <code>DSButton</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-button--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html) | 6 | | 🚨 _error_ | 🔗🔲 Element <code>button</code> in attribute <code>class</code> uses deprecated class <code>btn-primary</code>. Use <code>DSButton</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-button--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html) | 6 | </details> Coverage audit for DSButton component. Matching classes: btn, btn-primary, legacy-button ### Usage coverage for DSAlert component (Angular Design System Coverage) <details> <summary>🟥 <b>6 classes found</b> (score: 0)</summary> #### Issues | Severity | Message | Source file | Line(s) | | :--------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----: | | 🚨 _error_ | ✏️🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>alert</code>. Use <code>DSAlert</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-alert--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-alert-tooltip-input.component.ts`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-alert-tooltip-input.component.ts) | 6 | | 🚨 _error_ | ✏️🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>alert</code>. Use <code>DSAlert</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-alert--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-alert.component.ts`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-alert.component.ts) | 5 | | 🚨 _error_ | ✏️🎨 ️ The selector's class <code>alert</code> is deprecated. Use <code>DSAlert</code> and delete the styles. <a href="https://storybook.company.com/latest/?path=/docs/components-alert--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-alert.component.ts`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-alert.component.ts) | 7-10 | | 🚨 _error_ | ✏️🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>alert</code>. Use <code>DSAlert</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-alert--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts) | 46 | | 🚨 _error_ | 🔗🎨 ️ The selector's class <code>alert</code> is deprecated. Use <code>DSAlert</code> and delete the styles. <a href="https://storybook.company.com/latest/?path=/docs/components-alert--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css) | 43-47 | | 🚨 _error_ | 🔗🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>alert</code>. Use <code>DSAlert</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-alert--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html) | 22 | </details> Coverage audit for DSAlert component. Matching classes: alert, notification, legacy-alert ### Usage coverage for DSTooltip component (Angular Design System Coverage) <details> <summary>🟥 <b>5 classes found</b> (score: 0)</summary> #### Issues | Severity | Message | Source file | Line(s) | | :--------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----: | | 🚨 _error_ | ✏️🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>tooltip</code>. Use <code>DSTooltip</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-tooltip--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-alert-tooltip-input.component.ts`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-alert-tooltip-input.component.ts) | 8 | | 🚨 _error_ | ✏️🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>tooltip</code>. Use <code>DSTooltip</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-tooltip--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts) | 52 | | 🚨 _error_ | 🔗🎨 ️ The selector's class <code>tooltip</code> is deprecated. Use <code>DSTooltip</code> and delete the styles. <a href="https://storybook.company.com/latest/?path=/docs/components-tooltip--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css) | 57-61 | | 🚨 _error_ | 🔗🎨 ️ The selector's class <code>tooltip</code> is deprecated. Use <code>DSTooltip</code> and delete the styles. <a href="https://storybook.company.com/latest/?path=/docs/components-tooltip--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css) | 63-73 | | 🚨 _error_ | 🔗🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>tooltip</code>. Use <code>DSTooltip</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-tooltip--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html) | 31 | </details> Coverage audit for DSTooltip component. Matching classes: tooltip, legacy-tooltip, info-bubble ### Usage coverage for DSBreadcrumb component (Angular Design System Coverage) <details> <summary>🟥 <b>4 classes found</b> (score: 0)</summary> #### Issues | Severity | Message | Source file | Line(s) | | :--------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----: | | 🚨 _error_ | ✏️🔲 Element <code>nav</code> in attribute <code>class</code> uses deprecated class <code>breadcrumb</code>. Use <code>DSBreadcrumb</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-breadcrumb--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts) | 62-64 | | 🚨 _error_ | 🔗🎨 ️ The selector's class <code>breadcrumb</code> is deprecated. Use <code>DSBreadcrumb</code> and delete the styles. <a href="https://storybook.company.com/latest/?path=/docs/components-breadcrumb--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css) | 76-79 | | 🚨 _error_ | 🔗🎨 ️ The selector's class <code>breadcrumb</code> is deprecated. Use <code>DSBreadcrumb</code> and delete the styles. <a href="https://storybook.company.com/latest/?path=/docs/components-breadcrumb--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css) | 81-84 | | 🚨 _error_ | 🔗🔲 Element <code>nav</code> in attribute <code>class</code> uses deprecated class <code>breadcrumb</code>. Use <code>DSBreadcrumb</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-breadcrumb--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html) | 34-36 | </details> Coverage audit for DSBreadcrumb component. Matching classes: breadcrumb, legacy-breadcrumb, nav-breadcrumb ### Usage coverage for DSDropdown component (Angular Design System Coverage) <details> <summary>🟥 <b>4 classes found</b> (score: 0)</summary> #### Issues | Severity | Message | Source file | Line(s) | | :--------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----: | | 🚨 _error_ | ✏️🔲 Element <code>select</code> in attribute <code>class</code> uses deprecated class <code>dropdown</code>. Use <code>DSDropdown</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-dropdown--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-button-dropdown.component.ts`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-button-dropdown.component.ts) | 7-10 | | 🚨 _error_ | ✏️🔲 Element <code>select</code> in attribute <code>class</code> uses deprecated class <code>dropdown</code>. Use <code>DSDropdown</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-dropdown--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts) | 37-40 | | 🚨 _error_ | 🔗🎨 ️ The selector's class <code>dropdown</code> is deprecated. Use <code>DSDropdown</code> and delete the styles. <a href="https://storybook.company.com/latest/?path=/docs/components-dropdown--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css) | 50-54 | | 🚨 _error_ | 🔗🔲 Element <code>select</code> in attribute <code>class</code> uses deprecated class <code>dropdown</code>. Use <code>DSDropdown</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-dropdown--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html) | 25-28 | </details> Coverage audit for DSDropdown component. Matching classes: dropdown, legacy-dropdown, custom-dropdown ### Usage coverage for DSModal component (Angular Design System Coverage) <details> <summary>🟥 <b>4 classes found</b> (score: 0)</summary> #### Issues | Severity | Message | Source file | Line(s) | | :--------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----: | | 🚨 _error_ | ✏️🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>modal</code>. Use <code>DSModal</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-modal--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts) | 18-23 | | 🚨 _error_ | ✏️🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>modal</code>. Use <code>DSModal</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-modal--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-modal-progress.component.ts`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-modal-progress.component.ts) | 6-11 | | 🚨 _error_ | 🔗🎨 ️ The selector's class <code>modal</code> is deprecated. Use <code>DSModal</code> and delete the styles. <a href="https://storybook.company.com/latest/?path=/docs/components-modal--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css) | 17-25 | | 🚨 _error_ | 🔗🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>modal</code>. Use <code>DSModal</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-modal--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html) | 9-14 | </details> Coverage audit for DSModal component. Matching classes: modal, popup, legacy-dialog ### Usage coverage for DSProgressBar component (Angular Design System Coverage) <details> <summary>🟥 <b>4 classes found</b> (score: 0)</summary> #### Issues | Severity | Message | Source file | Line(s) | | :--------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----: | | 🚨 _error_ | ✏️🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>progress-bar</code>. Use <code>DSProgressBar</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-progressbar--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts) | 29-31 | | 🚨 _error_ | ✏️🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>progress-bar</code>. Use <code>DSProgressBar</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-progressbar--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-modal-progress.component.ts`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-modal-progress.component.ts) | 13-15 | | 🚨 _error_ | 🔗🎨 ️ The selector's class <code>progress-bar</code> is deprecated. Use <code>DSProgressBar</code> and delete the styles. <a href="https://storybook.company.com/latest/?path=/docs/components-progressbar--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css) | 32-35 | | 🚨 _error_ | 🔗🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>progress-bar</code>. Use <code>DSProgressBar</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-progressbar--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html) | 17-19 | </details> Coverage audit for DSProgressBar component. Matching classes: progress-bar, loading-bar, legacy-progress ### Usage coverage for DSInput component (Angular Design System Coverage) <details> <summary>🟥 <b>1 class found</b> (score: 0)</summary> #### Issues | Severity | Message | Source file | Line(s) | | :--------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----: | | 🚨 _error_ | ✏️🔲 Element <code>input</code> in attribute <code>class</code> uses deprecated class <code>form-control</code>. Use <code>DSInput</code> instead. <a href="https://storybook.company.com/latest/?path=/docs/components-input--overview" target="_blank">Learn more</a>. | [`plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-alert-tooltip-input.component.ts`](../../../../plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-alert-tooltip-input.component.ts) | 10 | </details> Coverage audit for DSInput component. Matching classes: input, form-control, legacy-input ### Usage coverage for DSAccordion component (Angular Design System Coverage) 🟩 **0 classes found** (score: 100) Coverage audit for DSAccordion component. Matching classes: accordion, collapse-panel, legacy-accordion ### Usage coverage for DSCard component (Angular Design System Coverage) 🟩 **0 classes found** (score: 100) Coverage audit for DSCard component. Matching classes: card, legacy-card, custom-card ### Usage coverage for DSNavbar component (Angular Design System Coverage) 🟩 **0 classes found** (score: 100) Coverage audit for DSNavbar component. Matching classes: navbar, navigation, legacy-navbar ### Usage coverage for DSSlider component (Angular Design System Coverage) 🟩 **0 classes found** (score: 100) Coverage audit for DSSlider component. Matching classes: slider, range-slider, legacy-slider ### Usage coverage for DSTabsModule component (Angular Design System Coverage) 🟩 **0 classes found** (score: 100) Coverage audit for DSTabsModule component. Matching classes: ms-tab-bar, legacy-tabs, custom-tabs ## About Report was created by [Code PushUp](https://github.com/code-pushup/cli#readme) on Mon, Feb 10, 2025, 11:48 PM GMT+1. | Plugin | Audits | Version | Duration | | :----------------------------- | :----: | :-----: | -------: | | Angular Design System Coverage | 13 | | 366 ms | | Commit | Version | Duration | Plugins | Categories | Audits | | :--------------------------------------------- | :------: | -------: | :-----: | :--------: | :----: | | wip (523fdf3354f4fdb952ab324ac92f7e0f3cd61957) | `0.57.0` | 418 ms | 1 | 1 | 13 | --- Made with ❤ by [Code PushUp](https://github.com/code-pushup/cli#readme) ``` -------------------------------------------------------------------------------- /packages/shared/ds-component-coverage/docs/examples/report.json: -------------------------------------------------------------------------------- ```json { "commit": { "hash": "523fdf3354f4fdb952ab324ac92f7e0f3cd61957", "message": "wip", "date": "2025-02-10T22:11:27.000Z", "author": "Michael" }, "packageName": "@push-based/core", "version": "0.57.0", "date": "2025-02-10T22:48:50.259Z", "duration": 418, "categories": [ { "slug": "design-system-coverage", "refs": [ { "slug": "coverage-dsbutton", "weight": 1, "type": "audit", "plugin": "ds-component-coverage" }, { "slug": "coverage-dstabsmodule", "weight": 1, "type": "audit", "plugin": "ds-component-coverage" }, { "slug": "coverage-dscard", "weight": 1, "type": "audit", "plugin": "ds-component-coverage" }, { "slug": "coverage-dsmodal", "weight": 1, "type": "audit", "plugin": "ds-component-coverage" }, { "slug": "coverage-dsinput", "weight": 1, "type": "audit", "plugin": "ds-component-coverage" }, { "slug": "coverage-dsdropdown", "weight": 1, "type": "audit", "plugin": "ds-component-coverage" }, { "slug": "coverage-dsaccordion", "weight": 1, "type": "audit", "plugin": "ds-component-coverage" }, { "slug": "coverage-dsalert", "weight": 1, "type": "audit", "plugin": "ds-component-coverage" }, { "slug": "coverage-dstooltip", "weight": 1, "type": "audit", "plugin": "ds-component-coverage" }, { "slug": "coverage-dsbreadcrumb", "weight": 1, "type": "audit", "plugin": "ds-component-coverage" }, { "slug": "coverage-dsprogressbar", "weight": 1, "type": "audit", "plugin": "ds-component-coverage" }, { "slug": "coverage-dsslider", "weight": 1, "type": "audit", "plugin": "ds-component-coverage" }, { "slug": "coverage-dsnavbar", "weight": 1, "type": "audit", "plugin": "ds-component-coverage" } ], "title": "Design System Coverage", "description": "Usage of design system components" } ], "plugins": [ { "title": "Angular Design System Coverage", "slug": "ds-component-coverage", "icon": "angular", "date": "2025-02-10T22:48:50.286Z", "duration": 366, "audits": [ { "slug": "coverage-dsbutton", "displayValue": "7 classes found", "value": 7, "score": 0, "details": { "issues": [ { "message": "✏️🔲 Element <code>button</code> in attribute <code>class</code> uses deprecated class <code>btn</code>. Use <code>DSButton</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-button--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts", "position": { "startLine": 10, "startColumn": 4, "endLine": 10, "endColumn": 55 } } }, { "message": "✏️🔲 Element <code>button</code> in attribute <code>class</code> uses deprecated class <code>btn-primary</code>. Use <code>DSButton</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-button--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts", "position": { "startLine": 10, "startColumn": 4, "endLine": 10, "endColumn": 55 } } }, { "message": "✏️🔲 Element <code>button</code> in attribute <code>class</code> uses deprecated class <code>btn</code>. Use <code>DSButton</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-button--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-button-dropdown.component.ts", "position": { "startLine": 6, "startColumn": 4, "endLine": 6, "endColumn": 53 } } }, { "message": "✏️🔲 Element <code>button</code> in attribute <code>class</code> uses deprecated class <code>btn-primary</code>. Use <code>DSButton</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-button--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-button-dropdown.component.ts", "position": { "startLine": 6, "startColumn": 4, "endLine": 6, "endColumn": 53 } } }, { "message": "🔗🔲 Element <code>button</code> in attribute <code>class</code> uses deprecated class <code>btn</code>. Use <code>DSButton</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-button--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html", "position": { "startLine": 6, "endLine": 6, "endColumn": 54 } } }, { "message": "🔗🔲 Element <code>button</code> in attribute <code>class</code> uses deprecated class <code>btn-primary</code>. Use <code>DSButton</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-button--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html", "position": { "startLine": 6, "endLine": 6, "endColumn": 54 } } }, { "message": "🔗🎨 ️ The selector's class <code>btn</code> is deprecated. Use <code>DSButton</code> and delete the styles. <a href=\"https://storybook.company.com/latest/?path=/docs/components-button--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css", "position": { "startLine": 7, "startColumn": 1, "endLine": 14, "endColumn": 1 } } } ] }, "title": "Usage coverage for DSButton component", "description": "Coverage audit for DSButton component. Matching classes: btn, btn-primary, legacy-button" }, { "slug": "coverage-dstabsmodule", "displayValue": "0 classes found", "value": 0, "score": 1, "details": { "issues": [] }, "title": "Usage coverage for DSTabsModule component", "description": "Coverage audit for DSTabsModule component. Matching classes: ms-tab-bar, legacy-tabs, custom-tabs" }, { "slug": "coverage-dscard", "displayValue": "0 classes found", "value": 0, "score": 1, "details": { "issues": [] }, "title": "Usage coverage for DSCard component", "description": "Coverage audit for DSCard component. Matching classes: card, legacy-card, custom-card" }, { "slug": "coverage-dsmodal", "displayValue": "4 classes found", "value": 4, "score": 0, "details": { "issues": [ { "message": "✏️🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>modal</code>. Use <code>DSModal</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-modal--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-modal-progress.component.ts", "position": { "startLine": 6, "startColumn": 4, "endLine": 11, "endColumn": 10 } } }, { "message": "✏️🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>modal</code>. Use <code>DSModal</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-modal--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts", "position": { "startLine": 18, "startColumn": 4, "endLine": 23, "endColumn": 10 } } }, { "message": "🔗🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>modal</code>. Use <code>DSModal</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-modal--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html", "position": { "startLine": 9, "endLine": 14, "endColumn": 6 } } }, { "message": "🔗🎨 ️ The selector's class <code>modal</code> is deprecated. Use <code>DSModal</code> and delete the styles. <a href=\"https://storybook.company.com/latest/?path=/docs/components-modal--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css", "position": { "startLine": 17, "startColumn": 1, "endLine": 25, "endColumn": 1 } } } ] }, "title": "Usage coverage for DSModal component", "description": "Coverage audit for DSModal component. Matching classes: modal, popup, legacy-dialog" }, { "slug": "coverage-dsinput", "displayValue": "1 class found", "value": 1, "score": 0, "details": { "issues": [ { "message": "✏️🔲 Element <code>input</code> in attribute <code>class</code> uses deprecated class <code>form-control</code>. Use <code>DSInput</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-input--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-alert-tooltip-input.component.ts", "position": { "startLine": 10, "startColumn": 4, "endLine": 10, "endColumn": 64 } } } ] }, "title": "Usage coverage for DSInput component", "description": "Coverage audit for DSInput component. Matching classes: input, form-control, legacy-input" }, { "slug": "coverage-dsdropdown", "displayValue": "4 classes found", "value": 4, "score": 0, "details": { "issues": [ { "message": "✏️🔲 Element <code>select</code> in attribute <code>class</code> uses deprecated class <code>dropdown</code>. Use <code>DSDropdown</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-dropdown--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts", "position": { "startLine": 37, "startColumn": 4, "endLine": 40, "endColumn": 13 } } }, { "message": "✏️🔲 Element <code>select</code> in attribute <code>class</code> uses deprecated class <code>dropdown</code>. Use <code>DSDropdown</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-dropdown--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-button-dropdown.component.ts", "position": { "startLine": 7, "startColumn": 4, "endLine": 10, "endColumn": 13 } } }, { "message": "🔗🔲 Element <code>select</code> in attribute <code>class</code> uses deprecated class <code>dropdown</code>. Use <code>DSDropdown</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-dropdown--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html", "position": { "startLine": 25, "endLine": 28, "endColumn": 9 } } }, { "message": "🔗🎨 ️ The selector's class <code>dropdown</code> is deprecated. Use <code>DSDropdown</code> and delete the styles. <a href=\"https://storybook.company.com/latest/?path=/docs/components-dropdown--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css", "position": { "startLine": 50, "startColumn": 1, "endLine": 54, "endColumn": 1 } } } ] }, "title": "Usage coverage for DSDropdown component", "description": "Coverage audit for DSDropdown component. Matching classes: dropdown, legacy-dropdown, custom-dropdown" }, { "slug": "coverage-dsaccordion", "displayValue": "0 classes found", "value": 0, "score": 1, "details": { "issues": [] }, "title": "Usage coverage for DSAccordion component", "description": "Coverage audit for DSAccordion component. Matching classes: accordion, collapse-panel, legacy-accordion" }, { "slug": "coverage-dsalert", "displayValue": "6 classes found", "value": 6, "score": 0, "details": { "issues": [ { "message": "✏️🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>alert</code>. Use <code>DSAlert</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-alert--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts", "position": { "startLine": 46, "startColumn": 4, "endLine": 46, "endColumn": 51 } } }, { "message": "✏️🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>alert</code>. Use <code>DSAlert</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-alert--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-alert-tooltip-input.component.ts", "position": { "startLine": 6, "startColumn": 4, "endLine": 6, "endColumn": 67 } } }, { "message": "✏️🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>alert</code>. Use <code>DSAlert</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-alert--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-alert.component.ts", "position": { "startLine": 5, "startColumn": 1, "endLine": 5, "endColumn": 62 } } }, { "message": "✏️🎨 ️ The selector's class <code>alert</code> is deprecated. Use <code>DSAlert</code> and delete the styles. <a href=\"https://storybook.company.com/latest/?path=/docs/components-alert--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-alert.component.ts", "position": { "startLine": 7, "startColumn": 1, "endLine": 10, "endColumn": 7 } } }, { "message": "🔗🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>alert</code>. Use <code>DSAlert</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-alert--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html", "position": { "startLine": 22, "endLine": 22, "endColumn": 61 } } }, { "message": "🔗🎨 ️ The selector's class <code>alert</code> is deprecated. Use <code>DSAlert</code> and delete the styles. <a href=\"https://storybook.company.com/latest/?path=/docs/components-alert--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css", "position": { "startLine": 43, "startColumn": 1, "endLine": 47, "endColumn": 1 } } } ] }, "title": "Usage coverage for DSAlert component", "description": "Coverage audit for DSAlert component. Matching classes: alert, notification, legacy-alert" }, { "slug": "coverage-dstooltip", "displayValue": "5 classes found", "value": 5, "score": 0, "details": { "issues": [ { "message": "✏️🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>tooltip</code>. Use <code>DSTooltip</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-tooltip--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts", "position": { "startLine": 52, "startColumn": 4, "endLine": 52, "endColumn": 42 } } }, { "message": "✏️🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>tooltip</code>. Use <code>DSTooltip</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-tooltip--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-alert-tooltip-input.component.ts", "position": { "startLine": 8, "startColumn": 4, "endLine": 8, "endColumn": 45 } } }, { "message": "🔗🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>tooltip</code>. Use <code>DSTooltip</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-tooltip--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html", "position": { "startLine": 31, "endLine": 31, "endColumn": 49 } } }, { "message": "🔗🎨 ️ The selector's class <code>tooltip</code> is deprecated. Use <code>DSTooltip</code> and delete the styles. <a href=\"https://storybook.company.com/latest/?path=/docs/components-tooltip--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css", "position": { "startLine": 57, "startColumn": 1, "endLine": 61, "endColumn": 1 } } }, { "message": "🔗🎨 ️ The selector's class <code>tooltip</code> is deprecated. Use <code>DSTooltip</code> and delete the styles. <a href=\"https://storybook.company.com/latest/?path=/docs/components-tooltip--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css", "position": { "startLine": 63, "startColumn": 1, "endLine": 73, "endColumn": 1 } } } ] }, "title": "Usage coverage for DSTooltip component", "description": "Coverage audit for DSTooltip component. Matching classes: tooltip, legacy-tooltip, info-bubble" }, { "slug": "coverage-dsbreadcrumb", "displayValue": "4 classes found", "value": 4, "score": 0, "details": { "issues": [ { "message": "✏️🔲 Element <code>nav</code> in attribute <code>class</code> uses deprecated class <code>breadcrumb</code>. Use <code>DSBreadcrumb</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-breadcrumb--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts", "position": { "startLine": 62, "startColumn": 4, "endLine": 64, "endColumn": 10 } } }, { "message": "🔗🔲 Element <code>nav</code> in attribute <code>class</code> uses deprecated class <code>breadcrumb</code>. Use <code>DSBreadcrumb</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-breadcrumb--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html", "position": { "startLine": 34, "endLine": 36, "endColumn": 6 } } }, { "message": "🔗🎨 ️ The selector's class <code>breadcrumb</code> is deprecated. Use <code>DSBreadcrumb</code> and delete the styles. <a href=\"https://storybook.company.com/latest/?path=/docs/components-breadcrumb--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css", "position": { "startLine": 76, "startColumn": 1, "endLine": 79, "endColumn": 1 } } }, { "message": "🔗🎨 ️ The selector's class <code>breadcrumb</code> is deprecated. Use <code>DSBreadcrumb</code> and delete the styles. <a href=\"https://storybook.company.com/latest/?path=/docs/components-breadcrumb--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css", "position": { "startLine": 81, "startColumn": 1, "endLine": 84, "endColumn": 1 } } } ] }, "title": "Usage coverage for DSBreadcrumb component", "description": "Coverage audit for DSBreadcrumb component. Matching classes: breadcrumb, legacy-breadcrumb, nav-breadcrumb" }, { "slug": "coverage-dsprogressbar", "displayValue": "4 classes found", "value": 4, "score": 0, "details": { "issues": [ { "message": "✏️🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>progress-bar</code>. Use <code>DSProgressBar</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-progressbar--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-modal-progress.component.ts", "position": { "startLine": 13, "startColumn": 4, "endLine": 15, "endColumn": 10 } } }, { "message": "✏️🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>progress-bar</code>. Use <code>DSProgressBar</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-progressbar--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/bad-mixed.component.ts", "position": { "startLine": 29, "startColumn": 4, "endLine": 31, "endColumn": 10 } } }, { "message": "🔗🔲 Element <code>div</code> in attribute <code>class</code> uses deprecated class <code>progress-bar</code>. Use <code>DSProgressBar</code> instead. <a href=\"https://storybook.company.com/latest/?path=/docs/components-progressbar--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.html", "position": { "startLine": 17, "endLine": 19, "endColumn": 6 } } }, { "message": "🔗🎨 ️ The selector's class <code>progress-bar</code> is deprecated. Use <code>DSProgressBar</code> and delete the styles. <a href=\"https://storybook.company.com/latest/?path=/docs/components-progressbar--overview\" target=\"_blank\">Learn more</a>.", "severity": "error", "source": { "file": "plugins/ds-component-coverage/mocks/fixtures/coverage-audit/demo/mixed-external-assets.component.css", "position": { "startLine": 32, "startColumn": 1, "endLine": 35, "endColumn": 1 } } } ] }, "title": "Usage coverage for DSProgressBar component", "description": "Coverage audit for DSProgressBar component. Matching classes: progress-bar, loading-bar, legacy-progress" }, { "slug": "coverage-dsslider", "displayValue": "0 classes found", "value": 0, "score": 1, "details": { "issues": [] }, "title": "Usage coverage for DSSlider component", "description": "Coverage audit for DSSlider component. Matching classes: slider, range-slider, legacy-slider" }, { "slug": "coverage-dsnavbar", "displayValue": "0 classes found", "value": 0, "score": 1, "details": { "issues": [] }, "title": "Usage coverage for DSNavbar component", "description": "Coverage audit for DSNavbar component. Matching classes: navbar, navigation, legacy-navbar" } ], "description": "A plugin to measure and assert usage of styles in an Angular project." } ] } ``` -------------------------------------------------------------------------------- /docs/ds-refactoring-flow.md: -------------------------------------------------------------------------------- ```markdown # Design System Refactoring Flow ## Overview This document describes a 5-step AI-assisted refactoring process for migrating legacy components to the design system. Each step uses a specific rule file (.mdc) that guides the Cursor agent through automated analysis and code changes. **Flow Approaches:** The refactoring process offers two alternative approaches for the initial phases: **Option A: Targeted Approach** (recommended for focused, incremental migrations) 1. **Find Violations** (`01-find-violations.mdc`) → Identify specific deprecated component usage 2. **Plan Refactoring** (`02-plan-refactoring.mdc`) → Create detailed migration strategy for specific cases **Option B: Comprehensive Approach** (recommended for large-scale migrations) 1. **Find All Violations** (`01b-find-all-violations.mdc`) → Scan entire codebase, group by folders, select subfolder for detailed analysis 2. **Plan Refactoring for All Violations** (`02b-plan-refactoring-for-all-violations.mdc`) → Create comprehensive migration plan for all violations in scope **Continuation Steps** (used with both approaches): 3. **Fix Violations** → Execute code changes - **If viable:** Proceed with normal checklist (`03-fix-violations.mdc`) - **If non-viable:** Use alternative handling (`03-non-viable-cases.mdc`) 4. **Validate Changes** → Verify refactoring safety 5. **Prepare Report** → Generate testing checklists and documentation The process includes three quality gates where human review and approval are required. When components are identified as non-viable during planning, an alternative handling process is used instead of proceeding to the normal fix violations step. ## Prerequisites Before starting the refactoring flow, ensure you have: - Cursor IDE with this MCP (Model Context Protocol) server connected. This flow was tested with Cursor but should also work with Windsurf or Copilot. - The five rule files (.mdc) available in your workspace - A git branch for the refactoring work ## 01-find-violations.mdc ### Goal Identify and locate legacy component usage in a codebase to prepare for systematic refactoring. This rule helps developers find deprecated design system components and their usage patterns across the project in a structured, two-step process. ### Process To start this process, drag file `01-find-violations.mdc` to the cursor chat and provide `directory` and `component` parameters, your chat message will look like this ``` @01-find-violations.mdc directory=path/to/directory component=DsComponent ``` This rule follows a two-step process to find violations: **Step 1: Folder-level scan** - Scans the specified directory for component violations grouped by folder - Provides a ranked list of folders with violation counts - Allows user to select a specific subfolder for detailed analysis **Step 2: File-level scan** - Performs detailed scanning of the selected subfolder - Groups violations by individual files - Outputs a sorted list of files with violation counts - Prepares the transition to the planning phase > After the second scan, AI will explicitly ask you to attach the second rule for planning. ### Tools used - `report-violations` - Main MCP tool that analyzes deprecated design system CSS usage - Parameters: `componentName`, `directory`, `groupBy` (folder/file) - Returns violation data with counts and locations - Supports both folder-level and file-level grouping ### Flow > You don't need to manually perform any of the listed actions except providing the `component=DsComponent directory=path/to/folder` in the initial message. 1. **Initial Setup**: User provides `{{COMPONENT_NAME}}` and `{{DIRECTORY}}` parameters 2. **Folder Scan**: Execute `report-violations` with `groupBy: "folder"` 3. **Error Handling**: Check for tool errors or zero violations 4. **Folder Results**: Display ranked folder list with violation counts 5. **User Selection**: Prompt user to choose a subfolder for detailed analysis 6. **File Scan**: Execute `report-violations` with `groupBy: "file"` on selected subfolder 7. **File Results**: Display sorted file list with violation counts 8. **Transition**: Prompt user to attach "Plan Phase" rules for next step The rule enforces strict output formatting with `<folders>` and `<violations>` tags, and uses `<commentary>` blocks for error messages and clarifications. ### Preferred model Claude-4-Sonnet ## 01b-find-all-violations.mdc (Alternative Comprehensive Approach) ### Goal Perform comprehensive analysis of an entire codebase to identify all deprecated component usage patterns across multiple directories and components. This rule provides a broader scope alternative to the targeted approach, allowing teams to understand the full migration scope before focusing on specific areas for detailed planning. ### Process To start this process, drag file `01b-find-all-violations.mdc` to the cursor chat and provide the `directory` parameter, your chat message will look like this: ``` @01b-find-all-violations.mdc directory=path/to/directory ``` This rule follows a comprehensive two-step process to find all violations: **Step 1: Global folder-level scan** - Scans the entire specified directory tree for all deprecated component violations - Groups results by folder to provide overview of violation distribution - Provides a ranked list of folders with violation counts and file counts - Allows user to understand migration scope across the entire codebase - Enables selection of specific subfolder for focused analysis **Step 2: Targeted file-level scan** - Performs detailed scanning of the selected subfolder from step 1 - Groups violations by individual files within the selected scope - Outputs a sorted list of files with violation counts for precise targeting - Prepares comprehensive data for the planning phase > After the second scan, AI will explicitly ask you to attach the comprehensive planning rule. ### Tools used - `report-all-violations` - Comprehensive MCP tool that analyzes all deprecated design system CSS usage across the codebase - Parameters: `directory`, `groupBy` (folder/file) - Returns: Complete violation data with counts and locations across all components - Supports both folder-level overview and file-level detailed analysis ### Flow > You don't need to manually perform any of the listed actions except providing the `directory=path/to/folder` in the initial message. 1. **Initial Setup**: User provides `{{DIRECTORY}}` parameter for comprehensive analysis 2. **Global Scan**: Execute `report-all-violations` with `groupBy: "folder"` for complete overview 3. **Error Handling**: Check for tool errors or zero violations across entire codebase 4. **Folder Results**: Display ranked folder list with comprehensive violation and file counts 5. **User Selection**: Prompt user to choose a subfolder from the comprehensive results for detailed focus 6. **Targeted Scan**: Execute `report-all-violations` with `groupBy: "file"` on selected subfolder 7. **File Results**: Display sorted file list with precise violation counts for planning 8. **Transition**: Prompt user to attach comprehensive planning rules for next step The rule enforces structured output with `<folders>` and `<violations>` tags, and uses `<commentary>` blocks for error messages and progress updates. ### Preferred model Claude-4-Sonnet ## 02b-plan-refactoring-for-all-violations.mdc (Alternative Comprehensive Approach) ### Goal Create a comprehensive migration strategy for large-scale refactoring of legacy components across multiple files and violation types. This rule provides a thorough analysis approach for complex migration scenarios involving extensive deprecated component usage, focusing on creating detailed implementation plans for comprehensive scope migrations. ### Process To start this process, drag file `02b-plan-refactoring-for-all-violations.mdc` to the cursor chat after completing the comprehensive violations analysis. The rule implements an enhanced three-phase comprehensive planning process: **Phase 1: Comprehensive Analysis** - Reviews extensive component documentation, implementation code, and usage patterns across all violation files - Analyzes complete scope of affected files (templates, TypeScript, styles, specs, NgModules) - Assesses migration complexity across the entire selected scope and identifies potential non-viable migrations - Evaluates library dependencies and their comprehensive impact on large-scale migration - Considers cross-component dependencies and interaction patterns **Phase 2: Detailed Plan Creation for Complete Scope** - Compares deprecated usage patterns against design system exemplars across all files - Classifies each migration comprehensively as: Simple swap, Requires restructure, or Non-viable - Assigns complexity scores (1-10) with comprehensive penalties for animations/breakpoints/variants across scope - Creates comprehensive actionable plans ordered by effort with concrete edits needed for all files - Provides extensive verification notes for static file-based checks across the migration scope - Considers migration dependencies and optimal sequencing for large-scale changes --- **🚦 Quality Gate 1 (Comprehensive Review)** Before proceeding to Phase 3, you must review the comprehensive migration plan. **Required Actions:** - Review the complete migration strategy for all identified violations - **If all components are viable for migration:** Approve or request modifications, then proceed with comprehensive checklist creation - **If some components are non-viable:** Developer must thoroughly review and confirm non-viability decisions, then use `@03-non-viable-cases.mdc` for non-viable cases - **If mixed viability:** Proceed with checklist for viable cases and handle non-viable cases separately - Clarify any uncertainties regarding the comprehensive approach **Next Step:** - **All viable migrations:** When satisfied with the plan, the agent will create a comprehensive checklist - **Mixed or non-viable migrations:** Use appropriate handling rules for different component categories --- **Phase 3: Comprehensive Checklist Creation** - Generates extensive checklist covering all viable migrations with detailed checkbox items - Creates comprehensive verification phase with static checks across all affected files - Includes dependency management and sequencing considerations for large-scale migrations - Saves comprehensive checklist to `.cursor/tmp/refactoring-checklist-{{FOLDER_PATH}}.md` > After the comprehensive checklist is generated and you see it in the chat, it is time to attach the fix violations rule. ### Tools used - `list-ds-components` - Lists all available Design System components in the project - Parameters: `sections` (optional) - Array of sections to include: "implementation", "documentation", "stories", "all" - Returns: Complete inventory of DS components with their file paths and metadata - Provides: Overview of available components for comprehensive migration planning - `get-ds-component-data` - Retrieves comprehensive component information for all involved components - Parameters: `componentName`, `sections` (optional) - Array of sections to include: "implementation", "documentation", "stories", "all" - Returns: Complete implementation files, documentation files, import paths for multiple components - Provides: Component source code, API documentation, usage examples across scope - `build-component-usage-graph` - Maps comprehensive component dependencies and usage patterns - Parameters: `directory`, `violationFiles` (from comprehensive scan, automatically picked up) - Returns: Complete graph showing where all components are imported and used across scope - Analyzes: modules, specs, templates, styles, reverse dependencies for large-scale impact - `get-project-dependencies` - Analyzes project structure and dependencies for comprehensive scope - Parameters: `directory`, optional `componentName` - Returns: library type (buildable/publishable), peer dependencies for scope assessment - Validates: import paths, workspace configuration for large-scale migration compatibility ### Flow > You don't need to manually perform any of the listed actions. 1. **Comprehensive Input Gathering**: Collect all component data, folder path, documentation, code, usage graphs, and library data for complete scope 2. **Extensive Analysis**: Review all inputs and analyze comprehensive codebase impact across all violation files 3. **Large-Scale Complexity Assessment**: Evaluate migration difficulty and identify non-viable cases across complete scope 4. **Comprehensive File Classification**: Categorize each file's migration requirements within the broader context 5. **Detailed Plan Creation**: Generate comprehensive migration steps with complexity scores for all files 6. **Extensive Verification Design**: Create static checks for comprehensive plan validation across scope 7. **Large-Scale Ambiguity Resolution**: Identify and request clarification for unclear aspects across scope 8. **Comprehensive Approval Process**: Present complete plan with "🛠️ Approve this comprehensive plan or specify adjustments?" 9. **Extensive Checklist Generation**: Create detailed actionable checklist after approval covering all scope 10. **Comprehensive File Persistence**: Save complete checklist to temporary file for large-scale reference The rule enforces structured output with `<comprehensive_analysis>`, `<migration_plan>`, and `<checklist>` tags, and includes enhanced ambiguity safeguards for complex large-scale scenarios. ### Preferred model - Non-complex cases: Claude-4-Sonnet - Complex large-scale cases: Claude-4-Sonnet (thinking) ## 02-plan-refactoring.mdc ### Goal Create a comprehensive migration plan for refactoring legacy components to new design system components. This rule analyzes the current codebase, evaluates migration complexity, and provides a detailed, actionable plan with specific steps, classifications, and verification notes for each affected file. ### Process To start this process, drag file `02-plan-refactoring.mdc` to the cursor chat. The rule implements a three-phase migration planning process: **Phase 1: Comprehensive Analysis** - Reviews component documentation, implementation code, and usage patterns - Analyzes all affected files (templates, TypeScript, styles, specs, NgModules) - Assesses migration complexity and identifies potential non-viable migrations - Evaluates library dependencies and their impact on migration **Phase 2: Detailed Plan Creation** - Compares old markup against design system exemplars - Classifies each migration as: Simple swap, Requires restructure, or Non-viable - Assigns complexity scores (1-10) with penalties for animations/breakpoints/variants - Creates actionable plans ordered by effort with concrete edits needed - Provides verification notes for static file-based checks --- **🚦 Quality Gate 1** Before proceeding to Phase 3, you must review the migration plan. **Required Actions:** - Review the suggested plan thoroughly - **If components are viable for migration:** Approve or request modifications, then proceed with checklist creation - **If components are non-viable:** Developer must thoroughly review and confirm non-viability, then use `@03-non-viable-cases.mdc` instead of normal checklist - Clarify any uncertainties **Next Step:** - **Viable migrations:** When satisfied with the plan, the agent will create a checklist - **Non-viable migrations:** Use the non-viable cases rule instead of proceeding to fix violations --- **Phase 3: Checklist Creation** - Generates comprehensive checklist of actual changes as checkboxes - Creates verification phase with static checks that can be performed by reading files - Saves checklist to `.cursor/tmp/refactoring-checklist-{{FOLDER_PATH}}.md` > After the checklist is generated and you see it in the chat, it is time to attach the next rule. ### Tools used - `list-ds-components` - Lists all available Design System components in the project - Parameters: `sections` (optional) - Array of sections to include: "implementation", "documentation", "stories", "all" - Returns: Complete inventory of DS components with their file paths and metadata - Provides: Overview of available components for migration planning - `get-ds-component-data` - Retrieves comprehensive component information - Parameters: `componentName`, `sections` (optional) - Array of sections to include: "implementation", "documentation", "stories", "all" - Returns: implementation files, documentation files, import paths - Provides: component source code, API documentation, usage examples - `build-component-usage-graph` - Maps component dependencies and usage - Parameters: `directory`, `violationFiles` (from previous step, automatically picked up) - Returns: graph showing where components are imported and used - Analyzes: modules, specs, templates, styles, reverse dependencies - `get-project-dependencies` - Analyzes project structure and dependencies - Parameters: `directory`, optional `componentName` - Returns: library type (buildable/publishable), peer dependencies - Validates: import paths, workspace configuration ### Flow > You don't need to manually perform any of the listed actions. 1. **Input Gathering**: Collect component name, folder path, documentation, code, usage graph, and library data 2. **Comprehensive Analysis**: Review all inputs and analyze codebase impact 3. **Complexity Assessment**: Evaluate migration difficulty and identify non-viable cases 4. **File Classification**: Categorize each file's migration requirements 5. **Plan Creation**: Generate detailed migration steps with complexity scores 6. **Verification Design**: Create static checks for plan validation 7. **Ambiguity Resolution**: Identify and request clarification for unclear aspects 8. **Approval Process**: Present plan with "🛠️ Approve this plan or specify adjustments?" 9. **Checklist Generation**: Create actionable checklist after approval 10. **File Persistence**: Save checklist to temporary file for reference The rule enforces structured output with `<comprehensive_analysis>`, `<migration_plan>`, and `<checklist>` tags, and includes built-in ambiguity safeguards. ### Preferred model - Non-complex cases: Claude-4-Sonnet - Complex cases: Claude-4-Sonnet (thinking) ## Non-Viable Cases Handling ### When to Use During the **02-plan-refactoring.mdc** step, if the AI identifies components as non-viable for migration, this must be **thoroughly reviewed by an actual developer**. Only after developer confirmation should you proceed with non-viable handling instead of the normal checklist confirmation. ### Process When non-viable cases are confirmed during planning, instead of proceeding with the normal checklist, use the non-viable cases rule: - Reference: `@03-non-viable-cases.mdc` (or `@03-non-viable-cases.mdc` depending on your rule setup) - **Critical:** This replaces the normal "Fix Violations" step entirely The rule implements a systematic three-phase process for handling non-migratable components: **Phase 1: Identification & Discovery** - Identifies the target component class name from conversation context - Runs CSS discovery using `report-deprecated-css` tool on both global styles and style overrides directories - Creates a comprehensive implementation checklist with validation checks - Saves checklist to `.cursor/tmp/css-cleanup/[class-name]-[scope]-non-viable-migration-checklist.md` **Phase 2: Implementation** - Works systematically from the saved checklist file - **Step 1: HTML Template Updates (FIRST PRIORITY)** - Replaces original component classes with `after-migration-[ORIGINAL_CLASS]` in HTML files/templates - Must be done BEFORE any CSS changes to ensure consistency - **Step 2: CSS Selector Duplication (NOT REPLACEMENT)** - Duplicates CSS selectors rather than replacing them - Transforms: `.custom-radio {}` → `.custom-radio, .after-migration-custom-radio {}` - Maintains visual parity between original and prefixed versions **Phase 3: Validation (Mandatory)** - **Validation 1 - CSS Count Consistency**: Re-runs `report-deprecated-css` tool to verify deprecated class count remains identical - **Validation 2 - Violation Reduction**: Runs `report-violations` tool to verify the expected reduction in violations - Updates checklist with validation results and marks all items complete ### Key Features **Exclusion Strategy**: The `after-migration-` prefix serves as a marker that excludes these components from future violation reports, effectively removing them from the migration pipeline while preserving functionality. **Visual Consistency**: By duplicating CSS selectors rather than replacing them, the workflow ensures that both the original classes and the new prefixed classes render identically. **Comprehensive Tracking**: The workflow maintains detailed checklists and validation steps to ensure all instances are properly handled and tracked. **Error Prevention**: Systematic validation ensures that the transformation doesn't break existing functionality or miss any instances. ### Tools used - `report-deprecated-css` - Identifies deprecated CSS classes in style directories - Parameters: `directory`, `componentName` - Returns: List of deprecated CSS usage with file locations and line numbers - Used for: Discovery phase and validation of CSS count consistency - `report-violations` - Analyzes deprecated component usage in templates and code - Parameters: `directory`, `componentName` - Returns: List of component violations with file locations - Used for: Validation of violation reduction after implementation ### Flow > You don't need to manually perform any of the listed actions except providing directory paths when requested. 1. **Component Identification**: Extract target component class name from conversation context 2. **Directory Input**: Request global styles and style overrides directories from user (with fallback handling) 3. **CSS Discovery**: Run parallel `report-deprecated-css` scans on both directories 4. **Checklist Creation**: Generate comprehensive implementation checklist with validation checks 5. **HTML Updates**: Replace component classes with `after-migration-` prefixed versions in templates 6. **CSS Duplication**: Add prefixed selectors alongside original selectors in CSS files 7. **Validation Execution**: Run mandatory validation checks using actual tools 8. **Progress Tracking**: Update checklist file throughout the process with completion status 9. **Final Verification**: Confirm all validation criteria are met before completion The rule enforces structured output with `<target_component>`, `<checklist_summary>`, `<validation_1>`, and `<validation_2>` tags, and maintains strict validation criteria to ensure process integrity. ### When to Use This Workflow This workflow should be used when: - A component is identified as non-viable for migration during the planning phase - Legacy components cannot be updated due to technical constraints - Components need to be excluded from future violation reports - Maintaining existing visual appearance is critical during transition periods ### Integration with Main Flow This handling is integrated within the design system refactoring process: - **Decision Point**: During `02-plan-refactoring.mdc` when components are classified as "Non-viable" - **Developer Review Required**: Must be thoroughly reviewed and approved by actual developer before proceeding - **Replaces Steps 3-5**: When used, this replaces the normal Fix Violations → Validate Changes → Prepare Report sequence - **Outcome**: Successfully processed components will be excluded from subsequent violation reports ### Preferred model Claude-4-Sonnet ## 03-fix-violations.mdc ### Goal Execute the refactoring checklist by analyzing components, implementing changes, and tracking progress. ### Process To start this process, drag file `03-fix-violations.mdc` to the cursor chat AFTER you get a `<checklist>`. The rule implements a systematic refactoring execution process: **Step 1: Checklist Loading** - Reads the refactoring checklist from `.cursor/tmp/refactoring-checklist-{{FOLDER_PATH}}.md` - Parses checklist items and identifies components to be refactored **Step 2: Contract Generation** - Creates component contracts for each component before refactoring - Generates JSON snapshots of component's public API, DOM structure, and styles - Saves contracts to `.cursor/tmp/contracts/<ds-component-kebab>/` directory **Step 3: Refactoring Execution** - Analyzes each component using the generated contracts - Determines necessary changes based on checklist items - Implements code modifications (templates, TypeScript, styles, specs) - Updates checklist with progress notes **Step 4: Progress Tracking** - Updates checklist file with completion status and change descriptions - Documents what was changed or why no changes were needed - Maintains audit trail of refactoring progress **Step 5: Reflection and Confirmation** - Identifies uncertainties or areas needing user confirmation - Provides clear explanations of any ambiguous situations - Requests user approval for complex or uncertain changes --- **🚦 Quality Gate 2** At this point, initial refactoring is complete. **Required Actions:** - Review refactoring results - Resolve any ambiguities - Approve the results **Next Step:** After changes are approved and questions resolved, it is time to add the next rule to the chat. --- ### Tools used - `build_component_contract` - Creates component contracts for safe refactoring - Parameters: `saveLocation`, `typescriptFile` (required), `templateFile` (optional), `styleFile` (optional), `dsComponentName` (optional) - Returns: contract with public API, DOM structure, styles, and metadata - Generates: JSON contract files with SHA-256 hashes for validation - Note: Template and style files are optional—extracts inline templates/styles from TypeScript when not provided ### Flow > You don't need to manually perform any of the listed actions. 1. **Checklist Parsing**: Load and parse the refactoring checklist from temporary file 2. **Contract Generation**: Create baseline contracts for all components in scope 3. **Component Analysis**: Analyze each component using contract data 4. **Change Determination**: Evaluate what modifications are needed per checklist item 5. **Code Implementation**: Execute the actual refactoring changes 6. **Progress Documentation**: Update checklist with completion status and notes 7. **Reflection Phase**: Identify uncertainties and areas needing confirmation 8. **User Interaction**: Request approval for complex changes or clarifications 9. **Final Report**: Generate structured report with updates, reflections, and confirmations needed The rule enforces structured output with `<refactoring_report>`, `<checklist_updates>`, `<reflections>`, and `<user_confirmations_needed>` tags, and maintains detailed progress tracking throughout the process. ### Preferred model Claude-4-Sonnet ## 04-validate-changes.mdc ### Goal Analyze refactored code and component contracts to identify potential issues, breaking changes, and risky points that require attention from the development team. This rule provides comprehensive validation through static analysis, contract comparison, and structured reporting to ensure refactoring safety and quality. ### Process To start this process, drag file `04-validate-changes.mdc` to the cursor chat after refactoring is completed. The rule implements a comprehensive validation analysis process: **Step 1: Static Code Analysis** - Runs ESLint validation on all refactored files - Checks for Angular-specific rule violations and TypeScript issues - Reports any linting errors that need immediate attention **Step 2: Contract Generation** - Creates new component contracts for the refactored state - Captures current public API, DOM structure, and styles - Generates SHA-256 hashes for contract validation **Step 3: Contract Comparison** - Lists all available component contracts (before/after states) - Performs detailed diffs between old and new contracts - Identifies changes in function signatures, data structures, and interfaces **Step 4: Change Analysis** - Analyzes contract diffs for potential breaking changes - Evaluates severity and impact of each modification - Considers backwards compatibility and performance implications **Step 5: Risk Assessment** - Identifies high-risk changes requiring elevated attention - Evaluates potential impacts on other system parts - Assesses overall refactoring safety and quality **Step 6: Validation Reporting** - Generates structured analysis with detailed findings - Provides specific recommendations for development, QA, and UAT teams - Highlights critical issues requiring immediate action --- **🚦 Quality Gate 3** This is your last chance to make changes before opening the pull request. **Required Actions:** - Review validation report and risk assessment - Resolve any critical issues - Approve the final results **Next Step:** After all issues are resolved and no changes are needed, you can attach the next rule file. --- ### Tools used - `lint-changes` - Performs static code analysis using ESLint - Parameters: `directory`, optional `files` and `configPath` - Returns: Angular-specific rule violations, TypeScript issues, template errors - Features: Automatic ESLint config resolution, comprehensive rule coverage - `build_component_contract` - Creates contracts for refactored components - Parameters: `saveLocation`, `typescriptFile` (required), `templateFile` (optional), `styleFile` (optional), `dsComponentName` (optional) - Returns: JSON contract with public API, DOM structure, and styles - Purpose: Capture post-refactoring component state - Note: Template and style files are optional for components with inline templates/styles - `list_component_contracts` - Lists available component contracts - Parameters: `directory` - Returns: Available contract files with timestamps and metadata - Purpose: Identify before/after contract pairs for comparison - `diff_component_contract` - Compares component contracts - Parameters: `saveLocation`, `contractBeforePath`, `contractAfterPath`, `dsComponentName` - Returns: Detailed diff highlighting changes in API, DOM, and styles - Saves: Diff files to the specified saveLocation path ### Flow > You don't need to manually perform any of the listed actions. 1. **Input Processing**: Parse refactored files list and available component contracts 2. **Static Analysis**: Run ESLint validation on all refactored files 3. **Error Handling**: Address any linting errors before proceeding 4. **Contract Generation**: Create new contracts for refactored components 5. **Contract Discovery**: List all available contracts for comparison 6. **Contract Comparison**: Generate diffs between before/after contract states 7. **Change Analysis**: Analyze diffs for breaking changes and risks 8. **Impact Assessment**: Evaluate severity and system-wide implications 9. **Report Generation**: Create structured validation report with recommendations 10. **Quality Assurance**: Provide actionable insights for development teams The rule enforces structured output with `<analysis>`, `<questions_for_user>`, and `<validation_report>` tags, ensuring comprehensive coverage of all potential issues and clear communication of findings. ### Preferred model Claude-4-Sonnet (thinking) ## 05-prepare-report.mdc ### Goal Analyze the complete refactoring session, create comprehensive testing checklists for different roles, and generate documentation for code changes. This rule provides the final deliverables including role-specific testing checklists, semantic commit messages, and PR descriptions to ensure proper handoff to development teams and quality assurance processes. ### Process To start this process, drag file `05-prepare-report.mdc` to the cursor chat after validation is completed. The rule implements a comprehensive reporting and documentation process: **Step 1: Chat History Analysis** - Reviews the entire refactoring session conversation - Identifies all refactoring changes discussed and implemented - Extracts analysis, insights, and code modifications - Documents potential risks and concerns mentioned **Step 2: Impact Assessment** - Evaluates the overall impact of changes on the system - Identifies potential edge cases and affected scenarios - Determines areas requiring special attention during testing - Assesses both functional and non-functional implications **Step 3: Testing Checklist Creation** - Generates role-specific testing checklists for three key roles: - **Developer**: Unit tests, integration tests, code review points - **Manual QA Engineer**: Functional testing, regression testing, edge cases - **UAT Professional**: User acceptance criteria, business logic validation - Highlights uncertainties requiring clarification - Specifies critical verification points **Step 4: Documentation Generation** - Creates semantic commit message following conventional commit format - Generates PR description summarizing changes and review points - Saves comprehensive verification checklist to `.cursor/tmp/verification-checklist-{{FOLDER}}.md` **Step 5: Deliverable Packaging** - Structures all outputs in standardized format - Ensures proper handoff documentation - Provides actionable items for each stakeholder role > This is the end of the flow. ### Tools used None ### Flow > You don't need to manually perform any of the listed actions. 1. **History Review**: Analyze complete chat history for refactoring changes and insights 2. **Change Analysis**: Identify specific code areas modified and potential risks 3. **Impact Evaluation**: Assess overall system impact and edge cases 4. **Checklist Generation**: Create detailed testing checklists for each role 5. **Documentation Creation**: Generate semantic commit messages and PR descriptions 6. **File Persistence**: Save verification checklist to temporary directory 7. **Output Structuring**: Format all deliverables in standardized sections 8. **Quality Assurance**: Ensure comprehensive coverage and actionable items 9. **Stakeholder Handoff**: Provide clear documentation for development teams The rule enforces structured output with `<analysis>`, `<testing_checklists>`, `<verification_document_path>`, `<commit_message>`, and `<pr_description>` tags, ensuring complete documentation of the refactoring process and clear next steps for all stakeholders. ### Preferred model Claude-4-Sonnet ## clean-global-styles.mdc (Independent Step) ### Goal Analyze a project for deprecated CSS classes and component violations to provide a comprehensive assessment of design system migration readiness. This rule serves as a preliminary analysis step that can be used independently of the main refactoring flow to understand the scope of deprecated usage across both global styles and component-specific code. ### Process To start this process, drag file `clean-global-styles.mdc` to the cursor chat and provide the required parameters: ``` directory=path/to/source/directory stylesDirectory=path/to/global/styles/directory componentName=DsComponentName @clean-global-styles.mdc ``` This rule follows a three-step analysis process: **Step 1: Global Styles Analysis** - Scans the global styles directory for deprecated CSS classes - Identifies occurrences of deprecated classes across all style files - Reports file locations and line numbers for each violation **Step 2: Source Directory Analysis** - Scans the source directory for deprecated CSS classes in component styles - Identifies deprecated CSS usage in component-specific style files - Reports violations with precise file and line information **Step 3: Component Violations Analysis** - Scans the source directory for deprecated component usage in templates and TypeScript files - Identifies HTML elements and TypeScript code using deprecated classes - Reports violations with context about where deprecated components are used ### Tools used - `report-deprecated-css` - Analyzes deprecated CSS classes in style files - Parameters: `directory`, `componentName` - Returns: List of deprecated CSS class usage with file locations and line numbers - Scans: .scss, .sass, .less, .css files for deprecated class selectors - `report-violations` - Analyzes deprecated component usage in templates and code - Parameters: `directory`, `componentName` - Returns: List of component violations with file locations and line numbers - Scans: .html, .ts files for deprecated component usage in templates and inline templates ### Flow > You don't need to manually perform any of the listed actions except providing the initial parameters. 1. **Parameter Setup**: User provides `{{SOURCE_PATH}}`, `{{GLOBAL_STYLES_PATH}}`, and `{{COMPONENT_NAME}}` 2. **Global Styles Scan**: Execute `report-deprecated-css` on global styles directory 3. **Source Directory Scan**: Execute `report-deprecated-css` on source directory 4. **Component Violations Scan**: Execute `report-violations` on source directory 5. **Results Analysis**: Analyze all findings and determine next steps 6. **Recommendation Generation**: Provide structured recommendations based on findings 7. **User Action Decision**: Present options for handling deprecated CSS if no violations found ### Output Structure The rule provides structured output with three key sections: **Analysis Section** - Summary of violations found in source folder - Count and distribution of deprecated CSS occurrences - Assessment of migration readiness **Recommendation Section** - Priority actions based on findings - Guidance on whether to fix violations first or clean up deprecated CSS - Strategic recommendations for migration approach **User Action Required Section** - Interactive options when no violations are found but deprecated CSS exists - Choices for handling deprecated CSS (remove, save, or ignore) - Clear next steps for the user ### Decision Tree The rule follows a decision tree approach: 1. **If component violations are found**: Recommend fixing violations first before cleaning up deprecated CSS 2. **If no violations but deprecated CSS exists**: Offer options to remove, save, or ignore deprecated CSS 3. **If no violations and no deprecated CSS**: Confirm the directory is clean and ready ### Integration with Main Flow While this rule operates independently, it can inform the main refactoring flow: - **Before Main Flow**: Use to assess overall migration scope and readiness - **During Planning**: Reference findings to understand global impact - **After Refactoring**: Use to verify cleanup completeness ### Preferred model Claude-4-Sonnet ## discover-affected-urls.mdc (Independent Step) ### Goal Analyze Angular routing hierarchy to discover URL(s) where specific component files can be accessed in a web application. This rule performs comprehensive routing analysis using a bottom-up approach to identify both directly routable components and non-routable components (modals, dialogs, child components) that are accessible through their parent routes, providing complete URL discovery with redirect resolution. ### Process To start this process, drag file `discover-affected-urls.mdc` to the cursor chat and provide the required parameters: ``` app_directory=src/app files=["src/app/components/user.component.ts", "src/app/dialogs/confirmation.component.ts"] @discover-affected-urls.mdc ``` This rule implements a comprehensive five-phase analysis process: **Phase 1: Routing Hierarchy Discovery & Bottom-Top Point Identification** - Scans the complete app directory to identify ALL routing files and build routing hierarchy tree - Discovers top point (complete app routing structure) and bottom point (file parent routes) - Classifies each file as either directly routable or non-routable - Validates that both routing points are properly identified before proceeding **Phase 2: Non-Routable Component Analysis** - Identifies components without direct route definitions (modals, dialogs, library components) - Traverses component hierarchy upward through multiple levels to find routable parent components - Analyzes modal/dialog trigger mechanisms (MatDialog.open, component selectors, service calls) - Maps complete relationship chains from non-routable components to their accessible routes **Phase 3: Bottom-Up Route Connection & Path Construction** - Creates comprehensive redirect mapping from all routing files in the hierarchy - Traces routable components upward through routing hierarchy with full redirect resolution - Resolves non-routable component paths using parent relationships from Phase 2 - Constructs complete paths with redirect audit trails and concrete URL examples **Phase 4: Parameter & Visibility Analysis** - Extracts parameter constraints from TypeScript files using established connections - Scans for visibility conditions (@if, *ngIf directives, route guards, permissions) - Provides realistic examples with culture codes and parameter values - Validates parameter inheritance and visibility constraints along routing paths **Phase 5: Quick Access Summary Generation** - Collects and organizes all route examples from previous phases - Generates structured summary with mandatory bullet list format - Provides 1-3 concrete URL examples per file with realistic parameters - Ensures complete coverage of all analyzed files with proper formatting ### Tools used None - This rule uses pure Angular routing analysis without external MCP tools ### Flow > You don't need to manually perform any of the listed actions except providing the initial parameters. 1. **Parameter Setup**: User provides `{{APP_DIRECTORY}}` and `{{FILES}}` array for analysis 2. **Routing Discovery**: Scan app directory for complete routing hierarchy and classify files 3. **Non-Routable Analysis**: Identify parent relationships for components without direct routes 4. **Route Construction**: Build complete paths with redirect resolution and concrete examples 5. **Parameter Analysis**: Extract constraints and visibility conditions along routing paths 6. **Summary Generation**: Create quick access summary with formatted URL examples for all files 7. **Validation**: Ensure complete coverage and proper formatting of all analyzed components ### Output Structure The rule provides structured output across five tagged sections: **Routing Discovery Section** (`<routing_discovery>`) - Complete app routing hierarchy tree - File classification (routable vs non-routable) - Top and bottom point identification **Non-Routable Analysis Section** (`<non_routable_analysis>`) - Parent component relationships - Multi-level hierarchy traversal results - Modal/dialog trigger analysis **Bottom-Up Connection Section** (`<bottom_up_connection>`) - Comprehensive redirect mapping - Complete path construction with examples - Redirect audit trails **Parameter Analysis Section** (`<parameter_analysis>`) - Parameter constraints and visibility conditions - Realistic examples with culture codes - Guard and permission analysis **Quick Access Summary Section** (`<quick_access_summary>`) - Structured summary with bullet format - 1-3 URL examples per file - Complete coverage verification ### Use Cases This rule is particularly useful for: - **Component Migration Planning**: Understanding where components are accessible before refactoring - **Testing Strategy**: Identifying all URLs that need testing after component changes - **Documentation**: Creating comprehensive route documentation for components - **Debugging**: Troubleshooting routing issues and finding component access points - **Impact Analysis**: Understanding the scope of changes when modifying routable components ### Integration with Main Flow While this rule operates independently, it complements the design system refactoring flow: - **Before Refactoring**: Identify all URLs where legacy components are accessible - **During Planning**: Understand routing impact of component changes - **After Migration**: Verify that refactored components remain accessible at expected URLs - **Testing Phase**: Use discovered URLs for comprehensive component testing ### Preferred model Claude-4-Sonnet ```