@svgrid/grid 3.0.1 → 3.0.2

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 (77) hide show
  1. package/dist/GridFooter.svelte +14 -5
  2. package/dist/GridFooter.svelte.d.ts +8 -0
  3. package/dist/GridMenus.svelte +18 -10
  4. package/dist/GridMenus.svelte.d.ts +2 -1
  5. package/dist/SvGrid.controller.svelte.d.ts +17 -0
  6. package/dist/SvGrid.controller.svelte.js +128 -14
  7. package/dist/SvGrid.css +79 -10
  8. package/dist/SvGrid.svelte +191 -186
  9. package/dist/SvGrid.types.d.ts +42 -1
  10. package/dist/SvGridChart.svelte +571 -41
  11. package/dist/SvGridChart.svelte.d.ts +63 -1
  12. package/dist/SvGridChartPanel.svelte +169 -21
  13. package/dist/SvGridChartView.svelte +9 -0
  14. package/dist/SvGridChartView.svelte.d.ts +7 -0
  15. package/dist/SvGroupCell.svelte +28 -3
  16. package/dist/SvGroupCell.svelte.d.ts +8 -0
  17. package/dist/SvRowGroupPanel.svelte +20 -4
  18. package/dist/SvRowGroupPanel.svelte.d.ts +8 -0
  19. package/dist/ai.d.ts +11 -2
  20. package/dist/ai.js +51 -7
  21. package/dist/cdn/GridMenus-DyFA-QxA.js +602 -0
  22. package/dist/cdn/{GridMenus-DFB6iwF8.js → GridMenus-M2XP9t0_.js} +152 -150
  23. package/dist/cdn/SvGridChart-DAb9RbRs.js +1480 -0
  24. package/dist/cdn/SvGridChart-Yl-IXZFO.js +1481 -0
  25. package/dist/cdn/SvGridChartPanel-DayQpDsR.js +834 -0
  26. package/dist/cdn/SvGridChartPanel-aqf8n-vJ.js +810 -0
  27. package/dist/cdn/{SvGridChartView-BhUEJ5ki.js → SvGridChartView-CxfakxR0.js} +5 -3
  28. package/dist/cdn/{SvGridChartView-00LPUHL1.js → SvGridChartView-Dm_YEx9L.js} +5 -3
  29. package/dist/cdn/cell-formatting-C2Hf5gqd.js +86 -0
  30. package/dist/cdn/chart-CKJRCPOk.js +1652 -0
  31. package/dist/cdn/{export-format-Cv1Dll6k.js → export-format-CUDLy2yn.js} +84 -168
  32. package/dist/cdn/{src-C8QjSaq-.js → src-BJ2opd0j.js} +3608 -3414
  33. package/dist/cdn/{src-D0hO2eYN.js → src-DNbz94Ct.js} +8617 -8423
  34. package/dist/cdn/svgrid.js +16 -15
  35. package/dist/cdn/svgrid.svelte-external.js +16 -15
  36. package/dist/cell-formatting.d.ts +7 -0
  37. package/dist/cell-formatting.js +7 -1
  38. package/dist/chart-export.d.ts +23 -2
  39. package/dist/chart-export.js +80 -6
  40. package/dist/chart.d.ts +410 -18
  41. package/dist/chart.js +824 -24
  42. package/dist/grid-icons.d.ts +49 -0
  43. package/dist/grid-icons.js +86 -0
  44. package/dist/index.d.ts +3 -2
  45. package/dist/index.js +3 -2
  46. package/package.json +11 -11
  47. package/src/GridFooter.svelte +14 -5
  48. package/src/GridMenus.svelte +18 -10
  49. package/src/SvGrid.controller.svelte.ts +146 -13
  50. package/src/SvGrid.css +79 -10
  51. package/src/SvGrid.svelte +191 -186
  52. package/src/SvGrid.types.ts +42 -1
  53. package/src/SvGridChart.svelte +571 -41
  54. package/src/SvGridChart.test.ts +243 -1
  55. package/src/SvGridChartPanel.svelte +169 -21
  56. package/src/SvGridChartView.svelte +9 -0
  57. package/src/SvGroupCell.svelte +28 -3
  58. package/src/SvRowGroupPanel.svelte +20 -4
  59. package/src/ai.test.ts +60 -1
  60. package/src/ai.ts +59 -6
  61. package/src/cell-formatting.ts +7 -1
  62. package/src/chart-export.test.ts +112 -0
  63. package/src/chart-export.ts +76 -8
  64. package/src/chart.test.ts +830 -1
  65. package/src/chart.ts +1053 -32
  66. package/src/grid-icons.test.ts +46 -0
  67. package/src/grid-icons.ts +184 -0
  68. package/src/icon-overrides.grid.test.ts +188 -0
  69. package/src/icon-seam.test.ts +100 -0
  70. package/src/index.ts +19 -0
  71. package/src/svgrid.charting.test.ts +120 -0
  72. package/dist/cdn/GridMenus-CYzOvmNQ.js +0 -600
  73. package/dist/cdn/SvGridChart-BEJmNNx9.js +0 -1203
  74. package/dist/cdn/SvGridChart-BwVos976.js +0 -1202
  75. package/dist/cdn/SvGridChartPanel-BOknOkrP.js +0 -561
  76. package/dist/cdn/SvGridChartPanel-D2PjII4O.js +0 -585
  77. package/dist/cdn/chart-i4XcXyHJ.js +0 -1214
