@siemens/element-ng 51.1.0 → 51.3.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.
Files changed (130) hide show
  1. package/README.md +2 -2
  2. package/fesm2022/siemens-element-ng-about.mjs.map +1 -1
  3. package/fesm2022/siemens-element-ng-accordion.mjs.map +1 -1
  4. package/fesm2022/siemens-element-ng-action-modal.mjs.map +1 -1
  5. package/fesm2022/siemens-element-ng-ag-grid.mjs.map +1 -1
  6. package/fesm2022/siemens-element-ng-application-header.mjs.map +1 -1
  7. package/fesm2022/siemens-element-ng-auto-collapsable-list.mjs.map +1 -1
  8. package/fesm2022/siemens-element-ng-autocomplete.mjs.map +1 -1
  9. package/fesm2022/siemens-element-ng-avatar.mjs.map +1 -1
  10. package/fesm2022/siemens-element-ng-badge.mjs.map +1 -1
  11. package/fesm2022/siemens-element-ng-breadcrumb-router.mjs.map +1 -1
  12. package/fesm2022/siemens-element-ng-breadcrumb.mjs.map +1 -1
  13. package/fesm2022/siemens-element-ng-card.mjs.map +1 -1
  14. package/fesm2022/siemens-element-ng-carousel.mjs.map +1 -1
  15. package/fesm2022/siemens-element-ng-chat-messages.mjs.map +1 -1
  16. package/fesm2022/siemens-element-ng-circle-status.mjs.map +1 -1
  17. package/fesm2022/siemens-element-ng-color-picker.mjs.map +1 -1
  18. package/fesm2022/siemens-element-ng-column-selection-dialog.mjs.map +1 -1
  19. package/fesm2022/siemens-element-ng-common.mjs +13 -17
  20. package/fesm2022/siemens-element-ng-common.mjs.map +1 -1
  21. package/fesm2022/siemens-element-ng-connection-strength.mjs.map +1 -1
  22. package/fesm2022/siemens-element-ng-content-action-bar.mjs.map +1 -1
  23. package/fesm2022/siemens-element-ng-copyright-notice.mjs.map +1 -1
  24. package/fesm2022/siemens-element-ng-dashboard.mjs +15 -1
  25. package/fesm2022/siemens-element-ng-dashboard.mjs.map +1 -1
  26. package/fesm2022/siemens-element-ng-datatable.mjs.map +1 -1
  27. package/fesm2022/siemens-element-ng-date-range-filter.mjs.map +1 -1
  28. package/fesm2022/siemens-element-ng-datepicker.mjs +13 -3
  29. package/fesm2022/siemens-element-ng-datepicker.mjs.map +1 -1
  30. package/fesm2022/siemens-element-ng-electron-titlebar.mjs.map +1 -1
  31. package/fesm2022/siemens-element-ng-empty-state.mjs.map +1 -1
  32. package/fesm2022/siemens-element-ng-file-uploader.mjs.map +1 -1
  33. package/fesm2022/siemens-element-ng-filter-bar.mjs.map +1 -1
  34. package/fesm2022/siemens-element-ng-filtered-search.mjs +8 -5
  35. package/fesm2022/siemens-element-ng-filtered-search.mjs.map +1 -1
  36. package/fesm2022/siemens-element-ng-footer.mjs.map +1 -1
  37. package/fesm2022/siemens-element-ng-form.mjs +4 -4
  38. package/fesm2022/siemens-element-ng-form.mjs.map +1 -1
  39. package/fesm2022/siemens-element-ng-formly-legacy.mjs.map +1 -1
  40. package/fesm2022/siemens-element-ng-formly.mjs.map +1 -1
  41. package/fesm2022/siemens-element-ng-header-dropdown.mjs.map +1 -1
  42. package/fesm2022/siemens-element-ng-help-button.mjs.map +1 -1
  43. package/fesm2022/siemens-element-ng-icon.mjs.map +1 -1
  44. package/fesm2022/siemens-element-ng-info-page.mjs.map +1 -1
  45. package/fesm2022/siemens-element-ng-inline-notification.mjs.map +1 -1
  46. package/fesm2022/siemens-element-ng-ip-input.mjs.map +1 -1
  47. package/fesm2022/siemens-element-ng-landing-page.mjs.map +1 -1
  48. package/fesm2022/siemens-element-ng-language-switcher.mjs.map +1 -1
  49. package/fesm2022/siemens-element-ng-link.mjs.map +1 -1
  50. package/fesm2022/siemens-element-ng-list-details.mjs.map +1 -1
  51. package/fesm2022/siemens-element-ng-loading-spinner.mjs.map +1 -1
  52. package/fesm2022/siemens-element-ng-localization.mjs.map +1 -1
  53. package/fesm2022/siemens-element-ng-main-detail-container.mjs.map +1 -1
  54. package/fesm2022/siemens-element-ng-maplibre.mjs +2 -2
  55. package/fesm2022/siemens-element-ng-maplibre.mjs.map +1 -1
  56. package/fesm2022/siemens-element-ng-markdown-directives-tabs.mjs.map +1 -1
  57. package/fesm2022/siemens-element-ng-markdown-extensions-citations.mjs.map +1 -1
  58. package/fesm2022/siemens-element-ng-markdown-extensions-katex.mjs +2 -2
  59. package/fesm2022/siemens-element-ng-markdown-extensions-katex.mjs.map +1 -1
  60. package/fesm2022/siemens-element-ng-markdown-extensions-mermaid.mjs.map +1 -1
  61. package/fesm2022/siemens-element-ng-markdown-hightlighter-highlightjs.mjs.map +1 -1
  62. package/fesm2022/siemens-element-ng-markdown.mjs.map +1 -1
  63. package/fesm2022/siemens-element-ng-menu.mjs.map +1 -1
  64. package/fesm2022/siemens-element-ng-modal.mjs.map +1 -1
  65. package/fesm2022/siemens-element-ng-navbar-vertical-next.mjs.map +1 -1
  66. package/fesm2022/siemens-element-ng-navbar-vertical.mjs.map +1 -1
  67. package/fesm2022/siemens-element-ng-navbar.mjs.map +1 -1
  68. package/fesm2022/siemens-element-ng-notification-item.mjs.map +1 -1
  69. package/fesm2022/siemens-element-ng-number-input.mjs +3 -3
  70. package/fesm2022/siemens-element-ng-number-input.mjs.map +1 -1
  71. package/fesm2022/siemens-element-ng-pagination.mjs +2 -2
  72. package/fesm2022/siemens-element-ng-pagination.mjs.map +1 -1
  73. package/fesm2022/siemens-element-ng-password-strength.mjs.map +1 -1
  74. package/fesm2022/siemens-element-ng-password-toggle.mjs.map +1 -1
  75. package/fesm2022/siemens-element-ng-phone-number.mjs.map +1 -1
  76. package/fesm2022/siemens-element-ng-photo-upload.mjs.map +1 -1
  77. package/fesm2022/siemens-element-ng-pills-input.mjs.map +1 -1
  78. package/fesm2022/siemens-element-ng-popover-legacy.mjs.map +1 -1
  79. package/fesm2022/siemens-element-ng-popover.mjs +16 -5
  80. package/fesm2022/siemens-element-ng-popover.mjs.map +1 -1
  81. package/fesm2022/siemens-element-ng-progressbar.mjs.map +1 -1
  82. package/fesm2022/siemens-element-ng-resize-observer.mjs.map +1 -1
  83. package/fesm2022/siemens-element-ng-result-details-list.mjs.map +1 -1
  84. package/fesm2022/siemens-element-ng-search-bar.mjs.map +1 -1
  85. package/fesm2022/siemens-element-ng-select.mjs.map +1 -1
  86. package/fesm2022/siemens-element-ng-shadow-root.mjs.map +1 -1
  87. package/fesm2022/siemens-element-ng-side-panel.mjs.map +1 -1
  88. package/fesm2022/siemens-element-ng-skip-links.mjs.map +1 -1
  89. package/fesm2022/siemens-element-ng-slider.mjs.map +1 -1
  90. package/fesm2022/siemens-element-ng-source-chip.mjs.map +1 -1
  91. package/fesm2022/siemens-element-ng-split.mjs.map +1 -1
  92. package/fesm2022/siemens-element-ng-status-bar.mjs.map +1 -1
  93. package/fesm2022/siemens-element-ng-status-counter.mjs.map +1 -1
  94. package/fesm2022/siemens-element-ng-status-toggle.mjs.map +1 -1
  95. package/fesm2022/siemens-element-ng-summary-chip.mjs.map +1 -1
  96. package/fesm2022/siemens-element-ng-summary-widget.mjs.map +1 -1
  97. package/fesm2022/siemens-element-ng-system-banner.mjs.map +1 -1
  98. package/fesm2022/siemens-element-ng-tabs-legacy.mjs.map +1 -1
  99. package/fesm2022/siemens-element-ng-tabs.mjs +7 -5
  100. package/fesm2022/siemens-element-ng-tabs.mjs.map +1 -1
  101. package/fesm2022/siemens-element-ng-theme.mjs.map +1 -1
  102. package/fesm2022/siemens-element-ng-threshold.mjs.map +1 -1
  103. package/fesm2022/siemens-element-ng-toast-notification.mjs.map +1 -1
  104. package/fesm2022/siemens-element-ng-tooltip.mjs.map +1 -1
  105. package/fesm2022/siemens-element-ng-tour.mjs.map +1 -1
  106. package/fesm2022/siemens-element-ng-translate.mjs.map +1 -1
  107. package/fesm2022/siemens-element-ng-tree-view.mjs +15 -10
  108. package/fesm2022/siemens-element-ng-tree-view.mjs.map +1 -1
  109. package/fesm2022/siemens-element-ng-typeahead.mjs +9 -0
  110. package/fesm2022/siemens-element-ng-typeahead.mjs.map +1 -1
  111. package/fesm2022/siemens-element-ng-wizard.mjs.map +1 -1
  112. package/fesm2022/siemens-element-ng.mjs.map +1 -1
  113. package/maplibre/styles/maplibre-gl.scss +8 -2
  114. package/package.json +5 -5
  115. package/schematics/migrations/data/attribute-selectors.js +8 -1
  116. package/schematics/migrations/data/element-selectors.js +7 -1
  117. package/schematics/migrations/data/symbol-renaming.js +10 -0
  118. package/schematics/migrations/utilities/attribute-selector.migration.js +26 -10
  119. package/schematics/migrations/utilities/element-selector.migration.js +25 -15
  120. package/schematics/migrations/utilities/symbol-renaming.migration.js +90 -3
  121. package/schematics/utils/template-edit-utils.js +9 -0
  122. package/template-i18n.json +2 -2
  123. package/types/siemens-element-ng-dashboard.d.ts +2 -0
  124. package/types/siemens-element-ng-datepicker.d.ts +6 -1
  125. package/types/siemens-element-ng-form.d.ts +1 -1
  126. package/types/siemens-element-ng-number-input.d.ts +2 -2
  127. package/types/siemens-element-ng-popover.d.ts +1 -1
  128. package/types/siemens-element-ng-tabs.d.ts +1 -0
  129. package/types/siemens-element-ng-tree-view.d.ts +1 -0
  130. package/types/siemens-element-ng-typeahead.d.ts +7 -0
