Skip to content
Snippets Groups Projects
BlockDropDownComponent.js 3.13 KiB
Newer Older
chris's avatar
chris committed
/* eslint-disable no-underscore-dangle */
chris's avatar
chris committed
import React, { useContext, useMemo, useState, useEffect } from 'react';
chris's avatar
chris committed
import { isEmpty } from 'lodash';
chris's avatar
chris committed
import styled from 'styled-components';
chris's avatar
chris committed
import { useTranslation } from 'react-i18next';
chris's avatar
chris committed
import { WaxContext, ReactDropDownStyles } from 'wax-prosemirror-core';
import Dropdown from 'react-dropdown';
import { v4 as uuidv4 } from 'uuid';

const Wrapper = styled.div`
  ${ReactDropDownStyles};
`;
const DropdownStyled = styled(Dropdown)`
  display: inline-flex;
  cursor: not-allowed;
  opacity: ${props => (props.select ? 1 : 0.4)};
  pointer-events: ${props => (props.select ? 'default' : 'none')};
  .Dropdown-control {
chris's avatar
chris committed
    width: 170px;
chris's avatar
chris committed
    border: none;
chris's avatar
chris committed
    padding: 12px 26px 8px 10px;
chris's avatar
chris committed
    &:hover {
      box-shadow: none;
    }
  }

  .Dropdown-arrow {
    top: 17px;
  }

  .Dropdown-menu {
chris's avatar
chris committed
    width: 102%;
chris's avatar
chris committed
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    .Dropdown-option {
      width: 100%;
    }
  }
`;

// eslint-disable-next-line react/prop-types
const BlockDropDownComponent = ({ view, tools }) => {
chris's avatar
chris committed
  const { t, i18n } = useTranslation();
chris's avatar
chris committed
  const context = useContext(WaxContext);
  const {
    activeViewId,
    pmViews: { main },
  } = context;
chris's avatar
chris committed
  const [label, setLabel] = useState(null);
chris's avatar
chris committed

chris's avatar
chris committed
  const isEditable = main.props.editable(editable => {
    return editable;
  });

chris's avatar
chris committed
  const translatedLabel = (translation, defaultLabel) => {
    return !isEmpty(i18n) && i18n.exists(translation)
      ? t(translation)
      : defaultLabel;
  };

chris's avatar
chris committed
  const dropDownOptions = [
chris's avatar
chris committed
    {
chris's avatar
chris committed
      label: translatedLabel(`Wax.BlockLevel.Heading 2`, 'Heading 2'),
chris's avatar
chris committed
      value: '5',
      item: tools[5],
    },
    {
chris's avatar
chris committed
      label: translatedLabel(`Wax.BlockLevel.Heading 3`, 'Heading 3'),
chris's avatar
chris committed
      value: '6',
      item: tools[6],
    },
    {
chris's avatar
chris committed
      label: translatedLabel(`Wax.BlockLevel.Paragraph`, 'Paragraph'),
chris's avatar
chris committed
      value: '8',
      item: tools[8],
    },
    {
chris's avatar
chris committed
      label: translatedLabel(`Wax.BlockLevel.Block Quote`, 'Block Quote'),
chris's avatar
chris committed
      value: '13',
      item: tools[13],
    },
chris's avatar
chris committed
  ];

chris's avatar
chris committed
  useEffect(() => {
chris's avatar
chris committed
    setLabel(translatedLabel('Wax.BlockLevel.Block Level', 'Heading styles'));
chris's avatar
chris committed
    dropDownOptions.forEach(option => {
      if (option.item.active(main.state, activeViewId)) {
        setTimeout(() => {
chris's avatar
chris committed
          setLabel(
            translatedLabel(
              `Wax.BlockLevel.${option.item.label}`,
              option.item.label,
            ),
          );
chris's avatar
chris committed
        });
      }
    });
chris's avatar
chris committed
  }, [
    main.state.selection.$from.parent.type.name,
    t('Wax.BlockLevel.Paragraph'),
  ]);
chris's avatar
chris committed

  const MultipleDropDown = useMemo(
    () => (
      <Wrapper key={uuidv4()}>
        <DropdownStyled
          key={uuidv4()}
          onChange={option => {
chris's avatar
chris committed
            tools[option.value].run(main.state, main.dispatch);
chris's avatar
chris committed
          }}
          options={dropDownOptions}
chris's avatar
chris committed
          placeholder={translatedLabel(
            'Wax.BlockLevel.Block Level',
            'Heading styles',
          )}
chris's avatar
chris committed
          select={isEditable}
chris's avatar
chris committed
          value={label}
chris's avatar
chris committed
        />
      </Wrapper>
    ),
chris's avatar
chris committed
    [label, isEditable, t('Wax.BlockLevel.Paragraph')],
chris's avatar
chris committed
  );

  return MultipleDropDown;
};

export default BlockDropDownComponent;