@trebco/treb 26.0.6 → 27.0.1

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 (50) hide show
  1. package/dist/treb-spreadsheet.mjs +14 -14
  2. package/dist/treb.d.ts +150 -337
  3. package/esbuild-utils.mjs +1 -1
  4. package/package.json +3 -3
  5. package/treb-base-types/src/cell.ts +3 -3
  6. package/treb-base-types/src/cells.ts +33 -15
  7. package/treb-base-types/src/color.ts +21 -21
  8. package/treb-base-types/src/import.ts +2 -2
  9. package/treb-base-types/src/style.ts +150 -288
  10. package/treb-base-types/src/table.ts +3 -2
  11. package/treb-base-types/src/theme.ts +18 -18
  12. package/treb-base-types/src/value-type.ts +20 -1
  13. package/treb-calculator/src/calculator.ts +4 -4
  14. package/treb-calculator/src/functions/checkbox.ts +8 -8
  15. package/treb-calculator/src/functions/sparkline.ts +25 -25
  16. package/treb-charts/style/charts.scss +8 -1
  17. package/treb-embed/src/custom-element/spreadsheet-constructor.ts +10 -10
  18. package/treb-embed/src/embedded-spreadsheet.ts +15 -15
  19. package/treb-embed/src/selection-state.ts +2 -2
  20. package/treb-embed/src/toolbar-message.ts +3 -3
  21. package/treb-embed/src/types.ts +4 -4
  22. package/treb-embed/style/autocomplete.scss +1 -1
  23. package/treb-embed/style/dialog.scss +1 -1
  24. package/treb-embed/style/dropdown-select.scss +1 -1
  25. package/treb-embed/style/formula-bar.scss +1 -1
  26. package/treb-embed/style/grid.scss +1 -1
  27. package/treb-embed/style/layout.scss +13 -2
  28. package/treb-embed/style/mouse-mask.scss +1 -1
  29. package/treb-embed/style/note.scss +1 -1
  30. package/treb-embed/style/overlay-editor.scss +1 -1
  31. package/treb-embed/style/spinner.scss +1 -1
  32. package/treb-embed/style/tab-bar.scss +1 -1
  33. package/treb-embed/style/table.scss +1 -1
  34. package/treb-embed/style/theme-defaults.scss +1 -1
  35. package/treb-embed/style/toolbar.scss +1 -1
  36. package/treb-embed/style/tooltip.scss +1 -1
  37. package/treb-embed/style/treb-icons.scss +1 -1
  38. package/treb-export/src/export2.ts +6 -6
  39. package/treb-export/src/workbook-style2.ts +19 -19
  40. package/treb-grid/src/editors/overlay_editor.ts +4 -4
  41. package/treb-grid/src/render/tile_renderer.ts +15 -14
  42. package/treb-grid/src/types/annotation.ts +9 -6
  43. package/treb-grid/src/types/clipboard_data.ts +2 -2
  44. package/treb-grid/src/types/data_model.ts +2 -2
  45. package/treb-grid/src/types/grid.ts +9 -7
  46. package/treb-grid/src/types/grid_base.ts +9 -9
  47. package/treb-grid/src/types/grid_command.ts +3 -3
  48. package/treb-grid/src/types/grid_selection.ts +26 -1
  49. package/treb-grid/src/types/sheet.ts +66 -63
  50. package/treb-grid/src/types/sheet_types.ts +17 -10
@@ -19,189 +19,160 @@
19
19
  *
20
20
  */
21
21
 
22
- // why is this a namespace? module is implicit... it's because of how
23
- // base types exports; we can't export * as Style, so we're stuck with
24
- // the namespace (or you could add an intermediate file and import ->
25
- // export, but that just seems like unecessary complexity and still kludgy).
22
+ const empty_json = JSON.stringify({}); // we could probably hard-code this
26
23
 
