pixel-react 1.1.8 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (173) hide show
  1. package/lib/components/AddButton/AddButton.d.ts +5 -0
  2. package/lib/components/AddButton/AddButton.stories.d.ts +6 -0
  3. package/lib/components/AddButton/index.d.ts +1 -0
  4. package/lib/components/AddButton/types.d.ts +4 -0
  5. package/lib/components/AppHeader/types.d.ts +7 -7
  6. package/lib/components/Drawer/Drawer.stories.d.ts +2 -0
  7. package/lib/components/Drawer/Types.d.ts +11 -0
  8. package/lib/components/ExcelFile/ChangeExcelStyles.d.ts +14 -0
  9. package/lib/components/ExcelFile/ColorBarSelector/ColorBarSelector.d.ts +8 -0
  10. package/lib/components/ExcelFile/ContextMenu/ContextMenu.d.ts +4 -0
  11. package/lib/components/ExcelFile/ExcelFile/Excel/ActiveCell.d.ts +7 -0
  12. package/lib/components/ExcelFile/ExcelFile/Excel/Cell.d.ts +4 -0
  13. package/lib/components/ExcelFile/ExcelFile/Excel/ColumnIndicator.d.ts +5 -0
  14. package/lib/components/ExcelFile/ExcelFile/Excel/Copied.d.ts +3 -0
  15. package/lib/components/ExcelFile/ExcelFile/Excel/CornerIndicator.d.ts +5 -0
  16. package/lib/components/ExcelFile/ExcelFile/Excel/DataEditor.d.ts +5 -0
  17. package/lib/components/ExcelFile/ExcelFile/Excel/DataViewer.d.ts +8 -0
  18. package/lib/components/ExcelFile/ExcelFile/Excel/FloatingRect.d.ts +10 -0
  19. package/lib/components/ExcelFile/ExcelFile/Excel/HeaderRow.d.ts +3 -0
  20. package/lib/components/ExcelFile/ExcelFile/Excel/Row.d.ts +3 -0
  21. package/lib/components/ExcelFile/ExcelFile/Excel/RowIndicator.d.ts +5 -0
  22. package/lib/components/ExcelFile/ExcelFile/Excel/Selected.d.ts +3 -0
  23. package/lib/components/ExcelFile/ExcelFile/Excel/Spreadsheet.d.ts +81 -0
  24. package/lib/components/ExcelFile/ExcelFile/Excel/Table.d.ts +3 -0
  25. package/lib/components/ExcelFile/ExcelFile/Excel/actions.d.ts +130 -0
  26. package/lib/components/ExcelFile/ExcelFile/Excel/areModelsEqual.d.ts +1 -0
  27. package/lib/components/ExcelFile/ExcelFile/Excel/context.d.ts +8 -0
  28. package/lib/components/ExcelFile/ExcelFile/Excel/engine/engine.d.ts +22 -0
  29. package/lib/components/ExcelFile/ExcelFile/Excel/engine/formula.d.ts +17 -0
  30. package/lib/components/ExcelFile/ExcelFile/Excel/engine/index.d.ts +2 -0
  31. package/lib/components/ExcelFile/ExcelFile/Excel/engine/point-graph.d.ts +21 -0
  32. package/lib/components/ExcelFile/ExcelFile/Excel/engine/point-hash.d.ts +3 -0
  33. package/lib/components/ExcelFile/ExcelFile/Excel/engine/point-set.d.ts +24 -0
  34. package/lib/components/ExcelFile/ExcelFile/Excel/index.d.ts +13 -0
  35. package/lib/components/ExcelFile/ExcelFile/Excel/matrix.d.ts +67 -0
  36. package/lib/components/ExcelFile/ExcelFile/Excel/point-range.d.ts +22 -0
  37. package/lib/components/ExcelFile/ExcelFile/Excel/point.d.ts +11 -0
  38. package/lib/components/ExcelFile/ExcelFile/Excel/reducer.d.ts +27 -0
  39. package/lib/components/ExcelFile/ExcelFile/Excel/selection.d.ts +95 -0
  40. package/lib/components/ExcelFile/ExcelFile/Excel/types.d.ts +215 -0
  41. package/lib/components/ExcelFile/ExcelFile/Excel/use-dispatch.d.ts +3 -0
  42. package/lib/components/ExcelFile/ExcelFile/Excel/use-selector.d.ts +3 -0
  43. package/lib/components/ExcelFile/ExcelFile/Excel/util.d.ts +45 -0
  44. package/lib/components/ExcelFile/ExcelFile/ExcelFile.d.ts +3 -0
  45. package/lib/components/ExcelFile/ExcelFile.stories.d.ts +6 -0
  46. package/lib/components/ExcelFile/ExcelSheetBar/ExcelSheetBar.d.ts +15 -0
  47. package/lib/components/ExcelFile/ExcelToolBar/ExcelToolBar.d.ts +3 -0
  48. package/lib/components/ExcelFile/ImportExcelStyles.d.ts +24 -0
  49. package/lib/components/ExcelFile/Types.d.ts +176 -0
  50. package/lib/components/ExcelFile/index.d.ts +1 -0
  51. package/lib/components/Icon/Icon.stories.d.ts +1 -0
  52. package/lib/components/Icon/types.d.ts +1 -0
  53. package/lib/components/IconRadioGroup/IconRadioGroup.d.ts +5 -0
  54. package/lib/components/IconRadioGroup/IconRadioGroup.stories.d.ts +7 -0
  55. package/lib/components/IconRadioGroup/index.d.ts +1 -0
  56. package/lib/components/IconRadioGroup/type.d.ts +41 -0
  57. package/lib/components/Table/Table.d.ts +1 -1
  58. package/lib/components/Table/Table.stories.d.ts +2 -0
  59. package/lib/components/Table/Types.d.ts +16 -0
  60. package/lib/index.d.ts +81 -9
  61. package/lib/index.esm.js +739 -248
  62. package/lib/index.esm.js.map +1 -1
  63. package/lib/index.js +739 -247
  64. package/lib/index.js.map +1 -1
  65. package/lib/tsconfig.tsbuildinfo +1 -1
  66. package/lib/utils/find/findAndInsert.d.ts +7 -0
  67. package/lib/utils/find/findAndInsert.stories.d.ts +7 -0
  68. package/package.json +4 -2
  69. package/src/assets/Themes/BaseTheme.scss +4 -0
  70. package/src/assets/Themes/DarkTheme.scss +4 -0
  71. package/src/assets/icons/all_borders.svg +3 -0
  72. package/src/assets/icons/bold.svg +3 -0
  73. package/src/assets/icons/border_bottom.svg +3 -0
  74. package/src/assets/icons/border_left.svg +3 -0
  75. package/src/assets/icons/border_right.svg +3 -0
  76. package/src/assets/icons/border_top.svg +3 -0
  77. package/src/assets/icons/clone_icon.svg +3 -0
  78. package/src/assets/icons/double_underline.svg +5 -0
  79. package/src/assets/icons/eye_closed.svg +3 -0
  80. package/src/assets/icons/fill_color.svg +7 -0
  81. package/src/assets/icons/formate_painter.svg +5 -0
  82. package/src/assets/icons/full_access_icon.svg +4 -0
  83. package/src/assets/icons/history_icon.svg +19 -0
  84. package/src/assets/icons/italic.svg +3 -0
  85. package/src/assets/icons/jira.svg +3 -0
  86. package/src/assets/icons/linked_defects.svg +11 -0
  87. package/src/assets/icons/move_icon.svg +5 -0
  88. package/src/assets/icons/no_access_icon.svg +4 -0
  89. package/src/assets/icons/no_border.svg +3 -0
  90. package/src/assets/icons/strike_through.svg +3 -0
  91. package/src/assets/icons/text_align_center.svg +3 -0
  92. package/src/assets/icons/text_align_left.svg +3 -0
  93. package/src/assets/icons/text_align_right.svg +3 -0
  94. package/src/assets/icons/text_color.svg +3 -0
  95. package/src/assets/icons/underline.svg +4 -0
  96. package/src/assets/icons/view_access_icon.svg +4 -0
  97. package/src/components/AppHeader/AppHeader.scss +23 -10
  98. package/src/components/AppHeader/AppHeader.stories.tsx +29 -28
  99. package/src/components/AppHeader/AppHeader.tsx +18 -16
  100. package/src/components/AppHeader/types.ts +7 -7
  101. package/src/components/Button/Button.scss +1 -0
  102. package/src/components/Checkbox/Checkbox.tsx +1 -1
  103. package/src/components/Drawer/Drawer.scss +13 -9
  104. package/src/components/Drawer/Drawer.stories.tsx +28 -0
  105. package/src/components/Drawer/Drawer.tsx +29 -6
  106. package/src/components/Drawer/Types.ts +11 -0
  107. package/src/components/ExcelFile/ChangeExcelStyles.tsx +78 -0
  108. package/src/components/ExcelFile/ColorBarselector/ColorBarSelector.scss +13 -0
  109. package/src/components/ExcelFile/ColorBarselector/ColorBarSelector.tsx +43 -0
  110. package/src/components/ExcelFile/ContextMenu/ContextMenu.scss +102 -0
  111. package/src/components/ExcelFile/ContextMenu/ContextMenu.tsx +104 -0
  112. package/src/components/ExcelFile/ExcelFile/Excel/ActiveCell.tsx +131 -0
  113. package/src/components/ExcelFile/ExcelFile/Excel/Cell.tsx +201 -0
  114. package/src/components/ExcelFile/ExcelFile/Excel/ColumnIndicator.tsx +123 -0
  115. package/src/components/ExcelFile/ExcelFile/Excel/Copied.tsx +25 -0
  116. package/src/components/ExcelFile/ExcelFile/Excel/CornerIndicator.tsx +49 -0
  117. package/src/components/ExcelFile/ExcelFile/Excel/DataEditor.tsx +37 -0
  118. package/src/components/ExcelFile/ExcelFile/Excel/DataViewer.tsx +46 -0
  119. package/src/components/ExcelFile/ExcelFile/Excel/FloatingRect.tsx +31 -0
  120. package/src/components/ExcelFile/ExcelFile/Excel/HeaderRow.tsx +5 -0
  121. package/src/components/ExcelFile/ExcelFile/Excel/Row.tsx +5 -0
  122. package/src/components/ExcelFile/ExcelFile/Excel/RowIndicator.tsx +102 -0
  123. package/src/components/ExcelFile/ExcelFile/Excel/Selected.tsx +32 -0
  124. package/src/components/ExcelFile/ExcelFile/Excel/Spreadsheet.css +144 -0
  125. package/src/components/ExcelFile/ExcelFile/Excel/Spreadsheet.tsx +494 -0
  126. package/src/components/ExcelFile/ExcelFile/Excel/Table.tsx +19 -0
  127. package/src/components/ExcelFile/ExcelFile/Excel/actions.ts +302 -0
  128. package/src/components/ExcelFile/ExcelFile/Excel/areModelsEqual.ts +18 -0
  129. package/src/components/ExcelFile/ExcelFile/Excel/context.ts +12 -0
  130. package/src/components/ExcelFile/ExcelFile/Excel/engine/engine.ts +200 -0
  131. package/src/components/ExcelFile/ExcelFile/Excel/engine/formula.ts +137 -0
  132. package/src/components/ExcelFile/ExcelFile/Excel/engine/index.ts +2 -0
  133. package/src/components/ExcelFile/ExcelFile/Excel/engine/point-graph.ts +154 -0
  134. package/src/components/ExcelFile/ExcelFile/Excel/engine/point-hash.ts +10 -0
  135. package/src/components/ExcelFile/ExcelFile/Excel/engine/point-set.ts +69 -0
  136. package/src/components/ExcelFile/ExcelFile/Excel/index.ts +48 -0
  137. package/src/components/ExcelFile/ExcelFile/Excel/matrix.ts +388 -0
  138. package/src/components/ExcelFile/ExcelFile/Excel/point-range.ts +82 -0
  139. package/src/components/ExcelFile/ExcelFile/Excel/point.ts +15 -0
  140. package/src/components/ExcelFile/ExcelFile/Excel/reducer.ts +682 -0
  141. package/src/components/ExcelFile/ExcelFile/Excel/selection.ts +257 -0
  142. package/src/components/ExcelFile/ExcelFile/Excel/types.ts +269 -0
  143. package/src/components/ExcelFile/ExcelFile/Excel/typings/fast-formula-parser.d.ts +58 -0
  144. package/src/components/ExcelFile/ExcelFile/Excel/use-dispatch.ts +8 -0
  145. package/src/components/ExcelFile/ExcelFile/Excel/use-selector.ts +9 -0
  146. package/src/components/ExcelFile/ExcelFile/Excel/util.ts +173 -0
  147. package/src/components/ExcelFile/ExcelFile/ExcelFile.scss +27 -0
  148. package/src/components/ExcelFile/ExcelFile/ExcelFile.tsx +520 -0
  149. package/src/components/ExcelFile/ExcelFile.stories.tsx +132 -0
  150. package/src/components/ExcelFile/ExcelSheetBar/ExcelSheetBar.scss +16 -0
  151. package/src/components/ExcelFile/ExcelSheetBar/ExcelSheetBar.tsx +79 -0
  152. package/src/components/ExcelFile/ExcelToolBar/ExcelToolBar.scss +22 -0
  153. package/src/components/ExcelFile/ExcelToolBar/ExcelToolBar.tsx +271 -0
  154. package/src/components/ExcelFile/ImportExcelStyles.tsx +86 -0
  155. package/src/components/ExcelFile/Types.ts +241 -0
  156. package/src/components/ExcelFile/index.ts +1 -0
  157. package/src/components/Icon/Icon.stories.tsx +27 -0
  158. package/src/components/Icon/Icon.tsx +5 -1
  159. package/src/components/Icon/Icons.scss +15 -5
  160. package/src/components/Icon/iconList.ts +52 -1
  161. package/src/components/Icon/types.ts +1 -0
  162. package/src/components/IconRadioGroup/IconRadioGroup.scss +60 -0
  163. package/src/components/IconRadioGroup/IconRadioGroup.stories.tsx +108 -0
  164. package/src/components/IconRadioGroup/IconRadioGroup.tsx +72 -0
  165. package/src/components/IconRadioGroup/index.ts +1 -0
  166. package/src/components/IconRadioGroup/type.ts +50 -0
  167. package/src/components/Modal/Modal.tsx +8 -1
  168. package/src/components/Modal/modal.scss +10 -2
  169. package/src/components/Table/Table.scss +16 -4
  170. package/src/components/Table/Table.stories.tsx +36 -12
  171. package/src/components/Table/Table.tsx +33 -16
  172. package/src/components/Table/Types.ts +121 -105
  173. package/src/index.ts +2 -0
