From b8699e6bcb8d124b35149bd55598a55e2478fa61 Mon Sep 17 00:00:00 2001 From: Viktor Kirst Date: Thu, 2 Apr 2026 18:01:58 +0400 Subject: [PATCH 1/3] dbeaver/pro#8896 Fix driver description (#4257) --- server/bundles/io.cloudbeaver.resources.drivers.base/plugin.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/bundles/io.cloudbeaver.resources.drivers.base/plugin.xml b/server/bundles/io.cloudbeaver.resources.drivers.base/plugin.xml index aa00541b0d..37808a0eeb 100644 --- a/server/bundles/io.cloudbeaver.resources.drivers.base/plugin.xml +++ b/server/bundles/io.cloudbeaver.resources.drivers.base/plugin.xml @@ -36,7 +36,7 @@ - + From a6a191629953d0f992279f130027169762b78eaa Mon Sep 17 00:00:00 2001 From: Serge Rider Date: Thu, 2 Apr 2026 16:09:06 +0200 Subject: [PATCH 2/3] dbeaver/pro#8894 Fix tests --- .../cloudbeaver/model/session/WebSessionTest.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/model/session/WebSessionTest.java b/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/model/session/WebSessionTest.java index 4de3577d39..5c8aff73e7 100644 --- a/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/model/session/WebSessionTest.java +++ b/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/model/session/WebSessionTest.java @@ -1,6 +1,6 @@ /* * DBeaver - Universal Database Manager - * Copyright (C) 2010-2025 DBeaver Corp and others + * Copyright (C) 2010-2026 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,12 +62,15 @@ public class WebSessionTest extends CloudbeaverMockTest { String created = session.getAttribute("createdKey", creator, disposer); Assert.assertEquals("created", created); - // After close() non-persistent attribute should be disposed; persistent remain - session.close(); - - Assert.assertTrue("disposer must be invoked during close()", disposed.get()); // persistent attribute should still be available Assert.assertEquals("persistValue", session.getAttribute("persistentKey")); + + session.close(); + + // persistent attribute should иу тгдд + Assert.assertNull("persistValue", session.getAttribute("persistentKey")); + + Assert.assertTrue("disposer must be invoked during close()", disposed.get()); } @Test From ea362477972326ca4c33f03eab72bc8ba9a58773 Mon Sep 17 00:00:00 2001 From: sergeyteleshev Date: Thu, 2 Apr 2026 18:24:19 +0200 Subject: [PATCH 3/3] [CB] Replace material ui with native css variables and tailwind utilities (#4188) * dbeaver/pro#8433 initial version of material ui refactor * fixes arrow colors * fixes arrow colors 2 * fixes colors * pr fixes * removes layers due to it loses styles specificity race * fixes autocomplete styles * adds variables for typography * moves switch logic to module styles * removes elevation styles * removes unused code * migrates ripple effect to tw class * Revert "migrates ripple effect to tw class" This reverts commit 78229ac0073e4b8b5119882b8131664c5f63f739. * uses classname theme-typography for button * adds elevation styles * adds elevation styles 2 * moves theme ripple * reverts scss for sql editor * reverts scss for sql editor 2 * adds tailwindcss utilities + example * Revert "adds tailwindcss utilities + example" This reverts commit 20ca1b787c0b806729f7e3ff448d5200e1a323c5. * creates tailwindcss plugin with shadow tokens + spread it across the app * moves typography to the tailwindcss styles * refactors sql editor styles * moves styles from tailwindcss folder to styles * moves ripple to tailwindcss plugin * removes unused files * removes unused file index * removes redundant tailwindcss import * adds animation layer for tailwindcss * refactors animations * build fix * removes redundant imports of tailwindcss for styles * removes layer components to keep some styles for switch * removes animation from ripple effect * makes ripple effect more contrast * fixes fonts across the app to json view has correct font-mono from the tailwindcss box * deletes module ts * Revert "removes layer components to keep some styles for switch" This reverts commit ee8b0e199eae85d3a76b58e0460656fd90699ab8. * fixes race for switch bold style * changes ripple from 7% to 9% * Reduce hover opacity in ripple effect (#4260) * Reduce hover opacity in ripple effect * Update ripple.css --------- Co-authored-by: mr-anton-t <42037741+mr-anton-t@users.noreply.github.com> --- webapp/packages/core-blocks/src/Button.css | 4 - webapp/packages/core-blocks/src/Button.tsx | 42 ++- .../CommonDialogWrapper.module.css | 2 +- .../CommonDialog/CommonDialogWrapper.tsx | 4 +- .../src/CommonDialog/DialogsPortal.module.css | 2 +- .../src/CommonDialog/DialogsPortal.tsx | 4 +- .../ConnectionMark.module.css | 2 +- .../core-blocks/src/Expand/Expandable.css | 6 +- .../src/FormControls/BaseDropdown.module.css | 2 +- .../FormControls/Checkboxes/Switch.module.css | 127 +++++-- .../Checkboxes/SwitchDense.module.css | 39 +- .../Checkboxes/SwitchPrimary.module.css | 15 +- .../FormControls/InputAutocompletionMenu.tsx | 43 ++- .../core-blocks/src/Loader/Loader.module.css | 2 +- .../src/Overlay/Overlay.module.css | 62 ++-- .../core-blocks/src/Overlay/Overlay.tsx | 4 +- .../src/SlideDialog/SlideDialog.css | 2 +- .../SnackbarWrapper.module.css | 11 +- .../SnackbarMarkups/SnackbarWrapper.tsx | 4 +- .../src/Split/ResizerControls.module.css | 3 +- .../src/Table/TableColumnValue.module.css | 3 +- .../src/Table/TableItemExpand.module.css | 2 +- .../src/Table/TableItemGroupExpand.module.css | 2 +- webapp/packages/core-theming/package.json | 9 - .../packages/core-theming/src/ThemeService.ts | 2 - .../core-theming/src/styles/_branding.scss | 15 - .../core-theming/src/styles/_color.scss | 143 ++++---- .../src/styles/_form-controls.scss | 39 +- .../core-theming/src/styles/_mixins.scss | 10 - .../core-theming/src/styles/_placeholder.scss | 33 -- .../core-theming/src/styles/_ripple.scss | 31 -- .../core-theming/src/styles/_switch.scss | 79 ---- .../core-theming/src/styles/_theme-dark.scss | 16 - .../core-theming/src/styles/_theme-light.scss | 1 + .../src/styles/_theme-ripple.scss | 114 ------ .../core-theming/src/styles/_variables.scss | 24 +- .../core-theming/src/styles/layout-grid.scss | 109 ------ .../styles/main/app-loading-screen.pure.css | 27 +- .../src/styles/main/dark.theme.scss | 5 - .../src/styles/main/elevation.pure.scss | 32 -- .../src/styles/main/light.theme.scss | 5 - .../src/styles/main/typography.pure.scss | 23 -- .../src/styles/theme-dark.module.scss | 5 - .../src/styles/theme-light.module.scss | 5 - .../MenuBar/MenuBarItem.module.css | 1 + .../core-ui/src/Tabs/Tab/Tab.module.css | 4 - .../Finish/FinishPage.module.css | 10 +- .../packages/plugin-codemirror6/package.json | 1 + .../_base-code-editor-autocompletion.scss | 46 --- .../src/theme/_base-code-editor-tooltip.scss | 18 - .../src/theme/_base-code-editor.scss | 339 ------------------ .../theme/base-code-editor-autocompletion.css | 39 ++ .../src/theme/base-code-editor-tooltip.css | 14 + .../src/theme/base-code-editor.css | 327 +++++++++++++++++ .../plugin-codemirror6/src/theme/dark.css | 31 ++ .../src/theme/dark.module.scss | 49 --- .../plugin-codemirror6/src/theme/light.css | 31 ++ .../src/theme/light.module.scss | 49 --- .../plugin-codemirror6/src/theme/styles.ts | 14 +- .../packages/plugin-codemirror6/tsconfig.json | 3 + .../ConnectionPreferencesForm.tsx | 2 +- .../src/TableViewer/TableError.module.css | 8 +- .../src/HolidayActionButton.module.css | 5 +- .../NavigationNodeProjectControl.module.css | 3 +- .../ElementsTreeToolsIconButton.module.css | 5 +- .../NavigationNodeControlRenderer.module.css | 3 +- .../NavigationNodeProjectControl.module.css | 3 +- .../ExecutionPlan/Expand.module.css | 2 +- .../plugin-tailwindcss-theme/package.json | 39 ++ .../src/styles/animation.css | 55 +++ .../src/styles/index.css | 8 + .../src/styles/ripple.css | 38 ++ .../src/styles/shadow.css | 6 + .../src/styles/typography-utilities.css | 86 +++++ .../src/styles/typography.css | 53 +++ .../plugin-tailwindcss-theme/tsconfig.json | 34 ++ .../src/UserMenu/UserMenu.module.css | 1 + webapp/packages/product-default/package.json | 1 + .../packages/product-default/src/styles.css | 3 +- webapp/packages/product-default/tsconfig.json | 3 + webapp/yarn.lock | 230 +----------- 81 files changed, 1190 insertions(+), 1488 deletions(-) delete mode 100644 webapp/packages/core-theming/src/styles/_placeholder.scss delete mode 100644 webapp/packages/core-theming/src/styles/_ripple.scss delete mode 100644 webapp/packages/core-theming/src/styles/_switch.scss delete mode 100644 webapp/packages/core-theming/src/styles/_theme-ripple.scss delete mode 100644 webapp/packages/core-theming/src/styles/layout-grid.scss delete mode 100644 webapp/packages/core-theming/src/styles/main/elevation.pure.scss delete mode 100644 webapp/packages/core-theming/src/styles/main/typography.pure.scss delete mode 100644 webapp/packages/plugin-codemirror6/src/theme/_base-code-editor-autocompletion.scss delete mode 100644 webapp/packages/plugin-codemirror6/src/theme/_base-code-editor-tooltip.scss delete mode 100644 webapp/packages/plugin-codemirror6/src/theme/_base-code-editor.scss create mode 100644 webapp/packages/plugin-codemirror6/src/theme/base-code-editor-autocompletion.css create mode 100644 webapp/packages/plugin-codemirror6/src/theme/base-code-editor-tooltip.css create mode 100644 webapp/packages/plugin-codemirror6/src/theme/base-code-editor.css create mode 100644 webapp/packages/plugin-codemirror6/src/theme/dark.css delete mode 100644 webapp/packages/plugin-codemirror6/src/theme/dark.module.scss create mode 100644 webapp/packages/plugin-codemirror6/src/theme/light.css delete mode 100644 webapp/packages/plugin-codemirror6/src/theme/light.module.scss create mode 100644 webapp/packages/plugin-tailwindcss-theme/package.json create mode 100644 webapp/packages/plugin-tailwindcss-theme/src/styles/animation.css create mode 100644 webapp/packages/plugin-tailwindcss-theme/src/styles/index.css create mode 100644 webapp/packages/plugin-tailwindcss-theme/src/styles/ripple.css create mode 100644 webapp/packages/plugin-tailwindcss-theme/src/styles/shadow.css create mode 100644 webapp/packages/plugin-tailwindcss-theme/src/styles/typography-utilities.css create mode 100644 webapp/packages/plugin-tailwindcss-theme/src/styles/typography.css create mode 100644 webapp/packages/plugin-tailwindcss-theme/tsconfig.json diff --git a/webapp/packages/core-blocks/src/Button.css b/webapp/packages/core-blocks/src/Button.css index 803c66f177..013e968c72 100644 --- a/webapp/packages/core-blocks/src/Button.css +++ b/webapp/packages/core-blocks/src/Button.css @@ -42,10 +42,6 @@ min-width: 64px; - font-family: Roboto, sans-serif; - -moz-osx-font-smoothing: grayscale; - -webkit-font-smoothing: antialiased; - font-weight: 500; letter-spacing: 0.0892857143em; text-decoration: none; diff --git a/webapp/packages/core-blocks/src/Button.tsx b/webapp/packages/core-blocks/src/Button.tsx index 546a889000..ebf17c2921 100644 --- a/webapp/packages/core-blocks/src/Button.tsx +++ b/webapp/packages/core-blocks/src/Button.tsx @@ -1,6 +1,6 @@ /* * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2025 DBeaver Corp and others + * Copyright (C) 2020-2026 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. @@ -8,7 +8,7 @@ import { createElement } from 'react'; import { observable } from 'mobx'; import { observer } from 'mobx-react-lite'; -import { Button as UIKitButton, ButtonIcon } from '@dbeaver/ui-kit'; +import { Button as UIKitButton, ButtonIcon, clsx } from '@dbeaver/ui-kit'; import { IconOrImage } from './IconOrImage.js'; import { useObjectRef } from './useObjectRef.js'; @@ -19,20 +19,20 @@ import './Button.css'; export type ButtonProps = (React.ButtonHTMLAttributes & React.LinkHTMLAttributes & React.HTMLAttributes) & { - loading?: boolean; - icon?: string; - viewBox?: string; - iconPlacement?: 'start' | 'end'; - iconSize?: number; - variant?: 'primary' | 'secondary' | 'danger' | 'ghost'; - size?: 'small' | 'medium' | 'large'; - tag?: 'button' | 'a' | 'div'; - href?: string; - target?: '_blank' | '_self' | '_parent' | '_top'; - loader?: boolean; - onClick?: React.MouseEventHandler | (() => Promise); - download?: boolean; - }; + loading?: boolean; + icon?: string; + viewBox?: string; + iconPlacement?: 'start' | 'end'; + iconSize?: number; + variant?: 'primary' | 'secondary' | 'danger' | 'ghost'; + size?: 'small' | 'medium' | 'large'; + tag?: 'button' | 'a' | 'div'; + href?: string; + target?: '_blank' | '_self' | '_parent' | '_top'; + loader?: boolean; + onClick?: React.MouseEventHandler | (() => Promise); + download?: boolean; +}; export const Button = observer(function Button({ children, @@ -81,7 +81,15 @@ export const Button = observer(function Button({ const Tag = createElement(tag); return ( - + {icon && ( diff --git a/webapp/packages/core-blocks/src/CommonDialog/CommonDialog/CommonDialogWrapper.module.css b/webapp/packages/core-blocks/src/CommonDialog/CommonDialog/CommonDialogWrapper.module.css index 71c7abd8f4..f7e1c8762c 100644 --- a/webapp/packages/core-blocks/src/CommonDialog/CommonDialog/CommonDialogWrapper.module.css +++ b/webapp/packages/core-blocks/src/CommonDialog/CommonDialog/CommonDialogWrapper.module.css @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. */ .dialog { - composes: theme-background-surface theme-text-on-surface theme-elevation-z10 from global; + composes: theme-background-surface theme-text-on-surface from global; &.fixedSize[data-size='small'] { width: 404px; diff --git a/webapp/packages/core-blocks/src/CommonDialog/CommonDialog/CommonDialogWrapper.tsx b/webapp/packages/core-blocks/src/CommonDialog/CommonDialog/CommonDialogWrapper.tsx index 5d94bdeb7f..6a0f6e2e02 100644 --- a/webapp/packages/core-blocks/src/CommonDialog/CommonDialog/CommonDialogWrapper.tsx +++ b/webapp/packages/core-blocks/src/CommonDialog/CommonDialog/CommonDialogWrapper.tsx @@ -1,6 +1,6 @@ /* * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2025 DBeaver Corp and others + * Copyright (C) 2020-2026 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. @@ -61,7 +61,7 @@ export const CommonDialogWrapper = observer | null | undefined} diff --git a/webapp/packages/core-blocks/src/CommonDialog/DialogsPortal.module.css b/webapp/packages/core-blocks/src/CommonDialog/DialogsPortal.module.css index 9f99726b35..65ed3c6269 100644 --- a/webapp/packages/core-blocks/src/CommonDialog/DialogsPortal.module.css +++ b/webapp/packages/core-blocks/src/CommonDialog/DialogsPortal.module.css @@ -10,7 +10,7 @@ } .error { - composes: theme-background-surface theme-text-on-surface theme-elevation-z10 from global; + composes: theme-background-surface theme-text-on-surface from global; border-radius: 0.25rem; } diff --git a/webapp/packages/core-blocks/src/CommonDialog/DialogsPortal.tsx b/webapp/packages/core-blocks/src/CommonDialog/DialogsPortal.tsx index 6b6c8aa1df..be30b18dbb 100644 --- a/webapp/packages/core-blocks/src/CommonDialog/DialogsPortal.tsx +++ b/webapp/packages/core-blocks/src/CommonDialog/DialogsPortal.tsx @@ -1,6 +1,6 @@ /* * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2025 DBeaver Corp and others + * Copyright (C) 2020-2026 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. @@ -87,7 +87,7 @@ const NestedDialog: React.FC = function NestedDialog({ dialog, return ( - + * { overflow: hidden; @@ -36,7 +36,7 @@ opacity: 0.5; width: var(--dbv-kit-disclosure-icon-size); height: var(--dbv-kit-disclosure-icon-size); - transition: transform 150ms ease-in-out; + transition: transform var(--duration-medium) var(--ease-smooth); transform-origin: center; transform: rotate(-90deg); } diff --git a/webapp/packages/core-blocks/src/FormControls/BaseDropdown.module.css b/webapp/packages/core-blocks/src/FormControls/BaseDropdown.module.css index b1d974bf89..600b6fa06a 100644 --- a/webapp/packages/core-blocks/src/FormControls/BaseDropdown.module.css +++ b/webapp/packages/core-blocks/src/FormControls/BaseDropdown.module.css @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. */ .menu { - composes: theme-text-on-surface theme-background-surface theme-typography--caption theme-elevation-z3 from global; + composes: theme-text-on-surface theme-background-surface theme-typography--caption from global; display: flex; flex-direction: column; max-height: 300px; diff --git a/webapp/packages/core-blocks/src/FormControls/Checkboxes/Switch.module.css b/webapp/packages/core-blocks/src/FormControls/Checkboxes/Switch.module.css index b5c58838b4..b782d4bdcd 100644 --- a/webapp/packages/core-blocks/src/FormControls/Checkboxes/Switch.module.css +++ b/webapp/packages/core-blocks/src/FormControls/Checkboxes/Switch.module.css @@ -5,6 +5,7 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ + @layer components { .field { --dbv-kit-control-outline-offset: -8px; @@ -41,34 +42,118 @@ border-width: var(--dbv-kit-control-outline-width); } } -} -.switchControl { - composes: theme-switch from global; -} + .switchControl { + position: relative; + display: inline-flex; + align-items: center; + width: 36px; + height: 20px; + vertical-align: middle; + outline: none; + flex-shrink: 0; -.disabled { - composes: theme-switch--disabled mdc-switch--disabled from global; -} + &:not(.disabled):hover .switchControlThumb { + box-shadow: + 0px 3px 1px -2px rgba(0, 0, 0, 0.2), + 0px 2px 2px 0px rgba(0, 0, 0, 0.14), + 0px 1px 5px 0px rgba(0, 0, 0, 0.12), + 0px 0px 0px 8px color-mix(in srgb, var(--theme-on-surface) 4%, transparent); + } -.checked { - composes: theme-switch--checked mdc-switch--checked from global; -} + &:not(.disabled):has(.switchInput:focus-visible) .switchControlThumb { + box-shadow: + 0px 3px 1px -2px rgba(0, 0, 0, 0.2), + 0px 2px 2px 0px rgba(0, 0, 0, 0.14), + 0px 1px 5px 0px rgba(0, 0, 0, 0.12), + 0px 0px 0px 12px color-mix(in srgb, var(--theme-on-surface) 8%, transparent); + } + } -.switchControlTrack { - composes: theme-switch__track from global; -} + .switchInput { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + cursor: pointer; + margin: 0; + padding: 0; + z-index: 2; -.switchInput { - composes: theme-switch_native-control from global; -} + &:disabled { + cursor: default; + pointer-events: none; + } + } -.switchControlUnderlay { - composes: theme-switch__thumb-underlay from global; -} + .switchControlTrack { + box-sizing: border-box; + position: absolute; + top: 50%; + left: 0; + transform: translateY(-50%); + width: 100%; + height: 14px; + border: 1px solid var(--theme-on-surface, #000); + border-radius: 7px; + background-color: var(--theme-on-surface, #000); + opacity: 0.38; + border: none; + transition: + background-color var(--duration-fast) var(--ease-smooth-start), + border-color var(--duration-fast) var(--ease-smooth-start), + opacity var(--duration-fast) var(--ease-smooth-start); + } -.switchControlThumb { - composes: theme-switch__thumb from global; + .switchControlUnderlay { + margin-left: -2px; + display: flex; + align-items: center; + justify-content: center; + transition: margin-left var(--duration-fast) var(--ease-smooth-start); + } + + .switchControlThumb { + box-sizing: border-box; + width: 20px; + height: 20px; + border: 10px solid var(--theme-switch-thumb, #fff); + border-radius: 50%; + background-color: var(--theme-surface, #fff); + box-shadow: + 0px 3px 1px -2px rgba(0, 0, 0, 0.2), + 0px 2px 2px 0px rgba(0, 0, 0, 0.14), + 0px 1px 5px 0px rgba(0, 0, 0, 0.12); + pointer-events: none; + z-index: 1; + transition: + background-color var(--duration-fast) var(--ease-smooth-start), + border-color var(--duration-fast) var(--ease-smooth-start); + } + + .checked { + & .switchControlTrack { + background-color: color-mix(in srgb, var(--theme-primary, #2a7cb4) 50%, transparent); + border-color: color-mix(in srgb, var(--theme-primary, #2a7cb4) 50%, transparent); + opacity: 1; + } + + & .switchControlUnderlay { + margin-left: 18px; + } + + & .switchControlThumb { + background-color: var(--theme-primary, #2a7cb4); + border-color: var(--theme-primary, #2a7cb4); + } + } + + .disabled { + opacity: 0.38; + pointer-events: none; + } } .switchBody { diff --git a/webapp/packages/core-blocks/src/FormControls/Checkboxes/SwitchDense.module.css b/webapp/packages/core-blocks/src/FormControls/Checkboxes/SwitchDense.module.css index b7ed125044..b8d5b539bc 100644 --- a/webapp/packages/core-blocks/src/FormControls/Checkboxes/SwitchDense.module.css +++ b/webapp/packages/core-blocks/src/FormControls/Checkboxes/SwitchDense.module.css @@ -5,14 +5,39 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ -.switchBody { - composes: theme-switch_dense from global; +@layer components { + .switchBody { + & .switchControl { + width: 24px; + height: 16px; + } + + & .switchControlTrack { + height: 10px; + border-radius: 5px; + } + + & .switchControlUnderlay { + margin-left: -3px; + } + + & .switchControlThumb { + width: 14px; + height: 14px; + border-width: 7px; + } + + & .checked .switchControlUnderlay { + margin-left: 13px; + } + } + + /* overrides bold label style from SwitchDense.module.css because of specificity */ + .switchBody .fieldLabel { + font-weight: initial; + } } + .fieldLabel { composes: theme-typography--body2 from global; } - -/* overrides bold label style from SwitchDense.module.css because of specificity */ -.switchBody .fieldLabel { - font-weight: initial; -} diff --git a/webapp/packages/core-blocks/src/FormControls/Checkboxes/SwitchPrimary.module.css b/webapp/packages/core-blocks/src/FormControls/Checkboxes/SwitchPrimary.module.css index 6b876c5931..538663e78f 100644 --- a/webapp/packages/core-blocks/src/FormControls/Checkboxes/SwitchPrimary.module.css +++ b/webapp/packages/core-blocks/src/FormControls/Checkboxes/SwitchPrimary.module.css @@ -5,10 +5,15 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ -.switchControl { - composes: theme-switch_primary from global; -} +@layer components { + .switchBody { + .switchControl { + width: 36px; + height: 20px; + } -.fieldLabel { - font-weight: 500; + .fieldLabel { + font-weight: 500; + } + } } diff --git a/webapp/packages/core-blocks/src/FormControls/InputAutocompletionMenu.tsx b/webapp/packages/core-blocks/src/FormControls/InputAutocompletionMenu.tsx index 4352e46c65..650804cd11 100644 --- a/webapp/packages/core-blocks/src/FormControls/InputAutocompletionMenu.tsx +++ b/webapp/packages/core-blocks/src/FormControls/InputAutocompletionMenu.tsx @@ -20,26 +20,25 @@ interface AutocompletionProps { onSelect?: (proposal: InputAutocompleteProposal) => void; } -export const InputAutocompletionMenu = observer(forwardRef(function InputAutocompletionMenu({ - proposals, - onSelect, -}, ref) { - const styles = useS(BaseDropdownStyles); +export const InputAutocompletionMenu = observer( + forwardRef(function InputAutocompletionMenu({ proposals, onSelect }, ref) { + const styles = useS(BaseDropdownStyles); - return ( - - - {proposals.map(proposal => ( - onSelect?.(proposal)}> - {proposal.icon && ( -
- -
- )} - {proposal.displayString} -
- ))} -
-
- ); -})); + return ( + + + {proposals.map(proposal => ( + onSelect?.(proposal)}> + {proposal.icon && ( +
+ +
+ )} + {proposal.displayString} +
+ ))} +
+
+ ); + }), +); diff --git a/webapp/packages/core-blocks/src/Loader/Loader.module.css b/webapp/packages/core-blocks/src/Loader/Loader.module.css index f27219b826..687f9e3c75 100644 --- a/webapp/packages/core-blocks/src/Loader/Loader.module.css +++ b/webapp/packages/core-blocks/src/Loader/Loader.module.css @@ -28,7 +28,7 @@ justify-content: center; align-items: center; opacity: 0; - transition: opacity cubic-bezier(0.4, 0, 0.2, 1) 0.3s; + transition: opacity var(--duration-slow) var(--ease-smooth-start); &:global(.animate) { opacity: 1; } diff --git a/webapp/packages/core-blocks/src/Overlay/Overlay.module.css b/webapp/packages/core-blocks/src/Overlay/Overlay.module.css index 6fdc5ee573..51e868d000 100644 --- a/webapp/packages/core-blocks/src/Overlay/Overlay.module.css +++ b/webapp/packages/core-blocks/src/Overlay/Overlay.module.css @@ -6,41 +6,41 @@ * you may not use this file except in compliance with the License. */ .overlay { - composes: theme-text-on-primary from global; - display: none; - flex-direction: column; - justify-content: center; - align-items: center; - overflow: auto; - position: absolute; - margin: auto; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.4); - box-shadow: none; + composes: theme-text-on-primary from global; + display: none; + flex-direction: column; + justify-content: center; + align-items: center; + overflow: auto; + position: absolute; + margin: auto; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.4); + box-shadow: none; - &.active { - display: flex; - } + &.active { + display: flex; + } - &.fill { - background-color: var(--theme-background-surface); - & .box { - box-shadow: none; - } + &.fill { + background-color: var(--theme-background-surface); + & .box { + box-shadow: none; } + } } .box { - composes: theme-background-surface theme-text-on-surface theme-elevation-z6 from global; - display: flex; - flex-direction: column; - justify-content: center; - overflow: auto; - border-radius: 0.25rem; - align-items: normal; - max-width: calc(100% - 48px); - max-height: calc(100% - 48px); + composes: theme-background-surface theme-text-on-surface from global; + display: flex; + flex-direction: column; + justify-content: center; + overflow: auto; + border-radius: 0.25rem; + align-items: normal; + max-width: calc(100% - 48px); + max-height: calc(100% - 48px); } diff --git a/webapp/packages/core-blocks/src/Overlay/Overlay.tsx b/webapp/packages/core-blocks/src/Overlay/Overlay.tsx index 1eb8841c61..c65e6fdb95 100644 --- a/webapp/packages/core-blocks/src/Overlay/Overlay.tsx +++ b/webapp/packages/core-blocks/src/Overlay/Overlay.tsx @@ -1,6 +1,6 @@ /* * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others + * Copyright (C) 2020-2026 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ export const Overlay = observer>(function Overlay return (
-
{children}
+
{children}
); }); diff --git a/webapp/packages/core-blocks/src/SlideDialog/SlideDialog.css b/webapp/packages/core-blocks/src/SlideDialog/SlideDialog.css index fff12d61ed..10bf4e4130 100644 --- a/webapp/packages/core-blocks/src/SlideDialog/SlideDialog.css +++ b/webapp/packages/core-blocks/src/SlideDialog/SlideDialog.css @@ -4,7 +4,7 @@ inset: 0; z-index: 999; background: rgb(0 0 0 / 0%); - transition: background ease-in-out 0.3s; + transition: background var(--duration-slow) var(--ease-smooth); pointer-events: none; &[data-active] { diff --git a/webapp/packages/core-blocks/src/Snackbars/SnackbarMarkups/SnackbarWrapper.module.css b/webapp/packages/core-blocks/src/Snackbars/SnackbarMarkups/SnackbarWrapper.module.css index 1a3ee1d3eb..aa6704dc62 100644 --- a/webapp/packages/core-blocks/src/Snackbars/SnackbarMarkups/SnackbarWrapper.module.css +++ b/webapp/packages/core-blocks/src/Snackbars/SnackbarMarkups/SnackbarWrapper.module.css @@ -5,8 +5,9 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ + .notification { - composes: theme-background-surface theme-text-on-surface theme-elevation-z5 from global; + composes: theme-background-surface theme-text-on-surface from global; position: relative; display: flex; box-sizing: border-box; @@ -18,8 +19,8 @@ opacity: 0; border-radius: var(--theme-group-element-radius); transition: - opacity 0.3s ease-in-out, - transform 0.5s ease-in-out; + opacity var(--duration-slow) var(--ease-smooth), + transform var(--duration-slowest) var(--ease-smooth); transform: translateX(-100%); &.mounted { @@ -31,8 +32,8 @@ opacity: 0; transform: translateX(-100%); transition: - opacity 0.5s ease-in-out, - transform 0.5s ease-in-out; + opacity var(--duration-slowest) var(--ease-smooth), + transform var(--duration-slowest) var(--ease-smooth); } } diff --git a/webapp/packages/core-blocks/src/Snackbars/SnackbarMarkups/SnackbarWrapper.tsx b/webapp/packages/core-blocks/src/Snackbars/SnackbarMarkups/SnackbarWrapper.tsx index 401889bff8..167c86883e 100644 --- a/webapp/packages/core-blocks/src/Snackbars/SnackbarMarkups/SnackbarWrapper.tsx +++ b/webapp/packages/core-blocks/src/Snackbars/SnackbarMarkups/SnackbarWrapper.tsx @@ -1,6 +1,6 @@ /* * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2025 DBeaver Corp and others + * Copyright (C) 2020-2026 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. @@ -41,7 +41,7 @@ export const SnackbarWrapper: React.FC> = functio role="alert" aria-live="assertive" aria-atomic="true" - className={s(styles, { notification: true, mounted, closing }, className)} + className={s(styles, { notification: true, mounted, closing }, 'tw:shadow-medium', className)} > {children} {!persistent && onClose && ( diff --git a/webapp/packages/core-blocks/src/Split/ResizerControls.module.css b/webapp/packages/core-blocks/src/Split/ResizerControls.module.css index 07cfdb2a69..42ca9b7384 100644 --- a/webapp/packages/core-blocks/src/Split/ResizerControls.module.css +++ b/webapp/packages/core-blocks/src/Split/ResizerControls.module.css @@ -5,6 +5,7 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ + .resizerControls { composes: theme-background-background theme-text-on-secondary from global; position: relative; @@ -12,7 +13,7 @@ cursor: ew-resize; user-select: none; z-index: 1; - transition: background-color 0.3s ease-in-out; + transition: background-color var(--duration-slow) var(--ease-smooth); &:before { content: ' '; diff --git a/webapp/packages/core-blocks/src/Table/TableColumnValue.module.css b/webapp/packages/core-blocks/src/Table/TableColumnValue.module.css index 3918a9c03f..ffa0276bdc 100644 --- a/webapp/packages/core-blocks/src/Table/TableColumnValue.module.css +++ b/webapp/packages/core-blocks/src/Table/TableColumnValue.module.css @@ -5,12 +5,13 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ + .cell { position: relative; box-sizing: border-box; height: 28px; padding: 0 16px; - transition: padding ease-in-out 0.24s; + transition: padding var(--duration-medium) var(--ease-smooth); &.nowrap, &.ellipsis { diff --git a/webapp/packages/core-blocks/src/Table/TableItemExpand.module.css b/webapp/packages/core-blocks/src/Table/TableItemExpand.module.css index eddaedb28e..f643dc9781 100644 --- a/webapp/packages/core-blocks/src/Table/TableItemExpand.module.css +++ b/webapp/packages/core-blocks/src/Table/TableItemExpand.module.css @@ -10,7 +10,7 @@ width: 16px; height: 16px; padding: 0; - transition: transform ease-in-out 0.2s; + transition: transform var(--duration-medium) var(--ease-smooth); &.expanded { transform: rotate(180deg); diff --git a/webapp/packages/core-blocks/src/Table/TableItemGroupExpand.module.css b/webapp/packages/core-blocks/src/Table/TableItemGroupExpand.module.css index e9e9a4b0bc..f6ef3d5b01 100644 --- a/webapp/packages/core-blocks/src/Table/TableItemGroupExpand.module.css +++ b/webapp/packages/core-blocks/src/Table/TableItemGroupExpand.module.css @@ -20,7 +20,7 @@ cursor: pointer; opacity: 0.5; transform: rotate(-90deg); - transition: transform 0.15s ease-in-out; + transition: transform var(--duration-medium) var(--ease-smooth); &.expanded { transform: rotate(0deg); diff --git a/webapp/packages/core-theming/package.json b/webapp/packages/core-theming/package.json index 7e37172ebb..67536515d3 100644 --- a/webapp/packages/core-theming/package.json +++ b/webapp/packages/core-theming/package.json @@ -40,15 +40,6 @@ "@dbeaver/cli": "workspace:*", "@dbeaver/react-tests": "workspace:*", "@fontsource/roboto": "^5", - "@material/button": "^4", - "@material/checkbox": "^4", - "@material/elevation": "^4", - "@material/layout-grid": "^4", - "@material/radio": "^4", - "@material/ripple": "^4", - "@material/switch": "^4", - "@material/theme": "^4", - "@material/typography": "^4", "rimraf": "^6", "typescript": "^5", "typescript-plugin-css-modules": "^5", diff --git a/webapp/packages/core-theming/src/ThemeService.ts b/webapp/packages/core-theming/src/ThemeService.ts index d611359b56..1d09c76286 100644 --- a/webapp/packages/core-theming/src/ThemeService.ts +++ b/webapp/packages/core-theming/src/ThemeService.ts @@ -14,11 +14,9 @@ import { type ISyncExecutor, SyncExecutor } from '@cloudbeaver/core-executor'; import type { Style } from './ComponentStyle.js'; import './styles/main/base.pure.css'; import './styles/main/color.pure.scss'; -import './styles/main/elevation.pure.scss'; import './styles/main/fonts.pure.css'; // TODO: important to keep normalize first import './styles/main/normalize.pure.css'; -import './styles/main/typography.pure.scss'; import './styles/UiIconButton.css'; import './styles/UiSpinner.css'; import './styles/UiInput.css'; diff --git a/webapp/packages/core-theming/src/styles/_branding.scss b/webapp/packages/core-theming/src/styles/_branding.scss index 51c503f89a..9673c7ba11 100644 --- a/webapp/packages/core-theming/src/styles/_branding.scss +++ b/webapp/packages/core-theming/src/styles/_branding.scss @@ -6,21 +6,6 @@ * you may not use this file except in compliance with the License. */ -@mixin stripes-background($color, $important: false) { - // background-image: linear-gradient( - // 45deg, - // transparent 37.5%, - // $color 37.5%, - // $color 50%, - // transparent 50%, - // transparent 87.5%, - // $color 87.5%, - // $color 100% - // ); - // background-size: 8px 8px; - background-color: $color #{if($important, '!important', '')}; -} - @mixin delimiter($color) { hr { border-color: $color; diff --git a/webapp/packages/core-theming/src/styles/_color.scss b/webapp/packages/core-theming/src/styles/_color.scss index 27c5326897..95a87c4b84 100644 --- a/webapp/packages/core-theming/src/styles/_color.scss +++ b/webapp/packages/core-theming/src/styles/_color.scss @@ -6,90 +6,89 @@ * you may not use this file except in compliance with the License. */ -@mixin colors($query: mdc-feature-all()) { - $feat-color: mdc-feature-create-target($query, color); +@mixin colors() { + // Export all theme colors as CSS variables + --theme-primary: #{$mdc-theme-primary}; + --theme-on-primary: #{$mdc-theme-on-primary}; + --theme-secondary: #{$mdc-theme-secondary}; + --theme-on-secondary: #{$mdc-theme-on-secondary}; + --theme-error: #{$mdc-theme-error}; + --theme-surface: #{$mdc-theme-surface}; + --theme-on-surface: #{$mdc-theme-on-surface}; + --theme-background: #{$mdc-theme-background}; + --theme-sub-secondary: #{$mdc-theme-sub-secondary}; + --theme-on-sub-secondary: #{$mdc-theme-on-sub-secondary}; + --theme-positive: #{$color-positive}; + --theme-on-positive: #{$color-on-positive}; + --theme-negative: #{$color-negative}; + --theme-status: #{$color-status}; + --theme-link-color: #{$link-color}; + --theme-input-color: #{$input-color}; + --theme-input-color-disabled: #{$input-color-disabled}; + --theme-input-color-readonly: #{$input-color-readonly}; + --theme-input-color-placeholder: #{$input-color-placeholder}; + --theme-input-border: #{$input-border}; + --theme-input-border-readonly: #{$input-border-readonly}; + --theme-input-border-disabled: #{$input-border-disabled}; + --theme-input-background: #{$input-background}; + --theme-input-background-disabled: #{$input-background-disabled}; + --theme-input-background-readonly: #{$input-background-readonly}; + --theme-switch-thumb: #{lighten($mdc-theme-surface, 5%)}; - /*:root {*/ - @include mdc-feature-targets($feat-color) { - @each $style in map-keys($mdc-theme-property-values) { - --theme-#{$style}: #{map-get($mdc-theme-property-values, $style)}; + // Text color variants derived from $mdc-theme-text-colors + // Map keys "light"/"dark" describe the ink color, not the background. + // "on-light" (on light background) needs dark ink, "on-dark" needs light ink. + $light-ink-colors: map-get($mdc-theme-text-colors, light); + $dark-ink-colors: map-get($mdc-theme-text-colors, dark); + + @each $variant in (primary, secondary, sub-secondary, hint, disabled, icon, negative) { + --theme-text-#{$variant}-on-light: #{map-get($dark-ink-colors, $variant)}; + --theme-text-#{$variant}-on-dark: #{map-get($light-ink-colors, $variant)}; + } + + // Theme color utility classes + @each $color-name in (primary, on-primary, secondary, on-secondary, error, on-error, surface, on-surface, background, positive, negative, status) { + &.theme-text-#{$color-name}, + .theme-text-#{$color-name} { + color: var(--theme-#{$color-name}); + + svg, + & > svg { + fill: var(--theme-#{$color-name}); + } + } + + &.theme-border-color-#{$color-name}, + .theme-border-color-#{$color-name} { + border-color: var(--theme-#{$color-name}) !important; + } + + &.theme-fill-#{$color-name}, + .theme-fill-#{$color-name} { + fill: var(--theme-#{$color-name}); } } - /*}*/ - @each $style in map-keys($mdc-theme-property-values) { - @if $style != 'background' and $style != 'surface' and $style != 'on-surface' { - &.theme-text-#{$style}, - .theme-text-#{$style} { - @include theme-ripple-color($query, $style); - - @include mdc-feature-targets($feat-color) { - @include mdc-theme-prop(color, $style, true); - } + // Text variant utility classes (text-primary-on-light, text-hint-on-light, etc.) + @each $variant in (primary, secondary, sub-secondary, hint, disabled, icon, negative) { + @each $tone in (light, dark) { + &.theme-text-text-#{$variant}-on-#{$tone}, + .theme-text-text-#{$variant}-on-#{$tone} { + color: var(--theme-text-#{$variant}-on-#{$tone}); svg, & > svg { - @include mdc-feature-targets($feat-color) { - @include mdc-theme-prop(fill, $style, true); - } - } - } - &.theme-border-color-#{$style}, - .theme-border-color-#{$style} { - @include mdc-feature-targets($feat-color) { - @include mdc-theme-prop(border-color, $style, true); - } - } - &.theme-fill-#{$style}, - .theme-fill-#{$style} { - @include mdc-feature-targets($feat-color) { - @include mdc-theme-prop(fill, $style, true); - } - } - } @else { - &.theme-text-#{$style}, - .theme-text-#{$style} { - @include theme-ripple-color($query, $style); - - @include mdc-feature-targets($feat-color) { - @include mdc-theme-prop(color, $style); - } - - svg, - & > svg { - @include mdc-feature-targets($feat-color) { - @include mdc-theme-prop(fill, $style); - } - } - } - &.theme-background-#{$style}, - .theme-background-#{$style} { - @include mdc-feature-targets($feat-color) { - @include mdc-theme-prop(background-color, $style); - } - } - &.theme-border-color-#{$style}, - .theme-border-color-#{$style} { - @include mdc-feature-targets($feat-color) { - @include mdc-theme-prop(border-color, $style, true); - } - } - &.theme-fill-#{$style}, - .theme-fill-#{$style} { - @include mdc-feature-targets($feat-color) { - @include mdc-theme-prop(fill, $style); + fill: var(--theme-text-#{$variant}-on-#{$tone}); } } } } - // CSS rules for using primary and secondary (plus light/dark variants) as background colors. - @each $style in ('primary', 'secondary', 'positive') { - &.theme-background-#{$style}, - .theme-background-#{$style} { - @include mdc-feature-targets($feat-color) { - @include mdc-theme-prop(background-color, $style, true); - } + // Background color classes + @each $color-name in (primary, secondary, surface, background, positive) { + &.theme-background-#{$color-name}, + .theme-background-#{$color-name} { + background-color: var(--theme-#{$color-name}); } } } diff --git a/webapp/packages/core-theming/src/styles/_form-controls.scss b/webapp/packages/core-theming/src/styles/_form-controls.scss index d3ce1285b0..9bdb2f1ac4 100644 --- a/webapp/packages/core-theming/src/styles/_form-controls.scss +++ b/webapp/packages/core-theming/src/styles/_form-controls.scss @@ -36,7 +36,7 @@ width: 0; height: 0; } - /* clears the ‘X’ from Chrome */ + /* clears the 'X' from Chrome */ &[type='search']::-webkit-search-decoration, &[type='search']::-webkit-search-cancel-button, &[type='search']::-webkit-search-results-button, @@ -53,20 +53,21 @@ width: 100%; border: 1px solid; outline: none !important; - border-radius: $theme-form-element-radius; + border-radius: var(--theme-form-element-radius); + + color: var(--theme-input-color); + border-color: var(--theme-input-border); + background-color: var(--theme-input-background); - @include mdc-theme-prop(color, input-color, false); - @include mdc-theme-prop(border-color, input-border, false); - @include mdc-theme-prop(background-color, input-background, false); // we use box-shadow to overlap internal background-color style, we can't override it due to chrome bug &:-internal-autofill-selected, &:-internal-autofill-previewed { - -webkit-text-fill-color: $mdc-theme-on-secondary; - box-shadow: 0 0 0 50px $input-background inset; + -webkit-text-fill-color: var(--theme-on-secondary); + box-shadow: 0 0 0 50px var(--theme-input-background) inset; } &:user-invalid { - @include mdc-theme-prop(border-color, negative, false); + border-color: var(--theme-negative); } &[type='color'] { @@ -81,36 +82,36 @@ &:focus, &[data-focus='true'] { - @include mdc-theme-prop(border-color, primary, false); + border-color: var(--theme-primary); } &:not([data-select='true'])[readonly] { - @include mdc-theme-prop(color, input-color-readonly, false); - @include mdc-theme-prop(border-color, input-border-readonly, false); - @include mdc-theme-prop(background-color, input-background-readonly, false); + color: var(--theme-input-color-readonly); + border-color: var(--theme-input-border-readonly); + background-color: var(--theme-input-background-readonly); opacity: 1; &:-internal-autofill-selected, &:-internal-autofill-previewed { - box-shadow: 0 0 0 50px $input-background-readonly inset; + box-shadow: 0 0 0 50px var(--theme-input-background-readonly) inset; } } &[disabled] { - @include mdc-theme-prop(color, input-color-readonly, false); - @include mdc-theme-prop(border-color, input-border-readonly, false); - @include mdc-theme-prop(background-color, input-background-readonly, false); + color: var(--theme-input-color-readonly); + border-color: var(--theme-input-border-readonly); + background-color: var(--theme-input-background-readonly); pointer-events: all; opacity: 1; &:-internal-autofill-selected, &:-internal-autofill-previewed { - box-shadow: 0 0 0 50px $input-background-readonly inset; + box-shadow: 0 0 0 50px var(--theme-input-background-readonly) inset; } } &[data-embedded='true'] { &[disabled], &:not([data-select='true'])[readonly] { - @include mdc-theme-prop(border-color, background, false); - @include mdc-theme-prop(background-color, input-background, false); + border-color: var(--theme-background); + background-color: var(--theme-input-background); } } } diff --git a/webapp/packages/core-theming/src/styles/_mixins.scss b/webapp/packages/core-theming/src/styles/_mixins.scss index a4fde18382..414654ad3b 100644 --- a/webapp/packages/core-theming/src/styles/_mixins.scss +++ b/webapp/packages/core-theming/src/styles/_mixins.scss @@ -6,20 +6,10 @@ * you may not use this file except in compliance with the License. */ -@import '@material/theme/mixins'; -@import '@material/ripple/mixins'; -@import '@material/button/mixins'; -@import '@material/elevation/mixins'; -@import '@material/typography/mixins'; @import './variables'; @import './theme'; @import './color-scheme'; -@import './layout-grid'; @import './branding'; -@import './theme-ripple'; -@import './ripple'; @import './color'; -@import './switch'; -@import './placeholder'; @import './form-controls'; @import './link'; diff --git a/webapp/packages/core-theming/src/styles/_placeholder.scss b/webapp/packages/core-theming/src/styles/_placeholder.scss deleted file mode 100644 index e80dbe9090..0000000000 --- a/webapp/packages/core-theming/src/styles/_placeholder.scss +++ /dev/null @@ -1,33 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others - * - * Licensed under the Apache License, Version 2.0. - * you may not use this file except in compliance with the License. - */ - -@mixin placeholder { - .placeholder { - box-sizing: border-box; - overflow: hidden; - position: relative; - background: #f0f0f0; - border-radius: $theme-form-element-radius; - margin: 2px; - animation: wave 1.5s linear infinite; - } - - @keyframes wave { - 0% { - opacity: 0; - } - - 50% { - opacity: 1; - } - - 100% { - opacity: 0; - } - } -} diff --git a/webapp/packages/core-theming/src/styles/_ripple.scss b/webapp/packages/core-theming/src/styles/_ripple.scss deleted file mode 100644 index 97c20dc522..0000000000 --- a/webapp/packages/core-theming/src/styles/_ripple.scss +++ /dev/null @@ -1,31 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others - * - * Licensed under the Apache License, Version 2.0. - * you may not use this file except in compliance with the License. - */ - -@mixin ripple-core-styles($query: mdc-feature-all()) { - $feat-structure: mdc-feature-create-target($query, structure); - - .theme-ripple-surface { - @include mdc-ripple-surface($query: $query); - @include mdc-states($query: $query); - @include mdc-ripple-radius-bounded($query: $query); - - @include mdc-feature-targets($feat-structure) { - position: relative; - outline: none; - overflow: hidden; - } - - &--primary { - @include mdc-states(primary, $query: $query); - } - - &--accent { - @include mdc-states(secondary, $query: $query); - } - } -} \ No newline at end of file diff --git a/webapp/packages/core-theming/src/styles/_switch.scss b/webapp/packages/core-theming/src/styles/_switch.scss deleted file mode 100644 index c0b5d518d4..0000000000 --- a/webapp/packages/core-theming/src/styles/_switch.scss +++ /dev/null @@ -1,79 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 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 '@material/switch/mixins'; - -@mixin switch-core-styles($query: mdc-feature-all()) { - @include mdc-switch-core-styles($query); - - .theme-switch { - @extend .mdc-switch; - } - .theme-switch_native-control { - @extend .mdc-switch__native-control; - - &:disabled { - opacity: 0; - } - } - .theme-switch__track { - @extend .mdc-switch__track; - } - .theme-switch__thumb-underlay { - @extend .mdc-switch__thumb-underlay; - } - .theme-switch__thumb { - @extend .mdc-switch__thumb; - } - .theme-switch--checked { - @extend .mdc-switch--checked; - } - .theme-switch--disabled { - @extend .mdc-switch--disabled; - } - - .theme-switch_dense { - @include switch-core-styles-dense($query); - } - - .theme-switch_dense .theme-switch_primary, - .theme-switch_primary { - $mdc-switch-baseline-theme-color: primary; - - @include mdc-switch-toggled-on-track-color($mdc-switch-baseline-theme-color, $query); - @include mdc-switch-toggled-on-thumb-color($mdc-switch-baseline-theme-color, $query); - @include mdc-switch-toggled-off-track-color($mdc-switch-toggled-off-track-color, $query); - @include mdc-switch-toggled-off-thumb-color($mdc-switch-toggled-off-thumb-color, $query); - } -} - -@mixin switch-core-styles-dense($query: mdc-feature-all()) { - $mdc-switch-baseline-theme-color: primary !global; - $mdc-switch-track-width: 24px !global; - $mdc-switch-track-height: 10px !global; - $mdc-switch-thumb-diameter: 14px !global; - $mdc-switch-ripple-size: 36px !global; - $mdc-switch-toggled-off-thumb-color: lighten($mdc-switch-toggled-off-thumb-color, 5%) !global; - - $mdc-switch-minimum-size: 24px !global; - $mdc-switch-maximum-size: $mdc-switch-ripple-size !global; - $mdc-switch-density-scale: $mdc-density-default-scale !global; - $mdc-switch-density-config: ( - size: ( - minimum: $mdc-switch-minimum-size, - default: $mdc-switch-maximum-size, - maximum: $mdc-switch-maximum-size, - ), - ) !global; - - $mdc-switch-thumb-offset: 2px !global; - - $mdc-switch-thumb-active-margin: $mdc-switch-track-width - $mdc-switch-thumb-diameter + $mdc-switch-thumb-offset * 2 !global; - - @include mdc-switch-core-styles($query); -} diff --git a/webapp/packages/core-theming/src/styles/_theme-dark.scss b/webapp/packages/core-theming/src/styles/_theme-dark.scss index b6cc437dcc..898397d281 100644 --- a/webapp/packages/core-theming/src/styles/_theme-dark.scss +++ b/webapp/packages/core-theming/src/styles/_theme-dark.scss @@ -60,22 +60,6 @@ $mdc-theme-text-colors: ( ), ); -$mdc-ripple-dark-ink-opacities: ( - hover: 0.04, - focus: 0.1, - press: 0.1, - selected: 0.06, - activated: 0.1, -) !default; - -$mdc-ripple-light-ink-opacities: ( - hover: 0.04, - focus: 0.1, - press: 0.1, - selected: 0.06, - activated: 0.1, -) !default; - $theme-name: 'dark'; @import './mixins'; diff --git a/webapp/packages/core-theming/src/styles/_theme-light.scss b/webapp/packages/core-theming/src/styles/_theme-light.scss index f804ce6c94..634a81a697 100644 --- a/webapp/packages/core-theming/src/styles/_theme-light.scss +++ b/webapp/packages/core-theming/src/styles/_theme-light.scss @@ -17,6 +17,7 @@ $mdc-theme-on-sub-secondary: #6d6d6d; $mdc-theme-surface: #ffffff; $mdc-theme-on-surface: #353535; $mdc-theme-background: #dedede; +$mdc-theme-error: #e94948; $color-scheme: light; $color-positive: #52c41a; diff --git a/webapp/packages/core-theming/src/styles/_theme-ripple.scss b/webapp/packages/core-theming/src/styles/_theme-ripple.scss deleted file mode 100644 index 667a77e3b3..0000000000 --- a/webapp/packages/core-theming/src/styles/_theme-ripple.scss +++ /dev/null @@ -1,114 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others - * - * Licensed under the Apache License, Version 2.0. - * you may not use this file except in compliance with the License. - */ - -@mixin theme-ripple-color($query, $color) { - &.theme-ripple, - .theme-ripple { - @include mdc-states($color, $query: $query); - - &[aria-expanded='true'] { - &::before { - opacity: mdc-states-opacity($color, focus) + mdc-states-opacity($color, hover); - } - } - - &.theme-ripple-selectable { - &[aria-selected='true'] { - &::before { - opacity: mdc-states-opacity($color, focus) + mdc-states-opacity($color, hover); - } - } - } - } -} - -@mixin theme-ripple($query: mdc-feature-all()) { - $feat-structure: mdc-feature-create-target($query, structure); - @include mdc-ripple-common($query); - - &.theme-ripple, - .theme-ripple { - position: relative; - - &::before { - @include mdc-ripple-surface($query); - @include mdc-ripple-radius-bounded($query: $query); - - @include mdc-feature-targets($feat-structure) { - position: absolute; - content: ''; - opacity: 0; - top: 0; - left: 0; - width: 100%; - height: 100%; - overflow: hidden; - } - } - - &.theme-ripple-background { - @include mdc-theme-prop(background-color, background, false); - @include mdc-theme-prop(color, text-hint-on-light, false); - - &.theme-ripple-selectable { - &:hover { - @include mdc-theme-prop(color, text-primary-on-light, false); - } - - &[aria-selected='true'] { - @include mdc-theme-prop(background-color, surface, false); - @include mdc-theme-prop(color, text-primary-on-light, false); - - &::before { - opacity: 0 !important; - } - } - } - } - - &.theme-ripple-secondary { - @include mdc-theme-prop(background-color, secondary, false); - @include mdc-theme-prop(color, text-hint-on-light, false); - - &.theme-ripple-selectable { - &:hover { - @include mdc-theme-prop(color, text-primary-on-light, false); - } - - &[aria-selected='true'] { - @include mdc-theme-prop(background-color, surface, false); - @include mdc-theme-prop(color, text-primary-on-light, false); - - &::before { - opacity: 0 !important; - } - } - } - } - - &.theme-ripple-surface { - @include mdc-theme-prop(background-color, surface, false); - @include mdc-theme-prop(color, text-hint-on-light, false); - - &.theme-ripple-selectable { - &:hover { - @include mdc-theme-prop(color, text-primary-on-light, false); - } - - &[aria-selected='true'] { - @include mdc-theme-prop(background-color, surface, false); - @include mdc-theme-prop(color, text-primary-on-light, false); - - &::before { - opacity: 0 !important; - } - } - } - } - } -} diff --git a/webapp/packages/core-theming/src/styles/_variables.scss b/webapp/packages/core-theming/src/styles/_variables.scss index 2abaebd2bb..4b9caec8a3 100644 --- a/webapp/packages/core-theming/src/styles/_variables.scss +++ b/webapp/packages/core-theming/src/styles/_variables.scss @@ -6,28 +6,6 @@ * you may not use this file except in compliance with the License. */ -$mdc-theme-extra-property-values: ( - sub-secondary: $mdc-theme-sub-secondary, - on-sub-secondary: $mdc-theme-on-sub-secondary, - positive: $color-positive, - on-positive: $color-on-positive, - negative: $color-negative, - status: $color-status, - link-color: $link-color, - input-color: $input-color, - input-color-disabled: $input-color-disabled, - input-color-readonly: $input-color-readonly, - input-color-placeholder: $input-color-placeholder, - input-border: $input-border, - input-border-readonly: $input-border-readonly, - input-border-disabled: $input-border-disabled, - input-background: $input-background, - input-background-disabled: $input-background-disabled, - input-background-readonly: $input-background-readonly, -); - -$mdc-theme-property-values: map-merge($mdc-theme-property-values, $mdc-theme-extra-property-values); - $theme-class: 'theme-#{$theme-name}'; $theme-form-element-radius: 3px !default; $theme-group-element-radius: 4px !default; @@ -51,6 +29,8 @@ $app-height: 100vh !default; --theme-form-element-radius: #{$theme-form-element-radius}; --theme-group-element-radius: #{$theme-group-element-radius}; --theme-menu-bar-small-action-radius: #{$theme-menu-bar-small-action-radius}; + --theme-font-family: Roboto, sans-serif; + --theme-font-family-mono: RobotoMono, sans-serif; } @layer components { diff --git a/webapp/packages/core-theming/src/styles/layout-grid.scss b/webapp/packages/core-theming/src/styles/layout-grid.scss deleted file mode 100644 index 767f4b15a8..0000000000 --- a/webapp/packages/core-theming/src/styles/layout-grid.scss +++ /dev/null @@ -1,109 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 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 "@material/layout-grid/variables"; -@import "@material/layout-grid/mixins"; - -@mixin layout-grid($query: mdc-feature-all()) { - :root { - @each $size in map-keys($mdc-layout-grid-columns) { - --mdc-layout-grid-margin-#{$size}: #{map-get($mdc-layout-grid-default-margin, $size)}; - --mdc-layout-grid-gutter-#{$size}: #{map-get($mdc-layout-grid-default-gutter, $size)}; - --mdc-layout-grid-column-width-#{$size}: #{map-get($mdc-layout-grid-column-width, $size)}; - } - } - - .layout-grid { - @each $size in map-keys($mdc-layout-grid-columns) { - @include mdc-layout-grid-media-query_($size) { - $margin: map-get($mdc-layout-grid-default-margin, $size); - - @include mdc-layout-grid($size, $margin, $mdc-layout-grid-max-width); - } - } - } - - .layout-grid__inner { - @each $size in map-keys($mdc-layout-grid-columns) { - @include mdc-layout-grid-media-query_($size) { - $margin: map-get($mdc-layout-grid-default-margin, $size); - $gutter: map-get($mdc-layout-grid-default-gutter, $size); - - @include mdc-layout-grid-inner($size, $margin, $gutter); - } - } - } - - .layout-grid__cell { - // select the upper breakpoint - $upper-breakpoint: nth(map-keys($mdc-layout-grid-columns), 1); - - @each $size in map-keys($mdc-layout-grid-columns) { - @include mdc-layout-grid-media-query_($size) { - $gutter: map-get($mdc-layout-grid-default-gutter, $size); - - @include mdc-layout-grid-cell($size, $mdc-layout-grid-default-column-span, $gutter); - - @for $span from 1 through map-get($mdc-layout-grid-columns, $upper-breakpoint) { - // Span classes. - @at-root .layout-grid__cell--span-#{$span}, - .layout-grid__cell--span-#{$span}-#{$size}, - .layout-grid__cell[data-span="#{$span}"], - .layout-grid__cell[data-span-#{$size}="#{$span}"] { - @include mdc-layout-grid-cell-span_($size, $span, $gutter); - } - } - } - } - - // Order override classes. - @for $i from 1 through map-get($mdc-layout-grid-columns, $upper-breakpoint) { - &--order-#{$i} { - @include mdc-layout-grid-cell-order($i); - } - } - - // Alignment classes. - &--align-top { - @include mdc-layout-grid-cell-align(top); - } - - &--align-middle { - @include mdc-layout-grid-cell-align(middle); - } - - &--align-bottom { - @include mdc-layout-grid-cell-align(bottom); - } - } - - .layout-grid--fixed-column-width, - .layout-grid[data-grid-fixed-width=true] { - @each $size in map-keys($mdc-layout-grid-columns) { - @include mdc-layout-grid-media-query_($size) { - $margin: map-get($mdc-layout-grid-default-margin, $size); - $gutter: map-get($mdc-layout-grid-default-gutter, $size); - $column-width: map-get($mdc-layout-grid-column-width, $size); - - @include mdc-layout-grid-fixed-column-width($size, $margin, $gutter, $column-width); - } - } - } - - .layout-grid--align-left, - [data--grid-align="left"] { - margin-right: auto; - margin-left: 0; - } - - .layout-grid--align-right, - [data-grid-align="right"] { - margin-right: 0; - margin-left: auto; - } -} diff --git a/webapp/packages/core-theming/src/styles/main/app-loading-screen.pure.css b/webapp/packages/core-theming/src/styles/main/app-loading-screen.pure.css index 590c4a9fac..774e41e819 100644 --- a/webapp/packages/core-theming/src/styles/main/app-loading-screen.pure.css +++ b/webapp/packages/core-theming/src/styles/main/app-loading-screen.pure.css @@ -8,14 +8,14 @@ display: flex; align-items: center; justify-content: center; - transition: opacity 0.3s; + transition: opacity var(--duration-slow); background: white; } #app-loading-screen .app-loading-screen__logo-spinner { transform-origin: center; - -webkit-animation:spin 2s linear infinite; - -moz-animation:spin 2s linear infinite; - animation:spin 2s linear infinite; + -webkit-animation: spin var(--duration-spin) var(--ease-evenly) infinite; + -moz-animation: spin var(--duration-spin) var(--ease-evenly) infinite; + animation: spin var(--duration-spin) var(--ease-evenly) infinite; } :not(:empty) + #app-loading-screen.app-loading-screen--fade-out { opacity: 0; @@ -24,6 +24,19 @@ display: none; } -@-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } } -@-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } } -@keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } } \ No newline at end of file +@-moz-keyframes spin { + 100% { + -moz-transform: rotate(360deg); + } +} +@-webkit-keyframes spin { + 100% { + -webkit-transform: rotate(360deg); + } +} +@keyframes spin { + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} diff --git a/webapp/packages/core-theming/src/styles/main/dark.theme.scss b/webapp/packages/core-theming/src/styles/main/dark.theme.scss index bcc66c712e..f89cf9370f 100644 --- a/webapp/packages/core-theming/src/styles/main/dark.theme.scss +++ b/webapp/packages/core-theming/src/styles/main/dark.theme.scss @@ -13,13 +13,8 @@ @include colors; @include color-scheme; @include css-variables; - @include ripple-core-styles; - @include theme-ripple; - @include layout-grid; @include form-controls; - @include switch-core-styles; @include link; - @include placeholder; @include delimiter($mdc-theme-secondary); @include branding-overflow; } diff --git a/webapp/packages/core-theming/src/styles/main/elevation.pure.scss b/webapp/packages/core-theming/src/styles/main/elevation.pure.scss deleted file mode 100644 index 750fe71c68..0000000000 --- a/webapp/packages/core-theming/src/styles/main/elevation.pure.scss +++ /dev/null @@ -1,32 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 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 '@material/elevation/mixins'; - -@mixin elevation-core-styles($query: mdc-feature-all()) { - $feat-animation: mdc-feature-create-target($query, animation); - $feat-structure: mdc-feature-create-target($query, structure); - - @for $z-value from 0 through 24 { - .theme-elevation-z#{$z-value} { - @include mdc-elevation($z-value, $query: $query); - } - } - - .theme-elevation-transition { - @include mdc-feature-targets($feat-animation) { - transition: mdc-elevation-transition-value(); - } - - @include mdc-feature-targets($feat-structure) { - will-change: $mdc-elevation-property; - } - } -} - -@include elevation-core-styles; diff --git a/webapp/packages/core-theming/src/styles/main/light.theme.scss b/webapp/packages/core-theming/src/styles/main/light.theme.scss index 51e516175f..7fedd53c91 100644 --- a/webapp/packages/core-theming/src/styles/main/light.theme.scss +++ b/webapp/packages/core-theming/src/styles/main/light.theme.scss @@ -13,13 +13,8 @@ @include colors; @include color-scheme; @include css-variables; - @include ripple-core-styles; - @include theme-ripple; - @include layout-grid; @include form-controls; - @include switch-core-styles; @include link; - @include placeholder; @include delimiter($mdc-theme-secondary); @include branding-overflow; } diff --git a/webapp/packages/core-theming/src/styles/main/typography.pure.scss b/webapp/packages/core-theming/src/styles/main/typography.pure.scss deleted file mode 100644 index 751f013bd4..0000000000 --- a/webapp/packages/core-theming/src/styles/main/typography.pure.scss +++ /dev/null @@ -1,23 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 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 '@material/typography/mixins'; - -@mixin typography-core-styles($query: mdc-feature-all()) { - .theme-typography { - @include mdc-typography-base($query: $query); - } - - @each $style in map-keys($mdc-typography-styles) { - .theme-typography--#{$style} { - @include mdc-typography($style, $query: $query); - } - } -} - -@include typography-core-styles; \ No newline at end of file diff --git a/webapp/packages/core-theming/src/styles/theme-dark.module.scss b/webapp/packages/core-theming/src/styles/theme-dark.module.scss index 55d48c0873..7dc927147f 100644 --- a/webapp/packages/core-theming/src/styles/theme-dark.module.scss +++ b/webapp/packages/core-theming/src/styles/theme-dark.module.scss @@ -9,13 +9,8 @@ @import './theme-dark'; @include theme-matcher; -@include layout-grid; @include colors; -@include ripple-core-styles; -@include theme-ripple; -@include switch-core-styles; @include form-controls; @include link; -@include placeholder; @include delimiter($mdc-theme-background); @include branding-overflow; diff --git a/webapp/packages/core-theming/src/styles/theme-light.module.scss b/webapp/packages/core-theming/src/styles/theme-light.module.scss index 1ff9994780..076759280f 100644 --- a/webapp/packages/core-theming/src/styles/theme-light.module.scss +++ b/webapp/packages/core-theming/src/styles/theme-light.module.scss @@ -9,13 +9,8 @@ @import './theme-light'; @include theme-matcher; -@include layout-grid; @include colors; -@include ripple-core-styles; -@include theme-ripple; -@include switch-core-styles; @include form-controls; @include link; -@include placeholder; @include delimiter($mdc-theme-background); @include branding-overflow; diff --git a/webapp/packages/core-ui/src/ContextMenu/MenuBar/MenuBarItem.module.css b/webapp/packages/core-ui/src/ContextMenu/MenuBar/MenuBarItem.module.css index 9419c54dbb..eb47601250 100644 --- a/webapp/packages/core-ui/src/ContextMenu/MenuBar/MenuBarItem.module.css +++ b/webapp/packages/core-ui/src/ContextMenu/MenuBar/MenuBarItem.module.css @@ -60,6 +60,7 @@ display: none; & .icon { + fill: var(--theme-on-primary); width: 12px; } } diff --git a/webapp/packages/core-ui/src/Tabs/Tab/Tab.module.css b/webapp/packages/core-ui/src/Tabs/Tab/Tab.module.css index b91ceb1ef8..6566dd6914 100644 --- a/webapp/packages/core-ui/src/Tabs/Tab/Tab.module.css +++ b/webapp/packages/core-ui/src/Tabs/Tab/Tab.module.css @@ -6,10 +6,6 @@ * you may not use this file except in compliance with the License. */ -.placeholder { - composes: placeholder from global; -} - .tab { position: relative; font-weight: normal; diff --git a/webapp/packages/plugin-administration/src/ConfigurationWizard/Finish/FinishPage.module.css b/webapp/packages/plugin-administration/src/ConfigurationWizard/Finish/FinishPage.module.css index 8dacd1a186..26a6841563 100644 --- a/webapp/packages/plugin-administration/src/ConfigurationWizard/Finish/FinishPage.module.css +++ b/webapp/packages/plugin-administration/src/ConfigurationWizard/Finish/FinishPage.module.css @@ -1,17 +1,21 @@ .layoutGrid { - composes: layout-grid from global; + display: grid; + box-sizing: border-box; width: 100%; flex: 1; + padding: 24px; } .layoutGridInner { - composes: layout-grid__inner from global; + display: grid; + grid-template-columns: repeat(12, 1fr); + gap: 24px; min-height: 100%; } .layoutGridCell { - composes: layout-grid__cell from global; composes: theme-background-surface theme-text-on-surface theme-border-color-background from global; + grid-column: 1 / -1; position: relative; border: solid 1px; padding: 16px 24px; diff --git a/webapp/packages/plugin-codemirror6/package.json b/webapp/packages/plugin-codemirror6/package.json index 3c429143eb..8996eb8570 100644 --- a/webapp/packages/plugin-codemirror6/package.json +++ b/webapp/packages/plugin-codemirror6/package.json @@ -27,6 +27,7 @@ "@cloudbeaver/core-localization": "workspace:*", "@cloudbeaver/core-theming": "workspace:*", "@cloudbeaver/core-utils": "workspace:*", + "@cloudbeaver/plugin-tailwindcss-theme": "workspace:*", "@codemirror/autocomplete": "^6", "@codemirror/commands": "^6", "@codemirror/lang-html": "^6", diff --git a/webapp/packages/plugin-codemirror6/src/theme/_base-code-editor-autocompletion.scss b/webapp/packages/plugin-codemirror6/src/theme/_base-code-editor-autocompletion.scss deleted file mode 100644 index b05bff013e..0000000000 --- a/webapp/packages/plugin-codemirror6/src/theme/_base-code-editor-autocompletion.scss +++ /dev/null @@ -1,46 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others - * - * Licensed under the Apache License, Version 2.0. - * you may not use this file except in compliance with the License. - */ - -@mixin base-code-editor-autocompletion() { - .cm-tooltip.cm-tooltip-autocomplete { - &>:global(ul) { - border-radius: var(--theme-form-element-radius); - } - - & :global(li) { - display: flex; - align-items: center; - } - - & .cm-completionIcon { - opacity: 1; - width: 16px; - height: 16px; - padding: 0; - margin-right: .6em; - - &:not(:global([src])) { - opacity: 0; - } - } - - & :global(li):hover { - @include mdc-theme-prop(background, sub-secondary, false); - @include mdc-theme-prop(color, on-secondary, false); - } - - & :global(li):global([aria-selected=true]) { - @include mdc-theme-prop(background, secondary, false); - @include mdc-theme-prop(color, text-primary-on-light, false); - } - } - - .cm-tooltip.cm-completionInfo { - margin-left: 8px; - } -} \ No newline at end of file diff --git a/webapp/packages/plugin-codemirror6/src/theme/_base-code-editor-tooltip.scss b/webapp/packages/plugin-codemirror6/src/theme/_base-code-editor-tooltip.scss deleted file mode 100644 index 45e900d061..0000000000 --- a/webapp/packages/plugin-codemirror6/src/theme/_base-code-editor-tooltip.scss +++ /dev/null @@ -1,18 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others - * - * Licensed under the Apache License, Version 2.0. - * you may not use this file except in compliance with the License. - */ - -@mixin base-code-editor-tooltip() { - .cm-tooltip { - @include mdc-theme-prop(background-color, surface, false); - @include mdc-theme-prop(color, on-surface, false); - @include mdc-elevation(3); - @include mdc-typography(body2); - border: none; - border-radius: var(--theme-form-element-radius); - } -} \ No newline at end of file diff --git a/webapp/packages/plugin-codemirror6/src/theme/_base-code-editor.scss b/webapp/packages/plugin-codemirror6/src/theme/_base-code-editor.scss deleted file mode 100644 index 6a8a5cc71b..0000000000 --- a/webapp/packages/plugin-codemirror6/src/theme/_base-code-editor.scss +++ /dev/null @@ -1,339 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2025 DBeaver Corp and others - * - * Licensed under the Apache License, Version 2.0. - * you may not use this file except in compliance with the License. - */ - -@mixin base-code-editor() { - .editor, - .cm-editor, - .cm-mergeView, - .cm-mergeViewEditors, - .cm-scroller, - .ReactCodemirror { - width: 100%; - height: 100% !important; - } - - .editor, - .ReactCodemirror, - .cm-mergeView, - .cm-mergeViewEditors, - .cm-editor, - .cm-gotoLine { - @include mdc-typography('body2'); - } - - .cm-mergeViewEditor:first-child { - border-right: 1px solid; - @include mdc-theme-prop(border-color, background, false); - } - - .editor .cm-highlightTab { - opacity: 0.6; - color: var(--theme-text-hint-on-light); - pointer-events: none; - } - - .editor .cm-newline { - color: var(--theme-text-hint-on-light); - opacity: 0.6; - margin-left: 4px; - cursor: default; - pointer-events: none; - } - - .editor .cm-highlightSpace { - background-image: radial-gradient(circle at 50% 55%, var(--theme-text-hint-on-light) 15%, transparent 5%); - opacity: 0.6; - background-position: center; - } - - .editor { - @include mdc-theme-prop(background-color, surface, false); - @include mdc-theme-prop(color, on-surface, false); - } - - .editor .cm-scroller { - outline: none; - line-height: unset; - } - - .editor .cm-content { - caret-color: $cursor; - } - - .editor .cm-cursor { - border-left-color: $cursor; - } - - .editor .cm-link { - &.cm-link-loaded { - @include mdc-theme-prop(color, primary, false); - text-decoration: underline; - cursor: pointer; - } - } - - .editor .cm-dropCursor { - border-left: 1.2px solid $cursor; - } - - .editor .cm-gutters, - .cm-panel { - @include mdc-theme-prop(background-color, surface, false); - @include mdc-theme-prop(color, text-hint-on-light, false); - @include mdc-theme-prop(border-color, background, false); - } - - .cm-panels-top, - .cm-panels-bottom { - @include mdc-theme-prop(border-color, background, false); - } - - .editor .cm-activeLine { - box-shadow: 0 0 0 2px $mdc-theme-sub-secondary; - } - - .editor .cm-activeLineGutter { - @include mdc-theme-prop(color, on-surface, false); - } - - .ͼ2 .cm-activeLine:not(.cm-changedLine, .cm-deletedLine), - .ͼ2 .cm-activeLineGutter:not(.cm-changedLineGutter, .cm-deletedLineGutter) { - background-color: unset; - } - - .editor .active-query { - /* disable because look too ugly */ - /* - display: inline-block; - @include mdc-theme-prop(background, secondary, false); - */ - } - - .editor .cm-gotoLine.cm-panel { - display: flex; - align-items: flex-end; - flex-wrap: wrap; - padding: 4px 8px; - gap: 8px; - min-width: 160px; - container-type: inline-size; - - & label { - display: flex; - flex-wrap: wrap; - align-items: center; - text-transform: uppercase; - letter-spacing: -0.1px; - gap: 4px; - } - - & input { - @include mdc-typography('body2'); - max-width: 60px; - height: 24px; - padding-inline: 8px; - - &:focus { - @include mdc-theme-prop(border-color, primary, false); - } - } - & .cm-button { - @include mdc-typography('body2'); - background: transparent; - height: 24px; - padding-block: 0; - margin-right: 24px; - - font-weight: 500; - text-transform: uppercase; - - color: var(--theme-primary); - border-radius: 4px; - border-color: var(--theme-primary); - - &:hover { - background: color-mix(in srgb, transparent, var(--theme-primary) 5%); - } - - @container (width < 240px) { - display: none; - } - } - - & button[name='close'] { - margin-left: auto; - padding: 0 8px; - top: 4px; - height: 24px; - width: 24px; - border-radius: 4px; - background: transparent; - color: var(--theme-on-surface); - border-color: var(--theme-on-surface); - font-size: 16px; - - &:hover { - background: color-mix(in srgb, transparent, var(--theme-on-surface) 5%); - } - } - } - - .editor .cm-content ::selection { - @include mdc-theme-prop(background, primary, false); - color: white; - } - - .editor .cm-lineNumbers .cm-gutterElement { - min-width: 3ch; - box-sizing: content-box; - } - - .editor .cm-gutters .cm-foldGutter .cm-gutterElement { - display: flex; - align-items: center; - cursor: pointer; - user-select: none; - } - - .editor .cm-gutters .cm-foldGutter .cm-gutterElement-icon { - padding: 0 3px 0 5px; - width: 20px; - height: 12px; - display: flex; - - &.cm-foldGutter-folded :global(svg) { - transform: rotate(-90deg); - } - } - - .editor .cm-gutters .query-status .cm-gutterElement { - display: flex; - align-items: center; - justify-content: center; - width: 14px; - - .running-query-line { - display: flex; - height: 8px; - width: 8px; - border-radius: 100%; - @include mdc-theme-prop(background, primary, false); - } - - .running-query-error-line { - display: flex; - height: 8px; - width: 8px; - border-radius: 100%; - @include mdc-theme-prop(background, negative, false); - } - } - - .editor .tok-keyword { - color: $keyword; - font-weight: bold; - } - - .editor .tok-operator { - color: $operator; - } - - .editor .tok-variable-2 { - color: $variable-2; - } - - .editor .tok-variable-3, - .editor .tok-type { - color: $variable-3; - } - - .editor .tok-builtin { - color: $builtin; - } - - .editor .tok-atom { - color: $atom; - } - - .editor .tok-number { - color: $number; - } - - .editor .tok-def { - color: $def; - } - - .editor .tok-string { - color: $string; - } - - .editor .tok-string2 { - color: $string-2; - } - - .editor .tok-comment { - color: $comment; - } - - .editor .tok-variable { - color: $variable; - } - - .editor .tok-tag { - color: $tag; - } - - .editor .tok-meta { - color: $meta; - } - - .editor .tok-attribute { - color: $attribute; - } - - .editor .tok-property { - color: $property; - } - - .editor .tok-qualifier { - color: $qualifier; - } - - .editor .tok-variable-3, - .editor .tok-type { - color: $variable-3; - } - - .editor .tok-typeName { - color: $type-name; - } - - .editor .tok-punctuation { - color: $punctuation; - } - - .editor .tok-propertyName { - color: $property-name; - } - - .editor .tok-className { - color: $class-name; - } - - .editor .tok-bool { - color: $bool; - } - - .editor .tok-variableName { - color: $variable-name; - } - - .editor .tok-labelName { - color: $label-name; - } -} diff --git a/webapp/packages/plugin-codemirror6/src/theme/base-code-editor-autocompletion.css b/webapp/packages/plugin-codemirror6/src/theme/base-code-editor-autocompletion.css new file mode 100644 index 0000000000..f80a707396 --- /dev/null +++ b/webapp/packages/plugin-codemirror6/src/theme/base-code-editor-autocompletion.css @@ -0,0 +1,39 @@ +/* Increase specificity by selector repetition */ +.cm-tooltip.cm-tooltip { + &.cm-tooltip-autocomplete { + & > ul { + border-radius: var(--theme-form-element-radius); + } + + & li { + display: flex; + align-items: center; + + &:hover { + background: var(--theme-sub-secondary); + color: var(--theme-on-secondary); + } + + &[aria-selected='true'] { + background: var(--theme-secondary); + color: var(--theme-text-primary-on-light); + } + } + + & .cm-completionIcon { + opacity: 1; + width: 16px; + height: 16px; + padding: 0; + margin-right: 0.6em; + + &:not([src]) { + opacity: 0; + } + } + } + + &.cm-completionInfo { + margin-left: 8px; + } +} diff --git a/webapp/packages/plugin-codemirror6/src/theme/base-code-editor-tooltip.css b/webapp/packages/plugin-codemirror6/src/theme/base-code-editor-tooltip.css new file mode 100644 index 0000000000..acd4fee8c9 --- /dev/null +++ b/webapp/packages/plugin-codemirror6/src/theme/base-code-editor-tooltip.css @@ -0,0 +1,14 @@ +@import '@cloudbeaver/plugin-tailwindcss-theme/tailwind.css'; + +/* Increase specificity by selector repetition */ +.cm-tooltip.cm-tooltip { + @apply tw:typography-body2; + box-shadow: + 0px 3px 3px -2px rgba(0, 0, 0, 0.2), + 0px 3px 4px 0px rgba(0, 0, 0, 0.14), + 0px 1px 8px 0px rgba(0, 0, 0, 0.12); + background-color: var(--theme-surface); + color: var(--theme-on-surface); + border: none; + border-radius: var(--theme-form-element-radius); +} diff --git a/webapp/packages/plugin-codemirror6/src/theme/base-code-editor.css b/webapp/packages/plugin-codemirror6/src/theme/base-code-editor.css new file mode 100644 index 0000000000..1cbf02a625 --- /dev/null +++ b/webapp/packages/plugin-codemirror6/src/theme/base-code-editor.css @@ -0,0 +1,327 @@ +@import '@cloudbeaver/plugin-tailwindcss-theme/tailwind.css'; +/* Increase specificity by selector repetition */ +.editor.editor, +.cm-editor.cm-editor, +.cm-mergeView.cm-mergeView, +.cm-mergeViewEditors.cm-mergeViewEditors, +.cm-scroller.cm-scroller, +.ReactCodemirror.ReactCodemirror { + width: 100%; + height: 100% !important; +} + +.editor.editor, +.ReactCodemirror.ReactCodemirror, +.cm-mergeView.cm-mergeView, +.cm-mergeViewEditors.cm-mergeViewEditors, +.cm-editor.cm-editor, +.cm-gotoLine.cm-gotoLine { + @apply tw:typography-body2; +} + +.cm-mergeViewEditor.cm-mergeViewEditor { + &:first-child { + border-right: 1px solid; + border-color: var(--theme-background); + } +} + +.editor.editor { + background-color: var(--theme-surface); + color: var(--theme-on-surface); + + & .cm-highlightTab { + opacity: 0.6; + color: var(--theme-text-hint-on-light); + pointer-events: none; + } + + & .cm-newline { + color: var(--theme-text-hint-on-light); + opacity: 0.6; + margin-left: 4px; + cursor: default; + pointer-events: none; + } + + & .cm-highlightSpace { + background-image: radial-gradient(circle at 50% 55%, var(--theme-text-hint-on-light) 15%, transparent 5%); + opacity: 0.6; + background-position: center; + } + + & .cm-scroller { + outline: none; + line-height: unset; + } + + & .cm-content { + caret-color: var(--editor-cursor); + } + + & .cm-cursor { + border-left-color: var(--editor-cursor); + } + + & .cm-link { + &.cm-link-loaded { + color: var(--theme-primary); + text-decoration: underline; + cursor: pointer; + } + } + + & .cm-dropCursor { + border-left: 1.2px solid var(--editor-cursor); + } + + & .cm-gutters { + background-color: var(--theme-surface); + color: var(--theme-text-hint-on-light); + border-color: var(--theme-background); + } + + & .cm-activeLine { + box-shadow: 0 0 0 2px var(--theme-sub-secondary); + } + + & .cm-activeLineGutter { + color: var(--theme-on-surface); + } + + & .cm-gotoLine.cm-panel { + display: flex; + align-items: flex-end; + flex-wrap: wrap; + padding: 4px 8px; + gap: 8px; + min-width: 160px; + container-type: inline-size; + + & label { + display: flex; + flex-wrap: wrap; + align-items: center; + text-transform: uppercase; + letter-spacing: -0.1px; + gap: 4px; + } + + & input { + @apply tw:typography-body2; + max-width: 60px; + height: 24px; + padding-inline: 8px; + + &:focus { + border-color: var(--theme-primary); + } + } + & .cm-button { + @apply tw:typography-body2; + background: transparent; + height: 24px; + padding-block: 0; + margin-right: 24px; + + font-weight: 500; + text-transform: uppercase; + + color: var(--theme-primary); + border-radius: 4px; + border-color: var(--theme-primary); + + &:hover { + background: color-mix(in srgb, transparent, var(--theme-primary) 5%); + } + + @container (width < 240px) { + display: none; + } + } + + & button[name='close'] { + margin-left: auto; + padding: 0 8px; + top: 4px; + height: 24px; + width: 24px; + border-radius: 4px; + background: transparent; + color: var(--theme-on-surface); + border-color: var(--theme-on-surface); + font-size: 16px; + + &:hover { + background: color-mix(in srgb, transparent, var(--theme-on-surface) 5%); + } + } + } + + & .cm-content ::selection { + background: var(--theme-primary); + color: white; + } + + & .cm-lineNumbers .cm-gutterElement { + min-width: 3ch; + box-sizing: content-box; + } + + & .cm-gutters .cm-foldGutter .cm-gutterElement { + display: flex; + align-items: center; + cursor: pointer; + user-select: none; + } + + & .cm-gutters .cm-foldGutter .cm-gutterElement-icon { + padding: 0 3px 0 5px; + width: 20px; + height: 12px; + display: flex; + + &.cm-foldGutter-folded svg { + transform: rotate(-90deg); + } + } + + & .cm-gutters .query-status .cm-gutterElement { + display: flex; + align-items: center; + justify-content: center; + width: 14px; + + .running-query-line { + display: flex; + height: 8px; + width: 8px; + border-radius: 100%; + background: var(--theme-primary); + } + + .running-query-error-line { + display: flex; + height: 8px; + width: 8px; + border-radius: 100%; + background: var(--theme-negative); + } + } + + & .tok-keyword { + color: var(--editor-keyword); + font-weight: bold; + } + + & .tok-operator { + color: var(--editor-operator); + } + + & .tok-variable-2 { + color: var(--editor-variable-2); + } + + & .tok-variable-3, + & .tok-type { + color: var(--editor-variable-3); + } + + & .tok-builtin { + color: var(--editor-builtin); + } + + & .tok-atom { + color: var(--editor-atom); + } + + & .tok-number { + color: var(--editor-number); + } + + & .tok-def { + color: var(--editor-def); + } + + & .tok-string { + color: var(--editor-string); + } + + & .tok-string2 { + color: var(--editor-string-2); + } + + & .tok-comment { + color: var(--editor-comment); + } + + & .tok-variable { + color: var(--editor-variable); + } + + & .tok-tag { + color: var(--editor-tag); + } + + & .tok-meta { + color: var(--editor-meta); + } + + & .tok-attribute { + color: var(--editor-attribute); + } + + & .tok-property { + color: var(--editor-property); + } + + & .tok-qualifier { + color: var(--editor-qualifier); + } + + & .tok-typeName { + color: var(--editor-type-name); + } + + & .tok-punctuation { + color: var(--editor-punctuation); + } + + & .tok-propertyName { + color: var(--editor-property-name); + } + + & .tok-className { + color: var(--editor-class-name); + } + + & .tok-bool { + color: var(--editor-bool); + } + + & .tok-variableName { + color: var(--editor-variable-name); + } + + & .tok-labelName { + color: var(--editor-label-name); + } +} + +.cm-panel.cm-panel { + background-color: var(--theme-surface); + color: var(--theme-text-hint-on-light); + border-color: var(--theme-background); +} + +.cm-panels-top.cm-panels-top, +.cm-panels-bottom.cm-panels-bottom { + border-color: var(--theme-background) !important; +} + +.ͼ2.ͼ2 { + & .cm-activeLine:not(.cm-changedLine, .cm-deletedLine), + & .cm-activeLineGutter:not(.cm-changedLineGutter, .cm-deletedLineGutter) { + background-color: unset; + } +} diff --git a/webapp/packages/plugin-codemirror6/src/theme/dark.css b/webapp/packages/plugin-codemirror6/src/theme/dark.css new file mode 100644 index 0000000000..1a2d0b92cf --- /dev/null +++ b/webapp/packages/plugin-codemirror6/src/theme/dark.css @@ -0,0 +1,31 @@ +.theme-dark { + --editor-meta: #ff1717; + --editor-keyword: rgb(115, 158, 202); + --editor-atom: #56c8d8; + --editor-number: rgb(192, 192, 192); + --editor-def: #00f; + --editor-variable: rgb(126, 186, 211); + --editor-variable-2: rgb(193, 170, 108); + --editor-variable-3: rgb(193, 170, 108); + --editor-property: rgb(126, 186, 211); + --editor-operator: rgb(126, 186, 211); + --editor-comment: rgb(102, 151, 104); + --editor-string: rgb(202, 197, 128); + --editor-string-2: #f50; + --editor-qualifier: #555; + --editor-builtin: #ab87ff; + --editor-bracket: #cc7; + --editor-tag: #170; + --editor-attribute: #00c; + --editor-link: #219; + --editor-error: #f00; + --editor-delimiter: rgb(238, 204, 100); + --editor-cursor: #fff; + --editor-type-name: #c586c0; + --editor-class-name: #c586c0; + --editor-punctuation: #ffffff8c; + --editor-property-name: #569cd6; + --editor-bool: #56c8d8; + --editor-variable-name: #56c8d8; + --editor-label-name: #cf6edf; +} diff --git a/webapp/packages/plugin-codemirror6/src/theme/dark.module.scss b/webapp/packages/plugin-codemirror6/src/theme/dark.module.scss deleted file mode 100644 index d8ce497fb0..0000000000 --- a/webapp/packages/plugin-codemirror6/src/theme/dark.module.scss +++ /dev/null @@ -1,49 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 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 '@cloudbeaver/core-theming/src/styles/theme-dark'; -@import './base-code-editor'; -@import './base-code-editor-autocompletion'; -@import './base-code-editor-tooltip'; - -$meta: #ff1717; -$keyword: rgb(115, 158, 202); -$atom: #56c8d8; -$number: rgb(192, 192, 192); -$def: #00f; -$variable: rgb(126, 186, 211); -$variable-2: rgb(193, 170, 108); -$variable-3: rgb(193, 170, 108); -$property: rgb(126, 186, 211); -$operator: rgb(126, 186, 211); -$comment: rgb(102, 151, 104); -$string: rgb(202, 197, 128); -$string-2: #f50; -$qualifier: #555; -$builtin: #ab87ff; -$bracket: #cc7; -$tag: #170; -$attribute: #00c; -$link: #219; -$error: #f00; -$delimiter: rgb(238, 204, 100); -$cursor: #fff; -$active-query: $color-positive; -$type-name: #c586c0; -$class-name: #c586c0; -$punctuation: #ffffff8c; -$property-name: #569cd6; -$bool: #56c8d8; -$variable-name: #56c8d8; -$label-name: #cf6edf; - -:global .#{$theme-class} { - @include base-code-editor; - @include base-code-editor-autocompletion; - @include base-code-editor-tooltip; -} diff --git a/webapp/packages/plugin-codemirror6/src/theme/light.css b/webapp/packages/plugin-codemirror6/src/theme/light.css new file mode 100644 index 0000000000..d1d8028dc8 --- /dev/null +++ b/webapp/packages/plugin-codemirror6/src/theme/light.css @@ -0,0 +1,31 @@ +.theme-light { + --editor-meta: #ff1717; + --editor-keyword: #07a; + --editor-atom: #905; + --editor-number: #905; + --editor-def: #00f; + --editor-variable: black; + --editor-variable-2: #a8bd00; + --editor-variable-3: #a8bd00; + --editor-property: black; + --editor-operator: #a67f59; + --editor-comment: #3f7f5f; + --editor-string: #1f8900; + --editor-string-2: #f50; + --editor-qualifier: #555; + --editor-builtin: #07a; + --editor-bracket: #cc7; + --editor-tag: #170; + --editor-attribute: #00c; + --editor-link: #905; + --editor-error: #f00; + --editor-delimiter: rgb(238, 204, 100); + --editor-cursor: #000; + --editor-type-name: #007acc; + --editor-class-name: #007acc; + --editor-punctuation: #6d6d6d; + --editor-property-name: #c42626; + --editor-bool: #905; + --editor-variable-name: #905; + --editor-label-name: #81a1c1; +} diff --git a/webapp/packages/plugin-codemirror6/src/theme/light.module.scss b/webapp/packages/plugin-codemirror6/src/theme/light.module.scss deleted file mode 100644 index aad7e81507..0000000000 --- a/webapp/packages/plugin-codemirror6/src/theme/light.module.scss +++ /dev/null @@ -1,49 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 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 '@cloudbeaver/core-theming/src/styles/theme-light'; -@import './base-code-editor'; -@import './base-code-editor-autocompletion'; -@import './base-code-editor-tooltip'; - -$meta: #ff1717; -$keyword: #07a; -$atom: #905; -$number: #905; -$def: #00f; -$variable: black; -$variable-2: #a8bd00; -$variable-3: #a8bd00; -$property: black; -$operator: #a67f59; -$comment: #3f7f5f; -$string: #1f8900; -$string-2: #f50; -$qualifier: #555; -$builtin: #07a; -$bracket: #cc7; -$tag: #170; -$attribute: #00c; -$link: #905; -$error: #f00; -$delimiter: rgb(238, 204, 100); -$cursor: #000; -$active-query: $color-positive; -$type-name: #007acc; -$class-name: #007acc; -$punctuation: #6d6d6d; -$property-name: #c42626; -$bool: #905; -$variable-name: #905; -$label-name: #81a1c1; - -:global .#{$theme-class} { - @include base-code-editor; - @include base-code-editor-autocompletion; - @include base-code-editor-tooltip; -} diff --git a/webapp/packages/plugin-codemirror6/src/theme/styles.ts b/webapp/packages/plugin-codemirror6/src/theme/styles.ts index 35199acad6..0370735f6a 100644 --- a/webapp/packages/plugin-codemirror6/src/theme/styles.ts +++ b/webapp/packages/plugin-codemirror6/src/theme/styles.ts @@ -1,24 +1,24 @@ /* * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others + * Copyright (C) 2020-2026 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 type { ThemeSelector } from '@cloudbeaver/core-theming'; - -import type Dark from './dark.module.scss'; -import type Light from './light.module.scss'; +import './base-code-editor.css'; +import './base-code-editor-autocompletion.css'; +import './base-code-editor-tooltip.css'; export const EDITOR_BASE_STYLES: ThemeSelector = async theme => { - let styles: typeof Light & typeof Dark; + let styles: any; switch (theme) { case 'dark': - styles = (await import('./dark.module.scss')).default; + styles = (await import('./dark.css')).default; break; default: - styles = (await import('./light.module.scss')).default; + styles = (await import('./light.css')).default; break; } diff --git a/webapp/packages/plugin-codemirror6/tsconfig.json b/webapp/packages/plugin-codemirror6/tsconfig.json index 7ef04e01e0..b551442b8b 100644 --- a/webapp/packages/plugin-codemirror6/tsconfig.json +++ b/webapp/packages/plugin-codemirror6/tsconfig.json @@ -27,6 +27,9 @@ }, { "path": "../core-utils" + }, + { + "path": "../plugin-tailwindcss-theme" } ], "include": [ diff --git a/webapp/packages/plugin-connection-preferences/src/ConnectionPreferencesForm/ConnectionPreferencesForm.tsx b/webapp/packages/plugin-connection-preferences/src/ConnectionPreferencesForm/ConnectionPreferencesForm.tsx index 19348bcbf8..49545a3bcc 100644 --- a/webapp/packages/plugin-connection-preferences/src/ConnectionPreferencesForm/ConnectionPreferencesForm.tsx +++ b/webapp/packages/plugin-connection-preferences/src/ConnectionPreferencesForm/ConnectionPreferencesForm.tsx @@ -61,7 +61,7 @@ export const ConnectionPreferencesForm = observer
-
+