Grafana-UI: Refactor Checkbox to fix alignment issues (#36164)

* Grafana-UI: Fix Checkbox vertical layout issues

* reorganise css

* WIP for fixing checkboxes in manage dashboards

* Cleanup checkbox and fix issue in Dashboard manage page

* update tests
This commit is contained in:
Josh Hunt
2021-07-08 13:09:58 +01:00
committed by GitHub
parent f45d0a0b7a
commit 4c0acf335b
6 changed files with 105 additions and 89 deletions

View File

@@ -1,34 +1,19 @@
import React, { FC, memo } from 'react';
import { css } from '@emotion/css';
import { Checkbox, stylesFactory } from '@grafana/ui';
import { Checkbox } from '@grafana/ui';
interface Props {
checked?: boolean;
onClick: any;
onClick?: React.MouseEventHandler<HTMLInputElement>;
className?: string;
editable?: boolean;
}
export const SearchCheckbox: FC<Props> = memo(({ onClick, checked = false, editable = false }) => {
const styles = getStyles();
export const SearchCheckbox: FC<Props> = memo(({ onClick, className, checked = false, editable = false }) => {
return editable ? (
<div onClick={onClick} className={styles.wrapper}>
<div onClick={onClick} className={className}>
<Checkbox value={checked} />
</div>
) : null;
});
const getStyles = stylesFactory(() => ({
wrapper: css`
height: 21px;
& > label {
height: 100%;
& > input {
position: relative;
}
}
`,
}));
SearchCheckbox.displayName = 'SearchCheckbox';

View File

@@ -39,7 +39,7 @@ describe('SearchItem', () => {
expect(screen.getAllByText('Test 1')).toHaveLength(1);
});
it('should mark item as checked', () => {
it('should toggle items when checked', () => {
const mockedOnToggleChecked = jest.fn();
setup({ editable: true, onToggleChecked: mockedOnToggleChecked });
const checkbox = screen.getByRole('checkbox');
@@ -47,6 +47,10 @@ describe('SearchItem', () => {
fireEvent.click(checkbox);
expect(mockedOnToggleChecked).toHaveBeenCalledTimes(1);
expect(mockedOnToggleChecked).toHaveBeenCalledWith(data);
});
it('should mark items as checked', () => {
setup({ editable: true, item: { ...data, checked: true } });
expect(screen.getByRole('checkbox')).toBeChecked();
});

View File

@@ -34,9 +34,11 @@ export const SearchItem: FC<Props> = ({ item, editable, onToggleChecked, onTagSe
[onTagSelected]
);
const toggleItem = useCallback(
(event: React.MouseEvent) => {
event.preventDefault();
const handleCheckboxClick = useCallback(
(ev: React.MouseEvent) => {
ev.stopPropagation();
ev.preventDefault();
if (onToggleChecked) {
onToggleChecked(item);
}
@@ -54,7 +56,7 @@ export const SearchItem: FC<Props> = ({ item, editable, onToggleChecked, onTagSe
className={styles.container}
>
<Card.Figure align={'center'} className={styles.checkbox}>
<SearchCheckbox editable={editable} checked={item.checked} onClick={toggleItem} />
<SearchCheckbox editable={editable} checked={item.checked} onClick={handleCheckboxClick} />
</Card.Figure>
<Card.Meta separator={''}>
<span className={styles.metaContainer}>

View File

@@ -29,10 +29,12 @@ export const SectionHeader: FC<SectionHeaderProps> = ({
onSectionClick(section);
};
const onSectionChecked = useCallback(
(e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
const handleCheckboxClick = useCallback(
(ev: React.MouseEvent) => {
console.log('section header handleCheckboxClick');
ev.stopPropagation();
ev.preventDefault();
if (onToggleChecked) {
onToggleChecked(section);
}
@@ -46,7 +48,12 @@ export const SectionHeader: FC<SectionHeaderProps> = ({
onClick={onSectionExpand}
aria-label={section.expanded ? `Collapse folder ${section.id}` : `Expand folder ${section.id}`}
>
<SearchCheckbox editable={editable} checked={section.checked} onClick={onSectionChecked} />
<SearchCheckbox
className={styles.checkbox}
editable={editable}
checked={section.checked}
onClick={handleCheckboxClick}
/>
<div className={styles.icon}>
<Icon name={getSectionIcon(section)} />
@@ -90,6 +97,9 @@ const getSectionHeaderStyles = stylesFactory((theme: GrafanaTheme, selected = fa
'pointer',
{ selected }
),
checkbox: css`
padding: 0 ${sm} 0 0;
`,
icon: css`
padding: 0 ${sm} 0 ${editable ? 0 : sm};
`,