@@ -0,0 +1,302 @@
1
+ import { Matrix } from "./matrix";
2
+ import { Point } from "./point";
3
+ import {
4
+ CellBase,
5
+ Dimensions,
6
+ CommitChanges,
7
+ CreateFormulaParser,
8
+ } from "./types";
9
+ import { Selection } from "./selection";
10
+
11
+ export const SET_DATA = "SET_DATA";
12
+ export const SET_CREATE_FORMULA_PARSER = "SET_CREATE_FORMULA_PARSER";
13
+ export const SELECT_ENTIRE_ROW = "SELECT_ENTIRE_ROW";
14
+ export const SELECT_ENTIRE_COLUMN = "SELECT_ENTIRE_COLUMN";
15
+ export const SELECT_ENTIRE_WORKSHEET = "SELECT_ENTIRE_WORKSHEET";
16
+ export const SET_SELECTION = "SET_SELECTION";
17
+ export const SELECT = "SELECT";
18
+ export const ACTIVATE = "ACTIVATE";
19
+ export const SET_CELL_DATA = "SET_CELL_DATA";
20
+ export const SET_CELL_DIMENSIONS = "SET_CELL_DIMENSIONS";
21
+ export const COPY = "COPY";
22
+ export const CUT = "CUT";
23
+ export const PASTE = "PASTE";
24
+ export const EDIT = "EDIT";
25
+ export const VIEW = "VIEW";
26
+ export const CLEAR = "CLEAR";
27
+ export const BLUR = "BLUR";
28
+ export const KEY_PRESS = "KEY_PRESS";
29
+ export const KEY_DOWN = "KEY_DOWN";
30
+ export const DRAG_START = "DRAG_START";
31
+ export const DRAG_END = "DRAG_END";
32
+ export const COMMIT = "COMMIT";
33
+
34
+ export type BaseAction<T extends string> = {
35
+ type: T;
36
+ };
37
+
38
+ export type SetDataAction = BaseAction<typeof SET_DATA> & {
39
+ payload: {
40
+ data: Matrix<CellBase>;
41
+ };
42
+ };
43
+
44
+ export function setData(data: Matrix<CellBase>): SetDataAction {
45
+ return {
46
+ type: SET_DATA,
47
+ payload: { data },
48
+ };
49
+ }
50
+
51
+ export type SetCreateFormulaParserAction = BaseAction<
52
+ typeof SET_CREATE_FORMULA_PARSER
53
+ > & {
54
+ payload: {
55
+ createFormulaParser: CreateFormulaParser;
56
+ };
57
+ };
58
+
59
+ export function setCreateFormulaParser(
60
+ createFormulaParser: CreateFormulaParser
61
+ ): SetCreateFormulaParserAction {
62
+ return {
63
+ type: SET_CREATE_FORMULA_PARSER,
64
+ payload: { createFormulaParser },
65
+ };
66
+ }
67
+
68
+ export type SelectEntireRowAction = BaseAction<typeof SELECT_ENTIRE_ROW> & {
69
+ payload: {
70
+ row: number;
71
+ extend: boolean;
72
+ };
73
+ };
74
+
75
+ export function selectEntireRow(
76
+ row: number,
77
+ extend: boolean
78
+ ): SelectEntireRowAction {
79
+ return {
80
+ type: SELECT_ENTIRE_ROW,
81
+ payload: { row, extend },
82
+ };
83
+ }
84
+
85
+ export type SelectEntireColumnAction = BaseAction<
86
+ typeof SELECT_ENTIRE_COLUMN
87
+ > & {
88
+ payload: {
89
+ column: number;
90
+ extend: boolean;
91
+ };
92
+ };
93
+
94
+ export function selectEntireColumn(
95
+ column: number,
96
+ extend: boolean
97
+ ): SelectEntireColumnAction {
98
+ return {
99
+ type: SELECT_ENTIRE_COLUMN,
100
+ payload: { column, extend },
101
+ };
102
+ }
103
+
104
+ export type SelectEntireWorksheetAction = BaseAction<
105
+ typeof SELECT_ENTIRE_WORKSHEET
106
+ >;
107
+
108
+ export function selectEntireWorksheet(): SelectEntireWorksheetAction {
109
+ return { type: SELECT_ENTIRE_WORKSHEET };
110
+ }
111
+
112
+ export type SetSelectionAction = BaseAction<typeof SET_SELECTION> & {
113
+ payload: {
114
+ selection: Selection;
115
+ };
116
+ };
117
+
118
+ export function setSelection(selection: Selection): SetSelectionAction {
119
+ return { type: SET_SELECTION, payload: { selection } };
120
+ }
121
+
122
+ export type SelectAction = BaseAction<typeof SELECT> & {
123
+ payload: {
124
+ point: Point;
125
+ };
126
+ };
127
+
128
+ export function select(point: Point): SelectAction {
129
+ return {
130
+ type: SELECT,
131
+ payload: { point },
132
+ };
133
+ }
134
+
135
+ export type ActivateAction = BaseAction<typeof ACTIVATE> & {
136
+
137
+ payload: {
138
+ point: Point;
139
+ };
140
+ };
141
+
142
+ export function activate(point: Point): ActivateAction {
143
+ return {
144
+ type: ACTIVATE,
145
+ payload: { point },
146
+ };
147
+ }
148
+
149
+ export type SetCellDataAction = BaseAction<typeof SET_CELL_DATA> & {
150
+ payload: {
151
+ active: Point;
152
+ data: CellBase;
153
+ };
154
+ };
155
+
156
+ export function setCellData(active: Point, data: CellBase): SetCellDataAction {
157
+ return {
158
+ type: SET_CELL_DATA,
159
+ payload: { active, data },
160
+ };
161
+ }
162
+
163
+ export type SetCellDimensionsAction = BaseAction<typeof SET_CELL_DIMENSIONS> & {
164
+ payload: {
165
+ point: Point;
166
+ dimensions: Dimensions;
167
+ };
168
+ };
169
+
170
+ export function setCellDimensions(
171
+ point: Point,
172
+ dimensions: Dimensions
173
+ ): SetCellDimensionsAction {
174
+ return {
175
+ type: SET_CELL_DIMENSIONS,
176
+ payload: { point, dimensions },
177
+ };
178
+ }
179
+
180
+ export type PasteAction = BaseAction<typeof PASTE> & {
181
+ payload: {
182
+ data: string;
183
+ };
184
+ };
185
+
186
+ export function paste(data: string): PasteAction {
187
+ return {
188
+ type: PASTE,
189
+ payload: { data },
190
+ };
191
+ }
192
+
193
+ export type KeyPressAction = BaseAction<typeof KEY_PRESS> & {
194
+ payload: {
195
+ event: React.KeyboardEvent;
196
+ };
197
+ };
198
+
199
+ export function keyPress(event: React.KeyboardEvent): KeyPressAction {
200
+ return {
201
+ type: KEY_PRESS,
202
+ payload: { event },
203
+ };
204
+ }
205
+
206
+ export type KeyDownAction = BaseAction<typeof KEY_DOWN> & {
207
+ payload: {
208
+ event: React.KeyboardEvent;
209
+ };
210
+ };
211
+
212
+ export function keyDown(event: React.KeyboardEvent): KeyDownAction {
213
+ return {
214
+ type: KEY_DOWN,
215
+ payload: { event },
216
+ };
217
+ }
218
+
219
+ export type DragStartAction = BaseAction<typeof DRAG_START>;
220
+
221
+ export function dragStart(): DragStartAction {
222
+ return { type: DRAG_START };
223
+ }
224
+
225
+ export type DragEndAction = BaseAction<typeof DRAG_END>;
226
+
227
+ export function dragEnd(): DragEndAction {
228
+ return { type: DRAG_END };
229
+ }
230
+
231
+ export type CommitAction = BaseAction<typeof COMMIT> & {
232
+ payload: {
233
+ changes: CommitChanges;
234
+ };
235
+ };
236
+
237
+ export function commit(changes: CommitChanges): CommitAction {
238
+ return {
239
+ type: COMMIT,
240
+ payload: { changes },
241
+ };
242
+ }
243
+
244
+ export type CopyAction = BaseAction<typeof COPY>;
245
+
246
+ export function copy(): CopyAction {
247
+ return { type: COPY };
248
+ }
249
+
250
+ export type CutAction = BaseAction<typeof CUT>;
251
+
252
+ export function cut(): CutAction {
253
+ return { type: CUT };
254
+ }
255
+
256
+ export type EditAction = BaseAction<typeof EDIT>;
257
+
258
+ export function edit(): EditAction {
259
+ return { type: EDIT };
260
+ }
261
+
262
+ export type ViewAction = BaseAction<typeof VIEW>;
263
+
264
+ export function view(): ViewAction {
265
+ return { type: VIEW };
266
+ }
267
+
268
+ export type ClearAction = BaseAction<typeof CLEAR>;
269
+
270
+ export function clear(): ClearAction {
271
+ return { type: CLEAR };
272
+ }
273
+
274
+ export type BlurAction = BaseAction<typeof BLUR>;
275
+
276
+ export function blur(): BlurAction {
277
+ return { type: BLUR };
278
+ }
279
+
280
+ export type Action =
281
+ | SetDataAction
282
+ | SetCreateFormulaParserAction
283
+ | SelectEntireRowAction
284
+ | SelectEntireColumnAction
285
+ | SelectEntireWorksheetAction
286
+ | SetSelectionAction
287
+ | SelectAction
288
+ | ActivateAction
289
+ | SetCellDataAction
290
+ | SetCellDimensionsAction
291
+ | PasteAction
292
+ | KeyPressAction
293
+ | KeyDownAction
294
+ | DragStartAction
295
+ | DragEndAction
296
+ | CommitAction
297
+ | CopyAction
298
+ | CutAction
299
+ | EditAction
300
+ | ViewAction
301
+ | ClearAction
302
+ | BlurAction;
@@ -0,0 +1,18 @@
1
+ import { Model } from "./engine";
2
+
3
+ function areModelsEqual(a: unknown, b: unknown): boolean | undefined {
4
+ const isAModule = a instanceof Model;
5
+ const isBModule = b instanceof Model;
6
+
7
+ if (isAModule && isBModule) {
8
+ // @ts-expect-error
9
+ return this.equals(a, b);
10
+ } else if (isAModule !== isBModule) {
11
+ return false;
12
+ } else {
13
+ return undefined;
14
+ }
15
+ }
16
+
17
+ // @ts-expect-error
18
+ expect.addEqualityTesters([areModelsEqual]);
@@ -0,0 +1,12 @@
1
+ import * as React from "react";
2
+ import { createContext } from "use-context-selector";
3
+ import reducer, { INITIAL_STATE } from "./reducer";
4
+ import { Action } from "./actions";
5
+
6
+ export type ReducerState = React.ReducerState<typeof reducer>;
7
+ export type Dispatch = React.Dispatch<Action>;
8
+ export type Value = [ReducerState, Dispatch];
9
+
10
+ const context = createContext<Value>([INITIAL_STATE, () => {}]);
11
+
12
+ export default context;
@@ -0,0 +1,200 @@
1
+ import FormulaParser, { FormulaError, Value } from "fast-formula-parser";
2
+ import * as Matrix from "../matrix";
3
+ import { Point } from "../point";
4
+ import { CellBase, CreateFormulaParser } from "../types";
5
+ import * as Formula from "./formula";
6
+ import { PointGraph } from "./point-graph";
7
+ import { PointSet } from "./point-set";
8
+
9
+ export class Model<Cell extends CellBase> {
10
+ readonly data!: Matrix.Matrix<Cell>;
11
+ readonly evaluatedData!: Matrix.Matrix<Cell>;
12
+ readonly referenceGraph!: PointGraph;
13
+ readonly createFormulaParser!: CreateFormulaParser;
14
+
15
+ constructor(
16
+ createFormulaParser: CreateFormulaParser,
17
+ data: Matrix.Matrix<Cell>,
18
+ referenceGraph?: PointGraph,
19
+ evaluatedData?: Matrix.Matrix<Cell>
20
+ ) {
21
+ this.createFormulaParser = createFormulaParser;
22
+ this.data = data;
23
+ this.referenceGraph = referenceGraph || createReferenceGraph(data);
24
+ this.evaluatedData =
25
+ evaluatedData ||
26
+ createEvaluatedData(data, this.referenceGraph, this.createFormulaParser);
27
+ }
28
+ }
29
+
30
+ export function updateCellValue<Cell extends CellBase>(
31
+ model: Model<Cell>,
32
+ point: Point,
33
+ cell: Cell
34
+ ): Model<Cell> {
35
+ const nextData = Matrix.set(point, cell, model.data);
36
+ const nextReferenceGraph = Formula.isFormulaValue(cell.value)
37
+ ? updateReferenceGraph(model.referenceGraph, point, cell, nextData)
38
+ : model.referenceGraph;
39
+
40
+ const formulaParser = model.createFormulaParser(nextData);
41
+ const nextEvaluatedData = evaluateCell(
42
+ model.evaluatedData,
43
+ nextData,
44
+ nextReferenceGraph,
45
+ point,
46
+ cell,
47
+ formulaParser
48
+ );
49
+ return new Model(
50
+ model.createFormulaParser,
51
+ nextData,
52
+ nextReferenceGraph,
53
+ nextEvaluatedData
54
+ );
55
+ }
56
+
57
+ function updateReferenceGraph(
58
+ referenceGraph: PointGraph,
59
+ point: Point,
60
+ cell: CellBase<string>,
61
+ data: Matrix.Matrix<CellBase>
62
+ ): PointGraph {
63
+ const references = Formula.getReferences(
64
+ Formula.extractFormula(cell.value),
65
+ point,
66
+ data
67
+ );
68
+ const nextReferenceGraph = referenceGraph.set(point, references);
69
+ return nextReferenceGraph;
70
+ }
71
+
72
+ function evaluateCell<Cell extends CellBase>(
73
+ prevEvaluatedData: Matrix.Matrix<Cell>,
74
+ data: Matrix.Matrix<Cell>,
75
+ referenceGraph: PointGraph,
76
+ point: Point,
77
+ cell: Cell,
78
+ formulaParser: FormulaParser
79
+ ): Matrix.Matrix<Cell> {
80
+ if (referenceGraph.hasCircularDependency(point)) {
81
+ let visited = PointSet.from([point]);
82
+ let nextEvaluatedData = Matrix.set(
83
+ point,
84
+ { ...cell, value: FormulaError.REF },
85
+ prevEvaluatedData
86
+ );
87
+ for (const referrer of referenceGraph.getBackwardsRecursive(point)) {
88
+ if (visited.has(referrer)) {
89
+ break;
90
+ }
91
+ visited = visited.add(referrer);
92
+ const referrerCell = Matrix.get(referrer, data);
93
+ if (!referrerCell) {
94
+ continue;
95
+ }
96
+ nextEvaluatedData = Matrix.set(
97
+ referrer,
98
+ { ...referrerCell, value: FormulaError.REF },
99
+ nextEvaluatedData
100
+ );
101
+ }
102
+ return nextEvaluatedData;
103
+ }
104
+
105
+ let nextEvaluatedData = prevEvaluatedData;
106
+
107
+ const evaluatedValue = Formula.isFormulaValue(cell.value)
108
+ ? getFormulaComputedValue(cell.value, point, formulaParser)
109
+ : cell.value;
110
+
111
+ const evaluatedCell = { ...cell, value: evaluatedValue };
112
+
113
+ nextEvaluatedData = Matrix.set(point, evaluatedCell, nextEvaluatedData);
114
+
115
+ // for every formula cell that references the cell re-evaluate (recursive)
116
+ for (const referrer of referenceGraph.getBackwardsRecursive(point)) {
117
+ const referrerCell = Matrix.get(referrer, data);
118
+ if (!referrerCell) {
119
+ continue;
120
+ }
121
+ const evaluatedValue = Formula.isFormulaValue(referrerCell.value)
122
+ ? getFormulaComputedValue(referrerCell.value, point, formulaParser)
123
+ : referrerCell.value;
124
+ const evaluatedCell = { ...referrerCell, value: evaluatedValue };
125
+ nextEvaluatedData = Matrix.set(referrer, evaluatedCell, nextEvaluatedData);
126
+ }
127
+
128
+ return nextEvaluatedData;
129
+ }
130
+
131
+ /**
132
+ *
133
+ * @param data - the spreadsheet data
134
+ * @returns the spreadsheet reference graph
135
+ */
136
+ export function createReferenceGraph(
137
+ data: Matrix.Matrix<CellBase>
138
+ ): PointGraph {
139
+ const entries: Array<[Point, PointSet]> = [];
140
+ for (const [point, cell] of Matrix.entries(data)) {
141
+ if (cell && Formula.isFormulaValue(cell.value)) {
142
+ const references = Formula.getReferences(
143
+ Formula.extractFormula(cell.value),
144
+ point,
145
+ data
146
+ );
147
+ entries.push([point, references]);
148
+ }
149
+ }
150
+ return PointGraph.from(entries);
151
+ }
152
+
153
+ export function createEvaluatedData<Cell extends CellBase>(
154
+ data: Matrix.Matrix<Cell>,
155
+ referenceGraph: PointGraph,
156
+ createFormulaParser: CreateFormulaParser
157
+ ): Matrix.Matrix<Cell> {
158
+ let evaluatedData = data;
159
+ let formulaParser = createFormulaParser(evaluatedData);
160
+
161
+ // Iterate over the points in the reference graph, starting from the leaves
162
+ for (const point of referenceGraph.traverseBFSBackwards()) {
163
+ // Get the cell at the current point in the data Matrix
164
+ const cell = Matrix.get(point, data);
165
+ if (!cell) {
166
+ continue;
167
+ }
168
+
169
+ // If the cell is a formula cell, evaluate it
170
+ if (Formula.isFormulaValue(cell.value)) {
171
+ const evaluatedValue = getFormulaComputedValue(
172
+ cell.value,
173
+ point,
174
+ formulaParser
175
+ );
176
+ evaluatedData = Matrix.set(
177
+ point,
178
+ { ...cell, value: evaluatedValue },
179
+ evaluatedData
180
+ );
181
+ formulaParser = createFormulaParser(evaluatedData);
182
+ }
183
+ }
184
+
185
+ return evaluatedData;
186
+ }
187
+
188
+ /** Get the computed value of a formula cell */
189
+ export function getFormulaComputedValue(
190
+ value: string,
191
+ point: Point,
192
+ formulaParser: FormulaParser
193
+ ): Value {
194
+ const formula = Formula.extractFormula(value);
195
+ try {
196
+ return Formula.evaluate(formula, point, formulaParser);
197
+ } catch (e) {
198
+ return FormulaError.REF;
199
+ }
200
+ }
@@ -0,0 +1,137 @@
1
+ import FormulaParser, {
2
+ CellRef,
3
+ DepParser,
4
+ FormulaError,
5
+ FormulaParserConfig,
6
+ Value,
7
+ } from "fast-formula-parser";
8
+ import { PointRange } from "../point-range";
9
+ import { Point } from "../point";
10
+ import * as Matrix from "../matrix";
11
+ import { CellBase } from "../types";
12
+ import { PointSet } from "./point-set";
13
+
14
+ export const FORMULA_VALUE_PREFIX = "=";
15
+
16
+ /** Returns whether given value is a formula */
17
+ export function isFormulaValue(value: unknown): value is string {
18
+ return (
19
+ typeof value === "string" &&
20
+ value.startsWith(FORMULA_VALUE_PREFIX) &&
21
+ value.length > 1
22
+ );
23
+ }
24
+
25
+ /** Extracts formula from value */
26
+ export function extractFormula(value: string): string {
27
+ return value.slice(1);
28
+ }
29
+
30
+ export function createFormulaParser(
31
+ data: Matrix.Matrix<CellBase>,
32
+ config?: Omit<FormulaParserConfig, "onCell" | "onRange">
33
+ ): FormulaParser {
34
+ return new FormulaParser({
35
+ ...config,
36
+ onCell: (ref) => {
37
+ const point: Point = {
38
+ row: ref.row - 1,
39
+ column: ref.col - 1,
40
+ };
41
+ const cell = Matrix.get(point, data);
42
+ if (!isNaN(cell?.value as number)) return Number(cell?.value);
43
+ return cell?.value;
44
+ },
45
+ onRange: (ref) => {
46
+ const size = Matrix.getSize(data);
47
+ const start: Point = {
48
+ row: ref.from.row - 1,
49
+ column: ref.from.col - 1,
50
+ };
51
+ const end: Point = {
52
+ row: Math.min(ref.to.row - 1, size.rows - 1),
53
+ column: Math.min(ref.to.col - 1, size.columns - 1),
54
+ };
55
+ const dataSlice = Matrix.slice(start, end, data);
56
+ return Matrix.toArray(dataSlice, (cell) => {
57
+ if (!isNaN(cell?.value as number)) return Number(cell?.value);
58
+ return cell?.value;
59
+ });
60
+ },
61
+ });
62
+ }
63
+
64
+ const depParser = new DepParser();
65
+
66
+ /**
67
+ * For given formula returns the cell references
68
+ * @param formula - formula to get references for
69
+ */
70
+ export function getReferences(
71
+ formula: string,
72
+ point: Point,
73
+ data: Matrix.Matrix<CellBase>
74
+ ): PointSet {
75
+ const { rows, columns } = Matrix.getSize(data);
76
+ try {
77
+ const dependencies = depParser.parse(formula, convertPointToCellRef(point));
78
+
79
+ const references = PointSet.from(
80
+ dependencies.flatMap((reference) => {
81
+ const isRange = "from" in reference;
82
+ if (isRange) {
83
+ const { from, to } = reference;
84
+
85
+ const normalizedFrom: Point = {
86
+ row: from.row - 1,
87
+ column: from.col - 1,
88
+ };
89
+
90
+ const normalizedTo: Point = {
91
+ row: Math.min(to.row - 1, rows - 1),
92
+ column: Math.min(to.col - 1, columns - 1),
93
+ };
94
+
95
+ const range = new PointRange(normalizedFrom, normalizedTo);
96
+
97
+ return Array.from(range);
98
+ }
99
+ return { row: reference.row - 1, column: reference.col - 1 };
100
+ })
101
+ );
102
+
103
+ return references;
104
+ } catch (error) {
105
+ if (error instanceof FormulaError) {
106
+ return PointSet.from([]);
107
+ } else {
108
+ throw error;
109
+ }
110
+ }
111
+ }
112
+
113
+ export function evaluate(
114
+ formula: string,
115
+ point: Point,
116
+ formulaParser: FormulaParser
117
+ ): Value {
118
+ try {
119
+ const position = convertPointToCellRef(point);
120
+ const returned = formulaParser.parse(formula, position);
121
+ return returned instanceof FormulaError ? returned.toString() : returned;
122
+ } catch (error) {
123
+ if (error instanceof FormulaError) {
124
+ return error.toString();
125
+ }
126
+ throw error;
127
+ }
128
+ }
129
+
130
+ function convertPointToCellRef(point: Point): CellRef {
131
+ return {
132
+ row: point.row + 1,
133
+ col: point.column + 1,
134
+ // TODO: fill once we support multiple sheets
135
+ sheet: "Sheet1",
136
+ };
137
+ }
@@ -0,0 +1,2 @@
1
+ export { Model, updateCellValue } from "./engine";
2
+ export { createFormulaParser } from "./formula";