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.
- package/lib/components/AddButton/AddButton.d.ts +5 -0
- package/lib/components/AddButton/AddButton.stories.d.ts +6 -0
- package/lib/components/AddButton/index.d.ts +1 -0
- package/lib/components/AddButton/types.d.ts +4 -0
- package/lib/components/AppHeader/types.d.ts +7 -7
- package/lib/components/Drawer/Drawer.stories.d.ts +2 -0
- package/lib/components/Drawer/Types.d.ts +11 -0
- package/lib/components/ExcelFile/ChangeExcelStyles.d.ts +14 -0
- package/lib/components/ExcelFile/ColorBarSelector/ColorBarSelector.d.ts +8 -0
- package/lib/components/ExcelFile/ContextMenu/ContextMenu.d.ts +4 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/ActiveCell.d.ts +7 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/Cell.d.ts +4 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/ColumnIndicator.d.ts +5 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/Copied.d.ts +3 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/CornerIndicator.d.ts +5 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/DataEditor.d.ts +5 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/DataViewer.d.ts +8 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/FloatingRect.d.ts +10 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/HeaderRow.d.ts +3 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/Row.d.ts +3 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/RowIndicator.d.ts +5 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/Selected.d.ts +3 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/Spreadsheet.d.ts +81 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/Table.d.ts +3 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/actions.d.ts +130 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/areModelsEqual.d.ts +1 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/context.d.ts +8 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/engine/engine.d.ts +22 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/engine/formula.d.ts +17 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/engine/index.d.ts +2 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/engine/point-graph.d.ts +21 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/engine/point-hash.d.ts +3 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/engine/point-set.d.ts +24 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/index.d.ts +13 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/matrix.d.ts +67 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/point-range.d.ts +22 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/point.d.ts +11 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/reducer.d.ts +27 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/selection.d.ts +95 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/types.d.ts +215 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/use-dispatch.d.ts +3 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/use-selector.d.ts +3 -0
- package/lib/components/ExcelFile/ExcelFile/Excel/util.d.ts +45 -0
- package/lib/components/ExcelFile/ExcelFile/ExcelFile.d.ts +3 -0
- package/lib/components/ExcelFile/ExcelFile.stories.d.ts +6 -0
- package/lib/components/ExcelFile/ExcelSheetBar/ExcelSheetBar.d.ts +15 -0
- package/lib/components/ExcelFile/ExcelToolBar/ExcelToolBar.d.ts +3 -0
- package/lib/components/ExcelFile/ImportExcelStyles.d.ts +24 -0
- package/lib/components/ExcelFile/Types.d.ts +176 -0
- package/lib/components/ExcelFile/index.d.ts +1 -0
- package/lib/components/Icon/Icon.stories.d.ts +1 -0
- package/lib/components/Icon/types.d.ts +1 -0
- package/lib/components/IconRadioGroup/IconRadioGroup.d.ts +5 -0
- package/lib/components/IconRadioGroup/IconRadioGroup.stories.d.ts +7 -0
- package/lib/components/IconRadioGroup/index.d.ts +1 -0
- package/lib/components/IconRadioGroup/type.d.ts +41 -0
- package/lib/components/Table/Table.d.ts +1 -1
- package/lib/components/Table/Table.stories.d.ts +2 -0
- package/lib/components/Table/Types.d.ts +16 -0
- package/lib/index.d.ts +81 -9
- package/lib/index.esm.js +739 -248
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +739 -247
- package/lib/index.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/utils/find/findAndInsert.d.ts +7 -0
- package/lib/utils/find/findAndInsert.stories.d.ts +7 -0
- package/package.json +4 -2
- package/src/assets/Themes/BaseTheme.scss +4 -0
- package/src/assets/Themes/DarkTheme.scss +4 -0
- package/src/assets/icons/all_borders.svg +3 -0
- package/src/assets/icons/bold.svg +3 -0
- package/src/assets/icons/border_bottom.svg +3 -0
- package/src/assets/icons/border_left.svg +3 -0
- package/src/assets/icons/border_right.svg +3 -0
- package/src/assets/icons/border_top.svg +3 -0
- package/src/assets/icons/clone_icon.svg +3 -0
- package/src/assets/icons/double_underline.svg +5 -0
- package/src/assets/icons/eye_closed.svg +3 -0
- package/src/assets/icons/fill_color.svg +7 -0
- package/src/assets/icons/formate_painter.svg +5 -0
- package/src/assets/icons/full_access_icon.svg +4 -0
- package/src/assets/icons/history_icon.svg +19 -0
- package/src/assets/icons/italic.svg +3 -0
- package/src/assets/icons/jira.svg +3 -0
- package/src/assets/icons/linked_defects.svg +11 -0
- package/src/assets/icons/move_icon.svg +5 -0
- package/src/assets/icons/no_access_icon.svg +4 -0
- package/src/assets/icons/no_border.svg +3 -0
- package/src/assets/icons/strike_through.svg +3 -0
- package/src/assets/icons/text_align_center.svg +3 -0
- package/src/assets/icons/text_align_left.svg +3 -0
- package/src/assets/icons/text_align_right.svg +3 -0
- package/src/assets/icons/text_color.svg +3 -0
- package/src/assets/icons/underline.svg +4 -0
- package/src/assets/icons/view_access_icon.svg +4 -0
- package/src/components/AppHeader/AppHeader.scss +23 -10
- package/src/components/AppHeader/AppHeader.stories.tsx +29 -28
- package/src/components/AppHeader/AppHeader.tsx +18 -16
- package/src/components/AppHeader/types.ts +7 -7
- package/src/components/Button/Button.scss +1 -0
- package/src/components/Checkbox/Checkbox.tsx +1 -1
- package/src/components/Drawer/Drawer.scss +13 -9
- package/src/components/Drawer/Drawer.stories.tsx +28 -0
- package/src/components/Drawer/Drawer.tsx +29 -6
- package/src/components/Drawer/Types.ts +11 -0
- package/src/components/ExcelFile/ChangeExcelStyles.tsx +78 -0
- package/src/components/ExcelFile/ColorBarselector/ColorBarSelector.scss +13 -0
- package/src/components/ExcelFile/ColorBarselector/ColorBarSelector.tsx +43 -0
- package/src/components/ExcelFile/ContextMenu/ContextMenu.scss +102 -0
- package/src/components/ExcelFile/ContextMenu/ContextMenu.tsx +104 -0
- package/src/components/ExcelFile/ExcelFile/Excel/ActiveCell.tsx +131 -0
- package/src/components/ExcelFile/ExcelFile/Excel/Cell.tsx +201 -0
- package/src/components/ExcelFile/ExcelFile/Excel/ColumnIndicator.tsx +123 -0
- package/src/components/ExcelFile/ExcelFile/Excel/Copied.tsx +25 -0
- package/src/components/ExcelFile/ExcelFile/Excel/CornerIndicator.tsx +49 -0
- package/src/components/ExcelFile/ExcelFile/Excel/DataEditor.tsx +37 -0
- package/src/components/ExcelFile/ExcelFile/Excel/DataViewer.tsx +46 -0
- package/src/components/ExcelFile/ExcelFile/Excel/FloatingRect.tsx +31 -0
- package/src/components/ExcelFile/ExcelFile/Excel/HeaderRow.tsx +5 -0
- package/src/components/ExcelFile/ExcelFile/Excel/Row.tsx +5 -0
- package/src/components/ExcelFile/ExcelFile/Excel/RowIndicator.tsx +102 -0
- package/src/components/ExcelFile/ExcelFile/Excel/Selected.tsx +32 -0
- package/src/components/ExcelFile/ExcelFile/Excel/Spreadsheet.css +144 -0
- package/src/components/ExcelFile/ExcelFile/Excel/Spreadsheet.tsx +494 -0
- package/src/components/ExcelFile/ExcelFile/Excel/Table.tsx +19 -0
- package/src/components/ExcelFile/ExcelFile/Excel/actions.ts +302 -0
- package/src/components/ExcelFile/ExcelFile/Excel/areModelsEqual.ts +18 -0
- package/src/components/ExcelFile/ExcelFile/Excel/context.ts +12 -0
- package/src/components/ExcelFile/ExcelFile/Excel/engine/engine.ts +200 -0
- package/src/components/ExcelFile/ExcelFile/Excel/engine/formula.ts +137 -0
- package/src/components/ExcelFile/ExcelFile/Excel/engine/index.ts +2 -0
- package/src/components/ExcelFile/ExcelFile/Excel/engine/point-graph.ts +154 -0
- package/src/components/ExcelFile/ExcelFile/Excel/engine/point-hash.ts +10 -0
- package/src/components/ExcelFile/ExcelFile/Excel/engine/point-set.ts +69 -0
- package/src/components/ExcelFile/ExcelFile/Excel/index.ts +48 -0
- package/src/components/ExcelFile/ExcelFile/Excel/matrix.ts +388 -0
- package/src/components/ExcelFile/ExcelFile/Excel/point-range.ts +82 -0
- package/src/components/ExcelFile/ExcelFile/Excel/point.ts +15 -0
- package/src/components/ExcelFile/ExcelFile/Excel/reducer.ts +682 -0
- package/src/components/ExcelFile/ExcelFile/Excel/selection.ts +257 -0
- package/src/components/ExcelFile/ExcelFile/Excel/types.ts +269 -0
- package/src/components/ExcelFile/ExcelFile/Excel/typings/fast-formula-parser.d.ts +58 -0
- package/src/components/ExcelFile/ExcelFile/Excel/use-dispatch.ts +8 -0
- package/src/components/ExcelFile/ExcelFile/Excel/use-selector.ts +9 -0
- package/src/components/ExcelFile/ExcelFile/Excel/util.ts +173 -0
- package/src/components/ExcelFile/ExcelFile/ExcelFile.scss +27 -0
- package/src/components/ExcelFile/ExcelFile/ExcelFile.tsx +520 -0
- package/src/components/ExcelFile/ExcelFile.stories.tsx +132 -0
- package/src/components/ExcelFile/ExcelSheetBar/ExcelSheetBar.scss +16 -0
- package/src/components/ExcelFile/ExcelSheetBar/ExcelSheetBar.tsx +79 -0
- package/src/components/ExcelFile/ExcelToolBar/ExcelToolBar.scss +22 -0
- package/src/components/ExcelFile/ExcelToolBar/ExcelToolBar.tsx +271 -0
- package/src/components/ExcelFile/ImportExcelStyles.tsx +86 -0
- package/src/components/ExcelFile/Types.ts +241 -0
- package/src/components/ExcelFile/index.ts +1 -0
- package/src/components/Icon/Icon.stories.tsx +27 -0
- package/src/components/Icon/Icon.tsx +5 -1
- package/src/components/Icon/Icons.scss +15 -5
- package/src/components/Icon/iconList.ts +52 -1
- package/src/components/Icon/types.ts +1 -0
- package/src/components/IconRadioGroup/IconRadioGroup.scss +60 -0
- package/src/components/IconRadioGroup/IconRadioGroup.stories.tsx +108 -0
- package/src/components/IconRadioGroup/IconRadioGroup.tsx +72 -0
- package/src/components/IconRadioGroup/index.ts +1 -0
- package/src/components/IconRadioGroup/type.ts +50 -0
- package/src/components/Modal/Modal.tsx +8 -1
- package/src/components/Modal/modal.scss +10 -2
- package/src/components/Table/Table.scss +16 -4
- package/src/components/Table/Table.stories.tsx +36 -12
- package/src/components/Table/Table.tsx +33 -16
- package/src/components/Table/Types.ts +121 -105
- 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
|
+
}
|