basalt-ui 1.31.0 → 1.32.0

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 (91) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/MIGRATING.md +101 -17
  3. package/agent/rules/basalt-mantine.md +4 -4
  4. package/configs/oxlint-plugin.js +159 -42
  5. package/configs/oxlint-plugin.test.ts +182 -0
  6. package/dist/charts/kinds/BandStrip.d.ts.map +1 -1
  7. package/dist/charts/kinds/BandStrip.js +18 -66
  8. package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
  9. package/dist/charts/kinds/DualPanel.js +5 -26
  10. package/dist/charts/kinds/MirroredBars.d.ts.map +1 -1
  11. package/dist/charts/kinds/MirroredBars.js +10 -68
  12. package/dist/charts/kinds/band-chrome.d.ts +31 -0
  13. package/dist/charts/kinds/band-chrome.d.ts.map +1 -0
  14. package/dist/charts/kinds/band-chrome.js +71 -0
  15. package/dist/charts/primitives/CartesianChart.d.ts.map +1 -1
  16. package/dist/charts/primitives/CartesianChart.js +49 -76
  17. package/dist/charts/primitives/ChartCard.d.ts.map +1 -1
  18. package/dist/charts/primitives/ChartCard.js +5 -23
  19. package/dist/charts/primitives/ChartFrame.d.ts.map +1 -1
  20. package/dist/charts/primitives/ChartFrame.js +23 -40
  21. package/dist/charts/primitives/ChartLegend.d.ts.map +1 -1
  22. package/dist/charts/primitives/ChartLegend.js +5 -133
  23. package/dist/charts/primitives/ChartTooltip.d.ts +5 -0
  24. package/dist/charts/primitives/ChartTooltip.d.ts.map +1 -1
  25. package/dist/charts/primitives/ChartTooltip.js +16 -1
  26. package/dist/charts/primitives/HoverOverlay.d.ts +24 -9
  27. package/dist/charts/primitives/HoverOverlay.d.ts.map +1 -1
  28. package/dist/charts/primitives/HoverOverlay.js +17 -1
  29. package/dist/charts/primitives/chart-card-context.d.ts +17 -13
  30. package/dist/charts/primitives/chart-card-context.d.ts.map +1 -1
  31. package/dist/charts/primitives/chart-card-context.js +10 -5
  32. package/dist/charts/primitives/chart-frame-layout.d.ts.map +1 -1
  33. package/dist/charts/primitives/chart-frame-layout.js +25 -31
  34. package/dist/charts/primitives/legend-disclosure.d.ts +27 -0
  35. package/dist/charts/primitives/legend-disclosure.d.ts.map +1 -0
  36. package/dist/charts/primitives/legend-disclosure.js +153 -0
  37. package/dist/controls/controls.module.css +5 -0
  38. package/dist/controls/sync-button.module.css +1 -0
  39. package/dist/dashboard/stat-group.module.css +19 -64
  40. package/dist/dashboard/widget-grid.module.css +11 -38
  41. package/dist/data/data-table-state.d.ts +83 -0
  42. package/dist/data/data-table-state.d.ts.map +1 -0
  43. package/dist/data/data-table-state.js +139 -0
  44. package/dist/data/data-table.d.ts +33 -2
  45. package/dist/data/data-table.d.ts.map +1 -1
  46. package/dist/data/data-table.js +179 -277
  47. package/dist/forms/form-layout.module.css +3 -13
  48. package/dist/guard/index.d.ts.map +1 -1
  49. package/dist/guard/index.js +6 -5
  50. package/dist/notifications/center.d.ts.map +1 -1
  51. package/dist/provider/index.d.ts.map +1 -1
  52. package/dist/provider/index.js +12 -10
  53. package/dist/shell/aside-docking.d.ts +31 -0
  54. package/dist/shell/aside-docking.d.ts.map +1 -0
  55. package/dist/shell/aside-docking.js +19 -0
  56. package/dist/shell/index.d.ts +0 -11
  57. package/dist/shell/index.d.ts.map +1 -1
  58. package/dist/shell/index.js +13 -14
  59. package/dist/shell/use-breakpoint.d.ts +1 -1
  60. package/dist/theme/floating.module.css +1 -0
  61. package/dist/theme-lab/derive-controls.d.ts.map +1 -1
  62. package/llms.txt +2 -2
  63. package/package.json +2 -1
  64. package/src/charts/kinds/BandStrip.tsx +18 -64
  65. package/src/charts/kinds/DualPanel.tsx +4 -24
  66. package/src/charts/kinds/MirroredBars.tsx +12 -66
  67. package/src/charts/kinds/band-chrome.tsx +91 -0
  68. package/src/charts/primitives/CartesianChart.tsx +79 -122
  69. package/src/charts/primitives/ChartCard.tsx +5 -27
  70. package/src/charts/primitives/ChartFrame.tsx +37 -76
  71. package/src/charts/primitives/ChartLegend.tsx +7 -154
  72. package/src/charts/primitives/ChartTooltip.tsx +16 -0
  73. package/src/charts/primitives/HoverOverlay.tsx +52 -21
  74. package/src/charts/primitives/chart-card-context.ts +25 -16
  75. package/src/charts/primitives/chart-frame-layout.ts +44 -56
  76. package/src/charts/primitives/legend-disclosure.tsx +177 -0
  77. package/src/controls/controls.module.css +5 -0
  78. package/src/controls/sync-button.module.css +1 -0
  79. package/src/dashboard/stat-group.module.css +19 -64
  80. package/src/dashboard/widget-grid.module.css +11 -38
  81. package/src/data/data-table-state.ts +218 -0
  82. package/src/data/data-table.tsx +127 -218
  83. package/src/forms/form-layout.module.css +3 -13
  84. package/src/guard/index.ts +21 -16
  85. package/src/notifications/center.tsx +3 -0
  86. package/src/provider/index.tsx +18 -17
  87. package/src/shell/aside-docking.ts +54 -0
  88. package/src/shell/index.tsx +15 -37
  89. package/src/shell/use-breakpoint.ts +2 -2
  90. package/src/theme/floating.module.css +1 -0
  91. package/src/theme-lab/derive-controls.tsx +2 -0