27
- // eslint-disable-next-line @typescript-eslint/no-namespace
28
- export namespace Style {
24
+ /** horizontal align constants for cell style */
25
+ export type HorizontalAlign = '' | 'left' | 'center' | 'right';
29
26
 
30
- const empty_json = JSON.stringify({}); // we could probably hard-code this
27
+ /** vertical align constants for cell style */
28
+ export type VerticalAlign = '' | 'top' | 'bottom' | 'middle';
31
29
 
32
- /**
33
- * horizontal align constants
34
- */
35
- export enum HorizontalAlign {
36
- None = '',
37
- Left = 'left',
38
- Center = 'center',
39
- Right = 'right',
40
- }
41
-
42
- /**
43
- * vertical align constants
44
- *
45
- * @privateRemarks
46
- *
47
- * horizontal alignment was (none), left, center, right.
48
- * vertical aligment was (none), top, bottom, middle.
49
- *
50
- * not sure why these were not symmetrical, but having strings makes it
51
- * easier to manage.
52
- */
53
- export enum VerticalAlign {
54
- None = '',
55
- Top = 'top',
56
- Bottom = 'bottom',
57
- Middle = 'middle',
58
- }
59
-
60
- /** composite font size */
61
- export interface FontSize {
62
- unit: 'pt'|'px'|'em'|'%';
63
- value: number;
64
- }
65
-
66
- /**
67
- * color is either a theme color (theme index plus tint), or CSS text
68
- *
69
- * @privateRemarks
70
- *
71
- * FIXME: this should be a union type
72
- */
73
- export interface Color {
74
-
75
- theme?: number;
76
- tint?: number;
77
- text?: string;
30
+ /**
31
+ * font size for cell style. we generally prefer relative sizes
32
+ * (percent or em) because they are relative to the default theme
33
+ * size, which might be different on different platforms.
34
+ */
35
+ export interface FontSize {
36
+ unit: 'pt'|'px'|'em'|'%';
37
+ value: number;
38
+ }
78
39
 
79
- /** @internal */
80
- offset?: Color;
40
+ /**
41
+ * color for cell style. color is used for foreground, background and
42
+ * borders in the cell style. can be either a theme color (theme index
43
+ * plus tint), or CSS text.
44
+ *
45
+ * @privateRemarks
46
+ * FIXME: this should be a union type. we do a lot of if switching anyway.
47
+ */
48
+ export interface Color {
81
49
 
82
- /** @deprecated */
83
- none?: boolean;
84
- }
50
+ theme?: number;
51
+ tint?: number;
52
+ text?: string;
85
53
 
86
54
  /** @internal */
87
- export interface CompositeBorderEdge {
88
- width: number;
89
- color: Color;
90
- }
55
+ offset?: Color;
91
56
 
92
- /** @internal */
93
- export interface CompositeBorder {
94
- top: CompositeBorderEdge,
95
- left: CompositeBorderEdge,
96
- right: CompositeBorderEdge,
97
- bottom: CompositeBorderEdge,
98
- }
99
-
100
- /**
101
- * style properties applied to a cell.
102
- */
103
- export interface Properties {
104
-
105
- /** horizontal align defaults to left */
106
- horizontal_align?: HorizontalAlign;
107
-
108
- /** vertical align defaults to bottom */
109
- vertical_align?: VerticalAlign;
57
+ /** @deprecated */
58
+ none?: boolean;
59
+ }
110
60
 
111
- /** representation for NaN */
112
- nan?: string;
61
+ /** @internal */
62
+ export interface CompositeBorderEdge {
63
+ width: number;
64
+ color: Color;
65
+ }
113
66
 
114
- /** number format, either a symbolic name like "General" or a format string */
115
- number_format?: string;
67
+ /** @internal */
68
+ export interface CompositeBorder {
69
+ top: CompositeBorderEdge,
70
+ left: CompositeBorderEdge,
71
+ right: CompositeBorderEdge,
72
+ bottom: CompositeBorderEdge,
73
+ }
116
74
 
117
- /** wrap text */
118
- wrap?: boolean;
119
75
 
120
- /**
121
- * font size. we recommend using relative font sizes (either % or em)
122
- * which will be relative to the theme font size.
123
- */
124
- font_size?: FontSize;
76
+ /**
77
+ * style properties applied to a single cell, row, column, or sheet.
78
+ * when rendering a cell, we composite all styles that might apply.
79
+ */
80
+ export interface CellStyle {
125
81
 
126
- /** font face. this can be a comma-delimited list, like CSS */
127
- font_face?: string;
82
+ /** horizontal align defaults to left */
83
+ horizontal_align?: HorizontalAlign;
128
84
 
129
- /** flag */
130
- bold?: boolean; // FIXME: switch to weight
85
+ /** vertical align defaults to bottom */
86
+ vertical_align?: VerticalAlign;
131
87
 
132
- /** flag */
133
- italic?: boolean;
88
+ /** representation for NaN */
89
+ nan?: string;
134
90
 
135
- /** flag */
136
- underline?: boolean;
91
+ /** number format, either a symbolic name like "General" or a format string */
92
+ number_format?: string;
137
93
 
138
- /** flag */
139
- strike?: boolean;
94
+ /** wrap text */
95
+ wrap?: boolean;
140
96
 
141
- // font_weight?: number;
142
-
143
- /** border weight */
144
- border_top?: number;
97
+ /**
98
+ * font size. we recommend using relative font sizes (either % or em)
99
+ * which will be relative to the theme font size.
100
+ */
101
+ font_size?: FontSize;
145
102
 
146
- /** border weight */
147
- border_right?: number;
103
+ /** font face. this can be a comma-delimited list, like CSS */
104
+ font_face?: string;
148
105
 
149
- /** border weight */
150
- border_left?: number;
106
+ /** flag */
107
+ bold?: boolean; // FIXME: switch to weight
151
108
 
152
- /** border weight */
153
- border_bottom?: number;
109
+ /** flag */
110
+ italic?: boolean;
154
111
 
155
- // COLORS. there's a new thing with colors where we need to
156
- // be able to clear them, in a merge operation. these should
157
- // perhaps be an object, but for the time being for colors,
158
- // "" in a merge means "remove this property".
112
+ /** flag */
113
+ underline?: boolean;
159
114
 
160
- // background?: string;
161
- // text_color?: string;
162
-
163
- //border_top_color?: string;
164
- //border_left_color?: string;
165
- //border_right_color?: string;
166
- //border_bottom_color?: string;
115
+ /** flag */
116
+ strike?: boolean;
117
+
118
+ /** border weight */
119
+ border_top?: number;
167
120
 
168
- // changing colors to support styles... starting with text
121
+ /** border weight */
122
+ border_right?: number;
169
123
 
170
- /** text color */
171
- text?: Color;
124
+ /** border weight */
125
+ border_left?: number;
172
126
 
173
- /** background color */
174
- fill?: Color;
127
+ /** border weight */
128
+ border_bottom?: number;
175
129
 
176
- /** border color */
177
- border_top_fill?: Color;
130
+ /** text color */
131
+ text?: Color;
178
132
 
179
- /** border color */
180
- border_left_fill?: Color;
133
+ /** background color */
134
+ fill?: Color;
181
135
 
182
- /** border color */
183
- border_right_fill?: Color;
136
+ /** border color */
137
+ border_top_fill?: Color;
184
138
 
185
- /** border color */
186
- border_bottom_fill?: Color;
139
+ /** border color */
140
+ border_left_fill?: Color;
187
141
 
188
- // NEW
189
- // FIXME: change name to editable, default true? (...)
142
+ /** border color */
143
+ border_right_fill?: Color;
190
144
 
191
- // this is not properly in style -- should be in cell
145
+ /** border color */
146
+ border_bottom_fill?: Color;
192
147
 
193
- // UPDATE: whether it's appropriate or not, style is a better place
194
- // because it can cascade
148
+ /**
149
+ * cell is locked for editing
150
+ *
151
+ * @privateRemarks
152
+ *
153
+ * this should properly be in cell, not style -- but we keep
154
+ * it here so it can cascade like other styles.
155
+ *
156
+ */
157
+ locked?: boolean;
195
158
 
196
- /**
197
- * cell is locked for editing
198
- */
199
- locked?: boolean;
159
+ }
200
160
 
201
- }
161
+ /** @internal */
162
+ export type PropertyKeys = keyof CellStyle;
202
163
 
203
- /** @internal */
204
- export type PropertyKeys = keyof Style.Properties;
164
+ /**
165
+ * (finally) removing the old namespace. we keep this object around for
166
+ * some internal methods, but all the types have moved to the top-level
167
+ * of this module and need to be imported separately.
168
+ *
169
+ * we could theoretically build a backcompat module that re-exports all
170
+ * the types, but it's probably not necessary -- most updates will just
171
+ * require a find-and-replace (plus adding some imports).
172
+ *
173
+ * @internal
174
+ */
175
+ export const Style = {
205
176
 
206
177
  /**
207
178
  * note that there are no default colors; those should be set
@@ -211,47 +182,29 @@ export namespace Style {
211
182
  *
212
183
  * @internal
213
184
  */
214
- export const DefaultProperties: Properties = {
215
- horizontal_align: HorizontalAlign.None,
216
- vertical_align: VerticalAlign.None,
185
+ DefaultProperties: {
186
+
187
+ horizontal_align: '',
188
+ vertical_align: '',
217
189
  number_format: 'General', // '0.######', // use symbolic, e.g. "general"
218
190
  nan: 'NaN',
219
- // font_size: 10, // should have units
220
191
 
221
192
  font_size: { unit: 'pt', value: 10.5 },
222
193
  font_face: 'sans-serif',
223
194
 
224
- /*
225
- // font_size_value: 10,
226
- // font_size_unit: 'pt',
227
- font_size: {
228
- unit: 'em', value: 1,
229
- },
230
-
231
- font_face: 'times new roman', // switch to something generic "sans serif"
232
- */
233
-
234
195
  bold: false, // drop "font_"
235
196
  italic: false, // ...
236
197
  underline: false, // ...
237
198
  strike: false, //
238
- // background: 'none',
239
199
 
240
- // text_color: 'none',
241
- // text: 'theme',
242
- // text_theme: 0,
243
200
  text: { theme: 1 },
244
-
245
- // border_top_color: 'none',
246
- // border_left_color: 'none',
247
- // border_right_color: 'none',
248
- // border_bottom_color: 'none',
249
201
 
250
202
  border_top: 0, // adding defaults so these prune propery
251
203
  border_left: 0,
252
204
  border_right: 0,
253
205
  border_bottom: 0,
254
- };
206
+
207
+ } as CellStyle,
255
208
 
256
209
  /**
257
210
  * this is a utility function for callers that use borders, to
@@ -259,7 +212,7 @@ export namespace Style {
259
212
  *
260
213
  * @internal
261
214
  */
262
- export const CompositeBorders = (style: Properties): CompositeBorder => {
215
+ CompositeBorders: (style: CellStyle): CompositeBorder => {
263
216
  return {
264
217
  top: {
265
218
  width: style.border_top || 0,
@@ -278,17 +231,7 @@ export namespace Style {
278
231
  color: style.border_bottom_fill || {},
279
232
  },
280
233
  };
281
- };
282
-
283
- /* *
284
- * this version of merge is used to support explicit deletes, via
285
- * "undefined" properties. we use a trick via JSON to skip iterating
286
- * properties (I believe this is faster, but have not tested).
287
- * /
288
- export const Merge2 = (dest: Properties, src: Properties): Properties => {
289
- return JSON.parse(JSON.stringify({...dest, ...src}));
290
- }
291
- */
234
+ },
292
235
 
293
236
  /**
294
237
  * merge. returns a new object, does not update dest in place.
@@ -297,80 +240,33 @@ export namespace Style {
297
240
  *
298
241
  * @internal
299
242
  */
300
- export const Merge = (dest: Properties, src: Properties, delta = true): Properties => {
301
- const properties: Properties = delta ? {...dest, ...src} : {...src};
243
+ Merge: (dest: CellStyle, src: CellStyle, delta = true): CellStyle => {
244
+ const properties: CellStyle = delta ? {...dest, ...src} : {...src};
302
245
  return JSON.parse(JSON.stringify(properties));
303
- };
246
+ },
304
247
 
305
248
  /** @internal */
306
- export const Composite = (list: Properties[]): Properties => {
249
+ Composite: (list: CellStyle[]): CellStyle => {
307
250
  return JSON.parse(JSON.stringify(list.reduce((composite, item) => ({...composite, ...item}), {})));
308
- };
251
+ },
309
252
 
310
253
  /** @internal */
311
- export const Empty = (style: Properties): boolean => {
254
+ Empty: (style: CellStyle): boolean => {
312
255
  return JSON.stringify(style) === empty_json;
313
- };
256
+ },
314
257
 
315
- /** @internal */
316
- export const ValidColor = (color?: Color): boolean => {
258
+ /**
259
+ * this looks like a type guard, we should switch to a union
260
+ * type and then add real type guards
261
+ *
262
+ * @internal
263
+ */
264
+ ValidColor: (color?: Color): boolean => {
317
265
  return !!(color && (!color.none) && (color.text || color.theme || color.theme === 0));
318
- };
319
-
320
- /*
321
- export const Prune = (style: Properties): void => {
322
-
323
- // text default is theme 0, so we can remove that if we see it.
324
- // same for borders, we can group
325
-
326
- if (style.text && !style.text.text && !style.text.theme) {
327
- style.text = undefined;
328
- }
329
-
330
- if (style.border_top_fill && !style.border_top_fill.text && !style.border_top_fill.theme) {
331
- style.border_top_fill = undefined;
332
- }
333
-
334
- if (style.border_left_fill && !style.border_left_fill.text && !style.border_left_fill.theme) {
335
- style.border_left_fill = undefined;
336
- }
337
-
338
- if (style.border_right_fill && !style.border_right_fill.text && !style.border_right_fill.theme) {
339
- style.border_right_fill = undefined;
340
- }
341
-
342
- if (style.border_bottom_fill && !style.border_bottom_fill.text && !style.border_bottom_fill.theme) {
343
- style.border_bottom_fill = undefined;
344
- }
345
-
346
- // background has no default, so check for 0
347
- if (style.fill && !style.fill.text && !style.fill.theme && style.fill.theme !== 0) {
348
- style.fill = undefined;
349
- }
350
-
351
- };
352
- */
353
-
354
- /* *
355
- * overlay. will always put defaults at the bottom.
356
- * /
357
- export const Composite = (list: Properties[]) => {
358
- return list.reduce((composite, item) => ({...composite, ...item}),
359
- {...DefaultProperties});
360
- };
361
-
362
- / * *
363
- * modify default properties. useful for theming.
364
- * /
365
- export const UpdateDefaultProperties = (opts: Properties) => {
366
- DefaultProperties = {
367
- ...DefaultProperties, ...opts,
368
- };
369
- };
370
- */
266
+ },
371
267
 
372
268
  /** @internal */
373
- export const ParseFontSize = (text = '', default_unit = 'em'): Properties => {
269
+ ParseFontSize: (text = '', default_unit = 'em'): CellStyle => {
374
270
  const match = text.match(/(-*[\d.]+)\s*(\S*)/);
375
271
 
376
272
  if (match) {
@@ -388,7 +284,7 @@ export namespace Style {
388
284
  }
389
285
 
390
286
  return {};
391
- };
287
+ },
392
288
 
393
289
  /**
394
290
  * returns the font size of the properties argument as a ratio of the
@@ -405,7 +301,7 @@ export namespace Style {
405
301
  *
406
302
  * @internal
407
303
  */
408
- export const RelativeFontSize = (properties: Properties, base: Properties): number => {
304
+ RelativeFontSize: (properties: CellStyle, base: CellStyle): number => {
409
305
 
410
306
  // we can assume (I think) that base will be either points or px;
411
307
  // there's no case where it should be relative. in fact, let's treat
@@ -455,10 +351,10 @@ export namespace Style {
455
351
 
456
352
  return props_pt / base_pt;
457
353
 
458
- };
354
+ },
459
355
 
460
356
  /** @internal */
461
- export const FontSize = (properties: Properties, prefer_points = true): string => {
357
+ FontSize: (properties: CellStyle, prefer_points = true): string => {
462
358
 
463
359
  const value = properties.font_size?.value;
464
360
 
@@ -482,34 +378,15 @@ export namespace Style {
482
378
  }
483
379
 
484
380
  return '';
485
- };
381
+ },
486
382
 
487
383
  /**
488
384
  * returns a string representation suitable for canvas (or style)
489
- *
490
- * @internal
491
385
  */
492
- export const Font = (properties: Properties, scale = 1) => {
493
-
494
- /*
495
- let font_size = properties.font_size;
496
- if (typeof font_size === 'number') {
497
- font_size = (font_size * scale) + 'pt';
498
- }
499
- else if (font_size && scale !== 1) {
500
- const font_parts = font_size.match(/^([\d\.]+)(\D*)$/);
501
- if (font_parts) {
502
- font_size = (Number(font_parts[1]) * scale) + font_parts[2];
503
- }
504
- }
505
- */
386
+ Font: (properties: CellStyle, scale = 1) => {
506
387
 
507
388
  const parts: string[] = [];
508
389
 
509
- //if (properties.font_weight) {
510
- // parts.push(properties.font_weight.toString());
511
- //}
512
- //else
513
390
  if (properties.bold) {
514
391
  parts.push('bold');
515
392
  }
@@ -524,22 +401,7 @@ export namespace Style {
524
401
  parts.push(properties.font_face || '');
525
402
 
526
403
  return parts.join(' ');
527
-
528
- /*
529
- // console.info("FS", font_size);
530
-
531
- if (properties.font_weight) {
532
- return (properties.font_weight + ' ')
533
- + (properties.font_italic ? 'italic ' : '')
534
- + font_size + ' ' + properties.font_face;
535
- }
536
- else {
537
- return (properties.font_bold ? 'bold ' : '')
538
- + (properties.font_italic ? 'italic ' : '')
539
- + font_size + ' ' + properties.font_face;
540
- }
541
- */
542
404
 
543
- };
405
+ },
544
406
 
545
- }
407
+ };
@@ -95,11 +95,12 @@ export interface Table {
95
95
  * (not meaning difficult). we may keep track of the last sort so we
96
96
  * can toggle asc/desc, for example. atm this will not survive serialization.
97
97
  */
98
- sort?: {
98
+ sort?: TableSortOptions;
99
+ /* {
99
100
  column: number;
100
101
  type: TableSortType;
101
102
  asc: boolean;
102
- }
103
+ } */
103
104
 
104
105
  }
105
106