diff --git a/frontend/src/metabase/components/Button.jsx b/frontend/src/metabase/components/Button.tsx similarity index 72% rename from frontend/src/metabase/components/Button.jsx rename to frontend/src/metabase/components/Button.tsx index d68f02e9d1c929ddb588f525dc1ffe885454bea9..20fdd444ea02d7be736d4de56bdbb728b401cab7 100644 --- a/frontend/src/metabase/components/Button.jsx +++ b/frontend/src/metabase/components/Button.tsx @@ -1,13 +1,10 @@ -/* eslint-disable react/prop-types */ -import React, { forwardRef } from "react"; -import PropTypes from "prop-types"; import cx from "classnames"; -import _ from "underscore"; +import React, { ButtonHTMLAttributes, forwardRef, ReactNode, Ref } from "react"; import styled from "styled-components"; import { color, space } from "styled-system"; - -import { forwardRefToInnerRef } from "metabase/styled-components/utils"; +import _ from "underscore"; import Icon from "metabase/components/Icon"; +import { forwardRefToInnerRef } from "metabase/styled-components/utils"; const BUTTON_VARIANTS = [ "small", @@ -23,7 +20,34 @@ const BUTTON_VARIANTS = [ "white", "borderless", "onlyIcon", -]; +] as const; + +interface Props extends ButtonHTMLAttributes<HTMLButtonElement> { + className?: string; + icon?: string; + iconSize?: number; + iconColor?: string; + iconRight?: string; + iconVertical?: boolean; + labelBreakpoint?: string; + children?: ReactNode; + + small?: boolean; + medium?: boolean; + large?: boolean; + + primary?: boolean; + success?: boolean; + danger?: boolean; + warning?: boolean; + cancel?: boolean; + white?: boolean; + purple?: boolean; + + round?: boolean; + borderless?: boolean; + onlyIcon?: boolean; +} const BaseButton = forwardRef(function BaseButton( { @@ -34,11 +58,10 @@ const BaseButton = forwardRef(function BaseButton( iconColor, iconVertical, labelBreakpoint, - color, children, ...props - }, - ref, + }: Props, + ref: Ref<HTMLButtonElement>, ) { const variantClasses = BUTTON_VARIANTS.filter(variant => props[variant]).map( variant => "Button--" + variant, @@ -54,7 +77,7 @@ const BaseButton = forwardRef(function BaseButton( > <div className={cx("flex layout-centered", { "flex-column": iconVertical })} - style={iconVertical ? { minWidth: 60 } : null} + style={iconVertical ? { minWidth: 60 } : undefined} > {icon && ( <Icon color={iconColor} name={icon} size={iconSize ? iconSize : 14} /> @@ -82,24 +105,6 @@ const BaseButton = forwardRef(function BaseButton( ); }); -BaseButton.propTypes = { - className: PropTypes.string, - icon: PropTypes.string, - iconSize: PropTypes.number, - children: PropTypes.any, - - small: PropTypes.bool, - medium: PropTypes.bool, - large: PropTypes.bool, - - primary: PropTypes.bool, - warning: PropTypes.bool, - cancel: PropTypes.bool, - purple: PropTypes.bool, - - borderless: PropTypes.bool, -}; - const Button = forwardRefToInnerRef(styled(BaseButton)` ${color}; ${space}; diff --git a/frontend/src/metabase/components/ExternalLink.jsx b/frontend/src/metabase/components/ExternalLink.tsx similarity index 66% rename from frontend/src/metabase/components/ExternalLink.jsx rename to frontend/src/metabase/components/ExternalLink.tsx index 2cadcb73c68812481f8dceac0a4e2843eeac5033..9f3c651e0af6834b6a00b136f65326fdd942a213 100644 --- a/frontend/src/metabase/components/ExternalLink.jsx +++ b/frontend/src/metabase/components/ExternalLink.tsx @@ -1,11 +1,16 @@ -/* eslint-disable react/prop-types */ -import React, { forwardRef } from "react"; - +import React, { AnchorHTMLAttributes, forwardRef, ReactNode, Ref } from "react"; import { getUrlTarget } from "metabase/lib/dom"; +interface Props extends AnchorHTMLAttributes<HTMLAnchorElement> { + href?: string; + target?: string; + className?: string; + children?: ReactNode; +} + const ExternalLink = forwardRef(function ExternalLink( - { href, target = getUrlTarget(href), className, children, ...props }, - ref, + { href, target = getUrlTarget(href), className, children, ...props }: Props, + ref: Ref<HTMLAnchorElement>, ) { return ( <a diff --git a/frontend/src/metabase/components/Icon.tsx b/frontend/src/metabase/components/Icon.tsx index 7595c1f3fe2af8a5ee6fbe45260cd06aee1f47e6..7fc41a43de4b092501ffd2d29ad3e6f1d8a0ab9f 100644 --- a/frontend/src/metabase/components/Icon.tsx +++ b/frontend/src/metabase/components/Icon.tsx @@ -1,13 +1,12 @@ +import cx from "classnames"; import PropTypes from "prop-types"; import React, { Component, forwardRef } from "react"; import styled from "styled-components"; -import { color, space, hover } from "styled-system"; -import cx from "classnames"; - -import { color as c } from "metabase/lib/colors"; +import { color, hover, space } from "styled-system"; +import Tooltip from "metabase/components/Tooltip"; import { loadIcon } from "metabase/icon_paths"; +import { color as c } from "metabase/lib/colors"; import { stripLayoutProps } from "metabase/lib/utils"; -import Tooltip from "metabase/components/Tooltip"; import { forwardRefToInnerRef } from "metabase/styled-components/utils"; const MISSING_ICON_NAME = "unknown"; @@ -51,13 +50,15 @@ const stringOrNumberPropType = PropTypes.oneOfType([ export const iconPropTypes = { name: PropTypes.string.isRequired, + color: PropTypes.string, size: stringOrNumberPropType, width: stringOrNumberPropType, height: stringOrNumberPropType, scale: stringOrNumberPropType, tooltip: PropTypes.string, className: PropTypes.string, - innerRef: PropTypes.func.isRequired, + innerRef: PropTypes.any, + onClick: PropTypes.func, }; type IconProps = PropTypes.InferProps<typeof iconPropTypes>; diff --git a/frontend/src/metabase/components/Link.jsx b/frontend/src/metabase/components/Link.tsx similarity index 60% rename from frontend/src/metabase/components/Link.jsx rename to frontend/src/metabase/components/Link.tsx index 689e2b6e81caf802e3e36e3aa9c36e02fc546376..c775485039d416a407151cb4cb52a1dfcda3a753 100644 --- a/frontend/src/metabase/components/Link.jsx +++ b/frontend/src/metabase/components/Link.tsx @@ -1,22 +1,27 @@ -import React from "react"; import cx from "classnames"; -import PropTypes from "prop-types"; -import { Link as ReactRouterLink } from "react-router"; +import React, { ReactNode } from "react"; +import { Link as ReactRouterLink, LinkProps } from "react-router"; import styled from "styled-components"; -import { display, color, hover, space } from "styled-system"; - -import { stripLayoutProps } from "metabase/lib/utils"; +import { color, display, hover, space } from "styled-system"; import Tooltip from "metabase/components/Tooltip"; +import { stripLayoutProps } from "metabase/lib/utils"; -BaseLink.propTypes = { - to: PropTypes.string.isRequired, - disabled: PropTypes.bool, - className: PropTypes.string, - children: PropTypes.node, - tooltip: PropTypes.string, -}; +interface Props extends LinkProps { + to: string; + disabled?: boolean; + className?: string; + children?: ReactNode; + tooltip?: string; +} -function BaseLink({ to, className, children, disabled, tooltip, ...props }) { +function BaseLink({ + to, + className, + children, + disabled, + tooltip, + ...props +}: Props) { const link = ( <ReactRouterLink to={to}