@sap-ux/control-property-editor 0.5.0 → 0.5.2
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/CHANGELOG.md +12 -0
- package/dist/app.css +1 -1
- package/dist/app.css.map +3 -3
- package/dist/app.js +55 -58
- package/dist/app.js.map +3 -3
- package/package.json +3 -3
- package/src/components/ThemeSelectorCallout.scss +6 -6
- package/src/components/ThemeSelectorCallout.tsx +9 -20
- package/src/index.css +506 -449
- package/src/index.tsx +0 -5
- package/src/panels/LeftPanel.tsx +2 -1
- package/src/panels/changes/ChangesPanel.module.scss +1 -4
- package/src/panels/changes/ChangesPanel.tsx +1 -1
- package/src/panels/outline/OutlinePanel.scss +4 -3
- package/src/panels/outline/Tree.tsx +14 -3
- package/src/use-theme.ts +19 -0
- package/test/unit/toolbar/ThemeSelector.test.tsx +7 -7
package/src/index.tsx
CHANGED
|
@@ -10,8 +10,6 @@ import { initI18n } from './i18n';
|
|
|
10
10
|
import './index.css';
|
|
11
11
|
import App from './App';
|
|
12
12
|
import { store } from './store';
|
|
13
|
-
import type { ThemeName } from './components';
|
|
14
|
-
import { setThemeOnDocument } from './components';
|
|
15
13
|
import { registerAppIcons } from './icons';
|
|
16
14
|
import { initializeLivereload, setProjectScenario } from './slice';
|
|
17
15
|
|
|
@@ -41,9 +39,6 @@ export function start(options: StartOptions): void {
|
|
|
41
39
|
registerAppIcons();
|
|
42
40
|
initIcons();
|
|
43
41
|
|
|
44
|
-
const theme = localStorage.getItem('theme') ?? 'dark';
|
|
45
|
-
setThemeOnDocument(theme as ThemeName);
|
|
46
|
-
|
|
47
42
|
store.dispatch(setProjectScenario(scenario));
|
|
48
43
|
store.dispatch(initializeLivereload({ port: options.livereloadPort, url: options.livereloadUrl }));
|
|
49
44
|
|
package/src/panels/LeftPanel.tsx
CHANGED
|
@@ -26,13 +26,14 @@ export function LeftPanel(): ReactElement {
|
|
|
26
26
|
sizesAsPercents={true}
|
|
27
27
|
animation={true}>
|
|
28
28
|
<UISections.Section
|
|
29
|
-
scrollable={
|
|
29
|
+
scrollable={false}
|
|
30
30
|
layout={UISectionLayout.Standard}
|
|
31
31
|
className="editor__outline"
|
|
32
32
|
height="100%">
|
|
33
33
|
<OutlinePanel />
|
|
34
34
|
</UISections.Section>
|
|
35
35
|
<UISections.Section
|
|
36
|
+
scrollable={false}
|
|
36
37
|
layout={UISectionLayout.Standard}
|
|
37
38
|
className="editor__outline"
|
|
38
39
|
height="100%"
|
|
@@ -3,9 +3,6 @@
|
|
|
3
3
|
padding: 15px 15px 15px 15px;
|
|
4
4
|
flex-direction: row;
|
|
5
5
|
align-items: center;
|
|
6
|
-
position: sticky;
|
|
7
|
-
top: 0px;
|
|
8
|
-
z-index: 1;
|
|
9
6
|
background-color: var(--vscode-sideBar-background);
|
|
10
7
|
}
|
|
11
8
|
|
|
@@ -23,4 +20,4 @@
|
|
|
23
20
|
.infoIcon {
|
|
24
21
|
margin-left: 15px;
|
|
25
22
|
margin-top: 5px;
|
|
26
|
-
}
|
|
23
|
+
}
|
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
padding: 15px 14px 15px 14px;
|
|
4
4
|
flex-direction: row;
|
|
5
5
|
align-items: center;
|
|
6
|
-
position: sticky;
|
|
7
|
-
top: 0px;
|
|
8
|
-
z-index: 1;
|
|
9
6
|
background-color: var(--vscode-sideBar-background);
|
|
10
7
|
}
|
|
11
8
|
|
|
9
|
+
.auto-element-scroller {
|
|
10
|
+
height: calc(100% - 55px);
|
|
11
|
+
}
|
|
12
|
+
|
|
12
13
|
.funnel-icon {
|
|
13
14
|
margin-left: 16px;
|
|
14
15
|
i {
|
|
@@ -22,6 +22,15 @@ interface OutlineNodeItem extends OutlineNode {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export const Tree = (): ReactElement => {
|
|
25
|
+
// padding + height of `Search` bar
|
|
26
|
+
const SEARCH_HEIGHT = 56;
|
|
27
|
+
|
|
28
|
+
// height of the tree row in a outline
|
|
29
|
+
const TREE_ROW_HEIGHT = 28;
|
|
30
|
+
|
|
31
|
+
// margin of the highlighted control from the top including `Search` bar height and tree row height, it doesn't include the height of main toolbar
|
|
32
|
+
const HIGHLIGHTED_CONTROL_TOP_MARGIN = SEARCH_HEIGHT + TREE_ROW_HEIGHT;
|
|
33
|
+
|
|
25
34
|
const dispatch = useDispatch();
|
|
26
35
|
const { t } = useTranslation();
|
|
27
36
|
|
|
@@ -74,8 +83,10 @@ export const Tree = (): ReactElement => {
|
|
|
74
83
|
setTimeout(() => {
|
|
75
84
|
// make sure that tree is fully rendered
|
|
76
85
|
const rect = node.getBoundingClientRect();
|
|
77
|
-
const outlineContainer = document.getElementsByClassName('
|
|
78
|
-
|
|
86
|
+
const outlineContainer = document.getElementsByClassName('auto-element-scroller')[0];
|
|
87
|
+
|
|
88
|
+
// check if highlighted control is behind the `Search` bar or check if it is outside of viewport from bottom
|
|
89
|
+
if (rect.top <= HIGHLIGHTED_CONTROL_TOP_MARGIN || rect.bottom >= outlineContainer?.clientHeight) {
|
|
79
90
|
node.scrollIntoView(true);
|
|
80
91
|
}
|
|
81
92
|
}, 0);
|
|
@@ -462,7 +473,7 @@ export const Tree = (): ReactElement => {
|
|
|
462
473
|
};
|
|
463
474
|
|
|
464
475
|
return (
|
|
465
|
-
<div id="list-outline" className="app-panel-scroller">
|
|
476
|
+
<div id="list-outline" className="app-panel-scroller auto-element-scroller">
|
|
466
477
|
<UIList
|
|
467
478
|
{...listProp}
|
|
468
479
|
items={items as never[]}
|
package/src/use-theme.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
import { useLocalStorage } from './use-local-storage';
|
|
4
|
+
|
|
5
|
+
export type ThemeName = 'dark modern' | 'light modern' | 'high contrast black';
|
|
6
|
+
/**
|
|
7
|
+
* React hook that lets you read and update applications theme.
|
|
8
|
+
*
|
|
9
|
+
* @returns [theme, setTheme] [T, React.Dispatch<T>]
|
|
10
|
+
*/
|
|
11
|
+
export function useTheme(): [ThemeName, React.Dispatch<ThemeName>] {
|
|
12
|
+
const [theme, setTheme] = useLocalStorage<ThemeName>('theme', 'dark modern');
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
document.getElementsByTagName('HTML')[0].setAttribute('data-theme', theme);
|
|
16
|
+
}, [theme]);
|
|
17
|
+
|
|
18
|
+
return [theme, setTheme];
|
|
19
|
+
}
|
|
@@ -32,12 +32,12 @@ test('renders theme selector callout', () => {
|
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
test('check selected theme', () => {
|
|
35
|
-
localStorage.setItem('theme', 'light');
|
|
35
|
+
localStorage.setItem('com.sap.ux.control-property-editor.theme', '"light modern"');
|
|
36
36
|
render(<ThemeSelectorCallout />);
|
|
37
37
|
screen.getByRole('button').click();
|
|
38
38
|
const themeCalloutContent = screen.getAllByRole('button', { pressed: true });
|
|
39
39
|
const pressedButton = themeCalloutContent.find((button) => button.getAttribute('aria-pressed') === 'true');
|
|
40
|
-
expect(pressedButton?.getAttribute('id')).toStrictEqual('theme-light-rect');
|
|
40
|
+
expect(pressedButton?.getAttribute('id')).toStrictEqual('theme-light-modern-rect');
|
|
41
41
|
});
|
|
42
42
|
|
|
43
43
|
test('change theme to light', () => {
|
|
@@ -46,12 +46,12 @@ test('change theme to light', () => {
|
|
|
46
46
|
screen.getByTitle('Light').click();
|
|
47
47
|
const themeCalloutContent = screen.getAllByRole('button', { pressed: true });
|
|
48
48
|
const pressedButton = themeCalloutContent.find((button) => button.getAttribute('aria-pressed') === 'true');
|
|
49
|
-
expect(pressedButton?.getAttribute('id')).toStrictEqual('theme-light-rect');
|
|
50
|
-
expect(localStorage.getItem('theme')).toStrictEqual('light');
|
|
49
|
+
expect(pressedButton?.getAttribute('id')).toStrictEqual('theme-light-modern-rect');
|
|
50
|
+
expect(localStorage.getItem('com.sap.ux.control-property-editor.theme')).toStrictEqual('"light modern"');
|
|
51
51
|
});
|
|
52
52
|
|
|
53
53
|
test('change theme to light and navigate via keyboard for dark to have focus', async () => {
|
|
54
|
-
localStorage.setItem('theme', 'light');
|
|
54
|
+
localStorage.setItem('com.sap.ux.control-property-editor.theme', '"light modern"');
|
|
55
55
|
// Use 'isVisible' property to make virtual nodes visible - 'isVisible' is used by fluent for testing purposes
|
|
56
56
|
Object.defineProperty(HTMLElement.prototype, 'isVisible', {
|
|
57
57
|
configurable: true,
|
|
@@ -75,7 +75,7 @@ test('change theme to light and navigate via keyboard for dark to have focus', a
|
|
|
75
75
|
const darkButton = screen.getByTitle('Dark');
|
|
76
76
|
expect(document.activeElement).toEqual(darkButton);
|
|
77
77
|
// select focused theme
|
|
78
|
-
expect(localStorage.getItem('theme')).toStrictEqual('light');
|
|
78
|
+
expect(localStorage.getItem('com.sap.ux.control-property-editor.theme')).toStrictEqual('"light modern"');
|
|
79
79
|
triggerKeyDown('Enter', 13);
|
|
80
|
-
expect(localStorage.getItem('theme')).toStrictEqual('dark');
|
|
80
|
+
expect(localStorage.getItem('com.sap.ux.control-property-editor.theme')).toStrictEqual('"dark modern"');
|
|
81
81
|
});
|