@@ -19,15 +19,18 @@ import basaltPlugin, {
19
19
  KNOWN_RULE_IDS,
20
20
  PLUGIN_RULE_ADVISORY,
21
21
  PLUGIN_RULE_GRACE,
22
+ RAW_BREAKPOINT_RECIPE,
22
23
  RETIRED_RULE_IDS,
23
24
  } from './oxlint-plugin.js'
24
25
  import { CTL_THEME } from '../src/theme/ctl-theme'
25
26
  import {
27
+ GRACE_PERIOD_KINDS,
26
28
  GUARD_RULES,
27
29
  PLUGIN_RULE_IDS,
28
30
  WAIVER_ID_ALIASES as GUARD_WAIVER_ID_ALIASES,
29
31
  } from '../src/guard/index.ts'
30
32
  import { PLUGIN_RULE_ID_LIST, SURFACES } from '../src/surfaces.ts'
33
+ import { CONTAINER_CLASSES } from '../src/tokens/size-classes.ts'
31
34
 
32
35
  const PLUGIN_PATH = resolve(import.meta.dirname, 'oxlint-plugin.js')
33
36
  const OXLINT_BIN = resolve(import.meta.dirname, '..', '..', '..', 'node_modules', '.bin', 'oxlint')
@@ -1332,6 +1335,42 @@ describe('assertGraceLedger', () => {
1332
1335
  })
1333
1336
  })
1334
1337
 
