Source

atoms/story-elements/blockquote/blockquote.tsx

import React from "react";
import styled from "styled-components";
import { StoryElementProps } from "../types";
import { Spacer } from "../../spacer";
import { withStoryAndConfig } from "../../../context";
import get from "lodash.get";

const Wrapper = styled.div<{ textDirection: "ltr" | "rtl" }>`
  display: flex;
  flex-direction: column;
  position: relative;

  &:before {
    ${(props) => (props.textDirection === "ltr" ? ` left:0; content: "\\201C";` : ` right: 0; content: "\\201D";`)}
    font-size: ${(props) => props.theme.font.size.big};
    font-weight: bold;
    color: ${(props) => props.theme.color.mono7};
    margin: 0 ${(props) => props.theme.spacing.s};
    position: absolute;
    top: 4px;
  }
`;
const StyledBlockQuote = styled.blockquote<{ textDirection: "ltr" | "rtl" }>`
  ${(props) => (props.textDirection === "ltr" ? ` padding: 0 0 0 50px; ` : ` padding: 0 50px 0 0; `)}
  margin: 0;
  font-size: ${(props) => props.theme.font.size.l};
  color: ${(props) => props.theme.color.mono6};
  line-height: ${(props) => props.theme.font.lineHeight.level5};
`;
const StyledAttribution = styled.span`
  color: ${(props) => props.theme.color.mono6};
  font-size: ${(props) => props.theme.font.size.m};
  font-weight: bold;
  padding: 0 0 0 38px;
  &:before {
    content: "-";
    margin-right: 5px;
  }
`;
export const FallbackBlockQuote = styled.div`
  div {
    display: flex;
    flex-direction: column;
    position: relative;

    &:before {
      content: "\\201C";
      font-size: ${(props) => props.theme.font.size.big};
      font-weight: bold;
      color: ${(props) => props.theme.color.mono7};
      margin: 0 ${(props) => props.theme.spacing.s};
      position: absolute;
      top: 4px;
    }
  }

  blockquote {
    padding: 0 0 0 50px;
    margin: 0;
    font-size: ${(props) => props.theme.font.size.l};
    color: ${(props) => props.theme.color.mono6};
    line-height: ${(props) => props.theme.font.lineHeight.level5};
  }

  .attribution {
    text-align: right;
    color: ${(props) => props.theme.color.mono6};
    font-size: ${(props) => props.theme.font.size.m};
    font-weight: bold;
    &:before {
      content: "-";
      margin-right: 5px;
    }
  }
`;

export const DefaultBlockQuote = ({ element, config }: StoryElementProps) => {
  const textDirection = get(config, ["publisherConfig", "language", "direction"], "ltr");

  if (element.metadata) {
    const { content, attribution } = element.metadata;
    return (
      <Wrapper textDirection={textDirection}>
        <StyledBlockQuote textDirection={textDirection}>{content}</StyledBlockQuote>
        {attribution && attribution.length && (
          <React.Fragment>
            <Spacer token="s" />
            <StyledAttribution>{attribution}</StyledAttribution>
          </React.Fragment>
        )}
      </Wrapper>
    );
  }

  return <FallbackBlockQuote dangerouslySetInnerHTML={{ __html: element.text || "" }} />;
};

export const BlockQuoteBase = ({ element, story, config }: StoryElementProps) => {
  const blockquoteRender = get(config, ["opts", "render", "storyElementRender", "blockquoteRender"], null);

  return blockquoteRender ? (
    blockquoteRender({ story, config, element })
  ) : (
    <DefaultBlockQuote element={element} config={config} />
  );
};
/**
 * BlockQuote is a story element.
 * The look of the BlockQuote can be changed using the render prop blockquoteRender. In case blockquoteRender is passed in the config, it is rendered. Otherwise a default BlockQuote is rendered.
 *
 * @param {Object} params object containing parameters passed to the render prop
 * @param {Object} params.story story object
 * @param {Object} params.config config object
 * @param {Object} params.element the story element. This is same as the story element found in the story API response
 *
 * ```javascript
 * ...
 * ampRoutes(app, {
 *  render: {
 *    storyElementRender: {
 *      blockquoteRender: ({ story, config, element }) => <MyCustomBlockQuote story={story} config={config} storyElement={element} />
 *    }
 *  }
 * })
 * ...
 * ```
 *
 * @category StoryElements
 * @module BlockQuote
 * @component
 */
export const BlockQuote = withStoryAndConfig(BlockQuoteBase);