diff --git a/superset-frontend/src/components/DatabaseSelector.tsx b/superset-frontend/src/components/DatabaseSelector.tsx index 4cc2e73476c..2567a58ae93 100644 --- a/superset-frontend/src/components/DatabaseSelector.tsx +++ b/superset-frontend/src/components/DatabaseSelector.tsx @@ -21,9 +21,8 @@ import { styled, SupersetClient, t } from '@superset-ui/core'; import rison from 'rison'; import { Select } from 'src/components/Select'; import Label from 'src/components/Label'; - +import RefreshLabel from 'src/components/RefreshLabel'; import SupersetAsyncSelect from './AsyncSelect'; -import RefreshLabel from './RefreshLabel'; const FieldTitle = styled.p` color: ${({ theme }) => theme.colors.secondary.light2}; @@ -41,6 +40,7 @@ const DatabaseSelectorWrapper = styled.div` display: flex; align-items: center; width: 30px; + margin-left: ${({ theme }) => theme.gridUnit}px; } .section { diff --git a/superset-frontend/src/components/Icon/index.tsx b/superset-frontend/src/components/Icon/index.tsx index 8f6834efa65..1e3d5cb391f 100644 --- a/superset-frontend/src/components/Icon/index.tsx +++ b/superset-frontend/src/components/Icon/index.tsx @@ -405,7 +405,7 @@ export const iconsRegistry: Record< warning: WarningIcon, }; -interface IconProps extends SVGProps { +export interface IconProps extends SVGProps { name: IconName; } diff --git a/superset-frontend/src/components/RefreshLabel.less b/superset-frontend/src/components/RefreshLabel/RefreshLabel.stories.tsx similarity index 63% rename from superset-frontend/src/components/RefreshLabel.less rename to superset-frontend/src/components/RefreshLabel/RefreshLabel.stories.tsx index 0d447ace2cc..27eb5a1b726 100644 --- a/superset-frontend/src/components/RefreshLabel.less +++ b/superset-frontend/src/components/RefreshLabel/RefreshLabel.stories.tsx @@ -16,12 +16,29 @@ * specific language governing permissions and limitations * under the License. */ -@import '../../stylesheets/less/variables.less'; +import React from 'react'; +import RefreshLabel, { RefreshLabelProps } from '.'; -.RefreshLabel { - color: @bs-gray-light; +export default { + title: 'RefreshLabel', +}; - &:hover { - color: @brand-primary; - } -} +export const InteractiveRefreshLabel = (args: RefreshLabelProps) => ( + +); + +InteractiveRefreshLabel.args = { + tooltipContent: 'Tooltip', +}; + +InteractiveRefreshLabel.argTypes = { + onClick: { action: 'onClick' }, +}; + +InteractiveRefreshLabel.story = { + parameters: { + knobs: { + disable: true, + }, + }, +}; diff --git a/superset-frontend/src/components/RefreshLabel/RefreshLabel.test.tsx b/superset-frontend/src/components/RefreshLabel/RefreshLabel.test.tsx new file mode 100644 index 00000000000..55750fba828 --- /dev/null +++ b/superset-frontend/src/components/RefreshLabel/RefreshLabel.test.tsx @@ -0,0 +1,47 @@ +/** + * 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 { render, screen } from 'spec/helpers/testing-library'; +import userEvent from '@testing-library/user-event'; +import RefreshLabel from 'src/components/RefreshLabel'; + +test('renders with default props', () => { + render(); + const refresh = screen.getByRole('button'); + expect(refresh).toBeInTheDocument(); + userEvent.hover(refresh); +}); + +test('renders tooltip on hover', async () => { + const tooltipText = 'Tooltip'; + render(); + const refresh = screen.getByRole('button'); + userEvent.hover(refresh); + const tooltip = await screen.findByRole('tooltip'); + expect(tooltip).toBeInTheDocument(); + expect(tooltip).toHaveTextContent(tooltipText); +}); + +test('triggers on click event', () => { + const onClick = jest.fn(); + render(); + const refresh = screen.getByRole('button'); + userEvent.click(refresh); + expect(onClick).toHaveBeenCalled(); +}); diff --git a/superset-frontend/src/components/RefreshLabel.jsx b/superset-frontend/src/components/RefreshLabel/index.tsx similarity index 51% rename from superset-frontend/src/components/RefreshLabel.jsx rename to superset-frontend/src/components/RefreshLabel/index.tsx index bac7ae18cf1..e3e15fff052 100644 --- a/superset-frontend/src/components/RefreshLabel.jsx +++ b/superset-frontend/src/components/RefreshLabel/index.tsx @@ -16,32 +16,36 @@ * specific language governing permissions and limitations * under the License. */ -import React from 'react'; -import PropTypes from 'prop-types'; +import React, { MouseEventHandler } from 'react'; +import { SupersetTheme } from '@superset-ui/core'; import { Tooltip } from 'src/common/components/Tooltip'; +import Icon, { IconProps } from 'src/components/Icon'; -import './RefreshLabel.less'; +export interface RefreshLabelProps { + onClick: MouseEventHandler; + tooltipContent: string; +} -const propTypes = { - onClick: PropTypes.func, - tooltipContent: PropTypes.string.isRequired, +const RefreshLabel = ({ onClick, tooltipContent }: RefreshLabelProps) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const IconWithoutRef = React.forwardRef((props: IconProps, ref: any) => ( + + )); + + return ( + + ({ + cursor: 'pointer', + color: theme.colors.grayscale.base, + '&:hover': { color: theme.colors.primary.base }, + })} + /> + + ); }; -class RefreshLabel extends React.PureComponent { - render() { - return ( - - - - ); - } -} -RefreshLabel.propTypes = propTypes; - export default RefreshLabel; diff --git a/superset-frontend/src/components/TableSelector.less b/superset-frontend/src/components/TableSelector.less index 6e583dcac5d..c5c1c11e438 100644 --- a/superset-frontend/src/components/TableSelector.less +++ b/superset-frontend/src/components/TableSelector.less @@ -22,12 +22,6 @@ padding-left: 9px; } -.TableSelector .refresh-col { - display: flex; - align-items: center; - width: 30px; -} - .TableSelector .section { padding-bottom: 5px; display: flex; diff --git a/superset-frontend/src/components/TableSelector/index.tsx b/superset-frontend/src/components/TableSelector/index.tsx index f45e30c2627..f66b9b2115c 100644 --- a/superset-frontend/src/components/TableSelector/index.tsx +++ b/superset-frontend/src/components/TableSelector/index.tsx @@ -47,6 +47,7 @@ const TableSelectorWrapper = styled.div` display: flex; align-items: center; width: 30px; + margin-left: ${({ theme }) => theme.gridUnit}px; } .section {