Files
Torkel Ödegaard 8f78b0e7bc Chore: Fix all Typescript strict null errors (#26204)
* Chore: Fix typescript strict null errors

* Added new limit

* Fixed ts issue

* fixed tests

* trying to fix type inference

* Fixing more ts errors

* Revert tsconfig option

* Fix

* Fixed code

* More fixes

* fix tests

* Updated snapshot

* Chore: More ts strict null fixes

* More fixes in some really messed up azure config components

* More fixes, current count: 441

* 419

* More fixes

* Fixed invalid initial state in explore

* Fixing tests

* Fixed tests

* Explore fix

* More fixes

* Progress

* Sub 300

* Now at 218

* Progress

* Update

* Progress

* Updated tests

* at 159

* fixed tests

* Progress

* YAy blow 100! at 94

* 10,9,8,7,6,5,4,3,2,1... lift off

* Fixed tests

* Fixed more type errors

Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2020-07-10 12:46:59 +02:00

119 lines
3.3 KiB
TypeScript

import React, { useState } from 'react';
import { HorizontalGroup, Icon, renderOrCallToRender, stylesFactory, useTheme } from '@grafana/ui';
import { GrafanaTheme } from '@grafana/data';
import { css } from 'emotion';
import { useUpdateEffect } from 'react-use';
interface QueryOperationRowProps {
title?: ((props: { isOpen: boolean }) => React.ReactNode) | React.ReactNode;
headerElement?: React.ReactNode;
actions?:
| ((props: { isOpen: boolean; openRow: () => void; closeRow: () => void }) => React.ReactNode)
| React.ReactNode;
onOpen?: () => void;
onClose?: () => void;
children: React.ReactNode;
isOpen?: boolean;
}
export const QueryOperationRow: React.FC<QueryOperationRowProps> = ({
children,
actions,
title,
headerElement,
onClose,
onOpen,
isOpen,
}: QueryOperationRowProps) => {
const [isContentVisible, setIsContentVisible] = useState(isOpen !== undefined ? isOpen : true);
const theme = useTheme();
const styles = getQueryOperationRowStyles(theme);
useUpdateEffect(() => {
if (isContentVisible) {
if (onOpen) {
onOpen();
}
} else {
if (onClose) {
onClose();
}
}
}, [isContentVisible]);
const titleElement = title && renderOrCallToRender(title, { isOpen: isContentVisible });
const actionsElement =
actions &&
renderOrCallToRender(actions, {
isOpen: isContentVisible,
openRow: () => {
setIsContentVisible(true);
},
closeRow: () => {
setIsContentVisible(false);
},
});
return (
<div className={styles.wrapper}>
<div className={styles.header}>
<HorizontalGroup justify="space-between">
<div
className={styles.titleWrapper}
onClick={() => {
setIsContentVisible(!isContentVisible);
}}
aria-label="Query operation row title"
>
<Icon name={isContentVisible ? 'angle-down' : 'angle-right'} className={styles.collapseIcon} />
{title && <span className={styles.title}>{titleElement}</span>}
{headerElement}
</div>
{actions && actionsElement}
</HorizontalGroup>
</div>
{isContentVisible && <div className={styles.content}>{children}</div>}
</div>
);
};
const getQueryOperationRowStyles = stylesFactory((theme: GrafanaTheme) => {
return {
wrapper: css`
margin-bottom: ${theme.spacing.md};
`,
header: css`
padding: ${theme.spacing.xs} ${theme.spacing.sm};
border-radius: ${theme.border.radius.sm};
background: ${theme.colors.bg2};
min-height: ${theme.spacing.formInputHeight}px;
line-height: ${theme.spacing.sm}px;
display: flex;
align-items: center;
justify-content: space-between;
`,
collapseIcon: css`
color: ${theme.colors.textWeak};
&:hover {
color: ${theme.colors.text};
}
`,
titleWrapper: css`
display: flex;
align-items: center;
cursor: pointer;
`,
title: css`
font-weight: ${theme.typography.weight.semibold};
color: ${theme.colors.textBlue};
margin-left: ${theme.spacing.sm};
`,
content: css`
margin-top: ${theme.spacing.inlineFormMargin};
margin-left: ${theme.spacing.lg};
`,
};
});
QueryOperationRow.displayName = 'QueryOperationRow';