@weasel-js/labkit 1.6.0 → 1.7.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.
- package/dist/_dts/{CanvasStackContext-DQgcH1ny.d.ts → CanvasStackContext-D2jnIwfk.d.ts} +1 -1
- package/dist/_dts/FloatingPanel-7j0IcXwz.d.ts +30 -0
- package/dist/_dts/{LayerList.d-2c9yup5Y.d.ts → LayerList.d-DiuEArKq.d.ts} +4 -4
- package/dist/_dts/PrefsRow.d-TOZ7BgD9.d.ts +79 -0
- package/dist/_dts/PropertyPanel.d-D-1paCbE.d.ts +141 -0
- package/dist/_dts/{Select.d-BchGMC2Y.d.ts → Select.d-Bensr_MT.d.ts} +15 -6
- package/dist/_dts/Stage-CCWfQQWM.d.ts +202 -0
- package/dist/_dts/index-B2Yj5aA0.d.ts +274 -0
- package/dist/_dts/{index-B0--8PEM.d.ts → index-CsYqUHD3.d.ts} +12 -13
- package/dist/_dts/{types-B7y8hX1D.d.ts → types-CRPSGFAp.d.ts} +33 -5
- package/dist/_dts/{frac-DTRq7Xpb.d.ts → types-CSm9jgol.d.ts} +700 -650
- package/dist/_dts/{useTrialState-CP4jfuKl.d.ts → useTrialState-CTZPgeZ7.d.ts} +2 -3
- package/dist/canvas/index.d.ts +40 -8
- package/dist/canvas/index.js +5 -3
- package/dist/chrome/index.d.ts +5 -6
- package/dist/chrome/index.js +9 -7
- package/dist/chunk-24W5VEJW.js +18 -0
- package/dist/chunk-24W5VEJW.js.map +1 -0
- package/dist/chunk-275JRRVD.js +728 -0
- package/dist/chunk-275JRRVD.js.map +1 -0
- package/dist/chunk-3RY6WL5T.js +38 -0
- package/dist/chunk-3RY6WL5T.js.map +1 -0
- package/dist/chunk-4LJSC7MB.js +143 -0
- package/dist/chunk-4LJSC7MB.js.map +1 -0
- package/dist/{chunk-3FI7Y4R4.js → chunk-7BO7HNGF.js} +5 -5
- package/dist/{chunk-3FI7Y4R4.js.map → chunk-7BO7HNGF.js.map} +1 -1
- package/dist/chunk-AWQG7FCC.js +19 -0
- package/dist/chunk-AWQG7FCC.js.map +1 -0
- package/dist/chunk-CZZPXUOU.js +3 -0
- package/dist/{chunk-SBXNQW4G.js.map → chunk-CZZPXUOU.js.map} +1 -1
- package/dist/{chunk-ZORVNOKX.js → chunk-FMK7UQ6V.js} +24 -145
- package/dist/chunk-FMK7UQ6V.js.map +1 -0
- package/dist/{chunk-BVL7Y574.js → chunk-FZ7YFQN7.js} +26 -10
- package/dist/chunk-FZ7YFQN7.js.map +1 -0
- package/dist/{chunk-USO6TERP.js → chunk-GOZLNM4L.js} +11 -9
- package/dist/chunk-GOZLNM4L.js.map +1 -0
- package/dist/{chunk-H5VIV7MQ.js → chunk-I5DUQ5HM.js} +88 -82
- package/dist/chunk-I5DUQ5HM.js.map +1 -0
- package/dist/chunk-J7OWWTCW.js +143 -0
- package/dist/chunk-J7OWWTCW.js.map +1 -0
- package/dist/{chunk-H6ZAOWNE.js → chunk-JVBYV6TL.js} +3 -3
- package/dist/{chunk-H6ZAOWNE.js.map → chunk-JVBYV6TL.js.map} +1 -1
- package/dist/{chunk-VQ47KWD5.js → chunk-KMJ7RWD3.js} +18 -7
- package/dist/chunk-KMJ7RWD3.js.map +1 -0
- package/dist/{chunk-ERFMC6WU.js → chunk-M7HP3FTK.js} +20 -11
- package/dist/chunk-M7HP3FTK.js.map +1 -0
- package/dist/chunk-MIM5R4ZT.js +14972 -0
- package/dist/chunk-MIM5R4ZT.js.map +1 -0
- package/dist/{chunk-HFRE4QQV.js → chunk-T5IBSPAM.js} +96 -32
- package/dist/chunk-T5IBSPAM.js.map +1 -0
- package/dist/chunk-UNAZSLWE.js +294 -0
- package/dist/chunk-UNAZSLWE.js.map +1 -0
- package/dist/{chunk-RS3HRQWU.js → chunk-WPLAANH4.js} +4 -3
- package/dist/chunk-WPLAANH4.js.map +1 -0
- package/dist/{chunk-AWH3SRPW.js → chunk-Y23G2VZL.js} +5 -37
- package/dist/chunk-Y23G2VZL.js.map +1 -0
- package/dist/{chunk-MOLIUNVH.js → chunk-YT75VYRD.js} +4 -4
- package/dist/{chunk-MOLIUNVH.js.map → chunk-YT75VYRD.js.map} +1 -1
- package/dist/chunk-ZIFPHIWZ.js +302 -0
- package/dist/chunk-ZIFPHIWZ.js.map +1 -0
- package/dist/config/index.d.ts +48 -40
- package/dist/config/index.js +4 -5
- package/dist/controls/index.d.ts +91 -7
- package/dist/controls/index.js +5 -4
- package/dist/dragdrop/index.d.ts +9 -7
- package/dist/dragdrop/index.js +3 -2
- package/dist/index.d.ts +294 -82
- package/dist/index.js +425 -402
- package/dist/index.js.map +1 -1
- package/dist/layers/index.d.ts +4 -5
- package/dist/layers/index.js +2 -1
- package/dist/loupe/index.d.ts +20 -17
- package/dist/loupe/index.js +5 -3
- package/dist/overview/index.d.ts +56 -0
- package/dist/overview/index.js +289 -0
- package/dist/overview/index.js.map +1 -0
- package/dist/passthrough/weasel-ui.d.ts +239 -69
- package/dist/passthrough/weasel-ui.js +3 -2
- package/dist/primitives/index.d.ts +5 -204
- package/dist/primitives/index.js +6 -4
- package/dist/state/index.d.ts +8 -8
- package/dist/state/index.js +4 -5
- package/dist/state/index.js.map +1 -1
- package/dist/styles.css +152 -82
- package/dist/undo/index.d.ts +4 -4
- package/package.json +17 -12
- package/src/annotations/AnnotationOverlay.tsx +2 -2
- package/src/annotations/Annotations.less +0 -10
- package/src/annotations/MarkList.tsx +4 -8
- package/src/annotations/index.ts +1 -0
- package/src/annotations/paint.test.ts +3 -14
- package/src/annotations/paint.ts +3 -19
- package/src/annotations/store.test.ts +26 -0
- package/src/annotations/store.ts +25 -6
- package/src/annotations/svgNodes.test.ts +6 -9
- package/src/annotations/svgNodes.ts +3 -3
- package/src/annotations/toolMap.test.ts +37 -2
- package/src/annotations/toolMap.ts +13 -0
- package/src/annotations/types.ts +27 -0
- package/src/canvas/AGENTS.md +9 -10
- package/src/canvas/CameraInput.test.tsx +136 -0
- package/src/canvas/CameraInput.tsx +322 -0
- package/src/canvas/CanvasStack.tsx +47 -58
- package/src/canvas/LinkedCursor.less +16 -0
- package/src/canvas/LinkedCursor.tsx +54 -0
- package/src/canvas/Stage.test.tsx +33 -4
- package/src/canvas/Stage.tsx +47 -37
- package/src/canvas/cameraRegistry.test.ts +55 -0
- package/src/canvas/cameraRegistry.ts +86 -0
- package/src/canvas/cameraView.test.ts +60 -0
- package/src/canvas/cameraView.ts +61 -0
- package/src/canvas/cameraZoom.test.ts +46 -0
- package/src/canvas/cameraZoom.ts +24 -0
- package/src/canvas/index.ts +23 -2
- package/src/canvas/sharedScope.test.tsx +94 -0
- package/src/chrome/ChromeRegions.stories.tsx +1 -0
- package/src/chrome/regions/PaletteRegion.less +0 -7
- package/src/chrome/regions/SidebarRegion.less +12 -2
- package/src/chrome/regions/SidebarRegion.test.tsx +9 -2
- package/src/config/builder.test.ts +2 -1
- package/src/config/builder.ts +15 -8
- package/src/config/entry.test.ts +3 -1
- package/src/config/fromConfigField.test.ts +14 -0
- package/src/config/fromConfigField.ts +19 -4
- package/src/config/index.ts +4 -1
- package/src/config/path.ts +2 -5
- package/src/config/resolve.ts +15 -1
- package/src/config/sectionTree.test.ts +12 -6
- package/src/config/sectionTree.ts +15 -5
- package/src/config/types.ts +34 -9
- package/src/controls/ControlPanel.less +1 -1
- package/src/controls/ControlPanel.stories.tsx +3 -2
- package/src/controls/ControlPanel.test.tsx +76 -13
- package/src/controls/ControlPanel.tsx +80 -11
- package/src/controls/inDialog.test.tsx +18 -0
- package/src/controls/inDialog.tsx +2 -10
- package/src/index.test.ts +1 -1
- package/src/index.ts +23 -5
- package/src/instrument/SineWave.smoke.test.tsx +2 -0
- package/src/instrument/types.ts +10 -1
- package/src/lab/Lab.nebula.test.tsx +11 -2
- package/src/lab/Lab.test.tsx +3 -1
- package/src/lab/Lab.tsx +87 -76
- package/src/lab/{LabFit.stories.less → LabFit.browser.test.less} +1 -1
- package/src/lab/{LabFit.stories.tsx → LabFit.browser.test.tsx} +41 -63
- package/src/lab/LabFullChrome.stories.tsx +1 -0
- package/src/lab/LabHeader.test.tsx +24 -14
- package/src/lab/LabHeader.tsx +11 -12
- package/src/lab/LabShell.less +8 -17
- package/src/lab/LabSwitcher.less +6 -6
- package/src/lab/LabZoom.test.tsx +223 -0
- package/src/lab/LabZoom.tsx +170 -0
- package/src/lab/index.ts +1 -0
- package/src/loupe/AGENTS.md +7 -6
- package/src/loupe/LoupeGestures.tsx +15 -10
- package/src/loupe/TrialLoupe.tsx +5 -5
- package/src/loupe/index.ts +1 -0
- package/src/loupe/loupeActions.ts +6 -2
- package/src/overview/AGENTS.md +38 -0
- package/src/overview/OverviewMarks.test.tsx +100 -0
- package/src/overview/OverviewMarks.tsx +93 -0
- package/src/overview/TrialOverview.less +53 -0
- package/src/overview/TrialOverview.stories.tsx +50 -0
- package/src/overview/TrialOverview.test.tsx +116 -0
- package/src/overview/TrialOverview.tsx +376 -0
- package/src/overview/index.ts +2 -0
- package/src/passthrough/weasel-ui.test.ts +2 -0
- package/src/passthrough/weasel-ui.ts +23 -4
- package/src/primitives/FloatingPanel.test.tsx +11 -0
- package/src/primitives/FloatingPanel.tsx +2 -5
- package/src/primitives/JobProgress.less +1 -1
- package/src/primitives/Legend.stories.tsx +1 -0
- package/src/primitives/Readout.browser.test.tsx +137 -0
- package/src/primitives/Readout.less +12 -0
- package/src/primitives/Readout.stories.tsx +58 -0
- package/src/primitives/Readout.test.tsx +93 -0
- package/src/primitives/Readout.tsx +56 -0
- package/src/primitives/index.ts +2 -0
- package/src/specimen/Specimen.stories.tsx +1 -0
- package/src/specimen/Specimen.tsx +21 -4
- package/src/state/Persistence.browser.test.tsx +47 -0
- package/src/state/labRecords.test.ts +4 -1
- package/src/state/store.test.ts +9 -5
- package/src/state/usePersistedState.test.tsx +1 -1
- package/src/state/useTrialState.test.tsx +1 -1
- package/src/styles.less +3 -0
- package/src/theme/Interstellar.stories.tsx +4 -6
- package/src/theme/base.less +21 -47
- package/src/theme/interstellar.test.ts +1 -1
- package/src/theme/interstellar.theme.json +10 -3
- package/src/tools/labTool.ts +6 -2
- package/src/trial/Trial.annotations.test.tsx +16 -0
- package/src/trial/Trial.less +0 -13
- package/src/trial/Trial.loupe.test.tsx +73 -1
- package/src/trial/Trial.stories.tsx +2 -0
- package/src/trial/Trial.tsx +23 -1
- package/src/trial/TrialChrome.tsx +21 -3
- package/src/trial/trialOps.test.ts +4 -4
- package/dist/_dts/PrefsRow.d-DFpPIeIC.d.ts +0 -39
- package/dist/_dts/inDialog-D5ZKGjiD.d.ts +0 -23
- package/dist/_dts/index-DINmCuLA.d.ts +0 -453
- package/dist/_dts/number.d-OeQYQoUO.d.ts +0 -28
- package/dist/_dts/usePanZoom-Bq73pwFe.d.ts +0 -117
- package/dist/chunk-2AYGEN57.js +0 -32
- package/dist/chunk-2AYGEN57.js.map +0 -1
- package/dist/chunk-AWH3SRPW.js.map +0 -1
- package/dist/chunk-BVL7Y574.js.map +0 -1
- package/dist/chunk-ERFMC6WU.js.map +0 -1
- package/dist/chunk-H5VIV7MQ.js.map +0 -1
- package/dist/chunk-HFRE4QQV.js.map +0 -1
- package/dist/chunk-RS3HRQWU.js.map +0 -1
- package/dist/chunk-SBXNQW4G.js +0 -3
- package/dist/chunk-TT5C5S6R.js +0 -368
- package/dist/chunk-TT5C5S6R.js.map +0 -1
- package/dist/chunk-USO6TERP.js.map +0 -1
- package/dist/chunk-VQ47KWD5.js.map +0 -1
- package/dist/chunk-WUJXJC5O.js +0 -14568
- package/dist/chunk-WUJXJC5O.js.map +0 -1
- package/dist/chunk-ZORVNOKX.js.map +0 -1
- package/src/canvas/usePanZoom.test.ts +0 -244
- package/src/canvas/usePanZoom.ts +0 -147
- package/src/state/Persistence.stories.tsx +0 -75
|
@@ -1,453 +0,0 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import * as react from 'react';
|
|
3
|
-
import { ReactNode } from 'react';
|
|
4
|
-
import { S as StanceProps } from './PrefsRow.d-DFpPIeIC.js';
|
|
5
|
-
import { ToolPrefNumberFormat, FillStyle, PaintKind } from '@weasel-js/core';
|
|
6
|
-
import { U as UnitTable } from './number.d-OeQYQoUO.js';
|
|
7
|
-
import { R as ResolvedConfig, b as ConfigField, C as ControlRenderer } from './types-B7y8hX1D.js';
|
|
8
|
-
import './inDialog-D5ZKGjiD.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* How much room a container gives its rows — gaps, padding, and field height,
|
|
12
|
-
* moved together. Set on any container in the family; it reaches every
|
|
13
|
-
* descendant, so an inner group can differ from the panel around it.
|
|
14
|
-
*/
|
|
15
|
-
type PropertyDensity = 'tight' | 'normal' | 'roomy';
|
|
16
|
-
/** Where an inline row's label and control sit on the row's cross axis. Set on
|
|
17
|
-
* a container to line a whole column of them up. */
|
|
18
|
-
type PropertyAlign = 'start' | 'center' | 'end' | 'baseline';
|
|
19
|
-
/** Metric props every container in the family takes. Both reach descendants,
|
|
20
|
-
* so the nearest container that states one wins. */
|
|
21
|
-
interface PropertyMetricProps {
|
|
22
|
-
/** Room the rows get. Unset inherits from an outer container, else `normal`. */
|
|
23
|
-
density?: PropertyDensity;
|
|
24
|
-
/**
|
|
25
|
-
* Cross-axis alignment of an inline row's label and control. `baseline` sits
|
|
26
|
-
* the control on the label's first-line baseline, which is what lines a
|
|
27
|
-
* column of swatches up against labels of different heights. Unset keeps each
|
|
28
|
-
* variant's own alignment — a color row centers its label and swatch and
|
|
29
|
-
* sinks the pair to the row's bottom edge, which keeps a paired alpha track
|
|
30
|
-
* level with its neighbour.
|
|
31
|
-
*/
|
|
32
|
-
align?: PropertyAlign;
|
|
33
|
-
}
|
|
34
|
-
/** Props for `<PropertyPanel>`. */
|
|
35
|
-
interface PropertyPanelProps extends PropertyMetricProps, StanceProps {
|
|
36
|
-
title?: ReactNode;
|
|
37
|
-
/** Controls on the trailing edge of the title row — a switch, a clear
|
|
38
|
-
* button. They sit outside the heading, so they neither take its type nor
|
|
39
|
-
* join its accessible name. */
|
|
40
|
-
actions?: ReactNode;
|
|
41
|
-
/**
|
|
42
|
-
* Lets text inside the panel be selected and copied. A panel is chrome by
|
|
43
|
-
* default, so a drag across it moves a slider rather than painting a
|
|
44
|
-
* selection; a `debug` panel defaults to selectable, since what it shows —
|
|
45
|
-
* ids, keys, traces — is there to be copied.
|
|
46
|
-
*/
|
|
47
|
-
selectable?: boolean;
|
|
48
|
-
children: ReactNode;
|
|
49
|
-
className?: string;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* A titled panel holding property rows — the sidebar container the rest of
|
|
53
|
-
* this module's components fill.
|
|
54
|
-
*
|
|
55
|
-
* `stance` says what kind of content it holds and `tone` which of its peers it
|
|
56
|
-
* is; the theme's `--wzl-panel-*` and `--wzl-stance-*` slots decide how each looks. A stanced
|
|
57
|
-
* panel's title takes the row-label recipe rather than the display title.
|
|
58
|
-
*/
|
|
59
|
-
declare function PropertyPanel({ title, actions, selectable, children, className, density, align, stance, tone, }: PropertyPanelProps): react_jsx_runtime.JSX.Element;
|
|
60
|
-
/** How a property list packs its rows into two columns. */
|
|
61
|
-
type PropertyListPack = 'auto-color' | 'pairs' | 'one-up';
|
|
62
|
-
/** Props for `<PropertyList>`. */
|
|
63
|
-
interface PropertyListProps extends PropertyMetricProps {
|
|
64
|
-
children: ReactNode;
|
|
65
|
-
className?: string;
|
|
66
|
-
/**
|
|
67
|
-
* How rows pack into the 2-column grid.
|
|
68
|
-
* - `'auto-color'` (default): only color rows pair side-by-side; everything
|
|
69
|
-
* else spans the full width. Right for sparse top-level panels.
|
|
70
|
-
* - `'pairs'`: every row auto-places into the 2-column grid two-per-row.
|
|
71
|
-
* Headers and subpanels still span the full width; wrap any other
|
|
72
|
-
* full-width child in `<PropertySpan>`. Right for dense effect bodies.
|
|
73
|
-
* - `'one-up'`: every row spans the full width, color rows included. Right
|
|
74
|
-
* for a palette — a column of swatches read as a group.
|
|
75
|
-
*/
|
|
76
|
-
pack?: PropertyListPack;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Grid container for PropertyRows. Use standalone for chrome-less layouts, or
|
|
80
|
-
* nest inside <PropertyPanel/> for the standard glass card.
|
|
81
|
-
*/
|
|
82
|
-
declare const PropertyList: react.ForwardRefExoticComponent<PropertyListProps & react.RefAttributes<HTMLDivElement>>;
|
|
83
|
-
/** Props for `<PropertySpan>`. */
|
|
84
|
-
interface PropertySpanProps {
|
|
85
|
-
children: ReactNode;
|
|
86
|
-
className?: string;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Wrapper that makes an arbitrary child span both columns of a
|
|
90
|
-
* `<PropertyList pack="pairs">`, a `<PropertyGroup pack="pairs">` body, or a
|
|
91
|
-
* `<Subpanel>`. `<PropertyRow span>` covers the row case; this covers
|
|
92
|
-
* everything else a consumer puts in the grid.
|
|
93
|
-
*/
|
|
94
|
-
declare function PropertySpan({ children, className }: PropertySpanProps): react_jsx_runtime.JSX.Element;
|
|
95
|
-
/** Which control shape a row holds, which decides its intrinsic layout. */
|
|
96
|
-
type PropertyRowVariant = 'default' | 'color' | 'checkbox';
|
|
97
|
-
/** Whether a row's label sits above its control or beside it. */
|
|
98
|
-
type PropertyRowLayout = 'block' | 'inline';
|
|
99
|
-
/** Props for `<PropertyRow>`. */
|
|
100
|
-
interface PropertyRowProps extends PropertyMetricProps {
|
|
101
|
-
label: ReactNode;
|
|
102
|
-
/** Right-aligned readout shown next to the label (e.g. current value). */
|
|
103
|
-
readout?: ReactNode;
|
|
104
|
-
/**
|
|
105
|
-
* Help text for the row, shown in a tooltip off an ⓘ affordance beside the
|
|
106
|
-
* label. Empty or absent renders no affordance.
|
|
107
|
-
*/
|
|
108
|
-
description?: string;
|
|
109
|
-
variant?: PropertyRowVariant;
|
|
110
|
-
/**
|
|
111
|
-
* Label position relative to the control. Unset takes the variant's own
|
|
112
|
-
* orientation: `block` — label above control — for the default variant, and
|
|
113
|
-
* `inline` for the color and checkbox variants, which read as a row.
|
|
114
|
-
*/
|
|
115
|
-
layout?: PropertyRowLayout;
|
|
116
|
-
/**
|
|
117
|
-
* Take the full width of the enclosing grid. Only has an effect inside a
|
|
118
|
-
* `<PropertyList pack="pairs">` or a `<Subpanel>`; elsewhere rows are already
|
|
119
|
-
* full width.
|
|
120
|
-
*/
|
|
121
|
-
span?: boolean;
|
|
122
|
-
children: ReactNode;
|
|
123
|
-
htmlFor?: string;
|
|
124
|
-
/** The control is a group of several (a segmented toggle), not one element.
|
|
125
|
-
* The row then renders as a `<div>`: a `<label>` hands a click on its text to
|
|
126
|
-
* its first control, which in a group means selecting the first option. Each
|
|
127
|
-
* member has to carry its own name. */
|
|
128
|
-
group?: boolean;
|
|
129
|
-
className?: string;
|
|
130
|
-
/** The row is auto: its value is not pinned and the owner computes it. The
|
|
131
|
-
* control is hidden — its box kept, so the row does not resize — and the
|
|
132
|
-
* row reads out the word instead. */
|
|
133
|
-
auto?: boolean;
|
|
134
|
-
/** Given, the row's label toggles `auto` when it is clicked. Omitted, the row
|
|
135
|
-
* can show an auto state but not change it.
|
|
136
|
-
*
|
|
137
|
-
* The label then names that toggle, so a control passed as `children` has to
|
|
138
|
-
* carry its own accessible name — every `<PropertyField>` does. */
|
|
139
|
-
onAutoChange?: (next: boolean) => void;
|
|
140
|
-
/**
|
|
141
|
-
* What draws the row's control. `bare` (the default) is a native input the
|
|
142
|
-
* row's stylesheet dresses; `framed` is a kit field bringing its own frame,
|
|
143
|
-
* which the row then leaves alone — see {@link PropertyFieldChrome}.
|
|
144
|
-
*/
|
|
145
|
-
chrome?: PropertyFieldChrome;
|
|
146
|
-
}
|
|
147
|
-
/** The label-plus-control frame `<PropertyField>` draws its rows in. Use it
|
|
148
|
-
* directly for a control no field kind covers. */
|
|
149
|
-
declare function PropertyRow({ label, readout, description, variant, layout, span, children, htmlFor, group, className, density, align, auto, onAutoChange, chrome, }: PropertyRowProps): react_jsx_runtime.JSX.Element;
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Which controls a field is drawn with.
|
|
153
|
-
*
|
|
154
|
-
* - `'bare'` (the default): native inputs the property row's own stylesheet
|
|
155
|
-
* draws — the compact controls of an inspector sidebar or a lab panel.
|
|
156
|
-
* - `'framed'`: the kit's field components, each bringing its own frame —
|
|
157
|
-
* for a surface whose row does not style its controls (`SelectionPanel`,
|
|
158
|
-
* `ToolOptionsBar`), or that needs what only they do, such as reading a
|
|
159
|
-
* unit typed into a number (`accepts`).
|
|
160
|
-
*
|
|
161
|
-
* The two differ only where the kit still has two widgets for one job; a
|
|
162
|
-
* slider, a switch, a font picker and a paint are the same in both.
|
|
163
|
-
*/
|
|
164
|
-
type PropertyFieldChrome = 'bare' | 'framed';
|
|
165
|
-
/** One choice of an enum field. */
|
|
166
|
-
interface PropertyOption<T extends string> {
|
|
167
|
-
value: T;
|
|
168
|
-
/** The option's name. A string also names its segment for a screen reader. */
|
|
169
|
-
label: ReactNode;
|
|
170
|
-
/** What a segment shows in place of `label` when the full one would not fit
|
|
171
|
-
* — a glyph or a letter. `label` stays the accessible name. */
|
|
172
|
-
glyph?: ReactNode;
|
|
173
|
-
/** Shown but not choosable: a value the control reports and cannot author. */
|
|
174
|
-
disabled?: boolean;
|
|
175
|
-
}
|
|
176
|
-
/** Props every kind of field shares. */
|
|
177
|
-
interface FieldBase {
|
|
178
|
-
/** The control's accessible name. A `<PropertyField>` takes it from a string
|
|
179
|
-
* `label` when this is omitted. */
|
|
180
|
-
name?: string;
|
|
181
|
-
/** The sources the field reads disagree — a multi-selection whose nodes
|
|
182
|
-
* differ. The control shows no value, in whatever form it has for that. */
|
|
183
|
-
mixed?: boolean;
|
|
184
|
-
/**
|
|
185
|
-
* The sources agree on holding nothing: whatever is in effect comes from a
|
|
186
|
-
* fallback further down. The control shows no chosen value rather than
|
|
187
|
-
* inventing one, since the next edit would write the invention back.
|
|
188
|
-
*/
|
|
189
|
-
unset?: boolean;
|
|
190
|
-
chrome?: PropertyFieldChrome;
|
|
191
|
-
/** Class on the control element itself. */
|
|
192
|
-
className?: string;
|
|
193
|
-
/** Id for the control element, for a `<label htmlFor>` outside it. */
|
|
194
|
-
id?: string;
|
|
195
|
-
}
|
|
196
|
-
/** A boolean field. */
|
|
197
|
-
interface PropertyBooleanFieldProps extends FieldBase {
|
|
198
|
-
kind: 'boolean';
|
|
199
|
-
/** `checkbox` (default), `switch`, or `toggle` — a one-segment pressable bar. */
|
|
200
|
-
control?: 'checkbox' | 'switch' | 'toggle';
|
|
201
|
-
/** Absent reads as off. */
|
|
202
|
-
value: boolean | undefined;
|
|
203
|
-
onChange: (next: boolean) => void;
|
|
204
|
-
/** A `toggle`'s segment content. Defaults to the first letter of `name`. */
|
|
205
|
-
glyph?: ReactNode;
|
|
206
|
-
}
|
|
207
|
-
/** A number field. */
|
|
208
|
-
interface PropertyNumberFieldProps extends FieldBase {
|
|
209
|
-
kind: 'number';
|
|
210
|
-
/** `input` (default) for a typed number; `slider` for a track with an
|
|
211
|
-
* editable readout, where the range matters more than the exact value. */
|
|
212
|
-
control?: 'input' | 'slider';
|
|
213
|
-
/** Absent reads as an empty field. */
|
|
214
|
-
value: number | null | undefined;
|
|
215
|
-
/**
|
|
216
|
-
* The committed value. Given `onInput` as well, it fires once a drag ends,
|
|
217
|
-
* or on blur or Enter in a typed field; on its own it fires on every move
|
|
218
|
-
* and keystroke. A `framed` typed field commits only on blur or Enter,
|
|
219
|
-
* whichever callbacks it has.
|
|
220
|
-
*/
|
|
221
|
-
onChange: (next: number) => void;
|
|
222
|
-
/** The live value, fired continuously. Pass it alongside `onChange` when the
|
|
223
|
-
* write is expensive — cheap state here, the costly work there. */
|
|
224
|
-
onInput?: (next: number) => void;
|
|
225
|
-
/** A slider's track runs 0..100 where these are omitted. */
|
|
226
|
-
min?: number;
|
|
227
|
-
max?: number;
|
|
228
|
-
step?: number;
|
|
229
|
-
/**
|
|
230
|
-
* Suffix after the value. A string becomes a dim word unit (`px`); pass JSX
|
|
231
|
-
* like `<sup>°</sup>` for a symbol. Display only — the value stays a number.
|
|
232
|
-
*/
|
|
233
|
-
unit?: ReactNode;
|
|
234
|
-
/** Units a person may type into a `framed` field, each mapped to the factor
|
|
235
|
-
* that turns it into the unit shown: `{ mm: 0.1, cm: 1 }`. */
|
|
236
|
-
accepts?: Readonly<UnitTable>;
|
|
237
|
-
/** A slider readout's display. Defaults to the value at `step`'s precision. */
|
|
238
|
-
format?: (value: number) => ReactNode;
|
|
239
|
-
/** A named display for the value: `compact` reads `2.00M`. `format` wins. */
|
|
240
|
-
notation?: ToolPrefNumberFormat;
|
|
241
|
-
placeholder?: string;
|
|
242
|
-
/** A `framed` unitless field's stepper buttons. Default `true`. */
|
|
243
|
-
steppers?: boolean;
|
|
244
|
-
}
|
|
245
|
-
/** A text field. */
|
|
246
|
-
interface PropertyStringFieldProps extends FieldBase {
|
|
247
|
-
kind: 'string';
|
|
248
|
-
control?: 'input' | 'textarea';
|
|
249
|
-
/** Absent reads as an empty field. */
|
|
250
|
-
value: string | null | undefined;
|
|
251
|
-
/**
|
|
252
|
-
* The committed text. On its own it fires on every keystroke. Given
|
|
253
|
-
* `onInput` as well, the field drafts: `onInput` gets each keystroke and
|
|
254
|
-
* this fires once, on blur or Enter, and only if the text changed.
|
|
255
|
-
*/
|
|
256
|
-
onChange: (next: string) => void;
|
|
257
|
-
onInput?: (next: string) => void;
|
|
258
|
-
placeholder?: string;
|
|
259
|
-
maxLength?: number;
|
|
260
|
-
}
|
|
261
|
-
/** A choice among fixed options. */
|
|
262
|
-
interface PropertyEnumFieldProps<T extends string = string> extends FieldBase {
|
|
263
|
-
kind: 'enum';
|
|
264
|
-
/**
|
|
265
|
-
* `select` (default) is a dropdown. `radio` and `toggle` show every option
|
|
266
|
-
* at once — a radio group chooses, and a toggle is a row of pressable
|
|
267
|
-
* segments. Drawn `bare`, both are segments.
|
|
268
|
-
*/
|
|
269
|
-
control?: 'select' | 'radio' | 'toggle';
|
|
270
|
-
/** Absent, or not one of `options`, chooses nothing. */
|
|
271
|
-
value: T | undefined;
|
|
272
|
-
options: ReadonlyArray<PropertyOption<T>>;
|
|
273
|
-
onChange: (next: T) => void;
|
|
274
|
-
/** Shown while no option is chosen. Defaults to "Choose option…". */
|
|
275
|
-
placeholder?: string;
|
|
276
|
-
}
|
|
277
|
-
/** A single color. */
|
|
278
|
-
interface PropertyColorFieldProps extends FieldBase {
|
|
279
|
-
kind: 'color';
|
|
280
|
-
/** `#rrggbb`, or `#rrggbbaa` when `alpha` is `true`. */
|
|
281
|
-
value: string | undefined;
|
|
282
|
-
/**
|
|
283
|
-
* The committed color. `bare`: given `onInput` as well, it fires once the
|
|
284
|
-
* picker closes; on its own it fires on every move. `framed`: it fires once
|
|
285
|
-
* per gesture, whichever callbacks it has.
|
|
286
|
-
*/
|
|
287
|
-
onChange: (next: string) => void;
|
|
288
|
-
onInput?: (next: string) => void;
|
|
289
|
-
/**
|
|
290
|
-
* Offer an opacity track. `true` keeps the alpha in `value` as `#rrggbbaa`;
|
|
291
|
-
* a number is the 0..1 alpha held apart from it, reported through
|
|
292
|
-
* `onAlphaChange` / `onAlphaInput`.
|
|
293
|
-
*/
|
|
294
|
-
alpha?: boolean | number;
|
|
295
|
-
onAlphaChange?: (next: number) => void;
|
|
296
|
-
onAlphaInput?: (next: number) => void;
|
|
297
|
-
/** Draw the opacity track inert, for a consumer that drops alpha. */
|
|
298
|
-
alphaDisabled?: boolean;
|
|
299
|
-
}
|
|
300
|
-
/** A whole paint: a solid, a gradient, a pattern, or none. */
|
|
301
|
-
interface PropertyPaintFieldProps extends FieldBase {
|
|
302
|
-
kind: 'paint';
|
|
303
|
-
/** `swatch` (default) opens the editor in a popover, for a narrow slot;
|
|
304
|
-
* `inline` draws the kind bar and its editor in place. */
|
|
305
|
-
control?: 'swatch' | 'inline';
|
|
306
|
-
/** `null` is an explicit "no paint"; `undefined` is nothing to show. */
|
|
307
|
-
value: FillStyle | null | undefined;
|
|
308
|
-
onChange: (next: FillStyle | null) => void;
|
|
309
|
-
onInput?: (next: FillStyle | null) => void;
|
|
310
|
-
/** Offer "None". Default `true`. */
|
|
311
|
-
allowNone?: boolean;
|
|
312
|
-
/** Restrict the kinds offered. Default: every registered kind. */
|
|
313
|
-
kinds?: readonly PaintKind[];
|
|
314
|
-
}
|
|
315
|
-
/** A font family, picked from the live font registry. */
|
|
316
|
-
interface PropertyFontFamilyFieldProps extends FieldBase {
|
|
317
|
-
kind: 'font-family';
|
|
318
|
-
value: string | undefined;
|
|
319
|
-
onChange: (next: string) => void;
|
|
320
|
-
/** The weight and slant the family is drawn at, so the picker names the
|
|
321
|
-
* variant that will actually paint. */
|
|
322
|
-
weight?: number;
|
|
323
|
-
fontStyle?: 'normal' | 'italic';
|
|
324
|
-
}
|
|
325
|
-
/**
|
|
326
|
-
* One field for {@link PropertyControl} and {@link PropertyField}, keyed by
|
|
327
|
-
* `kind`.
|
|
328
|
-
*/
|
|
329
|
-
type PropertyControlProps<T extends string = string> = PropertyBooleanFieldProps | PropertyNumberFieldProps | PropertyStringFieldProps | PropertyEnumFieldProps<T> | PropertyColorFieldProps | PropertyPaintFieldProps | PropertyFontFamilyFieldProps;
|
|
330
|
-
/** Row props {@link PropertyField} adds to the field it draws. */
|
|
331
|
-
interface PropertyFieldRowProps extends PropertyMetricProps {
|
|
332
|
-
label: ReactNode;
|
|
333
|
-
/**
|
|
334
|
-
* Text beside the label. On a slider it replaces the editable readout —
|
|
335
|
-
* use it when the row is not showing a number a caller could type back,
|
|
336
|
-
* such as an auto row's `auto`.
|
|
337
|
-
*/
|
|
338
|
-
readout?: ReactNode;
|
|
339
|
-
description?: string;
|
|
340
|
-
layout?: PropertyRowLayout;
|
|
341
|
-
/** Take the full width of the enclosing grid — see `<PropertyRow span>`. */
|
|
342
|
-
span?: boolean;
|
|
343
|
-
/** The row is auto — see `<PropertyRow auto>`. */
|
|
344
|
-
auto?: boolean;
|
|
345
|
-
/** Toggles `auto` from the row's label — see `<PropertyRow onAutoChange>`. */
|
|
346
|
-
onAutoChange?: (next: boolean) => void;
|
|
347
|
-
/** Class on the row. `controlClassName` reaches the control. */
|
|
348
|
-
rowClassName?: string;
|
|
349
|
-
controlClassName?: string;
|
|
350
|
-
}
|
|
351
|
-
/** Props for {@link PropertyField}: one field, and the row around it. */
|
|
352
|
-
type PropertyFieldProps<T extends string = string> = PropertyFieldRowProps & DistributiveOmit<PropertyControlProps<T>, 'className' | 'id'>;
|
|
353
|
-
type DistributiveOmit<U, K extends PropertyKey> = U extends unknown ? Omit<U, K> : never;
|
|
354
|
-
/**
|
|
355
|
-
* A labeled settings row for one field, its control chosen by `kind` (and
|
|
356
|
-
* `control`): `<PropertyField kind="number" control="slider" label="Blur" …>`.
|
|
357
|
-
*
|
|
358
|
-
* The row is a {@link PropertyRow}; the control is the one
|
|
359
|
-
* {@link PropertyControl} draws for the same props. Every schema-driven
|
|
360
|
-
* settings surface in the kit — `ControlPanel`, `PrefsForm`, `SelectionPanel`
|
|
361
|
-
* — draws its built-in kinds through that one mapping, so a kind's control
|
|
362
|
-
* is decided once.
|
|
363
|
-
*
|
|
364
|
-
* Callbacks follow the field's shape: a discrete control (a box, a choice)
|
|
365
|
-
* reports each pick; a continuous or typed one reports every change through
|
|
366
|
-
* `onChange` alone, or splits them into live `onInput` and settled
|
|
367
|
-
* `onChange` when given both. `mixed` and `unset` show a field whose sources
|
|
368
|
-
* disagree, or agree on holding nothing.
|
|
369
|
-
*/
|
|
370
|
-
declare function PropertyField<T extends string = string>(props: PropertyFieldProps<T>): react_jsx_runtime.JSX.Element;
|
|
371
|
-
/**
|
|
372
|
-
* The control for one field, with no row around it — for a cell that shares
|
|
373
|
-
* a row with others, or a surface that draws its own row. Keyed by `kind`
|
|
374
|
-
* (and `control`), the same mapping {@link PropertyField} draws.
|
|
375
|
-
*
|
|
376
|
-
* A slider brings its readout beside the track. Several elements come back
|
|
377
|
-
* as siblings rather than wrapped, so the surrounding row lays them out.
|
|
378
|
-
*/
|
|
379
|
-
declare function PropertyControl<T extends string = string>(typed: PropertyControlProps<T>): react_jsx_runtime.JSX.Element;
|
|
380
|
-
|
|
381
|
-
/** How a panel packs its rows into the two-column property grid.
|
|
382
|
-
* - `'auto'`: narrow controls (numbers, checkboxes, dropdowns, colors) sit
|
|
383
|
-
* two per row; the ones that need the width — text, sliders, segmented
|
|
384
|
-
* toggles — span it.
|
|
385
|
-
* - `'pairs'`: every row pairs. A control that needs the full width says so
|
|
386
|
-
* itself, with `<PropertyRow span>`.
|
|
387
|
-
* - `'one-up'`: one control per row, colors excepted.
|
|
388
|
-
*/
|
|
389
|
-
type ControlPack = 'auto' | 'pairs' | 'one-up';
|
|
390
|
-
interface ControlPanelProps<TC extends Record<string, unknown>> extends StanceProps {
|
|
391
|
-
/** The instrument's resolved config schema. */
|
|
392
|
-
schema?: ResolvedConfig;
|
|
393
|
-
/** @deprecated Pass `schema`. A field list is adapted into one internally. */
|
|
394
|
-
fields?: ConfigField[];
|
|
395
|
-
config: TC;
|
|
396
|
-
/** Writes one value. The path is dotted for a leaf inside an `f.group`, and
|
|
397
|
-
* the bare key for one at the root. */
|
|
398
|
-
setConfig: (path: string, value: unknown) => void;
|
|
399
|
-
/**
|
|
400
|
-
* Control overrides and app-defined kinds, PrefsForm-style. Keys are config
|
|
401
|
-
* paths (checked first) or leaf kinds. A renderer returning `null` collapses
|
|
402
|
-
* the row; entries override the built-in rows on collision.
|
|
403
|
-
*/
|
|
404
|
-
renderers?: Record<string, ControlRenderer>;
|
|
405
|
-
/** How rows pack into the two-column grid. Defaults to `'pairs'`. */
|
|
406
|
-
pack?: ControlPack;
|
|
407
|
-
/**
|
|
408
|
-
* Where a row's label sits relative to its control. Unset takes each row's
|
|
409
|
-
* own orientation — `block` (label above, which is what leaves a paired row
|
|
410
|
-
* room for its value) for most, `inline` for colors and checkboxes.
|
|
411
|
-
*/
|
|
412
|
-
layout?: PropertyRowLayout;
|
|
413
|
-
/** Room the rows get. Passed straight to the property list. */
|
|
414
|
-
density?: PropertyDensity;
|
|
415
|
-
/** Cross-axis alignment of an inline row's label and control. */
|
|
416
|
-
align?: PropertyAlign;
|
|
417
|
-
/**
|
|
418
|
-
* Fold each section away behind a twisty, starting `'open'` or `'closed'`.
|
|
419
|
-
* Unset draws the heading alone, as the panel always has — unless a section
|
|
420
|
-
* in the schema declares how it opens, which makes that section foldable on
|
|
421
|
-
* its own and outranks this for that one section.
|
|
422
|
-
*/
|
|
423
|
-
collapse?: 'open' | 'closed';
|
|
424
|
-
/**
|
|
425
|
-
* Which sections are folded, keyed as `onCollapse` reports them. Given, the
|
|
426
|
-
* panel keeps no state of its own: every toggle arrives at `onCollapse`
|
|
427
|
-
* instead, which is where a lab that remembers a trial's sections writes
|
|
428
|
-
* them.
|
|
429
|
-
*/
|
|
430
|
-
collapsed?: Readonly<Record<string, boolean>>;
|
|
431
|
-
/** A fold moved. The key is a section's label — prefixed by its group's
|
|
432
|
-
* dotted path when the section sits inside one — or a group's own path. */
|
|
433
|
-
onCollapse?: (key: string, collapsed: boolean) => void;
|
|
434
|
-
/** Dotted paths currently unpinned. A row in this set hides its control and
|
|
435
|
-
* reads out `auto`, and clicking its label writes the sentinel back through
|
|
436
|
-
* `setConfig`. Omitted, the panel keeps the set itself: the labels still
|
|
437
|
-
* toggle and the sentinel never reaches `setConfig`, which would otherwise
|
|
438
|
-
* store it as the row's value. */
|
|
439
|
-
auto?: ReadonlySet<string>;
|
|
440
|
-
/** Draw leaves marked `hidden`. */
|
|
441
|
-
showHidden?: boolean;
|
|
442
|
-
/** Heads the panel. With `title`, `stance` or `tone` given, the rows sit in a
|
|
443
|
-
* `<PropertyPanel>` carrying them; with none, they are the bare list. */
|
|
444
|
-
title?: ReactNode;
|
|
445
|
-
className?: string;
|
|
446
|
-
}
|
|
447
|
-
/** Render an instrument's config schema as a stack of controls, each writing
|
|
448
|
-
* back through `setConfig`. Built on the property rows, so a lab's controls
|
|
449
|
-
* are the same aligned, themed rows the rest of the kit uses. */
|
|
450
|
-
declare function ControlPanel<TC extends Record<string, unknown>>({ schema, fields, config, setConfig, renderers, pack, layout, density, align, collapse, collapsed, onCollapse, auto: given, showHidden, title, stance, tone, className, }: ControlPanelProps<TC>): react_jsx_runtime.JSX.Element;
|
|
451
|
-
|
|
452
|
-
export { ControlPanel as C, PropertyControl as b, PropertyField as d, PropertyList as f, PropertyPanel as i, PropertyRow as k, PropertySpan as o };
|
|
453
|
-
export type { PropertyMetricProps as P, PropertyListPack as a, PropertyControlProps as c, PropertyFieldProps as e, PropertyListProps as g, PropertyOption as h, PropertyPanelProps as j, PropertyRowLayout as l, PropertyRowProps as m, PropertyRowVariant as n, PropertySpanProps as p };
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Display-formatter for numbers. Use this anywhere a number is shown to
|
|
3
|
-
* a user. The whole point: negative values get prefixed with the real
|
|
4
|
-
* MINUS SIGN (U+2212) instead of the ASCII HYPHEN-MINUS (U+002D) that
|
|
5
|
-
* `toLocaleString` and template literals produce by default.
|
|
6
|
-
*
|
|
7
|
-
* U+2212 is the same visual width as `+` and reads as a sign rather
|
|
8
|
-
* than a hyphen — columns of signed numbers align cleanly and the
|
|
9
|
-
* glyph doesn't get confused with a bullet or list dash.
|
|
10
|
-
*/
|
|
11
|
-
declare const MINUS_SIGN = "\u2212";
|
|
12
|
-
/**
|
|
13
|
-
* Formats a number for display, substituting {@link MINUS_SIGN} for the ASCII
|
|
14
|
-
* hyphen `toLocaleString` emits. Non-finite values stringify as-is.
|
|
15
|
-
*/
|
|
16
|
-
declare function formatNumber(value: number, options?: Intl.NumberFormatOptions): string;
|
|
17
|
-
/** One unit's conversion into the shown unit: a bare factor, or a scale that
|
|
18
|
-
* also moves zero. Structurally the kit's `UnitEntry`, kept local so this
|
|
19
|
-
* formatting helper stays free of the scene vocabulary. */
|
|
20
|
-
type UnitTableEntry = number | {
|
|
21
|
-
factor: number;
|
|
22
|
-
offset?: number;
|
|
23
|
-
};
|
|
24
|
-
/** Suffixes a person may type, each mapped to its conversion. */
|
|
25
|
-
type UnitTable = Record<string, UnitTableEntry>;
|
|
26
|
-
|
|
27
|
-
export { MINUS_SIGN as M, formatNumber as f };
|
|
28
|
-
export type { UnitTable as U };
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ReactNode, WheelEvent, PointerEvent as PointerEvent$1 } from 'react';
|
|
3
|
-
import { m as ViewTransform, b as WorldSpec, V as ViewportSize, n as Point, W as WorldFrame } from './frac-DTRq7Xpb.js';
|
|
4
|
-
import { C as CanvasLayerDescriptor } from './CanvasStackContext-DQgcH1ny.js';
|
|
5
|
-
|
|
6
|
-
/** Props for `<CanvasStack>`. */
|
|
7
|
-
interface CanvasStackProps {
|
|
8
|
-
layers: CanvasLayerDescriptor[];
|
|
9
|
-
view: ViewTransform;
|
|
10
|
-
onViewChange: (v: ViewTransform) => void;
|
|
11
|
-
/** The instrument's coordinate system. Omitted, world (0,0) sits at the
|
|
12
|
-
* element's top-left with y running down. */
|
|
13
|
-
worldSpec?: WorldSpec;
|
|
14
|
-
minZoom?: number;
|
|
15
|
-
maxZoom?: number;
|
|
16
|
-
width?: number | string;
|
|
17
|
-
height?: number | string;
|
|
18
|
-
className?: string;
|
|
19
|
-
/** Fired whenever the stack is measured, so a consumer can place a view that
|
|
20
|
-
* only makes sense in terms of the viewport. */
|
|
21
|
-
onResize?: (size: ViewportSize) => void;
|
|
22
|
-
onHitTest?: (worldPos: Point) => void;
|
|
23
|
-
children?: ReactNode;
|
|
24
|
-
}
|
|
25
|
-
/** Stacks one `<canvas>` per layer and drives them from a shared view, so a
|
|
26
|
-
* layer that changes rarely is not redrawn with one that changes every frame.
|
|
27
|
-
* Handles sizing, device pixel ratio, and pan/zoom. */
|
|
28
|
-
declare function CanvasStack({ layers, view: viewProp, onViewChange, worldSpec, minZoom, maxZoom, width, height, className, onResize, onHitTest, children, }: CanvasStackProps): react_jsx_runtime.JSX.Element;
|
|
29
|
-
|
|
30
|
-
/** Bounds and coordinate system a {@link zoomAt} works in. */
|
|
31
|
-
interface ZoomAtOptions {
|
|
32
|
-
/** The instrument's coordinate system, resolved against the viewport.
|
|
33
|
-
* Omitted, `at` is measured from the element's top-left. */
|
|
34
|
-
frame?: WorldFrame;
|
|
35
|
-
min?: number;
|
|
36
|
-
max?: number;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Zoom a view by `factor` about a fixed point, so whatever world coordinate
|
|
40
|
-
* `at` was over stays under it.
|
|
41
|
-
*
|
|
42
|
-
* `at` is in the element's own pixels — a cursor position, or the centre of a
|
|
43
|
-
* lens. The clamp is applied before the pan is solved, so a zoom that hits a
|
|
44
|
-
* bound still anchors on the zoom it actually reached.
|
|
45
|
-
*/
|
|
46
|
-
declare function zoomAt(view: ViewTransform, factor: number, at: Point, { frame, min, max }?: ZoomAtOptions): ViewTransform;
|
|
47
|
-
/** The view that puts a world point at the centre of a `size` viewport, at
|
|
48
|
-
* `zoom`. What a lens showing a region around one point renders through. */
|
|
49
|
-
declare function centerOn(world: Point, zoom: number, size: ViewportSize, frame?: WorldFrame): ViewTransform;
|
|
50
|
-
|
|
51
|
-
/** Project a world point into screen coordinates under a view.
|
|
52
|
-
*
|
|
53
|
-
* `frame` is the instrument's declared coordinate system, resolved against the
|
|
54
|
-
* viewport; omitting it gives labkit's original one — origin at the top-left,
|
|
55
|
-
* y downward. */
|
|
56
|
-
declare function worldToScreen(world: Point, view: ViewTransform, frame?: WorldFrame): Point;
|
|
57
|
-
/** Unproject a screen point back to world coordinates under a view. */
|
|
58
|
-
declare function screenToWorld(screen: Point, view: ViewTransform, frame?: WorldFrame): Point;
|
|
59
|
-
|
|
60
|
-
/** Props for `<Stage>`. */
|
|
61
|
-
interface StageProps {
|
|
62
|
-
/** The content's own size in CSS pixels, at zoom 1. */
|
|
63
|
-
size: ViewportSize;
|
|
64
|
-
view: ViewTransform;
|
|
65
|
-
onViewChange: (v: ViewTransform) => void;
|
|
66
|
-
minZoom?: number;
|
|
67
|
-
maxZoom?: number;
|
|
68
|
-
/** Fired whenever the stage's viewport is measured at a non-zero size. */
|
|
69
|
-
onResize?: (viewport: ViewportSize) => void;
|
|
70
|
-
/** Handed the viewport element, for a consumer tracking the pointer over it. */
|
|
71
|
-
hostRef?: {
|
|
72
|
-
current: HTMLDivElement | null;
|
|
73
|
-
};
|
|
74
|
-
/** Drawn over the content in viewport pixels, outside the camera. */
|
|
75
|
-
overlay?: ReactNode;
|
|
76
|
-
children?: ReactNode;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* The camera a stage opens at: the content centered in its viewport, shrunk to
|
|
80
|
-
* fit if it has to be and never enlarged past its own size.
|
|
81
|
-
*/
|
|
82
|
-
declare function fitStage(size: ViewportSize, viewport: ViewportSize): ViewTransform;
|
|
83
|
-
/**
|
|
84
|
-
* DOM content of a fixed size, panned and zoomed by a camera — what
|
|
85
|
-
* `<CanvasStack>` is for layers drawn to a canvas. The content is laid out at
|
|
86
|
-
* its own size and transformed, so everything inside keeps its layout and a
|
|
87
|
-
* measurement of any element in it reports where it is actually drawn.
|
|
88
|
-
*/
|
|
89
|
-
declare function Stage({ size, view: viewProp, onViewChange, minZoom, maxZoom, onResize, hostRef, overlay, children, }: StageProps): react_jsx_runtime.JSX.Element;
|
|
90
|
-
|
|
91
|
-
interface UsePanZoomOptions {
|
|
92
|
-
view: ViewTransform;
|
|
93
|
-
onViewChange: (v: ViewTransform) => void;
|
|
94
|
-
/** The opening `view.zoom` always stays reachable, widening these past
|
|
95
|
-
* whatever is passed here if it would otherwise exclude it. */
|
|
96
|
-
minZoom?: number;
|
|
97
|
-
maxZoom?: number;
|
|
98
|
-
/** The instrument's coordinate system, resolved against the viewport. The
|
|
99
|
-
* wheel anchors in this frame; omitting it anchors at the element's
|
|
100
|
-
* top-left, which is what labkit did before a frame could be declared. */
|
|
101
|
-
frame?: WorldFrame;
|
|
102
|
-
/** A primary-button press released without ever crossing the drag
|
|
103
|
-
* threshold. The pointer session owns the release, so the gesture's end is
|
|
104
|
-
* reported here rather than left for a consumer's own `onPointerUp`. */
|
|
105
|
-
onTap?: (e: PointerEvent) => void;
|
|
106
|
-
}
|
|
107
|
-
interface PanZoomHandlers {
|
|
108
|
-
/** Zoom about the pointer. `anchor` is the element the pointer position is
|
|
109
|
-
* measured against, for an event whose `currentTarget` is some other box. */
|
|
110
|
-
onWheel: (e: WheelEvent<HTMLElement> | globalThis.WheelEvent, anchor?: Element) => void;
|
|
111
|
-
onPointerDown: (e: PointerEvent$1<HTMLElement>) => void;
|
|
112
|
-
isDragging: () => boolean;
|
|
113
|
-
}
|
|
114
|
-
declare function usePanZoom({ view, onViewChange, minZoom, maxZoom, frame, onTap, }: UsePanZoomOptions): PanZoomHandlers;
|
|
115
|
-
|
|
116
|
-
export { CanvasStack as C, Stage as S, centerOn as c, fitStage as f, screenToWorld as s, usePanZoom as u, worldToScreen as w, zoomAt as z };
|
|
117
|
-
export type { PanZoomHandlers as P, UsePanZoomOptions as U, ZoomAtOptions as Z, CanvasStackProps as a, StageProps as b };
|
package/dist/chunk-2AYGEN57.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
// src/canvas/worldSpec.ts
|
|
2
|
-
var DEFAULT_FRAME = { originPx: { x: 0, y: 0 }, yDir: 1 };
|
|
3
|
-
function resolveFrame(spec, size) {
|
|
4
|
-
if (!spec) return DEFAULT_FRAME;
|
|
5
|
-
const origin = spec.origin ?? { x: 0, y: 0 };
|
|
6
|
-
return {
|
|
7
|
-
originPx: { x: origin.x * size.width, y: origin.y * size.height },
|
|
8
|
-
yDir: spec.yAxis === "up" ? -1 : 1
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
function applyCamera(ctx, view, frame = DEFAULT_FRAME) {
|
|
12
|
-
ctx.translate(frame.originPx.x + view.pan.x, frame.originPx.y + view.pan.y);
|
|
13
|
-
ctx.scale(view.zoom, view.zoom * frame.yDir);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// src/canvas/canvasCoords.ts
|
|
17
|
-
function worldToScreen(world, view, frame = DEFAULT_FRAME) {
|
|
18
|
-
return {
|
|
19
|
-
x: frame.originPx.x + view.pan.x + world.x * view.zoom,
|
|
20
|
-
y: frame.originPx.y + view.pan.y + world.y * view.zoom * frame.yDir
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
function screenToWorld(screen, view, frame = DEFAULT_FRAME) {
|
|
24
|
-
return {
|
|
25
|
-
x: (screen.x - frame.originPx.x - view.pan.x) / view.zoom,
|
|
26
|
-
y: (screen.y - frame.originPx.y - view.pan.y) / (view.zoom * frame.yDir)
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export { DEFAULT_FRAME, applyCamera, resolveFrame, screenToWorld, worldToScreen };
|
|
31
|
-
//# sourceMappingURL=chunk-2AYGEN57.js.map
|
|
32
|
-
//# sourceMappingURL=chunk-2AYGEN57.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/canvas/worldSpec.ts","../src/canvas/canvasCoords.ts"],"names":[],"mappings":";AA2BO,IAAM,aAAA,GAA4B,EAAE,QAAA,EAAU,EAAE,CAAA,EAAG,GAAG,CAAA,EAAG,CAAA,EAAE,EAAG,IAAA,EAAM,CAAA;AAEpE,SAAS,YAAA,CAAa,MAA6B,IAAA,EAAgC;AACxF,EAAA,IAAI,CAAC,MAAM,OAAO,aAAA;AAClB,EAAA,MAAM,SAAS,IAAA,CAAK,MAAA,IAAU,EAAE,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAE;AAC3C,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,EAAE,CAAA,EAAG,MAAA,CAAO,CAAA,GAAI,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,MAAA,CAAO,CAAA,GAAI,IAAA,CAAK,MAAA,EAAO;AAAA,IAChE,IAAA,EAAM,IAAA,CAAK,KAAA,KAAU,IAAA,GAAO,EAAA,GAAK;AAAA,GACnC;AACF;AAIO,SAAS,WAAA,CACd,GAAA,EACA,IAAA,EACA,KAAA,GAAoB,aAAA,EACd;AACN,EAAA,GAAA,CAAI,SAAA,CAAU,KAAA,CAAM,QAAA,CAAS,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,QAAA,CAAS,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA;AAC1E,EAAA,GAAA,CAAI,MAAM,IAAA,CAAK,IAAA,EAAM,IAAA,CAAK,IAAA,GAAO,MAAM,IAAI,CAAA;AAC7C;;;ACvCO,SAAS,aAAA,CACd,KAAA,EACA,IAAA,EACA,KAAA,GAAoB,aAAA,EACb;AACP,EAAA,OAAO;AAAA,IACL,CAAA,EAAG,MAAM,QAAA,CAAS,CAAA,GAAI,KAAK,GAAA,CAAI,CAAA,GAAI,KAAA,CAAM,CAAA,GAAI,IAAA,CAAK,IAAA;AAAA,IAClD,CAAA,EAAG,KAAA,CAAM,QAAA,CAAS,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,GAAI,KAAA,CAAM,CAAA,GAAI,IAAA,CAAK,IAAA,GAAO,KAAA,CAAM;AAAA,GACjE;AACF;AAGO,SAAS,aAAA,CACd,MAAA,EACA,IAAA,EACA,KAAA,GAAoB,aAAA,EACb;AACP,EAAA,OAAO;AAAA,IACL,CAAA,EAAA,CAAI,OAAO,CAAA,GAAI,KAAA,CAAM,SAAS,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,IAAK,IAAA,CAAK,IAAA;AAAA,IACrD,CAAA,EAAA,CAAI,MAAA,CAAO,CAAA,GAAI,KAAA,CAAM,QAAA,CAAS,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,KAAM,IAAA,CAAK,IAAA,GAAO,KAAA,CAAM,IAAA;AAAA,GACrE;AACF","file":"chunk-2AYGEN57.js","sourcesContent":["import type { Point, ViewTransform } from '../instrument/types';\n\n/** How an instrument's world sits on the canvas, independent of the camera.\n * The defaults reproduce the convention labkit shipped before this existed:\n * world (0,0) at the element's top-left, y growing downward. */\nexport interface WorldSpec {\n /** Where world (0,0) sits at `pan` zero, as a fraction of the viewport.\n * `{x:0,y:0}` top-left (default); `{x:0.5,y:0.5}` centre. */\n origin?: Point;\n /** Which way the world y axis runs on screen. Default `'down'`. */\n yAxis?: 'down' | 'up';\n}\n\n/** A viewport's CSS-pixel size. */\nexport interface ViewportSize {\n width: number;\n height: number;\n}\n\n/** A `WorldSpec` resolved against a viewport: what the coordinate helpers,\n * the camera and the wheel all read. */\nexport interface WorldFrame {\n /** Screen position of world (0,0) at `pan` zero. */\n originPx: Point;\n yDir: 1 | -1;\n}\n\nexport const DEFAULT_FRAME: WorldFrame = { originPx: { x: 0, y: 0 }, yDir: 1 };\n\nexport function resolveFrame(spec: WorldSpec | undefined, size: ViewportSize): WorldFrame {\n if (!spec) return DEFAULT_FRAME;\n const origin = spec.origin ?? { x: 0, y: 0 };\n return {\n originPx: { x: origin.x * size.width, y: origin.y * size.height },\n yDir: spec.yAxis === 'up' ? -1 : 1,\n };\n}\n\n/** Put a 2D context into the instrument's world coordinates, so a layer's\n * `draw` works in them. Must stay the exact inverse of `screenToWorld`. */\nexport function applyCamera(\n ctx: CanvasRenderingContext2D,\n view: ViewTransform,\n frame: WorldFrame = DEFAULT_FRAME,\n): void {\n ctx.translate(frame.originPx.x + view.pan.x, frame.originPx.y + view.pan.y);\n ctx.scale(view.zoom, view.zoom * frame.yDir);\n}\n","import type { Point, ViewTransform } from '../instrument/types';\nimport { DEFAULT_FRAME, type WorldFrame } from './worldSpec';\n\n/** Project a world point into screen coordinates under a view.\n *\n * `frame` is the instrument's declared coordinate system, resolved against the\n * viewport; omitting it gives labkit's original one — origin at the top-left,\n * y downward. */\nexport function worldToScreen(\n world: Point,\n view: ViewTransform,\n frame: WorldFrame = DEFAULT_FRAME,\n): Point {\n return {\n x: frame.originPx.x + view.pan.x + world.x * view.zoom,\n y: frame.originPx.y + view.pan.y + world.y * view.zoom * frame.yDir,\n };\n}\n\n/** Unproject a screen point back to world coordinates under a view. */\nexport function screenToWorld(\n screen: Point,\n view: ViewTransform,\n frame: WorldFrame = DEFAULT_FRAME,\n): Point {\n return {\n x: (screen.x - frame.originPx.x - view.pan.x) / view.zoom,\n y: (screen.y - frame.originPx.y - view.pan.y) / (view.zoom * frame.yDir),\n };\n}\n"]}
|