Skip to content
This repository has been archived by the owner on Aug 8, 2018. It is now read-only.

Commit

Permalink
[editor] feat(heading-switch-button): implemented and added to the to…
Browse files Browse the repository at this point in the history
…olbars instead of drop-down
  • Loading branch information
lxgreen committed Jul 10, 2018
1 parent a89121c commit 4eeb098
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ import {
ItalicIcon,
UnderlineIcon,
IndentIcon,
TitleIcon,
TitleOneIcon,
TitleTwoIcon,
BlockQuoteIcon,
OrderedListIcon,
UnorderedListIcon,
Expand Down Expand Up @@ -44,13 +41,6 @@ export const IndentButton = createTextBlockStyleButton({
tooltipTextKey: 'IndentButton_Tooltip',
});

export const TitleButton = createTextBlockStyleButton({
blockTypes: ['header-two', 'header-three'],
Icons: [TitleOneIcon, TitleTwoIcon],
InactiveIcon: TitleIcon,
tooltipTextKey: 'TitleButton_Tooltip',
});

export const BlockquoteButton = createTextBlockStyleButton({
blockTypes: ['blockquote'],
Icons: [BlockQuoteIcon],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ export const DesktopTextButtonList = [
'Italic',
'Underline',
'Title',
'HeadingsDropDown',
'Blockquote',
'Separator',
'Alignment',
Expand All @@ -30,7 +29,6 @@ export const MobileTextButtonList = [
'UnorderedList',
];

export { default as HeadingsDropDown } from './inline-styling/HeadingsDropDown';
export { default as TextAlignmentButton } from './TextAlignmentButton';
export { default as TextLinkButton } from './TextLinkButton';
export { default as AddPluginButton } from './AddPluginButton';
Expand All @@ -39,7 +37,6 @@ export {
ItalicButton,
UnderlineButton,
IndentButton,
TitleButton,
BlockquoteButton,
AlignTextLeftButton,
AlignTextCenterButton,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { RichUtils } from '@wix/draft-js';
import { HEADING, getSelectionStyles } from 'wix-rich-content-common';
import createInlineStyleSwitchButton from './createInlineStyleSwitchButton';
import { TitleIcon, TitleOneIcon, TitleTwoIcon } from '../../../../../statics/icons';

const styles = Object.keys(HEADING).map(k => HEADING[k]).filter(style => style !== HEADING.TITLE);
const HeadingSwitchButton = createInlineStyleSwitchButton({
Icons: [TitleIcon, TitleOneIcon, TitleTwoIcon],
styles,
onStyleChange: ({ getEditorState, setEditorState, styles, nextStyle }) => {
let editorState = getEditorState();
// toggle off all exclusive inline styles
const selectionStyles = getSelectionStyles(styles, editorState);
selectionStyles.forEach(appliedStyle => {
editorState = RichUtils.toggleInlineStyle(editorState, appliedStyle);
});
// apply new style
if (nextStyle !== HEADING.NORMAL) {
editorState = RichUtils.toggleInlineStyle(editorState, nextStyle);
}
setEditorState(editorState);
},
getSelectionStyle: ({ editorState, styles }) => {
const selection = editorState.getSelection();
if (selection.getEndOffset() - selection.getStartOffset() > 0) {
const selectionStyles = getSelectionStyles(styles, editorState);

if (selectionStyles.length !== 1) {
return HEADING.NORMAL;
}
return selectionStyles[0];
}
},
tooltipTextKey: 'TitleButton_tooltip'
});

export default HeadingSwitchButton;
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
import { RichUtils } from '@wix/draft-js';

import { getSelectionStyles } from 'wix-rich-content-common';
import { getSelectionStyles, HEADING } from 'wix-rich-content-common';
import createInlineStyleButton from './createInlineStyleButton';
import createInlineStyleDropDown from './createInlineStyleDropDown';
import styles from '../../../../../statics/styles/heading-buttons.scss';

const headings = [{
style: 'inline-normal-text', // TODO: common style consts
style: HEADING.NORMAL,
labelKey: 'NormalTextButton_label',
tooltipTextKey: 'NorNormalTextButton_tooltip',
className: styles.normalTextButton
}, {
style: 'inline-header-one',
style: HEADING.TITLE,
labelKey: 'HeadingOneButton_label',
tooltipTextKey: 'HeadingOneButton_tooltip',
className: styles.headingOneButton
}, {
style: 'inline-header-two',
style: HEADING.TWO,
labelKey: 'HeadingTwoButton_label',
tooltipTextKey: 'HeadingTwoButton_tooltip',
className: styles.headingTwoButton
}, {
style: 'inline-header-three',
style: HEADING.THREE,
labelKey: 'HeadingThreeButton_label',
tooltipTextKey: 'HeadingThreeButton_tooltip',
className: styles.headingThreeButton
}];

const getActiveStyle = (editorState, value, defaultValue) => {
const selectionStyles = getSelectionStyles(headings.map(heading => heading.style), editorState);
const getSelectionStyle = ({ editorState, styles, defaultValue }) => {
const selectionStyles = getSelectionStyles(styles, editorState);
if (selectionStyles.length === 0) {
return defaultValue;
} else if (selectionStyles.length > 1) {
return { style: '', labelKey: '' };
}
return headings.filter(h => h.style === selectionStyles[0])[0];
return styles.filter(s => s === selectionStyles[0])[0];
};

const HeadingsDropDown = createInlineStyleDropDown({
Expand All @@ -43,10 +43,13 @@ const HeadingsDropDown = createInlineStyleDropDown({
if (value) {
return headings.filter(h => h.style === value)[0];
}
const style = getActiveStyle(getEditorState(), value, headings[0]);
const style = getSelectionStyle({
editorState: getEditorState(),
styles: headings.map(h => h.style),
defaultValue: headings[0].style });
return style;
},
tooltipTextKey: 'HeadingsDropDown_tooltip',
tooltipTextKey: 'TitleButton_tooltip',
onChange: (getEditorState, setEditorState, style) => {
let editorState = getEditorState();
// toggle off all exclusive inline styles
Expand All @@ -55,7 +58,7 @@ const HeadingsDropDown = createInlineStyleDropDown({
editorState = RichUtils.toggleInlineStyle(editorState, appliedStyle);
});
// apply new style
if (style !== 'inline-normal-text') {
if (style !== HEADING.NORMAL) {
editorState = RichUtils.toggleInlineStyle(editorState, style);
}
setEditorState(editorState);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import TextButton from '../TextButton';

export default ({ onStyleChange, getSelectionStyle, styles, Icons, InactiveIcon = null, tooltipTextKey }) =>
class InlineStyleSwitchButton extends Component {
static propTypes = {
getEditorState: PropTypes.func.isRequired,
setEditorState: PropTypes.func.isRequired,
theme: PropTypes.object.isRequired,
isVisible: PropTypes.bool,
isMobile: PropTypes.bool,
t: PropTypes.func,
tabIndex: PropTypes.number,
};

constructor(props) {
super(props);
this.state = {
styleIndex: undefined,
};
}

get selectionStyle() {
const { getEditorState } = this.props;
const editorState = getEditorState();
return getSelectionStyle({ editorState, styles });
}

get Icon() {
const { styleIndex } = this.state;
if (styleIndex !== undefined) {
return Icons[styleIndex];
} else {
return InactiveIcon ? InactiveIcon : Icons[0];
}
}

componentWillReceiveProps(nextProps) {
if (this.props.isVisible === false && nextProps.isVisible === true) {
const { selectionStyle } = this;
const styleFoundIndex = styles.findIndex(b => b === selectionStyle);
const styleIndex = styleFoundIndex > -1 ? styleFoundIndex : undefined;
this.setState({ styleIndex });
}
}

getNextStyleIndex() {
const style = this.selectionStyle;
if (style) {
const styleIndex = styles.findIndex(s => s === style);
return (styleIndex + 1) % styles.length;
}
}

setStyle = () => {
const { getEditorState, setEditorState } = this.props;
const newStyleIndex = this.getNextStyleIndex();
if (newStyleIndex === undefined) {
return;
}
const nextStyle = styles[newStyleIndex];
onStyleChange({ getEditorState, setEditorState, styles, nextStyle });
this.setState({ styleIndex: newStyleIndex });
};

styleIsActive = () => {
const { style } = this;
return typeof style !== 'undefined' && style === this.selectionStyle;
};

render() {
const { Icon } = this;
const { theme, isMobile, t, tabIndex } = this.props;
const tooltipText = t(tooltipTextKey);
const textForHooks = tooltipText.replace(/\s+/, ''); // TODO: data-hooks
const dataHookText = `textBlockStyleButton_${textForHooks}`;

return (
<TextButton
icon={Icon}
theme={theme}
isMobile={isMobile}
isActive={this.styleIsActive}
onClick={this.setStyle}
tooltipText={tooltipText}
dataHook={dataHookText}
tabIndex={tabIndex}
/>
);
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
ItalicButton,
UnderlineButton,
IndentButton,
TitleButton,
BlockquoteButton,
TextAlignmentButton,
AlignTextLeftButton,
Expand All @@ -14,18 +13,15 @@ import {
UnorderedListButton,
OrderedListButton,
TextLinkButton,
HeadingsDropDown
} from '../index';
import createThemedSeparator from './createThemedSeparator';
import HeadingSwitchButton from '../inline-styling/HeadingSwitchButton';

export default ({ buttons, theme, t, isMobile }) => {
const themedSeparator = horizontal => createThemedSeparator({ theme, horizontal });
const structure = [];
buttons.forEach(buttonName => {
switch (buttonName) {
case 'HeadingsDropDown':
structure.push(HeadingsDropDown);
break;
case 'Bold':
structure.push(BoldButton);
break;
Expand All @@ -39,7 +35,7 @@ export default ({ buttons, theme, t, isMobile }) => {
structure.push(IndentButton);
break;
case 'Title':
structure.push(TitleButton);
structure.push(HeadingSwitchButton);
break;
case 'Blockquote':
structure.push(BlockquoteButton);
Expand Down
1 change: 0 additions & 1 deletion packages/editor/statics/locale/messages_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@
"EmojiPlugin_EmojiGroups_Objects": "Objects",
"EmojiPlugin_EmojiGroups_Symbols": "Symbols",
"EmojiPlugin_EmojiGroups_Flags": "Flags",
"HeadingsDropDown_tooltip": "Headings",
"TitleButton_label": "Title",
"TitleButton_tooltip": "Title",
"HeadingOneButton_label": "Heading 1",
Expand Down

0 comments on commit 4eeb098

Please sign in to comment.