diff --git a/modules/ui/components/NeverUpdate.jsx b/modules/ui/components/NeverUpdate.jsx
new file mode 100644
index 00000000..780e7b1f
--- /dev/null
+++ b/modules/ui/components/NeverUpdate.jsx
@@ -0,0 +1,13 @@
+import React, {Fragment} from 'react';
+
+export default class NeverUpdate extends React.Component {
+
+ shouldComponentUpdate() {
+ return false;
+ }
+
+ render() {
+ return {this.props.children};
+ }
+
+}
\ No newline at end of file
diff --git a/modules/ui/connect.jsx b/modules/ui/connect.jsx
index 712fd8c4..9f1f6dd2 100644
--- a/modules/ui/connect.jsx
+++ b/modules/ui/connect.jsx
@@ -1,12 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
-import shallowEqual from "../gems/shallowEqual";
-export default function connect(WrappedComponent, tokens, {staticProps, mapProps, mapActions}) {
-
- if (!Array.isArray(tokens)) {
- tokens = [tokens];
- }
+export default function connect(WrappedComponent, tokens, {staticProps, mapProps, mapActions, mapSelfProps}) {
mapProps = createMapper(mapProps);
@@ -14,20 +9,30 @@ export default function connect(WrappedComponent, tokens, {staticProps, mapProps
return dispatch;
};
- return class StateConnector extends React.Component {
+ mapSelfProps = mapSelfProps || (() => undefined);
+
+ return class StateConnector extends React.PureComponent {
- constructor(context) {
+ constructor(props) {
super();
this.mounted = false;
this.stateProps = {};
- this.dispatchProps = mapActions(this.dispatch);
+ this.dispatchProps = mapActions(this.dispatch, props);
}
componentWillMount() {
- this.externalStateConnection = this.context.bus.connectToState(tokens, this.setExternalState);
+ this.externalStateConnection = this.context.bus.connectToState(this.getTokens(), this.setExternalState);
this.externalStateConnection();
}
+ getTokens() {
+ let tokensArr = tokens instanceof Function ? tokens(this.props) : tokens;
+ if (!Array.isArray(tokensArr)) {
+ tokensArr = [tokensArr];
+ }
+ return tokensArr;
+ }
+
componentDidMount() {
this.mounted = true;
}
@@ -38,23 +43,21 @@ export default function connect(WrappedComponent, tokens, {staticProps, mapProps
}
setExternalState = (state) => {
- this.stateProps = mapProps(state);
+ this.stateProps = mapProps(state, this.props);
if (this.mounted) {
this.forceUpdate();
}
};
- shouldComponentUpdate(nextProps, nextState) {
- return !shallowEqual(this.props, nextProps);
-
- }
-
dispatch = (event, data) => {
this.context.bus.dispatch(event, data);
};
render() {
- return
+ return
}
componentDidCatch() {
@@ -66,13 +69,9 @@ export default function connect(WrappedComponent, tokens, {staticProps, mapProps
}
}
-function createMapper(mapper) {
+function createMapper(mapper, comp) {
if (!mapper) {
- return function (state) {
- let props = {};
- state.forEach(stateItem => Object.assign(props, stateItem));
- return props;
- };
+ return DEFAULT_MAPPER;
} else if (Array.isArray(mapper)) {
return function (state) {
let props = {};
@@ -87,5 +86,8 @@ function createMapper(mapper) {
return mapper;
}
-
-
+export function DEFAULT_MAPPER(state) {
+ let props = {};
+ state.forEach(stateItem => Object.assign(props, stateItem));
+ return props;
+}
diff --git a/web/app/cad/actions/actionButtonBehavior.js b/web/app/cad/actions/actionButtonBehavior.js
index 9b7d3e29..5eed39cc 100644
--- a/web/app/cad/actions/actionButtonBehavior.js
+++ b/web/app/cad/actions/actionButtonBehavior.js
@@ -1,12 +1,12 @@
-
import {TOKENS as ACTION_TOKENS} from "./actionSystemPlugin";
-export function mapActionBehavior(actionId) {
- let actionRunToken = ACTION_TOKENS.actionRun(actionId);
-
- return dispatch => ({
- onClick: data => dispatch(actionRunToken, data),
- onMouseEnter: ({pageX, pageY}) => dispatch(ACTION_TOKENS.SHOW_HINT_FOR, [actionId, pageX, pageY]),
- onMouseLeave: () => dispatch(ACTION_TOKENS.SHOW_HINT_FOR, null)
- });
+export function mapActionBehavior(actionIdProp) {
+ return (dispatch, props) => {
+ const actionId = props[actionIdProp];
+ const actionRunToken = ACTION_TOKENS.actionRun(actionId);
+ return {
+ onClick: data => dispatch(actionRunToken, data),
+ onMouseEnter: ({pageX, pageY}) => dispatch(ACTION_TOKENS.SHOW_HINT_FOR, [actionId, pageX, pageY]),
+ onMouseLeave: () => dispatch(ACTION_TOKENS.SHOW_HINT_FOR, null)
+ }};
}
\ No newline at end of file
diff --git a/web/app/cad/dom/components/PlugableControlBar.jsx b/web/app/cad/dom/components/PlugableControlBar.jsx
index 8839beb5..4ac6fff7 100644
--- a/web/app/cad/dom/components/PlugableControlBar.jsx
+++ b/web/app/cad/dom/components/PlugableControlBar.jsx
@@ -6,6 +6,7 @@ import {TOKENS as UI_TOKENS} from '../uiEntryPointsPlugin';
import {TOKENS as ACTION_TOKENS} from '../../actions/actionSystemPlugin';
import {toIdAndOverrides} from "../../actions/actionRef";
import {mapActionBehavior} from "../../actions/actionButtonBehavior";
+import {DEFAULT_MAPPER} from "../../../../../modules/ui/connect";
export default function PlugableControlBar() {
@@ -15,15 +16,7 @@ export default function PlugableControlBar() {
function ButtonGroup({actions}) {
return actions.map(actionRef => {
let [id, overrides] = toIdAndOverrides(actionRef);
- let Comp = connect(ActionButton,
- [ACTION_TOKENS.actionAppearance(id), ACTION_TOKENS.actionState(id)],
- {
- staticProps: {actionId: id},
- mapProps: ([appearance, state]) => Object.assign({}, appearance, state, overrides),
- mapActions: mapActionBehavior(id)
- }
- );
- return ;
+ return ;
});
}
@@ -56,6 +49,16 @@ const BUTTON_CONNECTOR = {
const LeftGroup = connect(ButtonGroup, UI_TOKENS.CONTROL_BAR_LEFT, BUTTON_CONNECTOR);
const RightGroup = connect(ButtonGroup, UI_TOKENS.CONTROL_BAR_RIGHT, BUTTON_CONNECTOR);
+
+const ConnectedActionButton = connect(ActionButton,
+ props => [ACTION_TOKENS.actionAppearance(props.actionId),
+ ACTION_TOKENS.actionState(props.actionId)],
+ {
+ mapProps: (state, props) => Object.assign(DEFAULT_MAPPER(state), props),
+ mapActions: mapActionBehavior('actionId'),
+ }
+);
+
function getMenuData(el) {
//TODO: make more generic
return {
diff --git a/web/app/cad/dom/menu/MenuHolder.jsx b/web/app/cad/dom/menu/MenuHolder.jsx
index f1e8eaa8..7c6d9824 100644
--- a/web/app/cad/dom/menu/MenuHolder.jsx
+++ b/web/app/cad/dom/menu/MenuHolder.jsx
@@ -6,33 +6,20 @@ import Menu, {MenuItem, MenuSeparator} from "../../../../../modules/ui/component
import Fa from "../../../../../modules/ui/components/Fa";
import Filler from "../../../../../modules/ui/components/Filler";
import {TOKENS as KeyboardTokens} from "../../keyboard/keyboardPlugin";
+import {DEFAULT_MAPPER} from "../../../../../modules/ui/connect";
function MenuHolder({menus}) {
- return menus.map(({id, actions}) => {
- let menuToken = MENU_TOKENS.menuState(id);
- let connectedMenu = connect(ActionMenu, [menuToken, KeyboardTokens.KEYMAP], {
- staticProps: {actions},
- mapProps: [,keymap => ({keymap})]
- });
- return React.createElement(connectedMenu, {key: id});
- });
+ return menus.map(({id, actions}) => );
}
-function ActionMenu({actions, keymap, ...props}) {
- return