@sap-ux/control-property-editor 0.7.23 → 0.7.24

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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "displayName": "Control Property Editor",
4
4
  "description": "Control Property Editor",
5
5
  "license": "Apache-2.0",
6
- "version": "0.7.23",
6
+ "version": "0.7.24",
7
7
  "main": "dist/app.js",
8
8
  "repository": {
9
9
  "type": "git",
@@ -24,6 +24,7 @@
24
24
  "@types/remote-redux-devtools": "0.5.8",
25
25
  "@types/source-map-support": "0.5.10",
26
26
  "@types/react": "16.14.69",
27
+ "eslint": "9.39.1",
27
28
  "eslint-plugin-react": "7.37.5",
28
29
  "http-proxy-middleware": "3.0.5",
29
30
  "i18next": "25.10.10",
@@ -39,7 +40,7 @@
39
40
  "source-map-support": "0.5.21",
40
41
  "stream-browserify": "3.0.0",
41
42
  "ts-import-plugin": "3.0.0",
42
- "ts-jest": "29.4.6",
43
+ "ts-jest": "29.4.9",
43
44
  "postcss-modules": "6.0.1",
44
45
  "ejs": "3.1.10",
45
46
  "@ui5/fs": "4.0.5",
@@ -47,7 +48,7 @@
47
48
  "esbuild-plugin-copy": "2.1.1",
48
49
  "@esbuild-plugins/node-modules-polyfill": "0.2.2",
49
50
  "uuid": "11.1.0",
50
- "@sap-ux/ui-components": "2.1.5",
51
+ "@sap-ux/ui-components": "2.1.12",
51
52
  "@sap-ux-private/control-property-editor-common": "0.7.7"
52
53
  },