1338
+ // ── twin lanes: one law, two lanes, one promotion ─────────────────────────────
1339
+ // A guard kind and a plugin rule that enforce ONE law in two lanes (CSS/text vs. JSX AST) must
1340
+ // promote together — a consumer failing one spelling and warned on the other is the confusion the
1341
+ // pairing exists to prevent. `raw-media-query` split from `basalt/raw-breakpoint` exactly that way
1342
+ // (1.32.0 vs 1.33.0). Twins are DERIVED, not hand-listed, from the two places they are declared: a
1343
+ // `WAIVER_ID_ALIASES` pair, and a guard entry whose `why` calls itself the twin of `basalt/<id>`.
1344
+
1345
+ const pluginGrace = PLUGIN_RULE_GRACE as Record<string, GraceEntry>
1346
+ const guardGrace = GRACE_PERIOD_KINDS as Record<string, GraceEntry>
1347
+
1348
+ function twinLanes(): Array<[kind: string, rule: string]> {
1349
+ const pairs = new Map<string, string>()
1350
+ for (const [kind, aliases] of Object.entries(WAIVER_ID_ALIASES)) {
1351
+ for (const rule of aliases) if (kind in guardGrace || rule in pluginGrace) pairs.set(kind, rule)
1352
+ }
1353
+ for (const [kind, entry] of Object.entries(guardGrace)) {
1354
+ const match = /twin of the oxlint plugin's `basalt\/([a-z-]+)`/.exec(entry.why)
1355
+ if (match?.[1] !== undefined) pairs.set(kind, match[1])
1356
+ }
1357
+ return [...pairs].filter(([kind]) => kind in guardGrace)
1358
+ }
1359
+
1360
+ describe('twin lanes share one promotion', () => {
1361
+ it('derives the raw-media-query ↔ raw-breakpoint pair (the derivation is not silently empty)', () => {
1362
+ expect(twinLanes()).toContainEqual(['raw-media-query', 'raw-breakpoint'])
1363
+ })
1364
+
1365
+ it.each(twinLanes())('%s and basalt/%s are both in grace with the same promote', (kind, rule) => {
1366
+ expect([kind, rule, guardGrace[kind]?.promote]).toEqual([
1367
+ kind,
1368
+ rule,
1369
+ pluginGrace[rule]?.promote,
1370
+ ])
1371
+ })
1372
+ })
1373
+
1335
1374
  describe('PLUGIN_RULE_GRACE', () => {
1336
1375
  const shipped = JSON.parse(readFileSync(resolve(import.meta.dirname, 'oxlint.json'), 'utf8')) as {
1337
1376
  rules: Record<string, unknown>
@@ -3467,6 +3506,149 @@ describe('basalt/raw-breakpoint', () => {
3467
3506
  expect(rules).not.toContain('raw-breakpoint')
3468
3507
  })
3469
3508
 
3509
+ // The recipe's px keys are CONTAINER_CLASSES written out by hand in two places — the plugin
3510
+ // (plain JS, cannot import TS source) and MIGRATING's rule entry. Retuning a class must fail here.
3511
+ describe('recipe px literals ↔ CONTAINER_CLASSES', () => {
3512
+ const boundaries = new Set<number>(Object.values(CONTAINER_CLASSES).filter((px) => px > 0))
3513
+ const pxLiterals = (text: string) => [...text.matchAll(/(\d+)px/g)].map((m) => Number(m[1]))
3514
+
3515
+ it('every px key in the rule messages is a CONTAINER_CLASSES boundary', () => {
3516
+ const found = pxLiterals(RAW_BREAKPOINT_RECIPE as string)
3517
+ expect(found.length).toBeGreaterThan(0)
3518
+ for (const px of found) expect([px, boundaries.has(px)]).toEqual([px, true])
3519
+ })
3520
+
3521
+ it("every px value and the class table in MIGRATING's raw-breakpoint entry match", () => {
3522
+ const migrating = readFileSync(resolve(import.meta.dir, '../MIGRATING.md'), 'utf8')
3523
+ const start = migrating.indexOf('### `basalt/raw-breakpoint`')
3524
+ expect(start).toBeGreaterThan(-1)
3525
+ const end = migrating.indexOf('\n### ', start + 1)
3526
+ const section = migrating.slice(start, end === -1 ? undefined : end)
3527
+ for (const px of pxLiterals(section)) expect([px, boundaries.has(px)]).toEqual([px, true])
3528
+ const { compact, regular, wide } = CONTAINER_CLASSES
3529
+ expect(section).toContain(`compact ${compact} · regular ${regular} · wide ${wide}`)
3530
+ })
3531
+ })
3532
+
3533
+ // The sanctioned answer, read from @mantine/core 9.3 source: SimpleGrid type="container" writes
3534
+ // each key verbatim as `@container simple-grid (min-width: <key>)`, Grid type="container" only
3535
+ // goes container WITH a `breakpoints` map. Exempt exactly where Mantine resolves the object.
3536
+ describe('Mantine type="container" grids', () => {
3537
+ const grid = (jsx: string) =>
3538
+ run(`import { Grid, SimpleGrid } from '@mantine/core'\nexport const C = () => ${jsx}\n`)
3539
+ const CONTAINER_MESSAGE = /Theme breakpoint name under type="container"/
3540
+
3541
+ it('does NOT flag a px-keyed container SimpleGrid (the recipe)', () => {
3542
+ expect(
3543
+ grid(`<SimpleGrid type="container" cols={{ base: 1, '480px': 2, '800px': 3 }} />`).rules,
3544
+ ).not.toContain('raw-breakpoint')
3545
+ })
3546
+
3547
+ it('does NOT flag a lone `base` under type="container"', () => {
3548
+ expect(grid(`<SimpleGrid type="container" cols={{ base: 2 }} />`).rules).not.toContain(
3549
+ 'raw-breakpoint',
3550
+ )
3551
+ })
3552
+
3553
+ it('flags a theme-named key on a container SimpleGrid — Mantine emits a dead (min-width: sm)', () => {
3554
+ const { rules, output } = grid(`<SimpleGrid type="container" cols={{ base: 1, sm: 2 }} />`)
3555
+ expect(rules).toContain('raw-breakpoint')
3556
+ expect(CONTAINER_MESSAGE.test(output)).toBe(true)
3557
+ })
3558
+
3559
+ it('still flags type="media" (and a dynamic type) with the viewport message', () => {
3560
+ for (const type of [`"media"`, `{kind}`]) {
3561
+ const { rules, output } = grid(`<SimpleGrid type=${type} cols={{ base: 1, sm: 2 }} />`)
3562
+ expect(rules).toContain('raw-breakpoint')
3563
+ expect(CONTAINER_MESSAGE.test(output)).toBe(false)
3564
+ }
3565
+ })
3566
+
3567
+ it('does NOT flag Grid.Col spans under a container Grid with a breakpoints map', () => {
3568
+ const src =
3569
+ `<Grid type="container" breakpoints={{ xs: '240px', sm: '480px' }}>\n` +
3570
+ ` {items.map((i) => <Grid.Col key={i} span={{ base: 12, sm: 6 }}>x</Grid.Col>)}\n` +
3571
+ `</Grid>`
3572
+ expect(grid(src).rules).not.toContain('raw-breakpoint')
3573
+ })
3574
+
3575
+ it('flags Grid.Col spans under a container Grid with NO breakpoints — Mantine falls back to media', () => {
3576
+ const { rules, output } = grid(
3577
+ `<Grid type="container"><Grid.Col span={{ base: 12, sm: 6 }}>x</Grid.Col></Grid>`,
3578
+ )
3579
+ expect(rules).toContain('raw-breakpoint')
3580
+ expect(CONTAINER_MESSAGE.test(output)).toBe(true)
3581
+ })
3582
+
3583
+ it('reports a const-extracted theme-keyed object on a container SimpleGrid — still a dead query', () => {
3584
+ const { rules, output } = run(
3585
+ `import { SimpleGrid } from '@mantine/core'\n` +
3586
+ `const cols = { base: 1, sm: 2 }\n` +
3587
+ `export const C = () => <SimpleGrid type="container" cols={cols} />\n`,
3588
+ )
3589
+ expect(rules).toContain('raw-breakpoint')
3590
+ expect(CONTAINER_MESSAGE.test(output)).toBe(true)
3591
+ })
3592
+
3593
+ // Grid goes container only on a truthy map, and an empty one emits no query — so the exemption
3594
+ // needs a map that statically resolves to a non-empty object, not the attribute's presence.
3595
+ it.each([
3596
+ ['undefined', `breakpoints={undefined}`, ''],
3597
+ ['an empty object', `breakpoints={{}}`, ''],
3598
+ ['an unresolvable identifier', `breakpoints={imported}`, `import { imported } from './bp'\n`],
3599
+ ])('flags Grid.Col spans under a container Grid whose breakpoints is %s', (_, bp, extra) => {
3600
+ const { rules, output } = run(
3601
+ `import { Grid } from '@mantine/core'\n${extra}` +
3602
+ `export const C = () => <Grid type="container" ${bp}><Grid.Col span={{ base: 12, sm: 6 }}>x</Grid.Col></Grid>\n`,
3603
+ )
3604
+ expect(rules).toContain('raw-breakpoint')
3605
+ expect(CONTAINER_MESSAGE.test(output)).toBe(true)
3606
+ })
3607
+
3608
+ it('does NOT flag Grid.Col spans under a container Grid whose breakpoints is a same-file const', () => {
3609
+ const { rules } = run(
3610
+ `import { Grid } from '@mantine/core'\n` +
3611
+ `const bp = { xs: '240px', sm: '480px', md: '800px', lg: '800px', xl: '800px' }\n` +
3612
+ `export const C = () => <Grid type="container" breakpoints={bp}><Grid.Col span={{ base: 12, sm: 6 }}>x</Grid.Col></Grid>\n`,
3613
+ )
3614
+ expect(rules).not.toContain('raw-breakpoint')
3615
+ })
3616
+
3617
+ // Only the grid-keyed props route through the container queries; Box style props on the same
3618
+ // element still compile to viewport @media, so they keep the ordinary viewport message.
3619
+ it.each([
3620
+ [
3621
+ 'SimpleGrid p',
3622
+ `<SimpleGrid type="container" cols={{ base: 1, '480px': 2 }} p={{ base: 'xs', lg: 'md' }} />`,
3623
+ ],
3624
+ [
3625
+ 'Grid mt',
3626
+ `<Grid type="container" breakpoints={{ xs: '240px', sm: '480px', md: '800px', lg: '800px', xl: '800px' }} mt={{ base: 0, sm: 'md' }}>x</Grid>`,
3627
+ ],
3628
+ [
3629
+ 'Grid.Col mih',
3630
+ `<Grid type="container" breakpoints={{ xs: '240px', sm: '480px', md: '800px', lg: '800px', xl: '800px' }}><Grid.Col span={6} mih={{ base: 80, lg: 120 }}>x</Grid.Col></Grid>`,
3631
+ ],
3632
+ ])('flags a Box style prop on a container grid as viewport (%s)', (_, jsx) => {
3633
+ const { rules, output } = grid(jsx)
3634
+ expect(rules).toContain('raw-breakpoint')
3635
+ expect(CONTAINER_MESSAGE.test(output)).toBe(false)
3636
+ })
3637
+
3638
+ it('does NOT flag container-routed spacing props on a container grid', () => {
3639
+ const src =
3640
+ `<Grid type="container" breakpoints={{ xs: '240px', sm: '480px', md: '800px', lg: '800px', xl: '800px' }} gap={{ base: 'xs', sm: 'md' }}>` +
3641
+ `<Grid.Col span={{ base: 12, sm: 6 }} order={{ base: 2, sm: 1 }}>x</Grid.Col></Grid>`
3642
+ expect(grid(src).rules).not.toContain('raw-breakpoint')
3643
+ })
3644
+
3645
+ it('still flags Grid.Col spans under an ordinary Grid', () => {
3646
+ expect(
3647
+ grid(`<Grid><Grid.Col span={{ base: 12, sm: 6 }}>x</Grid.Col></Grid>`).rules,
3648
+ ).toContain('raw-breakpoint')
3649
+ })
3650
+ })
3651
+
3470
3652
  it('flags visibleFrom/hiddenFrom outside a shell home', () => {
3471
3653
  const { rules } = run(
3472
3654
  `import { Box } from '@mantine/core'\n` +
@@ -1 +1 @@
1
- {"version":3,"file":"BandStrip.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/BandStrip.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BandStrip.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/BandStrip.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAEvE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAIrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAK/D;;;GAGG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,WAAW,GAAG;IAC7C;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,GAAG,IAAI,CAAA;CACtC,CAAA;AAED,0FAA0F;AAC1F,MAAM,MAAM,QAAQ,GAAG;IACrB;;;;;;;;;OASG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;OAIG;IACH,MAAM,CAAC,EAAE;QACP,iFAAiF;QACjF,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,uEAAuE;QACvE,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,CAAA;CACF,CAAA;AAED,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,WAAW,GAAG;IAC5C,IAAI,EAAE,SAAS,CAAC,EAAE,CAAA;IAClB,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAA;IACf;yFACqF;IACrF,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB;sCACkC;IAClC,MAAM,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAA;IACrC,oCAAoC;IACpC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,QAAQ,CAAA;IAC3B;;uFAEmF;IACnF,MAAM,CAAC,EAAE,MAAM,GAAG,qBAAqB,CAAA;IACvC,+EAA+E;IAC/E,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,6DAA6D;IAC7D,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IACjC,mDAAmD;IACnD,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,KAAK,SAAS,MAAM,EAAE,CAAA;IAC/E,4EAA4E;IAC5E,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;IAClB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,OAAO,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAA;IACtC,MAAM,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAClC;;;;;wEAKoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iEAAiE;IACjE,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;IAC7B;iDAC6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;4FACwF;IACxF,KAAK,CAAC,EAAE,UAAU,CAAA;CACnB,CAAA;AA2CD;;;;;;;;;;;;;GAaG;AACH,iBAAS,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,+BAwBlD;AA0OD,eAAO,MAAM,SAAS,EAAoB,OAAO,cAAc,CAAA"}
@@ -4,18 +4,12 @@ import { memo, useMemo } from "react";
4
4
  import { assertRequiredProps } from "../../common/validate.js";
5
5
  import { VX, alpha } from "../../tokens/index.js";
6
6
  import { useBandPlot } from "../hooks/useBandPlot.js";
7
- import { AxisBottomDate } from "../primitives/Axes.js";
8
7
  import { ChartFrame, resolveLegend } from "../primitives/ChartFrame.js";
9
- import {
10
- ChartTooltipFloat,
11
- TooltipBody,
12
- TooltipHeader,
13
- TooltipRow
14
- } from "../primitives/ChartTooltip.js";
8
+ import { TooltipRow } from "../primitives/ChartTooltip.js";
15
9
  import { Crosshair } from "../primitives/Crosshair.js";
16
10
  import { HatchPattern, hatchFill, hatchSizeFor } from "../primitives/HatchPattern.js";
17
- import { HoverOverlay } from "../primitives/HoverOverlay.js";
18
11
  import { fmtAxisDate } from "../utils/format.js";
12
+ import { BandAxisOverlay, BandTooltip, clampFraction } from "./band-chrome.js";
19
13
  import { isDev } from "../../common/is-dev.js";
20
14
  const DEFAULT_MARKER_INSET = 6;
21
15
  const NO_READING = "\u2014";
@@ -85,7 +79,7 @@ function BandStripPlot(props) {
85
79
  ...marginOverride !== void 0 && { margin: marginOverride },
86
80
  ...tooltip !== void 0 && { tooltip }
87
81
  });
88
- const { bands, margin, plotWidth, scale, cursor, point, crosshairX, step, bandWidth } = band;
82
+ const { bands, margin, plotWidth, point, crosshairX, step, bandWidth } = band;
89
83
  const stripHeight = Math.max(plot.height - margin.top - margin.bottom, 1);
90
84
  const hatchId = `${chartId}-band-absent`;
91
85
  if (absentState !== void 0 && !styleByKey.has(absentState)) {
@@ -171,8 +165,6 @@ function BandStripPlot(props) {
171
165
  return out;
172
166
  }, [bands, getBand, getX, styleByKey, hidden, bandWidth, step, stripHeight, hatchId, absentState]);
173
167
  if (plotWidth <= 0 || bands.length === 0) return null;
174
- const cfg = tooltip === false ? void 0 : tooltip;
175
- const badge = cfg?.label === void 0 || point === null ? null : cfg.label(point);
176
168
  const row = point === null ? null : deriveBandRow(getBand(point), styleByKey, hidden, point);
177
169
  return /* @__PURE__ */ jsxs(Fragment, { children: [
178
170
  /* @__PURE__ */ jsxs(
@@ -196,71 +188,31 @@ function BandStripPlot(props) {
196
188
  rects,
197
189
  crosshairX !== null && /* @__PURE__ */ jsx(Crosshair, { x: crosshairX, top: 0, bottom: stripHeight }),
198
190
  /* @__PURE__ */ jsx(
199
- AxisBottomDate,
191
+ BandAxisOverlay,
200
192
  {
201
- top: stripHeight,
202
- scale,
203
- tickValues: band.tickValues,
204
- tickFormat: (v) => formatX(String(v)),
205
- anchorTerminals: band.xAnchorTerminals,
206
- ...band.xWrapWidth !== void 0 && { wrapWidth: band.xWrapWidth }
207
- }
208
- ),
209
- /* @__PURE__ */ jsx(
210
- HoverOverlay,
211
- {
212
- width: plotWidth,
193
+ band,
213
194
  height: stripHeight,
214
- onMove: cursor.onPointerMove,
215
- onDown: cursor.onPointerDown,
216
- onUp: cursor.onPointerUp,
217
- onLeave: cursor.onPointerLeave,
218
- onKeyDown: cursor.onKeyDown,
219
- onBlur: cursor.onBlur,
220
- valueMax: Math.max(bands.length - 1, 0),
221
- ...point !== null && {
222
- valueNow: bands.indexOf(point),
223
- valueText: formatX(getX(point))
224
- },
225
- ...ariaLabel !== void 0 && { ariaLabel }
195
+ getX,
196
+ formatX,
197
+ ariaLabel
226
198
  }
227
199
  )
228
200
  ] })
229
201
  ]
230
202
  }
231
203
  ),
232
- band.showTooltip && point !== null && /* @__PURE__ */ jsxs(ChartTooltipFloat, { anchor: band.tooltipAnchor, ariaLive: band.ariaLive, children: [
233
- /* @__PURE__ */ jsx(
234
- TooltipHeader,
235
- {
236
- date: getX(point),
237
- ...cfg?.formatHeader !== void 0 && {
238
- format: (key) => cfg.formatHeader?.(key, point) ?? key
239
- },
240
- ...badge !== null && { label: badge.text, labelColor: badge.color }
241
- }
242
- ),
243
- /* @__PURE__ */ jsxs(TooltipBody, { children: [
244
- cfg?.prependRows?.(point, { hidden }),
245
- row !== null && /* @__PURE__ */ jsx(
246
- TooltipRow,
247
- {
248
- color: row.color,
249
- label: row.label,
250
- value: row.value,
251
- shape: row.shape,
252
- dashed: row.dashed
253
- }
254
- ),
255
- cfg?.extraRows?.(point, { hidden })
256
- ] })
257
- ] })
204
+ /* @__PURE__ */ jsx(BandTooltip, { band, tooltip, getX, hidden, children: row !== null && /* @__PURE__ */ jsx(
205
+ TooltipRow,
206
+ {
207
+ color: row.color,
208
+ label: row.label,
209
+ value: row.value,
210
+ shape: row.shape,
211
+ dashed: row.dashed
212
+ }
213
+ ) })
258
214
  ] });
259
215
  }
