devextreme-cli 1.7.0 → 1.7.3

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 (66) hide show
  1. package/package.json +2 -2
  2. package/src/.DS_Store +0 -0
  3. package/src/applications/application.angular.js +4 -8
  4. package/src/applications/application.react.js +2 -0
  5. package/src/applications/application.vue.js +2 -0
  6. package/src/commands.json +3 -6
  7. package/src/templates/.DS_Store +0 -0
  8. package/src/templates/react/.DS_Store +0 -0
  9. package/src/templates/react/application/.DS_Store +0 -0
  10. package/src/templates/react/application/devextreme.json +28 -0
  11. package/src/templates/react/application/src/App.tsx +11 -7
  12. package/src/templates/react/application/src/components/create-account-form/CreateAccountForm.scss +3 -3
  13. package/src/templates/react/application/src/components/footer/Footer.scss +7 -4
  14. package/src/templates/react/application/src/components/header/Header.scss +4 -5
  15. package/src/templates/react/application/src/components/header/Header.tsx +8 -12
  16. package/src/templates/react/application/src/components/login-form/LoginForm.scss +1 -1
  17. package/src/templates/react/application/src/components/reset-password-form/ResetPasswordForm.scss +1 -1
  18. package/src/templates/react/application/src/components/side-navigation-menu/SideNavigationMenu.scss +49 -68
  19. package/src/templates/react/application/src/components/side-navigation-menu/SideNavigationMenu.tsx +5 -3
  20. package/src/templates/react/application/src/components/theme-switcher/ThemeSwitcher.tsx +20 -0
  21. package/src/templates/react/application/src/components/user-panel/UserPanel.scss +41 -53
  22. package/src/templates/react/application/src/components/user-panel/UserPanel.tsx +22 -25
  23. package/src/templates/react/application/src/dx-styles.scss +63 -67
  24. package/src/templates/react/application/src/layouts/side-nav-inner-toolbar/side-nav-inner-toolbar.scss +1 -6
  25. package/src/templates/react/application/src/layouts/side-nav-outer-toolbar/side-nav-outer-toolbar.scss +3 -3
  26. package/src/templates/react/application/src/layouts/side-nav-outer-toolbar/side-nav-outer-toolbar.tsx +2 -2
  27. package/src/templates/react/application/src/layouts/single-card/single-card.scss +4 -2
  28. package/src/templates/react/application/src/theme.tsx +51 -0
  29. package/src/templates/react/application/src/themes/metadata.additional.dark.json +11 -0
  30. package/src/templates/react/application/src/themes/metadata.additional.json +1 -1
  31. package/src/templates/react/application/src/themes/metadata.base.dark.json +8 -0
  32. package/src/templates/react/application/src/themes/metadata.base.json +1 -1
  33. package/src/templates/react/application/src/types.tsx +55 -55
  34. package/src/templates/react/application/src/variables.scss +37 -0
  35. package/src/templates/react/page/page.tsx +1 -1
  36. package/src/templates/react/sample-pages/home/home.scss +20 -15
  37. package/src/templates/react/sample-pages/home/home.tsx +50 -4
  38. package/src/templates/react/sample-pages/profile/profile.tsx +1 -1
  39. package/src/templates/react/sample-pages/tasks/tasks.scss +3 -0
  40. package/src/templates/react/sample-pages/tasks/tasks.tsx +3 -2
  41. package/src/templates/vue-v3/application/devextreme.json +28 -0
  42. package/src/templates/vue-v3/application/src/App.vue +1 -5
  43. package/src/templates/vue-v3/application/src/components/app-footer.vue +7 -4
  44. package/src/templates/vue-v3/application/src/components/header-toolbar.vue +23 -30
  45. package/src/templates/vue-v3/application/src/components/side-nav-menu.vue +63 -73
  46. package/src/templates/vue-v3/application/src/components/theme-switcher.vue +19 -0
  47. package/src/templates/vue-v3/application/src/components/user-panel.vue +61 -81
  48. package/src/templates/vue-v3/application/src/dx-styles.scss +66 -51
  49. package/src/templates/vue-v3/application/src/layouts/side-nav-inner-toolbar.vue +4 -7
  50. package/src/templates/vue-v3/application/src/layouts/side-nav-outer-toolbar.vue +4 -2
  51. package/src/templates/vue-v3/application/src/layouts/single-card.vue +2 -4
  52. package/src/templates/vue-v3/application/src/theme-service.js +40 -0
  53. package/src/templates/vue-v3/application/src/themes/metadata.additional.dark.json +11 -0
  54. package/src/templates/vue-v3/application/src/themes/metadata.additional.json +1 -1
  55. package/src/templates/vue-v3/application/src/themes/metadata.base.dark.json +8 -0
  56. package/src/templates/vue-v3/application/src/themes/metadata.base.json +1 -1
  57. package/src/templates/vue-v3/application/src/variables.scss +37 -0
  58. package/src/templates/vue-v3/application/src/views/create-account-form.vue +5 -7
  59. package/src/templates/vue-v3/application/src/views/login-form.vue +1 -3
  60. package/src/templates/vue-v3/application/src/views/reset-password-form.vue +2 -4
  61. package/src/templates/vue-v3/page/page.vue +1 -1
  62. package/src/templates/vue-v3/sample-pages/home-page.vue +86 -45
  63. package/src/templates/vue-v3/sample-pages/profile-page.vue +1 -1
  64. package/src/templates/vue-v3/sample-pages/tasks-page.vue +7 -2
  65. package/src/utility/latest-versions.js +4 -4
  66. package/src/templates/react/application/src/index.tsx +0 -16
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devextreme-cli",
3
- "version": "1.7.0",
3
+ "version": "1.7.3",
4
4
  "description": "DevExtreme CLI",
