@trebco/treb 31.7.8 → 31.9.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.
package/dist/treb.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- /*! API v31.7. Copyright 2018-2024 trebco, llc. All rights reserved. LGPL: https://treb.app/license */
1
+ /*! API v31.9. Copyright 2018-2024 trebco, llc. All rights reserved. LGPL: https://treb.app/license */
2
2
 
3
3
  /**
4
4
  * add our tag to the map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trebco/treb",
3
- "version": "31.7.8",
3
+ "version": "31.9.1",
4
4
  "license": "LGPL-3.0-or-later",
5
5
  "homepage": "https://treb.app",
6
6
  "repository": {
@@ -16,7 +16,7 @@
16
16
  "@types/uzip": "^0.20201231.0",
17
17
  "base64-js": "^1.5.1",
18
18
  "cssnano": "^7.0.4",
19
- "esbuild": "^0.23.1",
19
+ "esbuild": "^0.24.0",
20
20
  "eslint": "^9.9.1",
21
21
  "fast-xml-parser": "^4.0.7",
22
22
  "html-minifier-terser": "^7.2.0",
@@ -201,7 +201,7 @@ export interface AnnotationTextBoxData extends AnnotationDataBase {
201
201
  style?: CellStyle,
202
202
  content: {
203
203
  text: string,
204
- style?: CellStyle
204
+ style?: CellStyle ,
205
205
  }[],
206
206
  }[];
207
207
  };
@@ -98,6 +98,11 @@
98
98
  <div class="treb-color-chooser">
99
99
  <div class="treb-caption">Theme colors</div>
100
100
  <div class="treb-swatches"></div>
101
+ <div class="treb-caption">No color</div>
102
+ <div class="treb-default-swatch">
103
+ <button class="treb-default-color" data-command="set-color" data-color="{}"></button>
104
+ <span class="treb-default-color-label" data-command="set-color" data-color="{}">...</span>
105
+ </div>
101
106
  <div class="treb-caption">Other colors</div>
102
107
  <div class="treb-swatches"></div>
103
108
  <div>
@@ -778,12 +778,15 @@ export class SpreadsheetConstructor<USER_DATA_TYPE = unknown> {
778
778
  this.swatch_lists.theme?.replaceChildren(fragment);
779
779
 
780
780
  fragment = this.DOM.Fragment();
781
+
782
+ /*
781
783
  this.DOM.Create('button', 'treb-default-color', fragment, {
782
784
  attrs: { title: 'Default color' },
783
785
  data: { command: 'set-color', color: JSON.stringify({}) },
784
786
  });
787
+ */
785
788
 
786
- const colors = ['Black', 'White', 'Gray', 'Red', 'Orange', 'Yellow', 'Green', 'Blue', 'Violet'];
789
+ const colors = ['Black', 'White', 'Gray', 'Red', 'Orange', 'Yellow', 'Green', 'Blue', 'Indigo', 'Violet'];
787
790
 
788
791
  const lc = colors.map(color => color.toLowerCase());