260
- function clampFraction(value) {
261
- if (value === void 0 || !Number.isFinite(value)) return 0;
262
- return Math.min(Math.max(value, 0), 1);
263
- }
264
216
  function deriveBandRow(span, styleByKey, hidden, datum) {
265
217
  const style = styleByKey.get(span.state);
266
218
  if (style === void 0) {
@@ -1 +1 @@
1
- {"version":3,"file":"DualPanel.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/DualPanel.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DualPanel.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/DualPanel.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAUrD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAIrE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAIzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAe,MAAM,WAAW,CAAA;AAK5E,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,WAAW,GAAG;IAC5C,IAAI,EAAE,CAAC,EAAE,CAAA;IACT;kGAC8F;IAC9F,MAAM,CAAC,EAAE,MAAM,GAAG,qBAAqB,CAAA;IACvC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB;gEAC4D;IAC5D,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IACjC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC;8DAC0D;IAC1D,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IACxB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAA;IACtC;iGAC6F;IAC7F,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5E,wGAAwG;IACxG,WAAW,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;IAClE,oDAAoD;IACpD,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAA;IACrB,8DAA8D;IAC9D,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,GAAG,IAAI,CAAA;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,gBAAgB,EAAE,MAAM,CAAA;IACxB,gBAAgB,EAAE,MAAM,CAAA;IACxB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;IAChC,+FAA+F;IAC/F,YAAY,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;IACnC;;yFAEqF;IACrF,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACvC;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAA;IACzC;iGAC6F;IAC7F,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,kEAAkE;IAClE,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IAC/D;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IAC5C;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;4CACwC;IACxC,MAAM,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAClC,iGAAiG;IACjG,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4FAA4F;IAC5F,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;4FACwF;IACxF,KAAK,CAAC,EAAE,UAAU,CAAA;CACnB,CAAA;AAID;;;;;;;;;;;GAWG;AACH,iBAAS,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,+BAqDlD;AAqhBD,eAAO,MAAM,SAAS,EAAoB,OAAO,cAAc,CAAA"}
@@ -11,11 +11,12 @@ import {
11
11
  ChartTooltipFloat,
12
12
  TooltipBody,
13
13
  TooltipHeader,
14
- TooltipRow
14
+ TooltipRow,
15
+ TooltipRows
15
16
  } from "../primitives/ChartTooltip.js";
16
17
  import { ChartFrame, resolveLegend } from "../primitives/ChartFrame.js";
17
18
  import { Crosshair, SeriesDot } from "../primitives/Crosshair.js";
18
- import { HoverOverlay } from "../primitives/HoverOverlay.js";
19
+ import { cursorSliderProps, HoverOverlay } from "../primitives/HoverOverlay.js";
19
20
  import { ZoneRects } from "../primitives/ZoneRects.js";
20
21
  import { useChartCursor } from "../hooks/useChartCursor.js";
21
22
  import { autoMargin, probeAxisLabels } from "../layout/auto-margin.js";
@@ -365,18 +366,7 @@ function DualPanelPlot(props) {
365
366
  {
366
367
  width: xMax,
367
368
  height: topH + PANE_GAP,
368
- onMove: cursor.onPointerMove,
369
- onDown: cursor.onPointerDown,
370
- onUp: cursor.onPointerUp,
371
- onLeave: cursor.onPointerLeave,
372
- onKeyDown: cursor.onKeyDown,
373
- onBlur: cursor.onBlur,
374
- valueMax: Math.max(data.length - 1, 0),
375
- ...point !== null && {
376
- valueNow: data.indexOf(point),
377
- valueText: formatX(getX(point))
378
- },
379
- ...ariaLabel !== void 0 && { ariaLabel }
369
+ ...cursorSliderProps({ cursor, data, getX, formatX, ariaLabel })
380
370
  }
381
371
  )
382
372
  ] }),
