import { n as normalizeComponent, u as use, r as registerComponent } from './normalize-component-63e8c7a0.js';
import './es.object.to-string-5a59fbfc.js';
import './es.regexp.to-string-784af81c.js';
import './es.symbol.description-3b56bced.js';
import { _ as _objectSpread2 } from './objectSpread2-605331b1.js';
import { _ as _slicedToArray, e as extractNestedPropertyValue } from './utils-21c04279.js';
import { _ as _toConsumableArray } from './toConsumableArray-fb122614.js';
import { _ as _typeof } from './typeof-6c6d8d7a.js';
import './es.array.includes-1f433385.js';
import './es.string.includes-53dbb113.js';
import './es.object.keys-6369b884.js';
import './es.number.constructor-16a232f3.js';
import './es.array.slice-e9c3dd03.js';
import './es.json.stringify-9b0e9796.js';
import './web.dom-collections.for-each-917714ef.js';
import { i as i18n } from './i18n-e25edebe.js';
import './web.dom-collections.iterator-5ecbd86d.js';
import './es.string.iterator-eb7ab984.js';
import './es.array.concat-9f3136dc.js';
import './es.array.map-093cfbca.js';
import './es.array.filter-9f634d7c.js';
import './regexp-exec-abstract-04d119fc.js';
import './es.string.replace-07eeebfe.js';
import './es.array.sort-92cbfa54.js';
import { n as navigateList } from './navigateList-3cf6631c.js';
import { B as BaseImageBox } from './BaseImageBox-0b824f00.js';
import './classof-b10e7604.js';
import './export-ecf4b1cb.js';
import './regexp-flags-b5fc4ddb.js';
import './array-species-create-afb281e6.js';
import './object-keys-a5d351f7.js';
import './set-to-string-tag-452fb9b0.js';
import './array-iteration-dec5536e.js';
import './function-bind-context-b3fabf77.js';
import './defineProperty-18999f8e.js';
import './unsupportedIterableToArray-577176bf.js';
import './es.array.join-6ca857ff.js';
import './array-method-is-strict-903f485b.js';
import './es.string.split-cd1f3afc.js';
import './is-regexp-5558fd03.js';
import './object-set-prototype-of-9853ad1a.js';
import './create-property-c00b5c27.js';
import './array-method-has-species-support-d96108b0.js';
import './dom-iterables-b6f5ef3b.js';
import './set-species-77dd094d.js';
import './string-multibyte-88926e02.js';
import './BaseBox-a4447dc8.js';
import './BaseIcon-d03b1fa2.js';
import './BaseImage-7306e391.js';
import './es.object.values-a2198dd7.js';
import 'lazysizes';

/**
 * A component to display rows of boxes with or without pagination
 */