789
792
  const additional_colors = sheet.document_styles.colors.filter(test => {
@@ -1320,6 +1323,10 @@ export class SpreadsheetConstructor<USER_DATA_TYPE = unknown> {
1320
1323
 
1321
1324
  if (parent.dataset.colorCommand) {
1322
1325
  color_chooser.querySelector('.treb-default-color')?.setAttribute('title', parent.dataset.defaultColorText || 'Default color');
1326
+ const label = color_chooser.querySelector('.treb-default-color-label');
1327
+ if (label) {
1328
+ label.textContent = parent.dataset.defaultColorText || 'Default color';
1329
+ }
1323
1330
 
1324
1331
  parent.appendChild(color_chooser);
1325
1332
  color_chooser.dataset.colorCommand = parent.dataset.colorCommand;
@@ -76,7 +76,8 @@ import type {
76
76
 
77
77
  import {
78
78
  IsArea, ThemeColorTable, ComplexToString, Rectangle, IsComplex, type CellStyle,
79
- Localization, Style, type Color, ResolveThemeColor, IsCellAddress, Area, IsFlatData, IsFlatDataArray, Gradient, DOMContext
79
+ Localization, Style, type Color, ResolveThemeColor, IsCellAddress, Area, IsFlatData, IsFlatDataArray, Gradient, DOMContext,
80
+ ValueType,
80
81
  } from 'treb-base-types';
81
82
 
82
83
  import { EventSource, ValidateURI } from 'treb-utils';
@@ -5209,13 +5210,8 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
5209
5210
  // now we have to inflate them on sheet change
5210
5211
 
5211
5212
  for (const annotation of event.activate.annotations) {
5212
- // if (annotation.update_callback) {
5213
- // annotation.update_callback();
5214
- // }
5215
-
5216
5213
  this.InflateAnnotation(annotation);
5217
5214
  this.calculator.UpdateAnnotations(annotation, event.activate);
5218
-
5219
5215
  }
5220
5216
 
5221
5217
  // we also need to update annotations that are already inflated
@@ -5529,21 +5525,9 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
5529
5525
  if (view) {
5530
5526
  view.dirty = true;
5531
5527
  }
5532
- // else {
5533
- // console.info("empty view")
5534
- // }
5535
5528
 
5536
5529
  }
5537
5530
  }
5538
-
5539
- /*
5540
- const view: AnnotationViewData = annotation.view[this.grid.view_index] || {};
5541
- if (view.update_callback) {
5542
- view.update_callback();
5543
- }
5544
-
5545
- this.grid.AnnotationUpdated(annotation);
5546
- */
5547
5531
  }
5548
5532
 
5549
5533
  const view: AnnotationViewData = annotation.view[this.grid.view_index] || {};
@@ -5670,19 +5654,11 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
5670
5654
 
5671
5655
  if (annotation.data.type === 'treb-chart') {
5672
5656
 
5673
- // if (!(self as any).TREB || !(self as any).TREB.CreateChart2) {
5674
- // console.warn('missing chart library');
5675
- // }
5676
- // else
5677
5657
  {
5678
5658
 
5679
5659
  const chart = this.CreateChart();
5680
5660
  chart.Initialize(view.content_node);
5681
5661
 
5682
- //if (this.calculator.RegisterLibrary('treb-charts', ChartFunctions)) {
5683
- // this.UpdateAC();
5684
- //}
5685
-
5686
5662
  const update_chart = () => {
5687
5663
 
5688
5664
  if (annotation.data.formula) {
@@ -5766,11 +5742,21 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
5766
5742
  else if (annotation.data.type === 'textbox') {
5767
5743
 
5768
5744
  if (annotation.data.data) {
5745
+
5746
+ let target: HTMLElement|undefined;
5747
+
5769
5748
  const container = document.createElement('div');
5770
5749
  container.classList.add('treb-annotation-textbox');
5771
5750
 
5772
5751
  for (const paragraph of annotation.data.data.paragraphs) {
5773
5752
  const p = document.createElement('p');
5753
+
5754
+ // FIXME: styling should move (to layout?) so we can
5755
+ // update it. possibly content as well? although we
5756
+ // can leave the formula in here, I guess.
5757
+ //
5758
+ // how about we move styling to the update routine?
5759
+
5774
5760
  if (paragraph.style) {
5775
5761
  if (paragraph.style.horizontal_align === 'right' ||
5776
5762
  paragraph.style.horizontal_align === 'center') {
@@ -5779,17 +5765,36 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
5779
5765
  }
5780
5766
 
5781
5767
  for (const entry of paragraph.content) {
5768
+
5782
5769
  const span = document.createElement('span');
5783
- span.textContent = entry.text || '';
5770
+
5771
+ if (!target) { target = span; }
5772
+
5773
+ if (!annotation.data.formula) {
5774
+ span.textContent = entry.text || '';
5775
+ }
5776
+
5784
5777
  if (entry.style?.bold) {
5785
5778
  span.style.fontWeight = '600';
5786
5779
  }
5780
+
5787
5781
  if (entry.style?.italic) {
5788
5782
  span.style.fontStyle = 'italic';
5789
5783
  }
5784
+
5790
5785
  p.appendChild(span);
5786
+
5787
+ if (annotation.data.formula) {
5788
+ break; // only one text node allowed for formula (?)
5789
+ }
5790
+
5791
5791
  }
5792
5792
  container.append(p);
5793
+
5794
+ if (annotation.data.formula) {
5795
+ break; // only one text node allowed for formula (?)
5796
+ }
5797
+
5793
5798
  }
5794
5799
 
5795
5800
  view.content_node.append(container);
@@ -5807,12 +5812,68 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
5807
5812
  };
5808
5813
 
5809
5814
  view.update_callback = () => {
5815
+
5810
5816
  if (!this.grid.headless) {
5811
5817
  update_textbox();
5812
5818
  }
5819
+
5820
+ if (target && annotation.data.formula) {
5821
+
5822
+ const parse_result = this.parser.Parse(annotation.data.formula);
5823
+ if (parse_result && parse_result.expression) {
5824
+
5825
+ // FIXME: make a method for doing this
5826
+
5827
+ this.parser.Walk(parse_result.expression, (unit) => {
5828
+ if (unit.type === 'address' || unit.type === 'range') {
5829
+ this.model.ResolveSheetID(unit, undefined, this.grid.active_sheet);
5830
+ }
5831
+ return true;
5832
+ });
5833
+
5834
+ const result = this.calculator.CalculateExpression(parse_result.expression);
5835
+
5836
+ let format = NumberFormatCache.Get('General');
5837
+ let source: ICellAddress|undefined;
5838
+ switch (parse_result.expression.type) {
5839
+ case 'address':
5840
+ source = parse_result.expression;
5841
+ break;
5842
+ case 'range':
5843
+ source = parse_result.expression.start;
5844
+ break;
5845
+ }
5846
+
5847
+ if (source) {
5848
+ const sheet = source.sheet_id ? this.model.sheets.Find(source.sheet_id) : this.grid.active_sheet;
5849
+ const style = sheet?.CellStyleData(source);
5850
+ if (style?.number_format) {
5851
+ format = NumberFormatCache.Get(style.number_format);
5852
+ }
5853
+ }
5854
+
5855
+ switch (result.type) {
5856
+ case ValueType.number:
5857
+ case ValueType.string:
5858
+ case ValueType.complex:
5859
+ target.textContent = format.Format(result.value);
5860
+ break;
5861
+
5862
+ default:
5863
+ target.textContent = result.value?.toString() || '';
5864
+ }
5865
+
5866
+
5867
+ // TODO: use reference number format
5868
+
5869
+ }
5870
+
5871
+ }
5872
+
5813
5873
  };
5814
5874
 
5815
- update_textbox();
5875
+ // update_textbox();
5876
+ view.update_callback();
5816
5877
 
5817
5878
  }
5818
5879
 
@@ -19,6 +19,10 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use 'z-index.scss' as *;
23
+ @use 'defaults.scss' as *;
24
+
25
+
22
26
  /**
23
27
  * this is getting attached to the document (why? b/c fixed pos?)
24
28
  * so it inherits a lot. that's not good.
@@ -19,6 +19,9 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use 'z-index.scss' as *;
23
+ @use 'defaults.scss' as *;
24
+
22
25
  .treb-main.treb-main {
23
26
 
24
27
  .treb-dropdown-caret {
@@ -19,6 +19,8 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use './defaults.scss' as *;
23
+
22
24
  //
23
25
  // thanks to
24
26
  // https://modernfontstacks.com/
@@ -21,20 +21,20 @@
21
21
 
22
22
  // sass vars only
23
23
 
24
- @import 'z-index.scss';
25
- @import 'defaults.scss';
24
+ @use 'z-index.scss' as *;
25
+ @use 'defaults.scss' as *;
26
26
 
27
27
  // clean, no imports (but use sass vars)
28
28
 
29
- @import 'mouse-mask.scss';
30
- @import 'note.scss';
31
- @import 'table.scss';
32
- @import 'tooltip.scss';
33
- @import 'dropdown-select.scss';
34
- @import 'autocomplete.scss';
35
- @import 'formula-bar.scss';
36
- @import 'tab-bar.scss';
37
- @import 'overlay-editor.scss';
29
+ @use 'mouse-mask.scss';
30
+ @use 'note.scss';
31
+ @use 'table.scss';
32
+ @use 'tooltip.scss';
33
+ @use 'dropdown-select.scss';
34
+ @use 'autocomplete.scss';
35
+ @use 'formula-bar.scss';
36
+ @use 'tab-bar.scss';
37
+ @use 'overlay-editor.scss';
38
38
 
39
39
  .treb-main.treb-main {
40
40
 
@@ -1,13 +1,16 @@
1
1
 
2
- @import './grid.scss';
3
- @import './theme-defaults.scss';
4
- @import './dark-theme.scss';
5
- @import '../../treb-charts/style/charts.scss';
6
- @import './dialog.scss';
7
- @import './spinner.scss';
8
- @import './treb-icons.scss';
9
- @import './toolbar.scss';
10
- @import './font-stacks.scss';
2
+ @use './defaults.scss' as *;
3
+ @use './z-index.scss' as *;
4
+
5
+ @use './grid.scss';
6
+ @use './theme-defaults.scss';
7
+ @use './dark-theme.scss';
8
+ @use '../../treb-charts/style/charts.scss';
9
+ @use './dialog.scss';
10
+ @use './spinner.scss';
11
+ @use './treb-icons.scss';
12
+ @use './toolbar.scss';
13
+ @use './font-stacks.scss';
11
14
 
12
15
  /*
13
16
  * switching to a double-selector to increase specificity. the particular
@@ -19,6 +19,9 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use 'z-index.scss' as *;
23
+ @use 'defaults.scss' as *;
24
+
22
25
  .treb-main.treb-main {
23
26
 
24
27
  /**
@@ -19,6 +19,10 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use 'z-index.scss' as *;
23
+ @use 'defaults.scss' as *;
24
+
25
+
22
26
  .treb-main.treb-main {
23
27
 
24
28
  // are these exactly the same? clearly we copied-and-pasted
@@ -19,6 +19,9 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use 'z-index.scss' as *;
23
+ @use 'defaults.scss' as *;
24
+
22
25
  .treb-main.treb-main {
23
26
 
24
27
  .treb-grid {
@@ -19,6 +19,10 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use 'z-index.scss' as *;
23
+ @use 'defaults.scss' as *;
24
+
25
+
22
26
  .treb-main.treb-main {
23
27
 
24
28
  .treb-mouse-mask .ghost-tab {
@@ -19,6 +19,9 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use 'z-index.scss' as *;
23
+ @use 'defaults.scss' as *;
24
+
22
25
  .treb-main.treb-main {
23
26
 
24
27
  .treb-sort-button {
@@ -19,6 +19,8 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use './defaults.scss' as *;
23
+
22
24
  /**
23
25
  * we're using variables for selection colors because the colors are used
24
26
  * in more than one place; that's a drawback of using CSS, but I think overall
@@ -356,12 +358,12 @@ $text-reference-color-5: rgb(254, 47, 1);
356
358
  .selection {
357
359
  stroke-width: var(--treb-selection-stroke-width, 2px);
358
360
 
359
- .outline {
361
+ .treb-selection-outline {
360
362
  stroke: currentColor;
361
363
  fill: none;
362
364
  }
363
365
 
364
- .fill {
366
+ .treb-selection-fill {
365
367
  stroke: none;
366
368
  fill: currentColor;
367
369
  opacity: var(--treb-selection-fill-opacity, .1);
@@ -405,7 +407,7 @@ $text-reference-color-5: rgb(254, 47, 1);
405
407
  .primary-selection {
406
408
  color: var(--treb-selection-color-unfocused, var(--treb-selection-color, $primary-selection-color));
407
409
 
408
- .nub {
410
+ .treb-selection-nub {
409
411
  stroke: #fff; // <-- ? maybe grid background color?
410
412
  fill: currentColor;
411
413
  stroke-width: 1px;
@@ -367,11 +367,7 @@ $swatch-size: 18px;
367
367
 
368
368
  }
369
369
 
370
- .treb-swatches {
371
-
372
- display: grid;
373
- grid-template-columns: repeat(10, 1fr);
374
- gap: .5rem;
370
+ .treb-swatches, .treb-default-swatch {
375
371
 
376
372
  button {
377
373
  width: $swatch-size;
@@ -399,6 +395,22 @@ $swatch-size: 18px;
399
395
  mask-size: 24px 24px;
400
396
  -webkit-mask-size: 24px 24px;
401
397
  }
398
+
399
+ }
400
+
401
+ .treb-default-swatch {
402
+ display: grid;
403
+ grid-template-columns: auto 1fr;
404
+ gap: .5rem;
405
+ align-items: center;
406
+ }
407
+
408
+ .treb-swatches {
409
+
410
+ display: grid;
411
+ grid-template-columns: repeat(10, 1fr);
412
+ gap: .5rem;
413
+
402
414
  }
403
415
  }
404
416
 
@@ -19,6 +19,10 @@
19
19
  *
20
20
  */
21
21
 
22
+ @use 'z-index.scss' as *;
23
+ @use 'defaults.scss' as *;
24
+
25
+
22
26
  .treb-main.treb-main {
23
27
 
24
28
  .treb-tooltip {
@@ -1,5 +1,5 @@
1
1
 
2
- @import 'layout.scss';
2
+ @use 'layout.scss';
3
3
 
4
4
  /**
5
5
  * default styles for custom element. we basically want
@@ -1104,14 +1104,20 @@ export class Importer {
1104
1104
 
1105
1105
  // console.info({descriptor});
1106
1106
 
1107
- annotations.push({
1107
+ const anchored_annotation: AnchoredAnnotation = {
1108
1108
  layout,
1109
1109
  type: 'textbox',
1110
1110
  data: {
1111
1111
  style: descriptor.style,
1112
1112
  paragraphs: descriptor.paragraphs,
1113
- }
1114
- });
1113
+ },
1114
+ };
1115
+
1116
+ if (descriptor.reference) {
1117
+ anchored_annotation.formula = `=` + descriptor.reference;
1118
+ }
1119
+
1120
+ annotations.push(anchored_annotation);
1115
1121
 
1116
1122
  }
1117
1123
 
@@ -983,45 +983,6 @@ export class StyleCache {
983
983
  const new_fill: Fill = {...fill};
984
984
  this.fills.push(new_fill);
985
985
 
986
- /*
987
- // add the node structure
988
-
989
- if (!this.dom) throw new Error('missing dom');
990
- const fills = this.dom.find('./fills');
991
-
992
- if (!fills) throw new Error('fills not found');
993
- fills.attrib.count = (Number(fills.attrib.count || 0) + 1).toString();
994
-
995
- const new_element = Element('fill');
996
- const pattern_fill = Element('patternFill', { patternType: fill.pattern_type });
997
-
998
- switch (fill.pattern_type) {
999
- case 'none':
1000
- break;
1001
- case 'solid':
1002
- if (fill.fg_color) {
1003
- const attrs: Record<string, string> = {};
1004
-
1005
- if (fill.fg_color.argb) { attrs.rgb = fill.fg_color.argb; }
1006
- if (fill.fg_color.indexed) { attrs.indexed = fill.fg_color.indexed.toString(); }
1007
- if (fill.fg_color.tint) { attrs.tint = fill.fg_color.tint.toString(); }
1008
- if (typeof fill.fg_color.theme !== 'undefined') { attrs.theme = fill.fg_color.theme.toString(); }
1009
-
1010
- pattern_fill.append(Element('fgColor', attrs));
1011
- }
1012
- break;
1013
- case 'gray':
1014
-
1015
- // ...
1016
-
1017
- break;
1018
- }
1019
-
1020
- new_element.append(pattern_fill);
1021
-
1022
- fills.append(new_element);
1023
- */
1024
-
1025
986
  return this.fills.length - 1;
1026
987
  }
1027
988