function CoupledParent (name) {
  // @vue/component
  return {
    provide: function provide() {
      var _this = this;

      var proxy = {};
      Object.defineProperty(proxy, 'activeChild', {
        get: function get() {
          return _this.activeChild;
        }
      });
      proxy.$_addCoupledChild = this.$_addCoupledChild.bind(this);
      proxy.$_removeCoupledChild = this.$_removeCoupledChild.bind(this);
      return _defineProperty({}, name, proxy);
    },
    props: {
      childIndex: {
        default: 0
      }
    },
    data: function data() {
      return {
        children: [],
        activeChildIndex: parseInt(this.childIndex) || 0
      };
    },
    computed: {
      activeChild: function activeChild() {
        if (this.activeChildIndex < this.children.length) {
          return this.children[this.activeChildIndex];
        }
      }
    },
    watch: {
      childIndex: function childIndex(val) {
        this.activateChild(parseInt(val) || 0, true);
      }
    },
    methods: {
      /**
       * Activates a child.
       * @param {number} index Index of child to activate
       * @param {boolean} external Indicates if the activation comes from an external source (like props)
       */
      activateChild: function activateChild(index) {
        var external = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
        var oldIndex = this.activeChildIndex;

        if (index < 0) {
          index = 0;
        } else if (index >= this.children.length) {
          index = this.children.length - 1;
        }

        this.activeChildIndex = index;
        this.$emit('update:childIndex', index);
        this.childActivated(index, oldIndex, external);
      },

      /**
       * Hook called when a child is activated.
       * @param {number} index Index of the activated child
       * @param {number} oldIndex Index of the previously activated child
       * @param {boolean} external Indicates if the activation comes from an external source (like props)
       */
      childActivated: function childActivated(index, oldIndex, external) {// Override this in component
      },

      /**
       * Add a child component while preserving its order in the children list.
       * @param {object} proxyVm Vue instance
       */
      $_addCoupledChild: function $_addCoupledChild(proxyVm) {
        var _this2 = this;

        // Guard
        if (this.$slots && this.$slots.default) {
          // We need to wait for the instances creation
          this.$nextTick(function () {
            // We need to get the components in the slot
            var childComponents = _this2.$slots.default.reduce(function (list, vnode) {
              var coupledChild = findCoupledChild(vnode);

              if (coupledChild) {
                list.push(coupledChild.$_couplingProxy);
              }

              return list;
            }, []); // List has the child component in the right order
            // We can now register the child component in the right place


            var index = childComponents.indexOf(proxyVm); // Add child

            if (index !== -1) {
              _this2.children.splice(index, 0, proxyVm); // Hook


              _this2.$_updateChildren('add', index, proxyVm);
            }
          });
        }
      },

      /**
       * Removes a child component. Automatically activates the next remaining component.
       * @param {object} proxyVm Vue instance
       */
      $_removeCoupledChild: function $_removeCoupledChild(proxyVm) {
        var index = this.children.indexOf(proxyVm); // Remove child

        if (index !== -1) {
          this.children.splice(index, 1);
        } // Hook


        this.$_updateChildren('remove', index, proxyVm);
      },

      /**
       * Hook called when an operation is processed. It will intelligently activate a child if needed.
       * @param {string} operation Name of the operation. Can be 'add' or 'remove'
       * @param {number} index Index of the related child.
       * @param {object} proxyVm Related child Vue instance
       */
      $_updateChildren: function $_updateChildren(operation, index, proxyVm) {
        if (operation === 'add') {
          // If the child was added before the currently active one,
          // we need to move the selection to the right
          if (index <= this.activeChildIndex) {
            this.activateChild(this.activeChildIndex + 1);
          } // Default when there is only one child


          if (this.children.length === 1) {
            this.activateChild(0);
          }
        } else if (operation === 'remove') {
          // If we remove a child before the currently active one,
          // we need to move the selection to the left
          if (index <= this.activeChildIndex) {
            this.activateChild(this.activeChildIndex - 1);
          }
        }
      }
    }
  };
}
(Use with the CoupledChild mixin)
Mixin allowing the automatic collection of children while preserving the virtual dom children order at all times.
Useful for creating tabs-style component, when we need to replicate the order of the children to display
a group of button (tab strip).
@param {string} name Name of the injection