53
54
  "engines": {
@@ -1,6 +1,8 @@
1
+ import { UIIcon } from '@sap-ux/ui-components';
1
2
  import type { ReactElement } from 'react';
2
3
  import React from 'react';
3
4
  import { useTranslation } from 'react-i18next';
5
+ import { IconName } from '../../src/icons';
4
6
 
5
7
  interface ChangeIndicatorProps {
6
8
  saved: number;
@@ -18,64 +20,33 @@ interface ChangeIndicatorProps {
18
20
  export function ChangeIndicator(props: ChangeIndicatorProps): ReactElement {
19
21
  const { saved, pending, id } = props;
20
22
  const rest = { id };
21
- const color = 'var(--vscode-terminal-ansiGreen)';
22
23
 
23
24
  if (saved > 0 && pending === 0) {
24
- return (
25
- <svg
26
- role="img"
27
- width="8"
28
- height="8"
29
- viewBox="0 0 8 8"
30
- fill="none"
31
- xmlns="http://www.w3.org/2000/svg"
32
- {...rest}>
33
- <ChangeIndicatorTooltip {...props} />
34
- <circle cx="4" cy="4" r="4" fill={color} />
35
- </svg>
36
- );
25
+ return <UIIcon iconName={IconName.filledCircle} title={ChangeIndicatorTooltip(props)} {...rest} />;
37
26
  }
38
27
 
39
28
  if (pending > 0 && saved === 0) {
40
- return (
41
- <svg
42
- role="img"
43
- width="8"
44
- height="8"
45
- viewBox="0 0 8 8"
46
- fill="none"
47
- xmlns="http://www.w3.org/2000/svg"
48
- {...rest}>
49
- <ChangeIndicatorTooltip {...props} />
50
- <circle cx="4" cy="4" r="3.5" stroke={color} />
51
- </svg>
52
- );
29
+ return <UIIcon iconName={IconName.unfilledCircle} title={ChangeIndicatorTooltip(props)} {...rest} />;
53
30
  }
54
31
 
55
- return (
56
- <svg role="img" width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg" {...rest}>
57
- <ChangeIndicatorTooltip {...props} />
58
- <circle cx="4" cy="4" r="3.5" stroke={color} />
59
- <path d="M4 8a4 4 0 1 0 0-8v8Z" fill={color} />
60
- </svg>
61
- );
32
+ return <UIIcon iconName={IconName.partiallyFilledCircle} title={ChangeIndicatorTooltip(props)} {...rest} />;
62
33
  }
63
34
 
64
35
  /**
65
36
  * React element for change indicator tooltip.
66
37
  *
67
38
  * @param changeIndicatorProps - ChangeIndicatorProps
68
- * @returns ReactElement
39
+ * @returns string
69
40
  */
70
- function ChangeIndicatorTooltip(changeIndicatorProps: ChangeIndicatorProps): ReactElement {
41
+ function ChangeIndicatorTooltip(changeIndicatorProps: ChangeIndicatorProps): string {
71
42
  const { saved, pending, type } = changeIndicatorProps;
72
43
  const { t } = useTranslation();
73
44
  if (saved > 0 && pending === 0) {
74
- return <title>{t('SAVED_CHANGES', { type: type })}</title>;
45
+ return t('SAVED_CHANGES', { type: type });
75
46
  }
76
47
 
77
48
  if (pending > 0 && saved === 0) {
78
- return <title>{t('UNSAVED_CHANGES', { type: type })}</title>;
49
+ return t('UNSAVED_CHANGES', { type: type });
79
50
  }
80
- return <title>{t('SAVED_AND_UNSAVED_CHANGES', { type: type })}</title>;
51
+ return t('SAVED_AND_UNSAVED_CHANGES', { type: type });
81
52
  }
package/src/icons.tsx CHANGED
@@ -20,7 +20,10 @@ export enum IconName {
20
20
  grabber = 'grabber',
21
21
  themePainter = 'themePainter',
22
22
  chevronLeft = 'chevronLeft',
23
- saveAndReload = 'saveAndReload'
23
+ saveAndReload = 'saveAndReload',
24
+ unfilledCircle = 'unfilledCircle',
25
+ filledCircle = 'filledCircle',
26
+ partiallyFilledCircle = 'partiallyFilledCircle'
24
27
  }
25
28
 
26
29
  export function registerAppIcons(): void {
@@ -232,6 +235,22 @@ export function registerAppIcons(): void {
232
235
  </clipPath>
233
236
  </defs>
234
237
  </svg>
238
+ ),
239
+ unfilledCircle: (
240
+ <svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
241
+ <circle cx="4" cy="4" r="3.5" stroke="var(--vscode-terminal-ansiGreen)" />
242
+ </svg>
243
+ ),
244
+ filledCircle: (
245
+ <svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
246
+ <circle cx="4" cy="4" r="4" fill="var(--vscode-terminal-ansiGreen)" />
247
+ </svg>
248
+ ),
249
+ partiallyFilledCircle: (
250
+ <svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
251
+ <circle cx="4" cy="4" r="3.5" stroke="var(--vscode-terminal-ansiGreen)" />
252
+ <path d="M4 8a4 4 0 1 0 0-8v8Z" fill="var(--vscode-terminal-ansiGreen)" />
253
+ </svg>
235
254
  )
236
255
  }
237
256
  });
@@ -88,7 +88,7 @@ export function ViewChanger(): ReactElement {
88
88
  } else if (value) {
89
89
  const match = SCALE_INPUT_PATTERN.exec(value);
90
90
  if (match) {
91
- const percent = parseInt(match[1], 10);
91
+ const percent = Number.parseInt(match[1], 10);
92
92
  const newScale = percent / 100;
93
93
  if (newScale >= MIN_SCALE && newScale <= MAX_SCALE) {
94
94
  dispatch(changePreviewScale(newScale));
@@ -5,107 +5,30 @@ import { render } from '../utils';
5
5
  import { ChangeIndicator } from '../../../src/components/ChangeIndicator';
6
6
 
7
7
  describe('ChangeIndicator', () => {
8
- test('saved changes', () => {
8
+ test('saved changes - shows tooltip on hover', () => {
9
9
  const { container } = render(<ChangeIndicator id={'change-indicator'} saved={1} pending={0} type="property" />);
10
- expect(container.querySelector('svg')).toMatchInlineSnapshot(`
11
- <svg
12
- fill="none"
13
- height="8"
14
- id="change-indicator"
15
- role="img"
16
- viewBox="0 0 8 8"
17
- width="8"
18
- xmlns="http://www.w3.org/2000/svg"
19
- >
20
- <title>
21
- All changes on this property are saved
22
- </title>
23
- <circle
24
- cx="4"
25
- cy="4"
26
- fill="var(--vscode-terminal-ansiGreen)"
27
- r="4"
28
- />
29
- </svg>
30
- `);
10
+ const icon = container.querySelector('i');
11
+ expect(icon).toHaveAttribute('title', 'All changes on this property are saved');
31
12
  });
32
13
 
33
- test('pending changes', () => {
14
+ test('pending changes - shows tooltip on hover', () => {
34
15
  const { container } = render(<ChangeIndicator saved={0} pending={2} type="property" />);
35
- expect(container.querySelector('svg')).toMatchInlineSnapshot(`
36
- <svg
37
- fill="none"
38
- height="8"
39
- role="img"
40
- viewBox="0 0 8 8"
41
- width="8"
42
- xmlns="http://www.w3.org/2000/svg"
43
- >
44
- <title>
45
- All changes on this property are not saved
46
- </title>
47
- <circle
48
- cx="4"
49
- cy="4"
50
- r="3.5"
51
- stroke="var(--vscode-terminal-ansiGreen)"
52
- />
53
- </svg>
54
- `);
16
+ const icon = container.querySelector('i');
17
+ expect(icon).toHaveAttribute('title', 'All changes on this property are not saved');
55
18
  });
56
19
 
57
- test('pending and saved changes', () => {
20
+ test('pending and saved changes - shows tooltip on hover', () => {
58
21
  const { container } = render(<ChangeIndicator saved={3} pending={2} type="property" />);
59
- expect(container.querySelector('svg')).toMatchInlineSnapshot(`
60
- <svg
61
- fill="none"
62
- height="8"
63
- role="img"
64
- viewBox="0 0 8 8"
65
- width="8"
66
- xmlns="http://www.w3.org/2000/svg"
67
- >
68
- <title>
69
- This property has previously saved changes and currently unsaved changes
70
- </title>
71
- <circle
72
- cx="4"
73
- cy="4"
74
- r="3.5"
75
- stroke="var(--vscode-terminal-ansiGreen)"
76
- />
77
- <path
78
- d="M4 8a4 4 0 1 0 0-8v8Z"
79
- fill="var(--vscode-terminal-ansiGreen)"
80
- />
81
- </svg>
82
- `);
22
+ const icon = container.querySelector('i');
23
+ expect(icon).toHaveAttribute(
24
+ 'title',
25
+ 'This property has previously saved changes and currently unsaved changes'
26
+ );
83
27
  });
84
28
 
85
- test('do not add unknown properties', () => {
86
- const { container } = render(
87
- <ChangeIndicator id={'change-indicator'} saved={1} pending={0} {...{ xyz: 'abc ' }} type="property" />
88
- );
89
- expect(container.querySelector('svg')).toMatchInlineSnapshot(`
90
- <svg
91
- fill="none"
92
- height="8"
93
- id="change-indicator"
94
- role="img"
95
- viewBox="0 0 8 8"
96
- width="8"
97
- xmlns="http://www.w3.org/2000/svg"
98
- >
99
- <title>
100
- All changes on this property are saved
101
- </title>
102
- <circle
103
- cx="4"
104
- cy="4"
105
- fill="var(--vscode-terminal-ansiGreen)"
106
- r="4"
107
- />
108
- </svg>
109
- `);
29
+ test('id prop is applied to icon element', () => {
30
+ const { container } = render(<ChangeIndicator id={'change-indicator'} saved={1} pending={0} type="property" />);
31
+ const icon = container.querySelector('i');
32
+ expect(icon).toHaveAttribute('id', 'change-indicator');
110
33
  });
111
34
  });