'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var grapple = require('@bluframe/grapple');
var React = require('react');
var ReactMarkdown = require('react-markdown');
var styled = require('styled-components');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
var ReactMarkdown__default = /*#__PURE__*/_interopDefaultLegacy(ReactMarkdown);
var styled__default = /*#__PURE__*/_interopDefaultLegacy(styled);

const Wrapper = styled__default["default"].span.withConfig({
  displayName: "styled__Wrapper",
  componentId: "sc-1oa8elu-0"
})(["color:", ";"], ({
  theme
}) => theme.palette.text);

const Content = ({
  components,
  content,
  rehypePlugins,
  remarkPlugins
}) => /*#__PURE__*/React__default["default"].createElement(Wrapper, null, /*#__PURE__*/React__default["default"].createElement(ReactMarkdown__default["default"], {
  components: components,
  rehypePlugins: rehypePlugins,
  remarkPlugins: remarkPlugins
}, content));

/**
 * @typedef {import('mdast').Content} Content
 * @typedef {import('mdast').Root} Root
 * @typedef {Root|Content} Node
 * @typedef {Node['type']} Type
 *
 * @callback Handler
 * @param {any} node
 * @returns {Node|Node[]} node
 *
 * @typedef {Partial<Record<Type, Handler>>} Handlers
 *
 * @typedef Options
 *   Configuration.
 * @property {Array.<Type>|undefined} [keep]
 *   List of node types to leave unchanged.
 * @property {Array.<Type|[Type, Handler]>|undefined} [remove]
 *   List of additional node types to remove or replace.
 */

/**
 * Expose modifiers for available node types.
 * Node types not listed here are not changed (but their children are).
 *
 * @type {Handlers}
 */
const defaults = {
  heading: paragraph,
  text,
  inlineCode: text,
  image,
  imageReference: image,
  break: lineBreak,
  blockquote: children,
  list: children,
  listItem: children,
  strong: children,
  emphasis: children,
  delete: children,
  link: children,
  linkReference: children,
  code: empty,
  thematicBreak: empty,
  html: empty,
  table: empty,
  tableCell: empty,
  definition: empty,
  yaml: empty,
  // @ts-expect-error: custom frontmatter node.
  toml: empty,
  footnoteReference: empty,
  footnoteDefinition: empty
};
const own = {}.hasOwnProperty;
/**
 * Plugin to remove markdown formatting.
 *
 * @type {import('unified').Plugin<[Options?] | void[], Root>}
 * @returns {import('unified').Transformer<Root>}
 */

function stripMarkdown(options = {}) {
  const handlers = Object.assign({}, defaults);
  const remove = options.remove || [];
  const keep = options.keep || [];
  let index = -1;

  while (++index < remove.length) {
    const value = remove[index];

    if (Array.isArray(value)) {
      handlers[value[0]] = value[1];
    } else {
      handlers[value] = empty;
    }
  }
  /** @type {Handlers} */


  let map = {};

  if (keep.length === 0) {
    map = handlers;
  } else {
    /** @type {Type} */
    let key;

    for (key in handlers) {
      if (!keep.includes(key)) {
        map[key] = handlers[key];
      }
    }

    index = -1; // Warn if unknown keys are turned off.

    while (++index < keep.length) {
      key = keep[index];

      if (!own.call(handlers, key)) {
        throw new Error('Invalid `keep` option: No modifier is defined for node type `' + key + '`');
      }
    }
  } // @ts-expect-error: assume content model (for root) matches.


  return one;
  /**
   * @param {Node} node
   * @returns {Node|Node[]}
   */

  function one(node) {
    /** @type {Type} */
    const type = node.type;
    /** @type {Node|Node[]} */

    let result = node;

    if (type in map) {
      const handler = map[type];
      if (handler) result = handler(result);
    }

    result = Array.isArray(result) ? all(result) : result;

    if ('children' in result) {
      // @ts-expect-error: assume content models match.
      result.children = all(result.children);
    }

    return result;
  }
  /**
   * @param {Node[]} nodes
   * @returns {Node[]}
   */


  function all(nodes) {
    let index = -1;
    /** @type {Node[]} */

    const result = [];

    while (++index < nodes.length) {
      const value = one(nodes[index]);

      if (Array.isArray(value)) {
        result.push(...value.flatMap(d => one(d)));
      } else {
        result.push(value);
      }
    }

    return clean(result);
  }
}
/**
 * Clean nodes: merges literals.
 *
 * @param {Node[]} values
 * @returns {Node[]}
 */

function clean(values) {
  let index = -1;
  /** @type {Node[]} */

  const result = [];
  /** @type {Node|undefined} */

  let previous;

  while (++index < values.length) {
    const value = values[index];

    if (previous && value.type === previous.type && 'value' in value) {
      // @ts-expect-error: we just checked that they’re the same node.
      previous.value += value.value;
    } else {
      result.push(value);
      previous = value;
    }
  }

  return result;
}
/**
 * @type {Handler}
 * @param {import('mdast').Image|import('mdast').ImageReference} node
 */


function image(node) {
  const title = 'title' in node ? node.title : '';
  return {
    type: 'text',
    value: node.alt || title || ''
  };
}
/**
 * @type {Handler}
 * @param {import('mdast').Text} node
 */


function text(node) {
  return {
    type: 'text',
    value: node.value
  };
}
/**
 * @type {Handler}
 * @param {import('mdast').Paragraph} node
 */


function paragraph(node) {
  return {
    type: 'paragraph',
    children: node.children
  };
}
/**
 * @type {Handler}
 * @param {Extract<Node, import('unist').Parent>} node
 */


function children(node) {
  return node.children || [];
}
/**
 * @type {Handler}
 */


function lineBreak() {
  return {
    type: 'text',
    value: '\n'
  };
}
/**
 * @type {Handler}
 */


function empty() {
  return {
    type: 'text',
    value: ''
  };
}

/* eslint-disable max-lines-per-function */

const usePrepareComponent = ({
  components: overrideComponents = {},
  content,
  max = Infinity,
  paragraphAs,
  stripMarkdown: stripMarkdown$1
}) => {
  const components = {};

  if (paragraphAs) {
    // eslint-disable-next-line react/display-name, no-unused-vars, id-length
    components.p = ({
      node,
      ...props
    }) => /*#__PURE__*/React__default["default"].createElement(paragraphAs, props);
  }

  const remarkPlugins = [];

  if (stripMarkdown$1) {
    remarkPlugins.push(stripMarkdown);
  }

  const rehypePlugins = [];
  return {
    components: { ...components,
      ...overrideComponents
    },
    content: grapple.useTrimText(content, max),
    rehypePlugins,
    remarkPlugins
  };
};

var index = grapple.prepareComponent(usePrepareComponent)(Content);

exports["default"] = index;
