diff --git a/services/web/frontend/js/features/editor-navigation-toolbar/components/back-to-projects-button.js b/services/web/frontend/js/features/editor-navigation-toolbar/components/back-to-projects-button.tsx similarity index 65% rename from services/web/frontend/js/features/editor-navigation-toolbar/components/back-to-projects-button.js rename to services/web/frontend/js/features/editor-navigation-toolbar/components/back-to-projects-button.tsx index 1c7e2316f1..96cf64ab34 100644 --- a/services/web/frontend/js/features/editor-navigation-toolbar/components/back-to-projects-button.js +++ b/services/web/frontend/js/features/editor-navigation-toolbar/components/back-to-projects-button.tsx @@ -1,18 +1,15 @@ -import Icon from '../../../shared/components/icon' import { useTranslation } from 'react-i18next' -import { OverlayTrigger, Tooltip } from 'react-bootstrap' +import Tooltip from '../../../shared/components/tooltip' +import Icon from '../../../shared/components/icon' function BackToProjectsButton() { const { t } = useTranslation() return ( - - {t('back_to_your_projects')} - - } +
@@ -23,7 +20,7 @@ function BackToProjectsButton() { />
-
+ ) } diff --git a/services/web/frontend/js/features/editor-navigation-toolbar/components/layout-dropdown-button.js b/services/web/frontend/js/features/editor-navigation-toolbar/components/layout-dropdown-button.js index 4f1b5d5064..72b23882e3 100644 --- a/services/web/frontend/js/features/editor-navigation-toolbar/components/layout-dropdown-button.js +++ b/services/web/frontend/js/features/editor-navigation-toolbar/components/layout-dropdown-button.js @@ -1,7 +1,8 @@ import { useCallback } from 'react' import PropTypes from 'prop-types' -import { Dropdown, MenuItem, OverlayTrigger, Tooltip } from 'react-bootstrap' +import { Dropdown, MenuItem } from 'react-bootstrap' import { Trans, useTranslation } from 'react-i18next' +import Tooltip from '../../../shared/components/tooltip' import Icon from '../../../shared/components/icon' import IconChecked from '../../../shared/components/icon-checked' import ControlledDropdown from '../../../shared/components/controlled-dropdown' @@ -50,21 +51,19 @@ function PdfDetachMenuItem({ handleDetach, children }) { if (!('BroadcastChannel' in window)) { return ( - - {t('your_browser_does_not_support_this_feature')} - - } + {children} - + ) } return {children} } + PdfDetachMenuItem.propTypes = { handleDetach: PropTypes.func.isRequired, children: PropTypes.arrayOf(PropTypes.node).isRequired, @@ -126,13 +125,13 @@ function LayoutDropdownButton() { {processing ? : } {t('layout')} - Beta feature} - delayHide={100} + - + handleChangeLayout('sideBySide')}> diff --git a/services/web/frontend/js/features/editor-navigation-toolbar/components/online-users-widget.js b/services/web/frontend/js/features/editor-navigation-toolbar/components/online-users-widget.js index 7742631863..b32445822a 100644 --- a/services/web/frontend/js/features/editor-navigation-toolbar/components/online-users-widget.js +++ b/services/web/frontend/js/features/editor-navigation-toolbar/components/online-users-widget.js @@ -1,7 +1,8 @@ import React from 'react' import PropTypes from 'prop-types' import { useTranslation } from 'react-i18next' -import { Dropdown, MenuItem, OverlayTrigger, Tooltip } from 'react-bootstrap' +import { Dropdown, MenuItem } from 'react-bootstrap' +import Tooltip from '../../../shared/components/tooltip' import Icon from '../../../shared/components/icon' import { getHueForUserId } from '../../../shared/utils/colors' import ControlledDropdown from '../../../shared/components/controlled-dropdown' @@ -37,17 +38,17 @@ function OnlineUsersWidget({ onlineUsers, goToUser }) { return (
{onlineUsers.map((user, index) => ( - {user.name}} + id="online-user" + description={user.name} + overlayProps={{ placement: 'bottom', trigger: ['hover', 'focus'] }} > {/* OverlayTrigger won't fire unless UserIcon is wrapped in a span */} - + ))}
) @@ -94,11 +95,10 @@ UserIcon.propTypes = { const DropDownToggleButton = React.forwardRef((props, ref) => { const { t } = useTranslation() return ( - {t('connected_users')} - } + - + ) }) diff --git a/services/web/frontend/js/features/editor-navigation-toolbar/components/pdf-toggle-button.js b/services/web/frontend/js/features/editor-navigation-toolbar/components/pdf-toggle-button.tsx similarity index 57% rename from services/web/frontend/js/features/editor-navigation-toolbar/components/pdf-toggle-button.js rename to services/web/frontend/js/features/editor-navigation-toolbar/components/pdf-toggle-button.tsx index 8c7c230421..6d20a39ecd 100644 --- a/services/web/frontend/js/features/editor-navigation-toolbar/components/pdf-toggle-button.js +++ b/services/web/frontend/js/features/editor-navigation-toolbar/components/pdf-toggle-button.tsx @@ -1,9 +1,13 @@ -import PropTypes from 'prop-types' -import { OverlayTrigger, Tooltip } from 'react-bootstrap' import classNames from 'classnames' +import Tooltip from '../../../shared/components/tooltip' import Icon from '../../../shared/components/icon' -function PdfToggleButton({ onClick, pdfViewIsOpen }) { +type PdfToggleButtonProps = { + onClick: () => void + pdfViewIsOpen?: boolean +} + +function PdfToggleButton({ onClick, pdfViewIsOpen }: PdfToggleButtonProps) { const classes = classNames( 'btn', 'btn-full-height', @@ -14,22 +18,17 @@ function PdfToggleButton({ onClick, pdfViewIsOpen }) { ) return ( - PDF} + {/* eslint-disable-next-line jsx-a11y/anchor-is-valid,jsx-a11y/click-events-have-key-events,jsx-a11y/interactive-supports-focus */} - + ) } -PdfToggleButton.propTypes = { - onClick: PropTypes.func.isRequired, - pdfViewIsOpen: PropTypes.bool, -} - export default PdfToggleButton diff --git a/services/web/frontend/js/features/editor-navigation-toolbar/components/project-name-editable-label.js b/services/web/frontend/js/features/editor-navigation-toolbar/components/project-name-editable-label.tsx similarity index 74% rename from services/web/frontend/js/features/editor-navigation-toolbar/components/project-name-editable-label.js rename to services/web/frontend/js/features/editor-navigation-toolbar/components/project-name-editable-label.tsx index 44a1eec5cf..78e9a41d7f 100644 --- a/services/web/frontend/js/features/editor-navigation-toolbar/components/project-name-editable-label.js +++ b/services/web/frontend/js/features/editor-navigation-toolbar/components/project-name-editable-label.tsx @@ -1,16 +1,22 @@ import { useEffect, useState, useRef } from 'react' -import PropTypes from 'prop-types' -import { OverlayTrigger, Tooltip } from 'react-bootstrap' import { useTranslation } from 'react-i18next' import classNames from 'classnames' +import Tooltip from '../../../shared/components/tooltip' import Icon from '../../../shared/components/icon' +type ProjectNameEditableLabelProps = { + projectName: string + onChange: (value: string) => void + hasRenamePermissions?: boolean + className?: string +} + function ProjectNameEditableLabel({ projectName, hasRenamePermissions, onChange, className, -}) { +}: ProjectNameEditableLabelProps) { const { t } = useTranslation() const [isRenaming, setIsRenaming] = useState(false) @@ -19,11 +25,11 @@ function ProjectNameEditableLabel({ const [inputContent, setInputContent] = useState(projectName) - const inputRef = useRef(null) + const inputRef = useRef(null) useEffect(() => { if (isRenaming) { - inputRef.current.select() + inputRef.current?.select() } }, [isRenaming]) @@ -39,14 +45,14 @@ function ProjectNameEditableLabel({ onChange(inputContent) } - function handleKeyDown(event) { + function handleKeyDown(event: React.KeyboardEvent) { if (event.key === 'Enter') { event.preventDefault() finishRenaming() } } - function handleOnChange(event) { + function handleOnChange(event: React.ChangeEvent) { setInputContent(event.target.value) } @@ -75,26 +81,19 @@ function ProjectNameEditableLabel({ /> )} {canRename && ( - {t('rename')}} + {/* eslint-disable-next-line jsx-a11y/anchor-is-valid, jsx-a11y/click-events-have-key-events, jsx-a11y/interactive-supports-focus */} - + )} ) } -ProjectNameEditableLabel.propTypes = { - projectName: PropTypes.string.isRequired, - hasRenamePermissions: PropTypes.bool, - onChange: PropTypes.func.isRequired, - className: PropTypes.string, -} - export default ProjectNameEditableLabel diff --git a/services/web/frontend/js/features/file-tree/components/file-tree-toolbar.js b/services/web/frontend/js/features/file-tree/components/file-tree-toolbar.js index 9bdafb2965..5de59f3930 100644 --- a/services/web/frontend/js/features/file-tree/components/file-tree-toolbar.js +++ b/services/web/frontend/js/features/file-tree/components/file-tree-toolbar.js @@ -1,8 +1,9 @@ import PropTypes from 'prop-types' import { useTranslation } from 'react-i18next' +import { Button } from 'react-bootstrap' +import Tooltip from '../../../shared/components/tooltip' import Icon from '../../../shared/components/icon' -import TooltipButton from '../../../shared/components/tooltip-button' import { useEditorContext } from '../../../shared/context/editor-context' import { useFileTreeActionable } from '../contexts/file-tree-actionable' @@ -37,27 +38,33 @@ function FileTreeToolbarLeft() { return (
- - - - + + + + - - - + + + + - - + +
) } @@ -74,22 +81,26 @@ function FileTreeToolbarRight() { return (
{canRename ? ( - - - + + ) : null} {canDelete ? ( - - - + + ) : null}
) diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-compile-button-inner.js b/services/web/frontend/js/features/pdf-preview/components/pdf-compile-button-inner.tsx similarity index 65% rename from services/web/frontend/js/features/pdf-preview/components/pdf-compile-button-inner.js rename to services/web/frontend/js/features/pdf-preview/components/pdf-compile-button-inner.tsx index 03a44a90a1..a7f01e1178 100644 --- a/services/web/frontend/js/features/pdf-preview/components/pdf-compile-button-inner.js +++ b/services/web/frontend/js/features/pdf-preview/components/pdf-compile-button-inner.tsx @@ -1,26 +1,35 @@ -import { Button, OverlayTrigger, Tooltip } from 'react-bootstrap' -import PropTypes from 'prop-types' +import { Button } from 'react-bootstrap' +import Tooltip from '../../../shared/components/tooltip' import Icon from '../../../shared/components/icon' import { useTranslation } from 'react-i18next' import { memo } from 'react' const modifierKey = /Mac/i.test(navigator.platform) ? 'Cmd' : 'Ctrl' -function PdfCompileButtonInner({ startCompile, compiling }) { +type PdfCompileButtonInnerProps = { + startCompile: () => void + compiling: boolean +} + +function PdfCompileButtonInner({ + startCompile, + compiling, +}: PdfCompileButtonInnerProps) { const { t } = useTranslation() const compileButtonLabel = compiling ? t('compiling') + '…' : t('recompile') return ( - + {t('recompile_pdf')}{' '} ({modifierKey} + Enter) - + } + tooltipProps={{ className: 'keyboard-tooltip' }} + overlayProps={{ delayShow: 500 }} > - + ) } -PdfCompileButtonInner.propTypes = { - compiling: PropTypes.bool.isRequired, - startCompile: PropTypes.func.isRequired, -} - export default memo(PdfCompileButtonInner) diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-expand-button.js b/services/web/frontend/js/features/pdf-preview/components/pdf-expand-button.tsx similarity index 70% rename from services/web/frontend/js/features/pdf-preview/components/pdf-expand-button.js rename to services/web/frontend/js/features/pdf-preview/components/pdf-expand-button.tsx index 78f047cac5..41375931f3 100644 --- a/services/web/frontend/js/features/pdf-preview/components/pdf-expand-button.js +++ b/services/web/frontend/js/features/pdf-preview/components/pdf-expand-button.tsx @@ -1,7 +1,8 @@ -import { Button, OverlayTrigger, Tooltip } from 'react-bootstrap' import { useTranslation } from 'react-i18next' +import { Button } from 'react-bootstrap' +import Tooltip from '../../../shared/components/tooltip' import Icon from '../../../shared/components/icon' -import { memo, useMemo } from 'react' +import { useMemo } from 'react' import { useLayoutContext } from '../../../shared/context/layout-context' function PdfExpandButton() { @@ -14,9 +15,10 @@ function PdfExpandButton() { }, [pdfLayout, t]) return ( - {text}} + - + ) } -export default memo(PdfExpandButton) +export default PdfExpandButton diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-hybrid-download-button.js b/services/web/frontend/js/features/pdf-preview/components/pdf-hybrid-download-button.tsx similarity index 59% rename from services/web/frontend/js/features/pdf-preview/components/pdf-hybrid-download-button.js rename to services/web/frontend/js/features/pdf-preview/components/pdf-hybrid-download-button.tsx index 3516e80a07..76b6d06aec 100644 --- a/services/web/frontend/js/features/pdf-preview/components/pdf-hybrid-download-button.js +++ b/services/web/frontend/js/features/pdf-preview/components/pdf-hybrid-download-button.tsx @@ -1,25 +1,19 @@ import { useTranslation } from 'react-i18next' -import { Button, OverlayTrigger, Tooltip } from 'react-bootstrap' +import { Button } from 'react-bootstrap' +import Tooltip from '../../../shared/components/tooltip' import Icon from '../../../shared/components/icon' -import { memo } from 'react' import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context' function PdfHybridDownloadButton() { const { pdfDownloadUrl } = useCompileContext() const { t } = useTranslation() + const description = pdfDownloadUrl + ? t('download_pdf') + : t('please_compile_pdf_before_download') return ( - - {pdfDownloadUrl - ? t('download_pdf') - : t('please_compile_pdf_before_download')} - - } - > + - + ) } -export default memo(PdfHybridDownloadButton) +export default PdfHybridDownloadButton diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-hybrid-logs-button.js b/services/web/frontend/js/features/pdf-preview/components/pdf-hybrid-logs-button.tsx similarity index 82% rename from services/web/frontend/js/features/pdf-preview/components/pdf-hybrid-logs-button.js rename to services/web/frontend/js/features/pdf-preview/components/pdf-hybrid-logs-button.tsx index 09194ffb8b..fae09a580a 100644 --- a/services/web/frontend/js/features/pdf-preview/components/pdf-hybrid-logs-button.js +++ b/services/web/frontend/js/features/pdf-preview/components/pdf-hybrid-logs-button.tsx @@ -1,6 +1,7 @@ import { memo, useCallback } from 'react' import { useTranslation } from 'react-i18next' -import { Button, Label, OverlayTrigger, Tooltip } from 'react-bootstrap' +import { Button, Label } from 'react-bootstrap' +import Tooltip from '../../../shared/components/tooltip' import Icon from '../../../shared/components/icon' import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context' @@ -18,11 +19,10 @@ function PdfHybridLogsButton() { const totalCount = errorCount + warningCount return ( - {t('logs_and_output_files')} - } + - + ) } diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-synctex-controls.js b/services/web/frontend/js/features/pdf-preview/components/pdf-synctex-controls.js index 312ec1ac54..5cbe22ec84 100644 --- a/services/web/frontend/js/features/pdf-preview/components/pdf-synctex-controls.js +++ b/services/web/frontend/js/features/pdf-preview/components/pdf-synctex-controls.js @@ -7,7 +7,8 @@ import { getJSON } from '../../../infrastructure/fetch-json' import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context' import { useLayoutContext } from '../../../shared/context/layout-context' import useScopeValue from '../../../shared/hooks/use-scope-value' -import { Button, OverlayTrigger, Tooltip } from 'react-bootstrap' +import { Button } from 'react-bootstrap' +import Tooltip from '../../../shared/components/tooltip' import Icon from '../../../shared/components/icon' import { useTranslation } from 'react-i18next' import useIsMounted from '../../../shared/hooks/use-is-mounted' @@ -38,13 +39,10 @@ function GoToCodeButton({ } return ( - - {t('go_to_pdf_location_in_code')} - - } + - + ) } @@ -82,13 +80,10 @@ function GoToPdfButton({ } return ( - - {t('go_to_code_location_in_pdf')} - - } + - + ) } diff --git a/services/web/frontend/js/features/preview/components/preview-log-entry-header.js b/services/web/frontend/js/features/preview/components/preview-log-entry-header.js index 5047bf19fc..f24552ab3d 100644 --- a/services/web/frontend/js/features/preview/components/preview-log-entry-header.js +++ b/services/web/frontend/js/features/preview/components/preview-log-entry-header.js @@ -2,8 +2,8 @@ import PropTypes from 'prop-types' import classNames from 'classnames' import { useState, useRef } from 'react' import { useTranslation } from 'react-i18next' -import { OverlayTrigger, Tooltip } from 'react-bootstrap' import useResizeObserver from '../hooks/use-resize-observer' +import Tooltip from '../../../shared/components/tooltip' import Icon from '../../../shared/components/icon' function PreviewLogEntryHeader({ @@ -84,13 +84,6 @@ function PreviewLogEntryHeader({ ) : null - const locationTooltip = - locationSpanOverflown && locationLinkText ? ( - - {locationLinkText} - - ) : null - const headerTitleText = logType ? `${logType} ${headerTitle}` : headerTitle return ( @@ -99,10 +92,15 @@ function PreviewLogEntryHeader({
{headerIcon}
) : null}

