@trebco/treb 27.9.0 → 27.11.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 (31) hide show
  1. package/dist/treb-spreadsheet.mjs +9 -9
  2. package/dist/treb.d.ts +8 -6
  3. package/package.json +1 -1
  4. package/{treb-grid/src/util/dom_utilities.ts → treb-base-types/src/dom-utilities.ts} +29 -20
  5. package/treb-base-types/src/index.ts +1 -0
  6. package/treb-base-types/src/theme.ts +3 -5
  7. package/treb-embed/src/custom-element/global.d.ts +3 -1
  8. package/treb-embed/src/custom-element/spreadsheet-constructor.ts +13 -19
  9. package/treb-embed/src/embedded-spreadsheet.ts +27 -92
  10. package/treb-embed/src/spinner.ts +3 -3
  11. package/treb-embed/style/layout.scss +1 -1
  12. package/treb-export/src/drawing2/chart2.ts +11 -2
  13. package/treb-export/src/export2.ts +14 -4
  14. package/treb-export/src/workbook-style2.ts +3 -2
  15. package/treb-grid/src/editors/autocomplete.ts +28 -24
  16. package/treb-grid/src/editors/editor.ts +3 -4
  17. package/treb-grid/src/editors/formula_bar.ts +1 -1
  18. package/treb-grid/src/layout/base_layout.ts +11 -16
  19. package/treb-grid/src/layout/grid_layout.ts +17 -28
  20. package/treb-grid/src/render/selection-renderer.ts +2 -3
  21. package/treb-grid/src/render/svg_header_overlay.ts +4 -11
  22. package/treb-grid/src/render/svg_selection_block.ts +27 -34
  23. package/treb-grid/src/render/tile_renderer.ts +6 -5
  24. package/treb-grid/src/types/grid.ts +32 -41
  25. package/treb-grid/src/types/grid_base.ts +2 -0
  26. package/treb-grid/src/types/scale-control.ts +2 -2
  27. package/treb-grid/src/types/sheet.ts +2 -2
  28. package/treb-grid/src/types/tab_bar.ts +4 -8
  29. package/treb-utils/src/index.ts +0 -1
  30. package/treb-utils/src/resizable.ts +26 -27
  31. package/treb-utils/src/template.ts +0 -70
package/dist/treb.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- /*! API v27.9. Copyright 2018-2023 trebco, llc. All rights reserved. LGPL: https://treb.app/license */
1
+ /*! API v27.11. Copyright 2018-2023 trebco, llc. All rights reserved. LGPL: https://treb.app/license */
2
2
 
3
3
  /**
4
4
  * add our tag to the map
@@ -6,7 +6,9 @@
6
6
  declare global {
7
7
  interface HTMLElementTagNameMap {
8
8
  'treb-spreadsheet': HTMLElement & {
9
- sheet: EmbeddedSpreadsheet|undefined;
9
+ instance: {
10
+ sheet: EmbeddedSpreadsheet | undefined;
11
+ } | undefined;
10
12
  };
11
13
  }
12
14
  }
@@ -385,11 +387,11 @@ export declare class EmbeddedSpreadsheet {
385
387
  * @param formula - annotation formula. For charts, the chart formula.
386
388
  * @param type - annotation type. Defaults to `treb-chart`.
387
389
  * @param rect - coordinates, or a range reference for layout.
388
- *
389
- * @param argument_separator - the argument separator to use when evaluating
390
- * the function. defaults to current locale.
390
+ * @param options - evaluate options. because this function used to take
391
+ * the argument separator, we allow that to be passed directly, but this
392
+ * is deprecated. new code should use the options object.
391
393
  */
392
- InsertAnnotation(formula: string, type?: AnnotationType, rect?: IRectangle | RangeReference, argument_separator?: ',' | ';'): void;
394
+ InsertAnnotation(formula: string, type?: AnnotationType, rect?: IRectangle | RangeReference, options?: EvaluateOptions | ',' | ';'): void;
393
395
 
