diff --git a/imports/plugins/core/checkout/client/components/emptyCartDrawer.js b/imports/plugins/core/checkout/client/components/emptyCartDrawer.js
index a0e87fa4425..e5a70d35e39 100644
--- a/imports/plugins/core/checkout/client/components/emptyCartDrawer.js
+++ b/imports/plugins/core/checkout/client/components/emptyCartDrawer.js
@@ -1,9 +1,18 @@
import React from "react";
import PropTypes from "prop-types";
-import { Button, Translation } from "/imports/plugins/core/ui/client/components";
+import { $ } from "meteor/jquery";
+import { Components, registerComponent } from "@reactioncommerce/reaction-components";
+import { Reaction } from "/client/api";
+function handleKeepShopping(event) {
+ event.stopPropagation();
+ event.preventDefault();
+ return $("#cart-drawer-container").fadeOut(300, function () {
+ return Reaction.toggleSession("displayCart");
+ });
+}
-const EmptyCartDrawer = ({ keepShopping }) => {
+const EmptyCartDrawer = () => {
return (
@@ -12,17 +21,17 @@ const EmptyCartDrawer = ({ keepShopping }) => {
-
+
-
@@ -35,4 +44,6 @@ EmptyCartDrawer.propTypes = {
keepShopping: PropTypes.func
};
+registerComponent("EmptyCartDrawer", EmptyCartDrawer);
+
export default EmptyCartDrawer;
diff --git a/imports/plugins/core/checkout/client/container/cartIconContainer.js b/imports/plugins/core/checkout/client/container/cartIconContainer.js
deleted file mode 100644
index 39bed4dc6c5..00000000000
--- a/imports/plugins/core/checkout/client/container/cartIconContainer.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import React, { Component } from "react";
-import { Cart } from "/lib/collections";
-import { composeWithTracker } from "/lib/api/compose";
-import { Reaction } from "/client/api";
-import CartIcon from "../components/cartIcon";
-
-class CartIconContainer extends Component {
- render() {
- return (
-
-
-
- );
- }
-}
-
-const composer = (props, onData) => {
- const subscription = Reaction.Subscriptions.Cart;
-
- if (subscription.ready()) {
- const cart = Cart.findOne();
-
- onData(null, {
- cart: cart
- });
- }
-};
-
-export default composeWithTracker(composer)(CartIconContainer);
diff --git a/imports/plugins/core/checkout/client/container/emptyCartContainer.js b/imports/plugins/core/checkout/client/container/emptyCartContainer.js
deleted file mode 100644
index 1bfb59bb719..00000000000
--- a/imports/plugins/core/checkout/client/container/emptyCartContainer.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import React, { Component } from "react";
-import { $ } from "meteor/jquery";
-import { Reaction } from "/client/api";
-import EmptyCartDrawer from "../components/emptyCartDrawer";
-
-class EmptyCartContainer extends Component {
- handleKeepShopping(event) {
- event.stopPropagation();
- event.preventDefault();
- return $("#cart-drawer-container").fadeOut(300, function () {
- return Reaction.toggleSession("displayCart");
- });
- }
- render() {
- return (
-
-
-
- );
- }
-}
-
-export default EmptyCartContainer;
diff --git a/imports/plugins/core/checkout/client/container/cartDrawerContainer.js b/imports/plugins/core/checkout/client/containers/cartDrawerContainer.js
similarity index 68%
rename from imports/plugins/core/checkout/client/container/cartDrawerContainer.js
rename to imports/plugins/core/checkout/client/containers/cartDrawerContainer.js
index 3ebc9754e5e..3a2efa7d906 100644
--- a/imports/plugins/core/checkout/client/container/cartDrawerContainer.js
+++ b/imports/plugins/core/checkout/client/containers/cartDrawerContainer.js
@@ -1,34 +1,28 @@
-import React, { Component } from "react";
-import PropTypes from "prop-types";
+import { compose, withProps } from "recompose";
+import { registerComponent, composeWithTracker } from "@reactioncommerce/reaction-components";
import { $ } from "meteor/jquery";
import { Session } from "meteor/session";
import { Meteor } from "meteor/meteor";
import { Cart, Media } from "/lib/collections";
import { Reaction } from "/client/api";
-import { composeWithTracker } from "/lib/api/compose";
-import { Loading } from "/imports/plugins/core/ui/client/components";
import CartDrawer from "../components/cartDrawer";
-class CartDrawerContainer extends Component {
- static propTypes = {
- defaultImage: PropTypes.object,
- lowInventory: PropTypes.bool,
- productItems: PropTypes.array
- }
-
+// event handlers to pass in as props
+const handlers = {
handleImage(item) {
const { defaultImage } = item;
if (defaultImage && defaultImage.url({ store: "small" })) {
return defaultImage;
}
return false;
- }
+ },
+
/**
* showLowInventoryWarning
* @param {Object} productItem - product item object
* @return {Boolean} return true if low inventory on variant
*/
- showItemLowInventoryWarning(productItem) {
+ handleLowInventory(productItem) {
const { variants } = productItem;
if (variants && variants.inventoryPolicy &&
variants.lowInventoryWarningThreshold) {
@@ -36,20 +30,16 @@ class CartDrawerContainer extends Component {
variants.lowInventoryWarningThreshold;
}
return false;
- }
-
- handleLowInventory = (productItem) => {
- return this.showItemLowInventoryWarning(productItem);
- }
+ },
- handleShowProduct = (productItem) => {
+ handleShowProduct(productItem) {
if (productItem) {
Reaction.Router.go("product", {
handle: productItem.productId,
variantId: productItem.variants._id
});
}
- }
+ },
pdpPath(productItem) {
if (productItem) {
@@ -61,7 +51,7 @@ class CartDrawerContainer extends Component {
}
});
}
- }
+ },
handleRemoveItem(event) {
event.stopPropagation();
@@ -70,28 +60,16 @@ class CartDrawerContainer extends Component {
$(`#${currentCartItemId}`).fadeOut(500, () => {
return Meteor.call("cart/removeFromCart", currentCartItemId);
});
- }
+ },
+
handleCheckout() {
$("#cart-drawer-container").fadeOut();
Session.set("displayCart", false);
return Reaction.Router.go("cart/checkout");
}
- render() {
- const { productItems } = this.props;
- return (
-
- );
- }
-}
+};
+// reactive Tracker wrapped function
function composer(props, onData) {
const userId = Meteor.userId();
const shopId = Reaction.getShopId();
@@ -116,4 +94,13 @@ function composer(props, onData) {
});
}
-export default composeWithTracker(composer, Loading)(CartDrawerContainer);
+// register the containers
+registerComponent("CartDrawer", CartDrawer, [
+ withProps(handlers),
+ composeWithTracker(composer)
+]);
+
+export default compose(
+ withProps(handlers),
+ composeWithTracker(composer)
+)(CartDrawer);
diff --git a/imports/plugins/core/checkout/client/containers/cartIconContainer.js b/imports/plugins/core/checkout/client/containers/cartIconContainer.js
new file mode 100644
index 00000000000..c46d8d4c54e
--- /dev/null
+++ b/imports/plugins/core/checkout/client/containers/cartIconContainer.js
@@ -0,0 +1,35 @@
+import Velocity from "velocity-animate";
+import { compose, withProps } from "recompose";
+import { registerComponent, composeWithTracker } from "@reactioncommerce/reaction-components";
+import { Cart } from "/lib/collections";
+import { Reaction } from "/client/api";
+import CartIcon from "../components/cartIcon";
+
+const handlers = {
+ handleClick(e) {
+ e.preventDefault();
+ const cartDrawer = document.querySelector("#cart-drawer-container");
+ Velocity(cartDrawer, { opacity: 1 }, 300, () => {
+ Reaction.toggleSession("displayCart");
+ });
+ }
+};
+
+const composer = (props, onData) => {
+ const subscription = Reaction.Subscriptions.Cart;
+
+ if (subscription.ready()) {
+ const cart = Cart.findOne();
+ onData(null, { cart });
+ }
+};
+
+registerComponent("CartIcon", CartIcon, [
+ withProps(handlers),
+ composeWithTracker(composer)
+]);
+
+export default compose(
+ withProps(handlers),
+ composeWithTracker(composer)
+)(CartIcon);
diff --git a/imports/plugins/core/checkout/client/containers/cartPanelContainer.js b/imports/plugins/core/checkout/client/containers/cartPanelContainer.js
new file mode 100644
index 00000000000..a6b717fdc22
--- /dev/null
+++ b/imports/plugins/core/checkout/client/containers/cartPanelContainer.js
@@ -0,0 +1,18 @@
+import { withProps } from "recompose";
+import { registerComponent } from "@reactioncommerce/reaction-components";
+import { $ } from "meteor/jquery";
+import { Session } from "meteor/session";
+import { Reaction } from "/client/api";
+import CartPanel from "../components/cartPanel";
+
+const handlers = {
+ checkout() {
+ $("#cart-drawer-container").fadeOut();
+ Session.set("displayCart", false);
+ return Reaction.Router.go("cart/checkout");
+ }
+};
+
+registerComponent("CartPanel", CartPanel, withProps(handlers));
+
+export default withProps(handlers)(CartPanel);
diff --git a/imports/plugins/core/checkout/client/container/cartSubTotalContainer.js b/imports/plugins/core/checkout/client/containers/cartSubTotalContainer.js
similarity index 51%
rename from imports/plugins/core/checkout/client/container/cartSubTotalContainer.js
rename to imports/plugins/core/checkout/client/containers/cartSubTotalContainer.js
index 8e694cf207f..16ba9bc3eb3 100644
--- a/imports/plugins/core/checkout/client/container/cartSubTotalContainer.js
+++ b/imports/plugins/core/checkout/client/containers/cartSubTotalContainer.js
@@ -1,19 +1,7 @@
-import React, { Component } from "react";
+import { registerComponent, composeWithTracker } from "@reactioncommerce/reaction-components";
import { Cart } from "/lib/collections";
-import { composeWithTracker } from "/lib/api/compose";
-import { Loading } from "/imports/plugins/core/ui/client/components";
import CartSubTotal from "../components/cartSubTotal";
-class CartSubTotalContainer extends Component {
- render() {
- return (
-
- );
- }
-}
-
function composer(props, onData) {
const cart = Cart.findOne();
if (cart) {
@@ -25,9 +13,9 @@ function composer(props, onData) {
cartTaxes: cart.cartTaxes(),
cartTotal: cart.cartTotal()
});
- } else {
- onData(null, {});
}
}
-export default composeWithTracker(composer, Loading)(CartSubTotalContainer);
+registerComponent("CartSubTotal", CartSubTotal, composeWithTracker(composer));
+
+export default composeWithTracker(composer)(CartSubTotal);
diff --git a/imports/plugins/core/checkout/client/index.js b/imports/plugins/core/checkout/client/index.js
index 788200366b5..d851c168016 100644
--- a/imports/plugins/core/checkout/client/index.js
+++ b/imports/plugins/core/checkout/client/index.js
@@ -19,3 +19,15 @@ import "./templates/checkout/review/review.html";
import "./templates/checkout/review/review.js";
import "./templates/checkout/checkout.html";
import "./templates/checkout/checkout.js";
+
+export { default as CartDrawer } from "./components/cartDrawer";
+export { default as CartIcon } from "./components/cartIcon";
+export { default as CartItems } from "./components/cartItems";
+export { default as CartPanel } from "./components/cartPanel";
+export { default as CartSubTotal } from "./components/cartSubTotal";
+export { default as EmptyCartDrawer } from "./components/emptyCartDrawer";
+
+export { default as CartDrawerContainer } from "./containers/cartDrawerContainer";
+export { default as CartIconContainer } from "./containers/cartIconContainer";
+export { default as CartPanelContainer } from "./containers/cartPanelContainer";
+export { default as CartSubTotalContainer } from "./containers/cartSubTotalContainer";
diff --git a/imports/plugins/core/checkout/client/templates/cartDrawer/cartDrawer.html b/imports/plugins/core/checkout/client/templates/cartDrawer/cartDrawer.html
index 94bf474624d..6e4d9af34ed 100644
--- a/imports/plugins/core/checkout/client/templates/cartDrawer/cartDrawer.html
+++ b/imports/plugins/core/checkout/client/templates/cartDrawer/cartDrawer.html
@@ -1,7 +1,7 @@
-
-{{> displayCartDrawer}}
-
+
+ {{> displayCartDrawer}}
+
@@ -9,12 +9,11 @@
{{> React component=EmptyCartDrawer}}
-
-
- {{> React component=CartDrawerContainer}}
-
+
+ {{> React component=CartDrawerContainer}}
+
diff --git a/imports/plugins/core/checkout/client/templates/cartDrawer/cartDrawer.js b/imports/plugins/core/checkout/client/templates/cartDrawer/cartDrawer.js
index 2fffad7bc97..16741a4cafd 100644
--- a/imports/plugins/core/checkout/client/templates/cartDrawer/cartDrawer.js
+++ b/imports/plugins/core/checkout/client/templates/cartDrawer/cartDrawer.js
@@ -1,10 +1,10 @@
+import Swiper from "swiper";
+import { Components } from "@reactioncommerce/reaction-components";
import { $ } from "meteor/jquery";
import { Cart } from "/lib/collections";
import { Session } from "meteor/session";
import { Template } from "meteor/templating";
-import Swiper from "swiper";
-import CartDrawerContainer from "../../container/cartDrawerContainer";
-import EmptyCartDrawer from "../../container/emptyCartContainer";
+
/**
* cartDrawer helpers
*
@@ -66,7 +66,7 @@ Template.openCartDrawer.onRendered(function () {
Template.openCartDrawer.helpers({
CartDrawerContainer() {
- return CartDrawerContainer;
+ return Components.CartDrawer;
}
});
@@ -76,6 +76,6 @@ Template.emptyCartDrawer.onRendered(function () {
Template.emptyCartDrawer.helpers({
EmptyCartDrawer() {
- return EmptyCartDrawer;
+ return Components.EmptyCartDrawer;
}
});
diff --git a/imports/plugins/core/checkout/client/templates/cartPanel/component/cartPanel.js b/imports/plugins/core/checkout/client/templates/cartPanel/component/cartPanel.js
deleted file mode 100644
index ae994452463..00000000000
--- a/imports/plugins/core/checkout/client/templates/cartPanel/component/cartPanel.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import React, { Component } from "react";
-import PropTypes from "prop-types";
-import { Button } from "/imports/plugins/core/ui/client/components";
-
-class CartPanel extends Component {
- render() {
- return (
-
- );
- }
-}
-
-CartPanel.propTypes = {
- checkout: PropTypes.func,
- onClick: PropTypes.func
-};
-
-export default CartPanel;
diff --git a/imports/plugins/core/checkout/client/templates/cartPanel/container/cartPanelContainer.js b/imports/plugins/core/checkout/client/templates/cartPanel/container/cartPanelContainer.js
deleted file mode 100644
index 5e4d16001b3..00000000000
--- a/imports/plugins/core/checkout/client/templates/cartPanel/container/cartPanelContainer.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import React, { Component } from "react";
-import { $ } from "meteor/jquery";
-import { Session } from "meteor/session";
-import { Reaction } from "/client/api";
-import CartPanel from "../component/cartPanel";
-
-class CartPanelContainer extends Component {
- handleCheckout() {
- $("#cart-drawer-container").fadeOut();
- Session.set("displayCart", false);
- return Reaction.Router.go("cart/checkout");
- }
- render() {
- return (
-
- );
- }
-}
-
-export default CartPanelContainer;
diff --git a/imports/plugins/core/checkout/client/templates/checkout/review/review.js b/imports/plugins/core/checkout/client/templates/checkout/review/review.js
index fb832cececa..4de20aa386f 100644
--- a/imports/plugins/core/checkout/client/templates/checkout/review/review.js
+++ b/imports/plugins/core/checkout/client/templates/checkout/review/review.js
@@ -1,7 +1,7 @@
import "./review.html";
import { Meteor } from "meteor/meteor";
import { Template } from "meteor/templating";
-import CartSubTotals from "../../../container/cartSubTotalContainer";
+import CartSubTotals from "../../../containers/cartSubTotalContainer";
/**
* review status
diff --git a/imports/plugins/core/components/lib/components.js b/imports/plugins/core/components/lib/components.js
new file mode 100644
index 00000000000..3a0b6c22b97
--- /dev/null
+++ b/imports/plugins/core/components/lib/components.js
@@ -0,0 +1,156 @@
+import { compose, setDisplayName } from "recompose";
+
+
+export const Components = {}; // populated with final wrapped components
+export const ComponentsTable = {}; // storage for separate elements of each component
+
+
+/**
+ * Register a component and container(s) with a name.
+ * The raw component can then be extended or replaced.
+ *
+ * Structure of a component in the list:
+ *
+ * ComponentsTable.MyComponent = {
+ * name: 'MyComponent',
+ * hocs: [fn1, fn2],
+ * rawComponent: React.Component
+ * }
+ *
+ * @param {String} name The name of the component to register.
+ * @param {React.Component} rawComponent Interchangeable/extendable component.
+ * @param {Function|[Function]} hocs The HOCs to wrap around the raw component.
+ *
+ * @returns {React.Component} returns the final wrapped component
+ */
+export function registerComponent(name, rawComponent, hocs = []) {
+ if (!name || !rawComponent) {
+ throw new Error("A name and component are required for registerComponent");
+ }
+
+ // store the component in the table
+ ComponentsTable[name] = {
+ name,
+ rawComponent,
+ hocs: Array.isArray(hocs) ? hocs : [hocs]
+ };
+}
+
+
+/**
+ * Register containers (HOC) with a name.
+ * If some containers already exist for the component, they will be extended.
+ * @param {String} name The name of the component to register.
+ * @param {Function|[Function]} hocs The HOCs to wrap around the raw component.
+ *
+ * @returns {undefined}
+ */
+export function registerHOC(name, hocs = []) {
+ if (!name || !hocs) {
+ throw new Error("A name and HOC(s) are required for registerHOC");
+ }
+
+ const newHOCs = Array.isArray(hocs) ? hocs : [hocs];
+
+ const existingComponent = ComponentsTable[name];
+
+ // Check to see if this component has already been registered and whether it has
+ // HOC's to merge with our new ones. If not, just register it like a new component.
+ // This allows us to register HOCs _before_ registering the UI component.
+ // Just keep in mind that the resulting component will definitely throw an error
+ // if a UI component doesn't eventually get registered.
+ if (!!existingComponent && !!existingComponent.hocs) {
+ const existingHOCs = existingComponent.hocs;
+
+ ComponentsTable[name] = {
+ name,
+ hocs: [...newHOCs, ...existingHOCs]
+ };
+ } else {
+ ComponentsTable[name] = {
+ name,
+ hocs: newHOCs
+ };
+ }
+}
+
+
+/**
+ * Get a component registered with registerComponent(name, component, ...hocs).
+ * @param {String} name The name of the component to get.
+ * @return {Function|React.Component} A (wrapped) React component
+ */
+export function getComponent(name) {
+ const component = ComponentsTable[name];
+
+ if (!component) {
+ throw new Error(`Component ${name} not registered.`);
+ }
+
+ const hocs = component.hocs.map((hoc) => Array.isArray(hoc) ? hoc[0](hoc[1]) : hoc);
+
+ return compose(...hocs, setDisplayName(`Reaction(${name})`))(component.rawComponent);
+}
+
+
+/**
+ * Replace a Reaction component with a new component and optionally add one or more higher order components.
+ * This function keeps track of the previous HOCs and wraps the new HOCs around previous ones
+ * @param {String} name The name of the component to register.
+ * @param {React.Component} newComponent Interchangeable/extendable component.
+ * @param {Function|[Function]} hocs The HOCs to compose with the raw component.
+ * @returns {Function|React.Component} A component callable with Components[name]
+ */
+export function replaceComponent(name, newComponent, hocs = []) {
+ const previousComponent = ComponentsTable[name];
+
+ if (!previousComponent) {
+ throw new Error(`Component '${name}' not found. Use registerComponent to create it.`);
+ }
+
+ const newHocs = Array.isArray(hocs) ? hocs : [hocs];
+
+ return registerComponent(name, newComponent, [...newHocs, ...previousComponent.hocs]);
+}
+
+
+/**
+ * Get the raw UI component without any possible HOCs wrapping it.
+ * @param {String} name The name of the component to get.
+ * @returns {Function|React.Component} A React component
+ */
+export const getRawComponent = (name) => ComponentsTable[name].rawComponent;
+
+
+/**
+ * Get the raw UI component without any possible HOCs wrapping it.
+ * @param {String} name The name of the component to get.
+ * @returns {Function|React.Component} Array of HOCs
+ */
+export const getHOCs = (name) => ComponentsTable[name].hocs;
+
+
+/**
+ * Wrap a new component with the HOCs from a different component
+ * @param {String} sourceComponentName The name of the component to get the HOCs from
+ * @param {Function|React.Component} targetComponent Component to wrap
+ * @returns {Function|React.Component} A new component wrapped with the HOCs of the source component
+ */
+export function copyHOCs(sourceComponentName, targetComponent) {
+ const sourceComponent = ComponentsTable[sourceComponentName];
+ return compose(...sourceComponent.hocs)(targetComponent);
+}
+
+
+/**
+ * Populate the final Components object with the contents of the lookup table.
+ * This should only be called once on app startup.
+ * @returns {Object} An object containing all of the registered components
+ **/
+export function loadRegisteredComponents() {
+ Object.keys(ComponentsTable).map((name) => {
+ Components[name] = getComponent(name);
+ });
+
+ return Components;
+}
diff --git a/imports/plugins/core/components/lib/composer/compose.js b/imports/plugins/core/components/lib/composer/compose.js
new file mode 100644
index 00000000000..90925f765c0
--- /dev/null
+++ b/imports/plugins/core/components/lib/composer/compose.js
@@ -0,0 +1,143 @@
+import React from "react";
+import shallowEqual from "shallowequal";
+import hoistStatics from "hoist-non-react-statics";
+import _ from "lodash";
+import { getDisplayName } from "recompose";
+
+export default function compose(dataLoader, options = {}) {
+ return function (Child) {
+ const {
+ errorHandler = (err) => { throw err; },
+ loadingHandler = () => null,
+ env = {},
+ pure = false,
+ propsToWatch = null, // Watch all the props.
+ shouldSubscribe = null,
+ shouldUpdate = null
+ } = options;
+
+ class Container extends React.Component {
+ constructor(props, ...args) {
+ super(props, ...args);
+ this.state = {};
+ this.propsCache = {};
+
+ this._subscribe(props);
+ }
+
+ componentDidMount() {
+ this._mounted = true;
+ }
+
+ componentWillReceiveProps(props) {
+ this._subscribe(props);
+ }
+
+ shouldComponentUpdate(nextProps, nextState) {
+ if (shouldUpdate) {
+ return shouldUpdate(this.props, nextProps);
+ }
+
+ if (!pure) {
+ return true;
+ }
+
+ return (
+ !shallowEqual(this.props, nextProps) ||
+ this.state.error !== nextState.error ||
+ !shallowEqual(this.state.data, nextState.data)
+ );
+ }
+
+ componentWillUnmount() {
+ this._unmounted = true;
+ this._unsubscribe();
+ }
+
+ _shouldSubscribe(props) {
+ const firstRun = !this._cachedWatchingProps;
+ const nextProps = _.pick(props, propsToWatch);
+ const currentProps = this._cachedWatchingProps || {};
+ this._cachedWatchingProps = nextProps;
+
+ if (firstRun) return true;
+ if (typeof shouldSubscribe === "function") {
+ return shouldSubscribe(currentProps, nextProps);
+ }
+
+ if (propsToWatch === null) return true;
+ if (propsToWatch.length === 0) return false;
+ return !shallowEqual(currentProps, nextProps);
+ }
+
+ _subscribe(props) {
+ if (!this._shouldSubscribe(props)) return;
+
+ const onData = (error, data) => {
+ if (this._unmounted) {
+ throw new Error(`Trying to set data after component(${Container.displayName}) has unmounted.`);
+ }
+
+ const payload = { error, data };
+
+ if (!this._mounted) {
+ this.state = {
+ ...this.state,
+ ...payload
+ };
+ return;
+ }
+
+ this.setState(payload);
+ };
+
+ // We need to do this before subscribing again.
+ this._unsubscribe();
+ this._stop = dataLoader(props, onData, env);
+ }
+
+ _unsubscribe() {
+ if (this._stop) {
+ this._stop();
+ }
+ }
+
+ render() {
+ const props = this.props;
+ const { data, error } = this.state;
+
+ if (error) {
+ return errorHandler(error);
+ }
+
+ if (!data) {
+ return loadingHandler();
+ }
+
+ const finalProps = {
+ ...props,
+ ...data
+ };
+
+ const setChildRef = (c) => {
+ this.child = c;
+ };
+
+ return (
+
+ );
+ }
+ }
+
+ Container.__composerData = {
+ dataLoader,
+ options
+ };
+
+ Container.displayName = `Tracker(${getDisplayName(Child)})`;
+
+ hoistStatics(Container, Child);
+
+ return Container;
+ };
+}
diff --git a/imports/plugins/core/components/lib/composer/index.js b/imports/plugins/core/components/lib/composer/index.js
new file mode 100644
index 00000000000..cb742ac787e
--- /dev/null
+++ b/imports/plugins/core/components/lib/composer/index.js
@@ -0,0 +1,2 @@
+export { default as compose } from "./compose";
+export * from "./tracker";
diff --git a/imports/plugins/core/components/lib/composer/tracker.js b/imports/plugins/core/components/lib/composer/tracker.js
new file mode 100644
index 00000000000..ba890ef8e83
--- /dev/null
+++ b/imports/plugins/core/components/lib/composer/tracker.js
@@ -0,0 +1,56 @@
+import React from "react";
+import { Tracker } from "meteor/tracker";
+import { Components } from "../components";
+import compose from "./compose";
+
+
+/**
+ * getTrackerLoader creates a Meteor Tracker to watch dep updates from
+ * the passed in reactiveMapper function
+ * @param {Function} reactiveMapper data fetching function to bind to a tracker
+ * @return {Function} composed function
+ */
+function getTrackerLoader(reactiveMapper) {
+ return (props, onData, env) => {
+ let trackerCleanup = null;
+ const handler = Tracker.nonreactive(() => {
+ return Tracker.autorun(() => {
+ // assign the custom clean-up function.
+ trackerCleanup = reactiveMapper(props, onData, env);
+ });
+ });
+
+ return () => {
+ if (typeof trackerCleanup === "function") trackerCleanup();
+ return handler.stop();
+ };
+ };
+}
+
+
+/**
+ * A higher order component to wrap a reactive function with Meteor's Tracker
+ * @param {Function} reactiveMapper data fetching function to bind to a tracker
+ * @param {React.Component|Boolean|Object} options can be a custom loader, false (to disable), or a full options object
+ * @return {Function} composed function
+ */
+export function composeWithTracker(reactiveMapper, options) {
+ let composeOptions = {};
+
+ if (typeof options === "undefined") {
+ // eslint-disable-next-line react/display-name
+ composeOptions.loadingHandler = () =>
;
+ }
+
+ if (typeof options === "function") {
+ const CustomLoader = options;
+ // eslint-disable-next-line
+ composeOptions.loadingHandler = () =>
;
+ }
+
+ if (typeof options === "object") {
+ composeOptions = options;
+ }
+
+ return compose(getTrackerLoader(reactiveMapper), composeOptions);
+}
diff --git a/imports/plugins/core/components/lib/hoc.js b/imports/plugins/core/components/lib/hoc.js
new file mode 100644
index 00000000000..77161c7669e
--- /dev/null
+++ b/imports/plugins/core/components/lib/hoc.js
@@ -0,0 +1,77 @@
+import { composeWithTracker } from "./composer";
+import { Meteor } from "meteor/meteor";
+import { Roles } from "meteor/alanning:roles";
+import { Accounts } from "/lib/collections";
+
+let Reaction;
+
+if (Meteor.isClient) {
+ Reaction = require("/client/api").Reaction;
+} else {
+ Reaction = require("/server/api").Reaction;
+}
+
+
+/**
+ * A wrapper to reactively inject the current user into a component
+ * @param {Function|React.Component} component - the component to wrap
+ * @return {Function} the new wrapped component with a "currentUser" prop
+ */
+export function withCurrentUser(component) {
+ return composeWithTracker((props, onData) => {
+ onData(null, { currentUser: Meteor.user() });
+ })(component);
+}
+
+
+/**
+ * A wrapper to reactively inject the current account into a component.
+ * This assumes you have signed up and are not an anonymous user.
+ * @param {Function|React.Component} component - the component to wrap
+ * @return {Function} the new wrapped component with a "currentAccount" prop
+ */
+export function withCurrentAccount(component) {
+ return composeWithTracker((props, onData) => {
+ const shopId = Reaction.getShopId();
+ const user = Meteor.user();
+
+ if (!shopId || !user) {
+ return null;
+ }
+
+ // shoppers should always be guests
+ const isGuest = Roles.userIsInRole(user, "guest", shopId);
+ // but if a user has never logged in then they are anonymous
+ const isAnonymous = Roles.userIsInRole(user, "anonymous", shopId);
+
+ const account = Accounts.findOne(user._id);
+
+ onData(null, { currentAccount: isGuest && !isAnonymous && account });
+ })(component);
+}
+
+
+/**
+ * A wrapper to reactively inject the current user's admin status.
+ * Sets a boolean 'isAdmin' prop on the wrapped component.
+ * @param {Function|React.Component} component - the component to wrap
+ * @return {Function} the new wrapped component with an "isAdmin" prop
+ */
+export function withIsAdmin(component) {
+ return composeWithTracker((props, onData) => {
+ onData(null, { isAdmin: Reaction.hasAdminAccess() });
+ })(component);
+}
+
+
+/**
+ * A wrapper to reactively inject the current user's owner status.
+ * Sets a boolean 'isOwner' prop on the wrapped component.
+ * @param {Function|React.Component} component - the component to wrap
+ * @return {Function} the new wrapped component with an "isOwner" prop
+ */
+export function withIsOwner(component) {
+ return composeWithTracker((props, onData) => {
+ onData(null, { isOwner: Reaction.hasOwnerAccess() });
+ })(component);
+}
diff --git a/imports/plugins/core/components/lib/index.js b/imports/plugins/core/components/lib/index.js
new file mode 100644
index 00000000000..604b36276ad
--- /dev/null
+++ b/imports/plugins/core/components/lib/index.js
@@ -0,0 +1,3 @@
+export { composeWithTracker } from "./composer";
+export * from "./components";
+export * from "./hoc";
diff --git a/imports/plugins/core/dashboard/client/containers/actionViewContainer.js b/imports/plugins/core/dashboard/client/containers/actionViewContainer.js
index 607a31d523a..7a27cb1e188 100644
--- a/imports/plugins/core/dashboard/client/containers/actionViewContainer.js
+++ b/imports/plugins/core/dashboard/client/containers/actionViewContainer.js
@@ -1,10 +1,9 @@
import React from "react";
import { StyleRoot } from "radium";
import _ from "lodash";
-import { composeWithTracker } from "/lib/api/compose";
+import { composeWithTracker } from "@reactioncommerce/reaction-components";
import { Reaction } from "/client/api";
import { TranslationProvider, AdminContextProvider } from "/imports/plugins/core/ui/client/providers";
-import { Loading } from "/imports/plugins/core/ui/client/components";
function handleActionViewBack() {
@@ -86,5 +85,5 @@ export default function ActionViewContainer(Comp) {
);
}
- return composeWithTracker(composer, Loading)(CompositeComponent);
+ return composeWithTracker(composer)(CompositeComponent);
}
diff --git a/imports/plugins/core/dashboard/client/containers/packageListContainer.js b/imports/plugins/core/dashboard/client/containers/packageListContainer.js
index ffe4975484d..9fef3207dc7 100644
--- a/imports/plugins/core/dashboard/client/containers/packageListContainer.js
+++ b/imports/plugins/core/dashboard/client/containers/packageListContainer.js
@@ -1,10 +1,9 @@
import React from "react";
+import { composeWithTracker } from "@reactioncommerce/reaction-components";
import { Meteor } from "meteor/meteor";
import { Template } from "meteor/templating";
import { Roles } from "meteor/alanning:roles";
-import { composeWithTracker } from "/lib/api/compose";
import { Reaction } from "/client/api";
-import { Loading } from "/imports/plugins/core/ui/client/components";
import { TranslationProvider } from "/imports/plugins/core/ui/client/providers";
/**
@@ -78,5 +77,5 @@ export default function PackageListContainer(Comp) {
);
}
- return composeWithTracker(composer, Loading)(CompositeComponent);
+ return composeWithTracker(composer)(CompositeComponent);
}
diff --git a/imports/plugins/core/dashboard/client/containers/toolbarContainer.js b/imports/plugins/core/dashboard/client/containers/toolbarContainer.js
index 196b42055b2..640b755e88c 100644
--- a/imports/plugins/core/dashboard/client/containers/toolbarContainer.js
+++ b/imports/plugins/core/dashboard/client/containers/toolbarContainer.js
@@ -1,7 +1,7 @@
import React from "react";
import { Meteor } from "meteor/meteor";
import { Session } from "meteor/session";
-import { composeWithTracker } from "/lib/api/compose";
+import { composeWithTracker } from "@reactioncommerce/reaction-components";
import { Reaction, i18next } from "/client/api";
import { Tags } from "/lib/collections";
import { TranslationProvider, AdminContextProvider } from "/imports/plugins/core/ui/client/providers";
@@ -108,5 +108,5 @@ export default function ToolbarContainer(Comp) {
);
}
- return composeWithTracker(composer, null)(CompositeComponent);
+ return composeWithTracker(composer)(CompositeComponent);
}
diff --git a/imports/plugins/core/discounts/client/components/list.js b/imports/plugins/core/discounts/client/components/list.js
index 5b4b830bad5..68af525e189 100644
--- a/imports/plugins/core/discounts/client/components/list.js
+++ b/imports/plugins/core/discounts/client/components/list.js
@@ -3,7 +3,7 @@ import PropTypes from "prop-types";
import { Meteor } from "meteor/meteor";
import { Translation, IconButton } from "/imports/plugins/core/ui/client/components";
import DiscountForm from "./form";
-import { composeWithTracker } from "/lib/api/compose";
+import { composeWithTracker } from "@reactioncommerce/reaction-components";
import { Reaction } from "/client/api";
class DiscountList extends Component {
diff --git a/imports/plugins/core/email/client/actions/index.js b/imports/plugins/core/email/client/actions/index.js
index b73f2e27c01..fd818eab033 100644
--- a/imports/plugins/core/email/client/actions/index.js
+++ b/imports/plugins/core/email/client/actions/index.js
@@ -1,2 +1 @@
-export { default as logs } from "./logs";
export { default as settings } from "./settings";
diff --git a/imports/plugins/core/email/client/actions/logs.js b/imports/plugins/core/email/client/actions/logs.js
deleted file mode 100644
index 0e47f19ea54..00000000000
--- a/imports/plugins/core/email/client/actions/logs.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import { Meteor } from "meteor/meteor";
-import { i18next } from "/client/api";
-
-export default {
- /**
- * Restart a failed or cancelled email job
- * @param {Object} email - the email job object
- * @return {null} triggers an alert
- */
- resend(email) {
- Meteor.call("emails/retryFailed", email._id, (err) => {
- if (err) {
- return Alerts.toast(i18next.t("app.error", { error: err.reason }), "error");
- }
- return Alerts.toast(i18next.t("mail.alerts.resendSuccess", { email: email.data.to }), "success");
- });
- }
-};
diff --git a/imports/plugins/core/email/client/components/emailConfig.js b/imports/plugins/core/email/client/components/emailConfig.js
index b6bb2999caf..48247ed7ede 100644
--- a/imports/plugins/core/email/client/components/emailConfig.js
+++ b/imports/plugins/core/email/client/components/emailConfig.js
@@ -1,8 +1,7 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
-import { Card, CardHeader, CardBody, CardGroup, Icon, Translation } from "/imports/plugins/core/ui/client/components";
-import EmailSettings from "../containers/emailSettings";
-
+import { Components } from "@reactioncommerce/reaction-components";
+import { Translation } from "/imports/plugins/core/ui/client/components";
class EmailConfig extends Component {
constructor(props) {
@@ -40,7 +39,7 @@ class EmailConfig extends Component {
return (
: {status ?
@@ -92,7 +91,7 @@ class EmailConfig extends Component {
i18nKey={"admin.settings.editSettings"}
/>
-
+
);
}
@@ -102,21 +101,19 @@ class EmailConfig extends Component {
render() {
return (
-
-
-
+
+
-
+
{this.renderSettingsDisplay()}
{this.renderSettingsUpdate()}
-
-
-
+
+
+
);
}
}
diff --git a/imports/plugins/core/email/client/components/emailLogs.js b/imports/plugins/core/email/client/components/emailLogs.js
index 0476c7ac7ac..cea2ce77811 100644
--- a/imports/plugins/core/email/client/components/emailLogs.js
+++ b/imports/plugins/core/email/client/components/emailLogs.js
@@ -1,7 +1,7 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
-import { Card, CardHeader, CardBody, CardGroup, Loading, SortableTable } from "/imports/plugins/core/ui/client/components";
-import EmailTableColumn from "./emailTableColumn";
+import { Components } from "@reactioncommerce/reaction-components";
+import { SortableTable } from "/imports/plugins/core/ui/client/components";
import { Jobs } from "/lib/collections";
import { i18next } from "/client/api";
@@ -35,8 +35,8 @@ class EmailLogs extends Component {
const columnMeta = {
accessor: field,
Header: i18next.t(`admin.logs.headers.${field}`),
- Cell: row => (
-
+ Cell: (row) => (
+
),
className: colClassName,
width: colWidth,
@@ -56,27 +56,27 @@ class EmailLogs extends Component {
filteredFields={filteredFields}
noDataMessage={noDataMessage}
columnMetadata={customColumnMetadata}
- externalLoadingComponent={Loading}
+ externalLoadingComponent={Components.Loading}
/>
);
}
render() {
return (
-
-
+
-
-
+
{this.renderEmailsTable()}
-
-
-
+
+
+
);
}
}
diff --git a/imports/plugins/core/email/client/components/emailSettings.js b/imports/plugins/core/email/client/components/emailSettings.js
index 01328d280e2..ea7a8a78797 100644
--- a/imports/plugins/core/email/client/components/emailSettings.js
+++ b/imports/plugins/core/email/client/components/emailSettings.js
@@ -1,6 +1,6 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
-import { Button, Select, TextField } from "/imports/plugins/core/ui/client/components";
+import { Components } from "@reactioncommerce/reaction-components";
class EmailSettings extends Component {
constructor(props) {
@@ -48,7 +48,7 @@ class EmailSettings extends Component {
return (
);
}
diff --git a/imports/plugins/core/email/client/components/emailTableColumn.js b/imports/plugins/core/email/client/components/emailTableColumn.js
index 5f2ffb0233e..a29fa96c9fe 100644
--- a/imports/plugins/core/email/client/components/emailTableColumn.js
+++ b/imports/plugins/core/email/client/components/emailTableColumn.js
@@ -2,7 +2,7 @@ import React, { Component } from "react";
import PropTypes from "prop-types";
import { Meteor } from "meteor/meteor";
import moment from "moment";
-import { Icon } from "/imports/plugins/core/ui/client/components";
+import { Components, registerComponent } from "@reactioncommerce/reaction-components";
import { i18next } from "/client/api";
class EmailTableColumn extends Component {
@@ -34,18 +34,18 @@ class EmailTableColumn extends Component {
if (row.value === "completed") {
return (
-
+
-
+
);
}
return (
-
+
-
+
);
@@ -62,4 +62,6 @@ class EmailTableColumn extends Component {
}
}
+registerComponent("EmailTableColumn", EmailTableColumn);
+
export default EmailTableColumn;
diff --git a/imports/plugins/core/email/client/containers/emailConfig.js b/imports/plugins/core/email/client/containers/emailConfig.js
index 651e136006e..7fffb625e59 100644
--- a/imports/plugins/core/email/client/containers/emailConfig.js
+++ b/imports/plugins/core/email/client/containers/emailConfig.js
@@ -1,60 +1,61 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
-import { useDeps } from "react-simple-di";
+import { compose, withProps } from "recompose";
import getServiceConfig from "nodemailer-wellknown";
+import { registerComponent, composeWithTracker } from "@reactioncommerce/reaction-components";
import { Meteor } from "meteor/meteor";
import { Reaction } from "/client/api";
-import { Loading } from "/imports/plugins/core/ui/client/components";
import actions from "../actions";
import EmailConfig from "../components/emailConfig";
-import { composeWithTracker, merge } from "/lib/api/compose";
-class EmailConfigContainer extends Component {
- constructor(props) {
- super(props);
+const wrapComponent = (Comp) => (
+ class EmailConfigContainer extends Component {
+ static propTypes = {
+ settings: PropTypes.shape({
+ host: PropTypes.string,
+ password: PropTypes.string,
+ port: PropTypes.oneOfType([
+ PropTypes.number,
+ PropTypes.string
+ ]),
+ service: PropTypes.string,
+ user: PropTypes.string
+ })
+ }
- this.state = {
- status: null,
- error: null
- };
- }
+ constructor(props) {
+ super(props);
- componentWillMount() {
- const { settings } = this.props;
- const { service, host, port, user, password } = settings;
+ this.state = {
+ status: null,
+ error: null
+ };
+ }
- if (service && host && port && user && password) {
- Meteor.call("email/verifySettings", (error) => {
- if (error) {
- this.setState({ status: "error" });
- }
- this.setState({ status: "valid" });
- });
- } else {
- this.setState({ status: "error" });
+ componentWillMount() {
+ const { settings } = this.props;
+ const { service, host, port, user, password } = settings;
+
+ if (service && host && port && user && password) {
+ Meteor.call("email/verifySettings", (error) => {
+ if (error) {
+ this.setState({ status: "error" });
+ }
+ this.setState({ status: "valid" });
+ });
+ } else {
+ this.setState({ status: "error" });
+ }
}
- }
- render() {
- const { status } = this.state;
- return (
-
- );
+ render() {
+ const { status } = this.state;
+ return (
+
+ );
+ }
}
-}
-
-EmailConfigContainer.propTypes = {
- settings: PropTypes.shape({
- host: PropTypes.string,
- password: PropTypes.string,
- port: PropTypes.oneOfType([
- PropTypes.number,
- PropTypes.string
- ]),
- service: PropTypes.string,
- user: PropTypes.string
- })
-};
+);
const composer = ({}, onData) => {
if (Meteor.subscribe("Packages").ready()) {
@@ -72,11 +73,16 @@ const composer = ({}, onData) => {
}
};
-const depsMapper = () => ({
- toggleSettings: actions.settings.toggleSettings
-});
+const handlers = { saveSettings: actions.settings.saveSettings };
+
+registerComponent("EmailConfig", EmailConfig, [
+ composeWithTracker(composer),
+ withProps(handlers),
+ wrapComponent
+]);
-export default merge(
- composeWithTracker(composer, Loading),
- useDeps(depsMapper)
-)(EmailConfigContainer);
+export default compose(
+ composeWithTracker(composer),
+ withProps(handlers),
+ wrapComponent
+)(EmailConfig);
diff --git a/imports/plugins/core/email/client/containers/emailLogs.js b/imports/plugins/core/email/client/containers/emailLogs.js
index 957e64bb431..bcdc30011dd 100644
--- a/imports/plugins/core/email/client/containers/emailLogs.js
+++ b/imports/plugins/core/email/client/containers/emailLogs.js
@@ -1,10 +1,9 @@
-import { useDeps } from "react-simple-di";
+import { compose, withProps } from "recompose";
+import { registerComponent, composeWithTracker } from "@reactioncommerce/reaction-components";
import { Meteor } from "meteor/meteor";
-import actions from "../actions";
+import { i18next } from "/client/api";
import EmailLogs from "../components/emailLogs";
-import { Loading } from "/imports/plugins/core/ui/client/components";
import { Jobs } from "/lib/collections";
-import { composeWithTracker, merge } from "/lib/api/compose";
const composer = ({}, onData) => {
if (Meteor.subscribe("Emails").ready()) {
@@ -13,11 +12,28 @@ const composer = ({}, onData) => {
}
};
-const depsMapper = () => ({
- resend: actions.logs.resend
-});
+const handlers = {
+ /**
+ * Restart a failed or cancelled email job
+ * @param {Object} email - the email job object
+ * @return {null} triggers an alert
+ */
+ resend(email) {
+ Meteor.call("emails/retryFailed", email._id, (err) => {
+ if (err) {
+ return Alerts.toast(i18next.t("app.error", { error: err.reason }), "error");
+ }
+ return Alerts.toast(i18next.t("mail.alerts.resendSuccess", { email: email.data.to }), "success");
+ });
+ }
+};
+
+registerComponent("EmailLogs", EmailLogs, [
+ composeWithTracker(composer),
+ withProps(handlers)
+]);
-export default merge(
- composeWithTracker(composer, Loading),
- useDeps(depsMapper)
+export default compose(
+ composeWithTracker(composer),
+ withProps(handlers)
)(EmailLogs);
diff --git a/imports/plugins/core/email/client/containers/emailSettings.js b/imports/plugins/core/email/client/containers/emailSettings.js
index 3b09405ef61..d2f2c00b2ae 100644
--- a/imports/plugins/core/email/client/containers/emailSettings.js
+++ b/imports/plugins/core/email/client/containers/emailSettings.js
@@ -1,10 +1,9 @@
-import { useDeps } from "react-simple-di";
+import { compose, withProps } from "recompose";
+import { registerComponent, composeWithTracker } from "@reactioncommerce/reaction-components";
import { Meteor } from "meteor/meteor";
import { Reaction } from "/client/api";
-import { Loading } from "/imports/plugins/core/ui/client/components";
import actions from "../actions";
import EmailSettings from "../components/emailSettings";
-import { composeWithTracker, merge } from "/lib/api/compose";
const providers = Object.keys(require("nodemailer-wellknown/services.json"));
@@ -22,11 +21,14 @@ const composer = ({}, onData) => {
}
};
-const depsMapper = () => ({
- saveSettings: actions.settings.saveSettings
-});
+const handlers = { saveSettings: actions.settings.saveSettings };
-export default merge(
- composeWithTracker(composer, Loading),
- useDeps(depsMapper)
+registerComponent("EmailSettings", EmailSettings, [
+ composeWithTracker(composer),
+ withProps(handlers)
+]);
+
+export default compose(
+ composeWithTracker(composer),
+ withProps(handlers)
)(EmailSettings);
diff --git a/imports/plugins/core/email/client/index.js b/imports/plugins/core/email/client/index.js
index 0c66106023e..954caa901e7 100644
--- a/imports/plugins/core/email/client/index.js
+++ b/imports/plugins/core/email/client/index.js
@@ -1,2 +1,6 @@
import "./templates/email.html";
import "./templates/email.js";
+
+export { default as EmailConfig } from "./containers/emailConfig";
+export { default as EmailLogs } from "./containers/emailLogs";
+export { default as EmailSettings } from "./containers/emailSettings";
diff --git a/imports/plugins/core/i18n/client/containers/localizationSettingsContainer.js b/imports/plugins/core/i18n/client/containers/localizationSettingsContainer.js
index a7d2fd6d68f..4b717894091 100644
--- a/imports/plugins/core/i18n/client/containers/localizationSettingsContainer.js
+++ b/imports/plugins/core/i18n/client/containers/localizationSettingsContainer.js
@@ -1,8 +1,8 @@
import React, { Component } from "react";
import moment from "moment-timezone";
+import { composeWithTracker } from "@reactioncommerce/reaction-components";
import { Meteor } from "meteor/meteor";
import { Reaction, i18next } from "/client/api";
-import { composeWithTracker } from "/lib/api/compose";
import { Countries } from "/client/collections";
import { Shops } from "/lib/collections";
import LocalizationSettings from "../components/localizationSettings";
diff --git a/imports/plugins/core/layout/client/components/coreLayout.js b/imports/plugins/core/layout/client/components/coreLayout.js
index b6dd00292bb..2d954998b71 100644
--- a/imports/plugins/core/layout/client/components/coreLayout.js
+++ b/imports/plugins/core/layout/client/components/coreLayout.js
@@ -1,43 +1,43 @@
-import React, { Component } from "react";
+import React from "react";
import PropTypes from "prop-types";
import classnames from "classnames";
+import { Components, registerComponent } from "@reactioncommerce/reaction-components";
import Blaze from "meteor/gadicc:blaze-react-component";
import { Template } from "meteor/templating";
-class CoreLayout extends Component {
- static propTypes = {
- actionViewIsOpen: PropTypes.bool,
- data: PropTypes.object,
- structure: PropTypes.object
- }
-
- render() {
- const { layoutHeader, layoutFooter, template } = this.props.structure || {};
- const pageClassName = classnames({
- "page": true,
- "show-settings": this.props.actionViewIsOpen
- });
-
- return (
-
- { Template[layoutHeader] &&
-
- }
-
-
-
- { Template[template] &&
-
-
-
- }
-
- { Template[layoutFooter] &&
-
- }
-
- );
- }
-}
+const CoreLayout = ({ actionViewIsOpen, structure }) => {
+ const { layoutFooter, template } = structure || {};
+
+ const pageClassName = classnames({
+ "page": true,
+ "show-settings": actionViewIsOpen
+ });
+
+ return (
+
+
+
+
+
+ { Template[template] &&
+
+
+
+ }
+
+ { Template[layoutFooter] &&
+
+ }
+
+ );
+};
+
+CoreLayout.propTypes = {
+ actionViewIsOpen: PropTypes.bool,
+ data: PropTypes.object,
+ structure: PropTypes.object
+};
+
+registerComponent("CoreLayout", CoreLayout);
export default CoreLayout;
diff --git a/imports/plugins/core/layout/client/containers/adminContainer.js b/imports/plugins/core/layout/client/containers/adminContainer.js
index cdbda232c21..5dd0b6f8dec 100644
--- a/imports/plugins/core/layout/client/containers/adminContainer.js
+++ b/imports/plugins/core/layout/client/containers/adminContainer.js
@@ -1,12 +1,11 @@
-import _ from "lodash";
-import { composeWithTracker } from "/lib/api/compose";
+import { composeWithTracker } from "@reactioncommerce/reaction-components";
import { Reaction } from "/client/api";
function composer(props, onData) {
const shortcuts = Reaction.Apps({ provides: "shortcut", enabled: true });
const items = [];
- if (_.isArray(shortcuts)) {
+ if (Array.isArray(shortcuts)) {
for (const shortcut of shortcuts) {
if (!shortcut.container) {
items.push({
diff --git a/imports/plugins/core/layout/client/containers/quickMenuContainer.js b/imports/plugins/core/layout/client/containers/quickMenuContainer.js
index cd186fb96d7..d4eb168ab4a 100644
--- a/imports/plugins/core/layout/client/containers/quickMenuContainer.js
+++ b/imports/plugins/core/layout/client/containers/quickMenuContainer.js
@@ -1,19 +1,8 @@
-import React, { Component } from "react";
import _ from "lodash";
-import { composeWithTracker } from "/lib/api/compose";
+import { composeWithTracker } from "@reactioncommerce/reaction-components";
import { QuickMenu } from "../components";
import { Reaction } from "/client/api";
-class QuickMenuContainer extends Component {
- render() {
- return (
-
- );
- }
-}
-
function composer(props, onData) {
const shortcuts = Reaction.Apps({ provides: "shortcut", enabled: true });
const items = [];
@@ -48,4 +37,4 @@ function composer(props, onData) {
});
}
-export default composeWithTracker(composer)(QuickMenuContainer);
+export default composeWithTracker(composer)(QuickMenu);
diff --git a/imports/plugins/core/layout/client/index.js b/imports/plugins/core/layout/client/index.js
index dd338e8cd4a..f0bfa184a71 100644
--- a/imports/plugins/core/layout/client/index.js
+++ b/imports/plugins/core/layout/client/index.js
@@ -16,7 +16,6 @@ import "./templates/layout/notFound/notFound.html";
import "./templates/layout/notFound/notFound.js";
import "./templates/layout/notice/unauthorized.html";
import "./templates/layout/notice/unauthorized.js";
-import "./templates/layout/layout.html";
import "./templates/theme/theme.html";
import "./templates/theme/theme.js";
diff --git a/imports/plugins/core/layout/client/templates/layout/layout.html b/imports/plugins/core/layout/client/templates/layout/layout.html
deleted file mode 100644
index 546019c7b15..00000000000
--- a/imports/plugins/core/layout/client/templates/layout/layout.html
+++ /dev/null
@@ -1,31 +0,0 @@
-
- {{> Template.dynamic template=template}}
-
-
-
- {{#if hasDashboardAccess}}
- {{> coreAdminLayout}}
- {{else}}
-
-
-
-
-
- {{> inlineAlerts}}
- {{#if hasPermission 'guest'}}
-
- {{> Template.dynamic template=template}}
-
- {{/if}}
-
-
-
-
- {{/if}}
-
diff --git a/imports/plugins/core/layout/lib/reactionLayout.js b/imports/plugins/core/layout/lib/reactionLayout.js
index c5b9a6b938f..5e4772096a1 100644
--- a/imports/plugins/core/layout/lib/reactionLayout.js
+++ b/imports/plugins/core/layout/lib/reactionLayout.js
@@ -1,13 +1,13 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import Radium from "radium";
+import { compose } from "recompose";
+import { registerComponent, composeWithTracker } from "@reactioncommerce/reaction-components";
import { Meteor } from "meteor/meteor";
-import { composeWithTracker } from "/lib/api/compose";
import { Reaction } from "/client/api";
import classnames from "classnames";
import { getComponent } from "/imports/plugins/core/layout/lib/components";
import { Templates } from "/lib/collections";
-import { Loading } from "/imports/plugins/core/ui/client/components";
class ReactionLayout extends Component {
get layout() {
@@ -129,4 +129,12 @@ function composer(props, onData) {
}
}
-export default composeWithTracker(composer, Loading)(Radium(ReactionLayout));
+registerComponent("ReactionLayout", ReactionLayout, [
+ composeWithTracker(composer),
+ Radium
+]);
+
+export default compose(
+ composeWithTracker(composer),
+ Radium
+)(ReactionLayout);
diff --git a/imports/plugins/core/orders/client/containers/invoiceActionsContainer.js b/imports/plugins/core/orders/client/containers/invoiceActionsContainer.js
index 69ca603504d..9015fdcfa43 100644
--- a/imports/plugins/core/orders/client/containers/invoiceActionsContainer.js
+++ b/imports/plugins/core/orders/client/containers/invoiceActionsContainer.js
@@ -1,8 +1,7 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
-import { composeWithTracker } from "/lib/api/compose";
+import { composeWithTracker } from "@reactioncommerce/reaction-components";
import InvoiceActions from "../components/invoiceActions";
-import { Loading } from "/imports/plugins/core/ui/client/components";
class InvoiceActionsContainer extends Component {
static propTypes = {
@@ -48,4 +47,4 @@ const composer = (props, onData) => {
});
};
-export default composeWithTracker(composer, Loading)(InvoiceActionsContainer);
+export default composeWithTracker(composer)(InvoiceActionsContainer);
diff --git a/imports/plugins/core/orders/client/containers/invoiceContainer.js b/imports/plugins/core/orders/client/containers/invoiceContainer.js
index 97866f4aea1..1e36c57d3da 100644
--- a/imports/plugins/core/orders/client/containers/invoiceContainer.js
+++ b/imports/plugins/core/orders/client/containers/invoiceContainer.js
@@ -1,8 +1,7 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import moment from "moment";
-import { composeWithTracker } from "/lib/api/compose";
-import { Loading } from "/imports/plugins/core/ui/client/components";
+import { composeWithTracker } from "@reactioncommerce/reaction-components";
import { TranslationProvider } from "/imports/plugins/core/ui/client/providers";
import Invoice from "../components/invoice.js";
@@ -79,4 +78,4 @@ const composer = (props, onData) => {
});
};
-export default composeWithTracker(composer, Loading)(InvoiceContainer);
+export default composeWithTracker(composer)(InvoiceContainer);
diff --git a/imports/plugins/core/orders/client/containers/lineItemsContainer.js b/imports/plugins/core/orders/client/containers/lineItemsContainer.js
index 18178ce7a49..3bb57567b96 100644
--- a/imports/plugins/core/orders/client/containers/lineItemsContainer.js
+++ b/imports/plugins/core/orders/client/containers/lineItemsContainer.js
@@ -1,9 +1,8 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
+import { composeWithTracker } from "@reactioncommerce/reaction-components";
import { Meteor } from "meteor/meteor";
-import { composeWithTracker } from "/lib/api/compose";
import { Media } from "/lib/collections";
-import { Loading } from "/imports/plugins/core/ui/client/components";
import { TranslationProvider } from "/imports/plugins/core/ui/client/providers";
import LineItems from "../components/lineItems.js";
@@ -101,4 +100,4 @@ const composer = (props, onData) => {
}
};
-export default composeWithTracker(composer, Loading)(LineItemsContainer);
+export default composeWithTracker(composer)(LineItemsContainer);
diff --git a/imports/plugins/core/orders/client/containers/orderSummaryContainer.js b/imports/plugins/core/orders/client/containers/orderSummaryContainer.js
index f61b133e4c4..601c7cbcce2 100644
--- a/imports/plugins/core/orders/client/containers/orderSummaryContainer.js
+++ b/imports/plugins/core/orders/client/containers/orderSummaryContainer.js
@@ -2,10 +2,10 @@ import React, { Component } from "react";
import PropTypes from "prop-types";
import moment from "moment";
import _ from "lodash";
+import { composeWithTracker } from "@reactioncommerce/reaction-components";
import { Meteor } from "meteor/meteor";
-import { composeWithTracker } from "/lib/api/compose";
import { Orders } from "/lib/collections";
-import { Card, CardHeader, CardBody, CardGroup, Loading } from "/imports/plugins/core/ui/client/components";
+import { Card, CardHeader, CardBody, CardGroup } from "/imports/plugins/core/ui/client/components";
import { i18next } from "/client/api";
import OrderSummary from "../components/orderSummary";
@@ -155,4 +155,4 @@ const composer = (props, onData) => {
}
};
-export default composeWithTracker(composer, Loading)(OrderSummaryContainer);
+export default composeWithTracker(composer)(OrderSummaryContainer);
diff --git a/imports/plugins/core/orders/client/containers/ordersActionContainer.js b/imports/plugins/core/orders/client/containers/ordersActionContainer.js
index f3656a367b3..b07bada34ef 100644
--- a/imports/plugins/core/orders/client/containers/ordersActionContainer.js
+++ b/imports/plugins/core/orders/client/containers/ordersActionContainer.js
@@ -1,8 +1,8 @@
import React from "react";
+import { composeWithTracker } from "@reactioncommerce/reaction-components";
import { Meteor } from "meteor/meteor";
import { Counts } from "meteor/tmeasday:publish-counts";
import { Reaction, i18next } from "/client/api";
-import { composeWithTracker } from "/lib/api/compose";
import OrderActions from "../components/orderActions";
import * as Constants from "../../lib/constants";
@@ -55,4 +55,4 @@ function OrdersActionContainer(props) {
);
}
-export default composeWithTracker(composer, null)(OrdersActionContainer);
+export default composeWithTracker(composer)(OrdersActionContainer);
diff --git a/imports/plugins/core/orders/client/containers/ordersListContainer.js b/imports/plugins/core/orders/client/containers/ordersListContainer.js
index 18b7eeded94..95d51102b94 100644
--- a/imports/plugins/core/orders/client/containers/ordersListContainer.js
+++ b/imports/plugins/core/orders/client/containers/ordersListContainer.js
@@ -1,10 +1,9 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
+import { composeWithTracker } from "@reactioncommerce/reaction-components";
import { Meteor } from "meteor/meteor";
-import { composeWithTracker } from "/lib/api/compose";
import { Media } from "/lib/collections";
import { Reaction } from "/client/api";
-import { Loading } from "/imports/plugins/core/ui/client/components";
import OrdersList from "../components/ordersList.js";
import {
PACKAGE_NAME,
@@ -100,4 +99,4 @@ const composer = (props, onData) => {
}
};
-export default composeWithTracker(composer, Loading)(OrdersListContainer);
+export default composeWithTracker(composer)(OrdersListContainer);
diff --git a/imports/plugins/core/orders/client/containers/totalActionsContainer.js b/imports/plugins/core/orders/client/containers/totalActionsContainer.js
index 6d4bfc15337..669c68941c4 100644
--- a/imports/plugins/core/orders/client/containers/totalActionsContainer.js
+++ b/imports/plugins/core/orders/client/containers/totalActionsContainer.js
@@ -1,8 +1,7 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
-import { composeWithTracker } from "/lib/api/compose";
+import { composeWithTracker } from "@reactioncommerce/reaction-components";
import TotalActions from "../components/totalActions";
-import { Loading } from "/imports/plugins/core/ui/client/components";
class TotalActionsContaner extends Component {
static propTypes = {
@@ -48,4 +47,4 @@ const composer = (props, onData) => {
});
};
-export default composeWithTracker(composer, Loading)(TotalActionsContaner);
+export default composeWithTracker(composer)(TotalActionsContaner);
diff --git a/imports/plugins/core/revisions/client/containers/publishContainer.js b/imports/plugins/core/revisions/client/containers/publishContainer.js
index 9e6345e44ca..e7c148bf442 100644
--- a/imports/plugins/core/revisions/client/containers/publishContainer.js
+++ b/imports/plugins/core/revisions/client/containers/publishContainer.js
@@ -1,6 +1,6 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
-import { composeWithTracker } from "/lib/api/compose";
+import { composeWithTracker } from "@reactioncommerce/reaction-components";
import PublishControls from "../components/publishControls";
import { Revisions } from "/lib/collections";
import { Meteor } from "meteor/meteor";
@@ -148,4 +148,4 @@ function composer(props, onData) {
});
}
-export default composeWithTracker(composer, null)(PublishContainer);
+export default composeWithTracker(composer)(PublishContainer);
diff --git a/imports/plugins/core/revisions/client/containers/settingsContainer.js b/imports/plugins/core/revisions/client/containers/settingsContainer.js
index 26de206ecb0..a25b65ae952 100644
--- a/imports/plugins/core/revisions/client/containers/settingsContainer.js
+++ b/imports/plugins/core/revisions/client/containers/settingsContainer.js
@@ -1,6 +1,6 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
-import { composeWithTracker } from "/lib/api/compose";
+import { composeWithTracker } from "@reactioncommerce/reaction-components";
import SettingsComponent from "../components/settings";
import { Packages } from "/lib/collections";
import { Meteor } from "meteor/meteor";
diff --git a/imports/plugins/core/router/client/app.js b/imports/plugins/core/router/client/app.js
index bbf655cf994..eaf8fed4233 100644
--- a/imports/plugins/core/router/client/app.js
+++ b/imports/plugins/core/router/client/app.js
@@ -1,9 +1,8 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import classnames from "classnames";
+import { composeWithTracker } from "@reactioncommerce/reaction-components";
import { Reaction, Router } from "/client/api";
-import { composeWithTracker } from "/lib/api/compose";
-import { Loading } from "/imports/plugins/core/ui/client/components";
import ToolbarContainer from "/imports/plugins/core/dashboard/client/containers/toolbarContainer";
import Toolbar from "/imports/plugins/core/dashboard/client/components/toolbar";
import { ActionViewContainer, PackageListContainer } from "/imports/plugins/core/dashboard/client/containers";
@@ -109,4 +108,4 @@ function composer(props, onData) {
});
}
-export default composeWithTracker(composer, Loading)(App);
+export default composeWithTracker(composer)(App);
diff --git a/imports/plugins/core/router/client/startup.js b/imports/plugins/core/router/client/startup.js
index 6dddb4e67e6..4b992d226be 100644
--- a/imports/plugins/core/router/client/startup.js
+++ b/imports/plugins/core/router/client/startup.js
@@ -1,3 +1,4 @@
+import { loadRegisteredComponents } from "@reactioncommerce/reaction-components";
import { Meteor } from "meteor/meteor";
import { Tracker } from "meteor/tracker";
import { Accounts } from "meteor/accounts-base";
@@ -6,6 +7,8 @@ import { initBrowserRouter } from "./browserRouter";
import { Router } from "../lib";
Meteor.startup(function () {
+ loadRegisteredComponents();
+
Tracker.autorun(function () {
// initialize client routing
diff --git a/imports/plugins/core/router/lib/index.js b/imports/plugins/core/router/lib/index.js
index 79c04b5814c..373f23cb8fd 100644
--- a/imports/plugins/core/router/lib/index.js
+++ b/imports/plugins/core/router/lib/index.js
@@ -1 +1,2 @@
+export { Link, NavLink, Prompt, withRouter } from "react-router-dom";
export { default as Router } from "./router";
diff --git a/imports/plugins/core/ui-navbar/client/components/navbar/components/brand.js b/imports/plugins/core/ui-navbar/client/components/brand.js
similarity index 76%
rename from imports/plugins/core/ui-navbar/client/components/navbar/components/brand.js
rename to imports/plugins/core/ui-navbar/client/components/brand.js
index 586e4032336..e08ad6fbef4 100644
--- a/imports/plugins/core/ui-navbar/client/components/navbar/components/brand.js
+++ b/imports/plugins/core/ui-navbar/client/components/brand.js
@@ -1,15 +1,16 @@
-import React, { Component } from "react";
+import React, { PureComponent } from "react";
import _ from "lodash";
+import { registerComponent } from "@reactioncommerce/reaction-components";
import { Reaction } from "/client/api";
import { Media, Shops } from "/lib/collections";
-class Brand extends Component {
+class Brand extends PureComponent {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
- handleClick = (event) => {
+ handleClick(event) {
event.preventDefault();
Reaction.Router.go("/");
}
@@ -19,7 +20,7 @@ class Brand extends Component {
}
getLogo() {
- if (_.isArray(this.getShop().brandAssets)) {
+ if (Array.isArray(this.getShop().brandAssets)) {
const brandAsset = _.find(this.getShop().brandAssets, (asset) => asset.type === "navbarBrandImage");
return Media.findOne(brandAsset.mediaId);
}
@@ -40,4 +41,6 @@ class Brand extends Component {
}
}
+registerComponent("Brand", Brand);
+
export default Brand;
diff --git a/imports/plugins/core/ui-navbar/client/components/brand/brand.html b/imports/plugins/core/ui-navbar/client/components/brand/brand.html
deleted file mode 100644
index b081ddab920..00000000000
--- a/imports/plugins/core/ui-navbar/client/components/brand/brand.html
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- {{#with logo}}
-
-

-
- {{/with}}
- {{siteName}}
-
-
diff --git a/imports/plugins/core/ui-navbar/client/components/brand/brand.js b/imports/plugins/core/ui-navbar/client/components/brand/brand.js
deleted file mode 100644
index a5ee2e6a0ef..00000000000
--- a/imports/plugins/core/ui-navbar/client/components/brand/brand.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import _ from "lodash";
-import { Template } from "meteor/templating";
-import { Reaction, Router } from "/client/api";
-import { Media, Shops } from "/lib/collections";
-
-Template.coreNavigationBrand.helpers({
- logo() {
- const shop = Shops.findOne(Reaction.getShopId());
-
- if (_.isArray(shop.brandAssets)) {
- const brandAsset = _.find(shop.brandAssets, (asset) => asset.type === "navbarBrandImage");
- return Media.findOne(brandAsset.mediaId);
- }
-
- return false;
- }
-});
-
-Template.coreNavigationBrand.events({
- "click a.brand"(event) {
- event.preventDefault();
- Router.go("/");
- }
-});
diff --git a/imports/plugins/core/ui-navbar/client/components/i18n/i18n.html b/imports/plugins/core/ui-navbar/client/components/i18n/i18n.html
deleted file mode 100644
index 7a8bfd4b92b..00000000000
--- a/imports/plugins/core/ui-navbar/client/components/i18n/i18n.html
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
diff --git a/imports/plugins/core/ui-navbar/client/components/i18n/i18n.js b/imports/plugins/core/ui-navbar/client/components/i18n/i18n.js
deleted file mode 100644
index 2ee34890b25..00000000000
--- a/imports/plugins/core/ui-navbar/client/components/i18n/i18n.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import { Shops } from "/lib/collections";
-import { Session } from "meteor/session";
-import { Template } from "meteor/templating";
-
-/**
- * i18nChooser helpers
- */
-
-Template.CoreNavigationLanguage.helpers({
- languages: function () {
- const languages = [];
- const shop = Shops.findOne();
- if (typeof shop === "object" && shop.languages) {
- for (const language of shop.languages) {
- if (language.enabled === true) {
- language.translation = "languages." + language.label.toLowerCase();
- languages.push(language);
- }
- }
- return languages;
- }
- },
- active: function () {
- if (Session.equals("language", this.i18n)) {
- return "active";
- }
- }
-});
-
-/**
- * i18nChooser events
- */
-
-Template.CoreNavigationLanguage.events({
- "click .i18n-language": function (event) {
- event.preventDefault();
- return Session.set("language", this.i18n);
- }
-});
diff --git a/imports/plugins/core/ui-navbar/client/components/navbar/components/navbar.js b/imports/plugins/core/ui-navbar/client/components/navbar.js
similarity index 66%
rename from imports/plugins/core/ui-navbar/client/components/navbar/components/navbar.js
rename to imports/plugins/core/ui-navbar/client/components/navbar.js
index 44f3b3aff45..297875b69cb 100644
--- a/imports/plugins/core/ui-navbar/client/components/navbar/components/navbar.js
+++ b/imports/plugins/core/ui-navbar/client/components/navbar.js
@@ -1,14 +1,25 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
-import { FlatButton, Button } from "/imports/plugins/core/ui/client/components";
-import { NotificationContainer } from "/imports/plugins/included/notifications/client/containers";
-import CartIconContainer from "/imports/plugins/core/checkout/client/container/cartIconContainer";
-import CartPanel from "/imports/plugins/core/checkout/client/templates/cartPanel/container/cartPanelContainer";
-import MainDropdown from "/client/modules/accounts/containers/dropdown/mainDropdownContainer";
+import { Components } from "@reactioncommerce/reaction-components";
+import { Meteor } from "meteor/meteor";
import LanguageContainer from "/client/modules/i18n/templates/header/containers/i18nContainer";
import CurrencyContainer from "/client/modules/i18n/templates/currency/containers/currencyContainer";
-import TagNavContainer from "/imports/plugins/core/ui-tagnav/client/containers/tagNavContainer";
-import Brand from "./brand";
+
+// TODO: Delete this, and do it the react way - Mike M.
+async function openSearchModalLegacy(props) {
+ if (Meteor.isClient) {
+ const { Blaze } = await import("meteor/blaze");
+ const { Template } = await import("meteor/templating");
+ const { default: $ } = await import("jquery");
+
+ const searchTemplate = Template[props.searchTemplate];
+
+ Blaze.renderWithData(searchTemplate, {}, $("html").get(0));
+
+ $("body").css("overflow", "hidden");
+ $("#search-input").focus();
+ }
+}
class NavBar extends Component {
static propTypes = {
@@ -27,7 +38,11 @@ class NavBar extends Component {
handleCloseNavbar = () => {
this.setState({ navBarVisible: false });
- };
+ }
+
+ handleOpenSearchModal = () => {
+ openSearchModalLegacy(this.props);
+ }
renderLanguage() {
return (
@@ -47,7 +62,7 @@ class NavBar extends Component {
renderBrand() {
return (
-
+
);
}
@@ -55,9 +70,10 @@ class NavBar extends Component {
if (this.props.searchEnabled) {
return (
-
);
@@ -67,7 +83,7 @@ class NavBar extends Component {
renderNotificationIcon() {
if (this.props.hasProperPermission) {
return (
-
+
);
}
}
@@ -76,10 +92,10 @@ class NavBar extends Component {
return (
);
@@ -87,25 +103,25 @@ class NavBar extends Component {
renderMainDropdown() {
return (
-
+
);
}
renderHamburgerButton() {
return (
-
+
);
}
renderTagNav() {
return (
-
-
-
+
+
);
}
diff --git a/imports/plugins/core/ui-navbar/client/components/navbar/navbar.html b/imports/plugins/core/ui-navbar/client/components/navbar/navbar.html
deleted file mode 100644
index df8e40c1756..00000000000
--- a/imports/plugins/core/ui-navbar/client/components/navbar/navbar.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
- {{>React navbar}}
-
-
diff --git a/imports/plugins/core/ui-navbar/client/components/navbar/navbar.js b/imports/plugins/core/ui-navbar/client/components/navbar/navbar.js
deleted file mode 100644
index 9b974fb2220..00000000000
--- a/imports/plugins/core/ui-navbar/client/components/navbar/navbar.js
+++ /dev/null
@@ -1,95 +0,0 @@
-import { Template } from "meteor/templating";
-import { $ } from "meteor/jquery";
-import { Blaze } from "meteor/blaze";
-import { ReactiveDict } from "meteor/reactive-dict";
-import { FlatButton } from "/imports/plugins/core/ui/client/components";
-import { NotificationContainer } from "/imports/plugins/included/notifications/client/containers";
-import { Reaction } from "/client/api";
-import CartPanel from "../../../../checkout/client/templates/cartPanel/container/cartPanelContainer";
-import MainDropdown from "/client/modules/accounts/containers/dropdown/mainDropdownContainer.js";
-import NavBarContainer from "./containers/navbarContainer";
-
-Template.CoreNavigationBar.onCreated(function () {
- this.state = new ReactiveDict();
- const searchPackage = Reaction.Apps({ provides: "ui-search" });
- if (searchPackage.length) {
- this.state.set("searchEnabled", true);
- this.state.set("searchTemplate", searchPackage[0].template);
- } else {
- this.state.set("searchEnabled", false);
- }
-});
-
-/**
- * layoutHeader events
- */
-Template.CoreNavigationBar.events({
- "click .navbar-accounts .dropdown-toggle": function () {
- return setTimeout(function () {
- return $("#login-email").focus();
- }, 100);
- },
- "click .header-tag, click .navbar-brand": function () {
- return $(".dashboard-navbar-packages ul li").removeClass("active");
- },
- "click .search": function () {
- const instance = Template.instance();
- const searchTemplateName = instance.state.get("searchTemplate");
- const searchTemplate = Template[searchTemplateName];
- Blaze.renderWithData(searchTemplate, {
- }, $("html").get(0));
- $("body").css("overflow", "hidden");
- $("#search-input").focus();
- }
-});
-
-Template.CoreNavigationBar.helpers({
- dropdown() {
- return {
- component: MainDropdown
- };
- },
- navbar() {
- return {
- component: NavBarContainer
- };
- },
-
- searchTemplate() {
- const instance = Template.instance();
- if (instance.state.get("searchEnabled")) {
- return instance.state.get("searchTemplate");
- }
- },
-
- onMenuButtonClick() {
- const instance = Template.instance();
- return () => {
- if (instance.toggleMenuCallback) {
- instance.toggleMenuCallback();
- }
- };
- },
-
- isSearchEnabled() {
- const instance = Template.instance();
- return instance.state.get("searchEnabled");
- },
-
- IconButtonComponent() {
- return {
- component: FlatButton,
- icon: "fa fa-search",
- kind: "flat"
- };
- },
- notificationButtonComponent() {
- return {
- component: NotificationContainer
- };
- },
-
- cartPanel() {
- return CartPanel;
- }
-});
diff --git a/imports/plugins/core/ui-navbar/client/components/navbar/containers/navbarContainer.js b/imports/plugins/core/ui-navbar/client/containers/navbar.js
similarity index 62%
rename from imports/plugins/core/ui-navbar/client/components/navbar/containers/navbarContainer.js
rename to imports/plugins/core/ui-navbar/client/containers/navbar.js
index 7f3accbd796..ba065321433 100644
--- a/imports/plugins/core/ui-navbar/client/components/navbar/containers/navbarContainer.js
+++ b/imports/plugins/core/ui-navbar/client/containers/navbar.js
@@ -1,20 +1,7 @@
-import React, { Component } from "react";
-import { composeWithTracker } from "/lib/api/compose";
+import { registerComponent, composeWithTracker } from "@reactioncommerce/reaction-components";
import { Reaction } from "/client/api";
import NavBar from "../components/navbar";
-class NavBarContainer extends Component {
- render() {
- return (
-
-
-
- );
- }
-}
-
function composer(props, onData) {
const searchPackage = Reaction.Apps({ provides: "ui-search" });
let searchEnabled;
@@ -36,4 +23,6 @@ function composer(props, onData) {
});
}
-export default composeWithTracker(composer)(NavBarContainer);
+registerComponent("NavBar", NavBar, composeWithTracker(composer));
+
+export default composeWithTracker(composer)(NavBar);
diff --git a/imports/plugins/core/ui-navbar/client/index.js b/imports/plugins/core/ui-navbar/client/index.js
index 8f69791dfed..54221bda4b4 100644
--- a/imports/plugins/core/ui-navbar/client/index.js
+++ b/imports/plugins/core/ui-navbar/client/index.js
@@ -1,8 +1,2 @@
-import "./components/brand/brand.html";
-import "./components/brand/brand.js";
-
-import "./components/i18n/i18n.html";
-import "./components/i18n/i18n.js";
-
-import "./components/navbar/navbar.html";
-import "./components/navbar/navbar.js";
+export { default as Brand } from "./components/brand";
+export { default as Navbar } from "./containers/navbar";
diff --git a/imports/plugins/core/ui-tagnav/client/components/tagGroup.js b/imports/plugins/core/ui-tagnav/client/components/tagGroup.js
index 5838304d7c2..1bef212f77a 100644
--- a/imports/plugins/core/ui-tagnav/client/components/tagGroup.js
+++ b/imports/plugins/core/ui-tagnav/client/components/tagGroup.js
@@ -1,15 +1,13 @@
-import React, { Component } from "react";
+import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import _ from "lodash";
+import { Components, registerComponent } from "@reactioncommerce/reaction-components";
import update from "react/lib/update";
-import TagGroupBody from "./tagGroupBody";
-import TagGroupHeader from "./tagGroupHeader";
-import { TagItem } from "/imports/plugins/core/ui/client/components/tags/";
import { TagHelpers } from "/imports/plugins/core/ui-tagnav/client/helpers";
import { getTagIds } from "/lib/selectors/tags";
import { Router } from "/client/api";
-class TagGroup extends Component {
+class TagGroup extends PureComponent {
constructor(props) {
super(props);
@@ -105,13 +103,13 @@ class TagGroup extends Component {
if (Array.isArray(tags)) {
return tags.map((tag) => (
-
-
@@ -138,7 +136,7 @@ class TagGroup extends Component {
{this.props.editable &&
-
{
- debounce(() => this.props.onTagSort(this.state.tagIds, this.state.parentTag), 500)();
+ _.debounce(() => this.props.onTagSort(this.state.tagIds, this.state.parentTag), 500)();
});
}
@@ -104,7 +103,7 @@ class TagGroupBody extends Component {
if (Array.isArray(tags)) {
return tags.map((tag, index) => {
return (
-
-
-
-
-
);
})}
@@ -143,4 +143,6 @@ class ButtonSelect extends Component {
}
}
+registerComponent("ButtonSelect", ButtonSelect);
+
export default ButtonSelect;
diff --git a/imports/plugins/core/ui/client/components/button/editButton.js b/imports/plugins/core/ui/client/components/button/editButton.js
index 7c1406590fc..5ae35d7baae 100644
--- a/imports/plugins/core/ui/client/components/button/editButton.js
+++ b/imports/plugins/core/ui/client/components/button/editButton.js
@@ -1,4 +1,6 @@
import React from "react";
+import { pure } from "recompose";
+import { registerComponent } from "@reactioncommerce/reaction-components";
import IconButton from "./iconButton";
/**
@@ -26,4 +28,6 @@ const EditButton = (props) => {
);
};
+registerComponent("EditButton", EditButton, pure);
+
export default EditButton;
diff --git a/imports/plugins/core/ui/client/components/button/flatButton.js b/imports/plugins/core/ui/client/components/button/flatButton.js
index 517d5c73cc0..de46b7701c5 100644
--- a/imports/plugins/core/ui/client/components/button/flatButton.js
+++ b/imports/plugins/core/ui/client/components/button/flatButton.js
@@ -1,51 +1,46 @@
-/* eslint no-unused-vars: 1 */
-
-import React, { Component } from "react";
+import React from "react";
import classnames from "classnames";
+import { pure } from "recompose";
+import { registerComponent } from "@reactioncommerce/reaction-components";
import Button from "./button.jsx";
-class FlatButton extends Component {
- static defaultProps = {
- bezelStyle: "flat"
- }
- render() {
- const {
- icon,
- onIcon,
- ...otherProps
- } = this.props;
-
- const buttonClassName = classnames({
- rui: true,
- button: true
+const FlatButton = ({ icon, onIcon, ...otherProps }) => {
+ const buttonClassName = classnames({
+ rui: true,
+ button: true
+ });
+
+ let iconClassName;
+ let onIconClassName;
+
+ if (icon) {
+ iconClassName = classnames({
+ [icon]: true
});
+ }
- let iconClassName;
- let onIconClassName;
-
- if (icon) {
- iconClassName = classnames({
- [icon]: true
- });
- }
-
- if (onIcon) {
- onIconClassName = classnames({
- [onIcon]: true
- });
- }
-
- return (
-
- );
+ if (onIcon) {
+ onIconClassName = classnames({
+ [onIcon]: true
+ });
}
-}
+
+ return (
+
+ );
+};
FlatButton.propTypes = Object.assign({}, Button.propTypes);
+FlatButton.defaultProps = {
+ bezelStyle: "flat"
+};
+
+registerComponent("FlatButton", FlatButton, pure);
+
export default FlatButton;
diff --git a/imports/plugins/core/ui/client/components/button/handle.js b/imports/plugins/core/ui/client/components/button/handle.js
index d7a7da3cbcc..65aff6f1ba3 100644
--- a/imports/plugins/core/ui/client/components/button/handle.js
+++ b/imports/plugins/core/ui/client/components/button/handle.js
@@ -1,6 +1,7 @@
import React from "react";
import PropTypes from "prop-types";
-import { Icon } from "../icon";
+import { pure } from "recompose";
+import { Components, registerComponent } from "@reactioncommerce/reaction-components";
/**
* Handle is a special type of button used for drag handles.
@@ -14,7 +15,7 @@ import { Icon } from "../icon";
const Handle = (props) => {
const handle = (
-
@@ -32,4 +33,6 @@ Handle.propTypes = {
connectDragSource: PropTypes.func
};
+registerComponent("Handle", Handle, pure);
+
export default Handle;
diff --git a/imports/plugins/core/ui/client/components/button/iconButton.js b/imports/plugins/core/ui/client/components/button/iconButton.js
index a4fced1e315..7a97c2be6bf 100644
--- a/imports/plugins/core/ui/client/components/button/iconButton.js
+++ b/imports/plugins/core/ui/client/components/button/iconButton.js
@@ -1,68 +1,64 @@
-import React, { Component } from "react";
+import React from "react";
import classnames from "classnames";
+import { pure } from "recompose";
+import { registerComponent } from "@reactioncommerce/reaction-components";
import Button from "./button.jsx";
-class IconButton extends Component {
- static defaultProps = {
- bezelStyle: "solid"
- }
-
- render() {
- const {
- icon,
- onIcon,
- ...otherProps
- } = this.props;
+const IconButton = ({ icon, onIcon, ...otherProps }) => {
+ // otherProps.buttonKind === 'flat'
+ // default should be default, flat is new css that makes the bakcground tarnsparent
+ let buttonClassName;
+ if (otherProps.kind === "flat") {
+ buttonClassName = classnames({
+ "icon": true,
+ "icon-only": true
+ });
+ } else if (otherProps.kind === "mediaGalleryStatus") {
+ buttonClassName = classnames({
+ "icon": true,
+ "icon-only": true,
+ "status-badge": true
+ });
+ } else {
+ buttonClassName = classnames({
+ "icon-only": true,
+ "variant-edit": true
+ });
+ }
- // this.props.buttonKind === 'flat'
- // default should be default, flat is new css that makes the bakcground tarnsparent
- let buttonClassName;
+ const iconClassName = classnames({
+ "fa-lg": true,
+ [icon]: true
+ });
- if (this.props.kind === "flat") {
- buttonClassName = classnames({
- "icon": true,
- "icon-only": true
- });
- } else if (this.props.kind === "mediaGalleryStatus") {
- buttonClassName = classnames({
- "icon": true,
- "icon-only": true,
- "status-badge": true
- });
- } else {
- buttonClassName = classnames({
- "icon-only": true,
- "variant-edit": true
- });
- }
+ let onIconClassName;
- const iconClassName = classnames({
+ if (onIcon) {
+ onIconClassName = classnames({
"fa-lg": true,
- [icon]: true
+ [onIcon]: true
});
+ }
- let onIconClassName;
+ return (
+
+ );
+};
- if (onIcon) {
- onIconClassName = classnames({
- "fa-lg": true,
- [onIcon]: true
- });
- }
+IconButton.propTypes = Object.assign({}, Button.propTypes);
- return (
-
- );
- }
-}
+IconButton.defaultProps = {
+ bezelStyle: "solid"
+};
-IconButton.propTypes = Object.assign({}, Button.propTypes);
+registerComponent("IconButton", IconButton, pure);
export default IconButton;
diff --git a/imports/plugins/core/ui/client/components/button/visibilityButton.js b/imports/plugins/core/ui/client/components/button/visibilityButton.js
index 27d8535345e..4bd34d391ab 100644
--- a/imports/plugins/core/ui/client/components/button/visibilityButton.js
+++ b/imports/plugins/core/ui/client/components/button/visibilityButton.js
@@ -1,4 +1,6 @@
import React from "react";
+import { pure } from "recompose";
+import { registerComponent } from "@reactioncommerce/reaction-components";
import IconButton from "./iconButton";
/**
@@ -24,4 +26,6 @@ const VisibilityButton = (props) => {
);
};
+registerComponent("VisibilityButton", VisibilityButton, pure);
+
export default VisibilityButton;
diff --git a/imports/plugins/core/ui/client/components/buttonGroup/buttonGroup.js b/imports/plugins/core/ui/client/components/buttonGroup/buttonGroup.js
index bf63fb46644..e30dd491260 100644
--- a/imports/plugins/core/ui/client/components/buttonGroup/buttonGroup.js
+++ b/imports/plugins/core/ui/client/components/buttonGroup/buttonGroup.js
@@ -1,24 +1,26 @@
-import React, { Component } from "react";
+import React from "react";
import PropTypes from "prop-types";
import classnames from "classnames";
+import { pure } from "recompose";
+import { registerComponent } from "@reactioncommerce/reaction-components";
-class ButtonGroup extends Component {
- render() {
- const baseClassName = classnames({
- "rui": true,
- "btn-group": true
- });
+const ButtonGroup = () => {
+ const baseClassName = classnames({
+ "rui": true,
+ "btn-group": true
+ });
- return (
-
- {this.props.children}
-
- );
- }
-}
+ return (
+
+ {this.props.children}
+
+ );
+};
ButtonGroup.propTypes = {
children: PropTypes.node
};
+registerComponent("ButtonGroup", ButtonGroup, pure);
+
export default ButtonGroup;
diff --git a/imports/plugins/core/ui/client/components/buttonGroup/buttonToolbar.js b/imports/plugins/core/ui/client/components/buttonGroup/buttonToolbar.js
index d6b34a2b6a4..0de06be4a3f 100644
--- a/imports/plugins/core/ui/client/components/buttonGroup/buttonToolbar.js
+++ b/imports/plugins/core/ui/client/components/buttonGroup/buttonToolbar.js
@@ -1,24 +1,26 @@
-import React, { Component } from "react";
+import React from "react";
import PropTypes from "prop-types";
import classnames from "classnames";
+import { pure } from "recompose";
+import { registerComponent } from "@reactioncommerce/reaction-components";
-class ButtonToolbar extends Component {
- render() {
- const baseClassName = classnames({
- "rui": true,
- "btn-toolbar": true
- });
+const ButtonToolbar = () => {
+ const baseClassName = classnames({
+ "rui": true,
+ "btn-toolbar": true
+ });
- return (
-
- {this.props.children}
-
- );
- }
-}
+ return (
+
+ {this.props.children}
+
+ );
+};
ButtonToolbar.propTypes = {
children: PropTypes.node
};
+registerComponent("ButtonToolbar", ButtonToolbar, pure);
+
export default ButtonToolbar;
diff --git a/imports/plugins/core/ui/client/components/cards/card.js b/imports/plugins/core/ui/client/components/cards/card.js
index 10d68956dec..18e2451d8f6 100644
--- a/imports/plugins/core/ui/client/components/cards/card.js
+++ b/imports/plugins/core/ui/client/components/cards/card.js
@@ -1,6 +1,7 @@
import React, { Children, Component } from "react";
import PropTypes from "prop-types";
import classnames from "classnames";
+import { registerComponent } from "@reactioncommerce/reaction-components";
class Card extends Component {
constructor(props) {
@@ -72,4 +73,6 @@ Card.propTypes = {
style: PropTypes.object
};
+registerComponent("Card", Card);
+
export default Card;
diff --git a/imports/plugins/core/ui/client/components/cards/cardBody.js b/imports/plugins/core/ui/client/components/cards/cardBody.js
index 1a08978cb2b..87c1f5dda59 100644
--- a/imports/plugins/core/ui/client/components/cards/cardBody.js
+++ b/imports/plugins/core/ui/client/components/cards/cardBody.js
@@ -3,6 +3,7 @@ import PropTypes from "prop-types";
import { VelocityTransitionGroup } from "velocity-react";
import Radium from "radium";
import classnames from "classnames";
+import { registerComponent } from "@reactioncommerce/reaction-components";
const styles = {
noPadding: {
@@ -57,4 +58,6 @@ class CardBody extends Component {
}
}
+registerComponent("CardBody", CardBody, Radium);
+
export default Radium(CardBody);
diff --git a/imports/plugins/core/ui/client/components/cards/cardGroup.js b/imports/plugins/core/ui/client/components/cards/cardGroup.js
index 298c7382fd9..00ca569dfb1 100644
--- a/imports/plugins/core/ui/client/components/cards/cardGroup.js
+++ b/imports/plugins/core/ui/client/components/cards/cardGroup.js
@@ -1,18 +1,17 @@
-import React, { Component } from "react";
+import React from "react";
import PropTypes from "prop-types";
+import { registerComponent } from "@reactioncommerce/reaction-components";
-class CardGroup extends Component {
- render() {
- return (
-
- {this.props.children}
-
- );
- }
-}
+const CardGroup = ({ children }) => (
+
+ {children}
+
+);
CardGroup.propTypes = {
children: PropTypes.node
};
+registerComponent("CardGroup", CardGroup);
+
export default CardGroup;
diff --git a/imports/plugins/core/ui/client/components/cards/cardHeader.js b/imports/plugins/core/ui/client/components/cards/cardHeader.js
index 7a85e184c43..91d627e982d 100644
--- a/imports/plugins/core/ui/client/components/cards/cardHeader.js
+++ b/imports/plugins/core/ui/client/components/cards/cardHeader.js
@@ -1,12 +1,9 @@
-import React, { Component } from "react";
+import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import classnames from "classnames";
-import CardTitle from "./cardTitle";
-import IconButton from "../button/iconButton";
-import Icon from "../icon/icon";
-import Switch from "../switch/switch";
+import { Components, registerComponent } from "@reactioncommerce/reaction-components";
-class CardHeader extends Component {
+class CardHeader extends PureComponent {
static defaultProps = {
actAsExpander: false,
expandable: false
@@ -49,7 +46,7 @@ class CardHeader extends Component {
renderTitle() {
if (this.props.title) {
return (
-
@@ -62,7 +59,7 @@ class CardHeader extends Component {
if (this.props.icon) {
return (
-
+
);
}
@@ -87,7 +84,7 @@ class CardHeader extends Component {
return (
-
{
+ const { element, ...rest } = props;
- if (element) {
- return React.cloneElement(element, props);
- }
-
- return (
-
-
- {this.props.children}
-
- );
+ if (element) {
+ return React.cloneElement(element, rest);
}
-}
+
+ return (
+
+
+ {props.children}
+
+ );
+};
CardTitle.propTypes = {
children: PropTypes.node,
@@ -26,4 +25,6 @@ CardTitle.propTypes = {
title: PropTypes.string
};
+registerComponent("CardTitle", CardTitle, pure);
+
export default CardTitle;
diff --git a/imports/plugins/core/ui/client/components/cards/cardToolbar.js b/imports/plugins/core/ui/client/components/cards/cardToolbar.js
index 1b706b1c798..99924a39c35 100644
--- a/imports/plugins/core/ui/client/components/cards/cardToolbar.js
+++ b/imports/plugins/core/ui/client/components/cards/cardToolbar.js
@@ -1,18 +1,19 @@
-import React, { Component } from "react";
+import React from "react";
import PropTypes from "prop-types";
+import { pure } from "recompose";
+import { registerComponent } from "@reactioncommerce/reaction-components";
-class CardToobar extends Component {
- static propTypes = {
- children: PropTypes.node
- }
+const CardToolbar = ({ children }) => (
+
+ {children}
+
+);
- render() {
- return (
-
- {this.props.children}
-
- );
- }
-}
-export default CardToobar;
+CardToolbar.propTypes = {
+ children: PropTypes.node
+};
+
+registerComponent("CardToolbar", CardToolbar, pure);
+
+export default CardToolbar;
diff --git a/imports/plugins/core/ui/client/components/cards/settingsCard.js b/imports/plugins/core/ui/client/components/cards/settingsCard.js
index 43ad0866b87..90444c07afa 100644
--- a/imports/plugins/core/ui/client/components/cards/settingsCard.js
+++ b/imports/plugins/core/ui/client/components/cards/settingsCard.js
@@ -3,14 +3,13 @@
* creation settings cards (panels) in the dashboard.
*/
-import React, { Component } from "react";
+import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import Blaze from "meteor/gadicc:blaze-react-component";
import { Reaction } from "/client/api";
-import { composeWithTracker } from "/lib/api/compose";
-import { Card, CardHeader, CardBody } from "/imports/plugins/core/ui/client/components";
+import { Components, registerComponent, composeWithTracker } from "@reactioncommerce/reaction-components";
-class SettingsCard extends Component {
+class SettingsCard extends PureComponent {
static defaultProps = {
showSwitch: true
}
@@ -71,13 +70,13 @@ class SettingsCard extends Component {
render() {
return (
-
-
-
+
{this.renderCardBody()}
-
-
+
+
);
}
}
@@ -99,10 +98,7 @@ class SettingsCard extends Component {
function composer(props, onData) {
if (props.packageName && props.saveOpenStateToPreferences) {
const preferences = Reaction.getUserPreferences(props.packageName, "settingsCards", {});
-
- onData(null, {
- preferences
- });
+ onData(null, { preferences });
} else {
onData(null, {});
}
@@ -110,4 +106,6 @@ function composer(props, onData) {
const decoratedComponent = composeWithTracker(composer)(SettingsCard);
+registerComponent("SettingsCard", SettingsCard, composeWithTracker(composer));
+
export default decoratedComponent;
diff --git a/imports/plugins/core/ui/client/components/checkbox/checkbox.js b/imports/plugins/core/ui/client/components/checkbox/checkbox.js
index 4541129e621..a316dad4e22 100644
--- a/imports/plugins/core/ui/client/components/checkbox/checkbox.js
+++ b/imports/plugins/core/ui/client/components/checkbox/checkbox.js
@@ -1,8 +1,8 @@
-import React, { Component } from "react";
+import React, { PureComponent } from "react";
import PropTypes from "prop-types";
-import { Translation } from "/imports/plugins/core/ui/client/components";
+import { Components, registerComponent } from "@reactioncommerce/reaction-components";
-class Checkbox extends Component {
+class Checkbox extends PureComponent {
handleChange = (event) => {
if (this.props.onChange) {
const isInputChecked = !this.props.checked;
@@ -19,7 +19,7 @@ class Checkbox extends Component {
ref="checkbox"
type="checkbox"
/>
-
+
);
}
@@ -37,4 +37,6 @@ Checkbox.propTypes = {
onChange: PropTypes.func
};
+registerComponent("Checkbox", Checkbox);
+
export default Checkbox;
diff --git a/imports/plugins/core/ui/client/components/clickToCopy/clickToCopy.js b/imports/plugins/core/ui/client/components/clickToCopy/clickToCopy.js
index fba723406d0..499e9a8da9b 100644
--- a/imports/plugins/core/ui/client/components/clickToCopy/clickToCopy.js
+++ b/imports/plugins/core/ui/client/components/clickToCopy/clickToCopy.js
@@ -1,9 +1,9 @@
-import React, { Component } from "react";
+import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import CopyToClipboard from "react-copy-to-clipboard";
-import { Tooltip, Translation } from "/imports/plugins/core/ui/client/components";
+import { Components, registerComponent } from "@reactioncommerce/reaction-components";
-class ClickToCopy extends Component {
+class ClickToCopy extends PureComponent {
constructor(props) {
super(props);
@@ -35,7 +35,7 @@ class ClickToCopy extends Component {
if (this.isTooltipOpen) {
if (typeof this.props.tooltip === "string") {
return (
-
+
);
}
@@ -58,14 +58,14 @@ class ClickToCopy extends Component {
onMouseOut={this.handleCtcMouseOut}
style={{ display: "inline-flex" }}
>
-
+
this.setState({ copied: true })}
>
{this.props.displayText}
-
+
);
}
@@ -84,4 +84,6 @@ ClickToCopy.defaultProps = {
tooltipPosition: "middle left"
};
+registerComponent("ClickToCopy", ClickToCopy);
+
export default ClickToCopy;
diff --git a/imports/plugins/core/ui/client/components/divider/divider.js b/imports/plugins/core/ui/client/components/divider/divider.js
index 3282868fa91..8670978f7a1 100644
--- a/imports/plugins/core/ui/client/components/divider/divider.js
+++ b/imports/plugins/core/ui/client/components/divider/divider.js
@@ -1,43 +1,37 @@
-import React, { Component } from "react";
+import React from "react";
import PropTypes from "prop-types";
import classnames from "classnames";
-import { Translation } from "../";
+import { pure } from "recompose";
+import { Components, registerComponent } from "@reactioncommerce/reaction-components";
-class Divider extends Component {
- renderLabel() {
- return (
-
- );
- }
-
- render() {
- const { label, i18nKeyLabel } = this.props;
- const classes = classnames({
- rui: true,
- separator: true,
- divider: true,
- labeled: label || i18nKeyLabel
- });
+const Divider = (props) => {
+ const { label, i18nKeyLabel } = props;
- if (label) {
- return (
-
-
-
-
-
-
-
- );
- }
+ const classes = classnames({
+ rui: true,
+ separator: true,
+ divider: true,
+ labeled: label || i18nKeyLabel
+ });
+ if (label) {
return (
-
+
+
+
+
+
);
}
-}
+
+ return (
+
+
+
+ );
+};
Divider.propTypes = {
i18nKeyLabel: PropTypes.string,
@@ -45,4 +39,6 @@ Divider.propTypes = {
label: PropTypes.string
};
+registerComponent("Divider", Divider, pure);
+
export default Divider;
diff --git a/imports/plugins/core/ui/client/components/divider/verticalDivider.js b/imports/plugins/core/ui/client/components/divider/verticalDivider.js
index 654a4bf8c9f..8ef725c02ce 100644
--- a/imports/plugins/core/ui/client/components/divider/verticalDivider.js
+++ b/imports/plugins/core/ui/client/components/divider/verticalDivider.js
@@ -1,14 +1,18 @@
import React from "react";
+import { pure } from "recompose";
+import { registerComponent } from "@reactioncommerce/reaction-components";
-export default function VerticalDivider() {
- return (
-
- );
-}
+const VerticalDivider = () => (
+
+);
+
+registerComponent("VerticalDivider", VerticalDivider, pure);
+
+export default VerticalDivider;
diff --git a/imports/plugins/core/ui/client/components/forms/form.js b/imports/plugins/core/ui/client/components/forms/form.js
index fbae19daee7..e266d143e14 100644
--- a/imports/plugins/core/ui/client/components/forms/form.js
+++ b/imports/plugins/core/ui/client/components/forms/form.js
@@ -2,7 +2,7 @@ import React, { Component } from "react";
import PropTypes from "prop-types";
import { map, update, set, at, isEqual } from "lodash";
import classnames from "classnames";
-import { Switch, Button, TextField, Select, FormActions } from "../";
+import { Components, registerComponent } from "@reactioncommerce/reaction-components";
class Form extends Component {
static defaultProps = {
@@ -151,7 +151,7 @@ class Form extends Component {
switch (field.type) {
case "boolean":
fieldElement = (
-
-