{headerTitleText}

- {locationTooltip ? ( - + {locationSpanOverflown && locationLinkText ? ( + {locationLink} - + ) : ( locationLink )} diff --git a/services/web/frontend/js/features/share-project-modal/components/edit-member.js b/services/web/frontend/js/features/share-project-modal/components/edit-member.js index 6e792856b8..384a4a06cd 100644 --- a/services/web/frontend/js/features/share-project-modal/components/edit-member.js +++ b/services/web/frontend/js/features/share-project-modal/components/edit-member.js @@ -2,18 +2,11 @@ import { useState, useEffect } from 'react' import PropTypes from 'prop-types' import { Trans, useTranslation } from 'react-i18next' import { useShareProjectContext } from './share-project-modal' -import Icon from '../../../shared/components/icon' import TransferOwnershipModal from './transfer-ownership-modal' -import { - Button, - Col, - Form, - FormControl, - FormGroup, - OverlayTrigger, - Tooltip, -} from 'react-bootstrap' import { removeMemberFromProject, updateMember } from '../utils/api' +import { Button, Col, Form, FormControl, FormGroup } from 'react-bootstrap' +import Tooltip from '../../../shared/components/tooltip' +import Icon from '../../../shared/components/icon' import { useProjectContext } from '../../../shared/context/project-context' export default function EditMember({ member }) { @@ -110,6 +103,7 @@ function SelectPrivilege({ value, handleChange }) { ) } + SelectPrivilege.propTypes = { value: PropTypes.string.isRequired, handleChange: PropTypes.func.isRequired, @@ -134,13 +128,10 @@ function RemoveMemberAction({ member }) { return ( - - - - } + } + overlayProps={{ placement: 'bottom' }} > - + ) } + RemoveMemberAction.propTypes = { member: PropTypes.shape({ _id: PropTypes.string.isRequired, @@ -179,6 +171,7 @@ function ChangePrivilegesActions({ handleReset }) { ) } + ChangePrivilegesActions.propTypes = { handleReset: PropTypes.func.isRequired, } diff --git a/services/web/frontend/js/features/share-project-modal/components/invite.js b/services/web/frontend/js/features/share-project-modal/components/invite.js index 83c7429f6d..be3bba4b40 100644 --- a/services/web/frontend/js/features/share-project-modal/components/invite.js +++ b/services/web/frontend/js/features/share-project-modal/components/invite.js @@ -2,7 +2,8 @@ import { useCallback } from 'react' import PropTypes from 'prop-types' import { useShareProjectContext } from './share-project-modal' import Icon from '../../../shared/components/icon' -import { Button, Col, Row, OverlayTrigger, Tooltip } from 'react-bootstrap' +import { Button, Col, Row } from 'react-bootstrap' +import Tooltip from '../../../shared/components/tooltip' import { Trans, useTranslation } from 'react-i18next' import MemberPrivileges from './member-privileges' import { resendInvite, revokeInvite } from '../utils/api' @@ -68,6 +69,7 @@ function ResendInvite({ invite }) { ) } + ResendInvite.propTypes = { invite: PropTypes.object.isRequired, } @@ -88,13 +90,10 @@ function RevokeInvite({ invite }) { } return ( - - - - } + } + overlayProps={{ placement: 'bottom' }} > - + ) } + RevokeInvite.propTypes = { invite: PropTypes.object.isRequired, } diff --git a/services/web/frontend/js/features/share-project-modal/components/link-sharing.js b/services/web/frontend/js/features/share-project-modal/components/link-sharing.js index 7f7bdf4b42..2c4fdc0ef9 100644 --- a/services/web/frontend/js/features/share-project-modal/components/link-sharing.js +++ b/services/web/frontend/js/features/share-project-modal/components/link-sharing.js @@ -1,7 +1,8 @@ import { useCallback, useState } from 'react' import PropTypes from 'prop-types' -import { Button, Col, OverlayTrigger, Row, Tooltip } from 'react-bootstrap' +import { Button, Col, Row } from 'react-bootstrap' import { Trans } from 'react-i18next' +import Tooltip from '../../../shared/components/tooltip' import Icon from '../../../shared/components/icon' import { useShareProjectContext } from './share-project-modal' import { setProjectAccessLevel } from '../utils/api' @@ -93,6 +94,7 @@ function PrivateSharing({ setAccessLevel, inflight }) { ) } + PrivateSharing.propTypes = { setAccessLevel: PropTypes.func.isRequired, inflight: PropTypes.bool, @@ -144,6 +146,7 @@ function TokenBasedSharing({ setAccessLevel, inflight }) { ) } + TokenBasedSharing.propTypes = { setAccessLevel: PropTypes.func.isRequired, inflight: PropTypes.bool, @@ -177,6 +180,7 @@ function LegacySharing({ accessLevel, setAccessLevel, inflight }) { ) } + LegacySharing.propTypes = { accessLevel: PropTypes.string.isRequired, setAccessLevel: PropTypes.func.isRequired, @@ -230,6 +234,7 @@ function AccessToken({ token, path, tooltipId }) { ) } + AccessToken.propTypes = { token: PropTypes.string, tooltipId: PropTypes.string.isRequired, @@ -238,13 +243,9 @@ AccessToken.propTypes = { function LinkSharingInfo() { return ( - - - - } + } > - + ) } diff --git a/services/web/frontend/js/shared/components/beta-badge.js b/services/web/frontend/js/shared/components/beta-badge.js deleted file mode 100644 index b05cb6f5bf..0000000000 --- a/services/web/frontend/js/shared/components/beta-badge.js +++ /dev/null @@ -1,35 +0,0 @@ -import { OverlayTrigger, Tooltip } from 'react-bootstrap' -import PropTypes from 'prop-types' - -export default function BetaBadge({ tooltip, url = '/beta/participate' }) { - return ( - - {tooltip.text} - - } - delayHide={100} - > - - {tooltip.text} - - - ) -} - -BetaBadge.propTypes = { - tooltip: PropTypes.shape({ - id: PropTypes.string.isRequired, - text: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired, - placement: PropTypes.string, - className: PropTypes.string, - }), - url: PropTypes.string, -} diff --git a/services/web/frontend/js/shared/components/beta-badge.tsx b/services/web/frontend/js/shared/components/beta-badge.tsx new file mode 100644 index 0000000000..aa4b84277c --- /dev/null +++ b/services/web/frontend/js/shared/components/beta-badge.tsx @@ -0,0 +1,39 @@ +import Tooltip from './tooltip' +import { OverlayTriggerProps } from 'react-bootstrap' + +type TooltipProps = { + id: string + text: React.ReactNode + placement?: OverlayTriggerProps['placement'] + className?: string +} + +type BetaBadgeProps = { + tooltip: TooltipProps + url?: string +} + +function BetaBadge({ tooltip, url = '/beta/participate' }: BetaBadgeProps) { + return ( + + + {tooltip.text} + + + ) +} + +export default BetaBadge diff --git a/services/web/frontend/js/shared/components/copy-link.js b/services/web/frontend/js/shared/components/copy-link.tsx similarity index 59% rename from services/web/frontend/js/shared/components/copy-link.js rename to services/web/frontend/js/shared/components/copy-link.tsx index 80509cc38d..96603a0beb 100644 --- a/services/web/frontend/js/shared/components/copy-link.js +++ b/services/web/frontend/js/shared/components/copy-link.tsx @@ -1,10 +1,15 @@ import { useCallback, useState } from 'react' -import { Button, OverlayTrigger, Tooltip } from 'react-bootstrap' -import PropTypes from 'prop-types' +import { Button } from 'react-bootstrap' import { Trans, useTranslation } from 'react-i18next' +import Tooltip from './tooltip' import Icon from './icon' -export default function CopyLink({ link, tooltipId }) { +type CopyLinkProps = { + link: string + tooltipId: string +} + +function CopyLink({ link, tooltipId }: CopyLinkProps) { const { t } = useTranslation() const [copied, setCopied] = useState(false) @@ -23,15 +28,13 @@ export default function CopyLink({ link, tooltipId }) { } return ( - - {copied ? 'Copied!' : } - - } + } + overlayProps={{ + delayHide: copied ? 1000 : 250, + shouldUpdatePosition: true, + }} > - + ) } -CopyLink.propTypes = { - link: PropTypes.string.isRequired, - tooltipId: PropTypes.string.isRequired, -} + +export default CopyLink diff --git a/services/web/frontend/js/shared/components/tooltip-button.js b/services/web/frontend/js/shared/components/tooltip-button.js deleted file mode 100644 index 1689cf4699..0000000000 --- a/services/web/frontend/js/shared/components/tooltip-button.js +++ /dev/null @@ -1,24 +0,0 @@ -import PropTypes from 'prop-types' -import { Button, Tooltip, OverlayTrigger } from 'react-bootstrap' - -function TooltipButton({ id, description, onClick, children }) { - const tooltip = {description} - - return ( - - - - ) -} - -TooltipButton.propTypes = { - id: PropTypes.string.isRequired, - description: PropTypes.string.isRequired, - onClick: PropTypes.func, - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.node), - PropTypes.node, - ]), -} - -export default TooltipButton diff --git a/services/web/frontend/js/shared/components/tooltip.tsx b/services/web/frontend/js/shared/components/tooltip.tsx index 19c5996214..106bcdff25 100644 --- a/services/web/frontend/js/shared/components/tooltip.tsx +++ b/services/web/frontend/js/shared/components/tooltip.tsx @@ -4,11 +4,15 @@ import { Tooltip as BSTooltip, } from 'react-bootstrap' +type OverlayTriggerCustomProps = { + shouldUpdatePosition?: boolean // Not officially documented https://stackoverflow.com/a/43138470 +} & OverlayTriggerProps + type TooltipProps = { children: React.ReactNode - description: string + description: React.ReactNode id: string - overlayProps?: Omit + overlayProps?: Omit tooltipProps?: BSTooltip.TooltipProps }