UNPKG

monday-ui-react-core

Version:

Official monday.com UI resources for application development in React.js

86 lines (78 loc) 2.31 kB
import React, { useLayoutEffect } from "react"; import PropTypes from "prop-types"; import cx from "classnames"; import { TYPES } from "./HeadingConstants"; import Tooltip from "../Tooltip/Tooltip"; import useIsOverflowing from "../../hooks/useIsOverflowing"; import useRefWithCallback from "../../hooks/useRefWithCallback"; import { SIZES } from "../../constants/sizes"; import "./Heading.scss"; const Heading = ({ className, value, type, size, ariaLabel, id, ellipsis, ellipsisMaxLines, style, tooltipPosition, suggestEditOnHover, nonEllipsisTooltip // tooltip to show when no overflow }) => { const [componentRef, setRef] = useRefWithCallback(node => node.style.setProperty("--heading-clamp-lines", ellipsisMaxLines) ); const classNames = cx("heading-component", className, `element-type-${type}`, `size-${size}`, { "heading-element-ellipsis": ellipsis, "suggest-edit-on-hover": suggestEditOnHover }); const Element = React.createElement( type, { className: classNames, "aria-label": ariaLabel, id, ref: setRef, style }, value ); const isOverflowing = useIsOverflowing({ ref: ellipsis && componentRef }); useLayoutEffect(() => { if (componentRef.current) { componentRef.current.style.setProperty("--heading-clamp-lines", ellipsisMaxLines); } }, [componentRef, ellipsisMaxLines, isOverflowing]); if (isOverflowing || nonEllipsisTooltip) { const tooltipContent = isOverflowing ? value : nonEllipsisTooltip; return ( <Tooltip content={tooltipContent} position={tooltipPosition}> {Element} </Tooltip> ); } return Element; }; Heading.propTypes = { className: PropTypes.string, type: PropTypes.oneOf(Object.keys(TYPES)), ariaLabel: PropTypes.string, value: PropTypes.string, id: PropTypes.string, ellipsis: PropTypes.bool, ellipsisMaxLines: PropTypes.number, suggestEditOnHover: PropTypes.bool, nonEllipsisTooltip: PropTypes.string, size: PropTypes.oneOf(Object.values(SIZES)) }; Heading.defaultProps = { className: "", type: TYPES.H1, ariaLabel: "", value: "", id: "", ellipsis: true, ellipsisMaxLines: 1, suggestEditOnHover: false, nonEllipsisTooltip: null, size: SIZES.LARGE }; Heading.types = TYPES; Heading.sizes = SIZES; export default Heading;