394
396
  /**
395
397
  * Insert an image. This method will open a file chooser and (if an image
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trebco/treb",
3
- "version": "27.9.0",
3
+ "version": "27.11.1",
4
4
  "license": "LGPL-3.0-or-later",
5
5
  "homepage": "https://treb.app",
6
6
  "repository": {
@@ -19,25 +19,50 @@
19
19
  *
20
20
  */
21
21
 
22
+ const SVGNS = 'http://www.w3.org/2000/svg';
23
+
22
24
  export class DOMUtilities {
23
25
 
24
26
  /** creates a div and assigns class name/names */
25
- public static CreateDiv(classes = '', parent?: HTMLElement, scope?: string): HTMLDivElement {
27
+ public static Div(classes?: string|string[], parent?: HTMLElement, scope?: string): HTMLDivElement {
26
28
  return this.Create('div', classes, parent, scope);
27
29
  }
28
30
 
31
+ public static ClassNames(element: HTMLElement|SVGElement, classes: string|string[]) {
32
+ element.classList.add(...(Array.isArray(classes) ? classes : [classes]).reduce((arr: string[], entry) => [...arr, ...entry.split(/\s+/g)], []));
33
+ }
34
+
35
+ public static SVG<K extends keyof SVGElementTagNameMap>(
36
+ tag: K,
37
+ classes?: string|string[],
38
+ parent?: HTMLElement|SVGElement
39
+ ): SVGElementTagNameMap[K] {
40
+
41
+ const element = document.createElementNS(SVGNS, tag);
42
+
43
+ if (classes) {
44
+ this.ClassNames(element, classes);
45
+ }
46
+
47
+ if (parent) {
48
+ parent.appendChild(element);
49
+ }
50
+
51
+ return element;
52
+ }
53
+
29
54
  /** better typing */
30
55
  public static Create<K extends keyof HTMLElementTagNameMap>(
31
56
  tag: K,
32
- class_name = '',
57
+ classes?: string|string[],
33
58
  parent?: HTMLElement,
34
59
  scope?: string,
35
60
  attrs?: Record<string, string>): HTMLElementTagNameMap[K] {
36
61
 
37
62
  const element = document.createElement(tag);
38
63
 
39
- if (class_name) {
40
- element.className = class_name;
64
+ if (classes) {
65
+ this.ClassNames(element, classes);
41
66
  }
42
67
 
43
68
  if (scope) {
@@ -58,20 +83,4 @@ export class DOMUtilities {
58
83
  return element;
59
84
  }
60
85
 
61
- /* * generic element constructor. shame we need the tag AND the type. * /
62
- public static Create1<E extends HTMLElement>(tag = '', classes = '', parent?: HTMLElement, scope?: string, attrs?: Record<string, string>){
63
- const element = document.createElement(tag) as E;
64
- if (classes) element.setAttribute('class', classes);
65
- if (scope) element.setAttribute(scope, '');
66
- if (attrs) {
67
- const keys = Object.keys(attrs);
68
- for (const key of keys) {
69
- element.setAttribute(key, attrs[key]);
70
- }
71
- }
72
- if (parent) parent.appendChild(element);
73
- return element;
74
- }
75
- */
76
-
77
86
  }
@@ -38,6 +38,7 @@ export * from './api_types';
38
38
  export * from './table';
39
39
  export * from './gradient';
40
40
  export * from './evaluate-options';
41
+ export * from './dom-utilities';
41
42
 
42
43
  // import * as Style from './style';
43
44
  // export { Style };
@@ -21,6 +21,7 @@
21
21
 
22
22
  import type { Color, CellStyle } from './style';
23
23
  import { ColorFunctions } from './color';
24
+ import { DOMUtilities } from './dom-utilities';
24
25
 
25
26
  /*
26
27
  * so this is a little strange. we use CSS to populate a theme object,
@@ -494,10 +495,7 @@ export const LoadThemeProperties = (container: HTMLElement): Theme => {
494
495
  const theme: Theme = JSON.parse(JSON.stringify(DefaultTheme));
495
496
 
496
497
  const Append = (parent: HTMLElement, classes: string): HTMLDivElement => {
497
- const node = document.createElement('div');
498
- node.setAttribute('class', classes);
499
- parent.appendChild(node);
500
- return node;
498
+ return DOMUtilities.Div(classes, parent);
501
499
  }
502
500
 
503
501
  const ElementCSS = (parent: HTMLElement, classes: string): CSSStyleDeclaration => {
@@ -574,7 +572,7 @@ export const LoadThemeProperties = (container: HTMLElement): Theme => {
574
572
  // we could just parse, we know the returned css format is going
575
573
  // to be an rgb triple (I think?)
576
574
 
577
- const canvas = document.createElement('canvas');
575
+ const canvas = DOMUtilities.Create('canvas');
578
576
 
579
577
  canvas.width = 3;
580
578
  canvas.height = 3;
@@ -5,7 +5,9 @@
5
5
  declare global {
6
6
  interface HTMLElementTagNameMap {
7
7
  'treb-spreadsheet': HTMLElement & {
8
- sheet: EmbeddedSpreadsheet|undefined;
8
+ instance: {
9
+ sheet: EmbeddedSpreadsheet | undefined;
10
+ } | undefined;
9
11
  };
10
12
  }
11
13
  }
@@ -19,8 +19,11 @@ interface ElementOptions {
19
19
  classes: string|string[];
20
20
  }
21
21
 
22
- const Element = <T extends HTMLElement>(tag: string, parent?: HTMLElement|DocumentFragment, options: Partial<ElementOptions> = {}, attrs: Record<string, string> = {}): T => {
23
- const element = document.createElement(tag) as T;
22
+ /**
23
+ * FIXME: unify this with DOMUtils
24
+ */
25
+ const Element = <K extends keyof HTMLElementTagNameMap>(tag: K, parent?: HTMLElement|DocumentFragment, options: Partial<ElementOptions> = {}, attrs: Record<string, string> = {}): HTMLElementTagNameMap[K] => {
26
+ const element = document.createElement(tag);
24
27
  if (options.classes) {
25
28
 
26
29
  // you can't use an array destructure in a ternary expression? TIL
@@ -105,21 +108,12 @@ export class SpreadsheetConstructor {
105
108
 
106
109
  const style_node = document.head.querySelector('style[treb-stylesheet]');
107
110
  if (!style_node) {
108
- const style = document.createElement('style');
111
+ const style = Element('style');
109
112
  style.setAttribute('treb-stylesheet', '');
110
113
  style.textContent = css;
111
114
  document.head.prepend(style);
112
115
  }
113
116
 
114
- /*
115
- if (!SpreadsheetConstructor.stylesheets_attached) {
116
- const style = document.createElement('style');
117
- style.textContent = css;
118
- document.head.prepend(style);
119
- SpreadsheetConstructor.stylesheets_attached = true;
120
- }
121
- */
122
-
123
117
  }
124
118
 
125
119
  }
@@ -509,9 +503,9 @@ export class SpreadsheetConstructor {
509
503
 
510
504
  const resize_parent = root.querySelector('.treb-main') as HTMLElement; // was document.body
511
505
 
512
- resizer = Element<HTMLDivElement>('div', resize_parent, { classes: 'treb-resize-rect' });
506
+ resizer = Element('div', resize_parent, { classes: 'treb-resize-rect' });
513
507
 
514
- mask = Element<HTMLDivElement>('div', resize_parent, {
508
+ mask = Element('div', resize_parent, {
515
509
  classes: 'treb-resize-mask',
516
510
  style: 'cursor: nw-resize;',
517
511
  });
@@ -724,7 +718,7 @@ export class SpreadsheetConstructor {
724
718
  }
725
719
 
726
720
  }
727
- Element<HTMLButtonElement>('button', fragment, { style, title, data: { command: 'set-color', color: JSON.stringify(entry.color) } });
721
+ Element('button', fragment, { style, title, data: { command: 'set-color', color: JSON.stringify(entry.color) } });
728
722
  }
729
723
  }
730
724
 
@@ -733,7 +727,7 @@ export class SpreadsheetConstructor {
733
727
  this.swatch_lists.theme?.replaceChildren(fragment);
734
728
 
735
729
  fragment = document.createDocumentFragment();
736
- Element<HTMLButtonElement>('button', fragment, {
730
+ Element('button', fragment, {
737
731
  classes: 'treb-default-color',
738
732
  title: 'Default color',
739
733
  data: { command: 'set-color', color: JSON.stringify({}) },
@@ -748,7 +742,7 @@ export class SpreadsheetConstructor {
748
742
 
749
743
  for (const text of [...colors, ...additional_colors]) {
750
744
  const style = `background: ${text.toLowerCase()};`;
751
- Element<HTMLButtonElement>('button', fragment, { style, title: text, data: { command: 'set-color', color: JSON.stringify({text: text.toLowerCase()})}});
745
+ Element('button', fragment, { style, title: text, data: { command: 'set-color', color: JSON.stringify({text: text.toLowerCase()})}});
752
746
  }
753
747
 
754
748
  this.swatch_lists.other?.replaceChildren(fragment);
@@ -777,7 +771,7 @@ export class SpreadsheetConstructor {
777
771
  }
778
772
 
779
773
  const Button = (format: string) => {
780
- return Element<HTMLButtonElement>('button', undefined, {
774
+ return Element('button', undefined, {
781
775
  text: format, data: { format, command: 'number-format' },
782
776
  });
783
777
  };
@@ -785,7 +779,7 @@ export class SpreadsheetConstructor {
785
779
  const fragment = document.createDocumentFragment();
786
780
  fragment.append(...number_formats.map(format => Button(format)));
787
781
 
788
- fragment.append(Element<HTMLDivElement>('div', undefined, {}, {separator: ''}));
782
+ fragment.append(Element('div', undefined, {}, {separator: ''}));
789
783
  fragment.append(...date_formats.map(format => Button(format)));
790
784
 
791
785
  format_menu.textContent = '';
@@ -65,7 +65,7 @@ import type {
65
65
 
66
66
  import {
67
67
  IsArea, ThemeColorTable, ComplexToString, Rectangle, IsComplex, type CellStyle,
68
- Localization, Style, type Color, ThemeColor2, IsCellAddress, Area, IsFlatData, IsFlatDataArray, Gradient, ValueType,
68
+ Localization, Style, type Color, ThemeColor2, IsCellAddress, Area, IsFlatData, IsFlatDataArray, Gradient, ValueType, DOMUtilities,
69
69
  } from 'treb-base-types';
70
70
 
71
71
  import { EventSource, Yield, ValidateURI } from 'treb-utils';
@@ -2206,19 +2206,29 @@ export class EmbeddedSpreadsheet {
2206
2206
  * @param formula - annotation formula. For charts, the chart formula.
2207
2207
  * @param type - annotation type. Defaults to `treb-chart`.
2208
2208
  * @param rect - coordinates, or a range reference for layout.
2209
- *
2210
- * @param argument_separator - the argument separator to use when evaluating
2211
- * the function. defaults to current locale.
2209
+ * @param options - evaluate options. because this function used to take
2210
+ * the argument separator, we allow that to be passed directly, but this
2211
+ * is deprecated. new code should use the options object.
2212
2212
  */
2213
- public InsertAnnotation(formula: string, type: AnnotationType = 'treb-chart', rect?: IRectangle|RangeReference, argument_separator?: ','|';'): void {
2213
+ public InsertAnnotation(formula: string, type: AnnotationType = 'treb-chart', rect?: IRectangle|RangeReference, options?: EvaluateOptions|','|';'): void {
2214
2214
 
2215
2215
  let target: IRectangle | Partial<Area> | undefined;
2216
+ let argument_separator: ','|';'|undefined = undefined;
2217
+ let r1c1 = false;
2218
+
2219
+ if (typeof options === 'object') {
2220
+ argument_separator = options.argument_separator;
2221
+ r1c1 = !!options.r1c1;
2222
+ }
2223
+ else if (options === ',' || options === ';') {
2224
+ argument_separator = options;
2225
+ }
2216
2226
 
2217
2227
  if (rect) {
2218
2228
  target = Rectangle.IsRectangle(rect) ? rect : this.model.ResolveArea(rect, this.grid.active_sheet);
2219
2229
  }
2220
2230
 
2221
- if (argument_separator && argument_separator !== this.parser.argument_separator) {
2231
+ if (argument_separator && argument_separator !== this.parser.argument_separator || r1c1) {
2222
2232
  const current = {
2223
2233
  argument_separator: this.parser.argument_separator,
2224
2234
  decimal_mark: this.parser.decimal_mark,
@@ -2233,11 +2243,17 @@ export class EmbeddedSpreadsheet {
2233
2243
  this.parser.decimal_mark = DecimalMarkType.Comma;
2234
2244
  }
2235
2245
 
2246
+ const r1c1_state = this.parser.flags.r1c1;
2247
+ if (r1c1) {
2248
+ this.parser.flags.r1c1 = r1c1;
2249
+ }
2250
+
2236
2251
  const result = this.parser.Parse(formula);
2237
2252
 
2238
2253
  // reset
2239
2254
  this.parser.argument_separator = current.argument_separator;
2240
2255
  this.parser.decimal_mark = current.decimal_mark;
2256
+ this.parser.flags.r1c1 = r1c1_state;
2241
2257
 
2242
2258
  if (result.expression) {
2243
2259
  formula = '=' + this.parser.Render(result.expression, { missing: '' });
@@ -3106,14 +3122,6 @@ export class EmbeddedSpreadsheet {
3106
3122
 
3107
3123
  if (text && filename) {
3108
3124
  const blob = new Blob([text as any], { type: 'text/plain;charset=utf-8' });
3109
- /*
3110
- // FileSaver.saveAs(blob, filename, { autoBom: false });
3111
- const a = document.createElement('a');
3112
- a.href = URL.createObjectURL(blob);
3113
- a.download = filename;
3114
- a.click();
3115
- URL.revokeObjectURL(a.href);
3116
- */
3117
3125
  this.SaveAs(blob, filename);
3118
3126
  }
3119
3127
 
@@ -4312,7 +4320,7 @@ export class EmbeddedSpreadsheet {
4312
4320
  */
4313
4321
  protected SaveAs(blob: Blob, filename: string) {
4314
4322
 
4315
- const a = document.createElement('a');
4323
+ const a = DOMUtilities.Create('a');
4316
4324
  a.href = URL.createObjectURL(blob);
4317
4325
  a.download = filename;
4318
4326
  a.click();
@@ -4437,7 +4445,7 @@ export class EmbeddedSpreadsheet {
4437
4445
  return;
4438
4446
  }
4439
4447
 
4440
- const a = document.createElement('a');
4448
+ const a = DOMUtilities.Create('a');
4441
4449
  a.setAttribute('target', this.options.hyperlinks);
4442
4450
  a.setAttribute('href', data);
4443
4451
  a.setAttribute('noreferrer', 'true');
@@ -4578,7 +4586,7 @@ export class EmbeddedSpreadsheet {
4578
4586
  protected SelectFile2(accept: string, operation: FileChooserOperation) {
4579
4587
 
4580
4588
  if (!this.file_chooser) {
4581
- this.file_chooser = document.createElement('input');
4589
+ this.file_chooser = DOMUtilities.Create('input');
4582
4590
  this.file_chooser.type = 'file';
4583
4591
 
4584
4592
  const file_chooser = this.file_chooser;
@@ -4611,79 +4619,6 @@ export class EmbeddedSpreadsheet {
4611
4619
 
4612
4620
  }
4613
4621
 
4614
- /* *
4615
- * show file chooser and resolve with the selected file, or undefined
4616
- * /
4617
- protected SelectFile(accept?: string): Promise<File | undefined> {
4618
-
4619
- return new Promise((resolve) => {
4620
-
4621
- const file_chooser = document.createElement('input');
4622
- file_chooser.type = 'file';
4623
-
4624
- if (accept) {
4625
- file_chooser.accept = accept;
4626
- }
4627
-
4628
- // so the thing here is there is no way to trap a "cancel" event
4629
- // from the file chooser. if you are waiting on a promise, that will
4630
- // just get orphaned forever.
4631
-
4632
- // it's not the end of the world, really, to leave a few of these
4633
- // dangling, but this should allow it to clean up.
4634
-
4635
- // the concept is that since file chooser is modal, there will never
4636
- // be a focus event until the modal is closed. unfortunately the focus
4637
- // event comes _before_ any input or change event from the file input,
4638
- // so we have to wait.
4639
-
4640
- // tested Cr, FF, IE11
4641
- // update: works in Safari, although oddly not if you call the API
4642
- // function from the console. not sure if that's a browserstack thing.
4643
-
4644
- // eslint-disable-next-line prefer-const
4645
- let finalize: (file?: File) => void;
4646
- let timeout: NodeJS.Timeout|undefined;
4647
-
4648
- // if you get a focus event, allow some reasonable time for the
4649
- // corresponding change event. realistically this should be immediate,
4650
- // but as long as there's not a lot of logic waiting on a cancel, it
4651
- // doesn't really matter.
4652
-
4653
- const window_focus = () => {
4654
-
4655
- // prevent this from accidentally being called more than once
4656
- window.removeEventListener('focus', window_focus);
4657
- timeout = setTimeout(finalize, 250);
4658
- }
4659
-
4660
- const change_handler = () => {
4661
- if (timeout) {
4662
- clearTimeout(timeout);
4663
- timeout = undefined; // necessary?
4664
- }
4665
- finalize(file_chooser.files ? file_chooser.files[0] : undefined);
4666
- }
4667
-
4668
- // our finalize method cleans up and resolves
4669
-
4670
- finalize = (file?: File) => {
4671
- file_chooser.removeEventListener('change', change_handler);
4672
- window.removeEventListener('focus', window_focus);
4673
- resolve(file);
4674
- };
4675
-
4676
- file_chooser.addEventListener('change', change_handler);
4677
- window.addEventListener('focus', window_focus);
4678
-
4679
- file_chooser.click();
4680
-
4681
-
4682
- });
4683
-
4684
- }
4685
- */
4686
-
4687
4622
  /**
4688
4623
  * Insert an image. This method will open a file chooser and (if an image
4689
4624
  * is selected) insert the image into the document.
@@ -4728,7 +4663,7 @@ export class EmbeddedSpreadsheet {
4728
4663
  }
4729
4664
  }
4730
4665
 
4731
- const img = document.createElement('img');
4666
+ const img = DOMUtilities.Create('img');
4732
4667
  img.src = contents;
4733
4668
 
4734
4669
  // this is to let the browser figure out the image size.
@@ -5093,7 +5028,7 @@ export class EmbeddedSpreadsheet {
5093
5028
  const reference = ValidateURI(annotation.data.data.src);
5094
5029
  if (reference) {
5095
5030
 
5096
- const img = document.createElement('img');
5031
+ const img = DOMUtilities.Create('img');
5097
5032
  img.src = reference;
5098
5033
 
5099
5034
  if (annotation.data.data.scale === 'fixed') {
@@ -19,16 +19,16 @@
19
19
  *
20
20
  */
21
21
 
22
+ import { DOMUtilities } from 'treb-base-types';
23
+
22
24
  export class Spinner {
23
25
 
24
26
  private node: HTMLDivElement;
25
27
  private visible = false;
26
28
 
27
29
  constructor(public container: HTMLElement) {
28
- this.node = document.createElement('div');
29
- this.node.classList.add('treb-spinner');
30
+ this.node = DOMUtilities.Div('treb-spinner', container);
30
31
  this.node.innerHTML = `<div><div></div><div></div><div></div><div></div></div>`;
31
- container.appendChild(this.node);
32
32
  }
33
33
 
34
34
  public Show(): void {
@@ -228,7 +228,7 @@
228
228
  justify-self: end;
229
229
  align-self: end;
230
230
 
231
- border: .5rem solid var(--treb-resize-handle-color, blue);
231
+ border: .5rem solid var(--treb-resize-handle-color, #0059B9);
232
232
  border-top-color: transparent;
233
233
  border-left-color: transparent;
234
234
 
@@ -169,7 +169,11 @@ export class Chart {
169
169
  }
170
170
  }
171
171
 
172
- series['c:spPr']['a:ln']['a:solidFill']['a:schemeClr'].a$['val'] = `accent${i+1}`;
172
+ // "accent7" will break
173
+
174
+ if (i < 6) {
175
+ series['c:spPr']['a:ln']['a:solidFill']['a:schemeClr'].a$['val'] = `accent${i+1}`;
176
+ }
173
177
 
174
178
  series['c:yVal']['c:numRef']['c:f'] = this.options.data[i]?.label;
175
179
 
@@ -255,7 +259,12 @@ export class Chart {
255
259
 
256
260
  series['c:idx'] = { a$: { val: i.toString() }};
257
261
  series['c:order'] = { a$: { val: i.toString() }};
258
- series['c:spPr']['a:solidFill']['a:schemeClr'].a$['val'] = `accent${i+1}`;
262
+
263
+ // "accent7" will break
264
+
265
+ if (i < 6) {
266
+ series['c:spPr']['a:solidFill']['a:schemeClr'].a$['val'] = `accent${i+1}`;
267
+ }
259
268
 
260
269
  if (!i && this.options.labels) {
261
270
  series['c:cat'] = {
@@ -642,6 +642,9 @@ export class Exporter {
642
642
  // is this backwards, vis a vis our rendering? I think it might be...
643
643
  // YES: should be row pattern -> row -> column -> cell [corrected]
644
644
 
645
+ // FIXME: can't we just ask the sheet? (A: no, because we don't have
646
+ // an actual sheet, although we could?)
647
+
645
648
  // if (sheet.row_style && sheet.row_style[row]) {
646
649
  // list.push(sheet.row_style[row]);
647
650
  // }
@@ -1270,6 +1273,7 @@ export class Exporter {
1270
1273
  },
1271
1274
  dataValidations: {},
1272
1275
  hyperlinks: {},
1276
+ conditionalFormatting: {},
1273
1277
  pageMargins: {
1274
1278
  a$: {
1275
1279
  left: 0.7,
@@ -2157,7 +2161,13 @@ export class Exporter {
2157
2161
  if (conditionalFormatting.length) {
2158
2162
  dom.worksheet.conditionalFormatting = (conditionalFormatting.length > 1) ? conditionalFormatting : conditionalFormatting[0];
2159
2163
  }
2160
-
2164
+ else {
2165
+ delete dom.worksheet.conditionalFormatting;
2166
+ }
2167
+
2168
+ }
2169
+ else {
2170
+ delete dom.worksheet.conditionalFormatting;
2161
2171
  }
2162
2172
 
2163
2173
  // --- merges ------------------------------------------------------------
@@ -2333,9 +2343,9 @@ export class Exporter {
2333
2343
 
2334
2344
  // --- move page margins -------------------------------------------------
2335
2345
 
2336
- const margins = dom.worksheet.pageMargins;
2337
- delete dom.worksheet.pageMargins;
2338
- dom.worksheet.pageMargins = margins;
2346
+ // const margins = dom.worksheet.pageMargins;
2347
+ // delete dom.worksheet.pageMargins;
2348
+ // dom.worksheet.pageMargins = margins;
2339
2349
 
2340
2350
  // --- end? --------------------------------------------------------------
2341
2351
 
@@ -424,17 +424,18 @@ export class StyleCache {
424
424
  fill.pattern_type = 'solid';
425
425
  if (composite.fill.text) {
426
426
  fill.fg_color = { argb: composite.fill.text };
427
+ options.fill = fill;
427
428
  }
428
429
  else if (typeof composite.fill.theme === 'number') {
429
430
  fill.fg_color = { theme: composite.fill.theme };
430
431
  if (composite.fill.tint) {
431
432
  fill.fg_color.tint = composite.fill.tint;
432
433
  }
434
+ options.fill = fill;
433
435
  }
434
436
  else {
435
- fill.fg_color = { theme: 1 };
437
+ // fill.fg_color = { theme: 1 };
436
438
  }
437
- options.fill = fill;
438
439
  }
439
440
 
440
441
  if (composite.wrap) {
@@ -1,25 +1,25 @@
1
- /*
2
- * This file is part of TREB.
3
- *
4
- * TREB is free software: you can redistribute it and/or modify it under the
5
- * terms of the GNU General Public License as published by the Free Software
6
- * Foundation, either version 3 of the License, or (at your option) any
7
- * later version.
8
- *
9
- * TREB is distributed in the hope that it will be useful, but WITHOUT ANY
10
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12
- * details.
13
- *
14
- * You should have received a copy of the GNU General Public License along
15
- * with TREB. If not, see <https://www.gnu.org/licenses/>.
16
- *
17
- * Copyright 2022-2023 trebco, llc.
18
- * info@treb.app
19
- *
20
- */
21
-
22
- import { DOMUtilities } from '../util/dom_utilities';
1
+ /*
2
+ * This file is part of TREB.
3
+ *
4
+ * TREB is free software: you can redistribute it and/or modify it under the
5
+ * terms of the GNU General Public License as published by the Free Software
6
+ * Foundation, either version 3 of the License, or (at your option) any
7
+ * later version.
8
+ *
9
+ * TREB is distributed in the hope that it will be useful, but WITHOUT ANY
10
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12
+ * details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License along
15
+ * with TREB. If not, see <https://www.gnu.org/licenses/>.
16
+ *
17
+ * Copyright 2022-2023 trebco, llc.
18
+ * info@treb.app
19
+ *
20
+ */
21
+
22
+ import { DOMUtilities } from 'treb-base-types';
23
23
  import type { Theme, Rectangle } from 'treb-base-types';
24
24
  import type { AutocompleteExecResult, DescriptorType } from './autocomplete_matcher';
25
25
 
@@ -76,7 +76,7 @@ export class Autocomplete {
76
76
 
77
77
  // this.scope = 'AC' + Math.round(Math.random() * Math.pow(10, 10)).toString(16);
78
78
 
79
- this.completion_list = DOMUtilities.CreateDiv(
79
+ this.completion_list = DOMUtilities.Div(
80
80
  'treb-cell-editor-ac-list treb-autocomplete',
81
81
  options.container || document.body,
82
82
  ); // this.scope);
@@ -87,7 +87,7 @@ export class Autocomplete {
87
87
 
88
88
  this.completion_list.addEventListener('mousemove', (event) => this.ListMouseMove(event));
89
89
 
90
- this.tooltip = DOMUtilities.CreateDiv('treb-cell-editor-ac-tooltip treb-autocomplete-tooltip',
90
+ this.tooltip = DOMUtilities.Div('treb-cell-editor-ac-tooltip treb-autocomplete-tooltip',
91
91
  options.container || document.body,
92
92
  ); // this.scope);
93
93
 
@@ -173,6 +173,10 @@ export class Autocomplete {
173
173
  this.active_element = undefined;
174
174
  }
175
175
 
176
+ public SetBlock(): void {
177
+ this.block = true;
178
+ }
179
+
176
180
  public ResetBlock(): void {
177
181
  this.block = false;
178
182
  }