mirror of
				https://github.com/strapi/strapi.git
				synced 2025-11-04 03:43:34 +00:00 
			
		
		
		
	Created components folder
This commit is contained in:
		
							parent
							
								
									8be6df24b3
								
							
						
					
					
						commit
						aed37546ff
					
				@ -1,192 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * Utils components for the WYSIWYG
 | 
			
		||||
 * It includes decorators toggle buttons...
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { CompositeDecorator, ContentState, convertFromHTML, EditorState } from 'draft-js';
 | 
			
		||||
import { FormattedMessage } from 'react-intl';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import cn from 'classnames';
 | 
			
		||||
import { isEmpty } from 'lodash';
 | 
			
		||||
import Select from 'components/InputSelect';
 | 
			
		||||
import WysiwygEditor from 'components/WysiwygEditor';
 | 
			
		||||
 | 
			
		||||
import { SELECT_OPTIONS } from './constants';
 | 
			
		||||
import converter from './converter';
 | 
			
		||||
import { getBlockStyle } from './helpers';
 | 
			
		||||
import { findLinkEntities, findImageEntities } from './strategies';
 | 
			
		||||
 | 
			
		||||
import styles from './styles.scss';
 | 
			
		||||
/* eslint-disable react/no-multi-comp */
 | 
			
		||||
 | 
			
		||||
class CustomSelect extends React.Component {
 | 
			
