UNPKG

react-ionicons

Version:

A React SVG ionicon component

1,773 lines (1,490 loc) • 65.8 kB
import isPlainObject from 'is-plain-object'; import Stylis from 'stylis'; import React, { Component, createElement } from 'react'; import PropTypes from 'prop-types'; import isFunction from 'is-function'; import hoistStatics from 'hoist-non-react-statics'; /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * @typechecks */ var _uppercasePattern = /([A-Z])/g; /** * Hyphenates a camelcased string, for example: * * > hyphenate('backgroundColor') * < "background-color" * * For CSS style names, use `hyphenateStyleName` instead which works properly * with all vendor prefixes, including `ms`. * * @param {string} string * @return {string} */ function hyphenate$2(string) { return string.replace(_uppercasePattern, '-$1').toLowerCase(); } var hyphenate_1 = hyphenate$2; var hyphenate = hyphenate_1; var msPattern = /^ms-/; /** * Hyphenates a camelcased CSS property name, for example: * * > hyphenateStyleName('backgroundColor') * < "background-color" * > hyphenateStyleName('MozTransition') * < "-moz-transition" * > hyphenateStyleName('msTransition') * < "-ms-transition" * * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix * is converted to `-ms-`. * * @param {string} string * @return {string} */ function hyphenateStyleName(string) { return hyphenate(string).replace(msPattern, '-ms-'); } var hyphenateStyleName_1 = hyphenateStyleName; // var objToCss = function objToCss(obj, prevKey) { var css = Object.keys(obj).filter(function (key) { var chunk = obj[key]; return chunk !== undefined && chunk !== null && chunk !== false && chunk !== ''; }).map(function (key) { if (isPlainObject(obj[key])) return objToCss(obj[key], key); return hyphenateStyleName_1(key) + ': ' + obj[key] + ';'; }).join(' '); return prevKey ? prevKey + ' {\n ' + css + '\n}' : css; }; var flatten = function flatten(chunks, executionContext) { return chunks.reduce(function (ruleSet, chunk) { /* Remove falsey values */ if (chunk === undefined || chunk === null || chunk === false || chunk === '') return ruleSet; /* Flatten ruleSet */ if (Array.isArray(chunk)) return [].concat(ruleSet, flatten(chunk, executionContext)); /* Handle other components */ // $FlowFixMe not sure how to make this pass if (chunk.hasOwnProperty('styledComponentId')) return [].concat(ruleSet, ['.' + chunk.styledComponentId]); /* Either execute or defer the function */ if (typeof chunk === 'function') { return executionContext ? ruleSet.concat.apply(ruleSet, flatten([chunk(executionContext)], executionContext)) : ruleSet.concat(chunk); } /* Handle objects */ // $FlowFixMe have to add %checks somehow to isPlainObject return ruleSet.concat(isPlainObject(chunk) ? objToCss(chunk) : chunk.toString()); }, []); }; // var stylis = new Stylis({ global: false, cascade: true, keyframe: false, prefix: true, compress: false, semicolon: true }); var stringifyRules = function stringifyRules(rules, selector, prefix) { var flatCSS = rules.join('').replace(/^\s*\/\/.*$/gm, ''); // replace JS comments var cssStr = selector && prefix ? prefix + ' ' + selector + ' { ' + flatCSS + ' }' : flatCSS; return stylis(prefix || !selector ? '' : selector, cssStr); }; // var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''); var charsLength = chars.length; /* Some high number, usually 9-digit base-10. Map it to base-šŸ˜Ž */ var generateAlphabeticName = function generateAlphabeticName(code) { var name = ''; var x = void 0; for (x = code; x > charsLength; x = Math.floor(x / charsLength)) { name = chars[x % charsLength] + name; } return chars[x % charsLength] + name; }; // var interleave = (function (strings, interpolations) { return interpolations.reduce(function (array, interp, i) { return array.concat(interp, strings[i + 1]); }, [strings[0]]); }); // var css = (function (strings) { for (var _len = arguments.length, interpolations = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { interpolations[_key - 1] = arguments[_key]; } return flatten(interleave(strings, interpolations)); }); // var SC_COMPONENT_ID = /^[^\S\n]*?\/\* sc-component-id:\s+(\S+)\s+\*\//mg; var extractCompsFromCSS = (function (maybeCSS) { var css = '' + (maybeCSS || ''); // Definitely a string, and a clone var existingComponents = []; css.replace(SC_COMPONENT_ID, function (match, componentId, matchIndex) { existingComponents.push({ componentId: componentId, matchIndex: matchIndex }); return match; }); return existingComponents.map(function (_ref, i) { var componentId = _ref.componentId, matchIndex = _ref.matchIndex; var nextComp = existingComponents[i + 1]; var cssFromDOM = nextComp ? css.slice(matchIndex, nextComp.matchIndex) : css.slice(matchIndex); return { componentId: componentId, cssFromDOM: cssFromDOM }; }); }); // /* eslint-disable camelcase, no-undef */ var getNonce = (function () { return typeof __webpack_nonce__ !== 'undefined' ? __webpack_nonce__ : null; }); var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }; var objectWithoutProperties = function (obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }; var possibleConstructorReturn = function (self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }; // /* eslint-disable no-underscore-dangle */ /* * Browser Style Sheet with Rehydration * * <style data-styled-components="x y z" * data-styled-components-is-local="true"> * /Ā· sc-component-id: a Ā·/ * .sc-a { ... } * .x { ... } * /Ā· sc-component-id: b Ā·/ * .sc-b { ... } * .y { ... } * .z { ... } * </style> * * Note: replace Ā· with * in the above snippet. * */ var COMPONENTS_PER_TAG = 40; var BrowserTag = function () { function BrowserTag(el, isLocal) { var existingSource = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; classCallCheck(this, BrowserTag); this.el = el; this.isLocal = isLocal; this.ready = false; var extractedComps = extractCompsFromCSS(existingSource); this.size = extractedComps.length; this.components = extractedComps.reduce(function (acc, obj) { acc[obj.componentId] = obj; // eslint-disable-line no-param-reassign return acc; }, {}); } BrowserTag.prototype.isFull = function isFull() { return this.size >= COMPONENTS_PER_TAG; }; BrowserTag.prototype.addComponent = function addComponent(componentId) { if (!this.ready) this.replaceElement(); if (this.components[componentId]) throw new Error('Trying to add Component \'' + componentId + '\' twice!'); var comp = { componentId: componentId, textNode: document.createTextNode('') }; this.el.appendChild(comp.textNode); this.size += 1; this.components[componentId] = comp; }; BrowserTag.prototype.inject = function inject(componentId, css, name) { if (!this.ready) this.replaceElement(); var comp = this.components[componentId]; if (!comp) throw new Error('Must add a new component before you can inject css into it'); if (comp.textNode.data === '') comp.textNode.appendData('\n/* sc-component-id: ' + componentId + ' */\n'); comp.textNode.appendData(css); if (name) { var existingNames = this.el.getAttribute(SC_ATTR); this.el.setAttribute(SC_ATTR, existingNames ? existingNames + ' ' + name : name); } var nonce = getNonce(); if (nonce) { this.el.setAttribute('nonce', nonce); } }; BrowserTag.prototype.toHTML = function toHTML() { return this.el.outerHTML; }; BrowserTag.prototype.toReactElement = function toReactElement() { throw new Error('BrowserTag doesn\'t implement toReactElement!'); }; BrowserTag.prototype.clone = function clone() { throw new Error('BrowserTag cannot be cloned!'); }; /* Because we care about source order, before we can inject anything we need to * create a text node for each component and replace the existing CSS. */ BrowserTag.prototype.replaceElement = function replaceElement() { var _this = this; this.ready = true; // We have nothing to inject. Use the current el. if (this.size === 0) return; // Build up our replacement style tag var newEl = this.el.cloneNode(); newEl.appendChild(document.createTextNode('\n')); Object.keys(this.components).forEach(function (key) { var comp = _this.components[key]; // eslint-disable-next-line no-param-reassign comp.textNode = document.createTextNode(comp.cssFromDOM); newEl.appendChild(comp.textNode); }); if (!this.el.parentNode) throw new Error("Trying to replace an element that wasn't mounted!"); // The ol' switcheroo this.el.parentNode.replaceChild(newEl, this.el); this.el = newEl; }; return BrowserTag; }(); /* Factory function to separate DOM operations from logical ones*/ var BrowserStyleSheet = { create: function create() { var tags = []; var names = {}; /* Construct existing state from DOM */ var nodes = document.querySelectorAll('[' + SC_ATTR + ']'); var nodesLength = nodes.length; for (var i = 0; i < nodesLength; i += 1) { var el = nodes[i]; tags.push(new BrowserTag(el, el.getAttribute(LOCAL_ATTR) === 'true', el.innerHTML)); var attr = el.getAttribute(SC_ATTR); if (attr) { attr.trim().split(/\s+/).forEach(function (name) { names[name] = true; }); } } /* Factory for making more tags */ var tagConstructor = function tagConstructor(isLocal) { var el = document.createElement('style'); el.type = 'text/css'; el.setAttribute(SC_ATTR, ''); el.setAttribute(LOCAL_ATTR, isLocal ? 'true' : 'false'); if (!document.head) throw new Error('Missing document <head>'); document.head.appendChild(el); return new BrowserTag(el, isLocal); }; return new StyleSheet(tagConstructor, tags, names); } }; // var SC_ATTR = 'data-styled-components'; var LOCAL_ATTR = 'data-styled-components-is-local'; var CONTEXT_KEY = '__styled-components-stylesheet__'; var instance = null; // eslint-disable-next-line no-use-before-define var clones = []; var StyleSheet = function () { function StyleSheet(tagConstructor) { var tags = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; var names = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; classCallCheck(this, StyleSheet); this.hashes = {}; this.deferredInjections = {}; this.stylesCacheable = typeof document !== 'undefined'; this.tagConstructor = tagConstructor; this.tags = tags; this.names = names; this.constructComponentTagMap(); } // helper for `ComponentStyle` to know when it cache static styles. // staticly styled-component can not safely cache styles on the server // without all `ComponentStyle` instances saving a reference to the // the styleSheet instance they last rendered with, // or listening to creation / reset events. otherwise you might create // a component with one stylesheet and render it another api response // with another, losing styles on from your server-side render. StyleSheet.prototype.constructComponentTagMap = function constructComponentTagMap() { var _this = this; this.componentTags = {}; this.tags.forEach(function (tag) { Object.keys(tag.components).forEach(function (componentId) { _this.componentTags[componentId] = tag; }); }); }; /* Best level of caching—get the name from the hash straight away. */ StyleSheet.prototype.getName = function getName(hash) { return this.hashes[hash.toString()]; }; /* Second level of caching—if the name is already in the dom, don't * inject anything and record the hash for getName next time. */ StyleSheet.prototype.alreadyInjected = function alreadyInjected(hash, name) { if (!this.names[name]) return false; this.hashes[hash.toString()] = name; return true; }; /* Third type of caching—don't inject components' componentId twice. */ StyleSheet.prototype.hasInjectedComponent = function hasInjectedComponent(componentId) { return !!this.componentTags[componentId]; }; StyleSheet.prototype.deferredInject = function deferredInject(componentId, isLocal, css) { if (this === instance) { clones.forEach(function (clone) { clone.deferredInject(componentId, isLocal, css); }); } this.getOrCreateTag(componentId, isLocal); this.deferredInjections[componentId] = css; }; StyleSheet.prototype.inject = function inject(componentId, isLocal, css, hash, name) { if (this === instance) { clones.forEach(function (clone) { clone.inject(componentId, isLocal, css); }); } var tag = this.getOrCreateTag(componentId, isLocal); var deferredInjection = this.deferredInjections[componentId]; if (deferredInjection) { tag.inject(componentId, deferredInjection); delete this.deferredInjections[componentId]; } tag.inject(componentId, css, name); if (hash && name) { this.hashes[hash.toString()] = name; } }; StyleSheet.prototype.toHTML = function toHTML() { return this.tags.map(function (tag) { return tag.toHTML(); }).join(''); }; StyleSheet.prototype.toReactElements = function toReactElements() { return this.tags.map(function (tag, i) { return tag.toReactElement('sc-' + i); }); }; StyleSheet.prototype.getOrCreateTag = function getOrCreateTag(componentId, isLocal) { var existingTag = this.componentTags[componentId]; if (existingTag) { return existingTag; } var lastTag = this.tags[this.tags.length - 1]; var componentTag = !lastTag || lastTag.isFull() || lastTag.isLocal !== isLocal ? this.createNewTag(isLocal) : lastTag; this.componentTags[componentId] = componentTag; componentTag.addComponent(componentId); return componentTag; }; StyleSheet.prototype.createNewTag = function createNewTag(isLocal) { var newTag = this.tagConstructor(isLocal); this.tags.push(newTag); return newTag; }; StyleSheet.reset = function reset(isServer) { instance = StyleSheet.create(isServer); }; /* We can make isServer totally implicit once Jest 20 drops and we * can change environment on a per-test basis. */ StyleSheet.create = function create() { var isServer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : typeof document === 'undefined'; return (isServer ? ServerStyleSheet : BrowserStyleSheet).create(); }; StyleSheet.clone = function clone(oldSheet) { var newSheet = new StyleSheet(oldSheet.tagConstructor, oldSheet.tags.map(function (tag) { return tag.clone(); }), _extends({}, oldSheet.names)); newSheet.hashes = _extends({}, oldSheet.hashes); newSheet.deferredInjections = _extends({}, oldSheet.deferredInjections); clones.push(newSheet); return newSheet; }; createClass(StyleSheet, null, [{ key: 'instance', get: function get$$1() { return instance || (instance = StyleSheet.create()); } }]); return StyleSheet; }(); var _StyleSheetManager$ch; // var StyleSheetManager = function (_Component) { inherits(StyleSheetManager, _Component); function StyleSheetManager() { classCallCheck(this, StyleSheetManager); return possibleConstructorReturn(this, _Component.apply(this, arguments)); } StyleSheetManager.prototype.getChildContext = function getChildContext() { var _ref; return _ref = {}, _ref[CONTEXT_KEY] = this.props.sheet, _ref; }; StyleSheetManager.prototype.render = function render() { /* eslint-disable react/prop-types */ // Flow v0.43.1 will report an error accessing the `children` property, // but v0.47.0 will not. It is necessary to use a type cast instead of // a "fixme" comment to satisfy both Flow versions. return React.Children.only(this.props.children); }; return StyleSheetManager; }(Component); StyleSheetManager.childContextTypes = (_StyleSheetManager$ch = {}, _StyleSheetManager$ch[CONTEXT_KEY] = PropTypes.oneOfType([PropTypes.instanceOf(StyleSheet), PropTypes.instanceOf(ServerStyleSheet)]).isRequired, _StyleSheetManager$ch); StyleSheetManager.propTypes = { sheet: PropTypes.oneOfType([PropTypes.instanceOf(StyleSheet), PropTypes.instanceOf(ServerStyleSheet)]).isRequired }; // /* eslint-disable no-underscore-dangle */ var ServerTag = function () { function ServerTag(isLocal) { classCallCheck(this, ServerTag); this.isLocal = isLocal; this.components = {}; this.size = 0; this.names = []; } ServerTag.prototype.isFull = function isFull() { return false; }; ServerTag.prototype.addComponent = function addComponent(componentId) { if (this.components[componentId]) throw new Error('Trying to add Component \'' + componentId + '\' twice!'); this.components[componentId] = { componentId: componentId, css: '' }; this.size += 1; }; ServerTag.prototype.concatenateCSS = function concatenateCSS() { var _this = this; return Object.keys(this.components).reduce(function (styles, k) { return styles + _this.components[k].css; }, ''); }; ServerTag.prototype.inject = function inject(componentId, css, name) { var comp = this.components[componentId]; if (!comp) throw new Error('Must add a new component before you can inject css into it'); if (comp.css === '') comp.css = '/* sc-component-id: ' + componentId + ' */\n'; comp.css += css.replace(/\n*$/, '\n'); if (name) this.names.push(name); }; ServerTag.prototype.toHTML = function toHTML() { var attrs = ['type="text/css"', SC_ATTR + '="' + this.names.join(' ') + '"', LOCAL_ATTR + '="' + (this.isLocal ? 'true' : 'false') + '"']; var nonce = getNonce(); if (nonce) { attrs.push('nonce="' + nonce + '"'); } return '<style ' + attrs.join(' ') + '>' + this.concatenateCSS() + '</style>'; }; ServerTag.prototype.toReactElement = function toReactElement(key) { var _attrs; var attrs = (_attrs = {}, _attrs[SC_ATTR] = this.names.join(' '), _attrs[LOCAL_ATTR] = this.isLocal.toString(), _attrs); var nonce = getNonce(); if (nonce) { attrs.nonce = nonce; } return React.createElement('style', _extends({ key: key, type: 'text/css' }, attrs, { dangerouslySetInnerHTML: { __html: this.concatenateCSS() } })); }; ServerTag.prototype.clone = function clone() { var _this2 = this; var copy = new ServerTag(this.isLocal); copy.names = [].concat(this.names); copy.size = this.size; copy.components = Object.keys(this.components).reduce(function (acc, key) { acc[key] = _extends({}, _this2.components[key]); // eslint-disable-line no-param-reassign return acc; }, {}); return copy; }; return ServerTag; }(); var ServerStyleSheet = function () { function ServerStyleSheet() { classCallCheck(this, ServerStyleSheet); this.instance = StyleSheet.clone(StyleSheet.instance); } ServerStyleSheet.prototype.collectStyles = function collectStyles(children) { if (this.closed) throw new Error("Can't collect styles once you've called getStyleTags!"); return React.createElement( StyleSheetManager, { sheet: this.instance }, children ); }; ServerStyleSheet.prototype.getStyleTags = function getStyleTags() { if (!this.closed) { clones.splice(clones.indexOf(this.instance), 1); this.closed = true; } return this.instance.toHTML(); }; ServerStyleSheet.prototype.getStyleElement = function getStyleElement() { if (!this.closed) { clones.splice(clones.indexOf(this.instance), 1); this.closed = true; } return this.instance.toReactElements(); }; ServerStyleSheet.create = function create() { return new StyleSheet(function (isLocal) { return new ServerTag(isLocal); }); }; return ServerStyleSheet; }(); // var LIMIT = 200; var createWarnTooManyClasses = (function (displayName) { var generatedClasses = {}; var warningSeen = false; return function (className) { if (!warningSeen) { generatedClasses[className] = true; if (Object.keys(generatedClasses).length >= LIMIT) { // Unable to find latestRule in test environment. /* eslint-disable no-console, prefer-template */ console.warn('Over ' + LIMIT + ' classes were generated for component ' + displayName + '. \n' + 'Consider using the attrs method, together with a style object for frequently changed styles.\n' + 'Example:\n' + ' const Component = styled.div.attrs({\n' + ' style: ({ background }) => ({\n' + ' background,\n' + ' }),\n' + ' })`width: 100%;`\n\n' + ' <Component />'); warningSeen = true; generatedClasses = {}; } } }; }); // /* Trying to avoid the unknown-prop errors on styled components by filtering by React's attribute whitelist. */ /* Logic copied from ReactDOMUnknownPropertyHook */ var reactProps = { children: true, dangerouslySetInnerHTML: true, key: true, ref: true, autoFocus: true, defaultValue: true, valueLink: true, defaultChecked: true, checkedLink: true, innerHTML: true, suppressContentEditableWarning: true, onFocusIn: true, onFocusOut: true, className: true, /* List copied from https://facebook.github.io/react/docs/events.html */ onCopy: true, onCut: true, onPaste: true, onCompositionEnd: true, onCompositionStart: true, onCompositionUpdate: true, onKeyDown: true, onKeyPress: true, onKeyUp: true, onFocus: true, onBlur: true, onChange: true, onInput: true, onSubmit: true, onReset: true, onClick: true, onContextMenu: true, onDoubleClick: true, onDrag: true, onDragEnd: true, onDragEnter: true, onDragExit: true, onDragLeave: true, onDragOver: true, onDragStart: true, onDrop: true, onMouseDown: true, onMouseEnter: true, onMouseLeave: true, onMouseMove: true, onMouseOut: true, onMouseOver: true, onMouseUp: true, onSelect: true, onTouchCancel: true, onTouchEnd: true, onTouchMove: true, onTouchStart: true, onScroll: true, onWheel: true, onAbort: true, onCanPlay: true, onCanPlayThrough: true, onDurationChange: true, onEmptied: true, onEncrypted: true, onEnded: true, onError: true, onLoadedData: true, onLoadedMetadata: true, onLoadStart: true, onPause: true, onPlay: true, onPlaying: true, onProgress: true, onRateChange: true, onSeeked: true, onSeeking: true, onStalled: true, onSuspend: true, onTimeUpdate: true, onVolumeChange: true, onWaiting: true, onLoad: true, onAnimationStart: true, onAnimationEnd: true, onAnimationIteration: true, onTransitionEnd: true, onCopyCapture: true, onCutCapture: true, onPasteCapture: true, onCompositionEndCapture: true, onCompositionStartCapture: true, onCompositionUpdateCapture: true, onKeyDownCapture: true, onKeyPressCapture: true, onKeyUpCapture: true, onFocusCapture: true, onBlurCapture: true, onChangeCapture: true, onInputCapture: true, onSubmitCapture: true, onResetCapture: true, onClickCapture: true, onContextMenuCapture: true, onDoubleClickCapture: true, onDragCapture: true, onDragEndCapture: true, onDragEnterCapture: true, onDragExitCapture: true, onDragLeaveCapture: true, onDragOverCapture: true, onDragStartCapture: true, onDropCapture: true, onMouseDownCapture: true, onMouseEnterCapture: true, onMouseLeaveCapture: true, onMouseMoveCapture: true, onMouseOutCapture: true, onMouseOverCapture: true, onMouseUpCapture: true, onSelectCapture: true, onTouchCancelCapture: true, onTouchEndCapture: true, onTouchMoveCapture: true, onTouchStartCapture: true, onScrollCapture: true, onWheelCapture: true, onAbortCapture: true, onCanPlayCapture: true, onCanPlayThroughCapture: true, onDurationChangeCapture: true, onEmptiedCapture: true, onEncryptedCapture: true, onEndedCapture: true, onErrorCapture: true, onLoadedDataCapture: true, onLoadedMetadataCapture: true, onLoadStartCapture: true, onPauseCapture: true, onPlayCapture: true, onPlayingCapture: true, onProgressCapture: true, onRateChangeCapture: true, onSeekedCapture: true, onSeekingCapture: true, onStalledCapture: true, onSuspendCapture: true, onTimeUpdateCapture: true, onVolumeChangeCapture: true, onWaitingCapture: true, onLoadCapture: true, onAnimationStartCapture: true, onAnimationEndCapture: true, onAnimationIterationCapture: true, onTransitionEndCapture: true }; /* From HTMLDOMPropertyConfig */ var htmlProps = { /** * Standard Properties */ accept: true, acceptCharset: true, accessKey: true, action: true, allowFullScreen: true, allowTransparency: true, alt: true, // specifies target context for links with `preload` type as: true, async: true, autoComplete: true, // autoFocus is polyfilled/normalized by AutoFocusUtils // autoFocus: true, autoPlay: true, capture: true, cellPadding: true, cellSpacing: true, charSet: true, challenge: true, checked: true, cite: true, classID: true, className: true, cols: true, colSpan: true, content: true, contentEditable: true, contextMenu: true, controls: true, coords: true, crossOrigin: true, data: true, // For `<object />` acts as `src`. dateTime: true, default: true, defer: true, dir: true, disabled: true, download: true, draggable: true, encType: true, form: true, formAction: true, formEncType: true, formMethod: true, formNoValidate: true, formTarget: true, frameBorder: true, headers: true, height: true, hidden: true, high: true, href: true, hrefLang: true, htmlFor: true, httpEquiv: true, icon: true, id: true, inputMode: true, integrity: true, is: true, keyParams: true, keyType: true, kind: true, label: true, lang: true, list: true, loop: true, low: true, manifest: true, marginHeight: true, marginWidth: true, max: true, maxLength: true, media: true, mediaGroup: true, method: true, min: true, minLength: true, // Caution; `option.selected` is not updated if `select.multiple` is // disabled with `removeAttribute`. multiple: true, muted: true, name: true, nonce: true, noValidate: true, open: true, optimum: true, pattern: true, placeholder: true, playsInline: true, poster: true, preload: true, profile: true, radioGroup: true, readOnly: true, referrerPolicy: true, rel: true, required: true, reversed: true, role: true, rows: true, rowSpan: true, sandbox: true, scope: true, scoped: true, scrolling: true, seamless: true, selected: true, shape: true, size: true, sizes: true, span: true, spellCheck: true, src: true, srcDoc: true, srcLang: true, srcSet: true, start: true, step: true, style: true, summary: true, tabIndex: true, target: true, title: true, // Setting .type throws on non-<input> tags type: true, useMap: true, value: true, width: true, wmode: true, wrap: true, /** * RDFa Properties */ about: true, datatype: true, inlist: true, prefix: true, // property is also supported for OpenGraph in meta tags. property: true, resource: true, typeof: true, vocab: true, /** * Non-standard Properties */ // autoCapitalize and autoCorrect are supported in Mobile Safari for // keyboard hints. autoCapitalize: true, autoCorrect: true, // autoSave allows WebKit/Blink to persist values of input fields on page reloads autoSave: true, // color is for Safari mask-icon link color: true, // itemProp, itemScope, itemType are for // Microdata support. See http://schema.org/docs/gs.html itemProp: true, itemScope: true, itemType: true, // itemID and itemRef are for Microdata support as well but // only specified in the WHATWG spec document. See // https://html.spec.whatwg.org/multipage/microdata.html#microdata-dom-api itemID: true, itemRef: true, // results show looking glass icon and recent searches on input // search fields in WebKit/Blink results: true, // IE-only attribute that specifies security restrictions on an iframe // as an alternative to the sandbox attribute on IE<10 security: true, // IE-only attribute that controls focus behavior unselectable: 0 }; var svgProps = { accentHeight: true, accumulate: true, additive: true, alignmentBaseline: true, allowReorder: true, alphabetic: true, amplitude: true, arabicForm: true, ascent: true, attributeName: true, attributeType: true, autoReverse: true, azimuth: true, baseFrequency: true, baseProfile: true, baselineShift: true, bbox: true, begin: true, bias: true, by: true, calcMode: true, capHeight: true, clip: true, clipPath: true, clipRule: true, clipPathUnits: true, colorInterpolation: true, colorInterpolationFilters: true, colorProfile: true, colorRendering: true, contentScriptType: true, contentStyleType: true, cursor: true, cx: true, cy: true, d: true, decelerate: true, descent: true, diffuseConstant: true, direction: true, display: true, divisor: true, dominantBaseline: true, dur: true, dx: true, dy: true, edgeMode: true, elevation: true, enableBackground: true, end: true, exponent: true, externalResourcesRequired: true, fill: true, fillOpacity: true, fillRule: true, filter: true, filterRes: true, filterUnits: true, floodColor: true, floodOpacity: true, focusable: true, fontFamily: true, fontSize: true, fontSizeAdjust: true, fontStretch: true, fontStyle: true, fontVariant: true, fontWeight: true, format: true, from: true, fx: true, fy: true, g1: true, g2: true, glyphName: true, glyphOrientationHorizontal: true, glyphOrientationVertical: true, glyphRef: true, gradientTransform: true, gradientUnits: true, hanging: true, horizAdvX: true, horizOriginX: true, ideographic: true, imageRendering: true, in: true, in2: true, intercept: true, k: true, k1: true, k2: true, k3: true, k4: true, kernelMatrix: true, kernelUnitLength: true, kerning: true, keyPoints: true, keySplines: true, keyTimes: true, lengthAdjust: true, letterSpacing: true, lightingColor: true, limitingConeAngle: true, local: true, markerEnd: true, markerMid: true, markerStart: true, markerHeight: true, markerUnits: true, markerWidth: true, mask: true, maskContentUnits: true, maskUnits: true, mathematical: true, mode: true, numOctaves: true, offset: true, opacity: true, operator: true, order: true, orient: true, orientation: true, origin: true, overflow: true, overlinePosition: true, overlineThickness: true, paintOrder: true, panose1: true, pathLength: true, patternContentUnits: true, patternTransform: true, patternUnits: true, pointerEvents: true, points: true, pointsAtX: true, pointsAtY: true, pointsAtZ: true, preserveAlpha: true, preserveAspectRatio: true, primitiveUnits: true, r: true, radius: true, refX: true, refY: true, renderingIntent: true, repeatCount: true, repeatDur: true, requiredExtensions: true, requiredFeatures: true, restart: true, result: true, rotate: true, rx: true, ry: true, scale: true, seed: true, shapeRendering: true, slope: true, spacing: true, specularConstant: true, specularExponent: true, speed: true, spreadMethod: true, startOffset: true, stdDeviation: true, stemh: true, stemv: true, stitchTiles: true, stopColor: true, stopOpacity: true, strikethroughPosition: true, strikethroughThickness: true, string: true, stroke: true, strokeDasharray: true, strokeDashoffset: true, strokeLinecap: true, strokeLinejoin: true, strokeMiterlimit: true, strokeOpacity: true, strokeWidth: true, surfaceScale: true, systemLanguage: true, tableValues: true, targetX: true, targetY: true, textAnchor: true, textDecoration: true, textRendering: true, textLength: true, to: true, transform: true, u1: true, u2: true, underlinePosition: true, underlineThickness: true, unicode: true, unicodeBidi: true, unicodeRange: true, unitsPerEm: true, vAlphabetic: true, vHanging: true, vIdeographic: true, vMathematical: true, values: true, vectorEffect: true, version: true, vertAdvY: true, vertOriginX: true, vertOriginY: true, viewBox: true, viewTarget: true, visibility: true, widths: true, wordSpacing: true, writingMode: true, x: true, xHeight: true, x1: true, x2: true, xChannelSelector: true, xlinkActuate: true, xlinkArcrole: true, xlinkHref: true, xlinkRole: true, xlinkShow: true, xlinkTitle: true, xlinkType: true, xmlBase: true, xmlns: true, xmlnsXlink: true, xmlLang: true, xmlSpace: true, y: true, y1: true, y2: true, yChannelSelector: true, z: true, zoomAndPan: true }; /* From DOMProperty */ var ATTRIBUTE_NAME_START_CHAR = ':A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD'; var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040'; var isCustomAttribute = RegExp.prototype.test.bind(new RegExp('^(data|aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$')); var hasOwnProperty = {}.hasOwnProperty; var validAttr = (function (name) { return hasOwnProperty.call(htmlProps, name) || hasOwnProperty.call(svgProps, name) || isCustomAttribute(name.toLowerCase()) || hasOwnProperty.call(reactProps, name); }); // function isTag(target) /* : %checks */{ return typeof target === 'string'; } // function isStyledComponent(target) /* : %checks */{ return typeof target === 'function' && typeof target.styledComponentId === 'string'; } // /* eslint-disable no-undef */ function getComponentName(target) { return target.displayName || target.name || 'Component'; } // var determineTheme = (function (props, fallbackTheme, defaultProps) { // Props should take precedence over ThemeProvider, which should take precedence over // defaultProps, but React automatically puts defaultProps on props. /* eslint-disable react/prop-types */ var isDefaultTheme = defaultProps && props.theme === defaultProps.theme; var theme = props.theme && !isDefaultTheme ? props.theme : fallbackTheme; /* eslint-enable */ return theme; }); // /** * Creates a broadcast that can be listened to, i.e. simple event emitter * * @see https://github.com/ReactTraining/react-broadcast */ var createBroadcast = function createBroadcast(initialState) { var listeners = {}; var id = 0; var state = initialState; function publish(nextState) { state = nextState; // eslint-disable-next-line guard-for-in, no-restricted-syntax for (var key in listeners) { var listener = listeners[key]; if (listener === undefined) { // eslint-disable-next-line no-continue continue; } listener(state); } } function subscribe(listener) { var currentId = id; listeners[currentId] = listener; id += 1; listener(state); return currentId; } function unsubscribe(unsubID) { listeners[unsubID] = undefined; } return { publish: publish, subscribe: subscribe, unsubscribe: unsubscribe }; }; // // Helper to call a given function, only once var once = (function (cb) { var called = false; return function () { if (!called) { called = true; cb(); } }; }); var _ThemeProvider$childC; var _ThemeProvider$contex; // /* globals React$Element */ // NOTE: DO NOT CHANGE, changing this is a semver major change! var CHANNEL = '__styled-components__'; var CHANNEL_NEXT = CHANNEL + 'next__'; var CONTEXT_CHANNEL_SHAPE = PropTypes.shape({ getTheme: PropTypes.func, subscribe: PropTypes.func, unsubscribe: PropTypes.func }); var warnChannelDeprecated = once(function () { // eslint-disable-next-line no-console console.error('Warning: Usage of `context.' + CHANNEL + '` as a function is deprecated. It will be replaced with the object on `.context.' + CHANNEL_NEXT + '` in a future version.'); }); /** * Provide a theme to an entire react component tree via context and event listeners (have to do * both context and event emitter as pure components block context updates) */ var ThemeProvider = function (_Component) { inherits(ThemeProvider, _Component); function ThemeProvider() { classCallCheck(this, ThemeProvider); var _this = possibleConstructorReturn(this, _Component.call(this)); _this.unsubscribeToOuterId = -1; _this.getTheme = _this.getTheme.bind(_this); return _this; } ThemeProvider.prototype.componentWillMount = function componentWillMount() { var _this2 = this; // If there is a ThemeProvider wrapper anywhere around this theme provider, merge this theme // with the outer theme var outerContext = this.context[CHANNEL_NEXT]; if (outerContext !== undefined) { this.unsubscribeToOuterId = outerContext.subscribe(function (theme) { _this2.outerTheme = theme; }); } this.broadcast = createBroadcast(this.getTheme()); }; ThemeProvider.prototype.getChildContext = function getChildContext() { var _this3 = this, _babelHelpers$extends; return _extends({}, this.context, (_babelHelpers$extends = {}, _babelHelpers$extends[CHANNEL_NEXT] = { getTheme: this.getTheme, subscribe: this.broadcast.subscribe, unsubscribe: this.broadcast.unsubscribe }, _babelHelpers$extends[CHANNEL] = function (subscriber) { warnChannelDeprecated(); // Patch the old `subscribe` provide via `CHANNEL` for older clients. var unsubscribeId = _this3.broadcast.subscribe(subscriber); return function () { return _this3.broadcast.unsubscribe(unsubscribeId); }; }, _babelHelpers$extends)); }; ThemeProvider.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { if (this.props.theme !== nextProps.theme) this.broadcast.publish(this.getTheme(nextProps.theme)); }; ThemeProvider.prototype.componentWillUnmount = function componentWillUnmount() { if (this.unsubscribeToOuterId !== -1) { this.context[CHANNEL_NEXT].unsubscribe(this.unsubscribeToOuterId); } }; // Get the theme from the props, supporting both (outerTheme) => {} as well as object notation ThemeProvider.prototype.getTheme = function getTheme(passedTheme) { var theme = passedTheme || this.props.theme; if (isFunction(theme)) { var mergedTheme = theme(this.outerTheme); if (!isPlainObject(mergedTheme)) { throw new Error('[ThemeProvider] Please return an object from your theme function, i.e. theme={() => ({})}!'); } return mergedTheme; } if (!isPlainObject(theme)) { throw new Error('[ThemeProvider] Please make your theme prop a plain object'); } return _extends({}, this.outerTheme, theme); }; ThemeProvider.prototype.render = function render() { if (!this.props.children) { return null; } return React.Children.only(this.props.children); }; return ThemeProvider; }(Component); ThemeProvider.childContextTypes = (_ThemeProvider$childC = {}, _ThemeProvider$childC[CHANNEL] = PropTypes.func, _ThemeProvider$childC[CHANNEL_NEXT] = CONTEXT_CHANNEL_SHAPE, _ThemeProvider$childC); ThemeProvider.contextTypes = (_ThemeProvider$contex = {}, _ThemeProvider$contex[CHANNEL_NEXT] = CONTEXT_CHANNEL_SHAPE, _ThemeProvider$contex); // var escapeRegex = /[[\].#*$><+~=|^:(),"'`]/g; var multiDashRegex = /--+/g; // HACK for generating all static styles without needing to allocate // an empty execution context every single time... var STATIC_EXECUTION_CONTEXT = {}; var _StyledComponent = (function (ComponentStyle, constructWithOptions) { /* We depend on components having unique IDs */ var identifiers = {}; var generateId = function generateId(_displayName, parentComponentId) { var displayName = typeof _displayName !== 'string' ? 'sc' : _displayName.replace(escapeRegex, '-') // Replace all possible CSS selectors .replace(multiDashRegex, '-'); // Replace multiple -- with single - var nr = (identifiers[displayName] || 0) + 1; identifiers[displayName] = nr; var hash = ComponentStyle.generateName(displayName + nr); var componentId = displayName + '-' + hash; return parentComponentId !== undefined ? parentComponentId + '-' + componentId : componentId; }; var BaseStyledComponent = function (_Component) { inherits(BaseStyledComponent, _Component); function BaseStyledComponent() { var _temp, _this, _ret; classCallCheck(this, BaseStyledComponent); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args))), _this), _this.attrs = {}, _this.state = { theme: null, generatedClassName: '' }, _this.unsubscribeId = -1, _temp), possibleConstructorReturn(_this, _ret); } BaseStyledComponent.prototype.unsubscribeFromContext = function unsubscribeFromContext() { if (this.unsubscribeId !== -1) { this.context[CHANNEL_NEXT].unsubscribe(this.unsubscribeId); } }; BaseStyledComponent.prototype.buildExecutionContext = function buildExecutionContext(theme, props) { var attrs = this.constructor.attrs; var context = _extends({}, props, { theme: theme }); if (attrs === undefined) { return context; } this.attrs = Object.keys(attrs).reduce(function (acc, key) { var attr = attrs[key]; // eslint-disable-next-line no-param-reassign acc[key] = typeof attr === 'function' ? attr(context) : attr; return acc; }, {}); return _extends({}, context, this.attrs); }; BaseStyledComponent.prototype.generateAndInjectStyles = function generateAndInjectStyles(theme, props) { var _constructor = this.constructor, attrs = _constructor.attrs, componentStyle = _constructor.componentStyle, warnTooManyClasses = _constructor.warnTooManyClasses; var styleSheet = this.context[CONTEXT_KEY] || StyleSheet.instance; // staticaly styled-components don't need to build an execution context object, // and shouldn't be increasing the number of class names if (componentStyle.isStatic && attrs === undefined) { return componentStyle.generateAndInjectStyles(STATIC_EXECUTION_CONTEXT, styleSheet); } else { var executionContext = this.buildExecutionContext(theme, props); var className = componentStyle.generateAndInjectStyles(executionContext, styleSheet); if (warnTooManyClasses !== undefined) warnTooManyClasses(className); return className; } }; BaseStyledComponent.prototype.componentWillMount = function componentWillMount() { var _this2 = this; var componentStyle = this.constructor.componentStyle; var styledContext = this.context[CHANNEL_NEXT]; // If this is a staticaly-styled component, we don't need to the theme // to generate or build styles. if (componentStyle.isStatic) { var generatedClassName = this.generateAndInjectStyles(STATIC_EXECUTION_CONTEXT, this.props); this.setState({ generatedClassName: generatedClassName }); // 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 } else if (styledContext !== undefined) { var subscribe = styledContext.subscribe; this.unsubscribeId = subscribe(function (nextTheme) { // This will be called once immediately var theme = determineTheme(_this2.props, nextTheme, _this2.constructor.defaultProps); var generatedClassName = _this2.generateAndInjectStyles(theme, _this2.props); _this2.setState({ theme: theme, generatedClassName: generatedClassName }); }); } else { // eslint-disable-next-line react/prop-types var theme = this.props.theme || {}; var _generatedClassName = this.generateAndInjectStyles(theme, this.props); this.setState({ theme: theme, generatedClassName: _generatedClassName }); } }; BaseStyledComponent.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { var _this3 = this; // If this is a staticaly-styled component, we don't need to listen to // props changes to update styles var componentStyle = this.constructor.componentStyle; if (componentStyle.isStatic) { return; } this.setState(function (oldState) { var theme = determineTheme(nextProps, oldState.theme, _this3.constructor.defaultProps); var generatedClassName = _this3.generateAndInjectStyles(theme, nextProps); return { theme: theme, generatedClassName: generatedClassName }; }); }; BaseStyledComponent.prototype.componentWillUnmount = function componentWillUnmount() { this.unsubscribeFromContext(); }; BaseStyledComponent.prototype.render = function render() { var _this4 = this; // eslint-disable-next-line react/prop-types var innerRef = this.props.innerRef; var generatedClassName = this.state.generatedClassName; var _constructor2 = this.constructor, styledComponentId = _constructor2.styledComponentId, target = _constructor2.target; var isTargetTag = isTag(target); var className = [ // eslint-disable-next-line react/prop-types this.props.className, styledComponentId, this.attrs.className, generatedClassName].filter(Boolean).join(' '); var baseProps = _extends({}, this.attrs, { className: className }); if (isStyledComponent(target)) { baseProps.innerRef = innerRef; } else { baseProps.ref = innerRef; } var propsForElement = Object.keys(this.props).reduce(function (acc, propName) { // Don't pass through non HTML tags through to HTML elements // always omit innerRef if (propName !== 'innerRef' && propName !== 'className' && (!isTargetTag || validAttr(propName))) { // eslint-disable-next-line no-param-reassign acc[propName] = _this4.props[propName]; } return acc; }, baseProps); return createElement(target, propsForElement); }; return BaseStyledComponent; }(Component); var createStyledComponent = function createStyledComponent(target, options, rules) { var _StyledComponent$cont; var _options$displayName = options.displayName, displayName = _options$displayName === undefined ? isTag(target) ? 'styled.' + target : 'Styled(' + getComponentName(target) + ')' : _options$displayName, _options$componentId = options.componentId,