@siemens/element-ng 51.0.0-rc.8 → 51.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/fesm2022/siemens-element-ng-ag-grid.mjs +17 -25
  2. package/fesm2022/siemens-element-ng-ag-grid.mjs.map +1 -1
  3. package/fesm2022/siemens-element-ng-application-header.mjs +2 -2
  4. package/fesm2022/siemens-element-ng-application-header.mjs.map +1 -1
  5. package/fesm2022/siemens-element-ng-avatar.mjs +3 -3
  6. package/fesm2022/siemens-element-ng-avatar.mjs.map +1 -1
  7. package/fesm2022/siemens-element-ng-chat-messages.mjs +123 -23
  8. package/fesm2022/siemens-element-ng-chat-messages.mjs.map +1 -1
  9. package/fesm2022/siemens-element-ng-color-picker.mjs +18 -18
  10. package/fesm2022/siemens-element-ng-color-picker.mjs.map +1 -1
  11. package/fesm2022/siemens-element-ng-column-selection-dialog.mjs +2 -2
  12. package/fesm2022/siemens-element-ng-column-selection-dialog.mjs.map +1 -1
  13. package/fesm2022/siemens-element-ng-dashboard.mjs +4 -4
  14. package/fesm2022/siemens-element-ng-dashboard.mjs.map +1 -1
  15. package/fesm2022/siemens-element-ng-date-range-filter.mjs +2 -2
  16. package/fesm2022/siemens-element-ng-date-range-filter.mjs.map +1 -1
  17. package/fesm2022/siemens-element-ng-datepicker.mjs +4 -4
  18. package/fesm2022/siemens-element-ng-datepicker.mjs.map +1 -1
  19. package/fesm2022/siemens-element-ng-file-uploader.mjs +2 -2
  20. package/fesm2022/siemens-element-ng-file-uploader.mjs.map +1 -1
  21. package/fesm2022/siemens-element-ng-filtered-search.mjs +2 -2
  22. package/fesm2022/siemens-element-ng-filtered-search.mjs.map +1 -1
  23. package/fesm2022/siemens-element-ng-form.mjs +19 -6
  24. package/fesm2022/siemens-element-ng-form.mjs.map +1 -1
  25. package/fesm2022/siemens-element-ng-formly.mjs +4 -4
  26. package/fesm2022/siemens-element-ng-formly.mjs.map +1 -1
  27. package/fesm2022/siemens-element-ng-icon.mjs +1 -1
  28. package/fesm2022/siemens-element-ng-icon.mjs.map +1 -1
  29. package/fesm2022/siemens-element-ng-info-page.mjs +2 -2
  30. package/fesm2022/siemens-element-ng-info-page.mjs.map +1 -1
  31. package/fesm2022/siemens-element-ng-landing-page.mjs +4 -4
  32. package/fesm2022/siemens-element-ng-landing-page.mjs.map +1 -1
  33. package/fesm2022/siemens-element-ng-list-details.mjs +62 -16
  34. package/fesm2022/siemens-element-ng-list-details.mjs.map +1 -1
  35. package/fesm2022/siemens-element-ng-main-detail-container.mjs +72 -24
  36. package/fesm2022/siemens-element-ng-main-detail-container.mjs.map +1 -1
  37. package/fesm2022/siemens-element-ng-maplibre.mjs +282 -6
  38. package/fesm2022/siemens-element-ng-maplibre.mjs.map +1 -1
  39. package/fesm2022/siemens-element-ng-markdown-hightlighter-highlightjs.mjs +2 -2
  40. package/fesm2022/siemens-element-ng-markdown-hightlighter-highlightjs.mjs.map +1 -1
  41. package/fesm2022/siemens-element-ng-menu.mjs +6 -6
  42. package/fesm2022/siemens-element-ng-menu.mjs.map +1 -1
  43. package/fesm2022/siemens-element-ng-navbar-vertical-next.mjs +6 -6
  44. package/fesm2022/siemens-element-ng-navbar-vertical-next.mjs.map +1 -1
  45. package/fesm2022/siemens-element-ng-navbar-vertical.mjs +4 -4
  46. package/fesm2022/siemens-element-ng-navbar-vertical.mjs.map +1 -1
  47. package/fesm2022/siemens-element-ng-result-details-list.mjs +2 -2
  48. package/fesm2022/siemens-element-ng-result-details-list.mjs.map +1 -1
  49. package/fesm2022/siemens-element-ng-select.mjs +44 -5
  50. package/fesm2022/siemens-element-ng-select.mjs.map +1 -1
  51. package/fesm2022/siemens-element-ng-side-panel.mjs +48 -13
  52. package/fesm2022/siemens-element-ng-side-panel.mjs.map +1 -1
  53. package/fesm2022/siemens-element-ng-slider.mjs +2 -2
  54. package/fesm2022/siemens-element-ng-slider.mjs.map +1 -1
  55. package/fesm2022/siemens-element-ng-source-chip.mjs +2 -2
  56. package/fesm2022/siemens-element-ng-source-chip.mjs.map +1 -1
  57. package/fesm2022/siemens-element-ng-split.mjs +18 -16
  58. package/fesm2022/siemens-element-ng-split.mjs.map +1 -1
  59. package/fesm2022/siemens-element-ng-status-bar.mjs +2 -2
  60. package/fesm2022/siemens-element-ng-status-bar.mjs.map +1 -1
  61. package/fesm2022/siemens-element-ng-status-toggle.mjs +2 -2
  62. package/fesm2022/siemens-element-ng-status-toggle.mjs.map +1 -1
  63. package/fesm2022/siemens-element-ng-summary-chip.mjs +2 -2
  64. package/fesm2022/siemens-element-ng-summary-chip.mjs.map +1 -1
  65. package/fesm2022/siemens-element-ng-summary-widget.mjs +2 -2
  66. package/fesm2022/siemens-element-ng-summary-widget.mjs.map +1 -1
  67. package/fesm2022/siemens-element-ng-system-banner.mjs +5 -5
  68. package/fesm2022/siemens-element-ng-system-banner.mjs.map +1 -1
  69. package/fesm2022/siemens-element-ng-tabs.mjs +93 -71
  70. package/fesm2022/siemens-element-ng-tabs.mjs.map +1 -1
  71. package/fesm2022/siemens-element-ng-toast-notification.mjs +2 -2
  72. package/fesm2022/siemens-element-ng-toast-notification.mjs.map +1 -1
  73. package/fesm2022/siemens-element-ng-tour.mjs +2 -2
  74. package/fesm2022/siemens-element-ng-tour.mjs.map +1 -1
  75. package/fesm2022/siemens-element-ng-translate.mjs.map +1 -1
  76. package/fesm2022/siemens-element-ng-tree-view.mjs +4 -4
  77. package/fesm2022/siemens-element-ng-tree-view.mjs.map +1 -1
  78. package/package.json +4 -4
  79. package/schematics/collection.json +5 -0
  80. package/schematics/migrate-tabs-legacy/index.js +5 -0
  81. package/schematics/migrate-tabs-legacy/migrate-tabs-legacy-rule.js +675 -0
  82. package/schematics/migrate-tabs-legacy/schema.json +14 -0
  83. package/schematics/migrations/data/css-custom-properties.js +67 -1
  84. package/schematics/migrations/data/element-class-changes.js +31 -12
  85. package/schematics/ng-update/migrate-list-details-units.js +86 -0
  86. package/schematics/ng-update/migrate-main-detail-units.js +89 -0
  87. package/schematics/ng-update/migrate-split-collapse.js +1 -32
  88. package/schematics/ng-update/migrate-split-scale.js +524 -0
  89. package/schematics/ng-update/migrate-split-sizes.js +5 -3
  90. package/schematics/ng-update/migrate-to-v51.js +6 -0
  91. package/schematics/utils/index.js +1 -0
  92. package/schematics/utils/template-edit-utils.js +35 -0
  93. package/schematics/utils/template-utils.js +31 -45
  94. package/template-i18n.json +1 -0
  95. package/types/siemens-element-ng-avatar.d.ts +1 -1
  96. package/types/siemens-element-ng-chat-messages.d.ts +81 -17
  97. package/types/siemens-element-ng-form.d.ts +3 -0
  98. package/types/siemens-element-ng-list-details.d.ts +25 -3
  99. package/types/siemens-element-ng-main-detail-container.d.ts +23 -3
  100. package/types/siemens-element-ng-maplibre.d.ts +131 -7
  101. package/types/siemens-element-ng-select.d.ts +31 -4
  102. package/types/siemens-element-ng-side-panel.d.ts +17 -3
  103. package/types/siemens-element-ng-split.d.ts +3 -10
  104. package/types/siemens-element-ng-system-banner.d.ts +2 -2
  105. package/types/siemens-element-ng-translate.d.ts +1 -0
