Skip to content
Snippets Groups Projects
Unverified Commit d4c8b5fa authored by IzStriker's avatar IzStriker Committed by GitHub
Browse files

[TS migration] Reafactor tooltips.js to use typescript (#2073)

parent e62e8ca2
No related branches found
No related tags found
No related merge requests found
...@@ -15,7 +15,7 @@ import { remarkBreaks, sequentialNewlinesPlugin } from '../util/markdown'; ...@@ -15,7 +15,7 @@ import { remarkBreaks, sequentialNewlinesPlugin } from '../util/markdown';
import Button from './common/Button'; import Button from './common/Button';
import Text from './common/Text'; import Text from './common/Text';
import View from './common/View'; import View from './common/View';
import { Tooltip, useTooltip } from './tooltips'; import { Tooltip, type TooltipPosition, useTooltip } from './tooltips';
const remarkPlugins = [sequentialNewlinesPlugin, remarkGfm, remarkBreaks]; const remarkPlugins = [sequentialNewlinesPlugin, remarkGfm, remarkBreaks];
...@@ -86,7 +86,7 @@ const markdownStyles = css({ ...@@ -86,7 +86,7 @@ const markdownStyles = css({
type NotesTooltipProps = { type NotesTooltipProps = {
editable?: boolean; editable?: boolean;
defaultNotes?: string; defaultNotes?: string;
position?: string; position?: TooltipPosition;
onClose?: (notes: string) => void; onClose?: (notes: string) => void;
}; };
function NotesTooltip({ function NotesTooltip({
...@@ -138,7 +138,7 @@ type NotesButtonProps = { ...@@ -138,7 +138,7 @@ type NotesButtonProps = {
width?: number; width?: number;
height?: number; height?: number;
defaultColor?: string; defaultColor?: string;
tooltipPosition?: string; tooltipPosition?: TooltipPosition;
style?: CSSProperties; style?: CSSProperties;
}; };
export default function NotesButton({ export default function NotesButton({
......
import React, { Component, createContext, createRef, useState } from 'react'; import {
Component,
createContext,
createRef,
useState,
type RefObject,
type ReactNode,
type MouseEventHandler,
type MouseEvent,
type ContextType,
} from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import { css } from 'glamor'; import { css } from 'glamor';
import { styles, theme } from '../style'; import { type CSSProperties, styles, theme } from '../style';
export const IntersectionBoundary = createContext(); export const IntersectionBoundary = createContext<RefObject<HTMLElement>>(null);
export function useTooltip() { export function useTooltip() {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState<boolean>(false);
return { return {
getOpenEvents: (events = {}) => ({ getOpenEvents: (events: { onClick?: MouseEventHandler } = {}) => ({
onClick: e => { onClick: (e: MouseEvent) => {
e.stopPropagation(); e.stopPropagation();
events.onClick?.(e); events.onClick?.(e);
setIsOpen(true); setIsOpen(true);
...@@ -24,14 +34,56 @@ export function useTooltip() { ...@@ -24,14 +34,56 @@ export function useTooltip() {
}; };
} }
export class Tooltip extends Component { export type TooltipPosition =
| 'top'
| 'top-left'
| 'top-right'
| 'bottom'
| 'bottom-left'
| 'bottom-right'
| 'bottom-stretch'
| 'top-stretch'
| 'bottom-center'
| 'top-center'
| 'left-center'
| 'right';
type TooltipProps = {
position?: TooltipPosition;
onClose?: () => void;
forceLayout?: boolean;
forceTop?: number;
ignoreBoundary?: boolean;
targetRect?: DOMRect;
offset?: number;
style?: CSSProperties;
width?: number;
children: ReactNode;
targetHeight?: number;
};
type MutableDomRect = {
top: number;
left: number;
width: number;
height: number;
};
export class Tooltip extends Component<TooltipProps> {
static contextType = IntersectionBoundary; static contextType = IntersectionBoundary;
state = { position: null }; position: TooltipPosition;
contentRef: RefObject<HTMLDivElement>;
cleanup: () => void;
target: HTMLDivElement;
context: ContextType<typeof IntersectionBoundary> = this.context; // assign type to context without using declare.
constructor(props) { constructor(props) {
super(props); super(props);
this.position = props.position || 'bottom-right'; this.position = props.position || 'bottom-right';
this.contentRef = createRef(); this.contentRef = createRef<HTMLDivElement>();
}
isHTMLElement(element: unknown): element is HTMLElement {
return element instanceof HTMLElement;
} }
setup() { setup() {
...@@ -107,7 +159,7 @@ export class Tooltip extends Component { ...@@ -107,7 +159,7 @@ export class Tooltip extends Component {
} }
} }
getContainer() { getContainer(): HTMLElement {
const { ignoreBoundary = false } = this.props; const { ignoreBoundary = false } = this.props;
if (!ignoreBoundary && this.context) { if (!ignoreBoundary && this.context) {
...@@ -123,6 +175,7 @@ export class Tooltip extends Component { ...@@ -123,6 +175,7 @@ export class Tooltip extends Component {
if ( if (
container.parentNode && container.parentNode &&
this.isHTMLElement(container.parentNode) &&
container.parentNode.style.overflow === 'auto' container.parentNode.style.overflow === 'auto'
) { ) {
return container.parentNode; return container.parentNode;
...@@ -138,9 +191,18 @@ export class Tooltip extends Component { ...@@ -138,9 +191,18 @@ export class Tooltip extends Component {
} }
const box = contentEl.getBoundingClientRect(); const box = contentEl.getBoundingClientRect();
const anchorEl = this.target.parentNode; const anchorEl = this.target.parentNode;
let anchorRect = targetRect || anchorEl.getBoundingClientRect(); let anchorRect: MutableDomRect | undefined =
targetRect ||
(this.isHTMLElement(anchorEl)
? anchorEl?.getBoundingClientRect()
: undefined);
if (!anchorRect) {
return;
}
// Copy it so we can mutate it // Copy it so we can mutate it
anchorRect = { anchorRect = {
...@@ -238,6 +300,7 @@ export class Tooltip extends Component { ...@@ -238,6 +300,7 @@ export class Tooltip extends Component {
bottom: 'inherit', bottom: 'inherit',
left: 'inherit', left: 'inherit',
right: 'inherit', right: 'inherit',
width: undefined as string | undefined,
}; };
if ( if (
......
---
category: Enhancements
authors: [IzStriker]
---
Migrate tooltips.js to typescript
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment