import { forwardRef } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import CustomPropTypes from "../../../utils/prop-types/index.js";
import useResponsiveValues from "../../../hooks/breakpoint/useResponsiveValues/index.js";
import classes from './styles.module.scss';

/**
 * Renders a paragraph as defined by our typography specifications.
 *
 * ```js
 *
 * import { Paragraph } from '@politico/interactive-style';
 * ```
 */
const Paragraph = forwardRef((props, ref) => {
  const {
    as: Tag,
    family,
    size,
    role,
    weight,
    overline,
    align,
    children
  } = props;
  const sizeValue = useResponsiveValues(size);
  return <Tag ref={ref} className={classnames(classes[`text-${role}-${sizeValue}-${overline ? 'overline' : 'normal'}`], classes[`family-${family}`], classes[`weight-${weight}`], classes[`align-${align}`])}>
      {children}
    </Tag>;
});
Paragraph.displayName = 'Paragraph';
Paragraph.defaultProps = {
  as: 'p',
  family: 'serif',
  size: '300',
  role: 'body',
  weight: 'regular',
  overline: false,
  align: undefined,
  children: undefined
};
Paragraph.propTypes = {
  /**
   * The kind of tag to use to render this paragraph, if, for some reason, you
   * want to stray from the standard `<p>` tag.
   */
  as: PropTypes.elementType,
  /**
   * The font family of the paragraph text.
   */
  family: PropTypes.oneOf(['serif', 'sans', 'magazine']),
  /**
   * The font size level of the paragraph text.
   */
  size: CustomPropTypes.responsive(PropTypes.oneOf(['000', '100', '200', '300', '400', '500', '600', '700', '800'])),
  /**
   * The "role" of the paragraph, which determines its line height. Body text
   * has a larger line height for easier readability in big blocks of text,
   * while component text has a slightly reduced line height for density in
   * components. Label text has no extra line height, making it suitable for
   * things like button labels.
   */
  role: PropTypes.oneOf(['body', 'component', 'label']),
  /**
   * The font weight of the paragraph.
   */
  weight: PropTypes.oneOf(['light', 'regular', 'bold']),
  /**
   * Whether this paragraph should be rendered in Overline style.
   */
  overline: PropTypes.bool,
  /**
   * The text alignment of the paragraph.
   */
  align: PropTypes.oneOf(['left', 'right', 'center']),
  /**
   * The contents of the paragraph.
   */
  children: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)])
};
export default Paragraph;