Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
view-container / dist / models / StyledNativeComponent.js
Size: Mime:
"use strict";
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
            t[p[i]] = s[p[i]];
    return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
// @flow
const hoist_non_react_statics_1 = __importDefault(require("hoist-non-react-statics"));
const prop_types_1 = __importDefault(require("prop-types"));
const react_1 = require("react");
const determineTheme_1 = __importDefault(require("../utils/determineTheme"));
const generateDisplayName_1 = __importDefault(require("../utils/generateDisplayName"));
const isStyledComponent_1 = __importDefault(require("../utils/isStyledComponent"));
const isTag_1 = __importDefault(require("../utils/isTag"));
const hasInInheritanceChain_1 = __importDefault(require("../utils/hasInInheritanceChain"));
const ThemeProvider_1 = require("./ThemeProvider");
const exporting = (constructWithOptions, InlineStyle) => {
    // $FlowFixMe
    class BaseStyledNativeComponent extends react_1.Component {
        constructor() {
            super(...arguments);
            this.attrs = {};
            this.state = {
                theme: null,
                generatedStyles: undefined,
            };
            this.unsubscribeId = -1;
            this.onRef = (node) => {
                // eslint-disable-next-line react/prop-types
                const { innerRef } = this.props;
                this.root = node;
                if (typeof innerRef === 'function') {
                    innerRef(node);
                }
                else if (typeof innerRef === 'object' &&
                    innerRef &&
                    innerRef.hasOwnProperty('current')) {
                    innerRef.current = node;
                }
            };
        }
        unsubscribeFromContext() {
            if (this.unsubscribeId !== -1) {
                this.context[ThemeProvider_1.CHANNEL_NEXT].unsubscribe(this.unsubscribeId);
            }
        }
        buildExecutionContext(theme, props) {
            const { attrs } = this.constructor;
            const context = Object.assign({}, props, { theme });
            if (attrs === undefined) {
                return context;
            }
            this.attrs = Object.keys(attrs).reduce((acc, key) => {
                const attr = attrs[key];
                // eslint-disable-next-line no-param-reassign
                acc[key] =
                    typeof attr === 'function' && !hasInInheritanceChain_1.default(attr, react_1.Component)
                        ? attr(context)
                        : attr;
                return acc;
            }, {});
            return Object.assign({}, context, this.attrs);
        }
        generateAndInjectStyles(theme, props) {
            const { inlineStyle } = this.constructor;
            const executionContext = this.buildExecutionContext(theme, props);
            return inlineStyle.generateStyleObject(executionContext);
        }
        componentWillMount() {
            // If there is a theme in the context, subscribe to the event emitter. This
            // is necessary due to pure components blocking context updates, this circumvents
            // that by updating when an event is emitted
            const styledContext = this.context[ThemeProvider_1.CHANNEL_NEXT];
            if (styledContext !== undefined) {
                const { subscribe } = styledContext;
                this.unsubscribeId = subscribe(nextTheme => {
                    // This will be called once immediately
                    const theme = determineTheme_1.default(this.props, nextTheme, this.constructor.defaultProps);
                    const generatedStyles = this.generateAndInjectStyles(theme, this.props);
                    this.setState({ theme, generatedStyles });
                });
            }
            else {
                // eslint-disable-next-line react/prop-types
                const theme = this.props.theme || {};
                const generatedStyles = this.generateAndInjectStyles(theme, this.props);
                this.setState({ theme, generatedStyles });
            }
        }
        componentWillReceiveProps(nextProps) {
            this.setState(prevState => {
                const theme = determineTheme_1.default(nextProps, prevState.theme, this.constructor.defaultProps);
                const generatedStyles = this.generateAndInjectStyles(theme, nextProps);
                return { theme, generatedStyles };
            });
        }
        componentWillUnmount() {
            this.unsubscribeFromContext();
        }
        setNativeProps(nativeProps) {
            if (this.root !== undefined) {
                // $FlowFixMe
                this.root.setNativeProps(nativeProps);
            }
            else if (process.env.NODE_ENV !== 'production') {
                const { displayName } = this.constructor;
                // eslint-disable-next-line no-console
                console.warn('setNativeProps was called on a Styled Component wrapping a stateless functional component. ' +
                    'In this case no ref will be stored, and instead an innerRef prop will be passed on.\n' +
                    `Check whether the stateless functional component is passing on innerRef as a ref in ${displayName ||
                        'UnknownStyledNativeComponent'}.`);
            }
        }
        render() {
            // eslint-disable-next-line react/prop-types
            const { children, style } = this.props;
            const { generatedStyles } = this.state;
            const { target } = this.constructor;
            const propsForElement = Object.assign({}, this.attrs, this.props, { style: [generatedStyles, style] });
            if (!isStyledComponent_1.default(target) &&
                // NOTE: We can't pass a ref to a stateless functional component
                (typeof target !== 'function' ||
                    // $FlowFixMe TODO: flow for prototype
                    (target.prototype && 'isReactComponent' in target.prototype))) {
                propsForElement.ref = this.onRef;
                delete propsForElement.innerRef;
            }
            else {
                propsForElement.innerRef = this.onRef;
            }
            return react_1.createElement(target, propsForElement, children);
        }
    }
    const createStyledNativeComponent = (target, options, rules) => {
        const { isClass = !isTag_1.default(target), displayName = generateDisplayName_1.default(target), ParentComponent = BaseStyledNativeComponent, rules: extendingRules, attrs, } = options;
        const inlineStyle = new InlineStyle(extendingRules === undefined ? rules : extendingRules.concat(rules));
        class StyledNativeComponent extends ParentComponent {
            static withComponent(tag) {
                const { displayName: _, componentId: __ } = options, optionsToCopy = __rest(options, ["displayName", "componentId"]);
                const newOptions = Object.assign({}, optionsToCopy, { ParentComponent: StyledNativeComponent });
                return createStyledNativeComponent(tag, newOptions, rules);
            }
            static get extend() {
                const { displayName: _, componentId: __, rules: rulesFromOptions } = options, optionsToCopy = __rest(options, ["displayName", "componentId", "rules"]);
                const newRules = rulesFromOptions === undefined
                    ? rules
                    : rulesFromOptions.concat(rules);
                const newOptions = Object.assign({}, optionsToCopy, { rules: newRules, ParentComponent: StyledNativeComponent });
                return constructWithOptions(createStyledNativeComponent, target, newOptions);
            }
        }
        StyledNativeComponent.attrs = attrs;
        StyledNativeComponent.displayName = displayName;
        StyledNativeComponent.inlineStyle = inlineStyle;
        StyledNativeComponent.styledComponentId = 'StyledNativeComponent';
        StyledNativeComponent.target = target;
        StyledNativeComponent.contextTypes = {
            [ThemeProvider_1.CHANNEL]: prop_types_1.default.func,
            [ThemeProvider_1.CHANNEL_NEXT]: ThemeProvider_1.CONTEXT_CHANNEL_SHAPE,
        };
        if (isClass) {
            hoist_non_react_statics_1.default(StyledNativeComponent, target, {
                // all SC-specific things should not be hoisted
                attrs: true,
                displayName: true,
                extend: true,
                inlineStyle: true,
                styledComponentId: true,
                target: true,
                withComponent: true,
            });
        }
        return StyledNativeComponent;
    };
    return createStyledNativeComponent;
};
exports.default = exporting;
//# sourceMappingURL=StyledNativeComponent.js.map