UNPKG

@handsontable/vue3

Version:

Best Data Grid for Vue with Spreadsheet Look and Feel.

385 lines (370 loc) • 13.8 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var vue = require('vue'); var Handsontable = require('handsontable/base'); function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; } var Handsontable__default = /*#__PURE__*/_interopDefaultCompat(Handsontable); function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread2(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), true).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } var unassignedPropSymbol = Symbol('unassigned'); /** * Message for the warning thrown if the Handsontable instance has been destroyed. */ var HOT_DESTROYED_WARNING = 'The Handsontable instance bound to this component was destroyed and cannot be' + ' used properly.'; /** * Check if at specified `key` there is any value for `object`. * * @param {object} object Object to search value at specyfic key. * @param {string} key String key to check. * @returns {boolean} */ function hasOwnProperty(object, key) { return Object.prototype.hasOwnProperty.call(object, key); } /** * Generate an object containing all the available Handsontable properties and plugin hooks. * * @param {string} source Source for the factory (either 'HotTable' or 'HotColumn'). * @returns {object} */ function propFactory(source) { var registeredHooks = Handsontable__default["default"].hooks.getRegistered(); var propSchema = {}; Object.assign(propSchema, Handsontable__default["default"].DefaultSettings); // eslint-disable-next-line no-restricted-syntax, guard-for-in for (var prop in propSchema) { propSchema[prop] = { "default": unassignedPropSymbol }; } for (var i = 0; i < registeredHooks.length; i++) { propSchema[registeredHooks[i]] = { "default": unassignedPropSymbol }; } propSchema.settings = { "default": unassignedPropSymbol }; if (source === 'HotTable') { propSchema.id = { type: String, "default": "hot-".concat(Math.random().toString(36).substring(5)) }; } return propSchema; } /** * Filter out all of the unassigned props, and return only the one passed to the component. * * @param {object} props Object containing all the possible props. * @returns {object} Object containing only used props. */ function filterPassedProps(props) { var filteredProps = {}; var columnSettingsProp = props.settings; if (columnSettingsProp !== unassignedPropSymbol) { // eslint-disable-next-line no-restricted-syntax for (var propName in columnSettingsProp) { if (hasOwnProperty(columnSettingsProp, propName) && columnSettingsProp[propName] !== unassignedPropSymbol) { filteredProps[propName] = columnSettingsProp[propName]; } } } // eslint-disable-next-line no-restricted-syntax for (var _propName in props) { if (hasOwnProperty(props, _propName) && _propName !== 'settings' && props[_propName] !== unassignedPropSymbol) { filteredProps[_propName] = props[_propName]; } } return filteredProps; } /** * Prepare the settings object to be used as the settings for Handsontable, based on the props provided to the component. * * @param {HotTableProps} props The props passed to the component. * @param {Handsontable.GridSettings} currentSettings The current Handsontable settings. * @returns {Handsontable.GridSettings} An object containing the properties, ready to be used within Handsontable. */ function prepareSettings(props, currentSettings) { var assignedProps = filterPassedProps(props); var hotSettingsInProps = props.settings ? props.settings : assignedProps; var additionalHotSettingsInProps = props.settings ? assignedProps : null; var newSettings = {}; // eslint-disable-next-line no-restricted-syntax for (var key in hotSettingsInProps) { if (hasOwnProperty(hotSettingsInProps, key) && hotSettingsInProps[key] !== void 0 && (currentSettings && key !== 'data' ? !simpleEqual(currentSettings[key], hotSettingsInProps[key]) : true)) { newSettings[key] = hotSettingsInProps[key]; } } // eslint-disable-next-line no-restricted-syntax for (var _key in additionalHotSettingsInProps) { if (hasOwnProperty(additionalHotSettingsInProps, _key) && _key !== 'id' && _key !== 'settings' && additionalHotSettingsInProps[_key] !== void 0 && (currentSettings && _key !== 'data' ? !simpleEqual(currentSettings[_key], additionalHotSettingsInProps[_key]) : true)) { newSettings[_key] = additionalHotSettingsInProps[_key]; } } return newSettings; } /** * Compare two objects using `JSON.stringify`. * *Note: * As it's using the stringify function to compare objects, the property order in both objects is * important. It will return `false` for the same objects, if they're defined in a different order. * * @param {object} objectA First object to compare. * @param {object} objectB Second object to compare. * @returns {boolean} `true` if they're the same, `false` otherwise. */ function simpleEqual(objectA, objectB) { var stringifyToJSON = function stringifyToJSON(val) { var circularReplacer = function () { var seen = new WeakSet(); return function (key, value) { if (_typeof(value) === 'object' && value !== null) { if (seen.has(value)) { return; } seen.add(value); } return value; }; }(); return JSON.stringify(val, circularReplacer); }; if (typeof objectA === 'function' && typeof objectB === 'function') { return objectA.toString() === objectB.toString(); } else if (_typeof(objectA) !== _typeof(objectB)) { return false; } else { return stringifyToJSON(objectA) === stringifyToJSON(objectB); } } var version="15.3.0"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore var HotTable = vue.defineComponent({ name: 'HotTable', props: propFactory('HotTable'), provide: function provide() { return { columnsCache: this.columnsCache }; }, watch: { $props: { handler: function handler(props) { var settings = prepareSettings(props, this.hotInstance ? this.hotInstance.getSettings() : void 0); if (!this.hotInstance || settings === void 0) { return; } if (settings.data) { if (this.hotInstance.isColumnModificationAllowed() || !this.hotInstance.isColumnModificationAllowed() && this.hotInstance.countSourceCols() === this.miscCache.currentSourceColumns) { // If the dataset dimensions change, update the index mappers. this.matchHotMappersSize(); // Data is automatically synchronized by reference. delete settings.data; } } // If there are another options changed, update the HOT settings, render the table otherwise. if (Object.keys(settings).length) { this.hotInstance.updateSettings(settings); } else { this.hotInstance.render(); } this.miscCache.currentSourceColumns = this.hotInstance.countSourceCols(); }, deep: true, immediate: true } }, data: function data() { return { /* eslint-disable vue/no-reserved-keys */ __hotInstance: null, /* eslint-enable vue/no-reserved-keys */ miscCache: { currentSourceColumns: null }, columnSettings: null, columnsCache: new Map(), get hotInstance() { if (!this.__hotInstance || this.__hotInstance && !this.__hotInstance.isDestroyed) { // Will return the Handsontable instance or `null` if it's not yet been created. return this.__hotInstance; } else { /* eslint-disable-next-line no-console */ console.warn(HOT_DESTROYED_WARNING); return null; } }, set hotInstance(hotInstance) { this.__hotInstance = hotInstance; } }; }, methods: { /** * Initialize Handsontable. */ hotInit: function hotInit() { var newSettings = prepareSettings(this.$props); newSettings.columns = this.columnSettings ? this.columnSettings : newSettings.columns; this.hotInstance = vue.markRaw(new Handsontable__default["default"].Core(this.$el, newSettings)); this.hotInstance.init(); this.miscCache.currentSourceColumns = this.hotInstance.countSourceCols(); }, matchHotMappersSize: function matchHotMappersSize() { var _this = this; if (!this.hotInstance) { return; } var data = this.hotInstance.getSourceData(); var rowsToRemove = []; var columnsToRemove = []; var indexMapperRowCount = this.hotInstance.rowIndexMapper.getNumberOfIndexes(); var isColumnModificationAllowed = this.hotInstance.isColumnModificationAllowed(); var indexMapperColumnCount = 0; if (data && data.length !== indexMapperRowCount) { if (data.length < indexMapperRowCount) { for (var r = data.length; r < indexMapperRowCount; r++) { rowsToRemove.push(r); } } } if (isColumnModificationAllowed) { var _data$; indexMapperColumnCount = this.hotInstance.columnIndexMapper.getNumberOfIndexes(); if (data && data[0] && ((_data$ = data[0]) === null || _data$ === void 0 ? void 0 : _data$.length) !== indexMapperColumnCount) { if (data[0].length < indexMapperColumnCount) { for (var c = data[0].length; c < indexMapperColumnCount; c++) { columnsToRemove.push(c); } } } } this.hotInstance.batch(function () { if (rowsToRemove.length > 0) { _this.hotInstance.rowIndexMapper.removeIndexes(rowsToRemove); } else { _this.hotInstance.rowIndexMapper.insertIndexes(indexMapperRowCount - 1, data.length - indexMapperRowCount); } if (isColumnModificationAllowed && data.length !== 0) { if (columnsToRemove.length > 0) { _this.hotInstance.columnIndexMapper.removeIndexes(columnsToRemove); } else { _this.hotInstance.columnIndexMapper.insertIndexes(indexMapperColumnCount - 1, data[0].length - indexMapperColumnCount); } } }); }, /** * Get settings for the columns provided in the `hot-column` components. * * @returns {HotTableProps[] | undefined} */ getColumnSettings: function getColumnSettings() { var columnSettings = Array.from(this.columnsCache.values()); return columnSettings.length ? columnSettings : void 0; } }, mounted: function mounted() { this.columnSettings = this.getColumnSettings(); this.hotInit(); }, beforeUnmount: function beforeUnmount() { if (this.hotInstance) { this.hotInstance.destroy(); } }, version: version }); var _hoisted_1 = ["id"]; function render(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("div", { id: _ctx.id }, [vue.renderSlot(_ctx.$slots, "default")], 8 /* PROPS */, _hoisted_1); } HotTable.render = render; HotTable.__file = "src/HotTable.vue"; var HotColumn = vue.defineComponent({ name: 'HotColumn', props: propFactory('HotColumn'), inject: ['columnsCache'], methods: { /** * Create the column settings based on the data provided to the `hot-column` * component and it's child components. */ createColumnSettings: function createColumnSettings() { var assignedProps = filterPassedProps(this.$props); var columnSettings = _objectSpread2({}, assignedProps); if (assignedProps.renderer) { columnSettings.renderer = assignedProps.renderer; } if (assignedProps.editor) { columnSettings.editor = assignedProps.editor; } this.columnsCache.set(this, columnSettings); } }, mounted: function mounted() { this.createColumnSettings(); }, unmounted: function unmounted() { this.columnsCache["delete"](this); }, render: function render() { return null; } }); HotColumn.__file = "src/HotColumn.vue"; exports.HotColumn = HotColumn; exports.HotTable = HotTable; exports["default"] = HotTable;