5
5
  "keywords": [
6
6
  "devexpress",
@@ -72,5 +72,5 @@
72
72
  "typescript": "^4.0.2",
73
73
  "typescript-eslint-parser": "^22.0.0"
74
74
  },
75
- "gitHead": "5289a6c9aa525ea566b22a1e21a9782e434395f8"
75
+ "gitHead": "9ffa22649c6db4043492f34a03108bb2ae4adc20"
76
76
  }
package/src/.DS_Store ADDED
Binary file
@@ -10,8 +10,7 @@ const latestVersions = require('../utility/latest-versions');
10
10
  const { extractToolingVersion, toolingVersionOptionName } = require('../utility/extract-tooling-version');
11
11
  const schematicsVersion = latestVersions['devextreme-schematics'] || 'latest';
12
12
 
13
- const minNgCliVersion = new semver('16.0.0');
14
- const ngCliWithStandalone = new semver('17.0.0');
13
+ const minNgCliVersion = new semver('17.0.0');
15
14
 
16
15
  async function runSchematicCommand(schematicCommand, options, evaluatingOptions) {
17
16
  const collectionName = 'devextreme-schematics';
@@ -77,7 +76,6 @@ const install = async(options) => {
77
76
 
78
77
  const create = async(appName, options) => {
79
78
  const layout = await getLayoutInfo(options.layout);
80
- const currentNgVersion = ngVersion.getNgCliVersion().version;
81
79
 
82
80
  const commandArguments = [
83
81
  'new',
@@ -85,13 +83,11 @@ const create = async(appName, options) => {
85
83
  '--style=scss',
86
84
  '--routing=false',
87
85
  '--skip-tests=true',
88
- '--skip-install=true'
86
+ '--skip-install=true',
87
+ '--standalone=false',
88
+ '--ssr=false'
89
89
  ];
90
90
 
91
- if(ngCliWithStandalone.compare(currentNgVersion) <= 0) {
92
- commandArguments.push('--standalone=false', '--ssr=false');
93
- }
94
-
95
91
  await runNgCommand(commandArguments, options);
96
92
 
97
93
  const appPath = path.join(process.cwd(), appName);
@@ -100,7 +100,9 @@ const addTemplate = (appPath, appName, templateOptions) => {
100
100
 
101
101
  const styles = [
102
102
  './themes/generated/theme.additional.css',
103
+ './themes/generated/theme.additional.dark.css',
103
104
  './themes/generated/theme.base.css',
105
+ './themes/generated/theme.base.dark.css',
104
106
  'devextreme/dist/css/dx.common.css'
105
107
  ];
106
108
 
@@ -77,7 +77,9 @@ const addTemplate = (appPath, appName, templateOptions) => {
77
77
  const applicationTemplatePath = path.join(templateCreator.getTempaltePath('vue-v3'), 'application');
78
78
  const styles = [
79
79
  './themes/generated/theme.additional.css',
80
+ './themes/generated/theme.additional.dark.css',
80
81
  './themes/generated/theme.base.css',
82
+ './themes/generated/theme.base.dark.css',
81
83
  'devextreme/dist/css/dx.common.css'
82
84
  ];
83
85
 
package/src/commands.json CHANGED
@@ -57,7 +57,7 @@
57
57
  "description": "Specifies base theme name (default value is generic.light)"
58
58
  }, {
59
59
  "name": "--input-file",
60
- "description": "Specifies file name with input data (a .json file with metadata or a .less/.scss file with Bootstrap variables)"
60
+ "description": "Specifies file name with input data (a .json file with metadata or a .scss file with Bootstrap 5 variables)"
61
61
  }, {
62
62
  "name": "--make-swatch",
63
63
  "description": "If present, adds a CSS scope to each CSS rule (.dx-swatch-xxx), where xxx is the value from the --output-color-scheme parameter"
@@ -76,9 +76,6 @@
76
76
  }, {
77
77
  "name": "--remove-external-resources",
78
78
  "description": "When present, removes links to external resources, such as fonts. The theme will use local fallbacks instead. Available from DevExtreme v20.2.7."
79
- }, {
80
- "name": "--bootstrap-version",
81
- "description": "Specifies Bootstrap version 4 or 5 if '--input-file' is a '.scss' file. Available from DevExtreme v21.1.5. Default value: 4."
82
79
  }]
83
80
  }, {
84
81
  "name": "export-theme-vars",
@@ -89,7 +86,7 @@
89
86
  "description": "Specifies base theme name (default value is generic.light)"
90
87
  }, {
91
88
  "name": "--input-file",
92
- "description": "Specifies file name with input data (a .json file with metadata or a .less/.scss file with Bootstrap variables)"
89
+ "description": "Specifies file name with input data (a .json file with metadata or a .scss file with Bootstrap 5 variables)"
93
90
  }, {
94
91
  "name": "--output-format",
95
92
  "description": "Specifies the format of output variables (less or scss) (default value is less or the extension extracted from the --output-file value (if it contains any))"
@@ -112,7 +109,7 @@
112
109
  "description": "Specifies base theme name (default value is generic.light)"
113
110
  }, {
114
111
  "name": "--input-file",
115
- "description": "Specifies file name with input data (a .json file with metadata or a .less/.scss file with Bootstrap variables)"
112
+ "description": "Specifies file name with input data (a .json file with metadata or a .scss file with Bootstrap 5 variables)"
116
113
  }, {
117
114
  "name": "--output-file",
118
115
  "description": "Specifies output file name"
Binary file
Binary file
@@ -9,6 +9,13 @@
9
9
  "outputFile": "src/themes/generated/theme.base.css"
10
10
  }
11
11
  },
12
+ {
13
+ "command": "build-theme",
14
+ "options": {
15
+ "inputFile": "src/themes/metadata.base.dark.json",
16
+ "outputFile": "src/themes/generated/theme.base.dark.css"
17
+ }
18
+ },
12
19
  {
13
20
  "command": "build-theme",
14
21
  "options": {
@@ -16,6 +23,13 @@
16
23
  "outputFile": "src/themes/generated/theme.additional.css"
17
24
  }
18
25
  },
26
+ {
27
+ "command": "build-theme",
28
+ "options": {
29
+ "inputFile": "src/themes/metadata.additional.dark.json",
30
+ "outputFile": "src/themes/generated/theme.additional.dark.css"
31
+ }
32
+ },
19
33
  {
20
34
  "command": "export-theme-vars",
21
35
  "options": {
@@ -23,12 +37,26 @@
23
37
  "outputFile": "src/themes/generated/variables.base.scss"
24
38
  }
25
39
  },
40
+ {
41
+ "command": "export-theme-vars",
42
+ "options": {
43
+ "inputFile": "src/themes/metadata.base.dark.json",
44
+ "outputFile": "src/themes/generated/variables.base.dark.scss"
45
+ }
46
+ },
26
47
  {
27
48
  "command": "export-theme-vars",
28
49
  "options": {
29
50
  "inputFile": "src/themes/metadata.additional.json",
30
51
  "outputFile": "src/themes/generated/variables.additional.scss"
31
52
  }
53
+ },
54
+ {
55
+ "command": "export-theme-vars",
56
+ "options": {
57
+ "inputFile": "src/themes/metadata.additional.dark.json",
58
+ "outputFile": "src/themes/generated/variables.additional.dark.scss"
59
+ }
32
60
  }
33
61
  ]
34
62
  }
