Dashboard sipadu mbip
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ChildMapping.js 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. "use strict";
  2. exports.__esModule = true;
  3. exports.getChildMapping = getChildMapping;
  4. exports.mergeChildMappings = mergeChildMappings;
  5. exports.getInitialChildMapping = getInitialChildMapping;
  6. exports.getNextChildMapping = getNextChildMapping;
  7. var _react = require("react");
  8. /**
  9. * Given `this.props.children`, return an object mapping key to child.
  10. *
  11. * @param {*} children `this.props.children`
  12. * @return {object} Mapping of key to child
  13. */
  14. function getChildMapping(children, mapFn) {
  15. var mapper = function mapper(child) {
  16. return mapFn && (0, _react.isValidElement)(child) ? mapFn(child) : child;
  17. };
  18. var result = Object.create(null);
  19. if (children) _react.Children.map(children, function (c) {
  20. return c;
  21. }).forEach(function (child) {
  22. // run the map function here instead so that the key is the computed one
  23. result[child.key] = mapper(child);
  24. });
  25. return result;
  26. }
  27. /**
  28. * When you're adding or removing children some may be added or removed in the
  29. * same render pass. We want to show *both* since we want to simultaneously
  30. * animate elements in and out. This function takes a previous set of keys
  31. * and a new set of keys and merges them with its best guess of the correct
  32. * ordering. In the future we may expose some of the utilities in
  33. * ReactMultiChild to make this easy, but for now React itself does not
  34. * directly have this concept of the union of prevChildren and nextChildren
  35. * so we implement it here.
  36. *
  37. * @param {object} prev prev children as returned from
  38. * `ReactTransitionChildMapping.getChildMapping()`.
  39. * @param {object} next next children as returned from
  40. * `ReactTransitionChildMapping.getChildMapping()`.
  41. * @return {object} a key set that contains all keys in `prev` and all keys
  42. * in `next` in a reasonable order.
  43. */
  44. function mergeChildMappings(prev, next) {
  45. prev = prev || {};
  46. next = next || {};
  47. function getValueForKey(key) {
  48. return key in next ? next[key] : prev[key];
  49. } // For each key of `next`, the list of keys to insert before that key in
  50. // the combined list
  51. var nextKeysPending = Object.create(null);
  52. var pendingKeys = [];
  53. for (var prevKey in prev) {
  54. if (prevKey in next) {
  55. if (pendingKeys.length) {
  56. nextKeysPending[prevKey] = pendingKeys;
  57. pendingKeys = [];
  58. }
  59. } else {
  60. pendingKeys.push(prevKey);
  61. }
  62. }
  63. var i;
  64. var childMapping = {};
  65. for (var nextKey in next) {
  66. if (nextKeysPending[nextKey]) {
  67. for (i = 0; i < nextKeysPending[nextKey].length; i++) {
  68. var pendingNextKey = nextKeysPending[nextKey][i];
  69. childMapping[nextKeysPending[nextKey][i]] = getValueForKey(pendingNextKey);
  70. }
  71. }
  72. childMapping[nextKey] = getValueForKey(nextKey);
  73. } // Finally, add the keys which didn't appear before any key in `next`
  74. for (i = 0; i < pendingKeys.length; i++) {
  75. childMapping[pendingKeys[i]] = getValueForKey(pendingKeys[i]);
  76. }
  77. return childMapping;
  78. }
  79. function getProp(child, prop, props) {
  80. return props[prop] != null ? props[prop] : child.props[prop];
  81. }
  82. function getInitialChildMapping(props, onExited) {
  83. return getChildMapping(props.children, function (child) {
  84. return (0, _react.cloneElement)(child, {
  85. onExited: onExited.bind(null, child),
  86. in: true,
  87. appear: getProp(child, 'appear', props),
  88. enter: getProp(child, 'enter', props),
  89. exit: getProp(child, 'exit', props)
  90. });
  91. });
  92. }
  93. function getNextChildMapping(nextProps, prevChildMapping, onExited) {
  94. var nextChildMapping = getChildMapping(nextProps.children);
  95. var children = mergeChildMappings(prevChildMapping, nextChildMapping);
  96. Object.keys(children).forEach(function (key) {
  97. var child = children[key];
  98. if (!(0, _react.isValidElement)(child)) return;
  99. var hasPrev = key in prevChildMapping;
  100. var hasNext = key in nextChildMapping;
  101. var prevChild = prevChildMapping[key];
  102. var isLeaving = (0, _react.isValidElement)(prevChild) && !prevChild.props.in; // item is new (entering)
  103. if (hasNext && (!hasPrev || isLeaving)) {
  104. // console.log('entering', key)
  105. children[key] = (0, _react.cloneElement)(child, {
  106. onExited: onExited.bind(null, child),
  107. in: true,
  108. exit: getProp(child, 'exit', nextProps),
  109. enter: getProp(child, 'enter', nextProps)
  110. });
  111. } else if (!hasNext && hasPrev && !isLeaving) {
  112. // item is old (exiting)
  113. // console.log('leaving', key)
  114. children[key] = (0, _react.cloneElement)(child, {
  115. in: false
  116. });
  117. } else if (hasNext && hasPrev && (0, _react.isValidElement)(prevChild)) {
  118. // item hasn't changed transition states
  119. // copy over the last transition props;
  120. // console.log('unchanged', key)
  121. children[key] = (0, _react.cloneElement)(child, {
  122. onExited: onExited.bind(null, child),
  123. in: prevChild.props.in,
  124. exit: getProp(child, 'exit', nextProps),
  125. enter: getProp(child, 'enter', nextProps)
  126. });
  127. }
  128. });
  129. return children;
  130. }