mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
CB-3178: fix navigation tree tools styles (#1959)
* CB-3178: fix navigation tree tools styles * CB-3178: refactoring css-modules --------- Co-authored-by: Daria Marutkina <125263541+dariamarutkina@users.noreply.github.com>
This commit is contained in:
co-authored by
Daria Marutkina
parent
7a3b17081c
commit
534b02d5ee
@@ -0,0 +1,17 @@
|
||||
.iconButton {
|
||||
color: inherit;
|
||||
outline: none;
|
||||
border: none;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
margin: 4px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
|
||||
& .icon,
|
||||
& .staticImage {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
@@ -6,33 +6,16 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { Button, ButtonProps } from 'reakit/Button';
|
||||
import styled, { css } from 'reshadow';
|
||||
import styled from 'reshadow';
|
||||
|
||||
import type { ComponentStyle } from '@cloudbeaver/core-theming';
|
||||
|
||||
import { Icon } from './Icon';
|
||||
import { s } from './s';
|
||||
import { StaticImage } from './StaticImage';
|
||||
import { useS } from './useS';
|
||||
import { useStyles } from './useStyles';
|
||||
|
||||
const styles = css`
|
||||
Button {
|
||||
color: inherit;
|
||||
outline: none;
|
||||
border: none;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
margin: 4px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
|
||||
& Icon,
|
||||
& StaticImage {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
`;
|
||||
import IconButtonStyles from './IconButton.m.css';
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
@@ -41,11 +24,13 @@ interface Props {
|
||||
style?: ComponentStyle;
|
||||
}
|
||||
|
||||
export function IconButton({ name, img, viewBox, style, ...rest }: Props & ButtonProps) {
|
||||
return styled(useStyles(styles, style))(
|
||||
<Button {...rest}>
|
||||
{img && <StaticImage icon={name} />}
|
||||
{!img && <Icon name={name} viewBox={viewBox} />}
|
||||
export function IconButton({ name, img, viewBox, style, className, ...rest }: Props & ButtonProps) {
|
||||
const styles = useS(IconButtonStyles);
|
||||
|
||||
return styled(useStyles(style))(
|
||||
<Button {...rest} className={s(styles, { iconButton: true }, className)}>
|
||||
{img && <StaticImage className={s(styles, { staticImage: true })} icon={name} />}
|
||||
{!img && <Icon className={s(styles, { icon: true })} name={name} viewBox={viewBox} />}
|
||||
</Button>,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -163,6 +163,7 @@ export * from './StatusMessage';
|
||||
export * from './ExceptionMessage';
|
||||
export * from './getComputed';
|
||||
export * from './IconButton';
|
||||
export { default as IconButtonStyles } from './IconButton.m.css';
|
||||
export * from './IconOrImage';
|
||||
export * from './s';
|
||||
export * from './SContext';
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
.primary {
|
||||
composes: theme-text-primary from global;
|
||||
}
|
||||
|
||||
.tools {
|
||||
composes: theme-background-surface from global;
|
||||
display: block;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.fill {
|
||||
flex: 1;
|
||||
}
|
||||
+52
-72
@@ -7,63 +7,42 @@
|
||||
*/
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import React, { useState } from 'react';
|
||||
import styled, { css, use } from 'reshadow';
|
||||
import styled from 'reshadow';
|
||||
|
||||
import { ACTION_ICON_BUTTON_STYLES, IconButton, PlaceholderElement, useResource, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
|
||||
import {
|
||||
ACTION_ICON_BUTTON_STYLES,
|
||||
IconButton,
|
||||
IconButtonStyles,
|
||||
PlaceholderElement,
|
||||
s,
|
||||
SContext,
|
||||
StyleRegistry,
|
||||
useS,
|
||||
useStyles,
|
||||
useTranslate,
|
||||
} from '@cloudbeaver/core-blocks';
|
||||
import type { ComponentStyle } from '@cloudbeaver/core-theming';
|
||||
import { useCaptureViewContext } from '@cloudbeaver/core-view';
|
||||
|
||||
import { DATA_CONTEXT_ELEMENTS_TREE } from '../DATA_CONTEXT_ELEMENTS_TREE';
|
||||
import type { IElementsTree } from '../useElementsTree';
|
||||
import { ElementsTreeFilter } from './ElementsTreeFilter';
|
||||
import ElementsTreeToolsStyles from './ElementsTreeTools.m.css';
|
||||
import ElementsTreeToolsIconButtonStyles from './ElementsTreeToolsIconButton.m.css';
|
||||
import { ElementsTreeToolsMenu } from './ElementsTreeToolsMenu';
|
||||
import { DATA_CONTEXT_NAV_TREE_ROOT } from './NavigationTreeSettings/DATA_CONTEXT_NAV_TREE_ROOT';
|
||||
import type { IElementsTreeSettingsProps } from './NavigationTreeSettings/ElementsTreeSettingsService';
|
||||
import { NavigationTreeSettings } from './NavigationTreeSettings/NavigationTreeSettings';
|
||||
|
||||
const toolsStyles = css`
|
||||
[|primary] {
|
||||
composes: theme-text-primary from global;
|
||||
}
|
||||
tools {
|
||||
composes: theme-background-surface from global;
|
||||
display: block;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
actions {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
fill {
|
||||
flex: 1;
|
||||
}
|
||||
IconButton {
|
||||
& Icon,
|
||||
& StaticImage {
|
||||
transition: transform 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
&[|opened] Icon,
|
||||
&[|opened] StaticImage {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
&[|loading] Icon,
|
||||
&[|loading] StaticImage {
|
||||
animation: rotating 1.5s linear infinite;
|
||||
}
|
||||
}
|
||||
@keyframes rotating {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
`;
|
||||
const registry: StyleRegistry = [
|
||||
[
|
||||
IconButtonStyles,
|
||||
{
|
||||
mode: 'append',
|
||||
styles: [ElementsTreeToolsIconButtonStyles],
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
interface Props {
|
||||
tree: IElementsTree;
|
||||
@@ -75,7 +54,8 @@ export const ElementsTreeTools = observer<React.PropsWithChildren<Props>>(functi
|
||||
const root = tree.root;
|
||||
const translate = useTranslate();
|
||||
const [opened, setOpen] = useState(false);
|
||||
const styles = useStyles(ACTION_ICON_BUTTON_STYLES, toolsStyles, style);
|
||||
const deprecatedStyles = useStyles(ACTION_ICON_BUTTON_STYLES, style);
|
||||
const styles = useS(ElementsTreeToolsStyles, ElementsTreeToolsIconButtonStyles);
|
||||
|
||||
useCaptureViewContext(context => {
|
||||
context?.set(DATA_CONTEXT_NAV_TREE_ROOT, tree.baseRoot);
|
||||
@@ -84,34 +64,34 @@ export const ElementsTreeTools = observer<React.PropsWithChildren<Props>>(functi
|
||||
|
||||
const loading = tree.isLoading();
|
||||
|
||||
return styled(styles)(
|
||||
<tools>
|
||||
<actions>
|
||||
{tree.settings?.configurable && (
|
||||
return styled(deprecatedStyles)(
|
||||
<SContext registry={registry}>
|
||||
<tools className={s(styles, { tools: true })}>
|
||||
<actions className={s(styles, { actions: true })}>
|
||||
{tree.settings?.configurable && (
|
||||
<IconButton
|
||||
name="/icons/settings_cog_sm.svg"
|
||||
title={translate('ui_settings')}
|
||||
className={s(styles, { primary: true, opened })}
|
||||
img
|
||||
onClick={() => setOpen(!opened)}
|
||||
/>
|
||||
)}
|
||||
<div className={s(styles, { fill: true })} />
|
||||
<ElementsTreeToolsMenu tree={tree} />
|
||||
<IconButton
|
||||
name="/icons/settings_cog_sm.svg"
|
||||
title={translate('ui_settings')}
|
||||
style={toolsStyles}
|
||||
name="/icons/refresh_sm.svg#root"
|
||||
title={translate('app_navigationTree_refresh')}
|
||||
disabled={loading}
|
||||
className={s(styles, { primary: true, loading })}
|
||||
img
|
||||
onClick={() => setOpen(!opened)}
|
||||
{...use({ opened, primary: true })}
|
||||
onClick={() => tree.refresh(root)}
|
||||
/>
|
||||
)}
|
||||
<fill />
|
||||
<ElementsTreeToolsMenu tree={tree} />
|
||||
<IconButton
|
||||
name="/icons/refresh_sm.svg#root"
|
||||
title={translate('app_navigationTree_refresh')}
|
||||
style={toolsStyles}
|
||||
disabled={loading}
|
||||
img
|
||||
onClick={() => tree.refresh(root)}
|
||||
{...use({ primary: true, loading })}
|
||||
/>
|
||||
</actions>
|
||||
{tree.settings && opened && <NavigationTreeSettings tree={tree} elements={settingsElements} style={style} />}
|
||||
<ElementsTreeFilter tree={tree} style={style} />
|
||||
{children}
|
||||
</tools>,
|
||||
</actions>
|
||||
{tree.settings && opened && <NavigationTreeSettings tree={tree} elements={settingsElements} style={style} />}
|
||||
<ElementsTreeFilter tree={tree} style={style} />
|
||||
{children}
|
||||
</tools>
|
||||
</SContext>,
|
||||
);
|
||||
});
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
.iconButton {
|
||||
& .icon,
|
||||
& .staticImage {
|
||||
transition: transform 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
&.loading {
|
||||
& .icon,
|
||||
& .staticImage {
|
||||
animation: rotating 1.5s linear infinite;
|
||||
}
|
||||
}
|
||||
|
||||
&.opened {
|
||||
& .icon,
|
||||
& .staticImage {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotating {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
.settings {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.group {
|
||||
min-width: fit-content;
|
||||
margin-right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.settings > .groupPadding {
|
||||
padding: 12px;
|
||||
}
|
||||
+7
-22
@@ -6,27 +6,12 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import { Group, Loader, Placeholder, PlaceholderElement, useStyles } from '@cloudbeaver/core-blocks';
|
||||
import { Group, Loader, Placeholder, PlaceholderElement, s, useS } from '@cloudbeaver/core-blocks';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
|
||||
import { ElementsTreeSettingsService, IElementsTreeSettingsProps } from './ElementsTreeSettingsService';
|
||||
|
||||
const expandStyles = css`
|
||||
settings {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
Group {
|
||||
min-width: 350px;
|
||||
width: min-content;
|
||||
|
||||
&[dense] {
|
||||
padding: 12px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
import NavigationTreeSettingsStyles from './NavigationTreeSettings.m.css';
|
||||
|
||||
interface Props extends IElementsTreeSettingsProps {
|
||||
elements?: PlaceholderElement<IElementsTreeSettingsProps>[];
|
||||
@@ -34,16 +19,16 @@ interface Props extends IElementsTreeSettingsProps {
|
||||
}
|
||||
|
||||
export const NavigationTreeSettings = observer<Props>(function NavigationTreeSettings({ elements, tree, style, className }) {
|
||||
const styles = useStyles(expandStyles, style);
|
||||
const elementsTreeSettingsService = useService(ElementsTreeSettingsService);
|
||||
const styles = useS(NavigationTreeSettingsStyles);
|
||||
|
||||
return styled(styles)(
|
||||
<settings className={className}>
|
||||
<Group keepSize form gap dense>
|
||||
return (
|
||||
<div className={s(styles, { settings: true }, className)}>
|
||||
<Group className={s(styles, { group: true, groupPadding: true })} keepSize gap dense>
|
||||
<Loader suspense>
|
||||
<Placeholder container={elementsTreeSettingsService.placeholder} elements={elements} tree={tree} style={style} />
|
||||
</Loader>
|
||||
</Group>
|
||||
</settings>,
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -42,7 +42,7 @@ const navigationTreeStyles = css`
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
ElementsTree {
|
||||
|
||||
Reference in New Issue
Block a user