adds tailwindcss utilities + example

This commit is contained in:
sergeyteleshev
2026-03-17 01:47:53 +01:00
parent fa7c481bbc
commit 20ca1b787c
8 changed files with 917 additions and 111 deletions
@@ -5,19 +5,22 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
.space {
composes: theme-typography--body2 theme-background-surface theme-text-on-surface from global;
@import '@cloudbeaver/core-theming/src/styles/utilities';
.main-space {
@apply typography-body2 bg-theme-surface text-theme-on-surface;
display: flex;
flex-direction: row;
flex: 1;
overflow: hidden;
}
.pane {
composes: theme-background-surface theme-text-on-surface from global;
.main-pane {
@apply bg-theme-surface text-theme-on-surface;
display: flex;
position: relative;
overflow: hidden;
}
.loader {
.main-loader {
height: 100%;
}
@@ -13,11 +13,9 @@ import {
Loader,
Pane,
ResizerControls,
s,
SContext,
Split,
useExecutor,
useS,
useSplitUserState,
type StyleRegistry,
} from '@cloudbeaver/core-blocks';
@@ -25,7 +23,7 @@ import { useService } from '@cloudbeaver/core-di';
import { LeftBarPanelService, SideBarPanel, SideBarPanelService, TabStyles } from '@cloudbeaver/core-ui';
import { RightArea } from './RightArea.js';
import style from './Main.module.css';
import './Main.css';
import LeftSideBarPanel from './LeftSideBarPanel.module.css';
const LEFT_SIDEBAR_PANEL_REGISTRY: StyleRegistry = [
@@ -39,7 +37,6 @@ const LEFT_SIDEBAR_PANEL_REGISTRY: StyleRegistry = [
];
export const Main = observer(function Main() {
const styles = useS(style);
const sideBarPanelService = useService(SideBarPanelService);
const leftBarPanelService = useService(LeftBarPanelService);
@@ -61,10 +58,10 @@ export const Main = observer(function Main() {
});
return (
<Loader className={s(styles, { loader: true })} suspense>
<main className={s(styles, { space: true })}>
<Loader className="main-loader" suspense>
<main className="main-space">
<Split {...splitMainState} sticky={30} mode={leftBarDisabled ? 'minimize' : splitMainState.mode} disable={leftBarDisabled}>
<Pane className={s(styles, { pane: true })} basis="250px" main>
<Pane className="main-pane" basis="250px" main>
<Loader suspense>
<SContext registry={LEFT_SIDEBAR_PANEL_REGISTRY}>
<SideBarPanel container={leftBarPanelService.tabsContainer} panelId="dbeaver-left-sidebar" />
@@ -72,14 +69,14 @@ export const Main = observer(function Main() {
</Loader>
</Pane>
<ResizerControls />
<Pane className={s(styles, { pane: true })}>
<Pane className="main-pane">
<Split {...splitRightState} mode={sideBarDisabled ? 'minimize' : splitRightState.mode} disable={sideBarDisabled} sticky={30}>
<Pane className={s(styles, { pane: true })}>
<Pane className="main-pane">
<RightArea />
</Pane>
<ResizerControls />
<Pane className={s(styles, { pane: true })} basis="400px" main>
<Loader className={s(styles, { loader: true })} suspense>
<Pane className="main-pane" basis="400px" main>
<Loader className="main-loader" suspense>
<SideBarPanel container={sideBarPanelService.tabsContainer} panelId="dbeaver-right-sidebar" />
</Loader>
</Pane>
@@ -0,0 +1,26 @@
@utility radius-form-element {
border-radius: var(--theme-form-element-radius);
}
@utility radius-group-element {
border-radius: var(--theme-group-element-radius);
}
@utility radius-menu-bar-small {
border-radius: var(--theme-menu-bar-small-action-radius);
}
/* Component layer classes for backwards compatibility. TODO: Remove it once all components are migrated to the new utility classes */
@layer components {
.theme-form-element-radius {
@apply radius-form-element;
}
.theme-group-element-radius {
@apply radius-group-element;
}
.theme-menu-bar-small-action-radius {
@apply radius-menu-bar-small;
}
}
@@ -0,0 +1,680 @@
@utility text-theme-primary {
color: var(--theme-primary);
}
@utility text-theme-on-primary {
color: var(--theme-on-primary);
}
@utility text-theme-secondary {
color: var(--theme-secondary);
}
@utility text-theme-on-secondary {
color: var(--theme-on-secondary);
}
@utility text-theme-error {
color: var(--theme-error);
}
@utility text-theme-on-error {
color: var(--theme-on-error);
}
@utility text-theme-surface {
color: var(--theme-surface);
}
@utility text-theme-on-surface {
color: var(--theme-on-surface);
}
@utility text-theme-background {
color: var(--theme-background);
}
@utility text-theme-positive {
color: var(--theme-positive);
}
@utility text-theme-negative {
color: var(--theme-negative);
}
@utility text-theme-status {
color: var(--theme-status);
}
@utility text-theme-primary {
color: var(--theme-primary);
svg,
& > svg {
fill: var(--theme-primary);
}
}
@utility text-theme-on-primary {
color: var(--theme-on-primary);
svg,
& > svg {
fill: var(--theme-on-primary);
}
}
@utility text-theme-secondary {
color: var(--theme-secondary);
svg,
& > svg {
fill: var(--theme-secondary);
}
}
@utility text-theme-on-secondary {
color: var(--theme-on-secondary);
svg,
& > svg {
fill: var(--theme-on-secondary);
}
}
@utility text-theme-error {
color: var(--theme-error);
svg,
& > svg {
fill: var(--theme-error);
}
}
@utility text-theme-on-error {
color: var(--theme-on-error);
svg,
& > svg {
fill: var(--theme-on-error);
}
}
@utility text-theme-surface {
color: var(--theme-surface);
svg,
& > svg {
fill: var(--theme-surface);
}
}
@utility text-theme-on-surface {
color: var(--theme-on-surface);
svg,
& > svg {
fill: var(--theme-on-surface);
}
}
@utility text-theme-background {
color: var(--theme-background);
svg,
& > svg {
fill: var(--theme-background);
}
}
@utility text-theme-positive {
color: var(--theme-positive);
svg,
& > svg {
fill: var(--theme-positive);
}
}
@utility text-theme-negative {
color: var(--theme-negative);
svg,
& > svg {
fill: var(--theme-negative);
}
}
@utility text-theme-status {
color: var(--theme-status);
svg,
& > svg {
fill: var(--theme-status);
}
}
@utility border-theme-primary {
border-color: var(--theme-primary) !important;
}
@utility border-theme-on-primary {
border-color: var(--theme-on-primary) !important;
}
@utility border-theme-secondary {
border-color: var(--theme-secondary) !important;
}
@utility border-theme-on-secondary {
border-color: var(--theme-on-secondary) !important;
}
@utility border-theme-error {
border-color: var(--theme-error) !important;
}
@utility border-theme-on-error {
border-color: var(--theme-on-error) !important;
}
@utility border-theme-surface {
border-color: var(--theme-surface) !important;
}
@utility border-theme-on-surface {
border-color: var(--theme-on-surface) !important;
}
@utility border-theme-background {
border-color: var(--theme-background) !important;
}
@utility border-theme-positive {
border-color: var(--theme-positive) !important;
}
@utility border-theme-negative {
border-color: var(--theme-negative) !important;
}
@utility border-theme-status {
border-color: var(--theme-status) !important;
}
@utility fill-theme-primary {
fill: var(--theme-primary);
}
@utility fill-theme-on-primary {
fill: var(--theme-on-primary);
}
@utility fill-theme-secondary {
fill: var(--theme-secondary);
}
@utility fill-theme-on-secondary {
fill: var(--theme-on-secondary);
}
@utility fill-theme-error {
fill: var(--theme-error);
}
@utility fill-theme-on-error {
fill: var(--theme-on-error);
}
@utility fill-theme-surface {
fill: var(--theme-surface);
}
@utility fill-theme-on-surface {
fill: var(--theme-on-surface);
}
@utility fill-theme-background {
fill: var(--theme-background);
}
@utility fill-theme-positive {
fill: var(--theme-positive);
}
@utility fill-theme-negative {
fill: var(--theme-negative);
}
@utility fill-theme-status {
fill: var(--theme-status);
}
@utility bg-theme-primary {
background-color: var(--theme-primary);
}
@utility bg-theme-secondary {
background-color: var(--theme-secondary);
}
@utility bg-theme-surface {
background-color: var(--theme-surface);
}
@utility bg-theme-background {
background-color: var(--theme-background);
}
@utility bg-theme-positive {
background-color: var(--theme-positive);
}
@utility text-variant-primary-on-light {
color: var(--theme-text-primary-on-light);
}
@utility text-variant-secondary-on-light {
color: var(--theme-text-secondary-on-light);
}
@utility text-variant-sub-secondary-on-light {
color: var(--theme-text-sub-secondary-on-light);
}
@utility text-variant-hint-on-light {
color: var(--theme-text-hint-on-light);
}
@utility text-variant-disabled-on-light {
color: var(--theme-text-disabled-on-light);
}
@utility text-variant-icon-on-light {
color: var(--theme-text-icon-on-light);
}
@utility text-variant-negative-on-light {
color: var(--theme-text-negative-on-light);
}
@utility text-variant-primary-on-dark {
color: var(--theme-text-primary-on-dark);
}
@utility text-variant-secondary-on-dark {
color: var(--theme-text-secondary-on-dark);
}
@utility text-variant-sub-secondary-on-dark {
color: var(--theme-text-sub-secondary-on-dark);
}
@utility text-variant-hint-on-dark {
color: var(--theme-text-hint-on-dark);
}
@utility text-variant-disabled-on-dark {
color: var(--theme-text-disabled-on-dark);
}
@utility text-variant-icon-on-dark {
color: var(--theme-text-icon-on-dark);
}
@utility text-variant-negative-on-dark {
color: var(--theme-text-negative-on-dark);
}
@utility text-variant-primary-on-light {
color: var(--theme-text-primary-on-light);
svg,
& > svg {
fill: var(--theme-text-primary-on-light);
}
}
@utility text-variant-secondary-on-light {
color: var(--theme-text-secondary-on-light);
svg,
& > svg {
fill: var(--theme-text-secondary-on-light);
}
}
@utility text-variant-sub-secondary-on-light {
color: var(--theme-text-sub-secondary-on-light);
svg,
& > svg {
fill: var(--theme-text-sub-secondary-on-light);
}
}
@utility text-variant-hint-on-light {
color: var(--theme-text-hint-on-light);
svg,
& > svg {
fill: var(--theme-text-hint-on-light);
}
}
@utility text-variant-disabled-on-light {
color: var(--theme-text-disabled-on-light);
svg,
& > svg {
fill: var(--theme-text-disabled-on-light);
}
}
@utility text-variant-icon-on-light {
color: var(--theme-text-icon-on-light);
svg,
& > svg {
fill: var(--theme-text-icon-on-light);
}
}
@utility text-variant-negative-on-light {
color: var(--theme-text-negative-on-light);
svg,
& > svg {
fill: var(--theme-text-negative-on-light);
}
}
@utility text-variant-primary-on-dark {
color: var(--theme-text-primary-on-dark);
svg,
& > svg {
fill: var(--theme-text-primary-on-dark);
}
}
@utility text-variant-secondary-on-dark {
color: var(--theme-text-secondary-on-dark);
svg,
& > svg {
fill: var(--theme-text-secondary-on-dark);
}
}
@utility text-variant-sub-secondary-on-dark {
color: var(--theme-text-sub-secondary-on-dark);
svg,
& > svg {
fill: var(--theme-text-sub-secondary-on-dark);
}
}
@utility text-variant-hint-on-dark {
color: var(--theme-text-hint-on-dark);
svg,
& > svg {
fill: var(--theme-text-hint-on-dark);
}
}
@utility text-variant-disabled-on-dark {
color: var(--theme-text-disabled-on-dark);
svg,
& > svg {
fill: var(--theme-text-disabled-on-dark);
}
}
@utility text-variant-icon-on-dark {
color: var(--theme-text-icon-on-dark);
svg,
& > svg {
fill: var(--theme-text-icon-on-dark);
}
}
@utility text-variant-negative-on-dark {
color: var(--theme-text-negative-on-dark);
svg,
& > svg {
fill: var(--theme-text-negative-on-dark);
}
}
/* Component layer classes for backwards compatibility. Remove it once all components are migrated to the new utility classes */
@layer components {
* {
outline-color: var(--theme-primary);
}
.theme-text-primary {
@apply text-theme-primary;
}
.theme-text-on-primary {
@apply text-theme-on-primary;
}
.theme-text-secondary {
@apply text-theme-secondary;
}
.theme-text-on-secondary {
@apply text-theme-on-secondary;
}
.theme-text-error {
@apply text-theme-error;
}
.theme-text-on-error {
@apply text-theme-on-error;
}
.theme-text-surface {
@apply text-theme-surface;
}
.theme-text-on-surface {
@apply text-theme-on-surface;
}
.theme-text-background {
@apply text-theme-background;
}
.theme-text-positive {
@apply text-theme-positive;
}
.theme-text-negative {
@apply text-theme-negative;
}
.theme-text-status {
@apply text-theme-status;
}
.theme-border-color-primary {
@apply border-theme-primary;
}
.theme-border-color-on-primary {
@apply border-theme-on-primary;
}
.theme-border-color-secondary {
@apply border-theme-secondary;
}
.theme-border-color-on-secondary {
@apply border-theme-on-secondary;
}
.theme-border-color-error {
@apply border-theme-error;
}
.theme-border-color-on-error {
@apply border-theme-on-error;
}
.theme-border-color-surface {
@apply border-theme-surface;
}
.theme-border-color-on-surface {
@apply border-theme-on-surface;
}
.theme-border-color-background {
@apply border-theme-background;
}
.theme-border-color-positive {
@apply border-theme-positive;
}
.theme-border-color-negative {
@apply border-theme-negative;
}
.theme-border-color-status {
@apply border-theme-status;
}
.theme-fill-primary {
@apply fill-theme-primary;
}
.theme-fill-on-primary {
@apply fill-theme-on-primary;
}
.theme-fill-secondary {
@apply fill-theme-secondary;
}
.theme-fill-on-secondary {
@apply fill-theme-on-secondary;
}
.theme-fill-error {
@apply fill-theme-error;
}
.theme-fill-on-error {
@apply fill-theme-on-error;
}
.theme-fill-surface {
@apply fill-theme-surface;
}
.theme-fill-on-surface {
@apply fill-theme-on-surface;
}
.theme-fill-background {
@apply fill-theme-background;
}
.theme-fill-positive {
@apply fill-theme-positive;
}
.theme-fill-negative {
@apply fill-theme-negative;
}
.theme-fill-status {
@apply fill-theme-status;
}
.theme-background-primary {
@apply bg-theme-primary;
}
.theme-background-secondary {
@apply bg-theme-secondary;
}
.theme-background-surface {
@apply bg-theme-surface;
}
.theme-background-background {
@apply bg-theme-background;
}
.theme-background-positive {
@apply bg-theme-positive;
}
.theme-text-text-primary-on-light {
@apply text-variant-primary-on-light;
}
.theme-text-text-secondary-on-light {
@apply text-variant-secondary-on-light;
}
.theme-text-text-sub-secondary-on-light {
@apply text-variant-sub-secondary-on-light;
}
.theme-text-text-hint-on-light {
@apply text-variant-hint-on-light;
}
.theme-text-text-disabled-on-light {
@apply text-variant-disabled-on-light;
}
.theme-text-text-icon-on-light {
@apply text-variant-icon-on-light;
}
.theme-text-text-negative-on-light {
@apply text-variant-negative-on-light;
}
.theme-text-text-primary-on-dark {
@apply text-variant-primary-on-dark;
}
.theme-text-text-secondary-on-dark {
@apply text-variant-secondary-on-dark;
}
.theme-text-text-sub-secondary-on-dark {
@apply text-variant-sub-secondary-on-dark;
}
.theme-text-text-hint-on-dark {
@apply text-variant-hint-on-dark;
}
.theme-text-text-disabled-on-dark {
@apply text-variant-disabled-on-dark;
}
.theme-text-text-icon-on-dark {
@apply text-variant-icon-on-dark;
}
.theme-text-text-negative-on-dark {
@apply text-variant-negative-on-dark;
}
}
@@ -0,0 +1,46 @@
@utility elevation-small {
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);
}
@utility elevation-medium {
box-shadow:
0px 3px 5px -1px rgba(0, 0, 0, 0.2),
0px 5px 8px 0px rgba(0, 0, 0, 0.14),
0px 1px 14px 0px rgba(0, 0, 0, 0.12);
}
@utility elevation-large {
box-shadow:
0px 3px 5px -1px rgba(0, 0, 0, 0.2),
0px 6px 10px 0px rgba(0, 0, 0, 0.14),
0px 1px 18px 0px rgba(0, 0, 0, 0.12);
}
@utility elevation-xlarge {
box-shadow:
0px 6px 6px -3px rgba(0, 0, 0, 0.2),
0px 10px 14px 1px rgba(0, 0, 0, 0.14),
0px 4px 18px 3px rgba(0, 0, 0, 0.12);
}
/* Component layer classes for backwards compatibility. TODO: Remove it once all components are migrated to the new utility classes */
@layer components {
.theme-elevation-small {
@apply elevation-small;
}
.theme-elevation-medium {
@apply elevation-medium;
}
.theme-elevation-large {
@apply elevation-large;
}
.theme-elevation-xlarge {
@apply elevation-xlarge;
}
}
@@ -0,0 +1,5 @@
@import './border-radius.css';
@import './color.css';
@import './elevation.css';
@import './ripple.css';
@import './typography.css';
@@ -1,50 +1,51 @@
/**
* Ripple Effect Utilities
*
* Provides hover/focus/active feedback using a pseudo-element overlay.
* Uses currentColor so it adapts to the parent's text color.
*/
@utility ripple {
position: relative;
&::before {
position: absolute;
content: '';
opacity: 0;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
background-color: currentColor;
border-radius: inherit;
pointer-events: none;
transition: opacity 150ms linear;
}
&:hover::before {
opacity: 0.04;
}
&:focus::before {
opacity: 0.1;
}
&:active::before {
opacity: 0.1;
}
&[aria-expanded='true']::before {
opacity: 0.14;
}
}
@utility ripple-selectable {
&[aria-selected='true']::before {
opacity: 0.14;
}
}
/* Component layer classes for backwards compatibility. TODO: Remove it once all components are migrated to the new utility classes */
@layer components {
/* Base ripple effect */
.theme-ripple {
position: relative;
&::before {
position: absolute;
content: '';
opacity: 0;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
background-color: currentColor;
border-radius: inherit;
pointer-events: none;
transition: opacity 150ms linear;
}
&:hover::before {
opacity: 0.04;
}
&:focus::before {
opacity: 0.1;
}
&:active::before {
opacity: 0.1;
}
&[aria-expanded='true']::before {
opacity: 0.14;
}
@apply ripple;
}
.theme-ripple-selectable {
&[aria-selected='true']::before {
opacity: 0.14;
}
@apply ripple-selectable;
}
}
@@ -1,70 +1,118 @@
/**
* Typography Utilities
*
* Migrated from @material/typography
* Material Design typography system: https://material.io/design/typography/
*
* Provides typography classes based on Material Design Type Scale.
* All values are pixel-perfect copies from Material Design Components v4.
*/
@utility font-theme {
font-family: var(--theme-font-family);
}
@utility font-theme-mono {
font-family: var(--theme-font-family-mono);
}
@utility text-headline6 {
font-size: var(--theme-typography-headline6-font-size);
}
@utility leading-headline6 {
line-height: var(--theme-typography-headline6-line-height);
}
@utility font-headline6 {
font-weight: var(--theme-typography-headline6-font-weight);
}
@utility tracking-headline6 {
letter-spacing: var(--theme-typography-headline6-letter-spacing);
}
@utility text-body1 {
font-size: var(--theme-typography-body1-font-size);
}
@utility leading-body1 {
line-height: var(--theme-typography-body1-line-height);
}
@utility font-body1 {
font-weight: var(--theme-typography-body1-font-weight);
}
@utility tracking-body1 {
letter-spacing: var(--theme-typography-body1-letter-spacing);
}
@utility text-body2 {
font-size: var(--theme-typography-body2-font-size);
}
@utility leading-body2 {
line-height: var(--theme-typography-body2-line-height);
}
@utility font-body2 {
font-weight: var(--theme-typography-body2-font-weight);
}
@utility tracking-body2 {
letter-spacing: var(--theme-typography-body2-letter-spacing);
}
@utility text-caption {
font-size: var(--theme-typography-caption-font-size);
}
@utility leading-caption {
line-height: var(--theme-typography-caption-line-height);
}
@utility font-caption {
font-weight: var(--theme-typography-caption-font-weight);
}
@utility tracking-caption {
letter-spacing: var(--theme-typography-caption-letter-spacing);
}
@utility decoration-inherit {
text-decoration: inherit;
}
@utility transform-inherit {
text-transform: inherit;
}
@utility typography-headline6 {
@apply text-headline6 leading-headline6 font-headline6 tracking-headline6;
}
@utility typography-body1 {
@apply text-body1 leading-body1 font-body1 tracking-body1;
}
@utility typography-body2 {
@apply text-body2 leading-body2 font-body2 tracking-body2 decoration-inherit transform-inherit;
}
@utility typography-caption {
@apply text-caption leading-caption font-caption tracking-caption decoration-inherit transform-inherit;
}
/* Component layer classes for backwards compatibility. TODO: Remove it once all components are migrated to the new utility classes */
@layer components {
/* Base typography */
.theme-typography {
font-family: var(--theme-font-family);
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
@apply font-theme antialiased;
}
/* Headline 6 - 1.25rem (20px) */
.theme-typography--headline6 {
font-family: var(--theme-font-family);
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
font-size: var(--theme-typography-headline6-font-size);
line-height: var(--theme-typography-headline6-line-height);
font-weight: var(--theme-typography-headline6-font-weight);
letter-spacing: var(--theme-typography-headline6-letter-spacing);
text-decoration: inherit;
text-transform: inherit;
@apply typography-headline6;
}
/* Body 1 - 1rem (16px) */
.theme-typography--body1 {
font-family: var(--theme-font-family);
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
font-size: var(--theme-typography-body1-font-size);
line-height: var(--theme-typography-body1-line-height);
font-weight: var(--theme-typography-body1-font-weight);
letter-spacing: var(--theme-typography-body1-letter-spacing);
text-decoration: inherit;
text-transform: inherit;
@apply typography-body1;
}
/* Body 2 - 0.875rem (14px) */
.theme-typography--body2 {
font-family: var(--theme-font-family);
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
font-size: var(--theme-typography-body2-font-size);
line-height: var(--theme-typography-body2-line-height);
font-weight: var(--theme-typography-body2-font-weight);
letter-spacing: var(--theme-typography-body2-letter-spacing);
text-decoration: inherit;
text-transform: inherit;
@apply typography-body2;
}
/* Caption - 0.75rem (12px) */
.theme-typography--caption {
font-family: var(--theme-font-family);
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
font-size: var(--theme-typography-caption-font-size);
line-height: var(--theme-typography-caption-line-height);
font-weight: var(--theme-typography-caption-font-weight);
letter-spacing: var(--theme-typography-caption-letter-spacing);
text-decoration: inherit;
text-transform: inherit;
@apply typography-caption;
}
}