var script = {
  name: 'BaseResultBoxSection',
  components: {
    BaseImageBox: BaseImageBox,
    BaseLoader: function BaseLoader() {
      return import('./BaseLoader-a5bfc4d9.js').then(function (m) {
        return m.default || m;
      });
    },
    BaseOptions: function BaseOptions() {
      return import('./BaseOptions-1269f245.js').then(function (m) {
        return m.default || m;
      });
    },
    BaseButton: function BaseButton() {
      return import('./BaseButton-44a621e1.js').then(function (m) {
        return m.default || m;
      });
    },
    BasePagination: function BasePagination() {
      return import('./BasePagination-52fceef8.js').then(function (m) {
        return m.default || m;
      });
    },
    BaseBoxButton: function BaseBoxButton() {
      return import('./BaseBoxButton-821f076c.js').then(function (m) {
        return m.default || m;
      });
    },
    BaseSelectOptions: function BaseSelectOptions() {
      return import('./BaseSelectOptions-ed2b39fa.js').then(function (m) {
        return m.default || m;
      });
    }
  },
  mixins: [i18n, navigateList],
  model: {
    prop: 'entryList',
    event: 'entries-changed'
  },
  props: {
    /**
     * @model
     *
     * actual entries list - if slot result-box is not used to use custom elements this
     * object array should have the following properties to be displayed
     * in a [BaseImageBox](#baseimagebox):<br>
     *    **id** {string} - a unique identifier<br>
     *    **title** {?string} - the title of the box<br>
     *    **subtext** {?string} - a subtitle<br>
     *    **description** {?string} - text displayed at the bottom of the box<br>
     *    **imageUrl** {?string} - url to display an image<br>
     *    **text** {?string[]} - an array with strings that will be
     *    displayed if no image is provided<br>
     *    <br>
     *    if a different schema is used please use the slot 'result-box' to create your own
     *    elements - only id and title should still be provided but can also
     *    be customized via `identifierPropertyName` and `titlePropertyName`
     */
    entryList: {
      type: Array,
      default: function _default() {
        return [];
      }
    },

    /**
     * if false the header row (title and options) will not be available<br>
     *   caveat: for draggable functionality this needs to be true
     */
    showHeader: {
      type: Boolean,
      default: true
    },

    /**
     * title of section<br>
     * it is recommended to also set the headerText even if slot is used for header
     * for accessibility reasons
     */
    headerText: {
      type: String,
      default: ''
    },

    /**
     * define if options should be shown
     */
    showOptions: {
      type: Boolean,
      default: true
    },

    /**
     * set text for the options button if showOptions is true<br>
     *   this needs to be an object with 'show' (displayed when options are hidden)
     *   and 'hide' (displayed when options are visible) attributes
     */
    optionsButtonText: {
      type: Object,
      default: function _default() {
        return {
          show: 'edit',
          hide: 'editReturn'
        };
      },
      validator: function validator(val) {
        return ['show', 'hide'].every(function (requiredProp) {
          return Object.keys(val).includes(requiredProp);
        });
      }
    },
    optionsButtonIcon: {
      type: Object,
      default: function _default() {
        return {
          show: 'edit',
          hide: 'remove'
        };
      },
      validator: function validator(val) {
        return ['show', 'hide'].every(function (requiredProp) {
          return Object.keys(val).includes(requiredProp);
        });
      }
    },

    /**
     * specify how many boxes should be displayed in a row in an array
     * with "tupples" (array with min-size and number of boxes)
     * depending on the size of the container (not screen width - unless
     * `calcBoxNumberRelativeToWindow` is set to true)
     * like the following:<br>
     *   <code>
     *   [<br>
     *     \[0, [number of boxes]],<br>
     *     \[[min px size for this number of boxes\], [number]],<br>
     *     ...<br>
     *   ]
     *   </code>
     */
    boxBreakpoints: {
      type: Array,
      default: function _default() {
        return [[0, 2], [640, 4], [1024, 6]];
      },
      validator: function validator(val) {
        return val.every(function (point) {
          return _typeof(point) === 'object' && point.length === 2 && point.every(function (pointValue) {
            return typeof pointValue === 'number';
          });
        });
      }
    },

    /**
     * set component loader active
     */
    isLoading: {
      type: Boolean,
      default: false
    },

    /**
     * flag if component should be in edit mode (dragging, deleting,
     * other custom options visible)<br>
     *   the [.sync modifier](https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier) may be used on the corresponding prop
     */
    editMode: {
      type: Boolean,
      default: false
    },

    /**
     * set this variable true if background-color should be white in editMode
     */
    editModeWhiteBackground: {
      type: Boolean,
      default: false
    },

    /**
     * provide a list of selected entries for select options (can
     * be entry objects or entry ids)<br>
     *  the [.sync modifier](https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier) may be used on the corresponding prop
      */
    selectedList: {
      type: Array,
      default: function _default() {
        return [];
      }
    },

    /**
     * set a text for 'x entries selected' and 'select all / none'<br>
     */
    selectOptionsText: {
      type: Object,
      default: function _default() {
        return {
          selectAll: 'select all',
          selectNone: 'select none',
          entriesSelected: 'entries selected'
        };
      }
    },

    /**
     * if slot (options-message-area) is not used this variable
     * can be used to customize message text<br>
     *   this should be a string or an object with the actions needed (default: 'delete',
     *   if 'draggable' is true than also a 'drag' text is needed)<br>
     *     in case of a string the same text is used for all actions
     */
    messageText: {
      type: String,
      default: 'Drag or Select'
    },

    /**
     * if slot (options-message-area) is not used this variable
     * can be used to customize message subtext<br>
     *   this should be a string or an object with the actions needed (default: 'delete',
     *   if 'draggable' is true than also a 'drag' text is needed)<br>
     *     in case of a string the same text is used for all actions
     */
    messageSubtext: {
      type: String,
      default: 'Drag\'n Drop to reorder or select the relevant items and choose an action'
    },

    /**
     * determine if boxes can be dragged<br>
     *   (only applicable if `showHeader` and `showOptions` is set to `true`)
     */
    draggable: {
      type: Boolean,
      default: false
    },

    /**
     * set true if pagination should be used
     */
    usePagination: {
      type: Boolean,
      default: false
    },

    /**
     * if 'usePagination' is set true this will determine the number of
     * rows shown on one page<br>
     *   (only applicable if `usePagination` is set `true`)
     */
    maxRows: {
      type: Number,
      default: 5
    },

    /**
     * set this true if only a limited number of boxes should be shown
     * and rest can be displayed by clicking a "show more" button
     */
    useExpandMode: {
      type: Boolean,
      default: false
    },

    /**
     * in 'expand mode' set the state of 'show more' from outside<br>
     *   the [.sync modifier](https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier) may be used on this prop
     */
    expanded: {
      type: Boolean,
      default: false
    },

    /**
     * Provide text that should be shown within the button with the
     * expand / collapse functionality<br>
     *   should be an object with props `expand` for text to expand
     *   and `collapse` for text to collapse
     */
    expandText: {
      type: Object,
      default: function _default() {
        return {
          expand: 'more objects',
          collapse: 'collapse'
        };
      }
    },

    /**
     * add a number of total elements (needed for expandMode and
     * pagination
     */
    total: {
      type: Number,
      default: null
    },

    /**
     * add a number of total elements (needed for expandMode and
     * pagination<br>
     *   the [.sync modifier](https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier) may be used on this prop
     */
    currentPageNumber: {
      type: Number,
      default: null
    },

    /**
     * how many rows should be shown with show more button (expandMode)<br>
     *   (only applicable with `useExpandMode true`)
     */
    maxShowMoreRows: {
      type: Number,
      default: 1
    },

    /**
     * define if the section should scroll to top on page change<br>
     *   (only applicable with `usePagination true`)
     */
    jumpToTop: {
      type: Boolean,
      default: false
    },

    /**
     * define if the big button box at the end of all attached items should be shown
     */
    showActionButtonBoxes: {
      type: Boolean,
      default: false
    },

    /**
     * set some config for each action used<br>
     *   **text** {string} - the text displayed in the button<br>
     *   **icon** {string} - the icon name to display
     *    (for available icons see [BaseIcon](#baseicon) )<br>
     *   **value** {string} - the value emitted on button click<br>
     *   **[display='all']** {string} - define where the action should be displayed:<br>
     *     top: only in top row<br>
     *     bottom: only in action button box at bottom of list<br>
     *     all: on top as well as bottom<br>
     *   **disabled** {boolean} - disable button
     */
    actionButtonsConfig: {
      type: Array,
      default: function _default() {
        return [{
          text: 'delete',
          icon: 'waste-bin',
          value: 'delete',
          display: 'all',
          disabled: false
        }];
      },
      validator: function validator(val) {
        return val.every(function (action) {
          var requiredProps = ['text', 'icon', 'value'];
          var actionProps = Object.keys(action);
          return requiredProps.every(function (prop) {
            return actionProps.includes(prop);
          }) && (['all', 'top', 'bottom'].includes(action.display) || !action.display);
        });
      }
    },

    /**
     * define a custom identifier property name for objects in your
     * entryList array<br>
     *   if relevant property is contained in a nested object the string can
     *   be in dot notation. e.g. 'nestedObject.id'
     */
    identifierPropertyName: {
      type: String,
      default: 'id'
    },

    /**
     * define a custom title property name for objects in your
     * entryList array<br>
     *   if relevant property is contained in a nested object the string can
     *   be in dot notation. e.g. 'nestedObject.title'
     */
    titlePropertyName: {
      type: String,
      default: 'title'
    },

    /**
     * specify if pagination elements should be a link element - if pagination element should
     * be a link element - please specify the kind of element (currently only Vue components (e.g.
     * 'router-link', 'nuxt-link') are supported)
     */
    usePaginationLinkElement: {
      type: [String, Boolean],
      default: false,
      validator: function validator(val) {
        return typeof val === 'boolean' && !val || typeof val === 'string' && val;
      }
    },

    /**
     * set this variable true if pagination is used and data fetching is done per page
     */
    fetchDataExternally: {
      type: Boolean,
      default: false
    },

    /**
     * specify an additional number of px for the position the page
     * should jump to on page change
     */
    scrollToOffset: {
      type: Number,
      default: 0
    },

    /**
     * specify an initial number of items per row that should be assumed before
     * rendering the page
     */
    // this is necessary because otherwise in SSR serverside and client side DOM tree
    // might not match
    initialItemsPerRow: {
      type: Number,
      default: 6
    },

    /**
     * add text for screen reader users that helps them navigate list and use edit mode
     * functionalities<br>
     * object should have the following properties:<br>
     *   <b>description</b>: Text read on edit mode activation<br>
     *   <b>activated</b>: Text read after item was activated for reordering
     *    (selected by enter key)<br>
     *    property moved can contain variable {pos} which will be filled with current
     *    position<br>
     *   <b>moved</b>: Text read after item was moved<br>
     *    property moved can contain variables {pos} (new position) and {total} (total number
     *    of list items)
     */
    supportiveText: {
      type: Object,
      default: function _default() {
        return {
          description: 'Select items via space bar to carry out actions or use enter key to select an item for reordering. Use Tab key to navigate between items.',
          activated: 'Item at position {pos} selected for reordering. Use arrow keys to order item.',
          moved: 'Item moved to position {pos} of {total}'
        };
      }
    },

    /**
     * BaseResultBoxSection is for example used to display search results - which contain a link
     * to the entry - in this case the focus should be on the link element so that navigation to
     * route link triggers on enter and focus on the list element itself is disabled (if not edit
     * mode!)
     */
    disableListElementFocus: {
      type: Boolean,
      default: false
    }
  },
  data: function data() {
    return {
      // internal representation of entry list to be able to
      // modify list via draggable
      entryListInt: [],
      // flag for edit mode activated
      editModeActive: false,
      // current page number
      currentPageNumberInt: 1,
      // store the expand state internally
      expandedInt: false,
      // store collapsed state on action start
      wasExpanded: false,
      // how many items do fit in one row
      itemsPerRow: null,
      // try to only do initial box size calculation once
      initialBoxCalcDone: false,
      // to manipulate selectedList internally
      selectedListInt: [],
      imageBoxesSelectable: false,
      // unique id to assign javascript calculated styles to
      elementId: null,
      // store state if component is mounted and window is present
      initialized: false,

      /**
       * variable for keyboard sorting - is element currently selected for moving
       * @type {?string}
       */
      movableElementId: null,

      /**
       * add supportive text especially to ease use of drag mode accessibly
       * @type {string}
       */
      currentSupportiveText: ''
    };
  },
  computed: {
    /**
     * to lazy load vuedraggable only if draggable mode is set true
     *
     * @returns {string|(function(): Promise<U>)}
     */
    draggableComponent: function draggableComponent() {
      if (this.draggable) {
        return function () {
          return import('./vuedraggable.umd-8fe09713.js').then(function (n) { return n.v; }).then(function (m) {
            return m.default || m;
          });
        };
      }

      return 'ul';
    },

    /**
     * get the entries that should be displayed in the section -
     * taking into consideration pagination and 'show more' functionality
     * @returns {Object[]}
     */
    visibleBoxes: {
      get: function get() {
        if (this.editModeActive && (this.draggable || !this.usePagination)) {
          return _toConsumableArray(this.entryListInt);
        } // if expand mode is used and status is collapsed and there
        // are more items than can be displayed in the rows specified by 'show more'
        // slice first few


        if (!this.editModeActive && this.useExpandMode && !this.expandedInt && this.expandNeeded) {
          // slice from 0 to number of rows * items per row - 1 so that the button
          // take the last box
          return this.entryListInt.slice(0, this.itemsPerRow * this.maxShowMoreRows - 1);
        } // else if pagination is active and items are not fetched from outside
        // slice items fitting one page


        if (this.usePagination && !this.fetchDataExternally) {
          // slice taking into account current pagination and the total number of
          // visible items
          return this.entryListInt.slice((this.currentPageNumberInt - 1) * this.visibleNumberOfItems, this.currentPageNumberInt * this.visibleNumberOfItems);
        }

        if (this.fetchDataExternally) {
          return this.entryList.slice(0, this.visibleNumberOfItems);
        } // else return complete list


        return this.entryListInt;
      },
      set: function set(val) {
        this.entryListInt = _toConsumableArray(val);
      }
    },

    /** PAGINATION AND EXPAND MODE */

    /**
     * the number of items that should be visible on one page
     * (if pagination is active)
     * @returns {number}
     */
    visibleNumberOfItems: function visibleNumberOfItems() {
      var availableSpaces = this.itemsPerRow * this.maxRows;

      if (this.editModeActive && this.showActionButtonBoxes) {
        return availableSpaces - this.actionButtonsConfig.length;
      }

      if (!this.editModeActive && this.useExpandMode) {
        // subtract 1 for the Expand Box Button or Action Button
        return availableSpaces - 1;
      }

      return availableSpaces;
    },

    /**
     * number of pages (if pagination is active)
     * @returns {number}
     */
    pages: function pages() {
      return (this.total || this.entryListInt.length) && this.visibleNumberOfItems >= 0 ? Math.ceil((this.total || this.entryListInt.length) / this.visibleNumberOfItems) : 1;
    },

    /**
     * determines if the total number of entries exceeds the number of entries that
     * can be displayed and thus if an expand button is needed
     */
    expandNeeded: function expandNeeded() {
      return this.itemsPerRow * this.maxShowMoreRows < this.entryList.length;
    }
  },
  watch: {
    entryList: {
      handler: function handler(val) {
        if (JSON.stringify(val) !== JSON.stringify(this.entryListInt)) {
          this.entryListInt = _toConsumableArray(val);
        }
      },
      immediate: true,
      deep: true
    },
    entryListInt: {
      handler: function handler(val) {
        if (JSON.stringify(val) !== JSON.stringify(this.entryList)) {
          /**
           * event emitted when the list of entries changed internally
           * (relevant if `draggable` is set true)
           *
           * @event entries-changed
           * @param {Object[]} val - the updated list of entries
           */
          this.$emit('entries-changed', val);
        }
      },
      deep: true
    },
    // watch selectedList prop and assign to internal value if changes occur
    selectedList: {
      handler: function handler(val) {
        if (JSON.stringify(val) !== JSON.stringify(this.selectedListInt)) {
          this.selectedListInt = JSON.parse(JSON.stringify(val));
        }
      },
      immediate: true
    },
    // watch selectedList prop and assign to internal value if changes occur
    selectedListInt: function selectedListInt(val) {
      if (JSON.stringify(val) !== JSON.stringify(this.selectedList)) {
        /**
         * inform the parent of the changes in the selected list and provide
         * the ids of all selected<br>
         *   the [.sync modifier](https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier) may be used on the corresponding prop
         *
         * @event update:selected-list
         * @param {Array} val - the list of selected entry ids
         */
        this.$emit('update:selected-list', val);
      }
    },
    // watch pages in case of deletion of items and take care
    // current page is not higher than total page number
    pages: {
      handler: function handler(val) {
        if (this.currentPageNumberInt > val) {
          // if the current page number exceeds the total number of pages
          // set the value to the last existing page
          this.currentPageNumberInt = val;
        }
      },
      immediate: true
    },
    // update internal page number if changed from outside
    currentPageNumber: {
      handler: function handler(val) {
        if (val !== this.currentPageNumberInt) {
          // check if number is larger than max number of pages currently available and
          // set to max possible value if yes instead
          // TODO: changed this to internal handling for now because it makes problems with
          // externally provided data but maybe it would make sense to get rid of it all together
          this.currentPageNumberInt = val > this.pages && !this.fetchDataExternally ? this.pages : val;
        }
      },
      immediate: true
    },

    /**
     * watch internal page number to inform parent about changes
     * @param {number} val
     */
    currentPageNumberInt: {
      handler: function handler(val) {
        if (val !== this.currentPageNumber) {
          /** emitted when pagination is used and page number was changed
           *
           * @event update:current-page-number
           * @param {number} number - the new page number
          */
          this.$emit('update:current-page-number', this.currentPageNumberInt);
        }
      },
      immediate: true
    },
    // if expanded variable is set from outside change
    // internal variable accordingly
    expanded: {
      handler: function handler(val) {
        if (val !== this.expandedInt) {
          this.expandedInt = val;
        }
      },
      immediate: true
    },
    // if internal value changes, reset page number and inform parent
    expandedInt: function expandedInt(val) {
      // reset current page number on collapse
      if (!val) {
        this.currentPageNumberInt = 1;
      } // inform parent of internal change


      if (val !== this.expanded) {
        /**
         * event emitted on expand toggle<br>
         *   the [.sync modifier](https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier) may be used on the corresponding prop
         * @event update:expanded
         * @param { Boolean } val - true if list is expanded
         */
        this.$emit('update:expanded', val);
      }
    },
    editModeActive: function editModeActive(val) {
      var _this = this;

      // have setting true of selectable delayed for animation
      setTimeout(function () {
        _this.imageBoxesSelectable = val;
      }, 50);
      setTimeout(function () {
        if (val) {
          _this.$nextTick(function () {
            if (_this.$refs.resultBoxItem && _this.$refs.resultBoxItem.length) {
              _this.$refs.resultBoxItem.forEach(function (element) {
                var inputElement = element.getElementsByTagName('input');
                inputElement[0].setAttribute('tabindex', '-1');
              }); // it appears refs are not reactive and do not reflect reordering so we need
              // to look for the actual current first element in the visibleBoxes array


              var firstElement = _this.$refs.resultBoxItem.find(function (element) {
                return element.id.includes(_this.visibleBoxes[0].id);
              });

              firstElement.focus({
                preventScroll: true
              });
            }
          });
        }
      }, 500);

      if (val) {
        this.currentSupportiveText = this.supportiveText.description;
      } else {
        this.movableElementId = null;
        this.currentSupportiveText = '';
      }

      if (val !== this.editMode) {
        /**
         * emitted on edit mode toggle (options toggle)<br>
         *   the [.sync modifier](https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier) may be used on the corresponding prop
         *
         * @event update:edit-mode
         * @param {Boolean} val - flag for edit mode active
         */
        this.$emit('update:edit-mode', val);
      } // add listener to esc key event (toggle edit mode)


      if (!this.initialized) return;

      if (val) {
        window.addEventListener('keyup', this.escEventHandler);
      } else {
        window.removeEventListener('keyup', this.escEventHandler);
      }
    },
    editMode: {
      handler: function handler(val) {
        if (val !== this.editModeActive) {
          this.editModeActive = val && this.showOptions && this.showHeader;
        }
      },
      immediate: true
    },
    showOptions: function showOptions(val) {
      if (!val) {
        this.editModeActive = false;
      }
    },
    showHeader: function showHeader(val) {
      if (!val) {
        this.editModeActive = false;
      }
    }
  },
  created: function created() {
    if (!this.useExpandMode) {
      this.expandedInt = true;
    }

    this.itemsPerRow = this.initialItemsPerRow;
  },
  mounted: function mounted() {
    // create an element id to have an unique id to assign javascript calculated styles to
    // note: done here, cause of mismatching ids (entries, class definition) in ssr-mode
    // eslint-disable-next-line no-underscore-dangle
    this.elementId = this._uid;

    if (!this.initialBoxCalcDone && this.$refs.resultBoxesArea) {
      this.calcBoxNumber();
    } // need to get the correct number of boxes per row to calculate the visible
    // number of items correctly


    window.addEventListener('resize', this.resizeBoxes);
    this.initialized = true;
  },
  updated: function updated() {
    if (!this.initialBoxCalcDone && this.$refs.resultBoxesArea) {
      this.calcBoxNumber();
    }
  },
  methods: {
    /** EDIT MODE FUNCTIONALITIES */

    /**
     * toggling of options when options are behind a 'options' button
     *
     * @param {Boolean} actionsVisible true for open, false for close
     */
    optionsToggle: function optionsToggle(actionsVisible) {
      this.editModeActive = actionsVisible;

      if (!actionsVisible) {
        // on close return to original collapsed state
        this.expandedInt = this.wasExpanded; // clear selected boxes

        this.selectedListInt = []; // on open - store the original collapsed state
      } else {
        this.wasExpanded = this.expandedInt;
      }
    },

    /**
     * function triggered when selecteAll was clicked in select mode
     *
     * @param {boolean} selectAll - true if everything was selected,
     * false if everything was deselected
     */
    selectAllTriggered: function selectAllTriggered(selectAll) {
      var _this2 = this;

      if (selectAll) {
        // select all entries that are currently visible
        // deduplicate by creating Set and converting back to array
        this.selectedListInt = _toConsumableArray(new Set([].concat(_toConsumableArray(this.selectedListInt), _toConsumableArray(this.visibleBoxes.map(function (entry) {
          return _this2.getPropValue(_this2.identifierPropertyName, entry);
        })))));
      } else {
        var visibleEntryIds = this.visibleBoxes.map(function (visibleEntry) {
          return _this2.getPropValue(_this2.identifierPropertyName, visibleEntry);
        });
        this.selectedListInt = this.selectedListInt.filter(function (entry) {
          return !visibleEntryIds.includes(_this2.getPropValue(_this2.identifierPropertyName, entry) || entry);
        });
      }
    },

    /**
     * triggered when an entry is selected or is clicked upon
     *
     * @param {string} entryId - the entry id of the selected entry
     * @param {boolean} [selected=undefined] - not provided and thus undefined
     * if entry was clicked
     */
    entrySelected: function entrySelected(entryId, selected) {
      // if entry was selected in edit mode and list does not contain entry
      // already - add it to the list
      if (selected && !this.selectedListInt.includes(entryId)) {
        this.selectedListInt.push(entryId);
      } else if (!selected) {
        this.selectedListInt = this.selectedListInt.filter(function (boxId) {
          return boxId !== entryId;
        });
      }
    },

    /**
     * function to calc if image box is currently selected
     *
     * @param {Object} entry - the entry in question
     * @returns {Boolean}
     */
    isEntrySelected: function isEntrySelected(entry) {
      var _this3 = this;

      return this.selectedListInt.map(function (selectedEntry) {
        return _this3.getPropValue(_this3.identifierPropertyName, selectedEntry) || selectedEntry;
      }).includes(this.getPropValue(this.identifierPropertyName, entry));
    },

    /**
     * function triggered when user has
     * clicked action button to go through with the action
     */
    submitAction: function submitAction(action) {
      /**
       * event triggered when an action is triggered (after selecting boxes)
       *
       * @event submit-action
       * @param {string} action - the action type
       */
      this.$emit('submit-action', action);
    },

    /**
     * intercept escape key event and reset edit mode
     */
    escEventHandler: function escEventHandler(e) {
      if (e.key === 'Escape') {
        // first use escape key to leave drag mode
        if (this.movableElementId) {
          this.cancelDragMode(); // else use it to leave edit mode
        } else {
          this.editModeActive = false;
          this.currentSupportiveText = '';
        }
      }
    },

    /**
     * event handler on keydown 'Enter'
     * @param {KeyboardEvent} event - the keydown event
     * @param {Object} entry - the entry the event was triggered on
     * @param {number} index - the index of the entry in the visibleBoxes array
     */
    onEnterKey: function onEnterKey(event, entry, index) {
      if (this.editModeActive && this.draggable) {
        event.preventDefault(); // check if movableElementId is null

        if (!this.movableElementId) {
          // if yes activate drag mode by assigning the entry id as movableElementId
          this.movableElementId = entry.id; // add supportive text for the screen reader

          this.currentSupportiveText = this.supportiveText.activated.replace('{pos}', (index + 1).toString());
        } else {
          // if drag mode was active before - cancel it
          this.cancelDragMode();
        }
      } else {
        this.entryClicked(this.getPropValue(this.identifierPropertyName, entry));
      }
    },

    /**
     * event handler on keydown with arrow keys
     * @param {KeyboardEvent} event - the keydown event
     * @param {number} index - the index of the entry on which the event was triggered
     *  in the visibleBoxes array
     */
    moveEntry: function moveEntry(event, index) {
      var _this4 = this;

      // reset supportive text
      this.currentSupportiveText = ''; // get key that was pressed

      var key = event.key; // determine if element should be moved up or down in the list

      var shiftDown = ['ArrowRight', 'ArrowDown'].includes(key); // get the corresponding number to add to the array index

      var shiftIndex = shiftDown ? 1 : -1; // get new Index

      var newIndex = index + shiftIndex; // check if move is possible or if item is first or last respectively already

      if (this.isWithinArrayLimit(this.visibleBoxes, shiftDown, newIndex)) {
        // assign box list to variable so the set() of visibleBoxes is actually triggered
        // when it is assigned again later on (doing it directly on visibleBoxes or entryListInt
        // has no effect)
        var newArray = this.visibleBoxes; // do swapping with array destructuring

        var _ref = [newArray[newIndex], newArray[index]];
        newArray[index] = _ref[0];
        newArray[newIndex] = _ref[1];
        // assign it again to visibleBoxes variable
        this.visibleBoxes = newArray; // next tick so there is time to repaint and get new order

        this.$nextTick(function () {
          // get all box elements
          var movedElement = document.getElementById("li-".concat(_this4.movableElementId)); // element is loosing focus in the process of swapping so refocus here

          movedElement.focus();
        }); // add matching supportive text informing the user of the move and the new position

        this.currentSupportiveText = this.supportiveText.moved.replace('{pos}', newIndex + 1).replace('{total}', this.visibleBoxes.length);
      }
    },

    /**
     * reset drag related variable and supportive text
     */
    cancelDragMode: function cancelDragMode() {
      this.movableElementId = null;
      this.currentSupportiveText = '';
    },

    /** BOX DISPLAY FUNCTIONALITIES */

    /**
     * timeout function for resize event to limit the number of times
     * box number is recalculated
     */
    resizeBoxes: function resizeBoxes() {
      var _this5 = this;

      // check if there is a timeout already set and clear it if yes
      if (this.resizeTimeout) {
        clearTimeout(this.resizeTimeout);
        this.resizeTimeout = null;
      } // if yes set timeout to recalculate box number after


      this.resizeTimeout = setTimeout(function () {
        _this5.calcBoxNumber();
      }, 300);
    },

    /**
     * calculate the box number according to available space and breaking points set
     */
    calcBoxNumber: function calcBoxNumber() {
      // get the result boxes parent - in case of draggable active this is a vue component
      // and $el needs to be addressed - otherwise native HTML element can be used directly
      var resultBoxesElement = this.$refs.resultBoxesArea && this.$refs.resultBoxesArea.$el ? this.$refs.resultBoxesArea.$el : this.$refs.resultBoxesArea; // if such an element was found and element has children (= boxes are rendered)

      if (resultBoxesElement) {
        // get the element width
        var totalWidth = resultBoxesElement.clientWidth; // calculate how many items should be displayed according to
        // breakpoints set

        this.itemsPerRow = this.boxBreakpoints // then also sorting should not be necessary anymore (maybe keep to
        // be on the save side?
        .sort(function (a, b) {
          return a[0] > b[0];
        }) // get the correct box number
        .reduce(function (prev, _ref2) {
          var _ref3 = _slicedToArray(_ref2, 2),
              size = _ref3[0],
              number = _ref3[1];

          if (totalWidth > size) {
            return number;
          }

          return prev;
        }, 0); // set the styles
        // set a css variable that is responsible for the number of items

        this.$el.style.setProperty('--items-per-row', this.itemsPerRow); // set the correct margins for the boxes

        var nodeId = "base-result-box-section__box-style-".concat(this.elementId);
        var style = document.getElementById(nodeId); // check if element already exists to only create it once

        if (!style) {
          // if not - create the style element
          style = document.createElement('style'); // set an id

          style.id = nodeId; // append the style element

          this.$el.appendChild(style);
        } // set the actually css in the style element


        style.innerHTML = "\n          .base-result-box-section__box-item-".concat(this.elementId, ":nth-child(n + ").concat(this.itemsPerRow + 1, ") {\n            margin-top: var(--spacing-regular);\n          }\n          .base-result-box-section__box-item-").concat(this.elementId, ":not(:nth-child(").concat(this.itemsPerRow, "n)) {\n            margin-right: var(--spacing-regular);\n          }");
        this.initialBoxCalcDone = true;
        /**
         * communicate to parent when items per row changed, either after initial
         * render space calculations or when window was resized
         * @event items-per-row-changed
         * @type {number}
         */

        this.$emit('items-per-row-changed', this.itemsPerRow);
      }
    },

    /** PAGINATION */

    /**
     * function triggered when page in pagination component is selected
     *
     * @param {number} number - the selected page number
     */
    setPage: function setPage(number) {
      // set internal page number - this will also trigger an event to parent
      this.currentPageNumberInt = number; // if variable is set true jump to top of element

      if (this.jumpToTop) {
        window.scrollTo(0, this.$el.offsetTop - this.scrollToOffset);
      }
    },

    /** GENERAL FUNCTIONALITIES */

    /**
     * triggered when an entry is clicked upon (edit mode not acive)
     *
     * @param {string} entryId - the entry id of the selected entry
     */
    entryClicked: function entryClicked(entryId) {
      /**
       * event emitted from default image box when clicked
       * @event entry-clicked
       * @param {Object} object - an object with the following properties:
       * @property {string} entryId - the id of the clicked entry
       * the select mode was not active but the box was clicked
       */
      this.$emit('entry-clicked', {
        entryId: entryId
      });
    },

    /**
     * get an internationalized string
     *
     * @param {string|Object} localizationArguments - string or object to look
     * up in localization files<br>
     *   if it is an object it should have the following properties:
     * @property {string} string - string to look up in a Locale messages file
     * @property {number} count - for pluralization
     * @property {Object} variables - locale string variables object
     * @returns {string}
     */
    getI18nString: function getI18nString(localizationArguments) {
      // check if a string was provided
      if (typeof localizationArguments === 'string') {
        return this.getI18nTerm(localizationArguments);
      } // if not - assume an object with the relevant properties


      var _localizationArgument = _objectSpread2({}, localizationArguments),
          string = _localizationArgument.string,
          count = _localizationArgument.count,
          variables = _localizationArgument.variables;

      return this.getI18nTerm(string, count, variables);
    },

    /**
     * to get a nested object property value from a string in dot notation
     *
     * @param {string} string - the nested object property path in dot notation
     * @param {Object} object - the object from which the property value should be extracted
     * @returns {*}
     */
    getPropValue: function getPropValue(string, object) {
      return extractNestedPropertyValue(string, object);
    }
  }
};