@@ -370,6 +370,126 @@ describe('SvGrid built-in charting', () => {
370
370
  expect(formatChartValue(1500, 'number')).toBe('1.5k')
371
371
  })
372
372
 
373
+ it('formats through Intl once a locale or currency is set, and not before', () => {
374
+ // The whole point of the opt-in: an existing chart keeps byte-identical
375
+ // labels. Intl's own compact form for en-US is '1.5K', capitalised, so
376
+ // routing everything through it would restyle every axis already shipped.
377
+ expect(formatChartValue(1500, 'currency', {})).toBe('$1.5k')
378
+ expect(formatChartValue(1500, 'currency', { locale: undefined, currency: undefined })).toBe('$1.5k')
379
+
380
+ // A currency alone is enough - the symbol is the thing that was wrong.
381
+ const eur = formatChartValue(1500, 'currency', { currency: 'EUR', locale: 'en-US' })
382
+ expect(eur).toContain('€')
383
+ expect(eur).not.toContain('$')
384
+ // A currency with no minor unit still renders (JPY has 0 decimals).
385
+ expect(formatChartValue(2500, 'currency', { currency: 'JPY', locale: 'en-US' })).toContain('¥')
386
+
387
+ // A locale alone localizes the separators and the compact suffix.
388
+ const de = formatChartValue(1500, 'number', { locale: 'de-DE' })
389
+ expect(de).not.toBe('1.5k')
390
+ expect(formatChartValue(1234, 'number', { locale: 'en-US' })).toBe('1.2K')
391
+
392
+ // `style: 'currency'` throws with no code, so a locale-only currency chart
393
+ // must still draw rather than take the whole grid down.
394
+ expect(() => formatChartValue(1500, 'currency', { locale: 'de-DE' })).not.toThrow()
395
+
396
+ expect(formatChartValue(0.25, 'percent', { locale: 'en-US' })).toBe('25%')
397
+ expect(formatChartValue(Number.NaN, 'currency', { currency: 'EUR' })).toBe('')
398
+ })
399
+
400
+ it("inherits the grid's localization.locale, and charting.locale overrides it", async () => {
401
+ // A chart of localized data reading in a different locale is the kind of bug
402
+ // nobody thinks to check, so the grid's own locale is the default.
403
+ {
404
+ const { api, destroy } = await mountGrid({ charting: true, localization: { locale: 'de-DE' } })
405
+ try {
406
+ api.configureChart({ dimension: 'team', measure: 'salary', reduce: 'sum' })
407
+ await tick()
408
+ expect(api.getChartSpec()!.locale).toBe('de-DE')
409
+ } finally { destroy() }
410
+ }
411
+ {
412
+ const { api, destroy } = await mountGrid({
413
+ charting: { locale: 'ja-JP', currency: 'JPY' },
414
+ localization: { locale: 'de-DE' },
415
+ })
416
+ try {
417
+ api.configureChart({ dimension: 'team', measure: 'salary', reduce: 'sum' })
418
+ await tick()
419
+ const spec = api.getChartSpec()!
420
+ expect(spec.locale).toBe('ja-JP')
421
+ expect(spec.currency).toBe('JPY')
422
+ } finally { destroy() }
423
+ }
424
+ {
425
+ // No localization anywhere: the spec stays locale-free, which is what
426
+ // keeps every existing chart rendering exactly as it did.
427
+ const { api, destroy } = await mountGrid({ charting: true })
428
+ try {
429
+ api.configureChart({ dimension: 'team', measure: 'salary', reduce: 'sum' })
430
+ await tick()
431
+ expect(api.getChartSpec()!.locale).toBeUndefined()
432
+ expect(api.getChartSpec()!.currency).toBeUndefined()
433
+ } finally { destroy() }
434
+ }
435
+ })
436
+
437
+ it('builds the row-reading types through the panel: scatter, gauge, box plot', async () => {
438
+ // These three do not go through `rowsToChartSpec`, so their dispatch is the
439
+ // one bit of chart wiring a bar-chart test never touches. It lives in the
440
+ // lazy engine to keep the controller out of the base bundle, which is
441
+ // exactly the kind of move that can silently stop building a spec.
442
+ const { api, destroy } = await mountGrid({ charting: true })
443
+ try {
444
+ api.configureChart({ type: 'boxplot', dimension: 'team', measure: 'salary' })
445
+ await tick()
446
+ const box = api.getChartSpec()!
447
+ expect(box.type).toBe('boxplot')
448
+ expect(box.series[0]!.boxes!.length).toBe(box.categories.length)
449
+ expect(box.series[0]!.boxes!.some((b) => b && Number.isFinite(b.median))).toBe(true)
450
+
451
+ api.configureChart({ type: 'gauge', measure: 'salary', reduce: 'avg' })
452
+ await tick()
453
+ expect(api.getChartSpec()!.type).toBe('gauge')
454
+ expect(api.getChartSpec()!.gaugeValue).toBeGreaterThan(0)
455
+
456
+ api.configureChart({ type: 'scatter', dimension: 'team', measure: 'age' })
457
+ await tick()
458
+ const scatter = api.getChartSpec()
459
+ // Whatever the Y measure resolves to, the one thing that must never
460
+ // happen is falling through and drawing a BAR chart under a "Scatter"
461
+ // label. Asserted unconditionally: a `if (scatter)` here would pass by
462
+ // doing nothing the day the dispatch stops building a spec.
463
+ expect(scatter === null || scatter.type === 'scatter').toBe(true)
464
+ expect(scatter?.type).not.toBe('bar')
465
+
466
+ // Back to a bar chart: the fall-through still works after the early
467
+ // returns above.
468
+ api.configureChart({ type: 'bar', dimension: 'team', measure: 'salary', reduce: 'sum' })
469
+ await tick()
470
+ expect(api.getChartSpec()!.type).toBe('bar')
471
+ expect(api.getChartSpec()!.series[0]!.values.length).toBeGreaterThan(0)
472
+ } finally {
473
+ destroy()
474
+ }
475
+ })
476
+
477
+ it('the localized format reaches the axis ticks, not just the helper', () => {
478
+ const geo = buildChart({
479
+ type: 'bar',
480
+ categories: ['a', 'b'],
481
+ series: [{ label: 'Revenue', values: [1500, 3000] }],
482
+ valueFormat: 'currency',
483
+ currency: 'EUR',
484
+ locale: 'en-US',
485
+ width: 400,
486
+ height: 300,
487
+ })
488
+ expect(geo.yTicks.length).toBeGreaterThan(0)
489
+ expect(geo.yTicks.some((t) => t.label.includes('€'))).toBe(true)
490
+ expect(geo.yTicks.every((t) => !t.label.includes('$'))).toBe(true)
491
+ })
492
+
373
493
  it('applies a value format and an auto y-axis title to the spec', async () => {
374
494
  const { api, destroy } = await mountGrid({ charting: { defaultOpen: true } })
375
495
  try {