From 307fb23bd64e742cb203525805e3238b79a2a14c Mon Sep 17 00:00:00 2001 From: Phillip Kelley-Dotson Date: Thu, 7 May 2020 14:01:34 -0700 Subject: [PATCH] feat(control-utils): add infotooltipwithtrigger (#442) * PR to merge packges for controls migration * fix: add bootstrap * fix: change tooltip to tsx * fix: types * fix: tsx error * appease linter, enhance a11y * addressing PR feedback * tweaking bootstrap types * fix test * test enter key * moar tests * code > key * ugh fine Co-authored-by: Phillip Kelley-Dotson Co-authored-by: David Aaron Suddjian --- .../superset-ui-control-utils/package.json | 11 ++- .../src/InfoTooltipWithTrigger.tsx | 77 +++++++++++++++++++ .../superset-ui-control-utils/src/index.ts | 1 + .../test/InfoTooltipWithTrigger.test.tsx | 34 ++++++++ 4 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 superset-frontend/temporary_superset_ui/superset-ui/packages/superset-ui-control-utils/src/InfoTooltipWithTrigger.tsx create mode 100644 superset-frontend/temporary_superset_ui/superset-ui/packages/superset-ui-control-utils/test/InfoTooltipWithTrigger.test.tsx diff --git a/superset-frontend/temporary_superset_ui/superset-ui/packages/superset-ui-control-utils/package.json b/superset-frontend/temporary_superset_ui/superset-ui/packages/superset-ui-control-utils/package.json index 2d2f9a452b94..5feafb0f38b8 100644 --- a/superset-frontend/temporary_superset_ui/superset-ui/packages/superset-ui-control-utils/package.json +++ b/superset-frontend/temporary_superset_ui/superset-ui/packages/superset-ui-control-utils/package.json @@ -27,6 +27,15 @@ }, "peerDependencies": { "@superset-ui/translation": "^0.13", - "@superset-ui/validator": "^0.13" + "@superset-ui/validator": "^0.13", + "react": "^16.13.1" + }, + "devDependencies": { + "enzyme": "^3.11.0" + }, + "dependencies": { + "@types/react-bootstrap": "0.32.21", + "lodash": "^4.17.15", + "react-bootstrap": "^0.33.1" } } diff --git a/superset-frontend/temporary_superset_ui/superset-ui/packages/superset-ui-control-utils/src/InfoTooltipWithTrigger.tsx b/superset-frontend/temporary_superset_ui/superset-ui/packages/superset-ui-control-utils/src/InfoTooltipWithTrigger.tsx new file mode 100644 index 000000000000..77f6658e94b9 --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui/packages/superset-ui-control-utils/src/InfoTooltipWithTrigger.tsx @@ -0,0 +1,77 @@ +/** + * 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 { kebabCase } from 'lodash'; +import { Tooltip, OverlayTrigger } from 'react-bootstrap'; + +const tooltipStyle: React.CSSProperties = { wordWrap: 'break-word' }; + +interface Props { + label?: string; + tooltip?: string; + icon?: string; + onClick?: () => void; + placement?: string; + bsStyle?: string; + className?: string; +} + +export default function InfoTooltipWithTrigger({ + label, + tooltip, + bsStyle, + onClick, + icon = 'info-circle', + className = 'text-muted', + placement = 'right', +}: Props) { + const iconClass = `fa fa-${icon} ${className} ${bsStyle ? `text-${bsStyle}` : ''}`; + const iconEl = ( + { + if (event.key === 'Enter' || event.key === ' ') { + onClick(); + } + }) + } + /> + ); + if (!tooltip) { + return iconEl; + } + return ( + + {tooltip} + + } + > + {iconEl} + + ); +} diff --git a/superset-frontend/temporary_superset_ui/superset-ui/packages/superset-ui-control-utils/src/index.ts b/superset-frontend/temporary_superset_ui/superset-ui/packages/superset-ui-control-utils/src/index.ts index 6e485f3577e7..ad48f4417e72 100644 --- a/superset-frontend/temporary_superset_ui/superset-ui/packages/superset-ui-control-utils/src/index.ts +++ b/superset-frontend/temporary_superset_ui/superset-ui/packages/superset-ui-control-utils/src/index.ts @@ -3,3 +3,4 @@ import * as sectionModules from './sections'; export const sections = sectionModules; export { D3_FORMAT_DOCS, D3_FORMAT_OPTIONS, D3_TIME_FORMAT_OPTIONS } from './D3Formatting'; export { formatSelectOptions, formatSelectOptionsForRange } from './selectOptions'; +export { default as InfoTooltipWithTrigger } from './InfoTooltipWithTrigger'; diff --git a/superset-frontend/temporary_superset_ui/superset-ui/packages/superset-ui-control-utils/test/InfoTooltipWithTrigger.test.tsx b/superset-frontend/temporary_superset_ui/superset-ui/packages/superset-ui-control-utils/test/InfoTooltipWithTrigger.test.tsx new file mode 100644 index 000000000000..b4f85a8120aa --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui/packages/superset-ui-control-utils/test/InfoTooltipWithTrigger.test.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import { OverlayTrigger } from 'react-bootstrap'; +import InfoTooltipWithTrigger from '../src/InfoTooltipWithTrigger'; + +describe('InfoTooltipWithTrigger', () => { + it('renders a tooltip', () => { + const wrapper = shallow(); + expect(wrapper.find(OverlayTrigger)).toHaveLength(1); + }); + + it('renders an info icon', () => { + const wrapper = shallow(); + expect(wrapper.find('.fa-info-circle')).toHaveLength(1); + }); + + it('responds to keypresses', () => { + const clickHandler = jest.fn(); + const wrapper = shallow( + , + ); + wrapper.find('.fa-info-circle').simulate('keypress', { key: 'Tab' }); + expect(clickHandler).toHaveBeenCalledTimes(0); + wrapper.find('.fa-info-circle').simulate('keypress', { key: 'Enter' }); + expect(clickHandler).toHaveBeenCalledTimes(1); + wrapper.find('.fa-info-circle').simulate('keypress', { key: ' ' }); + expect(clickHandler).toHaveBeenCalledTimes(2); + }); + + it('has a bsStyle', () => { + const wrapper = shallow(); + expect(wrapper.find('.text-something')).toHaveLength(1); + }); +});