mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Drawer: align component style with PanelInspector (#23694)
* Drawer: add subtitle, expandable button and refactor style * Drawer: update header style and z-index * Drawer: refactor Drawer component and PanelInspector * PanelInspector: add expandable * Drawer: update stories with new props * Inspector: rename InspectHeader -> InspectSubtitle * Inspector: fix tabs spacing * Drawer: remove z-index * Update public/app/features/dashboard/components/Inspector/InspectSubtitle.tsx Co-Authored-By: Dominik Prokop <dominik.prokop@grafana.com> * Drawer: apply PR feedbacks Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
This commit is contained in:
@@ -33,6 +33,7 @@ export const global = () => {
|
||||
{state.isOpen && (
|
||||
<Drawer
|
||||
title={drawerTitle}
|
||||
subtitle="This is a subtitle."
|
||||
onClose={() => {
|
||||
updateValue({ isOpen: !state.isOpen });
|
||||
}}
|
||||
@@ -70,6 +71,7 @@ export const longContent = () => {
|
||||
{state.isOpen && (
|
||||
<Drawer
|
||||
scrollableContent
|
||||
expandable
|
||||
title="Drawer with long content"
|
||||
onClose={() => {
|
||||
updateValue({ isOpen: !state.isOpen });
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
import React, { CSSProperties, FC, ReactNode } from 'react';
|
||||
import React, { CSSProperties, FC, ReactNode, useState } from 'react';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import RcDrawer from 'rc-drawer';
|
||||
import { css } from 'emotion';
|
||||
import CustomScrollbar from '../CustomScrollbar/CustomScrollbar';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
import { IconButton } from '../IconButton/IconButton';
|
||||
import { stylesFactory, useTheme } from '../../themes';
|
||||
|
||||
export interface Props {
|
||||
children: ReactNode;
|
||||
/** Title shown at the top of the drawer */
|
||||
title?: JSX.Element | string;
|
||||
title?: ReactNode;
|
||||
/** Subtitle shown below the title */
|
||||
subtitle?: ReactNode;
|
||||
/** Should the Drawer be closable by clicking on the mask */
|
||||
closeOnMaskClick?: boolean;
|
||||
/** Render the drawer inside a container on the page */
|
||||
inline?: boolean;
|
||||
/** Either a number in px or a string with unit postfix */
|
||||
width?: number | string;
|
||||
/** Should the Drawer be expandable to full width */
|
||||
expandable?: boolean;
|
||||
|
||||
/** Set to true if the component rendered within in drawer content has its own scroll */
|
||||
scrollableContent?: boolean;
|
||||
@@ -24,9 +28,6 @@ export interface Props {
|
||||
}
|
||||
|
||||
const getStyles = stylesFactory((theme: GrafanaTheme, scollableContent: boolean) => {
|
||||
const closeButtonWidth = '50px';
|
||||
const borderColor = theme.colors.border2;
|
||||
|
||||
return {
|
||||
drawer: css`
|
||||
.drawer-content {
|
||||
@@ -36,25 +37,23 @@ const getStyles = stylesFactory((theme: GrafanaTheme, scollableContent: boolean)
|
||||
overflow: hidden;
|
||||
}
|
||||
`,
|
||||
titleWrapper: css`
|
||||
font-size: ${theme.typography.size.lg};
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid ${borderColor};
|
||||
padding: ${theme.spacing.sm} 0 ${theme.spacing.sm} ${theme.spacing.md};
|
||||
background-color: ${theme.colors.bodyBg};
|
||||
top: 0;
|
||||
header: css`
|
||||
background-color: ${theme.colors.bg2};
|
||||
z-index: 1;
|
||||
flex-grow: 0;
|
||||
padding-top: ${theme.spacing.xs};
|
||||
`,
|
||||
close: css`
|
||||
cursor: pointer;
|
||||
width: ${closeButtonWidth};
|
||||
height: 100%;
|
||||
actions: css`
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
justify-content: center;
|
||||
align-items: baseline;
|
||||
justify-content: flex-end;
|
||||
`,
|
||||
titleWrapper: css`
|
||||
margin-bottom: ${theme.spacing.lg};
|
||||
padding: 0 ${theme.spacing.sm} 0 ${theme.spacing.lg};
|
||||
`,
|
||||
titleSpacing: css`
|
||||
margin-bottom: ${theme.spacing.md};
|
||||
`,
|
||||
content: css`
|
||||
padding: ${theme.spacing.md};
|
||||
@@ -72,10 +71,14 @@ export const Drawer: FC<Props> = ({
|
||||
closeOnMaskClick = false,
|
||||
scrollableContent = false,
|
||||
title,
|
||||
subtitle,
|
||||
width = '40%',
|
||||
expandable = false,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const drawerStyles = getStyles(theme, scrollableContent);
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
const currentWidth = isExpanded ? '100%' : width;
|
||||
|
||||
return (
|
||||
<RcDrawer
|
||||
@@ -85,16 +88,26 @@ export const Drawer: FC<Props> = ({
|
||||
onClose={onClose}
|
||||
maskClosable={closeOnMaskClick}
|
||||
placement="right"
|
||||
width={width}
|
||||
width={currentWidth}
|
||||
getContainer={inline ? false : 'body'}
|
||||
style={{ position: `${inline && 'absolute'}` } as CSSProperties}
|
||||
className={drawerStyles.drawer}
|
||||
>
|
||||
{typeof title === 'string' && (
|
||||
<div className={drawerStyles.titleWrapper}>
|
||||
<div>{title}</div>
|
||||
<div className={drawerStyles.close} onClick={onClose}>
|
||||
<Icon name="times" />
|
||||
<div className={drawerStyles.header}>
|
||||
<div className={drawerStyles.actions}>
|
||||
{expandable && !isExpanded && (
|
||||
<IconButton name="angle-left" size="xl" onClick={() => setIsExpanded(true)} surface="header" />
|
||||
)}
|
||||
{expandable && isExpanded && (
|
||||
<IconButton name="angle-right" size="xl" onClick={() => setIsExpanded(false)} surface="header" />
|
||||
)}
|
||||
<IconButton name="times" size="xl" onClick={onClose} surface="header" />
|
||||
</div>
|
||||
<div className={drawerStyles.titleWrapper}>
|
||||
<h3>{title}</h3>
|
||||
{typeof subtitle === 'string' && <div className="muted">{subtitle}</div>}
|
||||
{typeof subtitle !== 'string' && subtitle}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user