@@ -7,6 +7,7 @@ import { AuthProvider, useAuth } from './contexts/auth';
7
7
  import { useScreenSizeClass } from './utils/media-query';
8
8
  import Content from './Content';
9
9
  import UnauthenticatedContent from './UnauthenticatedContent';
10
+ import { ThemeContext, useThemeContext} from "./theme";
10
11
 
11
12
  function App() {
12
13
  const { user, loading } = useAuth();
@@ -24,16 +25,19 @@ function App() {
24
25
 
25
26
  export default function Root() {
26
27
  const screenSizeClass = useScreenSizeClass();
28
+ const themeContext = useThemeContext();
27
29
 
28
30
  return (
29
31
  <Router>
30
- <AuthProvider>
31
- <NavigationProvider>
32
- <div className={`app ${screenSizeClass}`}>
33
- <App />
34
- </div>
35
- </NavigationProvider>
36
- </AuthProvider>
32
+ <ThemeContext.Provider value={themeContext}>
33
+ <AuthProvider>
34
+ <NavigationProvider>
35
+ <div className={`app ${screenSizeClass}`}>
36
+ <App />
37
+ </div>
38
+ </NavigationProvider>
39
+ </AuthProvider>
40
+ </ThemeContext.Provider>
37
41
  </Router>
38
42
  );
39
43
  }
@@ -3,17 +3,17 @@
3
3
  .create-account-form {
4
4
  .policy-info {
5
5
  margin: 10px 0;
6
- color: rgba($base-text-color, alpha($base-text-color) * 0.7);
6
+ color: var(--base-text-color-alpha-7);
7
7
  font-size: 14px;
8
8
  font-style: normal;
9
9
 
10
10
  a {
11
- color: rgba($base-text-color, alpha($base-text-color) * 0.7);
11
+ color: var(--base-text-color-alpha-7);
12
12
  }
13
13
  }
14
14
 
15
15
  .login-link {
16
- color: $base-accent;
16
+ color: var(--base-accent);
17
17
  font-size: 16px;
18
18
  text-align: center;
19
19
  }
@@ -1,9 +1,12 @@
1
- @import "../../themes/generated/variables.base.scss";
2
-
3
1
  .footer {
4
2
  display: block;
5
- color: rgba($base-text-color, alpha($base-text-color) * 0.7);
6
- border-top: 1px solid rgba(0, 0, 0, 0.1);
3
+ color: var(--base-text-color-alpha-7);
4
+ border-top: 1px solid var(--footer-border-color);
7
5
  padding-top: 20px;
8
6
  padding-bottom: 24px;
7
+ margin: 0 40px;
8
+
9
+ .screen-x-small & {
10
+ margin: 0 20px;
11
+ }
9
12
  }
@@ -1,14 +1,13 @@
1
- @import "../../themes/generated/variables.base.scss";
2
1
  @import "../../dx-styles.scss";
3
2
 
3
+ header {
4
+ background-color: var(--base-bg);
5
+ }
6
+
4
7
  .header-component {
5
8
  flex: 0 0 auto;
6
9
  z-index: 1;
7
10
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
8
-
9
- .dx-toolbar .dx-toolbar-item.menu-button>.dx-toolbar-item-content .dx-icon {
10
- color: $base-accent;
11
- }
12
11
  }
13
12
 
14
13
  .dx-toolbar.header-toolbar .dx-toolbar-items-container .dx-toolbar-after {
@@ -4,6 +4,7 @@ import Button from 'devextreme-react/button';
4
4
  import UserPanel from '../user-panel/UserPanel';
5
5
  import './Header.scss';
6
6
  import { Template } from 'devextreme-react/core/template';
7
+ import { ThemeSwitcher } from '../theme-switcher/ThemeSwitcher';
7
8
  <%=#isTypeScript%>import type { HeaderProps } from '../../types';<%=/isTypeScript%>
8
9
 
9
10
  export default function Header({ menuToggleEnabled, title, toggleMenu }<%=#isTypeScript%>: HeaderProps<%=/isTypeScript%>) {
@@ -26,21 +27,16 @@ export default function Header({ menuToggleEnabled, title, toggleMenu }<%=#isTyp
26
27
  />
27
28
  <Item
28
29
  location={'after'}
29
- locateInMenu={'auto'}
30
- menuItemTemplate={'userPanelTemplate'}
31
30
  >
32
- <Button
33
- className={'user-button authorization'}
34
- width={210}
35
- height={'100%'}
36
- stylingMode={'text'}
37
- >
38
- <UserPanel menuMode={'context'} />
39
- </Button>
31
+ <ThemeSwitcher />
40
32
  </Item>
41
- <Template name={'userPanelTemplate'}>
42
- <UserPanel menuMode={'list'} />
33
+ <Item location='after' locateInMenu='auto' menuItemTemplate='userPanelTemplate'>
34
+ <UserPanel menuMode='context' />
35
+ </Item>
36
+ <Template name='userPanelTemplate'>
37
+ <UserPanel menuMode='list' />
43
38
  </Template>
39
+
44
40
  </Toolbar>
45
41
  </header>
46
42
  )}
@@ -13,6 +13,6 @@
13
13
 
14
14
  .form-text {
15
15
  margin: 10px 0;
16
- color: rgba($base-text-color, alpha($base-text-color) * 0.7);
16
+ color: var(--base-text-color-alpha-7);
17
17
  }
18
18
  }
@@ -6,7 +6,7 @@
6
6
  }
7
7
 
8
8
  .login-link {
9
- color: $base-accent;
9
+ color: var(--base-accent);
10
10
  font-size: 16px;
11
11
  text-align: center;
12
12
  }
@@ -1,91 +1,72 @@
1
1
  @import "../../dx-styles.scss";
2
- @import "../../themes/generated/variables.additional.scss";
3
2
 
4
- .side-navigation-menu {
5
- display: flex;
6
- flex-direction: column;
7
- min-height: 100%;
8
- height: 100%;
9
- width: 250px !important;
10
-
11
- .menu-container {
12
- min-height: 100%;
3
+ .dx-swatch-additional, .dx-swatch-additional-dark {
4
+ &.side-navigation-menu {
13
5
  display: flex;
14
- flex: 1;
6
+ flex-direction: column;
7
+ min-height: 100%;
8
+ height: 100%;
9
+ width: 250px !important;
10
+ background-color: var(--base-bg);
15
11
 
16
- .dx-treeview {
17
- // ## Long text positioning
18
- white-space: nowrap;
19
- // ##
12
+ .menu-container {
13
+ min-height: 100%;
14
+ display: flex;
15
+ flex: 1;
20
16
 
21
- // ## Icon width customization
22
- .dx-treeview-item {
23
- padding-left: 0;
24
- flex-direction: row-reverse;
17
+ .dx-treeview {
18
+ // ## Long text positioning
19
+ white-space: nowrap;
20
+ // ##
25
21
 
26
- .dx-icon {
27
- width: $side-panel-min-width !important;
28
- margin: 0 !important;
22
+ .dx-treeview-node-container:empty {
23
+ display: none;
29
24
  }
30
- }
31
- // ##
32
-
33
- // ## Arrow customization
34
- .dx-treeview-node {
35
- padding: 0 0 !important;
36
- }
37
25
 
38
- .dx-treeview-toggle-item-visibility {
39
- right: 10px;
40
- left: auto;
41
- }
26
+ // ## Icon width customization
27
+ .dx-treeview-item {
28
+ padding-left: 0;
29
+ border-radius: 0;
30
+ flex-direction: row-reverse;
42
31
 
43
- .dx-rtl .dx-treeview-toggle-item-visibility {
44
- left: 10px;
45
- right: auto;
46
- }
47
- // ##
32
+ .dx-icon {
33
+ width: $side-panel-min-width !important;
34
+ margin: 0 !important;
35
+ }
36
+ }
48
37
 
49
- // ## Item levels customization
50
- .dx-treeview-node {
51
- &[aria-level='1'] {
52
- font-weight: bold;
53
- border-bottom: 1px solid $base-border-color;
38
+ // ##
39
+
40
+ // ## Arrow customization
41
+ .dx-treeview-node {
42
+ padding: 0 0 !important;
54
43
  }
55
-
56
- &[aria-level='2'] .dx-treeview-item-content {
57
- font-weight: normal;
58
- padding: 0 $side-panel-min-width;
44
+
45
+ .dx-treeview-toggle-item-visibility {
46
+ right: 10px;
47
+ left: auto;
59
48
  }
60
- }
61
- // ##
62
- }
63
49
 
64
- // ## Selected & Focuced items customization
65
- .dx-treeview {
66
- .dx-treeview-node-container {
67
- .dx-treeview-node {
68
- &.dx-state-selected:not(.dx-state-focused)> .dx-treeview-item {
69
- background: transparent;
70
- }
50
+ .dx-rtl .dx-treeview-toggle-item-visibility {
51
+ left: 10px;
52
+ right: auto;
53
+ }
54
+ // ##
71
55
 
72
- &.dx-state-selected > .dx-treeview-item * {
73
- color: $base-accent;
56
+ // ## Item levels customization
57
+ .dx-treeview-node {
58
+ &[aria-level="1"] {
59
+ font-weight: bold;
74
60
  }
75
61
 
76
- &:not(.dx-state-focused)>.dx-treeview-item.dx-state-hover {
77
- background-color: lighten($base-bg, 4.00);
62
+ &[aria-level="2"] .dx-treeview-item-content {
63
+ font-weight: normal;
64
+ padding: 0 $side-panel-min-width;
78
65
  }
79
66
  }
67
+ // ##
80
68
  }
81
69
  }
82
-
83
- .dx-theme-generic .dx-treeview {
84
- .dx-treeview-node-container .dx-treeview-node.dx-state-selected.dx-state-focused > .dx-treeview-item * {
85
- color: inherit;
86
- }
87
- }
88
- // ##
89
70
  }
90
71
  }
91
72
 
@@ -1,12 +1,13 @@
1
- import React, { useEffect, useRef, useCallback, useMemo } from 'react';
1
+ import React, { useEffect, useRef, useCallback, useMemo, useContext } from 'react';
2
2
  import { TreeView<%=#isTypeScript%>, TreeViewRef<%=/isTypeScript%> } from 'devextreme-react/tree-view';
3
+ import * as events from 'devextreme/events';
3
4
  import { navigation } from '../../app-navigation';
4
5
  import { useNavigation } from '../../contexts/navigation';
5
6
  import { useScreenSize } from '../../utils/media-query';
6
7
  import './SideNavigationMenu.scss';
7
8
  <%=#isTypeScript%>import type { SideNavigationMenuProps } from '../../types';<%=/isTypeScript%>
8
9
 
9
- import * as events from 'devextreme/events';
10
+ import { ThemeContext } from '../../theme';
10
11
 
11
12
  export default function SideNavigationMenu(props<%=#isTypeScript%>: React.PropsWithChildren<SideNavigationMenuProps><%=/isTypeScript%>) {
12
13
  const {
@@ -17,6 +18,7 @@ export default function SideNavigationMenu(props<%=#isTypeScript%>: React.PropsW
17
18
  onMenuReady
18
19
  } = props;
19
20
 
21
+ const theme = useContext(ThemeContext);
20
22
  const { isLarge } = useScreenSize();
21
23
  function normalizePath () {
22
24
  return navigation.map((item) => (
@@ -64,7 +66,7 @@ export default function SideNavigationMenu(props<%=#isTypeScript%>: React.PropsW
64
66
 
65
67
  return (
66
68
  <div
67
- className={'dx-swatch-additional side-navigation-menu'}
69
+ className={`dx-swatch-additional${theme?.isDark() ? '-dark' : ''} side-navigation-menu`}
68
70
  ref={getWrapperRef}
69
71
  >
70
72
  {children}
@@ -0,0 +1,20 @@
1
+ import React, { useCallback, useContext } from 'react';
2
+ import Button from 'devextreme-react/button';
3
+ import { ThemeContext } from '../../theme';
4
+
5
+ export const ThemeSwitcher = () => {
6
+ const themeContext = useContext(ThemeContext);
7
+
8
+ const onButtonClick = useCallback(() => {
9
+ themeContext?.switchTheme();
10
+ }, []);
11
+
12
+ return <div>
13
+ <Button
14
+ className='theme-button'
15
+ stylingMode='text'
16
+ icon={`${themeContext?.theme === 'dark' ? 'sun' : 'moon'}`}
17
+ onClick={onButtonClick}
18
+ />
19
+ </div>;
20
+ };
@@ -1,63 +1,51 @@
1
- @import "../../themes/generated/variables.base.scss";
1
+ .app .header-toolbar .user-panel .user-button.dx-dropdownbutton img.dx-icon {
2
+ height: 100%;
3
+ width: auto;
2
4
 
3
- .user-info {
4
- display: flex;
5
- align-items: center;
6
-
7
- .dx-toolbar-menu-section & {
8
- padding: 10px 6px;
9
- border-bottom: 1px solid rgba(0, 0, 0, 0.1);
5
+ .dx-theme-generic & {
6
+ max-height: 32px;
10
7
  }
8
+ }
11
9
 
12
- .image-container {
13
- overflow: hidden;
14
- border-radius: 50%;
15
- height: 30px;
16
- width: 30px;
17
- margin: 0 4px;
18
- border: 1px solid rgba(0, 0, 0, 0.1);
19
- box-shadow: 0 1px 3px rgba(0,0,0,0.15);
20
-
21
- .user-image {
22
- width: 100%;
23
- height: 100%;
10
+ .user-panel {
11
+ display: flex;
12
+ flex-direction: column;
13
+
14
+ .user-button.dx-dropdownbutton {
15
+ margin-left: 5px;
16
+
17
+ img.dx-icon {
18
+ border-radius: 50%;
19
+ margin: 0;
20
+ width: auto;
21
+ aspect-ratio: 1 / 1;
22
+ box-sizing: border-box;
23
+ border: 1px solid var(--dx-color-border);
24
+ object-fit: cover;
25
+ object-position: top;
26
+ background: rgb(255, 255, 255);
27
+ background-clip: padding-box;
24
28
  }
25
- }
26
29
 
27
- .user-name {
28
- font-size: 14px;
29
- color: $base-text-color;
30
- margin: 0 9px;
31
- }
32
- }
33
30
 
34
- .user-panel {
35
- .dx-list-item .dx-icon {
36
- vertical-align: middle;
37
- color: $base-text-color;
38
- margin-right: 16px;
39
- }
40
- .dx-rtl .dx-list-item .dx-icon {
41
- margin-right: 0;
42
- margin-left: 16px;
43
- }
44
- }
45
31
 
46
- .dx-context-menu.user-menu.dx-menu-base {
47
- &.dx-rtl {
48
- .dx-submenu .dx-menu-items-container .dx-icon {
49
- margin-left: 16px;
32
+ .dx-buttongroup {
33
+ vertical-align: middle;
34
+
35
+ .dx-button.dx-button-has-icon:not(.dx-button-has-text) {
36
+ .dx-button-content {
37
+ padding: 0;
38
+ }
39
+
40
+ &.dx-state-hover,
41
+ &.dx-state-focused {
42
+ background-color: transparent;
43
+
44
+ img.dx-icon {
45
+ border-color: var(--dx-color-primary);
46
+ }
47
+ }
48
+ }
50
49
  }
51
50
  }
52
- .dx-submenu .dx-menu-items-container .dx-icon {
53
- margin-right: 16px;
54
- }
55
- .dx-menu-item .dx-menu-item-content {
56
- padding: 3px 15px 4px;
57
- }
58
- }
59
-
60
- .dx-theme-generic .user-menu .dx-menu-item-content .dx-menu-item-text {
61
- padding-left: 4px;
62
- padding-right: 4px;
63
51
  }