@@ -454,18 +444,7 @@ function DualPanelPlot(props) {
454
444
  }
455
445
  ),
456
446
  /* @__PURE__ */ jsxs(TooltipBody, { children: [
457
- deriveTooltipRows(visibleSeries, point, formatTop).map((row) => /* @__PURE__ */ jsx(
458
- TooltipRow,
459
- {
460
- color: row.color,
461
- label: row.label,
462
- value: row.value,
463
- shape: row.shape,
464
- dashed: row.dashed,
465
- ...row.strokeWidth !== void 0 && { strokeWidth: row.strokeWidth }
466
- },
467
- row.key
468
- )),
447
+ /* @__PURE__ */ jsx(TooltipRows, { rows: deriveTooltipRows(visibleSeries, point, formatTop) }),
469
448
  barVisible && (() => {
470
449
  const v = getBar(point);
471
450
  if (v === null || v === void 0 || Number.isNaN(v)) return null;
@@ -1 +1 @@
1
- {"version":3,"file":"MirroredBars.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/MirroredBars.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAIvE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAUrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAE5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAG/D,gGAAgG;AAChG,MAAM,MAAM,eAAe,GAAG;IAC5B;mEAC+D;IAC/D,GAAG,EAAE,MAAM,CAAA;IACX;;;;;;;OAOG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACrB;sBACkB;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;oFACgF;IAChF,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI,WAAW,GAAG;IAC/C,IAAI,EAAE,SAAS,CAAC,EAAE,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,sFAAsF;IACtF,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB;;;;;OAKG;IACH,MAAM,EAAE,SAAS,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IACjC,yCAAyC;IACzC,EAAE,EAAE,eAAe,CAAA;IACnB,yCAAyC;IACzC,IAAI,EAAE,eAAe,CAAA;IACrB;8FAC0F;IAC1F,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACpC;kCAC8B;IAC9B,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IAChC;kGAC8F;IAC9F,MAAM,CAAC,EAAE,MAAM,GAAG,qBAAqB,CAAA;IACvC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IACjC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,KAAK,SAAS,MAAM,EAAE,CAAA;IAC/E,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;IAClB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,OAAO,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAA;IACtC,MAAM,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAClC;gFAC4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;4FACwF;IACxF,KAAK,CAAC,EAAE,UAAU,CAAA;CACnB,CAAA;AA8BD;;;;;;;;;;;;;GAaG;AACH,iBAAS,iBAAiB,CAAC,CAAC,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,+BAwBxD;AAgWD,eAAO,MAAM,YAAY,EAAuB,OAAO,iBAAiB,CAAA"}
1
+ {"version":3,"file":"MirroredBars.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/MirroredBars.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAIvE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAIrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAE5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAI/D,gGAAgG;AAChG,MAAM,MAAM,eAAe,GAAG;IAC5B;mEAC+D;IAC/D,GAAG,EAAE,MAAM,CAAA;IACX;;;;;;;OAOG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACrB;sBACkB;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;oFACgF;IAChF,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI,WAAW,GAAG;IAC/C,IAAI,EAAE,SAAS,CAAC,EAAE,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,sFAAsF;IACtF,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB;;;;;OAKG;IACH,MAAM,EAAE,SAAS,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IACjC,yCAAyC;IACzC,EAAE,EAAE,eAAe,CAAA;IACnB,yCAAyC;IACzC,IAAI,EAAE,eAAe,CAAA;IACrB;8FAC0F;IAC1F,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACpC;kCAC8B;IAC9B,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IAChC;kGAC8F;IAC9F,MAAM,CAAC,EAAE,MAAM,GAAG,qBAAqB,CAAA;IACvC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IACjC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,KAAK,SAAS,MAAM,EAAE,CAAA;IAC/E,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;IAClB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,OAAO,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAA;IACtC,MAAM,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAClC;gFAC4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;4FACwF;IACxF,KAAK,CAAC,EAAE,UAAU,CAAA;CACnB,CAAA;AA8BD;;;;;;;;;;;;;GAaG;AACH,iBAAS,iBAAiB,CAAC,CAAC,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,+BAwBxD;AA+SD,eAAO,MAAM,YAAY,EAAuB,OAAO,iBAAiB,CAAA"}
@@ -6,19 +6,14 @@ import { assertRequiredProps } from "../../common/validate.js";
6
6
  import { VX, alpha } from "../../tokens/index.js";
7
7
  import { useBandPlot } from "../hooks/useBandPlot.js";
8
8
  import { probeAxisLabels } from "../layout/auto-margin.js";
9
- import { AxisBottomDate, AxisLeftNumeric } from "../primitives/Axes.js";
9
+ import { AxisLeftNumeric } from "../primitives/Axes.js";
10
10
  import { ChartFrame, resolveLegend } from "../primitives/ChartFrame.js";
11
- import {
12
- ChartTooltipFloat,
13
- TooltipBody,
14
- TooltipHeader,
15
- TooltipRow
16
- } from "../primitives/ChartTooltip.js";
11
+ import { TooltipRows } from "../primitives/ChartTooltip.js";
17
12
  import { Crosshair } from "../primitives/Crosshair.js";
18
13
  import { HatchPattern, hatchFill, hatchSizeFor } from "../primitives/HatchPattern.js";
19
- import { HoverOverlay } from "../primitives/HoverOverlay.js";
20
14
  import { deriveTooltipRows } from "../series.js";
21
15
  import { fmtAxisDate } from "../utils/format.js";
16
+ import { BandAxisOverlay, BandTooltip, clampFraction } from "./band-chrome.js";
22
17
  const DEFAULT_UP_FRACTION = 0.35;
23
18
  const DEFAULT_PANE_TICKS = 3;
24
19
  function assertPaneKey(side, key, resolved, series) {
@@ -107,7 +102,7 @@ function MirroredBarsPlot(props) {
107
102
  ...marginOverride !== void 0 && { margin: marginOverride },
108
103
  ...tooltip !== void 0 && { tooltip }
109
104
  });
110
- const { bands, margin, plotWidth, scale, cursor, point, crosshairX, step, bandWidth } = band;
105
+ const { bands, margin, plotWidth, point, crosshairX, step, bandWidth } = band;
111
106
  const barBand = Math.max(plot.height - margin.top - margin.bottom, 2);
112
107
  const upHeight = Math.max(Math.round(barBand * upFraction), 1);
113
108
  const downHeight = Math.max(barBand - upHeight, 1);
@@ -198,8 +193,6 @@ function MirroredBarsPlot(props) {
198
193
  hatchId
199
194
  ]);
200
195
  if (plotWidth <= 0 || bands.length === 0) return null;
201
- const cfg = tooltip === false ? void 0 : tooltip;
202
- const badge = cfg?.label === void 0 || point === null ? null : cfg.label(point);
203
196
  const visibleSeries = series.filter((s) => !hidden.has(s.key)).map((s) => {
204
197
  if (s.formatValue !== void 0) return s;
205
198
  if (s.key === up.key) return { ...s, formatValue: (v) => up.format(v) };
@@ -258,73 +251,22 @@ function MirroredBarsPlot(props) {
258
251
  ),
259
252
  crosshairX !== null && /* @__PURE__ */ jsx(Crosshair, { x: crosshairX, top: 0, bottom: barBand }),
260
253
  /* @__PURE__ */ jsx(
261
- AxisBottomDate,
254
+ BandAxisOverlay,
262
255
  {
263
- top: barBand,
264
- scale,
265
- tickValues: band.tickValues,
266
- tickFormat: (v) => formatX(String(v)),
267
- anchorTerminals: band.xAnchorTerminals,
268
- ...band.xWrapWidth !== void 0 && { wrapWidth: band.xWrapWidth }
269
- }
270
- ),
271
- /* @__PURE__ */ jsx(
272
- HoverOverlay,
273
- {
274
- width: plotWidth,
256
+ band,
275
257
  height: barBand,
276
- onMove: cursor.onPointerMove,
277
- onDown: cursor.onPointerDown,
278
- onUp: cursor.onPointerUp,
279
- onLeave: cursor.onPointerLeave,
280
- onKeyDown: cursor.onKeyDown,
281
- onBlur: cursor.onBlur,
282
- valueMax: Math.max(bands.length - 1, 0),
283
- ...point !== null && {
284
- valueNow: bands.indexOf(point),
285
- valueText: formatX(getX(point))
286
- },
287
- ...ariaLabel !== void 0 && { ariaLabel }
258
+ getX,
259
+ formatX,
260
+ ariaLabel
288
261
  }
289
262
  )
290
263
  ] })
291
264
  ]
292
265
  }
293
266
  ),
