@design-factory/angular 21.1.0 → 22.0.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.ai/docs/components/accordion/accessibility.md +45 -0
- package/.ai/docs/components/accordion/api.md +279 -0
- package/.ai/docs/components/accordion/developer.md +43 -0
- package/.ai/docs/components/accordion/guidelines.md +99 -0
- package/.ai/docs/components/accordion/overview.md +17 -0
- package/.ai/docs/components/alert/accessibility.md +24 -0
- package/.ai/docs/components/alert/api.md +65 -0
- package/.ai/docs/components/alert/developer.md +63 -0
- package/.ai/docs/components/alert/guidelines.md +62 -0
- package/.ai/docs/components/alert/overview.md +12 -0
- package/.ai/docs/components/button/accessibility.md +25 -0
- package/.ai/docs/components/button/api.md +71 -0
- package/.ai/docs/components/button/developer.md +52 -0
- package/.ai/docs/components/button/guidelines.md +75 -0
- package/.ai/docs/components/button/overview.md +15 -0
- package/.ai/docs/components/buttongroup/api.md +16 -0
- package/.ai/docs/components/buttongroup/developer.md +32 -0
- package/.ai/docs/components/drawer/accessibility.md +15 -0
- package/.ai/docs/components/drawer/api.md +56 -0
- package/.ai/docs/components/drawer/developer.md +36 -0
- package/.ai/docs/components/drawer/examples.md +9 -0
- package/.ai/docs/components/drawer/guidelines.md +58 -0
- package/.ai/docs/components/drawer/overview.md +19 -0
- package/.ai/docs/components/dropdown/accessibility.md +27 -0
- package/.ai/docs/components/dropdown/api.md +85 -0
- package/.ai/docs/components/dropdown/developer.md +59 -0
- package/.ai/docs/components/dropdown/guidelines.md +80 -0
- package/.ai/docs/components/dropdown/overview.md +16 -0
- package/.ai/docs/components/sidenav/accessibility.md +48 -0
- package/.ai/docs/components/sidenav/api.md +110 -0
- package/.ai/docs/components/sidenav/developer.md +14 -0
- package/.ai/docs/components/sidenav/guidelines.md +83 -0
- package/.ai/docs/components/sidenav/overview.md +16 -0
- package/.ai/docs/components/tooltip/accessibility.md +11 -0
- package/.ai/docs/components/tooltip/api.md +39 -0
- package/.ai/docs/components/tooltip/developer.md +16 -0
- package/.ai/docs/components/tooltip/guidelines.md +84 -0
- package/.ai/docs/components/tooltip/overview.md +23 -0
- package/.ai/docs/components/topnav/accessibility.md +51 -0
- package/.ai/docs/components/topnav/api.md +190 -0
- package/.ai/docs/components/topnav/developer.md +43 -0
- package/.ai/docs/components/topnav/guidelines.md +121 -0
- package/.ai/docs/components/topnav/overview.md +17 -0
- package/.ai/docs/demos/accordion/addons-subtitle/accordion-addons-subtitle.html +75 -0
- package/.ai/docs/demos/accordion/addons-subtitle/accordion-addons-subtitle.ts +27 -0
- package/.ai/docs/demos/accordion/basic/accordion-basic.html +16 -0
- package/.ai/docs/demos/accordion/basic/accordion-basic.ts +14 -0
- package/.ai/docs/demos/accordion/close-others/accordion-close-others.html +16 -0
- package/.ai/docs/demos/accordion/close-others/accordion-close-others.ts +14 -0
- package/.ai/docs/demos/accordion/interactive/accordion-interactive.html +84 -0
- package/.ai/docs/demos/accordion/interactive/accordion-interactive.ts +30 -0
- package/.ai/docs/demos/accordion/interactive-addons-subtitle/accordion-interactive-addons-subtitle.html +126 -0
- package/.ai/docs/demos/accordion/interactive-addons-subtitle/accordion-interactive-addons-subtitle.ts +33 -0
- package/.ai/docs/demos/accordion/programmatic-control/accordion-programmatic-control.html +36 -0
- package/.ai/docs/demos/accordion/programmatic-control/accordion-programmatic-control.ts +15 -0
- package/.ai/docs/demos/accordion/selectable/accordion-selectable.html +16 -0
- package/.ai/docs/demos/accordion/selectable/accordion-selectable.ts +14 -0
- package/.ai/docs/demos/accordion/selectable-extended/accordion-selectable-extended.html +28 -0
- package/.ai/docs/demos/accordion/selectable-extended/accordion-selectable-extended.ts +80 -0
- package/.ai/docs/demos/accordion/separator/accordion-separator.html +16 -0
- package/.ai/docs/demos/accordion/separator/accordion-separator.ts +14 -0
- package/.ai/docs/demos/alert/banner/alert-banner.html +15 -0
- package/.ai/docs/demos/alert/banner/alert-banner.ts +16 -0
- package/.ai/docs/demos/alert/basic/alert-basic.html +6 -0
- package/.ai/docs/demos/alert/basic/alert-basic.ts +9 -0
- package/.ai/docs/demos/alert/card/alert-card.html +15 -0
- package/.ai/docs/demos/alert/card/alert-card.ts +9 -0
- package/.ai/docs/demos/alert/dismissal/alert-dismissal.html +5 -0
- package/.ai/docs/demos/alert/dismissal/alert-dismissal.ts +27 -0
- package/.ai/docs/demos/alert/expandable/alert-expandable.html +9 -0
- package/.ai/docs/demos/alert/expandable/alert-expandable.ts +11 -0
- package/.ai/docs/demos/button/basic/button-basic.html +4 -0
- package/.ai/docs/demos/button/basic/button-basic.ts +9 -0
- package/.ai/docs/demos/button/disabled/button-disabled.html +18 -0
- package/.ai/docs/demos/button/disabled/button-disabled.ts +12 -0
- package/.ai/docs/demos/button/icons/button-icons.html +17 -0
- package/.ai/docs/demos/button/icons/button-icons.ts +10 -0
- package/.ai/docs/demos/button/surfaces/button-surfaces.html +13 -0
- package/.ai/docs/demos/button/surfaces/button-surfaces.ts +9 -0
- package/.ai/docs/demos/button/variants/button-variants.html +49 -0
- package/.ai/docs/demos/button/variants/button-variants.ts +9 -0
- package/.ai/docs/demos/buttongroup/basic/buttongroup-basic.html +6 -0
- package/.ai/docs/demos/buttongroup/basic/buttongroup-basic.ts +10 -0
- package/.ai/docs/demos/buttongroup/disabled/buttongroup-disabled.html +6 -0
- package/.ai/docs/demos/buttongroup/disabled/buttongroup-disabled.ts +10 -0
- package/.ai/docs/demos/buttongroup/mirror/buttongroup-mirror.html +8 -0
- package/.ai/docs/demos/buttongroup/mirror/buttongroup-mirror.ts +10 -0
- package/.ai/docs/demos/buttongroup/orientation/buttongroup-orientation.html +19 -0
- package/.ai/docs/demos/buttongroup/orientation/buttongroup-orientation.ts +10 -0
- package/.ai/docs/demos/buttongroup/sizing/buttongroup-sizing.html +19 -0
- package/.ai/docs/demos/buttongroup/sizing/buttongroup-sizing.ts +10 -0
- package/.ai/docs/demos/drawer/inline/drawer-inline-basic.html +46 -0
- package/.ai/docs/demos/drawer/inline/drawer-inline-basic.ts +33 -0
- package/.ai/docs/demos/drawer/overlay/drawer-overlay-basic.html +30 -0
- package/.ai/docs/demos/drawer/overlay/drawer-overlay-basic.ts +25 -0
- package/.ai/docs/demos/dropdown/basic/dropdown-basic.html +8 -0
- package/.ai/docs/demos/dropdown/basic/dropdown-basic.ts +15 -0
- package/.ai/docs/demos/dropdown/sizes/dropdown-sizes.html +9 -0
- package/.ai/docs/demos/dropdown/sizes/dropdown-sizes.ts +21 -0
- package/.ai/docs/demos/dropdown/split/dropdown-split.html +9 -0
- package/.ai/docs/demos/dropdown/split/dropdown-split.ts +11 -0
- package/.ai/docs/demos/dropdown/toggle/dropdown-toggle.html +22 -0
- package/.ai/docs/demos/dropdown/toggle/dropdown-toggle.ts +10 -0
- package/.ai/docs/demos/sidenav/sidenav-basic-no-icon/routes.ts +95 -0
- package/.ai/docs/demos/sidenav/sidenav-basic-no-icon/sidenav-basic-no-icon.html +42 -0
- package/.ai/docs/demos/sidenav/sidenav-basic-no-icon/sidenav-basic-no-icon.ts +12 -0
- package/.ai/docs/demos/sidenav/sidenav-basic-with-icon/routes.ts +41 -0
- package/.ai/docs/demos/sidenav/sidenav-basic-with-icon/sidenav-basic-with-icon.html +34 -0
- package/.ai/docs/demos/sidenav/sidenav-basic-with-icon/sidenav-basic-with-icon.ts +12 -0
- package/.ai/docs/demos/tooltip/basic/tooltip-basic.html +1 -0
- package/.ai/docs/demos/tooltip/basic/tooltip-basic.ts +10 -0
- package/.ai/docs/demos/tooltip/placements/tooltip-placements.html +35 -0
- package/.ai/docs/demos/tooltip/placements/tooltip-placements.ts +12 -0
- package/.ai/docs/demos/tooltip/sizes/tooltip-sizes.html +5 -0
- package/.ai/docs/demos/tooltip/sizes/tooltip-sizes.ts +10 -0
- package/.ai/docs/demos/topnav/brand/topnav-brand.ts +64 -0
- package/.ai/docs/demos/topnav/environment-banner/topnav-environment-banner.ts +20 -0
- package/.ai/docs/demos/topnav/navigation/routes.ts +35 -0
- package/.ai/docs/demos/topnav/navigation/topnav-navigation-flat.ts +67 -0
- package/.ai/docs/demos/topnav/navigation/topnav-navigation-tree.ts +82 -0
- package/.ai/docs/demos/topnav/quick-actions/notifications.ts +75 -0
- package/.ai/docs/demos/topnav/quick-actions/topnav-quick-actions.ts +108 -0
- package/.ai/docs/demos/topnav/quick-actions/user-account.ts +23 -0
- package/.ai/index.md +26 -0
- package/fesm2022/design-factory-angular-accordion.mjs +1153 -0
- package/fesm2022/design-factory-angular-accordion.mjs.map +1 -0
- package/fesm2022/design-factory-angular-alert.mjs +312 -0
- package/fesm2022/design-factory-angular-alert.mjs.map +1 -0
- package/fesm2022/design-factory-angular-breakpoints.mjs +53 -0
- package/fesm2022/design-factory-angular-breakpoints.mjs.map +1 -0
- package/fesm2022/design-factory-angular-button.mjs +240 -0
- package/fesm2022/design-factory-angular-button.mjs.map +1 -0
- package/fesm2022/design-factory-angular-buttongroup.mjs +75 -0
- package/fesm2022/design-factory-angular-buttongroup.mjs.map +1 -0
- package/fesm2022/design-factory-angular-drawer.mjs +64 -62
- package/fesm2022/design-factory-angular-drawer.mjs.map +1 -1
- package/fesm2022/design-factory-angular-dropdown.mjs +323 -0
- package/fesm2022/design-factory-angular-dropdown.mjs.map +1 -0
- package/fesm2022/design-factory-angular-form-field.mjs +287 -0
- package/fesm2022/design-factory-angular-form-field.mjs.map +1 -0
- package/fesm2022/design-factory-angular-icon.mjs +24 -0
- package/fesm2022/design-factory-angular-icon.mjs.map +1 -0
- package/fesm2022/design-factory-angular-input.mjs +34 -0
- package/fesm2022/design-factory-angular-input.mjs.map +1 -0
- package/fesm2022/design-factory-angular-internals.mjs +119 -39
- package/fesm2022/design-factory-angular-internals.mjs.map +1 -1
- package/fesm2022/design-factory-angular-separator.mjs +43 -0
- package/fesm2022/design-factory-angular-separator.mjs.map +1 -0
- package/fesm2022/design-factory-angular-sidenav.mjs +652 -401
- package/fesm2022/design-factory-angular-sidenav.mjs.map +1 -1
- package/fesm2022/design-factory-angular-slider.mjs +451 -0
- package/fesm2022/design-factory-angular-slider.mjs.map +1 -0
- package/fesm2022/design-factory-angular-theme.mjs +29 -19
- package/fesm2022/design-factory-angular-theme.mjs.map +1 -1
- package/fesm2022/design-factory-angular-toggle.mjs +172 -0
- package/fesm2022/design-factory-angular-toggle.mjs.map +1 -0
- package/fesm2022/design-factory-angular-tooltip.mjs +138 -0
- package/fesm2022/design-factory-angular-tooltip.mjs.map +1 -0
- package/fesm2022/design-factory-angular-topnav.mjs +589 -589
- package/fesm2022/design-factory-angular-topnav.mjs.map +1 -1
- package/package.json +61 -8
- package/schematics/collection.json +35 -0
- package/schematics/component-migration/accordion/constants.d.ts +10 -0
- package/schematics/component-migration/accordion/constants.js +46 -0
- package/schematics/component-migration/accordion/guide.md +257 -0
- package/schematics/component-migration/accordion/index.d.ts +2 -0
- package/schematics/component-migration/accordion/index.js +5 -0
- package/schematics/component-migration/accordion/migration.d.ts +2 -0
- package/schematics/component-migration/accordion/migration.js +13 -0
- package/schematics/component-migration/accordion/schema.json +25 -0
- package/schematics/component-migration/accordion/steps/accordion-imports.d.ts +3 -0
- package/schematics/component-migration/accordion/steps/accordion-imports.js +41 -0
- package/schematics/component-migration/accordion/steps/template-migration.d.ts +3 -0
- package/schematics/component-migration/accordion/steps/template-migration.js +554 -0
- package/schematics/component-migration/accordion/steps/title-content.d.ts +9 -0
- package/schematics/component-migration/accordion/steps/title-content.js +75 -0
- package/schematics/component-migration/ai/prompt.md +83 -0
- package/schematics/component-migration/alert/guide.md +246 -0
- package/schematics/component-migration/alert/index.d.ts +2 -0
- package/schematics/component-migration/alert/index.js +5 -0
- package/schematics/component-migration/alert/migration.d.ts +2 -0
- package/schematics/component-migration/alert/migration.js +50 -0
- package/schematics/component-migration/alert/schema.json +25 -0
- package/schematics/component-migration/alert/steps/alert-imports.d.ts +4 -0
- package/schematics/component-migration/alert/steps/alert-imports.js +97 -0
- package/schematics/component-migration/alert/steps/animation-input.d.ts +3 -0
- package/schematics/component-migration/alert/steps/animation-input.js +17 -0
- package/schematics/component-migration/alert/steps/close-output.d.ts +3 -0
- package/schematics/component-migration/alert/steps/close-output.js +17 -0
- package/schematics/component-migration/alert/steps/icon-directive-imports.d.ts +3 -0
- package/schematics/component-migration/alert/steps/icon-directive-imports.js +84 -0
- package/schematics/component-migration/alert/steps/icon-directive.d.ts +3 -0
- package/schematics/component-migration/alert/steps/icon-directive.js +10 -0
- package/schematics/component-migration/alert/steps/legacy-module-imports.d.ts +3 -0
- package/schematics/component-migration/alert/steps/legacy-module-imports.js +57 -0
- package/schematics/component-migration/alert/steps/programmatic-close.d.ts +3 -0
- package/schematics/component-migration/alert/steps/programmatic-close.js +44 -0
- package/schematics/component-migration/alert/steps/selector.d.ts +3 -0
- package/schematics/component-migration/alert/steps/selector.js +18 -0
- package/schematics/component-migration/alert/steps/static-classes.d.ts +3 -0
- package/schematics/component-migration/alert/steps/static-classes.js +97 -0
- package/schematics/component-migration/alert/steps/static-type.d.ts +3 -0
- package/schematics/component-migration/alert/steps/static-type.js +28 -0
- package/schematics/component-migration/alert/steps/template-reference.d.ts +3 -0
- package/schematics/component-migration/alert/steps/template-reference.js +15 -0
- package/schematics/component-migration/alert/steps/template-todos.d.ts +3 -0
- package/schematics/component-migration/alert/steps/template-todos.js +78 -0
- package/schematics/component-migration/button/guide.md +278 -0
- package/schematics/component-migration/button/index.d.ts +2 -0
- package/schematics/component-migration/button/index.js +5 -0
- package/schematics/component-migration/button/migration.d.ts +2 -0
- package/schematics/component-migration/button/migration.js +180 -0
- package/schematics/component-migration/button/schema.json +25 -0
- package/schematics/component-migration/button/steps/static-classes.d.ts +10 -0
- package/schematics/component-migration/button/steps/static-classes.js +128 -0
- package/schematics/component-migration/button/steps/template-todos.d.ts +19 -0
- package/schematics/component-migration/button/steps/template-todos.js +120 -0
- package/schematics/component-migration/button/types.d.ts +7 -0
- package/schematics/component-migration/button/types.js +2 -0
- package/schematics/component-migration/dropdown/guide.md +252 -0
- package/schematics/component-migration/dropdown/index.d.ts +2 -0
- package/schematics/component-migration/dropdown/index.js +5 -0
- package/schematics/component-migration/dropdown/migration.d.ts +2 -0
- package/schematics/component-migration/dropdown/migration.js +41 -0
- package/schematics/component-migration/dropdown/schema.json +25 -0
- package/schematics/component-migration/dropdown/steps/dropdown-imports.d.ts +3 -0
- package/schematics/component-migration/dropdown/steps/dropdown-imports.js +308 -0
- package/schematics/component-migration/dropdown/steps/template-attributes.d.ts +10 -0
- package/schematics/component-migration/dropdown/steps/template-attributes.js +57 -0
- package/schematics/component-migration/dropdown/steps/template-helpers.d.ts +20 -0
- package/schematics/component-migration/dropdown/steps/template-helpers.js +125 -0
- package/schematics/component-migration/dropdown/steps/template-imports.d.ts +22 -0
- package/schematics/component-migration/dropdown/steps/template-imports.js +12 -0
- package/schematics/component-migration/dropdown/steps/template-items.d.ts +7 -0
- package/schematics/component-migration/dropdown/steps/template-items.js +58 -0
- package/schematics/component-migration/dropdown/steps/template-menu.d.ts +14 -0
- package/schematics/component-migration/dropdown/steps/template-menu.js +107 -0
- package/schematics/component-migration/dropdown/steps/template-todos.d.ts +19 -0
- package/schematics/component-migration/dropdown/steps/template-todos.js +118 -0
- package/schematics/component-migration/dropdown/steps/template-toggle.d.ts +9 -0
- package/schematics/component-migration/dropdown/steps/template-toggle.js +70 -0
- package/schematics/component-migration/dropdown/steps/template-wrapper.d.ts +12 -0
- package/schematics/component-migration/dropdown/steps/template-wrapper.js +105 -0
- package/schematics/component-migration/index.d.ts +3 -0
- package/schematics/component-migration/index.js +26 -0
- package/schematics/component-migration/next-steps/index.d.ts +13 -0
- package/schematics/component-migration/next-steps/index.js +34 -0
- package/schematics/component-migration/registry.d.ts +1 -0
- package/schematics/component-migration/registry.js +15 -0
- package/schematics/component-migration/schema.json +20 -0
- package/schematics/component-migration/shared/ai-handoff.d.ts +2 -0
- package/schematics/component-migration/shared/ai-handoff.js +28 -0
- package/schematics/component-migration/shared/angular-component.d.ts +10 -0
- package/schematics/component-migration/shared/angular-component.js +125 -0
- package/schematics/component-migration/shared/button-visual-classes.d.ts +24 -0
- package/schematics/component-migration/shared/button-visual-classes.js +111 -0
- package/schematics/component-migration/shared/component-context.d.ts +7 -0
- package/schematics/component-migration/shared/component-context.js +24 -0
- package/schematics/component-migration/shared/component-imports.d.ts +45 -0
- package/schematics/component-migration/shared/component-imports.js +380 -0
- package/schematics/component-migration/shared/create-component-schematic.d.ts +3 -0
- package/schematics/component-migration/shared/create-component-schematic.js +55 -0
- package/schematics/component-migration/shared/import-edits.d.ts +11 -0
- package/schematics/component-migration/shared/import-edits.js +157 -0
- package/schematics/component-migration/shared/legacy-config-todos.d.ts +3 -0
- package/schematics/component-migration/shared/legacy-config-todos.js +90 -0
- package/schematics/component-migration/shared/migrate-project.d.ts +12 -0
- package/schematics/component-migration/shared/migrate-project.js +151 -0
- package/schematics/component-migration/shared/project-templates.d.ts +15 -0
- package/schematics/component-migration/shared/project-templates.js +43 -0
- package/schematics/component-migration/shared/scan-project.d.ts +3 -0
- package/schematics/component-migration/shared/scan-project.js +24 -0
- package/schematics/component-migration/shared/static-placement.d.ts +1 -0
- package/schematics/component-migration/shared/static-placement.js +45 -0
- package/schematics/component-migration/shared/template-edits.d.ts +28 -0
- package/schematics/component-migration/shared/template-edits.js +153 -0
- package/schematics/component-migration/shared/template-result.d.ts +3 -0
- package/schematics/component-migration/shared/template-result.js +11 -0
- package/schematics/component-migration/shared/testing.d.ts +13 -0
- package/schematics/component-migration/shared/testing.js +59 -0
- package/schematics/component-migration/shared/todo-comments.d.ts +10 -0
- package/schematics/component-migration/shared/todo-comments.js +81 -0
- package/schematics/component-migration/shared/types.d.ts +41 -0
- package/schematics/component-migration/shared/types.js +2 -0
- package/schematics/component-migration/tooltip/guide.md +196 -0
- package/schematics/component-migration/tooltip/index.d.ts +2 -0
- package/schematics/component-migration/tooltip/index.js +5 -0
- package/schematics/component-migration/tooltip/migration.d.ts +2 -0
- package/schematics/component-migration/tooltip/migration.js +50 -0
- package/schematics/component-migration/tooltip/schema.json +25 -0
- package/schematics/component-migration/tooltip/steps/template-attributes.d.ts +13 -0
- package/schematics/component-migration/tooltip/steps/template-attributes.js +266 -0
- package/schematics/component-migration/tooltip/steps/template-todos.d.ts +24 -0
- package/schematics/component-migration/tooltip/steps/template-todos.js +115 -0
- package/schematics/component-migration/tooltip/steps/tooltip-imports.d.ts +3 -0
- package/schematics/component-migration/tooltip/steps/tooltip-imports.js +79 -0
- package/schematics/component-migration/utils/component-resource-collector.d.ts +34 -0
- package/schematics/component-migration/utils/component-resource-collector.js +107 -0
- package/schematics/component-migration/utils/project_tsconfig_paths.d.ts +18 -0
- package/schematics/component-migration/utils/project_tsconfig_paths.js +105 -0
- package/schematics/component-migration/utils/typescript/compiler_host.d.ts +44 -0
- package/schematics/component-migration/utils/typescript/compiler_host.js +87 -0
- package/schematics/component-migration/utils/typescript/decorators.d.ts +22 -0
- package/schematics/component-migration/utils/typescript/decorators.js +41 -0
- package/schematics/component-migration/utils/typescript/functions.d.ts +14 -0
- package/schematics/component-migration/utils/typescript/functions.js +20 -0
- package/schematics/component-migration/utils/typescript/imports.d.ts +17 -0
- package/schematics/component-migration/utils/typescript/imports.js +110 -0
- package/schematics/component-migration/utils/typescript/parse_tsconfig.d.ts +9 -0
- package/schematics/component-migration/utils/typescript/parse_tsconfig.js +29 -0
- package/schematics/component-migration/utils/typescript/property-name.d.ts +13 -0
- package/schematics/component-migration/utils/typescript/property-name.js +22 -0
- package/schematics/package.json +3 -0
- package/types/design-factory-angular-accordion.d.ts +553 -0
- package/types/design-factory-angular-alert.d.ts +166 -0
- package/types/design-factory-angular-breakpoints.d.ts +13 -0
- package/types/design-factory-angular-button.d.ts +166 -0
- package/types/design-factory-angular-buttongroup.d.ts +45 -0
- package/types/design-factory-angular-drawer.d.ts +10 -16
- package/types/design-factory-angular-dropdown.d.ts +148 -0
- package/types/design-factory-angular-form-field.d.ts +122 -0
- package/types/design-factory-angular-icon.d.ts +11 -0
- package/types/design-factory-angular-input.d.ts +16 -0
- package/types/design-factory-angular-internals.d.ts +78 -19
- package/types/design-factory-angular-separator.d.ts +29 -0
- package/types/design-factory-angular-sidenav.d.ts +98 -14
- package/types/design-factory-angular-slider.d.ts +239 -0
- package/types/design-factory-angular-toggle.d.ts +93 -0
- package/types/design-factory-angular-tooltip.d.ts +113 -0
- package/types/design-factory-angular-topnav.d.ts +35 -47
- package/drawer/README.md +0 -54
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# Dropdown Migration Guide
|
|
2
|
+
|
|
3
|
+
This guide is used by AI-assisted migration after the deterministic `migrate-dropdown` schematic has run.
|
|
4
|
+
|
|
5
|
+
Use it together with the user's current working tree and current git diff. The diff shows which safe changes were made
|
|
6
|
+
by the schematic and which `TODO(df-migration ...)` comments still need review.
|
|
7
|
+
|
|
8
|
+
## Legacy API
|
|
9
|
+
|
|
10
|
+
Legacy dropdowns are based on `NgbDropdown` / `NgbDropdownModule` from `@ng-bootstrap/ng-bootstrap/dropdown` or
|
|
11
|
+
`@ng-bootstrap/ng-bootstrap`.
|
|
12
|
+
|
|
13
|
+
Common legacy template pieces:
|
|
14
|
+
|
|
15
|
+
- `ngbDropdown`
|
|
16
|
+
- `ngbDropdownToggle`
|
|
17
|
+
- `ngbDropdownAnchor`
|
|
18
|
+
- `ngbDropdownMenu`
|
|
19
|
+
- `ngbDropdownItem`
|
|
20
|
+
- `NgbDropdownButtonItem` in standalone imports
|
|
21
|
+
- `placement`
|
|
22
|
+
- `open`
|
|
23
|
+
- `openChange`
|
|
24
|
+
- `autoClose`
|
|
25
|
+
- `container`
|
|
26
|
+
- `display`
|
|
27
|
+
- `dropdownClass`
|
|
28
|
+
- `popperOptions`
|
|
29
|
+
- `#dropdown="ngbDropdown"`
|
|
30
|
+
|
|
31
|
+
## New API
|
|
32
|
+
|
|
33
|
+
New dropdowns use standalone imports from `@design-factory/angular/dropdown` and, when separators are present,
|
|
34
|
+
`DfSeparator` from `@design-factory/angular/separator`.
|
|
35
|
+
|
|
36
|
+
Common template form:
|
|
37
|
+
|
|
38
|
+
```html
|
|
39
|
+
<button [dfDropdownToggle]="menu" appearance="outline">Actions</button>
|
|
40
|
+
<df-dropdown #menu placement="bottom-start bottom-end top-start top-end">
|
|
41
|
+
<button dfDropdownItem>Action</button>
|
|
42
|
+
<a dfDropdownItem href="/details">Details</a>
|
|
43
|
+
<df-separator />
|
|
44
|
+
</df-dropdown>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Deterministic Schematic Changes
|
|
48
|
+
|
|
49
|
+
The schematic handles these changes when syntax is local and unambiguous:
|
|
50
|
+
|
|
51
|
+
- wrappers with one `ngbDropdownToggle`, one `ngbDropdownMenu`, and no anchor, split, nested-dropdown, or datepicker
|
|
52
|
+
menu pattern
|
|
53
|
+
- `ngbDropdownToggle` -> `[dfDropdownToggle]="menuRef"`
|
|
54
|
+
- `ngbDropdownMenu` host element -> `<df-dropdown #menuRef>`
|
|
55
|
+
- `ngbDropdownItem` -> `dfDropdownItem` on `button` and `a` hosts
|
|
56
|
+
- static `dropdown-item` class removal on migrated items
|
|
57
|
+
- static `active` item class -> `active`
|
|
58
|
+
- `[class.active]` -> `[active]`
|
|
59
|
+
- simple `<hr class="dropdown-divider">` -> `<df-separator />`
|
|
60
|
+
- `placement` moved from wrapper to `df-dropdown`, with legacy `left` / `right` mapped to `start` / `end`
|
|
61
|
+
- legacy corner placement names such as `bottom-right` -> `bottom-end`
|
|
62
|
+
- static `auto` placements are preserved, for example `bottom-right auto` -> `bottom-end auto`
|
|
63
|
+
- `container` moved from wrapper to `df-dropdown`
|
|
64
|
+
- `[open]` -> `[opened]`
|
|
65
|
+
- `(openChange)` -> `(openedChange)`
|
|
66
|
+
- static dropdown menu size classes -> `size="sm"` / `size="lg"`
|
|
67
|
+
- `#dropdown="ngbDropdown"` template references moved to `<df-dropdown #dropdown>` when the dropdown is otherwise
|
|
68
|
+
migratable
|
|
69
|
+
- supported legacy toggle button visual classes -> dropdown toggle visual inputs
|
|
70
|
+
- pre-existing `dfButton` attributes removed from migrated dropdown toggles, while existing visual inputs such as
|
|
71
|
+
`appearance`, `variant`, and `size` are preserved
|
|
72
|
+
- standalone `DfDropdown`, `DfDropdownToggle`, `DfDropdownItemButton`, `DfDropdownItemLink`, and `DfSeparator` imports
|
|
73
|
+
where needed
|
|
74
|
+
- direct standalone `NgbDropdown*` imports, including `NgbDropdownButtonItem`, removed when no legacy dropdown template
|
|
75
|
+
remains in the component scope
|
|
76
|
+
- TODO comments for dynamic toggle button class logic
|
|
77
|
+
- TODO comments for cases that need review or AI/manual migration
|
|
78
|
+
|
|
79
|
+
Do not repeat these changes unless the schematic missed a local occurrence.
|
|
80
|
+
|
|
81
|
+
The schematic keeps the old wrapper element as a plain layout container. This preserves layout utility classes such as
|
|
82
|
+
`d-inline-block`, spacing, and width classes.
|
|
83
|
+
|
|
84
|
+
During AI-assisted cleanup, remove that wrapper only when it is empty or trivial and the DOM change is clearly harmless.
|
|
85
|
+
Keep it when it carries layout classes, ids, QA attributes, structural context, component CSS hooks, or anything whose
|
|
86
|
+
placement on the toggle button would not be equivalent.
|
|
87
|
+
|
|
88
|
+
## TODO Codes
|
|
89
|
+
|
|
90
|
+
TODO comments may include `[human]`.
|
|
91
|
+
|
|
92
|
+
Verify every TODO and remove it only when the underlying issue is actually resolved. Preserve `[human]` TODO comments
|
|
93
|
+
unchanged so a human can review them after the AI-assisted pass. `[human]` does not forbid AI-assisted edits around the
|
|
94
|
+
comment when the intent is clear; it means the final result must remain visible for human verification.
|
|
95
|
+
|
|
96
|
+
### `dropdown.review`
|
|
97
|
+
|
|
98
|
+
The dropdown was migrated automatically. Verify behavior and visual appearance.
|
|
99
|
+
|
|
100
|
+
Keep or remove this TODO based on review. If no behavior issue is found, remove it.
|
|
101
|
+
|
|
102
|
+
### `dropdown.structure`
|
|
103
|
+
|
|
104
|
+
The dropdown was left in legacy markup because it is not a supported one-toggle/one-menu pattern.
|
|
105
|
+
Adjacent TODOs usually name the unsupported feature, such as anchor, split button, datepicker, or programmatic API. When
|
|
106
|
+
there is no more specific adjacent TODO, inspect for missing toggles, missing menus, multiple toggles or menus, nested
|
|
107
|
+
dropdowns, or empty menu content.
|
|
108
|
+
|
|
109
|
+
Rebuild the dropdown using `[dfDropdownToggle]` and `<df-dropdown>` only when the behavior is clear. Keep the `[human]`
|
|
110
|
+
TODO after the conversion so the structure can be reviewed.
|
|
111
|
+
|
|
112
|
+
### `dropdown.dynamic-toggle-class`
|
|
113
|
+
|
|
114
|
+
Dynamic dropdown toggle classes were detected on a legacy-looking toggle.
|
|
115
|
+
|
|
116
|
+
This TODO is emitted only when the toggle has explicit dynamic legacy button class bindings, or when a generic `class`
|
|
117
|
+
or `ngClass` expression appears on a toggle that also has exact static `btn` evidence. It is not emitted for unrelated
|
|
118
|
+
class bindings such as spacing, icon, state, or layout classes.
|
|
119
|
+
|
|
120
|
+
Inspect `[class]`, `[ngClass]`, and class binding expressions. Convert legacy button styling to dropdown toggle inputs
|
|
121
|
+
only when the expression is clear:
|
|
122
|
+
|
|
123
|
+
- `[class.btn-lg]="large"` -> `[size]="large ? 'lg' : 'md'"`
|
|
124
|
+
- `[class.btn-sm]="small"` -> `[size]="small ? 'sm' : 'md'"`
|
|
125
|
+
- `[class.df-btn-tertiary]="text"` -> `[appearance]="text ? 'text' : defaultAppearance"` where `defaultAppearance`
|
|
126
|
+
preserves the existing static style, such as `solid` or `outline`
|
|
127
|
+
- `[class.df-btn-transparent]="transparent"` -> `[transparent]="transparent"`
|
|
128
|
+
- `[class.df-btn-primary-mirror]="mirror"` -> `[mirror]="mirror"` and keep/default `variant="primary"`
|
|
129
|
+
|
|
130
|
+
When multiple dynamic legacy classes can conflict, prefer a small TypeScript helper that returns a typed value for
|
|
131
|
+
`variant`, `appearance`, or `size`.
|
|
132
|
+
|
|
133
|
+
### `dropdown.auto-close`
|
|
134
|
+
|
|
135
|
+
Legacy `autoClose` behavior was not migrated.
|
|
136
|
+
|
|
137
|
+
The new dropdown has fixed outside-click dismissal behavior. Verify whether the old `inside`, `outside`, `false`, or
|
|
138
|
+
dynamic value still matters. Keep the `[human]` TODO for review after any related cleanup.
|
|
139
|
+
|
|
140
|
+
### `dropdown.anchor`
|
|
141
|
+
|
|
142
|
+
`ngbDropdownAnchor` is not supported by the new dropdown API.
|
|
143
|
+
|
|
144
|
+
Rebuild the anchor/toggle relationship only when the behavior is clear, using a supported toggle or another overlay
|
|
145
|
+
component. The new API expects a button with `[dfDropdownToggle]="menu"`. Keep the `[human]` TODO after any conversion.
|
|
146
|
+
|
|
147
|
+
### `dropdown.split`
|
|
148
|
+
|
|
149
|
+
Split dropdown button structure was not migrated.
|
|
150
|
+
|
|
151
|
+
Rebuild the split button using the current dropdown/button API only when behavior is clear. Verify keyboard and
|
|
152
|
+
accessible-name behavior, and keep the `[human]` TODO after any conversion.
|
|
153
|
+
|
|
154
|
+
### `dropdown.datepicker`
|
|
155
|
+
|
|
156
|
+
The dropdown menu contains an ng-bootstrap datepicker, which is not supported by the new dropdown API.
|
|
157
|
+
|
|
158
|
+
Rebuild it with a datepicker component or another dedicated overlay. Legacy datepicker dropdowns often use custom
|
|
159
|
+
anchoring, refs, open/close calls, and focus handling that should not be migrated as a regular menu. Keep the `[human]`
|
|
160
|
+
TODO after any conversion.
|
|
161
|
+
|
|
162
|
+
### `dropdown.rich-menu`
|
|
163
|
+
|
|
164
|
+
The dropdown menu contains non-item content such as forms, filters, or arbitrary layout.
|
|
165
|
+
|
|
166
|
+
This pattern is not supported by the new dropdown API and will not be supported in future versions. Rebuild the content
|
|
167
|
+
with supported dropdown items, or use another overlay component such as a popover or dialog. Keep the `[human]` TODO for
|
|
168
|
+
review after any conversion.
|
|
169
|
+
|
|
170
|
+
### `dropdown.custom-positioning`
|
|
171
|
+
|
|
172
|
+
Legacy positioning configuration was not fully migrated.
|
|
173
|
+
|
|
174
|
+
Review `display`, `popperOptions`, `dropdownClass`, and dynamic `placement` values. Keep intentional `auto`
|
|
175
|
+
placements. `container` is migrated to `df-dropdown`. Convert old `left` / `right` values to `start` / `end` when
|
|
176
|
+
they still exist in expressions. Keep the `[human]` TODO for review after any related cleanup.
|
|
177
|
+
|
|
178
|
+
### `dropdown.custom-menu-classes`
|
|
179
|
+
|
|
180
|
+
The legacy menu had custom classes.
|
|
181
|
+
|
|
182
|
+
The new menu content is rendered in an overlay window, so classes left on `<df-dropdown>` may not style the rendered
|
|
183
|
+
overlay. Replace the styling with supported inputs or updated CSS only when the styling intent is clear. Keep the
|
|
184
|
+
`[human]` TODO for review after any related cleanup.
|
|
185
|
+
|
|
186
|
+
### `dropdown.unsupported-item-host`
|
|
187
|
+
|
|
188
|
+
`ngbDropdownItem` was used on a host other than `button` or `a`.
|
|
189
|
+
|
|
190
|
+
Convert the item to a supported host only when semantics are clear, or rebuild the content if it is not a menu item.
|
|
191
|
+
Keep the `[human]` TODO after any conversion.
|
|
192
|
+
|
|
193
|
+
### `dropdown.icon-only-accessible-name`
|
|
194
|
+
|
|
195
|
+
An icon-only dropdown toggle needs an accessible name.
|
|
196
|
+
|
|
197
|
+
Add `aria-label`, `aria-labelledby`, or the project-standard equivalent after verifying the visible context. Keep the
|
|
198
|
+
`[human]` TODO after any conversion.
|
|
199
|
+
|
|
200
|
+
### `dropdown.btn-link-toggle`
|
|
201
|
+
|
|
202
|
+
The legacy toggle used `btn-link`.
|
|
203
|
+
|
|
204
|
+
There is no deterministic dropdown visual equivalent. Verify and choose the intended button appearance only when the
|
|
205
|
+
intent is clear. Keep the `[human]` TODO after any conversion.
|
|
206
|
+
|
|
207
|
+
### `dropdown.programmatic-api`
|
|
208
|
+
|
|
209
|
+
Programmatic `NgbDropdown` API usage was not migrated.
|
|
210
|
+
|
|
211
|
+
The schematic preserves simple template-reference names by moving `#dropdown="ngbDropdown"` to `<df-dropdown
|
|
212
|
+
#dropdown>` when the dropdown is otherwise migratable. Calls to `open()`, `close()`, `toggle()`, and `isOpen()` are
|
|
213
|
+
available on the new component, but TypeScript queries and imports are not equivalent.
|
|
214
|
+
|
|
215
|
+
Replace `ViewChild(NgbDropdown)`, `ViewChildren(NgbDropdown)`, typed `NgbDropdown` parameters, and any private legacy
|
|
216
|
+
usage such as `_nativeElement` with the new API manually. Keep the `[human]` TODO after any conversion.
|
|
217
|
+
|
|
218
|
+
### `dropdown.legacy-import`
|
|
219
|
+
|
|
220
|
+
A legacy dropdown import remains after deterministic migration.
|
|
221
|
+
|
|
222
|
+
Legacy modules such as `NgbDropdownModule` are intentionally kept for second-pass verification. Remove legacy imports
|
|
223
|
+
only after no legacy dropdown APIs remain.
|
|
224
|
+
|
|
225
|
+
### `dropdown.indirect-component-imports`
|
|
226
|
+
|
|
227
|
+
The component needs new DF dropdown imports, but its Angular `imports` metadata is not a simple array literal.
|
|
228
|
+
|
|
229
|
+
Inspect the referenced value or expression. Add the required standalone imports to the actual imports list only when the
|
|
230
|
+
shape is clear.
|
|
231
|
+
|
|
232
|
+
## Configuration Migration
|
|
233
|
+
|
|
234
|
+
Legacy `NgbDropdownConfig` is not supported anymore and is marked with `TODO(df-migration dropdown.config)` for human
|
|
235
|
+
review.
|
|
236
|
+
|
|
237
|
+
Do not migrate it automatically. `DfDropdown` currently has no `provideDfDropdownConfig()` equivalent, so review legacy
|
|
238
|
+
defaults manually and decide whether they should become local dropdown inputs or application-specific cleanup.
|
|
239
|
+
|
|
240
|
+
## Validation
|
|
241
|
+
|
|
242
|
+
After AI-assisted dropdown migration:
|
|
243
|
+
|
|
244
|
+
1. Confirm no unexpected `ngbDropdown`, `ngbDropdownToggle`, `ngbDropdownMenu`, `ngbDropdownItem`, `NgbDropdown`,
|
|
245
|
+
`NgbDropdownButtonItem`, or `NgbDropdownModule` usages remain in app code.
|
|
246
|
+
2. Confirm every migrated toggle points to the intended `df-dropdown` reference.
|
|
247
|
+
3. Confirm dynamic `placement` values use supported new placements and preserve intentional `auto` values.
|
|
248
|
+
4. Verify dynamic toggle button class logic.
|
|
249
|
+
5. Verify icon-only and split-button accessible names.
|
|
250
|
+
6. Run the narrowest useful typecheck/build command for touched projects when the command is clear.
|
|
251
|
+
7. Run visual or e2e checks for menus with custom classes, rich content, custom positioning, or programmatic control.
|
|
252
|
+
8. Ask the user before running broad or expensive validation commands if the right command is unclear.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const create_component_schematic_1 = require("../shared/create-component-schematic");
|
|
4
|
+
const migration_1 = require("./migration");
|
|
5
|
+
exports.default = (0, create_component_schematic_1.createComponentMigrationSchematic)(migration_1.dropdownMigration);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dropdownMigration = void 0;
|
|
4
|
+
const template_result_1 = require("../shared/template-result");
|
|
5
|
+
const template_edits_1 = require("../shared/template-edits");
|
|
6
|
+
const template_attributes_1 = require("./steps/template-attributes");
|
|
7
|
+
const dropdown_imports_1 = require("./steps/dropdown-imports");
|
|
8
|
+
const legacy_config_todos_1 = require("../shared/legacy-config-todos");
|
|
9
|
+
function getDropdownElements(template) {
|
|
10
|
+
return (0, template_edits_1.findTemplateElements)(template, template_attributes_1.countDropdownWrapperUsage);
|
|
11
|
+
}
|
|
12
|
+
function getTemplateReferenceNames(template) {
|
|
13
|
+
const names = new Set();
|
|
14
|
+
const templateRefPattern = /#([A-Za-z_$][\w$-]*)/g;
|
|
15
|
+
let match = templateRefPattern.exec(template);
|
|
16
|
+
while (match) {
|
|
17
|
+
names.add(match[1]);
|
|
18
|
+
match = templateRefPattern.exec(template);
|
|
19
|
+
}
|
|
20
|
+
return names;
|
|
21
|
+
}
|
|
22
|
+
function migrateDropdownTemplate(template) {
|
|
23
|
+
const edits = [];
|
|
24
|
+
const standaloneImports = [];
|
|
25
|
+
const usedReferenceNames = getTemplateReferenceNames(template);
|
|
26
|
+
for (const element of getDropdownElements(template)) {
|
|
27
|
+
const result = (0, template_attributes_1.editDropdownWrapper)(element, { usedReferenceNames }, edits);
|
|
28
|
+
standaloneImports.push(...result.standaloneImports);
|
|
29
|
+
}
|
|
30
|
+
return (0, template_result_1.createTemplateMigrationResult)(template, edits, standaloneImports);
|
|
31
|
+
}
|
|
32
|
+
function migrateDropdownSourceFile(context) {
|
|
33
|
+
return (0, dropdown_imports_1.editDropdownImports)(context);
|
|
34
|
+
}
|
|
35
|
+
exports.dropdownMigration = {
|
|
36
|
+
id: 'dropdown',
|
|
37
|
+
countLegacyTemplateUsages: (template) => getDropdownElements(template).length,
|
|
38
|
+
migrateTemplate: migrateDropdownTemplate,
|
|
39
|
+
migrateSourceFile: migrateDropdownSourceFile,
|
|
40
|
+
migrateProjectSourceFile: (context) => (0, legacy_config_todos_1.editLegacyConfigTodos)(context, ['NgbDropdownConfig'])
|
|
41
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"$id": "SchematicsMigrateDropdown",
|
|
4
|
+
"title": "Migrate Dropdown Schema",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"project": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "Name of the Angular project to scan or migrate",
|
|
10
|
+
"$default": {
|
|
11
|
+
"$source": "projectName"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"all": {
|
|
15
|
+
"type": "boolean",
|
|
16
|
+
"description": "Scan or migrate every buildable Angular project",
|
|
17
|
+
"default": false
|
|
18
|
+
},
|
|
19
|
+
"scan": {
|
|
20
|
+
"type": "boolean",
|
|
21
|
+
"description": "Only scan dropdown usages without applying the migration",
|
|
22
|
+
"default": false
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.editDropdownImports = editDropdownImports;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const ts = tslib_1.__importStar(require("typescript"));
|
|
6
|
+
const angular_component_1 = require("../../shared/angular-component");
|
|
7
|
+
const component_imports_1 = require("../../shared/component-imports");
|
|
8
|
+
const component_context_1 = require("../../shared/component-context");
|
|
9
|
+
const import_edits_1 = require("../../shared/import-edits");
|
|
10
|
+
const todo_comments_1 = require("../../shared/todo-comments");
|
|
11
|
+
const template_imports_1 = require("./template-imports");
|
|
12
|
+
const LEGACY_DROPDOWN_IMPORTS = new Set(['@ng-bootstrap/ng-bootstrap/dropdown', '@ng-bootstrap/ng-bootstrap']);
|
|
13
|
+
const NGB_DROPDOWN = 'NgbDropdown';
|
|
14
|
+
const DF_DROPDOWN = 'DfDropdown';
|
|
15
|
+
const LEGACY_DIRECTIVE_SCOPE_SYMBOLS = new Set([
|
|
16
|
+
NGB_DROPDOWN,
|
|
17
|
+
'NgbDropdownAnchor',
|
|
18
|
+
'NgbDropdownButtonItem',
|
|
19
|
+
'NgbDropdownItem',
|
|
20
|
+
'NgbDropdownMenu',
|
|
21
|
+
'NgbDropdownToggle'
|
|
22
|
+
]);
|
|
23
|
+
const LEGACY_MODULE_SCOPE_SYMBOLS = new Set(['NgbDropdownModule']);
|
|
24
|
+
const LEGACY_IMPORT_SYMBOLS = new Set([
|
|
25
|
+
...LEGACY_DIRECTIVE_SCOPE_SYMBOLS,
|
|
26
|
+
...LEGACY_MODULE_SCOPE_SYMBOLS,
|
|
27
|
+
'NgbDropdownConfig'
|
|
28
|
+
]);
|
|
29
|
+
function componentUsesLegacyDropdown(templates) {
|
|
30
|
+
return templates.some((template) => /(^|[\s<])(?:\[)?ngbDropdown(?:\]|=|\s|>)/.test(template.replace(/<!--[\s\S]*?-->/g, '')));
|
|
31
|
+
}
|
|
32
|
+
function componentUsesDfDropdown(templates) {
|
|
33
|
+
return templates.some((template) => template.includes('<df-dropdown') || template.includes('</df-dropdown>'));
|
|
34
|
+
}
|
|
35
|
+
function getLegacyDropdownImports(sourceFile) {
|
|
36
|
+
return (0, component_imports_1.getComponentNamedImports)(sourceFile, LEGACY_DROPDOWN_IMPORTS, LEGACY_IMPORT_SYMBOLS);
|
|
37
|
+
}
|
|
38
|
+
function getLegacyLocalNames(legacyImports, importedNames) {
|
|
39
|
+
return new Set(legacyImports
|
|
40
|
+
.filter((legacyImport) => importedNames.has(legacyImport.importedName))
|
|
41
|
+
.map((legacyImport) => legacyImport.localName));
|
|
42
|
+
}
|
|
43
|
+
function editUnusedLegacyImportDeclarations(context, legacyImports, migratedLocalNames) {
|
|
44
|
+
const sourceNeedsLegacyDropdown = (0, component_context_1.sourceFileNeedsComponentTemplate)(context, componentUsesLegacyDropdown);
|
|
45
|
+
const removableImports = legacyImports
|
|
46
|
+
.filter((legacyImport) => {
|
|
47
|
+
if (LEGACY_MODULE_SCOPE_SYMBOLS.has(legacyImport.importedName)) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
if (sourceNeedsLegacyDropdown && LEGACY_DIRECTIVE_SCOPE_SYMBOLS.has(legacyImport.importedName)) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
return LEGACY_DIRECTIVE_SCOPE_SYMBOLS.has(legacyImport.importedName);
|
|
54
|
+
})
|
|
55
|
+
.filter((legacyImport) => migratedLocalNames.has(legacyImport.localName) ||
|
|
56
|
+
!(0, component_imports_1.hasIdentifierReferenceOutsideImports)(context.sourceFile, legacyImport.localName))
|
|
57
|
+
.map((legacyImport) => legacyImport.importedName);
|
|
58
|
+
return (0, import_edits_1.removeNamedImports)(context.sourceFile, LEGACY_DROPDOWN_IMPORTS, removableImports);
|
|
59
|
+
}
|
|
60
|
+
function getSortedSymbolNames(requirements) {
|
|
61
|
+
return [...new Set(requirements.map((requirement) => requirement.symbolName))].sort();
|
|
62
|
+
}
|
|
63
|
+
function getRequirementsByModule(requirements) {
|
|
64
|
+
const requirementsByModule = new Map();
|
|
65
|
+
for (const requirement of requirements) {
|
|
66
|
+
const moduleRequirements = requirementsByModule.get(requirement.moduleName) ?? [];
|
|
67
|
+
moduleRequirements.push(requirement);
|
|
68
|
+
requirementsByModule.set(requirement.moduleName, moduleRequirements);
|
|
69
|
+
}
|
|
70
|
+
return new Map([...requirementsByModule.entries()].map(([moduleName, moduleRequirements]) => [
|
|
71
|
+
moduleName,
|
|
72
|
+
getSortedSymbolNames(moduleRequirements)
|
|
73
|
+
]));
|
|
74
|
+
}
|
|
75
|
+
function findComponentImportsProperty(sourceFile, component) {
|
|
76
|
+
const metadata = (0, angular_component_1.findComponentMetadata)(component);
|
|
77
|
+
if (!metadata) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
for (const property of metadata.properties) {
|
|
81
|
+
if (ts.isPropertyAssignment(property) && property.name.getText(sourceFile) === 'imports') {
|
|
82
|
+
return property;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
function editNewComponentImportsProperty(component, symbolNames) {
|
|
88
|
+
const metadata = (0, angular_component_1.findComponentMetadata)(component);
|
|
89
|
+
const lastProperty = metadata?.properties[metadata.properties.length - 1];
|
|
90
|
+
if (!lastProperty) {
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
return [
|
|
94
|
+
{ start: lastProperty.getEnd(), end: lastProperty.getEnd(), text: `,\n imports: [${symbolNames.join(', ')}]` }
|
|
95
|
+
];
|
|
96
|
+
}
|
|
97
|
+
function editNewNgModuleImportsProperty(moduleClass, symbolNames) {
|
|
98
|
+
const metadata = (0, angular_component_1.findNgModuleMetadata)(moduleClass);
|
|
99
|
+
const lastProperty = metadata?.properties[metadata.properties.length - 1];
|
|
100
|
+
if (!lastProperty) {
|
|
101
|
+
return [];
|
|
102
|
+
}
|
|
103
|
+
return [
|
|
104
|
+
{ start: lastProperty.getEnd(), end: lastProperty.getEnd(), text: `,\n imports: [${symbolNames.join(', ')}]` }
|
|
105
|
+
];
|
|
106
|
+
}
|
|
107
|
+
function isDeclaredInSourceNgModule(context, component) {
|
|
108
|
+
return (0, angular_component_1.getNgModuleClasses)(context.sourceFile).some((moduleClass) => {
|
|
109
|
+
const declarations = (0, angular_component_1.findNgModuleDeclarationsArray)(moduleClass);
|
|
110
|
+
return declarations?.elements.some((element) => (0, angular_component_1.resolveClassDeclaration)(context.typeChecker, element) === component);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
function editImportsArrayContents(context, importsArray, requirements, removableLocalNames) {
|
|
114
|
+
const requiredSymbols = getSortedSymbolNames(requirements);
|
|
115
|
+
const remaining = importsArray.elements
|
|
116
|
+
.map((element) => element.getText(context.sourceFile))
|
|
117
|
+
.filter((elementText) => !removableLocalNames.has(elementText));
|
|
118
|
+
const existing = new Set(remaining);
|
|
119
|
+
const missing = requiredSymbols.filter((symbolName) => !existing.has(symbolName));
|
|
120
|
+
if (remaining.length === importsArray.elements.length && missing.length === 0) {
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
const elements = [...remaining, ...missing];
|
|
124
|
+
return [
|
|
125
|
+
{
|
|
126
|
+
start: importsArray.getStart(context.sourceFile) + 1,
|
|
127
|
+
end: importsArray.getEnd() - 1,
|
|
128
|
+
text: elements.join(', ')
|
|
129
|
+
}
|
|
130
|
+
];
|
|
131
|
+
}
|
|
132
|
+
function addTopLevelImports(sourceFile, fileRequirements) {
|
|
133
|
+
const edits = [];
|
|
134
|
+
for (const [moduleName, symbolNames] of getRequirementsByModule(fileRequirements)) {
|
|
135
|
+
edits.push(...(0, import_edits_1.addNamedImports)(sourceFile, moduleName, symbolNames));
|
|
136
|
+
}
|
|
137
|
+
return edits;
|
|
138
|
+
}
|
|
139
|
+
function editDropdownStandaloneImports(context, legacyImports, additionalTopLevelImportNames = []) {
|
|
140
|
+
const edits = [];
|
|
141
|
+
const fileRequirements = [];
|
|
142
|
+
const removableLocalNames = getLegacyLocalNames(legacyImports, LEGACY_DIRECTIVE_SCOPE_SYMBOLS);
|
|
143
|
+
for (const [component, requirements] of context.standaloneImportsByComponent) {
|
|
144
|
+
if ((0, angular_component_1.isExplicitlyNonStandaloneComponent)(component)) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
const keepsLegacyDropdown = componentUsesLegacyDropdown(context.templatesByComponent.get(component) ?? []);
|
|
148
|
+
const importsArray = (0, angular_component_1.findComponentImportsArray)(component);
|
|
149
|
+
if (importsArray) {
|
|
150
|
+
edits.push(...editImportsArrayContents(context, importsArray, requirements, keepsLegacyDropdown ? new Set() : removableLocalNames));
|
|
151
|
+
if (requirements.length > 0) {
|
|
152
|
+
fileRequirements.push(...requirements);
|
|
153
|
+
}
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
if (requirements.length === 0) {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
const importsProperty = findComponentImportsProperty(context.sourceFile, component);
|
|
160
|
+
if (importsProperty) {
|
|
161
|
+
if (!ts.isArrayLiteralExpression(importsProperty.initializer)) {
|
|
162
|
+
const edit = (0, todo_comments_1.editSourceTodo)(context.sourceFile, importsProperty, {
|
|
163
|
+
code: 'dropdown.indirect-component-imports',
|
|
164
|
+
message: 'Component imports use an indirect value. Add the required DF dropdown imports after verifying its shape.'
|
|
165
|
+
});
|
|
166
|
+
if (edit) {
|
|
167
|
+
edits.push(edit);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
if (isDeclaredInSourceNgModule(context, component)) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
edits.push(...editNewComponentImportsProperty(component, getSortedSymbolNames(requirements)));
|
|
176
|
+
fileRequirements.push(...requirements);
|
|
177
|
+
}
|
|
178
|
+
for (const moduleClass of (0, angular_component_1.getNgModuleClasses)(context.sourceFile)) {
|
|
179
|
+
const declarationsArray = (0, angular_component_1.findNgModuleDeclarationsArray)(moduleClass);
|
|
180
|
+
if (!declarationsArray) {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
const requirements = declarationsArray.elements.flatMap((element) => {
|
|
184
|
+
const component = (0, angular_component_1.resolveClassDeclaration)(context.typeChecker, element);
|
|
185
|
+
return component ? (context.projectStandaloneImportsByComponent.get(component) ?? []) : [];
|
|
186
|
+
});
|
|
187
|
+
if (requirements.length === 0) {
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
const symbolNames = getSortedSymbolNames(requirements);
|
|
191
|
+
const importsArray = (0, angular_component_1.findNgModuleImportsArray)(moduleClass);
|
|
192
|
+
if (importsArray) {
|
|
193
|
+
const keepsLegacyDropdown = (0, component_context_1.moduleDeclaresComponentTemplate)(context, moduleClass, componentUsesLegacyDropdown);
|
|
194
|
+
edits.push(...editImportsArrayContents(context, importsArray, requirements, keepsLegacyDropdown ? new Set() : removableLocalNames));
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
edits.push(...editNewNgModuleImportsProperty(moduleClass, symbolNames));
|
|
198
|
+
}
|
|
199
|
+
fileRequirements.push(...requirements);
|
|
200
|
+
}
|
|
201
|
+
for (const symbolName of additionalTopLevelImportNames) {
|
|
202
|
+
fileRequirements.push({ moduleName: template_imports_1.DROPDOWN_IMPORTS.dropdown.moduleName, symbolName });
|
|
203
|
+
}
|
|
204
|
+
edits.push(...addTopLevelImports(context.sourceFile, fileRequirements));
|
|
205
|
+
return edits;
|
|
206
|
+
}
|
|
207
|
+
function editProgrammaticApiTodos(context, legacyImports, migratedLocalNames) {
|
|
208
|
+
const edits = [];
|
|
209
|
+
if (migratedLocalNames.size > 0) {
|
|
210
|
+
const edit = (0, todo_comments_1.editSourceTodo)(context.sourceFile, context.sourceFile, {
|
|
211
|
+
code: 'dropdown.programmatic-api',
|
|
212
|
+
marker: 'human',
|
|
213
|
+
message: 'Dropdown TypeScript references were migrated to DfDropdown. Verify open, close, toggle, isOpen, ViewChild, and ViewChildren behavior manually.'
|
|
214
|
+
});
|
|
215
|
+
if (edit) {
|
|
216
|
+
edits.push(edit);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
for (const legacyImport of legacyImports) {
|
|
220
|
+
if (legacyImport.importedName !== NGB_DROPDOWN ||
|
|
221
|
+
migratedLocalNames.has(legacyImport.localName) ||
|
|
222
|
+
!(0, component_imports_1.hasIdentifierReferenceOutsideImports)(context.sourceFile, legacyImport.localName)) {
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
const edit = (0, todo_comments_1.editSourceTodo)(context.sourceFile, context.sourceFile, {
|
|
226
|
+
code: 'dropdown.programmatic-api',
|
|
227
|
+
marker: 'human',
|
|
228
|
+
message: 'NgbDropdown is still referenced in TypeScript. Replace ViewChild, ViewChildren, open, close, toggle, and isOpen usage with the new API manually.'
|
|
229
|
+
});
|
|
230
|
+
if (edit) {
|
|
231
|
+
edits.push(edit);
|
|
232
|
+
}
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
return edits;
|
|
236
|
+
}
|
|
237
|
+
function getNewDropdownImportName(legacyImport) {
|
|
238
|
+
return legacyImport.importedName === NGB_DROPDOWN && legacyImport.localName !== NGB_DROPDOWN
|
|
239
|
+
? `${DF_DROPDOWN} as ${legacyImport.localName}`
|
|
240
|
+
: DF_DROPDOWN;
|
|
241
|
+
}
|
|
242
|
+
function getDropdownScopeName(legacyImport) {
|
|
243
|
+
return legacyImport.importedName === NGB_DROPDOWN && legacyImport.localName !== NGB_DROPDOWN
|
|
244
|
+
? legacyImport.localName
|
|
245
|
+
: DF_DROPDOWN;
|
|
246
|
+
}
|
|
247
|
+
function getSkippedRanges(sourceFile) {
|
|
248
|
+
const importDeclarationRanges = sourceFile.statements.flatMap((statement) => ts.isImportDeclaration(statement) ? [{ start: statement.getFullStart(), end: statement.getEnd() }] : []);
|
|
249
|
+
const decoratorImportsArrayRanges = (0, angular_component_1.findDecoratorImportsArrays)(sourceFile).map((importsArray) => ({
|
|
250
|
+
start: importsArray.getStart(sourceFile),
|
|
251
|
+
end: importsArray.getEnd()
|
|
252
|
+
}));
|
|
253
|
+
return [...importDeclarationRanges, ...decoratorImportsArrayRanges];
|
|
254
|
+
}
|
|
255
|
+
function editNgbDropdownReferences(sourceFile, legacyImports, newImports, migratedLocalNames) {
|
|
256
|
+
const edits = [];
|
|
257
|
+
const skippedRanges = getSkippedRanges(sourceFile);
|
|
258
|
+
const dropdownImports = legacyImports.filter((legacyImport) => legacyImport.importedName === NGB_DROPDOWN);
|
|
259
|
+
const scanner = ts.createScanner(ts.ScriptTarget.Latest, false, ts.LanguageVariant.Standard, sourceFile.text);
|
|
260
|
+
let token = scanner.scan();
|
|
261
|
+
while (token !== ts.SyntaxKind.EndOfFileToken) {
|
|
262
|
+
const start = scanner.getTokenStart();
|
|
263
|
+
const end = scanner.getTokenEnd();
|
|
264
|
+
const legacyImport = dropdownImports.find((candidate) => candidate.localName === scanner.getTokenText());
|
|
265
|
+
if (token === ts.SyntaxKind.Identifier &&
|
|
266
|
+
legacyImport &&
|
|
267
|
+
!skippedRanges.some((range) => start >= range.start && end <= range.end)) {
|
|
268
|
+
const replacement = getDropdownScopeName(legacyImport);
|
|
269
|
+
newImports.add(getNewDropdownImportName(legacyImport));
|
|
270
|
+
migratedLocalNames.add(legacyImport.localName);
|
|
271
|
+
if (scanner.getTokenText() !== replacement) {
|
|
272
|
+
edits.push({ start, end, text: replacement });
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
token = scanner.scan();
|
|
276
|
+
}
|
|
277
|
+
return edits;
|
|
278
|
+
}
|
|
279
|
+
function editRemainingLegacyImportTodos(context, legacyImports) {
|
|
280
|
+
if (legacyImports.length === 0) {
|
|
281
|
+
return [];
|
|
282
|
+
}
|
|
283
|
+
const sourceNeedsLegacyDropdown = (0, component_context_1.sourceFileNeedsComponentTemplate)(context, componentUsesLegacyDropdown);
|
|
284
|
+
return (0, component_imports_1.editLegacyImportTodos)(context.sourceFile, LEGACY_DROPDOWN_IMPORTS, (legacyImport) => LEGACY_MODULE_SCOPE_SYMBOLS.has(legacyImport.importedName) ||
|
|
285
|
+
(sourceNeedsLegacyDropdown && LEGACY_DIRECTIVE_SCOPE_SYMBOLS.has(legacyImport.importedName)), {
|
|
286
|
+
code: 'dropdown.legacy-import',
|
|
287
|
+
message: 'Legacy dropdown import remains for second-pass verification. Remove it after confirming no legacy dropdown APIs need it.'
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
function editDropdownImports(context) {
|
|
291
|
+
const edits = [];
|
|
292
|
+
const newImports = new Set();
|
|
293
|
+
const migratedLocalNames = new Set();
|
|
294
|
+
const legacyImports = getLegacyDropdownImports(context.sourceFile);
|
|
295
|
+
const sourceNeedsDfDropdown = (0, component_context_1.sourceFileNeedsComponentTemplate)(context, componentUsesDfDropdown);
|
|
296
|
+
const sourceNeedsLegacyDropdown = (0, component_context_1.sourceFileNeedsComponentTemplate)(context, componentUsesLegacyDropdown);
|
|
297
|
+
if (sourceNeedsDfDropdown && !sourceNeedsLegacyDropdown) {
|
|
298
|
+
edits.push(...editNgbDropdownReferences(context.sourceFile, legacyImports, newImports, migratedLocalNames));
|
|
299
|
+
}
|
|
300
|
+
edits.push(...editDropdownStandaloneImports(context, legacyImports, newImports));
|
|
301
|
+
if (legacyImports.length === 0) {
|
|
302
|
+
return edits;
|
|
303
|
+
}
|
|
304
|
+
edits.push(...editProgrammaticApiTodos(context, legacyImports, migratedLocalNames));
|
|
305
|
+
edits.push(...editUnusedLegacyImportDeclarations(context, legacyImports, migratedLocalNames));
|
|
306
|
+
edits.push(...editRemainingLegacyImportTodos(context, legacyImports));
|
|
307
|
+
return edits;
|
|
308
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { TmplAstElement } from '@angular/compiler';
|
|
2
|
+
import { TemplateEdit } from '../../shared/template-edits';
|
|
3
|
+
import { StandaloneImportRequirement } from '../../shared/types';
|
|
4
|
+
import { DropdownTemplateContext } from './template-wrapper';
|
|
5
|
+
export interface DropdownTemplateEditResult {
|
|
6
|
+
migrated: boolean;
|
|
7
|
+
standaloneImports: StandaloneImportRequirement[];
|
|
8
|
+
}
|
|
9
|
+
export declare function editDropdownWrapper(wrapper: TmplAstElement, context: DropdownTemplateContext, edits: TemplateEdit[]): DropdownTemplateEditResult;
|
|
10
|
+
export declare function countDropdownWrapperUsage(element: TmplAstElement): boolean;
|