@popmenu/ordering-ui 0.90.0 → 0.91.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.js CHANGED
@@ -50,7 +50,6 @@ var MuiToggleButton = require('@material-ui/lab/ToggleButton');
50
50
  var MuiToggleButtonGroup = require('@material-ui/lab/ToggleButtonGroup');
51
51
  var MuiTooltip = require('@material-ui/core/Tooltip');
52
52
  var lab = require('@material-ui/lab');
53
- var MuiRadioGroup = require('@material-ui/core/RadioGroup');
54
53
 
55
54
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
56
55
 
@@ -89,7 +88,6 @@ var Tab__default = /*#__PURE__*/_interopDefaultLegacy(Tab);
89
88
  var MuiToggleButton__default = /*#__PURE__*/_interopDefaultLegacy(MuiToggleButton);
90
89
  var MuiToggleButtonGroup__default = /*#__PURE__*/_interopDefaultLegacy(MuiToggleButtonGroup);
91
90
  var MuiTooltip__default = /*#__PURE__*/_interopDefaultLegacy(MuiTooltip);
92
- var MuiRadioGroup__default = /*#__PURE__*/_interopDefaultLegacy(MuiRadioGroup);
93
91
 
94
92
  /*! *****************************************************************************
95
93
  Copyright (c) Microsoft Corporation.
@@ -127,6 +125,16 @@ function __rest$1(s, e) {
127
125
  t[p[i]] = s[p[i]];
128
126
  }
129
127
  return t;
128
+ }
129
+
130
+ function __spreadArray(to, from, pack) {
131
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
132
+ if (ar || !(i in from)) {
133
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
134
+ ar[i] = from[i];
135
+ }
136
+ }
137
+ return to.concat(ar || from);
130
138
  }
131
139
 
132
140
  var Button = React.forwardRef(function (props, ref) {
@@ -972,10 +980,10 @@ var useTypographyStyles = styles.makeStyles(function (theme) {
972
980
  });
973
981
 
974
982
  var Typography = function (props) {
975
- props.weight; props.color; var restProps = __rest(props, ["weight", "color"]);
983
+ props.weight; props.color; var TypographyRef = props.TypographyRef, restProps = __rest(props, ["weight", "color", "TypographyRef"]);
976
984
  var classes = useTypographyStyles(__assign({}, props));
977
985
  var variantMapping = { subtitle1: 'p' };
978
- return React__default['default'].createElement(core.Typography, __assign({ classes: classes, variantMapping: variantMapping }, restProps));
986
+ return React__default['default'].createElement(core.Typography, __assign({ classes: classes, variantMapping: variantMapping, ref: TypographyRef }, restProps));
979
987
  };
980
988
  Typography.displayName = 'Typography';
981
989
  Typography.defaultProps = defaultTypographyProps;
@@ -1636,98 +1644,190 @@ var useLabelStyles = styles.makeStyles(function (theme) { return ({
1636
1644
  },
1637
1645
  }); });
1638
1646
 
1647
+ var useQuantityPickerStyles = styles.makeStyles(function (theme) { return ({
1648
+ root: {
1649
+ height: theme.spacing(7),
1650
+ backgroundColor: 'none',
1651
+ },
1652
+ }); });
1653
+ var useQuantityInputStyles = styles.makeStyles(function (theme) { return ({
1654
+ root: {
1655
+ height: '100%',
1656
+ width: 'min-content',
1657
+ borderRadius: theme.spacing(12.5),
1658
+ background: function (props) { return (props.variation === 'modifierCount' ? 'unset' : theme.palette.grey[100]); },
1659
+ },
1660
+ input: {
1661
+ '&::-webkit-clear-button, &::-webkit-outer-spin-button, &::-webkit-inner-spin-button': {
1662
+ display: 'none',
1663
+ },
1664
+ '-moz-appearance': 'textfield',
1665
+ fontWeight: 600,
1666
+ padding: 0,
1667
+ textAlign: 'center',
1668
+ zIndex: function (props) { return (props.value === 0 && props.variation === 'modifierCount' ? -1 : 1); },
1669
+ backgroundColor: function (props) { return (props.variation === 'modifierCount' ? theme.palette.grey[100] : 'unset'); },
1670
+ alignSelf: function (props) { return (props.variation === 'modifierCount' ? 'stretch' : 'unset'); },
1671
+ height: function (props) { return (props.variation === 'modifierCount' ? 'auto' : 'unset'); },
1672
+ minWidth: function (props) { return (props.variation === 'modifierCount' ? theme.spacing(5) : theme.spacing(2.75)); },
1673
+ borderRadius: function (props) { return (props.variation === 'modifierCount' ? theme.spacing(1) : 'unset'); },
1674
+ margin: function (props) { return (props.variation === 'modifierCount' ? theme.spacing(0.5, 0) : 0); },
1675
+ },
1676
+ }); });
1677
+ var useStartAdornmentStyles = styles.makeStyles(function (theme) { return ({
1678
+ root: {
1679
+ color: theme.palette.text.primary,
1680
+ zIndex: function (props) { return (props.value === 0 && props.variation === 'modifierCount' ? -1 : 1); },
1681
+ },
1682
+ }); });
1683
+ var useEndAdornmentStyles = styles.makeStyles(function (theme) { return ({
1684
+ root: {
1685
+ color: theme.palette.text.primary,
1686
+ },
1687
+ }); });
1688
+
1689
+ var QuantityPicker = function (props) {
1690
+ var value = props.value, onChange = props.onChange, disabled = props.disabled, disableIncrement = props.disableIncrement, preventManualChange = props.preventManualChange, variation = props.variation;
1691
+ var fieldClasses = useQuantityPickerStyles();
1692
+ var inputClasses = useQuantityInputStyles(props);
1693
+ var startAdornmentClasses = useStartAdornmentStyles(props);
1694
+ var endAdornmentClasses = useEndAdornmentStyles(props);
1695
+ var onIncrement = function (event) {
1696
+ onChange(event, { quantity: value + 1, reason: 'increment' });
1697
+ };
1698
+ var onDecrement = function (event) {
1699
+ onChange(event, { quantity: value - 1, reason: 'decrement' });
1700
+ };
1701
+ var handleChange = function (event) {
1702
+ if (preventManualChange) {
1703
+ event.preventDefault();
1704
+ }
1705
+ if (!preventManualChange) {
1706
+ onChange(event, { quantity: parseInt(event.target.value), reason: 'change' });
1707
+ }
1708
+ };
1709
+ return (React__default['default'].createElement(core.TextField, { classes: fieldClasses, type: "number", variant: variation === 'itemCount' ? 'filled' : 'standard', defaultValue: value, value: value, disabled: disabled, onChange: handleChange, InputProps: {
1710
+ classes: inputClasses,
1711
+ disableUnderline: true,
1712
+ endAdornment: (React__default['default'].createElement(IconButton, { className: endAdornmentClasses.root, color: "default", tabIndex: -1, onClick: onIncrement, disabled: disabled || disableIncrement },
1713
+ React__default['default'].createElement(Icon, { icon: SvgPlusCircle }))),
1714
+ startAdornment: (React__default['default'].createElement(IconButton, { className: startAdornmentClasses.root, color: "default", tabIndex: -1, onClick: onDecrement, disabled: disabled || value <= 0 },
1715
+ React__default['default'].createElement(Icon, { icon: SvgMinusCircle }))),
1716
+ } }));
1717
+ };
1718
+
1639
1719
  var Label = function (props) {
1640
- var name = props.name, price = props.price, disabled = props.disabled, isOutOfStock = props.isOutOfStock;
1720
+ var name = props.name, price = props.price, outOfStock = props.outOfStock, messages = props.messages;
1641
1721
  var classes = useLabelStyles();
1642
1722
  return (React__default['default'].createElement(core.Box, { display: "flex", flexDirection: "column", className: classes.label },
1643
1723
  React__default['default'].createElement(core.Box, { display: "flex", alignItems: "center", gridGap: 8 },
1644
1724
  React__default['default'].createElement(core.Typography, null, name),
1645
- !isOutOfStock && disabled && (React__default['default'].createElement(core.Typography, { variant: "caption", className: classes.outOfStock }, "Out of stock"))),
1646
- price && React__default['default'].createElement(core.Typography, { className: !disabled ? classes.price : '' },
1725
+ outOfStock && (React__default['default'].createElement(core.Typography, { variant: "caption", className: classes.outOfStock }, messages.outOfStockText))),
1726
+ price && React__default['default'].createElement(core.Typography, null,
1647
1727
  "+ ",
1648
1728
  price)));
1649
1729
  };
1650
- var CheckboxGroup = function (props) {
1651
- var value = props.value, modifiers = props.modifiers, onChange = props.onChange, disableNewSelections = props.disableNewSelections, isOutOfStock = props.isOutOfStock;
1652
- var classes = useCheckboxModifierFormStyles();
1653
- var appContext = useOrderingAppContext()[0];
1654
- var handleChange = function (event) {
1655
- var _a;
1656
- var price = (_a = modifiers.find(function (modifier) { return modifier.id === parseInt(event.target.value); })) === null || _a === void 0 ? void 0 : _a.price;
1730
+ var SingleSelectModifierControl = function (props) {
1731
+ var modifiers = props.modifiers, isOutOfStock = props.isOutOfStock, onChange = props.onChange, value = props.value, messages = props.messages;
1732
+ var radioClasses = useRadioModifierFormStyles();
1733
+ var makeHandleChange = function (modifier) { return function (e) {
1657
1734
  onChange([
1658
1735
  {
1659
- id: parseInt(event.target.value),
1660
- price: (price && parseInt(price)) || 0,
1661
- quantity: 1,
1662
- },
1663
- ], event.target.checked);
1664
- };
1665
- return (React__default['default'].createElement(core.Box, { display: "flex", flexDirection: "column" }, modifiers.map(function (modifier, index) {
1666
- var targetValue = value === null || value === void 0 ? void 0 : value.find(function (v) { return v.id == modifier.id; });
1667
- return (React__default['default'].createElement(core.FormControlLabel, { key: index, value: modifier.id, control: React__default['default'].createElement(core.Checkbox, { className: classes.radio, disabled: (!targetValue && disableNewSelections) || isOutOfStock || modifier.outOfStock }), label: React__default['default'].createElement(Label, { name: modifier.name, price: modifier.price
1668
- ? "" + (appContext && appContext.currencySymbol) + Number(modifier.price).toFixed(2)
1669
- : null, disabled: isOutOfStock || modifier.outOfStock, isOutOfStock: isOutOfStock }), className: classes.root, checked: !!targetValue, onChange: handleChange }));
1670
- })));
1671
- };
1672
- var RadioGroup = function (props) {
1673
- var value = props.value, modifiers = props.modifiers, onChange = props.onChange, isOutOfStock = props.isOutOfStock;
1674
- var classes = useRadioModifierFormStyles();
1675
- var appContext = useOrderingAppContext()[0];
1676
- var handleChange = function (event) {
1677
- var _a;
1678
- var price = (_a = modifiers.find(function (modifier) { return modifier.id === parseInt(event.target.value); })) === null || _a === void 0 ? void 0 : _a.price;
1679
- onChange([
1680
- {
1681
- id: parseInt(event.target.value),
1682
- price: (price && parseInt(price)) || 0,
1736
+ id: Number(e.target.value),
1737
+ price: modifier.price,
1683
1738
  quantity: 1,
1684
1739
  },
1685
1740
  ]);
1686
- };
1687
- return (React__default['default'].createElement(MuiRadioGroup__default['default'], { name: "selectedModifiers", value: value ? value[0].id : '', onChange: handleChange }, modifiers.map(function (modifier, index) { return (React__default['default'].createElement(core.FormControlLabel, { key: index, value: modifier.id, control: React__default['default'].createElement(core.Radio, { className: classes.radio, disabled: isOutOfStock || modifier.outOfStock }), label: React__default['default'].createElement(Label, { name: modifier.name, price: modifier.price ? "" + (appContext && appContext.currencySymbol) + Number(modifier.price).toFixed(2) : null, disabled: isOutOfStock || modifier.outOfStock, isOutOfStock: isOutOfStock }) })); })));
1688
- };
1689
-
1690
- var ModifierOptionsControl = function (props) {
1691
- var type = props.type, modifiers = props.modifiers, value = props.value, onChange = props.onChange, disableNewSelections = props.disableNewSelections, isOutOfStock = props.isOutOfStock;
1692
- switch (type) {
1741
+ }; };
1742
+ return (React__default['default'].createElement(core.FormControl, { fullWidth: true },
1743
+ React__default['default'].createElement(core.RadioGroup, null, modifiers.map(function (modifier) {
1744
+ var _a;
1745
+ return (React__default['default'].createElement(core.FormControlLabel, { key: modifier.id, value: modifier.id, control: React__default['default'].createElement(core.Radio, { checked: ((_a = value[0]) === null || _a === void 0 ? void 0 : _a.id) === modifier.id, className: radioClasses.radio, disabled: isOutOfStock || modifier.outOfStock, onChange: makeHandleChange(modifier) }), label: React__default['default'].createElement(Label, { messages: messages, name: modifier.name, price: modifier.formattedPrice, disabled: isOutOfStock || modifier.outOfStock, outOfStock: isOutOfStock }) }));
1746
+ }))));
1747
+ };
1748
+ var MultipleSelectControl = function (props) {
1749
+ var modifiers = props.modifiers, value = props.value, isOutOfStock = props.isOutOfStock, onChange = props.onChange, messages = props.messages, disableNewSelections = props.disableNewSelections;
1750
+ var classes = useCheckboxModifierFormStyles();
1751
+ var makeHandleChange = function (modifier) { return function () {
1752
+ var isModifierInValue = Boolean(value.find(function (v) { return v.id === modifier.id; }));
1753
+ if (isModifierInValue) {
1754
+ onChange(value.filter(function (v) { return v.id !== modifier.id; }));
1755
+ }
1756
+ else {
1757
+ onChange(__spreadArray(__spreadArray([], value), [{ id: modifier.id, price: modifier.price || 0, quantity: 1 }]));
1758
+ }
1759
+ }; };
1760
+ return (React__default['default'].createElement(core.FormControl, { fullWidth: true },
1761
+ React__default['default'].createElement(core.FormGroup, null, modifiers.map(function (modifier) { return (React__default['default'].createElement(core.FormControlLabel, { key: modifier.id, value: modifier.id, className: classes.root, checked: value.some(function (v) { return v.id === modifier.id; }), onChange: makeHandleChange(modifier), control: React__default['default'].createElement(core.Checkbox, { className: classes.radio, disabled: isOutOfStock || modifier.outOfStock || (!modifier.quantity && disableNewSelections) }), label: React__default['default'].createElement(Label, { messages: messages, name: modifier.name, price: modifier.formattedPrice, disabled: isOutOfStock || modifier.outOfStock, outOfStock: isOutOfStock }) })); }))));
1762
+ };
1763
+ var MultipleQuantitySelectControl = function (props) {
1764
+ var modifiers = props.modifiers, value = props.value, isOutOfStock = props.isOutOfStock, onChange = props.onChange, messages = props.messages, disableNewSelections = props.disableNewSelections;
1765
+ var makeHandleChange = function (modifier) { return function (_e, customEvent) {
1766
+ var isModifierInValue = Boolean(value.find(function (v) { return v.id === modifier.id; }));
1767
+ var isQuantityZero = customEvent.quantity === 0;
1768
+ var shouldRemoveModifierFromValue = isModifierInValue && isQuantityZero;
1769
+ var shouldAddModifierToValue = !isModifierInValue && !isQuantityZero;
1770
+ var shouldUpdateModifierInValue = isModifierInValue && !isQuantityZero;
1771
+ if (shouldRemoveModifierFromValue) {
1772
+ onChange(value.filter(function (v) { return v.id !== modifier.id; }));
1773
+ }
1774
+ if (shouldAddModifierToValue) {
1775
+ onChange(__spreadArray(__spreadArray([], value), [{ id: modifier.id, price: modifier.price, quantity: customEvent.quantity }]));
1776
+ }
1777
+ if (shouldUpdateModifierInValue) {
1778
+ onChange(value.map(function (val) { return (val.id === modifier.id ? __assign$1(__assign$1({}, val), { quantity: customEvent.quantity }) : val); }));
1779
+ }
1780
+ }; };
1781
+ return (React__default['default'].createElement(core.FormControl, { fullWidth: true },
1782
+ React__default['default'].createElement(core.FormGroup, null, modifiers.map(function (modifier) { return (React__default['default'].createElement(core.Box, { key: modifier.id, style: { justifyContent: 'space-between' }, display: "flex" },
1783
+ React__default['default'].createElement(Label, { messages: messages, name: modifier.name, price: modifier.formattedPrice, disabled: isOutOfStock || modifier.outOfStock, outOfStock: isOutOfStock }),
1784
+ React__default['default'].createElement(QuantityPicker, { variation: "modifierCount", value: modifier.quantity, disableIncrement: disableNewSelections, preventManualChange: true, onChange: makeHandleChange(modifier) }))); }))));
1785
+ };
1786
+ var ModifierControls = function (props) {
1787
+ switch (props.type) {
1693
1788
  case 'singleSelect':
1694
- return React__default['default'].createElement(RadioGroup, { modifiers: modifiers, value: value, onChange: onChange, isOutOfStock: isOutOfStock });
1789
+ return React__default['default'].createElement(SingleSelectModifierControl, __assign$1({}, props));
1695
1790
  case 'multipleSelect':
1696
- return (React__default['default'].createElement(CheckboxGroup, { modifiers: modifiers, value: value, onChange: onChange, disableNewSelections: disableNewSelections, isOutOfStock: isOutOfStock }));
1791
+ return React__default['default'].createElement(MultipleSelectControl, __assign$1({}, props));
1792
+ case 'multipleQuantitySelect':
1793
+ return React__default['default'].createElement(MultipleQuantitySelectControl, __assign$1({}, props));
1697
1794
  default:
1698
1795
  return null;
1699
1796
  }
1700
1797
  };
1701
1798
 
1702
- var DishModifierCard = function (props) {
1703
- var name = props.name, disableNewSelections = props.disableNewSelections, modifiers = props.modifiers, value = props.value, messages = props.messages, onChange = props.onChange, type = props.type, error = props.error, isRequired = props.isRequired, isOutOfStock = props.isOutOfStock;
1704
- var optionalText = messages.optionalText, outOfStockText = messages.outOfStockText, requiredText = messages.requiredText, helperText = messages.helperText;
1705
- var isFullyOutOfStock = isOutOfStock || !modifiers.some(function (modifier) { return !modifier.outOfStock; });
1706
- var classes = useDishModifierCardStyles();
1799
+ var getStatusTagProps = function (props) {
1800
+ var messages = props.messages, error = props.error, isRequired = props.isRequired, isOutOfStock = props.isOutOfStock;
1801
+ var optionalText = messages.optionalText, outOfStockText = messages.outOfStockText, requiredText = messages.requiredText;
1707
1802
  var color = 'default';
1708
1803
  switch (true) {
1709
1804
  case error:
1710
1805
  color = 'error';
1711
- case isFullyOutOfStock:
1806
+ case isOutOfStock:
1712
1807
  color = 'warning';
1713
1808
  }
1714
1809
  var label = optionalText;
1715
1810
  switch (true) {
1716
- case isFullyOutOfStock:
1811
+ case isOutOfStock:
1717
1812
  label = outOfStockText;
1718
1813
  break;
1719
1814
  case isRequired:
1720
1815
  label = requiredText;
1721
1816
  break;
1722
1817
  }
1818
+ var variant = isRequired || isOutOfStock ? 'outlined' : 'filled';
1819
+ return { color: color, label: label, variant: variant };
1820
+ };
1821
+ var DishModifierCard = function (props) {
1822
+ var name = props.name, disableNewSelections = props.disableNewSelections, modifiers = props.modifiers, value = props.value, messages = props.messages, onChange = props.onChange, type = props.type, error = props.error, isOutOfStock = props.isOutOfStock;
1823
+ var classes = useDishModifierCardStyles();
1723
1824
  return (React__default['default'].createElement(core.Box, { className: classes.root },
1724
1825
  React__default['default'].createElement(core.Box, { display: "flex", justifyContent: "space-between", width: "100%", alignItems: "center", height: "fit-content", marginBottom: 2 },
1725
- React__default['default'].createElement(StatusTag, { variant: isRequired || isFullyOutOfStock ? 'outlined' : 'filled', label: label, color: color }),
1726
- !isFullyOutOfStock && (React__default['default'].createElement(Typography, { variant: "subtitle1", className: error ? classes.error : undefined }, helperText))),
1826
+ React__default['default'].createElement(StatusTag, __assign$1({}, getStatusTagProps(props))),
1827
+ !isOutOfStock && (React__default['default'].createElement(Typography, { variant: "subtitle1", className: error ? classes.error : undefined }, messages.helperText))),
1727
1828
  React__default['default'].createElement(Typography, { className: classes.name }, name),
1728
1829
  React__default['default'].createElement(core.Box, null,
1729
- React__default['default'].createElement(core.FormControl, null,
1730
- React__default['default'].createElement(ModifierOptionsControl, { type: type, modifiers: modifiers, value: value, onChange: onChange, disableNewSelections: disableNewSelections, isOutOfStock: isFullyOutOfStock })))));
1830
+ React__default['default'].createElement(ModifierControls, { value: value, modifiers: modifiers, isOutOfStock: isOutOfStock, onChange: onChange, disableNewSelections: disableNewSelections, type: type, messages: messages }))));
1731
1831
  };
1732
1832
  DishModifierCard.displayName = 'DishModifierCard';
1733
1833
 
@@ -1947,61 +2047,6 @@ var MenuFilter = function (props) {
1947
2047
  React__default['default'].createElement(Typography, { variant: "body1", color: "grey.500" }, noOptionsLabel)))))));
1948
2048
  };
1949
2049
 
1950
- var useQuantityPickerStyles = styles.makeStyles(function (theme) { return ({
1951
- root: {
1952
- height: theme.spacing(7),
1953
- },
1954
- }); });
1955
- var useQuantityInputStyles = styles.makeStyles(function (theme) { return ({
1956
- root: {
1957
- height: '100%',
1958
- width: 'min-content',
1959
- borderRadius: theme.spacing(12.5),
1960
- background: theme.palette.grey[100],
1961
- },
1962
- input: {
1963
- '&::-webkit-clear-button, &::-webkit-outer-spin-button, &::-webkit-inner-spin-button': {
1964
- display: 'none',
1965
- },
1966
- '-moz-appearance': 'textfield',
1967
- fontWeight: 600,
1968
- minWidth: theme.spacing(2.75),
1969
- padding: 0,
1970
- textAlign: 'center',
1971
- position: 'relative',
1972
- left: 1,
1973
- },
1974
- adornedStart: {
1975
- padding: theme.spacing(0.25),
1976
- },
1977
- adornedEnd: {
1978
- padding: theme.spacing(0.5),
1979
- },
1980
- }); });
1981
-
1982
- var QuantityPicker = function (props) {
1983
- var value = props.value, onChange = props.onChange, disabled = props.disabled;
1984
- var fieldClasses = useQuantityPickerStyles();
1985
- var inputClasses = useQuantityInputStyles();
1986
- var onIncrement = function () {
1987
- onChange({ target: { value: value + 1 } }, 'increment');
1988
- };
1989
- var onDecrement = function () {
1990
- onChange({ target: { value: value - 1 } }, 'decrement');
1991
- };
1992
- var handleChange = function (event) {
1993
- onChange({ target: { value: parseInt(event.target.value) } }, 'change');
1994
- };
1995
- return (React__default['default'].createElement(core.TextField, { classes: __assign$1({}, fieldClasses), variant: "filled", type: "number", defaultValue: value, value: value, disabled: disabled, onChange: handleChange, InputProps: {
1996
- classes: __assign$1({}, inputClasses),
1997
- disableUnderline: true,
1998
- endAdornment: (React__default['default'].createElement(IconButton, { color: "default", tabIndex: -1, onClick: onIncrement, disabled: disabled },
1999
- React__default['default'].createElement(Icon, { icon: SvgPlusCircle }))),
2000
- startAdornment: (React__default['default'].createElement(IconButton, { color: "default", tabIndex: -1, onClick: onDecrement, disabled: disabled },
2001
- React__default['default'].createElement(Icon, { icon: SvgMinusCircle }))),
2002
- } }));
2003
- };
2004
-
2005
2050
  var useSelectableChipStyles = styles.makeStyles(function (theme) { return ({
2006
2051
  root: {
2007
2052
  border: '2px solid',