react-ui
Version:
Customisable components and primitives based on design tokens
1,763 lines (1,556 loc) • 67.7 kB
JavaScript
'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