@theme-ui/components
Version:
Primitive layout, typographic, and other components for use with Theme UI.
1,311 lines (1,233 loc) • 35.4 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var react = require('@emotion/react');
var React = require('react');
var css = require('@theme-ui/css');
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
var React__default = /*#__PURE__*/_interopDefault(React);
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);
}
const boxSystemProps = [// space scale props (inherited from @styled-system/space)
'margin', 'marginTop', 'marginRight', 'marginBottom', 'marginLeft', 'marginX', 'marginY', 'm', 'mt', 'mr', 'mb', 'ml', 'mx', 'my', 'padding', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft', 'paddingX', 'paddingY', 'p', 'pt', 'pr', 'pb', 'pl', 'px', 'py', // color props (inherited from @styled-system/color)
'color', 'backgroundColor', 'bg', 'opacity'];
/**
* @internal
*/
const __isBoxStyledSystemProp = prop => boxSystemProps.includes(prop);
const pickSystemProps = props => {
const res = {};
for (const key of boxSystemProps) {
res[key] = props[key];
}
return res;
};
/**
* Use the Box component as a layout primitive to add margin, padding, and colors to content.
* @see https://theme-ui.com/components/box
*/
const Box = /*#__PURE__*/React.forwardRef(function Box(props, ref) {
const theme = react.useTheme();
const {
__themeKey = 'variants',
__css,
variant,
css: cssProp,
sx,
as: Component = 'div',
...rest
} = props;
const baseStyles = {
boxSizing: 'border-box',
margin: 0,
minWidth: 0
};
const __cssStyles = css.css(__css)(theme);
const variantInTheme = css.get(theme, `${__themeKey}.${variant}`) || css.get(theme, variant);
const variantStyles = variantInTheme && css.css(variantInTheme)(theme);
const sxPropStyles = css.css(sx)(theme);
const systemPropsStyles = css.css(pickSystemProps(rest))(theme);
const style = [baseStyles, __cssStyles, variantStyles, sxPropStyles, systemPropsStyles, cssProp];
boxSystemProps.forEach(name => {
delete rest[name];
});
return react.jsx(Component, _extends({
ref: ref,
css: style
}, rest));
});
/**
* Use the Flex component to create flexbox layouts.
* @see https://theme-ui.com/components/flex
*/
const Flex = /*#__PURE__*/React__default['default'].forwardRef(function Flex(props, ref) {
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref
}, props, {
sx: {
display: 'flex',
...props.sx
}
}));
});
const getProps = test => props => {
const next = {};
for (const key in props) {
if (test(key || '')) next[key] = props[key];
}
return next;
};
const MRE = /^m[trblxy]?$/;
const getMargin = getProps(k => MRE.test(k));
const omitMargin = getProps(k => !MRE.test(k));
/** @internal */
function __internalProps(props) {
return props;
}
/**
* @internal Props used by Theme UI Components not intended for user code.
*/
const px = n => typeof n === 'number' ? n + 'px' : n;
const singleWidthToColumns = (width, repeat) => width ? `repeat(auto-${repeat}, minmax(${px(width)}, 1fr))` : null;
const widthToColumns = (width, repeat) => Array.isArray(width) ? width.map(w => singleWidthToColumns(w, repeat)) : singleWidthToColumns(width, repeat);
const singleCountToColumns = n => n ? typeof n === 'number' ? `repeat(${n}, 1fr)` : n : null;
const countToColumns = n => Array.isArray(n) ? n.map(singleCountToColumns) : singleCountToColumns(n);
/**
* CSS grid layout component to arrange direct child elements in a tiled grid layout.
* @see https://theme-ui.com/components/grid
*/
const Grid = /*#__PURE__*/React__default['default'].forwardRef(function Grid({
width,
columns,
gap = 3,
repeat = 'fit',
...props
}, ref) {
const gridTemplateColumns = !!width ? widthToColumns(width, repeat) : countToColumns(columns);
const __css = {
display: 'grid',
gridGap: gap,
gridTemplateColumns
};
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref
}, props, __internalProps({
__themeKey: 'grids',
__css
})));
});
const Box$1 = Box;
/**
* Primitive button component with variants
* @see https://theme-ui.com/components/button
*/
const Button = /*#__PURE__*/React__default['default'].forwardRef(function Button(props, ref) {
return /*#__PURE__*/React__default['default'].createElement(Box$1, _extends({
ref: ref,
as: "button",
variant: "primary"
}, props, __internalProps({
__themeKey: 'buttons',
__css: {
appearance: 'none',
display: props.hidden ? undefined : 'inline-block',
textAlign: 'center',
lineHeight: 'inherit',
textDecoration: 'none',
fontSize: 'inherit',
px: 3,
py: 2,
color: 'white',
bg: 'primary',
border: 0,
borderRadius: 4
}
})));
});
/**
* Link variants can be defined in the `theme.links` object.
* By default the Link component will use styles defined in `theme.styles.a`.
* @see https://theme-ui.com/components/link
*/
const Link = /*#__PURE__*/React__default['default'].forwardRef(function Link(props, ref) {
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "a",
variant: "styles.a"
}, props, __internalProps({
__themeKey: 'links'
})));
});
/**
* Primitive typographic component.
*
* Text style variants can be defined in the theme.text object.
* The Paragraph component uses theme.text.paragraph as its default variant style.
* @see https://theme-ui.com/components/paragraph
*/
const Paragraph = /*#__PURE__*/React__default['default'].forwardRef(function Paragraph(props, ref) {
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "p",
variant: "paragraph"
}, props, __internalProps({
__themeKey: 'text',
__css: {
fontFamily: 'body',
fontWeight: 'body',
lineHeight: 'body'
}
})));
});
/**
* Primitive typographic component.
*
* Text style variants can be defined in the theme.text object.
* @see https://theme-ui.com/components/text
*/
const Text = /*#__PURE__*/React__default['default'].forwardRef(function Text(props, ref) {
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
as: "span",
ref: ref,
variant: "default"
}, props, __internalProps({
__themeKey: 'text'
})));
});
/**
* Primitive heading component, defaults to <h2>.
*
* Text style variants can be defined in the theme.text object.
* The Heading component uses theme.text.heading as its default variant style.
* @see https://theme-ui.com/components/heading
*/
const Heading = /*#__PURE__*/React__default['default'].forwardRef(function Heading(props, ref) {
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "h2",
variant: "heading"
}, props, __internalProps({
__themeKey: 'text',
__css: {
fontFamily: 'heading',
fontWeight: 'heading',
lineHeight: 'heading'
}
})));
});
/**
* Image style variants can be defined in the theme.images object.
* @see https://theme-ui.com/components/image/
*/
const Image = /*#__PURE__*/React__default['default'].forwardRef(function Image(props, ref) {
const __outerCss = props.__css;
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "img"
}, props, __internalProps({
__themeKey: 'images',
__css: {
maxWidth: '100%',
height: 'auto',
...__outerCss
}
})));
});
/**
* Card style variants can be defined in the `theme.cards` object.
* By default the Card component uses the `theme.cards.primary` variant.
* @see https://theme-ui.com/components/card
*/
const Card = /*#__PURE__*/React__default['default'].forwardRef(function Card(props, ref) {
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
variant: "primary"
}, props, __internalProps({
__themeKey: 'cards'
})));
});
/**
* Label variants can be defined in `theme.forms`
* and the component uses the `theme.forms.label` variant by default.
* @see https://theme-ui.com/components/label/
*/
const Label = /*#__PURE__*/React__default['default'].forwardRef(function Label(props, ref) {
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "label",
variant: "label"
}, props, __internalProps({
__themeKey: 'forms',
__css: {
width: '100%',
display: 'flex'
}
})));
});
const autofillStyles = {
boxShadow: 'inset 0 0 0 1000px var(--theme-ui-input-autofill-bg)',
fontSize: 'inherit',
':first-line': {
fontSize: '1rem'
}
};
const defaultInputStyles = {
display: 'block',
width: '100%',
p: 2,
appearance: 'none',
fontSize: 'inherit',
lineHeight: 'inherit',
border: '1px solid',
borderRadius: 4,
color: 'inherit',
bg: 'transparent',
':autofill, :autofill:hover, :autofill:focus': autofillStyles,
':-webkit-autofill, :-webkit-autofill:hover, :-webkit-autofill:focus': autofillStyles
};
/**
* Input variants can be defined in `theme.forms`
* and the component uses the `theme.forms.input` variant by default.
* @see https://theme-ui.com/components/input/
*/
const Input = /*#__PURE__*/React__default['default'].forwardRef(function Input({
sx,
autofillBackgroundColor = 'background',
...rest
}, ref) {
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "input",
variant: "input",
sx: {
'--theme-ui-input-autofill-bg': theme => theme.colors && css.get(theme.colors, autofillBackgroundColor, null),
...sx
}
}, rest, __internalProps({
__themeKey: 'forms',
__css: defaultInputStyles
})));
});
const SVG = /*#__PURE__*/React__default['default'].forwardRef(function SVG({
size = 24,
...rest
}, ref) {
const svgProps = {
xmlns: 'http://www.w3.org/2000/svg',
width: size,
height: size,
viewBox: '0 0 24 24',
fill: 'currentcolor',
...rest
};
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "svg"
}, svgProps));
});
SVG.displayName = 'SVG';
const DownArrow = props => /*#__PURE__*/React__default['default'].createElement(SVG, props, /*#__PURE__*/React__default['default'].createElement("path", {
d: "M7 10l5 5 5-5z"
}));
/**
* Select variants can be defined in `theme.forms`
* and the component uses the `theme.forms.select` variant by default.
* @see https://theme-ui.com/components/select/
*/
const Select = /*#__PURE__*/React__default['default'].forwardRef(function Select({
arrow,
...props
}, ref) {
const __css = {
display: 'block',
width: '100%',
p: 2,
appearance: 'none',
fontSize: 'inherit',
lineHeight: 'inherit',
border: '1px solid',
borderRadius: 4,
color: 'inherit',
backgroundColor: theme => css.get(theme, 'colors.background', null)
};
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({}, getMargin(props), {
sx: {
display: 'flex'
}
}), /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "select",
variant: "select"
}, omitMargin(props), __internalProps({
__themeKey: 'forms',
__css
}))), arrow || /*#__PURE__*/React__default['default'].createElement(DownArrow, {
sx: {
ml: -28,
alignSelf: 'center',
pointerEvents: 'none'
}
}));
});
/**
* Form textarea component
*
* Textarea variants can be defined in `theme.forms`
* and the component uses the `theme.forms.textarea` variant by default.
* @see https://theme-ui.com/components/textarea/
*/
const Textarea = /*#__PURE__*/React__default['default'].forwardRef(function Textarea(props, ref) {
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "textarea",
variant: "textarea"
}, props, __internalProps({
__themeKey: 'forms',
__css: {
display: 'block',
width: '100%',
p: 2,
appearance: 'none',
fontSize: 'inherit',
lineHeight: 'inherit',
border: '1px solid',
borderRadius: 4,
color: 'inherit',
bg: 'transparent'
}
})));
});
const RadioChecked = props => /*#__PURE__*/React__default['default'].createElement(SVG, props, /*#__PURE__*/React__default['default'].createElement("path", {
d: "M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm0-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"
}));
const RadioUnchecked = props => /*#__PURE__*/React__default['default'].createElement(SVG, props, /*#__PURE__*/React__default['default'].createElement("path", {
d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"
}));
const RadioIcon = props => /*#__PURE__*/React__default['default'].createElement(React__default['default'].Fragment, null, /*#__PURE__*/React__default['default'].createElement(RadioChecked, _extends({}, props, __internalProps({
__css: {
display: 'none',
'input:checked ~ &': {
display: 'block'
}
}
}))), /*#__PURE__*/React__default['default'].createElement(RadioUnchecked, _extends({}, props, __internalProps({
__css: {
display: 'block',
'input:checked ~ &': {
display: 'none'
}
}
}))));
/**
* Form radio input component
*
* Radio variants can be defined in `theme.forms` and the
* component uses the `theme.forms.radio variant` by default.
* @see https://theme-ui.com/components/radio/
*/
const Radio = /*#__PURE__*/React__default['default'].forwardRef(function Radio({
className,
sx,
variant = 'radio',
...props
}, ref) {
return /*#__PURE__*/React__default['default'].createElement(Box, {
sx: {
minWidth: 'min-content'
}
}, /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "input",
type: "radio"
}, props, {
sx: {
position: 'absolute',
opacity: 0,
zIndex: -1,
width: 1,
height: 1,
overflow: 'hidden'
}
})), /*#__PURE__*/React__default['default'].createElement(Box, _extends({
as: RadioIcon,
"aria-hidden": "true",
variant: variant,
className: className,
sx: sx
}, __internalProps({
__themeKey: 'forms',
__css: {
mr: 2,
borderRadius: 9999,
color: 'gray',
flexShrink: 0,
'input:checked ~ &': {
color: 'primary'
},
'input:focus ~ &': {
bg: 'highlight'
}
}
}))));
});
const CheckboxChecked = props => /*#__PURE__*/React__default['default'].createElement(SVG, props, /*#__PURE__*/React__default['default'].createElement("path", {
d: "M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"
}));
const CheckboxUnchecked = props => /*#__PURE__*/React__default['default'].createElement(SVG, props, /*#__PURE__*/React__default['default'].createElement("path", {
d: "M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"
}));
const CheckboxIcon = props => /*#__PURE__*/React__default['default'].createElement(React__default['default'].Fragment, null, /*#__PURE__*/React__default['default'].createElement(CheckboxChecked, _extends({}, props, __internalProps({
__css: {
display: 'none',
'input:checked ~ &': {
display: 'block'
}
}
}))), /*#__PURE__*/React__default['default'].createElement(CheckboxUnchecked, _extends({}, props, __internalProps({
__css: {
display: 'block',
'input:checked ~ &': {
display: 'none'
}
}
}))));
/**
* Form checkbox input component
*
* Checkbox variants can be defined in `theme.forms` and the
* component uses the `theme.forms.checkbox` variant by default.
* @see https://theme-ui.com/components/checkbox/
*/
const Checkbox = /*#__PURE__*/React__default['default'].forwardRef(function Checkbox({
className,
sx,
variant = 'checkbox',
children,
...props
}, ref) {
return /*#__PURE__*/React__default['default'].createElement(Box, {
sx: {
minWidth: 'min-content'
}
}, /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "input",
type: "checkbox"
}, props, {
sx: {
position: 'absolute',
opacity: 0,
zIndex: -1,
width: 1,
height: 1,
overflow: 'hidden'
}
})), /*#__PURE__*/React__default['default'].createElement(Box, _extends({
as: CheckboxIcon,
"aria-hidden": "true",
variant: variant,
className: className,
sx: sx
}, __internalProps({
__themeKey: 'forms',
__css: {
mr: 2,
borderRadius: 4,
color: 'gray',
flexShrink: 0,
'input:checked ~ &': {
color: 'primary'
},
'input:focus ~ &': {
color: 'primary',
bg: 'highlight'
}
}
}))), children);
});
const GUTTER = 2;
const SIZE = 18;
/**
* Form switch component
*
* Switch variants can be defined in `theme.forms`
* and the component uses the `theme.forms.switch` variant by default.
*/
const Switch = /*#__PURE__*/React__default['default'].forwardRef(function Switch({
className,
label,
sx,
variant = 'switch',
...rest
}, ref) {
const __css = {
position: 'relative',
flexShrink: 0,
bg: 'gray',
borderRadius: SIZE,
height: SIZE + GUTTER * 2,
width: SIZE * 2 + GUTTER * 2,
mr: 2,
'input:disabled ~ &': {
opacity: 0.5,
cursor: 'not-allowed'
},
'& > div': {
display: 'flex',
alignItems: 'center',
borderRadius: '50%',
height: SIZE,
width: SIZE,
bg: 'white',
boxShadow: '0 1px 2px rgba(0, 0, 0, 0.1)',
position: 'relative',
transform: 'translateX(0%)',
transition: `transform 240ms cubic-bezier(0.165, 0.840, 0.440, 1.000)`
},
'input:checked ~ &': {
bg: 'primary',
'> div': {
transform: 'translateX(100%)'
}
}
};
return /*#__PURE__*/React__default['default'].createElement(Label, {
sx: {
cursor: 'pointer'
}
}, /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "input",
type: "checkbox",
"aria-label": label
}, rest, {
sx: {
position: 'absolute',
opacity: 0,
zIndex: -1,
width: 1,
height: 1,
overflow: 'hidden'
}
}, __internalProps({
__themeKey: 'forms'
}))), /*#__PURE__*/React__default['default'].createElement(Box, _extends({
css: {
padding: GUTTER
},
variant: variant,
className: className,
sx: sx
}, __internalProps({
__themeKey: 'forms',
__css
})), /*#__PURE__*/React__default['default'].createElement(Box, null)), /*#__PURE__*/React__default['default'].createElement("span", null, label));
});
const thumbStyle = {
appearance: 'none',
width: 16,
height: 16,
bg: 'currentcolor',
border: 0,
borderRadius: 9999,
variant: 'forms.slider.thumb'
};
const sliderStyle = {
display: 'block',
width: '100%',
height: 4,
my: 2,
cursor: 'pointer',
appearance: 'none',
borderRadius: 9999,
color: 'inherit',
bg: 'gray',
':focus': {
outline: 'none',
color: 'primary'
},
'&::-webkit-slider-thumb': thumbStyle,
'&::-moz-range-thumb': thumbStyle,
'&::-ms-thumb': thumbStyle
};
/**
* Range input element
*
* Slider variants can be defined in the `theme.forms` object.
* The Slider component uses `theme.forms.slider` as its default variant style.
* @see https://theme-ui.com/components/slider/
*/
const Slider = /*#__PURE__*/React__default['default'].forwardRef(function Slider(props, ref) {
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "input",
type: "range",
variant: "slider"
}, props, __internalProps({
__themeKey: 'forms',
__css: sliderStyle
})));
});
const Field = /*#__PURE__*/React__default['default'].forwardRef(function Field({
// if somebody specifies the generic parameter without passing `as` prop, they get Input anyway
as: Control = Input,
label,
id,
name,
...rest
}, ref) {
const fieldIdentifier = id || name;
const controlProps = {
ref,
name,
id: fieldIdentifier,
...omitMargin(rest)
};
return /*#__PURE__*/React__default['default'].createElement(Box, getMargin(rest), /*#__PURE__*/React__default['default'].createElement(Label, {
htmlFor: fieldIdentifier
}, label), /*#__PURE__*/React__default['default'].createElement(Control, controlProps));
}); // Field is generic bcs of `as` prop, so we can't just use types from forwardRef
/**
* Horizontal `<progress />` bar
* @see https://theme-ui.com/components/progress/
*/
const Progress = /*#__PURE__*/React__default['default'].forwardRef(function Progress(props, ref) {
const __css = {
display: 'block',
width: '100%',
height: '4px',
margin: 0,
padding: 0,
overflow: 'hidden',
appearance: 'none',
color: 'primary',
bg: 'gray',
borderRadius: 9999,
border: 'none',
'&::-webkit-progress-bar': {
bg: 'transparent'
},
'&::-webkit-progress-value': {
bg: 'currentcolor'
},
'&::-moz-progress-bar': {
bg: 'currentcolor'
}
};
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "progress",
variant: "styles.progress"
}, props, __internalProps({
__css
})));
});
/**
* Single value SVG donut chart
* @see https://theme-ui.com/components/donut/
*/
const Donut = /*#__PURE__*/React__default['default'].forwardRef(function Donut({
size = 128,
strokeWidth = 2,
value = 0,
min = 0,
max = 1,
title,
...props
}, ref) {
const r = 16 - (typeof strokeWidth === 'number' ? strokeWidth : parseFloat(strokeWidth));
const C = 2 * r * Math.PI;
const offset = C - (value - min) / (max - min) * C;
const svgProps = {
strokeWidth,
viewBox: '0 0 32 32',
width: size,
height: size,
fill: 'none',
stroke: 'currentcolor'
};
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "svg",
role: "img",
"aria-valuenow": value,
"aria-valuemin": min,
"aria-valuemax": max
}, svgProps, props, __internalProps({
__css: {
color: 'primary'
}
})), title && /*#__PURE__*/React__default['default'].createElement("title", null, title), /*#__PURE__*/React__default['default'].createElement("circle", {
cx: 16,
cy: 16,
r: r,
opacity: 1 / 8
}), /*#__PURE__*/React__default['default'].createElement("circle", {
cx: 16,
cy: 16,
r: r,
strokeDasharray: C,
strokeDashoffset: offset,
transform: "rotate(-90 16 16)"
}));
});
const spin = react.keyframes({
from: {
transform: 'rotate(0deg)'
},
to: {
transform: 'rotate(360deg)'
}
});
const Spinner = /*#__PURE__*/React__default['default'].forwardRef(function Spinner({
size = 48,
strokeWidth = 4,
max = 1,
title = 'Loading...',
duration = 500,
...props
}, ref) {
const r = 16 - strokeWidth;
const C = 2 * r * Math.PI;
const offset = C - 1 / 4 * C;
const __css = {
color: 'primary',
overflow: 'visible'
};
const circleProps = {
cx: 16,
cy: 16,
r,
strokeDasharray: C,
strokeDashoffset: offset
};
const __circleCss = {
transformOrigin: '50% 50%',
animationName: spin.toString(),
animationTimingFunction: 'linear',
animationDuration: duration + 'ms',
animationIterationCount: 'infinite'
};
const svgProps = {
strokeWidth,
viewBox: '0 0 32 32',
width: size,
height: size,
fill: 'none',
stroke: 'currentColor',
role: 'img'
};
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "svg"
}, svgProps, props, __internalProps({
__css
})), /*#__PURE__*/React__default['default'].createElement("title", null, title), /*#__PURE__*/React__default['default'].createElement("circle", {
cx: 16,
cy: 16,
r: r,
opacity: 1 / 8
}), /*#__PURE__*/React__default['default'].createElement(Box, _extends({
as: "circle"
}, circleProps, __internalProps({
__css: __circleCss
}))));
});
const Avatar = /*#__PURE__*/React__default['default'].forwardRef(function Avatar({
size = 48,
...props
}, ref) {
return /*#__PURE__*/React__default['default'].createElement(Image, _extends({
ref: ref,
width: size,
height: size,
variant: "avatar"
}, props, __internalProps({
__css: {
borderRadius: 9999
}
})));
});
const Badge = /*#__PURE__*/React__default['default'].forwardRef(function Badge(props, ref) {
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
variant: "primary"
}, props, __internalProps({
__themeKey: 'badges',
__css: {
display: 'inline-block',
verticalAlign: 'baseline',
fontSize: 0,
fontWeight: 'bold',
whiteSpace: 'nowrap',
px: 1,
borderRadius: 2,
color: 'white',
bg: 'primary'
}
})));
});
/**
* Transparent button for SVG icons
*
* IconButton variants can be defined in the `theme.buttons` object.
* By default the IconButton component will use styles defined in `theme.buttons.icon`.
*
* @see https://theme-ui.com/components/icon-button
*/
const IconButton = /*#__PURE__*/React__default['default'].forwardRef(function IconButton({
size = 32,
...props
}, ref) {
var _css;
const emotionCssLabel = ((_css = props.__css) == null ? void 0 : _css.label) || 'IconButton';
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "button",
variant: "icon"
}, props, __internalProps({
__themeKey: 'buttons',
__css: {
label: emotionCssLabel,
appearance: 'none',
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
padding: 1,
width: size,
height: size,
color: 'inherit',
bg: 'transparent',
border: 'none',
borderRadius: 4
}
})));
});
const CloseIcon = /*#__PURE__*/React__default['default'].createElement("svg", {
xmlns: "http://www.w3.org/2000/svg",
width: "24",
height: "24",
fill: "currentColor",
viewBox: "0 0 24 24"
}, /*#__PURE__*/React__default['default'].createElement("path", {
d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
}));
/**
* Button with close (×) icon.
*
* The Close component renders as a <button> element by default.
* Pass any button attributes as props to the component.
*
* Close component variants can be defined in the theme.buttons object.
* The Close component uses theme.buttons.close as its default variant style.
*/
const Close = /*#__PURE__*/React__default['default'].forwardRef(function Close({
size = 32,
...props
}, ref) {
return /*#__PURE__*/React__default['default'].createElement(IconButton, _extends({
ref: ref,
size: size,
title: "Close",
"aria-label": "Close",
variant: "close"
}, props, {
children: CloseIcon
}));
});
/**
* Component for displaying messages, notifications, or other application state.
*
* Alert variants can be defined in `theme.alerts`.
* The Alert component uses `theme.alerts.primary` as its default variant.
*/
const Alert = /*#__PURE__*/React__default['default'].forwardRef(function Alert(props, ref) {
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
variant: "primary"
}, props, __internalProps({
__themeKey: 'alerts',
__css: {
display: 'flex',
alignItems: 'center',
px: 3,
py: 2,
fontWeight: 'bold',
color: 'white',
bg: 'primary',
borderRadius: 4
}
})));
});
/**
* The Divider component reuses styles from `theme.styles.hr` as its default variant.
*/
const Divider = /*#__PURE__*/React__default['default'].forwardRef(function Divider(props, ref) {
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "hr",
variant: "styles.hr"
}, props, __internalProps({
__css: {
color: 'gray',
m: 0,
my: 2,
border: 0,
borderBottom: '1px solid'
}
})));
});
const getContainerProps = getProps(__isBoxStyledSystemProp);
const getIframeProps = getProps(str => !__isBoxStyledSystemProp(str));
/**
* Responsive iframe for video embeds.
*
* Embed variants can be defined anywhere in the theme object.
*
* @see https://theme-ui.com/components/embed
*/
const Embed = /*#__PURE__*/React__default['default'].forwardRef(function Embed({
variant,
sx,
ratio = 16 / 9,
src,
frameBorder = 0,
allowFullScreen = true,
width = 560,
height = 315,
allow,
...rest
}, ref) {
const iframeProps = {
src,
width,
height,
frameBorder,
allowFullScreen,
allow,
...getIframeProps(rest)
};
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
variant: variant,
sx: sx
}, getContainerProps(rest), __internalProps({
__css: {
width: '100%',
height: 0,
paddingBottom: 100 / ratio + '%',
position: 'relative',
overflow: 'hidden'
}
})), /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
as: "iframe"
}, iframeProps, __internalProps({
__css: {
position: 'absolute',
width: '100%',
height: '100%',
top: 0,
bottom: 0,
left: 0,
border: 0
}
}))));
});
/**
* Component for maintaining a fluid-width aspect ratio
* @see https://theme-ui.com/components/aspect-ratio
*/
const AspectRatio = /*#__PURE__*/React__default['default'].forwardRef(function AspectRatio({
ratio = 4 / 3,
children,
...props
}, ref) {
return /*#__PURE__*/React__default['default'].createElement(Box, {
ref: ref,
sx: {
position: 'relative',
overflow: 'hidden'
}
}, /*#__PURE__*/React__default['default'].createElement(Box, {
sx: {
width: '100%',
height: 0,
paddingBottom: 100 / ratio + '%'
}
}), /*#__PURE__*/React__default['default'].createElement(Box, _extends({}, props, __internalProps({
__css: {
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0
}
})), children));
});
/**
* Image component constrained by as aspect ratio.
* @see https://theme-ui.com/components/aspect-image
*/
const AspectImage = /*#__PURE__*/React__default['default'].forwardRef(function AspectImage({
ratio,
...props
}, ref) {
return /*#__PURE__*/React__default['default'].createElement(AspectRatio, {
ratio: ratio
}, /*#__PURE__*/React__default['default'].createElement(Image, _extends({
ref: ref
}, props, __internalProps({
__css: {
objectFit: 'cover'
}
}))));
});
/**
* Centered, max-width layout component
*
* Container variants can be defined in the `theme.layout` object.
* The Container component uses `theme.layout.container` as its default variant style.
* @see https://theme-ui.com/components/container
*/
const Container = /*#__PURE__*/React__default['default'].forwardRef(function Container(props, ref) {
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref,
variant: "container"
}, props, __internalProps({
__themeKey: 'layout',
__css: {
width: '100%',
maxWidth: 'container',
mx: 'auto'
}
})));
});
/**
* Link component for use in navigation
*
* NavLink variants can be defined in the `theme.links` object.
* By default the NavLink component will use styles defined in `theme.links.nav`.
* @see https://theme-ui.com/components/nav-link
*/
const NavLink = /*#__PURE__*/React__default['default'].forwardRef(function NavLink(props, ref) {
const __css = {
color: 'inherit',
textDecoration: 'none',
fontWeight: 'bold',
display: 'inline-block',
'&:hover, &:focus, &.active': {
color: 'primary'
}
};
return /*#__PURE__*/React__default['default'].createElement(Link, _extends({
ref: ref,
variant: "nav"
}, props, __internalProps({
__css
})));
});
/**
* Styled Box component for callouts and inline messages
*
* Message variants can be defined in the theme.messages object.
* @see https://theme-ui.com/components/message
*/
const Message = /*#__PURE__*/React__default['default'].forwardRef(function Message(props, ref) {
const __css = {
padding: 3,
paddingLeft: t => t.space && Number(t.space[3]) - Number(t.space[1]),
borderLeftWidth: t => t.space && Number(t.space[1]),
borderLeftStyle: 'solid',
borderLeftColor: 'primary',
borderRadius: 4,
bg: 'highlight'
};
return /*#__PURE__*/React__default['default'].createElement(Box, _extends({
ref: ref
}, props, __internalProps({
__themeKey: 'messages',
__css
})));
});
const MenuIcon = ({
size = 24
}) => {
return react.jsx("svg", {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24",
width: size,
height: size,
fill: "currentColor",
css: {
display: 'block',
margin: 0,
boxSizing: 'border-box',
minWidth: 0
}
}, react.jsx("path", {
d: "M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"
}));
};
/**
* MenuButton variants can be defined in the `theme.buttons` object.
* By default the MenuButton component will use styles defined in `theme.buttons.menu`.
*
* @see https://theme-ui.com/components/menu-button
*/
const MenuButton = /*#__PURE__*/React__default['default'].forwardRef(function MenuButton(props, ref) {
return react.jsx(IconButton, _extends({
ref: ref,
title: "Menu",
"aria-label": "Toggle Menu",
variant: "menu"
}, props), react.jsx(MenuIcon, null));
});
exports.Alert = Alert;
exports.AspectImage = AspectImage;
exports.AspectRatio = AspectRatio;
exports.Avatar = Avatar;
exports.Badge = Badge;
exports.Box = Box;
exports.Button = Button;
exports.Card = Card;
exports.Checkbox = Checkbox;
exports.Close = Close;
exports.CloseIcon = CloseIcon;
exports.Container = Container;
exports.Divider = Divider;
exports.Donut = Donut;
exports.Embed = Embed;
exports.Field = Field;
exports.Flex = Flex;
exports.Grid = Grid;
exports.Heading = Heading;
exports.IconButton = IconButton;
exports.Image = Image;
exports.Input = Input;
exports.Label = Label;
exports.Link = Link;
exports.MenuButton = MenuButton;
exports.MenuIcon = MenuIcon;
exports.Message = Message;
exports.NavLink = NavLink;
exports.Paragraph = Paragraph;
exports.Progress = Progress;
exports.Radio = Radio;
exports.Select = Select;
exports.Slider = Slider;
exports.Spinner = Spinner;
exports.Switch = Switch;
exports.Text = Text;
exports.Textarea = Textarea;
exports.__isBoxStyledSystemProp = __isBoxStyledSystemProp;