@@ -20,6 +20,7 @@ $icon-fullscreen: url('@siemens/element-icons/icons/element-zoom.svg');
20
20
  $icon-shrink: url('@siemens/element-icons/icons/element-pinch.svg');
21
21
  $icon-compass: url('@siemens/element-icons/icons/element-compass-needle.svg');
22
22
  $icon-glob: url('@siemens/element-icons/icons/element-global.svg');
23
+ $icon-map: url('@siemens/element-icons/icons/element-map.svg');
23
24
  $icon-locate: url('@siemens/element-icons/icons/element-locate.svg');
24
25
  $icon-terrain: url('@siemens/element-icons/icons/element-waters.svg');
25
26
 
@@ -303,13 +304,18 @@ $icon-terrain: url('@siemens/element-icons/icons/element-waters.svg');
303
304
  mask-image: $icon-shrink;
304
305
  }
305
306
 
306
- &.maplibregl-ctrl-globe,
307
- &.maplibregl-ctrl-globe-enabled {
307
+ &.maplibregl-ctrl-globe {
308
308
  .maplibregl-ctrl-icon {
309
309
  mask-image: $icon-glob;
310
310
  }
311
311
  }
312
312
 
313
+ &.maplibregl-ctrl-globe-enabled {
314
+ .maplibregl-ctrl-icon {
315
+ mask-image: $icon-map;
316
+ }
317
+ }
318
+
313
319
  &.maplibregl-ctrl-terrain,
314
320
  &.maplibregl-ctrl-terrain-enabled {
315
321
  .maplibregl-ctrl-icon {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@siemens/element-ng",
3
3
  "description": "Element Angular component library, implementing the Siemens Design Language",
4
- "version": "51.1.0",
4
+ "version": "51.3.0",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -47,9 +47,9 @@
47
47
  "@maplibre/ngx-maplibre-gl": "21 - 22",
48
48
  "maplibre-gl": "5 - 6",
49
49
  "@siemens/element-icons": "1",
50
- "@siemens/element-theme": "51.1.0",
51
- "@siemens/element-translate-ng": "51.1.0",
52
- "@siemens/map-styles": "51.1.0",
50
+ "@siemens/element-theme": "51.3.0",
51
+ "@siemens/element-translate-ng": "51.3.0",
52
+ "@siemens/map-styles": "51.3.0",
53
53
  "@siemens/ngx-datatable": "26 - 27",
54
54
  "ag-grid-community": "^34.3.1 || ^35.0.0 || ^36.0.0",
55
55
  "flag-icons": "^7.3.2",
@@ -523,5 +523,5 @@
523
523
  "dependencies": {
524
524
  "tslib": "^2.3.0"
525
525
  },
526
- "readme": "<p align=\"center\">\n <a href=\"https://element.siemens.io\" target=\"_blank\">\n <img src=\"https://raw.githubusercontent.com/siemens/element/refs/heads/main/element-logo.svg\" alt=\"Element Website\" height=\"132\" width=\"132\">\n </a>\n</p>\n\n<h1 align=\"center\">Siemens Element</h1>\n\n<p align=\"center\">\n <a href=\"https://www.npmjs.com/@siemens/element-ng\">\n <img src=\"https://img.shields.io/npm/v/@siemens/element-ng.svg?logo=npm&logoColor=fff&label=NPM+package&color=limegreen\" alt=\"Element on npm\" />\n </a>\n <a href=\"https://element.siemens.io/coverage/element-ng/index.html\">\n <img src=\"https://img.shields.io/endpoint?url=https://element.siemens.io/coverage-summary.json\" alt=\"Code Coverage\">\n </a>\n</p>\n\n<p></p>\n<p align=\"center\">\n Siemens Element is a design system of the smart infrastructure domain\n that implements the Siemens Design Language in Angular. It includes UI\n components, design tools and resources, human interface guidelines, and a\n vibrant community of contributors.\n</p>\n<p></p>\n\n<hr>\n\n## Contributing\n\nImprovements are always welcome! Feel free to log a bug,\nwrite a suggestion, or contribute code by creating a pull request.\nAll details are listed in our contribution guide.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md).\n\n## License\n\nThe following applies for code and documentation of the git repository,\nunless explicitly mentioned.\n\nCopyright (c) Siemens 2016 - 2026\n\nMIT, see [LICENSE](LICENSE).\n\n### Bootstrap\n\nThe source code in the folder [bootstrap](./projects/element-theme/src/styles/bootstrap/)\nis based on [Bootstrap (v5.1.3)](https://github.com/twbs/bootstrap). We changed and adapted\nthe SASS component files to our needs. At that point in time, it was under _MIT License_\nand _Copyright (c) 2011-2024 The Bootstrap Authors_.\n\n### API Goldens\n\nThe source code in the folder [tools/api-goldens](./tools/api-goldens/) is based on [dev-infra-private-build-tooling-builds](https://github.com/angular/dev-infra-private-build-tooling-builds/tree/main/bazel/api-golden).\nWe changed and adapted the code to our needs. At that point in time it was under _MIT License_ and _Copyright Google LLC_.\n"
526
+ "readme": "<p align=\"center\">\n <a href=\"https://element.siemens.io\" target=\"_blank\">\n <img src=\"https://raw.githubusercontent.com/siemens/element/refs/heads/main/element-logo.svg\" alt=\"Element Website\" height=\"132\" width=\"132\">\n </a>\n</p>\n\n<h1 align=\"center\">Siemens Element</h1>\n\n<p align=\"center\">\n <a href=\"https://www.npmjs.com/@siemens/element-ng\">\n <img src=\"https://img.shields.io/npm/v/@siemens/element-ng.svg?logo=npm&logoColor=fff&label=NPM+package&color=limegreen\" alt=\"Element on npm\" />\n </a>\n <a href=\"https://element.siemens.io/development/coverage/element-ng/index.html\">\n <img src=\"https://img.shields.io/endpoint?url=https://element.siemens.io/development/coverage-summary.json\" alt=\"Code Coverage\">\n </a>\n</p>\n\n<p></p>\n<p align=\"center\">\n Siemens Element is a design system of the smart infrastructure domain\n that implements the Siemens Design Language in Angular. It includes UI\n components, design tools and resources, human interface guidelines, and a\n vibrant community of contributors.\n</p>\n<p></p>\n\n<hr>\n\n## Contributing\n\nImprovements are always welcome! Feel free to log a bug,\nwrite a suggestion, or contribute code by creating a pull request.\nAll details are listed in our contribution guide.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md).\n\n## License\n\nThe following applies for code and documentation of the git repository,\nunless explicitly mentioned.\n\nCopyright (c) Siemens 2016 - 2026\n\nMIT, see [LICENSE](LICENSE).\n\n### Bootstrap\n\nThe source code in the folder [bootstrap](./projects/element-theme/src/styles/bootstrap/)\nis based on [Bootstrap (v5.1.3)](https://github.com/twbs/bootstrap). We changed and adapted\nthe SASS component files to our needs. At that point in time, it was under _MIT License_\nand _Copyright (c) 2011-2024 The Bootstrap Authors_.\n\n### API Goldens\n\nThe source code in the folder [tools/api-goldens](./tools/api-goldens/) is based on [dev-infra-private-build-tooling-builds](https://github.com/angular/dev-infra-private-build-tooling-builds/tree/main/bazel/api-golden).\nWe changed and adapted the code to our needs. At that point in time it was under _MIT License_ and _Copyright Google LLC_.\n"
527
527
  }
@@ -1 +1,8 @@
1
- export const ATTRIBUTE_SELECTORS_MIGRATION = [];
1
+ export const ATTRIBUTE_SELECTORS_MIGRATION = [
2
+ // v49 to v51
3
+ {
4
+ replace: 'si-header-siemens-logo',
5
+ replaceWith: 'siHeaderLogo',
6
+ removeAttributes: ['aria-label']
7
+ }
8
+ ];
@@ -1,3 +1,9 @@
1
1
  export const ELEMENT_SELECTORS_MIGRATION = [
2
- { replace: 'si-icon-status', replaceWith: 'si-status-counter' }
2
+ { replace: 'si-icon-status', replaceWith: 'si-status-counter' },
3
+ // v49 to v51
4
+ {
5
+ replace: 'si-header-siemens-logo',
6
+ replaceWith: 'si-header-logo',
7
+ removeAttributes: ['aria-label']
8
+ }
3
9
  ];
@@ -1,4 +1,14 @@
1
1
  export const SYMBOL_RENAMING_MIGRATION = [
2
+ // v49 to v51
3
+ {
4
+ module: /^@(siemens|simpl)\/element-ng\/application-header$/,
5
+ symbolRenamings: [
6
+ {
7
+ replace: 'SiHeaderSiemensLogoComponent',
8
+ replaceWith: 'SiHeaderLogoDirective'
9
+ }
10
+ ]
11
+ },
2
12
  {
3
13
  module: /@siemens\/element-ng\/icon-status$/,
4
14
  toModule: '@siemens/element-ng/status-counter',
@@ -3,7 +3,7 @@
3
3
  * SPDX-License-Identifier: MIT
4
4
  */
5
5
  import { join, dirname } from 'path/posix';
6
- import { findAttribute, getInlineTemplates, getTemplateUrl } from '../../utils/index.js';
6
+ import { findElement, getInlineTemplates, getTemplateUrl, removeAttributesFromElement } from '../../utils/index.js';
7
7
  export const applyAttributeSelectorMigration = (context, changes) => {
8
8
  const { tree, discoveredSourceFile, recorder } = context;
9
9
  if (!changes?.length) {
@@ -17,20 +17,25 @@ export const applyAttributeSelectorMigration = (context, changes) => {
17
17
  sourceFile,
18
18
  filePath,
19
19
  fromName: change.replace,
20
- toName: change.replaceWith
20
+ toName: change.replaceWith,
21
+ removeAttributes: change.removeAttributes
21
22
  });
22
23
  }
23
24
  };
24
- const renameAttribute = ({ tree, filePath, sourceFile, recorder, fromName, toName }) => {
25
+ const renameAttribute = ({ tree, filePath, sourceFile, recorder, fromName, toName, removeAttributes }) => {
25
26
  getInlineTemplates(sourceFile).forEach(template => renameAttributeInTemplate({
26
27
  template: sourceFile.text.substring(template.getStart() + 1, template.getEnd() - 1),
27
28
  offset: template.getStart() + 1,
28
29
  toName,
29
30
  fromName,
30
- recorder
31
+ recorder,
32
+ removeAttributes
31
33
  }));
32
34
  getTemplateUrl(sourceFile).forEach(templateUrl => {
33
35
  const templatePath = join(dirname(filePath), templateUrl);
36
+ if (!tree.exists(templatePath)) {
37
+ return;
38
+ }
34
39
  const templateContent = tree.read(templatePath).toString('utf-8');
35
40
  const templateRecorder = tree.beginUpdate(templatePath);
36
41
  renameAttributeInTemplate({
@@ -38,14 +43,25 @@ const renameAttribute = ({ tree, filePath, sourceFile, recorder, fromName, toNam
38
43
  offset: 0,
39
44
  toName,
40
45
  fromName,
41
- recorder: templateRecorder
46
+ recorder: templateRecorder,
47
+ removeAttributes
42
48
  });
43
49
  tree.commitUpdate(templateRecorder);
44
50
  });
45
51
  };
46
- const renameAttributeInTemplate = ({ template, offset, recorder, fromName, toName }) => {
47
- findAttribute(template, element => element.name === fromName).forEach(el => {
48
- recorder.remove(el.sourceSpan.start.offset + offset, fromName.length);
49
- recorder.insertLeft(el.sourceSpan.start.offset + offset, toName);
50
- });
52
+ const renameAttributeInTemplate = ({ template, offset, recorder, fromName, toName, removeAttributes }) => {
53
+ const elements = findElement(template, element => element.attrs.some(attribute => matchesSelectorAttribute(attribute.name, fromName)));
54
+ for (const element of elements) {
55
+ for (const attribute of element.attrs) {
56
+ if (!matchesSelectorAttribute(attribute.name, fromName)) {
57
+ continue;
58
+ }
59
+ const replacement = attribute.name === fromName ? toName : `[${toName}]`;
60
+ const start = attribute.sourceSpan.start.offset + offset;
61
+ recorder.remove(start, attribute.name.length);
62
+ recorder.insertLeft(start, replacement);
63
+ }
64
+ removeAttributesFromElement(template, element, removeAttributes ?? [], offset, recorder);
65
+ }
51
66
  };
67
+ const matchesSelectorAttribute = (attributeName, selector) => attributeName === selector || attributeName === `[${selector}]`;
@@ -3,7 +3,7 @@
3
3
  * SPDX-License-Identifier: MIT
4
4
  */
5
5
  import { join, dirname } from 'path/posix';
6
- import { findElement, getInlineTemplates, getTemplateUrl } from '../../utils/index.js';
6
+ import { findElement, getInlineTemplates, getTemplateUrl, removeAttributesFromElement } from '../../utils/index.js';
7
7
  export const applyElementSelectorMigration = (context, changes) => {
8
8
  const { tree, discoveredSourceFile, recorder } = context;
9
9
  if (!changes?.length) {
@@ -18,21 +18,26 @@ export const applyElementSelectorMigration = (context, changes) => {
18
18
  filePath,
19
19
  fromName: change.replace,
20
20
  toName: change.replaceWith,
21
- defaultAttributes: change.defaultAttributes
21
+ defaultAttributes: change.defaultAttributes,
22
+ removeAttributes: change.removeAttributes
22
23
  });
23
24
  }
24
25
  };
25
- const renameElementTag = ({ tree, filePath, sourceFile, recorder, fromName, toName, defaultAttributes }) => {
26
+ const renameElementTag = ({ tree, filePath, sourceFile, recorder, fromName, toName, defaultAttributes, removeAttributes }) => {
26
27
  getInlineTemplates(sourceFile).forEach(template => renameElementTagInTemplate({
27
28
  template: sourceFile.text.substring(template.getStart() + 1, template.getEnd() - 1),
28
29
  offset: template.getStart() + 1,
29
30
  toName,
30
31
  fromName,
31
32
  recorder,
32
- defaultAttributes
33
+ defaultAttributes,
34
+ removeAttributes
33
35
  }));
34
36
  getTemplateUrl(sourceFile).forEach(templateUrl => {
35
37
  const templatePath = join(dirname(filePath), templateUrl);
38
+ if (!tree.exists(templatePath)) {
39
+ return;
40
+ }
36
41
  const templateContent = tree.read(templatePath).toString('utf-8');
37
42
  const templateRecorder = tree.beginUpdate(templatePath);
38
43
  renameElementTagInTemplate({
@@ -41,27 +46,32 @@ const renameElementTag = ({ tree, filePath, sourceFile, recorder, fromName, toNa
41
46
  toName,
42
47
  fromName,
43
48
  recorder: templateRecorder,
44
- defaultAttributes
49
+ defaultAttributes,
50
+ removeAttributes
45
51
  });
46
52
  tree.commitUpdate(templateRecorder);
47
53
  });
48
54
  };
49
- const renameElementTagInTemplate = ({ template, offset, recorder, fromName, toName, defaultAttributes }) => {
50
- findElement(template, element => element.name === fromName).forEach(el => {
51
- recorder.remove(el.startSourceSpan.start.offset + 1 + offset, fromName.length);
52
- recorder.insertLeft(el.startSourceSpan.start.offset + 1 + offset, toName);
53
- if (el.endSourceSpan && el.startSourceSpan.start !== el.endSourceSpan.start) {
54
- recorder.remove(el.endSourceSpan?.start.offset + 2 + offset, fromName.length);
55
- recorder.insertLeft(el.endSourceSpan?.start.offset + 2 + offset, toName);
55
+ const renameElementTagInTemplate = ({ template, offset, recorder, fromName, toName, defaultAttributes, removeAttributes }) => {
56
+ for (const element of findElement(template, node => node.name === fromName)) {
57
+ const openingNameStart = element.startSourceSpan.start.offset + 1 + offset;
58
+ recorder.remove(openingNameStart, fromName.length);
59
+ recorder.insertLeft(openingNameStart, toName);
60
+ const closingTag = element.endSourceSpan;
61
+ if (closingTag && closingTag.start.offset !== element.startSourceSpan.start.offset) {
62
+ const closingNameStart = closingTag.start.offset + 2 + offset;
63
+ recorder.remove(closingNameStart, fromName.length);
64
+ recorder.insertLeft(closingNameStart, toName);
56
65
  }
57
66
  if (defaultAttributes && defaultAttributes.length > 0) {
58
- const existingAttrNames = new Set(el.attrs.map(attr => attr.name));
67
+ const existingAttrNames = new Set(element.attrs.map(attr => attr.name));
59
68
  const attrsToAdd = defaultAttributes.filter(attr => !existingAttrNames.has(attr.name));
60
69
  if (attrsToAdd.length > 0) {
61
- const insertPosition = el.startSourceSpan.start.offset + 1 + offset + toName.length;
70
+ const insertPosition = element.startSourceSpan.start.offset + 1 + offset + toName.length;
62
71
  const attrsString = attrsToAdd.map(attr => ` ${attr.name}="${attr.value}"`).join('');
63
72
  recorder.insertLeft(insertPosition, attrsString);
64
73
  }
65
74
  }
66
- });
75
+ removeAttributesFromElement(template, element, removeAttributes ?? [], offset, recorder);
76
+ }
67
77
  };
@@ -4,16 +4,18 @@
4
4
  */
5
5
  import * as ts from 'typescript';
6
6
  import { EmitHint } from 'typescript';
7
- import { findImportSpecifier } from '../../utils/index.js';
7
+ import { findImportSpecifier, getImportSpecifiers } from '../../utils/index.js';
8
+ import { removeImportSpecifiers } from './import-removal.js';
8
9
  export const applySymbolRenamingMigration = (context, changes) => {
9
10
  const { discoveredSourceFile, recorder } = context;
10
11
  if (!changes?.length) {
11
12
  return;
12
13
  }
13
- const { sourceFile } = discoveredSourceFile;
14
+ const { sourceFile, typeChecker } = discoveredSourceFile;
14
15
  const changeInstructions = [
15
16
  ...renameIdentifier({
16
17
  sourceFile,
18
+ typeChecker,
17
19
  renamingInstructions: changes
18
20
  })
19
21
  ];
@@ -26,7 +28,7 @@ export const applySymbolRenamingMigration = (context, changes) => {
26
28
  recorder.insertLeft(changeInstruction.start, printer.printNode(EmitHint.Unspecified, changeInstruction.newNode, sourceFile));
27
29
  }
28
30
  };
29
- function* renameIdentifier({ sourceFile, renamingInstructions }) {
31
+ function* renameIdentifier({ sourceFile, typeChecker, renamingInstructions }) {
30
32
  for (const node of sourceFile.statements) {
31
33
  if (!ts.isImportDeclaration(node) || !ts.isStringLiteral(node.moduleSpecifier)) {
32
34
  continue;
@@ -38,6 +40,10 @@ function* renameIdentifier({ sourceFile, renamingInstructions }) {
38
40
  if (!(node.importClause?.namedBindings && ts.isNamedImports(node.importClause.namedBindings))) {
39
41
  continue;
40
42
  }
43
+ if (!renamingInstruction.toModule) {
44
+ yield* renameSymbolsInPlace(sourceFile, typeChecker, node, renamingInstruction);
45
+ continue;
46
+ }
41
47
  // Find all symbols from this import that need to be renamed/moved
42
48
  const symbolsToProcess = [];
43
49
  for (const { replace, replaceWith } of renamingInstruction.symbolRenamings) {
@@ -126,3 +132,84 @@ function* renameIdentifier({ sourceFile, renamingInstructions }) {
126
132
  }
127
133
  }
128
134
  }
135
+ function* renameSymbolsInPlace(sourceFile, typeChecker, declaration, instruction) {
136
+ const importClause = declaration.importClause;
137
+ const bindings = importClause.namedBindings;
138
+ const replacements = new Map();
139
+ const references = new Map();
140
+ const redundantImports = [];
141
+ for (const specifier of bindings.elements) {
142
+ const importedName = specifier.propertyName ?? specifier.name;
143
+ const rename = instruction.symbolRenamings.find(change => change.replace === importedName.text);
144
+ if (!rename) {
145
+ continue;
146
+ }
147
+ // Aliases keep their local name and only change the imported symbol.
148
+ if (specifier.propertyName) {
149
+ replacements.set(specifier, rename.replaceWith);
150
+ continue;
151
+ }
152
+ const existingImport = getImportSpecifiers(sourceFile, declaration.moduleSpecifier.text, rename.replaceWith).find(candidate => {
153
+ const isTypeOnly = candidate.isTypeOnly || candidate.parent.parent.isTypeOnly;
154
+ return !isTypeOnly || specifier.isTypeOnly || importClause.isTypeOnly;
155
+ });
156
+ if (existingImport) {
157
+ redundantImports.push(specifier);
158
+ }
159
+ else {
160
+ replacements.set(specifier, rename.replaceWith);
161
+ }
162
+ const symbol = typeChecker.getSymbolAtLocation(specifier.name);
163
+ if (symbol) {
164
+ references.set(symbol, existingImport?.name.text ?? rename.replaceWith);
165
+ }
166
+ }
167
+ if (redundantImports.length) {
168
+ const edit = removeImportSpecifiers(sourceFile, declaration, redundantImports);
169
+ const remaining = bindings.elements.filter(specifier => !redundantImports.includes(specifier));
170
+ const updatedBindings = ts.factory.updateNamedImports(bindings, remaining.map(specifier => {
171
+ const replacement = replacements.get(specifier);
172
+ if (!replacement) {
173
+ return specifier;
174
+ }
175
+ return ts.factory.updateImportSpecifier(specifier, specifier.isTypeOnly, specifier.propertyName ? ts.factory.createIdentifier(replacement) : undefined, specifier.propertyName ? specifier.name : ts.factory.createIdentifier(replacement));
176
+ }));
177
+ yield {
178
+ start: edit.start,
179
+ width: edit.width,
180
+ newNode: edit.newNode
181
+ ? ts.factory.updateImportDeclaration(declaration, declaration.modifiers, ts.factory.updateImportClause(importClause, importClause.isTypeOnly, importClause.name, updatedBindings), declaration.moduleSpecifier, declaration.attributes)
182
+ : ts.factory.createIdentifier('')
183
+ };
184
+ }
185
+ else {
186
+ for (const [specifier, replacement] of replacements) {
187
+ const importedName = specifier.propertyName ?? specifier.name;
188
+ yield {
189
+ start: importedName.getStart(),
190
+ width: importedName.getWidth(),
191
+ newNode: ts.factory.createIdentifier(replacement)
192
+ };
193
+ }
194
+ }
195
+ const visit = function* (node) {
196
+ if (ts.isImportDeclaration(node)) {
197
+ return;
198
+ }
199
+ if (ts.isIdentifier(node)) {
200
+ const symbol = typeChecker.getSymbolAtLocation(node);
201
+ const replacement = symbol && references.get(symbol);
202
+ if (replacement) {
203
+ yield {
204
+ start: node.getStart(),
205
+ width: node.getWidth(),
206
+ newNode: ts.factory.createIdentifier(replacement)
207
+ };
208
+ }
209
+ }
210
+ for (const child of node.getChildren()) {
211
+ yield* visit(child);
212
+ }
213
+ };
214
+ yield* visit(sourceFile);
215
+ }
@@ -33,3 +33,12 @@ export const removeAttribute = (template, attribute, offset, recorder) => {
33
33
  const removeStart = start > 0 && /\s/.test(template[start - 1] ?? '') ? start - 1 : start;
34
34
  recorder.remove(removeStart + offset, end - removeStart);
35
35
  };
36
+ /** Removes static attributes and property/attribute bindings with the given names. */
37
+ export const removeAttributesFromElement = (template, element, names, offset, recorder) => {
38
+ for (const attribute of element.attrs) {
39
+ const matches = names.some(name => [name, `[${name}]`, `attr.${name}`, `[attr.${name}]`].includes(attribute.name));
40
+ if (matches) {
41
+ removeAttribute(template, attribute, offset, recorder);
42
+ }
43
+ }
44
+ };
@@ -183,8 +183,8 @@
183
183
  "SI_MAP.FIND_MY_LOCATION": "Find my location",
184
184
  "SI_MAP.FULLSCREEN_ENTER": "Enter full screen",
185
185
  "SI_MAP.FULLSCREEN_EXIT": "Exit full screen",
186
- "SI_MAP.GLOBE_DISABLE": "Disable globe",
187
- "SI_MAP.GLOBE_ENABLE": "Enable globe",
186
+ "SI_MAP.GLOBE_DISABLE": "Switch to flat view",
187
+ "SI_MAP.GLOBE_ENABLE": "Switch to globe view",
188
188
  "SI_MAP.LOCATION_NOT_AVAILABLE": "Location not available",
189
189
  "SI_MAP.LOGO_TITLE": "MapLibre logo",
190
190
  "SI_MAP.MAC_HELP": "Use ⌘ + scroll to zoom the map",
@@ -132,6 +132,7 @@ declare class SiDashboardComponent implements OnChanges, AfterViewInit {
132
132
  private scrollbarHelper;
133
133
  private cdRef;
134
134
  private document;
135
+ private injector;
135
136
  private readonly hideMenubarInternal;
136
137
  constructor();
137
138
  ngOnChanges(changes: SimpleChanges<this>): void;
@@ -153,6 +154,7 @@ declare class SiDashboardComponent implements OnChanges, AfterViewInit {
153
154
  * method. In general this is achieved by listening to card events.
154
155
  */
155
156
  private restoreDashboard;
157
+ private restoreCardFocus;
156
158
  private toggleCardsHide;
157
159
  private setDashboardFrameEndPadding;
158
160
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SiDashboardComponent, never>;
@@ -217,7 +217,7 @@ declare class SiDateInputDirective implements ControlValueAccessor, OnChanges, V
217
217
  registerOnTouched(fn: () => void): void;
218
218
  registerOnValidatorChange(fn: () => void): void;
219
219
  setDisabledState(isDisabled: boolean): void;
220
- writeValue(value?: Date | string): void;
220
+ writeValue(value?: Date | string | null): void;
221
221
  private updateNativeValue;
222
222
  /**
223
223
  * Handles `input` events on the input element.
@@ -920,6 +920,11 @@ declare class SiTimepickerComponent implements ControlValueAccessor, Validator,
920
920
  * Holds the time as date object that is presented by this control.
921
921
  */
922
922
  private time?;
923
+ /**
924
+ * Whether `null` was emitted due to an incomplete or invalid input.
925
+ * The next valid time must be emitted, even if it equals the previous `time`.
926
+ */
927
+ private invalidTimeEmitted;
923
928
  private periodDefaults;
924
929
  constructor();
925
930
  writeValue(obj?: Date | string): void;
@@ -388,7 +388,7 @@ declare class SiFormFieldsetComponent {
388
388
  /** @internal */
389
389
  readonly hasOnlyRadios: _angular_core.Signal<boolean>;
390
390
  protected readonly errors: _angular_core.Signal<readonly _siemens_element_ng_form.SiFormError[]>;
391
- protected readonly touched: _angular_core.Signal<boolean>;
391
+ protected readonly showErrors: _angular_core.Signal<boolean>;
392
392
  protected readonly isRequired: _angular_core.Signal<boolean>;
393
393
  protected readonly labelId: string;
394
394
  /** @internal */
@@ -26,7 +26,7 @@ declare class SiNumberInputComponent implements OnChanges, ControlValueAccessor,
26
26
  */
27
27
  readonly step: _angular_core.InputSignal<number | "any">;
28
28
  /** The value */
29
- readonly value: _angular_core.InputSignal<number | undefined>;
29
+ readonly value: _angular_core.InputSignal<number | null | undefined>;
30
30
  /** Optional unit label */
31
31
  readonly unit: _angular_core.InputSignal<string | undefined>;
32
32
  /**
@@ -104,7 +104,7 @@ declare class SiNumberInputComponent implements OnChanges, ControlValueAccessor,
104
104
  /** @internal */
105
105
  setDisabledState(isDisabled: boolean): void;
106
106
  /** @internal */
107
- writeValue(value: number | undefined): void;
107
+ writeValue(value: number | null | undefined): void;
108
108
  /** @internal */
109
109
  validate(control: AbstractControl): ValidationErrors | null;
110
110
  /** @internal */
@@ -13,7 +13,7 @@ declare class SiPopoverDirective implements OnDestroy {
13
13
  */
14
14
  readonly siPopover: _angular_core.InputSignal<TranslatableString | TemplateRef<unknown> | undefined>;
15
15
  /**
16
- * The placement of the popover. One of 'top', 'start', end', 'bottom'
16
+ * The placement of the popover. One of 'top', 'start', 'end', 'bottom'
17
17
  *
18
18
  * @defaultValue 'auto'
19
19
  */
@@ -127,6 +127,7 @@ declare class SiTabsetComponent {
127
127
  focusKeyManager: FocusKeyManager<SiTabBaseDirective>;
128
128
  /** @internal */
129
129
  protected readonly showMenuButton: _angular_core.WritableSignal<boolean>;
130
+ private readonly menuButton;
130
131
  protected tabIsLink(tab: unknown): tab is SiTabLinkComponent;
131
132
  constructor();
132
133
  /** @internal */
@@ -372,6 +372,7 @@ declare class SiTreeViewComponent implements OnInit, OnChanges, OnDestroy, After
372
372
  */
373
373
  private virtualRoot;
374
374
  private readonly _items;
375
+ protected readonly svgIcons: Record<"elementExpandAll" | "elementCollapseAll", string>;
375
376
  private updateTreeItemDefaults;
376
377
  /**
377
378
  * @internal
@@ -337,6 +337,13 @@ declare class SiTypeaheadDirective implements OnChanges, OnDestroy {
337
337
  private readonly unprocessedSearch;
338
338
  constructor();
339
339
  ngOnChanges(changes: SimpleChanges<this>): void;
340
+ /**
341
+ * @internal
342
+ *
343
+ * Updates the position of the typeahead overlay when already rendered.
344
+ * This can be useful if the input position/dimension changed.
345
+ */
346
+ updateOverlayPosition(): void;
340
347
  protected onBlur(): void;
341
348
  protected onInput(event: Event): void;
342
349
  protected onKeydownEscape(): void;