diff --git a/packages/grafana-data/src/text/string.ts b/packages/grafana-data/src/text/string.ts index 83754d51e01..79cf3ae05cd 100644 --- a/packages/grafana-data/src/text/string.ts +++ b/packages/grafana-data/src/text/string.ts @@ -1,3 +1,4 @@ +import { camelCase } from 'lodash'; const specialChars = ['(', '[', '{', '}', ']', ')', '|', '*', '+', '-', '.', '?', '<', '>', '#', '&', '^', '$']; export const escapeStringForRegex = (value: string) => { @@ -89,3 +90,8 @@ export function toFloatOrUndefined(value: string): number | undefined { const v = parseFloat(value); return isNaN(v) ? undefined : v; } + +export const toPascalCase = (string: string) => { + const str = camelCase(string); + return str.charAt(0).toUpperCase() + str.substring(1); +}; diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json index 02729e56986..09d687054ec 100644 --- a/packages/grafana-ui/package.json +++ b/packages/grafana-ui/package.json @@ -31,6 +31,7 @@ "@grafana/data": "7.0.0-pre.0", "@grafana/slate-react": "0.22.9-grafana", "@grafana/tsconfig": "^1.0.0-rc1", + "@iconscout/react-unicons": "^1.0.0", "@torkelo/react-select": "3.0.8", "@types/react-color": "3.0.1", "@types/react-select": "3.0.8", diff --git a/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.tsx b/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.tsx index 02fc50ac5dd..e6a166bc7b3 100644 --- a/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.tsx +++ b/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.tsx @@ -40,7 +40,7 @@ export const ButtonCascader: React.FC = props => { expandIcon={null} > ); diff --git a/packages/grafana-ui/src/components/Cascader/Cascader.tsx b/packages/grafana-ui/src/components/Cascader/Cascader.tsx index 31671b60785..2a27952dd49 100644 --- a/packages/grafana-ui/src/components/Cascader/Cascader.tsx +++ b/packages/grafana-ui/src/components/Cascader/Cascader.tsx @@ -212,7 +212,7 @@ export class Cascader extends React.PureComponent value={activeLabel} onKeyDown={this.onInputKeyDown} onChange={() => {}} - suffix={focusCascade ? : } + suffix={focusCascade ? : } /> diff --git a/packages/grafana-ui/src/components/Collapse/Collapse.tsx b/packages/grafana-ui/src/components/Collapse/Collapse.tsx index 0d47544878c..2a512e7631c 100644 --- a/packages/grafana-ui/src/components/Collapse/Collapse.tsx +++ b/packages/grafana-ui/src/components/Collapse/Collapse.tsx @@ -123,7 +123,7 @@ export const Collapse: FunctionComponent = ({ isOpen, label, loading, col
- +
{label}
diff --git a/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.story.tsx b/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.story.tsx index d40bd8a8092..68dff7b4853 100644 --- a/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.story.tsx +++ b/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.story.tsx @@ -11,7 +11,7 @@ const getKnobs = () => { body: text('Body', 'Are you sure you want to delete this user?'), confirm: text('Confirm', 'Delete'), visible: boolean('Visible', true), - icon: select('Icon', ['exclamation-triangle', 'power-off', 'cog', 'lock'], 'exclamation-triangle'), + icon: select('Icon', ['exclamation-triangle', 'power', 'cog', 'lock'], 'exclamation-triangle'), }; }; diff --git a/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.tsx b/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.tsx index 6da04f85357..94637f6d8d9 100644 --- a/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.tsx +++ b/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.tsx @@ -1,7 +1,7 @@ import React, { FC, useContext } from 'react'; import { css } from 'emotion'; import { Modal } from '../Modal/Modal'; -import { IconType } from '../Icon/types'; +import { IconName } from '../../types'; import { Button } from '../Button'; import { stylesFactory, ThemeContext } from '../../themes'; import { GrafanaTheme } from '@grafana/data'; @@ -22,7 +22,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => ({ `, })); -const defaultIcon: IconType = 'exclamation-triangle'; +const defaultIcon: IconName = 'exclamation-triangle'; interface Props { isOpen: boolean; @@ -30,7 +30,7 @@ interface Props { body: React.ReactNode; confirmText: string; dismissText?: string; - icon?: IconType; + icon?: IconName; onConfirm(): void; onDismiss(): void; } diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.tsx index c7a8da97a65..401a1c7eb69 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.tsx @@ -42,10 +42,10 @@ export const DataLinksListItem: FC = ({
- +
- +
diff --git a/packages/grafana-ui/src/components/FieldConfigs/FieldConfigItemHeaderTitle.tsx b/packages/grafana-ui/src/components/FieldConfigs/FieldConfigItemHeaderTitle.tsx index 62a91fe2f69..0bb0bc1cdd7 100644 --- a/packages/grafana-ui/src/components/FieldConfigs/FieldConfigItemHeaderTitle.tsx +++ b/packages/grafana-ui/src/components/FieldConfigs/FieldConfigItemHeaderTitle.tsx @@ -26,7 +26,7 @@ export const FieldConfigItemHeaderTitle: React.FC {title}
onRemove()} aria-label="FieldConfigItemHeaderTitle remove button"> - +
{children} diff --git a/packages/grafana-ui/src/components/Forms/Input/Input.story.tsx b/packages/grafana-ui/src/components/Forms/Input/Input.story.tsx index 80cda6a4451..6a0236e5082 100644 --- a/packages/grafana-ui/src/components/Forms/Input/Input.story.tsx +++ b/packages/grafana-ui/src/components/Forms/Input/Input.story.tsx @@ -4,7 +4,7 @@ import { withCenteredStory } from '../../../utils/storybook/withCenteredStory'; import { Input } from './Input'; import { Button } from '../../Button'; import mdx from './Input.mdx'; -import { getAvailableIcons, IconType } from '../../Icon/types'; +import { getAvailableIcons, IconName } from '../../../types'; import { KeyValue } from '@grafana/data'; import { Icon } from '../../Icon/Icon'; import { Field } from '../Field'; @@ -59,11 +59,11 @@ export const simple = () => { const suffix = select('Suffix', prefixSuffixOpts, null, VISUAL_GROUP); let prefixEl: any = prefix; if (prefix && prefix.match(/icon-/g)) { - prefixEl = ; + prefixEl = ; } let suffixEl: any = suffix; if (suffix && suffix.match(/icon-/g)) { - suffixEl = ; + suffixEl = ; } const CONTAINER_GROUP = 'Container options'; diff --git a/packages/grafana-ui/src/components/Forms/Input/Input.tsx b/packages/grafana-ui/src/components/Forms/Input/Input.tsx index f14509d5674..390881ccd49 100644 --- a/packages/grafana-ui/src/components/Forms/Input/Input.tsx +++ b/packages/grafana-ui/src/components/Forms/Input/Input.tsx @@ -3,7 +3,6 @@ import { GrafanaTheme } from '@grafana/data'; import { css, cx } from 'emotion'; import { getFocusStyle, inputSizes, sharedInputStyle } from '../commonStyles'; import { stylesFactory, useTheme } from '../../../themes'; -import { Icon } from '../../Icon/Icon'; import { useClientRect } from '../../../utils/useClientRect'; import { FormInputSize } from '../types'; @@ -246,7 +245,7 @@ export const Input = React.forwardRef((props, ref) => { {(suffix || loading) && (
- {loading && } + {loading && } {suffix}
)} diff --git a/packages/grafana-ui/src/components/Icon/Icon.mdx b/packages/grafana-ui/src/components/Icon/Icon.mdx deleted file mode 100644 index 53b94a65217..00000000000 --- a/packages/grafana-ui/src/components/Icon/Icon.mdx +++ /dev/null @@ -1,28 +0,0 @@ -import { Meta, Story, Preview, Props } from '@storybook/addon-docs/blocks'; -import { Icon } from './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; -`; - - -``` - - - diff --git a/packages/grafana-ui/src/components/Icon/Icon.story.tsx b/packages/grafana-ui/src/components/Icon/Icon.story.tsx deleted file mode 100644 index cc1954f4a97..00000000000 --- a/packages/grafana-ui/src/components/Icon/Icon.story.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import React, { ChangeEvent, useState } from 'react'; -import { css } from 'emotion'; - -import { Forms } from '../index'; -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: 'General/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 ( -
- -
- {name} -
-
- ); -}; - -const icons = getAvailableIcons().sort((a, b) => a.localeCompare(b)); - -export const simple = () => { - const [filter, setFilter] = useState(''); - - const searchIcon = (event: ChangeEvent) => { - setFilter(event.target.value); - }; - - return ( -
- - - -
- {icons - .filter(val => val.includes(filter)) - .map(i => { - return ; - })} -
-
- ); -}; diff --git a/packages/grafana-ui/src/components/Icon/Icon.tsx b/packages/grafana-ui/src/components/Icon/Icon.tsx index 11002e6191b..cbd0577e5e2 100644 --- a/packages/grafana-ui/src/components/Icon/Icon.tsx +++ b/packages/grafana-ui/src/components/Icon/Icon.tsx @@ -1,36 +1,78 @@ import React from 'react'; -import { cx, css } from 'emotion'; +import { css, cx } from 'emotion'; +import { GrafanaTheme, toPascalCase } from '@grafana/data'; import { stylesFactory } from '../../themes'; -import { IconType } from './types'; +import { useTheme } from '../../themes/ThemeContext'; +import { IconName, IconType } from '../../types'; +import { ComponentSize } from '../../types/size'; +//@ts-ignore +import * as DefaultIcon from '@iconscout/react-unicons'; +import * as MonoIcon from './assets'; -export interface IconProps { - name: IconType; +interface IconProps extends React.HTMLAttributes { + name: IconName; + size?: ComponentSize | 'xl' | 'xxl'; + type?: IconType; +} +export interface SvgProps extends React.HTMLAttributes { + size: number; + secondaryColor?: string; className?: string; - onClick?: () => void; - onMouseDown?: React.MouseEventHandler; } -const getIconStyles = stylesFactory(() => { +const getIconStyles = stylesFactory((theme: GrafanaTheme, type: IconType) => { + const defaultIconColor = type === 'default' ? 'currentColor' : theme.colors.orange; return { + container: css` + display: inline-block; + `, icon: css` - display: inline-flex; - width: 16px; - align-items: center; - justify-content: center; - height: 16px; - text-align: center; - font-size: 14px; - - &:before { - vertical-align: middle; + vertical-align: middle; + display: inline-block; + margin-bottom: ${theme.spacing.xxs}; + cursor: pointer; + * { + fill: ${defaultIconColor}; } `, }; }); -export const Icon: React.FC = ({ name, className, onClick, onMouseDown }) => { - const styles = getIconStyles(); - return ; -}; +export const Icon = React.forwardRef( + ({ size = 'md', type = 'default', title, name, className, style, ...divElementProps }, ref) => { + const theme = useTheme(); + const styles = getIconStyles(theme, type); + const svgSize = getSvgSize(size, theme); + const iconName = type === 'default' ? `Uil${toPascalCase(name)}` : toPascalCase(name); + + /* Unicons don't have type definitions */ + //@ts-ignore + const Component = type === 'default' ? DefaultIcon[iconName] : MonoIcon[iconName]; + + if (!Component) { + return
; + } + + return ( +
+ {type === 'default' && } + {type === 'mono' && } +
+ ); + } +); Icon.displayName = 'Icon'; + +/* Transform string with px to number and add 2 pxs as path in svg is 2px smaller */ +const getSvgSize = (size: ComponentSize | 'xl' | 'xxl', theme: GrafanaTheme) => { + let svgSize; + if (size === 'xl') { + svgSize = Number(theme.typography.heading.h1.slice(0, -2)); + } else if (size === 'xxl') { + svgSize = Number(theme.height.lg.slice(0, -2)); + } else { + svgSize = Number(theme.typography.size[size].slice(0, -2)) + 2; + } + return svgSize; +}; diff --git a/packages/grafana-ui/src/components/Icon/assets/Apps.tsx b/packages/grafana-ui/src/components/Icon/assets/Apps.tsx new file mode 100644 index 00000000000..577c7d8d773 --- /dev/null +++ b/packages/grafana-ui/src/components/Icon/assets/Apps.tsx @@ -0,0 +1,13 @@ +import React, { FunctionComponent } from 'react'; +import { SvgProps } from '../Icon'; + +export const Apps: FunctionComponent = ({ size, ...rest }) => { + return ( + + + + + + + ); +}; diff --git a/packages/grafana-ui/src/components/Icon/assets/Cog.tsx b/packages/grafana-ui/src/components/Icon/assets/Cog.tsx new file mode 100644 index 00000000000..57004e95074 --- /dev/null +++ b/packages/grafana-ui/src/components/Icon/assets/Cog.tsx @@ -0,0 +1,14 @@ +import React, { FunctionComponent } from 'react'; +import { SvgProps } from '../Icon'; + +export const Cog: FunctionComponent = ({ size, ...rest }) => { + return ( + + + + + ); +}; diff --git a/packages/grafana-ui/src/components/Icon/assets/Favorite.tsx b/packages/grafana-ui/src/components/Icon/assets/Favorite.tsx new file mode 100644 index 00000000000..914bb29c763 --- /dev/null +++ b/packages/grafana-ui/src/components/Icon/assets/Favorite.tsx @@ -0,0 +1,10 @@ +import React, { FunctionComponent } from 'react'; +import { SvgProps } from '../Icon'; + +export const Favorite: FunctionComponent = ({ size, color, secondaryColor, ...rest }) => { + return ( + + + + ); +}; diff --git a/packages/grafana-ui/src/components/Icon/assets/Shield.tsx b/packages/grafana-ui/src/components/Icon/assets/Shield.tsx new file mode 100644 index 00000000000..c0b32708774 --- /dev/null +++ b/packages/grafana-ui/src/components/Icon/assets/Shield.tsx @@ -0,0 +1,14 @@ +import React, { FunctionComponent } from 'react'; +import { SvgProps } from '../Icon'; + +export const Shield: FunctionComponent = ({ size, ...rest }) => { + return ( + + + + + ); +}; diff --git a/packages/grafana-ui/src/components/Icon/assets/index.ts b/packages/grafana-ui/src/components/Icon/assets/index.ts new file mode 100644 index 00000000000..f25c61a5285 --- /dev/null +++ b/packages/grafana-ui/src/components/Icon/assets/index.ts @@ -0,0 +1,4 @@ +export * from './Apps'; +export * from './Cog'; +export * from './Shield'; +export * from './Favorite'; diff --git a/packages/grafana-ui/src/components/Icon/types.ts b/packages/grafana-ui/src/components/Icon/types.ts deleted file mode 100644 index ce31ea64515..00000000000 --- a/packages/grafana-ui/src/components/Icon/types.ts +++ /dev/null @@ -1,1306 +0,0 @@ -export type IconType = - | 'glass' - | 'music' - | 'search' - | 'envelope-o' - | 'heart' - | 'star' - | 'star-o' - | 'user' - | 'film' - | 'th-large' - | 'th' - | 'th-list' - | 'check' - | 'times' - | 'search-plus' - | 'search-minus' - | 'power-off' - | 'signal' - | 'cog' - | 'trash-o' - | 'home' - | 'file-o' - | 'clock-o' - | 'road' - | 'download' - | 'arrow-circle-o-down' - | 'arrow-circle-o-up' - | 'inbox' - | 'play-circle-o' - | 'repeat' - | 'refresh' - | 'list-alt' - | 'lock' - | 'flag' - | 'headphones' - | 'volume-off' - | 'volume-down' - | 'volume-up' - | 'qrcode' - | 'barcode' - | 'tag' - | 'tags' - | 'book' - | 'bookmark' - | 'print' - | 'camera' - | 'font' - | 'bold' - | 'italic' - | 'text-height' - | 'text-width' - | 'align-left' - | 'align-center' - | 'align-right' - | 'align-justify' - | 'list' - | 'outdent' - | 'indent' - | 'video-camera' - | 'picture-o' - | 'pencil' - | 'map-marker' - | 'adjust' - | 'tint' - | 'pencil-square-o' - | 'share-square-o' - | 'check-square-o' - | 'arrows' - | 'step-backward' - | 'fast-backward' - | 'backward' - | 'play' - | 'pause' - | 'stop' - | 'forward' - | 'fast-forward' - | 'step-forward' - | 'eject' - | 'chevron-left' - | 'chevron-right' - | 'plus-circle' - | 'minus-circle' - | 'times-circle' - | 'check-circle' - | 'question-circle' - | 'info-circle' - | 'crosshairs' - | 'times-circle-o' - | 'check-circle-o' - | 'ban' - | 'remove' - | 'arrow-left' - | 'arrow-right' - | 'arrow-up' - | 'arrow-down' - | 'share' - | 'expand' - | 'compress' - | 'plus' - | 'minus' - | 'asterisk' - | 'exclamation-circle' - | 'gift' - | 'leaf' - | 'fire' - | 'eye' - | 'eye-slash' - | 'exclamation-triangle' - | 'plane' - | 'calendar' - | 'random' - | 'comment' - | 'magnet' - | 'chevron-up' - | 'chevron-down' - | 'retweet' - | 'shopping-cart' - | 'folder' - | 'folder-open' - | 'arrows-v' - | 'arrows-h' - | 'bar-chart' - | 'camera-retro' - | 'key' - | 'cogs' - | 'comments' - | 'thumbs-o-up' - | 'thumbs-o-down' - | 'star-half' - | 'heart-o' - | 'sign-out' - | 'linkedin-square' - | 'thumb-tack' - | 'external-link' - | 'sign-in' - | 'trophy' - | 'github-square' - | 'upload' - | 'lemon-o' - | 'phone' - | 'square-o' - | 'bookmark-o' - | 'phone-square' - | 'github' - | 'unlock' - | 'credit-card' - | 'rss' - | 'hdd-o' - | 'bullhorn' - | 'bell' - | 'certificate' - | 'hand-o-right' - | 'hand-o-left' - | 'hand-o-up' - | 'hand-o-down' - | 'arrow-circle-left' - | 'arrow-circle-right' - | 'arrow-circle-up' - | 'arrow-circle-down' - | 'globe' - | 'wrench' - | 'tasks' - | 'filter' - | 'briefcase' - | 'arrows-alt' - | 'users' - | 'link' - | 'cloud' - | 'flask' - | 'scissors' - | 'files-o' - | 'paperclip' - | 'floppy-o' - | 'square' - | 'bars' - | 'list-ul' - | 'list-ol' - | 'strikethrough' - | 'underline' - | 'table' - | 'magic' - | 'truck' - | 'pinterest' - | 'pinterest-square' - | 'google-plus-square' - | 'google-plus' - | 'money' - | 'caret-down' - | 'caret-up' - | 'caret-left' - | 'caret-right' - | 'columns' - | 'sort' - | 'sort-desc' - | 'sort-asc' - | 'envelope' - | 'linkedin' - | 'undo' - | 'gavel' - | 'tachometer' - | 'comment-o' - | 'comments-o' - | 'bolt' - | 'sitemap' - | 'umbrella' - | 'clipboard' - | 'lightbulb-o' - | 'exchange' - | 'cloud-download' - | 'cloud-upload' - | 'user-md' - | 'stethoscope' - | 'suitcase' - | 'bell-o' - | 'coffee' - | 'cutlery' - | 'file-text-o' - | 'building-o' - | 'hospital-o' - | 'ambulance' - | 'medkit' - | 'fighter-jet' - | 'beer' - | 'h-square' - | 'plus-square' - | 'angle-double-left' - | 'angle-double-right' - | 'angle-double-up' - | 'angle-double-down' - | 'angle-left' - | 'angle-right' - | 'angle-up' - | 'angle-down' - | 'desktop' - | 'laptop' - | 'tablet' - | 'mobile' - | 'circle-o' - | 'quote-left' - | 'quote-right' - | 'spinner' - | 'circle' - | 'reply' - | 'github-alt' - | 'folder-o' - | 'folder-open-o' - | 'smile-o' - | 'frown-o' - | 'meh-o' - | 'gamepad' - | 'keyboard-o' - | 'flag-o' - | 'flag-checkered' - | 'terminal' - | 'code' - | 'reply-all' - | 'star-half-o' - | 'location-arrow' - | 'crop' - | 'code-fork' - | 'chain-broken' - | 'question' - | 'info' - | 'exclamation' - | 'superscript' - | 'subscript' - | 'eraser' - | 'puzzle-piece' - | 'microphone' - | 'microphone-slash' - | 'shield' - | 'calendar-o' - | 'fire-extinguisher' - | 'rocket' - | 'maxcdn' - | 'chevron-circle-left' - | 'chevron-circle-right' - | 'chevron-circle-up' - | 'chevron-circle-down' - | 'html5' - | 'css3' - | 'anchor' - | 'unlock-alt' - | 'bullseye' - | 'ellipsis-h' - | 'ellipsis-v' - | 'rss-square' - | 'play-circle' - | 'ticket' - | 'minus-square' - | 'minus-square-o' - | 'level-up' - | 'level-down' - | 'check-square' - | 'pencil-square' - | 'external-link-square' - | 'share-square' - | 'compass' - | 'caret-square-o-down' - | 'caret-square-o-up' - | 'caret-square-o-right' - | 'eur' - | 'gbp' - | 'usd' - | 'inr' - | 'jpy' - | 'rub' - | 'krw' - | 'btc' - | 'file' - | 'file-text' - | 'sort-alpha-asc' - | 'sort-alpha-desc' - | 'sort-amount-asc' - | 'sort-amount-desc' - | 'sort-numeric-asc' - | 'sort-numeric-desc' - | 'thumbs-up' - | 'thumbs-down' - | 'youtube-square' - | 'youtube' - | 'xing' - | 'xing-square' - | 'youtube-play' - | 'dropbox' - | 'stack-overflow' - | 'instagram' - | 'flickr' - | 'adn' - | 'bitbucket' - | 'bitbucket-square' - | 'tumblr' - | 'tumblr-square' - | 'long-arrow-down' - | 'long-arrow-up' - | 'long-arrow-left' - | 'long-arrow-right' - | 'apple' - | 'windows' - | 'android' - | 'linux' - | 'dribbble' - | 'skype' - | 'foursquare' - | 'trello' - | 'female' - | 'male' - | 'gratipay' - | 'sun-o' - | 'moon-o' - | 'archive' - | 'bug' - | 'vk' - | 'weibo' - | 'renren' - | 'pagelines' - | 'stack-exchange' - | 'arrow-circle-o-right' - | 'arrow-circle-o-left' - | 'caret-square-o-left' - | 'dot-circle-o' - | 'wheelchair' - | 'vimeo-square' - | 'try' - | 'plus-square-o' - | 'space-shuttle' - | 'slack' - | 'envelope-square' - | 'wordpress' - | 'openid' - | 'university' - | 'graduation-cap' - | 'yahoo' - | 'google' - | 'reddit' - | 'reddit-square' - | 'stumbleupon-circle' - | 'stumbleupon' - | 'delicious' - | 'digg' - | 'pied-piper-pp' - | 'pied-piper-alt' - | 'drupal' - | 'joomla' - | 'language' - | 'fax' - | 'building' - | 'child' - | 'paw' - | 'spoon' - | 'cube' - | 'cubes' - | 'behance' - | 'behance-square' - | 'steam' - | 'steam-square' - | 'recycle' - | 'car' - | 'taxi' - | 'tree' - | 'database' - | 'file-pdf-o' - | 'file-word-o' - | 'file-excel-o' - | 'file-powerpoint-o' - | 'file-image-o' - | 'file-archive-o' - | 'file-audio-o' - | 'file-video-o' - | 'file-code-o' - | 'life-ring' - | 'circle-o-notch' - | 'rebel' - | 'empire' - | 'git-square' - | 'git' - | 'qq' - | 'paper-plane' - | 'paper-plane-o' - | 'history' - | 'circle-thin' - | 'header' - | 'paragraph' - | 'sliders' - | 'share-alt' - | 'share-alt-square' - | 'bomb' - | 'futbol-o' - | 'tty' - | 'binoculars' - | 'plug' - | 'newspaper-o' - | 'wifi' - | 'calculator' - | 'cc-visa' - | 'cc-mastercard' - | 'cc-discover' - | 'cc-amex' - | 'cc-paypal' - | 'cc-stripe' - | 'bell-slash' - | 'bell-slash-o' - | 'trash' - | 'copyright' - | 'at' - | 'eyedropper' - | 'paint-brush' - | 'birthday-cake' - | 'area-chart' - | 'pie-chart' - | 'line-chart' - | 'lastfm' - | 'lastfm-square' - | 'toggle-off' - | 'toggle-on' - | 'bicycle' - | 'bus' - | 'ioxhost' - | 'angellist' - | 'cc' - | 'ils' - | 'meanpath' - | 'buysellads' - | 'connectdevelop' - | 'dashcube' - | 'forumbee' - | 'leanpub' - | 'sellsy' - | 'shirtsinbulk' - | 'simplybuilt' - | 'skyatlas' - | 'cart-plus' - | 'cart-arrow-down' - | 'diamond' - | 'ship' - | 'user-secret' - | 'motorcycle' - | 'street-view' - | 'heartbeat' - | 'venus' - | 'mars' - | 'mercury' - | 'transgender' - | 'transgender-alt' - | 'venus-double' - | 'mars-double' - | 'venus-mars' - | 'mars-stroke' - | 'mars-stroke-v' - | 'mars-stroke-h' - | 'neuter' - | 'genderless' - | 'facebook-official' - | 'pinterest-p' - | 'whatsapp' - | 'server' - | 'user-plus' - | 'user-times' - | 'bed' - | 'viacoin' - | 'train' - | 'subway' - | 'medium' - | 'y-combinator' - | 'optin-monster' - | 'opencart' - | 'expeditedssl' - | 'battery-full' - | 'battery-three-quarters' - | 'battery-half' - | 'battery-quarter' - | 'battery-empty' - | 'mouse-pointer' - | 'i-cursor' - | 'object-group' - | 'object-ungroup' - | 'sticky-note' - | 'sticky-note-o' - | 'cc-jcb' - | 'cc-diners-club' - | 'clone' - | 'balance-scale' - | 'hourglass-o' - | 'hourglass-start' - | 'hourglass-half' - | 'hourglass-end' - | 'hourglass' - | 'hand-rock-o' - | 'hand-paper-o' - | 'hand-scissors-o' - | 'hand-lizard-o' - | 'hand-spock-o' - | 'hand-pointer-o' - | 'hand-peace-o' - | 'trademark' - | 'registered' - | 'creative-commons' - | 'gg' - | 'gg-circle' - | 'tripadvisor' - | 'odnoklassniki' - | 'odnoklassniki-square' - | 'get-pocket' - | 'wikipedia-w' - | 'safari' - | 'chrome' - | 'firefox' - | 'opera' - | 'internet-explorer' - | 'television' - | 'contao' - | 'calendar-plus-o' - | 'calendar-minus-o' - | 'calendar-times-o' - | 'calendar-check-o' - | 'industry' - | 'map-pin' - | 'map-signs' - | 'map-o' - | 'map' - | 'commenting' - | 'commenting-o' - | 'houzz' - | 'vimeo' - | 'black-tie' - | 'fonticons' - | 'reddit-alien' - | 'edge' - | 'credit-card-alt' - | 'codiepie' - | 'modx' - | 'fort-awesome' - | 'usb' - | 'product-hunt' - | 'mixcloud' - | 'scribd' - | 'pause-circle' - | 'pause-circle-o' - | 'stop-circle' - | 'stop-circle-o' - | 'shopping-bag' - | 'shopping-basket' - | 'hashtag' - | 'bluetooth' - | 'bluetooth-b' - | 'percent' - | 'gitlab' - | 'wpbeginner' - | 'wpforms' - | 'envira' - | 'universal-access' - | 'wheelchair-alt' - | 'question-circle-o' - | 'blind' - | 'audio-description' - | 'volume-control-phone' - | 'braille' - | 'assistive-listening-systems' - | 'american-sign-language-interpreting' - | 'deaf' - | 'glide' - | 'glide-g' - | 'sign-language' - | 'low-vision' - | 'viadeo' - | 'viadeo-square' - | 'snapchat' - | 'snapchat-ghost' - | 'snapchat-square' - | 'pied-piper' - | 'first-order' - | 'themeisle' - | 'google-plus-official' - | 'font-awesome' - | 'handshake-o' - | 'envelope-open' - | 'envelope-open-o' - | 'linode' - | 'address-book' - | 'address-book-o' - | 'address-card' - | 'address-card-o' - | 'user-circle' - | 'user-circle-o' - | 'user-o' - | 'id-badge' - | 'id-card' - | 'id-card-o' - | 'thermometer-full' - | 'thermometer-three-quarters' - | 'thermometer-half' - | 'thermometer-quarter' - | 'thermometer-empty' - | 'shower' - | 'bath' - | 'podcast' - | 'window-maximize' - | 'window-minimize' - | 'window-restore' - | 'window-close' - | 'window-close-o' - | 'bandcamp' - | 'grav' - | 'imdb' - | 'ravelry' - | 'eercast' - | 'microchip' - | 'snowflake-o' - | 'superpowers' - | 'wpexplorer' - | 'meetup' - | 'copy'; - -export const getAvailableIcons = (): IconType[] => [ - 'glass', - 'music', - 'search', - 'envelope-o', - 'heart', - 'star', - 'star-o', - 'user', - 'film', - 'th-large', - 'th', - 'th-list', - 'check', - 'times', - 'search-plus', - 'search-minus', - 'power-off', - 'signal', - 'cog', - 'trash-o', - 'home', - 'file-o', - 'clock-o', - 'road', - 'download', - 'arrow-circle-o-down', - 'arrow-circle-o-up', - 'inbox', - 'play-circle-o', - 'repeat', - 'refresh', - 'list-alt', - 'lock', - 'flag', - 'headphones', - 'volume-off', - 'volume-down', - 'volume-up', - 'qrcode', - 'barcode', - 'tag', - 'tags', - 'book', - 'bookmark', - 'print', - 'camera', - 'font', - 'bold', - 'italic', - 'text-height', - 'text-width', - 'align-left', - 'align-center', - 'align-right', - 'align-justify', - 'list', - 'outdent', - 'indent', - 'video-camera', - 'picture-o', - 'pencil', - 'map-marker', - 'adjust', - 'tint', - 'pencil-square-o', - 'share-square-o', - 'check-square-o', - 'arrows', - 'step-backward', - 'fast-backward', - 'backward', - 'play', - 'pause', - 'stop', - 'forward', - 'fast-forward', - 'step-forward', - 'eject', - 'chevron-left', - 'chevron-right', - 'plus-circle', - 'minus-circle', - 'times-circle', - 'check-circle', - 'question-circle', - 'info-circle', - 'crosshairs', - 'times-circle-o', - 'check-circle-o', - 'ban', - 'arrow-left', - 'arrow-right', - 'arrow-up', - 'arrow-down', - 'share', - 'expand', - 'compress', - 'plus', - 'minus', - 'asterisk', - 'exclamation-circle', - 'gift', - 'leaf', - 'fire', - 'eye', - 'eye-slash', - 'exclamation-triangle', - 'plane', - 'calendar', - 'random', - 'comment', - 'magnet', - 'chevron-up', - 'chevron-down', - 'retweet', - 'shopping-cart', - 'folder', - 'folder-open', - 'arrows-v', - 'arrows-h', - 'bar-chart', - 'camera-retro', - 'key', - 'cogs', - 'comments', - 'thumbs-o-up', - 'thumbs-o-down', - 'star-half', - 'heart-o', - 'sign-out', - 'linkedin-square', - 'thumb-tack', - 'external-link', - 'sign-in', - 'trophy', - 'github-square', - 'upload', - 'lemon-o', - 'phone', - 'square-o', - 'bookmark-o', - 'phone-square', - 'github', - 'unlock', - 'credit-card', - 'rss', - 'hdd-o', - 'bullhorn', - 'bell', - 'certificate', - 'hand-o-right', - 'hand-o-left', - 'hand-o-up', - 'hand-o-down', - 'arrow-circle-left', - 'arrow-circle-right', - 'arrow-circle-up', - 'arrow-circle-down', - 'globe', - 'wrench', - 'tasks', - 'filter', - 'briefcase', - 'arrows-alt', - 'users', - 'link', - 'cloud', - 'flask', - 'scissors', - 'files-o', - 'paperclip', - 'floppy-o', - 'square', - 'bars', - 'list-ul', - 'list-ol', - 'strikethrough', - 'underline', - 'table', - 'magic', - 'truck', - 'pinterest', - 'pinterest-square', - 'google-plus-square', - 'google-plus', - 'money', - 'caret-down', - 'caret-up', - 'caret-left', - 'caret-right', - 'columns', - 'sort', - 'sort-desc', - 'sort-asc', - 'envelope', - 'linkedin', - 'undo', - 'gavel', - 'tachometer', - 'comment-o', - 'comments-o', - 'bolt', - 'sitemap', - 'umbrella', - 'clipboard', - 'lightbulb-o', - 'exchange', - 'cloud-download', - 'cloud-upload', - 'user-md', - 'stethoscope', - 'suitcase', - 'bell-o', - 'coffee', - 'cutlery', - 'file-text-o', - 'building-o', - 'hospital-o', - 'ambulance', - 'medkit', - 'fighter-jet', - 'beer', - 'h-square', - 'plus-square', - 'angle-double-left', - 'angle-double-right', - 'angle-double-up', - 'angle-double-down', - 'angle-left', - 'angle-right', - 'angle-up', - 'angle-down', - 'desktop', - 'laptop', - 'tablet', - 'mobile', - 'circle-o', - 'quote-left', - 'quote-right', - 'spinner', - 'circle', - 'reply', - 'github-alt', - 'folder-o', - 'folder-open-o', - 'smile-o', - 'frown-o', - 'meh-o', - 'gamepad', - 'keyboard-o', - 'flag-o', - 'flag-checkered', - 'terminal', - 'code', - 'reply-all', - 'star-half-o', - 'location-arrow', - 'crop', - 'code-fork', - 'chain-broken', - 'question', - 'info', - 'exclamation', - 'superscript', - 'subscript', - 'eraser', - 'puzzle-piece', - 'microphone', - 'microphone-slash', - 'shield', - 'calendar-o', - 'fire-extinguisher', - 'rocket', - 'maxcdn', - 'chevron-circle-left', - 'chevron-circle-right', - 'chevron-circle-up', - 'chevron-circle-down', - 'html5', - 'css3', - 'anchor', - 'unlock-alt', - 'bullseye', - 'ellipsis-h', - 'ellipsis-v', - 'rss-square', - 'play-circle', - 'ticket', - 'minus-square', - 'minus-square-o', - 'level-up', - 'level-down', - 'check-square', - 'pencil-square', - 'external-link-square', - 'share-square', - 'compass', - 'caret-square-o-down', - 'caret-square-o-up', - 'caret-square-o-right', - 'eur', - 'gbp', - 'usd', - 'inr', - 'jpy', - 'rub', - 'krw', - 'btc', - 'file', - 'file-text', - 'sort-alpha-asc', - 'sort-alpha-desc', - 'sort-amount-asc', - 'sort-amount-desc', - 'sort-numeric-asc', - 'sort-numeric-desc', - 'thumbs-up', - 'thumbs-down', - 'youtube-square', - 'youtube', - 'xing', - 'xing-square', - 'youtube-play', - 'dropbox', - 'stack-overflow', - 'instagram', - 'flickr', - 'adn', - 'bitbucket', - 'bitbucket-square', - 'tumblr', - 'tumblr-square', - 'long-arrow-down', - 'long-arrow-up', - 'long-arrow-left', - 'long-arrow-right', - 'apple', - 'windows', - 'android', - 'linux', - 'dribbble', - 'skype', - 'foursquare', - 'trello', - 'female', - 'male', - 'gratipay', - 'sun-o', - 'moon-o', - 'archive', - 'bug', - 'vk', - 'weibo', - 'renren', - 'pagelines', - 'stack-exchange', - 'arrow-circle-o-right', - 'arrow-circle-o-left', - 'caret-square-o-left', - 'dot-circle-o', - 'wheelchair', - 'vimeo-square', - 'try', - 'plus-square-o', - 'space-shuttle', - 'slack', - 'envelope-square', - 'wordpress', - 'openid', - 'university', - 'graduation-cap', - 'yahoo', - 'google', - 'reddit', - 'reddit-square', - 'stumbleupon-circle', - 'stumbleupon', - 'delicious', - 'digg', - 'pied-piper-pp', - 'pied-piper-alt', - 'drupal', - 'joomla', - 'language', - 'fax', - 'building', - 'child', - 'paw', - 'spoon', - 'cube', - 'cubes', - 'behance', - 'behance-square', - 'steam', - 'steam-square', - 'recycle', - 'car', - 'taxi', - 'tree', - 'database', - 'file-pdf-o', - 'file-word-o', - 'file-excel-o', - 'file-powerpoint-o', - 'file-image-o', - 'file-archive-o', - 'file-audio-o', - 'file-video-o', - 'file-code-o', - 'life-ring', - 'circle-o-notch', - 'rebel', - 'empire', - 'git-square', - 'git', - 'qq', - 'paper-plane', - 'paper-plane-o', - 'history', - 'circle-thin', - 'header', - 'paragraph', - 'sliders', - 'share-alt', - 'share-alt-square', - 'bomb', - 'futbol-o', - 'tty', - 'binoculars', - 'plug', - 'newspaper-o', - 'wifi', - 'calculator', - 'cc-visa', - 'cc-mastercard', - 'cc-discover', - 'cc-amex', - 'cc-paypal', - 'cc-stripe', - 'bell-slash', - 'bell-slash-o', - 'trash', - 'copyright', - 'at', - 'eyedropper', - 'paint-brush', - 'birthday-cake', - 'area-chart', - 'pie-chart', - 'line-chart', - 'lastfm', - 'lastfm-square', - 'toggle-off', - 'toggle-on', - 'bicycle', - 'bus', - 'ioxhost', - 'angellist', - 'cc', - 'ils', - 'meanpath', - 'buysellads', - 'connectdevelop', - 'dashcube', - 'forumbee', - 'leanpub', - 'sellsy', - 'shirtsinbulk', - 'simplybuilt', - 'skyatlas', - 'cart-plus', - 'cart-arrow-down', - 'diamond', - 'ship', - 'user-secret', - 'motorcycle', - 'street-view', - 'heartbeat', - 'venus', - 'mars', - 'mercury', - 'transgender', - 'transgender-alt', - 'venus-double', - 'mars-double', - 'venus-mars', - 'mars-stroke', - 'mars-stroke-v', - 'mars-stroke-h', - 'neuter', - 'genderless', - 'facebook-official', - 'pinterest-p', - 'whatsapp', - 'server', - 'user-plus', - 'user-times', - 'bed', - 'viacoin', - 'train', - 'subway', - 'medium', - 'y-combinator', - 'optin-monster', - 'opencart', - 'expeditedssl', - 'battery-full', - 'battery-three-quarters', - 'battery-half', - 'battery-quarter', - 'battery-empty', - 'mouse-pointer', - 'i-cursor', - 'object-group', - 'object-ungroup', - 'sticky-note', - 'sticky-note-o', - 'cc-jcb', - 'cc-diners-club', - 'clone', - 'balance-scale', - 'hourglass-o', - 'hourglass-start', - 'hourglass-half', - 'hourglass-end', - 'hourglass', - 'hand-rock-o', - 'hand-paper-o', - 'hand-scissors-o', - 'hand-lizard-o', - 'hand-spock-o', - 'hand-pointer-o', - 'hand-peace-o', - 'trademark', - 'registered', - 'creative-commons', - 'gg', - 'gg-circle', - 'tripadvisor', - 'odnoklassniki', - 'odnoklassniki-square', - 'get-pocket', - 'wikipedia-w', - 'safari', - 'chrome', - 'firefox', - 'opera', - 'internet-explorer', - 'television', - 'contao', - 'calendar-plus-o', - 'calendar-minus-o', - 'calendar-times-o', - 'calendar-check-o', - 'industry', - 'map-pin', - 'map-signs', - 'map-o', - 'map', - 'commenting', - 'commenting-o', - 'houzz', - 'vimeo', - 'black-tie', - 'fonticons', - 'reddit-alien', - 'edge', - 'credit-card-alt', - 'codiepie', - 'modx', - 'fort-awesome', - 'usb', - 'product-hunt', - 'mixcloud', - 'scribd', - 'pause-circle', - 'pause-circle-o', - 'stop-circle', - 'stop-circle-o', - 'shopping-bag', - 'shopping-basket', - 'hashtag', - 'bluetooth', - 'bluetooth-b', - 'percent', - 'gitlab', - 'wpbeginner', - 'wpforms', - 'envira', - 'universal-access', - 'wheelchair-alt', - 'question-circle-o', - 'blind', - 'audio-description', - 'volume-control-phone', - 'braille', - 'assistive-listening-systems', - 'american-sign-language-interpreting', - 'deaf', - 'glide', - 'glide-g', - 'sign-language', - 'low-vision', - 'viadeo', - 'viadeo-square', - 'snapchat', - 'snapchat-ghost', - 'snapchat-square', - 'pied-piper', - 'first-order', - 'themeisle', - 'google-plus-official', - 'font-awesome', - 'handshake-o', - 'envelope-open', - 'envelope-open-o', - 'linode', - 'address-book', - 'address-book-o', - 'address-card', - 'address-card-o', - 'user-circle', - 'user-circle-o', - 'user-o', - 'id-badge', - 'id-card', - 'id-card-o', - 'thermometer-full', - 'thermometer-three-quarters', - 'thermometer-half', - 'thermometer-quarter', - 'thermometer-empty', - 'shower', - 'bath', - 'podcast', - 'window-maximize', - 'window-minimize', - 'window-restore', - 'window-close', - 'window-close-o', - 'bandcamp', - 'grav', - 'imdb', - 'ravelry', - 'eercast', - 'microchip', - 'snowflake-o', - 'superpowers', - 'wpexplorer', - 'meetup', -]; diff --git a/packages/grafana-ui/src/components/Modal/Modal.tsx b/packages/grafana-ui/src/components/Modal/Modal.tsx index 047d472cc7e..5d36e7fae2c 100644 --- a/packages/grafana-ui/src/components/Modal/Modal.tsx +++ b/packages/grafana-ui/src/components/Modal/Modal.tsx @@ -2,13 +2,13 @@ import React from 'react'; import { Portal } from '../Portal/Portal'; import { cx } from 'emotion'; import { withTheme } from '../../themes'; -import { IconType } from '../Icon/types'; +import { IconName } from '../../types'; import { Themeable } from '../../types'; import { getModalStyles } from './getModalStyles'; import { ModalHeader } from './ModalHeader'; interface Props extends Themeable { - icon?: IconType; + icon?: IconName; title: string | JSX.Element; className?: string; diff --git a/packages/grafana-ui/src/components/Modal/ModalHeader.tsx b/packages/grafana-ui/src/components/Modal/ModalHeader.tsx index 8b82643ab11..fc9df5cab32 100644 --- a/packages/grafana-ui/src/components/Modal/ModalHeader.tsx +++ b/packages/grafana-ui/src/components/Modal/ModalHeader.tsx @@ -1,12 +1,12 @@ import React, { useContext } from 'react'; import { getModalStyles } from './getModalStyles'; -import { IconType } from '../Icon/types'; +import { IconName } from '../../types'; import { ThemeContext } from '../../themes'; import { Icon } from '../Icon/Icon'; interface Props { title: string; - icon?: IconType; + icon?: IconName; } export const ModalHeader: React.FC = ({ icon, title, children }) => { diff --git a/packages/grafana-ui/src/components/Modal/ModalTabContent.tsx b/packages/grafana-ui/src/components/Modal/ModalTabContent.tsx index 8defc27f3ad..dafadfe4062 100644 --- a/packages/grafana-ui/src/components/Modal/ModalTabContent.tsx +++ b/packages/grafana-ui/src/components/Modal/ModalTabContent.tsx @@ -1,9 +1,9 @@ import React from 'react'; -import { IconType } from '../Icon/types'; +import { IconName } from '../../types'; import { Icon } from '../Icon/Icon'; interface Props { - icon?: IconType; + icon?: IconName; iconClass?: string; } diff --git a/packages/grafana-ui/src/components/Modal/ModalTabsHeader.tsx b/packages/grafana-ui/src/components/Modal/ModalTabsHeader.tsx index a1628a33661..fb164cdb116 100644 --- a/packages/grafana-ui/src/components/Modal/ModalTabsHeader.tsx +++ b/packages/grafana-ui/src/components/Modal/ModalTabsHeader.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { IconType } from '../Icon/types'; +import { IconName } from '../../types'; import { TabsBar } from '../Tabs/TabsBar'; import { Tab } from '../Tabs/Tab'; import { ModalHeader } from './ModalHeader'; @@ -11,7 +11,7 @@ interface ModalTab { } interface Props { - icon: IconType; + icon: IconName; title: string; tabs: ModalTab[]; activeTab: string; diff --git a/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.tsx b/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.tsx index 9ff215d24f9..c119bb694b5 100644 --- a/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.tsx +++ b/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.tsx @@ -3,6 +3,7 @@ import classNames from 'classnames'; import { SelectableValue } from '@grafana/data'; import { css } from 'emotion'; import { Tooltip } from '../Tooltip/Tooltip'; +import { Icon } from '../Icon/Icon'; import { ButtonSelect } from '../Forms/Legacy/Select/ButtonSelect'; import memoizeOne from 'memoize-one'; import { GrafanaTheme } from '@grafana/data'; @@ -87,7 +88,7 @@ export class RefreshPickerBase extends PureComponent { className="btn btn--radius-right-0 navbar-button navbar-button--border-right-0" onClick={onRefresh!} > - + )} diff --git a/packages/grafana-ui/src/components/Select/ButtonSelect.tsx b/packages/grafana-ui/src/components/Select/ButtonSelect.tsx index f98eddd5cc8..95e95de2070 100644 --- a/packages/grafana-ui/src/components/Select/ButtonSelect.tsx +++ b/packages/grafana-ui/src/components/Select/ButtonSelect.tsx @@ -8,16 +8,16 @@ import { SelectCommonProps, CustomControlProps } from './types'; import { SelectBase } from './SelectBase'; import { stylesFactory, useTheme } from '../../themes'; import { Icon } from '../Icon/Icon'; -import { IconType } from '../Icon/types'; +import { IconName } from '../../types'; interface ButtonSelectProps extends Omit, 'renderControl' | 'size' | 'prefix'> { - icon?: IconType; + icon?: IconName; variant?: ButtonVariant; size?: ComponentSize; } interface SelectButtonProps extends Omit { - icon?: IconType; + icon?: IconName; isOpen?: boolean; } @@ -42,14 +42,12 @@ const SelectButton = React.forwardRef( `, })); const styles = getStyles(useTheme()); - const buttonIcon = `fa fa-${icon}`; - const caretIcon = isOpen ? 'caret-up' : 'caret-down'; return ( - diff --git a/packages/grafana-ui/src/components/Select/DropdownIndicator.tsx b/packages/grafana-ui/src/components/Select/DropdownIndicator.tsx index 7bfa90bf336..0da7adfd403 100644 --- a/packages/grafana-ui/src/components/Select/DropdownIndicator.tsx +++ b/packages/grafana-ui/src/components/Select/DropdownIndicator.tsx @@ -6,6 +6,6 @@ interface DropdownIndicatorProps { } export const DropdownIndicator: React.FC = ({ isOpen }) => { - const icon = isOpen ? 'caret-up' : 'caret-down'; + const icon = isOpen ? 'angle-up' : 'angle-down'; return ; }; diff --git a/packages/grafana-ui/src/components/Select/Select.story.tsx b/packages/grafana-ui/src/components/Select/Select.story.tsx index 9e9a78c9f80..18b5d943f32 100644 --- a/packages/grafana-ui/src/components/Select/Select.story.tsx +++ b/packages/grafana-ui/src/components/Select/Select.story.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { Select, AsyncSelect, MultiSelect, AsyncMultiSelect } from './Select'; import { withCenteredStory, withHorizontallyCenteredStory } from '../../utils/storybook/withCenteredStory'; import { SelectableValue } from '@grafana/data'; -import { getAvailableIcons, IconType } from '../Icon/types'; +import { getAvailableIcons, IconName } from '../../types'; import { select, boolean } from '@storybook/addon-knobs'; import { Icon } from '../Icon/Icon'; import { Button } from '../Button'; @@ -46,7 +46,7 @@ const getKnobs = () => { let prefixEl: any = prefix; if (prefix && prefix.match(/icon-/g)) { - prefixEl = ; + prefixEl = ; } return { diff --git a/packages/grafana-ui/src/components/Select/SelectBase.tsx b/packages/grafana-ui/src/components/Select/SelectBase.tsx index e3b7aa4c818..41adf0fa569 100644 --- a/packages/grafana-ui/src/components/Select/SelectBase.tsx +++ b/packages/grafana-ui/src/components/Select/SelectBase.tsx @@ -242,7 +242,7 @@ export function SelectBase({ ); }, LoadingIndicator: (props: any) => { - return ; + return ; }, LoadingMessage: (props: any) => { return
{loadingMessage}
; diff --git a/packages/grafana-ui/src/components/Table/Table.tsx b/packages/grafana-ui/src/components/Table/Table.tsx index 9cfc18ce7c9..9d46368c24d 100644 --- a/packages/grafana-ui/src/components/Table/Table.tsx +++ b/packages/grafana-ui/src/components/Table/Table.tsx @@ -105,7 +105,7 @@ function renderHeaderCell(column: any, className: string, field?: Field) { return (
{column.render('Header')} - {column.isSorted && (column.isSortedDesc ? : )} + {column.isSorted && (column.isSortedDesc ? : )}
); } diff --git a/packages/grafana-ui/src/components/ThresholdsEditorNew/ThresholdsEditor.tsx b/packages/grafana-ui/src/components/ThresholdsEditorNew/ThresholdsEditor.tsx index 8ebd1303a69..b4f961ca001 100644 --- a/packages/grafana-ui/src/components/ThresholdsEditorNew/ThresholdsEditor.tsx +++ b/packages/grafana-ui/src/components/ThresholdsEditorNew/ThresholdsEditor.tsx @@ -182,7 +182,9 @@ export class ThresholdsEditor extends PureComponent { {isPercent &&
%
}
} - suffix={ this.onRemoveThreshold(threshold)} />} + suffix={ + this.onRemoveThreshold(threshold)} /> + } /> ); } diff --git a/packages/grafana-ui/src/components/TimePicker/TimeOfDayPicker.tsx b/packages/grafana-ui/src/components/TimePicker/TimeOfDayPicker.tsx index 5c5be9f2dbb..20be1a9ada2 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimeOfDayPicker.tsx +++ b/packages/grafana-ui/src/components/TimePicker/TimeOfDayPicker.tsx @@ -111,7 +111,7 @@ interface CaretProps { const Caret: FC = ({ wrapperStyle = '' }) => { return (
- +
); }; diff --git a/packages/grafana-ui/src/components/TimePicker/TimePicker.tsx b/packages/grafana-ui/src/components/TimePicker/TimePicker.tsx index 5e16255a545..4c78bbce263 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimePicker.tsx +++ b/packages/grafana-ui/src/components/TimePicker/TimePicker.tsx @@ -4,6 +4,7 @@ import { css, cx } from 'emotion'; // Components import { Tooltip } from '../Tooltip/Tooltip'; +import { Icon } from '../Icon/Icon'; import { TimePickerContent } from './TimePickerContent/TimePickerContent'; import { ClickOutsideWrapper } from '../ClickOutsideWrapper/ClickOutsideWrapper'; @@ -63,11 +64,10 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => { display: flex; `, caretIcon: css` - margin-left: 3px; - - i { - font-size: ${theme.typography.size.md}; - } + margin-left: ${theme.spacing.xs}; + `, + clockIcon: css` + margin-right: ${theme.spacing.xs}; `, noRightBorderStyle: css` label: noRightBorderStyle; @@ -144,7 +144,7 @@ export class UnthemedTimePicker extends PureComponent { const styles = getStyles(theme); const hasAbsolute = isDateTime(value.raw.from) || isDateTime(value.raw.to); const syncedTimePicker = timeSyncButton && isSynced; - const timePickerIconClass = cx('fa fa-clock-o fa-fw', { ['icon-brand-gradient']: syncedTimePicker }); + const timePickerIconClass = cx({ ['icon-brand-gradient']: syncedTimePicker }); const timePickerButtonClass = cx('btn navbar-button navbar-button--tight', { [`btn--radius-right-0 ${styles.noRightBorderStyle}`]: !!timeSyncButton, [`explore-active-button`]: syncedTimePicker, @@ -155,17 +155,15 @@ export class UnthemedTimePicker extends PureComponent {
{hasAbsolute && ( )}
} placement="bottom"> {isOpen && ( @@ -186,13 +184,13 @@ export class UnthemedTimePicker extends PureComponent { {hasAbsolute && ( )}
diff --git a/packages/grafana-ui/src/components/TimePicker/TimePickerContent/TimePickerContent.tsx b/packages/grafana-ui/src/components/TimePicker/TimePickerContent/TimePickerContent.tsx index 990c2a7a76b..223d525b0c7 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimePickerContent/TimePickerContent.tsx +++ b/packages/grafana-ui/src/components/TimePicker/TimePickerContent/TimePickerContent.tsx @@ -3,6 +3,7 @@ import { useMedia } from 'react-use'; import { css } from 'emotion'; import { useTheme, stylesFactory } from '../../../themes'; import { GrafanaTheme, TimeOption, TimeRange, TimeZone, isDateTime } from '@grafana/data'; +import { Icon } from '../../Icon/Icon'; import { TimePickerTitle } from './TimePickerTitle'; import { TimeRangeForm } from './TimeRangeForm'; import { CustomScrollbar } from '../../CustomScrollbar/CustomScrollbar'; @@ -193,7 +194,7 @@ const NarrowScreenForm: React.FC = props => { <>
setCollapsed(!collapsed)}> Absolute time range - {collapsed ? : } + {}
{collapsed && (
diff --git a/packages/grafana-ui/src/components/TimePicker/__snapshots__/TimePicker.test.tsx.snap b/packages/grafana-ui/src/components/TimePicker/__snapshots__/TimePicker.test.tsx.snap index 6fe2d63d5db..65ee7a7a791 100644 --- a/packages/grafana-ui/src/components/TimePicker/__snapshots__/TimePicker.test.tsx.snap +++ b/packages/grafana-ui/src/components/TimePicker/__snapshots__/TimePicker.test.tsx.snap @@ -11,8 +11,8 @@ exports[`TimePicker renders buttons correctly 1`] = ` className="btn navbar-button navbar-button--tight" onClick={[Function]} > -
@@ -38,8 +38,9 @@ exports[`TimePicker renders buttons correctly 1`] = ` className="btn navbar-button navbar-button--tight" onClick={[Function]} > - - @@ -289,8 +290,8 @@ exports[`TimePicker renders buttons correctly 1`] = ` className="btn navbar-button navbar-button--tight" onClick={[Function]} > - - @@ -321,8 +322,8 @@ exports[`TimePicker renders content correctly after beeing open 1`] = ` className="btn navbar-button navbar-button--tight" onClick={[Function]} > -
@@ -348,8 +349,9 @@ exports[`TimePicker renders content correctly after beeing open 1`] = ` className="btn navbar-button navbar-button--tight" onClick={[Function]} > - - @@ -804,8 +806,8 @@ exports[`TimePicker renders content correctly after beeing open 1`] = ` className="btn navbar-button navbar-button--tight" onClick={[Function]} > - - diff --git a/packages/grafana-ui/src/components/ValuePicker/ValuePicker.tsx b/packages/grafana-ui/src/components/ValuePicker/ValuePicker.tsx index 6259fe35817..9b7199dd7fb 100644 --- a/packages/grafana-ui/src/components/ValuePicker/ValuePicker.tsx +++ b/packages/grafana-ui/src/components/ValuePicker/ValuePicker.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { IconType } from '../Icon/types'; +import { IconName } from '../../types'; import { SelectableValue } from '@grafana/data'; import { Button, ButtonVariant } from '../Button'; import { Select } from '../Select/Select'; @@ -9,7 +9,7 @@ interface ValuePickerProps { /** Label to display on the picker button */ label: string; /** Icon to display on the picker button */ - icon?: IconType; + icon?: IconName; /** ValuePicker options */ options: Array>; onChange: (value: SelectableValue) => void; diff --git a/packages/grafana-ui/src/types/icon.ts b/packages/grafana-ui/src/types/icon.ts new file mode 100644 index 00000000000..9361f2d53d6 --- /dev/null +++ b/packages/grafana-ui/src/types/icon.ts @@ -0,0 +1,128 @@ +export type IconType = 'mono' | 'default'; + +export type IconName = + | 'question-circle' + | 'plus' + | 'angle-up' + | 'angle-down' + | 'angle-left' + | 'angle-right' + | 'pen' + | 'plane' + | 'power' + | 'trash-alt' + | 'exclamation-triangle' + | 'times' + | 'step-backward' + | 'square-shape' + | 'share-alt' + | 'forward' + | 'check' + | 'add-panel' + | 'copy' + | 'lock' + | 'panel-add' + | 'arrow-random' + | 'arrow-from-right' + | 'keyboard' + | 'search' + | 'chart-line' + | 'search-minus' + | 'clock-nine' + | 'sync' + | 'signin' + | 'cog' + | 'bars' + | 'save' + | 'apps' + | 'folder-plus' + | 'link' + | 'upload' + | 'home-alt' + | 'compass' + | 'sliders-v-alt' + | 'bell' + | 'database' + | 'user' + | 'plug' + | 'shield' + | 'key-skeleton-alt' + | 'users-alt' + | 'graph-bar' + | 'book' + | 'bolt' + | 'comments-alt' + | 'document-info' + | 'info-circle' + | 'bug' + | 'cube' + | 'star' + | 'edit' + | 'shield' + | 'eye' + | 'monitor' + | 'favorite'; + +export const getAvailableIcons = (): IconName[] => [ + 'question-circle', + 'plane', + 'plus', + 'angle-up', + 'shield', + 'angle-down', + 'angle-left', + 'angle-right', + 'pen', + 'power', + 'trash-alt', + 'exclamation-triangle', + 'times', + 'step-backward', + 'square-shape', + 'share-alt', + 'forward', + 'check', + 'add-panel', + 'copy', + 'lock', + 'panel-add', + 'arrow-random', + 'arrow-from-right', + 'keyboard', + 'search', + 'chart-line', + 'search-minus', + 'clock-nine', + 'sync', + 'signin', + 'cog', + 'bars', + 'save', + 'apps', + 'folder-plus', + 'link', + 'upload', + 'home-alt', + 'compass', + 'sliders-v-alt', + 'bell', + 'database', + 'user', + 'plug', + 'shield', + 'key-skeleton-alt', + 'users-alt', + 'graph-bar', + 'book', + 'bolt', + 'comments-alt', + 'document-info', + 'info-circle', + 'bug', + 'cube', + 'star', + 'edit', + 'eye', + 'monitor', + 'favorite', +]; diff --git a/packages/grafana-ui/src/types/index.ts b/packages/grafana-ui/src/types/index.ts index cdbfd6d82e2..3914ae5b02c 100644 --- a/packages/grafana-ui/src/types/index.ts +++ b/packages/grafana-ui/src/types/index.ts @@ -3,3 +3,4 @@ export * from './input'; export * from './completion'; export * from './storybook'; export * from './forms'; +export * from './icon'; diff --git a/packages/grafana-ui/src/utils/storybook/knobs.ts b/packages/grafana-ui/src/utils/storybook/knobs.ts index 1622ebf0d93..c9bc939c91c 100644 --- a/packages/grafana-ui/src/utils/storybook/knobs.ts +++ b/packages/grafana-ui/src/utils/storybook/knobs.ts @@ -1,5 +1,5 @@ import { select } from '@storybook/addon-knobs'; -import { getAvailableIcons } from '../../components/Icon/types'; +import { getAvailableIcons } from '../../types'; const VISUAL_GROUP = 'Visual options'; diff --git a/pkg/api/index.go b/pkg/api/index.go index 0e9e475f992..cf8efbcfc92 100644 --- a/pkg/api/index.go +++ b/pkg/api/index.go @@ -109,19 +109,19 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat if hasEditPermissionInFoldersQuery.Result { children := []*dtos.NavLink{ - {Text: "Dashboard", Icon: "gicon gicon-dashboard-new", Url: setting.AppSubUrl + "/dashboard/new"}, + {Text: "Dashboard", Icon: "apps", Url: setting.AppSubUrl + "/dashboard/new"}, } if c.OrgRole == models.ROLE_ADMIN || c.OrgRole == models.ROLE_EDITOR { - children = append(children, &dtos.NavLink{Text: "Folder", SubTitle: "Create a new folder to organize your dashboards", Id: "folder", Icon: "gicon gicon-folder-new", Url: setting.AppSubUrl + "/dashboards/folder/new"}) + children = append(children, &dtos.NavLink{Text: "Folder", SubTitle: "Create a new folder to organize your dashboards", Id: "folder", Icon: "folder-plus", Url: setting.AppSubUrl + "/dashboards/folder/new"}) } - children = append(children, &dtos.NavLink{Text: "Import", SubTitle: "Import dashboard from file or Grafana.com", Id: "import", Icon: "gicon gicon-dashboard-import", Url: setting.AppSubUrl + "/dashboard/import"}) + children = append(children, &dtos.NavLink{Text: "Import", SubTitle: "Import dashboard from file or Grafana.com", Id: "import", Icon: "upload", Url: setting.AppSubUrl + "/dashboard/import"}) data.NavTree = append(data.NavTree, &dtos.NavLink{ Text: "Create", Id: "create", - Icon: "fa fa-fw fa-plus", + Icon: "plus", Url: setting.AppSubUrl + "/dashboard/new", Children: children, SortWeight: dtos.WeightCreate, @@ -129,18 +129,18 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat } dashboardChildNavs := []*dtos.NavLink{ - {Text: "Home", Id: "home", Url: setting.AppSubUrl + "/", Icon: "gicon gicon-home", HideFromTabs: true}, + {Text: "Home", Id: "home", Url: setting.AppSubUrl + "/", Icon: "home-alt", HideFromTabs: true}, {Text: "Divider", Divider: true, Id: "divider", HideFromTabs: true}, - {Text: "Manage", Id: "manage-dashboards", Url: setting.AppSubUrl + "/dashboards", Icon: "gicon gicon-manage"}, - {Text: "Playlists", Id: "playlists", Url: setting.AppSubUrl + "/playlists", Icon: "gicon gicon-playlists"}, - {Text: "Snapshots", Id: "snapshots", Url: setting.AppSubUrl + "/dashboard/snapshots", Icon: "gicon gicon-snapshots"}, + {Text: "Manage", Id: "manage-dashboards", Url: setting.AppSubUrl + "/dashboards", Icon: "sitemap"}, + {Text: "Playlists", Id: "playlists", Url: setting.AppSubUrl + "/playlists", Icon: "presentation-play"}, + {Text: "Snapshots", Id: "snapshots", Url: setting.AppSubUrl + "/dashboard/snapshots", Icon: "camera"}, } data.NavTree = append(data.NavTree, &dtos.NavLink{ Text: "Dashboards", Id: "dashboards", SubTitle: "Manage dashboards & folders", - Icon: "gicon gicon-dashboard", + Icon: "apps", Url: setting.AppSubUrl + "/", SortWeight: dtos.WeightDashboard, Children: dashboardChildNavs, @@ -151,7 +151,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat Text: "Explore", Id: "explore", SubTitle: "Explore your data", - Icon: "gicon gicon-explore", + Icon: "compass", SortWeight: dtos.WeightExplore, Url: setting.AppSubUrl + "/explore", }) @@ -172,8 +172,8 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat HideFromMenu: true, SortWeight: dtos.WeightProfile, Children: []*dtos.NavLink{ - {Text: "Preferences", Id: "profile-settings", Url: setting.AppSubUrl + "/profile", Icon: "gicon gicon-preferences"}, - {Text: "Change Password", Id: "change-password", Url: setting.AppSubUrl + "/profile/password", Icon: "fa fa-fw fa-lock", HideFromMenu: true}, + {Text: "Preferences", Id: "profile-settings", Url: setting.AppSubUrl + "/profile", Icon: "sliders-v-alt"}, + {Text: "Change Password", Id: "change-password", Url: setting.AppSubUrl + "/profile/password", Icon: "lock", HideFromMenu: true}, }, } @@ -183,7 +183,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat Text: "Sign out", Id: "sign-out", Url: setting.AppSubUrl + "/logout", - Icon: "fa fa-fw fa-sign-out", + Icon: "arrow-from-right", Target: "_self", HideFromTabs: true, }) @@ -194,15 +194,15 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat if setting.AlertingEnabled && (c.OrgRole == models.ROLE_ADMIN || c.OrgRole == models.ROLE_EDITOR) { alertChildNavs := []*dtos.NavLink{ - {Text: "Alert Rules", Id: "alert-list", Url: setting.AppSubUrl + "/alerting/list", Icon: "gicon gicon-alert-rules"}, - {Text: "Notification channels", Id: "channels", Url: setting.AppSubUrl + "/alerting/notifications", Icon: "gicon gicon-alert-notification-channel"}, + {Text: "Alert Rules", Id: "alert-list", Url: setting.AppSubUrl + "/alerting/list", Icon: "list-ul"}, + {Text: "Notification channels", Id: "channels", Url: setting.AppSubUrl + "/alerting/notifications", Icon: "comment-alt-share"}, } data.NavTree = append(data.NavTree, &dtos.NavLink{ Text: "Alerting", SubTitle: "Alert rules & notifications", Id: "alerting", - Icon: "gicon gicon-alert", + Icon: "bell", Url: setting.AppSubUrl + "/alerting/list", Children: alertChildNavs, SortWeight: dtos.WeightAlerting, @@ -259,7 +259,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat if len(appLink.Children) > 0 && c.OrgRole == models.ROLE_ADMIN { appLink.Children = append(appLink.Children, &dtos.NavLink{Divider: true}) - appLink.Children = append(appLink.Children, &dtos.NavLink{Text: "Plugin Config", Icon: "gicon gicon-cog", Url: setting.AppSubUrl + "/plugins/" + plugin.Id + "/"}) + appLink.Children = append(appLink.Children, &dtos.NavLink{Text: "Plugin Config", Icon: "cog", Url: setting.AppSubUrl + "/plugins/" + plugin.Id + "/"}) } if len(appLink.Children) > 0 { @@ -273,7 +273,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat if c.OrgRole == models.ROLE_ADMIN { configNodes = append(configNodes, &dtos.NavLink{ Text: "Data Sources", - Icon: "gicon gicon-datasources", + Icon: "database", Description: "Add and configure data sources", Id: "datasources", Url: setting.AppSubUrl + "/datasources", @@ -282,7 +282,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat Text: "Users", Id: "users", Description: "Manage org members", - Icon: "gicon gicon-user", + Icon: "user", Url: setting.AppSubUrl + "/org/users", }) } @@ -292,7 +292,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat Text: "Teams", Id: "teams", Description: "Manage org groups", - Icon: "gicon gicon-team", + Icon: "users-alt", Url: setting.AppSubUrl + "/org/teams", }) } @@ -302,7 +302,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat Text: "Plugins", Id: "plugins", Description: "View and configure plugins", - Icon: "gicon gicon-plugins", + Icon: "plug", Url: setting.AppSubUrl + "/plugins", }) @@ -310,14 +310,14 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat Text: "Preferences", Id: "org-settings", Description: "Organization preferences", - Icon: "gicon gicon-preferences", + Icon: "sliders-v-alt", Url: setting.AppSubUrl + "/org", }) configNodes = append(configNodes, &dtos.NavLink{ Text: "API Keys", Id: "apikeys", Description: "Create & manage API keys", - Icon: "gicon gicon-apikeys", + Icon: "key-skeleton-alt", Url: setting.AppSubUrl + "/org/apikeys", }) } @@ -327,7 +327,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat Id: "cfg", Text: "Configuration", SubTitle: "Organization: " + c.OrgName, - Icon: "gicon gicon-cog", + Icon: "cog", Url: configNodes[0].Url, SortWeight: dtos.WeightConfig, Children: configNodes, @@ -336,15 +336,15 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat if c.IsGrafanaAdmin { adminNavLinks := []*dtos.NavLink{ - {Text: "Users", Id: "global-users", Url: setting.AppSubUrl + "/admin/users", Icon: "gicon gicon-user"}, - {Text: "Orgs", Id: "global-orgs", Url: setting.AppSubUrl + "/admin/orgs", Icon: "gicon gicon-org"}, - {Text: "Settings", Id: "server-settings", Url: setting.AppSubUrl + "/admin/settings", Icon: "gicon gicon-preferences"}, - {Text: "Stats", Id: "server-stats", Url: setting.AppSubUrl + "/admin/stats", Icon: "fa fa-fw fa-bar-chart"}, + {Text: "Users", Id: "global-users", Url: setting.AppSubUrl + "/admin/users", Icon: "user"}, + {Text: "Orgs", Id: "global-orgs", Url: setting.AppSubUrl + "/admin/orgs", Icon: "building"}, + {Text: "Settings", Id: "server-settings", Url: setting.AppSubUrl + "/admin/settings", Icon: "sliders-v-alt"}, + {Text: "Stats", Id: "server-stats", Url: setting.AppSubUrl + "/admin/stats", Icon: "graph-bar"}, } if setting.LDAPEnabled { adminNavLinks = append(adminNavLinks, &dtos.NavLink{ - Text: "LDAP", Id: "ldap", Url: setting.AppSubUrl + "/admin/ldap", Icon: "fa fa-fw fa-address-book-o", + Text: "LDAP", Id: "ldap", Url: setting.AppSubUrl + "/admin/ldap", Icon: "book", }) } @@ -353,7 +353,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat SubTitle: "Manage all users & orgs", HideFromTabs: true, Id: "admin", - Icon: "gicon gicon-shield", + Icon: "shield", Url: setting.AppSubUrl + "/admin/users", SortWeight: dtos.WeightAdmin, Children: adminNavLinks, @@ -365,7 +365,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat SubTitle: fmt.Sprintf(`%s v%s (%s)`, setting.ApplicationName, setting.BuildVersion, setting.BuildCommit), Id: "help", Url: "#", - Icon: "gicon gicon-question", + Icon: "question-circle", HideFromMenu: true, SortWeight: dtos.WeightHelp, Children: []*dtos.NavLink{}, diff --git a/pkg/services/licensing/oss.go b/pkg/services/licensing/oss.go index d644a192994..a903567d95a 100644 --- a/pkg/services/licensing/oss.go +++ b/pkg/services/licensing/oss.go @@ -44,7 +44,7 @@ func (l *OSSLicensingService) Init() error { Text: "Upgrade", Id: "upgrading", Url: l.LicenseURL(req.SignedInUser), - Icon: "fa fa-fw fa-unlock-alt", + Icon: "unlock", }) } } diff --git a/public/app/core/components/Footer/Footer.tsx b/public/app/core/components/Footer/Footer.tsx index b5633c8eb60..f3641e1177d 100644 --- a/public/app/core/components/Footer/Footer.tsx +++ b/public/app/core/components/Footer/Footer.tsx @@ -12,19 +12,19 @@ export let getFooterLinks = (): FooterLink[] => { return [ { text: 'Documentation', - icon: 'fa fa-file-code-o', + icon: 'document-info', url: 'https://grafana.com/docs/grafana/latest/?utm_source=grafana_footer', target: '_blank', }, { text: 'Support', - icon: 'fa fa-support', + icon: 'question-circle', url: 'https://grafana.com/products/enterprise/?utm_source=grafana_footer', target: '_blank', }, { text: 'Community', - icon: 'fa fa-comments-o', + icon: 'comments-alt', url: 'https://community.grafana.com/?utm_source=grafana_footer', target: '_blank', }, diff --git a/public/app/core/components/OrgSwitcher.tsx b/public/app/core/components/OrgSwitcher.tsx index 39b13958d7a..6fab2a0f284 100644 --- a/public/app/core/components/OrgSwitcher.tsx +++ b/public/app/core/components/OrgSwitcher.tsx @@ -47,7 +47,7 @@ export class OrgSwitcher extends React.PureComponent { const currentOrgId = contextSrv.user.orgId; return ( - + diff --git a/public/app/core/components/sidemenu/BottomNavLinks.tsx b/public/app/core/components/sidemenu/BottomNavLinks.tsx index 03c640c8ea6..d04f1275d9a 100644 --- a/public/app/core/components/sidemenu/BottomNavLinks.tsx +++ b/public/app/core/components/sidemenu/BottomNavLinks.tsx @@ -1,7 +1,9 @@ import React, { PureComponent } from 'react'; +import { css } from 'emotion'; import appEvents from '../../app_events'; import { User } from '../../services/context_srv'; import { NavModelItem } from '@grafana/data'; +import { Icon, IconName } from '@grafana/ui'; import { CoreEvents } from 'app/types'; import { OrgSwitcher } from '../OrgSwitcher'; import { getFooterLinks } from '../Footer/Footer'; @@ -15,7 +17,7 @@ interface State { showSwitcherModal: boolean; } -class BottomNavLinks extends PureComponent { +export default class BottomNavLinks extends PureComponent { state: State = { showSwitcherModal: false, }; @@ -35,6 +37,9 @@ class BottomNavLinks extends PureComponent { render() { const { link, user } = this.props; const { showSwitcherModal } = this.state; + const subMenuIconClassName = css` + margin-right: 8px; + `; let children = link.children || []; @@ -46,7 +51,7 @@ class BottomNavLinks extends PureComponent {
- {link.icon && } + {link.icon && } {link.img && } @@ -64,7 +69,7 @@ class BottomNavLinks extends PureComponent {
{user.orgName}
- + Switch
@@ -77,7 +82,7 @@ class BottomNavLinks extends PureComponent { return (
  • - {child.icon && } + {child.icon && } {child.text}
  • @@ -87,7 +92,7 @@ class BottomNavLinks extends PureComponent { {link.id === 'help' && (
  • this.onOpenShortcuts()}> - Keyboard shortcuts + Keyboard shortcuts
  • )} @@ -100,5 +105,3 @@ class BottomNavLinks extends PureComponent { ); } } - -export default BottomNavLinks; diff --git a/public/app/core/components/sidemenu/DropDownChild.tsx b/public/app/core/components/sidemenu/DropDownChild.tsx index 41aa794999e..e82ebe5b17f 100644 --- a/public/app/core/components/sidemenu/DropDownChild.tsx +++ b/public/app/core/components/sidemenu/DropDownChild.tsx @@ -1,4 +1,6 @@ import React, { FC } from 'react'; +import { css } from 'emotion'; +import { Icon, IconName, useTheme } from '@grafana/ui'; export interface Props { child: any; @@ -7,11 +9,15 @@ export interface Props { const DropDownChild: FC = props => { const { child } = props; const listItemClassName = child.divider ? 'divider' : ''; + const theme = useTheme(); + const iconClassName = css` + margin-right: ${theme.spacing.sm}; + `; return (
  • - {child.icon && } + {child.icon && } {child.text}
  • diff --git a/public/app/core/components/sidemenu/SideMenu.tsx b/public/app/core/components/sidemenu/SideMenu.tsx index fc3cf6035b6..1a0496c089e 100644 --- a/public/app/core/components/sidemenu/SideMenu.tsx +++ b/public/app/core/components/sidemenu/SideMenu.tsx @@ -5,6 +5,7 @@ import BottomSection from './BottomSection'; import config from 'app/core/config'; import { CoreEvents } from 'app/types'; import { Branding } from 'app/core/components/Branding/Branding'; +import { Icon } from '@grafana/ui'; const homeUrl = config.appSubUrl || '/'; @@ -19,9 +20,9 @@ export class SideMenu extends PureComponent { ,
    - + - +  Close
    , diff --git a/public/app/core/components/sidemenu/TopSectionItem.tsx b/public/app/core/components/sidemenu/TopSectionItem.tsx index 0aca32c3ba3..e9b3649b873 100644 --- a/public/app/core/components/sidemenu/TopSectionItem.tsx +++ b/public/app/core/components/sidemenu/TopSectionItem.tsx @@ -1,5 +1,6 @@ import React, { FC } from 'react'; import SideMenuDropDown from './SideMenuDropDown'; +import { Icon } from '@grafana/ui'; export interface Props { link: any; @@ -11,7 +12,7 @@ const TopSectionItem: FC = props => {
    - + {link.img && } diff --git a/public/app/core/components/sidemenu/__snapshots__/BottomNavLinks.test.tsx.snap b/public/app/core/components/sidemenu/__snapshots__/BottomNavLinks.test.tsx.snap index 083a7a54a3e..194168b0c8d 100644 --- a/public/app/core/components/sidemenu/__snapshots__/BottomNavLinks.test.tsx.snap +++ b/public/app/core/components/sidemenu/__snapshots__/BottomNavLinks.test.tsx.snap @@ -118,8 +118,9 @@ exports[`Render should render organization switcher 1`] = `
    - Switch
    diff --git a/public/app/core/components/sidemenu/__snapshots__/DropDownChild.test.tsx.snap b/public/app/core/components/sidemenu/__snapshots__/DropDownChild.test.tsx.snap index fcfd8ea936a..1c5cd7f16c4 100644 --- a/public/app/core/components/sidemenu/__snapshots__/DropDownChild.test.tsx.snap +++ b/public/app/core/components/sidemenu/__snapshots__/DropDownChild.test.tsx.snap @@ -13,8 +13,9 @@ exports[`Render should render icon if exists 1`] = ` className="" > - diff --git a/public/app/core/components/sidemenu/__snapshots__/SideMenu.test.tsx.snap b/public/app/core/components/sidemenu/__snapshots__/SideMenu.test.tsx.snap index 859fc89ec1c..5ad4b33d432 100644 --- a/public/app/core/components/sidemenu/__snapshots__/SideMenu.test.tsx.snap +++ b/public/app/core/components/sidemenu/__snapshots__/SideMenu.test.tsx.snap @@ -14,14 +14,14 @@ Array [ key="hamburger" onClick={[Function]} > - -  Close diff --git a/public/app/core/components/sidemenu/__snapshots__/TopSectionItem.test.tsx.snap b/public/app/core/components/sidemenu/__snapshots__/TopSectionItem.test.tsx.snap index d79e9171581..3c8cb548cf9 100644 --- a/public/app/core/components/sidemenu/__snapshots__/TopSectionItem.test.tsx.snap +++ b/public/app/core/components/sidemenu/__snapshots__/TopSectionItem.test.tsx.snap @@ -10,7 +10,9 @@ exports[`Render should render component 1`] = ` - + Documentation @@ -177,7 +177,7 @@ exports[`ServerStats Should render table with stats 1`] = ` target="_blank" > Support @@ -190,7 +190,7 @@ exports[`ServerStats Should render table with stats 1`] = ` target="_blank" > Community diff --git a/public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.tsx b/public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.tsx index 085ad5c6393..2c8077c310b 100644 --- a/public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.tsx +++ b/public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.tsx @@ -2,6 +2,7 @@ import React from 'react'; import _ from 'lodash'; import { LocationUpdate } from '@grafana/runtime'; +import { Icon, IconName } from '@grafana/ui'; import { e2e } from '@grafana/e2e'; import { connect, MapDispatchToProps } from 'react-redux'; // Utils @@ -139,7 +140,7 @@ export class AddPanelWidgetUnconnected extends React.Component { dashboard.removePanel(this.props.panel); }; - renderOptionLink = (icon: string, text: string, onClick: any) => { + renderOptionLink = (icon: IconName, text: string, onClick: any) => { return (
    { aria-label={e2e.pages.AddDashboard.selectors.ctaButtons(text)} >
    - +
    {text}
    @@ -164,16 +165,16 @@ export class AddPanelWidgetUnconnected extends React.Component {
    - + New Panel
    - {this.renderOptionLink('queries', 'Add Query', this.onCreateNewPanel)} - {this.renderOptionLink('visualization', 'Choose Visualization', () => + {this.renderOptionLink('search', 'Add Query', this.onCreateNewPanel)} + {this.renderOptionLink('chart-line', 'Choose Visualization', () => this.onCreateNewPanel('visualization') )}
    diff --git a/public/app/features/dashboard/components/AddPanelWidget/__snapshots__/AddPanelWidget.test.tsx.snap b/public/app/features/dashboard/components/AddPanelWidget/__snapshots__/AddPanelWidget.test.tsx.snap index d14e438d833..18e59ec0f3a 100644 --- a/public/app/features/dashboard/components/AddPanelWidget/__snapshots__/AddPanelWidget.test.tsx.snap +++ b/public/app/features/dashboard/components/AddPanelWidget/__snapshots__/AddPanelWidget.test.tsx.snap @@ -10,8 +10,16 @@ exports[`Render should render component 1`] = `
    - -
    @@ -43,8 +51,9 @@ exports[`Render should render component 1`] = `
    -
    @@ -62,8 +71,9 @@ exports[`Render should render component 1`] = `
    -
    diff --git a/public/app/features/dashboard/components/DashNav/DashNav.tsx b/public/app/features/dashboard/components/DashNav/DashNav.tsx index ff5a9f76f63..40adb371c03 100644 --- a/public/app/features/dashboard/components/DashNav/DashNav.tsx +++ b/public/app/features/dashboard/components/DashNav/DashNav.tsx @@ -1,6 +1,7 @@ // Libaries import React, { PureComponent } from 'react'; import { connect } from 'react-redux'; +import { css } from 'emotion'; import { e2e } from '@grafana/e2e'; // Utils & Services import { appEvents } from 'app/core/app_events'; @@ -8,7 +9,7 @@ import { PlaylistSrv } from 'app/features/playlist/playlist_srv'; // Components import { DashNavButton } from './DashNavButton'; import { DashNavTimeControls } from './DashNavTimeControls'; -import { ModalsController } from '@grafana/ui'; +import { ModalsController, Icon } from '@grafana/ui'; import { BackButton } from 'app/core/components/BackButton/BackButton'; // State import { updateLocation } from 'app/core/actions'; @@ -34,7 +35,7 @@ export interface StateProps { type Props = StateProps & OwnProps; -export class DashNav extends PureComponent { +class DashNav extends PureComponent { playlistSrv: PlaylistSrv; constructor(props: Props) { @@ -95,6 +96,10 @@ export class DashNav extends PureComponent { renderDashboardTitleSearchButton() { const { dashboard, isFullscreen } = this.props; + /* Hard-coded value so we don't have to wrap whole component in withTheme because of 1 variable */ + const iconClassName = css` + margin-right: 8px; + `; const folderTitle = dashboard.meta.folderTitle; const haveFolder = dashboard.meta.folderId > 0; @@ -103,17 +108,17 @@ export class DashNav extends PureComponent { <>
    - {!isFullscreen && } + {!isFullscreen && } {haveFolder && ( <> {folderTitle} - + )} - {dashboard.title} + {dashboard.title}
    @@ -146,39 +151,33 @@ export class DashNav extends PureComponent {
    )}
    - {canSave && ( - - )} + {canSave && } {canStar && ( )} @@ -189,7 +188,7 @@ export class DashNav extends PureComponent { { showModal(ShareModal, { dashboard, @@ -207,7 +206,7 @@ export class DashNav extends PureComponent { { showModal(SaveDashboardModalProxy, { dashboard, @@ -223,7 +222,7 @@ export class DashNav extends PureComponent { )} @@ -232,19 +231,14 @@ export class DashNav extends PureComponent { )}
    - +
    {!dashboard.timepicker.hidden && ( diff --git a/public/app/features/dashboard/components/DashNav/DashNavButton.tsx b/public/app/features/dashboard/components/DashNav/DashNavButton.tsx index 1a170994897..fcb484593fc 100644 --- a/public/app/features/dashboard/components/DashNav/DashNavButton.tsx +++ b/public/app/features/dashboard/components/DashNav/DashNavButton.tsx @@ -1,19 +1,28 @@ // Libraries import React, { FunctionComponent } from 'react'; // Components -import { Tooltip } from '@grafana/ui'; +import { Tooltip, Icon, IconName, IconType } from '@grafana/ui'; import { e2e } from '@grafana/e2e'; interface Props { - icon?: string; + icon?: IconName; tooltip: string; classSuffix?: string; onClick?: () => void; href?: string; children?: React.ReactNode; + iconType?: IconType; } -export const DashNavButton: FunctionComponent = ({ icon, tooltip, classSuffix, onClick, href, children }) => { +export const DashNavButton: FunctionComponent = ({ + icon, + iconType, + tooltip, + classSuffix, + onClick, + href, + children, +}) => { if (onClick) { return ( @@ -22,7 +31,7 @@ export const DashNavButton: FunctionComponent = ({ icon, tooltip, classSu onClick={onClick} aria-label={e2e.pages.Dashboard.Toolbar.selectors.toolbarItems(tooltip)} > - {icon && } + {icon && } {children} @@ -32,7 +41,7 @@ export const DashNavButton: FunctionComponent = ({ icon, tooltip, classSu return ( - {icon && } + {icon && } {children} diff --git a/public/app/features/dashboard/components/Inspector/InspectHeader.tsx b/public/app/features/dashboard/components/Inspector/InspectHeader.tsx index 61a27a15664..df808220d7c 100644 --- a/public/app/features/dashboard/components/Inspector/InspectHeader.tsx +++ b/public/app/features/dashboard/components/Inspector/InspectHeader.tsx @@ -33,7 +33,7 @@ export const InspectHeader: FC = ({
    - +
    diff --git a/public/app/features/dashboard/components/PanelEditor/OptionsGroup.tsx b/public/app/features/dashboard/components/PanelEditor/OptionsGroup.tsx index 106e98a35ac..d851ceb3637 100644 --- a/public/app/features/dashboard/components/PanelEditor/OptionsGroup.tsx +++ b/public/app/features/dashboard/components/PanelEditor/OptionsGroup.tsx @@ -17,7 +17,7 @@ export const OptionsGroup: FC = ({ title, children }) => {
    toggleExpand(!isExpanded)}> {title}
    - +
    {isExpanded &&
    {children}
    } diff --git a/public/app/features/dashboard/components/ShareModal/ShareModal.tsx b/public/app/features/dashboard/components/ShareModal/ShareModal.tsx index efe68781a3f..0466f8eaf2d 100644 --- a/public/app/features/dashboard/components/ShareModal/ShareModal.tsx +++ b/public/app/features/dashboard/components/ShareModal/ShareModal.tsx @@ -101,7 +101,7 @@ export class ShareModal extends React.Component { return ( { {notice.inspect ? (
    this.openInspect(e, notice.inspect!)}> - +
    ) : ( - + )}
    @@ -163,7 +163,8 @@ export class PanelHeader extends Component { {Object.values(notices).map(this.renderNotice)} - {title} + {title} + {this.state.panelMenuOpen && ( @@ -172,7 +173,7 @@ export class PanelHeader extends Component { )} {data.request && data.request.timeInfo && ( - {data.request.timeInfo} + {data.request.timeInfo} )}
    diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem.tsx index 5682217df96..6f27f3ed01d 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem.tsx @@ -1,5 +1,7 @@ import React, { FC } from 'react'; +import { css } from 'emotion'; import { PanelMenuItem } from '@grafana/data'; +import { Icon, IconName, useTheme } from '@grafana/ui'; import { e2e } from '@grafana/e2e'; interface Props { @@ -9,19 +11,37 @@ interface Props { export const PanelHeaderMenuItem: FC = props => { const isSubMenu = props.type === 'submenu'; const isDivider = props.type === 'divider'; + const theme = useTheme(); + const menuIconClassName = css` + margin-right: ${theme.spacing.sm}; + a::after { + display: none; + } + `; + const shortcutIconClassName = css` + position: absolute; + margin-top: 3px; + right: ${theme.spacing.xs}; + color: ${theme.colors.textWeak}; + `; return isDivider ? (
  • ) : (
  • - {props.iconClassName && } + {props.iconClassName && } {props.text} + {isSubMenu && } - {props.shortcut && {props.shortcut}} + {props.shortcut && ( + + {props.shortcut} + + )} {props.children}
  • diff --git a/public/app/features/dashboard/utils/getPanelMenu.test.ts b/public/app/features/dashboard/utils/getPanelMenu.test.ts index 1b24bdf2305..9e7f531237d 100644 --- a/public/app/features/dashboard/utils/getPanelMenu.test.ts +++ b/public/app/features/dashboard/utils/getPanelMenu.test.ts @@ -10,31 +10,31 @@ describe('getPanelMenu', () => { expect(menuItems).toMatchInlineSnapshot(` Array [ Object { - "iconClassName": "gicon gicon-viewer", + "iconClassName": "eye", "onClick": [Function], "shortcut": "v", "text": "View", }, Object { - "iconClassName": "gicon gicon-editor", + "iconClassName": "edit", "onClick": [Function], "shortcut": "e", "text": "Edit", }, Object { - "iconClassName": "fa fa-fw fa-share", + "iconClassName": "share-alt", "onClick": [Function], "shortcut": "p s", "text": "Share", }, Object { - "iconClassName": "fa fa-fw fa-info-circle", + "iconClassName": "info-circle", "onClick": [Function], "shortcut": "p i", "text": "Inspect", }, Object { - "iconClassName": "fa fa-fw fa-cube", + "iconClassName": "cube", "onClick": [Function], "subMenu": Array [ Object { @@ -58,7 +58,7 @@ describe('getPanelMenu', () => { "type": "divider", }, Object { - "iconClassName": "fa fa-fw fa-trash", + "iconClassName": "trash-alt", "onClick": [Function], "shortcut": "p r", "text": "Remove", diff --git a/public/app/features/dashboard/utils/getPanelMenu.ts b/public/app/features/dashboard/utils/getPanelMenu.ts index 44a9360a301..e8e9ca79994 100644 --- a/public/app/features/dashboard/utils/getPanelMenu.ts +++ b/public/app/features/dashboard/utils/getPanelMenu.ts @@ -106,7 +106,7 @@ export function getPanelMenu( menu.push({ text: 'View', - iconClassName: 'gicon gicon-viewer', + iconClassName: 'eye', onClick: onViewPanel, shortcut: 'v', }); @@ -114,7 +114,7 @@ export function getPanelMenu( if (dashboard.canEditPanel(panel)) { menu.push({ text: 'Edit', - iconClassName: 'gicon gicon-editor', + iconClassName: 'edit', onClick: onEditPanel, shortcut: 'e', }); @@ -122,7 +122,7 @@ export function getPanelMenu( menu.push({ text: 'Share', - iconClassName: 'fa fa-fw fa-share', + iconClassName: 'share-alt', onClick: onSharePanel, shortcut: 'p s', }); @@ -130,7 +130,7 @@ export function getPanelMenu( if (contextSrv.hasAccessToExplore() && !(panel.plugin && panel.plugin.meta.skipDataQuery)) { menu.push({ text: 'Explore', - iconClassName: 'gicon gicon-explore', + iconClassName: 'compass', shortcut: 'x', onClick: onNavigateToExplore, }); @@ -138,7 +138,7 @@ export function getPanelMenu( menu.push({ text: 'Inspect', - iconClassName: 'fa fa-fw fa-info-circle', + iconClassName: 'info-circle', onClick: onInspectPanel, shortcut: 'p i', }); @@ -146,7 +146,7 @@ export function getPanelMenu( if (config.featureToggles.newEdit) { menu.push({ text: 'New edit', - iconClassName: 'gicon gicon-editor', + iconClassName: 'edit', onClick: onNewEditPanel, shortcut: 'p i', }); @@ -198,7 +198,7 @@ export function getPanelMenu( menu.push({ type: 'submenu', text: 'More...', - iconClassName: 'fa fa-fw fa-cube', + iconClassName: 'cube', subMenu: subMenu, onClick: onMore, }); @@ -208,7 +208,7 @@ export function getPanelMenu( menu.push({ text: 'Remove', - iconClassName: 'fa fa-fw fa-trash', + iconClassName: 'trash-alt', onClick: onRemovePanel, shortcut: 'p r', }); diff --git a/public/app/features/search/components/SearchItem.tsx b/public/app/features/search/components/SearchItem.tsx index 095b512f74b..c22407f3def 100644 --- a/public/app/features/search/components/SearchItem.tsx +++ b/public/app/features/search/components/SearchItem.tsx @@ -54,7 +54,7 @@ export const SearchItem: FC = ({ item, editable, onToggleSelection, onTag > - +
    {item.title} {item.folderTitle} diff --git a/public/app/features/search/components/SearchResults.tsx b/public/app/features/search/components/SearchResults.tsx index 9ffb85103f6..72da1d8ab7a 100644 --- a/public/app/features/search/components/SearchResults.tsx +++ b/public/app/features/search/components/SearchResults.tsx @@ -1,8 +1,7 @@ import React, { FC } from 'react'; import { css, cx } from 'emotion'; import { GrafanaTheme } from '@grafana/data'; -import { Icon, stylesFactory, useTheme } from '@grafana/ui'; -import { IconType } from '@grafana/ui/src/components/Icon/types'; +import { Icon, IconName, stylesFactory, useTheme } from '@grafana/ui'; import { DashboardSection, ItemClickWithEvent } from '../types'; import { SearchItem } from './SearchItem'; import { SearchCheckbox } from './SearchCheckbox'; @@ -99,7 +98,7 @@ const SectionHeader: FC = ({ section, onSectionClick, onTogg checked={section.checked} onClick={(e: MouseEvent) => onToggleSelection(section, e)} /> - + {section.title} {section.url && ( diff --git a/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.tsx b/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.tsx index 8d67d56b31e..8c20c57deed 100644 --- a/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.tsx @@ -17,7 +17,7 @@ export function PromExploreExtraField(props: PromExploreExtraFieldProps) { const { label, onChangeFunc, onKeyDownFunc, value, hasTooltip, tooltipContent } = props; return ( -
    +
    {label} diff --git a/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx b/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx index 4487137a954..2a6dcc95467 100644 --- a/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx @@ -1,8 +1,7 @@ import React from 'react'; -import { mount, shallow } from 'enzyme'; +import { shallow } from 'enzyme'; import { act } from 'react-dom/test-utils'; import PromExploreQueryEditor from './PromExploreQueryEditor'; -import { PromExploreExtraField } from './PromExploreExtraField'; import { PrometheusDatasource } from '../datasource'; import { PromQuery } from '../types'; import { LoadingState, PanelData, toUtc } from '@grafana/data'; @@ -81,8 +80,8 @@ describe('PromExploreQueryEditor', () => { it('should render PromQueryField with ExtraFieldElement', async () => { // @ts-ignore strict null errpr TS2345: Argument of type '() => Promise' is not assignable to parameter of type '() => void | undefined'. await act(async () => { - const wrapper = setup(mount); - expect(wrapper.find(PromExploreExtraField).length).toBe(1); + const wrapper = setup(shallow); + expect(wrapper.html()).toContain('aria-label="Prometheus extra field"'); }); }); }); diff --git a/public/app/plugins/datasource/prometheus/components/__snapshots__/PromExploreExtraField.test.tsx.snap b/public/app/plugins/datasource/prometheus/components/__snapshots__/PromExploreExtraField.test.tsx.snap index 3f10e3ec74a..9bc6d1896f1 100644 --- a/public/app/plugins/datasource/prometheus/components/__snapshots__/PromExploreExtraField.test.tsx.snap +++ b/public/app/plugins/datasource/prometheus/components/__snapshots__/PromExploreExtraField.test.tsx.snap @@ -2,6 +2,7 @@ exports[`PrometheusExploreExtraField should render component 1`] = `
    {
    @@ -54,7 +54,7 @@ interface HomeLinkProps { title: string; url: string; target?: string; - icon: string; + icon: IconName; } export const HomeLink: FC = ({ title, url, target, icon }) => { @@ -62,7 +62,7 @@ export const HomeLink: FC = ({ title, url, target, icon }) => { return ( - + {title} ); @@ -89,7 +89,7 @@ export const getStyles = stylesFactory(() => { padding: ${theme.spacing.md}; `, icon: css` - padding-right: ${theme.spacing.sm}; + margin-right: ${theme.spacing.sm}; `, footer: css` ${styleMixins.listItem(theme)} diff --git a/public/sass/components/_dropdown.scss b/public/sass/components/_dropdown.scss index 70e1e10e604..efd91ad36cb 100644 --- a/public/sass/components/_dropdown.scss +++ b/public/sass/components/_dropdown.scss @@ -260,19 +260,17 @@ margin-bottom: -2px; @include border-radius(5px 5px 5px 0); } - -// Caret to indicate there is a submenu -.dropdown-submenu > a::after { - position: absolute; - top: 35%; - right: $space-sm; - background-color: transparent; - color: $text-color-weak; - font: normal normal normal $font-size-sm/1 FontAwesome; - content: '\f0da'; - pointer-events: none; - font-size: 11px; -} +// .dropdown-submenu > a::after { +// position: absolute; +// top: 35%; +// right: $space-sm; +// background-color: transparent; +// color: $text-color-weak; +// font: normal normal normal $font-size-sm/1 FontAwesome; +// content: '\f0da'; +// pointer-events: none; +// font-size: 11px; +// } .dropdown-submenu:hover > a::after { border-left-color: $dropdownLinkColorHover; } @@ -310,14 +308,6 @@ margin-left: $spacer; color: $text-muted; min-width: 47px; - - &::before { - font-family: FontAwesome; - width: 28px; - display: inline-block; - text-align: center; - content: '\f11c'; - } } .dropdown-menu.dropdown-menu--new { diff --git a/public/sass/components/_panel_header.scss b/public/sass/components/_panel_header.scss index 9a9c1bf5b72..70ec9eb2b88 100644 --- a/public/sass/components/_panel_header.scss +++ b/public/sass/components/_panel_header.scss @@ -61,13 +61,9 @@ $panel-header-no-title-zindex: 1; .panel-menu-toggle { color: $text-color-weak; cursor: pointer; - padding: 3px 5px; + margin: 2px 0 0 2px; visibility: hidden; opacity: 0; - width: 16px; - height: 16px; - left: 1px; - top: 2px; &:hover { color: $link-hover-color; diff --git a/public/sass/components/_sidemenu.scss b/public/sass/components/_sidemenu.scss index fc06c477cc8..15f64c3c74b 100644 --- a/public/sass/components/_sidemenu.scss +++ b/public/sass/components/_sidemenu.scss @@ -116,26 +116,9 @@ $mobile-menu-breakpoint: md; width: 35px; height: 35px; display: inline-block; - - .fa, - .icon-gf, - .gicon { - color: $side-menu-link-color; - position: relative; - opacity: 0.7; - font-size: 130%; - height: 22px; - width: 22px; - } - - .fa { - top: 2px; - position: relative; - } - - .icon-gf { - top: 5px; - } + color: $side-menu-link-color; + position: relative; + opacity: 0.7; img { position: relative; diff --git a/public/test/jest-setup.ts b/public/test/jest-setup.ts index da9b22ad119..fdcc0361906 100644 --- a/public/test/jest-setup.ts +++ b/public/test/jest-setup.ts @@ -23,6 +23,15 @@ angular.module('grafana.routes', ['ngRoute']); jest.mock('app/core/core', () => ({})); jest.mock('app/features/plugins/plugin_loader', () => ({})); +/* Temporary solution as Jest can't parse Unicons imports. + * Therefore we are mocking in for all tests. Needs to be fixed before merging to master. + */ +jest.mock('@grafana/ui/src/components/Icon/Icon', () => { + return { + Icon: () => null as any, + }; +}); + configure({ adapter: new Adapter() }); const localStorageMock = (() => { diff --git a/scripts/webpack/webpack.common.js b/scripts/webpack/webpack.common.js index d8954e61ec6..f7cc9d81e62 100644 --- a/scripts/webpack/webpack.common.js +++ b/scripts/webpack/webpack.common.js @@ -7,7 +7,15 @@ function shouldExclude(filename) { return false; } - const packagesToProcessbyBabel = ['debug', 'lru-cache', 'yallist', 'apache-arrow', 'react-hook-form', 'rc-trigger']; + const packagesToProcessbyBabel = [ + 'debug', + 'lru-cache', + 'yallist', + 'apache-arrow', + 'react-hook-form', + 'rc-trigger', + '@iconscout/react-unicons', + ]; for (const package of packagesToProcessbyBabel) { if (filename.indexOf(`node_modules/${package}`) > 0) { return false;