UNPKG

@geist-ui/core

Version:

Modern and minimalist React UI library.

749 lines (607 loc) 20.2 kB
'use strict' var React = require('react') function _interopDefaultLegacy(e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e } } var React__default = /*#__PURE__*/ _interopDefaultLegacy(React) var style$1 = {} var stylesheetRegistry = {} function hash(str) { var hash = 5381, i = str.length while (i) { hash = (hash * 33) ^ str.charCodeAt(--i) } /* JavaScript does bitwise operations (like XOR, above) on 32-bit signed * integers. Since we want the results to be always positive, convert the * signed int to an unsigned by doing an unsigned bitshift. */ return hash >>> 0 } var stringHash = hash var stylesheet = {} ;(function (exports) { exports.__esModule = true exports['default'] = void 0 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) } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps) if (staticProps) _defineProperties(Constructor, staticProps) return Constructor } /* Based on Glamor's sheet https://github.com/threepointone/glamor/blob/667b480d31b3721a905021b26e1290ce92ca2879/src/sheet.js */ var isProd = typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'production' var isString = function isString(o) { return Object.prototype.toString.call(o) === '[object String]' } var StyleSheet = /*#__PURE__*/ (function () { function StyleSheet(_temp) { var _ref = _temp === void 0 ? {} : _temp, _ref$name = _ref.name, name = _ref$name === void 0 ? 'stylesheet' : _ref$name, _ref$optimizeForSpeed = _ref.optimizeForSpeed, optimizeForSpeed = _ref$optimizeForSpeed === void 0 ? isProd : _ref$optimizeForSpeed, _ref$isBrowser = _ref.isBrowser, isBrowser = _ref$isBrowser === void 0 ? typeof window !== 'undefined' : _ref$isBrowser invariant(isString(name), '`name` must be a string') this._name = name this._deletedRulePlaceholder = '#' + name + '-deleted-rule____{}' invariant( typeof optimizeForSpeed === 'boolean', '`optimizeForSpeed` must be a boolean', ) this._optimizeForSpeed = optimizeForSpeed this._isBrowser = isBrowser this._serverSheet = undefined this._tags = [] this._injected = false this._rulesCount = 0 var node = this._isBrowser && document.querySelector('meta[property="csp-nonce"]') this._nonce = node ? node.getAttribute('content') : null } var _proto = StyleSheet.prototype _proto.setOptimizeForSpeed = function setOptimizeForSpeed(bool) { invariant(typeof bool === 'boolean', '`setOptimizeForSpeed` accepts a boolean') invariant( this._rulesCount === 0, 'optimizeForSpeed cannot be when rules have already been inserted', ) this.flush() this._optimizeForSpeed = bool this.inject() } _proto.isOptimizeForSpeed = function isOptimizeForSpeed() { return this._optimizeForSpeed } _proto.inject = function inject() { var _this = this invariant(!this._injected, 'sheet already injected') this._injected = true if (this._isBrowser && this._optimizeForSpeed) { this._tags[0] = this.makeStyleTag(this._name) this._optimizeForSpeed = 'insertRule' in this.getSheet() if (!this._optimizeForSpeed) { if (!isProd) { console.warn( 'StyleSheet: optimizeForSpeed mode not supported falling back to standard mode.', ) } this.flush() this._injected = true } return } this._serverSheet = { cssRules: [], insertRule: function insertRule(rule, index) { if (typeof index === 'number') { _this._serverSheet.cssRules[index] = { cssText: rule, } } else { _this._serverSheet.cssRules.push({ cssText: rule, }) } return index }, deleteRule: function deleteRule(index) { _this._serverSheet.cssRules[index] = null }, } } _proto.getSheetForTag = function getSheetForTag(tag) { if (tag.sheet) { return tag.sheet } // this weirdness brought to you by firefox for (var i = 0; i < document.styleSheets.length; i++) { if (document.styleSheets[i].ownerNode === tag) { return document.styleSheets[i] } } } _proto.getSheet = function getSheet() { return this.getSheetForTag(this._tags[this._tags.length - 1]) } _proto.insertRule = function insertRule(rule, index) { invariant(isString(rule), '`insertRule` accepts only strings') if (!this._isBrowser) { if (typeof index !== 'number') { index = this._serverSheet.cssRules.length } this._serverSheet.insertRule(rule, index) return this._rulesCount++ } if (this._optimizeForSpeed) { var sheet = this.getSheet() if (typeof index !== 'number') { index = sheet.cssRules.length } // this weirdness for perf, and chrome's weird bug // https://stackoverflow.com/questions/20007992/chrome-suddenly-stopped-accepting-insertrule try { sheet.insertRule(rule, index) } catch (error) { if (!isProd) { console.warn( 'StyleSheet: illegal rule: \n\n' + rule + '\n\nSee https://stackoverflow.com/q/20007992 for more info', ) } return -1 } } else { var insertionPoint = this._tags[index] this._tags.push(this.makeStyleTag(this._name, rule, insertionPoint)) } return this._rulesCount++ } _proto.replaceRule = function replaceRule(index, rule) { if (this._optimizeForSpeed || !this._isBrowser) { var sheet = this._isBrowser ? this.getSheet() : this._serverSheet if (!rule.trim()) { rule = this._deletedRulePlaceholder } if (!sheet.cssRules[index]) { // @TBD Should we throw an error? return index } sheet.deleteRule(index) try { sheet.insertRule(rule, index) } catch (error) { if (!isProd) { console.warn( 'StyleSheet: illegal rule: \n\n' + rule + '\n\nSee https://stackoverflow.com/q/20007992 for more info', ) } // In order to preserve the indices we insert a deleteRulePlaceholder sheet.insertRule(this._deletedRulePlaceholder, index) } } else { var tag = this._tags[index] invariant(tag, 'old rule at index `' + index + '` not found') tag.textContent = rule } return index } _proto.deleteRule = function deleteRule(index) { if (!this._isBrowser) { this._serverSheet.deleteRule(index) return } if (this._optimizeForSpeed) { this.replaceRule(index, '') } else { var tag = this._tags[index] invariant(tag, 'rule at index `' + index + '` not found') tag.parentNode.removeChild(tag) this._tags[index] = null } } _proto.flush = function flush() { this._injected = false this._rulesCount = 0 if (this._isBrowser) { this._tags.forEach(function (tag) { return tag && tag.parentNode.removeChild(tag) }) this._tags = [] } else { // simpler on server this._serverSheet.cssRules = [] } } _proto.cssRules = function cssRules() { var _this2 = this if (!this._isBrowser) { return this._serverSheet.cssRules } return this._tags.reduce(function (rules, tag) { if (tag) { rules = rules.concat( Array.prototype.map.call( _this2.getSheetForTag(tag).cssRules, function (rule) { return rule.cssText === _this2._deletedRulePlaceholder ? null : rule }, ), ) } else { rules.push(null) } return rules }, []) } _proto.makeStyleTag = function makeStyleTag(name, cssString, relativeToTag) { if (cssString) { invariant( isString(cssString), 'makeStyleTag acceps only strings as second parameter', ) } var tag = document.createElement('style') if (this._nonce) tag.setAttribute('nonce', this._nonce) tag.type = 'text/css' tag.setAttribute('data-' + name, '') if (cssString) { tag.appendChild(document.createTextNode(cssString)) } var head = document.head || document.getElementsByTagName('head')[0] if (relativeToTag) { head.insertBefore(tag, relativeToTag) } else { head.appendChild(tag) } return tag } _createClass(StyleSheet, [ { key: 'length', get: function get() { return this._rulesCount }, }, ]) return StyleSheet })() exports['default'] = StyleSheet function invariant(condition, message) { if (!condition) { throw new Error('StyleSheet: ' + message + '.') } } })(stylesheet) ;(function (exports) { exports.__esModule = true exports['default'] = void 0 var _stringHash = _interopRequireDefault(stringHash) var _stylesheet = _interopRequireDefault(stylesheet) function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj } } var sanitize = function sanitize(rule) { return rule.replace(/\/style/gi, '\\/style') } var StyleSheetRegistry = /*#__PURE__*/ (function () { function StyleSheetRegistry(_temp) { var _ref = _temp === void 0 ? {} : _temp, _ref$styleSheet = _ref.styleSheet, styleSheet = _ref$styleSheet === void 0 ? null : _ref$styleSheet, _ref$optimizeForSpeed = _ref.optimizeForSpeed, optimizeForSpeed = _ref$optimizeForSpeed === void 0 ? false : _ref$optimizeForSpeed, _ref$isBrowser = _ref.isBrowser, isBrowser = _ref$isBrowser === void 0 ? typeof window !== 'undefined' : _ref$isBrowser this._sheet = styleSheet || new _stylesheet['default']({ name: 'styled-jsx', optimizeForSpeed: optimizeForSpeed, }) this._sheet.inject() if (styleSheet && typeof optimizeForSpeed === 'boolean') { this._sheet.setOptimizeForSpeed(optimizeForSpeed) this._optimizeForSpeed = this._sheet.isOptimizeForSpeed() } this._isBrowser = isBrowser this._fromServer = undefined this._indices = {} this._instancesCounts = {} this.computeId = this.createComputeId() this.computeSelector = this.createComputeSelector() } var _proto = StyleSheetRegistry.prototype _proto.add = function add(props) { var _this = this if (undefined === this._optimizeForSpeed) { this._optimizeForSpeed = Array.isArray(props.children) this._sheet.setOptimizeForSpeed(this._optimizeForSpeed) this._optimizeForSpeed = this._sheet.isOptimizeForSpeed() } if (this._isBrowser && !this._fromServer) { this._fromServer = this.selectFromServer() this._instancesCounts = Object.keys(this._fromServer).reduce(function ( acc, tagName, ) { acc[tagName] = 0 return acc }, {}) } var _this$getIdAndRules = this.getIdAndRules(props), styleId = _this$getIdAndRules.styleId, rules = _this$getIdAndRules.rules // Deduping: just increase the instances count. if (styleId in this._instancesCounts) { this._instancesCounts[styleId] += 1 return } var indices = rules .map(function (rule) { return _this._sheet.insertRule(rule) }) // Filter out invalid rules .filter(function (index) { return index !== -1 }) this._indices[styleId] = indices this._instancesCounts[styleId] = 1 } _proto.remove = function remove(props) { var _this2 = this var _this$getIdAndRules2 = this.getIdAndRules(props), styleId = _this$getIdAndRules2.styleId invariant(styleId in this._instancesCounts, 'styleId: `' + styleId + '` not found') this._instancesCounts[styleId] -= 1 if (this._instancesCounts[styleId] < 1) { var tagFromServer = this._fromServer && this._fromServer[styleId] if (tagFromServer) { tagFromServer.parentNode.removeChild(tagFromServer) delete this._fromServer[styleId] } else { this._indices[styleId].forEach(function (index) { return _this2._sheet.deleteRule(index) }) delete this._indices[styleId] } delete this._instancesCounts[styleId] } } _proto.update = function update(props, nextProps) { this.add(nextProps) this.remove(props) } _proto.flush = function flush() { this._sheet.flush() this._sheet.inject() this._fromServer = undefined this._indices = {} this._instancesCounts = {} this.computeId = this.createComputeId() this.computeSelector = this.createComputeSelector() } _proto.cssRules = function cssRules() { var _this3 = this var fromServer = this._fromServer ? Object.keys(this._fromServer).map(function (styleId) { return [styleId, _this3._fromServer[styleId]] }) : [] var cssRules = this._sheet.cssRules() return fromServer.concat( Object.keys(this._indices) .map(function (styleId) { return [ styleId, _this3._indices[styleId] .map(function (index) { return cssRules[index].cssText }) .join(_this3._optimizeForSpeed ? '' : '\n'), ] }) // filter out empty rules .filter(function (rule) { return Boolean(rule[1]) }), ) } /** * createComputeId * * Creates a function to compute and memoize a jsx id from a basedId and optionally props. */ _proto.createComputeId = function createComputeId() { var cache = {} return function (baseId, props) { if (!props) { return 'jsx-' + baseId } var propsToString = String(props) var key = baseId + propsToString // return `jsx-${hashString(`${baseId}-${propsToString}`)}` if (!cache[key]) { cache[key] = 'jsx-' + (0, _stringHash['default'])(baseId + '-' + propsToString) } return cache[key] } } /** * createComputeSelector * * Creates a function to compute and memoize dynamic selectors. */ _proto.createComputeSelector = function createComputeSelector( selectoPlaceholderRegexp, ) { if (selectoPlaceholderRegexp === void 0) { selectoPlaceholderRegexp = /__jsx-style-dynamic-selector/g } var cache = {} return function (id, css) { // Sanitize SSR-ed CSS. // Client side code doesn't need to be sanitized since we use // document.createTextNode (dev) and the CSSOM api sheet.insertRule (prod). if (!this._isBrowser) { css = sanitize(css) } var idcss = id + css if (!cache[idcss]) { cache[idcss] = css.replace(selectoPlaceholderRegexp, id) } return cache[idcss] } } _proto.getIdAndRules = function getIdAndRules(props) { var _this4 = this var css = props.children, dynamic = props.dynamic, id = props.id if (dynamic) { var styleId = this.computeId(id, dynamic) return { styleId: styleId, rules: Array.isArray(css) ? css.map(function (rule) { return _this4.computeSelector(styleId, rule) }) : [this.computeSelector(styleId, css)], } } return { styleId: this.computeId(id), rules: Array.isArray(css) ? css : [css], } } /** * selectFromServer * * Collects style tags from the document with id __jsx-XXX */ _proto.selectFromServer = function selectFromServer() { var elements = Array.prototype.slice.call( document.querySelectorAll('[id^="__jsx-"]'), ) return elements.reduce(function (acc, element) { var id = element.id.slice(2) acc[id] = element return acc }, {}) } return StyleSheetRegistry })() exports['default'] = StyleSheetRegistry function invariant(condition, message) { if (!condition) { throw new Error('StyleSheetRegistry: ' + message + '.') } } })(stylesheetRegistry) ;(function (exports) { exports.__esModule = true exports['default'] = JSXStyle exports.flush = flush var _react = React__default['default'] var _stylesheetRegistry = _interopRequireDefault(stylesheetRegistry) function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj } } var styleSheetRegistry = new _stylesheetRegistry['default']() function JSXStyle(props) { if (typeof window === 'undefined') { styleSheetRegistry.add(props) return null } ;(0, _react.useLayoutEffect)( function () { styleSheetRegistry.add(props) return function () { styleSheetRegistry.remove(props) } // props.children can be string[], will be striped since id is identical }, [props.id, String(props.dynamic)], ) return null } JSXStyle.dynamic = function (info) { return info .map(function (tagInfo) { var baseId = tagInfo[0] var props = tagInfo[1] return styleSheetRegistry.computeId(baseId, props) }) .join(' ') } function flush() { var cssRules = styleSheetRegistry.cssRules() styleSheetRegistry.flush() return cssRules } })(style$1) var style = style$1.default || style$1 style.flush = style$1.flush var server$1 = {} ;(function (exports) { exports.__esModule = true exports['default'] = flushToReact exports.flushToHTML = flushToHTML var _react = _interopRequireDefault(React__default['default']) var _style = style$1.default || style$1 _style.flush = style$1.flush function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj } } function flushToReact(options) { if (options === void 0) { options = {} } return (0, _style.flush)().map(function (args) { var id = args[0] var css = args[1] return _react['default'].createElement('style', { id: '__' + id, // Avoid warnings upon render with a key key: '__' + id, nonce: options.nonce ? options.nonce : undefined, dangerouslySetInnerHTML: { __html: css, }, }) }) } function flushToHTML(options) { if (options === void 0) { options = {} } return (0, _style.flush)().reduce(function (html, args) { var id = args[0] var css = args[1] html += '<style id="__' + id + '"' + (options.nonce ? ' nonce="' + options.nonce + '"' : '') + '>' + css + '</style>' return html }, '') } })(server$1) var server = server$1.default || server$1 server.flushToHTML = server$1.flushToHTML exports.server = server exports.style = style