		||||
  render() {
 | 
			
		||||
    const { isPreviewMode, headerValue, isFullscreen, handleChangeSelect } = this.context;
 | 
			
		||||
    const selectClassName = isFullscreen ? styles.selectFullscreen : styles.editorSelect;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <div className={selectClassName}>
 | 
			
		||||
        <Select
 | 
			
		||||
          disabled={isPreviewMode}
 | 
			
		||||
          name="headerSelect"
 | 
			
		||||
          onChange={handleChangeSelect}
 | 
			
		||||
          value={headerValue}
 | 
			
		||||
          selectOptions={SELECT_OPTIONS}
 | 
			
		||||
        />
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CustomSelect.contextTypes = {
 | 
			
		||||
  handleChangeSelect: PropTypes.func,
 | 
			
		||||
  headerValue: PropTypes.string,
 | 
			
		||||
  isPreviewMode: PropTypes.bool,
 | 
			
		||||
  isFullscreen: PropTypes.bool,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const Image = props => {
 | 
			
		||||
  const { alt, height, src, width } = props.contentState.getEntity(props.entityKey).getData();
 | 
			
		||||
 | 
			
		||||
  return <img alt={alt} src={src} height={height} width={width} style={{ maxWidth: '100%' }} />;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Image.propTypes = {
 | 
			
		||||
  contentState: PropTypes.object.isRequired,
 | 
			
		||||
  entityKey: PropTypes.string.isRequired,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const Link = props => {
 | 
			
		||||
  const { url } = props.contentState.getEntity(props.entityKey).getData();
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <a href={url} style={styles.link}>
 | 
			
		||||
      {props.children}
 | 
			
		||||
    </a>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Link.defaultProps = {
 | 
			
		||||
  children: '',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Link.propTypes = {
 | 
			
		||||
  children: PropTypes.node,
 | 
			
		||||
  contentState: PropTypes.object.isRequired,
 | 
			
		||||
  entityKey: PropTypes.string.isRequired,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const PreviewControl = ({ characters, onClick }) => (
 | 
			
		||||
  <div className={styles.previewControlsWrapper} onClick={onClick}>
 | 
			
		||||
    <div>
 | 
			
		||||
      <span>{characters} </span>
 | 
			
		||||
      <FormattedMessage
 | 
			
		||||
        id="components.WysiwygBottomControls.charactersIndicators"
 | 
			
		||||
      />
 | 
			
		||||
    </div>
 | 
			
		||||
    <div className={styles.wysiwygCollapse}>
 | 
			
		||||
      <FormattedMessage id="components.Wysiwyg.collapse" />
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
PreviewControl.defaultProps = {
 | 
			
		||||
  characters: 0,
 | 
			
		||||
  onClick: () => {},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PreviewControl.propTypes = {
 | 
			
		||||
  characters: PropTypes.number,
 | 
			
		||||
  onClick: PropTypes.func,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class PreviewWysiwyg extends React.Component {
 | 
			
		||||
  getClassName = () => {
 | 
			
		||||
    if (this.context.isFullscreen) {
 | 
			
		||||
      return cn(styles.editor, styles.editorFullScreen, styles.fullscreenPreviewEditor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return styles.editor;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  previewHTML = () => {
 | 
			
		||||
    const initHtml = isEmpty(this.context.html) ? '<p></p>' : this.context.html;
 | 
			
		||||
    const html = converter.makeHtml(initHtml);
 | 
			
		||||
    console.log('h', html);
 | 
			
		||||
    const decorator = new CompositeDecorator([
 | 
			
		||||
      {
 | 
			
		||||
        strategy: findLinkEntities,
 | 
			
		||||
        component: Link,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        strategy: findImageEntities,
 | 
			
		||||
        component: Image,
 | 
			
		||||
      },
 | 
			
		||||
    ]);
 | 
			
		||||
    const blocksFromHTML = convertFromHTML(html);
 | 
			
		||||
    // Make sure blocksFromHTML.contentBlocks !== null
 | 
			
		||||
    if (blocksFromHTML.contentBlocks) {
 | 
			
		||||
      const contentState = ContentState.createFromBlockArray(
 | 
			
		||||
        blocksFromHTML.contentBlocks,
 | 
			
		||||
        blocksFromHTML.entityMap,
 | 
			
		||||
      );
 | 
			
		||||
      return EditorState.createWithContent(contentState, decorator);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Prevent errors if value is empty
 | 
			
		||||
    return EditorState.createEmpty();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    const { placeholder } = this.context;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <div className={this.getClassName()}>
 | 
			
		||||
        <WysiwygEditor
 | 
			
		||||
          blockStyleFn={getBlockStyle}
 | 
			
		||||
          editorState={this.previewHTML()}
 | 
			
		||||
          onChange={() => {}}
 | 
			
		||||
          placeholder={placeholder}
 | 
			
		||||
          spellCheck
 | 
			
		||||
        />
 | 
			
		||||
        <input className={styles.editorInput} value="" tabIndex="-1" />
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PreviewWysiwyg.contextTypes = {
 | 
			
		||||
  editorState: PropTypes.func,
 | 
			
		||||
  html: PropTypes.string,
 | 
			
		||||
  isFullscreen: PropTypes.bool,
 | 
			
		||||
  placeholder: PropTypes.string,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const ToggleMode = props => {
 | 
			
		||||
  const label = props.isPreviewMode
 | 
			
		||||
    ? 'components.Wysiwyg.ToggleMode.markdown'
 | 
			
		||||
    : 'components.Wysiwyg.ToggleMode.preview';
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div className={styles.toggleModeWrapper}>
 | 
			
		||||
      <button type="button" className={styles.toggleModeButton} onClick={props.onClick}>
 | 
			
		||||
        <FormattedMessage id={label} />
 | 
			
		||||
      </button>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ToggleMode.defaultProps = {
 | 
			
		||||
  isPreviewMode: false,
 | 
			
		||||
  onClick: () => {},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ToggleMode.propTypes = {
 | 
			
		||||
  isPreviewMode: PropTypes.bool,
 | 
			
		||||
  onClick: PropTypes.func,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export { CustomSelect, Image, Link, PreviewControl, PreviewWysiwyg, ToggleMode };
 | 
			
		||||
@ -0,0 +1,42 @@
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * CustomSelect
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
 | 
			
		||||
import Select from 'components/InputSelect';
 | 
			
		||||
import { SELECT_OPTIONS } from '../constants';
 | 
			
		||||
 | 
			
		||||
import styles from './styles.scss';
 | 
			
		||||
 | 
			
		||||
class CustomSelect extends React.Component {
 | 
			
		||||
  render() {
 | 
			
		||||
    const { isPreviewMode, headerValue, isFullscreen, handleChangeSelect } = this.context;
 | 
			
		||||
    const selectClassName = isFullscreen ? styles.selectFullscreen : styles.editorSelect;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <div className={selectClassName}>
 | 
			
		||||
        <Select
 | 
			
		||||
          disabled={isPreviewMode}
 | 
			
		||||
          name="headerSelect"
 | 
			
		||||
          onChange={handleChangeSelect}
 | 
			
		||||
          value={headerValue}
 | 
			
		||||
          selectOptions={SELECT_OPTIONS}
 | 
			
		||||
        />
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CustomSelect.contextTypes = {
 | 
			
		||||
  handleChangeSelect: PropTypes.func,
 | 
			
		||||
  headerValue: PropTypes.string,
 | 
			
		||||
  isPreviewMode: PropTypes.bool,
 | 
			
		||||
  isFullscreen: PropTypes.bool,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default CustomSelect;
 | 
			
		||||
@ -0,0 +1,22 @@
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * Image
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
 | 
			
		||||
const Image = props => {
 | 
			
		||||
  const { alt, height, src, width } = props.contentState.getEntity(props.entityKey).getData();
 | 
			
		||||
 | 
			
		||||
  return <img alt={alt} src={src} height={height} width={width} style={{ maxWidth: '100%' }} />;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Image.propTypes = {
 | 
			
		||||
  contentState: PropTypes.object.isRequired,
 | 
			
		||||
  entityKey: PropTypes.string.isRequired,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default Image;
 | 
			
		||||
@ -0,0 +1,21 @@
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * Wysiwyg components' index
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import CustomSelect from './customSelect';
 | 
			
		||||
import Image from './image';
 | 
			
		||||
import Link from './link';
 | 
			
		||||
import PreviewControl from './previewControl';
 | 
			
		||||
import PreviewWysiwyg from './previewWysiwyg';
 | 
			
		||||
import ToggleMode from './toggleMode';
 | 
			
		||||
 | 
			
		||||
export {
 | 
			
		||||
  CustomSelect,
 | 
			
		||||
  Image,
 | 
			
		||||
  Link,
 | 
			
		||||
  PreviewControl,
 | 
			
		||||
  PreviewWysiwyg,
 | 
			
		||||
  ToggleMode,
 | 
			
		||||
};
 | 
			
		||||
@ -0,0 +1,30 @@
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * Link
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
 | 
			
		||||
const Link = props => {
 | 
			
		||||
  const { url } = props.contentState.getEntity(props.entityKey).getData();
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <a href={url}>
 | 
			
		||||
      {props.children}
 | 
			
		||||
    </a>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Link.defaultProps = {
 | 
			
		||||
  children: '',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Link.propTypes = {
 | 
			
		||||
  children: PropTypes.node,
 | 
			
		||||
  contentState: PropTypes.object.isRequired,
 | 
			
		||||
  entityKey: PropTypes.string.isRequired,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default Link;
 | 
			
		||||
@ -0,0 +1,36 @@
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * PreviewControl
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import { FormattedMessage } from 'react-intl';
 | 
			
		||||
import styles from './styles.scss';
 | 
			
		||||
 | 
			
		||||
const PreviewControl = ({ characters, onClick }) => (
 | 
			
		||||
  <div className={styles.previewControlsWrapper} onClick={onClick}>
 | 
			
		||||
    <div>
 | 
			
		||||
      <span>{characters} </span>
 | 
			
		||||
      <FormattedMessage
 | 
			
		||||
        id="components.WysiwygBottomControls.charactersIndicators"
 | 
			
		||||
      />
 | 
			
		||||
    </div>
 | 
			
		||||
    <div className={styles.wysiwygCollapse}>
 | 
			
		||||
      <FormattedMessage id="components.Wysiwyg.collapse" />
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
PreviewControl.defaultProps = {
 | 
			
		||||
  characters: 0,
 | 
			
		||||
  onClick: () => {},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PreviewControl.propTypes = {
 | 
			
		||||
  characters: PropTypes.number,
 | 
			
		||||
  onClick: PropTypes.func,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default PreviewControl;
 | 
			
		||||
@ -0,0 +1,82 @@
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * PreviewWysiwyg
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import { CompositeDecorator, ContentState, convertFromHTML, EditorState } from 'draft-js';
 | 
			
		||||
import cn from 'classnames';
 | 
			
		||||
import { isEmpty } from 'lodash';
 | 
			
		||||
 | 
			
		||||
import WysiwygEditor from 'components/WysiwygEditor';
 | 
			
		||||
import converter from '../converter';
 | 
			
		||||
import { getBlockStyle } from '../helpers';
 | 
			
		||||
import { findLinkEntities, findImageEntities } from '../strategies';
 | 
			
		||||
 | 
			
		||||
import styles from './styles.scss';
 | 
			
		||||
import { Image, Link } from './index';
 | 
			
		||||
 | 
			
		||||
class PreviewWysiwyg extends React.Component {
 | 
			
		||||
  getClassName = () => {
 | 
			
		||||
    if (this.context.isFullscreen) {
 | 
			
		||||
      return cn(styles.editor, styles.editorFullScreen, styles.fullscreenPreviewEditor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return styles.editor;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  previewHTML = () => {
 | 
			
		||||
    const initHtml = isEmpty(this.context.html) ? '<p></p>' : this.context.html;
 | 
			
		||||
    const html = converter.makeHtml(initHtml);
 | 
			
		||||
    const decorator = new CompositeDecorator([
 | 
			
		||||
      {
 | 
			
		||||
        strategy: findLinkEntities,
 | 
			
		||||
        component: Link,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        strategy: findImageEntities,
 | 
			
		||||
        component: Image,
 | 
			
		||||
      },
 | 
			
		||||
    ]);
 | 
			
		||||
    const blocksFromHTML = convertFromHTML(html);
 | 
			
		||||
    // Make sure blocksFromHTML.contentBlocks !== null
 | 
			
		||||
    if (blocksFromHTML.contentBlocks) {
 | 
			
		||||
      const contentState = ContentState.createFromBlockArray(
 | 
			
		||||
        blocksFromHTML.contentBlocks,
 | 
			
		||||
        blocksFromHTML.entityMap,
 | 
			
		||||
      );
 | 
			
		||||
      return EditorState.createWithContent(contentState, decorator);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Prevent errors if value is empty
 | 
			
		||||
    return EditorState.createEmpty();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    const { placeholder } = this.context;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <div className={this.getClassName()}>
 | 
			
		||||
        <WysiwygEditor
 | 
			
		||||
          blockStyleFn={getBlockStyle}
 | 
			
		||||
          editorState={this.previewHTML()}
 | 
			
		||||
          onChange={() => {}}
 | 
			
		||||
          placeholder={placeholder}
 | 
			
		||||
          spellCheck
 | 
			
		||||
        />
 | 
			
		||||
        <input className={styles.editorInput} value="" tabIndex="-1" />
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PreviewWysiwyg.contextTypes = {
 | 
			
		||||
  editorState: PropTypes.func,
 | 
			
		||||
  html: PropTypes.string,
 | 
			
		||||
  isFullscreen: PropTypes.bool,
 | 
			
		||||
  placeholder: PropTypes.string,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default PreviewWysiwyg;
 | 
			
		||||
@ -0,0 +1,117 @@
 | 
			
		||||
.editor {
 | 
			
		||||
  min-height: 303px;
 | 
			
		||||
  padding: 10px 20px 0 20px;
 | 
			
		||||
  font-size: 16px;
 | 
			
		||||
  margin-top: 10px;
 | 
			
		||||
  background-color: #fff;
 | 
			
		||||
  line-height: 18px !important;
 | 
			
		||||
  cursor: text;
 | 
			
		||||
  // TODO define rules for header's margin
 | 
			
		||||
  h1, h2, h3, h4, h5, h6 {
 | 
			
		||||
    margin: 0;
 | 
			
		||||
    line-height: 18px !important;
 | 
			
		||||
  }
 | 
			
		||||
  h1 {
 | 
			
		||||
    margin-top: 13px !important;
 | 
			
		||||
    margin-bottom: 22px;
 | 
			
		||||
  }
 | 
			
		||||
  > div {
 | 
			
		||||
    > div {
 | 
			
		||||
      > div {
 | 
			
		||||
        margin-bottom: 32px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  li {
 | 
			
		||||
    margin-top: 0;
 | 
			
		||||
  }
 | 
			
		||||
  ul, ol {
 | 
			
		||||
    margin-bottom: 18px;
 | 
			
		||||
  }
 | 
			
		||||
  span {
 | 
			
		||||
    white-space: pre-line;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.editorFullScreen {
 | 
			
		||||
  max-height: calc(100% - 100px) !important;
 | 
			
		||||
  margin-bottom: 0;
 | 
			
		||||
  overflow: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.editorInput {
 | 
			
		||||
  height: 0;
 | 
			
		||||
  width: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.editorSelect {
 | 
			
		||||
  min-width: 161px;
 | 
			
		||||
  margin-left: 15px;
 | 
			
		||||
  margin-right: 5px;
 | 
			
		||||
  > select {
 | 
			
		||||
    box-shadow: 0 0 0 rgba(0,0,0,0)!important;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.fullscreenPreviewEditor {
 | 
			
		||||
  margin-top: 9px;
 | 
			
		||||
  padding: 10px 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.previewControlsWrapper {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  height: 49px;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  padding: 0 17px;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
  background-color: #FAFAFB;
 | 
			
		||||
  line-height: 30px;
 | 
			
		||||
  font-size: 12px;
 | 
			
		||||
  font-family: Lato;
 | 
			
		||||
  background-color: #fff;
 | 
			
		||||
  border-bottom: 1px solid #F3F4F4;
 | 
			
		||||
  line-height: 49px;
 | 
			
		||||
  font-size: 13px;
 | 
			
		||||
  >div:first-child {
 | 
			
		||||
    >span:last-child {
 | 
			
		||||
      font-size: 12px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.selectFullscreen {
 | 
			
		||||
  min-width: 115px;
 | 
			
		||||
  margin-left: 15px;
 | 
			
		||||
  > select {
 | 
			
		||||
    min-width: 110px !important;
 | 
			
		||||
    box-shadow: 0 0 0 rgba(0,0,0,0)!important;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.toggleModeButton {
 | 
			
		||||
  height: 32px;
 | 
			
		||||
  min-width: 32px;
 | 
			
		||||
  padding-left: 10px;
 | 
			
		||||
  padding-right: 10px;
 | 
			
		||||
  border: 1px solid rgba(16,22,34,0.10);
 | 
			
		||||
  border-radius: 3px;
 | 
			
		||||
  background: #F3F4F4;
 | 
			
		||||
  font-size: 13px;
 | 
			
		||||
  font-weight: 500;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.toggleModeWrapper {
 | 
			
		||||
  margin-left: auto;
 | 
			
		||||
  margin-right: 15px;
 | 
			
		||||
  padding-top: 8px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.wysiwygCollapse {
 | 
			
		||||
  &:after {
 | 
			
		||||
    content: '\f066';
 | 
			
		||||
    font-family: FontAwesome;
 | 
			
		||||
    margin-left: 8px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,36 @@
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * ToggleMode
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { FormattedMessage } from 'react-intl';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import styles from './styles.scss';
 | 
			
		||||
 | 
			
		||||
const ToggleMode = props => {
 | 
			
		||||
  const label = props.isPreviewMode
 | 
			
		||||
    ? 'components.Wysiwyg.ToggleMode.markdown'
 | 
			
		||||
    : 'components.Wysiwyg.ToggleMode.preview';
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div className={styles.toggleModeWrapper}>
 | 
			
		||||
      <button type="button" className={styles.toggleModeButton} onClick={props.onClick}>
 | 
			
		||||
        <FormattedMessage id={label} />
 | 
			
		||||
      </button>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ToggleMode.defaultProps = {
 | 
			
		||||
  isPreviewMode: false,
 | 
			
		||||
  onClick: () => {},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ToggleMode.propTypes = {
 | 
			
		||||
  isPreviewMode: PropTypes.bool,
 | 
			
		||||
  onClick: PropTypes.func,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default ToggleMode;
 | 
			
		||||
@ -12,6 +12,15 @@ export function getBlockStyle(block) {
 | 
			
		||||
      return styles.editorBlockquote;
 | 
			
		||||
    case 'code-block':
 | 
			
		||||
      return styles.editorCodeBlock;
 | 
			
		||||
    case 'paragraph':
 | 
			
		||||
    case 'unordered-list-item':
 | 
			
		||||
    case 'ordered-list-item':
 | 
			
		||||
    case 'header-one':
 | 
			
		||||
    case 'header-two':
 | 
			
		||||
    case 'header-three':
 | 
			
		||||
    case 'header-four':
 | 
			
		||||
    case 'header-five':
 | 
			
		||||
    case 'header-six':
 | 
			
		||||
    default:
 | 
			
		||||
      return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,7 @@ import Drop from 'components/WysiwygDropUpload';
 | 
			
		||||
import WysiwygBottomControls from 'components/WysiwygBottomControls';
 | 
			
		||||
import WysiwygEditor from 'components/WysiwygEditor';
 | 
			
		||||
import request from 'utils/request';
 | 
			
		||||
import { CustomSelect, PreviewControl, PreviewWysiwyg, ToggleMode } from './components';
 | 
			
		||||
import { CustomSelect, PreviewControl, PreviewWysiwyg, ToggleMode } from './components/index';
 | 
			
		||||
import { CONTROLS } from './constants';
 | 
			
		||||
import { getBlockContent, getBlockStyle, getDefaultSelectionOffsets, getOffSets } from './helpers';
 | 
			
		||||
import styles from './styles.scss';
 | 
			
		||||
 | 
			
		||||
@ -64,24 +64,6 @@
 | 
			
		||||
  border-color: #ff203c !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.editorSelect {
 | 
			
		||||
  min-width: 161px;
 | 
			
		||||
  margin-left: 15px;
 | 
			
		||||
  margin-right: 5px;
 | 
			
		||||
  > select {
 | 
			
		||||
    box-shadow: 0 0 0 rgba(0,0,0,0)!important;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.selectFullscreen {
 | 
			
		||||
  min-width: 115px;
 | 
			
		||||
  margin-left: 15px;
 | 
			
		||||
  > select {
 | 
			
		||||
    min-width: 110px !important;
 | 
			
		||||
    box-shadow: 0 0 0 rgba(0,0,0,0)!important;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.editorInput {
 | 
			
		||||
  height: 0;
 | 
			
		||||
  width: 0;
 | 
			
		||||
@ -145,57 +127,3 @@
 | 
			
		||||
  margin-bottom: 0;
 | 
			
		||||
  overflow: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.previewControlsWrapper {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  height: 49px;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  padding: 0 17px;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
  background-color: #FAFAFB;
 | 
			
		||||
  line-height: 30px;
 | 
			
		||||
  font-size: 12px;
 | 
			
		||||
  font-family: Lato;
 | 
			
		||||
  background-color: #fff;
 | 
			
		||||
  border-bottom: 1px solid #F3F4F4;
 | 
			
		||||
  line-height: 49px;
 | 
			
		||||
  font-size: 13px;
 | 
			
		||||
  >div:first-child {
 | 
			
		||||
    >span:last-child {
 | 
			
		||||
      font-size: 12px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.fullscreenPreviewEditor {
 | 
			
		||||
  margin-top: 9px;
 | 
			
		||||
  padding: 10px 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.toggleModeButton {
 | 
			
		||||
  height: 32px;
 | 
			
		||||
  min-width: 32px;
 | 
			
		||||
  padding-left: 10px;
 | 
			
		||||
  padding-right: 10px;
 | 
			
		||||
  border: 1px solid rgba(16,22,34,0.10);
 | 
			
		||||
  border-radius: 3px;
 | 
			
		||||
  background: #F3F4F4;
 | 
			
		||||
  font-size: 13px;
 | 
			
		||||
  font-weight: 500;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.toggleModeWrapper {
 | 
			
		||||
  margin-left: auto;
 | 
			
		||||
  margin-right: 15px;
 | 
			
		||||
  padding-top: 8px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.wysiwygCollapse {
 | 
			
		||||
  &:after {
 | 
			
		||||
    content: '\f066';
 | 
			
		||||
    font-family: FontAwesome;
 | 
			
		||||
    margin-left: 8px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user