mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Search: use Card component (#29892)
* Search: Use Card component for search items * Search: Set min height of search item * Search: Adjust item height * Search: Move tags to the right * Search: Center item content * Search: Align tags * Search: Adjust Card spacing * Search: Adjust dimensions
This commit is contained in:
@@ -19,12 +19,14 @@ export const SearchCheckbox: FC<Props> = memo(({ onClick, checked = false, edita
|
||||
});
|
||||
|
||||
const getStyles = stylesFactory(() => ({
|
||||
// Vertically align absolutely positioned checkbox element
|
||||
wrapper: css`
|
||||
height: 21px;
|
||||
margin-right: 12px;
|
||||
& > label {
|
||||
height: 100%;
|
||||
|
||||
& > input {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
`,
|
||||
}));
|
||||
|
||||
@@ -1,26 +1,23 @@
|
||||
import React, { FC, useCallback, CSSProperties } from 'react';
|
||||
import { css, cx } from 'emotion';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import React, { FC, useCallback } from 'react';
|
||||
import { css } from 'emotion';
|
||||
import { selectors as e2eSelectors } from '@grafana/e2e-selectors';
|
||||
import { useTheme, TagList, styleMixins, stylesFactory } from '@grafana/ui';
|
||||
import { TagList, Card, useStyles } from '@grafana/ui';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { DashboardSectionItem, OnToggleChecked } from '../types';
|
||||
import { SearchCheckbox } from './SearchCheckbox';
|
||||
import { SEARCH_ITEM_HEIGHT, SEARCH_ITEM_MARGIN } from '../constants';
|
||||
import { SEARCH_ITEM_HEIGHT } from '../constants';
|
||||
|
||||
export interface Props {
|
||||
item: DashboardSectionItem;
|
||||
editable?: boolean;
|
||||
onTagSelected: (name: string) => any;
|
||||
onToggleChecked?: OnToggleChecked;
|
||||
style?: CSSProperties;
|
||||
}
|
||||
|
||||
const selectors = e2eSelectors.pages.Dashboards;
|
||||
|
||||
export const SearchItem: FC<Props> = ({ item, editable, onToggleChecked, onTagSelected, style }) => {
|
||||
const theme = useTheme();
|
||||
const styles = getResultsItemStyles(theme);
|
||||
|
||||
export const SearchItem: FC<Props> = ({ item, editable, onToggleChecked, onTagSelected }) => {
|
||||
const styles = useStyles(getStyles);
|
||||
const tagSelected = useCallback((tag: string, event: React.MouseEvent<HTMLElement>) => {
|
||||
onTagSelected(tag);
|
||||
}, []);
|
||||
@@ -36,71 +33,28 @@ export const SearchItem: FC<Props> = ({ item, editable, onToggleChecked, onTagSe
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={style}
|
||||
<Card
|
||||
aria-label={selectors.dashboards(item.title)}
|
||||
className={cx(styles.wrapper, { [styles.selected]: item.selected })}
|
||||
heading={item.title}
|
||||
href={item.url}
|
||||
style={{ minHeight: SEARCH_ITEM_HEIGHT }}
|
||||
className={styles.container}
|
||||
>
|
||||
<SearchCheckbox editable={editable} checked={item.checked} onClick={toggleItem} />
|
||||
|
||||
<a href={item.url} className={styles.link}>
|
||||
<div className={styles.body}>
|
||||
<span>{item.title}</span>
|
||||
<span className={styles.folderTitle}>{item.folderTitle}</span>
|
||||
</div>
|
||||
</a>
|
||||
<TagList tags={item.tags} onClick={tagSelected} className={styles.tags} />
|
||||
</div>
|
||||
<Card.Figure align={'center'}>
|
||||
<SearchCheckbox editable={editable} checked={item.checked} onClick={toggleItem} />
|
||||
</Card.Figure>
|
||||
{item.folderTitle && <Card.Meta>{item.folderTitle}</Card.Meta>}
|
||||
<Card.Tags>
|
||||
<TagList tags={item.tags} onClick={tagSelected} />
|
||||
</Card.Tags>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
const getResultsItemStyles = stylesFactory((theme: GrafanaTheme) => ({
|
||||
wrapper: css`
|
||||
${styleMixins.listItem(theme)};
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: ${SEARCH_ITEM_HEIGHT}px;
|
||||
margin-bottom: ${SEARCH_ITEM_MARGIN}px;
|
||||
padding: 0 ${theme.spacing.md};
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: ${SEARCH_ITEM_MARGIN * 2}px;
|
||||
}
|
||||
|
||||
:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
`,
|
||||
selected: css`
|
||||
${styleMixins.listItemSelected(theme)};
|
||||
`,
|
||||
body: css`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
flex: 1 1 auto;
|
||||
overflow: hidden;
|
||||
`,
|
||||
folderTitle: css`
|
||||
color: ${theme.colors.textWeak};
|
||||
font-size: ${theme.typography.size.sm};
|
||||
line-height: ${theme.typography.lineHeight.sm};
|
||||
`,
|
||||
icon: css`
|
||||
margin-left: 10px;
|
||||
`,
|
||||
tags: css`
|
||||
flex-grow: 0;
|
||||
justify-content: flex-end;
|
||||
@media only screen and (max-width: ${theme.breakpoints.md}) {
|
||||
display: none;
|
||||
}
|
||||
`,
|
||||
link: css`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
flex-grow: 1;
|
||||
height: 100%;
|
||||
`,
|
||||
}));
|
||||
const getStyles = (theme: GrafanaTheme) => {
|
||||
return {
|
||||
container: css`
|
||||
padding: ${theme.spacing.sm} ${theme.spacing.md};
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export const NO_ID_SECTIONS = ['Recent', 'Starred'];
|
||||
// Height of the search result item
|
||||
export const SEARCH_ITEM_HEIGHT = 48;
|
||||
export const SEARCH_ITEM_MARGIN = 4;
|
||||
export const SEARCH_ITEM_HEIGHT = 62;
|
||||
export const SEARCH_ITEM_MARGIN = 8;
|
||||
export const DEFAULT_SORT = { label: 'A-Z', value: 'alpha-asc' };
|
||||
export const SECTION_STORAGE_KEY = 'search.sections';
|
||||
export const GENERAL_FOLDER_ID = 0;
|
||||
|
||||
Reference in New Issue
Block a user