var __vue_script__ = script;
/* template */

var __vue_render__ = function __vue_render__() {
  var _vm = this;

  var _h = _vm.$createElement;

  var _c = _vm._self._c || _h;

  return _c('div', {
    staticClass: "base-result-box-section"
  }, [_vm.isLoading ? _c('div', {
    staticClass: "base-result-box-section__loading"
  }, [_c('BaseLoader', {
    staticClass: "base-result-box-section__loader"
  })], 1) : _vm._e(), _vm._v(" "), _c('div', {
    staticClass: "base-result-box-section__container"
  }, [_vm.showHeader ? _c('div', {
    staticClass: "base-result-box-section__header-row"
  }, [_vm.showOptions ? _c('BaseOptions', {
    attrs: {
      "show-options": _vm.editModeActive,
      "options-button-icon": _vm.optionsButtonIcon,
      "options-button-text": _vm.optionsButtonText,
      "use-options-button-on": "always"
    },
    on: {
      "update:show-options": _vm.optionsToggle
    },
    scopedSlots: _vm._u([{
      key: "beforeOptions",
      fn: function fn() {
        return [_vm._t("header", function () {
          return [_vm.headerText ? _c('h3', {
            staticClass: "base-result-box-section__header"
          }, [_vm._v("\n              " + _vm._s(_vm.headerText) + "\n            ")]) : _vm._e()];
        })];
      },
      proxy: true
    }, {
      key: "options",
      fn: function fn() {
        return [_vm._t("optionButtons", function () {
          return [_vm._l(_vm.actionButtonsConfig, function (action) {
            return [action.display === 'top' || action.display === 'all' || !action.display ? _c('BaseButton', {
              key: action.text,
              attrs: {
                "text": _vm.getI18nString(action.text),
                "icon": action.icon,
                "has-background-color": false,
                "disabled": action.disabled,
                "icon-size": "large",
                "button-style": "single"
              },
              on: {
                "clicked": function clicked($event) {
                  return _vm.submitAction(action.value);
                }
              }
            }) : _vm._e()];
          })];
        }, {
          "submitAction": _vm.submitAction
        })];
      },
      proxy: true
    }], null, true)
  }) : [_vm._t("header", function () {
    return [_vm.headerText ? _c('h3', {
      staticClass: "base-result-box-section__header"
    }, [_vm._v("\n            " + _vm._s(_vm.headerText) + "\n          ")]) : _vm._e()];
  })]], 2) : _vm._e(), _vm._v(" "), _c('div', {
    class: ['base-result-box-section__background', {
      'base-result-box-section__background--white': _vm.editModeWhiteBackground && _vm.editModeActive
    }]
  }, [_vm.editModeActive ? _c('div', {
    key: _vm.headerText + '_messageArea',
    staticClass: "base-result-box-section__message-area"
  }, [_c('div', {
    staticClass: "base-result-box-section__message-area-text"
  }, [_vm._v("\n          " + _vm._s(_vm.messageText) + "\n        ")]), _vm._v(" "), _c('span', {
    staticClass: "base-result-box-section__message-area-subtext"
  }, [_vm._v(_vm._s(_vm.messageSubtext))]), _vm._v(" "), _vm._t("optionsMessageAreaAfter")], 2) : _vm._e(), _vm._v(" "), _vm.editModeActive ? _c('BaseSelectOptions', {
    key: _vm.headerText + '_selectOptions',
    attrs: {
      "selected-number-text": _vm.getI18nString(_vm.selectOptionsText.entriesSelected),
      "select-text": _vm.getI18nString(_vm.selectOptionsText.selectAll),
      "deselect-text": _vm.getI18nString(_vm.selectOptionsText.selectNone),
      "list": _vm.visibleBoxes,
      "selected-list": _vm.selectedListInt
    },
    on: {
      "selected": _vm.selectAllTriggered
    }
  }) : _vm._e(), _vm._v(" "), _c('span', {
    staticClass: "supportive-text",
    attrs: {
      "aria-live": "assertive"
    }
  }, [_vm._v("\n        " + _vm._s(_vm.currentSupportiveText) + "\n      ")]), _vm._v(" "), _vm.entryListInt.length ? [_c(_vm.draggableComponent, {
    ref: "resultBoxesArea",
    tag: "component",
    staticClass: "base-result-box-section__boxes-container",
    attrs: {
      "animation": _vm.draggable ? 150 : false,
      "tag": _vm.draggable ? 'ul' : false,
      "draggable": _vm.editModeActive ? '.base-result-box-section__result-box-item' : false,
      "aria-label": _vm.headerText,
      "tabindex": "0",
      "handle": ".base-result-box-section__result-box-item__draggable .base-image-box-content",
      "force-fallback": "true",
      "role": "list"
    },
    model: {
      value: _vm.visibleBoxes,
      callback: function callback($$v) {
        _vm.visibleBoxes = $$v;
      },
      expression: "visibleBoxes"
    }
  }, [_vm._l(_vm.visibleBoxes, function (entry, index) {
    return _c('li', {
      key: _vm.getPropValue(_vm.identifierPropertyName, entry),
      ref: "resultBoxItem",
      refInFor: true,
      class: ['base-result-box-section__box-item', 'base-result-box-section__result-box-item', {
        'base-result-box-section__box-item__hidden': !_vm.initialBoxCalcDone
      }, "base-result-box-section__box-item-" + _vm.elementId, {
        'base-result-box-section__result-box-item__draggable': _vm.draggable && _vm.editModeActive
      }, {
        'base-result-box-section__result-box-item__dragging': _vm.movableElementId === entry.id
      }],
      attrs: {
        "id": "li-" + entry.id,
        "tabindex": _vm.editModeActive || !_vm.disableListElementFocus ? 0 : -1,
        "aria-label": _vm.getPropValue(_vm.titlePropertyName, entry),
        "aria-grabbed": (_vm.movableElementId === entry.id).toString(),
        "aria-selected": _vm.editModeActive ? _vm.isEntrySelected(entry).toString() : false,
        "role": "listitem"
      },
      on: {
        "keydown": [function ($event) {
          if (!$event.type.indexOf('key') && _vm._k($event.keyCode, "enter", 13, $event.key, "Enter")) {
            return null;
          }

          return _vm.onEnterKey($event, entry, index);
        }, function ($event) {
          if (!$event.type.indexOf('key') && _vm._k($event.keyCode, "up", 38, $event.key, ["Up", "ArrowUp"]) && _vm._k($event.keyCode, "down", 40, $event.key, ["Down", "ArrowDown"]) && _vm._k($event.keyCode, "left", 37, $event.key, ["Left", "ArrowLeft"]) && _vm._k($event.keyCode, "right", 39, $event.key, ["Right", "ArrowRight"])) {
            return null;
          }

          if ('button' in $event && $event.button !== 0) {
            return null;
          }

          if ('button' in $event && $event.button !== 2) {
            return null;
          }

          $event.preventDefault();
          _vm.editModeActive && _vm.draggable && _vm.movableElementId ? _vm.moveEntry($event, index) : false;
        }, function ($event) {
          if (!$event.type.indexOf('key') && _vm._k($event.keyCode, "space", 32, $event.key, [" ", "Spacebar"])) {
            return null;
          }

          $event.preventDefault();
          _vm.editModeActive ? _vm.entrySelected(_vm.getPropValue(_vm.identifierPropertyName, entry), !_vm.isEntrySelected(entry)) : false;
        }, function ($event) {
          if (!$event.type.indexOf('key') && _vm._k($event.keyCode, "tab", 9, $event.key, "Tab")) {
            return null;
          }

          return _vm.cancelDragMode.apply(null, arguments);
        }]
      }
    }, [_vm._t("resultBox", function () {
      return [_c('BaseImageBox', {
        key: _vm.getPropValue(_vm.identifierPropertyName, entry),
        attrs: {
          "selectable": _vm.imageBoxesSelectable,
          "draggable": _vm.editModeActive && _vm.draggable,
          "selected": _vm.isEntrySelected(entry),
          "box-size": {
            width: 'auto'
          },
          "box-ratio": 100,
          "title": _vm.getPropValue(_vm.titlePropertyName, entry),
          "subtext": entry.subtext,
          "description": entry.description,
          "image-url": entry.imageUrl,
          "box-text": entry.text,
          "lazyload": true
        },
        on: {
          "select-triggered": function selectTriggered($event) {
            _vm.entrySelected(_vm.getPropValue(_vm.identifierPropertyName, entry), $event);
          },
          "clicked": function clicked($event) {
            _vm.entryClicked(_vm.getPropValue(_vm.identifierPropertyName, entry));
          }
        }
      })];
    }, {
      "item": entry,
      "index": index,
      "selectActive": _vm.editModeActive,
      "isEntrySelected": _vm.isEntrySelected,
      "entrySelected": _vm.entrySelected
    })], 2);
  }), _vm._v(" "), _vm.showActionButtonBoxes && _vm.editModeActive ? _vm._t("actionButtons", function () {
    return [_vm._l(_vm.actionButtonsConfig, function (action) {
      return [action.display === 'bottom' || action.display === 'all' || !action.display ? _c('BaseBoxButton', {
        key: action.value,
        class: ['base-result-box-section__box-item', "base-result-box-section__box-item-" + _vm.elementId],
        attrs: {
          "text": _vm.getI18nString(action.text),
          "box-size": {
            width: 'calc(25% - 8rem/19 - (8rem/19/2))',
            height: '100%'
          },
          "icon": action.icon,
          "box-style": "small",
          "box-type": "button"
        },
        on: {
          "clicked": function clicked($event) {
            return _vm.submitAction(action.value);
          }
        }
      }) : _vm._e()];
    })];
  }, {
    "itemsPerRow": _vm.itemsPerRow,
    "elementId": _vm.elementId
  }) : _vm.useExpandMode && !_vm.editModeActive && _vm.expandNeeded && _vm.initialBoxCalcDone ? _c('BaseBoxButton', {
    class: ['base-result-box-section__box-item', "base-result-box-section__box-item-" + _vm.elementId],
    attrs: {
      "box-size": {
        width: 'calc(25% - 8rem/19 - (8rem/19/2))',
        height: '100%'
      },
      "icon": "",
      "text": "",
      "box-type": "button"
    },
    on: {
      "clicked": function clicked($event) {
        _vm.expandedInt = !_vm.expandedInt;
      }
    },
    scopedSlots: _vm._u([{
      key: "default",
      fn: function fn() {
        return [!_vm.editModeActive ? _c('div', {
          staticClass: "base-result-box-section__expand-button__content"
        }, [!_vm.expandedInt ? _c('span', {
          staticClass: "base-result-box-section__expand-button__content-number"
        }, [_vm._v("\n                  " + _vm._s("+" + ((_vm.total || _vm.entryList.length) - _vm.visibleBoxes.length)) + "\n                ")]) : _vm._e(), _vm._v(" "), _c('span', {
          class: [_vm.expandedInt ? 'base-result-box-section__expand-button__content-text-expanded' : 'base-result-box-section__expand-button__content-text-collapsed']
        }, [_vm._v("\n                  " + _vm._s(_vm.expandedInt ? _vm.expandText.collapse : _vm.expandText.expand) + "\n                ")])]) : _vm._e()];
      },
      proxy: true
    }], null, false, 902529970)
  }) : _vm._e()], 2), _vm._v(" "), _vm.usePagination && _vm.pages > 1 && (_vm.editModeActive && !_vm.draggable || !_vm.editModeActive && _vm.expandedInt) ? _c('BasePagination', {
    key: 'pagination-' + _vm.elementId,
    attrs: {
      "total": _vm.pages,
      "current": _vm.currentPageNumberInt,
      "use-link-element": _vm.usePaginationLinkElement
    },
    on: {
      "set-page": _vm.setPage
    }
  }) : _vm._e()] : _vm._e()], 2)])]);
};

var __vue_staticRenderFns__ = [];
/* style */

var __vue_inject_styles__ = undefined;
/* scoped */

var __vue_scope_id__ = "data-v-3c60afe4";
/* module identifier */

var __vue_module_identifier__ = undefined;
/* functional template */

var __vue_is_functional_template__ = false;
/* style inject */

/* style inject SSR */

/* style inject shadow dom */

var __vue_component__ = /*#__PURE__*/normalizeComponent({
  render: __vue_render__,
  staticRenderFns: __vue_staticRenderFns__
}, __vue_inject_styles__, __vue_script__, __vue_scope_id__, __vue_is_functional_template__, __vue_module_identifier__, false, undefined, undefined, undefined);

var BaseResultBoxSection = __vue_component__;

var Plugin = {
  install: function install(Vue) {
    registerComponent(Vue, BaseResultBoxSection);
  }
};
use(Plugin);

export { BaseResultBoxSection, Plugin as default };
