@jbrowse/display-ui 5.0.0-beta.13 → 5.0.0-beta.14
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.
- package/README.md +70 -76
- package/esm/AxisCaption.d.ts +2 -2
- package/esm/AxisCaption.js +6 -4
- package/esm/AxisGutter.d.ts +2 -2
- package/esm/AxisGutter.js +5 -4
- package/esm/CrossHatches.d.ts +3 -2
- package/esm/CrossHatches.js +5 -2
- package/esm/DisplayUIProvider.d.ts +3 -2
- package/esm/DisplayUIProvider.js +4 -2
- package/esm/FloatingLegend.js +2 -2
- package/esm/FloatingText.d.ts +5 -5
- package/esm/FloatingText.js +6 -5
- package/esm/ScoreDomainCaption.d.ts +2 -2
- package/esm/ScoreDomainCaption.js +3 -2
- package/esm/ScoreRules.d.ts +3 -2
- package/esm/ScoreRules.js +5 -2
- package/esm/YScaleBar.js +1 -8
- package/esm/YScaleBarOverlay.d.ts +3 -2
- package/esm/YScaleBarOverlay.js +4 -2
- package/esm/axisPlacement.d.ts +11 -5
- package/esm/axisPlacement.js +15 -8
- package/esm/bottomRightCorner.d.ts +19 -47
- package/esm/bottomRightCorner.js +19 -47
- package/esm/chromeOverlayContext.js +10 -25
- package/esm/chromeOverlays.d.ts +73 -67
- package/esm/embed/engineBoundary.d.ts +34 -0
- package/esm/embed/engineBoundary.js +29 -0
- package/esm/embed/index.d.ts +6 -0
- package/esm/embed/index.js +18 -3
- package/esm/embed/legend.js +2 -2
- package/esm/embed/location.d.ts +2 -1
- package/esm/embed/location.js +18 -17
- package/esm/embed/notifications.d.ts +29 -0
- package/esm/embed/notifications.js +38 -0
- package/esm/embed/provider.d.ts +5 -3
- package/esm/embed/provider.js +6 -4
- package/esm/embed/regions.d.ts +3 -2
- package/esm/embed/regions.js +9 -7
- package/esm/embed/searchPicker.d.ts +24 -0
- package/esm/embed/searchPicker.js +14 -0
- package/esm/embed/toolbar.d.ts +16 -0
- package/esm/embed/toolbar.js +22 -0
- package/esm/index.d.ts +1 -1
- package/esm/isLiveModel.d.ts +10 -15
- package/esm/isLiveModel.js +10 -15
- package/esm/plainChromeOverlays.d.ts +2 -2
- package/esm/plainChromeOverlays.js +17 -44
- package/esm/tooltip/Tooltip.d.ts +3 -3
- package/esm/tooltip/Tooltip.js +4 -2
- package/esm/trackControl/plainTrackControl.d.ts +2 -1
- package/esm/trackControl/plainTrackControl.js +8 -6
- package/esm/trackOverlay/TrackOverlaySlot.d.ts +3 -3
- package/esm/trackOverlay/TrackOverlaySlot.js +4 -3
- package/esm/valueScale.d.ts +5 -5
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -34,19 +34,19 @@ above them.
|
|
|
34
34
|
|
|
35
35
|
## What is here
|
|
36
36
|
|
|
37
|
-
| |
|
|
38
|
-
| ------------------------------------------- |
|
|
39
|
-
| `DisplayChromeOverlays` | the `displayPhase` states, as a five-component set
|
|
40
|
-
| `DisplayChromeOverlayProvider` | redirects those states for JBrowse's own displays
|
|
41
|
-
| `TrackControlComponent` | one shape for every ambient bottom-right control, icons named rather than passed
|
|
42
|
-
| `TrackControlProvider` | redirects those
|
|
43
|
-
| `DisplayUIProvider` | both at once, defaulting to the plain sets — what an embedder mounts
|
|
44
|
-
| `plainChromeOverlays` / `plainTrackControl` | the toolkit-free sets, CSS system
|
|
45
|
-
| `TrackOverlaySlot` / `TrackOverlayPortal` | the per-track overlay layer, and the host's half of it
|
|
46
|
-
| `FloatingLegend` | the one legend box every display with
|
|
47
|
-
| `BottomRightCornerContext` | the corner `BackgroundProgress` is laid out in, which its prop types cannot express
|
|
48
|
-
| `tooLargeBannerText` | what the byte gate says, shared by every set that renders it
|
|
49
|
-
| `isLiveModel` | the liveness guard an overlay's one button needs, for an MST node or a plain object
|
|
37
|
+
| | |
|
|
38
|
+
| ------------------------------------------- | ----------------------------------------------------------------------------------- |
|
|
39
|
+
| `DisplayChromeOverlays` | the `displayPhase` states, as a five-component set taking plain props |
|
|
40
|
+
| `DisplayChromeOverlayProvider` | redirects those states for JBrowse's own displays |
|
|
41
|
+
| `TrackControlComponent` | one shape for every ambient bottom-right control, icons named rather than passed |
|
|
42
|
+
| `TrackControlProvider` | redirects those |
|
|
43
|
+
| `DisplayUIProvider` | both at once, defaulting to the plain sets — what an embedder mounts |
|
|
44
|
+
| `plainChromeOverlays` / `plainTrackControl` | the toolkit-free sets, CSS system colors, no theme object |
|
|
45
|
+
| `TrackOverlaySlot` / `TrackOverlayPortal` | the per-track overlay layer, and the host's half of it |
|
|
46
|
+
| `FloatingLegend` | the one legend box every display with colors to explain draws |
|
|
47
|
+
| `BottomRightCornerContext` | the corner `BackgroundProgress` is laid out in, which its prop types cannot express |
|
|
48
|
+
| `tooLargeBannerText` | what the byte gate says, shared by every set that renders it |
|
|
49
|
+
| `isLiveModel` | the liveness guard an overlay's one button needs, for an MST node or a plain object |
|
|
50
50
|
|
|
51
51
|
## What is _not_ here, and cannot be
|
|
52
52
|
|
|
@@ -69,42 +69,23 @@ Auto-generated from `#api` JSDoc tags in this package. Do not edit by hand.
|
|
|
69
69
|
|
|
70
70
|
The one box per display that owns the bottom-right corner.
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
`DisplayChromeOverlays.BackgroundProgress`
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
used to claim `bottom: 2; right: 2` there with their own `position: absolute`
|
|
86
|
-
box — so they simply drew on top of each other, the controls winning on z-index
|
|
87
|
-
and the status text disappearing under them.
|
|
88
|
-
|
|
89
|
-
It has never been reachable: the two displays that render the control row
|
|
90
|
-
(alignments, canvas) are not among the four that report a `ready`-phase status
|
|
91
|
-
(clustering, on multi-wiggle / multi-row features / maf / the multi-sample
|
|
92
|
-
variant pair). The layout is structural anyway, because neither side checks for
|
|
93
|
-
the constraint, so the first display to want both would hit the bug as a status
|
|
94
|
-
message that never appears.
|
|
95
|
-
|
|
96
|
-
`BottomRightIndicators` already described itself as "the single anchor point for
|
|
97
|
-
every bottom-right overlay ... so they lay out as one row instead of each
|
|
98
|
-
picking their own position and colliding". This makes that true of the chip too:
|
|
99
|
-
the chrome renders the anchor, puts its chip in it, and publishes the node here
|
|
100
|
-
so the display's row — rendered several components away, inside the chrome's
|
|
101
|
-
body — lands in the same flex box instead of over it.
|
|
102
|
-
|
|
103
|
-
`null` outside a chrome (a display an embedder mounts standalone, a unit test,
|
|
104
|
-
the SVG export), where `BottomRightIndicators` keeps its own anchored box. That
|
|
105
|
-
fallback is why this can be added without every consumer changing.
|
|
72
|
+
Two members share it: the display's own control row (`BottomRightIndicators`)
|
|
73
|
+
and the chrome's background-progress chip
|
|
74
|
+
(`DisplayChromeOverlays.BackgroundProgress`). Both portal into the same
|
|
75
|
+
per-track overlay node, so each claiming the corner with its own
|
|
76
|
+
`position: absolute` box draws one over the other. The chrome renders this box,
|
|
77
|
+
lays its chip out in it, and publishes the node here so the control row,
|
|
78
|
+
rendered inside the chrome's body, lands in the same flex column.
|
|
79
|
+
|
|
80
|
+
- A host writing their own display over `DisplayChromeBase` builds the corner
|
|
81
|
+
from this; the chip is told to render in-flow, with no `position` and no
|
|
82
|
+
corner offsets.
|
|
83
|
+
- `null` outside a chrome (a standalone mount, a unit test, the SVG export),
|
|
84
|
+
where `BottomRightIndicators` anchors its own box.
|
|
106
85
|
|
|
107
86
|
```js
|
|
87
|
+
import { BottomRightCornerContext } from '@jbrowse/display-ui'
|
|
88
|
+
|
|
108
89
|
// type signature
|
|
109
90
|
Context<HTMLElement | null>
|
|
110
91
|
```
|
|
@@ -172,33 +153,32 @@ no toolkit. See
|
|
|
172
153
|
[DISPLAYCHROME.md](https://github.com/GMOD/jbrowse-components/blob/main/agent-docs/reference/DISPLAYCHROME.md).
|
|
173
154
|
|
|
174
155
|
```js
|
|
156
|
+
import { DisplayUIProvider } from '@jbrowse/display-ui'
|
|
157
|
+
|
|
175
158
|
// type signature
|
|
176
|
-
({ overlays, trackControl, children, }: { overlays?: Partial
|
|
159
|
+
({ overlays, trackControl, children, }: { overlays?: Partial<DisplayChromeOverlays> | undefined; trackControl?: TrackControlComponent | undefined; children: ReactNode; }) => Element
|
|
177
160
|
```
|
|
178
161
|
|
|
179
162
|
[Source code](https://github.com/GMOD/jbrowse-components/blob/main/packages/display-ui/src/DisplayUIProvider.tsx)
|
|
180
163
|
|
|
181
164
|
### isLiveModel
|
|
182
165
|
|
|
183
|
-
Whether
|
|
166
|
+
Whether a display model can still be called into.
|
|
184
167
|
|
|
185
|
-
The
|
|
186
|
-
|
|
187
|
-
|
|
168
|
+
The chrome's overlay slots guard every button with it: the terminal states
|
|
169
|
+
unmount the canvas, so a click landing after the track was closed would
|
|
170
|
+
otherwise run an action on a destroyed node.
|
|
188
171
|
|
|
189
|
-
**`isAlive` alone is wrong here, and it throws rather than answering.**
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
plain object
|
|
194
|
-
|
|
195
|
-
button looking live and doing nothing, which is the exact state
|
|
196
|
-
`DisplayChromeOverlays.TooLarge` documents itself as existing to prevent.
|
|
197
|
-
|
|
198
|
-
A plain object is never destroyed, so it is always callable. The liveness
|
|
199
|
-
question only exists for an MST node.
|
|
172
|
+
**`isAlive` alone is wrong here, and it throws rather than answering.** A host
|
|
173
|
+
writing their own display over `DisplayChromeBase` may hand the chrome a plain
|
|
174
|
+
object, and `isAlive` runs `assertIsStateTreeNode`, which throws inside the
|
|
175
|
+
click handler, where React logs it and moves on: a Force load button that looks
|
|
176
|
+
live and does nothing. A plain object is never destroyed, so it is always
|
|
177
|
+
callable.
|
|
200
178
|
|
|
201
179
|
```js
|
|
180
|
+
import { isLiveModel } from '@jbrowse/display-ui'
|
|
181
|
+
|
|
202
182
|
// type signature
|
|
203
183
|
(model: unknown) => boolean
|
|
204
184
|
```
|
|
@@ -213,7 +193,7 @@ inside someone else's design system.
|
|
|
213
193
|
|
|
214
194
|
`DisplayUIProvider` installs this by default, so mount that rather than naming
|
|
215
195
|
this — reach for it directly only to wrap a state or to build a context value by
|
|
216
|
-
hand.
|
|
196
|
+
hand. Colors come from `currentColor` and the CSS system colors, so the host's
|
|
217
197
|
own cascade drives them in both light and dark.
|
|
218
198
|
|
|
219
199
|
The `data-testid` values it renders are a contract four of JBrowse's test
|
|
@@ -221,6 +201,8 @@ systems key on, so a replacement set that keeps them can be driven by those
|
|
|
221
201
|
suites too.
|
|
222
202
|
|
|
223
203
|
```js
|
|
204
|
+
import { plainChromeOverlays } from '@jbrowse/display-ui'
|
|
205
|
+
|
|
224
206
|
// type signature
|
|
225
207
|
DisplayChromeOverlays
|
|
226
208
|
```
|
|
@@ -265,6 +247,8 @@ two consecutive measurements rather than from a threshold; see
|
|
|
265
247
|
`ByteEstimate.zoomIneffective`.
|
|
266
248
|
|
|
267
249
|
```js
|
|
250
|
+
import { tooLargeBannerText } from '@jbrowse/display-ui'
|
|
251
|
+
|
|
268
252
|
// type signature
|
|
269
253
|
(regionTooLargeReason: string, { zoomCanRelease }?: { zoomCanRelease?: boolean | undefined; }) => string
|
|
270
254
|
```
|
|
@@ -303,8 +287,10 @@ chrome is built on, uses the same trigger pattern; only the toolkit differs.
|
|
|
303
287
|
without the cloning, for a host writing its own markup.
|
|
304
288
|
|
|
305
289
|
```js
|
|
290
|
+
import { Tooltip } from '@jbrowse/display-ui'
|
|
291
|
+
|
|
306
292
|
// type signature
|
|
307
|
-
({ title, placement, children, }: { title: ReactNode; placement?: TooltipPlacement | undefined; children: ReactElement
|
|
293
|
+
({ title, placement, children, }: { title: ReactNode; placement?: TooltipPlacement | undefined; children: ReactElement<TriggerProps, string | JSXElementConstructor<any>>; }) => Element
|
|
308
294
|
```
|
|
309
295
|
|
|
310
296
|
[Source code](https://github.com/GMOD/jbrowse-components/blob/main/packages/display-ui/src/tooltip/Tooltip.tsx)
|
|
@@ -324,6 +310,8 @@ default), which preserves chrome that is still meaningful unescaped. Pass
|
|
|
324
310
|
draws itself some other way elsewhere.
|
|
325
311
|
|
|
326
312
|
```js
|
|
313
|
+
import { TrackOverlayPortal } from '@jbrowse/display-ui'
|
|
314
|
+
|
|
327
315
|
// type signature
|
|
328
316
|
({ children, fallbackInline, }: { children: ReactNode; fallbackInline?: boolean | undefined; }) => ReactNode
|
|
329
317
|
```
|
|
@@ -338,7 +326,7 @@ escapes into. Pair to `TrackOverlayPortal`, which is the other end.
|
|
|
338
326
|
A display's React tree is sealed in a `contain: strict` sandbox — that is what
|
|
339
327
|
isolates its paint, and dropping it is measured and rejected (ADR-058). A
|
|
340
328
|
stacking context comes with the isolation, so floating chrome a display draws (a
|
|
341
|
-
|
|
329
|
+
color key, hi-c's overlay panel, maf's row labels) cannot out-z-index anything
|
|
342
330
|
painted over the track stack from outside. The escape is a node mounted _beside_
|
|
343
331
|
the sandbox rather than inside it, published through `TrackOverlayContext`; this
|
|
344
332
|
component is that node, its context and the paint order between them, in the one
|
|
@@ -373,6 +361,8 @@ wants them takes them back on its own positioned box; it also carries
|
|
|
373
361
|
click-drag pan.
|
|
374
362
|
|
|
375
363
|
```js
|
|
364
|
+
import { TrackOverlaySlot } from '@jbrowse/display-ui'
|
|
365
|
+
|
|
376
366
|
// type signature
|
|
377
367
|
({ children, zIndex, style, overlayStyle, }: { children: ReactNode; zIndex: number; style?: CSSProperties | undefined; overlayStyle?: CSSProperties | undefined; }) => Element
|
|
378
368
|
```
|
|
@@ -402,6 +392,8 @@ with it. Any other handler on this list has to compose rather than replace —
|
|
|
402
392
|
spread first, then call `triggerProps.onFocus` from yours.
|
|
403
393
|
|
|
404
394
|
```js
|
|
395
|
+
import { useTooltip } from '@jbrowse/display-ui'
|
|
396
|
+
|
|
405
397
|
// type signature
|
|
406
398
|
(title: ReactNode, { placement }?: { placement?: TooltipPlacement | undefined; }) => TooltipTrigger
|
|
407
399
|
```
|
|
@@ -422,6 +414,8 @@ Render `menuProps` only while `open`, and portal it to `document.body` —
|
|
|
422
414
|
carries position only.
|
|
423
415
|
|
|
424
416
|
```js
|
|
417
|
+
import { useTrackControlMenu } from '@jbrowse/display-ui'
|
|
418
|
+
|
|
425
419
|
// type signature
|
|
426
420
|
(onClose?: (() => void) | undefined) => TrackControlMenu
|
|
427
421
|
```
|
|
@@ -431,7 +425,7 @@ carries position only.
|
|
|
431
425
|
### ValueScale
|
|
432
426
|
|
|
433
427
|
A value scale a display places its y through, declared so the chrome can derive
|
|
434
|
-
the axis from it — the score axis's counterpart to a
|
|
428
|
+
the axis from it — the score axis's counterpart to a color scale.
|
|
435
429
|
|
|
436
430
|
`domain` is the resolved `[min, max]`; `height` the band it rules and `offset`
|
|
437
431
|
the inset of the plot box inside that band (`axisPlotBox(height, offset)`);
|
|
@@ -444,15 +438,15 @@ geometry); `ScoreScaleMixin` derives one through `computeYTicks` otherwise.
|
|
|
444
438
|
display stacks the same plot: the multi-wiggle's rows, a grouped alignments
|
|
445
439
|
track's coverage band per group, each projected through the display's own
|
|
446
440
|
scroll; the chrome drops the ones off screen. `[]` is a scale the display maps
|
|
447
|
-
to
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
scale measures (`TLEN`), as a
|
|
453
|
-
once for the scale, beside the bands on screen, however many it rules.
|
|
454
|
-
are the reference lines the scale declares and `grid` a line at every
|
|
455
|
-
drawn across every band.
|
|
441
|
+
to color rather than to y (density rows each in their own color), which gets the
|
|
442
|
+
`[min, max]` caption and no axis, as a scale whose bands are too short for one
|
|
443
|
+
does. `side` and `left` are which of the band's edges the display's own panels
|
|
444
|
+
leave clear for a gutter: `right` where a group label chip takes the left,
|
|
445
|
+
`left: n` where a dendrogram and row labels take the first `n` px. `caption` is
|
|
446
|
+
what the scale measures (`TLEN`), as a color scale's `field` is; the chrome
|
|
447
|
+
draws it once for the scale, beside the bands on screen, however many it rules.
|
|
448
|
+
`rules` are the reference lines the scale declares and `grid` a line at every
|
|
449
|
+
tick, both drawn across every band.
|
|
456
450
|
|
|
457
451
|
A member describes the scale or the band it rules, never the axis — not an
|
|
458
452
|
orientation, a form, a gutter width or a font. The chrome reads a member to keep
|
package/esm/AxisCaption.d.ts
CHANGED
|
@@ -16,9 +16,9 @@ export default function AxisCaption({ axis, bandTops, height, }: {
|
|
|
16
16
|
* The on-screen caption of one scale: an `<svg>` over the gutter column, the
|
|
17
17
|
* height of the display, with `AxisCaption` inside.
|
|
18
18
|
*/
|
|
19
|
-
export declare
|
|
19
|
+
export declare const AxisCaptionOverlay: ({ axis, bandTops, width, height, }: {
|
|
20
20
|
axis: YAxis;
|
|
21
21
|
bandTops: number[];
|
|
22
22
|
width: number;
|
|
23
23
|
height: number;
|
|
24
|
-
})
|
|
24
|
+
}) => import("react").JSX.Element;
|
package/esm/AxisCaption.js
CHANGED
|
@@ -2,7 +2,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { usePalette } from '@jbrowse/core/ui/PaletteContext';
|
|
3
3
|
import { VERTICAL_SCROLLBAR_CLEARANCE } from '@jbrowse/core/ui/VerticalScrollbar';
|
|
4
4
|
import { measureText } from '@jbrowse/core/util/measureText';
|
|
5
|
-
import {
|
|
5
|
+
import { observer } from 'mobx-react';
|
|
6
|
+
import { axisCaptionY, axisGutterLeft, axisGutterWidth, numbersGrowRight, } from './axisPlacement.js';
|
|
6
7
|
import { AXIS_FONT_PX, CAPTION_INSET_PX } from './yAxisConstants.js';
|
|
7
8
|
// The caption and its length, cut to an ellipsis where it is longer than
|
|
8
9
|
// `room`, as a Vega-Lite axis title is cut at its `titleLimit`. The ellipsis
|
|
@@ -28,9 +29,10 @@ function fitCaption(caption, room) {
|
|
|
28
29
|
* and the export both draw through this, so the two cannot place a caption
|
|
29
30
|
* differently.
|
|
30
31
|
*/
|
|
32
|
+
// eslint-disable-next-line no-restricted-syntax -- drawn inside a frozen SVG figure
|
|
31
33
|
export default function AxisCaption({ axis, bandTops, height, }) {
|
|
32
34
|
const palette = usePalette();
|
|
33
|
-
const x = axis
|
|
35
|
+
const x = numbersGrowRight(axis)
|
|
34
36
|
? axisGutterWidth(axis) - CAPTION_INSET_PX
|
|
35
37
|
: CAPTION_INSET_PX;
|
|
36
38
|
const caption = fitCaption(axis.caption ?? '', height);
|
|
@@ -45,7 +47,7 @@ export default function AxisCaption({ axis, bandTops, height, }) {
|
|
|
45
47
|
* The on-screen caption of one scale: an `<svg>` over the gutter column, the
|
|
46
48
|
* height of the display, with `AxisCaption` inside.
|
|
47
49
|
*/
|
|
48
|
-
export function AxisCaptionOverlay({ axis, bandTops, width, height, }) {
|
|
50
|
+
export const AxisCaptionOverlay = observer(function AxisCaptionOverlay({ axis, bandTops, width, height, }) {
|
|
49
51
|
return (_jsx("svg", { style: {
|
|
50
52
|
position: 'absolute',
|
|
51
53
|
top: 0,
|
|
@@ -54,4 +56,4 @@ export function AxisCaptionOverlay({ axis, bandTops, width, height, }) {
|
|
|
54
56
|
height,
|
|
55
57
|
width: axisGutterWidth(axis),
|
|
56
58
|
}, children: _jsx(AxisCaption, { axis: axis, bandTops: bandTops, height: height }) }));
|
|
57
|
-
}
|
|
59
|
+
});
|
package/esm/AxisGutter.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { YAxis } from './valueScale.ts';
|
|
2
2
|
/**
|
|
3
3
|
* One band's axis drawn inside its gutter, the origin at the gutter's left
|
|
4
|
-
* edge: the spine on the gutter's
|
|
5
|
-
*
|
|
4
|
+
* edge: the spine on the gutter's left edge with the numbers growing right
|
|
5
|
+
* where `numbersGrowRight` says so, and on its right edge otherwise. The
|
|
6
6
|
* on-screen overlay and the export both draw through this, so the two cannot
|
|
7
7
|
* place a spine differently. The scale's caption is `AxisCaption`'s, drawn once
|
|
8
8
|
* for the scale and not per band.
|
package/esm/AxisGutter.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import YScaleBar from './YScaleBar.js';
|
|
3
|
-
import { axisGutterWidth } from './axisPlacement.js';
|
|
3
|
+
import { axisGutterWidth, numbersGrowRight } from './axisPlacement.js';
|
|
4
4
|
/**
|
|
5
5
|
* One band's axis drawn inside its gutter, the origin at the gutter's left
|
|
6
|
-
* edge: the spine on the gutter's
|
|
7
|
-
*
|
|
6
|
+
* edge: the spine on the gutter's left edge with the numbers growing right
|
|
7
|
+
* where `numbersGrowRight` says so, and on its right edge otherwise. The
|
|
8
8
|
* on-screen overlay and the export both draw through this, so the two cannot
|
|
9
9
|
* place a spine differently. The scale's caption is `AxisCaption`'s, drawn once
|
|
10
10
|
* for the scale and not per band.
|
|
11
11
|
*/
|
|
12
|
+
// eslint-disable-next-line no-restricted-syntax -- drawn inside a frozen SVG figure
|
|
12
13
|
export default function AxisGutter({ axis }) {
|
|
13
|
-
const right = axis
|
|
14
|
+
const right = numbersGrowRight(axis);
|
|
14
15
|
return (_jsx("g", { transform: `translate(${right ? 0 : axisGutterWidth(axis)} 0)`, children: _jsx(YScaleBar, { ticks: axis.ticks, orientation: right ? 'right' : 'left', bandHeight: axis.height }) }));
|
|
15
16
|
}
|
package/esm/CrossHatches.d.ts
CHANGED
|
@@ -4,9 +4,10 @@ export declare function CrossHatchLines({ ticks, width, offsetY, }: {
|
|
|
4
4
|
width: number;
|
|
5
5
|
offsetY?: number;
|
|
6
6
|
}): import("react").JSX.Element;
|
|
7
|
-
|
|
7
|
+
declare const CrossHatches: ({ ticks, width, height, bandTops, }: {
|
|
8
8
|
ticks: YScaleTicks;
|
|
9
9
|
width: number;
|
|
10
10
|
height: number;
|
|
11
11
|
bandTops: number[];
|
|
12
|
-
})
|
|
12
|
+
}) => import("react").JSX.Element;
|
|
13
|
+
export default CrossHatches;
|
package/esm/CrossHatches.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { observer } from 'mobx-react';
|
|
2
3
|
import { clampStrokeInsideAxis } from './yScaleTicks.js';
|
|
3
4
|
// Bare <line> set for the Y-scale tick guide lines, no wrapping <svg>. Shared by
|
|
4
5
|
// the absolutely-positioned on-screen CrossHatches overlay and the flat SVG
|
|
5
6
|
// export, so the two can't drift. `offsetY` is the band's top.
|
|
7
|
+
// eslint-disable-next-line no-restricted-syntax -- drawn inside a frozen SVG figure
|
|
6
8
|
export function CrossHatchLines({ ticks, width, offsetY = 0, }) {
|
|
7
9
|
return (_jsx(_Fragment, { children: ticks.items.map(({ value, y }) => {
|
|
8
10
|
// Same clamp the axis ticks take, so a guide line and the tick it
|
|
@@ -19,7 +21,7 @@ export function CrossHatchLines({ ticks, width, offsetY = 0, }) {
|
|
|
19
21
|
}
|
|
20
22
|
// Horizontal guide lines at each Y-scale tick, once per band the scale rules.
|
|
21
23
|
// Pointer-events disabled so the underlying canvas still receives mouse events.
|
|
22
|
-
|
|
24
|
+
const CrossHatches = observer(function CrossHatches({ ticks, width, height, bandTops, }) {
|
|
23
25
|
return (_jsx("svg", { style: {
|
|
24
26
|
position: 'absolute',
|
|
25
27
|
top: 0,
|
|
@@ -28,4 +30,5 @@ export default function CrossHatches({ ticks, width, height, bandTops, }) {
|
|
|
28
30
|
height,
|
|
29
31
|
width,
|
|
30
32
|
}, children: bandTops.map(top => (_jsx(CrossHatchLines, { ticks: ticks, width: width, offsetY: top }, top))) }));
|
|
31
|
-
}
|
|
33
|
+
});
|
|
34
|
+
export default CrossHatches;
|
|
@@ -63,8 +63,9 @@ export declare function resolveOverlays(overlays?: Partial<DisplayChromeOverlays
|
|
|
63
63
|
* prop and imports no toolkit. See
|
|
64
64
|
* [DISPLAYCHROME.md](https://github.com/GMOD/jbrowse-components/blob/main/agent-docs/reference/DISPLAYCHROME.md).
|
|
65
65
|
*/
|
|
66
|
-
|
|
66
|
+
declare const DisplayUIProvider: ({ overlays, trackControl, children, }: {
|
|
67
67
|
overlays?: Partial<DisplayChromeOverlays>;
|
|
68
68
|
trackControl?: TrackControlComponent;
|
|
69
69
|
children: ReactNode;
|
|
70
|
-
})
|
|
70
|
+
}) => import("react").JSX.Element;
|
|
71
|
+
export default DisplayUIProvider;
|
package/esm/DisplayUIProvider.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { observer } from 'mobx-react';
|
|
2
3
|
import { DisplayChromeOverlayProvider } from './chromeOverlayContext.js';
|
|
3
4
|
import plainChromeOverlays from './plainChromeOverlays.js';
|
|
4
5
|
import plainTrackControl from './trackControl/plainTrackControl.js';
|
|
@@ -91,6 +92,7 @@ export function resolveOverlays(overlays) {
|
|
|
91
92
|
* prop and imports no toolkit. See
|
|
92
93
|
* [DISPLAYCHROME.md](https://github.com/GMOD/jbrowse-components/blob/main/agent-docs/reference/DISPLAYCHROME.md).
|
|
93
94
|
*/
|
|
94
|
-
|
|
95
|
+
const DisplayUIProvider = observer(function DisplayUIProvider({ overlays, trackControl = plainTrackControl, children, }) {
|
|
95
96
|
return (_jsx(DisplayChromeOverlayProvider, { value: resolveOverlays(overlays), children: _jsx(TrackControlProvider, { value: trackControl, children: children }) }));
|
|
96
|
-
}
|
|
97
|
+
});
|
|
98
|
+
export default DisplayUIProvider;
|
package/esm/FloatingLegend.js
CHANGED
|
@@ -193,7 +193,7 @@ function gradientCss({ stops }, paper) {
|
|
|
193
193
|
});
|
|
194
194
|
return `linear-gradient(to right, ${list.join(', ')})`;
|
|
195
195
|
}
|
|
196
|
-
function GradientRow({ label, gradient, }) {
|
|
196
|
+
const GradientRow = observer(function GradientRow({ label, gradient, }) {
|
|
197
197
|
const { classes, theme } = useStyles();
|
|
198
198
|
return (_jsxs("div", { className: classes.gradientRow, children: [label ? _jsx("div", { className: classes.label, children: label }) : null, _jsx("div", { className: classes.gradientBar,
|
|
199
199
|
// backgroundImage (longhand), not the `background` shorthand: the
|
|
@@ -202,7 +202,7 @@ function GradientRow({ label, gradient, }) {
|
|
|
202
202
|
style: {
|
|
203
203
|
backgroundImage: gradientCss(gradient, theme.palette.background.paper),
|
|
204
204
|
} }), _jsxs("div", { className: classes.gradientLabels, children: [_jsx("span", { children: gradient.minLabel }), _jsx("span", { children: gradient.maxLabel })] })] }));
|
|
205
|
-
}
|
|
205
|
+
});
|
|
206
206
|
// One list of swatches with its own independent collapse state, so each section
|
|
207
207
|
// in a multi-section legend expands/collapses on its own.
|
|
208
208
|
const LegendItemList = observer(function LegendItemList({ items, maxItems, onItemClick, }) {
|
package/esm/FloatingText.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CSSProperties, ComponentPropsWithoutRef, ReactNode } from 'react';
|
|
2
2
|
/**
|
|
3
|
-
* Four offset shadows in the surface
|
|
3
|
+
* Four offset shadows in the surface color: a halo under a line of DOM text
|
|
4
4
|
* that needs no measured stroke and reads the same over a mark and over the
|
|
5
5
|
* background.
|
|
6
6
|
*/
|
|
@@ -17,11 +17,11 @@ export declare const TEXT_BASELINE_RATIO = 0.84;
|
|
|
17
17
|
* The canvas feature labels and the mark display's text marks emit through
|
|
18
18
|
* this, so the typography of a floated label is one declaration; what places
|
|
19
19
|
* each label is its display's own rule. `halo` draws {@link textHalo} under
|
|
20
|
-
* the glyphs in that
|
|
20
|
+
* the glyphs in that color. Everything else a caller passes reaches the div:
|
|
21
21
|
* a class for the pointer and the cursor, the data attributes a delegated
|
|
22
22
|
* handler reads, a `title`.
|
|
23
23
|
*/
|
|
24
|
-
export declare
|
|
24
|
+
export declare const FloatingText: ({ x, y, color, fontSize, halo, style, children, ...rest }: {
|
|
25
25
|
x: number;
|
|
26
26
|
y: number;
|
|
27
27
|
color: string;
|
|
@@ -29,10 +29,10 @@ export declare function FloatingText({ x, y, color, fontSize, halo, style, child
|
|
|
29
29
|
halo?: string;
|
|
30
30
|
style?: CSSProperties;
|
|
31
31
|
children: ReactNode;
|
|
32
|
-
} & Omit<ComponentPropsWithoutRef<'div'>, 'style' | 'color' | 'children'>)
|
|
32
|
+
} & Omit<ComponentPropsWithoutRef<'div'>, 'style' | 'color' | 'children'>) => import("react").JSX.Element;
|
|
33
33
|
/**
|
|
34
34
|
* The same line in an SVG export: two `<text>`s at the baseline `y`, a stroke
|
|
35
|
-
* in the surface
|
|
35
|
+
* in the surface color under the glyphs, since SVG paints stroke over fill
|
|
36
36
|
* and a thick stroke beneath a second copy is how a halo is drawn there. Both
|
|
37
37
|
* carry the size, because a `<text>` without one takes SVG's 16px default in a
|
|
38
38
|
* saved file. An export leaves `fontFamily` out, so the label inherits the
|
package/esm/FloatingText.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { observer } from 'mobx-react';
|
|
2
3
|
/**
|
|
3
|
-
* Four offset shadows in the surface
|
|
4
|
+
* Four offset shadows in the surface color: a halo under a line of DOM text
|
|
4
5
|
* that needs no measured stroke and reads the same over a mark and over the
|
|
5
6
|
* background.
|
|
6
7
|
*/
|
|
@@ -19,11 +20,11 @@ export const TEXT_BASELINE_RATIO = 0.84;
|
|
|
19
20
|
* The canvas feature labels and the mark display's text marks emit through
|
|
20
21
|
* this, so the typography of a floated label is one declaration; what places
|
|
21
22
|
* each label is its display's own rule. `halo` draws {@link textHalo} under
|
|
22
|
-
* the glyphs in that
|
|
23
|
+
* the glyphs in that color. Everything else a caller passes reaches the div:
|
|
23
24
|
* a class for the pointer and the cursor, the data attributes a delegated
|
|
24
25
|
* handler reads, a `title`.
|
|
25
26
|
*/
|
|
26
|
-
export function FloatingText({ x, y, color, fontSize, halo, style, children, ...rest }) {
|
|
27
|
+
export const FloatingText = observer(function FloatingText({ x, y, color, fontSize, halo, style, children, ...rest }) {
|
|
27
28
|
return (_jsx("div", { ...rest, style: {
|
|
28
29
|
position: 'absolute',
|
|
29
30
|
lineHeight: 1,
|
|
@@ -34,10 +35,10 @@ export function FloatingText({ x, y, color, fontSize, halo, style, children, ...
|
|
|
34
35
|
...(halo ? { textShadow: textHalo(halo) } : {}),
|
|
35
36
|
...style,
|
|
36
37
|
}, children: children }));
|
|
37
|
-
}
|
|
38
|
+
});
|
|
38
39
|
/**
|
|
39
40
|
* The same line in an SVG export: two `<text>`s at the baseline `y`, a stroke
|
|
40
|
-
* in the surface
|
|
41
|
+
* in the surface color under the glyphs, since SVG paints stroke over fill
|
|
41
42
|
* and a thick stroke beneath a second copy is how a halo is drawn there. Both
|
|
42
43
|
* carry the size, because a `<text>` without one takes SVG's 16px default in a
|
|
43
44
|
* saved file. An export leaves `fontFamily` out, so the label inherits the
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The one-line `[min, max]` caption that stands in for a y axis where none can
|
|
3
3
|
* be drawn — a scale whose bands are too short for tick labels, and a density
|
|
4
|
-
* track whose rows each carry their own
|
|
5
|
-
* them. An axis stand-in rather than a key, which is why it is not a
|
|
4
|
+
* track whose rows each carry their own color, so no single ramp describes
|
|
5
|
+
* them. An axis stand-in rather than a key, which is why it is not a color
|
|
6
6
|
* scale and draws whether or not the legend does. Right-aligned to
|
|
7
7
|
* `canvasWidth` at the top of the display, led by the scale's `caption` where
|
|
8
8
|
* it has one, which has no gutter to sit in here.
|
|
@@ -7,12 +7,13 @@ import { SCORE_CAPTION_HEIGHT } from './yAxisConstants.js';
|
|
|
7
7
|
/**
|
|
8
8
|
* The one-line `[min, max]` caption that stands in for a y axis where none can
|
|
9
9
|
* be drawn — a scale whose bands are too short for tick labels, and a density
|
|
10
|
-
* track whose rows each carry their own
|
|
11
|
-
* them. An axis stand-in rather than a key, which is why it is not a
|
|
10
|
+
* track whose rows each carry their own color, so no single ramp describes
|
|
11
|
+
* them. An axis stand-in rather than a key, which is why it is not a color
|
|
12
12
|
* scale and draws whether or not the legend does. Right-aligned to
|
|
13
13
|
* `canvasWidth` at the top of the display, led by the scale's `caption` where
|
|
14
14
|
* it has one, which has no gutter to sit in here.
|
|
15
15
|
*/
|
|
16
|
+
// eslint-disable-next-line no-restricted-syntax -- drawn inside a frozen SVG figure
|
|
16
17
|
export default function ScoreDomainCaption({ domain, scaleType, canvasWidth, caption, }) {
|
|
17
18
|
const palette = usePalette();
|
|
18
19
|
const suffix = scaleType === 'log' ? ' (log)' : scaleType === 'symlog' ? ' (symlog)' : '';
|
package/esm/ScoreRules.d.ts
CHANGED
|
@@ -13,9 +13,10 @@ export declare function ScoreRuleLines({ marks, width, offsetY, }: {
|
|
|
13
13
|
width: number;
|
|
14
14
|
offsetY?: number;
|
|
15
15
|
}): import("react").JSX.Element;
|
|
16
|
-
|
|
16
|
+
declare const ScoreRules: ({ marks, width, height, bandTops, }: {
|
|
17
17
|
marks: ScoreRuleMark[];
|
|
18
18
|
width: number;
|
|
19
19
|
height: number;
|
|
20
20
|
bandTops: number[];
|
|
21
|
-
})
|
|
21
|
+
}) => import("react").JSX.Element;
|
|
22
|
+
export default ScoreRules;
|
package/esm/ScoreRules.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { usePalette } from '@jbrowse/core/ui/PaletteContext';
|
|
3
|
+
import { observer } from 'mobx-react';
|
|
3
4
|
import { DEFAULT_RULE_COLOR } from './yAxisConstants.js';
|
|
4
5
|
const LABEL_FONT_SIZE = 10;
|
|
5
6
|
const LABEL_GAP = 2;
|
|
@@ -12,6 +13,7 @@ function labelY(y, offsetY) {
|
|
|
12
13
|
}
|
|
13
14
|
// Bare marks, no wrapping <svg>, so the on-screen overlay and the SVG export
|
|
14
15
|
// draw the same elements from the same y. Same split as CrossHatchLines.
|
|
16
|
+
// eslint-disable-next-line no-restricted-syntax -- drawn inside a frozen SVG figure
|
|
15
17
|
export function ScoreRuleLines({ marks, width, offsetY = 0, }) {
|
|
16
18
|
// A caption sits over the plot, not beside it, so it needs the halo the tick
|
|
17
19
|
// labels next to it already draw (YScaleBar) — without one a rule crossing
|
|
@@ -34,7 +36,7 @@ export function ScoreRuleLines({ marks, width, offsetY = 0, }) {
|
|
|
34
36
|
}
|
|
35
37
|
// Once per band the scale rules, like CrossHatches; pointer-events disabled so
|
|
36
38
|
// the canvas underneath still gets mouse events.
|
|
37
|
-
|
|
39
|
+
const ScoreRules = observer(function ScoreRules({ marks, width, height, bandTops, }) {
|
|
38
40
|
return (_jsx("svg", { style: {
|
|
39
41
|
position: 'absolute',
|
|
40
42
|
top: 0,
|
|
@@ -43,4 +45,5 @@ export default function ScoreRules({ marks, width, height, bandTops, }) {
|
|
|
43
45
|
height,
|
|
44
46
|
width,
|
|
45
47
|
}, children: bandTops.map(top => (_jsx(ScoreRuleLines, { marks: marks, width: width, offsetY: top }, top))) }));
|
|
46
|
-
}
|
|
48
|
+
});
|
|
49
|
+
export default ScoreRules;
|
package/esm/YScaleBar.js
CHANGED
|
@@ -2,18 +2,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { usePalette } from '@jbrowse/core/ui/PaletteContext';
|
|
3
3
|
import { AXIS_FONT_PX, TICK_LABEL_X_PX } from './yAxisConstants.js';
|
|
4
4
|
import { clampStrokeInsideAxis } from './yScaleTicks.js';
|
|
5
|
-
// Not an `observer`, and deliberately: there is nothing here to observe. Every
|
|
6
|
-
// caller already reads `model.ticks` inside its own observer and hands the
|
|
7
|
-
// resolved plain object down, and `usePalette` is a React context, not MobX.
|
|
8
|
-
// Wrapping it anyway allocated a Reaction per instance — multi-wiggle renders
|
|
9
|
-
// one per sample row, on screen as well as in export — and, per CLAUDE.md, put
|
|
10
|
-
// the component out of `babel-plugin-react-compiler`'s reach, so it got neither
|
|
11
|
-
// the MobX tracking it doesn't need nor the memoization it does. Its sibling
|
|
12
|
-
// `CrossHatchLines`, consuming the same ticks, is already plain.
|
|
13
5
|
// Half the vertical space a 10px label needs, halo included: digits reach about
|
|
14
6
|
// 3.6px above the centered baseline and the 2.5px-wide background stroke another
|
|
15
7
|
// 1.25px past that.
|
|
16
8
|
const LABEL_HALF_HEIGHT_PX = 5;
|
|
9
|
+
// eslint-disable-next-line no-restricted-syntax -- drawn inside a frozen SVG figure
|
|
17
10
|
export default function YScaleBar({ ticks, orientation, bandHeight, }) {
|
|
18
11
|
const palette = usePalette();
|
|
19
12
|
if (!ticks) {
|
|
@@ -4,8 +4,9 @@ import type { YAxis } from './valueScale.ts';
|
|
|
4
4
|
* positioned absolutely over the band at `top`, with `AxisGutter` inside. A
|
|
5
5
|
* right-side gutter clears the vertical scrollbar a display may mount.
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
declare const YScaleBarOverlay: ({ axis, top, width, }: {
|
|
8
8
|
axis: YAxis;
|
|
9
9
|
top: number;
|
|
10
10
|
width: number;
|
|
11
|
-
})
|
|
11
|
+
}) => import("react").JSX.Element;
|
|
12
|
+
export default YScaleBarOverlay;
|