@matchstick-trading/primitives 0.0.10

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 (216) hide show
  1. package/AGENTS.md +44 -0
  2. package/CHANGELOG.md +19 -0
  3. package/LICENSE +201 -0
  4. package/README.md +636 -0
  5. package/dist/Chart.d.ts +18 -0
  6. package/dist/Chart.js +6 -0
  7. package/dist/ChartParts.d.ts +151 -0
  8. package/dist/ChartParts.js +389 -0
  9. package/dist/CsvDrop.d.ts +8 -0
  10. package/dist/CsvDrop.js +5 -0
  11. package/dist/CsvDropParts.d.ts +33 -0
  12. package/dist/CsvDropParts.js +77 -0
  13. package/dist/Cursor.d.ts +6 -0
  14. package/dist/Cursor.js +5 -0
  15. package/dist/CursorParts.d.ts +51 -0
  16. package/dist/CursorParts.js +40 -0
  17. package/dist/DepthProfile.d.ts +13 -0
  18. package/dist/DepthProfile.js +5 -0
  19. package/dist/DepthProfileParts.d.ts +45 -0
  20. package/dist/DepthProfileParts.js +96 -0
  21. package/dist/DiffTable.d.ts +13 -0
  22. package/dist/DiffTable.js +5 -0
  23. package/dist/DiffTableParts.d.ts +57 -0
  24. package/dist/DiffTableParts.js +103 -0
  25. package/dist/Drawings.d.ts +13 -0
  26. package/dist/Drawings.js +5 -0
  27. package/dist/DrawingsParts.d.ts +194 -0
  28. package/dist/DrawingsParts.js +775 -0
  29. package/dist/Fullscreen.d.ts +7 -0
  30. package/dist/Fullscreen.js +5 -0
  31. package/dist/FullscreenParts.d.ts +54 -0
  32. package/dist/FullscreenParts.js +250 -0
  33. package/dist/Ladder.d.ts +13 -0
  34. package/dist/Ladder.js +5 -0
  35. package/dist/LadderParts.d.ts +49 -0
  36. package/dist/LadderParts.js +56 -0
  37. package/dist/Menu.d.ts +11 -0
  38. package/dist/Menu.js +5 -0
  39. package/dist/MenuParts.d.ts +52 -0
  40. package/dist/MenuParts.js +202 -0
  41. package/dist/Notice.d.ts +18 -0
  42. package/dist/Notice.js +9 -0
  43. package/dist/Panels.d.ts +9 -0
  44. package/dist/Panels.js +5 -0
  45. package/dist/PanelsParts.d.ts +62 -0
  46. package/dist/PanelsParts.js +387 -0
  47. package/dist/Receipt.d.ts +11 -0
  48. package/dist/Receipt.js +5 -0
  49. package/dist/ReceiptParts.d.ts +45 -0
  50. package/dist/ReceiptParts.js +71 -0
  51. package/dist/Scrubber.d.ts +9 -0
  52. package/dist/Scrubber.js +5 -0
  53. package/dist/ScrubberParts.d.ts +74 -0
  54. package/dist/ScrubberParts.js +126 -0
  55. package/dist/Selection.d.ts +14 -0
  56. package/dist/Selection.js +7 -0
  57. package/dist/SelectionParts.d.ts +63 -0
  58. package/dist/SelectionParts.js +208 -0
  59. package/dist/Studies.d.ts +9 -0
  60. package/dist/Studies.js +5 -0
  61. package/dist/StudiesParts.d.ts +45 -0
  62. package/dist/StudiesParts.js +153 -0
  63. package/dist/Submenu.d.ts +7 -0
  64. package/dist/Submenu.js +4 -0
  65. package/dist/SymbolSearch.d.ts +10 -0
  66. package/dist/SymbolSearch.js +5 -0
  67. package/dist/SymbolSearchParts.d.ts +39 -0
  68. package/dist/SymbolSearchParts.js +86 -0
  69. package/dist/Tape.d.ts +15 -0
  70. package/dist/Tape.js +5 -0
  71. package/dist/TapeParts.d.ts +69 -0
  72. package/dist/TapeParts.js +139 -0
  73. package/dist/Toolbar.d.ts +8 -0
  74. package/dist/Toolbar.js +5 -0
  75. package/dist/ToolbarParts.d.ts +61 -0
  76. package/dist/ToolbarParts.js +122 -0
  77. package/dist/Transport.d.ts +15 -0
  78. package/dist/Transport.js +5 -0
  79. package/dist/TransportParts.d.ts +52 -0
  80. package/dist/TransportParts.js +47 -0
  81. package/dist/VolumeProfile.d.ts +7 -0
  82. package/dist/VolumeProfile.js +5 -0
  83. package/dist/VolumeProfileParts.d.ts +37 -0
  84. package/dist/VolumeProfileParts.js +57 -0
  85. package/dist/accessible-name.d.ts +26 -0
  86. package/dist/accessible-name.js +14 -0
  87. package/dist/attributes.d.ts +8 -0
  88. package/dist/attributes.js +9 -0
  89. package/dist/core/adapter.d.ts +38 -0
  90. package/dist/core/adapter.js +64 -0
  91. package/dist/core/attributes.d.ts +36 -0
  92. package/dist/core/attributes.js +22 -0
  93. package/dist/core/candles.d.ts +6 -0
  94. package/dist/core/candles.js +19 -0
  95. package/dist/core/chart-gesture.d.ts +109 -0
  96. package/dist/core/chart-gesture.js +161 -0
  97. package/dist/core/chart-scale.d.ts +141 -0
  98. package/dist/core/chart-scale.js +302 -0
  99. package/dist/core/csv-bars.d.ts +54 -0
  100. package/dist/core/csv-bars.js +325 -0
  101. package/dist/core/depth-profile.d.ts +43 -0
  102. package/dist/core/depth-profile.js +66 -0
  103. package/dist/core/diff-table.d.ts +57 -0
  104. package/dist/core/diff-table.js +77 -0
  105. package/dist/core/drawing-fields.d.ts +11 -0
  106. package/dist/core/drawing-fields.js +15 -0
  107. package/dist/core/drawings.d.ts +194 -0
  108. package/dist/core/drawings.js +403 -0
  109. package/dist/core/fullscreen.d.ts +32 -0
  110. package/dist/core/fullscreen.js +16 -0
  111. package/dist/core/index.d.ts +41 -0
  112. package/dist/core/index.js +23 -0
  113. package/dist/core/ladder-keys.d.ts +35 -0
  114. package/dist/core/ladder-keys.js +43 -0
  115. package/dist/core/ladder.d.ts +65 -0
  116. package/dist/core/ladder.js +93 -0
  117. package/dist/core/panels.d.ts +72 -0
  118. package/dist/core/panels.js +151 -0
  119. package/dist/core/receipt-rules.d.ts +42 -0
  120. package/dist/core/receipt-rules.js +20 -0
  121. package/dist/core/scrubber-gesture.d.ts +66 -0
  122. package/dist/core/scrubber-gesture.js +69 -0
  123. package/dist/core/selection.d.ts +24 -0
  124. package/dist/core/selection.js +33 -0
  125. package/dist/core/series.d.ts +161 -0
  126. package/dist/core/series.js +331 -0
  127. package/dist/core/studies.d.ts +80 -0
  128. package/dist/core/studies.js +237 -0
  129. package/dist/core/symbol-search.d.ts +89 -0
  130. package/dist/core/symbol-search.js +223 -0
  131. package/dist/core/tape.d.ts +77 -0
  132. package/dist/core/tape.js +136 -0
  133. package/dist/core/volume-profile.d.ts +47 -0
  134. package/dist/core/volume-profile.js +86 -0
  135. package/dist/index.d.ts +82 -0
  136. package/dist/index.js +42 -0
  137. package/dist/ladder-keys.d.ts +16 -0
  138. package/dist/ladder-keys.js +86 -0
  139. package/dist/panels-context.d.ts +47 -0
  140. package/dist/panels-context.js +3 -0
  141. package/dist/selection-context.d.ts +41 -0
  142. package/dist/selection-context.js +4 -0
  143. package/examples/csv-to-chart-frame.mjs +17 -0
  144. package/examples/studies.mjs +12 -0
  145. package/llms.txt +16 -0
  146. package/package.json +67 -0
  147. package/src/Chart.tsx +7 -0
  148. package/src/ChartParts.tsx +529 -0
  149. package/src/CsvDrop.tsx +6 -0
  150. package/src/CsvDropParts.tsx +128 -0
  151. package/src/Cursor.tsx +6 -0
  152. package/src/CursorParts.tsx +77 -0
  153. package/src/DepthProfile.tsx +6 -0
  154. package/src/DepthProfileParts.tsx +154 -0
  155. package/src/DiffTable.tsx +6 -0
  156. package/src/DiffTableParts.tsx +160 -0
  157. package/src/Drawings.tsx +6 -0
  158. package/src/DrawingsParts.tsx +1080 -0
  159. package/src/Fullscreen.tsx +6 -0
  160. package/src/FullscreenParts.tsx +318 -0
  161. package/src/Ladder.tsx +6 -0
  162. package/src/LadderParts.tsx +114 -0
  163. package/src/Menu.tsx +6 -0
  164. package/src/MenuParts.tsx +364 -0
  165. package/src/Notice.tsx +27 -0
  166. package/src/Panels.tsx +6 -0
  167. package/src/PanelsParts.tsx +454 -0
  168. package/src/Receipt.tsx +6 -0
  169. package/src/ReceiptParts.tsx +118 -0
  170. package/src/Scrubber.tsx +6 -0
  171. package/src/ScrubberParts.tsx +207 -0
  172. package/src/Selection.tsx +12 -0
  173. package/src/SelectionParts.tsx +251 -0
  174. package/src/Studies.tsx +6 -0
  175. package/src/StudiesParts.tsx +226 -0
  176. package/src/Submenu.tsx +5 -0
  177. package/src/SymbolSearch.tsx +6 -0
  178. package/src/SymbolSearchParts.tsx +166 -0
  179. package/src/Tape.tsx +6 -0
  180. package/src/TapeParts.tsx +208 -0
  181. package/src/Toolbar.tsx +6 -0
  182. package/src/ToolbarParts.tsx +179 -0
  183. package/src/Transport.tsx +6 -0
  184. package/src/TransportParts.tsx +128 -0
  185. package/src/VolumeProfile.tsx +6 -0
  186. package/src/VolumeProfileParts.tsx +106 -0
  187. package/src/accessible-name.tsx +34 -0
  188. package/src/attributes.ts +12 -0
  189. package/src/core/adapter.ts +91 -0
  190. package/src/core/attributes.ts +51 -0
  191. package/src/core/candles.ts +22 -0
  192. package/src/core/chart-gesture.ts +228 -0
  193. package/src/core/chart-scale.ts +368 -0
  194. package/src/core/csv-bars.ts +328 -0
  195. package/src/core/depth-profile.ts +84 -0
  196. package/src/core/diff-table.ts +105 -0
  197. package/src/core/drawing-fields.ts +17 -0
  198. package/src/core/drawings.ts +478 -0
  199. package/src/core/fullscreen.ts +32 -0
  200. package/src/core/index.ts +42 -0
  201. package/src/core/ladder-keys.ts +61 -0
  202. package/src/core/ladder.ts +156 -0
  203. package/src/core/panels.ts +177 -0
  204. package/src/core/receipt-rules.ts +45 -0
  205. package/src/core/scrubber-gesture.ts +102 -0
  206. package/src/core/selection.ts +41 -0
  207. package/src/core/series.ts +374 -0
  208. package/src/core/studies.ts +260 -0
  209. package/src/core/symbol-search.ts +256 -0
  210. package/src/core/tape.ts +159 -0
  211. package/src/core/volume-profile.ts +116 -0
  212. package/src/index.ts +83 -0
  213. package/src/ladder-keys.ts +83 -0
  214. package/src/panels-context.ts +46 -0
  215. package/src/selection-context.ts +38 -0
  216. package/src/tokens.css +235 -0
