diff --git a/superset-frontend/src/components/FilterableTable/FilterableTable.tsx b/superset-frontend/src/components/FilterableTable/FilterableTable.tsx index 0616c925fd991..6fdb6f96469f6 100644 --- a/superset-frontend/src/components/FilterableTable/FilterableTable.tsx +++ b/superset-frontend/src/components/FilterableTable/FilterableTable.tsx @@ -30,7 +30,6 @@ import { Table, } from 'react-virtualized'; import { getMultipleTextDimensions, t, styled } from '@superset-ui/core'; -import { Tooltip } from 'src/components/Tooltip'; import Button from '../Button'; import CopyToClipboard from '../CopyToClipboard'; import ModalTrigger from '../ModalTrigger'; @@ -312,14 +311,15 @@ export default class FilterableTable extends PureComponent< this.props.orderedColumnKeys.forEach((key, index) => { // we can't use Math.max(...colWidths.slice(...)) here since the number // of elements might be bigger than the number of allowed arguments in a - // JavaScript function - widthsByColumnKey[key] = + // Javascript function + const value = (widthsByColumnKey[key] = colWidths .slice( index * (this.list.length + 1), (index + 1) * (this.list.length + 1), ) - .reduce((a, b) => Math.max(a, b)) + PADDING; + .reduce((a, b) => Math.max(a, b)) + PADDING); + widthsByColumnKey[key] = value; }); return widthsByColumnKey; @@ -513,20 +513,12 @@ export default class FilterableTable extends PureComponent< this.props.expandedColumns.indexOf(label) > -1 ? 'header-style-disabled' : 'header-style'; + return ( - -
- {label} - {sortBy === dataKey && ( - - )} -
-
+
+ {label} + {sortBy === dataKey && } +
); } @@ -545,32 +537,25 @@ export default class FilterableTable extends PureComponent< ? 'header-style-disabled' : 'header-style'; return ( - this.sortGrid(label)} > -
this.sortGrid(label)} - > - {label} - {this.state.sortBy === label && ( - - )} -
-
+ {label} + {this.state.sortBy === label && ( + + )} + ); } diff --git a/superset-frontend/src/components/TooltipParagraph/TooltipParagraph.stories.tsx b/superset-frontend/src/components/TooltipParagraph/TooltipParagraph.stories.tsx new file mode 100644 index 0000000000000..b50bbd8485de5 --- /dev/null +++ b/superset-frontend/src/components/TooltipParagraph/TooltipParagraph.stories.tsx @@ -0,0 +1,49 @@ +/** + * 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 TooltipParagraph from '.'; + +export default { + title: 'DynamicTooltip', + component: TooltipParagraph, +}; + +type IProps = { + title: string; + width: number; +}; + +export const InteractiveTooltip = (args: IProps) => ( +
+ {args.title} +
+); + +InteractiveTooltip.story = { + parameters: { + knobs: { + disable: true, + }, + }, +}; + +InteractiveTooltip.args = { + title: 'This is too long and should truncate.', + width: 200, +}; diff --git a/superset-frontend/src/components/TooltipParagraph/TooltipParagraph.test.tsx b/superset-frontend/src/components/TooltipParagraph/TooltipParagraph.test.tsx new file mode 100644 index 0000000000000..660df3489a9c2 --- /dev/null +++ b/superset-frontend/src/components/TooltipParagraph/TooltipParagraph.test.tsx @@ -0,0 +1,57 @@ +/** + * 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, waitFor } from 'spec/helpers/testing-library'; +import userEvent from '@testing-library/user-event'; +import TooltipParagraph from '.'; + +test('starts hidden with default props', () => { + render(This is tootlip description.); + expect(screen.queryByRole('tooltip')).not.toBeInTheDocument(); +}); + +test('not render on hover when not truncated', async () => { + const { container } = render( +
+ + This is short + +
, + ); + userEvent.hover(screen.getByTestId('test-text')); + await waitFor(() => + expect(container.firstChild?.firstChild).not.toHaveClass( + 'ant-tooltip-open', + ), + ); +}); + +test('render on hover when truncated', async () => { + const { container } = render( +
+ + This is too long and should truncate. + +
, + ); + userEvent.hover(screen.getByTestId('test-text')); + await waitFor(() => + expect(container.firstChild?.firstChild).toHaveClass('ant-tooltip-open'), + ); +}); diff --git a/superset-frontend/src/components/TooltipParagraph/index.tsx b/superset-frontend/src/components/TooltipParagraph/index.tsx new file mode 100644 index 0000000000000..35543643f8ffd --- /dev/null +++ b/superset-frontend/src/components/TooltipParagraph/index.tsx @@ -0,0 +1,43 @@ +/** + * 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, { useState } from 'react'; +import { Tooltip, Typography } from 'antd'; +import { ParagraphProps } from 'antd/es/typography/Paragraph'; + +const TooltipParagraph: React.FC = ({ + children, + ellipsis, + ...props +}) => { + const [truncated, setTruncated] = useState(false); + + return ( + + + {/* NOTE: Fragment is necessary to avoid showing the title */} + <>{children} + + + ); +}; + +export default TooltipParagraph;