294
- band.showTooltip && point !== null && /* @__PURE__ */ jsxs(ChartTooltipFloat, { anchor: band.tooltipAnchor, ariaLive: band.ariaLive, children: [
295
- /* @__PURE__ */ jsx(
296
- TooltipHeader,
297
- {
298
- date: getX(point),
299
- ...cfg?.formatHeader !== void 0 && {
300
- format: (key) => cfg.formatHeader?.(key, point) ?? key
301
- },
302
- ...badge !== null && { label: badge.text, labelColor: badge.color }
303
- }
304
- ),
305
- /* @__PURE__ */ jsxs(TooltipBody, { children: [
306
- cfg?.prependRows?.(point, { hidden }),
307
- rows.map((row) => /* @__PURE__ */ jsx(
308
- TooltipRow,
309
- {
310
- color: row.color,
311
- label: row.label,
312
- value: row.value,
313
- shape: row.shape,
314
- dashed: row.dashed,
315
- ...row.strokeWidth !== void 0 && { strokeWidth: row.strokeWidth }
316
- },
317
- row.key
318
- )),
319
- cfg?.extraRows?.(point, { hidden })
320
- ] })
321
- ] })
267
+ /* @__PURE__ */ jsx(BandTooltip, { band, tooltip, getX, hidden, children: /* @__PURE__ */ jsx(TooltipRows, { rows }) })
322
268
  ] });
