@chalabi/svelte-sheets 2.0.3 → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/Sheet.svelte +55 -24
  2. package/package.json +1 -1
package/dist/Sheet.svelte CHANGED
@@ -180,45 +180,58 @@ export function onInputChange(value, row, column) {
180
180
  }
181
181
  function refresh(data, viewport_height, viewport_width) {
182
182
  return __awaiter(this, void 0, void 0, function* () {
183
+ if (!viewport)
184
+ return;
183
185
  const { scrollTop, scrollLeft } = viewport;
184
186
  yield tick(); // wait until the DOM is up to date
187
+ const defaultHeight = 24;
188
+ const defaultWidth = config.defaultColWidth || 50;
189
+ // Safety limits to prevent infinite loops
190
+ const maxRowsToRender = Math.max(data.length, Math.ceil((viewport_height + bottom_buffer * 2) / defaultHeight) + 10, 100);
191
+ const maxColsToRender = Math.max(columns.length, Math.ceil((viewport_width + right_buffer * 2) / defaultWidth) + 10, 50);
185
192
  let content_height = top - scrollTop - bottom_buffer;
186
193
  let content_width = left - scrollLeft - left_buffer;
187
194
  // vertical
188
195
  let y = startY;
189
- while (content_height < viewport_height) {
196
+ while (content_height < viewport_height && y < maxRowsToRender) {
190
197
  let row = rowElements[y - startY];
191
198
  if (!row) {
192
199
  endY = y + 1;
193
200
  yield tick(); // render the newly visible row
194
201
  row = rowElements[y - startY];
202
+ // If still no row after tick, break to prevent infinite loop
203
+ if (!row)
204
+ break;
195
205
  }
196
206
  const row_height = (height_map[y] = getRowHeight(y));
197
207
  content_height += row_height;
198
208
  y += 1;
199
209
  }
200
- endY = y;
210
+ endY = Math.max(y, 1);
201
211
  let remaining = data.length - endY;
202
- average_height = (top + content_height) / endY;
203
- bottom = remaining * average_height;
212
+ average_height = endY > 0 ? (top + content_height) / endY : defaultHeight;
213
+ bottom = remaining * (average_height || defaultHeight);
204
214
  height_map.length = data.length;
205
215
  // horizontal
206
216
  let x = startX;
207
- while (content_width < viewport_width) {
217
+ while (content_width < viewport_width && x < maxColsToRender) {
208
218
  let col = colElements[x - startX];
209
219
  if (!col) {
210
220
  endX = x + 1;
211
221
  yield tick(); // render the newly visible col
212
222
  col = colElements[x - startX];
223
+ // If still no col after tick, break to prevent infinite loop
224
+ if (!col)
225
+ break;
213
226
  }
214
227
  const col_width = (width_map[x] = getColumnsWidth(x));
215
228
  content_width += col_width;
216
229
  x += 1;
217
230
  }
218
- endX = x;
231
+ endX = Math.max(x, 1);
219
232
  let remains = columns.length - endX;
220
- average_width = (left + content_width) / endX;
221
- right = remains * average_width;
233
+ average_width = endX > 0 ? (left + content_width) / endX : defaultWidth;
234
+ right = remains * (average_width || defaultWidth);
222
235
  width_map.length = columns.length;
223
236
  });
224
237
  }
@@ -229,6 +242,9 @@ let scrollTop;
229
242
  $: (function scrollX() {
230
243
  if (scrollLeft === undefined || !colElements)
231
244
  return;
245
+ // Ensure we have valid dimensions to work with
246
+ const totalCols = Math.max(columns.length, endX, 1);
247
+ const defaultWidth = config.defaultColWidth || 50;
232
248
  // if (!scrollLeft) ;
233
249
  // horizontal scrolling
234
250
  for (let v = 0; v < colElements.length; v += 1) {
@@ -236,8 +252,8 @@ $: (function scrollX() {
236
252
  }
237
253
  let c = 0;
238
254
  let x = 0;
239
- while (true) {
240
- const col_width = width_map[c] || average_width;
255
+ while (c < totalCols) {
256
+ const col_width = width_map[c] || average_width || defaultWidth;
241
257
  if (x + col_width > scrollLeft - left_buffer) {
242
258
  startX = c;
243
259
  left = x;
@@ -246,31 +262,40 @@ $: (function scrollX() {
246
262
  x += col_width;
247
263
  c += 1;
248
264
  }
249
- while (true) {
250
- x += width_map[c] || average_width;
265
+ // Safety: ensure we found a valid startX
266
+ if (c >= totalCols) {
267
+ startX = Math.max(0, totalCols - 1);
268
+ left = x;
269
+ }
270
+ while (c < totalCols + Math.ceil((viewport_width + right_buffer) / defaultWidth)) {
271
+ const w = width_map[c] || average_width || defaultWidth;
272
+ x += w;
251
273
  c += 1;
252
274
  if (x > scrollLeft + viewport_width + right_buffer)
253
275
  break;
254
276
  }
255
- endX = c;
277
+ endX = Math.max(c, 1);
256
278
  const remaining = endX > columns.length
257
- ? (viewport_width + right_buffer) / 24
279
+ ? (viewport_width + right_buffer) / defaultWidth
258
280
  : columns.length - endX;
259
- average_width = x / endX;
281
+ average_width = endX > 0 ? x / endX : defaultWidth;
260
282
  // while (c < columns.length) width_map[c++] = average_width;
261
- right = remaining * average_width;
283
+ right = remaining * (average_width || defaultWidth);
262
284
  })();
263
285
  $: (function scrollY() {
264
286
  if (scrollTop === undefined || !rowElements)
265
287
  return;
288
+ // Ensure we have valid dimensions to work with
289
+ const totalRows = Math.max(data.length, endY, 1);
290
+ const defaultHeight = 24;
266
291
  // vertical scrolling
267
292
  for (let v = 0; v < rowElements.length; v += 1) {
268
293
  height_map[startY + v] = getRowHeight(startY + v);
269
294
  }
270
295
  let r = 0;
271
296
  let y = 0;
272
- while (true) {
273
- const row_height = height_map[r] || average_height;
297
+ while (r < totalRows) {
298
+ const row_height = height_map[r] || average_height || defaultHeight;
274
299
  if (y + row_height > scrollTop - top_buffer) {
275
300
  startY = r;
276
301
  top = y;
@@ -279,19 +304,25 @@ $: (function scrollY() {
279
304
  y += row_height;
280
305
  r += 1;
281
306
  }
282
- while (true) {
283
- y += height_map[r] || average_height;
307
+ // Safety: ensure we found a valid startY
308
+ if (r >= totalRows) {
309
+ startY = Math.max(0, totalRows - 1);
310
+ top = y;
311
+ }
312
+ while (r < totalRows + Math.ceil((viewport_height + bottom_buffer) / defaultHeight)) {
313
+ const h = height_map[r] || average_height || defaultHeight;
314
+ y += h;
284
315
  r += 1;
285
316
  if (y > scrollTop + viewport_height + bottom_buffer)
286
317
  break;
287
318
  }
288
- endY = r;
319
+ endY = Math.max(r, 1);
289
320
  const remaining = endY > data.length
290
- ? (viewport_height + bottom_buffer) / 24
321
+ ? (viewport_height + bottom_buffer) / defaultHeight
291
322
  : data.length - endY;
292
- average_height = y / endY;
323
+ average_height = endY > 0 ? y / endY : defaultHeight;
293
324
  // while (r < data.length) height_map[r++] = average_height;
294
- bottom = remaining * average_height;
325
+ bottom = remaining * (average_height || defaultHeight);
295
326
  })();
296
327
  function handle_scroll(e) {
297
328
  scrollTop = viewport.scrollTop;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chalabi/svelte-sheets",
3
- "version": "2.0.3",
3
+ "version": "2.0.4",
4
4
  "description": "Run your excel sheet in the browser!",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",