Skip to content

Commit a2a3e6f

Browse files
committed
Merge branch 'release/3.0.0'
2 parents 76aaae5 + fd14592 commit a2a3e6f

File tree

260 files changed

+8111
-6855
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

260 files changed

+8111
-6855
lines changed

.config/babel/add-import-extension.js

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Based on https://github.com/handsontable/handsontable/blob/bd7628544ff83d6e74a9cc949e2c3c38fef74d76/handsontable/.config/plugin/babel/add-import-extension.js
2+
3+
const { existsSync, lstatSync } = require('fs');
4+
const { dirname, resolve } = require('path');
5+
const { types } = require('@babel/core');
6+
const { declare } = require('@babel/helper-plugin-utils');
7+
8+
const VALID_EXTENSIONS = ['js', 'mjs'];
9+
10+
const hasExtension = moduleName => VALID_EXTENSIONS.some(ext => moduleName.endsWith(`.${ext}`));
11+
const isCoreJSPolyfill = moduleName => moduleName.startsWith('core-js');
12+
const isLocalModule = moduleName => moduleName.startsWith('.');
13+
const isProcessableModule = (moduleName) => {
14+
return !hasExtension(moduleName) && (isCoreJSPolyfill(moduleName) || isLocalModule(moduleName));
15+
};
16+
17+
const createVisitor = ({ declaration, origArgs, extension = 'js' }) => {
18+
return (path, { file }) => {
19+
const { node: { source, exportKind, importKind } } = path;
20+
const { opts: { filename } } = file;
21+
const isTypeOnly = exportKind === 'type' || importKind === 'type';
22+
23+
if (!source || isTypeOnly || !isProcessableModule(source.value)) {
24+
return;
25+
}
26+
27+
const { value: moduleName } = source;
28+
const absoluteFilePath = resolve(dirname(filename), moduleName);
29+
const finalExtension = isCoreJSPolyfill(moduleName) ? 'js' : extension;
30+
31+
let newModulePath;
32+
33+
// Resolves a case where "import" points to a module name which exists as a file and
34+
// as a directory. For example in this case:
35+
// ```
36+
// import { registerPlugin } from 'plugins';
37+
// ```
38+
// and with this directory structure:
39+
// |- editors
40+
// |- plugins
41+
// |- filters/
42+
// |- ...
43+
// +- index.js
44+
// |- plugins.js
45+
// |- ...
46+
// +- index.js
47+
//
48+
// the plugin will rename import declaration to point to the `plugins.js` file.
49+
if (existsSync(`${absoluteFilePath}.js`)) {
50+
newModulePath = `${moduleName}.${finalExtension}`;
51+
52+
// In a case when the file doesn't exist and the module is a directory it will
53+
// rename to `plugins/index.js`.
54+
} else if (existsSync(absoluteFilePath) && lstatSync(absoluteFilePath).isDirectory()) {
55+
newModulePath = `${moduleName}/index.${finalExtension}`;
56+
57+
// And for other cases it simply put the extension on the end of the module path
58+
} else {
59+
newModulePath = `${moduleName}.${finalExtension}`;
60+
}
61+
62+
path.replaceWith(declaration(...origArgs(path), types.stringLiteral(newModulePath)));
63+
};
64+
};
65+
66+
module.exports = declare((api, options) => {
67+
api.assertVersion(7);
68+
69+
return {
70+
name: 'add-import-extension',
71+
visitor: {
72+
// It covers default and named imports
73+
ImportDeclaration: createVisitor({
74+
extension: options.extension,
75+
declaration: types.importDeclaration,
76+
origArgs: ({ node: { specifiers } }) => [specifiers],
77+
}),
78+
ExportNamedDeclaration: createVisitor({
79+
extension: options.extension,
80+
declaration: types.exportNamedDeclaration,
81+
origArgs: ({ node: { declaration, specifiers } }) => [declaration, specifiers],
82+
}),
83+
ExportAllDeclaration: createVisitor({
84+
extension: options.extension,
85+
declaration: types.exportAllDeclaration,
86+
origArgs: () => [],
87+
}),
88+
}
89+
};
90+
});

.config/karma/base.js