323
269
  }
324
- function clampFraction(value) {
325
- if (value === void 0 || !Number.isFinite(value)) return 0;
326
- return Math.min(Math.max(value, 0), 1);
327
- }
328
270
  function finiteOrNull(v) {
329
271
  return v === null || v === void 0 || Number.isNaN(v) ? null : v;
330
272
  }
@@ -0,0 +1,31 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { BandPlot, BandTooltipConfig } from '../hooks/useBandPlot.js';
3
+ /**
4
+ * The chrome `BandStrip` and `MirroredBars` share around their own marks — the slot axis, the
5
+ * keyboard/pointer overlay and the tooltip shell — so the two `useBandPlot` kinds cannot drift in
6
+ * any of them. Internal; neither is exported from a barrel.
7
+ *
8
+ * theme-allow-file hand-rolled-plot — the slot axis and overlay of the two declared banded
9
+ * exceptions (`BandStrip`, `MirroredBars`), which carry the same waiver for the same reason.
10
+ */
11
+ /** A 0..1 share. Non-finite (a 0/0 fold count) reads as "nothing is absent" — the conservative
12
+ * end, since the alternative is a band that does not render at all. */
13
+ export declare function clampFraction(value: number | undefined): number;
14
+ /** The slot axis under a `height`-tall band row, plus the hover/keyboard overlay over it. */
15
+ export declare function BandAxisOverlay<T>({ band, height, getX, formatX, ariaLabel, }: {
16
+ band: BandPlot<T>;
17
+ height: number;
18
+ getX: (d: T) => string;
19
+ formatX: (key: string) => string;
20
+ ariaLabel: string | undefined;
21
+ }): import("react").JSX.Element;
22
+ /** The tooltip shell: header (+ badge), the consumer's prepended rows, the kind's own derived
23
+ * `children` rows, the consumer's extra rows. Renders nothing off-hover or with `tooltip: false`. */
24
+ export declare function BandTooltip<T>({ band, tooltip, getX, hidden, children, }: {
25
+ band: BandPlot<T>;
26
+ tooltip: BandTooltipConfig<T> | false | undefined;
27
+ getX: (d: T) => string;
28
+ hidden: ReadonlySet<string>;
29
+ children: ReactNode;
30
+ }): import("react").JSX.Element | null;
31
+ //# sourceMappingURL=band-chrome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"band-chrome.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/band-chrome.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAKvE;;;;;;;GAOG;AAEH;uEACuE;AACvE,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAG/D;AAED,6FAA6F;AAC7F,wBAAgB,eAAe,CAAC,CAAC,EAAE,EACjC,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,OAAO,EACP,SAAS,GACV,EAAE;IACD,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IAChC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;CAC9B,+BAkBA;AAED;qGACqG;AACrG,wBAAgB,WAAW,CAAC,CAAC,EAAE,EAC7B,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,MAAM,EACN,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;IACjB,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,SAAS,CAAA;IACjD,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC3B,QAAQ,EAAE,SAAS,CAAA;CACpB,sCAqBA"}
@@ -0,0 +1,71 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { AxisBottomDate } from "../primitives/Axes.js";
3
+ import { ChartTooltipFloat, TooltipBody, TooltipHeader } from "../primitives/ChartTooltip.js";
4
+ import { cursorSliderProps, HoverOverlay } from "../primitives/HoverOverlay.js";
5
+ function clampFraction(value) {
6
+ if (value === void 0 || !Number.isFinite(value)) return 0;
7
+ return Math.min(Math.max(value, 0), 1);
8
+ }
9
+ function BandAxisOverlay({
10
+ band,
11
+ height,
12
+ getX,
13
+ formatX,
14
+ ariaLabel
15
+ }) {
16
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
17
+ /* @__PURE__ */ jsx(
18
+ AxisBottomDate,
19
+ {
20
+ top: height,
21
+ scale: band.scale,
22
+ tickValues: band.tickValues,
23
+ tickFormat: (v) => formatX(String(v)),
24
+ anchorTerminals: band.xAnchorTerminals,
25
+ ...band.xWrapWidth !== void 0 && { wrapWidth: band.xWrapWidth }
26
+ }
27
+ ),
28
+ /* @__PURE__ */ jsx(
29
+ HoverOverlay,
30
+ {
31
+ width: band.plotWidth,
32
+ height,
33
+ ...cursorSliderProps({ cursor: band.cursor, data: band.bands, getX, formatX, ariaLabel })
34
+ }
35
+ )
36
+ ] });
37
+ }
38
+ function BandTooltip({
39
+ band,
40
+ tooltip,
41
+ getX,
42
+ hidden,
43
+ children
44
+ }) {
45
+ const { point } = band;
46
+ if (!band.showTooltip || point === null) return null;
47
+ const cfg = tooltip === false ? void 0 : tooltip;
48
+ const badge = cfg?.label === void 0 ? null : cfg.label(point);
49
+ return /* @__PURE__ */ jsxs(ChartTooltipFloat, { anchor: band.tooltipAnchor, ariaLive: band.ariaLive, children: [
50
+ /* @__PURE__ */ jsx(
51
+ TooltipHeader,
52
+ {
53
+ date: getX(point),
54
+ ...cfg?.formatHeader !== void 0 && {
55
+ format: (key) => cfg.formatHeader?.(key, point) ?? key
56
+ },
57
+ ...badge !== null && { label: badge.text, labelColor: badge.color }
58
+ }
59
+ ),
60
+ /* @__PURE__ */ jsxs(TooltipBody, { children: [
61
+ cfg?.prependRows?.(point, { hidden }),
62
+ children,
63
+ cfg?.extraRows?.(point, { hidden })
64
+ ] })
65
+ ] });
66
+ }
67
+ export {
68
+ BandAxisOverlay,
69
+ BandTooltip,
70
+ clampFraction
71
+ };