lucid-ui
Version:
A UI component library from AppNexus.
190 lines (163 loc) • 9.39 kB
JavaScript
import _keys from "lodash/keys";
import _omit from "lodash/omit";
import _first from "lodash/first";
import _reject from "lodash/reject";
import _pick from "lodash/pick";
import _values from "lodash/values";
import _flatten from "lodash/flatten";
import _isNil from "lodash/isNil";
import _reduce from "lodash/reduce";
import _castArray from "lodash/castArray";
import _includes from "lodash/includes";
import _filter from "lodash/filter";
import _isUndefined from "lodash/isUndefined";
import _mapValues from "lodash/mapValues";
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
import React from 'react';
import createReactClass from 'create-react-class';
import PropTypes from 'react-peek/prop-types';
import { isPlainObjectOrEsModule, omitFunctionPropsDeep } from './state-management';
// creates a React component
export function createClass(spec) {
var _spec$_isPrivate = spec._isPrivate,
_isPrivate = _spec$_isPrivate === void 0 ? false : _spec$_isPrivate,
getDefaultProps = spec.getDefaultProps,
_spec$statics = spec.statics,
statics = _spec$statics === void 0 ? {} : _spec$statics,
_spec$components = spec.components,
components = _spec$components === void 0 ? {} : _spec$components,
_spec$reducers = spec.reducers,
reducers = _spec$reducers === void 0 ? {} : _spec$reducers,
_spec$selectors = spec.selectors,
selectors = _spec$selectors === void 0 ? {} : _spec$selectors,
_spec$initialState = spec.initialState,
initialState = _spec$initialState === void 0 ? getDefaultProps && omitFunctionPropsDeep(getDefaultProps.apply(spec)) : _spec$initialState,
_spec$propName = spec.propName,
propName = _spec$propName === void 0 ? null : _spec$propName,
_spec$propTypes = spec.propTypes,
propTypes = _spec$propTypes === void 0 ? {} : _spec$propTypes,
_spec$render = spec.render,
render = _spec$render === void 0 ? function () {
return null;
} : _spec$render,
restDefinition = _objectWithoutProperties(spec, ["_isPrivate", "getDefaultProps", "statics", "components", "reducers", "selectors", "initialState", "propName", "propTypes", "render"]);
var propTypeValidators = _objectSpread(_objectSpread({}, propTypes), _mapValues(spec.components, function (componentValue, componentKey) {
return PropTypes.any;
})); // Intentionally keep this object type inferred so it can be passed to
// `createReactClass`
var newDefinition = _objectSpread(_objectSpread({
getDefaultProps: getDefaultProps
}, restDefinition), {}, {
statics: _objectSpread(_objectSpread(_objectSpread({}, statics), components), {}, {
_isPrivate: _isPrivate,
reducers: reducers,
selectors: selectors,
initialState: initialState,
propName: propName
}),
propTypes: propTypeValidators,
render: render
});
if (!_isUndefined(newDefinition.statics)) {
newDefinition.statics.definition = newDefinition;
}
var newClass = createReactClass(newDefinition); // This conditional (and breaking change) was introduced to help us move from
// legacy React classes to functional components & es6 classes which lack
// `getDefaultProps`.
if (newClass.getDefaultProps) {
newClass.defaultProps = newClass.getDefaultProps();
delete newClass.getDefaultProps;
}
return newClass;
} // return all elements matching the specified types
export function filterTypes(children, types) {
if (types === undefined) return [];
return _filter(React.Children.toArray(children), function (element) {
return /*#__PURE__*/React.isValidElement(element) && _includes(_castArray(types), element.type);
});
} // return all elements found in props and children of the specified types
export function findTypes(props, types) {
if (types === undefined) {
return [];
} // get elements from props (using types.propName)
var elementsFromProps = _reduce(_castArray(types), function (acc, type) {
return _isNil(type.propName) ? [] : createElements(type, _flatten(_values(_pick(props, type.propName))));
}, []);
if (props.children === undefined) {
return elementsFromProps;
} // return elements from props and elements from children
return elementsFromProps.concat(filterTypes(props.children, types));
} // return all elements found in props and children of the specified types
// export function findTypes<P2>(
// props: { children?: React.ReactNode },
// types?: TypesType<P2>
// ): React.ReactNode[] {
// if (types === undefined) {
// return [];
// }
// // get elements from props (using types.propName)
// const elementsFromProps: React.ReactNode[] = _.reduce(
// _.castArray<any>(types),
// (acc: React.ReactNode[], type): React.ReactNode[] => {
// return _.isNil(type.propName)
// ? []
// : createElements(
// type,
// _.flatten(_.values(_.pick(props, type.propName)))
// );
// },
// []
// );
// if (props.children === undefined) {
// return elementsFromProps;
// }
// // return elements from props and elements from children
// return elementsFromProps.concat(filterTypes<P2>(props.children, types));
// }
// return all elements not matching the specified types
export function rejectTypes(children, types) {
types = [].concat(types); // coerce to Array
return _reject(React.Children.toArray(children), function (element) {
return /*#__PURE__*/React.isValidElement(element) && _includes(types, element.type);
});
} // return an array of elements (of the given type) for each of the values
export function createElements(type) {
var values = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
return _reduce(values, function (elements, typeValue) {
if ( /*#__PURE__*/React.isValidElement(typeValue) && typeValue.type === type) {
return elements.concat(typeValue);
} else if (isPlainObjectOrEsModule(typeValue) && ! /*#__PURE__*/React.isValidElement(typeValue)) {
return elements.concat( /*#__PURE__*/React.createElement(type, typeValue));
} else if (_isUndefined(typeValue)) {
return elements;
} else {
return elements.concat( /*#__PURE__*/React.createElement(type, null, typeValue));
}
}, []);
} // return the first element found in props and children of the specificed type(s)
export function getFirst(props, types, defaultValue) {
return _first(findTypes(props, types)) || defaultValue;
} // Omit props defined in propTypes of the given type and any extra keys given
// in third argument
//
// We also have a "magic" prop that's always excluded called `callbackId`. That
// prop can be used to identify a component in a list without having to create
// extra closures.
//
// Note: The Partial<P> type is referring to the props passed into the omitProps,
// not the props defined on the component.
export function omitProps(props, component) {
var keys = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
var targetIsDOMElement = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
// We only want to exclude the `callbackId` key when we're omitting props
// destined for a dom element
var additionalOmittedKeys = targetIsDOMElement ? ['initialState', 'callbackId'] : ['initialState']; // this is to support non-createClass components that we've converted to TypeScript
if (component === undefined) {
return _omit(props, keys.concat(additionalOmittedKeys));
}
return _omit(props, _keys(component.propTypes).concat(keys).concat(additionalOmittedKeys));
}