@@ -154,5 +154,71 @@ export const CSS_CUSTOM_PROPERTIES_MIGRATION = [
154
154
  {
155
155
  replace: '$si-font-weight-display-4',
156
156
  replaceWith: '$si-font-weight-display'
157
- }
157
+ },
158
+ {
159
+ replace: '$box-shadow',
160
+ replaceWith: '$si-sys-effects-shadow-2'
161
+ },
162
+ {
163
+ replace: '$box-shadow-sm',
164
+ replaceWith: '$si-sys-effects-shadow-1'
165
+ },
166
+ {
167
+ replace: '$box-shadow-lg',
168
+ replaceWith: '$si-sys-effects-shadow-3'
169
+ },
170
+ {
171
+ replace: '$popover-box-shadow',
172
+ replaceWith: '$si-sys-effects-shadow-3'
173
+ },
174
+ {
175
+ replace: '$modal-content-box-shadow-xs',
176
+ replaceWith: '$si-sys-effects-shadow-3'
177
+ },
178
+ {
179
+ replace: '$modal-content-box-shadow-sm-up',
180
+ replaceWith: '$si-sys-effects-shadow-2'
181
+ },
182
+ {
183
+ replace: '$thumbnail-box-shadow',
184
+ replaceWith: '$si-sys-effects-shadow-1'
185
+ },
186
+ {
187
+ replace: '$element-elevation-1',
188
+ replaceWith: '$si-sys-effects-shadow-1'
189
+ },
190
+ {
191
+ replace: '$element-elevation-2',
192
+ replaceWith: '$si-sys-effects-shadow-2'
193
+ },
194
+ {
195
+ replace: '$element-elevation-3',
196
+ replaceWith: '$si-sys-effects-shadow-3'
197
+ },
198
+ {
199
+ replace: '$element-elevation-4',
200
+ replaceWith: '$si-sys-effects-shadow-4'
201
+ },
202
+ ...['font-size', 'line-height', 'font-weight'].flatMap(property => [
203
+ {
204
+ replace: `$si-${property}-h1-bold`,
205
+ replaceWith: `$si-${property}-h1`
206
+ },
207
+ {
208
+ replace: `$si-${property}-h4-bold`,
209
+ replaceWith: `$si-${property}-h4`
210
+ },
211
+ {
212
+ replace: `$si-${property}-body-lg-bold`,
213
+ replaceWith: `$si-${property}-body-lg-sbold`
214
+ },
215
+ {
216
+ replace: `$si-${property}-caption`,
217
+ replaceWith: `$si-${property}-body-sm`
218
+ },
219
+ {
220
+ replace: `$si-${property}-display-bold`,
221
+ replaceWith: `$si-${property}-display-lg-sbold`
222
+ }
223
+ ])
158
224
  ];
