diff --git a/superset-frontend/src/CRUD/CollectionTable.tsx b/superset-frontend/src/CRUD/CollectionTable.tsx
index ea46856df7b8..6efe2e6a61ed 100644
--- a/superset-frontend/src/CRUD/CollectionTable.tsx
+++ b/superset-frontend/src/CRUD/CollectionTable.tsx
@@ -20,6 +20,7 @@ import React, { ReactNode } from 'react';
import shortid from 'shortid';
import { t, styled } from '@superset-ui/core';
import Button from 'src/components/Button';
+import Icons from 'src/components/Icons';
import Fieldset from './Fieldset';
import { recurseReactClone } from './utils';
import './crud.less';
@@ -251,13 +252,18 @@ export default class CRUDCollection extends React.PureComponent<
}
if (allowDeletes) {
tds.push(
-
-
+
| ,
diff --git a/superset-frontend/src/components/Icons/AntdEnhanced.tsx b/superset-frontend/src/components/Icons/AntdEnhanced.tsx
new file mode 100644
index 000000000000..02438fd111cc
--- /dev/null
+++ b/superset-frontend/src/components/Icons/AntdEnhanced.tsx
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React from 'react';
+import * as AntdIcons from '@ant-design/icons/lib/icons';
+import Icon from './Icon';
+import IconType from './IconType';
+
+const AntdEnhancedIcons = Object.keys(AntdIcons)
+ .map(k => ({
+ [k]: (props: IconType) => ,
+ }))
+ .reduce((l, r) => ({ ...l, ...r }));
+
+export default AntdEnhancedIcons;
diff --git a/superset-frontend/src/components/Icons/Icon.tsx b/superset-frontend/src/components/Icons/Icon.tsx
new file mode 100644
index 000000000000..00763172bdef
--- /dev/null
+++ b/superset-frontend/src/components/Icons/Icon.tsx
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React from 'react';
+import AntdIcon from '@ant-design/icons';
+import { styled } from '@superset-ui/core';
+import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon';
+import IconType from './IconType';
+
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+const EnhancedIcon = ({ iconColor, iconSize, ...rest }: IconType) => (
+
+);
+
+const Icon = styled(EnhancedIcon)`
+ ${({ iconColor }) => iconColor && `color: ${iconColor};`};
+ font-size: ${({ iconSize, theme }) =>
+ iconSize ? `${theme.typography.sizes[iconSize]}px` : '24px'};
+`;
+
+export const renderIcon = (
+ SVGComponent:
+ | React.ComponentClass<
+ CustomIconComponentProps | React.SVGProps,
+ any
+ >
+ | React.FunctionComponent<
+ CustomIconComponentProps | React.SVGProps
+ >
+ | undefined,
+ props: IconType,
+) => ;
+
+export default Icon;
diff --git a/superset-frontend/src/components/Icons/IconType.ts b/superset-frontend/src/components/Icons/IconType.ts
new file mode 100644
index 000000000000..85e0ad8ee1a2
--- /dev/null
+++ b/superset-frontend/src/components/Icons/IconType.ts
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import AntdIcon from '@ant-design/icons';
+
+type AntdIconType = typeof AntdIcon.defaultProps;
+type IconType = AntdIconType & {
+ iconColor?: string;
+ iconSize?: 's' | 'm' | 'l' | 'xl' | 'xxl';
+};
+
+export default IconType;
diff --git a/superset-frontend/src/components/Icons/icons.stories.jsx b/superset-frontend/src/components/Icons/icons.stories.jsx
new file mode 100644
index 000000000000..8a2201180334
--- /dev/null
+++ b/superset-frontend/src/components/Icons/icons.stories.jsx
@@ -0,0 +1,83 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import React from 'react';
+import { withKnobs, select } from '@storybook/addon-knobs';
+import { styled, supersetTheme } from '@superset-ui/core';
+import Icons from '.';
+import Icon from './Icon';
+
+export default {
+ title: 'Icons',
+ component: Icon,
+ decorators: [withKnobs],
+};
+
+const palette = {};
+Object.entries(supersetTheme.colors).forEach(([familyName, family]) => {
+ Object.entries(family).forEach(([colorName, colorValue]) => {
+ palette[`${familyName} / ${colorName}`] = colorValue;
+ });
+});
+
+const colorKnob = {
+ label: 'Color',
+ options: {
+ Default: null,
+ ...palette,
+ },
+ defaultValue: null,
+};
+
+const IconSet = styled.div`
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+`;
+
+const IconBlock = styled.div`
+ flex-grow: 0;
+ flex-shrink: 0;
+ flex-basis: 10%;
+ text-align: center;
+ padding: ${({ theme }) => theme.gridUnit * 2}px;
+ div {
+ white-space: nowrap;
+ font-size: ${({ theme }) => theme.typography.sizes.s}px;
+ }
+`;
+
+export const SupersetIcon = () => (
+
+ {Object.keys(Icons).map(k => {
+ const IconComponent = Icons[k];
+ return (
+
+
+
+ );
+ })}
+
+);
diff --git a/superset-frontend/src/components/Icons/index.ts b/superset-frontend/src/components/Icons/index.ts
new file mode 100644
index 000000000000..0bb0310fd92f
--- /dev/null
+++ b/superset-frontend/src/components/Icons/index.ts
@@ -0,0 +1,284 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { ReactComponent as AlertIcon } from 'images/icons/alert.svg';
+import { ReactComponent as AlertSolidIcon } from 'images/icons/alert_solid.svg';
+import { ReactComponent as AlertSolidSmallIcon } from 'images/icons/alert_solid_small.svg';
+import { ReactComponent as BinocularsIcon } from 'images/icons/binoculars.svg';
+import { ReactComponent as BoltIcon } from 'images/icons/bolt.svg';
+import { ReactComponent as BoltSmallIcon } from 'images/icons/bolt_small.svg';
+import { ReactComponent as BoltSmallRunIcon } from 'images/icons/bolt_small_run.svg';
+import { ReactComponent as CalendarIcon } from 'images/icons/calendar.svg';
+import { ReactComponent as CancelIcon } from 'images/icons/cancel.svg';
+import { ReactComponent as CancelSolidIcon } from 'images/icons/cancel_solid.svg';
+import { ReactComponent as CancelXIcon } from 'images/icons/cancel-x.svg';
+import { ReactComponent as CardViewIcon } from 'images/icons/card_view.svg';
+import { ReactComponent as CardsIcon } from 'images/icons/cards.svg';
+import { ReactComponent as CardsLockedIcon } from 'images/icons/cards_locked.svg';
+import { ReactComponent as CaretDownIcon } from 'images/icons/caret_down.svg';
+import { ReactComponent as CaretLeftIcon } from 'images/icons/caret_left.svg';
+import { ReactComponent as CaretRightIcon } from 'images/icons/caret_right.svg';
+import { ReactComponent as CaretUpIcon } from 'images/icons/caret_up.svg';
+import { ReactComponent as CertifiedIcon } from 'images/icons/certified.svg';
+import { ReactComponent as CheckIcon } from 'images/icons/check.svg';
+import { ReactComponent as CheckboxHalfIcon } from 'images/icons/checkbox-half.svg';
+import { ReactComponent as CheckboxOffIcon } from 'images/icons/checkbox-off.svg';
+import { ReactComponent as CheckboxOnIcon } from 'images/icons/checkbox-on.svg';
+import { ReactComponent as CircleCheckIcon } from 'images/icons/circle_check.svg';
+import { ReactComponent as CircleCheckSolidIcon } from 'images/icons/circle_check_solid.svg';
+import { ReactComponent as CircleIcon } from 'images/icons/circle.svg';
+import { ReactComponent as ClockIcon } from 'images/icons/clock.svg';
+import { ReactComponent as CloseIcon } from 'images/icons/close.svg';
+import { ReactComponent as CodeIcon } from 'images/icons/code.svg';
+import { ReactComponent as CogIcon } from 'images/icons/cog.svg';
+import { ReactComponent as CollapseIcon } from 'images/icons/collapse.svg';
+import { ReactComponent as ColorPaletteIcon } from 'images/icons/color_palette.svg';
+import { ReactComponent as ComponentsIcon } from 'images/icons/components.svg';
+import { ReactComponent as CopyIcon } from 'images/icons/copy.svg';
+import { ReactComponent as CursorTargeIcon } from 'images/icons/cursor_target.svg';
+import { ReactComponent as DatabaseIcon } from 'images/icons/database.svg';
+import { ReactComponent as DatasetPhysicalIcon } from 'images/icons/dataset_physical.svg';
+import { ReactComponent as DatasetVirtualGreyscaleIcon } from 'images/icons/dataset_virtual_greyscale.svg';
+import { ReactComponent as DatasetVirtualIcon } from 'images/icons/dataset_virtual.svg';
+import { ReactComponent as DownloadIcon } from 'images/icons/download.svg';
+import { ReactComponent as EditAltIcon } from 'images/icons/edit_alt.svg';
+import { ReactComponent as EditIcon } from 'images/icons/edit.svg';
+import { ReactComponent as EmailIcon } from 'images/icons/email.svg';
+import { ReactComponent as ErrorIcon } from 'images/icons/error.svg';
+import { ReactComponent as ErrorSolidIcon } from 'images/icons/error_solid.svg';
+import { ReactComponent as ErrorSolidSmallIcon } from 'images/icons/error_solid_small.svg';
+import { ReactComponent as ExclamationIcon } from 'images/icons/exclamation.svg';
+import { ReactComponent as ExpandIcon } from 'images/icons/expand.svg';
+import { ReactComponent as EyeIcon } from 'images/icons/eye.svg';
+import { ReactComponent as EyeSlashIcon } from 'images/icons/eye_slash.svg';
+import { ReactComponent as FavoriteSelectedIcon } from 'images/icons/favorite-selected.svg';
+import { ReactComponent as FavoriteSmallSelectedIcon } from 'images/icons/favorite_small_selected.svg';
+import { ReactComponent as FavoriteUnselectedIcon } from 'images/icons/favorite-unselected.svg';
+import { ReactComponent as FieldABCIcon } from 'images/icons/field_abc.svg';
+import { ReactComponent as FieldBooleanIcon } from 'images/icons/field_boolean.svg';
+import { ReactComponent as FieldDateIcon } from 'images/icons/field_date.svg';
+import { ReactComponent as FieldDerivedIcon } from 'images/icons/field_derived.svg';
+import { ReactComponent as FieldNumIcon } from 'images/icons/field_num.svg';
+import { ReactComponent as FieldStructIcon } from 'images/icons/field_struct.svg';
+import { ReactComponent as FileIcon } from 'images/icons/file.svg';
+import { ReactComponent as FilterIcon } from 'images/icons/filter.svg';
+import { ReactComponent as FilterSmallIcon } from 'images/icons/filter_small.svg';
+import { ReactComponent as FolderIcon } from 'images/icons/folder.svg';
+import { ReactComponent as FullIcon } from 'images/icons/full.svg';
+import { ReactComponent as FunctionIcon } from 'images/icons/function_x.svg';
+import { ReactComponent as GearIcon } from 'images/icons/gear.svg';
+import { ReactComponent as GridIcon } from 'images/icons/grid.svg';
+import { ReactComponent as ImageIcon } from 'images/icons/image.svg';
+import { ReactComponent as ImportIcon } from 'images/icons/import.svg';
+import { ReactComponent as InfoIcon } from 'images/icons/info.svg';
+import { ReactComponent as InfoSolidIcon } from 'images/icons/info-solid.svg';
+import { ReactComponent as InfoSolidSmallIcon } from 'images/icons/info_solid_small.svg';
+import { ReactComponent as JoinIcon } from 'images/icons/join.svg';
+import { ReactComponent as KeyboardIcon } from 'images/icons/keyboard.svg';
+import { ReactComponent as LayersIcon } from 'images/icons/layers.svg';
+import { ReactComponent as LightbulbIcon } from 'images/icons/lightbulb.svg';
+import { ReactComponent as LinkIcon } from 'images/icons/link.svg';
+import { ReactComponent as ListIcon } from 'images/icons/list.svg';
+import { ReactComponent as ListViewIcon } from 'images/icons/list_view.svg';
+import { ReactComponent as LocationIcon } from 'images/icons/location.svg';
+import { ReactComponent as LockLockedIcon } from 'images/icons/lock_locked.svg';
+import { ReactComponent as LockUnlockedIcon } from 'images/icons/lock_unlocked.svg';
+import { ReactComponent as MapIcon } from 'images/icons/map.svg';
+import { ReactComponent as MessageIcon } from 'images/icons/message.svg';
+import { ReactComponent as MinusIcon } from 'images/icons/minus.svg';
+import { ReactComponent as MinusSolidIcon } from 'images/icons/minus_solid.svg';
+import { ReactComponent as MoreHorizIcon } from 'images/icons/more_horiz.svg';
+import { ReactComponent as MoveIcon } from 'images/icons/move.svg';
+import { ReactComponent as NavChartsIcon } from 'images/icons/nav_charts.svg';
+import { ReactComponent as NavDashboardIcon } from 'images/icons/nav_dashboard.svg';
+import { ReactComponent as NavDataIcon } from 'images/icons/nav_data.svg';
+import { ReactComponent as NavExploreIcon } from 'images/icons/nav_explore.svg';
+import { ReactComponent as NavHomeIcon } from 'images/icons/nav_home.svg';
+import { ReactComponent as NavLabIcon } from 'images/icons/nav_lab.svg';
+import { ReactComponent as NoteIcon } from 'images/icons/note.svg';
+import { ReactComponent as OfflineIcon } from 'images/icons/offline.svg';
+import { ReactComponent as PaperclipIcon } from 'images/icons/paperclip.svg';
+import { ReactComponent as PlaceholderIcon } from 'images/icons/placeholder.svg';
+import { ReactComponent as PlusIcon } from 'images/icons/plus.svg';
+import { ReactComponent as PlusLargeIcon } from 'images/icons/plus_large.svg';
+import { ReactComponent as PlusSmallIcon } from 'images/icons/plus_small.svg';
+import { ReactComponent as PlusSolidIcon } from 'images/icons/plus_solid.svg';
+import { ReactComponent as QueuedIcon } from 'images/icons/queued.svg';
+import { ReactComponent as RefreshIcon } from 'images/icons/refresh.svg';
+import { ReactComponent as RunningIcon } from 'images/icons/running.svg';
+import { ReactComponent as SaveIcon } from 'images/icons/save.svg';
+import { ReactComponent as SQLIcon } from 'images/icons/sql.svg';
+import { ReactComponent as SearchIcon } from 'images/icons/search.svg';
+import { ReactComponent as ServerIcon } from 'images/icons/server.svg';
+import { ReactComponent as ShareIcon } from 'images/icons/share.svg';
+import { ReactComponent as SlackIcon } from 'images/icons/slack.svg';
+import { ReactComponent as SortAscIcon } from 'images/icons/sort_asc.svg';
+import { ReactComponent as SortDescIcon } from 'images/icons/sort_desc.svg';
+import { ReactComponent as SortIcon } from 'images/icons/sort.svg';
+import { ReactComponent as TableIcon } from 'images/icons/table.svg';
+import { ReactComponent as TagIcon } from 'images/icons/tag.svg';
+import { ReactComponent as TrashIcon } from 'images/icons/trash.svg';
+import { ReactComponent as TriangleChangeIcon } from 'images/icons/triangle_change.svg';
+import { ReactComponent as TriangleDownIcon } from 'images/icons/triangle_down.svg';
+import { ReactComponent as TriangleUpIcon } from 'images/icons/triangle_up.svg';
+import { ReactComponent as UpLevelIcon } from 'images/icons/up-level.svg';
+import { ReactComponent as UserIcon } from 'images/icons/user.svg';
+import { ReactComponent as WarningIcon } from 'images/icons/warning.svg';
+import { ReactComponent as WarningSolidIcon } from 'images/icons/warning_solid.svg';
+import { ReactComponent as XLargeIcon } from 'images/icons/x-large.svg';
+import { ReactComponent as XSmallIcon } from 'images/icons/x-small.svg';
+
+import AntdEnhancedIcons from './AntdEnhanced';
+import { renderIcon } from './Icon';
+import IconType from './IconType';
+
+export default {
+ ...AntdEnhancedIcons,
+ Alert: (props: IconType) => renderIcon(AlertIcon, props),
+ AlertSolid: (props: IconType) => renderIcon(AlertSolidIcon, props),
+ AlertSolidSmall: (props: IconType) => renderIcon(AlertSolidSmallIcon, props),
+ Binoculars: (props: IconType) => renderIcon(BinocularsIcon, props),
+ Bolt: (props: IconType) => renderIcon(BoltIcon, props),
+ BoltSmall: (props: IconType) => renderIcon(BoltSmallIcon, props),
+ BoltSmallRun: (props: IconType) => renderIcon(BoltSmallRunIcon, props),
+ Calendar: (props: IconType) => renderIcon(CalendarIcon, props),
+ Cancel: (props: IconType) => renderIcon(CancelIcon, props),
+ CancelSolid: (props: IconType) => renderIcon(CancelSolidIcon, props),
+ CancelX: (props: IconType) => renderIcon(CancelXIcon, props),
+ CardView: (props: IconType) => renderIcon(CardViewIcon, props),
+ Cards: (props: IconType) => renderIcon(CardsIcon, props),
+ CardsLocked: (props: IconType) => renderIcon(CardsLockedIcon, props),
+ CaretDown: (props: IconType) => renderIcon(CaretDownIcon, props),
+ CaretLeft: (props: IconType) => renderIcon(CaretLeftIcon, props),
+ CaretRight: (props: IconType) => renderIcon(CaretRightIcon, props),
+ CaretUp: (props: IconType) => renderIcon(CaretUpIcon, props),
+ Certified: (props: IconType) => renderIcon(CertifiedIcon, props),
+ Check: (props: IconType) => renderIcon(CheckIcon, props),
+ CheckboxHalf: (props: IconType) => renderIcon(CheckboxHalfIcon, props),
+ CheckboxOff: (props: IconType) => renderIcon(CheckboxOffIcon, props),
+ CheckboxOn: (props: IconType) => renderIcon(CheckboxOnIcon, props),
+ CircleCheck: (props: IconType) => renderIcon(CircleCheckIcon, props),
+ CircleCheckSolid: (props: IconType) =>
+ renderIcon(CircleCheckSolidIcon, props),
+ Circle: (props: IconType) => renderIcon(CircleIcon, props),
+ Clock: (props: IconType) => renderIcon(ClockIcon, props),
+ Close: (props: IconType) => renderIcon(CloseIcon, props),
+ Code: (props: IconType) => renderIcon(CodeIcon, props),
+ Cog: (props: IconType) => renderIcon(CogIcon, props),
+ Collapse: (props: IconType) => renderIcon(CollapseIcon, props),
+ ColorPalette: (props: IconType) => renderIcon(ColorPaletteIcon, props),
+ Components: (props: IconType) => renderIcon(ComponentsIcon, props),
+ Copy: (props: IconType) => renderIcon(CopyIcon, props),
+ CursorTarget: (props: IconType) => renderIcon(CursorTargeIcon, props),
+ Database: (props: IconType) => renderIcon(DatabaseIcon, props),
+ DatasetPhysical: (props: IconType) => renderIcon(DatasetPhysicalIcon, props),
+ DatasetVirtualGreyscale: (props: IconType) =>
+ renderIcon(DatasetVirtualGreyscaleIcon, props),
+ DatasetVirtual: (props: IconType) => renderIcon(DatasetVirtualIcon, props),
+ Download: (props: IconType) => renderIcon(DownloadIcon, props),
+ EditAlt: (props: IconType) => renderIcon(EditAltIcon, props),
+ Edit: (props: IconType) => renderIcon(EditIcon, props),
+ Email: (props: IconType) => renderIcon(EmailIcon, props),
+ Error: (props: IconType) => renderIcon(ErrorIcon, props),
+ ErrorSolid: (props: IconType) => renderIcon(ErrorSolidIcon, props),
+ ErrorSolidSmall: (props: IconType) => renderIcon(ErrorSolidSmallIcon, props),
+ Exclamation: (props: IconType) => renderIcon(ExclamationIcon, props),
+ Expand: (props: IconType) => renderIcon(ExpandIcon, props),
+ Eye: (props: IconType) => renderIcon(EyeIcon, props),
+ EyeSlash: (props: IconType) => renderIcon(EyeSlashIcon, props),
+ FavoriteSelected: (props: IconType) =>
+ renderIcon(FavoriteSelectedIcon, props),
+ FavoriteSmallSelected: (props: IconType) =>
+ renderIcon(FavoriteSmallSelectedIcon, props),
+ FavoriteUnselected: (props: IconType) =>
+ renderIcon(FavoriteUnselectedIcon, props),
+ FieldABCIcon: (props: IconType) => renderIcon(FieldABCIcon, props),
+ FieldBoolean: (props: IconType) => renderIcon(FieldBooleanIcon, props),
+ FieldDate: (props: IconType) => renderIcon(FieldDateIcon, props),
+ FieldDerived: (props: IconType) => renderIcon(FieldDerivedIcon, props),
+ FieldNum: (props: IconType) => renderIcon(FieldNumIcon, props),
+ FieldStruct: (props: IconType) => renderIcon(FieldStructIcon, props),
+ File: (props: IconType) => renderIcon(FileIcon, props),
+ Filter: (props: IconType) => renderIcon(FilterIcon, props),
+ FilterSmall: (props: IconType) => renderIcon(FilterSmallIcon, props),
+ Folder: (props: IconType) => renderIcon(FolderIcon, props),
+ Full: (props: IconType) => renderIcon(FullIcon, props),
+ Function: (props: IconType) => renderIcon(FunctionIcon, props),
+ Gear: (props: IconType) => renderIcon(GearIcon, props),
+ Grid: (props: IconType) => renderIcon(GridIcon, props),
+ Image: (props: IconType) => renderIcon(ImageIcon, props),
+ Import: (props: IconType) => renderIcon(ImportIcon, props),
+ Info: (props: IconType) => renderIcon(InfoIcon, props),
+ InfoSolid: (props: IconType) => renderIcon(InfoSolidIcon, props),
+ InfoSolidSmall: (props: IconType) => renderIcon(InfoSolidSmallIcon, props),
+ Join: (props: IconType) => renderIcon(JoinIcon, props),
+ Keyboard: (props: IconType) => renderIcon(KeyboardIcon, props),
+ Layers: (props: IconType) => renderIcon(LayersIcon, props),
+ Lightbulb: (props: IconType) => renderIcon(LightbulbIcon, props),
+ Link: (props: IconType) => renderIcon(LinkIcon, props),
+ List: (props: IconType) => renderIcon(ListIcon, props),
+ ListView: (props: IconType) => renderIcon(ListViewIcon, props),
+ Location: (props: IconType) => renderIcon(LocationIcon, props),
+ LockLocked: (props: IconType) => renderIcon(LockLockedIcon, props),
+ LockUnlocked: (props: IconType) => renderIcon(LockUnlockedIcon, props),
+ Map: (props: IconType) => renderIcon(MapIcon, props),
+ Message: (props: IconType) => renderIcon(MessageIcon, props),
+ Minus: (props: IconType) => renderIcon(MinusIcon, props),
+ MinusSolid: (props: IconType) => renderIcon(MinusSolidIcon, props),
+ MoreHoriz: (props: IconType) => renderIcon(MoreHorizIcon, props),
+ Move: (props: IconType) => renderIcon(MoveIcon, props),
+ NavCharts: (props: IconType) => renderIcon(NavChartsIcon, props),
+ NavDashboard: (props: IconType) => renderIcon(NavDashboardIcon, props),
+ NavData: (props: IconType) => renderIcon(NavDataIcon, props),
+ NavExplore: (props: IconType) => renderIcon(NavExploreIcon, props),
+ NavHome: (props: IconType) => renderIcon(NavHomeIcon, props),
+ NavLab: (props: IconType) => renderIcon(NavLabIcon, props),
+ Note: (props: IconType) => renderIcon(NoteIcon, props),
+ Offline: (props: IconType) => renderIcon(OfflineIcon, props),
+ Paperclip: (props: IconType) => renderIcon(PaperclipIcon, props),
+ Placeholder: (props: IconType) => renderIcon(PlaceholderIcon, props),
+ Plus: (props: IconType) => renderIcon(PlusIcon, props),
+ PlusLarge: (props: IconType) => renderIcon(PlusLargeIcon, props),
+ PlusSmall: (props: IconType) => renderIcon(PlusSmallIcon, props),
+ PlusSolid: (props: IconType) => renderIcon(PlusSolidIcon, props),
+ Queued: (props: IconType) => renderIcon(QueuedIcon, props),
+ Refresh: (props: IconType) => renderIcon(RefreshIcon, props),
+ Running: (props: IconType) => renderIcon(RunningIcon, props),
+ Save: (props: IconType) => renderIcon(SaveIcon, props),
+ SQL: (props: IconType) => renderIcon(SQLIcon, props),
+ Search: (props: IconType) => renderIcon(SearchIcon, props),
+ Server: (props: IconType) => renderIcon(ServerIcon, props),
+ Share: (props: IconType) => renderIcon(ShareIcon, props),
+ Slack: (props: IconType) => renderIcon(SlackIcon, props),
+ SortAsc: (props: IconType) => renderIcon(SortAscIcon, props),
+ SortDesc: (props: IconType) => renderIcon(SortDescIcon, props),
+ Sort: (props: IconType) => renderIcon(SortIcon, props),
+ Table: (props: IconType) => renderIcon(TableIcon, props),
+ Tag: (props: IconType) => renderIcon(TagIcon, props),
+ Trash: (props: IconType) => renderIcon(TrashIcon, props),
+ TriangleChange: (props: IconType) => renderIcon(TriangleChangeIcon, props),
+ TriangleDown: (props: IconType) => renderIcon(TriangleDownIcon, props),
+ TriangleUp: (props: IconType) => renderIcon(TriangleUpIcon, props),
+ UpLevel: (props: IconType) => renderIcon(UpLevelIcon, props),
+ User: (props: IconType) => renderIcon(UserIcon, props),
+ Warning: (props: IconType) => renderIcon(WarningIcon, props),
+ WarningSolid: (props: IconType) => renderIcon(WarningSolidIcon, props),
+ XLarge: (props: IconType) => renderIcon(XLargeIcon, props),
+ XSmall: (props: IconType) => renderIcon(XSmallIcon, props),
+};
diff --git a/superset-frontend/src/components/ListView/ActionsBar.tsx b/superset-frontend/src/components/ListView/ActionsBar.tsx
index b9785294ef11..135982208e85 100644
--- a/superset-frontend/src/components/ListView/ActionsBar.tsx
+++ b/superset-frontend/src/components/ListView/ActionsBar.tsx
@@ -19,7 +19,8 @@
import React from 'react';
import { styled } from '@superset-ui/core';
import { Tooltip } from 'src/common/components/Tooltip';
-import Icon, { IconName } from 'src/components/Icon';
+import { IconName } from 'src/components/Icon';
+import Icons from 'src/components/Icons';
import { TooltipPlacement } from 'antd/lib/tooltip';
export type ActionProps = {
@@ -37,7 +38,6 @@ interface ActionsBarProps {
const StyledActions = styled.span`
white-space: nowrap;
min-width: 100px;
-
svg,
i {
margin-right: 8px;
@@ -50,10 +50,15 @@ const StyledActions = styled.span`
}
`;
+const ActionWrapper = styled.span`
+ color: ${({ theme }) => theme.colors.grayscale.base};
+`;
+
export default function ActionsBar({ actions }: ActionsBarProps) {
return (
{actions.map((action, index) => {
+ const ActionIcon = Icons[action.icon];
if (action.tooltip) {
return (
-
-
-
+
+
);
}
return (
-
-
-
+
+
);
})}
diff --git a/superset-frontend/src/components/ListViewCard/ListViewCard.stories.tsx b/superset-frontend/src/components/ListViewCard/ListViewCard.stories.tsx
index 5f716c01f8d4..fdd3778d5dc4 100644
--- a/superset-frontend/src/components/ListViewCard/ListViewCard.stories.tsx
+++ b/superset-frontend/src/components/ListViewCard/ListViewCard.stories.tsx
@@ -23,6 +23,7 @@ import DashboardImg from 'images/dashboard-card-fallback.svg';
import ChartImg from 'images/chart-card-fallback.svg';
import { Dropdown, Menu } from 'src/common/components';
import Icon from 'src/components/Icon';
+import Icons from 'src/components/Icons';
import FaveStar from 'src/components/FaveStar';
import ListViewCard from '.';
@@ -67,10 +68,10 @@ export const SupersetListViewCard = () => (
overlay={
}
diff --git a/superset-frontend/src/components/ListViewCard/index.tsx b/superset-frontend/src/components/ListViewCard/index.tsx
index 94f14a8e403e..1090d8b88052 100644
--- a/superset-frontend/src/components/ListViewCard/index.tsx
+++ b/superset-frontend/src/components/ListViewCard/index.tsx
@@ -23,13 +23,6 @@ import { Card, Skeleton, ThinSkeleton } from 'src/common/components';
import { Tooltip } from 'src/common/components/Tooltip';
import ImageLoader, { BackgroundPosition } from './ImageLoader';
-const MenuIcon = styled(Icon)`
- width: ${({ theme }) => theme.gridUnit * 4}px;
- height: ${({ theme }) => theme.gridUnit * 4}px;
- position: relative;
- top: ${({ theme }) => theme.gridUnit / 2}px;
-`;
-
const ActionsWrapper = styled.div`
width: 64px;
display: flex;
@@ -250,5 +243,5 @@ function ListViewCard({
}
ListViewCard.Actions = ActionsWrapper;
-ListViewCard.MenuIcon = MenuIcon;
+
export default ListViewCard;
diff --git a/superset-frontend/src/views/CRUD/alert/AlertList.tsx b/superset-frontend/src/views/CRUD/alert/AlertList.tsx
index 7232b3da39ab..78bec5a9d324 100644
--- a/superset-frontend/src/views/CRUD/alert/AlertList.tsx
+++ b/superset-frontend/src/views/CRUD/alert/AlertList.tsx
@@ -24,7 +24,6 @@ import moment from 'moment';
import ActionsBar, { ActionProps } from 'src/components/ListView/ActionsBar';
import Button from 'src/components/Button';
import FacePile from 'src/components/FacePile';
-import { IconName } from 'src/components/Icon';
import { Tooltip } from 'src/common/components/Tooltip';
import ListView, {
FilterOperators,
@@ -297,7 +296,7 @@ function AlertList({
label: 'execution-log-action',
tooltip: t('Execution log'),
placement: 'bottom',
- icon: 'note' as IconName,
+ icon: 'Note',
onClick: handleGotoExecutionLog,
}
: null,
@@ -306,7 +305,7 @@ function AlertList({
label: 'edit-action',
tooltip: t('Edit'),
placement: 'bottom',
- icon: 'edit' as IconName,
+ icon: 'Edit',
onClick: handleEdit,
}
: null,
@@ -315,7 +314,7 @@ function AlertList({
label: 'delete-action',
tooltip: t('Delete'),
placement: 'bottom',
- icon: 'trash' as IconName,
+ icon: 'Trash',
onClick: handleDelete,
}
: null,
diff --git a/superset-frontend/src/views/CRUD/annotation/AnnotationList.tsx b/superset-frontend/src/views/CRUD/annotation/AnnotationList.tsx
index bdcbf4116389..a824b59cb3f1 100644
--- a/superset-frontend/src/views/CRUD/annotation/AnnotationList.tsx
+++ b/superset-frontend/src/views/CRUD/annotation/AnnotationList.tsx
@@ -31,7 +31,6 @@ import ListView, { ListViewProps } from 'src/components/ListView';
import SubMenu, { SubMenuProps } from 'src/components/Menu/SubMenu';
import { getClientErrorObject } from 'src/utils/getClientErrorObject';
import withToasts from 'src/messageToasts/enhancers/withToasts';
-import { IconName } from 'src/components/Icon';
import { useListViewResource } from 'src/views/CRUD/hooks';
import { createErrorHandler } from 'src/views/CRUD/utils';
@@ -179,14 +178,14 @@ function AnnotationList({
label: 'edit-action',
tooltip: t('Edit annotation'),
placement: 'bottom',
- icon: 'edit' as IconName,
+ icon: 'Edit',
onClick: handleEdit,
},
{
label: 'delete-action',
tooltip: t('Delete annotation'),
placement: 'bottom',
- icon: 'trash' as IconName,
+ icon: 'Trash',
onClick: handleDelete,
},
];
diff --git a/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayersList.tsx b/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayersList.tsx
index 44892c800199..4fa1c2b8006f 100644
--- a/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayersList.tsx
+++ b/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayersList.tsx
@@ -26,7 +26,6 @@ import { useListViewResource } from 'src/views/CRUD/hooks';
import { createFetchRelated, createErrorHandler } from 'src/views/CRUD/utils';
import withToasts from 'src/messageToasts/enhancers/withToasts';
import SubMenu, { SubMenuProps } from 'src/components/Menu/SubMenu';
-import { IconName } from 'src/components/Icon';
import ActionsBar, { ActionProps } from 'src/components/ListView/ActionsBar';
import ListView, { ListViewProps, Filters } from 'src/components/ListView';
import Button from 'src/components/Button';
@@ -230,7 +229,7 @@ function AnnotationLayersList({
label: 'edit-action',
tooltip: t('Edit template'),
placement: 'bottom',
- icon: 'edit' as IconName,
+ icon: 'Edit',
onClick: handleEdit,
}
: null,
@@ -239,7 +238,7 @@ function AnnotationLayersList({
label: 'delete-action',
tooltip: t('Delete template'),
placement: 'bottom',
- icon: 'trash' as IconName,
+ icon: 'Trash',
onClick: handleDelete,
}
: null,
diff --git a/superset-frontend/src/views/CRUD/chart/ChartCard.tsx b/superset-frontend/src/views/CRUD/chart/ChartCard.tsx
index 4b97942664c1..457f46b706b0 100644
--- a/superset-frontend/src/views/CRUD/chart/ChartCard.tsx
+++ b/superset-frontend/src/views/CRUD/chart/ChartCard.tsx
@@ -21,6 +21,7 @@ import { t } from '@superset-ui/core';
import { isFeatureEnabled, FeatureFlag } from 'src/featureFlags';
import ConfirmStatusChange from 'src/components/ConfirmStatusChange';
import Icon from 'src/components/Icon';
+import Icons from 'src/components/Icons';
import Chart from 'src/types/Chart';
import ListViewCard from 'src/components/ListViewCard';
@@ -95,29 +96,33 @@ export default function ChartCard({
className="action-button"
onClick={confirmDelete}
>
- {t('Delete')}
+ {t('Delete')}
)}
)}
{canExport && (
- handleBulkChartExport([chart])}
- >
- {t('Export')}
+
+ handleBulkChartExport([chart])}
+ >
+ {t('Export')}
+
)}
{canEdit && (
- openChartEditModal(chart)}
- >
- {t('Edit')}
+
+ openChartEditModal(chart)}
+ >
+ {t('Edit')}
+
)}
diff --git a/superset-frontend/src/views/CRUD/chart/ChartList.tsx b/superset-frontend/src/views/CRUD/chart/ChartList.tsx
index c37fcac37e6a..26edf5abd423 100644
--- a/superset-frontend/src/views/CRUD/chart/ChartList.tsx
+++ b/superset-frontend/src/views/CRUD/chart/ChartList.tsx
@@ -16,7 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { SupersetClient, getChartMetadataRegistry, t } from '@superset-ui/core';
+import {
+ SupersetClient,
+ getChartMetadataRegistry,
+ t,
+ styled,
+} from '@superset-ui/core';
import React, { useMemo, useState } from 'react';
import rison from 'rison';
import { uniqBy } from 'lodash';
@@ -34,7 +39,6 @@ import {
} from 'src/views/CRUD/hooks';
import ConfirmStatusChange from 'src/components/ConfirmStatusChange';
import SubMenu, { SubMenuProps } from 'src/components/Menu/SubMenu';
-import Icon from 'src/components/Icon';
import FaveStar from 'src/components/FaveStar';
import ListView, {
ListViewProps,
@@ -47,6 +51,7 @@ import PropertiesModal from 'src/explore/components/PropertiesModal';
import ImportModelsModal from 'src/components/ImportModal/index';
import Chart from 'src/types/Chart';
import { Tooltip } from 'src/common/components/Tooltip';
+import Icons from 'src/components/Icons';
import ChartCard from './ChartCard';
const PAGE_SIZE = 25;
@@ -111,6 +116,10 @@ interface ChartListProps {
};
}
+const Actions = styled.div`
+ color: ${({ theme }) => theme.colors.grayscale.base};
+`;
+
function ChartList(props: ChartListProps) {
const { addDangerToast, addSuccessToast } = props;
@@ -295,7 +304,7 @@ function ChartList(props: ChartListProps) {
}
return (
-
+
{canDelete && (
-
+
)}
@@ -337,7 +347,7 @@ function ChartList(props: ChartListProps) {
className="action-button"
onClick={handleExport}
>
-
+
)}
@@ -353,11 +363,11 @@ function ChartList(props: ChartListProps) {
className="action-button"
onClick={openEditModal}
>
-
+
)}
-
+
);
},
Header: t('Actions'),
@@ -535,7 +545,7 @@ function ChartList(props: ChartListProps) {
}
if (isFeatureEnabled(FeatureFlag.VERSIONED_EXPORT)) {
subMenuButtons.push({
- name: ,
+ name: ,
buttonStyle: 'link',
onClick: openChartImportModal,
});
diff --git a/superset-frontend/src/views/CRUD/csstemplates/CssTemplatesList.tsx b/superset-frontend/src/views/CRUD/csstemplates/CssTemplatesList.tsx
index 5e33bfad0fea..4d886d7d6b28 100644
--- a/superset-frontend/src/views/CRUD/csstemplates/CssTemplatesList.tsx
+++ b/superset-frontend/src/views/CRUD/csstemplates/CssTemplatesList.tsx
@@ -29,7 +29,6 @@ import SubMenu, { SubMenuProps } from 'src/components/Menu/SubMenu';
import DeleteModal from 'src/components/DeleteModal';
import { Tooltip } from 'src/common/components/Tooltip';
import ConfirmStatusChange from 'src/components/ConfirmStatusChange';
-import { IconName } from 'src/components/Icon';
import ActionsBar, { ActionProps } from 'src/components/ListView/ActionsBar';
import ListView, { ListViewProps, Filters } from 'src/components/ListView';
import CssTemplateModal from './CssTemplateModal';
@@ -209,7 +208,7 @@ function CssTemplatesList({
label: 'edit-action',
tooltip: t('Edit template'),
placement: 'bottom',
- icon: 'edit' as IconName,
+ icon: 'Edit',
onClick: handleEdit,
}
: null,
@@ -218,7 +217,7 @@ function CssTemplatesList({
label: 'delete-action',
tooltip: t('Delete template'),
placement: 'bottom',
- icon: 'trash' as IconName,
+ icon: 'Trash',
onClick: handleDelete,
}
: null,
diff --git a/superset-frontend/src/views/CRUD/dashboard/DashboardCard.tsx b/superset-frontend/src/views/CRUD/dashboard/DashboardCard.tsx
index 733217752d86..1431eb81bf39 100644
--- a/superset-frontend/src/views/CRUD/dashboard/DashboardCard.tsx
+++ b/superset-frontend/src/views/CRUD/dashboard/DashboardCard.tsx
@@ -26,7 +26,7 @@ import {
import { Dropdown, Menu } from 'src/common/components';
import ConfirmStatusChange from 'src/components/ConfirmStatusChange';
import ListViewCard from 'src/components/ListViewCard';
-import Icon from 'src/components/Icon';
+import Icons from 'src/components/Icons';
import Label from 'src/components/Label';
import FacePile from 'src/components/FacePile';
import FaveStar from 'src/components/FaveStar';
@@ -68,24 +68,31 @@ function DashboardCard({
const menu = (