+3
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ module.exports.create = function(config) {
5858
// how many browser should be started simultaneous
5959
concurrency: Infinity,
6060

61+
// Extending timeout fixes https://github.com/handsontable/hyperformula/issues/1430
62+
browserDisconnectTimeout : 60000,
63+
6164
// Webpack's configuration for Karma
6265
webpack: (function() {
6366
// Take the second config from an array - full HF build.

.config/source-license-header.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
/**
22
* @license
3-
* Copyright (c) 2024 Handsoncode. All rights reserved.
3+
* Copyright (c) 2025 Handsoncode. All rights reserved.
44
*/

.github/workflows/test.yml

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ jobs:
3838
3939
- name: Upload coverage to Codecov
4040
uses: codecov/codecov-action@6004246f47ab62d32be025ce173b241cd84ac58e # https://github.com/codecov/codecov-action/releases/tag/v1.0.13
41+
env:
42+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
4143

4244
browser-tests:
4345
strategy:

CHANGELOG.md

+16
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
77

88
## [Unreleased]
99

10+
## [3.0.0] - 2025-01-14
11+
12+
### Added
13+
14+
- Added a new function: XLOOKUP. [#1458](https://github.com/handsontable/hyperformula/issues/1458)
15+
16+
### Changed
17+
18+
- **Breaking change**: Changed ES module build to use `mjs` files and `exports` property in `package.json` to make importing language files possible in Node environment. [#1344](https://github.com/handsontable/hyperformula/issues/1344)
19+
- **Breaking change**: Changed the default value of the `precisionRounding` configuration option to `10`. [#1300](https://github.com/handsontable/hyperformula/issues/1300)
20+
- Make methods `simpleCellAddressToString` and `simpleCellRangeToString` more logical and easier to use. [#1151](https://github.com/handsontable/hyperformula/issues/1151)
21+
22+
### Removed
23+
24+
- **Breaking change**: Removed the `binarySearchThreshold` configuration option. [#1439](https://github.com/handsontable/hyperformula/issues/1439)
25+
1026
## [2.7.1] - 2024-07-18
1127

1228
### Fixed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ hf.setCellContents({ sheet: sheetId, row: 0, col: 0 }, [['Monthly Payment', '=PM
9797
console.log(`${hf.getCellValue({ sheet: sheetId, row: 0, col: 0 })}: ${hf.getCellValue({ sheet: sheetId, row: 0, col: 1 })}`);
9898
```
9999

100-
[Run this code in CodeSandbox](https://codesandbox.io/p/sandbox/github/handsontable/hyperformula-demos/tree/2.7.x/mortgage-calculator)
100+
[Run this code in CodeSandbox](https://codesandbox.io/p/sandbox/github/handsontable/hyperformula-demos/tree/3.0.x/mortgage-calculator)
101101

102102
## Contributing
103103

babel.config.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ module.exports = {
99
['@babel/preset-env', {
1010
modules: false,
1111
useBuiltIns: 'usage',
12-
corejs: '3.23',
12+
corejs: '3.39.0',
1313
}]
1414
],
1515
plugins: [
@@ -18,7 +18,7 @@ module.exports = {
1818
helpers: false,
1919
regenerator: false,
2020
useESModules: false,
21-
version: '^7.18.9',
21+
version: '^7.25.9',
2222
}],
2323
['@babel/plugin-transform-modules-commonjs', { loose: true }]
2424
]
@@ -31,7 +31,9 @@ module.exports = {
3131
},
3232
// Environment for transpiling files to be compatible with ES Modules.
3333
es: {
34-
plugins: [],
34+
plugins: [
35+
['./.config/babel/add-import-extension.js', { extension: 'mjs' }],
36+
],
3537
},
3638
},
3739
};

docs/.vuepress/config.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ module.exports = {
1414
head: [
1515
// Import HF (required for the examples)
1616
[ 'script', { src: 'https://cdn.jsdelivr.net/npm/hyperformula/dist/hyperformula.full.min.js' } ],
17-
[ 'script', { src: 'https://cdn.jsdelivr.net/npm/hyperformula@2.7.1/dist/languages/enUS.js' } ],
18-
[ 'script', { src: 'https://cdn.jsdelivr.net/npm/hyperformula@2.7.1/dist/languages/frFR.js' } ],
17+
[ 'script', { src: 'https://cdn.jsdelivr.net/npm/hyperformula/dist/languages/enUS.js' } ],
18+
[ 'script', { src: 'https://cdn.jsdelivr.net/npm/hyperformula/dist/languages/frFR.js' } ],
1919
// Import moment (required for the examples)
2020
[ 'script', { src: 'https://cdn.jsdelivr.net/npm/moment/moment.min.js' } ],
2121
// Google Tag Manager, an extra element within the `ssr.html` file.
@@ -265,7 +265,8 @@ module.exports = {
265265
children: [
266266
['/guide/release-notes', 'Release notes'],
267267
['/guide/migration-from-0.6-to-1.0', 'Migrating from 0.6 to 1.0'],
268-
['/guide/migration-from-1.0-to-2.0', 'Migrating from 1.x to 2.0'],
268+
['/guide/migration-from-1.x-to-2.0', 'Migrating from 1.x to 2.0'],
269+
['/guide/migration-from-2.x-to-3.0', 'Migrating from 2.x to 3.0'],
269270
]
270271
},
271272
{

docs/examples/advanced-usage/example1.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
color: #606c76;
44
font-family: sans-serif;
55
font-size: 14px;
6-
font-weight: 300;
6+
font-weight: 400;
77
letter-spacing: .01em;
88
line-height: 1.6;
99
-webkit-box-sizing: border-box;

docs/examples/advanced-usage/example1.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula';
33

44
console.log(
55
`%c Using HyperFormula ${HyperFormula.version}`,
6-
'color: blue; font-weight: bold'
6+
'color: blue; font-weight: bold',
77
);
88

99
/* end:skip-in-compilation */
@@ -67,7 +67,7 @@ hf.setSheetContent(hf.getSheetId(sheetInfo.formulas.sheetName), formulasData);
6767
function renderTable(sheetName) {
6868
const sheetId = hf.getSheetId(sheetName);
6969
const tbodyDOM = document.querySelector(
70-
`.example #${sheetName}-container tbody`
70+
`.example #${sheetName}-container tbody`,
7171
);
7272

7373
const { height, width } = hf.getSheetDimensions(sheetId);
@@ -101,7 +101,7 @@ function renderResult() {
101101
const resultOutputDOM = document.querySelector('.example #output');
102102
const cellAddress = hf.simpleCellAddressFromString(
103103
`${sheetInfo.formulas.sheetName}!A1`,
104-
hf.getSheetId(sheetInfo.formulas.sheetName)
104+
hf.getSheetId(sheetInfo.formulas.sheetName),
105105
);
106106

107107
resultOutputDOM.innerHTML = `<span>

docs/examples/advanced-usage/example1.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula';
33

44
console.log(
55
`%c Using HyperFormula ${HyperFormula.version}`,
6-
'color: blue; font-weight: bold'
6+
'color: blue; font-weight: bold',
77
);
88
/* end:skip-in-compilation */
99

@@ -69,7 +69,7 @@ hf.setSheetContent(hf.getSheetId(sheetInfo.formulas.sheetName), formulasData);
6969
function renderTable(sheetName) {
7070
const sheetId = hf.getSheetId(sheetName);
7171
const tbodyDOM = document.querySelector(
72-
`.example #${sheetName}-container tbody`
72+
`.example #${sheetName}-container tbody`,
7373
);
7474

7575
const { height, width } = hf.getSheetDimensions(sheetId);
@@ -103,7 +103,7 @@ function renderResult() {
103103
const resultOutputDOM = document.querySelector('.example #output');
104104
const cellAddress = hf.simpleCellAddressFromString(
105105
`${sheetInfo.formulas.sheetName}!A1`,
106-
hf.getSheetId(sheetInfo.formulas.sheetName)
106+
hf.getSheetId(sheetInfo.formulas.sheetName),
107107
);
108108

109109
resultOutputDOM.innerHTML = `<span>

docs/examples/basic-operations/example1.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
color: #606c76;
44
font-family: sans-serif;
55
font-size: 14px;
6-
font-weight: 300;
6+
font-weight: 400;
77
letter-spacing: .01em;
88
line-height: 1.6;
99
-webkit-box-sizing: border-box;

docs/examples/basic-operations/example1.js

+6-10
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula';
33

44
console.log(
55
`%c Using HyperFormula ${HyperFormula.version}`,
6-
'color: blue; font-weight: bold'
6+
'color: blue; font-weight: bold',
77
);
88

99
/* end:skip-in-compilation */
@@ -188,9 +188,7 @@ function renderTable() {
188188
cellValue = hf.getCellFormula(cellAddress);
189189
}
190190

191-
newTbodyHTML += `<td class="${
192-
cellHasFormula ? updatedCellClass : ''
193-
}"><span>
191+
newTbodyHTML += `<td class="${cellHasFormula ? updatedCellClass : ''}"><span>
194192
${cellValue}
195193
</span></td>`;
196194
}
@@ -213,9 +211,7 @@ function updateSheetDropdown() {
213211
sheetNames.forEach((sheetName) => {
214212
const isCurrent = sheetName === state.currentSheet;
215213

216-
dropdownContent += `<option value="${sheetName}" ${
217-
isCurrent ? 'selected' : ''
218-
}>${sheetName}</option>`;
214+
dropdownContent += `<option value="${sheetName}" ${isCurrent ? 'selected' : ''}>${sheetName}</option>`;
219215
});
220216
sheetDropdownDOM.innerHTML = dropdownContent;
221217
}
@@ -332,7 +328,7 @@ function doAction(action) {
332328
handleError(() => {
333329
hf.setSheetContent(
334330
hf.getSheetId(state.currentSheet),
335-
getSampleData(5, 5)
331+
getSampleData(5, 5),
336332
);
337333
});
338334
updateSheetDropdown();
@@ -398,7 +394,7 @@ function doAction(action) {
398394
cellAddress = handleError(() => {
399395
return hf.simpleCellAddressFromString(
400396
inputValues[0],
401-
hf.getSheetId(state.currentSheet)
397+
hf.getSheetId(state.currentSheet),
402398
);
403399
}, 'Invalid cell address format.');
404400

@@ -413,7 +409,7 @@ function doAction(action) {
413409
cellAddress = handleError(() => {
414410
return hf.simpleCellAddressFromString(
415411
inputValues[0],
416-
hf.getSheetId(state.currentSheet)
412+
hf.getSheetId(state.currentSheet),
417413
);
418414
}, 'Invalid cell address format.');
419415

docs/examples/basic-operations/example1.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula';
33

44
console.log(
55
`%c Using HyperFormula ${HyperFormula.version}`,
6-
'color: blue; font-weight: bold'
6+
'color: blue; font-weight: bold',
77
);
88
/* end:skip-in-compilation */
99

@@ -343,7 +343,7 @@ function doAction(action) {
343343
handleError(() => {
344344
hf.setSheetContent(
345345
hf.getSheetId(state.currentSheet),
346-
getSampleData(5, 5)
346+
getSampleData(5, 5),
347347
);
348348
});
349349

@@ -415,7 +415,7 @@ function doAction(action) {
415415
cellAddress = handleError(() => {
416416
return hf.simpleCellAddressFromString(
417417
inputValues[0],
418-
hf.getSheetId(state.currentSheet)
418+
hf.getSheetId(state.currentSheet),
419419
);
420420
}, 'Invalid cell address format.');
421421

@@ -430,7 +430,7 @@ function doAction(action) {
430430
cellAddress = handleError(() => {
431431
return hf.simpleCellAddressFromString(
432432
inputValues[0],
433-
hf.getSheetId(state.currentSheet)
433+
hf.getSheetId(state.currentSheet),
434434
);
435435
}, 'Invalid cell address format.');
436436

docs/examples/basic-usage/example1.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
color: #606c76;
44
font-family: sans-serif;
55
font-size: 14px;
6-
font-weight: 300;
6+
font-weight: 400;
77
letter-spacing: .01em;
88
line-height: 1.6;
99
-webkit-box-sizing: border-box;

docs/examples/basic-usage/example1.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ import HyperFormula from 'hyperformula';
33

44
console.log(
55
`%c Using HyperFormula ${HyperFormula.version}`,
6-
'color: blue; font-weight: bold'
6+
'color: blue; font-weight: bold',
77
);
88

99
/* end:skip-in-compilation */
1010
const tableData = [['10', '20', '=SUM(A1,B1)']];
1111
// Create an empty HyperFormula instance.
1212
const hf = HyperFormula.buildEmpty({
13-
precisionRounding: 10,
13+
precisionRounding: 9,
1414
licenseKey: 'gpl-v3',
1515
});
1616

@@ -25,7 +25,7 @@ hf.setCellContents(
2525
col: 0,
2626
sheet: sheetId,
2727
},
28-
tableData
28+
tableData,
2929
);
3030

3131
/**

0 commit comments

Comments
 (0)