diff --git a/webapp/configs/rollup.config.js b/webapp/configs/rollup.config.js index 2b609aecef..cfbfa955e0 100644 --- a/webapp/configs/rollup.config.js +++ b/webapp/configs/rollup.config.js @@ -67,6 +67,7 @@ export function configBuilder(options = defaultBuilderOptions) { firstPlugin: require('reshadow/postcss'), plugins: [ require('postcss-preset-env')({ stage: 0 }), + require('postcss-discard-comments'), // todo move 'reshadow/postcss' to custom loader to run it before postcss-loader // require('reshadow/postcss'), ] diff --git a/webapp/configs/webpack/common.js b/webapp/configs/webpack/common.js index 6a9cd92af7..9d8e27fda3 100644 --- a/webapp/configs/webpack/common.js +++ b/webapp/configs/webpack/common.js @@ -28,29 +28,26 @@ class IgnoreNotFoundExportPlugin { module.exports = (env, argv) => { - function generateStyleLoaders(options = {hasModule: false, hasReshadow: false}) { - // options.hasModule - const modules = options.hasModule - ? { - mode: 'local', - localIdentName: '[local]___[hash:base64:5]', - } - : undefined; + function generateStyleLoaders(options = { hasModule: false, hasReshadow: false }) { + const modules = { + mode: options.hasModule ? 'local' : 'global', + localIdentName: '[local]___[hash:base64:5]', + }; - // options.hasReshadow const postCssPlugins = [ require('postcss-preset-env')({ stage: 0 }), require('@csstools/postcss-sass')({ includePaths: ['node_modules', path.resolve('../../node_modules')], }), + require('postcss-discard-comments'), ]; + if (options.hasReshadow) { postCssPlugins.push(require('reshadow/postcss')); } // 'use' clause in webpack rules return [ - // 'style-loader', { loader: MiniCssExtractPlugin.loader, options: { @@ -75,124 +72,123 @@ module.exports = (env, argv) => { } return { - resolve: { - extensions: ['.ts', '.tsx', '.js', '.jsx'], - }, - module: { - rules: [ - { - test: /\.js$/, - use: [ - { - loader: 'babel-loader', - options: { - configFile: path.join(__dirname, '../babel.config.js') - }, - }, - 'source-map-loader' - ], - exclude: /node_modules/, - }, - { - test: /\.tsx?$/, - use: [ - { - loader: 'babel-loader', - options: { - configFile: path.join(__dirname, '../babel.config.js') - }, - }, - { - loader: 'eslint-loader', - // uncomment to fix after rule changes - // options: { - // fix: true, - // }, - } - ], - }, - { - test: /\.(css|scss|sass)$/, - oneOf: [ - // css-module files ( should have *.module mask ) - { - test: /\.module\.(css|scss|sass)$/, - use: generateStyleLoaders({hasModule: true, hasReshadow: true}), - }, - // not css-module files - 3 ways to treat them - { - test: /\.raw\.(css|scss|sass)$/, - use: generateStyleLoaders({hasModule: false, hasReshadow: false}), - }, - { - include: /node_modules/, - use: [ - // 'style-loader', - { - loader: MiniCssExtractPlugin.loader, - options: { - hot: argv.mode !== 'production', - }, + resolve: { + extensions: ['.ts', '.tsx', '.js', '.jsx'], + }, + module: { + rules: [ + { + test: /\.js$/, + use: [ + { + loader: 'babel-loader', + options: { + configFile: path.join(__dirname, '../babel.config.js') }, - 'css-loader', - ] - }, - { - use: generateStyleLoaders({hasModule: false, hasReshadow: true}), - } - ] - }, - { - test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i, - loader: 'url-loader', - options: { - limit: 8192, + }, + 'source-map-loader' + ], + exclude: /node_modules/, }, - }, + { + test: /\.tsx?$/, + use: [ + { + loader: 'babel-loader', + options: { + configFile: path.join(__dirname, '../babel.config.js') + }, + }, + { + loader: 'eslint-loader', + // uncomment to fix after rule changes + // options: { + // fix: true, + // }, + } + ], + }, + { + test: /\.(css|scss|sass)$/, + oneOf: [ + // css-module files ( should have *.module mask ) + { + test: /\.module\.(css|scss|sass)$/, + use: generateStyleLoaders({ hasModule: true, hasReshadow: true }), + }, + // not css-module files - 3 ways to treat them + { + test: /\.raw\.(css|scss|sass)$/, + use: generateStyleLoaders({ hasModule: false, hasReshadow: false }), + }, + { + include: /node_modules/, + use: [ + { + loader: MiniCssExtractPlugin.loader, + options: { + hot: argv.mode !== 'production', + }, + }, + 'css-loader', + ] + }, + { + use: generateStyleLoaders({ hasModule: false, hasReshadow: true }), + } + ] + }, + { + test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i, + loader: 'url-loader', + options: { + limit: 8192, + }, + }, + ], + }, + optimization: { + minimize: false, + namedModules: true, + concatenateModules: false, + }, + plugins: [ + new IgnoreNotFoundExportPlugin(), + new webpack.ProgressPlugin({ + entries: true, + modules: true, + modulesCount: 100, + profile: true, + handler: (percentage, message, ...args) => { + // custom logic + } + }), + new CircularDependencyPlugin({ + // exclude detection of files based on a RegExp + exclude: /a\.js|node_modules/, + // include specific files based on a RegExp + // include: /dir/, + // add errors to webpack instead of warnings + failOnError: false, + // allow import cycles that include an asyncronous import, + // e.g. via import(/* webpackMode: "weak" */ './file.js') + allowAsyncCycles: false, + // set the current working directory for displaying module paths + cwd: process.cwd(), + }), + new MiniCssExtractPlugin({ + // Options similar to the same options in webpackOptions.output + // all options are optional + filename: argv.mode !== 'production' ? '[name].css' : '[name].[hash].css', + chunkFilename: argv.mode !== 'production' ? '[name].css' : '[name].[hash].css', + ignoreOrder: false, // Enable to remove warnings about conflicting order + }), + // new webpack.optimize.LimitChunkCountPlugin({ + // maxChunks: 1, + // }), ], - }, - optimization: { - minimize: false, - namedModules: true, - concatenateModules: false, - }, - plugins: [ - new IgnoreNotFoundExportPlugin(), - new webpack.ProgressPlugin({ - entries: true, - modules: true, - modulesCount: 100, - profile: true, - handler: (percentage, message, ...args) => { - // custom logic - } - }), - new CircularDependencyPlugin({ - // exclude detection of files based on a RegExp - exclude: /a\.js|node_modules/, - // include specific files based on a RegExp - // include: /dir/, - // add errors to webpack instead of warnings - failOnError: false, - // allow import cycles that include an asyncronous import, - // e.g. via import(/* webpackMode: "weak" */ './file.js') - allowAsyncCycles: false, - // set the current working directory for displaying module paths - cwd: process.cwd(), - }), - new MiniCssExtractPlugin({ - // Options similar to the same options in webpackOptions.output - // all options are optional - filename: argv.mode !== 'production' ? '[name].css' : '[name].[hash].css', - chunkFilename: argv.mode !== 'production' ? '[name].css' : '[name].[hash].css', - ignoreOrder: false, // Enable to remove warnings about conflicting order - }), - // new webpack.optimize.LimitChunkCountPlugin({ - // maxChunks: 1, - // }), - ], - performance: { - hints: false, - }, -}; + performance: { + hints: false, + }, + }; }; diff --git a/webapp/package.json b/webapp/package.json index 8741b3aa75..91e5ac234d 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -77,6 +77,7 @@ "mini-css-extract-plugin": "^0.9.0", "node-sass": "^4.13.0", "peer-deps-externals-webpack-plugin": "^1.0.4", + "postcss-discard-comments": "^4.0.2", "postcss-extend-rule": "^3.0.0", "postcss-import": "^12.0.1", "postcss-loader": "^3.0.0", diff --git a/webapp/packages/ag-grid-plugin/src/AgGridTable/AgGridTable.tsx b/webapp/packages/ag-grid-plugin/src/AgGridTable/AgGridTable.tsx index dd8c8457b9..fe87a6cc93 100644 --- a/webapp/packages/ag-grid-plugin/src/AgGridTable/AgGridTable.tsx +++ b/webapp/packages/ag-grid-plugin/src/AgGridTable/AgGridTable.tsx @@ -12,17 +12,16 @@ import { observer, Observer } from 'mobx-react'; import { PropsWithChildren } from 'react'; import styled from 'reshadow'; -import '../styles/base.raw.scss'; // it leads to encapsulation of ag-gris style in main.css import { ComplexLoader, Loader } from '@dbeaver/core/blocks'; import { useController } from '@dbeaver/core/di'; import { useStyles } from '@dbeaver/core/theming'; import { RangeSelectionModule } from '../modules/RangeSelection/rangeSelectionModule'; +import { agGridStyles } from '../styles/styles'; import { AgGridTableController } from './AgGridTableController'; import { IAgGridModel } from './IAgGridModel'; import { LoadingCell } from './LoadingCell'; import { PlainTextEditor } from './PlainTextEditor/PlainTextEditor'; -import { agGridStyles } from './styles'; import { TableColumnHeader } from './TableColumnHeader/TableColumnHeader'; export type AgGridTableProps = PropsWithChildren< diff --git a/webapp/packages/ag-grid-plugin/src/AgGridTable/AgGridTableController.ts b/webapp/packages/ag-grid-plugin/src/AgGridTable/AgGridTableController.ts index 0bc834069e..f02282d2ef 100644 --- a/webapp/packages/ag-grid-plugin/src/AgGridTable/AgGridTableController.ts +++ b/webapp/packages/ag-grid-plugin/src/AgGridTable/AgGridTableController.ts @@ -54,7 +54,8 @@ export class AgGridTableController implements IInitializableController, IDestruc private readonly gridOptions: GridOptions = { defaultColDef: defaultColumnDef, - rowHeight: 28, + rowHeight: 24, + headerHeight: 28, rowModelType: 'infinite', cacheBlockSize: undefined, // to be set during init phase @@ -235,7 +236,7 @@ export class AgGridTableController implements IInitializableController, IDestruc } private cloneRows(rows: AgGridRow[]): AgGridRow[] { - return rows.map(row => [...row]); + return rows.map(row => [...row].map(v => (v === null ? '' : v))); // TODO: temporary fix dbeaver-corp/dbeaver-web#663 } } diff --git a/webapp/packages/ag-grid-plugin/src/AgGridTable/PlainTextEditor/PlainTextEditor.tsx b/webapp/packages/ag-grid-plugin/src/AgGridTable/PlainTextEditor/PlainTextEditor.tsx index 3ccd39060b..ac35a6e03c 100644 --- a/webapp/packages/ag-grid-plugin/src/AgGridTable/PlainTextEditor/PlainTextEditor.tsx +++ b/webapp/packages/ag-grid-plugin/src/AgGridTable/PlainTextEditor/PlainTextEditor.tsx @@ -24,7 +24,7 @@ const styles = css` position: absolute; left: 0; top: -1px; - bottom: -1px; + bottom: 0; width: 100%; } `; diff --git a/webapp/packages/ag-grid-plugin/src/AgGridTable/styles.ts b/webapp/packages/ag-grid-plugin/src/AgGridTable/styles.ts deleted file mode 100644 index 467a178040..0000000000 --- a/webapp/packages/ag-grid-plugin/src/AgGridTable/styles.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * cloudbeaver - Cloud Database Manager - * Copyright (C) 2020 DBeaver Corp and others - * - * Licensed under the Apache License, Version 2.0. - * you may not use this file except in compliance with the License. - */ - -import { ThemeSelector } from '@dbeaver/core/src/theming'; - -export const agGridStyles: ThemeSelector = async (theme) => { - const styles = theme === 'dark' - ? await import('../styles/themes/dark.module.scss') - : await import('../styles/themes/light.module.scss'); - return styles.default; -}; diff --git a/webapp/packages/ag-grid-plugin/src/styles/base.raw.scss b/webapp/packages/ag-grid-plugin/src/styles/base.raw.scss index e00c1ddd43..6b72360d4a 100644 --- a/webapp/packages/ag-grid-plugin/src/styles/base.raw.scss +++ b/webapp/packages/ag-grid-plugin/src/styles/base.raw.scss @@ -6,35 +6,50 @@ * you may not use this file except in compliance with the License. */ -/* changes the default icon color*/ -/* $icon-color: #03a9f4; */ - -/* changes the selected checkbox check mark color*/ -/* $accent-color: #03a9f4; */ - -$hover-color: cornsilk; -$background-color: transparent; - -/* $ag-range-selected-color-1: rgb(250, 235, 215); -$ag-range-selected-color-2: darken($ag-range-selected-color-1, 10%); -$ag-range-selected-color-3: darken($ag-range-selected-color-1, 20%); -$ag-range-selected-color-4: darken($ag-range-selected-color-1, 30%); */ - @import "ag-grid-community/src/styles/ag-grid.scss"; -@import "ag-grid-community/src/styles/ag-theme-balham/sass/ag-theme-balham.scss"; +@import "ag-grid-community/src/styles/ag-theme-balham/sass/ag-theme-balham-mixin.scss"; +@import "ag-grid-community/src/styles/webfont/agGridAlpineFont.scss"; + +:local(.__ag-grid-theme) { + composes: ag-theme-balham from global; +} .ag-theme-balham { + @include ag-theme-balham(); + + font-family: inherit; + + .ag-header, + .ag-root-wrapper, + .ag-row { + background-color: transparent; + } + .ag-header { + height: 28px; + min-height: 28px; + } + .ag-root-wrapper { + border: none; + border-radius: initial; + } + .ag-row { + height: 24px; + } + .ag-cell { + line-height: 22px; + } + .ag-center-cols-container { + min-width: 100%; + } .ag-react-container { position: relative; display: flex; width: 100%; height: 100%; - padding-left: 12px; - padding-right: 12px; } .ag-cell.ag-cell-inline-editing { overflow: visible; - height: 27px; + height: 24px; } } diff --git a/webapp/packages/ag-grid-plugin/src/styles/styles.ts b/webapp/packages/ag-grid-plugin/src/styles/styles.ts new file mode 100644 index 0000000000..ce342f7829 --- /dev/null +++ b/webapp/packages/ag-grid-plugin/src/styles/styles.ts @@ -0,0 +1,26 @@ +/* + * cloudbeaver - Cloud Database Manager + * Copyright (C) 2020 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +import { ThemeSelector } from '@dbeaver/core/src/theming'; + +export const agGridStyles: ThemeSelector = async (theme) => { + const baseStyles = await import('./base.raw.scss'); + let styles: any; + + switch (theme) { + case 'dark': + styles = await import('./themes/dark.scss'); + break; + default: + styles = await import('./themes/light.scss'); + break; + } + console.log(baseStyles.default, styles.default); + + return [baseStyles.default, styles.default]; +}; diff --git a/webapp/packages/ag-grid-plugin/src/styles/themes/_base-ag-grid.scss b/webapp/packages/ag-grid-plugin/src/styles/themes/_base-ag-grid.scss new file mode 100644 index 0000000000..2b3341fa8a --- /dev/null +++ b/webapp/packages/ag-grid-plugin/src/styles/themes/_base-ag-grid.scss @@ -0,0 +1,62 @@ +/* + * cloudbeaver - Cloud Database Manager + * Copyright (C) 2020 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +@import "@dbeaver/core/assets/styles/branding"; + +@mixin base-ag-grid() { + .ag-theme-balham { + .ag-header { + border-bottom: 1px solid; + @include mdc-theme-prop(color, on-surface, false); + @include mdc-theme-prop(border-color, background, false); + } + .ag-header-row { + @include mdc-theme-prop(color, on-surface, false); + } + + .ag-row { + border-top: none; + border-bottom: solid 1px; + @include mdc-theme-prop(color, on-surface, false); + @include mdc-theme-prop(border-color, background, false); + } + + .ag-row-selected { + border-color: #03a9f4; + background-color: transparent; + @include stripes-background($mdc-theme-secondary); + } + + .ag-cell-range-selected-1 { + background-color: rgba(0, 145, 234, 0.3); + } + + .ag-row-hover { + background-color: transparent; + @include stripes-background($mdc-theme-secondary); + border-color: $color-positive; + } + + .ag-cell.ag-cell-inline-editing { + border: 0 !important; + border-radius: 0; + @include mdc-theme-prop(background-color, surface, false); + } + + .ag-header-cell::after, + .ag-header-group-cell::after { + height: 100%; + top: 0; + @include mdc-theme-prop(background-color, background, false); + } + .ag-cell.ag-cell-last-left-pinned:not(.ag-cell-range-right):not(.ag-cell-range-single-cell), + .ag-pinned-left-header { + @include mdc-theme-prop(border-right-color, background, false); + } + } +} diff --git a/webapp/packages/ag-grid-plugin/src/styles/themes/_styles.scss b/webapp/packages/ag-grid-plugin/src/styles/themes/_styles.scss deleted file mode 100644 index 9cccefe272..0000000000 --- a/webapp/packages/ag-grid-plugin/src/styles/themes/_styles.scss +++ /dev/null @@ -1,88 +0,0 @@ -/* - * cloudbeaver - Cloud Database Manager - * Copyright (C) 2020 DBeaver Corp and others - * - * Licensed under the Apache License, Version 2.0. - * you may not use this file except in compliance with the License. - */ - -@import "@dbeaver/core/assets/styles/branding"; - -ag-grid-theme { - composes: ag-theme-balham from global; //reshadow compose - height: 100%; - - &:global(.ag-theme-balham) { - background-color: transparent !important; - - :global(.ag-root) { - border: none !important; - background-color: transparent !important; - } - - :global(.ag-header) { - border-bottom: 1px solid; - @include mdc-theme-prop(color, on-surface, false); - @include mdc-theme-prop(border-color, background, false); - } - - :global(.ag-header), - :global(.ag-row-even), - :global(.ag-row-odd) { - background: transparent; - } - - :global(.ag-row) { - border-width: 0px 0 1px !important; - @include mdc-theme-prop(color, on-surface, false); - @include mdc-theme-prop(border-color, background, false); - } - - :global(.ag-row-selected) { - border-color: #03a9f4; - background-color: transparent; - @include stripes-background($mdc-theme-secondary); - } - - :global(.ag-cell-range-selected-1) { - background-color: rgba(0, 145, 234, 0.3); - } - - :global(.ag-row-hover) { - background-color: transparent; - @include stripes-background($mdc-theme-secondary); - border-color: #01cca3; - } - - :global(.ag-cell.ag-cell-inline-editing) { - border: 0 !important; - border-radius: 0; - @include mdc-theme-prop(background-color, surface, false); - } - - :global(.ag-header-cell), - :global(.ag-header-group-cell) { - padding-left: 0; - padding-right: 0; - } - - :global(.ag-header-cell)::after, - :global(.ag-header-group-cell)::after { - height: 100%; - margin-top: 0; - border-right: 1px solid; - @include mdc-theme-prop(border-right-color, background, false); - } - - :global(.ag-ltr) - :global(.ag-cell):not(:global(.ag-cell-focus)):global(.ag-cell-last-left-pinned):not(:global(.ag-cell-range-right)), - :global(.ag-ltr) - :global(.ag-cell):global(.ag-cell-range-selected):not(:global(.ag-cell-range-single-cell)):global(.ag-cell-last-left-pinned):not(:global(.ag-cell-range-right)), - :global(.ag-ltr) - :global(.ag-root):not(:global(.ag-has-focus)) - :global(.ag-cell):global(.ag-cell-last-left-pinned):not(:global(.ag-cell-range-right)) { - border-right: 1px solid; - @include mdc-theme-prop(border-right-color, background, false); - } - } -} diff --git a/webapp/packages/ag-grid-plugin/src/styles/themes/dark.module.scss b/webapp/packages/ag-grid-plugin/src/styles/themes/dark.scss similarity index 65% rename from webapp/packages/ag-grid-plugin/src/styles/themes/dark.module.scss rename to webapp/packages/ag-grid-plugin/src/styles/themes/dark.scss index 5619680726..358356a6e0 100644 --- a/webapp/packages/ag-grid-plugin/src/styles/themes/dark.module.scss +++ b/webapp/packages/ag-grid-plugin/src/styles/themes/dark.scss @@ -6,5 +6,9 @@ * you may not use this file except in compliance with the License. */ -@import '@dbeaver/core/assets/styles/theme-dark'; -@import 'styles'; +@import "@dbeaver/core/assets/styles/theme-dark"; +@import "base-ag-grid"; + +.theme-dark { + @include base-ag-grid; +} diff --git a/webapp/packages/ag-grid-plugin/src/styles/themes/light.module.scss b/webapp/packages/ag-grid-plugin/src/styles/themes/light.scss similarity index 80% rename from webapp/packages/ag-grid-plugin/src/styles/themes/light.module.scss rename to webapp/packages/ag-grid-plugin/src/styles/themes/light.scss index 9515b97995..5d0c04271b 100644 --- a/webapp/packages/ag-grid-plugin/src/styles/themes/light.module.scss +++ b/webapp/packages/ag-grid-plugin/src/styles/themes/light.scss @@ -7,4 +7,8 @@ */ @import '@dbeaver/core/assets/styles/theme-light'; -@import "styles"; +@import "base-ag-grid"; + +.theme-light { + @include base-ag-grid; +} \ No newline at end of file diff --git a/webapp/packages/core/assets/styles/_color.scss b/webapp/packages/core/assets/styles/_color.scss index c0fd2680ef..7d72a0f8aa 100644 --- a/webapp/packages/core/assets/styles/_color.scss +++ b/webapp/packages/core/assets/styles/_color.scss @@ -25,6 +25,11 @@ } } } + .theme-border-color-#{$style} { + @include mdc-feature-targets($feat-color) { + @include mdc-theme-prop(border-color, $style, true); + } + } } @else { .theme-text-#{$style} { @include theme-ripple-color($query, $style); @@ -45,10 +50,10 @@ @include mdc-theme-prop(background-color, $style); } } - } - .theme-border-color-#{$style} { - @include mdc-feature-targets($feat-color) { - @include mdc-theme-prop(border-color, $style, true); + .theme-border-color-#{$style} { + @include mdc-feature-targets($feat-color) { + @include mdc-theme-prop(border-color, $style); + } } } } diff --git a/webapp/packages/core/src/app/shared/InlineEditor/styles.ts b/webapp/packages/core/src/app/shared/InlineEditor/styles.ts index 2dafab3e10..713762e09e 100644 --- a/webapp/packages/core/src/app/shared/InlineEditor/styles.ts +++ b/webapp/packages/core/src/app/shared/InlineEditor/styles.ts @@ -13,20 +13,23 @@ import { composes } from '@dbeaver/core/theming'; export const InlineEditorStyles = composes( css` editor-actions { - composes: theme-background-surface theme-text-on-surface from global; + composes: theme-background-surface theme-text-on-surface theme-border-color-background from global; } editor-action { composes: theme-ripple from global; } + + input { + composes: theme-text-text-primary-on-light from global; + } `, css` editor { position: relative; + box-sizing: border-box; width: 100%; height: 100%; - padding-left: 12px; - padding-right: 12px; border: solid 1px #01cca3; } @@ -37,10 +40,13 @@ export const InlineEditorStyles = composes( & input { color: inherit; background: inherit; + letter-spacing: inherit; + outline: none; border: none; - font-size: 13px; + padding-left: 11px; /* because of left border */ + padding-right: 12px; + padding-top: 1px; /* because of -1px top */ line-height: 24px; - font-weight: 700; width: 100%; height: 100%; } @@ -50,12 +56,14 @@ export const InlineEditorStyles = composes( position: absolute; top: -1px; left: 100%; - height: auto; + height: 100%; display: flex; flex-direction: row; - border: solid 1px #01cca3; - border-left-color: #dedede; + border: solid 1px; + border-top-color: #01cca3 !important; + border-right-color: #01cca3 !important; + border-bottom-color: #01cca3 !important; } editor-actions[|position=bottom], @@ -75,8 +83,9 @@ export const InlineEditorStyles = composes( } editor-action { + box-sizing: border-box; display: flex; - width: 27px; + width: 24px; padding: 5px; cursor: pointer; diff --git a/webapp/packages/core/src/theming/useStyles.ts b/webapp/packages/core/src/theming/useStyles.ts index d4b70fe295..a0c74a5c1a 100644 --- a/webapp/packages/core/src/theming/useStyles.ts +++ b/webapp/packages/core/src/theming/useStyles.ts @@ -15,9 +15,9 @@ import { useService } from '@dbeaver/core/di'; import { ThemeService } from './ThemeService'; import { applyComposes, ClassCollection, Composes } from './themeUtils'; -export type ThemeSelector = (theme: string) => Promise - -export type Style = ClassCollection | Composes | ThemeSelector +export type BaseStyles = ClassCollection | Composes +export type ThemeSelector = (theme: string) => Promise +export type Style = BaseStyles | ThemeSelector /** * Changes styles depending on theme @@ -30,7 +30,7 @@ export function useStyles( // todo do you understand that we store ALL STYLES in each component that uses this hook? - const [loadedStyles, setLoadedStyles] = useState>([]); + const [loadedStyles, setLoadedStyles] = useState([]); const themeService = useService(ThemeService); const currentThemeId = useObserver(() => themeService.currentThemeId); @@ -41,7 +41,7 @@ export function useStyles( style => ((typeof style === 'object' || style instanceof Composes) ? style : style(currentThemeId)) ) ) - .then(setLoadedStyles); + .then(styles => setLoadedStyles(styles.flat())); }, [currentThemeId]); const styles = useMemo(() => {