UNPKG

react-ui

Version:

Customisable components and primitives based on design tokens

1,763 lines (1,556 loc) 67.7 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var React = require('react'); var React__default = _interopDefault(React); var PropTypes = _interopDefault(require('prop-types')); var emotionTheming = require('emotion-theming'); var core = require('@emotion/core'); var merge$1 = _interopDefault(require('deepmerge')); var styled = _interopDefault(require('@emotion/styled')); var delve = _interopDefault(require('dlv')); var facepaint = _interopDefault(require('facepaint')); var autoId = require('@reach/auto-id'); var ReachAlert = _interopDefault(require('@reach/alert')); var ReachMenu = require('@reach/menu-button'); var ReachDialog = require('@reach/dialog'); var Reach = require('@reach/tabs'); var tooltip = require('@reach/tooltip'); var reactDom = require('react-dom'); var version = "1.0.0-beta.31"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function (obj) { return typeof obj; }; } else { _typeof = function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 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 _extends() { _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; }; return _extends.apply(this, arguments); } 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 _objectSpread2(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 _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; } 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 _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } function interpolate() { var styles = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var theme = arguments.length > 1 ? arguments[1] : undefined; var filledStyles = {}; var label = styles.label; var _loop = function _loop(key) { var value = styles[key]; if (Array.isArray(value)) { // responsive styles var breakpoints = theme.breakpoints; if (!breakpoints) return "continue"; // facepaint takes array of breakpoints not object var mq = facepaint(Object.values(breakpoints).map(function (breakpoint) { return "@media (min-width: ".concat(breakpoint, ")"); }), { overlap: true }); var values = value; // renaming to keep grammar easy to understand var responsiveValues = values.map(function (v) { return get(key, v, theme); }); var responsiveStyles = mq(_defineProperty({}, key, responsiveValues))[0]; filledStyles = merge$1(filledStyles, responsiveStyles); } else if (_typeof(value) === 'object') { // recursively interpolate filledStyles[key] = interpolate(value, theme); } else { filledStyles[key] = get(key, value, theme); } /** * The order of styles is important for css in shorthands * so { borderColor: 'blue', border: '1px solid' } * will not pick up borderColor, instead it will use the * missing value from the shorthand * * If we break the shorthand into its values, we don't face this * problem */ if (borderValues.includes(key) && value !== 'none') { var borderStyles = {}; var _value$split = value.split(' '), _value$split2 = _slicedToArray(_value$split, 3), borderWidth = _value$split2[0], borderStyle = _value$split2[1], borderColor = _value$split2[2]; if (borderWidth) borderStyles[key + 'Width'] = borderWidth; if (borderStyle) borderStyles[key + 'Style'] = borderStyle; if (borderColor) borderStyles[key + 'Color'] = borderColor; filledStyles = merge$1(filledStyles, borderStyles); delete filledStyles[key]; } if (key === 'variant') { var variantStyles = delve(theme.components, value); var interpolated = interpolate(variantStyles, theme); var isDefaultVariant = value === label + '.variants.default'; if (isDefaultVariant) filledStyles = merge$1(interpolated, filledStyles);else filledStyles = merge$1(filledStyles, interpolated); delete filledStyles.variant; } }; for (var key in styles) { var _ret = _loop(key); if (_ret === "continue") continue; } // TODO: this should happen in the get function, this is // too late to set it. // expand shortcuts like paddingX, size, etc. filledStyles = replaceShortcuts(filledStyles); return filledStyles; } function replaceShortcuts(styles) { var _loop2 = function _loop2(key) { var value = styles[key]; if (_typeof(value) === 'object') { value = replaceShortcuts(value); } if (shortcuts[key]) { shortcuts[key].forEach(function (realKeys) { return styles[realKeys] = value; }); delete styles[key]; } }; for (var key in styles) { _loop2(key); } return styles; } function interpolateFactory(styles) { return function (theme) { return interpolate(styles, theme); }; } // recursively resolve tokens function get(key, value, theme, label) { var scaleName = scales[key]; var scale = theme[scaleName]; // if scale doesn't exist, there's nothing to do here if (!scale) return value; if (typeof value === 'undefined') return; /** a value can be one of the following * a) css value * b) a scale token * c) reference to another token * d) a function */ var scaleValue; // scale can be an array or object if (typeof value === 'number') scaleValue = scale[value];else if (typeof value === 'function') scaleValue = value(theme); // delve uses dot.notation to resolve deep inside an object else scaleValue = delve(scale, value); // if the value doesn't exist on the scale, it must be a) css value if (!scaleValue) { if (scalesWithPixelUnits.includes(scaleName) && value !== 0 && value !== '0' && !hasUnits(value) // if it has units, we assume explicit intent ) ; else if (scaleName === 'colors' && !['transparent', 'inherit', 'initial'].includes(value) && !isHexCode(value)) ; return value; } else { // avoid infinite trap if (scaleValue === value) return value; var nestedScaleValue = get(key, scaleValue, theme); // if this value exists, it means it was a c) reference to another token if (nestedScaleValue) return nestedScaleValue; // otherwise it was a b) scale token else return scaleValue; } } var hasUnits = function hasUnits(value) { if (typeof value !== 'string') return false;else if (value.includes('%')) return true;else if (value.match(/[a-z]/i)) return true; }; var isHexCode = function isHexCode(value) { if (typeof value !== 'string') return false;else return value.startsWith('#'); }; var scales = { color: 'colors', backgroundColor: 'colors', background: 'colors', borderColor: 'colors', margin: 'space', marginTop: 'space', marginRight: 'space', marginBottom: 'space', marginLeft: 'space', marginInlineStart: 'space', marginInlineEnd: 'space', marginX: 'space', marginY: 'space', padding: 'space', paddingTop: 'space', paddingRight: 'space', paddingBottom: 'space', paddingLeft: 'space', paddingX: 'space', paddingY: 'space', top: 'space', right: 'space', bottom: 'space', left: 'space', gridGap: 'space', gridColumnGap: 'space', gridRowGap: 'space', gap: 'space', columnGap: 'space', rowGap: 'space', backgroundPosition: 'space', backgroundPositionX: 'space', backgroundPositionY: 'space', fontFamily: 'fonts', fontSize: 'fontSizes', fontWeight: 'fontWeights', lineHeight: 'lineHeights', letterSpacing: 'letterSpacings', border: 'borders', borderTop: 'borders', borderRight: 'borders', borderBottom: 'borders', borderLeft: 'borders', borderWidth: 'borderWidths', borderStyle: 'borderStyles', borderRadius: 'radii', borderTopRightRadius: 'radii', borderTopLeftRadius: 'radii', borderBottomRightRadius: 'radii', borderBottomLeftRadius: 'radii', borderTopRadius: 'radii', borderBottomRadius: 'radii', borderLeftRadius: 'radii', borderRightRadius: 'radii', borderTopWidth: 'borderWidths', borderTopColor: 'colors', borderTopStyle: 'borderStyles', borderBottomWidth: 'borderWidths', borderBottomColor: 'colors', borderBottomStyle: 'borderStyles', borderLeftWidth: 'borderWidths', borderLeftColor: 'colors', borderLeftStyle: 'borderStyles', borderRightWidth: 'borderWidths', borderRightColor: 'colors', borderRightStyle: 'borderStyles', outlineColor: 'colors', boxShadow: 'shadows', textShadow: 'shadows', zIndex: 'zIndices', width: 'sizes', minWidth: 'sizes', maxWidth: 'sizes', height: 'sizes', minHeight: 'sizes', maxHeight: 'sizes', flexBasis: 'sizes', size: 'sizes', transitionDuration: 'durations', animationDuration: 'durations', animationDelay: 'durations', // svg fill: 'colors', stroke: 'colors' }; var scalesWithPixelUnits = ['space', 'sizes', 'fontSizes', 'borderWidths', 'radii']; var shortcuts = { marginX: ['marginLeft', 'marginRight'], marginY: ['marginTop', 'marginBottom'], paddingX: ['paddingLeft', 'paddingRight'], paddingY: ['paddingTop', 'paddingBottom'], size: ['width', 'height'], borderTopRadius: ['borderTopLeftRadius', 'borderTopRightRadius'], borderBottomRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius'], borderLeftRadius: ['borderTopLeftRadius', 'borderBottomLeftRadius'], borderRightRadius: ['borderTopRightRadius', 'borderBottomRightRadius'] }; var borderValues = ['border', 'borderTop', 'borderRight', 'borderBottom', 'borderLeft']; // const shorthands = { var clone = function clone(obj) { return merge$1(obj, {}); }; /** Base element (name is prefixed to the component) */ var rui = styled('div')({ boxSizing: 'border-box' }); var marginProps = ['margin', 'marginX', 'marginY', 'marginTop', 'marginBottom', 'marginLeft', 'marginRight']; function Element(_ref, ref) { var _ref$css = _ref.css, cssProp = _ref$css === void 0 ? {} : _ref$css, _ref$style = _ref.style, inlineStyles = _ref$style === void 0 ? {} : _ref$style, _ref$variant = _ref.variant, variant = _ref$variant === void 0 ? 'default' : _ref$variant, _ref$size = _ref.size, size = _ref$size === void 0 ? 'medium' : _ref$size, component = _ref.component, theme = _ref.theme, props = _objectWithoutProperties(_ref, ["css", "style", "variant", "size", "component", "theme"]); // warn if theme provider is not used if (!theme.defined) { var warning = "Missing ThemeProvider. Please wrap your application in a ThemeProvider from react-ui"; warning += "\n\n"; warning += "Refer to the documentation at: /components/ThemeProvider"; console.warn(warning); } var css; if (typeof cssProp === 'function') css = cssProp(props);else css = clone(cssProp); var themeStyles = {}; if (theme.components) themeStyles = clone(theme.components[component]); if (typeof themeStyles === 'function') themeStyles = themeStyles(props); // if variant prop is given, attach the prop to css if (variant && themeStyles && themeStyles.variants && themeStyles.variants[variant]) { css.variant = component + '.variants.' + variant; } if (size && theme.sizes && theme.sizes[component]) { var width = css.width || css.size; var height = css.height || css.size; var value; if (_typeof(theme.sizes[component]) !== 'object') { // single value, attach to component value = theme.sizes[component]; } else { // if its multiple values, attach the corresponding key value = theme.sizes[component][size]; } // if the component already has a height / width property, // respect that and attach to the other property only if (!width && !height) css.size = value;else { if (!width) css.width = value; if (!height) css.height = value; } } var label; if (component) label = component;else if (typeof props.as === 'string') label = props.as;else if (props.as && typeof props.as.displayName === 'string') { label = props.as.displayName; } else { // give up label = 'Element'; } // reset: by default components should have no margin var margins = {}; // because of the above reset, we have to manually handle overrides marginProps.map(function (m) { if (typeof themeStyles[m] !== 'undefined') margins[m] = themeStyles[m]; if (typeof css[m] !== 'undefined') margins[m] = css[m]; if (typeof props[m] !== 'undefined') margins[m] = props[m]; delete props[m]; delete themeStyles[m]; delete css[m]; }); // deep merge with overriding var merged = mergeAll(themeStyles, css, margins); /** Allow nested component keys */ walk(merged, function (node) { var keys = Object.keys(node); // capitalized = component name var capitalisedKeys = keys.filter(function (key) { return /^[A-Z]/.test(key); }); capitalisedKeys.forEach(function (key) { var transformedKey = "[data-component=".concat(key, "]"); node[transformedKey] = node[key]; delete node[key]; }); }); // Better classNames for debugging props['data-component'] = label; merged.label = label; // instead of React.createElement return core.jsx(rui, _objectSpread2({ css: interpolateFactory(merged)(theme), style: interpolateFactory(inlineStyles)(theme), ref: ref }, props)); } function mergeAll() { var a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var c = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; return merge$1(merge$1(a, b), c); } function walk(obj, callback) { if (obj && _typeof(obj) === 'object') { callback(obj); Object.values(obj).map(function (node) { return walk(node, callback); }); } } var Element$1 = emotionTheming.withTheme(React.forwardRef(Element)); var styles = { Avatar: { borderRadius: '50%' } }; var mergeTwo = function mergeTwo() { var a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; // remove undefined values before merge Object.keys(a).forEach(function (key) { return a[key] == undefined && delete a[key]; }); Object.keys(b).forEach(function (key) { return b[key] == undefined && delete b[key]; }); return merge$1(a, b); }; var merge = function merge() { for (var _len = arguments.length, objs = new Array(_len), _key = 0; _key < _len; _key++) { objs[_key] = arguments[_key]; } return objs.reduce(function (merged, currentValue) { return mergeTwo(merged, currentValue); }, {}); }; var mergeFns = function mergeFns(a, b) { return function () { if (typeof a === 'function') a.apply(void 0, arguments); if (typeof b === 'function') b.apply(void 0, arguments); }; }; var hasUnits$1 = function hasUnits(value) { if (typeof value !== 'string') return false;else if (value.includes('%')) return true;else if (value.match(/[a-z]/i)) return true; }; var isComponent = function isComponent(value) { if (!value) return false; if (value.match(/[A-Z]/)) return true; return false; }; var calc = function calc(string) { var operator; if (string.includes('+')) operator = '+';else if (string.includes('-')) operator = '-';else if (string.includes('/')) operator = '/';else if (string.includes('*')) operator = '*'; if (!operator) return string; var _string$split = string.split(operator), _string$split2 = _slicedToArray(_string$split, 2), a = _string$split2[0], b = _string$split2[1]; a = a.trim(); b = b.trim(); return function (theme) { // check if theme.space and theme.sizes exist if ((hasUnits$1(a) || hasUnits$1(b)) && !theme.space) return string; if ((isComponent(a) || isComponent(b)) && !theme.sizes) return string; a = isComponent(a) ? theme.sizes[a] : a; a = hasUnits$1(a) ? a : theme.space[a] || theme.sizes[a]; b = isComponent(b) ? theme.sizes[b] : b; // dont multiple or divide pixcels b = hasUnits$1(b) || ['*', '/'].includes(operator) ? b : theme.space[b] || theme.sizes[b]; return "calc(".concat(a, " ").concat(operator, " ").concat(b, ")"); }; }; var Avatar = React__default.forwardRef(function Avatar(_ref, ref) { var css = _ref.css, props = _objectWithoutProperties(_ref, ["css"]); return React__default.createElement(Element$1, _extends({ ref: ref, as: "img", component: "Avatar", css: merge(styles.Avatar, css) }, props)); }); Avatar.propTypes = { /** Image url for avatar */ src: PropTypes.string.isRequired, /** size of avatar */ size: PropTypes.string }; Avatar.defaultProps = {}; var styles$1 = { Button: { boxSizing: 'border-box', display: 'inline-flex', justifyContent: 'center', alignItems: 'center', width: 'auto', minWidth: 'fit-content', lineHeight: 0, // trust height and flex for alignment cursor: 'pointer', transitionProperty: 'background-color, color, border-color', transitionDuration: 3, ':disabled': { opacity: 0.5, cursor: 'default' } } }; var Button = React__default.forwardRef(function Button(_ref, ref) { var size = _ref.size, fullWidth = _ref.fullWidth, css = _ref.css, props = _objectWithoutProperties(_ref, ["size", "fullWidth", "css"]); var width = fullWidth ? '100%' : 'auto'; return React__default.createElement(Element$1, _extends({ ref: ref, as: "button", component: "Button", css: merge(styles$1.Button, { width: width }, css) }, props)); }); Button.propTypes = { /** Description of an button prop */ fullWidth: PropTypes.bool, type: PropTypes.oneOf(['submit', 'button', 'reset']), variant: PropTypes.string }; Button.defaultProps = { type: 'submit', size: 'medium', variant: 'primary' }; var Text = React__default.forwardRef(function Text(_ref, ref) { var size = _ref.size, color = _ref.color, align = _ref.align, weight = _ref.weight, block = _ref.block, css = _ref.css, maxWidth = _ref.maxWidth, props = _objectWithoutProperties(_ref, ["size", "color", "align", "weight", "block", "css", "maxWidth"]); return React__default.createElement(Element$1, _extends({ ref: ref, as: "span", component: "Text", css: merge(_objectSpread2({ fontSize: size, textAlign: align, fontWeight: weight, color: color, display: block || props.marginBottom ? 'block' : 'inline', maxWidth: maxWidth }, maxWidth ? overflowStyles : {}), css) }, props)); }); var overflowStyles = { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }; Text.propTypes = { size: PropTypes.number, align: PropTypes.oneOf(['left', 'right', 'center', 'justify', 'inherit', 'initial']), weight: PropTypes.string, color: PropTypes.string, block: PropTypes.bool // variant: PropTypes.oneOf(['default', 'subtle', 'danger']), }; Text.defaultProps = {// we don't give default for size or align because we want the html default: inherit, // size: align: html default }; var createGap = function createGap(direction, gap) { if (direction === 'vertical') { return { marginTop: gap, marginInlineStart: 0 }; } return { marginTop: 0, marginInlineStart: gap }; }; var Stack = React__default.forwardRef(function Stack(_ref, ref) { var inline = _ref.inline, justify = _ref.justify, align = _ref.align, direction = _ref.direction, gap = _ref.gap, css = _ref.css, props = _objectWithoutProperties(_ref, ["inline", "justify", "align", "direction", "gap", "css"]); var styles = { display: inline ? 'inline-flex' : 'flex', // width: '100%', // causes weirdness in nested avatar. todo: debug justifyContent: justify, alignItems: align }; if (Array.isArray(direction)) { styles.flexDirection = direction.map(function (d) { return d === 'vertical' ? 'column' : 'row'; }); styles['> * + *'] = direction.map(function (d) { return createGap(d, gap); }); } else { styles.flexDirection = direction === 'vertical' ? 'column' : 'row'; styles['> * + *'] = createGap(direction, gap); } return React__default.createElement(Element$1, _extends({ ref: ref, as: "div", component: "Stack", css: merge(styles, css) }, props)); }); Stack.propTypes = { /** Description of the gap prop */ gap: PropTypes.oneOfType([// from scale PropTypes.number, PropTypes.arrayOf(PropTypes.number), // or a value with unit PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), // direction: PropTypes.oneOf(['horizontal', 'vertical']), justify: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), align: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), inline: PropTypes.oneOfType([PropTypes.bool, PropTypes.arrayOf(PropTypes.bool)]) }; Stack.defaultProps = { direction: 'horizontal', inline: false }; var styles$2 = { Checkbox: { margin: 0 } }; var Checkbox = function Checkbox(_ref) { var id = _ref.id, label = _ref.label, css = _ref.css, props = _objectWithoutProperties(_ref, ["id", "label", "css"]); var inputId = autoId.useId(id); return React__default.createElement(Stack, { align: "center", gap: 2 }, React__default.createElement(Element$1, _extends({ as: "input", type: "checkbox", component: "Checkbox", id: inputId }, props, { css: merge(styles$2.Checkbox, css) })), React__default.createElement(Text, { as: "label", htmlFor: inputId }, label)); }; Checkbox.propTypes = { label: PropTypes.string.isRequired }; Checkbox.defaultProps = { value: false }; var styles$3 = { Heading: { margin: 0 } }; /** Description of an input */ var Heading = React__default.forwardRef(function Heading(_ref, ref) { var size = _ref.size, css = _ref.css, props = _objectWithoutProperties(_ref, ["size", "css"]); return React__default.createElement(Element$1, _extends({ ref: ref, as: "h1", component: "Heading", css: merge(styles$3.Heading, { fontSize: getWithFallback("fontSizes.Heading.".concat(size), size) }, css) }, props)); }); var getWithFallback = function getWithFallback(value, fallback) { return function (theme) { var valueIfDefined = delve(theme, value); return valueIfDefined || fallback; }; }; Heading.propTypes = { /** Description of an Heading prop */ as: PropTypes.oneOf(['h1', 'h2', 'h3', 'h4', 'h5', 'h6']), size: PropTypes.oneOfType([PropTypes.string, PropTypes.number]) }; Heading.defaultProps = { as: 'h1' }; var styles$4 = { Image: { width: '100%' } }; var Image = React__default.forwardRef(function Image(_ref, ref) { var width = _ref.width, height = _ref.height, css = _ref.css, props = _objectWithoutProperties(_ref, ["width", "height", "css"]); return React__default.createElement(Element$1, _extends({ ref: ref, as: "img", css: merge(styles$4.Image, { width: width, height: height }, css), component: "Image" }, props)); }); var styles$5 = { Input: { boxSizing: 'border-box', lineHeight: 1, // trust the input height width: '100%', border: '1px solid', ':disabled': { opacity: 0.5, cursor: 'not-allowed' } } }; /** Description of an input */ var Input = React__default.forwardRef(function Input(_ref, ref) { var invalid = _ref.invalid, css = _ref.css, props = _objectWithoutProperties(_ref, ["invalid", "css"]); return React__default.createElement(Element$1, _extends({ ref: ref, as: "input", component: "Input", "aria-invalid": invalid, css: merge(styles$5.Input, css) }, props)); }); Input.propTypes = { /** Description of an input prop */ type: PropTypes.string }; Input.defaultProps = { type: 'text' }; var styles$6 = { Link: { textDecoration: 'none', cursor: 'pointer' } }; var Link = React__default.forwardRef(function Link(_ref, ref) { var css = _ref.css, props = _objectWithoutProperties(_ref, ["css"]); return React__default.createElement(Text, _extends({ ref: ref, as: "a", component: "Link", css: merge(styles$6.Link, css) }, props)); }); Link.propTypes = {}; Link.defaultProps = {}; var caret = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMTAgMjQiIHdpZHRoPSIxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjNzU3NTc1Ij48cGF0aCBkPSJtNS4wMDAwNiAxNy0zLjAwMDA2LTRoNnoiLz48cGF0aCBkPSJtNC45OTk5NCA3IDMuMDAwMDYgNGgtNnoiLz48L2c+PC9zdmc+'; var styles$7 = { Select: { appearance: 'none', backgroundImage: "url(".concat(caret, ")"), backgroundRepeat: 'no-repeat', backgroundPositionY: '50%', backgroundPositionX: calc('100% - 2'), // match input padding paddingRight: 4 // make room for caret } }; /** * We do a tiny dance to make selects look like they have a placeholder * just like an Input does. We do this by attaching an onChange handler * It's useful to note that we use mergeFns so that we don't override a * potential onChange from props * */ var usePlaceholder = function usePlaceholder(props) { var _React$useState = React__default.useState(props.defaultValue || props.value ? {} : { color: 'text.subtle' }), _React$useState2 = _slicedToArray(_React$useState, 2), placeholderStyles = _React$useState2[0], setPlaceholderStyles = _React$useState2[1]; var onChange = function onChange(event) { setPlaceholderStyles(event.target.value ? {} : { color: 'text.subtle' }); }; return { placeholderStyles: placeholderStyles, onChange: onChange }; }; var Select = React__default.forwardRef(function Select(_ref, ref) { var css = _ref.css, props = _objectWithoutProperties(_ref, ["css"]); var _usePlaceholder = usePlaceholder(props), placeholderStyles = _usePlaceholder.placeholderStyles, onChange = _usePlaceholder.onChange; return React__default.createElement(Input, _extends({ ref: ref, as: "select", component: "Select", css: merge(merge(styles$7.Select, placeholderStyles), css) }, props, { onChange: mergeFns(onChange, props.onChange) })); }); Select.propTypes = {}; Select.defaultProps = {}; Select.caret = caret; function _templateObject() { var data = _taggedTemplateLiteral(["\n 0% { background-position: 100% 50%; }\n 100% { background-position: -100% 50%; }\n"]); _templateObject = function _templateObject() { return data; }; return data; } var shine = core.keyframes(_templateObject()); var styles$8 = { Skeleton: { backgroundSize: '200% 200%', animationName: "".concat(shine), animationIterationCount: 'infinite', animationTimingFunction: 'linear' } }; var getLinearBackground = function getLinearBackground(theme) { /** Read special keys from theme but make sure * it doesn't break if the keys aren't present * */ var backgroundColor = delve(theme.components, 'Skeleton.backgroundColor', ''); var highlightColor = delve(theme.components, 'Skeleton.highlightColor', ''); var background = delve(theme.colors, backgroundColor, backgroundColor); var highlight = delve(theme.colors, highlightColor, highlightColor); return "linear-gradient(90deg,\n ".concat(background, " 0%,\n ").concat(background, " 20%,\n ").concat(highlight, " 50%,\n ").concat(background, " 80%,\n ").concat(background, " 100%\n )"); }; var Skeleton = React__default.forwardRef(function Skeleton(_ref, ref) { var css = _ref.css, width = _ref.width, props = _objectWithoutProperties(_ref, ["css", "width"]); return React__default.createElement(Element$1, _extends({ ref: ref, as: "span", component: "Skeleton", css: merge({ width: width, background: getLinearBackground }, styles$8.Skeleton, css) }, props)); }); Skeleton.propTypes = { width: PropTypes.number }; Skeleton.defaultProps = { width: 200 }; function _templateObject$1() { var data = _taggedTemplateLiteral(["\n 0% { transform: rotate(0deg) }\n 100% { transform: rotate(1turn) }\n"]); _templateObject$1 = function _templateObject() { return data; }; return data; } var rotate = core.keyframes(_templateObject$1()); var styles$9 = { Spinner: { display: 'inline-block', border: '2px solid', borderRadius: '50%', animation: "0.8s infinite ".concat(rotate) } }; var Spinner = React__default.forwardRef(function Spinner(_ref, ref) { var css = _ref.css, props = _objectWithoutProperties(_ref, ["css"]); return React__default.createElement(Element$1, _extends({ ref: ref, as: "span", component: "Spinner", css: merge(styles$9.Spinner, css) }, props)); }); Spinner.propTypes = {}; Spinner.defaultProps = {}; var styles$a = { SwitchBackground: { display: 'flex', alignItems: 'center', position: 'relative', width: '100%', height: 4 }, SwitchToggle: { width: 4, height: 4, position: 'absolute', left: 0, backgroundColor: 'white', border: '2px solid', borderRadius: '50%', transition: 'left ease', transitionDuration: 3 }, SwitchInput: { width: 0, opacity: 0, position: 'absolute' }, SwitchContainer: { display: 'inline-block', width: 7, borderRadius: '10px', overflow: 'hidden', cursor: 'pointer', '[data-component=SwitchBackground]': { backgroundColor: 'Switch.backgroundOff' }, '[data-component=SwitchToggle]': { borderColor: 'Switch.backgroundOff' }, 'input:checked + [data-component=SwitchBackground]': { backgroundColor: 'Switch.backgroundOn' }, 'input:checked + [data-component=SwitchBackground] [data-component=SwitchToggle]': { borderColor: 'Switch.backgroundOn', left: calc('100% - 4') }, 'input:disabled + [data-component=SwitchBackground]': { opacity: 0.4, cursor: 'not-allowed' } } }; var Switch = React__default.forwardRef(function Switch(_ref, ref) { var css = _ref.css, props = _objectWithoutProperties(_ref, ["css"]); return React__default.createElement(Element$1, { as: "label", css: merge(styles$a.SwitchContainer, css), component: "SwitchContainer" }, React__default.createElement(Element$1, _extends({ ref: ref, as: "input", type: "checkbox", css: styles$a.SwitchInput, component: "SwitchInput", checked: props.value, defaultChecked: props.defaultValue }, props)), React__default.createElement(Element$1, { as: "span", css: styles$a.SwitchBackground, component: "SwitchBackground" }, React__default.createElement(Element$1, { as: "span", css: styles$a.SwitchToggle, component: "SwitchToggle" }))); }); Switch.propTypes = { value: PropTypes.bool, defaultValue: PropTypes.bool, disabled: PropTypes.bool, onChange: PropTypes.func }; Switch.defaultProps = {}; var styles$b = { Textarea: { height: 'auto' // based on rows } }; var Textarea = React__default.forwardRef(function Textarea(_ref, ref) { var css = _ref.css, props = _objectWithoutProperties(_ref, ["css"]); return React__default.createElement(Input, _extends({ ref: ref, as: "textarea", css: merge(styles$b.Textarea, css), component: "Textarea" }, props)); }); Textarea.propTypes = { rows: PropTypes.number }; Textarea.defaultProps = { rows: 3 }; var styles$c = { Grid: { display: 'grid', gridTemplateColumns: 'repeat(12, 1fr)' // always 12 columns } }; var Grid = React__default.forwardRef(function Grid(_ref, ref) { var gap = _ref.gap, columnGap = _ref.columnGap, rowGap = _ref.rowGap, css = _ref.css, props = _objectWithoutProperties(_ref, ["gap", "columnGap", "rowGap", "css"]); var gaps = {}; if (gap === 'auto') { // picks up row and column gap based on body fontsize var fontSize = 1; // rem = 16px var lineHeight = fontSize * 1.5; gaps = { gridColumnGap: lineHeight * 2 + 'rem', gridRowGap: lineHeight + 'rem' }; } else gaps = { columnGap: columnGap, rowGap: rowGap }; return React__default.createElement(Element$1, _extends({ ref: ref, as: "div", component: "Grid", css: merge(styles$c.Grid, gaps, css) }, props)); }); var Column = React__default.forwardRef(function Column(_ref2, ref) { var start = _ref2.start, end = _ref2.end, span = _ref2.span, css = _ref2.css, props = _objectWithoutProperties(_ref2, ["start", "end", "span", "css"]); var column = {}; if (Array.isArray(start)) column.gridColumnStart = start.map(function (s) { return s; });else if (start) column.gridColumnStart = start; if (Array.isArray(end)) column.gridColumnEnd = end.map(function (s) { return s + 1; });else if (end) column.gridColumnEnd = end + 1; if (Array.isArray(span)) column.gridColumnEnd = span.map(function (s) { return 'span ' + s; });else if (span) column.gridColumnEnd = 'span ' + span; // not sure if span=0 is a good idea, we'll find out if (Array.isArray(span)) { column.display = span.map(function (s) { return s === 0 ? 'none' : 'block'; }); } else if (span === 0) column.display = 'none'; return React__default.createElement(Element$1, _extends({ ref: ref, as: "div", css: merge(column, css), component: "GridColumn" }, props)); }); var Row = React__default.forwardRef(function Row(props, ref) { return React__default.createElement(Column, _extends({ ref: ref, span: 12, as: Grid, component: "GridRow" }, props)); }); Grid.propTypes = { gap: PropTypes.oneOf(['auto', 'none']), columnGap: PropTypes.number, rowGap: PropTypes.number }; Grid.defaultProps = { gap: 'none', columnGap: 0, rowGap: 0 }; var styles$d = { Alert: { width: '100%' } }; var Alert = React__default.forwardRef(function Alert(_ref, ref) { var css = _ref.css, props = _objectWithoutProperties(_ref, ["css"]); return React__default.createElement(Element$1, _extends({ ref: ref, as: ReachAlert, component: "Alert", css: merge(styles$d.Alert, css) }, props)); }); Alert.propTypes = { variant: PropTypes.string, type: PropTypes.oneOf(['polite', 'assertive']) }; Alert.defaultProps = { variant: 'default', type: 'polite' }; var styles$e = { Breadcrumb: { ol: { paddingLeft: 0 } }, BreadcrumbSeparator: { display: 'inline-block' }, BreadcrumbItem: { display: 'inline-block' } }; var Separator = function Separator(props) { return React__default.createElement(Element$1, { as: "span", "aria-hidden": "true", component: "BreadcrumbSeparator", css: styles$e.BreadcrumbSeparator }, props.separator); }; var Breadcrumb = React__default.forwardRef(function Breadcrumb(_ref, ref) { var separator = _ref.separator, css = _ref.css, props = _objectWithoutProperties(_ref, ["separator", "css"]); var children = React__default.Children.map(props.children, function (child, index) { var isLast = index === props.children.length - 1; return React__default.createElement(Element$1, { ref: ref, as: "li", component: "BreadcrumbItem", css: styles$e.BreadcrumbItem, "aria-current": isLast ? 'page' : null }, child, isLast ? null : React__default.createElement(Separator, { separator: separator })); }); return React__default.createElement(Element$1, _extends({ as: "nav", "aria-label": "breadcrumb", component: "Breadcrumb", css: merge(styles$e.Breadcrumb, css) }, props), React__default.createElement("ol", null, children)); }); Breadcrumb.propTypes = { separator: PropTypes.node }; Breadcrumb.defaultProps = { separator: '/' }; var styles$f = { Card: {} }; var Card = React__default.forwardRef(function Card(_ref, ref) { var css = _ref.css, props = _objectWithoutProperties(_ref, ["css"]); return React__default.createElement(Element$1, _extends({ ref: ref, as: "div", component: "Card", css: merge(styles$f.Card, css) }, props)); }); var styles$g = { Form: { width: '100%' }, FormField: { width: '100%', border: 'none', padding: 0, marginX: 0 }, FormLabel: { display: 'block', lineHeight: 'default' }, FormHeader: { margin: 0 } }; var Form = React__default.forwardRef(function Form(_ref, ref) { var css = _ref.css, props = _objectWithoutProperties(_ref, ["css"]); return React__default.createElement(Element$1, _extends({ ref: ref, as: "form", component: "Form", css: merge(styles$g.Form, css) }, props), React__default.createElement(Stack, { component: "FormStack", direction: "vertical", gap: 6 }, props.children)); }); Form.propTypes = {}; Form.defaultProps = {}; Form.Header = React__default.forwardRef(function (_ref2, ref) { var css = _ref2.css, props = _objectWithoutProperties(_ref2, ["css"]); return React__default.createElement(Element$1, _extends({ ref: ref, as: "h1", component: "FormHeader", css: merge(styles$g.FormHeader, css) }, props)); }); Form.Header.displayName = 'Form.Header'; Form.Header.propTypes = { as: PropTypes.string }; Form.Header.defaultProps = { as: 'h1' }; Form.Label = React__default.forwardRef(function (_ref3, ref) { var css = _ref3.css, props = _objectWithoutProperties(_ref3, ["css"]); return React__default.createElement(Element$1, _extends({ ref: ref, as: "label", component: "FormLabel", css: merge(styles$g.FormLabel, css) }, props)); }); Form.Label.displayName = 'Form.Label'; // attach child components to Form Form.Field = React__default.forwardRef(function (_ref4, ref) { var label = _ref4.label, id = _ref4.id, required = _ref4.required, css = _ref4.css, props = _objectWithoutProperties(_ref4, ["label", "id", "required", "css"]); var inputId = autoId.useId(id); var children = React__default.Children.map(props.children, function (child, index) { var additionalProps = {}; // We only attach id to the first child. // This is irrelevant when there is only one form element. // When there are multiple elements in the same field, the first one gets focused. if (index === 0) additionalProps.id = inputId; // this one is tricky. We don't really know the intention here if the user // wanted to make both fields required or just one of them // we assume it's both // At the same time we should not override any props the child element has additionalProps.required = required || child.props.required; return React__default.cloneElement(child, _objectSpread2({}, additionalProps, { ref: ref })); }); return React__default.createElement(Element$1, _extends({ as: "fieldset", component: "FormField", css: merge(styles$g.FormField, css) }, props), React__default.createElement(Form.Label, { htmlFor: inputId }, label, " ", required ? React__default.createElement("span", null, "*") : null), children); }); Form.Field.displayName = 'Form.Field'; Form.Field.propTypes = { label: PropTypes.string.required, id: PropTypes.string, required: PropTypes.bool }; var styles$h = { MenuList: { paddingY: 0, minWidth: '120px', overflow: 'auto', // styles from reach display: 'block', whiteSpace: 'nowrap', outline: 'none' }, MenuItem: { display: 'block', userSelect: 'none', cursor: 'pointer', '&[data-selected]': { outline: 'none' } } }; var Menu = React__default.forwardRef(function Menu(props, ref) { return React__default.createElement(Element$1, _extends({ ref: ref, as: ReachMenu.Menu }, props)); }); var MenuButton = React__default.forwardRef(function (props, ref) { return React__default.createElement(Button, _extends({ ref: ref, variant: "secondary", as: ReachMenu.MenuButton }, props)); }); MenuButton.displayName = 'Menu.Button'; var MenuList = React__default.forwardRef(function (_ref, ref) { var css = _ref.css, props = _objectWithoutProperties(_ref, ["css"]); return React__default.createElement(Element$1, _extends({ ref: ref, as: ReachMenu.MenuList, component: "MenuList", css: merge(styles$h.MenuList, css) }, props)); }); MenuList.displayName = 'Menu.List'; var MenuItem = React__default.forwardRef(function (_ref2, ref) { var css = _ref2.css, props = _objectWithoutProperties(_ref2, ["css"]); return React__default.createElement(Element$1, _extends({ ref: ref, as: ReachMenu.MenuItem, component: "MenuItem", css: merge(styles$h.MenuItem, css) }, props)); }); MenuItem.displayName = 'Menu.Item'; Menu.Button = MenuButton; Menu.List = MenuList; Menu.Item = MenuItem; var styles$i = { DialogContent: { width: '50vw', outline: 'none' }, DialogOverlay: { position: 'fixed', top: 0, right: 0, bottom: 0, left: 0, overflow: 'auto', display: 'flex', justifyContent: 'center', alignItems: 'center' } }; var Dialog = function Dialog(_ref) { var css = _ref.css, children = _ref.children, isOpen = _ref.isOpen, onDismiss = _ref.onDismiss, props = _objectWithoutProperties(_ref, ["css", "children", "isOpen", "onDismiss"]); return React__default.createElement(Element$1, { as: ReachDialog.DialogOverlay, component: "DialogOverlay", css: merge(styles$i.DialogOverlay, css), isOpen: isOpen, onDismiss: onDismiss }, React__default.createElement(Element$1, _extends({ as: ReachDialog.DialogContent, component: "DialogContent", css: merge(styles$i.DialogContent, css) }, props), children)); }; var styles$j = { Paragraph: { margin: 0, '> span': { display: 'inline-block' } } }; var Paragraph = React__default.forwardRef(function Paragraph(_ref, ref) { var css = _ref.css, gap = _ref.gap, props = _objectWithoutProperties(_ref, ["css", "gap"]); return React__default.createElement(Stack, _extends({ ref: ref, as: "p", component: "Paragraph", gap: gap, direction: "vertical", css: merge(styles$j.Paragraph, css) }, props)); }); Paragraph.propTypes = { gap: PropTypes.oneOfType([PropTypes.number, PropTypes.arrayOf(PropTypes.number)]) }; Paragraph.defaultProps = { gap: 4 }; var styles$k = { Tabs: { width: '100%' }, TabList: { display: 'flex', borderBottom: '1px solid' }, Tab: { appearance: 'none', border: 'none', background: 'none', paddingX: 0, marginBottom: '-1px', borderBottom: '1px solid transparent', ':hover': { cursor: 'pointer' }, '&[data-selected]': { borderBottom: '1px solid currentColor' } } }; var Tabs = React__default.forwardRef(function (_ref, ref) { var css = _ref.css, props = _objectWithoutProperties(_ref, ["css"]); var tabs = []; var children = React__default.Children.map(props.children, function (child) { tabs.push({ label: child.props.label, disabled: child.props.disabled }); return child; }); return React__default.createElement(Element$1, _extends({ as: Reach.Tabs, component: "Tabs" }, props, { css: merge(styles$k.Tabs, css), ref: ref }), React__default.createElement(Element$1, { as: Reach.TabList, component: "TabList", css: styles$k.TabList }, tabs.map(function (_ref2, index) { var _React$createElement; var label = _ref2.label, disabled = _ref2.disabled; return React__default.createElement(Element$1, (_React$createElement = { as: Reach.Tab, component: "Tab", key: index, variant: "link" }, _defineProperty(_React$createElement, "component", "Tab"), _defineProperty(_React$createElement, "disabled", disabled), _defineProperty(_React$createElement, "css", styles$k.Tab), _React$createElement), label); })), React__default.createElement(Element$1, { as: Reach.TabPanels, component: "TabPanels" }, children)); }); var Tab = React__default.forwardRef(function (_ref3, ref) { var label = _ref3.label, props = _objectWithoutProperties(_ref3, ["label"]); return React__default.createElement(Element$1, _extends({ as: Reach.TabPanel, component: "TabPanel", ref: ref }, props)); }); Tabs.Tab = Tab; Tabs.displayName = 'Tabs'; Tabs.Tab.displayName = 'Tab'; /** * Copyright (c) 2014-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ /** * Similar to invariant but only logs a warning if the condition is not met. * This can be used to log issues in development environments in critical * paths. Removing the logging code for production environments will keep the * same logic and follow the same code paths. */ var __DEV__ = process.env.NODE_ENV !== 'production'; /* eslint-disable no-restricted-globals, eqeqeq, */ /** * React currently throws a warning when using useLayoutEffect on the server. * To get around it, we can conditionally useEffect on the server (no-op) and * useLayoutEffect in the browser. We occasionally need useLayoutEffect to * ensure we don't get a render flash for certain operations, but we may also * need affected components to render on the server. One example is when setting * a component's descendants to retrieve their index values. * * Important to note that using this hook as an escape hatch will break the * eslint dependency warnings unless you rename the import to `useLayoutEffect`. * Use sparingly only when the effect won't effect the rendered HTML to avoid * any server/client mismatch. * * If a useLayoutEffect is needed and the result would create a mismatch, it's * likely that the component in question shouldn't be rendered on the server at * all, so a better approach would be to lazily render those in a parent * component after client-side hydration. * * TODO: We are calling useLayoutEffect in a couple of places that will likely * cause some issues for SSR users, whether the warning shows or not. Audit and * fix these. * * https://gist.github.com/gaearon/e7d97cdf38a2907924ea12e4ebdf3c85 * https://git