react-sync-board 0.5.5 → 0.6.1

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/dist/cjs/index.js CHANGED
@@ -7,6 +7,27 @@ var recoil = require('recoil');
7
7
 
8
8
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
9
 
10
+ function _interopNamespace(e) {
11
+ if (e && e.__esModule) return e;
12
+ var n = Object.create(null);
13
+ if (e) {
14
+ Object.keys(e).forEach(function (k) {
15
+ if (k !== 'default') {
16
+ var d = Object.getOwnPropertyDescriptor(e, k);
17
+ Object.defineProperty(n, k, d.get ? d : {
18
+ enumerable: true,
19
+ get: function () {
20
+ return e[k];
21
+ }
22
+ });
23
+ }
24
+ });
25
+ }
26
+ n['default'] = e;
27
+ return Object.freeze(n);
28
+ }
29
+
30
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
10
31
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
11
32
 
12
33
  function ownKeys(object, enumerableOnly) {
@@ -468,26 +489,17 @@ function _createForOfIteratorHelper(o, allowArrayLike) {
468
489
  };
469
490
  }
470
491
 
471
- // This file replaces `index.js` in bundlers like webpack or Rollup,
472
-
473
492
  var nanoid = function nanoid() {
474
493
  var size = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 21;
475
494
  var id = '';
476
- var bytes = crypto.getRandomValues(new Uint8Array(size)); // A compact alternative for `for (var i = 0; i < step; i++)`.
495
+ var bytes = crypto.getRandomValues(new Uint8Array(size));
477
496
 
478
497
  while (size--) {
479
- // It is incorrect to use bytes exceeding the alphabet size.
480
- // The following mask reduces the random byte in the 0-255 value
481
- // range to the 0-63 value range. Therefore, adding hacks, such
482
- // as empty string fallback or magic numbers, is unneccessary because
483
- // the bitmask trims bytes down to the alphabet size.
484
498
  var _byte = bytes[size] & 63;
485
499
 
486
500
  if (_byte < 36) {
487
- // `0-9a-z`
488
501
  id += _byte.toString(36);
489
502
  } else if (_byte < 62) {
490
- // `A-Z`
491
503
  id += (_byte - 26).toString(36).toUpperCase();
492
504
  } else if (_byte < 63) {
493
505
  id += '_';
@@ -779,7 +791,7 @@ function memoize(fn) {
779
791
  };
780
792
  }
781
793
 
782
- var reactPropsRegex = /^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|disablePictureInPicture|download|draggable|encType|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|translate|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|fallback|inert|itemProp|itemScope|itemType|itemID|itemRef|on|option|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/; // https://esbench.com/bench/5bfee68a4cd7e6009ef61d23
794
+ var reactPropsRegex = /^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|abbr|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|disablePictureInPicture|download|draggable|encType|enterKeyHint|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|translate|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|incremental|fallback|inert|itemProp|itemScope|itemType|itemID|itemRef|on|option|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/; // https://esbench.com/bench/5bfee68a4cd7e6009ef61d23
783
795
 
784
796
  var isPropValid = /* #__PURE__ */memoize(function (prop) {
785
797
  return reactPropsRegex.test(prop) || prop.charCodeAt(0) === 111
@@ -852,7 +864,13 @@ var StyleSheet = /*#__PURE__*/function () {
852
864
  var before;
853
865
 
854
866
  if (_this.tags.length === 0) {
855
- before = _this.prepend ? _this.container.firstChild : _this.before;
867
+ if (_this.insertionPoint) {
868
+ before = _this.insertionPoint.nextSibling;
869
+ } else if (_this.prepend) {
870
+ before = _this.container.firstChild;
871
+ } else {
872
+ before = _this.before;
873
+ }
856
874
  } else {
857
875
  before = _this.tags[_this.tags.length - 1].nextSibling;
858
876
  }
@@ -870,6 +888,7 @@ var StyleSheet = /*#__PURE__*/function () {
870
888
  this.key = options.key;
871
889
  this.container = options.container;
872
890
  this.prepend = options.prepend;
891
+ this.insertionPoint = options.insertionPoint;
873
892
  this.before = null;
874
893
  }
875
894
 
@@ -910,7 +929,7 @@ var StyleSheet = /*#__PURE__*/function () {
910
929
  // the big drawback is that the css won't be editable in devtools
911
930
  sheet.insertRule(rule, sheet.cssRules.length);
912
931
  } catch (e) {
913
- if (process.env.NODE_ENV !== 'production' && !/:(-moz-placeholder|-ms-input-placeholder|-moz-read-write|-moz-read-only){/.test(rule)) {
932
+ if (process.env.NODE_ENV !== 'production' && !/:(-moz-placeholder|-moz-focus-inner|-moz-focusring|-ms-input-placeholder|-moz-read-write|-moz-read-only|-ms-clear){/.test(rule)) {
914
933
  console.error("There was a problem inserting the following rule: \"" + rule + "\"", e);
915
934
  }
916
935
  }
@@ -924,7 +943,7 @@ var StyleSheet = /*#__PURE__*/function () {
924
943
  _proto.flush = function flush() {
925
944
  // $FlowFixMe
926
945
  this.tags.forEach(function (tag) {
927
- return tag.parentNode.removeChild(tag);
946
+ return tag.parentNode && tag.parentNode.removeChild(tag);
928
947
  });
929
948
  this.tags = [];
930
949
  this.ctr = 0;
@@ -957,13 +976,19 @@ var abs = Math.abs;
957
976
  */
958
977
 
959
978
  var from = String.fromCharCode;
979
+ /**
980
+ * @param {object}
981
+ * @return {object}
982
+ */
983
+
984
+ var assign = Object.assign;
960
985
  /**
961
986
  * @param {string} value
962
987
  * @param {number} length
963
988
  * @return {number}
964
989
  */
965
990
 
966
- function hash(value, length) {
991
+ function hash$1(value, length) {
967
992
  return (((length << 2 ^ charat(value, 0)) << 2 ^ charat(value, 1)) << 2 ^ charat(value, 2)) << 2 ^ charat(value, 3);
968
993
  }
969
994
  /**
@@ -995,7 +1020,7 @@ function replace(value, pattern, replacement) {
995
1020
  }
996
1021
  /**
997
1022
  * @param {string} value
998
- * @param {string} value
1023
+ * @param {string} search
999
1024
  * @return {number}
1000
1025
  */
1001
1026
 
@@ -1064,11 +1089,11 @@ var character = 0;
1064
1089
  var characters = '';
1065
1090
  /**
1066
1091
  * @param {string} value
1067
- * @param {object} root
1068
- * @param {object?} parent
1092
+ * @param {object | null} root
1093
+ * @param {object | null} parent
1069
1094
  * @param {string} type
1070
- * @param {string[]} props
1071
- * @param {object[]} children
1095
+ * @param {string[] | string} props
1096
+ * @param {object[] | string} children
1072
1097
  * @param {number} length
1073
1098
  */
1074
1099
 
@@ -1087,13 +1112,15 @@ function node(value, root, parent, type, props, children, length) {
1087
1112
  };
1088
1113
  }
1089
1114
  /**
1090
- * @param {string} value
1091
1115
  * @param {object} root
1092
- * @param {string} type
1116
+ * @param {object} props
1117
+ * @return {object}
1093
1118
  */
1094
1119
 
1095
- function copy(value, root, type) {
1096
- return node(value, root.root, root.parent, type, root.props, root.children, 0);
1120
+ function copy(root, props) {
1121
+ return assign(node('', null, null, '', null, null, 0), root, {
1122
+ length: -root.length
1123
+ }, props);
1097
1124
  }
1098
1125
  /**
1099
1126
  * @return {number}
@@ -1252,7 +1279,8 @@ function delimiter(type) {
1252
1279
 
1253
1280
  case 34:
1254
1281
  case 39:
1255
- return delimiter(type === 34 || type === 39 ? type : character);
1282
+ if (type !== 34 && type !== 39) delimiter(character);
1283
+ break;
1256
1284
  // (
1257
1285
 
1258
1286
  case 40:
@@ -1336,11 +1364,18 @@ function parse(value, root, parent, rule, rules, rulesets, pseudo, points, decla
1336
1364
 
1337
1365
  while (scanning) {
1338
1366
  switch (previous = character, character = next()) {
1339
- // " ' [ (
1367
+ // (
1368
+ case 40:
1369
+ if (previous != 108 && characters.charCodeAt(length - 1) == 58) {
1370
+ if (indexof(characters += replace(delimit(character), '&', '&\f'), '&\f') != -1) ampersand = -1;
1371
+ break;
1372
+ }
1373
+
1374
+ // " ' [
1375
+
1340
1376
  case 34:
1341
1377
  case 39:
1342
1378
  case 91:
1343
- case 40:
1344
1379
  characters += delimit(character);
1345
1380
  break;
1346
1381
  // \t \n \r \s
@@ -1406,7 +1441,7 @@ function parse(value, root, parent, rule, rules, rulesets, pseudo, points, decla
1406
1441
  break;
1407
1442
 
1408
1443
  default:
1409
- parse(characters, reference, reference, reference, [''], children, length, points, children);
1444
+ parse(characters, reference, reference, reference, [''], children, 0, points, children);
1410
1445
  }
1411
1446
  }
1412
1447
 
@@ -1435,7 +1470,7 @@ function parse(value, root, parent, rule, rules, rulesets, pseudo, points, decla
1435
1470
  case 64:
1436
1471
  // -
1437
1472
  if (peek() === 45) characters += delimit(next());
1438
- atrule = peek(), offset = strlen(type = characters += identifier(caret())), character++;
1473
+ atrule = peek(), offset = length = strlen(type = characters += identifier(caret())), character++;
1439
1474
  break;
1440
1475
  // -
1441
1476
 
@@ -1505,7 +1540,7 @@ function declaration(value, root, parent, length) {
1505
1540
  */
1506
1541
 
1507
1542
  function prefix(value, length) {
1508
- switch (hash(value, length)) {
1543
+ switch (hash$1(value, length)) {
1509
1544
  // color-adjust
1510
1545
  case 5103:
1511
1546
  return WEBKIT + 'print-' + value + value;
@@ -1710,6 +1745,9 @@ function stringify(element, index, children, callback) {
1710
1745
  case COMMENT:
1711
1746
  return '';
1712
1747
 
1748
+ case KEYFRAMES:
1749
+ return element["return"] = element.value + '{' + serialize(element.children, callback) + '}';
1750
+
1713
1751
  case RULESET:
1714
1752
  element.value = element.props.join(',');
1715
1753
  }
@@ -1752,13 +1790,15 @@ function rulesheet(callback) {
1752
1790
  */
1753
1791
 
1754
1792
  function prefixer(element, index, children, callback) {
1755
- if (!element["return"]) switch (element.type) {
1793
+ if (element.length > -1) if (!element["return"]) switch (element.type) {
1756
1794
  case DECLARATION:
1757
1795
  element["return"] = prefix(element.value, element.length);
1758
1796
  break;
1759
1797
 
1760
1798
  case KEYFRAMES:
1761
- return serialize([copy(replace(element.value, '@', '@' + WEBKIT), element, '')], callback);
1799
+ return serialize([copy(element, {
1800
+ value: replace(element.value, '@', '@' + WEBKIT)
1801
+ })], callback);
1762
1802
 
1763
1803
  case RULESET:
1764
1804
  if (element.length) return combine(element.props, function (value) {
@@ -1766,11 +1806,19 @@ function prefixer(element, index, children, callback) {
1766
1806
  // :read-(only|write)
1767
1807
  case ':read-only':
1768
1808
  case ':read-write':
1769
- return serialize([copy(replace(value, /:(read-\w+)/, ':' + MOZ + '$1'), element, '')], callback);
1809
+ return serialize([copy(element, {
1810
+ props: [replace(value, /:(read-\w+)/, ':' + MOZ + '$1')]
1811
+ })], callback);
1770
1812
  // :placeholder
1771
1813
 
1772
1814
  case '::placeholder':
1773
- return serialize([copy(replace(value, /:(plac\w+)/, ':' + WEBKIT + 'input-$1'), element, ''), copy(replace(value, /:(plac\w+)/, ':' + MOZ + '$1'), element, ''), copy(replace(value, /:(plac\w+)/, MS + 'input-$1'), element, '')], callback);
1815
+ return serialize([copy(element, {
1816
+ props: [replace(value, /:(plac\w+)/, ':' + WEBKIT + 'input-$1')]
1817
+ }), copy(element, {
1818
+ props: [replace(value, /:(plac\w+)/, ':' + MOZ + '$1')]
1819
+ }), copy(element, {
1820
+ props: [replace(value, /:(plac\w+)/, MS + 'input-$1')]
1821
+ })], callback);
1774
1822
  }
1775
1823
 
1776
1824
  return '';
@@ -1780,6 +1828,29 @@ function prefixer(element, index, children, callback) {
1780
1828
 
1781
1829
  var last = function last(arr) {
1782
1830
  return arr.length ? arr[arr.length - 1] : null;
1831
+ }; // based on https://github.com/thysultan/stylis.js/blob/e6843c373ebcbbfade25ebcc23f540ed8508da0a/src/Tokenizer.js#L239-L244
1832
+
1833
+
1834
+ var identifierWithPointTracking = function identifierWithPointTracking(begin, points, index) {
1835
+ var previous = 0;
1836
+ var character = 0;
1837
+
1838
+ while (true) {
1839
+ previous = character;
1840
+ character = peek(); // &\f
1841
+
1842
+ if (previous === 38 && character === 12) {
1843
+ points[index] = 1;
1844
+ }
1845
+
1846
+ if (token(character)) {
1847
+ break;
1848
+ }
1849
+
1850
+ next();
1851
+ }
1852
+
1853
+ return slice(begin, position);
1783
1854
  };
1784
1855
 
1785
1856
  var toRules = function toRules(parsed, points) {
@@ -1799,7 +1870,7 @@ var toRules = function toRules(parsed, points) {
1799
1870
  points[index] = 1;
1800
1871
  }
1801
1872
 
1802
- parsed[index] += identifier(position - 1);
1873
+ parsed[index] += identifierWithPointTracking(position - 1, points, index);
1803
1874
  break;
1804
1875
 
1805
1876
  case 2:
@@ -1833,8 +1904,9 @@ var getRules = function getRules(value, points) {
1833
1904
  var fixedElements = /* #__PURE__ */new WeakMap();
1834
1905
 
1835
1906
  var compat = function compat(element) {
1836
- if (element.type !== 'rule' || !element.parent || // .length indicates if this rule contains pseudo or not
1837
- !element.length) {
1907
+ if (element.type !== 'rule' || !element.parent || // positive .length indicates that this rule contains pseudo
1908
+ // negative .length indicates that this rule has been already prefixed
1909
+ element.length < 1) {
1838
1910
  return;
1839
1911
  }
1840
1912
 
@@ -2070,7 +2142,8 @@ var createCache = function createCache(options) {
2070
2142
  container: container,
2071
2143
  nonce: options.nonce,
2072
2144
  speedy: options.speedy,
2073
- prepend: options.prepend
2145
+ prepend: options.prepend,
2146
+ insertionPoint: options.insertionPoint
2074
2147
  }),
2075
2148
  nonce: options.nonce,
2076
2149
  inserted: inserted,
@@ -2088,22 +2161,22 @@ var reactIs$1 = {exports: {}};
2088
2161
  var reactIs_production_min = {};
2089
2162
 
2090
2163
  var b = "function" === typeof Symbol && Symbol["for"],
2091
- c$1 = b ? Symbol["for"]("react.element") : 60103,
2164
+ c = b ? Symbol["for"]("react.element") : 60103,
2092
2165
  d = b ? Symbol["for"]("react.portal") : 60106,
2093
- e$1 = b ? Symbol["for"]("react.fragment") : 60107,
2094
- f$1 = b ? Symbol["for"]("react.strict_mode") : 60108,
2166
+ e = b ? Symbol["for"]("react.fragment") : 60107,
2167
+ f = b ? Symbol["for"]("react.strict_mode") : 60108,
2095
2168
  g = b ? Symbol["for"]("react.profiler") : 60114,
2096
2169
  h = b ? Symbol["for"]("react.provider") : 60109,
2097
2170
  k = b ? Symbol["for"]("react.context") : 60110,
2098
- l$1 = b ? Symbol["for"]("react.async_mode") : 60111,
2171
+ l = b ? Symbol["for"]("react.async_mode") : 60111,
2099
2172
  m = b ? Symbol["for"]("react.concurrent_mode") : 60111,
2100
- n$1 = b ? Symbol["for"]("react.forward_ref") : 60112,
2173
+ n = b ? Symbol["for"]("react.forward_ref") : 60112,
2101
2174
  p = b ? Symbol["for"]("react.suspense") : 60113,
2102
2175
  q = b ? Symbol["for"]("react.suspense_list") : 60120,
2103
2176
  r$1 = b ? Symbol["for"]("react.memo") : 60115,
2104
- t$1 = b ? Symbol["for"]("react.lazy") : 60116,
2177
+ t = b ? Symbol["for"]("react.lazy") : 60116,
2105
2178
  v = b ? Symbol["for"]("react.block") : 60121,
2106
- w$1 = b ? Symbol["for"]("react.fundamental") : 60117,
2179
+ w = b ? Symbol["for"]("react.fundamental") : 60117,
2107
2180
  x = b ? Symbol["for"]("react.responder") : 60118,
2108
2181
  y = b ? Symbol["for"]("react.scope") : 60119;
2109
2182
 
@@ -2112,21 +2185,21 @@ function z(a) {
2112
2185
  var u = a.$$typeof;
2113
2186
 
2114
2187
  switch (u) {
2115
- case c$1:
2188
+ case c:
2116
2189
  switch (a = a.type, a) {
2117
- case l$1:
2190
+ case l:
2118
2191
  case m:
2119
- case e$1:
2192
+ case e:
2120
2193
  case g:
2121
- case f$1:
2194
+ case f:
2122
2195
  case p:
2123
2196
  return a;
2124
2197
 
2125
2198
  default:
2126
2199
  switch (a = a && a.$$typeof, a) {
2127
2200
  case k:
2128
- case n$1:
2129
- case t$1:
2201
+ case n:
2202
+ case t:
2130
2203
  case r$1:
2131
2204
  case h:
2132
2205
  return a;
@@ -2147,22 +2220,22 @@ function A(a) {
2147
2220
  return z(a) === m;
2148
2221
  }
2149
2222
 
2150
- reactIs_production_min.AsyncMode = l$1;
2223
+ reactIs_production_min.AsyncMode = l;
2151
2224
  reactIs_production_min.ConcurrentMode = m;
2152
2225
  reactIs_production_min.ContextConsumer = k;
2153
2226
  reactIs_production_min.ContextProvider = h;
2154
- reactIs_production_min.Element = c$1;
2155
- reactIs_production_min.ForwardRef = n$1;
2156
- reactIs_production_min.Fragment = e$1;
2157
- reactIs_production_min.Lazy = t$1;
2227
+ reactIs_production_min.Element = c;
2228
+ reactIs_production_min.ForwardRef = n;
2229
+ reactIs_production_min.Fragment = e;
2230
+ reactIs_production_min.Lazy = t;
2158
2231
  reactIs_production_min.Memo = r$1;
2159
2232
  reactIs_production_min.Portal = d;
2160
2233
  reactIs_production_min.Profiler = g;
2161
- reactIs_production_min.StrictMode = f$1;
2234
+ reactIs_production_min.StrictMode = f;
2162
2235
  reactIs_production_min.Suspense = p;
2163
2236
 
2164
2237
  reactIs_production_min.isAsyncMode = function (a) {
2165
- return A(a) || z(a) === l$1;
2238
+ return A(a) || z(a) === l;
2166
2239
  };
2167
2240
 
2168
2241
  reactIs_production_min.isConcurrentMode = A;
@@ -2176,19 +2249,19 @@ reactIs_production_min.isContextProvider = function (a) {
2176
2249
  };
2177
2250
 
2178
2251
  reactIs_production_min.isElement = function (a) {
2179
- return "object" === _typeof(a) && null !== a && a.$$typeof === c$1;
2252
+ return "object" === _typeof(a) && null !== a && a.$$typeof === c;
2180
2253
  };
2181
2254
 
2182
2255
  reactIs_production_min.isForwardRef = function (a) {
2183
- return z(a) === n$1;
2256
+ return z(a) === n;
2184
2257
  };
2185
2258
 
2186
2259
  reactIs_production_min.isFragment = function (a) {
2187
- return z(a) === e$1;
2260
+ return z(a) === e;
2188
2261
  };
2189
2262
 
2190
2263
  reactIs_production_min.isLazy = function (a) {
2191
- return z(a) === t$1;
2264
+ return z(a) === t;
2192
2265
  };
2193
2266
 
2194
2267
  reactIs_production_min.isMemo = function (a) {
@@ -2204,7 +2277,7 @@ reactIs_production_min.isProfiler = function (a) {
2204
2277
  };
2205
2278
 
2206
2279
  reactIs_production_min.isStrictMode = function (a) {
2207
- return z(a) === f$1;
2280
+ return z(a) === f;
2208
2281
  };
2209
2282
 
2210
2283
  reactIs_production_min.isSuspense = function (a) {
@@ -2212,7 +2285,7 @@ reactIs_production_min.isSuspense = function (a) {
2212
2285
  };
2213
2286
 
2214
2287
  reactIs_production_min.isValidElementType = function (a) {
2215
- return "string" === typeof a || "function" === typeof a || a === e$1 || a === m || a === g || a === f$1 || a === p || a === q || "object" === _typeof(a) && null !== a && (a.$$typeof === t$1 || a.$$typeof === r$1 || a.$$typeof === h || a.$$typeof === k || a.$$typeof === n$1 || a.$$typeof === w$1 || a.$$typeof === x || a.$$typeof === y || a.$$typeof === v);
2288
+ return "string" === typeof a || "function" === typeof a || a === e || a === m || a === g || a === f || a === p || a === q || "object" === _typeof(a) && null !== a && (a.$$typeof === t || a.$$typeof === r$1 || a.$$typeof === h || a.$$typeof === k || a.$$typeof === n || a.$$typeof === w || a.$$typeof === x || a.$$typeof === y || a.$$typeof === v);
2216
2289
  };
2217
2290
 
2218
2291
  reactIs_production_min.typeOf = z;
@@ -2438,7 +2511,7 @@ function getRegisteredStyles$1(registered, registeredStyles, classNames) {
2438
2511
  return rawClassName;
2439
2512
  }
2440
2513
 
2441
- var insertStyles$1 = function insertStyles(cache, serialized, isStringTag) {
2514
+ var registerStyles$1 = function registerStyles(cache, serialized, isStringTag) {
2442
2515
  var className = cache.key + "-" + serialized.name;
2443
2516
 
2444
2517
  if ( // we only need to add the styles to the registered cache if the
@@ -2453,6 +2526,11 @@ var insertStyles$1 = function insertStyles(cache, serialized, isStringTag) {
2453
2526
  isBrowser$3 === false) && cache.registered[className] === undefined) {
2454
2527
  cache.registered[className] = serialized.styles;
2455
2528
  }
2529
+ };
2530
+
2531
+ var insertStyles$1 = function insertStyles(cache, serialized, isStringTag) {
2532
+ registerStyles$1(cache, serialized, isStringTag);
2533
+ var className = cache.key + "-" + serialized.name;
2456
2534
 
2457
2535
  if (cache.inserted[serialized.name] === undefined) {
2458
2536
  var current = serialized;
@@ -2610,7 +2688,7 @@ var processStyleValue$1 = function processStyleValue(key, value) {
2610
2688
  };
2611
2689
 
2612
2690
  if (process.env.NODE_ENV !== 'production') {
2613
- var contentValuePattern$1 = /(attr|counters?|url|(((repeating-)?(linear|radial))|conic)-gradient)\(|(no-)?(open|close)-quote/;
2691
+ var contentValuePattern$1 = /(var|attr|counters?|url|(((repeating-)?(linear|radial))|conic)-gradient)\(|(no-)?(open|close)-quote/;
2614
2692
  var contentValues$1 = ['normal', 'none', 'initial', 'inherit', 'unset'];
2615
2693
  var oldProcessStyleValue$1 = processStyleValue$1;
2616
2694
  var msPattern$1 = /^-ms-/;
@@ -2877,7 +2955,7 @@ var serializeStyles$1 = function serializeStyles(args, registered, mergedProps)
2877
2955
  };
2878
2956
  };
2879
2957
 
2880
- var hasOwnProperty = Object.prototype.hasOwnProperty;
2958
+ var hasOwnProperty = {}.hasOwnProperty;
2881
2959
  var EmotionCacheContext = /* #__PURE__ */React.createContext( // we're doing this to avoid preconstruct's dead code elimination in this one case
2882
2960
  // because this module is primarily intended for the browser and node
2883
2961
  // but it's also required in react native and similar environments sometimes
@@ -2887,6 +2965,11 @@ var EmotionCacheContext = /* #__PURE__ */React.createContext( // we're doing thi
2887
2965
  typeof HTMLElement !== 'undefined' ? /* #__PURE__ */createCache({
2888
2966
  key: 'css'
2889
2967
  }) : null);
2968
+
2969
+ if (process.env.NODE_ENV !== 'production') {
2970
+ EmotionCacheContext.displayName = 'EmotionCacheContext';
2971
+ }
2972
+
2890
2973
  EmotionCacheContext.Provider;
2891
2974
 
2892
2975
  var withEmotionCache = function withEmotionCache(func) {
@@ -2900,9 +2983,32 @@ var withEmotionCache = function withEmotionCache(func) {
2900
2983
 
2901
2984
  var ThemeContext = /* #__PURE__ */React.createContext({});
2902
2985
 
2986
+ if (process.env.NODE_ENV !== 'production') {
2987
+ ThemeContext.displayName = 'EmotionThemeContext';
2988
+ }
2989
+
2990
+ var useInsertionEffect$2 = React__namespace['useInsertion' + 'Effect'] ? React__namespace['useInsertion' + 'Effect'] : function useInsertionEffect(create) {
2991
+ create();
2992
+ };
2993
+
2994
+ function useInsertionEffectMaybe$1(create) {
2995
+ useInsertionEffect$2(create);
2996
+ }
2997
+
2903
2998
  var typePropName = '__EMOTION_TYPE_PLEASE_DO_NOT_USE__';
2904
2999
  var labelPropName = '__EMOTION_LABEL_PLEASE_DO_NOT_USE__';
2905
3000
 
3001
+ var Insertion$2 = function Insertion(_ref) {
3002
+ var cache = _ref.cache,
3003
+ serialized = _ref.serialized,
3004
+ isStringTag = _ref.isStringTag;
3005
+ registerStyles$1(cache, serialized, isStringTag);
3006
+ useInsertionEffectMaybe$1(function () {
3007
+ return insertStyles$1(cache, serialized, isStringTag);
3008
+ });
3009
+ return null;
3010
+ };
3011
+
2906
3012
  var Emotion = /* #__PURE__ */withEmotionCache(function (props, cache, ref) {
2907
3013
  var cssProp = props.css; // so that using `css` from `emotion` and passing the result to the css prop works
2908
3014
  // not passing the registered cache to serializeStyles because it would
@@ -2912,7 +3018,7 @@ var Emotion = /* #__PURE__ */withEmotionCache(function (props, cache, ref) {
2912
3018
  cssProp = cache.registered[cssProp];
2913
3019
  }
2914
3020
 
2915
- var type = props[typePropName];
3021
+ var WrappedComponent = props[typePropName];
2916
3022
  var registeredStyles = [cssProp];
2917
3023
  var className = '';
2918
3024
 
@@ -2922,7 +3028,7 @@ var Emotion = /* #__PURE__ */withEmotionCache(function (props, cache, ref) {
2922
3028
  className = props.className + " ";
2923
3029
  }
2924
3030
 
2925
- var serialized = serializeStyles$1(registeredStyles, undefined, typeof cssProp === 'function' || Array.isArray(cssProp) ? React.useContext(ThemeContext) : undefined);
3031
+ var serialized = serializeStyles$1(registeredStyles, undefined, React.useContext(ThemeContext));
2926
3032
 
2927
3033
  if (process.env.NODE_ENV !== 'production' && serialized.name.indexOf('-') === -1) {
2928
3034
  var labelFromStack = props[labelPropName];
@@ -2932,7 +3038,6 @@ var Emotion = /* #__PURE__ */withEmotionCache(function (props, cache, ref) {
2932
3038
  }
2933
3039
  }
2934
3040
 
2935
- insertStyles$1(cache, serialized, typeof type === 'string');
2936
3041
  className += cache.key + "-" + serialized.name;
2937
3042
  var newProps = {};
2938
3043
 
@@ -2944,8 +3049,11 @@ var Emotion = /* #__PURE__ */withEmotionCache(function (props, cache, ref) {
2944
3049
 
2945
3050
  newProps.ref = ref;
2946
3051
  newProps.className = className;
2947
- var ele = /*#__PURE__*/React.createElement(type, newProps);
2948
- return ele;
3052
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Insertion$2, {
3053
+ cache: cache,
3054
+ serialized: serialized,
3055
+ isStringTag: typeof WrappedComponent === 'string'
3056
+ }), /*#__PURE__*/React.createElement(WrappedComponent, newProps));
2949
3057
  });
2950
3058
 
2951
3059
  if (process.env.NODE_ENV !== 'production') {
@@ -2954,7 +3062,7 @@ if (process.env.NODE_ENV !== 'production') {
2954
3062
 
2955
3063
  var pkg = {
2956
3064
  name: "@emotion/react",
2957
- version: "11.4.0",
3065
+ version: "11.9.0",
2958
3066
  main: "dist/emotion-react.cjs.js",
2959
3067
  module: "dist/emotion-react.esm.js",
2960
3068
  browser: {
@@ -2962,19 +3070,19 @@ var pkg = {
2962
3070
  "./dist/emotion-react.esm.js": "./dist/emotion-react.browser.esm.js"
2963
3071
  },
2964
3072
  types: "types/index.d.ts",
2965
- files: ["src", "dist", "jsx-runtime", "jsx-dev-runtime", "isolated-hoist-non-react-statics-do-not-use-this-in-your-code", "types/*.d.ts", "macro.js", "macro.d.ts", "macro.js.flow"],
3073
+ files: ["src", "dist", "jsx-runtime", "jsx-dev-runtime", "_isolated-hnrs", "types/*.d.ts", "macro.js", "macro.d.ts", "macro.js.flow"],
2966
3074
  sideEffects: false,
2967
- author: "mitchellhamilton <mitchell@mitchellhamilton.me>",
3075
+ author: "Emotion Contributors",
2968
3076
  license: "MIT",
2969
3077
  scripts: {
2970
3078
  "test:typescript": "dtslint types"
2971
3079
  },
2972
3080
  dependencies: {
2973
3081
  "@babel/runtime": "^7.13.10",
2974
- "@emotion/cache": "^11.4.0",
2975
- "@emotion/serialize": "^1.0.2",
2976
- "@emotion/sheet": "^1.0.1",
2977
- "@emotion/utils": "^1.0.0",
3082
+ "@emotion/babel-plugin": "^11.7.1",
3083
+ "@emotion/cache": "^11.7.1",
3084
+ "@emotion/serialize": "^1.0.3",
3085
+ "@emotion/utils": "^1.1.0",
2978
3086
  "@emotion/weak-memoize": "^0.2.5",
2979
3087
  "hoist-non-react-statics": "^3.3.1"
2980
3088
  },
@@ -2992,15 +3100,16 @@ var pkg = {
2992
3100
  },
2993
3101
  devDependencies: {
2994
3102
  "@babel/core": "^7.13.10",
2995
- "@emotion/css": "11.1.3",
2996
- "@emotion/css-prettifier": "1.0.0",
3103
+ "@emotion/css": "11.9.0",
3104
+ "@emotion/css-prettifier": "1.0.1",
2997
3105
  "@emotion/server": "11.4.0",
2998
- "@emotion/styled": "11.3.0",
3106
+ "@emotion/styled": "11.8.1",
2999
3107
  "@types/react": "^16.9.11",
3000
- dtslint: "^0.3.0",
3108
+ dtslint: "^4.2.1",
3001
3109
  "html-tag-names": "^1.1.2",
3002
3110
  react: "16.14.0",
3003
- "svg-tag-names": "^1.1.1"
3111
+ "svg-tag-names": "^1.1.1",
3112
+ typescript: "^4.5.5"
3004
3113
  },
3005
3114
  repository: "https://github.com/emotion-js/emotion/tree/main/packages/react",
3006
3115
  publishConfig: {
@@ -3008,11 +3117,12 @@ var pkg = {
3008
3117
  },
3009
3118
  "umd:main": "dist/emotion-react.umd.min.js",
3010
3119
  preconstruct: {
3011
- entrypoints: ["./index.js", "./jsx-runtime.js", "./jsx-dev-runtime.js", "./isolated-hoist-non-react-statics-do-not-use-this-in-your-code.js"],
3120
+ entrypoints: ["./index.js", "./jsx-runtime.js", "./jsx-dev-runtime.js", "./_isolated-hnrs.js"],
3012
3121
  umdName: "emotionReact"
3013
3122
  }
3014
3123
  };
3015
3124
 
3125
+ var useInsertionEffect$1 = React__namespace['useInsertion' + 'Effect'] ? React__namespace['useInsertion' + 'Effect'] : React.useLayoutEffect;
3016
3126
  var warnedAboutCssPropForGlobal = false; // maintain place over rerenders.
3017
3127
  // initial render from browser, insertBefore context.sheet.tags[0] or if a style hasn't been inserted there yet, appendChild
3018
3128
  // initial client-side render from SSR, use place of hydrating tag
@@ -3028,14 +3138,15 @@ var Global = /* #__PURE__ */withEmotionCache(function (props, cache) {
3028
3138
  }
3029
3139
 
3030
3140
  var styles = props.styles;
3031
- var serialized = serializeStyles$1([styles], undefined, typeof styles === 'function' || Array.isArray(styles) ? React.useContext(ThemeContext) : undefined); // but it is based on a constant that will never change at runtime
3141
+ var serialized = serializeStyles$1([styles], undefined, React.useContext(ThemeContext)); // but it is based on a constant that will never change at runtime
3032
3142
  // it's effectively like having two implementations and switching them out
3033
3143
  // so it's not actually breaking anything
3034
3144
 
3035
3145
  var sheetRef = React.useRef();
3036
- React.useLayoutEffect(function () {
3037
- var key = cache.key + "-global";
3038
- var sheet = new StyleSheet({
3146
+ useInsertionEffect$1(function () {
3147
+ var key = cache.key + "-global"; // use case of https://github.com/emotion-js/emotion/issues/2675
3148
+
3149
+ var sheet = new cache.sheet.constructor({
3039
3150
  key: key,
3040
3151
  nonce: cache.sheet.nonce,
3041
3152
  container: cache.sheet.container,
@@ -3061,7 +3172,7 @@ var Global = /* #__PURE__ */withEmotionCache(function (props, cache) {
3061
3172
  sheet.flush();
3062
3173
  };
3063
3174
  }, [cache]);
3064
- React.useLayoutEffect(function () {
3175
+ useInsertionEffect$1(function () {
3065
3176
  var sheetRefCurrent = sheetRef.current;
3066
3177
  var sheet = sheetRefCurrent[0],
3067
3178
  rehydrating = sheetRefCurrent[1];
@@ -3176,8 +3287,20 @@ function merge(registered, css, className) {
3176
3287
  return rawClassName + css(registeredStyles);
3177
3288
  }
3178
3289
 
3290
+ var Insertion$1 = function Insertion(_ref) {
3291
+ var cache = _ref.cache,
3292
+ serializedArr = _ref.serializedArr;
3293
+ useInsertionEffectMaybe$1(function () {
3294
+ for (var i = 0; i < serializedArr.length; i++) {
3295
+ insertStyles$1(cache, serializedArr[i], false);
3296
+ }
3297
+ });
3298
+ return null;
3299
+ };
3300
+
3179
3301
  var ClassNames = /* #__PURE__ */withEmotionCache(function (props, cache) {
3180
3302
  var hasRendered = false;
3303
+ var serializedArr = [];
3181
3304
 
3182
3305
  var css = function css() {
3183
3306
  if (hasRendered && process.env.NODE_ENV !== 'production') {
@@ -3189,9 +3312,9 @@ var ClassNames = /* #__PURE__ */withEmotionCache(function (props, cache) {
3189
3312
  }
3190
3313
 
3191
3314
  var serialized = serializeStyles$1(args, cache.registered);
3192
- {
3193
- insertStyles$1(cache, serialized, false);
3194
- }
3315
+ serializedArr.push(serialized); // registration has to happen here as the result of this might get consumed by `cx`
3316
+
3317
+ registerStyles$1(cache, serialized, false);
3195
3318
  return cache.key + "-" + serialized.name;
3196
3319
  };
3197
3320
 
@@ -3214,7 +3337,10 @@ var ClassNames = /* #__PURE__ */withEmotionCache(function (props, cache) {
3214
3337
  };
3215
3338
  var ele = props.children(content);
3216
3339
  hasRendered = true;
3217
- return ele;
3340
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Insertion$1, {
3341
+ cache: cache,
3342
+ serializedArr: serializedArr
3343
+ }), ele);
3218
3344
  });
3219
3345
 
3220
3346
  if (process.env.NODE_ENV !== 'production') {
@@ -3227,7 +3353,10 @@ if (process.env.NODE_ENV !== 'production') {
3227
3353
  var isJest = typeof jest !== 'undefined';
3228
3354
 
3229
3355
  if (isBrowser$2 && !isJest) {
3230
- var globalContext = isBrowser$2 ? window : global;
3356
+ // globalThis has wide browser support - https://caniuse.com/?search=globalThis, Node.js 12 and later
3357
+ var globalContext = // $FlowIgnore
3358
+ typeof globalThis !== 'undefined' ? globalThis // eslint-disable-line no-undef
3359
+ : isBrowser$2 ? window : global;
3231
3360
  var globalKey = "__EMOTION_REACT_" + pkg.version.split('.')[0] + "__";
3232
3361
 
3233
3362
  if (globalContext[globalKey]) {
@@ -3252,7 +3381,7 @@ function getRegisteredStyles(registered, registeredStyles, classNames) {
3252
3381
  return rawClassName;
3253
3382
  }
3254
3383
 
3255
- var insertStyles = function insertStyles(cache, serialized, isStringTag) {
3384
+ var registerStyles = function registerStyles(cache, serialized, isStringTag) {
3256
3385
  var className = cache.key + "-" + serialized.name;
3257
3386
 
3258
3387
  if ( // we only need to add the styles to the registered cache if the
@@ -3267,6 +3396,11 @@ var insertStyles = function insertStyles(cache, serialized, isStringTag) {
3267
3396
  isBrowser$1 === false) && cache.registered[className] === undefined) {
3268
3397
  cache.registered[className] = serialized.styles;
3269
3398
  }
3399
+ };
3400
+
3401
+ var insertStyles = function insertStyles(cache, serialized, isStringTag) {
3402
+ registerStyles(cache, serialized, isStringTag);
3403
+ var className = cache.key + "-" + serialized.name;
3270
3404
 
3271
3405
  if (cache.inserted[serialized.name] === undefined) {
3272
3406
  var current = serialized;
@@ -3618,8 +3752,27 @@ var composeShouldForwardProps = function composeShouldForwardProps(tag, options,
3618
3752
  return shouldForwardProp;
3619
3753
  };
3620
3754
 
3755
+ var useInsertionEffect = React__namespace['useInsertion' + 'Effect'] ? React__namespace['useInsertion' + 'Effect'] : function useInsertionEffect(create) {
3756
+ create();
3757
+ };
3758
+
3759
+ function useInsertionEffectMaybe(create) {
3760
+ useInsertionEffect(create);
3761
+ }
3762
+
3621
3763
  var ILLEGAL_ESCAPE_SEQUENCE_ERROR = "You have illegal escape sequence in your template literal, most likely inside content's property value.\nBecause you write your CSS inside a JavaScript string you actually have to do double escaping, so for example \"content: '\\00d7';\" should become \"content: '\\\\00d7';\".\nYou can read more about this here:\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#ES2018_revision_of_illegal_escape_sequences";
3622
3764
 
3765
+ var Insertion = function Insertion(_ref) {
3766
+ var cache = _ref.cache,
3767
+ serialized = _ref.serialized,
3768
+ isStringTag = _ref.isStringTag;
3769
+ registerStyles(cache, serialized, isStringTag);
3770
+ useInsertionEffectMaybe(function () {
3771
+ return insertStyles(cache, serialized, isStringTag);
3772
+ });
3773
+ return null;
3774
+ };
3775
+
3623
3776
  var createStyled = function createStyled(tag, options) {
3624
3777
  if (process.env.NODE_ENV !== 'production') {
3625
3778
  if (tag === undefined) {
@@ -3670,7 +3823,7 @@ var createStyled = function createStyled(tag, options) {
3670
3823
 
3671
3824
 
3672
3825
  var Styled = withEmotionCache(function (props, cache, ref) {
3673
- var finalTag = shouldUseAs && props.as || baseTag;
3826
+ var FinalTag = shouldUseAs && props.as || baseTag;
3674
3827
  var className = '';
3675
3828
  var classInterpolations = [];
3676
3829
  var mergedProps = props;
@@ -3692,14 +3845,13 @@ var createStyled = function createStyled(tag, options) {
3692
3845
  }
3693
3846
 
3694
3847
  var serialized = serializeStyles(styles.concat(classInterpolations), cache.registered, mergedProps);
3695
- insertStyles(cache, serialized, typeof finalTag === 'string');
3696
3848
  className += cache.key + "-" + serialized.name;
3697
3849
 
3698
3850
  if (targetClassName !== undefined) {
3699
3851
  className += " " + targetClassName;
3700
3852
  }
3701
3853
 
3702
- var finalShouldForwardProp = shouldUseAs && shouldForwardProp === undefined ? getDefaultShouldForwardProp(finalTag) : defaultShouldForwardProp;
3854
+ var finalShouldForwardProp = shouldUseAs && shouldForwardProp === undefined ? getDefaultShouldForwardProp(FinalTag) : defaultShouldForwardProp;
3703
3855
  var newProps = {};
3704
3856
 
3705
3857
  for (var _key in props) {
@@ -3713,8 +3865,11 @@ var createStyled = function createStyled(tag, options) {
3713
3865
 
3714
3866
  newProps.className = className;
3715
3867
  newProps.ref = ref;
3716
- var ele = /*#__PURE__*/React.createElement(finalTag, newProps);
3717
- return ele;
3868
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Insertion, {
3869
+ cache: cache,
3870
+ serialized: serialized,
3871
+ isStringTag: typeof FinalTag === 'string'
3872
+ }), /*#__PURE__*/React.createElement(FinalTag, newProps));
3718
3873
  });
3719
3874
  Styled.displayName = identifierName !== undefined ? identifierName : "Styled(" + (typeof baseTag === 'string' ? baseTag : baseTag.displayName || baseTag.name || 'Component') + ")";
3720
3875
  Styled.defaultProps = tag.defaultProps;
@@ -3983,10 +4138,6 @@ var useItemList = function useItemList() {
3983
4138
  return items;
3984
4139
  };
3985
4140
 
3986
- var useSelectedItems = function useSelectedItems() {
3987
- return recoil.useRecoilValue(SelectedItemsAtom);
3988
- };
3989
-
3990
4141
  /**
3991
4142
  * Run effect only when component is unmounted.
3992
4143
  *
@@ -4174,6 +4325,28 @@ function useThrottledCallback(callback, deps, delay, noTrailing) {
4174
4325
  }, __spreadArray([delay, noTrailing], deps, true));
4175
4326
  }
4176
4327
 
4328
+ /* eslint-disable @typescript-eslint/no-explicit-any */
4329
+ /**
4330
+ * Like `useEffect`, but passed function is debounced.
4331
+ *
4332
+ * @param callback Callback like for `useEffect`, but without ability to return
4333
+ * a cleanup function.
4334
+ * @param deps Dependencies list that will be passed to underlying `useEffect`
4335
+ * and `useDebouncedCallback`.
4336
+ * @param delay Debounce delay.
4337
+ * @param maxWait Maximum amount of milliseconds that function can be delayed
4338
+ * before it's force execution. 0 means no max wait.
4339
+ */
4340
+
4341
+ function useDebouncedEffect(callback, deps, delay, maxWait) {
4342
+ if (maxWait === void 0) {
4343
+ maxWait = 0;
4344
+ } // eslint-disable-next-line react-hooks/exhaustive-deps
4345
+
4346
+
4347
+ React.useEffect(useDebouncedCallback(callback, deps, delay, maxWait), deps);
4348
+ }
4349
+
4177
4350
  /* eslint-disable @typescript-eslint/no-explicit-any */
4178
4351
  /**
4179
4352
  * Like `useEffect`, but passed function is throttled.
@@ -4318,1196 +4491,1349 @@ function useResizeObserver(target, callback, enabled) {
4318
4491
  }, [target, ro]);
4319
4492
  }
4320
4493
 
4321
- var img = "data:image/svg+xml,%3c%3fxml version='1.0' encoding='UTF-8' standalone='no'%3f%3e%3csvg xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:cc='http://creativecommons.org/ns%23' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns%23' xmlns:svg='http://www.w3.org/2000/svg' xmlns='http://www.w3.org/2000/svg' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' version='1.1' x='0px' y='0px' viewBox='0 0 75.601318 94.9' xml:space='preserve' id='svg26' sodipodi:docname='lock.svg' width='75.601318' height='94.900002' inkscape:version='0.92.5 (2060ec1f9f%2c 2020-04-08)'%3e%3cmetadata id='metadata32'%3e%3crdf:RDF%3e%3ccc:Work rdf:about=''%3e%3cdc:format%3eimage/svg%2bxml%3c/dc:format%3e%3cdc:type rdf:resource='http://purl.org/dc/dcmitype/StillImage' /%3e%3cdc:title%3e%3c/dc:title%3e%3c/cc:Work%3e%3c/rdf:RDF%3e%3c/metadata%3e%3cdefs id='defs30' /%3e%3csodipodi:namedview pagecolor='black' bordercolor='%23666666' borderopacity='1' objecttolerance='10' gridtolerance='10' guidetolerance='10' inkscape:pageopacity='0' inkscape:pageshadow='2' inkscape:window-width='1848' inkscape:window-height='1016' id='namedview28' showgrid='false' fit-margin-top='0' fit-margin-left='0' fit-margin-right='0' fit-margin-bottom='0' inkscape:zoom='5.3400704' inkscape:cx='3.2640013' inkscape:cy='45.072152' inkscape:window-x='1512' inkscape:window-y='27' inkscape:window-maximized='1' inkscape:current-layer='g16' /%3e%3cg id='g16' transform='translate(-12.2%2c-2.5)'%3e%3cpath d='M 75.4%2c36.8 H 34.1 V 24.6 c 0%2c-8.8 7.1%2c-15.9 15.9%2c-15.9 8.8%2c0 15.9%2c7.1 15.9%2c15.9 0%2c1.7 1.4%2c3.1 3.1%2c3.1 1.7%2c0 3.1%2c-1.4 3.1%2c-3.1 C 72.1%2c12.4 62.2%2c2.5 50%2c2.5 37.8%2c2.5 27.9%2c12.4 27.9%2c24.6 v 12.2 h -3.3 c -6.9%2c0 -12.4%2c5.6 -12.4%2c12.4 V 85 c 0%2c6.9 5.6%2c12.4 12.4%2c12.4 h 50.8 c 6.9%2c0 12.4%2c-5.6 12.4%2c-12.4 V 49.2 C 87.9%2c42.3 82.3%2c36.8 75.4%2c36.8 Z m 6.2%2c48.3 c 0%2c3.4 -2.8%2c6.2 -6.2%2c6.2 H 24.6 c -3.4%2c0 -6.2%2c-2.8 -6.2%2c-6.2 V 49.2 c 0%2c-3.4 2.8%2c-6.2 6.2%2c-6.2 h 50.8 c 3.4%2c0 6.2%2c2.8 6.2%2c6.2 z' id='path12' inkscape:connector-curvature='0' style='fill:white%3bfill-opacity:1' /%3e%3cpath d='m 59.8%2c57.6 -12.5%2c12.5 -7%2c-7 c -1.2%2c-1.2 -3.2%2c-1.2 -4.4%2c0 -1.2%2c1.2 -1.2%2c3.2 0%2c4.4 l 9.2%2c9.2 c 0.6%2c0.6 1.4%2c0.9 2.2%2c0.9 0.8%2c0 1.6%2c-0.3 2.2%2c-0.9 L 64.2%2c62 c 1.2%2c-1.2 1.2%2c-3.2 0%2c-4.4 -1.2%2c-1.2 -3.2%2c-1.2 -4.4%2c0 z' id='path14' inkscape:connector-curvature='0' style='fill:white%3bfill-opacity:1' /%3e%3c/g%3e%3c/svg%3e";
4494
+ var useDebouncedItems = function useDebouncedItems() {
4495
+ var items = recoil.useRecoilValue(AllItemsSelector);
4322
4496
 
4323
- var _excluded$2 = ["type", "rotation", "id", "locked", "layer"],
4324
- _excluded2 = ["state", "boardSize", "currentUser"],
4325
- _excluded3 = ["x", "y", "layer", "moving"];
4497
+ var _React$useState = React__default['default'].useState(items),
4498
+ _React$useState2 = _slicedToArray(_React$useState, 2),
4499
+ debouncedItems = _React$useState2[0],
4500
+ setDebouncedItems = _React$useState2[1];
4326
4501
 
4327
- var _templateObject$2;
4328
- var ItemWrapper = newStyled.div(_templateObject$2 || (_templateObject$2 = _taggedTemplateLiteral(["\n display: inline-block;\n transition: transform 150ms;\n user-select: none;\n padding: 2px;\n transform: rotate(", "deg);\n\n & .corner {\n position: absolute;\n width: 0px;\n height: 0px;\n }\n\n & .top-left {\n top: 0;\n left: 0;\n }\n & .top-right {\n top: 0;\n right: 0;\n }\n & .bottom-left {\n bottom: 0;\n left: 0;\n }\n & .bottom-right {\n bottom: 0;\n right: 0;\n }\n\n &.selected {\n border: 2px dashed #db5034;\n padding: 0px;\n cursor: pointer;\n }\n\n &.locked::after {\n content: \"\";\n position: absolute;\n width: 24px;\n height: 30px;\n top: 4px;\n right: 4px;\n opacity: 0.1;\n background-image: url(\"", "\");\n background-size: cover;\n user-select: none;\n }\n\n &.locked:hover::after {\n opacity: 0.3;\n }\n"])), function (_ref) {
4329
- var rotation = _ref.rotation;
4330
- return rotation;
4331
- }, img);
4502
+ var updateDebouncedItems = recoil.useRecoilCallback(function (_ref) {
4503
+ var snapshot = _ref.snapshot;
4504
+ return /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
4505
+ var currentItemMap;
4506
+ return regeneratorRuntime.wrap(function _callee$(_context) {
4507
+ while (1) {
4508
+ switch (_context.prev = _context.next) {
4509
+ case 0:
4510
+ _context.next = 2;
4511
+ return snapshot.getPromise(AllItemsSelector);
4332
4512
 
4333
- var DefaultErrorComponent = function DefaultErrorComponent(_ref2) {
4334
- var onReload = _ref2.onReload;
4335
- return /*#__PURE__*/React__default['default'].createElement("div", {
4336
- style: {
4337
- width: "100px",
4338
- display: "flex",
4339
- flexDirection: "column",
4340
- justifyContent: "center",
4341
- textAlign: "center",
4342
- color: "red"
4343
- },
4344
- className: "syncboard-error-item"
4345
- }, "Sorry, this item seems broken.", /*#__PURE__*/React__default['default'].createElement("button", {
4346
- onClick: onReload
4347
- }, "Reload it"));
4348
- };
4349
- /* Error boundary for broken item */
4513
+ case 2:
4514
+ currentItemMap = _context.sent;
4515
+ setDebouncedItems(currentItemMap);
4350
4516
 
4517
+ case 4:
4518
+ case "end":
4519
+ return _context.stop();
4520
+ }
4521
+ }
4522
+ }, _callee);
4523
+ }));
4524
+ }, []);
4525
+ useDebouncedEffect(updateDebouncedItems, [items], 300);
4526
+ return debouncedItems;
4527
+ };
4351
4528
 
4352
- var ItemErrorBoundary = /*#__PURE__*/function (_React$Component) {
4353
- _inherits(ItemErrorBoundary, _React$Component);
4529
+ var useSelectedItems = function useSelectedItems() {
4530
+ return recoil.useRecoilValue(SelectedItemsAtom);
4531
+ };
4354
4532
 
4355
- var _super = _createSuper(ItemErrorBoundary);
4533
+ var isMacOS = function isMacOS() {
4534
+ var userAgent = navigator.userAgent.toLowerCase();
4535
+ return /mac os ?x 10/.test(userAgent);
4536
+ }; // From https://stackoverflow.com/questions/20110224/what-is-the-height-of-a-line-in-a-wheel-event-deltamode-dom-delta-line
4356
4537
 
4357
- function ItemErrorBoundary(props) {
4358
- var _this;
4538
+ var getScrollLineHeight = function getScrollLineHeight() {
4539
+ var iframe = document.createElement("iframe");
4540
+ iframe.src = "#";
4541
+ document.body.appendChild(iframe); // Write content in Iframe
4359
4542
 
4360
- _classCallCheck(this, ItemErrorBoundary);
4543
+ var idoc = iframe.contentWindow.document;
4544
+ idoc.open();
4545
+ idoc.write("<!DOCTYPE html><html><head></head><body><span>a</span></body></html>");
4546
+ idoc.close();
4547
+ var scrollLineHeight = idoc.body.firstElementChild.offsetHeight;
4548
+ document.body.removeChild(iframe);
4549
+ return scrollLineHeight;
4550
+ };
4361
4551
 
4362
- _this = _super.call(this, props);
4363
- _this.state = {
4364
- hasError: false,
4365
- itemId: props.itemId
4366
- };
4367
- _this.onReload = _this.onReload.bind(_assertThisInitialized(_this));
4368
- return _this;
4369
- }
4552
+ var LINE_HEIGHT = getScrollLineHeight(); // Reasonable default from https://github.com/facebookarchive/fixed-data-table/blob/master/src/vendor_upstream/dom/normalizeWheel.js
4370
4553
 
4371
- _createClass(ItemErrorBoundary, [{
4372
- key: "componentDidCatch",
4373
- value: function componentDidCatch(error) {
4374
- // eslint-disable-next-line no-console
4375
- console.error("Error for item ".concat(this.state.itemId), error, this.props.state);
4376
- }
4377
- }, {
4378
- key: "onReload",
4379
- value: function onReload() {
4380
- this.setState({
4381
- hasError: false
4382
- });
4383
- }
4384
- }, {
4385
- key: "render",
4386
- value: function render() {
4387
- var ErrorComponent = this.props.ErrorComponent;
4554
+ var PAGE_HEIGHT = 800;
4388
4555
 
4389
- if (this.state.hasError) {
4390
- return /*#__PURE__*/React__default['default'].createElement(ErrorComponent, {
4391
- onReload: this.onReload
4392
- });
4393
- }
4556
+ var otherPointer = function otherPointer(pointers, currentPointer) {
4557
+ var p2 = Object.keys(pointers).map(function (p) {
4558
+ return Number(p);
4559
+ }).find(function (pointer) {
4560
+ return pointer !== currentPointer;
4561
+ });
4562
+ return pointers[p2];
4563
+ };
4394
4564
 
4395
- return this.props.children;
4396
- }
4397
- }], [{
4398
- key: "getDerivedStateFromError",
4399
- value: function getDerivedStateFromError() {
4400
- return {
4401
- hasError: true
4402
- };
4403
- }
4404
- }]);
4565
+ var computeDistance = function computeDistance(_ref, _ref2) {
4566
+ var _ref3 = _slicedToArray(_ref, 2),
4567
+ x1 = _ref3[0],
4568
+ y1 = _ref3[1];
4405
4569
 
4406
- return ItemErrorBoundary;
4407
- }(React__default['default'].Component);
4570
+ var _ref4 = _slicedToArray(_ref2, 2),
4571
+ x2 = _ref4[0],
4572
+ y2 = _ref4[1];
4408
4573
 
4409
- var removeClass = function removeClass(e) {
4410
- e.target.className = "";
4574
+ var distanceX = Math.abs(x1 - x2);
4575
+ var distanceY = Math.abs(y1 - y2);
4576
+ return Math.hypot(distanceX, distanceY);
4411
4577
  };
4412
4578
 
4413
- var Item = function Item(_ref3) {
4414
- var _itemMap$error;
4579
+ var empty = function empty() {};
4415
4580
 
4416
- var setState = _ref3.setState,
4417
- _ref3$state = _ref3.state;
4418
- _ref3$state = _ref3$state === void 0 ? {} : _ref3$state;
4419
-
4420
- var type = _ref3$state.type,
4421
- _ref3$state$rotation = _ref3$state.rotation,
4422
- rotation = _ref3$state$rotation === void 0 ? 0 : _ref3$state$rotation,
4423
- id = _ref3$state.id,
4424
- locked = _ref3$state.locked,
4425
- layer = _ref3$state.layer,
4426
- rest = _objectWithoutProperties(_ref3$state, _excluded$2),
4427
- _ref3$animate = _ref3.animate,
4428
- animate = _ref3$animate === void 0 ? "hvr-pop" : _ref3$animate,
4429
- isSelected = _ref3.isSelected,
4430
- itemMap = _ref3.itemMap,
4431
- unlocked = _ref3.unlocked;
4432
-
4433
- var animateRef = React__default['default'].useRef(null);
4434
-
4435
- var Component = itemMap[type].component || function () {
4436
- return null;
4437
- };
4581
+ var protect = function protect(fn) {
4582
+ return /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
4583
+ var _args = arguments;
4584
+ return regeneratorRuntime.wrap(function _callee$(_context) {
4585
+ while (1) {
4586
+ switch (_context.prev = _context.next) {
4587
+ case 0:
4588
+ _context.prev = 0;
4589
+ _context.next = 3;
4590
+ return fn.apply(void 0, _args);
4438
4591
 
4439
- var updateState = React__default['default'].useCallback(function (callbackOrItem) {
4440
- var sync = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
4441
- return setState(id, callbackOrItem, sync);
4442
- }, [setState, id]);
4443
- React__default['default'].useEffect(function () {
4444
- animateRef.current.className = animate;
4445
- }, [animate]);
4446
- var className = "item ".concat(id);
4447
-
4448
- if (locked) {
4449
- className += " locked";
4450
- }
4592
+ case 3:
4593
+ _context.next = 8;
4594
+ break;
4451
4595
 
4452
- if (isSelected) {
4453
- className += " selected";
4454
- }
4596
+ case 5:
4597
+ _context.prev = 5;
4598
+ _context.t0 = _context["catch"](0);
4599
+ // eslint-disable-next-line no-console
4600
+ console.error(_context.t0);
4455
4601
 
4456
- return /*#__PURE__*/React__default['default'].createElement(ItemWrapper, {
4457
- rotation: rotation,
4458
- locked: locked && !unlocked,
4459
- selected: isSelected,
4460
- layer: layer,
4461
- "data-id": id,
4462
- className: className
4463
- }, /*#__PURE__*/React__default['default'].createElement("div", {
4464
- style: {
4465
- display: "flex"
4466
- },
4467
- ref: animateRef,
4468
- onAnimationEnd: removeClass,
4469
- onKeyDown: function onKeyDown(e) {
4470
- return e.stopPropagation();
4471
- },
4472
- onKeyUp: function onKeyUp(e) {
4473
- return e.stopPropagation();
4474
- }
4475
- }, /*#__PURE__*/React__default['default'].createElement(ItemErrorBoundary, {
4476
- itemId: id,
4477
- state: rest,
4478
- setState: updateState,
4479
- ErrorComponent: (itemMap === null || itemMap === void 0 ? void 0 : (_itemMap$error = itemMap.error) === null || _itemMap$error === void 0 ? void 0 : _itemMap$error.component) || DefaultErrorComponent
4480
- }, /*#__PURE__*/React__default['default'].createElement(Component, _extends$1({}, rest, {
4481
- id: id,
4482
- setState: updateState
4483
- }))), /*#__PURE__*/React__default['default'].createElement("div", {
4484
- className: "corner top-left"
4485
- }), /*#__PURE__*/React__default['default'].createElement("div", {
4486
- className: "corner top-right"
4487
- }), /*#__PURE__*/React__default['default'].createElement("div", {
4488
- className: "corner bottom-left"
4489
- }), /*#__PURE__*/React__default['default'].createElement("div", {
4490
- className: "corner bottom-right"
4491
- })));
4602
+ case 8:
4603
+ case "end":
4604
+ return _context.stop();
4605
+ }
4606
+ }
4607
+ }, _callee, null, [[0, 5]]);
4608
+ }));
4492
4609
  };
4493
4610
 
4494
- var MemoizedItem = /*#__PURE__*/React.memo(Item, function (_ref4, _ref5) {
4495
- var prevState = _ref4.state,
4496
- prevSetState = _ref4.setState,
4497
- prevIsSelected = _ref4.isSelected,
4498
- prevUnlocked = _ref4.unlocked;
4499
- var nextState = _ref5.state,
4500
- nextSetState = _ref5.setState,
4501
- nextIsSelected = _ref5.isSelected,
4502
- nextUnlocked = _ref5.unlocked;
4503
- return prevIsSelected === nextIsSelected && prevUnlocked === nextUnlocked && prevSetState === nextSetState && JSON.stringify(prevState) === JSON.stringify(nextState);
4504
- }); // Exclude positioning from memoization
4611
+ var Gesture = function Gesture(_ref6) {
4612
+ var children = _ref6.children,
4613
+ _ref6$onDrag = _ref6.onDrag,
4614
+ onDrag = _ref6$onDrag === void 0 ? empty : _ref6$onDrag,
4615
+ _ref6$onDragStart = _ref6.onDragStart,
4616
+ onDragStart = _ref6$onDragStart === void 0 ? empty : _ref6$onDragStart,
4617
+ _ref6$onDragEnd = _ref6.onDragEnd,
4618
+ onDragEnd = _ref6$onDragEnd === void 0 ? empty : _ref6$onDragEnd,
4619
+ _ref6$onPan = _ref6.onPan,
4620
+ onPan = _ref6$onPan === void 0 ? empty : _ref6$onPan,
4621
+ _ref6$onTap = _ref6.onTap,
4622
+ onTap = _ref6$onTap === void 0 ? empty : _ref6$onTap,
4623
+ _ref6$onLongTap = _ref6.onLongTap,
4624
+ onLongTap = _ref6$onLongTap === void 0 ? empty : _ref6$onLongTap,
4625
+ _ref6$onDoubleTap = _ref6.onDoubleTap,
4626
+ onDoubleTap = _ref6$onDoubleTap === void 0 ? empty : _ref6$onDoubleTap,
4627
+ onZoom = _ref6.onZoom;
4628
+ var wrapperRef = React__default['default'].useRef(null);
4629
+ var stateRef = React__default['default'].useRef({
4630
+ moving: false,
4631
+ pointers: {},
4632
+ mainPointer: undefined
4633
+ });
4634
+ var queueRef = React__default['default'].useRef([]); // Queue event to avoid async mess
4505
4635
 
4506
- var PositionedItem = function PositionedItem(_ref6) {
4507
- var _rest$itemMap$state$t;
4636
+ var queue = React__default['default'].useCallback(function (callback, args) {
4637
+ queueRef.current.push( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
4638
+ return regeneratorRuntime.wrap(function _callee2$(_context2) {
4639
+ while (1) {
4640
+ switch (_context2.prev = _context2.next) {
4641
+ case 0:
4642
+ _context2.next = 2;
4643
+ return protect(callback)(args);
4508
4644
 
4509
- var _ref6$state = _ref6.state,
4510
- state = _ref6$state === void 0 ? {} : _ref6$state,
4511
- boardSize = _ref6.boardSize,
4512
- currentUser = _ref6.currentUser,
4513
- rest = _objectWithoutProperties(_ref6, _excluded2);
4645
+ case 2:
4646
+ queueRef.current.shift();
4514
4647
 
4515
- var stateTrans = ((_rest$itemMap$state$t = rest.itemMap[state.type]) === null || _rest$itemMap$state$t === void 0 ? void 0 : _rest$itemMap$state$t.stateHook) || function (st) {
4516
- return st;
4517
- };
4648
+ if (!(queueRef.current.length !== 0)) {
4649
+ _context2.next = 6;
4650
+ break;
4651
+ }
4518
4652
 
4519
- var _stateTrans = stateTrans(state, {
4520
- currentUser: currentUser
4521
- }),
4522
- _stateTrans$x = _stateTrans.x,
4523
- x = _stateTrans$x === void 0 ? 0 : _stateTrans$x,
4524
- _stateTrans$y = _stateTrans.y,
4525
- y = _stateTrans$y === void 0 ? 0 : _stateTrans$y,
4526
- _stateTrans$layer = _stateTrans.layer,
4527
- layer = _stateTrans$layer === void 0 ? 0 : _stateTrans$layer,
4528
- moving = _stateTrans.moving,
4529
- stateRest = _objectWithoutProperties(_stateTrans, _excluded3);
4653
+ _context2.next = 6;
4654
+ return protect(queueRef.current[0])();
4530
4655
 
4531
- return /*#__PURE__*/React__default['default'].createElement("div", {
4532
- style: {
4533
- position: "absolute",
4534
- top: "".concat(boardSize / 2, "px"),
4535
- left: "".concat(boardSize / 2, "px"),
4536
- display: "inline-block",
4537
- transform: "translate(".concat(x, "px, ").concat(y, "px)"),
4538
- zIndex: (layer + 4) * 10 + 100 + (moving ? 5 : 0) // Items z-index between 100 and 200
4656
+ case 6:
4657
+ case "end":
4658
+ return _context2.stop();
4659
+ }
4660
+ }
4661
+ }, _callee2);
4662
+ })));
4539
4663
 
4664
+ if (queueRef.current.length === 1) {
4665
+ protect(queueRef.current[0])();
4540
4666
  }
4541
- }, /*#__PURE__*/React__default['default'].createElement(MemoizedItem, _extends$1({}, rest, {
4542
- state: stateRest
4543
- })));
4544
- };
4667
+ }, []);
4668
+ var onWheel = React__default['default'].useCallback(function (e) {
4669
+ var deltaX = e.deltaX,
4670
+ deltaY = e.deltaY,
4671
+ clientX = e.clientX,
4672
+ clientY = e.clientY,
4673
+ deltaMode = e.deltaMode,
4674
+ ctrlKey = e.ctrlKey,
4675
+ altKey = e.altKey,
4676
+ metaKey = e.metaKey,
4677
+ target = e.target; // On a MacOs trackpad, the pinch gesture sets the ctrlKey to true.
4678
+ // In that situation, we want to use the custom scaling, not the browser default zoom.
4679
+ // Hence in this situation we avoid to return immediately.
4545
4680
 
4546
- var MemoizedPositionedItem = /*#__PURE__*/React.memo(PositionedItem);
4681
+ if (altKey || ctrlKey && !isMacOS()) {
4682
+ return;
4683
+ } // On a trackpad, the pinch and pan events are differentiated by the crtlKey value.
4684
+ // On a pinch gesture, the ctrlKey is set to true, so we want to have a scaling effect.
4685
+ // If we are only moving the fingers in the same direction, a pan is needed.
4686
+ // Ref: https://medium.com/@auchenberg/detecting-multi-touch-trackpad-gestures-in-javascript-a2505babb10e
4547
4687
 
4548
- var persistUser = function persistUser(user) {
4549
- localStorage.setItem("user", JSON.stringify(user));
4550
- };
4551
- var colors = ["#037758", "#99092a", "#067070", "#c6650f", "#008726", "#3d7004", "#348402", "#057f58", "#b58612", "#c44c01", "#0a7704", "#0e910e", "#027377", "#c99e02", "#054160", "#157a01", "#b10de2", "#0d6289", "#bc5d03", "#ba0cd1", "#d39f10", "#0c4c7a", "#460782", "#a51f10", "#cecb10", "#9b0943", "#607f0c", "#007a4b", "#bf0daa", "#af0ad8"];
4552
4688
 
4553
- var getRandomColor = function getRandomColor() {
4554
- return colors[Math.floor(Math.random() * colors.length)];
4555
- }; // TODO remove user persistence
4689
+ if (isMacOS() && !ctrlKey) {
4690
+ queue(onPan, {
4691
+ deltaX: -2 * deltaX,
4692
+ deltaY: -2 * deltaY,
4693
+ button: 1,
4694
+ ctrlKey: ctrlKey,
4695
+ metaKey: metaKey,
4696
+ target: target,
4697
+ event: e
4698
+ });
4699
+ } else {
4700
+ // Quit if onZoom is not set
4701
+ if (onZoom === undefined || !deltaY) return;
4702
+ var scale = deltaY;
4556
4703
 
4704
+ switch (deltaMode) {
4705
+ case 1:
4706
+ // Pixel
4707
+ scale *= LINE_HEIGHT;
4708
+ break;
4557
4709
 
4558
- var getUser = function getUser() {
4559
- if (localStorage.user) {
4560
- // Add some mandatory info if missing
4561
- var localUser = _objectSpread2({
4562
- name: "Player",
4563
- color: getRandomColor(),
4564
- uid: nanoid()
4565
- }, JSON.parse(localStorage.user)); // Id is given by server
4566
- // delete localUser.id;
4710
+ case 2:
4711
+ scale *= PAGE_HEIGHT;
4712
+ break;
4713
+ }
4567
4714
 
4715
+ if (isMacOS()) {
4716
+ scale *= 2;
4717
+ }
4568
4718
 
4569
- persistUser(localUser);
4570
- return localUser;
4571
- }
4719
+ queue(onZoom, {
4720
+ scale: scale,
4721
+ clientX: clientX,
4722
+ clientY: clientY,
4723
+ event: e
4724
+ });
4725
+ }
4726
+ }, [onPan, onZoom, queue]);
4727
+ var onPointerDown = React__default['default'].useCallback(function (_ref8) {
4728
+ var target = _ref8.target,
4729
+ button = _ref8.button,
4730
+ clientX = _ref8.clientX,
4731
+ clientY = _ref8.clientY,
4732
+ pointerId = _ref8.pointerId,
4733
+ altKey = _ref8.altKey,
4734
+ ctrlKey = _ref8.ctrlKey,
4735
+ metaKey = _ref8.metaKey,
4736
+ isPrimary = _ref8.isPrimary;
4737
+ // Add pointer to map
4738
+ stateRef.current.pointers[pointerId] = {
4739
+ clientX: clientX,
4740
+ clientY: clientY
4741
+ };
4572
4742
 
4573
- var newUser = {
4574
- name: "Player",
4575
- color: getRandomColor(),
4576
- uid: nanoid()
4577
- };
4578
- persistUser(newUser);
4579
- return newUser;
4580
- };
4581
- var userAtom = recoil.atom({
4582
- key: "user",
4583
- "default": getUser()
4584
- });
4585
- var usersAtom = recoil.atom({
4586
- key: "users",
4587
- "default": []
4588
- });
4589
- var localUsersAtom = recoil.selector({
4590
- key: "localUsersAtom",
4591
- get: function get(_ref) {
4592
- var _get = _ref.get;
4743
+ if (isPrimary) {
4744
+ // Clean mainPoint on primary pointer
4745
+ stateRef.current.mainPointer = undefined;
4746
+ }
4593
4747
 
4594
- var currentUser = _get(userAtom);
4748
+ if (stateRef.current.mainPointer !== undefined) {
4749
+ if (stateRef.current.mainPointer !== pointerId) {
4750
+ // This is not the main pointer
4751
+ try {
4752
+ var _otherPointer = otherPointer(stateRef.current.pointers, pointerId),
4753
+ clientX2 = _otherPointer.clientX,
4754
+ clientY2 = _otherPointer.clientY;
4595
4755
 
4596
- var users = _get(usersAtom);
4756
+ var newClientX = (clientX2 + clientX) / 2;
4757
+ var newClientY = (clientY2 + clientY) / 2;
4758
+ var distance = computeDistance([clientX2, clientY2], [clientX, clientY]); // We update previous position as the new position is the center beetween both finger
4597
4759
 
4598
- return users.filter(function (_ref2) {
4599
- var space = _ref2.space;
4600
- return space === currentUser.space;
4601
- });
4602
- }
4603
- });
4760
+ Object.assign(stateRef.current, {
4761
+ pressed: true,
4762
+ moving: false,
4763
+ gestureStart: false,
4764
+ startX: clientX,
4765
+ startY: clientY,
4766
+ prevX: newClientX,
4767
+ prevY: newClientY,
4768
+ startDistance: distance,
4769
+ prevDistance: distance
4770
+ });
4771
+ } catch (e) {
4772
+ // eslint-disable-next-line no-console
4773
+ console.log("Error while getting other pointer. Ignoring", e); // eslint-disable-next-line no-unused-expressions
4604
4774
 
4605
- var useUsers = function useUsers() {
4606
- var _useRecoilState = recoil.useRecoilState(userAtom),
4607
- _useRecoilState2 = _slicedToArray(_useRecoilState, 2),
4608
- currentUser = _useRecoilState2[0],
4609
- setCurrentUserState = _useRecoilState2[1];
4775
+ stateRef.current.mainPointer === undefined;
4776
+ }
4777
+ }
4610
4778
 
4611
- var users = recoil.useRecoilValue(usersAtom);
4612
- var localUsers = recoil.useRecoilValue(localUsersAtom);
4613
- var setCurrentUser = React__default['default'].useCallback(function (callbackOrUser) {
4614
- var callback = callbackOrUser;
4779
+ return;
4780
+ } // We set the mainpointer
4615
4781
 
4616
- if (_typeof(callbackOrUser) === "object") {
4617
- callback = function callback() {
4618
- return callbackOrUser;
4619
- };
4620
- }
4621
4782
 
4622
- setCurrentUserState(function (prevUser) {
4623
- var newUser = _objectSpread2(_objectSpread2({}, callback(prevUser)), {}, {
4624
- id: prevUser.id,
4625
- uid: prevUser.uid
4626
- });
4783
+ stateRef.current.mainPointer = pointerId; // And prepare move
4627
4784
 
4628
- persistUser(newUser);
4629
- return newUser;
4785
+ Object.assign(stateRef.current, {
4786
+ pressed: true,
4787
+ moving: false,
4788
+ gestureStart: false,
4789
+ startX: clientX,
4790
+ startY: clientY,
4791
+ prevX: clientX,
4792
+ prevY: clientY,
4793
+ currentButton: button,
4794
+ target: target,
4795
+ timeStart: Date.now(),
4796
+ longTapTimeout: setTimeout( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {
4797
+ return regeneratorRuntime.wrap(function _callee3$(_context3) {
4798
+ while (1) {
4799
+ switch (_context3.prev = _context3.next) {
4800
+ case 0:
4801
+ stateRef.current.noTap = true;
4802
+ queue(onLongTap, {
4803
+ clientX: clientX,
4804
+ clientY: clientY,
4805
+ altKey: altKey,
4806
+ ctrlKey: ctrlKey,
4807
+ metaKey: metaKey,
4808
+ target: target
4809
+ });
4810
+
4811
+ case 2:
4812
+ case "end":
4813
+ return _context3.stop();
4814
+ }
4815
+ }
4816
+ }, _callee3);
4817
+ })), 750)
4630
4818
  });
4631
- }, [setCurrentUserState]);
4632
- React__default['default'].useEffect(function () {
4633
- // eslint-disable-next-line no-console
4634
- console.debug("Curent user is in space ".concat(currentUser.space));
4635
- }, [currentUser.space]);
4636
- return {
4637
- currentUser: currentUser,
4638
- setCurrentUser: setCurrentUser,
4639
- users: users,
4640
- localUsers: localUsers
4641
- };
4642
- };
4643
4819
 
4644
- var SubscribeUserEvents = function SubscribeUserEvents() {
4645
- var usersRef = React__default['default'].useRef([]);
4646
- var setUsers = recoil.useSetRecoilState(usersAtom);
4820
+ try {
4821
+ target.setPointerCapture(pointerId);
4822
+ } catch (e) {
4823
+ // eslint-disable-next-line no-console
4824
+ console.log("Fail to capture pointer", e);
4825
+ }
4826
+ }, [onLongTap, queue]);
4827
+ var onPointerMove = React__default['default'].useCallback(function (e) {
4828
+ if (stateRef.current.pressed) {
4829
+ var pointerId = e.pointerId,
4830
+ eventClientX = e.clientX,
4831
+ eventClientY = e.clientY,
4832
+ altKey = e.altKey,
4833
+ ctrlKey = e.ctrlKey,
4834
+ metaKey = e.metaKey,
4835
+ pointerType = e.pointerType;
4647
4836
 
4648
- var _useRecoilState = recoil.useRecoilState(userAtom),
4649
- _useRecoilState2 = _slicedToArray(_useRecoilState, 2),
4650
- currentUser = _useRecoilState2[0],
4651
- setCurrentUserState = _useRecoilState2[1];
4837
+ if (stateRef.current.mainPointer !== pointerId) {
4838
+ // Event from other pointer
4839
+ stateRef.current.pointers[pointerId] = {
4840
+ clientX: eventClientX,
4841
+ clientY: eventClientY
4842
+ };
4843
+ return;
4844
+ }
4652
4845
 
4653
- var _useWire = useWire("room"),
4654
- wire = _useWire.wire,
4655
- isMaster = _useWire.isMaster,
4656
- roomSpace = _useWire.room;
4846
+ stateRef.current.moving = true; // Do we have two fingers ?
4657
4847
 
4658
- React__default['default'].useEffect(function () {
4659
- setCurrentUserState(function (prevUser) {
4660
- return _objectSpread2(_objectSpread2({}, prevUser), {}, {
4661
- id: wire.userId,
4662
- space: roomSpace
4663
- });
4664
- });
4665
- return function () {
4666
- setCurrentUserState(function (prevUser) {
4667
- return _objectSpread2(_objectSpread2({}, prevUser), {}, {
4668
- id: wire.userId,
4669
- space: null
4670
- });
4671
- });
4672
- };
4673
- }, [wire.userId, roomSpace, setCurrentUserState]);
4674
- React__default['default'].useEffect(function () {
4675
- if (!isMaster) {
4676
- var onGetUserList = function onGetUserList(userList) {
4677
- usersRef.current = userList;
4678
- setUsers(userList);
4679
- };
4848
+ var twoFingers = Object.keys(stateRef.current.pointers).length === 2;
4849
+ var clientX;
4850
+ var clientY;
4851
+ var distance;
4680
4852
 
4681
- wire.call("getUserList").then(onGetUserList, function () {
4682
- // retry later
4683
- setTimeout(function () {
4684
- wire.call("getUserList") // eslint-disable-next-line no-console
4685
- .then(onGetUserList, function (error) {
4686
- return console.log(error);
4687
- });
4688
- }, 1000);
4689
- });
4690
- }
4691
- }, [wire, isMaster, setUsers]); // eslint-disable-next-line react-hooks/exhaustive-deps
4853
+ if (twoFingers) {
4854
+ // Find other pointerId
4855
+ var _otherPointer2 = otherPointer(stateRef.current.pointers, pointerId),
4856
+ clientX2 = _otherPointer2.clientX,
4857
+ clientY2 = _otherPointer2.clientY; // Update client X with the center of each touch
4692
4858
 
4693
- var debouncedEmitUpdateUser = useDebouncedCallback(function (newUser) {
4694
- wire.publish("userUpdate", newUser, true);
4695
- }, [wire], 500);
4696
- React__default['default'].useEffect(function () {
4697
- if (currentUser && currentUser.id) {
4698
- debouncedEmitUpdateUser(currentUser);
4699
- }
4700
- }, [currentUser, debouncedEmitUpdateUser]);
4701
- React__default['default'].useEffect(function () {
4702
- var unsub = [];
4703
4859
 
4704
- if (isMaster) {
4705
- wire.register("getUserList", function () {
4706
- return usersRef.current;
4707
- }).then(function (unregister) {
4708
- unsub.push(unregister);
4709
- });
4710
- unsub.push(wire.subscribe("userUpdate", function (user) {
4711
- if (usersRef.current.find(function (u) {
4712
- return u.id === user.id;
4713
- })) {
4714
- var newUsers = usersRef.current.map(function (u) {
4715
- return u.id === user.id ? user : u;
4860
+ clientX = (clientX2 + eventClientX) / 2;
4861
+ clientY = (clientY2 + eventClientY) / 2;
4862
+ distance = computeDistance([clientX2, clientY2], [eventClientX, eventClientY]);
4863
+ } else {
4864
+ clientX = eventClientX;
4865
+ clientY = eventClientY;
4866
+ } // We drag if
4867
+ // On non touch device
4868
+ // - Button is 0
4869
+ // - Alt key is no pressed
4870
+ // or on touch devices
4871
+ // - We use only one finger
4872
+
4873
+
4874
+ var shouldDrag = pointerType !== "touch" ? stateRef.current.currentButton === 0 && !altKey : !twoFingers;
4875
+
4876
+ if (shouldDrag) {
4877
+ // Send drag start on first move
4878
+ if (!stateRef.current.gestureStart) {
4879
+ wrapperRef.current.style.cursor = "move";
4880
+ stateRef.current.gestureStart = true; // Clear tap timeout
4881
+
4882
+ clearTimeout(stateRef.current.longTapTimeout);
4883
+ queue(onDragStart, {
4884
+ deltaX: 0,
4885
+ deltaY: 0,
4886
+ startX: stateRef.current.startX,
4887
+ startY: stateRef.current.startY,
4888
+ clientX: stateRef.current.startX,
4889
+ clientY: stateRef.current.startY,
4890
+ distanceX: 0,
4891
+ distanceY: 0,
4892
+ button: stateRef.current.currentButton,
4893
+ altKey: altKey,
4894
+ ctrlKey: ctrlKey,
4895
+ metaKey: metaKey,
4896
+ target: stateRef.current.target,
4897
+ event: e
4716
4898
  });
4717
- usersRef.current = newUsers;
4718
- } else {
4719
- var _newUsers = [].concat(_toConsumableArray(usersRef.current), [user]);
4899
+ } // Create closure
4720
4900
 
4721
- usersRef.current = _newUsers;
4722
- }
4723
4901
 
4724
- setUsers(usersRef.current);
4725
- wire.publish("updateUserList", usersRef.current);
4726
- }));
4727
- }
4902
+ var deltaX = clientX - stateRef.current.prevX;
4903
+ var deltaY = clientY - stateRef.current.prevY;
4904
+ var distanceX = clientX - stateRef.current.startX;
4905
+ var distanceY = clientY - stateRef.current.startY; // Drag event
4728
4906
 
4729
- unsub.push(wire.subscribe("userLeave", function (userId) {
4730
- usersRef.current = usersRef.current.filter(function (_ref) {
4731
- var id = _ref.id;
4732
- return id !== userId;
4733
- });
4734
- setUsers(usersRef.current);
4907
+ queue(onDrag, {
4908
+ deltaX: deltaX,
4909
+ deltaY: deltaY,
4910
+ startX: stateRef.current.startX,
4911
+ startY: stateRef.current.startY,
4912
+ clientX: clientX,
4913
+ clientY: clientY,
4914
+ distanceX: distanceX,
4915
+ distanceY: distanceY,
4916
+ button: stateRef.current.currentButton,
4917
+ altKey: altKey,
4918
+ ctrlKey: ctrlKey,
4919
+ metaKey: metaKey,
4920
+ target: stateRef.current.target,
4921
+ event: e
4922
+ });
4923
+ } else {
4924
+ if (!stateRef.current.gestureStart) {
4925
+ wrapperRef.current.style.cursor = "move";
4926
+ stateRef.current.gestureStart = true; // Clear tap timeout on first move
4735
4927
 
4736
- if (isMaster) {
4737
- wire.publish("updateUserList", usersRef.current);
4928
+ clearTimeout(stateRef.current.longTapTimeout);
4929
+ } // Create closure
4930
+
4931
+
4932
+ var _deltaX = clientX - stateRef.current.prevX;
4933
+
4934
+ var _deltaY = clientY - stateRef.current.prevY;
4935
+
4936
+ var target = stateRef.current.target; // Pan event
4937
+
4938
+ queue(onPan, {
4939
+ deltaX: _deltaX,
4940
+ deltaY: _deltaY,
4941
+ button: stateRef.current.currentButton,
4942
+ altKey: altKey,
4943
+ ctrlKey: ctrlKey,
4944
+ metaKey: metaKey,
4945
+ target: target,
4946
+ event: e
4947
+ });
4948
+
4949
+ if (twoFingers && distance !== stateRef.current.prevDistance && onZoom) {
4950
+ var scale = stateRef.current.prevDistance - distance;
4951
+
4952
+ if (Math.abs(scale) > 0) {
4953
+ queue(onZoom, {
4954
+ scale: scale,
4955
+ clientX: clientX,
4956
+ clientY: clientY,
4957
+ event: e
4958
+ });
4959
+ stateRef.current.prevDistance = distance;
4960
+ }
4961
+ }
4738
4962
  }
4739
- }));
4740
- unsub.push(wire.subscribe("updateUserList", function (newList) {
4741
- usersRef.current = newList;
4742
- setUsers(usersRef.current);
4743
- }));
4744
- return function () {
4745
- unsub.forEach(function (u) {
4746
- return u();
4747
- });
4748
- };
4749
- }, [wire, isMaster, setUsers]);
4750
- return null;
4751
- };
4752
4963
 
4753
- /** Allow to operate on locked items while u or l key is pressed */
4964
+ stateRef.current.prevX = clientX;
4965
+ stateRef.current.prevY = clientY;
4966
+ }
4967
+ }, [onDrag, onDragStart, onPan, onZoom, queue]);
4968
+ var onPointerUp = React__default['default'].useCallback(function (e) {
4969
+ var clientX = e.clientX,
4970
+ clientY = e.clientY,
4971
+ altKey = e.altKey,
4972
+ ctrlKey = e.ctrlKey,
4973
+ metaKey = e.metaKey,
4974
+ target = e.target,
4975
+ pointerId = e.pointerId;
4754
4976
 
4755
- var useUnlock = function useUnlock() {
4756
- var _React$useState = React__default['default'].useState(false),
4757
- _React$useState2 = _slicedToArray(_React$useState, 2),
4758
- unlock = _React$useState2[0],
4759
- setUnlock = _React$useState2[1];
4977
+ if (!stateRef.current.pointers[pointerId]) {
4978
+ // Pointer already gone previously with another event
4979
+ // ignoring it
4980
+ return;
4981
+ } // Remove pointer from map
4760
4982
 
4761
- React__default['default'].useEffect(function () {
4762
- var onKeyDown = function onKeyDown(e) {
4763
- if (e.key === "u" || e.key === "l") {
4764
- setUnlock(true);
4765
- }
4766
- };
4767
4983
 
4768
- var onKeyUp = function onKeyUp(e) {
4769
- if (e.key === "u" || e.key === "l") {
4770
- setUnlock(false);
4771
- }
4772
- };
4984
+ delete stateRef.current.pointers[pointerId];
4773
4985
 
4774
- document.addEventListener("keydown", onKeyDown);
4775
- document.addEventListener("keyup", onKeyUp);
4776
- return function () {
4777
- document.removeEventListener("keydown", onKeyDown);
4778
- document.removeEventListener("keyup", onKeyUp);
4779
- };
4780
- }, []);
4781
- return unlock;
4782
- };
4986
+ if (stateRef.current.mainPointer !== pointerId) {
4987
+ // If this is not the main pointer we quit here
4988
+ return;
4989
+ }
4783
4990
 
4784
- var ItemList = function ItemList(_ref) {
4785
- var itemTemplates = _ref.itemTemplates;
4991
+ while (Object.keys(stateRef.current.pointers).length > 0) {
4992
+ // If was main pointer but we have another one, this one become main
4993
+ stateRef.current.mainPointer = Number(Object.keys(stateRef.current.pointers)[0]);
4786
4994
 
4787
- var _useItemActions = useItemActions(),
4788
- updateItem = _useItemActions.updateItem;
4995
+ try {
4996
+ stateRef.current.target.setPointerCapture(stateRef.current.mainPointer);
4997
+ return;
4998
+ } catch (error) {
4999
+ // eslint-disable-next-line no-console
5000
+ console.log("Fails to set pointer capture", error);
5001
+ stateRef.current.mainPointer = undefined;
5002
+ delete stateRef.current.pointers[Object.keys(stateRef.current.pointers)[0]];
5003
+ }
5004
+ }
4789
5005
 
4790
- var itemList = recoil.useRecoilValue(ItemListAtom);
4791
- var itemMap = recoil.useRecoilValue(ItemMapAtom);
4792
- var selectedItems = recoil.useRecoilValue(SelectedItemsAtom);
5006
+ stateRef.current.mainPointer = undefined;
5007
+ stateRef.current.pressed = false; // Clear longTap
4793
5008
 
4794
- var _useRecoilValue = recoil.useRecoilValue(ConfigurationAtom),
4795
- boardSize = _useRecoilValue.boardSize;
5009
+ clearTimeout(stateRef.current.longTapTimeout);
4796
5010
 
4797
- var _useUsers = useUsers(),
4798
- currentUser = _useUsers.currentUser;
5011
+ if (stateRef.current.moving) {
5012
+ // If we were moving, send drag end event
5013
+ stateRef.current.moving = false;
5014
+ queue(onDragEnd, {
5015
+ deltaX: clientX - stateRef.current.prevX,
5016
+ deltaY: clientY - stateRef.current.prevY,
5017
+ startX: stateRef.current.startX,
5018
+ startY: stateRef.current.startY,
5019
+ clientX: clientX,
5020
+ clientY: clientY,
5021
+ distanceX: clientX - stateRef.current.startX,
5022
+ distanceY: clientY - stateRef.current.startY,
5023
+ button: stateRef.current.currentButton,
5024
+ altKey: altKey,
5025
+ ctrlKey: ctrlKey,
5026
+ metaKey: metaKey,
5027
+ event: e
5028
+ });
5029
+ wrapperRef.current.style.cursor = "auto";
5030
+ } else {
5031
+ var now = Date.now();
4799
5032
 
4800
- var unlocked = useUnlock();
4801
- return itemList.map(function (itemId) {
4802
- return /*#__PURE__*/React__default['default'].createElement(MemoizedPositionedItem, {
4803
- key: itemId,
4804
- state: itemMap[itemId],
4805
- setState: updateItem,
4806
- isSelected: selectedItems.includes(itemId),
4807
- unlocked: unlocked,
4808
- itemMap: itemTemplates,
4809
- boardSize: boardSize,
4810
- currentUser: currentUser
4811
- });
4812
- });
5033
+ if (stateRef.current.noTap) {
5034
+ stateRef.current.noTap = false;
5035
+ } // Send tap event only if time less than 300ms
5036
+ else if (stateRef.current.timeStart - now < 300) {
5037
+ queue(onTap, {
5038
+ clientX: clientX,
5039
+ clientY: clientY,
5040
+ altKey: altKey,
5041
+ ctrlKey: ctrlKey,
5042
+ metaKey: metaKey,
5043
+ target: target
5044
+ });
5045
+ }
5046
+ }
5047
+ }, [onDragEnd, onTap, queue]);
5048
+ var onDoubleTapHandler = React__default['default'].useCallback(function (event) {
5049
+ queue(onDoubleTap, event);
5050
+ }, [onDoubleTap, queue]);
5051
+ return /*#__PURE__*/React__default['default'].createElement("div", {
5052
+ onWheel: onWheel,
5053
+ onPointerDown: onPointerDown,
5054
+ onPointerMove: onPointerMove,
5055
+ onPointerUp: onPointerUp,
5056
+ onPointerOut: onPointerUp,
5057
+ onPointerLeave: onPointerUp,
5058
+ onPointerCancel: onPointerUp,
5059
+ onDoubleClick: onDoubleTapHandler,
5060
+ style: {
5061
+ touchAction: "none"
5062
+ },
5063
+ ref: wrapperRef
5064
+ }, children);
4813
5065
  };
4814
5066
 
4815
- var SubcribeItemEvents = function SubcribeItemEvents() {
4816
- var _useWire = useWire("board"),
4817
- wire = _useWire.wire;
5067
+ var _excluded$3 = ["onResize"];
4818
5068
 
4819
- var setItemMap = recoil.useSetRecoilState(ItemMapAtom);
5069
+ var ResizeHandler = function ResizeHandler(_ref) {
5070
+ var onResize = _ref.onResize,
5071
+ rest = _objectWithoutProperties(_ref, _excluded$3);
4820
5072
 
4821
- var _useItemActions = useItemActions(),
4822
- updateItemOrder = _useItemActions.updateItemOrder,
4823
- moveItems = _useItemActions.moveItems,
4824
- removeItems = _useItemActions.removeItems,
4825
- pushItem = _useItemActions.pushItem;
5073
+ var onDrag = recoil.useRecoilCallback(function (_ref2) {
5074
+ var snapshot = _ref2.snapshot;
5075
+ return /*#__PURE__*/function () {
5076
+ var _ref4 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(_ref3) {
5077
+ var deltaX, deltaY, event, _yield$snapshot$getPr, scale;
4826
5078
 
4827
- var batchUpdate = React__default['default'].useCallback(function (updatedItems) {
4828
- setItemMap(function (prevItemMap) {
4829
- return _objectSpread2(_objectSpread2({}, prevItemMap), updatedItems);
4830
- });
4831
- }, [setItemMap]);
4832
- React__default['default'].useEffect(function () {
4833
- var unsub = wire.subscribe("batchItemsUpdate", function (updatedItems) {
4834
- batchUpdate(updatedItems);
4835
- });
4836
- return unsub;
4837
- }, [wire, batchUpdate]);
4838
- React__default['default'].useEffect(function () {
4839
- var unsub = wire.subscribe("selectedItemsMove", function (_ref) {
4840
- var itemIds = _ref.itemIds,
4841
- posDelta = _ref.posDelta;
4842
- moveItems(itemIds, posDelta, false);
4843
- });
4844
- return unsub;
4845
- }, [wire, moveItems]);
4846
- React__default['default'].useEffect(function () {
4847
- var unsub = wire.subscribe("updateItemListOrder", function (itemIds) {
4848
- updateItemOrder(itemIds, false);
4849
- });
4850
- return unsub;
4851
- }, [wire, updateItemOrder]);
4852
- React__default['default'].useEffect(function () {
4853
- var unsub = wire.subscribe("pushItem", function (newItem) {
4854
- pushItem(newItem, null, false);
4855
- });
4856
- return unsub;
4857
- }, [wire, pushItem]);
4858
- React__default['default'].useEffect(function () {
4859
- var unsub = wire.subscribe("insertItemBefore", function (_ref2) {
4860
- var _ref3 = _slicedToArray(_ref2, 2),
4861
- newItem = _ref3[0],
4862
- beforeId = _ref3[1];
5079
+ return regeneratorRuntime.wrap(function _callee$(_context) {
5080
+ while (1) {
5081
+ switch (_context.prev = _context.next) {
5082
+ case 0:
5083
+ deltaX = _ref3.deltaX, deltaY = _ref3.deltaY, event = _ref3.event;
5084
+ event.stopPropagation();
5085
+ _context.next = 4;
5086
+ return snapshot.getPromise(BoardTransformAtom);
4863
5087
 
4864
- pushItem(newItem, beforeId, false);
4865
- });
4866
- return unsub;
4867
- }, [wire, pushItem]);
4868
- React__default['default'].useEffect(function () {
4869
- var unsub = wire.subscribe("removeItems", function (itemIds) {
4870
- removeItems(itemIds, false);
4871
- });
4872
- return unsub;
4873
- }, [wire, removeItems]);
4874
- return null;
4875
- };
5088
+ case 4:
5089
+ _yield$snapshot$getPr = _context.sent;
5090
+ scale = _yield$snapshot$getPr.scale;
5091
+ onResize({
5092
+ width: deltaX / scale,
5093
+ height: deltaY / scale
5094
+ });
4876
5095
 
4877
- /**
4878
- * Check if element or parent has className.
4879
- * @param {DOMElement} element
4880
- * @param {string} className
4881
- */
4882
- var hasClass = function hasClass(element, className) {
4883
- return element.classList && element.classList.contains(className);
5096
+ case 7:
5097
+ case "end":
5098
+ return _context.stop();
5099
+ }
5100
+ }
5101
+ }, _callee);
5102
+ }));
5103
+
5104
+ return function (_x) {
5105
+ return _ref4.apply(this, arguments);
5106
+ };
5107
+ }();
5108
+ }, [onResize]);
5109
+ return /*#__PURE__*/React__default['default'].createElement(Gesture, {
5110
+ onDrag: onDrag
5111
+ }, /*#__PURE__*/React__default['default'].createElement("div", rest));
4884
5112
  };
4885
- var insideClass = function insideClass(element, className) {
4886
- if (hasClass(element, className)) {
4887
- return element;
4888
- }
4889
5113
 
4890
- if (!element.parentNode) {
4891
- return false;
4892
- }
5114
+ var img = "data:image/svg+xml,%3c%3fxml version='1.0' encoding='UTF-8' standalone='no'%3f%3e%3csvg xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:cc='http://creativecommons.org/ns%23' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns%23' xmlns:svg='http://www.w3.org/2000/svg' xmlns='http://www.w3.org/2000/svg' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' version='1.1' x='0px' y='0px' viewBox='0 0 75.601318 94.9' xml:space='preserve' id='svg26' sodipodi:docname='lock.svg' width='75.601318' height='94.900002' inkscape:version='0.92.5 (2060ec1f9f%2c 2020-04-08)'%3e%3cmetadata id='metadata32'%3e%3crdf:RDF%3e%3ccc:Work rdf:about=''%3e%3cdc:format%3eimage/svg%2bxml%3c/dc:format%3e%3cdc:type rdf:resource='http://purl.org/dc/dcmitype/StillImage' /%3e%3cdc:title%3e%3c/dc:title%3e%3c/cc:Work%3e%3c/rdf:RDF%3e%3c/metadata%3e%3cdefs id='defs30' /%3e%3csodipodi:namedview pagecolor='black' bordercolor='%23666666' borderopacity='1' objecttolerance='10' gridtolerance='10' guidetolerance='10' inkscape:pageopacity='0' inkscape:pageshadow='2' inkscape:window-width='1848' inkscape:window-height='1016' id='namedview28' showgrid='false' fit-margin-top='0' fit-margin-left='0' fit-margin-right='0' fit-margin-bottom='0' inkscape:zoom='5.3400704' inkscape:cx='3.2640013' inkscape:cy='45.072152' inkscape:window-x='1512' inkscape:window-y='27' inkscape:window-maximized='1' inkscape:current-layer='g16' /%3e%3cg id='g16' transform='translate(-12.2%2c-2.5)'%3e%3cpath d='M 75.4%2c36.8 H 34.1 V 24.6 c 0%2c-8.8 7.1%2c-15.9 15.9%2c-15.9 8.8%2c0 15.9%2c7.1 15.9%2c15.9 0%2c1.7 1.4%2c3.1 3.1%2c3.1 1.7%2c0 3.1%2c-1.4 3.1%2c-3.1 C 72.1%2c12.4 62.2%2c2.5 50%2c2.5 37.8%2c2.5 27.9%2c12.4 27.9%2c24.6 v 12.2 h -3.3 c -6.9%2c0 -12.4%2c5.6 -12.4%2c12.4 V 85 c 0%2c6.9 5.6%2c12.4 12.4%2c12.4 h 50.8 c 6.9%2c0 12.4%2c-5.6 12.4%2c-12.4 V 49.2 C 87.9%2c42.3 82.3%2c36.8 75.4%2c36.8 Z m 6.2%2c48.3 c 0%2c3.4 -2.8%2c6.2 -6.2%2c6.2 H 24.6 c -3.4%2c0 -6.2%2c-2.8 -6.2%2c-6.2 V 49.2 c 0%2c-3.4 2.8%2c-6.2 6.2%2c-6.2 h 50.8 c 3.4%2c0 6.2%2c2.8 6.2%2c6.2 z' id='path12' inkscape:connector-curvature='0' style='fill:white%3bfill-opacity:1' /%3e%3cpath d='m 59.8%2c57.6 -12.5%2c12.5 -7%2c-7 c -1.2%2c-1.2 -3.2%2c-1.2 -4.4%2c0 -1.2%2c1.2 -1.2%2c3.2 0%2c4.4 l 9.2%2c9.2 c 0.6%2c0.6 1.4%2c0.9 2.2%2c0.9 0.8%2c0 1.6%2c-0.3 2.2%2c-0.9 L 64.2%2c62 c 1.2%2c-1.2 1.2%2c-3.2 0%2c-4.4 -1.2%2c-1.2 -3.2%2c-1.2 -4.4%2c0 z' id='path14' inkscape:connector-curvature='0' style='fill:white%3bfill-opacity:1' /%3e%3c/g%3e%3c/svg%3e";
4893
5115
 
4894
- return insideClass(element.parentNode, className);
4895
- };
4896
- var isPointInsideRect = function isPointInsideRect(point, rect) {
4897
- return point.x > rect.left && point.x < rect.left + rect.width && point.y > rect.top && point.y < rect.top + rect.height;
4898
- };
4899
- var isItemInsideElement = function isItemInsideElement(itemElement, otherElem) {
4900
- var rect = otherElem.getBoundingClientRect();
4901
- var fourElem = Array.from(itemElement.querySelectorAll(".corner"));
4902
- return fourElem.every(function (corner) {
4903
- var _corner$getBoundingCl = corner.getBoundingClientRect(),
4904
- y = _corner$getBoundingCl.top,
4905
- x = _corner$getBoundingCl.left;
5116
+ var _excluded$2 = ["type", "rotation", "id", "locked", "layer"],
5117
+ _excluded2 = ["state", "boardSize", "currentUser"],
5118
+ _excluded3 = ["x", "y", "layer", "moving"];
4906
5119
 
4907
- return isPointInsideRect({
4908
- x: x,
4909
- y: y
4910
- }, rect);
4911
- });
4912
- };
4913
- var getItemElem = function getItemElem(wrapper, itemId) {
4914
- var elems = wrapper.getElementsByClassName("item ".concat(itemId));
4915
- var elem = elems[0];
5120
+ var _templateObject$2;
5121
+ var ItemWrapper = newStyled.div(_templateObject$2 || (_templateObject$2 = _taggedTemplateLiteral(["\n display: inline-block;\n transition: transform 150ms;\n user-select: none;\n padding: 2px;\n box-sizing: border-box;\n transform: rotate(", "deg);\n\n & .corner {\n position: absolute;\n width: 0px;\n height: 0px;\n }\n\n & .top-left {\n top: 0;\n left: 0;\n }\n & .top-right {\n top: 0;\n right: 0;\n }\n & .bottom-left {\n bottom: 0;\n left: 0;\n }\n & .bottom-right {\n bottom: 0;\n right: 0;\n }\n\n &.selected {\n border: 2px dashed #db5034;\n padding: 0px;\n cursor: pointer;\n }\n\n &.locked::after {\n content: \"\";\n position: absolute;\n width: 24px;\n height: 30px;\n top: 4px;\n right: 4px;\n opacity: 0.1;\n background-image: url(\"", "\");\n background-size: cover;\n user-select: none;\n }\n\n &.locked:hover::after {\n opacity: 0.3;\n }\n\n & .resize {\n position: absolute;\n\n width: 10px;\n height: 10px;\n border: 2px solid #db5034;\n background-color: #db5034;\n cursor: move;\n\n &.resize-width {\n cursor: ew-resize;\n right: -6px;\n top: calc(50% - 5px);\n }\n &.resize-height {\n cursor: ns-resize;\n bottom: -6px;\n left: calc(50% - 5px);\n }\n &.resize-ratio {\n cursor: nwse-resize;\n bottom: -6px;\n right: -6px;\n }\n }\n"])), function (_ref) {
5122
+ var rotation = _ref.rotation;
5123
+ return rotation;
5124
+ }, img);
4916
5125
 
4917
- if (!elem) {
4918
- // eslint-disable-next-line no-console
4919
- console.error("Missing item ".concat(itemId));
4920
- }
5126
+ var identity = function identity(x) {
5127
+ return x;
5128
+ };
4921
5129
 
4922
- return elem;
5130
+ var DefaultErrorComponent = function DefaultErrorComponent(_ref2) {
5131
+ var onReload = _ref2.onReload;
5132
+ return /*#__PURE__*/React__default['default'].createElement("div", {
5133
+ style: {
5134
+ width: "100px",
5135
+ display: "flex",
5136
+ flexDirection: "column",
5137
+ justifyContent: "center",
5138
+ textAlign: "center",
5139
+ color: "red"
5140
+ },
5141
+ className: "syncboard-error-item"
5142
+ }, "Sorry, this item seems broken.", /*#__PURE__*/React__default['default'].createElement("button", {
5143
+ onClick: onReload
5144
+ }, "Reload it"));
4923
5145
  };
4924
- var getIdFromElem = function getIdFromElem(elem) {
4925
- var _elem$dataset;
5146
+ /* Error boundary for broken item */
4926
5147
 
4927
- var value = elem === null || elem === void 0 ? void 0 : (_elem$dataset = elem.dataset) === null || _elem$dataset === void 0 ? void 0 : _elem$dataset.id;
4928
5148
 
4929
- if (!value) {
4930
- var _elem$dataset2;
5149
+ var ItemErrorBoundary = /*#__PURE__*/function (_React$Component) {
5150
+ _inherits(ItemErrorBoundary, _React$Component);
4931
5151
 
4932
- // eslint-disable-next-line no-console
4933
- console.error("getIdFromElem call fails", elem, JSON.stringify(elem === null || elem === void 0 ? void 0 : elem.dataset), elem === null || elem === void 0 ? void 0 : (_elem$dataset2 = elem.dataset) === null || _elem$dataset2 === void 0 ? void 0 : _elem$dataset2.id);
4934
- }
5152
+ var _super = _createSuper(ItemErrorBoundary);
4935
5153
 
4936
- return value;
4937
- };
4938
- var getItemBoundingBox = function getItemBoundingBox(items) {
4939
- var wrapper = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document;
4940
- var result = items.reduce(function (prev, itemId) {
4941
- var elem = getItemElem(wrapper, itemId);
4942
- if (!elem) return null;
5154
+ function ItemErrorBoundary(props) {
5155
+ var _this;
4943
5156
 
4944
- var _elem$getBoundingClie = elem.getBoundingClientRect(),
4945
- left = _elem$getBoundingClie.left,
4946
- right = _elem$getBoundingClie.right,
4947
- top = _elem$getBoundingClie.top,
4948
- bottom = _elem$getBoundingClie.bottom;
5157
+ _classCallCheck(this, ItemErrorBoundary);
4949
5158
 
4950
- var boundingBox;
5159
+ _this = _super.call(this, props);
5160
+ _this.state = {
5161
+ hasError: false,
5162
+ itemId: props.itemId
5163
+ };
5164
+ _this.onReload = _this.onReload.bind(_assertThisInitialized(_this));
5165
+ return _this;
5166
+ }
4951
5167
 
4952
- if (!prev) {
4953
- boundingBox = {
4954
- left: left,
4955
- top: top,
4956
- right: right,
4957
- bottom: bottom
4958
- };
4959
- } else {
4960
- boundingBox = prev;
5168
+ _createClass(ItemErrorBoundary, [{
5169
+ key: "componentDidCatch",
5170
+ value: function componentDidCatch(error) {
5171
+ // eslint-disable-next-line no-console
5172
+ console.error("Error for item ".concat(this.state.itemId), error, this.props.state);
4961
5173
  }
5174
+ }, {
5175
+ key: "onReload",
5176
+ value: function onReload() {
5177
+ this.setState({
5178
+ hasError: false
5179
+ });
5180
+ }
5181
+ }, {
5182
+ key: "render",
5183
+ value: function render() {
5184
+ var ErrorComponent = this.props.ErrorComponent;
4962
5185
 
4963
- boundingBox.left = Math.min(left, boundingBox.left);
4964
- boundingBox.top = Math.min(top, boundingBox.top);
4965
- boundingBox.right = Math.max(right, boundingBox.right);
4966
- boundingBox.bottom = Math.max(bottom, boundingBox.bottom);
4967
- return boundingBox;
4968
- }, null);
4969
-
4970
- if (!result) {
4971
- return result;
4972
- }
4973
-
4974
- result.width = result.right - result.left;
4975
- result.height = result.bottom - result.top;
4976
- return result;
4977
- };
5186
+ if (this.state.hasError) {
5187
+ return /*#__PURE__*/React__default['default'].createElement(ErrorComponent, {
5188
+ onReload: this.onReload
5189
+ });
5190
+ }
4978
5191
 
4979
- var isMacOS = function isMacOS() {
4980
- var userAgent = navigator.userAgent.toLowerCase();
4981
- return /mac os ?x 10/.test(userAgent);
4982
- }; // From https://stackoverflow.com/questions/20110224/what-is-the-height-of-a-line-in-a-wheel-event-deltamode-dom-delta-line
5192
+ return this.props.children;
5193
+ }
5194
+ }], [{
5195
+ key: "getDerivedStateFromError",
5196
+ value: function getDerivedStateFromError() {
5197
+ return {
5198
+ hasError: true
5199
+ };
5200
+ }
5201
+ }]);
4983
5202
 
4984
- var getScrollLineHeight = function getScrollLineHeight() {
4985
- var iframe = document.createElement("iframe");
4986
- iframe.src = "#";
4987
- document.body.appendChild(iframe); // Write content in Iframe
5203
+ return ItemErrorBoundary;
5204
+ }(React__default['default'].Component);
4988
5205
 
4989
- var idoc = iframe.contentWindow.document;
4990
- idoc.open();
4991
- idoc.write("<!DOCTYPE html><html><head></head><body><span>a</span></body></html>");
4992
- idoc.close();
4993
- var scrollLineHeight = idoc.body.firstElementChild.offsetHeight;
4994
- document.body.removeChild(iframe);
4995
- return scrollLineHeight;
5206
+ var removeClass = function removeClass(e) {
5207
+ e.target.className = "";
4996
5208
  };
4997
5209
 
4998
- var LINE_HEIGHT = getScrollLineHeight(); // Reasonable default from https://github.com/facebookarchive/fixed-data-table/blob/master/src/vendor_upstream/dom/normalizeWheel.js
5210
+ var defaultResize = function defaultResize(_ref3) {
5211
+ var width = _ref3.width,
5212
+ height = _ref3.height,
5213
+ actualWidth = _ref3.actualWidth,
5214
+ actualHeight = _ref3.actualHeight,
5215
+ prevState = _ref3.prevState,
5216
+ keepRatio = _ref3.keepRatio;
5217
+ var currentWidth = prevState.width,
5218
+ currentHeight = prevState.height; // Parse text values if any
5219
+
5220
+ var _ref4 = [parseFloat(currentWidth), parseFloat(currentHeight)];
5221
+ currentWidth = _ref4[0];
5222
+ currentHeight = _ref4[1];
5223
+
5224
+ if (!currentWidth || Number.isNaN(Number(currentWidth))) {
5225
+ currentWidth = actualWidth;
5226
+ }
4999
5227
 
5000
- var PAGE_HEIGHT = 800;
5228
+ if (!currentHeight || Number.isNaN(Number(currentHeight))) {
5229
+ currentHeight = actualHeight;
5230
+ }
5001
5231
 
5002
- var otherPointer = function otherPointer(pointers, currentPointer) {
5003
- var p2 = Object.keys(pointers).map(function (p) {
5004
- return Number(p);
5005
- }).find(function (pointer) {
5006
- return pointer !== currentPointer;
5232
+ if (keepRatio) {
5233
+ var ratio = currentWidth / currentHeight;
5234
+ return _objectSpread2(_objectSpread2({}, prevState), {}, {
5235
+ width: (currentWidth + width).toFixed(1),
5236
+ height: (currentHeight + height / ratio).toFixed(1)
5237
+ });
5238
+ }
5239
+
5240
+ return _objectSpread2(_objectSpread2({}, prevState), {}, {
5241
+ width: (currentWidth + width).toFixed(1),
5242
+ height: (currentHeight + height).toFixed(1)
5007
5243
  });
5008
- return pointers[p2];
5009
5244
  };
5010
5245
 
5011
- var computeDistance = function computeDistance(_ref, _ref2) {
5012
- var _ref3 = _slicedToArray(_ref, 2),
5013
- x1 = _ref3[0],
5014
- y1 = _ref3[1];
5015
-
5016
- var _ref4 = _slicedToArray(_ref2, 2),
5017
- x2 = _ref4[0],
5018
- y2 = _ref4[1];
5019
-
5020
- var distanceX = Math.abs(x1 - x2);
5021
- var distanceY = Math.abs(y1 - y2);
5022
- return Math.hypot(distanceX, distanceY);
5246
+ var defaultResizeDirection = {
5247
+ w: true,
5248
+ h: true,
5249
+ b: true
5023
5250
  };
5024
5251
 
5025
- var empty = function empty() {};
5252
+ var Item = function Item(_ref5) {
5253
+ var _itemMap$error;
5026
5254
 
5027
- var protect = function protect(fn) {
5028
- return /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
5029
- var _args = arguments;
5030
- return regeneratorRuntime.wrap(function _callee$(_context) {
5031
- while (1) {
5032
- switch (_context.prev = _context.next) {
5033
- case 0:
5034
- _context.prev = 0;
5035
- _context.next = 3;
5036
- return fn.apply(void 0, _args);
5255
+ var setState = _ref5.setState,
5256
+ _ref5$state = _ref5.state;
5257
+ _ref5$state = _ref5$state === void 0 ? {} : _ref5$state;
5258
+
5259
+ var type = _ref5$state.type,
5260
+ _ref5$state$rotation = _ref5$state.rotation,
5261
+ rotation = _ref5$state$rotation === void 0 ? 0 : _ref5$state$rotation,
5262
+ id = _ref5$state.id,
5263
+ locked = _ref5$state.locked,
5264
+ layer = _ref5$state.layer,
5265
+ rest = _objectWithoutProperties(_ref5$state, _excluded$2),
5266
+ _ref5$animate = _ref5.animate,
5267
+ animate = _ref5$animate === void 0 ? "hvr-pop" : _ref5$animate,
5268
+ isSelected = _ref5.isSelected,
5269
+ itemMap = _ref5.itemMap,
5270
+ _ref5$showResizeHandl = _ref5.showResizeHandle,
5271
+ showResizeHandle = _ref5$showResizeHandl === void 0 ? false : _ref5$showResizeHandl;
5272
+
5273
+ var itemWrapperRef = React__default['default'].useRef(null);
5274
+ var _itemMap$type = itemMap[type],
5275
+ _itemMap$type$compone = _itemMap$type.component,
5276
+ Component = _itemMap$type$compone === void 0 ? function () {
5277
+ return null;
5278
+ } : _itemMap$type$compone,
5279
+ _itemMap$type$resizeD = _itemMap$type.resizeDirections,
5280
+ resizeDirections = _itemMap$type$resizeD === void 0 ? defaultResizeDirection : _itemMap$type$resizeD,
5281
+ _itemMap$type$resize = _itemMap$type.resize,
5282
+ resize = _itemMap$type$resize === void 0 ? defaultResize : _itemMap$type$resize;
5283
+ var updateState = React__default['default'].useCallback(function (callbackOrItem) {
5284
+ var sync = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
5285
+ return setState(id, callbackOrItem, sync);
5286
+ }, [setState, id]);
5287
+ React__default['default'].useEffect(function () {
5288
+ itemWrapperRef.current.className = animate;
5289
+ }, [animate]);
5290
+ var className = "item ".concat(id);
5037
5291
 
5038
- case 3:
5039
- _context.next = 8;
5040
- break;
5292
+ if (locked) {
5293
+ className += " locked";
5294
+ }
5041
5295
 
5042
- case 5:
5043
- _context.prev = 5;
5044
- _context.t0 = _context["catch"](0);
5045
- // eslint-disable-next-line no-console
5046
- console.error(_context.t0);
5296
+ if (isSelected) {
5297
+ className += " selected";
5298
+ }
5047
5299
 
5048
- case 8:
5049
- case "end":
5050
- return _context.stop();
5051
- }
5052
- }
5053
- }, _callee, null, [[0, 5]]);
5054
- }));
5300
+ var onResize = React__default['default'].useCallback(function (_ref6) {
5301
+ var _ref6$width = _ref6.width,
5302
+ width = _ref6$width === void 0 ? 0 : _ref6$width,
5303
+ _ref6$height = _ref6.height,
5304
+ height = _ref6$height === void 0 ? 0 : _ref6$height,
5305
+ keepRatio = _ref6.keepRatio;
5306
+ updateState(function (prev) {
5307
+ var _itemWrapperRef$curre = itemWrapperRef.current,
5308
+ offsetWidth = _itemWrapperRef$curre.offsetWidth,
5309
+ offsetHeight = _itemWrapperRef$curre.offsetHeight;
5310
+ return resize({
5311
+ prevState: prev,
5312
+ width: width,
5313
+ height: height,
5314
+ actualHeight: offsetHeight,
5315
+ actualWidth: offsetWidth,
5316
+ keepRatio: keepRatio
5317
+ });
5318
+ });
5319
+ }, [resize, updateState]);
5320
+ var onResizeWidth = React__default['default'].useCallback(function (_ref7) {
5321
+ var width = _ref7.width;
5322
+ onResize({
5323
+ width: width
5324
+ });
5325
+ }, [onResize]);
5326
+ var onResizeHeight = React__default['default'].useCallback(function (_ref8) {
5327
+ var height = _ref8.height;
5328
+ onResize({
5329
+ height: height
5330
+ });
5331
+ }, [onResize]);
5332
+ var onResizeRatio = React__default['default'].useCallback(function (_ref9) {
5333
+ var width = _ref9.width;
5334
+ onResize({
5335
+ height: width,
5336
+ width: width,
5337
+ keepRatio: true
5338
+ });
5339
+ }, [onResize]);
5340
+ return /*#__PURE__*/React__default['default'].createElement(ItemWrapper, {
5341
+ rotation: rotation,
5342
+ locked: locked,
5343
+ selected: isSelected,
5344
+ layer: layer,
5345
+ "data-id": id,
5346
+ className: className
5347
+ }, /*#__PURE__*/React__default['default'].createElement("div", {
5348
+ style: {
5349
+ display: "flex"
5350
+ },
5351
+ ref: itemWrapperRef,
5352
+ onAnimationEnd: removeClass,
5353
+ onKeyDown: function onKeyDown(e) {
5354
+ return e.stopPropagation();
5355
+ },
5356
+ onKeyUp: function onKeyUp(e) {
5357
+ return e.stopPropagation();
5358
+ }
5359
+ }, /*#__PURE__*/React__default['default'].createElement(ItemErrorBoundary, {
5360
+ itemId: id,
5361
+ state: rest,
5362
+ setState: updateState,
5363
+ ErrorComponent: (itemMap === null || itemMap === void 0 ? void 0 : (_itemMap$error = itemMap.error) === null || _itemMap$error === void 0 ? void 0 : _itemMap$error.component) || DefaultErrorComponent
5364
+ }, /*#__PURE__*/React__default['default'].createElement(Component, _extends$1({}, rest, {
5365
+ id: id,
5366
+ setState: updateState
5367
+ }))), /*#__PURE__*/React__default['default'].createElement("div", {
5368
+ className: "corner top-left"
5369
+ }), /*#__PURE__*/React__default['default'].createElement("div", {
5370
+ className: "corner top-right"
5371
+ }), /*#__PURE__*/React__default['default'].createElement("div", {
5372
+ className: "corner bottom-right"
5373
+ }), /*#__PURE__*/React__default['default'].createElement("div", {
5374
+ className: "corner bottom-left"
5375
+ }), isSelected && showResizeHandle && /*#__PURE__*/React__default['default'].createElement(React__default['default'].Fragment, null, resizeDirections.b && /*#__PURE__*/React__default['default'].createElement(ResizeHandler, {
5376
+ className: "resize resize-ratio",
5377
+ onResize: onResizeRatio
5378
+ }), resizeDirections.h && /*#__PURE__*/React__default['default'].createElement(ResizeHandler, {
5379
+ className: "resize resize-height",
5380
+ onResize: onResizeHeight
5381
+ }), resizeDirections.w && /*#__PURE__*/React__default['default'].createElement(ResizeHandler, {
5382
+ className: "resize resize-width",
5383
+ onResize: onResizeWidth
5384
+ }))));
5055
5385
  };
5056
5386
 
5057
- var Gesture = function Gesture(_ref6) {
5058
- var children = _ref6.children,
5059
- _ref6$onDrag = _ref6.onDrag,
5060
- onDrag = _ref6$onDrag === void 0 ? empty : _ref6$onDrag,
5061
- _ref6$onDragStart = _ref6.onDragStart,
5062
- onDragStart = _ref6$onDragStart === void 0 ? empty : _ref6$onDragStart,
5063
- _ref6$onDragEnd = _ref6.onDragEnd,
5064
- onDragEnd = _ref6$onDragEnd === void 0 ? empty : _ref6$onDragEnd,
5065
- _ref6$onPan = _ref6.onPan,
5066
- onPan = _ref6$onPan === void 0 ? empty : _ref6$onPan,
5067
- _ref6$onTap = _ref6.onTap,
5068
- onTap = _ref6$onTap === void 0 ? empty : _ref6$onTap,
5069
- _ref6$onLongTap = _ref6.onLongTap,
5070
- onLongTap = _ref6$onLongTap === void 0 ? empty : _ref6$onLongTap,
5071
- _ref6$onDoubleTap = _ref6.onDoubleTap,
5072
- onDoubleTap = _ref6$onDoubleTap === void 0 ? empty : _ref6$onDoubleTap,
5073
- onZoom = _ref6.onZoom;
5074
- var wrapperRef = React__default['default'].useRef(null);
5075
- var stateRef = React__default['default'].useRef({
5076
- moving: false,
5077
- pointers: {},
5078
- mainPointer: undefined
5079
- });
5080
- var queueRef = React__default['default'].useRef([]); // Queue event to avoid async mess
5081
-
5082
- var queue = React__default['default'].useCallback(function (callback, args) {
5083
- queueRef.current.push( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
5084
- return regeneratorRuntime.wrap(function _callee2$(_context2) {
5085
- while (1) {
5086
- switch (_context2.prev = _context2.next) {
5087
- case 0:
5088
- _context2.next = 2;
5089
- return protect(callback)(args);
5387
+ var MemoizedItem = /*#__PURE__*/React.memo(Item, function (_ref10, _ref11) {
5388
+ var prevState = _ref10.state,
5389
+ prevSetState = _ref10.setState,
5390
+ prevIsSelected = _ref10.isSelected,
5391
+ prevShowResizeHandle = _ref10.showResizeHandle;
5392
+ var nextState = _ref11.state,
5393
+ nextSetState = _ref11.setState,
5394
+ nextIsSelected = _ref11.isSelected,
5395
+ nextShowResizeHandle = _ref11.showResizeHandle;
5396
+ return prevIsSelected === nextIsSelected && prevShowResizeHandle === nextShowResizeHandle && prevSetState === nextSetState && JSON.stringify(prevState) === JSON.stringify(nextState);
5397
+ }); // Exclude positioning from memoization
5090
5398
 
5091
- case 2:
5092
- queueRef.current.shift();
5399
+ var PositionedItem = function PositionedItem(_ref12) {
5400
+ var _ref12$state = _ref12.state,
5401
+ state = _ref12$state === void 0 ? {} : _ref12$state,
5402
+ boardSize = _ref12.boardSize,
5403
+ currentUser = _ref12.currentUser,
5404
+ rest = _objectWithoutProperties(_ref12, _excluded2);
5093
5405
 
5094
- if (!(queueRef.current.length !== 0)) {
5095
- _context2.next = 6;
5096
- break;
5097
- }
5406
+ if (!rest.itemMap[state.type]) {
5407
+ return null;
5408
+ }
5098
5409
 
5099
- _context2.next = 6;
5100
- return protect(queueRef.current[0])();
5410
+ var _rest$itemMap$state$t = rest.itemMap[state.type].stateHook,
5411
+ stateHook = _rest$itemMap$state$t === void 0 ? identity : _rest$itemMap$state$t;
5101
5412
 
5102
- case 6:
5103
- case "end":
5104
- return _context2.stop();
5105
- }
5106
- }
5107
- }, _callee2);
5108
- })));
5413
+ var _stateHook = stateHook(state, {
5414
+ currentUser: currentUser
5415
+ }),
5416
+ _stateHook$x = _stateHook.x,
5417
+ x = _stateHook$x === void 0 ? 0 : _stateHook$x,
5418
+ _stateHook$y = _stateHook.y,
5419
+ y = _stateHook$y === void 0 ? 0 : _stateHook$y,
5420
+ _stateHook$layer = _stateHook.layer,
5421
+ layer = _stateHook$layer === void 0 ? 0 : _stateHook$layer,
5422
+ moving = _stateHook.moving,
5423
+ stateRest = _objectWithoutProperties(_stateHook, _excluded3);
5424
+
5425
+ return /*#__PURE__*/React__default['default'].createElement("div", {
5426
+ style: {
5427
+ position: "absolute",
5428
+ top: "".concat(boardSize / 2, "px"),
5429
+ left: "".concat(boardSize / 2, "px"),
5430
+ display: "inline-block",
5431
+ transform: "translate(".concat(x, "px, ").concat(y, "px)"),
5432
+ zIndex: (layer + 4) * 10 + 100 + (moving ? 5 : 0) // Items z-index between 100 and 200
5109
5433
 
5110
- if (queueRef.current.length === 1) {
5111
- protect(queueRef.current[0])();
5112
5434
  }
5113
- }, []);
5114
- var onWheel = React__default['default'].useCallback(function (e) {
5115
- var deltaX = e.deltaX,
5116
- deltaY = e.deltaY,
5117
- clientX = e.clientX,
5118
- clientY = e.clientY,
5119
- deltaMode = e.deltaMode,
5120
- ctrlKey = e.ctrlKey,
5121
- altKey = e.altKey,
5122
- metaKey = e.metaKey,
5123
- target = e.target; // On a MacOs trackpad, the pinch gesture sets the ctrlKey to true.
5124
- // In that situation, we want to use the custom scaling, not the browser default zoom.
5125
- // Hence in this situation we avoid to return immediately.
5435
+ }, /*#__PURE__*/React__default['default'].createElement(MemoizedItem, _extends$1({}, rest, {
5436
+ // Helps to prevent render
5437
+ showResizeHandle: rest.isSelected && rest.showResizeHandle,
5438
+ state: stateRest
5439
+ })));
5440
+ };
5126
5441
 
5127
- if (altKey || ctrlKey && !isMacOS()) {
5128
- return;
5129
- } // On a trackpad, the pinch and pan events are differentiated by the crtlKey value.
5130
- // On a pinch gesture, the ctrlKey is set to true, so we want to have a scaling effect.
5131
- // If we are only moving the fingers in the same direction, a pan is needed.
5132
- // Ref: https://medium.com/@auchenberg/detecting-multi-touch-trackpad-gestures-in-javascript-a2505babb10e
5442
+ var MemoizedPositionedItem = /*#__PURE__*/React.memo(PositionedItem);
5133
5443
 
5444
+ var persistUser = function persistUser(user) {
5445
+ localStorage.setItem("user", JSON.stringify(user));
5446
+ };
5447
+ var colors = ["#037758", "#99092a", "#067070", "#c6650f", "#008726", "#3d7004", "#348402", "#057f58", "#b58612", "#c44c01", "#0a7704", "#0e910e", "#027377", "#c99e02", "#054160", "#157a01", "#b10de2", "#0d6289", "#bc5d03", "#ba0cd1", "#d39f10", "#0c4c7a", "#460782", "#a51f10", "#cecb10", "#9b0943", "#607f0c", "#007a4b", "#bf0daa", "#af0ad8"];
5134
5448
 
5135
- if (isMacOS() && !ctrlKey) {
5136
- queue(onPan, {
5137
- deltaX: -2 * deltaX,
5138
- deltaY: -2 * deltaY,
5139
- button: 1,
5140
- ctrlKey: ctrlKey,
5141
- metaKey: metaKey,
5142
- target: target,
5143
- event: e
5144
- });
5145
- } else {
5146
- // Quit if onZoom is not set
5147
- if (onZoom === undefined || !deltaY) return;
5148
- var scale = deltaY;
5449
+ var getRandomColor = function getRandomColor() {
5450
+ return colors[Math.floor(Math.random() * colors.length)];
5451
+ }; // TODO remove user persistence
5149
5452
 
5150
- switch (deltaMode) {
5151
- case 1:
5152
- // Pixel
5153
- scale *= LINE_HEIGHT;
5154
- break;
5155
5453
 
5156
- case 2:
5157
- scale *= PAGE_HEIGHT;
5158
- break;
5159
- }
5454
+ var getUser = function getUser() {
5455
+ if (localStorage.user) {
5456
+ // Add some mandatory info if missing
5457
+ var localUser = _objectSpread2({
5458
+ name: "Player",
5459
+ color: getRandomColor(),
5460
+ uid: nanoid()
5461
+ }, JSON.parse(localStorage.user)); // Id is given by server
5462
+ // delete localUser.id;
5160
5463
 
5161
- if (isMacOS()) {
5162
- scale *= 2;
5163
- }
5164
5464
 
5165
- queue(onZoom, {
5166
- scale: scale,
5167
- clientX: clientX,
5168
- clientY: clientY,
5169
- event: e
5170
- });
5171
- }
5172
- }, [onPan, onZoom, queue]);
5173
- var onPointerDown = React__default['default'].useCallback(function (_ref8) {
5174
- var target = _ref8.target,
5175
- button = _ref8.button,
5176
- clientX = _ref8.clientX,
5177
- clientY = _ref8.clientY,
5178
- pointerId = _ref8.pointerId,
5179
- altKey = _ref8.altKey,
5180
- ctrlKey = _ref8.ctrlKey,
5181
- metaKey = _ref8.metaKey,
5182
- isPrimary = _ref8.isPrimary;
5183
- // Add pointer to map
5184
- stateRef.current.pointers[pointerId] = {
5185
- clientX: clientX,
5186
- clientY: clientY
5187
- };
5465
+ persistUser(localUser);
5466
+ return localUser;
5467
+ }
5188
5468
 
5189
- if (isPrimary) {
5190
- // Clean mainPoint on primary pointer
5191
- stateRef.current.mainPointer = undefined;
5192
- }
5469
+ var newUser = {
5470
+ name: "Player",
5471
+ color: getRandomColor(),
5472
+ uid: nanoid()
5473
+ };
5474
+ persistUser(newUser);
5475
+ return newUser;
5476
+ };
5477
+ var userAtom = recoil.atom({
5478
+ key: "user",
5479
+ "default": getUser()
5480
+ });
5481
+ var usersAtom = recoil.atom({
5482
+ key: "users",
5483
+ "default": []
5484
+ });
5485
+ var localUsersAtom = recoil.selector({
5486
+ key: "localUsersAtom",
5487
+ get: function get(_ref) {
5488
+ var _get = _ref.get;
5193
5489
 
5194
- if (stateRef.current.mainPointer !== undefined) {
5195
- if (stateRef.current.mainPointer !== pointerId) {
5196
- // This is not the main pointer
5197
- try {
5198
- var _otherPointer = otherPointer(stateRef.current.pointers, pointerId),
5199
- clientX2 = _otherPointer.clientX,
5200
- clientY2 = _otherPointer.clientY;
5490
+ var currentUser = _get(userAtom);
5201
5491
 
5202
- var newClientX = (clientX2 + clientX) / 2;
5203
- var newClientY = (clientY2 + clientY) / 2;
5204
- var distance = computeDistance([clientX2, clientY2], [clientX, clientY]); // We update previous position as the new position is the center beetween both finger
5492
+ var users = _get(usersAtom);
5205
5493
 
5206
- Object.assign(stateRef.current, {
5207
- pressed: true,
5208
- moving: false,
5209
- gestureStart: false,
5210
- startX: clientX,
5211
- startY: clientY,
5212
- prevX: newClientX,
5213
- prevY: newClientY,
5214
- startDistance: distance,
5215
- prevDistance: distance
5216
- });
5217
- } catch (e) {
5218
- // eslint-disable-next-line no-console
5219
- console.log("Error while getting other pointer. Ignoring", e); // eslint-disable-next-line no-unused-expressions
5494
+ return users.filter(function (_ref2) {
5495
+ var space = _ref2.space;
5496
+ return space === currentUser.space;
5497
+ });
5498
+ }
5499
+ });
5220
5500
 
5221
- stateRef.current.mainPointer === undefined;
5222
- }
5223
- }
5501
+ var useUsers = function useUsers() {
5502
+ var _useRecoilState = recoil.useRecoilState(userAtom),
5503
+ _useRecoilState2 = _slicedToArray(_useRecoilState, 2),
5504
+ currentUser = _useRecoilState2[0],
5505
+ setCurrentUserState = _useRecoilState2[1];
5224
5506
 
5225
- return;
5226
- } // We set the mainpointer
5507
+ var users = recoil.useRecoilValue(usersAtom);
5508
+ var localUsers = recoil.useRecoilValue(localUsersAtom);
5509
+ var setCurrentUser = React__default['default'].useCallback(function (callbackOrUser) {
5510
+ var callback = callbackOrUser;
5227
5511
 
5512
+ if (_typeof(callbackOrUser) === "object") {
5513
+ callback = function callback() {
5514
+ return callbackOrUser;
5515
+ };
5516
+ }
5228
5517
 
5229
- stateRef.current.mainPointer = pointerId; // And prepare move
5518
+ setCurrentUserState(function (prevUser) {
5519
+ var newUser = _objectSpread2(_objectSpread2({}, callback(prevUser)), {}, {
5520
+ id: prevUser.id,
5521
+ uid: prevUser.uid
5522
+ });
5230
5523
 
5231
- Object.assign(stateRef.current, {
5232
- pressed: true,
5233
- moving: false,
5234
- gestureStart: false,
5235
- startX: clientX,
5236
- startY: clientY,
5237
- prevX: clientX,
5238
- prevY: clientY,
5239
- currentButton: button,
5240
- target: target,
5241
- timeStart: Date.now(),
5242
- longTapTimeout: setTimeout( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {
5243
- return regeneratorRuntime.wrap(function _callee3$(_context3) {
5244
- while (1) {
5245
- switch (_context3.prev = _context3.next) {
5246
- case 0:
5247
- stateRef.current.noTap = true;
5248
- queue(onLongTap, {
5249
- clientX: clientX,
5250
- clientY: clientY,
5251
- altKey: altKey,
5252
- ctrlKey: ctrlKey,
5253
- metaKey: metaKey,
5254
- target: target
5255
- });
5524
+ persistUser(newUser);
5525
+ return newUser;
5526
+ });
5527
+ }, [setCurrentUserState]);
5528
+ return {
5529
+ currentUser: currentUser,
5530
+ setCurrentUser: setCurrentUser,
5531
+ users: users,
5532
+ localUsers: localUsers
5533
+ };
5534
+ };
5256
5535
 
5257
- case 2:
5258
- case "end":
5259
- return _context3.stop();
5260
- }
5261
- }
5262
- }, _callee3);
5263
- })), 750)
5536
+ var SubscribeUserEvents = function SubscribeUserEvents() {
5537
+ var usersRef = React__default['default'].useRef([]);
5538
+ var setUsers = recoil.useSetRecoilState(usersAtom);
5539
+
5540
+ var _useRecoilState = recoil.useRecoilState(userAtom),
5541
+ _useRecoilState2 = _slicedToArray(_useRecoilState, 2),
5542
+ currentUser = _useRecoilState2[0],
5543
+ setCurrentUserState = _useRecoilState2[1];
5544
+
5545
+ var _useWire = useWire("room"),
5546
+ wire = _useWire.wire,
5547
+ isMaster = _useWire.isMaster,
5548
+ roomSpace = _useWire.room;
5549
+
5550
+ React__default['default'].useEffect(function () {
5551
+ setCurrentUserState(function (prevUser) {
5552
+ return _objectSpread2(_objectSpread2({}, prevUser), {}, {
5553
+ id: wire.userId,
5554
+ space: roomSpace
5555
+ });
5264
5556
  });
5557
+ return function () {
5558
+ setCurrentUserState(function (prevUser) {
5559
+ return _objectSpread2(_objectSpread2({}, prevUser), {}, {
5560
+ id: wire.userId,
5561
+ space: null
5562
+ });
5563
+ });
5564
+ };
5565
+ }, [wire.userId, roomSpace, setCurrentUserState]);
5566
+ React__default['default'].useEffect(function () {
5567
+ if (!isMaster) {
5568
+ var onGetUserList = function onGetUserList(userList) {
5569
+ usersRef.current = userList;
5570
+ setUsers(userList);
5571
+ };
5265
5572
 
5266
- try {
5267
- target.setPointerCapture(pointerId);
5268
- } catch (e) {
5269
- // eslint-disable-next-line no-console
5270
- console.log("Fail to capture pointer", e);
5573
+ wire.call("getUserList").then(onGetUserList, function () {
5574
+ // retry later
5575
+ setTimeout(function () {
5576
+ wire.call("getUserList") // eslint-disable-next-line no-console
5577
+ .then(onGetUserList, function (error) {
5578
+ return console.log(error);
5579
+ });
5580
+ }, 1000);
5581
+ });
5271
5582
  }
5272
- }, [onLongTap, queue]);
5273
- var onPointerMove = React__default['default'].useCallback(function (e) {
5274
- if (stateRef.current.pressed) {
5275
- var pointerId = e.pointerId,
5276
- eventClientX = e.clientX,
5277
- eventClientY = e.clientY,
5278
- altKey = e.altKey,
5279
- ctrlKey = e.ctrlKey,
5280
- metaKey = e.metaKey,
5281
- pointerType = e.pointerType;
5583
+ }, [wire, isMaster, setUsers]); // eslint-disable-next-line react-hooks/exhaustive-deps
5282
5584
 
5283
- if (stateRef.current.mainPointer !== pointerId) {
5284
- // Event from other pointer
5285
- stateRef.current.pointers[pointerId] = {
5286
- clientX: eventClientX,
5287
- clientY: eventClientY
5288
- };
5289
- return;
5290
- }
5585
+ var debouncedEmitUpdateUser = useDebouncedCallback(function (newUser) {
5586
+ wire.publish("userUpdate", newUser, true);
5587
+ }, [wire], 500);
5588
+ React__default['default'].useEffect(function () {
5589
+ if (currentUser && currentUser.id) {
5590
+ debouncedEmitUpdateUser(currentUser);
5591
+ }
5592
+ }, [currentUser, debouncedEmitUpdateUser]);
5593
+ React__default['default'].useEffect(function () {
5594
+ var unsub = [];
5291
5595
 
5292
- stateRef.current.moving = true; // Do we have two fingers ?
5596
+ if (isMaster) {
5597
+ wire.register("getUserList", function () {
5598
+ return usersRef.current;
5599
+ }).then(function (unregister) {
5600
+ unsub.push(unregister);
5601
+ });
5602
+ unsub.push(wire.subscribe("userUpdate", function (user) {
5603
+ if (usersRef.current.find(function (u) {
5604
+ return u.id === user.id;
5605
+ })) {
5606
+ var newUsers = usersRef.current.map(function (u) {
5607
+ return u.id === user.id ? user : u;
5608
+ });
5609
+ usersRef.current = newUsers;
5610
+ } else {
5611
+ var _newUsers = [].concat(_toConsumableArray(usersRef.current), [user]);
5293
5612
 
5294
- var twoFingers = Object.keys(stateRef.current.pointers).length === 2;
5295
- var clientX;
5296
- var clientY;
5297
- var distance;
5613
+ usersRef.current = _newUsers;
5614
+ }
5298
5615
 
5299
- if (twoFingers) {
5300
- // Find other pointerId
5301
- var _otherPointer2 = otherPointer(stateRef.current.pointers, pointerId),
5302
- clientX2 = _otherPointer2.clientX,
5303
- clientY2 = _otherPointer2.clientY; // Update client X with the center of each touch
5616
+ setUsers(usersRef.current);
5617
+ wire.publish("updateUserList", usersRef.current);
5618
+ }));
5619
+ }
5620
+
5621
+ unsub.push(wire.subscribe("userLeave", function (userId) {
5622
+ usersRef.current = usersRef.current.filter(function (_ref) {
5623
+ var id = _ref.id;
5624
+ return id !== userId;
5625
+ });
5626
+ setUsers(usersRef.current);
5304
5627
 
5628
+ if (isMaster) {
5629
+ wire.publish("updateUserList", usersRef.current);
5630
+ }
5631
+ }));
5632
+ unsub.push(wire.subscribe("updateUserList", function (newList) {
5633
+ usersRef.current = newList;
5634
+ setUsers(usersRef.current);
5635
+ }));
5636
+ return function () {
5637
+ unsub.forEach(function (u) {
5638
+ return u();
5639
+ });
5640
+ };
5641
+ }, [wire, isMaster, setUsers]);
5642
+ return null;
5643
+ };
5305
5644
 
5306
- clientX = (clientX2 + eventClientX) / 2;
5307
- clientY = (clientY2 + eventClientY) / 2;
5308
- distance = computeDistance([clientX2, clientY2], [eventClientX, eventClientY]);
5309
- } else {
5310
- clientX = eventClientX;
5311
- clientY = eventClientY;
5312
- } // We drag if
5313
- // On non touch device
5314
- // - Button is 0
5315
- // - Alt key is no pressed
5316
- // or on touch devices
5317
- // - We use only one finger
5645
+ var ItemList = function ItemList() {
5646
+ var _useItemActions = useItemActions(),
5647
+ updateItem = _useItemActions.updateItem;
5318
5648
 
5649
+ var itemList = recoil.useRecoilValue(ItemListAtom);
5650
+ var itemMap = recoil.useRecoilValue(ItemMapAtom);
5651
+ var selectedItems = recoil.useRecoilValue(SelectedItemsAtom);
5319
5652
 
5320
- var shouldDrag = pointerType !== "touch" ? stateRef.current.currentButton === 0 && !altKey : !twoFingers;
5653
+ var _useRecoilValue = recoil.useRecoilValue(ConfigurationAtom),
5654
+ boardSize = _useRecoilValue.boardSize,
5655
+ showResizeHandle = _useRecoilValue.showResizeHandle,
5656
+ itemTemplates = _useRecoilValue.itemTemplates;
5321
5657
 
5322
- if (shouldDrag) {
5323
- // Send drag start on first move
5324
- if (!stateRef.current.gestureStart) {
5325
- wrapperRef.current.style.cursor = "move";
5326
- stateRef.current.gestureStart = true; // Clear tap timeout
5658
+ var _useUsers = useUsers(),
5659
+ currentUser = _useUsers.currentUser;
5327
5660
 
5328
- clearTimeout(stateRef.current.longTapTimeout);
5329
- queue(onDragStart, {
5330
- deltaX: 0,
5331
- deltaY: 0,
5332
- startX: stateRef.current.startX,
5333
- startY: stateRef.current.startY,
5334
- clientX: stateRef.current.startX,
5335
- clientY: stateRef.current.startY,
5336
- distanceX: 0,
5337
- distanceY: 0,
5338
- button: stateRef.current.currentButton,
5339
- altKey: altKey,
5340
- ctrlKey: ctrlKey,
5341
- metaKey: metaKey,
5342
- target: stateRef.current.target,
5343
- event: e
5344
- });
5345
- } // Create closure
5661
+ return itemList.map(function (itemId) {
5662
+ return /*#__PURE__*/React__default['default'].createElement(MemoizedPositionedItem, {
5663
+ key: itemId,
5664
+ state: itemMap[itemId],
5665
+ setState: updateItem,
5666
+ isSelected: selectedItems.includes(itemId),
5667
+ itemMap: itemTemplates,
5668
+ boardSize: boardSize,
5669
+ currentUser: currentUser,
5670
+ showResizeHandle: showResizeHandle
5671
+ });
5672
+ });
5673
+ };
5346
5674
 
5675
+ var SubcribeItemEvents = function SubcribeItemEvents() {
5676
+ var _useWire = useWire("board"),
5677
+ wire = _useWire.wire;
5347
5678
 
5348
- var deltaX = clientX - stateRef.current.prevX;
5349
- var deltaY = clientY - stateRef.current.prevY;
5350
- var distanceX = clientX - stateRef.current.startX;
5351
- var distanceY = clientY - stateRef.current.startY; // Drag event
5679
+ var setItemMap = recoil.useSetRecoilState(ItemMapAtom);
5352
5680
 
5353
- queue(onDrag, {
5354
- deltaX: deltaX,
5355
- deltaY: deltaY,
5356
- startX: stateRef.current.startX,
5357
- startY: stateRef.current.startY,
5358
- clientX: clientX,
5359
- clientY: clientY,
5360
- distanceX: distanceX,
5361
- distanceY: distanceY,
5362
- button: stateRef.current.currentButton,
5363
- altKey: altKey,
5364
- ctrlKey: ctrlKey,
5365
- metaKey: metaKey,
5366
- target: stateRef.current.target,
5367
- event: e
5368
- });
5369
- } else {
5370
- if (!stateRef.current.gestureStart) {
5371
- wrapperRef.current.style.cursor = "move";
5372
- stateRef.current.gestureStart = true; // Clear tap timeout on first move
5681
+ var _useItemActions = useItemActions(),
5682
+ updateItemOrder = _useItemActions.updateItemOrder,
5683
+ moveItems = _useItemActions.moveItems,
5684
+ removeItems = _useItemActions.removeItems,
5685
+ pushItem = _useItemActions.pushItem;
5373
5686
 
5374
- clearTimeout(stateRef.current.longTapTimeout);
5375
- } // Create closure
5687
+ var batchUpdate = React__default['default'].useCallback(function (updatedItems) {
5688
+ setItemMap(function (prevItemMap) {
5689
+ return _objectSpread2(_objectSpread2({}, prevItemMap), updatedItems);
5690
+ });
5691
+ }, [setItemMap]);
5692
+ React__default['default'].useEffect(function () {
5693
+ var unsub = wire.subscribe("batchItemsUpdate", function (updatedItems) {
5694
+ batchUpdate(updatedItems);
5695
+ });
5696
+ return unsub;
5697
+ }, [wire, batchUpdate]);
5698
+ React__default['default'].useEffect(function () {
5699
+ var unsub = wire.subscribe("selectedItemsMove", function (_ref) {
5700
+ var itemIds = _ref.itemIds,
5701
+ posDelta = _ref.posDelta;
5702
+ moveItems(itemIds, posDelta, false);
5703
+ });
5704
+ return unsub;
5705
+ }, [wire, moveItems]);
5706
+ React__default['default'].useEffect(function () {
5707
+ var unsub = wire.subscribe("updateItemListOrder", function (itemIds) {
5708
+ updateItemOrder(itemIds, false);
5709
+ });
5710
+ return unsub;
5711
+ }, [wire, updateItemOrder]);
5712
+ React__default['default'].useEffect(function () {
5713
+ var unsub = wire.subscribe("pushItem", function (newItem) {
5714
+ pushItem(newItem, null, false);
5715
+ });
5716
+ return unsub;
5717
+ }, [wire, pushItem]);
5718
+ React__default['default'].useEffect(function () {
5719
+ var unsub = wire.subscribe("insertItemBefore", function (_ref2) {
5720
+ var _ref3 = _slicedToArray(_ref2, 2),
5721
+ newItem = _ref3[0],
5722
+ beforeId = _ref3[1];
5376
5723
 
5724
+ pushItem(newItem, beforeId, false);
5725
+ });
5726
+ return unsub;
5727
+ }, [wire, pushItem]);
5728
+ React__default['default'].useEffect(function () {
5729
+ var unsub = wire.subscribe("removeItems", function (itemIds) {
5730
+ removeItems(itemIds, false);
5731
+ });
5732
+ return unsub;
5733
+ }, [wire, removeItems]);
5734
+ return null;
5735
+ };
5377
5736
 
5378
- var _deltaX = clientX - stateRef.current.prevX;
5737
+ /**
5738
+ * Check if element or parent has className.
5739
+ * @param {DOMElement} element
5740
+ * @param {string} className
5741
+ */
5742
+ var hasClass = function hasClass(element, className) {
5743
+ return element.classList && element.classList.contains(className);
5744
+ };
5745
+ var insideClass = function insideClass(element, className) {
5746
+ if (hasClass(element, className)) {
5747
+ return element;
5748
+ }
5379
5749
 
5380
- var _deltaY = clientY - stateRef.current.prevY;
5750
+ if (!element.parentNode) {
5751
+ return false;
5752
+ }
5381
5753
 
5382
- var target = stateRef.current.target; // Pan event
5754
+ return insideClass(element.parentNode, className);
5755
+ };
5756
+ var isPointInsideRect = function isPointInsideRect(point, rect) {
5757
+ return point.x > rect.left && point.x < rect.left + rect.width && point.y > rect.top && point.y < rect.top + rect.height;
5758
+ };
5759
+ var isItemInsideElement = function isItemInsideElement(itemElement, otherElem) {
5760
+ var rect = otherElem.getBoundingClientRect();
5761
+ var fourElem = Array.from(itemElement.querySelectorAll(".corner"));
5762
+ return fourElem.every(function (corner) {
5763
+ var _corner$getBoundingCl = corner.getBoundingClientRect(),
5764
+ y = _corner$getBoundingCl.top,
5765
+ x = _corner$getBoundingCl.left;
5383
5766
 
5384
- queue(onPan, {
5385
- deltaX: _deltaX,
5386
- deltaY: _deltaY,
5387
- button: stateRef.current.currentButton,
5388
- altKey: altKey,
5389
- ctrlKey: ctrlKey,
5390
- metaKey: metaKey,
5391
- target: target,
5392
- event: e
5393
- });
5767
+ return isPointInsideRect({
5768
+ x: x,
5769
+ y: y
5770
+ }, rect);
5771
+ });
5772
+ };
5773
+ var getItemElem = function getItemElem(wrapper, itemId) {
5774
+ var elems = wrapper.getElementsByClassName("item ".concat(itemId));
5775
+ var elem = elems[0];
5394
5776
 
5395
- if (twoFingers && distance !== stateRef.current.prevDistance && onZoom) {
5396
- var scale = stateRef.current.prevDistance - distance;
5777
+ if (!elem) {
5778
+ // eslint-disable-next-line no-console
5779
+ console.error("Missing item ".concat(itemId));
5780
+ }
5397
5781
 
5398
- if (Math.abs(scale) > 0) {
5399
- queue(onZoom, {
5400
- scale: scale,
5401
- clientX: clientX,
5402
- clientY: clientY,
5403
- event: e
5404
- });
5405
- stateRef.current.prevDistance = distance;
5406
- }
5407
- }
5408
- }
5782
+ return elem;
5783
+ };
5784
+ var getIdFromElem = function getIdFromElem(elem) {
5785
+ var _elem$dataset;
5409
5786
 
5410
- stateRef.current.prevX = clientX;
5411
- stateRef.current.prevY = clientY;
5412
- }
5413
- }, [onDrag, onDragStart, onPan, onZoom, queue]);
5414
- var onPointerUp = React__default['default'].useCallback(function (e) {
5415
- var clientX = e.clientX,
5416
- clientY = e.clientY,
5417
- altKey = e.altKey,
5418
- ctrlKey = e.ctrlKey,
5419
- metaKey = e.metaKey,
5420
- target = e.target,
5421
- pointerId = e.pointerId;
5787
+ var value = elem === null || elem === void 0 ? void 0 : (_elem$dataset = elem.dataset) === null || _elem$dataset === void 0 ? void 0 : _elem$dataset.id;
5422
5788
 
5423
- if (!stateRef.current.pointers[pointerId]) {
5424
- // Pointer already gone previously with another event
5425
- // ignoring it
5426
- return;
5427
- } // Remove pointer from map
5789
+ if (!value) {
5790
+ var _elem$dataset2;
5428
5791
 
5792
+ // eslint-disable-next-line no-console
5793
+ console.error("getIdFromElem call fails", elem, JSON.stringify(elem === null || elem === void 0 ? void 0 : elem.dataset), elem === null || elem === void 0 ? void 0 : (_elem$dataset2 = elem.dataset) === null || _elem$dataset2 === void 0 ? void 0 : _elem$dataset2.id);
5794
+ }
5429
5795
 
5430
- delete stateRef.current.pointers[pointerId];
5796
+ return value;
5797
+ };
5798
+ var getItemBoundingBox = function getItemBoundingBox(items) {
5799
+ var wrapper = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document;
5800
+ var result = items.reduce(function (prev, itemId) {
5801
+ var elem = getItemElem(wrapper, itemId);
5802
+ if (!elem) return null;
5431
5803
 
5432
- if (stateRef.current.mainPointer !== pointerId) {
5433
- // If this is not the main pointer we quit here
5434
- return;
5435
- }
5804
+ var _elem$getBoundingClie = elem.getBoundingClientRect(),
5805
+ left = _elem$getBoundingClie.left,
5806
+ right = _elem$getBoundingClie.right,
5807
+ top = _elem$getBoundingClie.top,
5808
+ bottom = _elem$getBoundingClie.bottom;
5436
5809
 
5437
- while (Object.keys(stateRef.current.pointers).length > 0) {
5438
- // If was main pointer but we have another one, this one become main
5439
- stateRef.current.mainPointer = Number(Object.keys(stateRef.current.pointers)[0]);
5810
+ var boundingBox;
5440
5811
 
5441
- try {
5442
- stateRef.current.target.setPointerCapture(stateRef.current.mainPointer);
5443
- return;
5444
- } catch (error) {
5445
- // eslint-disable-next-line no-console
5446
- console.log("Fails to set pointer capture", error);
5447
- stateRef.current.mainPointer = undefined;
5448
- delete stateRef.current.pointers[Object.keys(stateRef.current.pointers)[0]];
5449
- }
5812
+ if (!prev) {
5813
+ boundingBox = {
5814
+ left: left,
5815
+ top: top,
5816
+ right: right,
5817
+ bottom: bottom
5818
+ };
5819
+ } else {
5820
+ boundingBox = prev;
5450
5821
  }
5451
5822
 
5452
- stateRef.current.mainPointer = undefined;
5453
- stateRef.current.pressed = false; // Clear longTap
5454
-
5455
- clearTimeout(stateRef.current.longTapTimeout);
5823
+ boundingBox.left = Math.min(left, boundingBox.left);
5824
+ boundingBox.top = Math.min(top, boundingBox.top);
5825
+ boundingBox.right = Math.max(right, boundingBox.right);
5826
+ boundingBox.bottom = Math.max(bottom, boundingBox.bottom);
5827
+ return boundingBox;
5828
+ }, null);
5456
5829
 
5457
- if (stateRef.current.moving) {
5458
- // If we were moving, send drag end event
5459
- stateRef.current.moving = false;
5460
- queue(onDragEnd, {
5461
- deltaX: clientX - stateRef.current.prevX,
5462
- deltaY: clientY - stateRef.current.prevY,
5463
- startX: stateRef.current.startX,
5464
- startY: stateRef.current.startY,
5465
- clientX: clientX,
5466
- clientY: clientY,
5467
- distanceX: clientX - stateRef.current.startX,
5468
- distanceY: clientY - stateRef.current.startY,
5469
- button: stateRef.current.currentButton,
5470
- altKey: altKey,
5471
- ctrlKey: ctrlKey,
5472
- metaKey: metaKey,
5473
- event: e
5474
- });
5475
- wrapperRef.current.style.cursor = "auto";
5476
- } else {
5477
- var now = Date.now();
5830
+ if (!result) {
5831
+ return result;
5832
+ }
5478
5833
 
5479
- if (stateRef.current.noTap) {
5480
- stateRef.current.noTap = false;
5481
- } // Send tap event only if time less than 300ms
5482
- else if (stateRef.current.timeStart - now < 300) {
5483
- queue(onTap, {
5484
- clientX: clientX,
5485
- clientY: clientY,
5486
- altKey: altKey,
5487
- ctrlKey: ctrlKey,
5488
- metaKey: metaKey,
5489
- target: target
5490
- });
5491
- }
5492
- }
5493
- }, [onDragEnd, onTap, queue]);
5494
- var onDoubleTapHandler = React__default['default'].useCallback(function (event) {
5495
- queue(onDoubleTap, event);
5496
- }, [onDoubleTap, queue]);
5497
- return /*#__PURE__*/React__default['default'].createElement("div", {
5498
- onWheel: onWheel,
5499
- onPointerDown: onPointerDown,
5500
- onPointerMove: onPointerMove,
5501
- onPointerUp: onPointerUp,
5502
- onPointerOut: onPointerUp,
5503
- onPointerLeave: onPointerUp,
5504
- onPointerCancel: onPointerUp,
5505
- onDoubleClick: onDoubleTapHandler,
5506
- style: {
5507
- touchAction: "none"
5508
- },
5509
- ref: wrapperRef
5510
- }, children);
5834
+ result.width = result.right - result.left;
5835
+ result.height = result.bottom - result.top;
5836
+ return result;
5511
5837
  };
5512
5838
 
5513
5839
  var defaultSelectorStyle = {
@@ -6103,154 +6429,223 @@ var ActionPane = function ActionPane(_ref) {
6103
6429
  }, children);
6104
6430
  };
6105
6431
 
6106
- function t(t, n, r) {
6107
- return Math.min(Math.max(t, r), n);
6432
+ /**
6433
+ * A simple guard function:
6434
+ *
6435
+ * ```js
6436
+ * Math.min(Math.max(low, value), high)
6437
+ * ```
6438
+ */
6439
+ function guard(low, high, value) {
6440
+ return Math.min(Math.max(low, value), high);
6108
6441
  }
6109
6442
 
6110
- var n = /*#__PURE__*/function (_Error) {
6111
- _inherits(n, _Error);
6443
+ var ColorError = /*#__PURE__*/function (_Error) {
6444
+ _inherits(ColorError, _Error);
6112
6445
 
6113
- var _super = _createSuper(n);
6446
+ var _super = _createSuper(ColorError);
6114
6447
 
6115
- function n(t) {
6116
- _classCallCheck(this, n);
6448
+ function ColorError(color) {
6449
+ _classCallCheck(this, ColorError);
6117
6450
 
6118
- return _super.call(this, "Failed to parse color: \"".concat(t, "\""));
6451
+ return _super.call(this, "Failed to parse color: \"".concat(color, "\""));
6119
6452
  }
6120
6453
 
6121
- return n;
6454
+ return ColorError;
6122
6455
  }( /*#__PURE__*/_wrapNativeSuper(Error));
6123
6456
 
6124
- function r(r) {
6125
- if ("string" != typeof r) throw new n(r);
6126
- if ("transparent" === r.trim().toLowerCase()) return [0, 0, 0, 0];
6127
- var e = r.trim();
6128
- e = u.test(r) ? function (t) {
6129
- var r = t.toLowerCase().trim(),
6130
- e = o[function (t) {
6131
- var n = 5381,
6132
- r = t.length;
6133
-
6134
- for (; r;) {
6135
- n = 33 * n ^ t.charCodeAt(--r);
6136
- }
6137
-
6138
- return (n >>> 0) % 2341;
6139
- }(r)];
6140
-
6141
- if (!e) throw new n(t);
6142
- return "#".concat(e);
6143
- }(r) : r;
6144
- var f = s.exec(e);
6145
-
6146
- if (f) {
6147
- var _t = Array.from(f).slice(1);
6457
+ var ColorError$1 = ColorError;
6458
+ /**
6459
+ * Parses a color into red, gree, blue, alpha parts
6460
+ *
6461
+ * @param color the input color. Can be a RGB, RBGA, HSL, HSLA, or named color
6462
+ */
6148
6463
 
6149
- return [].concat(_toConsumableArray(_t.slice(0, 3).map(function (t) {
6150
- return parseInt(_(t, 2), 16);
6151
- })), [parseInt(_(_t[3] || "f", 2), 16) / 255]);
6464
+ function parseToRgba(color) {
6465
+ if (typeof color !== 'string') throw new ColorError$1(color);
6466
+ if (color.trim().toLowerCase() === 'transparent') return [0, 0, 0, 0];
6467
+ var normalizedColor = color.trim();
6468
+ normalizedColor = namedColorRegex.test(color) ? nameToHex(color) : color;
6469
+ var reducedHexMatch = reducedHexRegex.exec(normalizedColor);
6470
+
6471
+ if (reducedHexMatch) {
6472
+ var arr = Array.from(reducedHexMatch).slice(1);
6473
+ return [].concat(_toConsumableArray(arr.slice(0, 3).map(function (x) {
6474
+ return parseInt(r(x, 2), 16);
6475
+ })), [parseInt(r(arr[3] || 'f', 2), 16) / 255]);
6152
6476
  }
6153
6477
 
6154
- var p = i.exec(e);
6478
+ var hexMatch = hexRegex.exec(normalizedColor);
6155
6479
 
6156
- if (p) {
6157
- var _t2 = Array.from(p).slice(1);
6480
+ if (hexMatch) {
6481
+ var _arr = Array.from(hexMatch).slice(1);
6158
6482
 
6159
- return [].concat(_toConsumableArray(_t2.slice(0, 3).map(function (t) {
6160
- return parseInt(t, 16);
6161
- })), [parseInt(_t2[3] || "ff", 16) / 255]);
6483
+ return [].concat(_toConsumableArray(_arr.slice(0, 3).map(function (x) {
6484
+ return parseInt(x, 16);
6485
+ })), [parseInt(_arr[3] || 'ff', 16) / 255]);
6162
6486
  }
6163
6487
 
6164
- var z = a.exec(e);
6488
+ var rgbaMatch = rgbaRegex.exec(normalizedColor);
6165
6489
 
6166
- if (z) {
6167
- var _t3 = Array.from(z).slice(1);
6490
+ if (rgbaMatch) {
6491
+ var _arr2 = Array.from(rgbaMatch).slice(1);
6168
6492
 
6169
- return [].concat(_toConsumableArray(_t3.slice(0, 3).map(function (t) {
6170
- return parseInt(t, 10);
6171
- })), [parseFloat(_t3[3] || "1")]);
6493
+ return [].concat(_toConsumableArray(_arr2.slice(0, 3).map(function (x) {
6494
+ return parseInt(x, 10);
6495
+ })), [parseFloat(_arr2[3] || '1')]);
6172
6496
  }
6173
6497
 
6174
- var h = c.exec(e);
6498
+ var hslaMatch = hslaRegex.exec(normalizedColor);
6175
6499
 
6176
- if (h) {
6177
- var _Array$from$slice$map = Array.from(h).slice(1).map(parseFloat),
6500
+ if (hslaMatch) {
6501
+ var _Array$from$slice$map = Array.from(hslaMatch).slice(1).map(parseFloat),
6178
6502
  _Array$from$slice$map2 = _slicedToArray(_Array$from$slice$map, 4),
6179
- _e = _Array$from$slice$map2[0],
6180
- _o = _Array$from$slice$map2[1],
6181
- _2 = _Array$from$slice$map2[2],
6182
- _s = _Array$from$slice$map2[3];
6183
-
6184
- if (t(0, 100, _o) !== _o) throw new n(r);
6185
- if (t(0, 100, _2) !== _2) throw new n(r);
6186
- return [].concat(_toConsumableArray(l(_e, _o, _2)), [_s || 1]);
6503
+ h = _Array$from$slice$map2[0],
6504
+ s = _Array$from$slice$map2[1],
6505
+ l = _Array$from$slice$map2[2],
6506
+ a = _Array$from$slice$map2[3];
6507
+
6508
+ if (guard(0, 100, s) !== s) throw new ColorError$1(color);
6509
+ if (guard(0, 100, l) !== l) throw new ColorError$1(color);
6510
+ return [].concat(_toConsumableArray(hslToRgb(h, s, l)), [a || 1]);
6187
6511
  }
6188
6512
 
6189
- throw new n(r);
6513
+ throw new ColorError$1(color);
6190
6514
  }
6191
6515
 
6192
- var e = function e(t) {
6193
- return parseInt(t.replace(/_/g, ""), 36);
6194
- },
6195
- o = "1q29ehhb 1n09sgk7 1kl1ekf_ _yl4zsno 16z9eiv3 1p29lhp8 _bd9zg04 17u0____ _iw9zhe5 _to73___ _r45e31e _7l6g016 _jh8ouiv _zn3qba8 1jy4zshs 11u87k0u 1ro9yvyo 1aj3xael 1gz9zjz0 _3w8l4xo 1bf1ekf_ _ke3v___ _4rrkb__ 13j776yz _646mbhl _nrjr4__ _le6mbhl 1n37ehkb _m75f91n _qj3bzfz 1939yygw 11i5z6x8 _1k5f8xs 1509441m 15t5lwgf _ae2th1n _tg1ugcv 1lp1ugcv 16e14up_ _h55rw7n _ny9yavn _7a11xb_ 1ih442g9 _pv442g9 1mv16xof 14e6y7tu 1oo9zkds 17d1cisi _4v9y70f _y98m8kc 1019pq0v 12o9zda8 _348j4f4 1et50i2o _8epa8__ _ts6senj 1o350i2o 1mi9eiuo 1259yrp0 1ln80gnw _632xcoy 1cn9zldc _f29edu4 1n490c8q _9f9ziet 1b94vk74 _m49zkct 1kz6s73a 1eu9dtog _q58s1rz 1dy9sjiq __u89jo3 _aj5nkwg _ld89jo3 13h9z6wx _qa9z2ii _l119xgq _bs5arju 1hj4nwk9 1qt4nwk9 1ge6wau6 14j9zlcw 11p1edc_ _ms1zcxe _439shk6 _jt9y70f _754zsow 1la40eju _oq5p___ _x279qkz 1fa5r3rv _yd2d9ip _424tcku _8y1di2_ _zi2uabw _yy7rn9h 12yz980_ __39ljp6 1b59zg0x _n39zfzp 1fy9zest _b33k___ _hp9wq92 1il50hz4 _io472ub _lj9z3eo 19z9ykg0 _8t8iu3a 12b9bl4a 1ak5yw0o _896v4ku _tb8k8lv _s59zi6t _c09ze0p 1lg80oqn 1id9z8wb _238nba5 1kq6wgdi _154zssg _tn3zk49 _da9y6tc 1sg7cv4f _r12jvtt 1gq5fmkz 1cs9rvci _lp9jn1c _xw1tdnb 13f9zje6 16f6973h _vo7ir40 _bt5arjf _rc45e4t _hr4e100 10v4e100 _hc9zke2 _w91egv_ _sj2r1kk 13c87yx8 _vqpds__ _ni8ggk8 _tj9yqfb 1ia2j4r4 _7x9b10u 1fc9ld4j 1eq9zldr _5j9lhpx _ez9zl6o _md61fzm".split(" ").reduce(function (t, n) {
6196
- var r = e(n.substring(0, 3)),
6197
- o = e(n.substring(3)).toString(16);
6198
- var _ = "";
6516
+ function hash(str) {
6517
+ var hash = 5381;
6518
+ var i = str.length;
6199
6519
 
6200
- for (var _t4 = 0; _t4 < 6 - o.length; _t4++) {
6201
- _ += "0";
6520
+ while (i) {
6521
+ hash = hash * 33 ^ str.charCodeAt(--i);
6202
6522
  }
6523
+ /* JavaScript does bitwise operations (like XOR, above) on 32-bit signed
6524
+ * integers. Since we want the results to be always positive, convert the
6525
+ * signed int to an unsigned by doing an unsigned bitshift. */
6526
+
6527
+
6528
+ return (hash >>> 0) % 2341;
6529
+ }
6203
6530
 
6204
- return t[r] = "".concat(_).concat(o), t;
6205
- }, {}),
6206
- _ = function _(t, n) {
6207
- return Array.from(Array(n)).map(function () {
6208
- return t;
6209
- }).join("");
6210
- },
6211
- s = new RegExp("^#".concat(_("([a-f0-9])", 3), "([a-f0-9])?$"), "i"),
6212
- i = new RegExp("^#".concat(_("([a-f0-9]{2})", 3), "([a-f0-9]{2})?$"), "i"),
6213
- a = new RegExp("^rgba?\\(\\s*(\\d+)\\s*".concat(_(",\\s*(\\d+)\\s*", 2), "(?:,\\s*([\\d.]+))?\\s*\\)$"), "i"),
6214
- c = /^hsla?\(\s*([\d.]+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%(?:\s*,\s*([\d.]+))?\s*\)$/i,
6215
- u = /^[a-z]+$/i,
6216
- f = function f(t) {
6217
- return Math.round(255 * t);
6218
- },
6219
- l = function l(t, n, r) {
6220
- var e = r / 100;
6221
- if (0 === n) return [e, e, e].map(f);
6222
-
6223
- var o = (t % 360 + 360) % 360 / 60,
6224
- _ = (1 - Math.abs(2 * e - 1)) * (n / 100),
6225
- s = _ * (1 - Math.abs(o % 2 - 1));
6226
-
6227
- var i = 0,
6228
- a = 0,
6229
- c = 0;
6230
- o >= 0 && o < 1 ? (i = _, a = s) : o >= 1 && o < 2 ? (i = s, a = _) : o >= 2 && o < 3 ? (a = _, c = s) : o >= 3 && o < 4 ? (a = s, c = _) : o >= 4 && o < 5 ? (i = s, c = _) : o >= 5 && o < 6 && (i = _, c = s);
6231
- var u = e - _ / 2;
6232
- return [i + u, a + u, c + u].map(f);
6531
+ var colorToInt = function colorToInt(x) {
6532
+ return parseInt(x.replace(/_/g, ''), 36);
6233
6533
  };
6234
6534
 
6235
- function w(t) {
6236
- if ("transparent" === t) return 0;
6535
+ var compressedColorMap = '1q29ehhb 1n09sgk7 1kl1ekf_ _yl4zsno 16z9eiv3 1p29lhp8 _bd9zg04 17u0____ _iw9zhe5 _to73___ _r45e31e _7l6g016 _jh8ouiv _zn3qba8 1jy4zshs 11u87k0u 1ro9yvyo 1aj3xael 1gz9zjz0 _3w8l4xo 1bf1ekf_ _ke3v___ _4rrkb__ 13j776yz _646mbhl _nrjr4__ _le6mbhl 1n37ehkb _m75f91n _qj3bzfz 1939yygw 11i5z6x8 _1k5f8xs 1509441m 15t5lwgf _ae2th1n _tg1ugcv 1lp1ugcv 16e14up_ _h55rw7n _ny9yavn _7a11xb_ 1ih442g9 _pv442g9 1mv16xof 14e6y7tu 1oo9zkds 17d1cisi _4v9y70f _y98m8kc 1019pq0v 12o9zda8 _348j4f4 1et50i2o _8epa8__ _ts6senj 1o350i2o 1mi9eiuo 1259yrp0 1ln80gnw _632xcoy 1cn9zldc _f29edu4 1n490c8q _9f9ziet 1b94vk74 _m49zkct 1kz6s73a 1eu9dtog _q58s1rz 1dy9sjiq __u89jo3 _aj5nkwg _ld89jo3 13h9z6wx _qa9z2ii _l119xgq _bs5arju 1hj4nwk9 1qt4nwk9 1ge6wau6 14j9zlcw 11p1edc_ _ms1zcxe _439shk6 _jt9y70f _754zsow 1la40eju _oq5p___ _x279qkz 1fa5r3rv _yd2d9ip _424tcku _8y1di2_ _zi2uabw _yy7rn9h 12yz980_ __39ljp6 1b59zg0x _n39zfzp 1fy9zest _b33k___ _hp9wq92 1il50hz4 _io472ub _lj9z3eo 19z9ykg0 _8t8iu3a 12b9bl4a 1ak5yw0o _896v4ku _tb8k8lv _s59zi6t _c09ze0p 1lg80oqn 1id9z8wb _238nba5 1kq6wgdi _154zssg _tn3zk49 _da9y6tc 1sg7cv4f _r12jvtt 1gq5fmkz 1cs9rvci _lp9jn1c _xw1tdnb 13f9zje6 16f6973h _vo7ir40 _bt5arjf _rc45e4t _hr4e100 10v4e100 _hc9zke2 _w91egv_ _sj2r1kk 13c87yx8 _vqpds__ _ni8ggk8 _tj9yqfb 1ia2j4r4 _7x9b10u 1fc9ld4j 1eq9zldr _5j9lhpx _ez9zl6o _md61fzm'.split(' ').reduce(function (acc, next) {
6536
+ var key = colorToInt(next.substring(0, 3));
6537
+ var hex = colorToInt(next.substring(3)).toString(16); // NOTE: padStart could be used here but it breaks Node 6 compat
6538
+ // https://github.com/ricokahler/color2k/issues/351
6237
6539
 
6238
- function n(t) {
6239
- var n = t / 255;
6240
- return n <= .03928 ? n / 12.92 : Math.pow((n + .055) / 1.055, 2.4);
6540
+ var prefix = '';
6541
+
6542
+ for (var i = 0; i < 6 - hex.length; i++) {
6543
+ prefix += '0';
6241
6544
  }
6242
6545
 
6243
- var _r = r(t),
6244
- _r2 = _slicedToArray(_r, 3),
6245
- e = _r2[0],
6246
- o = _r2[1],
6247
- _ = _r2[2];
6546
+ acc[key] = "".concat(prefix).concat(hex);
6547
+ return acc;
6548
+ }, {});
6549
+ /**
6550
+ * Checks if a string is a CSS named color and returns its equivalent hex value, otherwise returns the original color.
6551
+ */
6248
6552
 
6249
- return .2126 * n(e) + .7152 * n(o) + .0722 * n(_);
6553
+ function nameToHex(color) {
6554
+ var normalizedColorName = color.toLowerCase().trim();
6555
+ var result = compressedColorMap[hash(normalizedColorName)];
6556
+ if (!result) throw new ColorError$1(color);
6557
+ return "#".concat(result);
6250
6558
  }
6251
6559
 
6252
- function F(t) {
6253
- return w(t) > .179;
6560
+ var r = function r(str, amount) {
6561
+ return Array.from(Array(amount)).map(function () {
6562
+ return str;
6563
+ }).join('');
6564
+ };
6565
+
6566
+ var reducedHexRegex = new RegExp("^#".concat(r('([a-f0-9])', 3), "([a-f0-9])?$"), 'i');
6567
+ var hexRegex = new RegExp("^#".concat(r('([a-f0-9]{2})', 3), "([a-f0-9]{2})?$"), 'i');
6568
+ var rgbaRegex = new RegExp("^rgba?\\(\\s*(\\d+)\\s*".concat(r(',\\s*(\\d+)\\s*', 2), "(?:,\\s*([\\d.]+))?\\s*\\)$"), 'i');
6569
+ var hslaRegex = /^hsla?\(\s*([\d.]+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%(?:\s*,\s*([\d.]+))?\s*\)$/i;
6570
+ var namedColorRegex = /^[a-z]+$/i;
6571
+
6572
+ var roundColor = function roundColor(color) {
6573
+ return Math.round(color * 255);
6574
+ };
6575
+
6576
+ var hslToRgb = function hslToRgb(hue, saturation, lightness) {
6577
+ var l = lightness / 100;
6578
+
6579
+ if (saturation === 0) {
6580
+ // achromatic
6581
+ return [l, l, l].map(roundColor);
6582
+ } // formulae from https://en.wikipedia.org/wiki/HSL_and_HSV
6583
+
6584
+
6585
+ var huePrime = (hue % 360 + 360) % 360 / 60;
6586
+ var chroma = (1 - Math.abs(2 * l - 1)) * (saturation / 100);
6587
+ var secondComponent = chroma * (1 - Math.abs(huePrime % 2 - 1));
6588
+ var red = 0;
6589
+ var green = 0;
6590
+ var blue = 0;
6591
+
6592
+ if (huePrime >= 0 && huePrime < 1) {
6593
+ red = chroma;
6594
+ green = secondComponent;
6595
+ } else if (huePrime >= 1 && huePrime < 2) {
6596
+ red = secondComponent;
6597
+ green = chroma;
6598
+ } else if (huePrime >= 2 && huePrime < 3) {
6599
+ green = chroma;
6600
+ blue = secondComponent;
6601
+ } else if (huePrime >= 3 && huePrime < 4) {
6602
+ green = secondComponent;
6603
+ blue = chroma;
6604
+ } else if (huePrime >= 4 && huePrime < 5) {
6605
+ red = secondComponent;
6606
+ blue = chroma;
6607
+ } else if (huePrime >= 5 && huePrime < 6) {
6608
+ red = chroma;
6609
+ blue = secondComponent;
6610
+ }
6611
+
6612
+ var lightnessModification = l - chroma / 2;
6613
+ var finalRed = red + lightnessModification;
6614
+ var finalGreen = green + lightnessModification;
6615
+ var finalBlue = blue + lightnessModification;
6616
+ return [finalRed, finalGreen, finalBlue].map(roundColor);
6617
+ }; // taken from:
6618
+
6619
+ /**
6620
+ * Returns a number (float) representing the luminance of a color.
6621
+ */
6622
+
6623
+
6624
+ function getLuminance(color) {
6625
+ if (color === 'transparent') return 0;
6626
+
6627
+ function f(x) {
6628
+ var channel = x / 255;
6629
+ return channel <= 0.03928 ? channel / 12.92 : Math.pow((channel + 0.055) / 1.055, 2.4);
6630
+ }
6631
+
6632
+ var _parseToRgba = parseToRgba(color),
6633
+ _parseToRgba2 = _slicedToArray(_parseToRgba, 3),
6634
+ r = _parseToRgba2[0],
6635
+ g = _parseToRgba2[1],
6636
+ b = _parseToRgba2[2];
6637
+
6638
+ return 0.2126 * f(r) + 0.7152 * f(g) + 0.0722 * f(b);
6639
+ } // taken from:
6640
+ /**
6641
+ * An alternative function to `readableColor`. Returns whether or not the
6642
+ * readable color (i.e. the color to be place on top the input color) should be
6643
+ * black.
6644
+ */
6645
+
6646
+
6647
+ function readableColorIsBlack(color) {
6648
+ return getLuminance(color) > 0.179;
6254
6649
  }
6255
6650
 
6256
6651
  var _excluded$1 = ["pos"];
@@ -6271,7 +6666,7 @@ var Cursor = function Cursor(_ref3) {
6271
6666
  _ref3$size = _ref3.size,
6272
6667
  size = _ref3$size === void 0 ? 40 : _ref3$size,
6273
6668
  text = _ref3.text;
6274
- var textColor = F(color) ? "#222" : "#EEE";
6669
+ var textColor = readableColorIsBlack(color) ? "#222" : "#EEE";
6275
6670
  return /*#__PURE__*/React__default['default'].createElement(StyledCursor, null, /*#__PURE__*/React__default['default'].createElement("svg", {
6276
6671
  version: "1.1",
6277
6672
  id: "Layer_1",
@@ -6974,8 +7369,8 @@ var BoundingBox = function BoundingBox() {
6974
7369
  return /*#__PURE__*/React__default['default'].createElement("div", {
6975
7370
  style: _objectSpread2(_objectSpread2({}, defaultZoneStyle), {}, {
6976
7371
  transform: "translate(".concat(boundingBoxLast.left, "px, ").concat(boundingBoxLast.top, "px)"),
6977
- height: "".concat(boundingBoxLast.height - 2, "px"),
6978
- width: "".concat(boundingBoxLast.width - 2, "px")
7372
+ height: "".concat(boundingBoxLast.height, "px"),
7373
+ width: "".concat(boundingBoxLast.width, "px")
6979
7374
  }),
6980
7375
  className: "selection"
6981
7376
  });
@@ -6999,7 +7394,9 @@ var Board = function Board(_ref) {
6999
7394
  itemTemplates = _ref$itemTemplates === void 0 ? {} : _ref$itemTemplates,
7000
7395
  _ref$boardSize = _ref.boardSize,
7001
7396
  boardSize = _ref$boardSize === void 0 ? DEFAULT_BOARD_MAX_SIZE : _ref$boardSize,
7002
- children = _ref.children;
7397
+ children = _ref.children,
7398
+ _ref$showResizeHandle = _ref.showResizeHandle,
7399
+ showResizeHandle = _ref$showResizeHandle === void 0 ? false : _ref$showResizeHandle;
7003
7400
  var setConfiguration = recoil.useSetRecoilState(ConfigurationAtom);
7004
7401
 
7005
7402
  var _useDim = useDim(),
@@ -7017,10 +7414,11 @@ var Board = function Board(_ref) {
7017
7414
  setConfiguration(function (prev) {
7018
7415
  return _objectSpread2(_objectSpread2({}, prev), {}, {
7019
7416
  itemTemplates: itemTemplates,
7020
- boardSize: boardSize
7417
+ boardSize: boardSize,
7418
+ showResizeHandle: showResizeHandle
7021
7419
  });
7022
7420
  });
7023
- }, [itemTemplates, setConfiguration, boardSize]);
7421
+ }, [itemTemplates, setConfiguration, boardSize, showResizeHandle]);
7024
7422
  React__default['default'].useEffect(function () {
7025
7423
  updateItemExtent();
7026
7424
  setTimeout(updateItemExtent, 2000);
@@ -7035,9 +7433,7 @@ var Board = function Board(_ref) {
7035
7433
  },
7036
7434
  style: boardStyle,
7037
7435
  className: "board"
7038
- }, /*#__PURE__*/React__default['default'].createElement(ItemList, {
7039
- itemTemplates: itemTemplates
7040
- }), children))))), /*#__PURE__*/React__default['default'].createElement(Selection, null));
7436
+ }, /*#__PURE__*/React__default['default'].createElement(ItemList, null), children))))), /*#__PURE__*/React__default['default'].createElement(Selection, null));
7041
7437
  };
7042
7438
 
7043
7439
  var TOLERANCE = 100;
@@ -8345,8 +8741,10 @@ var getActionsFromItem = function getActionsFromItem(item, itemMap) {
8345
8741
  };
8346
8742
 
8347
8743
  var useAvailableActions = function useAvailableActions() {
8744
+ var itemMap = recoil.useRecoilValue(ItemMapAtom);
8745
+
8348
8746
  var _useRecoilValue = recoil.useRecoilValue(ConfigurationAtom),
8349
- itemMap = _useRecoilValue.itemTemplates;
8747
+ itemTemplates = _useRecoilValue.itemTemplates;
8350
8748
 
8351
8749
  var selected = recoil.useRecoilValue(SelectedItemsAtom);
8352
8750
 
@@ -8356,6 +8754,13 @@ var useAvailableActions = function useAvailableActions() {
8356
8754
  setAvailableActions = _React$useState2[1];
8357
8755
 
8358
8756
  var isMountedRef = React__default['default'].useRef(false);
8757
+ React__default['default'].useEffect(function () {
8758
+ // Mounted guard
8759
+ isMountedRef.current = true;
8760
+ return function () {
8761
+ isMountedRef.current = false;
8762
+ };
8763
+ }, []);
8359
8764
  var getItemListOrSelected = recoil.useRecoilCallback(function (_ref) {
8360
8765
  var snapshot = _ref.snapshot;
8361
8766
  return /*#__PURE__*/function () {
@@ -8403,19 +8808,12 @@ var useAvailableActions = function useAvailableActions() {
8403
8808
  };
8404
8809
  }();
8405
8810
  }, []);
8406
- React__default['default'].useEffect(function () {
8407
- // Mounted guard
8408
- isMountedRef.current = true;
8409
- return function () {
8410
- isMountedRef.current = false;
8411
- };
8412
- }, []);
8413
8811
  /**
8414
8812
  * Returns available actions for selected items. An action is kept only if all
8415
8813
  * items have this exact same action with same parameters.
8416
8814
  */
8417
8815
 
8418
- var updateAvailableActions = React__default['default'].useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
8816
+ var updateAvailableActions = React.useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
8419
8817
  var _yield$getItemListOrS, _yield$getItemListOrS2, selectedItemIds, selectedItemList, allActions;
8420
8818
 
8421
8819
  return regeneratorRuntime.wrap(function _callee2$(_context2) {
@@ -8445,13 +8843,13 @@ var useAvailableActions = function useAvailableActions() {
8445
8843
 
8446
8844
  case 9:
8447
8845
  allActions = selectedItemList.reduce(function (acc, item) {
8448
- var itemActions = getActionsFromItem(item, itemMap);
8846
+ var itemActions = getActionsFromItem(item, itemTemplates);
8449
8847
  return acc.filter(function (value) {
8450
8848
  return itemActions.some(function (itemAction) {
8451
8849
  return es6(value, itemAction);
8452
8850
  });
8453
8851
  });
8454
- }, getActionsFromItem(selectedItemList[0], itemMap));
8852
+ }, getActionsFromItem(selectedItemList[0], itemTemplates));
8455
8853
  setAvailableActions(allActions);
8456
8854
  _context2.next = 14;
8457
8855
  break;
@@ -8465,11 +8863,11 @@ var useAvailableActions = function useAvailableActions() {
8465
8863
  }
8466
8864
  }
8467
8865
  }, _callee2);
8468
- })), [getItemListOrSelected, itemMap]); // Update available actions when selection change
8866
+ })), [getItemListOrSelected, itemTemplates]); // Update available actions when selection change
8469
8867
 
8470
- React__default['default'].useEffect(function () {
8471
- updateAvailableActions();
8472
- }, [updateAvailableActions, selected]);
8868
+ React__default['default'].useEffect(updateAvailableActions, [updateAvailableActions, selected]); // Debounced update available actions when items change
8869
+
8870
+ useDebouncedEffect(updateAvailableActions, [itemMap, updateAvailableActions], 300);
8473
8871
  return {
8474
8872
  availableActions: availableActions
8475
8873
  };
@@ -8588,22 +8986,29 @@ var dayjs_min = {exports: {}};
8588
8986
  return void 0 === t;
8589
8987
  }
8590
8988
  },
8591
- D = "en",
8592
- v = {};
8989
+ v = "en",
8990
+ D = {};
8593
8991
 
8594
- v[D] = M;
8992
+ D[v] = M;
8595
8993
 
8596
8994
  var p = function p(t) {
8597
8995
  return t instanceof _;
8598
8996
  },
8599
- S = function S(t, e, n) {
8600
- var r;
8601
- if (!t) return D;
8602
- if ("string" == typeof t) v[t] && (r = t), e && (v[t] = e, r = t);else {
8603
- var i = t.name;
8604
- v[i] = t, r = i;
8997
+ S = function t(e, n, r) {
8998
+ var i;
8999
+ if (!e) return v;
9000
+
9001
+ if ("string" == typeof e) {
9002
+ var s = e.toLowerCase();
9003
+ D[s] && (i = s), n && (D[s] = n, i = s);
9004
+ var u = e.split("-");
9005
+ if (!i && u.length > 1) return t(u[0]);
9006
+ } else {
9007
+ var a = e.name;
9008
+ D[a] = e, i = a;
8605
9009
  }
8606
- return !n && r && (D = r), r || !n && D;
9010
+
9011
+ return !r && i && (v = i), i || !r && v;
8607
9012
  },
8608
9013
  w = function w(t, e) {
8609
9014
  if (p(t)) return t.clone();
@@ -8691,9 +9096,9 @@ var dayjs_min = {exports: {}};
8691
9096
  return r ? $(1, M) : $(0, M + 1);
8692
9097
 
8693
9098
  case o:
8694
- var D = this.$locale().weekStart || 0,
8695
- v = (y < D ? y + 7 : y) - D;
8696
- return $(r ? m - v : m + (6 - v), M);
9099
+ var v = this.$locale().weekStart || 0,
9100
+ D = (y < v ? y + 7 : y) - v;
9101
+ return $(r ? m - D : m + (6 - D), M);
8697
9102
 
8698
9103
  case a:
8699
9104
  case d:
@@ -8810,12 +9215,12 @@ var dayjs_min = {exports: {}};
8810
9215
  M = w(r),
8811
9216
  m = (M.utcOffset() - this.utcOffset()) * e,
8812
9217
  g = this - M,
8813
- D = O.m(this, M);
8814
- return D = (l = {}, l[c] = D / 12, l[f] = D, l[h] = D / 3, l[o] = (g - m) / 6048e5, l[a] = (g - m) / 864e5, l[u] = g / n, l[s] = g / e, l[i] = g / t, l)[y] || g, $ ? D : O.a(D);
9218
+ v = O.m(this, M);
9219
+ return v = (l = {}, l[c] = v / 12, l[f] = v, l[h] = v / 3, l[o] = (g - m) / 6048e5, l[a] = (g - m) / 864e5, l[u] = g / n, l[s] = g / e, l[i] = g / t, l)[y] || g, $ ? v : O.a(v);
8815
9220
  }, m.daysInMonth = function () {
8816
9221
  return this.endOf(f).$D;
8817
9222
  }, m.$locale = function () {
8818
- return v[this.$L];
9223
+ return D[this.$L];
8819
9224
  }, m.locale = function (t, e) {
8820
9225
  if (!t) return this.$L;
8821
9226
  var n = this.clone(),
@@ -8843,7 +9248,7 @@ var dayjs_min = {exports: {}};
8843
9248
  return t.$i || (t(e, _, w), t.$i = !0), w;
8844
9249
  }, w.locale = S, w.isDayjs = p, w.unix = function (t) {
8845
9250
  return w(1e3 * t);
8846
- }, w.en = v[D], w.Ls = v, w.p = {}, w;
9251
+ }, w.en = D[v], w.Ls = D, w.p = {}, w;
8847
9252
  });
8848
9253
  })(dayjs_min);
8849
9254
 
@@ -9047,7 +9452,11 @@ var SyncBoard = function SyncBoard(_ref) {
9047
9452
  });
9048
9453
  }, [setConfiguration, uid]);
9049
9454
  useResizeObserver(boardWrapperRef, function () {
9050
- return setConfiguration(function (prev) {
9455
+ if (!boardWrapperRef.current) {
9456
+ return;
9457
+ }
9458
+
9459
+ setConfiguration(function (prev) {
9051
9460
  return _objectSpread2(_objectSpread2({}, prev), {}, {
9052
9461
  boardWrapperRect: boardWrapperRef.current.getBoundingClientRect()
9053
9462
  });
@@ -9122,6 +9531,7 @@ exports.useAvailableActions = useAvailableActions;
9122
9531
  exports.useBoardConfig = useBoardConfig;
9123
9532
  exports.useBoardPosition = useDim;
9124
9533
  exports.useBoardState = useBoardState;
9534
+ exports.useDebouncedItems = useDebouncedItems;
9125
9535
  exports.useItemActions = useItemActions;
9126
9536
  exports.useItemInteraction = useItemInteraction;
9127
9537
  exports.useItems = useItemList;