mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
grafana/ui: Add Icon component (#20353)
* Add Icon component * Add missing Icon types * Polish icon story * Update packages/grafana-ui/src/components/Icon/Icon.mdx
This commit is contained in:
parent
5b42bb58f6
commit
17fe704ae8
28
packages/grafana-ui/src/components/Icon/Icon.mdx
Normal file
28
packages/grafana-ui/src/components/Icon/Icon.mdx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { Meta, Story, Preview, Props } from '@storybook/addon-docs/blocks';
|
||||||
|
import { Icon } from './Icon';
|
||||||
|
|
||||||
|
<Meta title="MDX|Icon" component={Icon} />
|
||||||
|
|
||||||
|
# Icon
|
||||||
|
|
||||||
|
Grafana's wrapper component over [Font Awesome](https://fontawesome.com/) icons
|
||||||
|
|
||||||
|
|
||||||
|
### Changing icon size
|
||||||
|
|
||||||
|
By default `Icon` has width and height of `16px` and font-size of `14px`. Pass `className` to control icon's size:
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import { css } from 'emotion';
|
||||||
|
|
||||||
|
const customIconSize = css`
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
font-size: 18px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
<Icon name="check" className={customIconSize} />
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
<Props of={Icon} />
|
103
packages/grafana-ui/src/components/Icon/Icon.story.tsx
Normal file
103
packages/grafana-ui/src/components/Icon/Icon.story.tsx
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { css } from 'emotion';
|
||||||
|
|
||||||
|
import { Icon } from './Icon';
|
||||||
|
import { getAvailableIcons, IconType } from './types';
|
||||||
|
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
||||||
|
import { useTheme, selectThemeVariant } from '../../themes';
|
||||||
|
import mdx from './Icon.mdx';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'UI/Icon',
|
||||||
|
component: Icon,
|
||||||
|
decorators: [withCenteredStory],
|
||||||
|
parameters: {
|
||||||
|
docs: {
|
||||||
|
page: mdx,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const IconWrapper: React.FC<{ name: IconType }> = ({ name }) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
const borderColor = selectThemeVariant(
|
||||||
|
{
|
||||||
|
light: theme.colors.gray5,
|
||||||
|
dark: theme.colors.dark6,
|
||||||
|
},
|
||||||
|
theme.type
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={css`
|
||||||
|
width: 150px;
|
||||||
|
height: 60px;
|
||||||
|
display: table-cell;
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid ${borderColor};
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: ${borderColor};
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
name={name}
|
||||||
|
className={css`
|
||||||
|
font-size: 18px;
|
||||||
|
`}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className={css`
|
||||||
|
padding-top: 16px;
|
||||||
|
word-break: break-all;
|
||||||
|
font-family: ${theme.typography.fontFamily.monospace};
|
||||||
|
font-size: ${theme.typography.size.xs};
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
{name}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const simple = () => {
|
||||||
|
const icons = getAvailableIcons();
|
||||||
|
const iconsPerRow = 10;
|
||||||
|
const rows: IconType[][] = [[]];
|
||||||
|
let rowIdx = 0;
|
||||||
|
|
||||||
|
icons.forEach((i: IconType, idx: number) => {
|
||||||
|
if (idx % iconsPerRow === 0) {
|
||||||
|
rows.push([]);
|
||||||
|
rowIdx++;
|
||||||
|
}
|
||||||
|
rows[rowIdx].push(i);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={css`
|
||||||
|
display: table;
|
||||||
|
table-layout: fixed;
|
||||||
|
border-collapse: collapse;
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
{rows.map(r => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={css`
|
||||||
|
display: table-row;
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
{r.map((i, index) => {
|
||||||
|
return <IconWrapper name={i} />;
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
31
packages/grafana-ui/src/components/Icon/Icon.tsx
Normal file
31
packages/grafana-ui/src/components/Icon/Icon.tsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { cx, css } from 'emotion';
|
||||||
|
import { stylesFactory } from '../../themes';
|
||||||
|
import { IconType } from './types';
|
||||||
|
|
||||||
|
export interface IconProps {
|
||||||
|
name: IconType;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getIconStyles = stylesFactory(() => {
|
||||||
|
return {
|
||||||
|
icon: css`
|
||||||
|
display: inline-block;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
&:before {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
export const Icon: React.FC<IconProps> = ({ name, className }) => {
|
||||||
|
const styles = getIconStyles();
|
||||||
|
return <i className={cx(styles.icon, 'fa', `fa-${name}`, className)} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
Icon.displayName = 'Icon';
|
1304
packages/grafana-ui/src/components/Icon/types.ts
Normal file
1304
packages/grafana-ui/src/components/Icon/types.ts
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user