From 431f454d57512813e153bb57e14344345c0e084d Mon Sep 17 00:00:00 2001 From: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> Date: Wed, 8 Apr 2020 14:33:31 +0200 Subject: [PATCH] @grafana/ui: Create Icon component and replace part of the icons (#23402) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Part1: Unicons implementation (#23197) * Create a new Icon component * Update icons in main sidebar * Update icons in Useful links and in react components on main site * Update icons in Useful links and in main top navigation * Adjust sizing * Update panel navigation and timepicker * Update icons in Panel menu * NewPanelEditor: Fixed so that test alert rule works in new edit mode (#23179) * Update icons in add panel widget * Resolve merge conflict * Fix part of the test errors and type errors * Fix storybook errors * Update getAvailableIcons import in storybook knobs * Fix import path * Fix SyntaxError: Cannot use import statement outside a module in test environment error * Remove dynamic imports * Remove types as using @ts-ignore * Update snapshot test * Add @iconscout/react-unicons to the shouldExclude list as it is blundled with es2015 syntax * Remove color prop from icon, remove color implemetation in mono icons * Update navbar styling * Move toPascalCase to utils/string Co-authored-by: Torkel Ödegaard * Resolve type errors resulted from merge * Part2: Unicons implementation (#23266) * Create a new Icon component * Update icons in main sidebar * Update icons in Useful links and in react components on main site * Update icons in Useful links and in main top navigation * Adjust sizing * Update panel navigation and timepicker * Update icons in Panel menu * Update icons in add panel widget * Resolve merge conflict * Fix part of the test errors and type errors * Fix storybook errors * Update getAvailableIcons import in storybook knobs * Fix import path * Fix SyntaxError: Cannot use import statement outside a module in test environment error * Remove dynamic imports * Remove types as using @ts-ignore * Update snapshot test * Add @iconscout/react-unicons to the shouldExclude list as it is blundled with es2015 syntax * Implment icons in Tabs * Implement icons in search items and empty list * Update buttons * Update button-related snapshot tests * Update icons in modals and page headers * Create anfular wrapper and update all icons on search screen * Update sizing, remove colors, update snapshot tests * Remove color prop from icon, remove color implemetation in mono icons * Remove color props from monochrome icons * Complete update of icons for search screen * Update icons for infor tooltips, playlist, permissions * Support temporarly font awesome icons used in enterprise grafana * Part1: Unicons implementation (#23197) * Create a new Icon component * Update icons in main sidebar * Update icons in Useful links and in react components on main site * Update icons in Useful links and in main top navigation * Adjust sizing * Update panel navigation and timepicker * Update icons in Panel menu * NewPanelEditor: Fixed so that test alert rule works in new edit mode (#23179) * Update icons in add panel widget * Resolve merge conflict * Fix part of the test errors and type errors * Fix storybook errors * Update getAvailableIcons import in storybook knobs * Fix import path * Fix SyntaxError: Cannot use import statement outside a module in test environment error * Remove dynamic imports * Remove types as using @ts-ignore * Update snapshot test * Add @iconscout/react-unicons to the shouldExclude list as it is blundled with es2015 syntax * Remove color prop from icon, remove color implemetation in mono icons * Update navbar styling * Move toPascalCase to utils/string Co-authored-by: Torkel Ödegaard * Icons update * Add optional chaining to for isFontAwesome variable Co-authored-by: Torkel Ödegaard * Part3: Unicons implementation (#23356) * Create a new Icon component * Update icons in main sidebar * Update icons in Useful links and in react components on main site * Update icons in Useful links and in main top navigation * Adjust sizing * Update panel navigation and timepicker * Update icons in Panel menu * Update icons in add panel widget * Resolve merge conflict * Fix part of the test errors and type errors * Fix storybook errors * Update getAvailableIcons import in storybook knobs * Fix import path * Fix SyntaxError: Cannot use import statement outside a module in test environment error * Remove dynamic imports * Remove types as using @ts-ignore * Update snapshot test * Add @iconscout/react-unicons to the shouldExclude list as it is blundled with es2015 syntax * Implment icons in Tabs * Implement icons in search items and empty list * Update buttons * Update button-related snapshot tests * Update icons in modals and page headers * Create anfular wrapper and update all icons on search screen * Update sizing, remove colors, update snapshot tests * Remove color prop from icon, remove color implemetation in mono icons * Remove color props from monochrome icons * Complete update of icons for search screen * Update icons for infor tooltips, playlist, permissions * Support temporarly font awesome icons used in enterprise grafana * Part1: Unicons implementation (#23197) * Create a new Icon component * Update icons in main sidebar * Update icons in Useful links and in react components on main site * Update icons in Useful links and in main top navigation * Adjust sizing * Update panel navigation and timepicker * Update icons in Panel menu * NewPanelEditor: Fixed so that test alert rule works in new edit mode (#23179) * Update icons in add panel widget * Resolve merge conflict * Fix part of the test errors and type errors * Fix storybook errors * Update getAvailableIcons import in storybook knobs * Fix import path * Fix SyntaxError: Cannot use import statement outside a module in test environment error * Remove dynamic imports * Remove types as using @ts-ignore * Update snapshot test * Add @iconscout/react-unicons to the shouldExclude list as it is blundled with es2015 syntax * Remove color prop from icon, remove color implemetation in mono icons * Update navbar styling * Move toPascalCase to utils/string Co-authored-by: Torkel Ödegaard * Update icons in Explore * Update icons in alerting * Update + and x buttons * Update icons in configurations and settings * Update close icons * Update icons in rich history * Update alert messages * Add optional chaining to for isFontAwesome variable * Remove icon mock, set up jest.config * Fix navbar plus icon * Fir enable-bacground to enableBackgournd Co-authored-by: Torkel Ödegaard * Merge remote branch origin master to icons-unicons * Revert "Merge remote branch origin master to icons-unicons" This reverts commit 3f25d50a39a940883fefe73ce51219139c1ed37f. * Size-up dashnav icons * Fix alerting icons, panel headers, update tests * Fix typecheck error * Adjustments - add panel icon, spacing * Set TerserPlugin sourceMap to false to prevent running out of memory when publishing storybook Co-authored-by: Torkel Ödegaard --- jest.config.js | 4 + packages/grafana-data/src/text/string.ts | 6 + .../grafana-ui/.storybook/webpack.config.js | 2 +- packages/grafana-ui/package.json | 1 + .../grafana-ui/src/components/Alert/Alert.tsx | 13 +- .../src/components/Button/Button.tsx | 11 +- .../src/components/Button/ButtonContent.tsx | 16 +- .../ButtonCascader/ButtonCascader.tsx | 2 +- .../CallToActionCard.story.tsx | 2 +- .../src/components/Cascader/Cascader.tsx | 2 +- .../src/components/Collapse/Collapse.tsx | 2 +- .../ConfirmButton/ConfirmButton.story.tsx | 2 +- .../components/ConfirmButton/DeleteButton.tsx | 2 +- .../ConfirmModal/ConfirmModal.story.tsx | 2 +- .../components/ConfirmModal/ConfirmModal.tsx | 6 +- .../components/DataLinks/DataLinksEditor.tsx | 2 +- .../DataLinksInlineEditor.tsx | 2 +- .../DataLinksListItem.tsx | 4 +- .../DataSourceSettings/TLSAuthSettings.tsx | 3 +- .../FieldConfigItemHeaderTitle.tsx | 2 +- .../src/components/FormLabel/FormLabel.tsx | 3 +- .../Forms/Legacy/Select/ButtonSelect.tsx | 5 +- .../Forms/Legacy/Select/_Select.scss | 17 +- .../grafana-ui/src/components/Icon/Icon.mdx | 10 +- .../src/components/Icon/Icon.story.tsx | 11 +- .../grafana-ui/src/components/Icon/Icon.tsx | 99 +- .../src/components/Icon/assets/Apps.tsx | 13 + .../src/components/Icon/assets/Bell.tsx | 21 + .../src/components/Icon/assets/Cog.tsx | 14 + .../src/components/Icon/assets/Favorite.tsx | 10 + .../src/components/Icon/assets/Folder.tsx | 10 + .../src/components/Icon/assets/FolderPlus.tsx | 21 + .../src/components/Icon/assets/Grafana.tsx | 70 + .../src/components/Icon/assets/Import.tsx | 23 + .../src/components/Icon/assets/PanelAdd.tsx | 49 + .../src/components/Icon/assets/PlusSquare.tsx | 21 + .../src/components/Icon/assets/Shield.tsx | 14 + .../src/components/Icon/assets/index.ts | 11 + .../grafana-ui/src/components/Icon/types.ts | 1306 ----------------- .../components/InfoTooltip/InfoTooltip.tsx | 3 +- .../src/components/Input/Input.story.tsx | 6 +- .../grafana-ui/src/components/Input/Input.tsx | 2 +- .../src/components/Logs/LogDetails.test.tsx | 6 +- .../components/Logs/LogDetailsRow.test.tsx | 11 +- .../src/components/Logs/LogDetailsRow.tsx | 17 +- .../grafana-ui/src/components/Logs/LogRow.tsx | 8 +- .../src/components/Logs/getLogRowStyles.ts | 4 +- .../grafana-ui/src/components/Modal/Modal.tsx | 7 +- .../src/components/Modal/ModalHeader.tsx | 6 +- .../src/components/Modal/ModalTabContent.tsx | 16 +- .../src/components/Modal/ModalTabsHeader.tsx | 6 +- .../PanelOptionsGroup/PanelOptionsGroup.tsx | 3 +- .../RefreshPicker/RefreshPicker.tsx | 3 +- .../src/components/Select/ButtonSelect.tsx | 12 +- .../components/Select/DropdownIndicator.tsx | 2 +- .../src/components/Select/Select.story.tsx | 4 +- .../src/components/Select/SelectBase.tsx | 2 +- .../src/components/Switch/Switch.tsx | 3 +- .../grafana-ui/src/components/Table/Table.tsx | 2 +- .../grafana-ui/src/components/Tabs/Tab.tsx | 13 +- .../ThresholdsEditorNew/ThresholdsEditor.tsx | 6 +- .../components/TimePicker/TimeOfDayPicker.tsx | 2 +- .../src/components/TimePicker/TimePicker.tsx | 24 +- .../TimePickerContent/TimePickerCalendar.tsx | 2 +- .../TimePickerContent/TimePickerContent.tsx | 3 +- .../TimePickerContent/TimeRangeForm.tsx | 2 +- .../__snapshots__/TimePicker.test.tsx.snap | 54 +- .../OrganizeFieldsTransformerEditor.tsx | 2 +- .../LegacyValueMappingsEditor.tsx | 2 +- .../ValueMappingsEditor.tsx | 2 +- .../LegacyValueMappingsEditor.test.tsx.snap | 2 +- .../components/ValuePicker/ValuePicker.tsx | 6 +- packages/grafana-ui/src/types/icon.ts | 191 +++ packages/grafana-ui/src/types/index.ts | 1 + .../grafana-ui/src/utils/storybook/knobs.ts | 2 +- pkg/api/index.go | 62 +- pkg/services/licensing/oss.go | 2 +- public/app/core/angular_wrappers.ts | 8 + .../DynamicImports/ErrorLoadingChunk.tsx | 2 +- .../components/EmptyListCTA/EmptyListCTA.tsx | 6 +- public/app/core/components/Footer/Footer.tsx | 6 +- .../LayoutSelector/LayoutSelector.tsx | 5 +- public/app/core/components/OrgSwitcher.tsx | 2 +- .../core/components/PageHeader/PageHeader.tsx | 16 +- .../PermissionList/AddPermission.tsx | 4 +- .../DisabledPermissionListItem.tsx | 6 +- .../PermissionList/PermissionListItem.tsx | 10 +- .../core/components/TagFilter/TagBadge.tsx | 4 +- .../core/components/TagFilter/TagFilter.tsx | 4 +- public/app/core/components/help/HelpModal.tsx | 5 +- public/app/core/components/info_popover.ts | 2 +- .../layout_selector/layout_selector.ts | 2 +- .../manage_dashboards/manage_dashboards.html | 68 +- public/app/core/components/search/search.html | 33 +- .../components/search/search_results.html | 47 +- .../components/sidemenu/BottomNavLinks.tsx | 17 +- .../components/sidemenu/DropDownChild.tsx | 8 +- .../app/core/components/sidemenu/SideMenu.tsx | 5 +- .../components/sidemenu/TopSectionItem.tsx | 3 +- .../BottomNavLinks.test.tsx.snap | 5 +- .../__snapshots__/DropDownChild.test.tsx.snap | 5 +- .../__snapshots__/SideMenu.test.tsx.snap | 8 +- .../TopSectionItem.test.tsx.snap | 4 +- public/app/core/controllers/invited_ctrl.ts | 2 +- .../core/controllers/reset_password_ctrl.ts | 2 +- public/app/core/controllers/signup_ctrl.ts | 2 +- .../app/features/admin/UserListAdminPage.tsx | 8 +- public/app/features/admin/UserPermissions.tsx | 4 +- .../__snapshots__/ServerStats.test.tsx.snap | 14 +- .../admin/ldap/LdapUserPermissions.tsx | 3 +- .../app/features/admin/partials/edit_org.html | 70 +- .../features/admin/partials/edit_user.html | 9 +- public/app/features/admin/partials/orgs.html | 2 +- .../app/features/alerting/AlertRuleItem.tsx | 16 +- public/app/features/alerting/AlertTab.tsx | 8 +- .../__snapshots__/AlertRuleItem.test.tsx.snap | 18 +- .../alerting/partials/alert_howto.html | 2 +- .../features/alerting/partials/alert_tab.html | 161 +- .../alerting/partials/notifications_list.html | 22 +- .../app/features/alerting/state/alertDef.ts | 12 +- .../features/alerting/state/reducers.test.ts | 10 +- .../features/annotations/partials/editor.html | 14 +- .../features/api-keys/ApiKeysAddedModal.tsx | 5 +- public/app/features/api-keys/ApiKeysPage.tsx | 6 +- .../ApiKeysAddedModal.test.tsx.snap | 8 +- .../__snapshots__/ApiKeysPage.test.tsx.snap | 6 +- .../AddPanelWidget/AddPanelWidget.tsx | 13 +- .../AddPanelWidget.test.tsx.snap | 26 +- .../components/DashLinks/editor.html | 17 +- .../dashboard/components/DashNav/DashNav.tsx | 49 +- .../components/DashNav/DashNavButton.tsx | 21 +- .../DashboardPermissions.tsx | 6 +- .../components/Inspector/InspectHeader.tsx | 2 +- .../PanelEditor/FieldConfigEditor.tsx | 2 +- .../components/PanelEditor/OptionsGroup.tsx | 2 +- .../PanelEditor/OptionsPaneContent.tsx | 11 +- .../components/PanelEditor/OverrideEditor.tsx | 2 +- .../components/PanelEditor/PanelEditor.tsx | 2 +- .../PanelEditor/PanelEditorTabs.tsx | 4 +- .../components/RowOptions/template.html | 2 +- .../components/ShareModal/ShareEmbed.tsx | 6 +- .../components/ShareModal/ShareExport.tsx | 6 +- .../components/ShareModal/ShareLink.tsx | 6 +- .../components/ShareModal/ShareModal.tsx | 2 +- .../components/ShareModal/ShareSnapshot.tsx | 12 +- .../TransformationsEditor.tsx | 2 +- .../UnsavedChangesModalCtrl.ts | 2 +- .../dashgrid/PanelHeader/PanelHeader.tsx | 11 +- .../PanelHeader/PanelHeaderMenuItem.tsx | 24 +- .../dashboard/utils/getPanelMenu.test.ts | 12 +- .../features/dashboard/utils/getPanelMenu.ts | 16 +- .../datasources/DataSourcesListPage.tsx | 3 +- .../datasources/NewDataSourcePage.tsx | 2 +- .../app/features/explore/ExploreToolbar.tsx | 21 +- .../app/features/explore/LiveTailButton.tsx | 7 +- .../explore/NoDataSourceCallToAction.tsx | 2 +- .../features/explore/QueryRowActions.test.tsx | 4 +- .../app/features/explore/QueryRowActions.tsx | 9 +- .../app/features/explore/ResponsiveButton.tsx | 18 +- .../explore/RichHistory/RichHistory.tsx | 12 +- .../RichHistory/RichHistoryCard.test.tsx | 22 +- .../explore/RichHistory/RichHistoryCard.tsx | 26 +- .../RichHistory/RichHistorySettings.tsx | 2 +- public/app/features/explore/RunButton.tsx | 3 +- .../QueryRowActions.test.tsx.snap | 14 +- .../features/folders/FolderPermissions.tsx | 6 +- .../folders/services/FolderPageLoader.ts | 8 +- public/app/features/folders/state/navModel.ts | 8 +- .../MoveToFolderModal/template.html | 2 +- .../partials/snapshot_list.html | 15 +- public/app/features/org/SelectOrgCtrl.ts | 2 +- .../features/playlist/partials/playlist.html | 198 +-- .../playlist/partials/playlist_search.html | 55 +- .../features/playlist/partials/playlists.html | 4 +- .../plugins/partials/update_instructions.html | 2 +- public/app/features/profile/SignupPage.tsx | 2 +- .../features/profile/UserProfileEditForm.tsx | 6 +- .../features/profile/partials/profile.html | 2 +- .../search/components/SearchField.tsx | 4 +- .../features/search/components/SearchItem.tsx | 7 +- .../search/components/SearchResults.tsx | 11 +- .../search/components/SearchResultsFilter.tsx | 4 +- public/app/features/teams/TeamGroupSync.tsx | 12 +- public/app/features/teams/TeamList.tsx | 2 +- public/app/features/teams/TeamMembers.tsx | 3 +- .../__snapshots__/TeamGroupSync.test.tsx.snap | 44 +- .../__snapshots__/TeamMembers.test.tsx.snap | 8 +- .../features/templating/partials/editor.html | 2 +- public/app/features/users/InviteeRow.tsx | 3 +- public/app/features/users/SignupInvited.tsx | 2 +- public/app/features/users/UsersTable.tsx | 3 +- .../__snapshots__/UsersTable.test.tsx.snap | 24 +- .../variables/editor/VariableEditorList.tsx | 5 +- .../variables/pickers/shared/VariableLink.tsx | 8 +- .../pickers/shared/VariableOptions.tsx | 6 +- public/app/partials/confirm_modal.html | 71 +- public/app/partials/edit_json.html | 2 +- public/app/partials/valueSelectDropdown.html | 6 +- .../elasticsearch/configuration/DataLink.tsx | 2 +- .../elasticsearch/configuration/DataLinks.tsx | 2 +- .../partials/query.editor.html | 282 +++- .../graphite/FunctionEditorControls.tsx | 12 +- .../influxdb/partials/query.editor.html | 2 +- .../loki/configuration/DerivedField.tsx | 2 +- .../loki/configuration/DerivedFields.tsx | 2 +- .../opentsdb/partials/query.editor.html | 8 +- .../components/PromExploreExtraField.tsx | 2 +- .../PromExploreQueryEditor.test.tsx | 7 +- .../PromExploreExtraField.test.tsx.snap | 1 + .../stackdriver/components/LabelFilter.tsx | 2 +- .../app/plugins/panel/alertlist/module.html | 2 +- public/app/plugins/panel/dashlist/module.html | 2 +- .../panel/gettingstarted/GettingStarted.tsx | 3 +- public/app/plugins/panel/homelinks/module.tsx | 18 +- .../plugins/panel/singlestat/mappings.html | 56 +- .../plugins/panel/table/column_options.html | 198 ++- public/app/plugins/panel/table/editor.html | 2 +- public/sass/base/_icons.scss | 2 +- public/sass/components/_buttons.scss | 3 + public/sass/components/_dropdown.scss | 32 +- public/sass/components/_gf-form.scss | 4 +- public/sass/components/_modals.scss | 11 +- public/sass/components/_page_header.scss | 2 +- public/sass/components/_panel_header.scss | 6 +- public/sass/components/_search.scss | 3 + public/sass/components/_sidemenu.scss | 23 +- public/sass/layout/_page.scss | 3 +- public/sass/pages/_alerting.scss | 1 + scripts/webpack/webpack.common.js | 10 +- 229 files changed, 2161 insertions(+), 2488 deletions(-) create mode 100644 packages/grafana-ui/src/components/Icon/assets/Apps.tsx create mode 100644 packages/grafana-ui/src/components/Icon/assets/Bell.tsx create mode 100644 packages/grafana-ui/src/components/Icon/assets/Cog.tsx create mode 100644 packages/grafana-ui/src/components/Icon/assets/Favorite.tsx create mode 100644 packages/grafana-ui/src/components/Icon/assets/Folder.tsx create mode 100644 packages/grafana-ui/src/components/Icon/assets/FolderPlus.tsx create mode 100644 packages/grafana-ui/src/components/Icon/assets/Grafana.tsx create mode 100644 packages/grafana-ui/src/components/Icon/assets/Import.tsx create mode 100644 packages/grafana-ui/src/components/Icon/assets/PanelAdd.tsx create mode 100644 packages/grafana-ui/src/components/Icon/assets/PlusSquare.tsx create mode 100644 packages/grafana-ui/src/components/Icon/assets/Shield.tsx create mode 100644 packages/grafana-ui/src/components/Icon/assets/index.ts delete mode 100644 packages/grafana-ui/src/components/Icon/types.ts create mode 100644 packages/grafana-ui/src/types/icon.ts diff --git a/jest.config.js b/jest.config.js index 6bac8515183..4b2c97b20ed 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,8 +1,12 @@ +const esModule = '@iconscout/react-unicons'; + module.exports = { verbose: false, transform: { '^.+\\.(ts|tsx|js|jsx)$': 'ts-jest', + [`(${esModule}).+\\.js$`]: 'babel-jest', }, + transformIgnorePatterns: [`/node_modules/(?!${esModule})`], moduleDirectories: ['node_modules', 'public'], roots: ['/public/app', '/public/test', '/packages', '/scripts'], testRegex: '(\\.|/)(test)\\.(jsx?|tsx?)$', 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/.storybook/webpack.config.js b/packages/grafana-ui/.storybook/webpack.config.js index 3f2b43709db..e482bb449d0 100644 --- a/packages/grafana-ui/.storybook/webpack.config.js +++ b/packages/grafana-ui/.storybook/webpack.config.js @@ -82,7 +82,7 @@ module.exports = ({ config, mode }) => { new TerserPlugin({ cache: false, parallel: false, - sourceMap: true, + sourceMap: false, }), new OptimizeCSSAssetsPlugin({}), ], diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json index c1d929a5a5d..9db4b586dc1 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-beautiful-dnd": "12.1.2", "@types/react-color": "3.0.1", diff --git a/packages/grafana-ui/src/components/Alert/Alert.tsx b/packages/grafana-ui/src/components/Alert/Alert.tsx index c218a89b7e7..aabeb8619c5 100644 --- a/packages/grafana-ui/src/components/Alert/Alert.tsx +++ b/packages/grafana-ui/src/components/Alert/Alert.tsx @@ -1,4 +1,5 @@ import React, { FC, ReactNode } from 'react'; +import { Icon, IconName } from '@grafana/ui'; import classNames from 'classnames'; export type AlertVariant = 'success' | 'warning' | 'error' | 'info'; @@ -15,16 +16,16 @@ interface AlertProps { function getIconFromSeverity(severity: AlertVariant): string { switch (severity) { case 'error': { - return 'fa fa-exclamation-triangle'; + return 'exclamation-triangle'; } case 'warning': { - return 'fa fa-exclamation-triangle'; + return 'exclamation-triangle'; } case 'info': { - return 'fa fa-info-circle'; + return 'info-circle'; } case 'success': { - return 'fa fa-check'; + return 'check'; } default: return ''; @@ -37,7 +38,7 @@ export const Alert: FC = ({ title, buttonText, onButtonClick, onRemo
- +
{title}
@@ -46,7 +47,7 @@ export const Alert: FC = ({ title, buttonText, onButtonClick, onRemo {/* If onRemove is specified , giving preference to onRemove */} {onRemove && ( )} {onButtonClick && ( diff --git a/packages/grafana-ui/src/components/Button/Button.tsx b/packages/grafana-ui/src/components/Button/Button.tsx index 8c975817288..91f4bc70ccf 100644 --- a/packages/grafana-ui/src/components/Button/Button.tsx +++ b/packages/grafana-ui/src/components/Button/Button.tsx @@ -2,6 +2,7 @@ import React, { AnchorHTMLAttributes, ButtonHTMLAttributes, useContext } from 'r import { css, cx } from 'emotion'; import tinycolor from 'tinycolor2'; import { selectThemeVariant, stylesFactory, ThemeContext } from '../../themes'; +import { IconName } from '../../types'; import { getFocusStyle, getPropertiesForButtonSize } from '../Forms/commonStyles'; import { GrafanaTheme } from '@grafana/data'; import { ButtonContent } from './ButtonContent'; @@ -134,7 +135,7 @@ export type ButtonVariant = 'primary' | 'secondary' | 'destructive' | 'link'; type CommonProps = { size?: ComponentSize; variant?: ButtonVariant; - icon?: string; + icon?: IconName; className?: string; }; @@ -151,7 +152,9 @@ export const Button = React.forwardRef( return ( ); } @@ -171,7 +174,9 @@ export const LinkButton = React.forwardRef( return ( - {children} + + {children} + ); } diff --git a/packages/grafana-ui/src/components/Button/ButtonContent.tsx b/packages/grafana-ui/src/components/Button/ButtonContent.tsx index 19c540aa66d..c01de9853f3 100644 --- a/packages/grafana-ui/src/components/Button/ButtonContent.tsx +++ b/packages/grafana-ui/src/components/Button/ButtonContent.tsx @@ -1,6 +1,8 @@ import React from 'react'; import { css } from 'emotion'; import { stylesFactory, useTheme } from '../../themes'; +import { IconName } from '../../types'; +import { Icon } from '../Icon/Icon'; import { ComponentSize } from '../../types/size'; import { GrafanaTheme } from '@grafana/data'; @@ -14,8 +16,6 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => ({ `, icon: css` - position: relative; - top: 1px; & + * { margin-left: ${theme.spacing.sm}; } @@ -23,28 +23,24 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => ({ })); type Props = { - icon?: string; + icon?: IconName; className?: string; children: React.ReactNode; size?: ComponentSize; }; export function ButtonContent(props: Props) { - const { icon, children } = props; + const { icon, children, size } = props; const theme = useTheme(); const styles = getStyles(theme); if (!children) { - return ( - - - - ); + return {icon && }; } const iconElement = icon && ( - + ); 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/CallToActionCard/CallToActionCard.story.tsx b/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.story.tsx index 45aeb6d5519..4927b3e6868 100644 --- a/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.story.tsx +++ b/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.story.tsx @@ -12,7 +12,7 @@ CallToActionCardStories.add('default', () => { const ctaElements: { [key: string]: JSX.Element } = { custom:

This is just H1 tag, you can any component as CTA element

, button: ( - ), diff --git a/packages/grafana-ui/src/components/Cascader/Cascader.tsx b/packages/grafana-ui/src/components/Cascader/Cascader.tsx index 15ff668f2fe..5eb4b08c757 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/ConfirmButton/ConfirmButton.story.tsx b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.story.tsx index 5bb392d6798..920f6103486 100644 --- a/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.story.tsx +++ b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.story.tsx @@ -65,7 +65,7 @@ storiesOf('General/ConfirmButton', module) action('Saved')('save!'); }} > - diff --git a/packages/grafana-ui/src/components/ConfirmButton/DeleteButton.tsx b/packages/grafana-ui/src/components/ConfirmButton/DeleteButton.tsx index 91875d7ea4a..e464afe98c2 100644 --- a/packages/grafana-ui/src/components/ConfirmButton/DeleteButton.tsx +++ b/packages/grafana-ui/src/components/ConfirmButton/DeleteButton.tsx @@ -18,7 +18,7 @@ export const DeleteButton: FC = ({ size, disabled, onConfirm }) => { disabled={disabled} onConfirm={onConfirm} > - )} diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx index fd3c937b187..47825e9c53c 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx @@ -100,7 +100,7 @@ export const DataLinksInlineEditor: React.FC = ({ li )} - 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/DataSourceSettings/TLSAuthSettings.tsx b/packages/grafana-ui/src/components/DataSourceSettings/TLSAuthSettings.tsx index 6112c866a8e..dd1620e2023 100644 --- a/packages/grafana-ui/src/components/DataSourceSettings/TLSAuthSettings.tsx +++ b/packages/grafana-ui/src/components/DataSourceSettings/TLSAuthSettings.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { KeyValue } from '@grafana/data'; import { css, cx } from 'emotion'; import { Tooltip } from '../Tooltip/Tooltip'; +import { Icon } from '../Icon/Icon'; import { CertificationKey } from './CertificationKey'; import { HttpSettingsBaseProps } from './types'; @@ -47,7 +48,7 @@ export const TLSAuthSettings: React.FC = ({ dataSourceCon theme="info" >
- +
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/FormLabel/FormLabel.tsx b/packages/grafana-ui/src/components/FormLabel/FormLabel.tsx index b4fc429727f..ca3fd9bf4f5 100644 --- a/packages/grafana-ui/src/components/FormLabel/FormLabel.tsx +++ b/packages/grafana-ui/src/components/FormLabel/FormLabel.tsx @@ -1,6 +1,7 @@ import React, { FunctionComponent, ReactNode } from 'react'; import classNames from 'classnames'; import { Tooltip, PopoverContent } from '../Tooltip/Tooltip'; +import { Icon } from '../Icon/Icon'; interface Props { children: ReactNode; @@ -33,7 +34,7 @@ export const FormLabel: FunctionComponent = ({ {tooltip && (
- +
)} diff --git a/packages/grafana-ui/src/components/Forms/Legacy/Select/ButtonSelect.tsx b/packages/grafana-ui/src/components/Forms/Legacy/Select/ButtonSelect.tsx index 5ad3a55d866..4379b35d457 100644 --- a/packages/grafana-ui/src/components/Forms/Legacy/Select/ButtonSelect.tsx +++ b/packages/grafana-ui/src/components/Forms/Legacy/Select/ButtonSelect.tsx @@ -1,6 +1,7 @@ import React, { PureComponent, ReactElement } from 'react'; import Select from './Select'; import { PopoverContent } from '../../../Tooltip/Tooltip'; +import { Icon } from '../../../Icon/Icon'; import { SelectableValue } from '@grafana/data'; interface ButtonComponentProps { @@ -23,8 +24,8 @@ const ButtonComponent = (buttonProps: ButtonComponentProps) => (props: any) => {
{iconClass && } {label ? label : ''} - {!props.menuIsOpen && } - {props.menuIsOpen && } + {!props.menuIsOpen && } + {props.menuIsOpen && }
); diff --git a/packages/grafana-ui/src/components/Forms/Legacy/Select/_Select.scss b/packages/grafana-ui/src/components/Forms/Legacy/Select/_Select.scss index a78e134f744..effa8a5fa74 100644 --- a/packages/grafana-ui/src/components/Forms/Legacy/Select/_Select.scss +++ b/packages/grafana-ui/src/components/Forms/Legacy/Select/_Select.scss @@ -135,26 +135,11 @@ $select-input-bg-disabled: $input-bg-disabled; position: absolute; height: 100%; right: 8px; + top: 1px; display: inline-block; text-align: right; } -.gf-form-select-box__select-arrow { - border-color: $input-color-select-arrow transparent transparent; - border-style: solid; - border-width: 4px 4px 2.5px; - display: inline-block; - position: absolute; - top: 50%; - right: 2px; - margin-top: -2px; - - &.gf-form-select-box__select-arrow--reversed { - border-color: transparent transparent $input-color-select-arrow; - border-width: 0 4px 4px; - } -} - .gf-form-input--form-dropdown { padding: 0; border: 0; diff --git a/packages/grafana-ui/src/components/Icon/Icon.mdx b/packages/grafana-ui/src/components/Icon/Icon.mdx index 53b94a65217..8f664d2e870 100644 --- a/packages/grafana-ui/src/components/Icon/Icon.mdx +++ b/packages/grafana-ui/src/components/Icon/Icon.mdx @@ -5,7 +5,7 @@ import { Icon } from './Icon'; # Icon -Grafana's wrapper component over [Font Awesome](https://fontawesome.com/) icons +Grafana's wrapper component over [Font Awesome](https://fontawesome.com/) and Unicons icons ### Changing icon size @@ -15,13 +15,7 @@ By default `Icon` has width and height of `16px` and font-size of `14px`. Pass ` ```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 index ed046c06be4..46d767c3325 100644 --- a/packages/grafana-ui/src/components/Icon/Icon.story.tsx +++ b/packages/grafana-ui/src/components/Icon/Icon.story.tsx @@ -4,7 +4,7 @@ import { css } from 'emotion'; import { Input } from '../Input/Input'; import { Field } from '../Forms/Field'; import { Icon } from './Icon'; -import { getAvailableIcons, IconType } from './types'; +import { getAvailableIcons, IconName } from '../../types'; import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { useTheme, selectThemeVariant } from '../../themes'; import mdx from './Icon.mdx'; @@ -20,7 +20,7 @@ export default { }, }; -const IconWrapper: React.FC<{ name: IconType }> = ({ name }) => { +const IconWrapper: React.FC<{ name: IconName }> = ({ name }) => { const theme = useTheme(); const borderColor = selectThemeVariant( { @@ -43,12 +43,7 @@ const IconWrapper: React.FC<{ name: IconType }> = ({ name }) => { } `} > - +
{ + name: IconName; + size?: IconSize; + 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) => { 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: currentColor; + `, + orange: css` + fill: ${theme.colors.orange}; `, }; }); -export const Icon: React.FC = ({ name, className, onClick, onMouseDown }) => { - const styles = getIconStyles(); - return ; -}; +export const Icon = React.forwardRef( + ({ size = 'md', type = 'default', name, className, style, ...divElementProps }, ref) => { + const theme = useTheme(); + const styles = getIconStyles(theme); + const svgSize = getSvgSize(size, theme); + + /* Temporary solution to display also font awesome icons */ + const isFontAwesome = name?.includes('fa-'); + if (isFontAwesome) { + return ; + } + + 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/Bell.tsx b/packages/grafana-ui/src/components/Icon/assets/Bell.tsx new file mode 100644 index 00000000000..906034a1621 --- /dev/null +++ b/packages/grafana-ui/src/components/Icon/assets/Bell.tsx @@ -0,0 +1,21 @@ +import React, { FunctionComponent } from 'react'; +import { SvgProps } from '../Icon'; + +export const Bell: 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..2cc995fecf4 --- /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, ...rest }) => { + return ( + + + + ); +}; diff --git a/packages/grafana-ui/src/components/Icon/assets/Folder.tsx b/packages/grafana-ui/src/components/Icon/assets/Folder.tsx new file mode 100644 index 00000000000..994d194da28 --- /dev/null +++ b/packages/grafana-ui/src/components/Icon/assets/Folder.tsx @@ -0,0 +1,10 @@ +import React, { FunctionComponent } from 'react'; +import { SvgProps } from '../Icon'; + +export const Folder: FunctionComponent = ({ size, ...rest }) => { + return ( + + + + ); +}; diff --git a/packages/grafana-ui/src/components/Icon/assets/FolderPlus.tsx b/packages/grafana-ui/src/components/Icon/assets/FolderPlus.tsx new file mode 100644 index 00000000000..24b368605b0 --- /dev/null +++ b/packages/grafana-ui/src/components/Icon/assets/FolderPlus.tsx @@ -0,0 +1,21 @@ +import React, { FunctionComponent } from 'react'; +import { SvgProps } from '../Icon'; + +export const FolderPlus: FunctionComponent = ({ size, ...rest }) => { + return ( + + + + + ); +}; diff --git a/packages/grafana-ui/src/components/Icon/assets/Grafana.tsx b/packages/grafana-ui/src/components/Icon/assets/Grafana.tsx new file mode 100644 index 00000000000..fa5c627c9dc --- /dev/null +++ b/packages/grafana-ui/src/components/Icon/assets/Grafana.tsx @@ -0,0 +1,70 @@ +import React, { FunctionComponent } from 'react'; +import { SvgProps } from '../Icon'; + +export const Grafana: FunctionComponent = ({ size, ...rest }) => { + return ( + + + + + + + + + + ); +}; diff --git a/packages/grafana-ui/src/components/Icon/assets/Import.tsx b/packages/grafana-ui/src/components/Icon/assets/Import.tsx new file mode 100644 index 00000000000..3fc827a911e --- /dev/null +++ b/packages/grafana-ui/src/components/Icon/assets/Import.tsx @@ -0,0 +1,23 @@ +import React, { FunctionComponent } from 'react'; +import { SvgProps } from '../Icon'; + +export const Import: FunctionComponent = ({ size, ...rest }) => { + return ( + + + + + + + ); +}; diff --git a/packages/grafana-ui/src/components/Icon/assets/PanelAdd.tsx b/packages/grafana-ui/src/components/Icon/assets/PanelAdd.tsx new file mode 100644 index 00000000000..b6f3b4076b7 --- /dev/null +++ b/packages/grafana-ui/src/components/Icon/assets/PanelAdd.tsx @@ -0,0 +1,49 @@ +import React, { FunctionComponent } from 'react'; +import { SvgProps } from '../Icon'; + +export const PanelAdd: FunctionComponent = ({ size, ...rest }) => { + return ( + + + + + + + + + + + + + + + + + + ); +}; diff --git a/packages/grafana-ui/src/components/Icon/assets/PlusSquare.tsx b/packages/grafana-ui/src/components/Icon/assets/PlusSquare.tsx new file mode 100644 index 00000000000..0ccb16b9435 --- /dev/null +++ b/packages/grafana-ui/src/components/Icon/assets/PlusSquare.tsx @@ -0,0 +1,21 @@ +import React, { FunctionComponent } from 'react'; +import { SvgProps } from '../Icon'; + +export const PlusSquare: FunctionComponent = ({ size, ...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..0d6cd925fe5 --- /dev/null +++ b/packages/grafana-ui/src/components/Icon/assets/index.ts @@ -0,0 +1,11 @@ +export * from './Apps'; +export * from './Cog'; +export * from './Shield'; +export * from './Favorite'; +export * from './Grafana'; +export * from './Bell'; +export * from './PlusSquare'; +export * from './FolderPlus'; +export * from './Folder'; +export * from './Import'; +export * from './PanelAdd'; 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/InfoTooltip/InfoTooltip.tsx b/packages/grafana-ui/src/components/InfoTooltip/InfoTooltip.tsx index 189aa36d86c..a9cb129e9fc 100644 --- a/packages/grafana-ui/src/components/InfoTooltip/InfoTooltip.tsx +++ b/packages/grafana-ui/src/components/InfoTooltip/InfoTooltip.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { Tooltip, TooltipProps, PopoverContent } from '../Tooltip/Tooltip'; +import { Icon } from '../Icon/Icon'; interface InfoTooltipProps extends Omit { children: PopoverContent; @@ -8,7 +9,7 @@ interface InfoTooltipProps extends Omit { export const InfoTooltip = ({ children, ...restProps }: InfoTooltipProps) => { return ( - + ); }; diff --git a/packages/grafana-ui/src/components/Input/Input.story.tsx b/packages/grafana-ui/src/components/Input/Input.story.tsx index f588d385e60..6c1249152dd 100644 --- a/packages/grafana-ui/src/components/Input/Input.story.tsx +++ b/packages/grafana-ui/src/components/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 '../Forms/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/Input/Input.tsx b/packages/grafana-ui/src/components/Input/Input.tsx index dd5a6ce4fd6..ae674f3328f 100644 --- a/packages/grafana-ui/src/components/Input/Input.tsx +++ b/packages/grafana-ui/src/components/Input/Input.tsx @@ -246,7 +246,7 @@ export const Input = React.forwardRef((props, ref) => { {(suffix || loading) && (
- {loading && } + {loading && } {suffix}
)} diff --git a/packages/grafana-ui/src/components/Logs/LogDetails.test.tsx b/packages/grafana-ui/src/components/Logs/LogDetails.test.tsx index 44a04549d17..be13187c4a2 100644 --- a/packages/grafana-ui/src/components/Logs/LogDetails.test.tsx +++ b/packages/grafana-ui/src/components/Logs/LogDetails.test.tsx @@ -37,7 +37,7 @@ describe('LogDetails', () => { describe('when labels are present', () => { it('should render heading', () => { const wrapper = setup(undefined, { labels: { key1: 'label1', key2: 'label2' } }); - expect(wrapper.find({ 'aria-label': 'Log Labels' })).toHaveLength(1); + expect(wrapper.find({ 'aria-label': 'Log Labels' }).hostNodes()).toHaveLength(1); }); it('should render labels', () => { const wrapper = setup(undefined, { labels: { key1: 'label1', key2: 'label2' } }); @@ -47,7 +47,7 @@ describe('LogDetails', () => { describe('when row entry has parsable fields', () => { it('should render heading ', () => { const wrapper = setup(undefined, { entry: 'test=successful' }); - expect(wrapper.find({ title: 'Ad-hoc statistics' })).toHaveLength(1); + expect(wrapper.find({ title: 'Ad-hoc statistics' }).hostNodes()).toHaveLength(1); }); it('should render parsed fields', () => { const wrapper = setup(undefined, { entry: 'test=successful' }); @@ -116,7 +116,7 @@ describe('LogDetails', () => { expect(wrapper.find(LogDetailsRow).length).toBe(3); const traceIdRow = wrapper.find(LogDetailsRow).filter({ parsedKey: 'traceId' }); expect(traceIdRow.length).toBe(1); - expect(traceIdRow.find('a').length).toBe(1); + expect(traceIdRow.find('a').hostNodes().length).toBe(1); expect((traceIdRow.find('a').getDOMNode() as HTMLAnchorElement).href).toBe('localhost:3210/1234'); }); }); diff --git a/packages/grafana-ui/src/components/Logs/LogDetailsRow.test.tsx b/packages/grafana-ui/src/components/Logs/LogDetailsRow.test.tsx index 2d1e19f6d1a..efc5a994ffa 100644 --- a/packages/grafana-ui/src/components/Logs/LogDetailsRow.test.tsx +++ b/packages/grafana-ui/src/components/Logs/LogDetailsRow.test.tsx @@ -32,16 +32,16 @@ describe('LogDetailsRow', () => { }); it('should render metrics button', () => { const wrapper = setup(); - expect(wrapper.find('i.fa-signal')).toHaveLength(1); + expect(wrapper.find({ title: 'Ad-hoc statistics' }).hostNodes()).toHaveLength(1); }); describe('if props is a label', () => { it('should render filter label button', () => { const wrapper = setup(); - expect(wrapper.find('i.fa-search-plus')).toHaveLength(1); + expect(wrapper.find({ title: 'Filter for value' }).hostNodes()).toHaveLength(1); }); it('should render filter out label button', () => { const wrapper = setup(); - expect(wrapper.find('i.fa-search-minus')).toHaveLength(1); + expect(wrapper.find({ title: 'Filter out value' }).hostNodes()).toHaveLength(1); }); }); @@ -66,7 +66,10 @@ describe('LogDetailsRow', () => { }); expect(wrapper.find(LogLabelStats).length).toBe(0); - wrapper.find({ title: 'Ad-hoc statistics' }).simulate('click'); + wrapper + .find({ title: 'Ad-hoc statistics' }) + .hostNodes() + .simulate('click'); expect(wrapper.find(LogLabelStats).length).toBe(1); expect(wrapper.find(LogLabelStats).contains('another value')).toBeTruthy(); }); diff --git a/packages/grafana-ui/src/components/Logs/LogDetailsRow.tsx b/packages/grafana-ui/src/components/Logs/LogDetailsRow.tsx index 792a48e5ac6..1d9b267bed0 100644 --- a/packages/grafana-ui/src/components/Logs/LogDetailsRow.tsx +++ b/packages/grafana-ui/src/components/Logs/LogDetailsRow.tsx @@ -10,6 +10,7 @@ import { stylesFactory } from '../../themes/stylesFactory'; //Components import { LogLabelStats } from './LogLabelStats'; import { LinkButton } from '../Button/Button'; +import { Icon } from '../Icon/Icon'; export interface Props extends Themeable { parsedValue: string; @@ -94,24 +95,16 @@ class UnThemedLogDetailsRow extends PureComponent { {/* Action buttons - show stats/filter results */} - + {isLabel && ( <> - + - + )} @@ -129,7 +122,7 @@ class UnThemedLogDetailsRow extends PureComponent { { topVerticalAlign: css` label: topVerticalAlign; vertical-align: top; + margin-top: -${theme.spacing.xs}; + margin-left: -${theme.spacing.xxs}; `, hoverBackground: css` label: hoverBackground; @@ -129,9 +132,6 @@ class UnThemedLogRow extends PureComponent { const style = getLogRowStyles(theme, row.logLevel); const styles = getStyles(theme); const showUtc = timeZone === 'utc'; - const showDetailsClassName = showDetails - ? cx(['fa fa-chevron-down', styles.topVerticalAlign]) - : cx(['fa fa-chevron-right', styles.topVerticalAlign]); const hoverBackground = cx(style.logsRow, { [styles.hoverBackground]: hasHoverBackground }); return ( @@ -150,7 +150,7 @@ class UnThemedLogRow extends PureComponent { {!allowDetails && ( - + )} {showTime && showUtc && ( diff --git a/packages/grafana-ui/src/components/Logs/getLogRowStyles.ts b/packages/grafana-ui/src/components/Logs/getLogRowStyles.ts index aaa1b1b1055..0978b4fbbb2 100644 --- a/packages/grafana-ui/src/components/Logs/getLogRowStyles.ts +++ b/packages/grafana-ui/src/components/Logs/getLogRowStyles.ts @@ -158,8 +158,10 @@ export const getLogRowStyles = stylesFactory((theme: GrafanaTheme, logLevel?: Lo logsDetailsIcon: css` label: logs-row-details__icon; position: relative; - padding-right: ${theme.spacing.md}; color: ${theme.colors.gray3}; + svg { + margin-right: ${theme.spacing.md}; + } `, logDetailsLabel: css` label: logs-row-details__label; diff --git a/packages/grafana-ui/src/components/Modal/Modal.tsx b/packages/grafana-ui/src/components/Modal/Modal.tsx index 047d472cc7e..e0e956a36b7 100644 --- a/packages/grafana-ui/src/components/Modal/Modal.tsx +++ b/packages/grafana-ui/src/components/Modal/Modal.tsx @@ -2,13 +2,14 @@ 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'; +import { Icon } from '../Icon/Icon'; interface Props extends Themeable { - icon?: IconType; + icon?: IconName; title: string | JSX.Element; className?: string; @@ -50,7 +51,7 @@ export class UnthemedModal extends React.PureComponent {
{typeof title === 'string' ? this.renderDefaultHeader(title) : title} - +
{this.props.children}
diff --git a/packages/grafana-ui/src/components/Modal/ModalHeader.tsx b/packages/grafana-ui/src/components/Modal/ModalHeader.tsx index 8b82643ab11..73ee7e04aac 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 }) => { @@ -16,7 +16,7 @@ export const ModalHeader: React.FC = ({ icon, title, children }) => { return ( <>

- {icon && } + {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..6f7a9074426 100644 --- a/packages/grafana-ui/src/components/Modal/ModalTabContent.tsx +++ b/packages/grafana-ui/src/components/Modal/ModalTabContent.tsx @@ -1,26 +1,18 @@ import React from 'react'; -import { IconType } from '../Icon/types'; +import { cx } from 'emotion'; +import { IconName } from '../../types'; import { Icon } from '../Icon/Icon'; interface Props { - icon?: IconType; + icon?: IconName; iconClass?: string; } export const ModalTabContent: React.FC = ({ icon, iconClass, children }) => { - let iconElem; - const showIcon = icon || iconClass; - if (iconClass) { - iconElem = ; - } - if (icon) { - iconElem = ; - } - return (
- {showIcon &&
{iconElem}
} + {icon && }
{children}
diff --git a/packages/grafana-ui/src/components/Modal/ModalTabsHeader.tsx b/packages/grafana-ui/src/components/Modal/ModalTabsHeader.tsx index a1628a33661..9f606da3ef4 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'; @@ -7,11 +7,11 @@ import { ModalHeader } from './ModalHeader'; interface ModalTab { value: string; label: string; - icon?: string; + icon?: IconName; } interface Props { - icon: IconType; + icon: IconName; title: string; tabs: ModalTab[]; activeTab: string; diff --git a/packages/grafana-ui/src/components/PanelOptionsGroup/PanelOptionsGroup.tsx b/packages/grafana-ui/src/components/PanelOptionsGroup/PanelOptionsGroup.tsx index fb641cd1dcb..22758f10c56 100644 --- a/packages/grafana-ui/src/components/PanelOptionsGroup/PanelOptionsGroup.tsx +++ b/packages/grafana-ui/src/components/PanelOptionsGroup/PanelOptionsGroup.tsx @@ -1,5 +1,6 @@ // Libraries import React, { FunctionComponent } from 'react'; +import { Icon } from '@grafana/ui'; interface Props { title?: string | JSX.Element; @@ -26,7 +27,7 @@ export const PanelOptionsGroup: FunctionComponent = props => { {props.title} {props.onClose && ( )}
diff --git a/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.tsx b/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.tsx index 9ff215d24f9..2982fc8e053 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/Switch/Switch.tsx b/packages/grafana-ui/src/components/Switch/Switch.tsx index 2573eb9238b..6dc7a3ecee4 100644 --- a/packages/grafana-ui/src/components/Switch/Switch.tsx +++ b/packages/grafana-ui/src/components/Switch/Switch.tsx @@ -1,6 +1,7 @@ import React, { PureComponent } from 'react'; import uniqueId from 'lodash/uniqueId'; import { Tooltip } from '../Tooltip/Tooltip'; +import { Icon } from '../Icon/Icon'; import * as PopperJS from 'popper.js'; export interface Props { @@ -54,7 +55,7 @@ export class Switch extends PureComponent { {tooltip && (
- +
)} diff --git a/packages/grafana-ui/src/components/Table/Table.tsx b/packages/grafana-ui/src/components/Table/Table.tsx index 317f7e35133..9913aa83bf3 100644 --- a/packages/grafana-ui/src/components/Table/Table.tsx +++ b/packages/grafana-ui/src/components/Table/Table.tsx @@ -132,7 +132,7 @@ function renderHeaderCell(column: any, tableStyles: TableStyles, field?: Field) {column.canSort && (
{column.render('Header')} - {column.isSorted && (column.isSortedDesc ? : )} + {column.isSorted && (column.isSortedDesc ? : )}
)} {!column.canSort &&
{column.render('Header')}
} diff --git a/packages/grafana-ui/src/components/Tabs/Tab.tsx b/packages/grafana-ui/src/components/Tabs/Tab.tsx index 888e802238f..4cbf59a0b26 100644 --- a/packages/grafana-ui/src/components/Tabs/Tab.tsx +++ b/packages/grafana-ui/src/components/Tabs/Tab.tsx @@ -1,12 +1,14 @@ import React, { FC } from 'react'; import { css, cx } from 'emotion'; import { GrafanaTheme } from '@grafana/data'; +import { Icon } from '../Icon/Icon'; +import { IconName } from '../../types'; import { stylesFactory, useTheme } from '../../themes'; export interface TabProps { label: string; active?: boolean; - icon?: string; + icon?: IconName; onChangeTab: () => void; } @@ -26,15 +28,10 @@ const getTabStyles = stylesFactory((theme: GrafanaTheme) => { color: ${colors.text}; cursor: pointer; - i { + svg { margin-right: ${theme.spacing.sm}; } - .gicon { - position: relative; - top: -2px; - } - &:hover, &:focus { color: ${colors.linkHover}; @@ -67,7 +64,7 @@ export const Tab: FC = ({ label, active, icon, onChangeTab }) => { return (
  • - {icon && } + {icon && } {label}
  • ); diff --git a/packages/grafana-ui/src/components/ThresholdsEditorNew/ThresholdsEditor.tsx b/packages/grafana-ui/src/components/ThresholdsEditorNew/ThresholdsEditor.tsx index 00b0ef811d9..517feae1c14 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)} /> + } /> ); } @@ -198,7 +200,7 @@ export class ThresholdsEditor extends PureComponent { return (
    - 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..50482b7ae9a 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/TimePickerCalendar.tsx b/packages/grafana-ui/src/components/TimePicker/TimePickerContent/TimePickerCalendar.tsx index d78285e8413..d77802e96f1 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimePickerContent/TimePickerCalendar.tsx +++ b/packages/grafana-ui/src/components/TimePicker/TimePickerContent/TimePickerCalendar.tsx @@ -82,7 +82,7 @@ const getBodyStyles = stylesFactory((theme: GrafanaTheme) => { return { title: css` - color: ${theme.colors.text} + color: ${theme.colors.text}; background-color: ${colors.background}; font-size: ${theme.typography.size.md}; border: 1px solid transparent; 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/TimePickerContent/TimeRangeForm.tsx b/packages/grafana-ui/src/components/TimePicker/TimePickerContent/TimeRangeForm.tsx index b5ece24f59e..538a9dd2b35 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimePickerContent/TimeRangeForm.tsx +++ b/packages/grafana-ui/src/components/TimePicker/TimePickerContent/TimeRangeForm.tsx @@ -62,7 +62,7 @@ export const TimeRangeForm: React.FC = props => { [timeZone] ); - const icon = isFullscreen ? null :
    @@ -38,8 +38,10 @@ exports[`TimePicker renders buttons correctly 1`] = ` className="btn navbar-button navbar-button--tight" onClick={[Function]} > - - @@ -289,8 +292,9 @@ exports[`TimePicker renders buttons correctly 1`] = ` className="btn navbar-button navbar-button--tight" onClick={[Function]} > - - @@ -321,8 +326,8 @@ exports[`TimePicker renders content correctly after beeing open 1`] = ` className="btn navbar-button navbar-button--tight" onClick={[Function]} > -
    @@ -348,8 +353,10 @@ exports[`TimePicker renders content correctly after beeing open 1`] = ` className="btn navbar-button navbar-button--tight" onClick={[Function]} > - - @@ -804,8 +812,9 @@ 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/TransformersUI/OrganizeFieldsTransformerEditor.tsx b/packages/grafana-ui/src/components/TransformersUI/OrganizeFieldsTransformerEditor.tsx index 59423e6d0d6..480e76c8b8b 100644 --- a/packages/grafana-ui/src/components/TransformersUI/OrganizeFieldsTransformerEditor.tsx +++ b/packages/grafana-ui/src/components/TransformersUI/OrganizeFieldsTransformerEditor.tsx @@ -126,7 +126,7 @@ const DraggableFieldName: React.FC = ({ className={styles.toggle} variant="link" size="md" - icon={visible ? 'fa fa-eye' : 'fa fa-eye-slash'} + icon={visible ? 'eye' : 'eye-slash'} onClick={() => onToggleVisibility(fieldName, visible)} /> {fieldName} diff --git a/packages/grafana-ui/src/components/ValueMappingsEditor/LegacyValueMappingsEditor.tsx b/packages/grafana-ui/src/components/ValueMappingsEditor/LegacyValueMappingsEditor.tsx index 07a73687858..632585c6ee8 100644 --- a/packages/grafana-ui/src/components/ValueMappingsEditor/LegacyValueMappingsEditor.tsx +++ b/packages/grafana-ui/src/components/ValueMappingsEditor/LegacyValueMappingsEditor.tsx @@ -98,7 +98,7 @@ export class LegacyValueMappingsEditor extends PureComponent { removeValueMapping={() => this.onRemoveMapping(valueMapping.id)} /> ))} -
    diff --git a/packages/grafana-ui/src/components/ValueMappingsEditor/ValueMappingsEditor.tsx b/packages/grafana-ui/src/components/ValueMappingsEditor/ValueMappingsEditor.tsx index 37ded12deca..c8265cc4b3d 100644 --- a/packages/grafana-ui/src/components/ValueMappingsEditor/ValueMappingsEditor.tsx +++ b/packages/grafana-ui/src/components/ValueMappingsEditor/ValueMappingsEditor.tsx @@ -68,7 +68,7 @@ export const ValueMappingsEditor: React.FC = ({ valueMappings, onChange, diff --git a/packages/grafana-ui/src/types/icon.ts b/packages/grafana-ui/src/types/icon.ts new file mode 100644 index 00000000000..a1a32f4a5c1 --- /dev/null +++ b/packages/grafana-ui/src/types/icon.ts @@ -0,0 +1,191 @@ +import { ComponentSize } from './size'; +export type IconType = 'mono' | 'default'; +export type IconSize = ComponentSize | 'xl' | 'xxl'; + +export type IconName = + | 'fa fa-fw fa-unlock' + | 'fa fa-envelope' + | 'fa fa-spinner' + | 'question-circle' + | 'angle-up' + | 'history' + | 'angle-down' + | 'filter' + | 'angle-left' + | 'angle-right' + | 'pen' + | 'plane' + | 'power' + | 'trash-alt' + | 'plus-square' + | 'folder-plus' + | 'folder-open' + | 'file-copy-alt' + | 'exchange-alt' + | 'import' + | 'exclamation-triangle' + | 'times' + | 'cloud-upload' + | 'step-backward' + | 'square-shape' + | 'share-alt' + | 'tag-alt' + | 'forward' + | 'check' + | 'add-panel' + | 'copy' + | 'lock' + | 'panel-add' + | 'arrow-random' + | 'arrow-down' + | 'comment-alt' + | 'arrow-right' + | 'arrow-up' + | 'arrow-from-right' + | 'keyboard' + | 'search' + | 'chart-line' + | 'search-minus' + | 'clock-nine' + | 'sync' + | 'signin' + | 'cog' + | 'bars' + | 'save' + | 'apps' + | 'folder-plus' + | 'link' + | 'upload' + | 'columns' + | 'home-alt' + | 'channel-add' + | 'calendar-alt' + | 'play' + | 'pause' + | 'calculator-alt' + | 'compass' + | 'sliders-v-alt' + | 'bell' + | 'database' + | 'user' + | 'camera' + | 'plug' + | 'shield' + | 'key-skeleton-alt' + | 'users-alt' + | 'graph-bar' + | 'book' + | 'bolt' + | 'comments-alt' + | 'document-info' + | 'info-circle' + | 'bug' + | 'cube' + | 'star' + | 'list-ul' + | 'edit' + | 'shield' + | 'eye' + | 'eye-slash' + | 'filter' + | 'monitor' + | 'plus-circle' + | 'arrow-left' + | 'repeat' + | 'external-link-alt' + | 'minus' + | 'signal' + | 'search-plus' + | 'search-minus' + | 'table' + | 'plus' + | 'heart' + | 'favorite'; + +export const getAvailableIcons = (): IconName[] => [ + 'question-circle', + 'plane', + 'plus', + 'plus-circle', + 'angle-up', + 'shield', + 'angle-down', + 'angle-left', + 'angle-right', + 'calendar-alt', + 'tag-alt', + 'calculator-alt', + 'pen', + 'repeat', + 'external-link-alt', + 'power', + 'play', + 'pause', + 'trash-alt', + 'exclamation-triangle', + 'times', + 'step-backward', + 'square-shape', + 'share-alt', + 'camera', + 'forward', + 'check', + 'add-panel', + 'copy', + 'lock', + 'panel-add', + 'arrow-random', + 'arrow-from-right', + 'arrow-left', + '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', + 'cloud-upload', + 'comments-alt', + 'list-ul', + 'document-info', + 'info-circle', + 'bug', + 'cube', + 'history', + 'star', + 'edit', + 'columns', + 'eye', + 'channel-add', + 'monitor', + 'favorite', + 'folder-plus', + 'plus-square', + 'import', + 'folder-open', + 'file-copy-alt', + 'arrow-down', + 'filter', + 'arrow-up', + 'exchange-alt', +]; 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..31d0def407f 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: "import", 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/angular_wrappers.ts b/public/app/core/angular_wrappers.ts index 4d0fc23c142..60ccc0cd94d 100644 --- a/public/app/core/angular_wrappers.ts +++ b/public/app/core/angular_wrappers.ts @@ -16,6 +16,7 @@ import { SecretFormField, SeriesColorPickerPopoverWithTheme, UnitPicker, + Icon, } from '@grafana/ui'; import { FunctionEditor } from 'app/plugins/datasource/graphite/FunctionEditor'; import ReactProfileWrapper from 'app/features/profile/ReactProfileWrapper'; @@ -32,6 +33,13 @@ import { SearchField, SearchResults, SearchResultsFilter } from '../features/sea export function registerAngularDirectives() { react2AngularDirective('footer', Footer, []); + react2AngularDirective('icon', Icon, [ + 'color', + 'name', + 'size', + 'type', + ['onClick', { watchDepth: 'reference', wrapApply: true }], + ]); react2AngularDirective('helpModal', HelpModal, []); react2AngularDirective('sidemenu', SideMenu, []); react2AngularDirective('functionEditor', FunctionEditor, ['func', 'onRemove', 'onMoveLeft', 'onMoveRight']); diff --git a/public/app/core/components/DynamicImports/ErrorLoadingChunk.tsx b/public/app/core/components/DynamicImports/ErrorLoadingChunk.tsx index 73bdf1bb0c1..396c6dfc8c1 100644 --- a/public/app/core/components/DynamicImports/ErrorLoadingChunk.tsx +++ b/public/app/core/components/DynamicImports/ErrorLoadingChunk.tsx @@ -20,7 +20,7 @@ export const ErrorLoadingChunk: FunctionComponent = ({ error }) => (

    Grafana has likely been updated. Please try reloading the page.


    -
    diff --git a/public/app/core/components/EmptyListCTA/EmptyListCTA.tsx b/public/app/core/components/EmptyListCTA/EmptyListCTA.tsx index 2239ac740fc..3f745909443 100644 --- a/public/app/core/components/EmptyListCTA/EmptyListCTA.tsx +++ b/public/app/core/components/EmptyListCTA/EmptyListCTA.tsx @@ -1,10 +1,10 @@ import React, { MouseEvent, useContext } from 'react'; -import { CallToActionCard, LinkButton, ThemeContext } from '@grafana/ui'; +import { CallToActionCard, LinkButton, ThemeContext, Icon, IconName } from '@grafana/ui'; import { css } from 'emotion'; export interface Props { title: string; - buttonIcon: string; + buttonIcon: IconName; buttonLink?: string; buttonTitle: string; onClick?: (event: MouseEvent) => void; @@ -45,7 +45,7 @@ const EmptyListCTA: React.FunctionComponent = ({ <> {proTip ? ( - + <> ProTip: {proTip} {proTipLinkTitle} 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/LayoutSelector/LayoutSelector.tsx b/public/app/core/components/LayoutSelector/LayoutSelector.tsx index 3afa1f931f2..d12f5d539af 100644 --- a/public/app/core/components/LayoutSelector/LayoutSelector.tsx +++ b/public/app/core/components/LayoutSelector/LayoutSelector.tsx @@ -1,4 +1,5 @@ import React, { FC } from 'react'; +import { Icon } from '@grafana/ui'; export type LayoutMode = LayoutModes.Grid | LayoutModes.List; @@ -22,7 +23,7 @@ const LayoutSelector: FC = props => { }} className={mode === LayoutModes.List ? 'active' : ''} > - +
    ); diff --git a/public/app/core/components/OrgSwitcher.tsx b/public/app/core/components/OrgSwitcher.tsx index 1954b3aa399..b608ed4ee11 100644 --- a/public/app/core/components/OrgSwitcher.tsx +++ b/public/app/core/components/OrgSwitcher.tsx @@ -45,7 +45,7 @@ export class OrgSwitcher extends React.PureComponent { const currentOrgId = contextSrv.user.orgId; return ( - + diff --git a/public/app/core/components/PageHeader/PageHeader.tsx b/public/app/core/components/PageHeader/PageHeader.tsx index aaf91ecb74e..57a44828540 100644 --- a/public/app/core/components/PageHeader/PageHeader.tsx +++ b/public/app/core/components/PageHeader/PageHeader.tsx @@ -1,5 +1,6 @@ import React, { FormEvent } from 'react'; -import { Tab, TabsBar } from '@grafana/ui'; +import { css } from 'emotion'; +import { Tab, TabsBar, Icon, IconName } from '@grafana/ui'; import appEvents from 'app/core/app_events'; import { NavModel, NavModelItem, NavModelBreadcrumb } from '@grafana/data'; import { CoreEvents } from 'app/types'; @@ -65,7 +66,7 @@ const Navigation = ({ main }: { main: NavModelItem }) => { label={child.text} active={child.active} key={`${child.url}-${index}`} - icon={child.icon} + icon={child.icon as IconName} onChangeTab={() => goToUrl(index)} /> ) @@ -113,10 +114,19 @@ export default class PageHeader extends React.Component { } renderHeaderTitle(main: NavModelItem) { + const iconClassName = + main.icon === 'grafana' + ? css` + margin-top: 12px; + ` + : css` + margin-top: 14px; + `; + return (
    - {main.icon && } + {main.icon && } {main.img && } diff --git a/public/app/core/components/PermissionList/AddPermission.tsx b/public/app/core/components/PermissionList/AddPermission.tsx index 99733d4373a..faeed7c22b1 100644 --- a/public/app/core/components/PermissionList/AddPermission.tsx +++ b/public/app/core/components/PermissionList/AddPermission.tsx @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import { UserPicker } from 'app/core/components/Select/UserPicker'; import { TeamPicker, Team } from 'app/core/components/Select/TeamPicker'; -import { LegacyForms } from '@grafana/ui'; +import { LegacyForms, Icon } from '@grafana/ui'; import { SelectableValue } from '@grafana/data'; import { User } from 'app/types'; import { @@ -91,7 +91,7 @@ class AddPermissions extends Component { return (
    Add Permission For
    diff --git a/public/app/core/components/PermissionList/DisabledPermissionListItem.tsx b/public/app/core/components/PermissionList/DisabledPermissionListItem.tsx index 2bb61bf60b1..8f28aee38e1 100644 --- a/public/app/core/components/PermissionList/DisabledPermissionListItem.tsx +++ b/public/app/core/components/PermissionList/DisabledPermissionListItem.tsx @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import { LegacyForms } from '@grafana/ui'; +import { LegacyForms, Icon } from '@grafana/ui'; import { dashboardPermissionLevels } from 'app/types/acl'; const { Select } = LegacyForms; @@ -15,7 +15,7 @@ export default class DisabledPermissionListItem extends Component { return (
    diff --git a/public/app/core/components/PermissionList/PermissionListItem.tsx b/public/app/core/components/PermissionList/PermissionListItem.tsx index 0579a2667a2..b3f11097aad 100644 --- a/public/app/core/components/PermissionList/PermissionListItem.tsx +++ b/public/app/core/components/PermissionList/PermissionListItem.tsx @@ -1,5 +1,5 @@ import React, { PureComponent } from 'react'; -import { LegacyForms } from '@grafana/ui'; +import { LegacyForms, Icon } from '@grafana/ui'; import { SelectableValue } from '@grafana/data'; import { dashboardPermissionLevels, DashboardAcl, PermissionLevel } from 'app/types/acl'; import { FolderInfo } from 'app/types'; @@ -17,10 +17,10 @@ function ItemAvatar({ item }: { item: DashboardAcl }) { return ; } if (item.role === 'Editor') { - return ; + return ; } - return ; + return ; } function ItemDescription({ item }: { item: DashboardAcl }) { @@ -89,11 +89,11 @@ export default class PermissionsListItem extends PureComponent { diff --git a/public/app/core/components/TagFilter/TagBadge.tsx b/public/app/core/components/TagFilter/TagBadge.tsx index 5897947331f..6b07285acef 100644 --- a/public/app/core/components/TagFilter/TagBadge.tsx +++ b/public/app/core/components/TagFilter/TagBadge.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { getTagColorsFromName } from '@grafana/ui'; +import { getTagColorsFromName, Icon } from '@grafana/ui'; export interface Props { label: string; @@ -24,7 +24,7 @@ export class TagBadge extends React.Component { return ( - {removeIcon && } + {removeIcon && } {label} {countLabel} ); diff --git a/public/app/core/components/TagFilter/TagFilter.tsx b/public/app/core/components/TagFilter/TagFilter.tsx index 263ba38ea87..0db6c7c0126 100644 --- a/public/app/core/components/TagFilter/TagFilter.tsx +++ b/public/app/core/components/TagFilter/TagFilter.tsx @@ -8,7 +8,7 @@ import { escapeStringForRegex } from '@grafana/data'; // Components import { TagOption } from './TagOption'; import { TagBadge } from './TagBadge'; -import { resetSelectStyles, LegacyForms } from '@grafana/ui'; +import { resetSelectStyles, LegacyForms, Icon } from '@grafana/ui'; const { IndicatorsContainer, NoOptionsMessage } = LegacyForms; export interface TermCount { @@ -90,7 +90,7 @@ export class TagFilter extends React.Component {
    - + ); } diff --git a/public/app/core/components/help/HelpModal.tsx b/public/app/core/components/help/HelpModal.tsx index 1c8bc30d2e9..552f19e9ae1 100644 --- a/public/app/core/components/help/HelpModal.tsx +++ b/public/app/core/components/help/HelpModal.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { appEvents } from 'app/core/core'; +import { Icon } from '@grafana/ui'; export class HelpModal extends React.PureComponent { static tabIndex = 0; @@ -52,11 +53,11 @@ export class HelpModal extends React.PureComponent {

    - + Shortcuts

    - +
    diff --git a/public/app/core/components/info_popover.ts b/public/app/core/components/info_popover.ts index 70451465930..995d9d139d1 100644 --- a/public/app/core/components/info_popover.ts +++ b/public/app/core/components/info_popover.ts @@ -6,7 +6,7 @@ import Drop from 'tether-drop'; export function infoPopover() { return { restrict: 'E', - template: '', + template: ``, transclude: true, link: (scope: any, elem: any, attrs: any, ctrl: any, transclude: any) => { const offset = attrs.offset || '0 -10px'; diff --git a/public/app/core/components/layout_selector/layout_selector.ts b/public/app/core/components/layout_selector/layout_selector.ts index 26988228df4..6782b846c9f 100644 --- a/public/app/core/components/layout_selector/layout_selector.ts +++ b/public/app/core/components/layout_selector/layout_selector.ts @@ -9,7 +9,7 @@ const template = `
    `; diff --git a/public/app/core/components/manage_dashboards/manage_dashboards.html b/public/app/core/components/manage_dashboards/manage_dashboards.html index dd4f11246fa..4356b16fd6b 100644 --- a/public/app/core/components/manage_dashboards/manage_dashboards.html +++ b/public/app/core/components/manage_dashboards/manage_dashboards.html @@ -1,17 +1,38 @@ -
    +
    - No dashboards found. + No dashboards found.
    -
    - - -
    +
    - diff --git a/public/app/core/components/search/search_results.html b/public/app/core/components/search/search_results.html index b3e17e18c5c..6b40087e355 100644 --- a/public/app/core/components/search/search_results.html +++ b/public/app/core/components/search/search_results.html @@ -1,32 +1,45 @@
    -
    +
    + ng-show="ctrl.editable" + on-change="ctrl.selectionChanged($event)" + checked="section.checked" + switch-class="gf-form-checkbox--transparent" + >
    {{::section.title}} - + - - + +
    - 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`] = ` - + = props => { value={props.query} spellCheck={false} onChange={event => props.changeQuery(event.currentTarget.value)} - prefix={} + prefix={} /> New user @@ -70,7 +70,7 @@ const UserListAdminPageUnConnected: React.FC = props => {
    @@ -113,7 +113,7 @@ const renderUser = (user: UserDTO) => { {user.isAdmin && ( - + )} diff --git a/public/app/features/admin/UserPermissions.tsx b/public/app/features/admin/UserPermissions.tsx index 24f39fc2e26..52a4f6674b8 100644 --- a/public/app/features/admin/UserPermissions.tsx +++ b/public/app/features/admin/UserPermissions.tsx @@ -1,5 +1,5 @@ import React, { PureComponent } from 'react'; -import { ConfirmButton, RadioButtonGroup } from '@grafana/ui'; +import { ConfirmButton, RadioButtonGroup, Icon } from '@grafana/ui'; import { cx } from 'emotion'; interface Props { @@ -73,7 +73,7 @@ export class UserPermissions extends PureComponent { @@ -138,7 +138,7 @@ @@ -152,7 +152,6 @@ -

    User status

    @@ -177,7 +176,9 @@ > Enable - +
    diff --git a/public/app/features/admin/partials/orgs.html b/public/app/features/admin/partials/orgs.html index a79e7812195..0fdd925b7c0 100644 --- a/public/app/features/admin/partials/orgs.html +++ b/public/app/features/admin/partials/orgs.html @@ -30,7 +30,7 @@
    diff --git a/public/app/features/alerting/AlertRuleItem.tsx b/public/app/features/alerting/AlertRuleItem.tsx index e630b921237..66f761d2b51 100644 --- a/public/app/features/alerting/AlertRuleItem.tsx +++ b/public/app/features/alerting/AlertRuleItem.tsx @@ -1,8 +1,8 @@ import React, { PureComponent } from 'react'; // @ts-ignore import Highlighter from 'react-highlight-words'; -import classNames from 'classnames'; import { AlertRule } from '../../types'; +import { Icon, IconName } from '@grafana/ui'; export interface Props { rule: AlertRule; @@ -24,19 +24,11 @@ class AlertRuleItem extends PureComponent { render() { const { rule, onTogglePause } = this.props; - const iconClassName = classNames({ - fa: true, - 'fa-play': rule.state === 'paused', - 'fa-pause': rule.state !== 'paused', - }); - const ruleUrl = `${rule.url}?panelId=${rule.panelId}&fullscreen&edit&tab=alert`; return (
  • - - - +
    @@ -56,10 +48,10 @@ class AlertRuleItem extends PureComponent { title="Pausing an alert rule prevents it from executing" onClick={onTogglePause} > - + - +
  • diff --git a/public/app/features/alerting/AlertTab.tsx b/public/app/features/alerting/AlertTab.tsx index 845a08f9c8f..b0d00a0f2b1 100644 --- a/public/app/features/alerting/AlertTab.tsx +++ b/public/app/features/alerting/AlertTab.tsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; import { connect, MapStateToProps, MapDispatchToProps } from 'react-redux'; import { css } from 'emotion'; -import { Alert, Button } from '@grafana/ui'; +import { Alert, Button, IconName } from '@grafana/ui'; import { AngularComponent, getAngularLoader, getDataSourceSrv } from '@grafana/runtime'; import appEvents from 'app/core/app_events'; @@ -130,7 +130,7 @@ class UnConnectedAlertTab extends PureComponent { title: 'Delete Alert', text: 'Are you sure you want to delete this alert rule?', text2: 'You need to save dashboard for the delete to take effect', - icon: 'fa-trash', + icon: 'trash-alt', yesText: 'Delete', onConfirm: () => { delete panel.alert; @@ -178,7 +178,7 @@ class UnConnectedAlertTab extends PureComponent {

    {validatonMessage}


    -
    @@ -199,7 +199,7 @@ class UnConnectedAlertTab extends PureComponent { const model = { title: 'Panel has no alert rule defined', - buttonIcon: 'gicon gicon-alert', + buttonIcon: 'bell' as IconName, onClick: this.onAddAlert, buttonTitle: 'Create Alert', }; diff --git a/public/app/features/alerting/__snapshots__/AlertRuleItem.test.tsx.snap b/public/app/features/alerting/__snapshots__/AlertRuleItem.test.tsx.snap index 3d5a61a3262..ef50083269d 100644 --- a/public/app/features/alerting/__snapshots__/AlertRuleItem.test.tsx.snap +++ b/public/app/features/alerting/__snapshots__/AlertRuleItem.test.tsx.snap @@ -4,13 +4,11 @@ exports[`Render should render component 1`] = `
  • - - - + name="icon" + size="xl" + />
    @@ -67,8 +65,8 @@ exports[`Render should render component 1`] = ` onClick={[MockFunction]} title="Pausing an alert rule prevents it from executing" > - -
    diff --git a/public/app/features/alerting/partials/alert_howto.html b/public/app/features/alerting/partials/alert_howto.html index 42de93e921f..65c0514ddbd 100644 --- a/public/app/features/alerting/partials/alert_howto.html +++ b/public/app/features/alerting/partials/alert_howto.html @@ -6,7 +6,7 @@ - + diff --git a/public/app/features/alerting/partials/alert_tab.html b/public/app/features/alerting/partials/alert_tab.html index 5dddf12e41b..7576a4f570a 100644 --- a/public/app/features/alerting/partials/alert_tab.html +++ b/public/app/features/alerting/partials/alert_tab.html @@ -1,7 +1,5 @@
    -
    - {{ctrl.error}} -
    +
    {{ctrl.error}}
    @@ -9,33 +7,35 @@
    Name - +
    Evaluate every - +
    - + - If an alert rule has a configured For and the query violates the configured - threshold it - will first go from OK to Pending. - Going from OK to Pending Grafana will not send any notifications. Once the alert - rule - has - been firing for more than For duration, it will change to Alerting and send alert - notifications. + If an alert rule has a configured For and the query violates the configured threshold it will first go + from OK to Pending. Going from OK to Pending Grafana will not send any notifications. Once the alert rule + has been firing for more than For duration, it will change to Alerting and send alert notifications.
    - +
    @@ -43,37 +43,57 @@

    Conditions

    - + WHEN
    - + OF
    - +
    - - - - + + + +
    - +
    Message - +
    Tags
    - +
  • @@ -62,7 +61,14 @@
    - +
    diff --git a/public/app/features/api-keys/ApiKeysAddedModal.tsx b/public/app/features/api-keys/ApiKeysAddedModal.tsx index 995aa46c773..47c4e2a3b0a 100644 --- a/public/app/features/api-keys/ApiKeysAddedModal.tsx +++ b/public/app/features/api-keys/ApiKeysAddedModal.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { Icon } from '@grafana/ui'; export interface Props { apiKey: string; @@ -10,12 +11,12 @@ export const ApiKeysAddedModal = (props: Props) => {

    - + API Key Created

    - +
    diff --git a/public/app/features/api-keys/ApiKeysPage.tsx b/public/app/features/api-keys/ApiKeysPage.tsx index b42730e3fd9..a1cc5eb3746 100644 --- a/public/app/features/api-keys/ApiKeysPage.tsx +++ b/public/app/features/api-keys/ApiKeysPage.tsx @@ -13,7 +13,7 @@ import ApiKeysAddedModal from './ApiKeysAddedModal'; import config from 'app/core/config'; import appEvents from 'app/core/app_events'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; -import { DeleteButton, EventsWithValidation, FormLabel, LegacyForms, ValidationEvents } from '@grafana/ui'; +import { DeleteButton, EventsWithValidation, FormLabel, LegacyForms, ValidationEvents, Icon } from '@grafana/ui'; const { Input, Switch } = LegacyForms; import { dateTime, isDateTime, NavModel } from '@grafana/data'; import { FilterInput } from 'app/core/components/FilterInput/FilterInput'; @@ -151,7 +151,7 @@ export class ApiKeysPage extends PureComponent { {!isAdding && ( {
    Add API Key
    diff --git a/public/app/features/api-keys/__snapshots__/ApiKeysAddedModal.test.tsx.snap b/public/app/features/api-keys/__snapshots__/ApiKeysAddedModal.test.tsx.snap index 0fcb13308eb..cec75a18cbc 100644 --- a/public/app/features/api-keys/__snapshots__/ApiKeysAddedModal.test.tsx.snap +++ b/public/app/features/api-keys/__snapshots__/ApiKeysAddedModal.test.tsx.snap @@ -10,8 +10,8 @@ exports[`Render should render component 1`] = `

    - -

    diff --git a/public/app/features/api-keys/__snapshots__/ApiKeysPage.test.tsx.snap b/public/app/features/api-keys/__snapshots__/ApiKeysPage.test.tsx.snap index 3545395237a..97c41436fdd 100644 --- a/public/app/features/api-keys/__snapshots__/ApiKeysPage.test.tsx.snap +++ b/public/app/features/api-keys/__snapshots__/ApiKeysPage.test.tsx.snap @@ -36,7 +36,7 @@ exports[`Render should render CTA if there are no API keys 1`] = ` isLoading={false} > -
    diff --git a/public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.tsx b/public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.tsx index 085ad5c6393..9d775db825f 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..df9f8ced98f 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/DashLinks/editor.html b/public/app/features/dashboard/components/DashLinks/editor.html index 532e7328529..d898716b79c 100644 --- a/public/app/features/dashboard/components/DashLinks/editor.html +++ b/public/app/features/dashboard/components/DashLinks/editor.html @@ -11,15 +11,22 @@ class="btn btn-primary" ng-click="ctrl.setupNew()" ng-if="ctrl.dashboard.links.length > 0" - ng-hide="ctrl.mode === 'edit' || ctrl.mode === 'new'"> - New - + New +
    - +
    @@ -62,7 +69,7 @@
    diff --git a/public/app/features/dashboard/components/DashNav/DashNav.tsx b/public/app/features/dashboard/components/DashNav/DashNav.tsx index ff5a9f76f63..2b146f388e1 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,14 @@ 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; + margin-bottom: -1px; + `; + const mainIconClassName = css` + margin-right: 8px; + `; const folderTitle = dashboard.meta.folderTitle; const haveFolder = dashboard.meta.folderId > 0; @@ -103,17 +112,17 @@ export class DashNav extends PureComponent { <>
    - {!isFullscreen && } + {!isFullscreen && } {haveFolder && ( <> {folderTitle} - + )} - {dashboard.title} + {dashboard.title}
    @@ -146,19 +155,19 @@ export class DashNav extends PureComponent { @@ -167,10 +176,12 @@ export class DashNav extends PureComponent {
    {canSave && ( )} @@ -178,7 +189,8 @@ export class DashNav extends PureComponent { )} @@ -189,7 +201,7 @@ export class DashNav extends PureComponent { { showModal(ShareModal, { dashboard, @@ -207,7 +219,7 @@ export class DashNav extends PureComponent { { showModal(SaveDashboardModalProxy, { dashboard, @@ -223,7 +235,7 @@ export class DashNav extends PureComponent { )} @@ -232,19 +244,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..1eafc8c7100 100644 --- a/public/app/features/dashboard/components/DashNav/DashNavButton.tsx +++ b/public/app/features/dashboard/components/DashNav/DashNavButton.tsx @@ -1,19 +1,30 @@ // Libraries import React, { FunctionComponent } from 'react'; // Components -import { Tooltip } from '@grafana/ui'; +import { Tooltip, Icon, IconName, IconType, IconSize } 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; + iconSize?: IconSize; } -export const DashNavButton: FunctionComponent = ({ icon, tooltip, classSuffix, onClick, href, children }) => { +export const DashNavButton: FunctionComponent = ({ + icon, + iconType, + iconSize, + tooltip, + classSuffix, + onClick, + href, + children, +}) => { if (onClick) { return ( @@ -22,7 +33,7 @@ export const DashNavButton: FunctionComponent = ({ icon, tooltip, classSu onClick={onClick} aria-label={e2e.pages.Dashboard.Toolbar.selectors.toolbarItems(tooltip)} > - {icon && } + {icon && } {children} @@ -32,7 +43,7 @@ export const DashNavButton: FunctionComponent = ({ icon, tooltip, classSu return ( - {icon && } + {icon && } {children} diff --git a/public/app/features/dashboard/components/DashboardPermissions/DashboardPermissions.tsx b/public/app/features/dashboard/components/DashboardPermissions/DashboardPermissions.tsx index e8af1e52dff..427a5ef2f8a 100644 --- a/public/app/features/dashboard/components/DashboardPermissions/DashboardPermissions.tsx +++ b/public/app/features/dashboard/components/DashboardPermissions/DashboardPermissions.tsx @@ -1,5 +1,5 @@ import React, { PureComponent } from 'react'; -import { Tooltip } from '@grafana/ui'; +import { Tooltip, Icon } from '@grafana/ui'; import { SlideDown } from 'app/core/components/Animations/SlideDown'; import { StoreState, FolderInfo } from 'app/types'; import { DashboardAcl, PermissionLevel, NewDashboardAclItem } from 'app/types/acl'; @@ -71,9 +71,7 @@ export class DashboardPermissions extends PureComponent {

    Permissions

    }> -
    - -
    +
    diff --git a/public/app/features/dashboard/components/UnsavedChangesModal/UnsavedChangesModalCtrl.ts b/public/app/features/dashboard/components/UnsavedChangesModal/UnsavedChangesModalCtrl.ts index ad95ef20dfe..1e83567729f 100644 --- a/public/app/features/dashboard/components/UnsavedChangesModal/UnsavedChangesModalCtrl.ts +++ b/public/app/features/dashboard/components/UnsavedChangesModal/UnsavedChangesModalCtrl.ts @@ -9,7 +9,7 @@ const template = ` - +
    diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx index acbcd54edbf..02361606e1b 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx @@ -3,7 +3,7 @@ import classNames from 'classnames'; import { isEqual } from 'lodash'; import { DataLink, ScopedVars, PanelMenuItem, PanelData, LoadingState, QueryResultMetaNotice } from '@grafana/data'; import { AngularComponent } from '@grafana/runtime'; -import { ClickOutsideWrapper, Tooltip } from '@grafana/ui'; +import { ClickOutsideWrapper, Tooltip, Icon } from '@grafana/ui'; import { e2e } from '@grafana/e2e'; import PanelHeaderCorner from './PanelHeaderCorner'; @@ -109,11 +109,11 @@ export class PanelHeader extends Component { {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..4502167cd9e 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; + top: 7px; + 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/datasources/DataSourcesListPage.tsx b/public/app/features/datasources/DataSourcesListPage.tsx index f7ad8834a80..a1438b079de 100644 --- a/public/app/features/datasources/DataSourcesListPage.tsx +++ b/public/app/features/datasources/DataSourcesListPage.tsx @@ -9,6 +9,7 @@ import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; import DataSourcesList from './DataSourcesList'; // Types import { DataSourceSettings, NavModel } from '@grafana/data'; +import { IconName } from '@grafana/ui'; import { StoreState } from 'app/types'; import { LayoutMode } from 'app/core/components/LayoutSelector/LayoutSelector'; // Actions @@ -37,7 +38,7 @@ export interface Props { const emptyListModel = { title: 'There are no data sources defined yet', - buttonIcon: 'gicon gicon-datasources', + buttonIcon: 'database' as IconName, buttonLink: 'datasources/new', buttonTitle: 'Add data source', proTip: 'You can also define data sources through configuration files.', diff --git a/public/app/features/datasources/NewDataSourcePage.tsx b/public/app/features/datasources/NewDataSourcePage.tsx index 9d377425a4f..05bef67d1d2 100644 --- a/public/app/features/datasources/NewDataSourcePage.tsx +++ b/public/app/features/datasources/NewDataSourcePage.tsx @@ -143,7 +143,7 @@ const DataSourceTypeCard: FC = props => { target="_blank" rel="noopener" onClick={onLearnMoreClick} - icon="fa fa-external-link" + icon="external-link-alt" > {learnMoreLink.name} diff --git a/public/app/features/explore/ExploreToolbar.tsx b/public/app/features/explore/ExploreToolbar.tsx index 29da103daac..179cd962609 100644 --- a/public/app/features/explore/ExploreToolbar.tsx +++ b/public/app/features/explore/ExploreToolbar.tsx @@ -7,7 +7,7 @@ import classNames from 'classnames'; import { css } from 'emotion'; import { ExploreId, ExploreItemState } from 'app/types/explore'; -import { ToggleButtonGroup, ToggleButton, Tooltip, LegacyForms, SetInterval } from '@grafana/ui'; +import { ToggleButtonGroup, ToggleButton, Tooltip, LegacyForms, SetInterval, Icon } from '@grafana/ui'; const { ButtonSelect } = LegacyForms; import { RawTimeRange, TimeZone, TimeRange, DataQuery, ExploreMode } from '@grafana/data'; import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker'; @@ -202,14 +202,21 @@ export class UnConnectedExploreToolbar extends PureComponent {
    {exploreId === 'left' && ( - + Explore )}
    {splitted && ( closeSplit(exploreId)}> - + )} @@ -261,7 +268,7 @@ export class UnConnectedExploreToolbar extends PureComponent {
    {originDashboardIsEditable && ( @@ -281,7 +288,8 @@ export class UnConnectedExploreToolbar extends PureComponent { splitted={splitted} title="Split" onClick={split} - iconClassName="fa fa-fw fa-columns icon-margin-right" + icon="columns" + iconClassName="icon-margin-right" disabled={isLive} />
    @@ -307,7 +315,8 @@ export class UnConnectedExploreToolbar extends PureComponent { splitted={splitted} title="Clear All" onClick={this.onClearAll} - iconClassName="fa fa-fw fa-trash icon-margin-right" + icon="trash-alt" + iconClassName="icon-margin-right" /> )} diff --git a/public/app/features/explore/LiveTailButton.tsx b/public/app/features/explore/LiveTailButton.tsx index 0528a6e4b10..7e346f7d4fd 100644 --- a/public/app/features/explore/LiveTailButton.tsx +++ b/public/app/features/explore/LiveTailButton.tsx @@ -128,11 +128,8 @@ export function LiveTailButton(props: LiveTailButtonProps) { [styles.isLive]: isLive && !isPaused, [styles.isPaused]: isLive && isPaused, })} - iconClassName={classNames( - 'fa', - isPaused || !isLive ? 'fa-play' : 'fa-pause', - isLive && 'icon-brand-gradient' - )} + icon={!isLive ? 'play' : 'pause'} + iconClassName={isLive && 'icon-brand-gradient'} onClick={onClickMain} title={'\xa0Live'} /> diff --git a/public/app/features/explore/NoDataSourceCallToAction.tsx b/public/app/features/explore/NoDataSourceCallToAction.tsx index ce5be0bfadc..8db137c61d6 100644 --- a/public/app/features/explore/NoDataSourceCallToAction.tsx +++ b/public/app/features/explore/NoDataSourceCallToAction.tsx @@ -23,7 +23,7 @@ export const NoDataSourceCallToAction = () => { ); const ctaElement = ( - + Add data source ); diff --git a/public/app/features/explore/QueryRowActions.test.tsx b/public/app/features/explore/QueryRowActions.test.tsx index 9cca244f2bc..89558494a2d 100644 --- a/public/app/features/explore/QueryRowActions.test.tsx +++ b/public/app/features/explore/QueryRowActions.test.tsx @@ -30,10 +30,10 @@ describe('QueryRowActions', () => { }); it('should change icon to fa-eye-slash when query row result is hidden', () => { const wrapper = setup({ isDisabled: true }); - expect(wrapper.find('i.fa-eye-slash')).toHaveLength(1); + expect(wrapper.find({ title: 'Enable query' })).toHaveLength(1); }); it('should change icon to fa-eye when query row result is not hidden', () => { const wrapper = setup({ isDisabled: false }); - expect(wrapper.find('i.fa-eye')).toHaveLength(1); + expect(wrapper.find({ title: 'Disable query' })).toHaveLength(1); }); }); diff --git a/public/app/features/explore/QueryRowActions.tsx b/public/app/features/explore/QueryRowActions.tsx index 83613276316..dc203049278 100644 --- a/public/app/features/explore/QueryRowActions.tsx +++ b/public/app/features/explore/QueryRowActions.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { Icon } from '@grafana/ui'; function formatLatency(value: number) { return `${(value / 1000).toFixed(1)}s`; @@ -34,7 +35,7 @@ export function QueryRowActions(props: Props) { className="gf-form-label gf-form-label--btn" onClick={onClickToggleEditorMode} > - + )} @@ -48,14 +49,14 @@ export function QueryRowActions(props: Props) { disabled={isNotStarted} className="gf-form-label gf-form-label--btn" onClick={onClickToggleDisabled} - title="Disable/enable query" + title={isDisabled ? 'Enable query' : 'Disable query'} > - +
    diff --git a/public/app/features/explore/ResponsiveButton.tsx b/public/app/features/explore/ResponsiveButton.tsx index 6821a163cf2..091cc983d6e 100644 --- a/public/app/features/explore/ResponsiveButton.tsx +++ b/public/app/features/explore/ResponsiveButton.tsx @@ -1,4 +1,5 @@ import React, { forwardRef } from 'react'; +import { IconName, Icon } from '@grafana/ui'; export enum IconSide { left = 'left', @@ -10,6 +11,7 @@ interface Props extends React.HTMLAttributes { title: string; onClick: () => void; buttonClassName?: string; + icon?: IconName; iconClassName?: string; iconSide?: IconSide; disabled?: boolean; @@ -25,7 +27,17 @@ export const ResponsiveButton = forwardRef((props, ref) = }; props = { ...defaultProps, ...props }; - const { title, onClick, buttonClassName, iconClassName, splitted, iconSide, disabled, ...divElementProps } = props; + const { + title, + onClick, + buttonClassName, + icon, + iconClassName, + splitted, + iconSide, + disabled, + ...divElementProps + } = props; return (
    @@ -34,9 +46,9 @@ export const ResponsiveButton = forwardRef((props, ref) = onClick={onClick} disabled={disabled || false} > - {iconClassName && iconSide === IconSide.left ? : null} + {icon && iconSide === IconSide.left ? : null} {!splitted ? formatBtnTitle(title, iconSide) : ''} - {iconClassName && iconSide === IconSide.right ? : null} + {icon && iconSide === IconSide.right ? : null}
    ); diff --git a/public/app/features/explore/RichHistory/RichHistory.tsx b/public/app/features/explore/RichHistory/RichHistory.tsx index f39376b3955..63dcf12b66c 100644 --- a/public/app/features/explore/RichHistory/RichHistory.tsx +++ b/public/app/features/explore/RichHistory/RichHistory.tsx @@ -10,7 +10,7 @@ import { stylesFactory, withTheme } from '@grafana/ui'; //Types import { RichHistoryQuery, ExploreId } from 'app/types/explore'; import { SelectableValue, GrafanaTheme } from '@grafana/data'; -import { TabsBar, Tab, TabContent, Themeable, CustomScrollbar } from '@grafana/ui'; +import { TabsBar, Tab, TabContent, Themeable, CustomScrollbar, IconName, Icon } from '@grafana/ui'; //Components import { RichHistorySettings } from './RichHistorySettings'; @@ -169,7 +169,7 @@ class UnThemedRichHistory extends PureComponent ), - icon: 'fa fa-history', + icon: 'history', }; const StarredTab = { @@ -186,7 +186,7 @@ class UnThemedRichHistory extends PureComponent ), - icon: 'fa fa-star', + icon: 'star', }; const SettingsTab = { @@ -203,7 +203,7 @@ class UnThemedRichHistory extends PureComponent ), - icon: 'gicon gicon-preferences', + icon: 'sliders-v-alt', }; let tabs = [QueriesTab, StarredTab, SettingsTab]; @@ -216,11 +216,11 @@ class UnThemedRichHistory extends PureComponent this.onSelectTab(t)} - icon={t.icon} + icon={t.icon as IconName} /> ))}
    - +
    { describe('commenting', () => { it('should render comment, if comment present', () => { const wrapper = setup({ query: starredQueryWithComment }); - expect(wrapper.find({ 'aria-label': 'Query comment' })).toHaveLength(1); + expect(wrapper.find({ 'aria-label': 'Query comment' }).hostNodes()).toHaveLength(1); expect(wrapper.find({ 'aria-label': 'Query comment' }).text()).toEqual('test comment'); }); it('should have title "Edit comment" at comment icon, if comment present', () => { const wrapper = setup({ query: starredQueryWithComment }); - expect(wrapper.find({ title: 'Edit comment' })).toHaveLength(1); - expect(wrapper.find({ title: 'Add comment' })).toHaveLength(0); + expect(wrapper.find({ title: 'Edit comment' }).hostNodes()).toHaveLength(1); + expect(wrapper.find({ title: 'Add comment' }).hostNodes()).toHaveLength(0); }); it('should have title "Add comment" at comment icon, if no comment present', () => { const wrapper = setup(); - expect(wrapper.find({ title: 'Add comment' })).toHaveLength(1); - expect(wrapper.find({ title: 'Edit comment' })).toHaveLength(0); + expect(wrapper.find({ title: 'Add comment' }).hostNodes()).toHaveLength(1); + expect(wrapper.find({ title: 'Edit comment' }).hostNodes()).toHaveLength(0); }); }); describe('starring', () => { it('should have title "Star query", if not starred', () => { const wrapper = setup(); - expect(wrapper.find({ title: 'Star query' })).toHaveLength(1); - }); - it('should render fa-star-o icon, if not starred', () => { - const wrapper = setup(); - expect(wrapper.find({ title: 'Star query' }).hasClass('fa-star-o')).toBe(true); + expect(wrapper.find({ title: 'Star query' }).hostNodes()).toHaveLength(1); }); it('should have title "Unstar query", if not starred', () => { const wrapper = setup({ query: starredQueryWithComment }); - expect(wrapper.find({ title: 'Unstar query' })).toHaveLength(1); - }); - it('should have fa-star icon, if not starred', () => { - const wrapper = setup({ query: starredQueryWithComment }); - expect(wrapper.find({ title: 'Unstar query' }).hasClass('fa-star')).toBe(true); + expect(wrapper.find({ title: 'Unstar query' }).hostNodes()).toHaveLength(1); }); }); }); diff --git a/public/app/features/explore/RichHistory/RichHistoryCard.tsx b/public/app/features/explore/RichHistory/RichHistoryCard.tsx index 0f0f86cbe78..373030d0ed7 100644 --- a/public/app/features/explore/RichHistory/RichHistoryCard.tsx +++ b/public/app/features/explore/RichHistory/RichHistoryCard.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { connect } from 'react-redux'; import { hot } from 'react-hot-loader'; import { css, cx } from 'emotion'; -import { stylesFactory, useTheme, Forms, Button } from '@grafana/ui'; +import { stylesFactory, useTheme, Forms, Button, Icon } from '@grafana/ui'; import { GrafanaTheme, AppEvents, DataSourceApi } from '@grafana/data'; import { RichHistoryQuery, ExploreId } from 'app/types/explore'; import { copyStringToClipboard, createUrlFromRichHistory, createDataQuery } from 'app/core/utils/richHistory'; @@ -76,9 +76,8 @@ const getStyles = stylesFactory((theme: GrafanaTheme, isRemoved: boolean) => { display: flex; justify-content: flex-end; font-size: ${theme.typography.size.base}; - i { - margin: ${theme.spacing.xs}; - cursor: pointer; + svg { + margin-left: ${theme.spacing.sm}; } `, queryContainer: css` @@ -212,19 +211,20 @@ export function RichHistoryCard(props: Props) { const queryActionButtons = (
    - 0 ? 'Edit comment' : 'Add comment'} - > - - {!isRemoved && } - - + + {!isRemoved && } + + + />
    ); diff --git a/public/app/features/explore/RichHistory/RichHistorySettings.tsx b/public/app/features/explore/RichHistory/RichHistorySettings.tsx index d7f9141102e..f5878893438 100644 --- a/public/app/features/explore/RichHistory/RichHistorySettings.tsx +++ b/public/app/features/explore/RichHistory/RichHistorySettings.tsx @@ -63,7 +63,7 @@ export function RichHistorySettings(props: RichHistorySettingsProps) { title: 'Delete', text: 'Are you sure you want to permanently delete your query history?', yesText: 'Delete', - icon: 'fa-trash', + icon: 'trash-alt', onConfirm: () => { deleteRichHistory(); appEvents.emit(AppEvents.alertSuccess, ['Query history deleted']); diff --git a/public/app/features/explore/RunButton.tsx b/public/app/features/explore/RunButton.tsx index 861e3efd9e1..33fa1982b60 100644 --- a/public/app/features/explore/RunButton.tsx +++ b/public/app/features/explore/RunButton.tsx @@ -40,7 +40,8 @@ export function RunButton(props: Props) { 'navbar-button--danger': loading, 'btn--radius-right-0': showDropdown, })} - iconClassName={loading ? 'fa fa-spinner fa-fw fa-spin run-icon' : 'fa fa-refresh fa-fw'} + icon={loading ? 'fa fa-spinner' : 'sync'} + iconClassName={loading && ' fa-spin run-icon'} /> ); diff --git a/public/app/features/explore/__snapshots__/QueryRowActions.test.tsx.snap b/public/app/features/explore/__snapshots__/QueryRowActions.test.tsx.snap index d077fbc5194..4f044cccaee 100644 --- a/public/app/features/explore/__snapshots__/QueryRowActions.test.tsx.snap +++ b/public/app/features/explore/__snapshots__/QueryRowActions.test.tsx.snap @@ -12,8 +12,8 @@ exports[`QueryRowActions should render component 1`] = ` className="gf-form-label gf-form-label--btn" onClick={[Function]} > - @@ -35,10 +35,10 @@ exports[`QueryRowActions should render component 1`] = ` className="gf-form-label gf-form-label--btn" disabled={true} onClick={[Function]} - title="Disable/enable query" + title="Disable query" > - @@ -50,8 +50,8 @@ exports[`QueryRowActions should render component 1`] = ` onClick={[Function]} title="Remove query" > - diff --git a/public/app/features/folders/FolderPermissions.tsx b/public/app/features/folders/FolderPermissions.tsx index aaaa061302f..f7f5105f9b5 100644 --- a/public/app/features/folders/FolderPermissions.tsx +++ b/public/app/features/folders/FolderPermissions.tsx @@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'; import { hot } from 'react-hot-loader'; import { connect } from 'react-redux'; import Page from 'app/core/components/Page/Page'; -import { Tooltip } from '@grafana/ui'; +import { Tooltip, Icon } from '@grafana/ui'; import { NavModel } from '@grafana/data'; import { SlideDown } from 'app/core/components/Animations/SlideDown'; import { getNavModel } from 'app/core/selectors/navModel'; @@ -91,9 +91,7 @@ export class FolderPermissions extends PureComponent {

    Folder Permissions

    }> -
    - -
    +
    diff --git a/public/app/features/manage-dashboards/partials/snapshot_list.html b/public/app/features/manage-dashboards/partials/snapshot_list.html index f0ee5f4733c..108669033c2 100644 --- a/public/app/features/manage-dashboards/partials/snapshot_list.html +++ b/public/app/features/manage-dashboards/partials/snapshot_list.html @@ -1,19 +1,19 @@
    -
    - + {item.name} @@ -36,7 +36,7 @@ export default class DisabledPermissionListItem extends Component {
    {!item.inherited ? ( - + ) : ( )} Seen  - + {isGrafanaAdmin ? ( <> - Yes + Yes ) : ( <>No diff --git a/public/app/features/admin/__snapshots__/ServerStats.test.tsx.snap b/public/app/features/admin/__snapshots__/ServerStats.test.tsx.snap index 28b04ffd653..b02fb952d51 100644 --- a/public/app/features/admin/__snapshots__/ServerStats.test.tsx.snap +++ b/public/app/features/admin/__snapshots__/ServerStats.test.tsx.snap @@ -54,7 +54,7 @@ exports[`ServerStats Should render table with stats 1`] = ` className="page-header__logo" >
  • - +
    Admin
  • @@ -164,7 +162,7 @@ exports[`ServerStats Should render table with stats 1`] = ` target="_blank" > Documentation @@ -177,7 +175,7 @@ exports[`ServerStats Should render table with stats 1`] = ` target="_blank" > Support @@ -190,7 +188,7 @@ exports[`ServerStats Should render table with stats 1`] = ` target="_blank" > Community diff --git a/public/app/features/admin/ldap/LdapUserPermissions.tsx b/public/app/features/admin/ldap/LdapUserPermissions.tsx index 180c4015912..0c26c76a5fe 100644 --- a/public/app/features/admin/ldap/LdapUserPermissions.tsx +++ b/public/app/features/admin/ldap/LdapUserPermissions.tsx @@ -1,5 +1,6 @@ import React, { FC } from 'react'; import { LdapPermissions } from 'app/types'; +import { Icon } from '@grafana/ui'; interface Props { permissions: LdapPermissions; @@ -21,7 +22,7 @@ export const LdapUserPermissions: FC = ({ permissions }) => {
    {permissions.isGrafanaAdmin ? ( <> - Yes + Yes ) : ( 'No' diff --git a/public/app/features/admin/partials/edit_org.html b/public/app/features/admin/partials/edit_org.html index 356fbaf14ab..6b053b1f4e7 100644 --- a/public/app/features/admin/partials/edit_org.html +++ b/public/app/features/admin/partials/edit_org.html @@ -1,46 +1,52 @@
    -

    Edit Organization

    +

    Edit Organization

    - -
    - Name - -
    + +
    + Name + +
    -
    - -
    - +
    + +
    + -

    Organization Users

    +

    Organization Users

    - - - - - - - - - - - + + +
    UsernameEmailRole
    {{orgUser.login}}{{orgUser.email}} + + + + + + + + + + + - - -
    UsernameEmailRole
    {{orgUser.login}}{{orgUser.email}}
    - +
    -
    - - - -
    +
    + + + +
    diff --git a/public/app/features/admin/partials/edit_user.html b/public/app/features/admin/partials/edit_user.html index a60ae98de6d..598267f3c7c 100644 --- a/public/app/features/admin/partials/edit_user.html +++ b/public/app/features/admin/partials/edit_user.html @@ -108,7 +108,7 @@
    - +
    {{session.browser}} on {{session.os}} {{session.osVersion}}
    - +
    -   - {{ annotation.name }} +   {{ annotation.name }}   @@ -53,7 +52,7 @@ class="btn btn-danger btn-small" ng-hide="annotation.builtIn" > - +
    - +
    +
    - - + + - -
    Name Snapshot url
    {{snapshot.name}} + {{snapshot.url}} @@ -21,18 +21,17 @@ - + View + - +
    -
    diff --git a/public/app/features/org/SelectOrgCtrl.ts b/public/app/features/org/SelectOrgCtrl.ts index b42aa33d0fe..e167b9d823a 100644 --- a/public/app/features/org/SelectOrgCtrl.ts +++ b/public/app/features/org/SelectOrgCtrl.ts @@ -10,7 +10,7 @@ export class SelectOrgCtrl { $scope.navModel = { main: { - icon: 'gicon gicon-branding', + icon: 'grafana', subTitle: 'Preferences', text: 'Select active organization', }, diff --git a/public/app/features/playlist/partials/playlist.html b/public/app/features/playlist/partials/playlist.html index c44c6a6cffd..f46e2d44ffa 100644 --- a/public/app/features/playlist/partials/playlist.html +++ b/public/app/features/playlist/partials/playlist.html @@ -1,104 +1,124 @@
    +

    Edit Playlist

    +

    New Playlist

    -

    Edit Playlist

    -

    New Playlist

    +

    + A playlist rotates through a pre-selected list of Dashboards. A Playlist can be a great way to build situational + awareness, or just show off your metrics to your team or visitors. +

    -

    A playlist rotates through a pre-selected list of Dashboards. A Playlist can be a great way to build situational awareness, or just show off your metrics to your team or visitors.

    +
    +
    + Name + +
    +
    + Interval + +
    +
    -
    -
    - Name - -
    -
    - Interval - -
    -
    +
    +

    Dashboards

    -
    -

    Dashboards

    + + + + -
    +   {{playlistItem.title}} + + + + {{playlistItem.title}} + +
    - - - + + + + + +
    -   {{playlistItem.title}} - - - - {{playlistItem.title}} - - + + + +
    Playlist is empty, add dashboards below.
    +
    - - - - - - - - Playlist is empty, add dashboards below. - - -
    +
    +

    Add dashboards

    + -
    -

    Add dashboards

    - +
    + + + + + +
    + +   {{playlistItem.title}} + + + +
    +
    +
    + + + + + +
    + + + {{tag.term}}  ({{tag.count}}) + + + +
    +
    +
    -
    - - - - - -
    - -   {{playlistItem.title}} - - - -
    -
    -
    - - - - - -
    - - - {{tag.term}}  ({{tag.count}}) - - - -
    -
    -
    +
    -
    - -
    - Create - Save - Cancel -
    +
    + Create + Save + Cancel +
    diff --git a/public/app/features/playlist/partials/playlist_search.html b/public/app/features/playlist/partials/playlist_search.html index ae4fea46e80..f1fcad8f63a 100644 --- a/public/app/features/playlist/partials/playlist_search.html +++ b/public/app/features/playlist/partials/playlist_search.html @@ -1,26 +1,35 @@ diff --git a/public/app/features/playlist/partials/playlists.html b/public/app/features/playlist/partials/playlists.html index 346e76e02fd..0de792b78eb 100644 --- a/public/app/features/playlist/partials/playlists.html +++ b/public/app/features/playlist/partials/playlists.html @@ -46,7 +46,7 @@ - + @@ -55,7 +55,7 @@ diff --git a/public/app/features/profile/SignupPage.tsx b/public/app/features/profile/SignupPage.tsx index a5dad9c29a9..50554188f28 100644 --- a/public/app/features/profile/SignupPage.tsx +++ b/public/app/features/profile/SignupPage.tsx @@ -8,7 +8,7 @@ import { StoreState } from 'app/types'; const navModel = { main: { - icon: 'gicon gicon-branding', + icon: 'grafana', text: 'Sign Up', subTitle: 'Register your Grafana account', breadcrumbs: [{ title: 'Login', url: 'login' }], diff --git a/public/app/features/profile/UserProfileEditForm.tsx b/public/app/features/profile/UserProfileEditForm.tsx index c1cffc3026a..a73c74db9fb 100644 --- a/public/app/features/profile/UserProfileEditForm.tsx +++ b/public/app/features/profile/UserProfileEditForm.tsx @@ -1,5 +1,5 @@ import React, { PureComponent, ChangeEvent, MouseEvent } from 'react'; -import { Button, FormLabel, LegacyForms, Tooltip } from '@grafana/ui'; +import { Button, FormLabel, LegacyForms, Tooltip, Icon } from '@grafana/ui'; const { Input } = LegacyForms; import { User } from 'app/types'; import config from 'app/core/config'; @@ -73,7 +73,7 @@ export class UserProfileEditForm extends PureComponent { /> {disableLoginForm && ( - + )}
    @@ -88,7 +88,7 @@ export class UserProfileEditForm extends PureComponent { /> {disableLoginForm && ( - + )}
    diff --git a/public/app/features/profile/partials/profile.html b/public/app/features/profile/partials/profile.html index c0450877a36..08e3ffdb68b 100644 --- a/public/app/features/profile/partials/profile.html +++ b/public/app/features/profile/partials/profile.html @@ -24,7 +24,7 @@ {{ session.browser }} on {{ session.os }} {{ session.osVersion }} diff --git a/public/app/features/search/components/SearchField.tsx b/public/app/features/search/components/SearchField.tsx index 46f8575468c..6d57b730be8 100644 --- a/public/app/features/search/components/SearchField.tsx +++ b/public/app/features/search/components/SearchField.tsx @@ -2,7 +2,7 @@ import React, { useContext } from 'react'; import { css, cx } from 'emotion'; // @ts-ignore import tinycolor from 'tinycolor2'; -import { ThemeContext } from '@grafana/ui'; +import { ThemeContext, Icon } from '@grafana/ui'; import { GrafanaTheme } from '@grafana/data'; import { SearchQuery } from 'app/core/components/search/search'; @@ -56,7 +56,7 @@ export const SearchField: React.FunctionComponent = ({ query, {/* based on it GrafanaCtrl (L256) decides whether or not hide search */}
    - +
    = ({ item, editable, onToggleSelection, onTag > - +
    {item.title} {item.folderTitle} @@ -99,10 +99,7 @@ const getResultsItemStyles = stylesFactory((theme: GrafanaTheme) => ({ top: -1px; `, icon: css` - font-size: ${theme.typography.size.lg}; - width: auto; - height: auto; - padding: 1px 2px 0 10px; + margin-left: 10px; `, tags: css` justify-content: flex-end; diff --git a/public/app/features/search/components/SearchResults.tsx b/public/app/features/search/components/SearchResults.tsx index 9ffb85103f6..af46bcff076 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 && ( @@ -107,7 +106,7 @@ const SectionHeader: FC = ({ section, onSectionClick, onTogg )} - +
    ) : (
    @@ -140,7 +139,6 @@ const getSectionHeaderStyles = stylesFactory((theme: GrafanaTheme, selected = fa { selected } ), icon: css` - padding: 5px 0; width: 43px; `, text: css` @@ -153,8 +151,5 @@ const getSectionHeaderStyles = stylesFactory((theme: GrafanaTheme, selected = fa opacity: 0; transition: opacity 150ms ease-in-out; `, - toggle: css` - padding: 5px; - `, }; }); diff --git a/public/app/features/search/components/SearchResultsFilter.tsx b/public/app/features/search/components/SearchResultsFilter.tsx index 29cc4d935b6..2d23ec64554 100644 --- a/public/app/features/search/components/SearchResultsFilter.tsx +++ b/public/app/features/search/components/SearchResultsFilter.tsx @@ -46,10 +46,10 @@ export const SearchResultsFilter: FC = ({ {showActions ? ( - - diff --git a/public/app/features/teams/TeamGroupSync.tsx b/public/app/features/teams/TeamGroupSync.tsx index 84100a421e8..fdbba5b3536 100644 --- a/public/app/features/teams/TeamGroupSync.tsx +++ b/public/app/features/teams/TeamGroupSync.tsx @@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'; import { connect } from 'react-redux'; import { SlideDown } from 'app/core/components/Animations/SlideDown'; -import { LegacyForms, Tooltip } from '@grafana/ui'; +import { LegacyForms, Tooltip, Icon } from '@grafana/ui'; const { Input } = LegacyForms; import { TeamGroup } from '../../types'; @@ -66,7 +66,7 @@ export class TeamGroupSync extends PureComponent { {group.groupId} this.onRemoveGroup(group)}> - + @@ -82,9 +82,7 @@ export class TeamGroupSync extends PureComponent {

    External group sync

    -
    - -
    +
    {groups.length > 0 && ( @@ -97,7 +95,7 @@ export class TeamGroupSync extends PureComponent {
    Add External Group
    @@ -123,7 +121,7 @@ export class TeamGroupSync extends PureComponent { {groups.length === 0 && !isAdding && ( { return ( {
    Add team member
    diff --git a/public/app/features/teams/__snapshots__/TeamGroupSync.test.tsx.snap b/public/app/features/teams/__snapshots__/TeamGroupSync.test.tsx.snap index 32abc277b39..df52c9ed59e 100644 --- a/public/app/features/teams/__snapshots__/TeamGroupSync.test.tsx.snap +++ b/public/app/features/teams/__snapshots__/TeamGroupSync.test.tsx.snap @@ -14,13 +14,10 @@ exports[`Render should render component 1`] = ` content="Sync LDAP or OAuth groups with your Grafana teams." placement="auto" > -
    - -
    +
    -
    @@ -73,7 +70,7 @@ exports[`Render should render component 1`] = `
    -
    - -
    +
    -
    @@ -204,8 +198,8 @@ exports[`Render should render groups table 1`] = ` className="btn btn-danger btn-small" onClick={[Function]} > - @@ -227,8 +221,8 @@ exports[`Render should render groups table 1`] = ` className="btn btn-danger btn-small" onClick={[Function]} > - @@ -250,8 +244,8 @@ exports[`Render should render groups table 1`] = ` className="btn btn-danger btn-small" onClick={[Function]} > - diff --git a/public/app/features/teams/__snapshots__/TeamMembers.test.tsx.snap b/public/app/features/teams/__snapshots__/TeamMembers.test.tsx.snap index 9d500d9a79f..18263d5f116 100644 --- a/public/app/features/teams/__snapshots__/TeamMembers.test.tsx.snap +++ b/public/app/features/teams/__snapshots__/TeamMembers.test.tsx.snap @@ -37,8 +37,8 @@ exports[`Render should render component 1`] = ` className="cta-form__close btn btn-transparent" onClick={[Function]} > -
    @@ -131,8 +131,8 @@ exports[`Render should render team members 1`] = ` className="cta-form__close btn btn-transparent" onClick={[Function]} > -
    diff --git a/public/app/features/templating/partials/editor.html b/public/app/features/templating/partials/editor.html index 8f4398b0183..d2a2bad6841 100644 --- a/public/app/features/templating/partials/editor.html +++ b/public/app/features/templating/partials/editor.html @@ -94,7 +94,7 @@ class="btn btn-danger btn-small" aria-label="{{::selectors.tableRowRemoveButtons(variable.name)}}" > - + diff --git a/public/app/features/users/InviteeRow.tsx b/public/app/features/users/InviteeRow.tsx index e75138cb700..c2d1d9ca498 100644 --- a/public/app/features/users/InviteeRow.tsx +++ b/public/app/features/users/InviteeRow.tsx @@ -2,6 +2,7 @@ import React, { createRef, PureComponent } from 'react'; import { connect } from 'react-redux'; import { Invitee } from 'app/types'; import { revokeInvite } from './state/actions'; +import { Icon } from '@grafana/ui'; export interface Props { invitee: Invitee; @@ -40,7 +41,7 @@ class InviteeRow extends PureComponent { diff --git a/public/app/features/users/SignupInvited.tsx b/public/app/features/users/SignupInvited.tsx index 861cb9059d6..6ea971cf049 100644 --- a/public/app/features/users/SignupInvited.tsx +++ b/public/app/features/users/SignupInvited.tsx @@ -27,7 +27,7 @@ interface FormModel { const navModel = { main: { - icon: 'gicon gicon-branding', + icon: 'grafana', text: 'Invite', subTitle: 'Register your Grafana account', breadcrumbs: [{ title: 'Login', url: 'login' }], diff --git a/public/app/features/users/UsersTable.tsx b/public/app/features/users/UsersTable.tsx index e393ad0260a..514aaaeaf13 100644 --- a/public/app/features/users/UsersTable.tsx +++ b/public/app/features/users/UsersTable.tsx @@ -1,5 +1,6 @@ import React, { FC } from 'react'; import { OrgUser } from 'app/types'; +import { Icon } from '@grafana/ui'; export interface Props { users: OrgUser[]; @@ -55,7 +56,7 @@ const UsersTable: FC = props => {
    onRemoveUser(user)} className="btn btn-danger btn-small"> - +
    diff --git a/public/app/features/users/__snapshots__/UsersTable.test.tsx.snap b/public/app/features/users/__snapshots__/UsersTable.test.tsx.snap index 8a3da3cc22b..5fbfb0104a9 100644 --- a/public/app/features/users/__snapshots__/UsersTable.test.tsx.snap +++ b/public/app/features/users/__snapshots__/UsersTable.test.tsx.snap @@ -127,8 +127,8 @@ exports[`Render should render users table 1`] = ` className="btn btn-danger btn-small" onClick={[Function]} > -
    @@ -193,8 +193,8 @@ exports[`Render should render users table 1`] = ` className="btn btn-danger btn-small" onClick={[Function]} > -
    @@ -259,8 +259,8 @@ exports[`Render should render users table 1`] = ` className="btn btn-danger btn-small" onClick={[Function]} > -
    @@ -325,8 +325,8 @@ exports[`Render should render users table 1`] = ` className="btn btn-danger btn-small" onClick={[Function]} > -
    @@ -391,8 +391,8 @@ exports[`Render should render users table 1`] = ` className="btn btn-danger btn-small" onClick={[Function]} > -
    @@ -457,8 +457,8 @@ exports[`Render should render users table 1`] = ` className="btn btn-danger btn-small" onClick={[Function]} > -
    diff --git a/public/app/features/variables/editor/VariableEditorList.tsx b/public/app/features/variables/editor/VariableEditorList.tsx index e91701ca154..3ae1e835e48 100644 --- a/public/app/features/variables/editor/VariableEditorList.tsx +++ b/public/app/features/variables/editor/VariableEditorList.tsx @@ -3,6 +3,7 @@ import { e2e } from '@grafana/e2e'; import EmptyListCTA from '../../../core/components/EmptyListCTA/EmptyListCTA'; import { QueryVariableModel, VariableModel } from '../../templating/types'; import { toVariableIdentifier, VariableIdentifier } from '../state/types'; +import { Icon } from '@grafana/ui'; export interface Props { variables: VariableModel[]; @@ -47,7 +48,7 @@ export class VariableEditorList extends PureComponent {
    @@ -148,7 +149,7 @@ export class VariableEditorList extends PureComponent { variable.name )} > - + diff --git a/public/app/features/variables/pickers/shared/VariableLink.tsx b/public/app/features/variables/pickers/shared/VariableLink.tsx index 9428ee84220..f402ee8ec7c 100644 --- a/public/app/features/variables/pickers/shared/VariableLink.tsx +++ b/public/app/features/variables/pickers/shared/VariableLink.tsx @@ -1,5 +1,5 @@ import React, { PureComponent } from 'react'; -import { getTagColorsFromName } from '@grafana/ui'; +import { getTagColorsFromName, Icon } from '@grafana/ui'; import { e2e } from '@grafana/e2e'; import { VariableTag } from '../../../templating/types'; @@ -30,12 +30,14 @@ export class VariableLink extends PureComponent { return ( -     {tag.text} +    + +   {tag.text} ); })} - + ); } diff --git a/public/app/features/variables/pickers/shared/VariableOptions.tsx b/public/app/features/variables/pickers/shared/VariableOptions.tsx index 18430ef6c83..08693f5af11 100644 --- a/public/app/features/variables/pickers/shared/VariableOptions.tsx +++ b/public/app/features/variables/pickers/shared/VariableOptions.tsx @@ -1,5 +1,5 @@ import React, { PureComponent } from 'react'; -import { getTagColorsFromName, Tooltip } from '@grafana/ui'; +import { getTagColorsFromName, Tooltip, Icon } from '@grafana/ui'; import { e2e } from '@grafana/e2e'; import { VariableOption, VariableTag } from '../../../templating/types'; @@ -79,7 +79,9 @@ export class VariableOptions extends PureComponent { > - {tag.text}    + {tag.text}   + +   ); diff --git a/public/app/partials/confirm_modal.html b/public/app/partials/confirm_modal.html index 62fb1bc54c9..940eae3bbe8 100644 --- a/public/app/partials/confirm_modal.html +++ b/public/app/partials/confirm_modal.html @@ -1,34 +1,51 @@ diff --git a/public/app/partials/edit_json.html b/public/app/partials/edit_json.html index 5f06606cd6c..03a2ade6537 100644 --- a/public/app/partials/edit_json.html +++ b/public/app/partials/edit_json.html @@ -5,7 +5,7 @@
    diff --git a/public/app/partials/valueSelectDropdown.html b/public/app/partials/valueSelectDropdown.html index 34509570239..79895ae1b23 100644 --- a/public/app/partials/valueSelectDropdown.html +++ b/public/app/partials/valueSelectDropdown.html @@ -7,10 +7,10 @@ {{vm.linkText}} -     {{tag.text}} +     {{tag.text}} - + {{tag.text}}   {{tag.text}}   
    diff --git a/public/app/plugins/datasource/elasticsearch/configuration/DataLink.tsx b/public/app/plugins/datasource/elasticsearch/configuration/DataLink.tsx index 446f4d1ff81..fd5da650548 100644 --- a/public/app/plugins/datasource/elasticsearch/configuration/DataLink.tsx +++ b/public/app/plugins/datasource/elasticsearch/configuration/DataLink.tsx @@ -51,7 +51,7 @@ export const DataLink = (props: Props) => {
    @@ -213,7 +213,7 @@ 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`] = `
    = { label: removeText, value: removeText, icon: 'fa fa-remove' }; +const removeOption: SelectableValue = { label: removeText, value: removeText, icon: 'times' }; const operators = ['=', '!=', '=~', '!=~']; export const LabelFilter: FunctionComponent = ({ diff --git a/public/app/plugins/panel/alertlist/module.html b/public/app/plugins/panel/alertlist/module.html index b8055b5fc7f..59ae054837c 100644 --- a/public/app/plugins/panel/alertlist/module.html +++ b/public/app/plugins/panel/alertlist/module.html @@ -7,7 +7,7 @@
    1. - +
      diff --git a/public/app/plugins/panel/dashlist/module.html b/public/app/plugins/panel/dashlist/module.html index fdba0c79f35..d6664722fd4 100644 --- a/public/app/plugins/panel/dashlist/module.html +++ b/public/app/plugins/panel/dashlist/module.html @@ -10,7 +10,7 @@ {{dash.title}} - +
      diff --git a/public/app/plugins/panel/gettingstarted/GettingStarted.tsx b/public/app/plugins/panel/gettingstarted/GettingStarted.tsx index a5f96f56c6d..0933f798730 100644 --- a/public/app/plugins/panel/gettingstarted/GettingStarted.tsx +++ b/public/app/plugins/panel/gettingstarted/GettingStarted.tsx @@ -2,6 +2,7 @@ import React, { PureComponent } from 'react'; import { PanelProps } from '@grafana/data'; +import { Icon } from '@grafana/ui'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { backendSrv } from 'app/core/services/backend_srv'; import { contextSrv } from 'app/core/core'; @@ -144,7 +145,7 @@ export class GettingStarted extends PureComponent { return (
      {this.steps.map((step, index) => { diff --git a/public/app/plugins/panel/homelinks/module.tsx b/public/app/plugins/panel/homelinks/module.tsx index d4923133dff..bbdf832a512 100755 --- a/public/app/plugins/panel/homelinks/module.tsx +++ b/public/app/plugins/panel/homelinks/module.tsx @@ -1,10 +1,10 @@ // Libraries import React, { PureComponent, FC } from 'react'; -import { css, cx } from 'emotion'; +import { css } from 'emotion'; // Utils & Services import { PanelPlugin } from '@grafana/data'; -import { stylesFactory, styleMixins } from '@grafana/ui'; +import { stylesFactory, styleMixins, Icon, IconName } from '@grafana/ui'; import config from 'app/core/config'; // Types @@ -21,25 +21,25 @@ export class GrafanaLinksPanel extends PureComponent {
      @@ -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/app/plugins/panel/singlestat/mappings.html b/public/app/plugins/panel/singlestat/mappings.html index 2f65efe78e2..027c77e6903 100644 --- a/public/app/plugins/panel/singlestat/mappings.html +++ b/public/app/plugins/panel/singlestat/mappings.html @@ -1,13 +1,17 @@
      - - Type - -
      - -
      + + Type + +
      + +
      @@ -16,13 +20,25 @@
      - + - + - + - +
      @@ -37,15 +53,15 @@
      Set range mappings
      - - - - From - - To - - Text - + + + + From + + To + + Text +
      diff --git a/public/app/plugins/panel/table/column_options.html b/public/app/plugins/panel/table/column_options.html index 05e6c3e07d7..51a355b1871 100644 --- a/public/app/plugins/panel/table/column_options.html +++ b/public/app/plugins/panel/table/column_options.html @@ -4,16 +4,39 @@
      - +
      - +
      - +
      @@ -22,37 +45,62 @@
      - +
      - +
      - +
      - +
      - +
      @@ -62,8 +110,14 @@
      - +
      @@ -77,20 +131,36 @@ Type
      - +
      - + - + - +
      -
      +
      @@ -204,4 +305,3 @@  Add column style
      - diff --git a/public/app/plugins/panel/table/editor.html b/public/app/plugins/panel/table/editor.html index 47874439713..52ade842f3e 100644 --- a/public/app/plugins/panel/table/editor.html +++ b/public/app/plugins/panel/table/editor.html @@ -18,7 +18,7 @@
      diff --git a/public/sass/base/_icons.scss b/public/sass/base/_icons.scss index 112e6d9e871..202a7da508a 100644 --- a/public/sass/base/_icons.scss +++ b/public/sass/base/_icons.scss @@ -11,7 +11,7 @@ vertical-align: middle; } -.gicon--has-hover { +.icon--has-hover { opacity: 0.7; &:hover { diff --git a/public/sass/components/_buttons.scss b/public/sass/components/_buttons.scss index 89280a78d35..fb00a645d40 100644 --- a/public/sass/components/_buttons.scss +++ b/public/sass/components/_buttons.scss @@ -82,6 +82,9 @@ .btn-small { @include button-size($btn-padding-y-sm, $space-sm, $font-size-sm, $border-radius-sm); height: $height-sm; + svg { + margin-bottom: 0; + } } // Deprecated, only used by old plugins 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/_gf-form.scss b/public/sass/components/_gf-form.scss index 4c74092f6e0..cf5815e3b16 100644 --- a/public/sass/components/_gf-form.scss +++ b/public/sass/components/_gf-form.scss @@ -40,8 +40,7 @@ $input-border: 1px solid $input-border-color; .gf-form-input-icon { position: absolute; - top: 50%; - margin-top: -9px; + top: 10px; font-size: $font-size-lg; left: 10px; color: $input-color-placeholder; @@ -378,7 +377,6 @@ $input-border: 1px solid $input-border-color; .gf-form-help-icon { flex-grow: 0; - padding-left: $spacer; color: $text-color-weak; &--bold { diff --git a/public/sass/components/_modals.scss b/public/sass/components/_modals.scss index 3af632a4cea..df1b629fc0c 100644 --- a/public/sass/components/_modals.scss +++ b/public/sass/components/_modals.scss @@ -142,15 +142,8 @@ } .share-modal-big-icon { - margin-bottom: 10px; - margin-right: $space-xl; - .fa { - font-size: 50px; - } - .gicon { - width: 48px; - height: 48px; - } + margin-right: 8px; + margin-top: -7px; } .share-modal-info-text { diff --git a/public/sass/components/_page_header.scss b/public/sass/components/_page_header.scss index 8312cdc3e11..f345a7e43ae 100644 --- a/public/sass/components/_page_header.scss +++ b/public/sass/components/_page_header.scss @@ -57,7 +57,7 @@ } .page-header__logo { - margin: 0 $spacer; + margin: -1px $spacer; } .page-header__sub-title { 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/_search.scss b/public/sass/components/_search.scss index 49ff97e873f..c3e0ff51792 100644 --- a/public/sass/components/_search.scss +++ b/public/sass/components/_search.scss @@ -74,6 +74,9 @@ font-size: 20px; margin-right: 5px; } + svg { + color: $orange; + } } .search-results-scroller { 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/sass/layout/_page.scss b/public/sass/layout/_page.scss index 65a723cb9ef..e6e11b7fed2 100644 --- a/public/sass/layout/_page.scss +++ b/public/sass/layout/_page.scss @@ -149,8 +149,7 @@ .page-sub-heading-icon { margin-left: $spacer; - vertical-align: 6px; - font-size: 13px; + margin-top: $space-xs; } .page-sidebar { diff --git a/public/sass/pages/_alerting.scss b/public/sass/pages/_alerting.scss index 3d031b7f308..23505d4d4e1 100644 --- a/public/sass/pages/_alerting.scss +++ b/public/sass/pages/_alerting.scss @@ -101,6 +101,7 @@ .alert-rule-item { display: flex; + align-items: center; width: 100%; height: 100%; background: $card-background; 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;