@siemens/element-ng 48.2.0 → 48.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 (63) hide show
  1. package/accordion/index.d.ts +5 -1
  2. package/application-header/index.d.ts +15 -2
  3. package/chat-messages/index.d.ts +654 -0
  4. package/chat-messages/package.json +3 -0
  5. package/dashboard/index.d.ts +1 -0
  6. package/fesm2022/siemens-element-ng-accordion.mjs +5 -1
  7. package/fesm2022/siemens-element-ng-accordion.mjs.map +1 -1
  8. package/fesm2022/siemens-element-ng-application-header.mjs +62 -1
  9. package/fesm2022/siemens-element-ng-application-header.mjs.map +1 -1
  10. package/fesm2022/siemens-element-ng-card.mjs +4 -4
  11. package/fesm2022/siemens-element-ng-card.mjs.map +1 -1
  12. package/fesm2022/siemens-element-ng-chat-messages.mjs +863 -0
  13. package/fesm2022/siemens-element-ng-chat-messages.mjs.map +1 -0
  14. package/fesm2022/siemens-element-ng-dashboard.mjs +8 -4
  15. package/fesm2022/siemens-element-ng-dashboard.mjs.map +1 -1
  16. package/fesm2022/siemens-element-ng-file-uploader.mjs +277 -118
  17. package/fesm2022/siemens-element-ng-file-uploader.mjs.map +1 -1
  18. package/fesm2022/siemens-element-ng-filtered-search.mjs +3 -4
  19. package/fesm2022/siemens-element-ng-filtered-search.mjs.map +1 -1
  20. package/fesm2022/siemens-element-ng-icon.mjs +3 -1
  21. package/fesm2022/siemens-element-ng-icon.mjs.map +1 -1
  22. package/fesm2022/siemens-element-ng-ip-input.mjs +92 -89
  23. package/fesm2022/siemens-element-ng-ip-input.mjs.map +1 -1
  24. package/fesm2022/siemens-element-ng-markdown-renderer.mjs +253 -0
  25. package/fesm2022/siemens-element-ng-markdown-renderer.mjs.map +1 -0
  26. package/fesm2022/siemens-element-ng-phone-number.mjs +5 -4
  27. package/fesm2022/siemens-element-ng-phone-number.mjs.map +1 -1
  28. package/fesm2022/siemens-element-ng-popover.mjs +3 -4
  29. package/fesm2022/siemens-element-ng-popover.mjs.map +1 -1
  30. package/fesm2022/siemens-element-ng-resize-observer.mjs +13 -0
  31. package/fesm2022/siemens-element-ng-resize-observer.mjs.map +1 -1
  32. package/fesm2022/siemens-element-ng-translate.mjs.map +1 -1
  33. package/fesm2022/siemens-element-ng-tree-view.mjs +41 -2
  34. package/fesm2022/siemens-element-ng-tree-view.mjs.map +1 -1
  35. package/file-uploader/index.d.ts +119 -15
  36. package/icon/index.d.ts +3 -1
  37. package/ip-input/index.d.ts +13 -0
  38. package/markdown-renderer/index.d.ts +36 -0
  39. package/markdown-renderer/package.json +3 -0
  40. package/package.json +11 -3
  41. package/resize-observer/index.d.ts +13 -0
  42. package/schematics/migrations/action-modal-migration/action-modal-migration.js +2 -2
  43. package/schematics/migrations/data/attribute-selectors.js +6 -0
  44. package/schematics/migrations/data/component-names.js +78 -0
  45. package/schematics/migrations/data/element-selectors.js +10 -0
  46. package/schematics/migrations/data/index.js +17 -0
  47. package/schematics/migrations/data/output-names.js +8 -0
  48. package/schematics/migrations/data/symbol-removals.js +58 -0
  49. package/schematics/migrations/element-migration/element-migration.js +101 -0
  50. package/schematics/migrations/element-migration/index.js +5 -0
  51. package/schematics/migrations/index.js +7 -2
  52. package/schematics/migrations/wizard-migration/index.js +88 -0
  53. package/schematics/scss-import-to-siemens-migration/index.js +3 -3
  54. package/schematics/ts-import-to-siemens-migration/index.js +2 -2
  55. package/schematics/utils/index.js +3 -3
  56. package/schematics/utils/project-utils.js +24 -35
  57. package/schematics/utils/template-utils.js +78 -2
  58. package/schematics/utils/ts-utils.js +5 -5
  59. package/template-i18n.json +9 -0
  60. package/translate/index.d.ts +9 -0
  61. package/tree-view/index.d.ts +40 -1
  62. package/schematics/migrations/to-legacy-migration/to-legacy-migration.js +0 -55
  63. package/schematics/migrations/to-legacy-migration/to-legacy-replacement.js +0 -35
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Copyright (c) Siemens 2016 - 2025
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+ import { join, dirname } from 'path';
6
+ import * as ts from 'typescript';
7
+ import { discoverSourceFiles, findElement, getImportSpecifiers, getInlineTemplates, getTemplateUrl } from '../../utils/index.js';
8
+ export const wizardMigrationRule = (options) => {
9
+ return async (tree, context) => {
10
+ context.logger.info('🔄 Migrating wizard api...');
11
+ const tsSourceFiles = await discoverSourceFiles(tree, context, options.path);
12
+ for (const filePath of tsSourceFiles) {
13
+ const content = tree.read(filePath);
14
+ if (!content) {
15
+ continue;
16
+ }
17
+ const sourceFile = ts.createSourceFile(filePath, content.toString(), ts.ScriptTarget.Latest, true);
18
+ const modulePathToMatch = /@(siemens|simpl)\/element-ng(\/wizard)?/;
19
+ const wizardImports = getImportSpecifiers(sourceFile, modulePathToMatch, [
20
+ 'SiWizardComponent',
21
+ 'SiWizardModule'
22
+ ]);
23
+ if (!wizardImports?.length) {
24
+ continue;
25
+ }
26
+ const recorder = tree.beginUpdate(filePath);
27
+ renameApi({
28
+ tree,
29
+ filePath,
30
+ sourceFile,
31
+ recorder,
32
+ elementName: 'si-wizard'
33
+ });
34
+ if (recorder) {
35
+ tree.commitUpdate(recorder);
36
+ }
37
+ }
38
+ };
39
+ };
40
+ const renameApi = ({ tree, filePath, sourceFile, recorder, elementName }) => {
41
+ getInlineTemplates(sourceFile).forEach(template => addOrRemoveInlineNavigationAttribute({
42
+ template: template.text,
43
+ offset: template.getStart() + 1,
44
+ elementName,
45
+ recorder
46
+ }));
47
+ getTemplateUrl(sourceFile).forEach(templateUrl => {
48
+ const templatePath = join(dirname(filePath), templateUrl);
49
+ const templateContent = tree.read(templatePath).toString('utf-8');
50
+ const templateRecorder = tree.beginUpdate(templatePath);
51
+ addOrRemoveInlineNavigationAttribute({
52
+ template: templateContent,
53
+ offset: 0,
54
+ elementName,
55
+ recorder: templateRecorder
56
+ });
57
+ tree.commitUpdate(templateRecorder);
58
+ });
59
+ };
60
+ /**
61
+ * Migrates the inlineNavigation attribute on wizard elements.
62
+ * - Adds `inlineNavigation` when not present (new default: true)
63
+ * - Removes `[inlineNavigation]="false"` (false is now the default)
64
+ * - Keeps `[inlineNavigation]="true"` and dynamic bindings unchanged
65
+ */
66
+ const addOrRemoveInlineNavigationAttribute = ({ template, offset, recorder, elementName }) => {
67
+ const elements = findElement(template, element => element.name === elementName);
68
+ for (const element of elements) {
69
+ const inlineNavigationAttr = element.attrs.find(attr => attr.name === '[inlineNavigation]' || attr.name === 'inlineNavigation');
70
+ if (!inlineNavigationAttr) {
71
+ // No attribute exists → Add default inlineNavigation
72
+ const insertPosition = element.startSourceSpan.end.offset + offset - 1;
73
+ recorder.insertLeft(insertPosition, ' inlineNavigation');
74
+ }
75
+ else if ((inlineNavigationAttr.name === '[inlineNavigation]' ||
76
+ inlineNavigationAttr.name === 'inlineNavigation') &&
77
+ inlineNavigationAttr.value === 'false') {
78
+ const { start, end } = inlineNavigationAttr.sourceSpan;
79
+ const length = end.offset - start.offset;
80
+ recorder.remove(start.offset + offset, length);
81
+ // Also remove extra whitespace if present
82
+ const nextChar = template.charAt(end.offset);
83
+ if (nextChar === ' ') {
84
+ recorder.remove(end.offset + offset, 1);
85
+ }
86
+ }
87
+ }
88
+ };
@@ -26,10 +26,10 @@ export const scssImportMigration = (_options) => {
26
26
  * ```
27
27
  */
28
28
  export const scssMigrationRule = (_options) => {
29
- return (tree, context) => {
29
+ return async (tree, context) => {
30
30
  const rules = [];
31
31
  context.logger.info('🎨 Migrating SCSS styles...');
32
- const globalStyles = getGlobalStyles(tree);
32
+ const globalStyles = await getGlobalStyles(tree);
33
33
  for (const style of globalStyles) {
34
34
  if (style.endsWith('.scss') || style.endsWith('.sass')) {
35
35
  const content = tree.readText(style);
@@ -51,7 +51,7 @@ export const scssMigrationRule = (_options) => {
51
51
  }
52
52
  }
53
53
  }
54
- const scssFiles = discoverSourceFiles(tree, context, _options.path, '.scss');
54
+ const scssFiles = await discoverSourceFiles(tree, context, _options.path, '.scss');
55
55
  for (const filePath of scssFiles) {
56
56
  const content = tree.readText(filePath);
57
57
  if (content.includes(STYLE_REPLACEMENTS[0].replace) ||
@@ -27,10 +27,10 @@ export const tsImportMigration = (_options) => {
27
27
  * ```
28
28
  */
29
29
  export const tsImportMigrationRule = (_options) => {
30
- return (tree, context) => {
30
+ return async (tree, context) => {
31
31
  const rules = [];
32
32
  context.logger.info('📦 Migrating TypeScript imports...');
33
- const sourceFiles = discoverSourceFiles(tree, context, _options.path);
33
+ const sourceFiles = await discoverSourceFiles(tree, context, _options.path);
34
34
  for (const filePath of sourceFiles) {
35
35
  const migrations = collectMigrationImports(filePath, tree, context);
36
36
  const { imports, toRemoveImports } = migrations;
@@ -2,9 +2,9 @@
2
2
  * Copyright (c) Siemens 2016 - 2025
3
3
  * SPDX-License-Identifier: MIT
4
4
  */
5
+ export * from './html-utils.js';
5
6
  export * from './project-utils.js';
6
- export * from './ts-utils.js';
7
- export * from './testing.js';
8
7
  export * from './schematics-file-system.js';
9
- export * from './html-utils.js';
10
8
  export * from './template-utils.js';
9
+ export * from './testing.js';
10
+ export * from './ts-utils.js';
@@ -4,44 +4,46 @@
4
4
  */
5
5
  import { normalize } from '@angular-devkit/core';
6
6
  import { SchematicsException } from '@angular-devkit/schematics';
7
+ import { allTargetOptions, allWorkspaceTargets, getWorkspace } from '@schematics/angular/utility/workspace';
7
8
  import { dirname, isAbsolute, resolve } from 'path';
8
9
  import { parseTsconfigFile } from './ts-utils.js';
9
- export const getGlobalStyles = (tree) => {
10
+ export const getGlobalStyles = async (tree) => {
10
11
  const globalStyles = new Set();
11
- for (const target of getTargets(getWorkspace(tree))) {
12
- if (target.options?.styles && Array.isArray(target.options.styles)) {
13
- target.options.styles.forEach((style) => {
14
- if (typeof style === 'string') {
15
- globalStyles.add(normalize(style));
12
+ for (const [name, target] of allWorkspaceTargets(await getWorkspace(tree))) {
13
+ if (['build', 'test'].includes(name)) {
14
+ for (const [, opt] of allTargetOptions(target)) {
15
+ if (opt.styles && Array.isArray(opt.styles)) {
16
+ opt.styles.forEach((style) => {
17
+ if (typeof style === 'string') {
18
+ globalStyles.add(normalize(style));
19
+ }
20
+ });
16
21
  }
17
- });
22
+ }
18
23
  }
19
24
  }
20
25
  return [...globalStyles];
21
26
  };
22
- export const getWorkspace = (tree) => {
23
- const workspace = tree.read('/angular.json');
24
- if (!workspace) {
25
- throw new SchematicsException('Could not find angular.json');
26
- }
27
- return JSON.parse(workspace.toString());
28
- };
29
- export const getTsConfigPaths = (tree) => {
27
+ export const getTsConfigPaths = async (tree) => {
30
28
  const buildPaths = new Set();
31
- for (const target of getTargets(getWorkspace(tree))) {
32
- if (target.options?.tsConfig && typeof target.options.tsConfig === 'string') {
33
- const tsConfig = target.options.tsConfig;
34
- if (tree.exists(tsConfig)) {
35
- buildPaths.add(normalize(tsConfig));
29
+ for (const [name, target] of allWorkspaceTargets(await getWorkspace(tree))) {
30
+ if (['build', 'test'].includes(name)) {
31
+ for (const [, opt] of allTargetOptions(target)) {
32
+ if (typeof opt?.tsConfig === 'string') {
33
+ const tsConfig = opt.tsConfig;
34
+ if (tree.exists(tsConfig)) {
35
+ buildPaths.add(normalize(tsConfig));
36
+ }
37
+ }
36
38
  }
37
39
  }
38
40
  }
39
41
  return [...buildPaths];
40
42
  };
41
- export const discoverSourceFiles = (tree, context, projectPath, extension = '.ts') => {
43
+ export const discoverSourceFiles = async (tree, context, projectPath, extension = '.ts') => {
42
44
  const basePath = normalize(process.cwd());
43
45
  // Wrap the tree to force full paths since parsing the typescript config requires full paths.
44
- const tsConfigs = getTsConfigPaths(tree);
46
+ const tsConfigs = await getTsConfigPaths(tree);
45
47
  if (!tsConfigs.length) {
46
48
  throw new SchematicsException('Could not find any tsconfig file. Cannot run the migration.');
47
49
  }
@@ -60,16 +62,3 @@ export const discoverSourceFiles = (tree, context, projectPath, extension = '.ts
60
62
  }
61
63
  return Array.from(new Set(sourceFiles)).map(p => p.substring(basePath.length + 1));
62
64
  };
63
- function* getTargets(workspace, targetNames = ['build', 'test']) {
64
- for (const [, projectRaw] of Object.entries(workspace.projects)) {
65
- const project = projectRaw;
66
- if (!project.architect) {
67
- continue;
68
- }
69
- for (const [name, target] of Object.entries(project.architect)) {
70
- if (targetNames.includes(name) && target) {
71
- yield target;
72
- }
73
- }
74
- }
75
- }
@@ -1,7 +1,7 @@
1
1
  import { join, dirname } from 'path';
2
2
  import ts from 'typescript';
3
3
  import { findAttribute, findElement } from './html-utils.js';
4
- const getInlineTemplates = (source) => {
4
+ export const getInlineTemplates = (source) => {
5
5
  const templateNodes = [];
6
6
  const componentDecoratorVisitor = (node) => {
7
7
  if (ts.isDecorator(node) &&
@@ -27,7 +27,7 @@ const getInlineTemplates = (source) => {
27
27
  source.forEachChild(componentDecoratorVisitor);
28
28
  return templateNodes;
29
29
  };
30
- const getTemplateUrl = (source) => {
30
+ export const getTemplateUrl = (source) => {
31
31
  const templateUrls = [];
32
32
  const componentDecoratorVisitor = (node) => {
33
33
  if (ts.isDecorator(node) &&
@@ -68,6 +68,36 @@ const renameAttributeInTemplate = ({ template, offset, recorder, fromName, toNam
68
68
  recorder.insertLeft(el.sourceSpan.start.offset + offset, toName);
69
69
  });
70
70
  };
71
+ const renameApiInTemplate = ({ template, offset, recorder, elementName, apis }) => {
72
+ findElement(template, element => element.name === elementName).forEach(el => {
73
+ for (const api of apis) {
74
+ el.attrs
75
+ .filter(attr => attr.name === api.replace)
76
+ .forEach(attr => {
77
+ recorder.remove(attr.sourceSpan.start.offset + offset, api.replace.length);
78
+ recorder.insertLeft(attr.sourceSpan.start.offset + offset, api.replaceWith);
79
+ });
80
+ }
81
+ });
82
+ };
83
+ const removeSymbols = ({ template, offset, recorder, elementName, attributeSelector, names }) => {
84
+ findElement(template, element => element.name === elementName).forEach(el => {
85
+ if (attributeSelector) {
86
+ const hasAttributeSelector = el.attrs.some(attr => attr.name === attributeSelector);
87
+ if (!hasAttributeSelector) {
88
+ return;
89
+ }
90
+ }
91
+ for (const name of names) {
92
+ el.attrs
93
+ .filter(attr => attr.name === name || attr.name === `[${name}]` || attr.name === `(${name})`)
94
+ .forEach(attr => {
95
+ const apiLength = attr.sourceSpan.toString().length;
96
+ recorder.remove(attr.sourceSpan.start.offset + offset, apiLength);
97
+ });
98
+ }
99
+ });
100
+ };
71
101
  export const renameElementTag = ({ tree, filePath, sourceFile, recorder, fromName, toName }) => {
72
102
  getInlineTemplates(sourceFile).forEach(template => renameElementTagInTemplate({
73
103
  template: template.text,
@@ -112,3 +142,49 @@ export const renameAttribute = ({ tree, filePath, sourceFile, recorder, fromName
112
142
  tree.commitUpdate(templateRecorder);
113
143
  });
114
144
  };
145
+ export const renameApi = ({ tree, filePath, sourceFile, recorder, elementName, apis }) => {
146
+ getInlineTemplates(sourceFile).forEach(template => renameApiInTemplate({
147
+ template: template.text,
148
+ offset: template.getStart() + 1,
149
+ elementName,
150
+ recorder,
151
+ apis
152
+ }));
153
+ getTemplateUrl(sourceFile).forEach(templateUrl => {
154
+ const templatePath = join(dirname(filePath), templateUrl);
155
+ const templateContent = tree.read(templatePath).toString('utf-8');
156
+ const templateRecorder = tree.beginUpdate(templatePath);
157
+ renameApiInTemplate({
158
+ template: templateContent,
159
+ offset: 0,
160
+ elementName,
161
+ recorder: templateRecorder,
162
+ apis
163
+ });
164
+ tree.commitUpdate(templateRecorder);
165
+ });
166
+ };
167
+ export const removeSymbol = ({ tree, filePath, sourceFile, recorder, elementName, attributeSelector, names }) => {
168
+ getInlineTemplates(sourceFile).forEach(template => removeSymbols({
169
+ template: template.text,
170
+ offset: template.getStart() + 1,
171
+ elementName,
172
+ attributeSelector,
173
+ recorder,
174
+ names
175
+ }));
176
+ getTemplateUrl(sourceFile).forEach(templateUrl => {
177
+ const templatePath = join(dirname(filePath), templateUrl);
178
+ const templateContent = tree.read(templatePath).toString('utf-8');
179
+ const templateRecorder = tree.beginUpdate(templatePath);
180
+ removeSymbols({
181
+ template: templateContent,
182
+ offset: 0,
183
+ elementName,
184
+ attributeSelector,
185
+ recorder: templateRecorder,
186
+ names
187
+ });
188
+ tree.commitUpdate(templateRecorder);
189
+ });
190
+ };
@@ -150,15 +150,15 @@ export function* renameIdentifier({ sourceFile, renamingInstructions }) {
150
150
  if (!(node.importClause?.namedBindings && ts.isNamedImports(node.importClause.namedBindings))) {
151
151
  continue;
152
152
  }
153
- for (const [index, [fromName, toName]] of renamingInstruction.symbolRenamings.entries()) {
154
- const importSpecifiers = findImportSpecifier(node.importClause.namedBindings.elements, fromName);
153
+ for (const [index, { replace, replaceWith }] of renamingInstruction.symbolRenamings.entries()) {
154
+ const importSpecifiers = findImportSpecifier(node.importClause.namedBindings.elements, replace);
155
155
  if (!importSpecifiers) {
156
156
  continue;
157
157
  }
158
158
  yield {
159
159
  start: importSpecifiers.name.getStart(),
160
160
  width: importSpecifiers.name.getWidth(),
161
- newNode: ts.factory.createIdentifier(toName)
161
+ newNode: ts.factory.createIdentifier(replaceWith)
162
162
  };
163
163
  if (renamingInstruction.toModule &&
164
164
  !node.moduleSpecifier.text.endsWith('@simpl/element-ng') &&
@@ -171,11 +171,11 @@ export function* renameIdentifier({ sourceFile, renamingInstructions }) {
171
171
  };
172
172
  }
173
173
  const visitor = function* (visitedNode) {
174
- if (ts.isIdentifier(visitedNode) && visitedNode.text === fromName) {
174
+ if (ts.isIdentifier(visitedNode) && visitedNode.text === replace) {
175
175
  yield {
176
176
  start: visitedNode.getStart(),
177
177
  width: visitedNode.getWidth(),
178
- newNode: ts.factory.createIdentifier(toName)
178
+ newNode: ts.factory.createIdentifier(replaceWith)
179
179
  };
180
180
  }
181
181
  else {
@@ -1,8 +1,10 @@
1
1
  {
2
+ "SI_AI_MESSAGE.SECONDARY_ACTIONS": "More actions",
2
3
  "SI_ALERT_DIALOG.OK": "OK",
3
4
  "SI_APPLICATION_HEADER.LAUNCHPAD": "Launchpad",
4
5
  "SI_APPLICATION_HEADER.TOGGLE_ACTIONS": "Toggle actions",
5
6
  "SI_APPLICATION_HEADER.TOGGLE_NAVIGATION": "Toggle navigation",
7
+ "SI_ATTACHMENT_LIST.REMOVE_ATTACHMENT": "Remove attachment",
6
8
  "SI_BREADCRUMB": "Breadcrumbs",
7
9
  "SI_CHANGE_PASSWORD.BACK": "Back",
8
10
  "SI_CHANGE_PASSWORD.CHANGE": "Change",
@@ -11,6 +13,12 @@
11
13
  "SI_CHANGE_PASSWORD.CONFIRM_PASSWORD": "Confirm password",
12
14
  "SI_CHANGE_PASSWORD.NEW_PASSWORD": "New password",
13
15
  "SI_CHANGE_PASSWORD.PASSWORD_POLICY": "Password policy",
16
+ "SI_CHAT_INPUT.ATTACH_FILE": "Attach file",
17
+ "SI_CHAT_INPUT.INTERRUPT": "Interrupt",
18
+ "SI_CHAT_INPUT.LABEL": "Chat message input",
19
+ "SI_CHAT_INPUT.PLACEHOLDER": "Enter a message…",
20
+ "SI_CHAT_INPUT.SECONDARY_ACTIONS": "More actions",
21
+ "SI_CHAT_INPUT.SEND": "Send",
14
22
  "SI_COLUMN_SELECTION_DIALOG.CANCEL": "Cancel",
15
23
  "SI_COLUMN_SELECTION_DIALOG.HIDDEN": "Hidden",
16
24
  "SI_COLUMN_SELECTION_DIALOG.ITEM_MOVED": "Item is now at position {{targetPosition}}",
@@ -207,6 +215,7 @@
207
215
  "SI_TREE_VIEW.COLLAPSE_ALL": "Collapse all",
208
216
  "SI_TREE_VIEW.EXPAND_ALL": "Expand all",
209
217
  "SI_TYPEAHEAD.AUTOCOMPLETE_LIST_LABEL": "Suggestions",
218
+ "SI_USER_MESSAGE.SECONDARY_ACTIONS": "More actions",
210
219
  "SI_WIZARD.BACK": "Back",
211
220
  "SI_WIZARD.CANCEL": "Cancel",
212
221
  "SI_WIZARD.COMPLETED": "Wizard completed!",
@@ -2,10 +2,12 @@ import { Provider } from '@angular/core';
2
2
  export * from '@siemens/element-translate-ng/translate';
3
3
 
4
4
  interface SiTranslatableKeys {
5
+ 'SI_AI_MESSAGE.SECONDARY_ACTIONS'?: string;
5
6
  'SI_ALERT_DIALOG.OK'?: string;
6
7
  'SI_APPLICATION_HEADER.LAUNCHPAD'?: string;
7
8
  'SI_APPLICATION_HEADER.TOGGLE_ACTIONS'?: string;
8
9
  'SI_APPLICATION_HEADER.TOGGLE_NAVIGATION'?: string;
10
+ 'SI_ATTACHMENT_LIST.REMOVE_ATTACHMENT'?: string;
9
11
  'SI_BREADCRUMB'?: string;
10
12
  'SI_CHANGE_PASSWORD.BACK'?: string;
11
13
  'SI_CHANGE_PASSWORD.CHANGE'?: string;
@@ -14,6 +16,12 @@ interface SiTranslatableKeys {
14
16
  'SI_CHANGE_PASSWORD.CONFIRM_PASSWORD'?: string;
15
17
  'SI_CHANGE_PASSWORD.NEW_PASSWORD'?: string;
16
18
  'SI_CHANGE_PASSWORD.PASSWORD_POLICY'?: string;
19
+ 'SI_CHAT_INPUT.ATTACH_FILE'?: string;
20
+ 'SI_CHAT_INPUT.INTERRUPT'?: string;
21
+ 'SI_CHAT_INPUT.LABEL'?: string;
22
+ 'SI_CHAT_INPUT.PLACEHOLDER'?: string;
23
+ 'SI_CHAT_INPUT.SECONDARY_ACTIONS'?: string;
24
+ 'SI_CHAT_INPUT.SEND'?: string;
17
25
  'SI_COLUMN_SELECTION_DIALOG.CANCEL'?: string;
18
26
  'SI_COLUMN_SELECTION_DIALOG.HIDDEN'?: string;
19
27
  'SI_COLUMN_SELECTION_DIALOG.ITEM_MOVED'?: string;
@@ -210,6 +218,7 @@ interface SiTranslatableKeys {
210
218
  'SI_TREE_VIEW.COLLAPSE_ALL'?: string;
211
219
  'SI_TREE_VIEW.EXPAND_ALL'?: string;
212
220
  'SI_TYPEAHEAD.AUTOCOMPLETE_LIST_LABEL'?: string;
221
+ 'SI_USER_MESSAGE.SECONDARY_ACTIONS'?: string;
213
222
  'SI_WIZARD.BACK'?: string;
214
223
  'SI_WIZARD.CANCEL'?: string;
215
224
  'SI_WIZARD.COMPLETED'?: string;
@@ -98,7 +98,7 @@ declare class SiTreeViewItemComponent implements OnInit, OnDestroy, AfterViewIni
98
98
  private onScrollIntoViewByConsumer;
99
99
  private expandOnClick;
100
100
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SiTreeViewItemComponent, never>;
101
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SiTreeViewItemComponent, "si-tree-view-item", never, {}, {}, never, never, true, never>;
101
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SiTreeViewItemComponent, "si-tree-view-item", never, {}, {}, never, [":not(si-tree-view-item):not([dragPreview])"], true, never>;
102
102
  }
103
103
 
104
104
  /**
@@ -687,6 +687,45 @@ type TreeItemContext = {
687
687
  parent: SiTreeViewComponent;
688
688
  };
689
689
 
690
+ /**
691
+ * Tree view item template directive for defining custom item templates.
692
+ *
693
+ * @deprecated Use `siTreeViewItem` instead.
694
+ *
695
+ * This directive is deprecated and will be removed in a future version.
696
+ *
697
+ * @example
698
+ * Migration Guide:
699
+ *
700
+ * Before (deprecated):
701
+ * ```html
702
+ * <si-tree-view>
703
+ * <ng-template siTreeViewItemTemplate="root" let-item>
704
+ * <div class="custom-item">Root {{ item.level }}</div>
705
+ * </ng-template>
706
+ * <ng-template siTreeViewItemTemplate="child" let-item>
707
+ * <div class="custom-item">Child {{ item.level }}</div>
708
+ * </ng-template>
709
+ * </si-tree-view>
710
+ * ```
711
+ *
712
+ * After (recommended):
713
+ * ```html
714
+ * <si-tree-view>
715
+ * <ng-template siTreeViewItem let-item="treeItem">
716
+ * <si-tree-view-item>
717
+ * <div class="custom-item">
718
+ * @if (item.level === 0) {
719
+ * Root {{ item.level }}
720
+ * } @else {
721
+ * Child {{ item.level }}
722
+ * }
723
+ * </div>
724
+ * </si-tree-view-item>
725
+ * </ng-template>
726
+ * </si-tree-view>
727
+ * ```
728
+ */
690
729
  declare class SiTreeViewItemTemplateDirective {
691
730
  /** @defaultValue undefined */
692
731
  readonly name: _angular_core.InputSignal<string | undefined>;
@@ -1,55 +0,0 @@
1
- import * as ts from 'typescript';
2
- import { EmitHint } from 'typescript';
3
- import { discoverSourceFiles, renameAttribute, renameElementTag, renameIdentifier } from '../../utils/index.js';
4
- import { IDENTIFIER_RENAMING_INSTRUCTIONS, ELEMENT_RENAMING_INSTRUCTIONS, ATTRIBUTE_RENAMING_INSTRUCTIONS } from './to-legacy-replacement.js';
5
- export const toLegacyMigrationRule = (options) => {
6
- return (tree, context) => {
7
- context.logger.info('🔄 Running legacy migration rule...');
8
- const tsSourceFiles = discoverSourceFiles(tree, context, options.path);
9
- for (const filePath of tsSourceFiles) {
10
- const content = tree.read(filePath);
11
- if (!content) {
12
- continue;
13
- }
14
- const sourceFile = ts.createSourceFile(filePath, content.toString(), ts.ScriptTarget.Latest, true);
15
- const changeInstructions = renameIdentifier({
16
- sourceFile,
17
- renamingInstructions: IDENTIFIER_RENAMING_INSTRUCTIONS
18
- });
19
- let recorder = undefined;
20
- let printer = undefined;
21
- for (const changeInstruction of changeInstructions) {
22
- recorder ??= tree.beginUpdate(filePath);
23
- printer ??= ts.createPrinter();
24
- recorder.remove(changeInstruction.start, changeInstruction.width);
25
- recorder.insertLeft(changeInstruction.start, printer.printNode(EmitHint.Unspecified, changeInstruction.newNode, sourceFile));
26
- }
27
- if (!recorder) {
28
- continue;
29
- }
30
- for (const [fromName, toName] of ELEMENT_RENAMING_INSTRUCTIONS) {
31
- renameElementTag({
32
- tree,
33
- recorder,
34
- sourceFile,
35
- filePath,
36
- fromName,
37
- toName
38
- });
39
- }
40
- for (const [fromName, toName] of ATTRIBUTE_RENAMING_INSTRUCTIONS) {
41
- renameAttribute({
42
- tree,
43
- recorder,
44
- sourceFile,
45
- filePath,
46
- fromName,
47
- toName
48
- });
49
- }
50
- tree.commitUpdate(recorder);
51
- }
52
- context.logger.info(`✅ Legacy migration complete!`);
53
- return tree;
54
- };
55
- };
@@ -1,35 +0,0 @@
1
- /**
2
- * Copyright (c) Siemens 2016 - 2025
3
- * SPDX-License-Identifier: MIT
4
- */
5
- export const IDENTIFIER_RENAMING_INSTRUCTIONS = [
6
- {
7
- module: /@(siemens|simpl)\/element-ng(\/icon)?/,
8
- symbolRenamings: [['SiIconComponent', 'SiIconLegacyComponent']]
9
- },
10
- {
11
- module: /@(siemens|simpl)\/element-ng(\/tabs)?/,
12
- symbolRenamings: [
13
- ['SiTabComponent', 'SiTabLegacyComponent'],
14
- ['SiTabsetComponent', 'SiTabsetLegacyComponent'],
15
- ['SiTabsModule', 'SiTabsLegacyModule']
16
- ],
17
- toModule: '@siemens/element-ng/tabs-legacy'
18
- },
19
- {
20
- module: /@(siemens|simpl)\/element-ng(\/popover)?/,
21
- symbolRenamings: [
22
- ['SiPopoverDirective', 'SiPopoverLegacyDirective'],
23
- ['SiPopoverModule', 'SiPopoverLegacyModule']
24
- ],
25
- toModule: '@siemens/element-ng/popover-legacy'
26
- }
27
- ];
28
- export const ELEMENT_RENAMING_INSTRUCTIONS = [
29
- ['si-icon', 'si-icon-legacy'],
30
- ['si-tabset', 'si-tabset-legacy'],
31
- ['si-tab', 'si-tab-legacy']
32
- ];
33
- export const ATTRIBUTE_RENAMING_INSTRUCTIONS = [
34
- ['siPopover', 'siPopoverLegacy']
35
- ];