@@ -0,0 +1,194 @@
1
+ import { type MutableRefObject, type ReactNode } from 'react';
2
+ import { type NameProps } from './accessible-name.js';
3
+ import type { CandleBar } from './core/chart-scale.js';
4
+ import { type Drawing, type DrawingAnchor, type DrawingTool, type SnapMode } from './core/drawings.js';
5
+ /**
6
+ * Drawings as parts: Root, Layer, Toolbar, List, Remove, Undo. Headless: parts draw SVG and add `data-part`, `data-tool`,
7
+ * `data-selected` and `data-draft`; the host gives them colour. Drawings are anchored to a time and a price, so they
8
+ * stay put when the chart pans, zooms or gets new bars.
9
+ *
10
+ * Root only holds state, with no element of its own, so put it above both the Chart and the Toolbar and List. Layer
11
+ * goes inside Chart.Plot. It takes no tab stop of its own: it listens for keys on the plot's own tab stop and only
12
+ * answers when a drawing is selected or a tool is in use, so the chart's keys work as before the rest of the time.
13
+ */
14
+ /** A drawing being placed: the anchors set so far and where the pointer is now. */
15
+ interface Draft {
16
+ tool: DrawingTool;
17
+ anchors: DrawingAnchor[];
18
+ preview: DrawingAnchor | null;
19
+ }
20
+ interface DrawingsContext {
21
+ drawings: readonly Drawing[];
22
+ setDrawings: (next: Drawing[]) => void;
23
+ tool: DrawingTool | null;
24
+ setTool: (tool: DrawingTool | null) => void;
25
+ selected: string | null;
26
+ setSelected: (id: string | null) => void;
27
+ snap: SnapMode;
28
+ draft: Draft | null;
29
+ setDraft: (draft: Draft | null) => void;
30
+ remove: (id: string) => void;
31
+ /** Lock or unlock one drawing. A locked drawing keeps its place: no drag, nudge, typed edit or removal. */
32
+ setLocked: (id: string, locked: boolean) => void;
33
+ /** Remove every drawing that is not locked. Undo puts them back. */
34
+ removeAll: () => void;
35
+ /** What the last removal took out, or null once it expired or was undone. */
36
+ removed: readonly Drawing[] | null;
37
+ /** Put the last removal back where it was. */
38
+ /** Puts the last removal back and says so in the live region. `describe` prints a drawing (default two decimals, UTC time); `focusRow` moves focus to the restored row of a List. */
39
+ undo: (options?: {
40
+ describe?: (drawing: Drawing) => string;
41
+ focusRow?: boolean;
42
+ }) => void;
43
+ /** How long a removal can be undone, in milliseconds; 0 means until the next removal. */
44
+ undoWindow: number;
45
+ /** The bars of the chart the Layer sits in (empty until a Layer mounts); the Edit form counts bars from them. */
46
+ bars: readonly CandleBar[];
47
+ setBars: (bars: readonly CandleBar[]) => void;
48
+ /** Say something in the polite live region of Drawings.Undo, for example "Updated Trend line ...". */
49
+ announce: (text: string) => void;
50
+ /** The last thing announced, or null. */
51
+ status: string | null;
52
+ /** The chart's plot element once a Layer mounts: where Escape in the toolbar sends focus. */
53
+ plotRef: MutableRefObject<SVGSVGElement | null>;
54
+ /** The Drawings.Undo region once it mounts, so a list that lost its last row can put focus on its Undo button. */
55
+ undoRegion: MutableRefObject<HTMLElement | null>;
56
+ /** Set by the Undo button: the List then focuses the restored row once it is back. */
57
+ focusRowNext: MutableRefObject<boolean>;
58
+ /** Set by a button that is about to remove drawings while focused: the Undo button takes focus once it shows. */
59
+ focusUndoNext: MutableRefObject<boolean>;
60
+ }
61
+ /** The drawings state of the Drawings.Root above. */
62
+ export declare function useDrawings(part?: string): DrawingsContext;
63
+ export interface DrawingsRootProps {
64
+ /** Controlled drawings; without it Root keeps its own list. */
65
+ drawings?: readonly Drawing[];
66
+ onDrawingsChange?: (drawings: Drawing[]) => void;
67
+ /** Controlled tool in use, or null for none. */
68
+ tool?: DrawingTool | null;
69
+ onToolChange?: (tool: DrawingTool | null) => void;
70
+ /** Controlled selected drawing id, or null. */
71
+ selected?: string | null;
72
+ onSelectedChange?: (id: string | null) => void;
73
+ /** 'magnet' puts new points on the nearest bar and its open, high, low or close. Default 'off'. */
74
+ snap?: SnapMode;
75
+ /** How long the last removal can be undone, in milliseconds. 0 keeps it until the next removal. Default 10 000. */
76
+ undoWindow?: number;
77
+ children?: ReactNode;
78
+ }
79
+ /** State for the other parts. Each of drawings, tool and selection is controlled when given, and kept here when not. */
80
+ declare function Root({ drawings, onDrawingsChange, tool, onToolChange, selected, onSelectedChange, snap, undoWindow, children }: DrawingsRootProps): import("react").JSX.Element;
81
+ /**
82
+ * Draws every drawing and the handles of the selected one. Put it inside Chart.Plot, after the candles.
83
+ *
84
+ * With a tool in use it adds a transparent `drawing-capture` rect over the plot: press to set the first point, move
85
+ * to preview, then release after a drag or click again to set the second. One-point tools place on the press. A new
86
+ * drawing is selected and the tool is put away. With no tool, pressing a drawing selects it and dragging moves it,
87
+ * or moves one anchor when a handle is grabbed; pressing anywhere else is left to the plot, which pans.
88
+ *
89
+ * From the keyboard, with a tool in use and the chart focused: Enter places a point at the crosshair (the bar the arrow keys
90
+ * moved to, at the crosshair price, which from the keyboard is that bar's close), Enter again places the second point of a
91
+ * two-point tool, and Escape drops the half-placed drawing. Each step is announced in Drawings.Undo's live region.
92
+ *
93
+ * `newText` is the words a new text note gets. `formatTime` prints times in those announcements (default HH:MM in UTC). The
94
+ * layer is hidden from assistive technology: the List is its text.
95
+ */
96
+ declare function Layer({ className, newText, formatTime }: {
97
+ className?: string;
98
+ newText?: string;
99
+ formatTime?: (timestamp: number) => string;
100
+ }): import("react").JSX.Element;
101
+ export interface DrawingsToolbarProps {
102
+ className?: string;
103
+ 'aria-label'?: string;
104
+ /** Which tools to offer, in order. Default all nine. */
105
+ tools?: readonly DrawingTool[];
106
+ /**
107
+ * A graphic for each tool, drawn before its words and hidden from assistive technology: an object by tool, or a
108
+ * function of the tool. No icons ship with the package. With `hideLabels` the icon is all that shows.
109
+ */
110
+ icon?: Partial<Record<DrawingTool, ReactNode>> | ((tool: DrawingTool) => ReactNode);
111
+ /** Each tool's words (its accessible name), by tool. Default: "Trend line", "Ray" and so on. */
112
+ labels?: Partial<Record<DrawingTool, string>>;
113
+ /** Show only the icons; the labels become each button's `aria-label`. Needs `icon`. Default false. */
114
+ hideLabels?: boolean;
115
+ }
116
+ /**
117
+ * One button per tool, built on Toolbar: one tab stop, the arrow keys, Home and End move between the buttons, and Tab
118
+ * leaves. A pressed button is the tool in use; pressing it again puts the tool away. Escape sends focus to the chart.
119
+ * Every button has its tool in words, even when an icon is all that shows.
120
+ */
121
+ declare function Toolbar({ className, 'aria-label': label, tools, icon, labels, hideLabels }: DrawingsToolbarProps): import("react").JSX.Element;
122
+ export interface DrawingsListProps {
123
+ className?: string;
124
+ 'aria-label'?: string;
125
+ /** Decimals for printed prices. Default 2. */
126
+ decimals?: number;
127
+ /** Prints a time. Default HH:MM in UTC, with the date when a drawing spans days. */
128
+ formatTime?: (timestamp: number) => string;
129
+ /** Shown when there are no drawings. */
130
+ empty?: string;
131
+ }
132
+ /**
133
+ * The drawings in words, with a button to select and a button to remove each. The selected one has aria-current.
134
+ * Delete or Backspace on a drawing's line removes it, as on the chart, and so does its Remove button. Focus moves to the
135
+ * next line; after the last line is removed it goes to the Undo button when Drawings.Undo is showing it, else to the empty
136
+ * list (the "No drawings" line), never to the top of the page.
137
+ */
138
+ declare function List({ className, 'aria-label': label, decimals, formatTime, empty }: DrawingsListProps): import("react").JSX.Element;
139
+ export interface DrawingsRemoveProps extends NameProps {
140
+ className?: string;
141
+ /** Remove every drawing that is not locked, not only the selected one. */
142
+ all?: boolean;
143
+ /** The button's words. Default "Remove", or "Remove all" with `all`. */
144
+ children?: ReactNode;
145
+ }
146
+ /**
147
+ * A button that removes the selected drawing, or with `all` every drawing that is not locked. It acts only on a
148
+ * selection that already exists, never on what was under a finger when it was pressed, and the removal can be undone
149
+ * (see Undo). With nothing to remove it is `aria-disabled` rather than disabled, so keyboard focus stays on it.
150
+ */
151
+ declare function Remove({ className, all, icon, label, hideLabel, children }: DrawingsRemoveProps): import("react").JSX.Element;
152
+ export interface DrawingsUndoProps extends NameProps {
153
+ className?: string;
154
+ /** Decimals for printed prices. Default 2. */
155
+ decimals?: number;
156
+ formatTime?: (timestamp: number) => string;
157
+ }
158
+ /**
159
+ * Says what the last removal took out and offers Undo for as long as the Root's undoWindow lasts (10 seconds by
160
+ * default). The region is always in the page and announced politely, so a screen reader hears each removal as it
161
+ * happens. It is also where the other drawing announcements land (a point placed from the keyboard, an applied Edit), in
162
+ * a `data-part='drawing-status'` line, so one live region carries everything. Ctrl or Cmd + Z does the same from the chart. Only the last removal can be undone. Undo says what it restored in the same region. Focus moves to the
163
+ * restored row of Drawings.List when one is showing, else to the region (which then holds that sentence), so the button going away does not drop it to the top of the page.
164
+ */
165
+ declare function Undo({ className, decimals, formatTime, icon, label, hideLabel }: DrawingsUndoProps): import("react").JSX.Element;
166
+ export interface DrawingsLockProps extends NameProps {
167
+ className?: string;
168
+ /** The button's words. Default "Lock". The state is carried by aria-pressed, so the words do not change. */
169
+ children?: ReactNode;
170
+ }
171
+ /**
172
+ * A toggle for the selected drawing's lock. Pressed means locked: it cannot be dragged, nudged, edited by typing or
173
+ * removed until it is unlocked. With nothing selected it is `aria-disabled` and does nothing.
174
+ */
175
+ declare function Lock({ className, icon, label, hideLabel, children }: DrawingsLockProps): import("react").JSX.Element;
176
+ export interface DrawingsEditProps extends NameProps {
177
+ className?: string;
178
+ /** Decimals shown in the price fields. Default 2. */
179
+ decimals?: number;
180
+ /** Prints a time in the "Updated ..." announcement. Default HH:MM in UTC. */
181
+ formatTime?: (timestamp: number) => string;
182
+ /** The toggle button's words. Default "Edit". */
183
+ children?: ReactNode;
184
+ }
185
+ /**
186
+ * Type exact values for the selected drawing: a price and/or a time (UTC) for each anchor, and the words of a text
187
+ * note. A closed "Edit" button opens a small form with only the fields that tool has (a horizontal line has just a
188
+ * price). Enter applies, Escape closes without applying, a bad value is named next to its field and nothing is half
189
+ * applied and "Updated ..." is announced in Drawings.Undo's live region. This is also the way to place a line at an exact
190
+ * price without a pointer. A locked drawing cannot be edited.
191
+ */
192
+ declare function Edit({ className, decimals: rawDecimals, formatTime, icon, label, hideLabel, children }: DrawingsEditProps): import("react").JSX.Element;
193
+ export { Root, Layer, Toolbar, List, Remove, Undo, Lock, Edit };
194
+ //# sourceMappingURL=DrawingsParts.d.ts.map