From 138fe22b8b4faa0cb9c541d38e2efa23008ba167 Mon Sep 17 00:00:00 2001 From: Brent Bovenzi Date: Mon, 13 Jun 2022 11:51:09 -0400 Subject: [PATCH 1/3] fully custom tooltip --- .../static/js/grid/components/StatusBox.jsx | 13 ++-- .../www/static/js/grid/components/Tooltip.tsx | 73 +++++++++++++++++++ 2 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 airflow/www/static/js/grid/components/Tooltip.tsx diff --git a/airflow/www/static/js/grid/components/StatusBox.jsx b/airflow/www/static/js/grid/components/StatusBox.jsx index 316529930f3b9..697696745600e 100644 --- a/airflow/www/static/js/grid/components/StatusBox.jsx +++ b/airflow/www/static/js/grid/components/StatusBox.jsx @@ -23,12 +23,12 @@ import React from 'react'; import { isEqual } from 'lodash'; import { Box, - Tooltip, useTheme, } from '@chakra-ui/react'; import InstanceTooltip from './InstanceTooltip'; import { useContainerRef } from '../context/containerRef'; +import Tooltip from './Tooltip'; export const boxSize = 10; export const boxSizePx = `${boxSize}px`; @@ -72,11 +72,11 @@ const StatusBox = ({ return ( } - portalProps={{ containerRef }} - hasArrow - placement="top" - openDelay={400} + content={} + // portalProps={{ containerRef }} + // hasArrow + // placement="top" + // openDelay={400} > diff --git a/airflow/www/static/js/grid/components/Tooltip.tsx b/airflow/www/static/js/grid/components/Tooltip.tsx new file mode 100644 index 0000000000000..bed9af52f4f99 --- /dev/null +++ b/airflow/www/static/js/grid/components/Tooltip.tsx @@ -0,0 +1,73 @@ +/*! + * 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, { ReactNode, useState } from 'react'; +import { Box, chakra } from '@chakra-ui/react'; + +interface Props { + delay?: number; + direction?: 'top' | 'bottom' | 'left' | 'right'; + content: string | ReactNode; +} + +const Tooltip: React.FC = ({ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + delay = 400, direction = 'top', content, children, +}) => { + let timeout: any; + const [active, setActive] = useState(false); + + const showTip = () => { + timeout = setTimeout(() => { + setActive(true); + }, delay); + }; + + const hideTip = () => { + clearInterval(timeout); + setActive(false); + }; + + return ( + + {children} + {active && ( + + {content} + + )} + + ); +}; + +export default Tooltip; From 0ea263411765c6678ddee5b220106a1369e2defc Mon Sep 17 00:00:00 2001 From: Brent Bovenzi Date: Mon, 13 Jun 2022 12:31:56 -0400 Subject: [PATCH 2/3] use a customized chakra tooltip --- .../static/js/grid/components/StatusBox.jsx | 13 +- .../www/static/js/grid/components/Tooltip.tsx | 192 ++++++++++++++---- 2 files changed, 155 insertions(+), 50 deletions(-) diff --git a/airflow/www/static/js/grid/components/StatusBox.jsx b/airflow/www/static/js/grid/components/StatusBox.jsx index 697696745600e..2f079949a9fb8 100644 --- a/airflow/www/static/js/grid/components/StatusBox.jsx +++ b/airflow/www/static/js/grid/components/StatusBox.jsx @@ -26,9 +26,9 @@ import { useTheme, } from '@chakra-ui/react'; +import Tooltip from './Tooltip'; import InstanceTooltip from './InstanceTooltip'; import { useContainerRef } from '../context/containerRef'; -import Tooltip from './Tooltip'; export const boxSize = 10; export const boxSizePx = `${boxSize}px`; @@ -72,11 +72,11 @@ const StatusBox = ({ return ( } - // portalProps={{ containerRef }} - // hasArrow - // placement="top" - // openDelay={400} + label={} + portalProps={{ containerRef }} + hasArrow + placement="top" + openDelay={400} > diff --git a/airflow/www/static/js/grid/components/Tooltip.tsx b/airflow/www/static/js/grid/components/Tooltip.tsx index bed9af52f4f99..1a80e91bcff8b 100644 --- a/airflow/www/static/js/grid/components/Tooltip.tsx +++ b/airflow/www/static/js/grid/components/Tooltip.tsx @@ -17,57 +17,163 @@ * under the License. */ -import React, { ReactNode, useState } from 'react'; -import { Box, chakra } from '@chakra-ui/react'; +/* Simplified version of chakra's Tooltip component for faster rendering but less customization */ -interface Props { - delay?: number; - direction?: 'top' | 'bottom' | 'left' | 'right'; - content: string | ReactNode; +import React from 'react'; +import { + chakra, + forwardRef, + HTMLChakraProps, + omitThemingProps, + ThemingProps, + useTheme, + useTooltip, + UseTooltipProps, + Portal, + PortalProps, +} from '@chakra-ui/react'; +import { AnimatePresence, motion } from 'framer-motion'; + +export interface TooltipProps + extends HTMLChakraProps<'div'>, + ThemingProps<'Tooltip'>, + UseTooltipProps { + /** + * The React component to use as the + * trigger for the tooltip + */ + children: React.ReactNode + /** + * The label of the tooltip + */ + label?: React.ReactNode + /** + * The accessible, human friendly label to use for + * screen readers. + * + * If passed, tooltip will show the content `label` + * but expose only `aria-label` to assistive technologies + */ + 'aria-label'?: string + /** + * If `true`, the tooltip will wrap its children + * in a `` with `tabIndex=0` + */ + shouldWrapChildren?: boolean + /** + * If `true`, the tooltip will show an arrow tip + */ + hasArrow?: boolean + /** + * Props to be forwarded to the portal component + */ + portalProps?: Pick } -const Tooltip: React.FC = ({ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - delay = 400, direction = 'top', content, children, -}) => { - let timeout: any; - const [active, setActive] = useState(false); +const StyledTooltip = chakra(motion.div); - const showTip = () => { - timeout = setTimeout(() => { - setActive(true); - }, delay); - }; +const styles = { + '--popper-arrow-bg': ['var(--tooltip-bg)'], + '--tooltip-bg': 'colors.gray.700', + bg: ['var(--tooltip-bg)'], + borderRadius: 'sm', + boxShadow: 'md', + color: 'whiteAlpha.900', + fontSize: 'md', + fontWeight: 'medium', + maxW: '320px', + px: '8px', + py: '2px', + zIndex: 'tooltip', +}; + +/** + * Tooltips display informative text when users hover, focus on, or tap an element. + * + * @see Docs https://chakra-ui.com/docs/overlay/tooltip + * @see WAI-ARIA https://www.w3.org/TR/wai-aria-practices/#tooltip + */ +const Tooltip = forwardRef((props, ref) => { + const ownProps = omitThemingProps(props); + const theme = useTheme(); - const hideTip = () => { - clearInterval(timeout); - setActive(false); + const { + children, + label, + shouldWrapChildren, + 'aria-label': ariaLabel, + hasArrow, + bg, + portalProps, + background, + backgroundColor, + bgColor, + ...rest + } = ownProps; + + const tooltip = useTooltip({ ...rest, direction: theme.direction }); + + /* + * Ensure tooltip has only one child node + */ + const child = React.Children.only(children) as React.ReactElement & { + ref?: React.Ref }; + const trigger: React.ReactElement = React.cloneElement( + child, + tooltip.getTriggerProps(child.props, child.ref), + ); + + const tooltipProps = tooltip.getTooltipProps({}, ref); + + /** + * If the `label` is empty, there's no point showing the tooltip. + * Let's simply return the children + */ + if (!label) { + return <>{children}; + } return ( - - {children} - {active && ( - - {content} - - )} - + <> + {trigger} + + {tooltip.isOpen && ( + + + + {label} + {hasArrow && ( + + + + )} + + + + )} + + ); -}; +}); export default Tooltip; From 1e632634be5a0858fd17a56a9ed2ea8e0cdac9a9 Mon Sep 17 00:00:00 2001 From: Brent Bovenzi Date: Mon, 13 Jun 2022 13:32:13 -0400 Subject: [PATCH 3/3] update notice --- NOTICE | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/NOTICE b/NOTICE index 4c7b795d88ce6..84c77cd4fc12c 100644 --- a/NOTICE +++ b/NOTICE @@ -20,3 +20,10 @@ This product contains a modified portion of 'Flask App Builder' developed by Dan (https://github.com/dpgaspar/Flask-AppBuilder). * Copyright 2013, Daniel Vaz Gaspar + +Chakra UI: +----- +This product contains a modified portion of 'Chakra UI' developed by Segun Adebayo. +(https://github.com/chakra-ui/chakra-ui). + +* Copyright 2019, Segun Adebayo