CB-3863: migrate overlay to css-modules (#1976)

This commit is contained in:
Dmitriy Osipov
2023-09-13 15:07:42 +03:00
committed by GitHub
parent d8ade2a09c
commit 7ea8befbe4
17 changed files with 167 additions and 177 deletions
@@ -1,127 +0,0 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 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 { css } from 'reshadow';
export const OVERLAY_BASE_STYLES = css`
overlay {
composes: theme-text-on-primary from global;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.4);
&:not([|active]) {
display: none;
}
&[|fill] {
background-color: var(--theme-background-surface);
}
}
overlay {
margin: auto;
}
overlay,
box {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
overflow: auto;
}
box {
composes: theme-background-surface theme-text-on-surface theme-elevation-z6 from global;
border-radius: 0.25rem;
align-items: normal;
max-width: calc(100% - 48px);
max-height: calc(100% - 48px);
}
overlay[|fill] box {
box-shadow: none;
}
actions {
gap: 16px;
display: flex;
}
header,
message,
actions {
flex-shrink: 0;
padding: 24px;
}
message {
padding-right: 0px;
overflow: auto;
flex: 1;
&:not(:first-child) {
padding-top: 0px;
}
}
message-box {
padding-right: 24px;
}
header {
position: relative;
display: grid;
grid-template-columns: max-content 1fr;
flex: 0 0 auto;
box-sizing: border-box;
}
header-title,
sub-title {
max-width: 400px;
}
header-title {
display: flex;
align-items: center;
justify-content: space-between;
position: relative;
min-height: 24px;
overflow: auto;
}
icon-container {
display: flex;
align-items: center;
justify-content: center;
}
IconOrImage {
width: 24px;
height: 24px;
margin-right: 16px;
}
h3 {
margin: 0;
overflow: hidden;
text-overflow: ellipsis;
}
sub-title {
composes: theme-typography--caption from global;
grid-column: 2;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
`;
@@ -0,0 +1,39 @@
.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;
&.active {
display: flex;
}
&.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);
}
@@ -6,9 +6,10 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import styled, { use } from 'reshadow';
import { OVERLAY_BASE_STYLES } from './OVERLAY_BASE_STYLES';
import { s } from '../s';
import { useS } from '../useS';
import style from './Overlay.m.css';
interface Props {
active?: boolean;
@@ -17,13 +18,11 @@ interface Props {
}
export const Overlay = observer<React.PropsWithChildren<Props>>(function Overlay({ active, fill, className, children }) {
if (!active) {
return null;
}
const styles = useS(style);
return styled(OVERLAY_BASE_STYLES)(
<overlay className={className} {...use({ active, fill })}>
<box>{children}</box>
</overlay>,
return (
<div className={s(styles, { overlay: true, active, fill }, className)}>
<div className={s(styles, { box: true })}>{children}</div>
</div>
);
});
@@ -0,0 +1,6 @@
.actions {
gap: 16px;
display: flex;
flex-shrink: 0;
padding: 24px;
}
@@ -6,14 +6,17 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import { OVERLAY_BASE_STYLES } from './OVERLAY_BASE_STYLES';
import { s } from '../s';
import { useS } from '../useS';
import style from './OverlayActions.m.css';
interface Props {
className?: string;
}
export const OverlayActions = observer<React.PropsWithChildren<Props>>(function OverlayActions({ className, children }) {
return styled(OVERLAY_BASE_STYLES)(<actions className={className}>{children}</actions>);
const styles = useS(style);
return <div className={s(styles, { actions: true }, className)}>{children}</div>;
});
@@ -0,0 +1,9 @@
.header {
flex-shrink: 0;
padding: 24px;
position: relative;
display: grid;
grid-template-columns: max-content 1fr;
flex: 0 0 auto;
box-sizing: border-box;
}
@@ -5,14 +5,16 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import styled from 'reshadow';
import { OVERLAY_BASE_STYLES } from './OVERLAY_BASE_STYLES';
import { s } from '../s';
import { useS } from '../useS';
import style from './OverlayHeader.m.css';
interface Props {
className?: string;
}
export const OverlayHeader: React.FC<React.PropsWithChildren<Props>> = function OverlayHeader({ className, children }) {
return styled(OVERLAY_BASE_STYLES)(<header className={className}>{children}</header>);
const styles = useS(style);
return <div className={s(styles, { header: true }, className)}>{children}</div>;
};
@@ -0,0 +1,11 @@
.iconContainer {
display: flex;
align-items: center;
justify-content: center;
}
.iconOrImage {
width: 24px;
height: 24px;
margin-right: 16px;
}
@@ -5,10 +5,10 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import styled from 'reshadow';
import { IconOrImage } from '../IconOrImage';
import { OVERLAY_BASE_STYLES } from './OVERLAY_BASE_STYLES';
import { s } from '../s';
import { useS } from '../useS';
import style from './OverlayHeaderIcon.m.css';
interface Props {
icon?: string;
@@ -17,14 +17,16 @@ interface Props {
}
export const OverlayHeaderIcon: React.FC<React.PropsWithChildren<Props>> = function OverlayHeaderIcon({ icon, viewBox, className, children }) {
const styles = useS(style);
if (!icon && !children) {
return null;
}
return styled(OVERLAY_BASE_STYLES)(
<icon-container className={className}>
{icon && <IconOrImage icon={icon} viewBox={viewBox} />}
return (
<div className={s(styles, { iconContainer: true }, className)}>
{icon && <IconOrImage className={s(styles, { iconOrImage: true })} icon={icon} viewBox={viewBox} />}
{children}
</icon-container>,
</div>
);
};
@@ -0,0 +1,8 @@
.subTitle {
composes: theme-typography--caption from global;
grid-column: 2;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 400px;
}
@@ -5,14 +5,16 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import styled from 'reshadow';
import { OVERLAY_BASE_STYLES } from './OVERLAY_BASE_STYLES';
import { s } from '../s';
import { useS } from '../useS';
import style from './OverlayHeaderSubTitle.m.css';
interface Props {
className?: string;
}
export const OverlayHeaderSubTitle: React.FC<React.PropsWithChildren<Props>> = function OverlayHeaderSubTitle({ className, children }) {
return styled(OVERLAY_BASE_STYLES)(<sub-title className={className}>{children}</sub-title>);
const styles = useS(style);
return <div className={s(styles, { subTitle: true }, className)}>{children}</div>;
};
@@ -0,0 +1,17 @@
.headerTitle {
max-width: 400px;
display: flex;
align-items: center;
justify-content: space-between;
position: relative;
min-height: 24px;
overflow: auto;
margin: 0;
text-overflow: ellipsis;
}
.headerTitleContent {
margin: 0;
overflow: hidden;
text-overflow: ellipsis;
}
@@ -5,18 +5,20 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import styled from 'reshadow';
import { OVERLAY_BASE_STYLES } from './OVERLAY_BASE_STYLES';
import { s } from '../s';
import { useS } from '../useS';
import style from './OverlayHeaderTitle.m.css';
interface Props {
className?: string;
}
export const OverlayHeaderTitle: React.FC<React.PropsWithChildren<Props>> = function OverlayHeaderTitle({ className, children }) {
return styled(OVERLAY_BASE_STYLES)(
<header-title className={className}>
<h3>{children}</h3>
</header-title>,
const styles = useS(style);
return (
<div className={s(styles, { headerTitle: true }, className)}>
<h3 className={s(styles, { headerTitleContent: true })}>{children}</h3>
</div>
);
};
@@ -0,0 +1,14 @@
.message {
flex-shrink: 0;
padding: 24px 0px 24px 24px;
overflow: auto;
flex: 1;
&:not(:first-child) {
padding-top: 0px;
}
}
.messageBox {
padding-right: 24px;
}
@@ -6,18 +6,21 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import { OVERLAY_BASE_STYLES } from './OVERLAY_BASE_STYLES';
import { s } from '../s';
import { useS } from '../useS';
import style from './OverlayMessage.m.css';
interface Props {
className?: string;
}
export const OverlayMessage = observer<React.PropsWithChildren<Props>>(function OverlayMessage({ className, children }) {
return styled(OVERLAY_BASE_STYLES)(
<message className={className}>
<message-box>{children}</message-box>
</message>,
const styles = useS(style);
return (
<div className={s(styles, { message: true }, className)}>
<div className={s(styles, { messageBox: true })}>{children}</div>
</div>
);
});
@@ -0,0 +1,3 @@
.overlayActions {
justify-content: space-between;
}
@@ -7,7 +7,6 @@
*/
import { observer } from 'mobx-react-lite';
import { useEffect } from 'react';
import styled, { css } from 'reshadow';
import {
Button,
@@ -19,7 +18,9 @@ import {
OverlayHeaderSubTitle,
OverlayHeaderTitle,
OverlayMessage,
s,
useResource,
useS,
useTranslate,
} from '@cloudbeaver/core-blocks';
import {
@@ -35,19 +36,15 @@ import { NodeManagerUtils } from '@cloudbeaver/core-navigation-tree';
import type { ISqlEditorTabState } from './ISqlEditorTabState';
import { SqlDataSourceService } from './SqlDataSource/SqlDataSourceService';
import style from './SqlEditorOverlay.m.css';
import { SqlEditorService } from './SqlEditorService';
const viewerStyles = css`
OverlayActions {
justify-content: space-between;
}
`;
interface Props {
state: ISqlEditorTabState;
}
export const SqlEditorOverlay = observer<Props>(function SqlEditorOverlay({ state }) {
const styles = useS(style);
const translate = useTranslate();
const sqlEditorService = useService(SqlEditorService);
const sqlDataSourceService = useService(SqlDataSourceService);
@@ -96,7 +93,7 @@ export const SqlEditorOverlay = observer<Props>(function SqlEditorOverlay({ stat
}
}, [connected, initExecutionContext]);
return styled(viewerStyles)(
return (
<Overlay active={initExecutionContext && !connection.tryGetData?.connected}>
<OverlayHeader>
<OverlayHeaderIcon icon={driver.tryGetData?.icon} />
@@ -104,7 +101,7 @@ export const SqlEditorOverlay = observer<Props>(function SqlEditorOverlay({ stat
{dataContainer && <OverlayHeaderSubTitle>{dataContainer}</OverlayHeaderSubTitle>}
</OverlayHeader>
<OverlayMessage>{translate('sql_editor_restore_message')}</OverlayMessage>
<OverlayActions>
<OverlayActions className={s(styles, { overlayActions: true })}>
<Button type="button" mod={['outlined']} loader onClick={cancelConnection}>
{translate('ui_processing_cancel')}
</Button>
@@ -112,6 +109,6 @@ export const SqlEditorOverlay = observer<Props>(function SqlEditorOverlay({ stat
{translate('sql_editor_restore')}
</Button>
</OverlayActions>
</Overlay>,
</Overlay>
);
});