@@ -4,13 +4,13 @@
4
4
  */
5
5
  export const ELEMENT_CLASS_CHANGES_MIGRATION = [
6
6
  ...[
7
- ['bg-primary', 'background-accent'],
8
- ['bg-secondary', 'background-neutral'],
7
+ ['bg-primary', 'background-accent', ['badge']],
8
+ ['bg-secondary', 'background-neutral', ['badge']],
9
9
  ['bg-tertiary', 'background-4'],
10
- ['bg-success', 'background-success'],
11
- ['bg-info', 'background-information'],
12
- ['bg-warning', 'background-warning'],
13
- ['bg-danger', 'background-danger'],
10
+ ['bg-success', 'background-success', ['badge']],
11
+ ['bg-info', 'background-information', ['badge']],
12
+ ['bg-warning', 'background-warning', ['badge']],
13
+ ['bg-danger', 'background-danger', ['badge']],
14
14
  ['bg-base-0', 'background-0'],
15
15
  ['bg-base-1', 'background-1'],
16
16
  ['bg-base-2', 'background-2'],
@@ -28,9 +28,18 @@ export const ELEMENT_CLASS_CHANGES_MIGRATION = [
28
28
  ['text-body', 'text-primary'],
29
29
  ['text-tertiary', 'text-disabled'],
30
30
  ['text-muted', 'text-disabled'],
31
- ['text-info', 'text-information']
32
- ].map(([oldClass, newClass]) => ({
31
+ ['text-info', 'text-information'],
32
+ ['shadow', 'shadow-2'],
33
+ ['shadow-sm', 'shadow-1'],
34
+ ['shadow-lg', 'shadow-3'],
35
+ ['elevation-none', 'shadow-none'],
36
+ ['elevation-1', 'shadow-1'],
37
+ ['elevation-2', 'shadow-2'],
38
+ ['elevation-3', 'shadow-3'],
39
+ ['elevation-4', 'shadow-4']
40
+ ].map(([oldClass, newClass, excludedClasses]) => ({
33
41
  requiredClasses: [oldClass],
42
+ excludedClasses,
34
43
  removeClasses: [oldClass],
35
44
  addClasses: [newClass]
36
45
  })),
@@ -56,12 +65,12 @@ export const ELEMENT_CLASS_CHANGES_MIGRATION = [
56
65
  {
57
66
  requiredClasses: ['si-h1-black'],
58
67
  removeClasses: ['si-h1-black'],
59
- addClasses: ['si-h1-bold']
68
+ addClasses: ['si-h1']
60
69
  },
61
70
  {
62
71
  requiredClasses: ['si-title-1-bold'],
63
72
  removeClasses: ['si-title-1-bold'],
64
- addClasses: ['si-h4-bold']
73
+ addClasses: ['si-h4']
65
74
  },
66
75
  {
67
76
  requiredClasses: ['si-title-1'],
@@ -101,11 +110,21 @@ export const ELEMENT_CLASS_CHANGES_MIGRATION = [
101
110
  {
102
111
  requiredClasses: ['si-display-3'],
103
112
  removeClasses: ['si-display-3'],
104
- addClasses: ['si-display-bold']
113
+ addClasses: ['si-display-lg-sbold']
105
114
  },
106
115
  {
107
116
  requiredClasses: ['si-display-4'],
108
117
  removeClasses: ['si-display-4'],
109
118
  addClasses: ['si-display']
110
- }
119
+ },
120
+ ...[
121
+ ['si-h1-bold', 'si-h1'],
122
+ ['si-h4-bold', 'si-h4'],
123
+ ['si-caption', 'si-body-sm'],
124
+ ['si-display-bold', 'si-display-lg-sbold']
125
+ ].map(([oldClass, newClass]) => ({
126
+ requiredClasses: [oldClass],
127
+ removeClasses: [oldClass],
128
+ addClasses: [newClass]
129
+ }))
111
130
  ];
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Copyright (c) Siemens 2016 - 2026
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+ import { dirname, join } from 'path/posix';
6
+ import ts from 'typescript';
7
+ import { discoverSourceFiles, findElement, getInlineTemplates, getTemplateUrl, insertAttribute } from '../utils/index.js';
8
+ const disableResizingAttributeNames = [
9
+ 'disableResizing',
10
+ '[disableResizing]',
11
+ 'bind-disableResizing'
12
+ ];
13
+ const listWidthUnitAttributeNames = ['listWidthUnit', '[listWidthUnit]', 'bind-listWidthUnit'];
14
+ export const listDetailsUnitsMigrationRule = (options) => {
15
+ return async (tree, context) => {
16
+ const processedTemplates = new Set();
17
+ for await (const discoveredSourceFile of discoverSourceFiles(tree, context, options.path)) {
18
+ const { path: filePath, sourceFile } = discoveredSourceFile;
19
+ const recorder = tree.beginUpdate(filePath);
20
+ for (const template of getInlineTemplates(sourceFile)) {
21
+ migrateListDetailsUnitsTemplate(sourceFile.text.substring(template.getStart() + 1, template.getEnd() - 1), template.getStart() + 1, recorder);
22
+ }
23
+ tree.commitUpdate(recorder);
24
+ for (const templateUrl of getTemplateUrl(sourceFile)) {
25
+ const templatePath = join(dirname(filePath), templateUrl);
26
+ if (processedTemplates.has(templatePath) || !tree.exists(templatePath)) {
27
+ continue;
28
+ }
29
+ processedTemplates.add(templatePath);
30
+ const templateRecorder = tree.beginUpdate(templatePath);
31
+ migrateListDetailsUnitsTemplate(tree.read(templatePath).toString('utf-8'), 0, templateRecorder);
32
+ tree.commitUpdate(templateRecorder);
33
+ }
34
+ }
35
+ return tree;
36
+ };
37
+ };
38
+ const migrateListDetailsUnitsTemplate = (template, offset, recorder) => {
39
+ findElement(template, element => element.name === 'si-list-details').forEach(element => {
40
+ migrateListDetailsElement(template, element, offset, recorder);
41
+ });
42
+ };
43
+ const migrateListDetailsElement = (template, element, offset, recorder) => {
44
+ const disableResizingAttribute = element.attrs.find(attr => disableResizingAttributeNames.includes(attr.name));
45
+ const isExplicitlyDisabled = disableResizingAttribute && getStaticBooleanValue(disableResizingAttribute) === true;
46
+ if (isExplicitlyDisabled) {
47
+ return;
48
+ }
49
+ const hasListWidthUnit = element.attrs.some(attr => listWidthUnitAttributeNames.includes(attr.name));
50
+ if (hasListWidthUnit) {
51
+ return;
52
+ }
53
+ insertAttribute(template, element, 'listWidthUnit="fr"', offset, recorder);
54
+ };
55
+ const getStaticBooleanValue = (attribute) => {
56
+ if (!attribute.name.startsWith('[')) {
57
+ if (/^\s*{{[\s\S]*}}\s*$/.test(attribute.value)) {
58
+ return undefined;
59
+ }
60
+ return attribute.value !== 'false';
61
+ }
62
+ const initializer = getExpression(attribute.value);
63
+ if (!initializer) {
64
+ return undefined;
65
+ }
66
+ if (initializer.kind === ts.SyntaxKind.TrueKeyword) {
67
+ return true;
68
+ }
69
+ if (initializer.kind === ts.SyntaxKind.FalseKeyword ||
70
+ initializer.kind === ts.SyntaxKind.NullKeyword ||
71
+ (ts.isIdentifier(initializer) && initializer.text === 'undefined') ||
72
+ (ts.isStringLiteral(initializer) && initializer.text === 'false')) {
73
+ return false;
74
+ }
75
+ if (ts.isStringLiteral(initializer) || ts.isNumericLiteral(initializer)) {
76
+ return true;
77
+ }
78
+ return undefined;
79
+ };
80
+ const getExpression = (value) => {
81
+ const statement = ts.createSourceFile('template-expression.ts', `const value = ${value};`, ts.ScriptTarget.Latest, true).statements[0];
82
+ if (!statement || !ts.isVariableStatement(statement)) {
83
+ return undefined;
84
+ }
85
+ return statement.declarationList.declarations[0]?.initializer;
86
+ };
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Copyright (c) Siemens 2016 - 2026
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+ import { dirname, join } from 'path/posix';
6
+ import ts from 'typescript';
7
+ import { discoverSourceFiles, findElement, getInlineTemplates, getTemplateUrl, insertAttribute } from '../utils/index.js';
8
+ const resizableAttributeNames = ['resizableParts', '[resizableParts]', 'bind-resizableParts'];
9
+ const mainUnitAttributeNames = [
10
+ 'mainContainerWidthUnit',
11
+ '[mainContainerWidthUnit]',
12
+ 'bind-mainContainerWidthUnit'
13
+ ];
14
+ export const mainDetailUnitsMigrationRule = (options) => {
15
+ return async (tree, context) => {
16
+ const processedTemplates = new Set();
17
+ for await (const discoveredSourceFile of discoverSourceFiles(tree, context, options.path)) {
18
+ const { path: filePath, sourceFile } = discoveredSourceFile;
19
+ const recorder = tree.beginUpdate(filePath);
20
+ for (const template of getInlineTemplates(sourceFile)) {
21
+ migrateMainDetailUnitsTemplate(sourceFile.text.substring(template.getStart() + 1, template.getEnd() - 1), template.getStart() + 1, recorder);
22
+ }
23
+ tree.commitUpdate(recorder);
24
+ for (const templateUrl of getTemplateUrl(sourceFile)) {
25
+ const templatePath = join(dirname(filePath), templateUrl);
26
+ if (processedTemplates.has(templatePath) || !tree.exists(templatePath)) {
27
+ continue;
28
+ }
29
+ processedTemplates.add(templatePath);
30
+ const templateRecorder = tree.beginUpdate(templatePath);
31
+ migrateMainDetailUnitsTemplate(tree.read(templatePath).toString('utf-8'), 0, templateRecorder);
32
+ tree.commitUpdate(templateRecorder);
33
+ }
34
+ }
35
+ return tree;
36
+ };
37
+ };
38
+ const migrateMainDetailUnitsTemplate = (template, offset, recorder) => {
39
+ findElement(template, element => element.name === 'si-main-detail-container').forEach(element => {
40
+ migrateMainDetailContainerElement(template, element, offset, recorder);
41
+ });
42
+ };
43
+ const migrateMainDetailContainerElement = (template, element, offset, recorder) => {
44
+ const resizableAttribute = element.attrs.find(attr => resizableAttributeNames.includes(attr.name));
45
+ if (!resizableAttribute) {
46
+ return;
47
+ }
48
+ const isExplicitlyDisabled = getStaticBooleanValue(resizableAttribute) === false;
49
+ if (isExplicitlyDisabled) {
50
+ return;
51
+ }
52
+ const hasMainUnit = element.attrs.some(attr => mainUnitAttributeNames.includes(attr.name));
53
+ if (hasMainUnit) {
54
+ return;
55
+ }
56
+ insertAttribute(template, element, 'mainContainerWidthUnit="fr"', offset, recorder);
57
+ };
58
+ const getStaticBooleanValue = (attribute) => {
59
+ if (!attribute.name.startsWith('[')) {
60
+ if (/^\s*{{[\s\S]*}}\s*$/.test(attribute.value)) {
61
+ return undefined;
62
+ }
63
+ return attribute.value !== 'false';
64
+ }
65
+ const initializer = getExpression(attribute.value);
66
+ if (!initializer) {
67
+ return undefined;
68
+ }
69
+ if (initializer.kind === ts.SyntaxKind.TrueKeyword) {
70
+ return true;
71
+ }
72
+ if (initializer.kind === ts.SyntaxKind.FalseKeyword ||
73
+ initializer.kind === ts.SyntaxKind.NullKeyword ||
74
+ (ts.isIdentifier(initializer) && initializer.text === 'undefined') ||
75
+ (ts.isStringLiteral(initializer) && initializer.text === 'false')) {
76
+ return false;
77
+ }
78
+ if (ts.isStringLiteral(initializer) || ts.isNumericLiteral(initializer)) {
79
+ return true;
80
+ }
81
+ return undefined;
82
+ };
83
+ const getExpression = (value) => {
84
+ const statement = ts.createSourceFile('template-expression.ts', `const value = ${value};`, ts.ScriptTarget.Latest, true).statements[0];
85
+ if (!statement || !ts.isVariableStatement(statement)) {
86
+ return undefined;
87
+ }
88
+ return statement.declarationList.declarations[0]?.initializer;
89
+ };
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { dirname, join } from 'path/posix';
6
6
  import ts from 'typescript';
7
- import { discoverSourceFiles, findElement, getInlineTemplates, getTemplateUrl } from '../utils/index.js';
7
+ import { discoverSourceFiles, findElement, formatBoundAttribute, getInlineTemplates, getTemplateUrl, insertAttribute, removeAttribute, replaceAttribute } from '../utils/index.js';
8
8
  const collapseValues = new Map([
9
9
  ['start', 'to-start'],
10
10
  ['end', 'to-end']
@@ -132,37 +132,6 @@ const getShowCollapseButtonExpression = (attribute) => {
132
132
  return attribute.value.replace(/^\s*{{\s*|\s*}}\s*$/g, '');
133
133
  };
134
134
  const getBooleanAttributeCondition = (expression) => `![false, null, undefined, 'false'].includes($any(${expression}))`;
135
- const formatBoundAttribute = (name, expression) => {
136
- const quote = expression.includes('"') && !expression.includes("'") ? "'" : '"';
137
- const escapedExpression = quote === '"' ? expression.replaceAll('"', '"') : expression.replaceAll("'", ''');
138
- return `[${name}]=${quote}${escapedExpression}${quote}`;
139
- };
140
- const replaceAttribute = (attribute, replacement, offset, recorder) => {
141
- const start = attribute.sourceSpan.start.offset + offset;
142
- recorder.remove(start, attribute.sourceSpan.end.offset - attribute.sourceSpan.start.offset);
143
- recorder.insertLeft(start, replacement);
144
- };
145
- const insertAttribute = (template, element, attribute, offset, recorder) => {
146
- const selfClosing = element.startSourceSpan.toString().endsWith('/>');
147
- const insertOffset = element.startSourceSpan.end.offset - (selfClosing ? 2 : 1);
148
- const prefix = /\s/.test(template[insertOffset - 1]) ? '' : ' ';
149
- recorder.insertLeft(insertOffset + offset, `${prefix}${attribute}${selfClosing ? ' ' : ''}`);
150
- };
151
- const removeAttribute = (template, attribute, offset, recorder) => {
152
- const start = attribute.sourceSpan.start.offset;
153
- const end = attribute.sourceSpan.end.offset;
154
- const lineStart = template.lastIndexOf('\n', start - 1) + 1;
155
- const lineEnd = template.indexOf('\n', end);
156
- const endOfLine = lineEnd === -1 ? template.length : lineEnd;
157
- if (template.slice(lineStart, start).trim() === '' &&
158
- template.slice(end, endOfLine).trim() === '') {
159
- const removeEnd = lineEnd === -1 ? endOfLine : lineEnd + 1;
160
- recorder.remove(lineStart + offset, removeEnd - lineStart);
161
- return;
162
- }
163
- const removeStart = start > 0 && /\s/.test(template[start - 1]) ? start - 1 : start;
164
- recorder.remove(removeStart + offset, attribute.sourceSpan.end.offset - removeStart);
165
- };
166
135
  const getStringLiteral = (value) => {
167
136
  const initializer = getExpression(value);
168
137
  return initializer && ts.isStringLiteral(initializer)