@facundo-tolosa-appspace/draft-js-plugins-inline-toolbar
Version:
Toolbar Plugin for DraftJS
208 lines (196 loc) • 7.82 kB
JavaScript
import React, { Component } from 'react';
import { createStore } from '@draft-js-plugins/utils';
import { getVisibleSelectionRect } from 'draft-js';
import { ItalicButton, BoldButton, UnderlineButton, CodeButton } from '@draft-js-plugins/buttons';
function _extends() {
return _extends = Object.assign ? Object.assign.bind() : function (n) {
for (var e = 1; e < arguments.length; e++) {
var t = arguments[e];
for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
}
return n;
}, _extends.apply(null, arguments);
}
function _inheritsLoose(t, o) {
t.prototype = Object.create(o.prototype), t.prototype.constructor = t, _setPrototypeOf(t, o);
}
function _setPrototypeOf(t, e) {
return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
return t.__proto__ = e, t;
}, _setPrototypeOf(t, e);
}
// FIXED FILE
var Toolbar = /*#__PURE__*/function (_Component) {
function Toolbar() {
var _this;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _Component.call.apply(_Component, [this].concat(args)) || this;
_this.toolbar = null;
_this.state = {
isVisible: false,
position: undefined,
overrideContent: undefined
};
_this.onOverrideContent = function (overrideContent) {
_this.setState({
overrideContent: overrideContent
});
};
_this.onSelectionChanged = function () {
// wait a tick for accurate window.getSelection()
setTimeout(function () {
if (!_this.toolbar) return;
var editorRef = _this.props.store.getItem('getEditorRef')();
if (!editorRef) return;
var editorRoot = editorRef.refs && editorRef.refs.editor ? editorRef.refs.editor : editorRef.editor;
while (editorRoot.className.indexOf('DraftEditor-root') === -1) {
editorRoot = editorRoot.parentNode;
}
var editorRootRect = editorRoot.getBoundingClientRect();
var parentWindow = editorRoot.ownerDocument && editorRoot.ownerDocument.defaultView;
var selectionRect = getVisibleSelectionRect(parentWindow || window);
if (!selectionRect) return;
// Vertical offsets
var toolbarHeight = _this.toolbar.offsetHeight;
var editorHeight = editorRootRect.height;
var extraTopOffset = -5; // when placing above
var extraBottomOffset = 5; // when placing below
// Compute positions
var rawAbove = selectionRect.top - editorRootRect.top - toolbarHeight + extraTopOffset;
var rawBelow = selectionRect.bottom - editorRootRect.top + extraBottomOffset;
// Choose below if above overflows
var rawTopRelative = rawAbove < 0 ? rawBelow : rawAbove;
// Clamp within editor vertical bounds
var clampedTopRelative = Math.min(Math.max(rawTopRelative, 0), editorHeight - toolbarHeight);
var top = editorRoot.offsetTop + clampedTopRelative;
// Horizontal position: center tooltip and clamp within editor width
var toolbarWidth = _this.toolbar.offsetWidth;
var editorWidth = editorRootRect.width;
var rawLeftRelative = selectionRect.left - editorRootRect.left + selectionRect.width / 2;
var halfToolbar = toolbarWidth / 2;
var clampedLeftRelative = Math.min(Math.max(rawLeftRelative, halfToolbar), editorWidth - halfToolbar);
var left = editorRoot.offsetLeft + clampedLeftRelative;
var position = {
top: top,
left: left
};
_this.setState({
position: position
});
});
};
return _this;
}
_inheritsLoose(Toolbar, _Component);
var _proto = Toolbar.prototype;
_proto.UNSAFE_componentWillMount = function UNSAFE_componentWillMount() {
this.props.store.subscribeToItem('selection', this.onSelectionChanged);
};
_proto.componentWillUnmount = function componentWillUnmount() {
this.props.store.unsubscribeFromItem('selection', this.onSelectionChanged);
};
_proto.getStyle = function getStyle() {
var store = this.props.store;
var _this$state = this.state,
overrideContent = _this$state.overrideContent,
position = _this$state.position;
var selection = store.getItem('getEditorState')().getSelection();
var isVisible = !selection.isCollapsed() && selection.getHasFocus() || !!overrideContent;
var style = _extends({}, position);
if (isVisible) {
style.visibility = 'visible';
style.transform = 'translate(-50%) scale(1)';
style.transition = 'transform 0.15s cubic-bezier(.3,1.2,.2,1)';
} else {
style.transform = 'translate(-50%) scale(0)';
style.visibility = 'hidden';
}
return style;
};
_proto.render = function render() {
var _this2 = this;
var _this$props = this.props,
theme = _this$props.theme,
store = _this$props.store,
children = _this$props.children;
var OverrideContent = this.state.overrideContent;
var childrenProps = {
theme: theme.buttonStyles,
getEditorState: store.getItem('getEditorState'),
setEditorState: store.getItem('setEditorState'),
onOverrideContent: this.onOverrideContent
};
return /*#__PURE__*/React.createElement("div", {
className: theme.toolbarStyles.toolbar,
style: this.getStyle(),
ref: function ref(element) {
_this2.toolbar = element;
}
}, OverrideContent ? /*#__PURE__*/React.createElement(OverrideContent, childrenProps) :
// Handle both FC and function that returns ReactElement
typeof children === 'function' ? children(childrenProps) : children && /*#__PURE__*/React.createElement(children, childrenProps));
};
return Toolbar;
}(Component);
Toolbar.defaultProps = {
children: function children(externalProps) {
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(ItalicButton, externalProps), /*#__PURE__*/React.createElement(BoldButton, externalProps), /*#__PURE__*/React.createElement(UnderlineButton, externalProps), /*#__PURE__*/React.createElement(CodeButton, externalProps));
}
};
var Toolbar$1 = Toolbar;
var separator = "s1o2cezu";
function Seperator(_ref) {
var _ref$className = _ref.className,
className = _ref$className === void 0 ? separator : _ref$className;
return /*#__PURE__*/React.createElement("div", {
className: className
});
}
var buttonStyles = {
buttonWrapper: "bpsgbes",
button: "b181v2oy",
active: "a9immln"
};
var toolbarStyles = {
toolbar: "tukdd6b"
};
var defaultTheme = {
buttonStyles: buttonStyles,
toolbarStyles: toolbarStyles
};
var index = (function (config) {
if (config === void 0) {
config = {};
}
var store = createStore({
isVisible: false
});
var _config = config,
_config$theme = _config.theme,
theme = _config$theme === void 0 ? defaultTheme : _config$theme;
var InlineToolbar = function InlineToolbar(props) {
return /*#__PURE__*/React.createElement(Toolbar$1, _extends({}, props, {
store: store,
theme: theme
}));
};
return {
initialize: function initialize(_ref) {
var getEditorState = _ref.getEditorState,
setEditorState = _ref.setEditorState,
getEditorRef = _ref.getEditorRef;
store.updateItem('getEditorState', getEditorState);
store.updateItem('setEditorState', setEditorState);
store.updateItem('getEditorRef', getEditorRef);
},
// Re-Render the text-toolbar on selection change
onChange: function onChange(editorState) {
store.updateItem('selection', editorState.getSelection());
return editorState;
},
InlineToolbar: InlineToolbar
};
});
export { Seperator as Separator, index as default };