@trebco/treb 23.6.2 → 25.0.0-rc1
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/.eslintignore +8 -0
- package/.eslintrc.js +164 -0
- package/README-shadow-DOM.md +88 -0
- package/README.md +37 -130
- package/api-config.json +29 -0
- package/api-generator/api-generator-types.ts +82 -0
- package/api-generator/api-generator.ts +1172 -0
- package/api-generator/package.json +3 -0
- package/build/treb-spreadsheet.mjs +14 -0
- package/{treb.d.ts → build/treb.d.ts} +293 -299
- package/esbuild-custom-element.mjs +336 -0
- package/esbuild.js +305 -0
- package/package.json +43 -14
- package/treb-base-types/package.json +5 -0
- package/treb-base-types/src/api_types.ts +36 -0
- package/treb-base-types/src/area.ts +583 -0
- package/treb-base-types/src/basic_types.ts +45 -0
- package/treb-base-types/src/cell.ts +612 -0
- package/treb-base-types/src/cells.ts +1066 -0
- package/treb-base-types/src/color.ts +124 -0
- package/treb-base-types/src/import.ts +71 -0
- package/treb-base-types/src/index-standalone.ts +29 -0
- package/treb-base-types/src/index.ts +42 -0
- package/treb-base-types/src/layout.ts +47 -0
- package/treb-base-types/src/localization.ts +187 -0
- package/treb-base-types/src/rectangle.ts +145 -0
- package/treb-base-types/src/render_text.ts +72 -0
- package/treb-base-types/src/style.ts +545 -0
- package/treb-base-types/src/table.ts +109 -0
- package/treb-base-types/src/text_part.ts +54 -0
- package/treb-base-types/src/theme.ts +608 -0
- package/treb-base-types/src/union.ts +152 -0
- package/treb-base-types/src/value-type.ts +164 -0
- package/treb-base-types/style/resizable.css +59 -0
- package/treb-calculator/modern.tsconfig.json +11 -0
- package/treb-calculator/package.json +5 -0
- package/treb-calculator/src/calculator.ts +2546 -0
- package/treb-calculator/src/complex-math.ts +558 -0
- package/treb-calculator/src/dag/array-vertex.ts +198 -0
- package/treb-calculator/src/dag/graph.ts +951 -0
- package/treb-calculator/src/dag/leaf_vertex.ts +118 -0
- package/treb-calculator/src/dag/spreadsheet_vertex.ts +327 -0
- package/treb-calculator/src/dag/spreadsheet_vertex_base.ts +44 -0
- package/treb-calculator/src/dag/vertex.ts +352 -0
- package/treb-calculator/src/descriptors.ts +162 -0
- package/treb-calculator/src/expression-calculator.ts +1069 -0
- package/treb-calculator/src/function-error.ts +103 -0
- package/treb-calculator/src/function-library.ts +103 -0
- package/treb-calculator/src/functions/base-functions.ts +1214 -0
- package/treb-calculator/src/functions/checkbox.ts +164 -0
- package/treb-calculator/src/functions/complex-functions.ts +253 -0
- package/treb-calculator/src/functions/finance-functions.ts +399 -0
- package/treb-calculator/src/functions/information-functions.ts +102 -0
- package/treb-calculator/src/functions/matrix-functions.ts +182 -0
- package/treb-calculator/src/functions/sparkline.ts +335 -0
- package/treb-calculator/src/functions/statistics-functions.ts +350 -0
- package/treb-calculator/src/functions/text-functions.ts +298 -0
- package/treb-calculator/src/index.ts +27 -0
- package/treb-calculator/src/notifier-types.ts +59 -0
- package/treb-calculator/src/primitives.ts +428 -0
- package/treb-calculator/src/utilities.ts +305 -0
- package/treb-charts/package.json +5 -0
- package/treb-charts/src/chart-functions.ts +156 -0
- package/treb-charts/src/chart-types.ts +230 -0
- package/treb-charts/src/chart.ts +1288 -0
- package/treb-charts/src/index.ts +24 -0
- package/treb-charts/src/main.ts +37 -0
- package/treb-charts/src/rectangle.ts +52 -0
- package/treb-charts/src/renderer.ts +1841 -0
- package/treb-charts/src/util.ts +122 -0
- package/treb-charts/style/charts.scss +221 -0
- package/treb-charts/style/old-charts.scss +250 -0
- package/treb-embed/markup/layout.html +137 -0
- package/treb-embed/markup/toolbar.html +175 -0
- package/treb-embed/modern.tsconfig.json +25 -0
- package/treb-embed/src/custom-element/content-types.d.ts +18 -0
- package/treb-embed/src/custom-element/global.d.ts +11 -0
- package/treb-embed/src/custom-element/spreadsheet-constructor.ts +1227 -0
- package/treb-embed/src/custom-element/treb-global.ts +44 -0
- package/treb-embed/src/custom-element/treb-spreadsheet-element.ts +52 -0
- package/treb-embed/src/embedded-spreadsheet.ts +5362 -0
- package/treb-embed/src/index.ts +16 -0
- package/treb-embed/src/language-model.ts +41 -0
- package/treb-embed/src/options.ts +320 -0
- package/treb-embed/src/progress-dialog.ts +228 -0
- package/treb-embed/src/selection-state.ts +16 -0
- package/treb-embed/src/spinner.ts +42 -0
- package/treb-embed/src/toolbar-message.ts +96 -0
- package/treb-embed/src/types.ts +167 -0
- package/treb-embed/style/autocomplete.scss +103 -0
- package/treb-embed/style/dark-theme.scss +114 -0
- package/treb-embed/style/defaults.scss +36 -0
- package/treb-embed/style/dialog.scss +181 -0
- package/treb-embed/style/dropdown-select.scss +101 -0
- package/treb-embed/style/formula-bar.scss +193 -0
- package/treb-embed/style/grid.scss +374 -0
- package/treb-embed/style/layout.scss +424 -0
- package/treb-embed/style/mouse-mask.scss +67 -0
- package/treb-embed/style/note.scss +92 -0
- package/treb-embed/style/overlay-editor.scss +102 -0
- package/treb-embed/style/spinner.scss +92 -0
- package/treb-embed/style/tab-bar.scss +228 -0
- package/treb-embed/style/table.scss +80 -0
- package/treb-embed/style/theme-defaults.scss +444 -0
- package/treb-embed/style/toolbar.scss +416 -0
- package/treb-embed/style/tooltip.scss +68 -0
- package/treb-embed/style/treb-icons.scss +130 -0
- package/treb-embed/style/treb-spreadsheet-element.scss +20 -0
- package/treb-embed/style/z-index.scss +43 -0
- package/treb-export/docs/charts.md +68 -0
- package/treb-export/modern.tsconfig.json +19 -0
- package/treb-export/package.json +4 -0
- package/treb-export/src/address-type.ts +77 -0
- package/treb-export/src/base-template.ts +22 -0
- package/treb-export/src/column-width.ts +85 -0
- package/treb-export/src/drawing2/chart-template-components2.ts +389 -0
- package/treb-export/src/drawing2/chart2.ts +282 -0
- package/treb-export/src/drawing2/column-chart-template2.ts +521 -0
- package/treb-export/src/drawing2/donut-chart-template2.ts +296 -0
- package/treb-export/src/drawing2/drawing2.ts +355 -0
- package/treb-export/src/drawing2/embedded-image.ts +71 -0
- package/treb-export/src/drawing2/scatter-chart-template2.ts +555 -0
- package/treb-export/src/export-worker/export-worker.ts +99 -0
- package/treb-export/src/export-worker/index-modern.ts +22 -0
- package/treb-export/src/export2.ts +2204 -0
- package/treb-export/src/import2.ts +882 -0
- package/treb-export/src/relationship.ts +36 -0
- package/treb-export/src/shared-strings2.ts +128 -0
- package/treb-export/src/template-2.ts +22 -0
- package/treb-export/src/unescape_xml.ts +47 -0
- package/treb-export/src/workbook-sheet2.ts +182 -0
- package/treb-export/src/workbook-style2.ts +1285 -0
- package/treb-export/src/workbook-theme2.ts +88 -0
- package/treb-export/src/workbook2.ts +491 -0
- package/treb-export/src/xml-utils.ts +201 -0
- package/treb-export/template/base/[Content_Types].xml +2 -0
- package/treb-export/template/base/_rels/.rels +2 -0
- package/treb-export/template/base/docProps/app.xml +2 -0
- package/treb-export/template/base/docProps/core.xml +12 -0
- package/treb-export/template/base/xl/_rels/workbook.xml.rels +2 -0
- package/treb-export/template/base/xl/sharedStrings.xml +2 -0
- package/treb-export/template/base/xl/styles.xml +2 -0
- package/treb-export/template/base/xl/theme/theme1.xml +2 -0
- package/treb-export/template/base/xl/workbook.xml +2 -0
- package/treb-export/template/base/xl/worksheets/sheet1.xml +2 -0
- package/treb-export/template/base.xlsx +0 -0
- package/treb-format/package.json +8 -0
- package/treb-format/src/format.test.ts +213 -0
- package/treb-format/src/format.ts +942 -0
- package/treb-format/src/format_cache.ts +199 -0
- package/treb-format/src/format_parser.ts +723 -0
- package/treb-format/src/index.ts +25 -0
- package/treb-format/src/number_format_section.ts +100 -0
- package/treb-format/src/value_parser.ts +337 -0
- package/treb-grid/package.json +5 -0
- package/treb-grid/src/editors/autocomplete.ts +394 -0
- package/treb-grid/src/editors/autocomplete_matcher.ts +260 -0
- package/treb-grid/src/editors/formula_bar.ts +473 -0
- package/treb-grid/src/editors/formula_editor_base.ts +910 -0
- package/treb-grid/src/editors/overlay_editor.ts +511 -0
- package/treb-grid/src/index.ts +37 -0
- package/treb-grid/src/layout/base_layout.ts +2618 -0
- package/treb-grid/src/layout/grid_layout.ts +299 -0
- package/treb-grid/src/layout/rectangle_cache.ts +86 -0
- package/treb-grid/src/render/selection-renderer.ts +414 -0
- package/treb-grid/src/render/svg_header_overlay.ts +93 -0
- package/treb-grid/src/render/svg_selection_block.ts +187 -0
- package/treb-grid/src/render/tile_renderer.ts +2122 -0
- package/treb-grid/src/types/annotation.ts +216 -0
- package/treb-grid/src/types/border_constants.ts +34 -0
- package/treb-grid/src/types/clipboard_data.ts +31 -0
- package/treb-grid/src/types/data_model.ts +334 -0
- package/treb-grid/src/types/drag_mask.ts +81 -0
- package/treb-grid/src/types/grid.ts +7743 -0
- package/treb-grid/src/types/grid_base.ts +3644 -0
- package/treb-grid/src/types/grid_command.ts +470 -0
- package/treb-grid/src/types/grid_events.ts +124 -0
- package/treb-grid/src/types/grid_options.ts +97 -0
- package/treb-grid/src/types/grid_selection.ts +60 -0
- package/treb-grid/src/types/named_range.ts +369 -0
- package/treb-grid/src/types/scale-control.ts +202 -0
- package/treb-grid/src/types/serialize_options.ts +72 -0
- package/treb-grid/src/types/set_range_options.ts +52 -0
- package/treb-grid/src/types/sheet.ts +3099 -0
- package/treb-grid/src/types/sheet_types.ts +95 -0
- package/treb-grid/src/types/tab_bar.ts +464 -0
- package/treb-grid/src/types/tile.ts +59 -0
- package/treb-grid/src/types/update_flags.ts +75 -0
- package/treb-grid/src/util/dom_utilities.ts +44 -0
- package/treb-grid/src/util/fontmetrics2.ts +179 -0
- package/treb-grid/src/util/ua.ts +104 -0
- package/treb-logo.svg +18 -0
- package/treb-parser/package.json +5 -0
- package/treb-parser/src/csv-parser.ts +122 -0
- package/treb-parser/src/index.ts +25 -0
- package/treb-parser/src/md-parser.ts +526 -0
- package/treb-parser/src/parser-types.ts +397 -0
- package/treb-parser/src/parser.test.ts +298 -0
- package/treb-parser/src/parser.ts +2673 -0
- package/treb-utils/package.json +5 -0
- package/treb-utils/src/dispatch.ts +57 -0
- package/treb-utils/src/event_source.ts +147 -0
- package/treb-utils/src/ievent_source.ts +33 -0
- package/treb-utils/src/index.ts +31 -0
- package/treb-utils/src/measurement.ts +174 -0
- package/treb-utils/src/resizable.ts +160 -0
- package/treb-utils/src/scale.ts +137 -0
- package/treb-utils/src/serialize_html.ts +124 -0
- package/treb-utils/src/template.ts +70 -0
- package/treb-utils/src/validate_uri.ts +61 -0
- package/tsconfig.json +10 -0
- package/tsproject.json +30 -0
- package/util/license-plugin-esbuild.js +86 -0
- package/util/list-css-vars.sh +46 -0
- package/README-esm.md +0 -37
- package/treb-bundle.css +0 -2
- package/treb-bundle.mjs +0 -15
|
@@ -0,0 +1,72 @@
|
|
|
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
|
+
/*
|
|
23
|
+
* render text types moved from tile renderer in grid
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* information about a rendered substring. FIXME: move this somewhere else
|
|
28
|
+
*
|
|
29
|
+
* FIXME: there's a lot of overlap between this and "TextPartFlag", which
|
|
30
|
+
* comes from base types and is used by formatter. can we consolidate these?
|
|
31
|
+
*
|
|
32
|
+
* testing some inline markdown...
|
|
33
|
+
* FIXME: gate on option? sheet option? (...)
|
|
34
|
+
*
|
|
35
|
+
*/
|
|
36
|
+
export interface RenderTextPart {
|
|
37
|
+
text: string;
|
|
38
|
+
hidden: boolean;
|
|
39
|
+
width: number;
|
|
40
|
+
|
|
41
|
+
// italic?: boolean; // for imaginary // looks like crap
|
|
42
|
+
|
|
43
|
+
// adding optional layout info (for hyperlink, basically)
|
|
44
|
+
|
|
45
|
+
top?: number;
|
|
46
|
+
left?: number;
|
|
47
|
+
height?: number;
|
|
48
|
+
|
|
49
|
+
// testing, md
|
|
50
|
+
strong?: boolean;
|
|
51
|
+
emphasis?: boolean;
|
|
52
|
+
strike?: boolean;
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface PreparedText {
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* strings now represents parts of individual lines; this both supports
|
|
60
|
+
* MD and unifies the old system where it meant _either_ parts _or_ lines,
|
|
61
|
+
* which was super confusing.
|
|
62
|
+
*/
|
|
63
|
+
strings: RenderTextPart[][];
|
|
64
|
+
|
|
65
|
+
/** this is the max rendered width. individual components have their own width */
|
|
66
|
+
width: number;
|
|
67
|
+
|
|
68
|
+
/** possibly override format; this is used for number formats that have [color] */
|
|
69
|
+
format?: string;
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
@@ -0,0 +1,545 @@
|
|
|
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
|
+
// 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).
|
|
26
|
+
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
28
|
+
export namespace Style {
|
|
29
|
+
|
|
30
|
+
const empty_json = JSON.stringify({}); // we could probably hard-code this
|
|
31
|
+
|
|
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;
|
|
78
|
+
|
|
79
|
+
/** @internal */
|
|
80
|
+
offset?: Color;
|
|
81
|
+
|
|
82
|
+
/** @deprecated */
|
|
83
|
+
none?: boolean;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** @internal */
|
|
87
|
+
export interface CompositeBorderEdge {
|
|
88
|
+
width: number;
|
|
89
|
+
color: Color;
|
|
90
|
+
}
|
|
91
|
+
|
|
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;
|
|
110
|
+
|
|
111
|
+
/** representation for NaN */
|
|
112
|
+
nan?: string;
|
|
113
|
+
|
|
114
|
+
/** number format, either a symbolic name like "General" or a format string */
|
|
115
|
+
number_format?: string;
|
|
116
|
+
|
|
117
|
+
/** wrap text */
|
|
118
|
+
wrap?: boolean;
|
|
119
|
+
|
|
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;
|
|
125
|
+
|
|
126
|
+
/** font face. this can be a comma-delimited list, like CSS */
|
|
127
|
+
font_face?: string;
|
|
128
|
+
|
|
129
|
+
/** flag */
|
|
130
|
+
bold?: boolean; // FIXME: switch to weight
|
|
131
|
+
|
|
132
|
+
/** flag */
|
|
133
|
+
italic?: boolean;
|
|
134
|
+
|
|
135
|
+
/** flag */
|
|
136
|
+
underline?: boolean;
|
|
137
|
+
|
|
138
|
+
/** flag */
|
|
139
|
+
strike?: boolean;
|
|
140
|
+
|
|
141
|
+
// font_weight?: number;
|
|
142
|
+
|
|
143
|
+
/** border weight */
|
|
144
|
+
border_top?: number;
|
|
145
|
+
|
|
146
|
+
/** border weight */
|
|
147
|
+
border_right?: number;
|
|
148
|
+
|
|
149
|
+
/** border weight */
|
|
150
|
+
border_left?: number;
|
|
151
|
+
|
|
152
|
+
/** border weight */
|
|
153
|
+
border_bottom?: number;
|
|
154
|
+
|
|
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".
|
|
159
|
+
|
|
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;
|
|
167
|
+
|
|
168
|
+
// changing colors to support styles... starting with text
|
|
169
|
+
|
|
170
|
+
/** text color */
|
|
171
|
+
text?: Color;
|
|
172
|
+
|
|
173
|
+
/** background color */
|
|
174
|
+
fill?: Color;
|
|
175
|
+
|
|
176
|
+
/** border color */
|
|
177
|
+
border_top_fill?: Color;
|
|
178
|
+
|
|
179
|
+
/** border color */
|
|
180
|
+
border_left_fill?: Color;
|
|
181
|
+
|
|
182
|
+
/** border color */
|
|
183
|
+
border_right_fill?: Color;
|
|
184
|
+
|
|
185
|
+
/** border color */
|
|
186
|
+
border_bottom_fill?: Color;
|
|
187
|
+
|
|
188
|
+
// NEW
|
|
189
|
+
// FIXME: change name to editable, default true? (...)
|
|
190
|
+
|
|
191
|
+
// this is not properly in style -- should be in cell
|
|
192
|
+
|
|
193
|
+
// UPDATE: whether it's appropriate or not, style is a better place
|
|
194
|
+
// because it can cascade
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* cell is locked for editing
|
|
198
|
+
*/
|
|
199
|
+
locked?: boolean;
|
|
200
|
+
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/** @internal */
|
|
204
|
+
export type PropertyKeys = keyof Style.Properties;
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* note that there are no default colors; those should be set
|
|
208
|
+
* in grid when style is applied. that way the default colors for
|
|
209
|
+
* border, text and background colors will be theme-dependent and
|
|
210
|
+
* can change.
|
|
211
|
+
*
|
|
212
|
+
* @internal
|
|
213
|
+
*/
|
|
214
|
+
export const DefaultProperties: Properties = {
|
|
215
|
+
horizontal_align: HorizontalAlign.None,
|
|
216
|
+
vertical_align: VerticalAlign.None,
|
|
217
|
+
number_format: 'General', // '0.######', // use symbolic, e.g. "general"
|
|
218
|
+
nan: 'NaN',
|
|
219
|
+
// font_size: 10, // should have units
|
|
220
|
+
|
|
221
|
+
font_size: { unit: 'pt', value: 10.5 },
|
|
222
|
+
font_face: 'sans-serif',
|
|
223
|
+
|
|
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
|
+
bold: false, // drop "font_"
|
|
235
|
+
italic: false, // ...
|
|
236
|
+
underline: false, // ...
|
|
237
|
+
strike: false, //
|
|
238
|
+
// background: 'none',
|
|
239
|
+
|
|
240
|
+
// text_color: 'none',
|
|
241
|
+
// text: 'theme',
|
|
242
|
+
// text_theme: 0,
|
|
243
|
+
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
|
+
|
|
250
|
+
border_top: 0, // adding defaults so these prune propery
|
|
251
|
+
border_left: 0,
|
|
252
|
+
border_right: 0,
|
|
253
|
+
border_bottom: 0,
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* this is a utility function for callers that use borders, to
|
|
258
|
+
* reduce testing and facilitate reusable methods
|
|
259
|
+
*
|
|
260
|
+
* @internal
|
|
261
|
+
*/
|
|
262
|
+
export const CompositeBorders = (style: Properties): CompositeBorder => {
|
|
263
|
+
return {
|
|
264
|
+
top: {
|
|
265
|
+
width: style.border_top || 0,
|
|
266
|
+
color: style.border_top_fill || {},
|
|
267
|
+
},
|
|
268
|
+
left: {
|
|
269
|
+
width: style.border_left || 0,
|
|
270
|
+
color: style.border_left_fill || {},
|
|
271
|
+
},
|
|
272
|
+
right: {
|
|
273
|
+
width: style.border_right || 0,
|
|
274
|
+
color: style.border_right_fill || {},
|
|
275
|
+
},
|
|
276
|
+
bottom: {
|
|
277
|
+
width: style.border_bottom || 0,
|
|
278
|
+
color: style.border_bottom_fill || {},
|
|
279
|
+
},
|
|
280
|
+
};
|
|
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
|
+
*/
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* merge. returns a new object, does not update dest in place.
|
|
295
|
+
* NOTE: if it does not update dest in place, then what would be
|
|
296
|
+
* the use case for a non-delta merge? (...)
|
|
297
|
+
*
|
|
298
|
+
* @internal
|
|
299
|
+
*/
|
|
300
|
+
export const Merge = (dest: Properties, src: Properties, delta = true): Properties => {
|
|
301
|
+
const properties: Properties = delta ? {...dest, ...src} : {...src};
|
|
302
|
+
return JSON.parse(JSON.stringify(properties));
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
/** @internal */
|
|
306
|
+
export const Composite = (list: Properties[]): Properties => {
|
|
307
|
+
return JSON.parse(JSON.stringify(list.reduce((composite, item) => ({...composite, ...item}), {})));
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
/** @internal */
|
|
311
|
+
export const Empty = (style: Properties): boolean => {
|
|
312
|
+
return JSON.stringify(style) === empty_json;
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
/** @internal */
|
|
316
|
+
export const ValidColor = (color?: Color): boolean => {
|
|
317
|
+
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
|
+
*/
|
|
371
|
+
|
|
372
|
+
/** @internal */
|
|
373
|
+
export const ParseFontSize = (text = '', default_unit = 'em'): Properties => {
|
|
374
|
+
const match = text.match(/(-*[\d.]+)\s*(\S*)/);
|
|
375
|
+
|
|
376
|
+
if (match) {
|
|
377
|
+
const value = Number(match[1]);
|
|
378
|
+
if (!value || isNaN(value) || value < 0) {
|
|
379
|
+
return {}; // invalid
|
|
380
|
+
}
|
|
381
|
+
const unit = match[2].toLowerCase() || default_unit;
|
|
382
|
+
if (unit === 'pt' || unit === 'em' || unit === '%' || unit === 'px') {
|
|
383
|
+
// return { font_size_unit: unit, font_size_value: value };
|
|
384
|
+
return {
|
|
385
|
+
font_size: { unit, value },
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
return {};
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* returns the font size of the properties argument as a ratio of the
|
|
395
|
+
* base argument. this is intended to show the relative font size of
|
|
396
|
+
* a spreadsheet cell; so anything with no value should be "1", and
|
|
397
|
+
* everything else is relative to that.
|
|
398
|
+
*
|
|
399
|
+
* we prefer relative sizes (em, essentially) to fixed sizes because
|
|
400
|
+
* we may have different base font sizes on different platforms (we do,
|
|
401
|
+
* in fact, on windows because calibri is too small).
|
|
402
|
+
*
|
|
403
|
+
* using relative sizes helps ensure that it looks similar, if not
|
|
404
|
+
* identical, on different platforms.
|
|
405
|
+
*
|
|
406
|
+
* @internal
|
|
407
|
+
*/
|
|
408
|
+
export const RelativeFontSize = (properties: Properties, base: Properties): number => {
|
|
409
|
+
|
|
410
|
+
// we can assume (I think) that base will be either points or px;
|
|
411
|
+
// there's no case where it should be relative. in fact, let's treat
|
|
412
|
+
// that as an error and return 1.
|
|
413
|
+
|
|
414
|
+
// note that if properties is relative (em or %) we don't have to
|
|
415
|
+
// calculate, it's implicit
|
|
416
|
+
|
|
417
|
+
let base_pt = 12;
|
|
418
|
+
let props_pt = 12;
|
|
419
|
+
|
|
420
|
+
switch (properties.font_size?.unit) {
|
|
421
|
+
case 'pt':
|
|
422
|
+
if (!properties.font_size.value) { return 1; } // also error
|
|
423
|
+
props_pt = properties.font_size.value;
|
|
424
|
+
break;
|
|
425
|
+
|
|
426
|
+
case 'px':
|
|
427
|
+
if (!properties.font_size.value) { return 1; } // also error
|
|
428
|
+
props_pt = Math.round(properties.font_size.value * 300 / 4) / 100;
|
|
429
|
+
break;
|
|
430
|
+
|
|
431
|
+
case 'em':
|
|
432
|
+
return (properties.font_size.value || 1); // short circuit
|
|
433
|
+
|
|
434
|
+
case '%':
|
|
435
|
+
return (properties.font_size.value || 100) / 100; // short circuit
|
|
436
|
+
|
|
437
|
+
default:
|
|
438
|
+
return 1; // error
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
switch (base.font_size?.unit) {
|
|
442
|
+
case 'pt':
|
|
443
|
+
if (!base.font_size.value) { return 1; } // also error
|
|
444
|
+
base_pt = base.font_size.value;
|
|
445
|
+
break;
|
|
446
|
+
|
|
447
|
+
case 'px':
|
|
448
|
+
if (!base.font_size.value) { return 1; } // also error
|
|
449
|
+
base_pt = Math.round(base.font_size.value * 300 / 4) / 100;
|
|
450
|
+
break;
|
|
451
|
+
|
|
452
|
+
default:
|
|
453
|
+
return 1; // error
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
return props_pt / base_pt;
|
|
457
|
+
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
/** @internal */
|
|
461
|
+
export const FontSize = (properties: Properties, prefer_points = true): string => {
|
|
462
|
+
|
|
463
|
+
const value = properties.font_size?.value;
|
|
464
|
+
|
|
465
|
+
switch (properties.font_size?.unit) {
|
|
466
|
+
case 'pt':
|
|
467
|
+
return (value||12) + 'pt';
|
|
468
|
+
|
|
469
|
+
case 'px':
|
|
470
|
+
if (prefer_points) {
|
|
471
|
+
const points = Math.round((value||16) * 300 / 4) / 100;
|
|
472
|
+
return (points) + 'pt';
|
|
473
|
+
}
|
|
474
|
+
return (value||16) + 'px';
|
|
475
|
+
|
|
476
|
+
case 'em':
|
|
477
|
+
return (value||1) + 'em';
|
|
478
|
+
|
|
479
|
+
case '%':
|
|
480
|
+
return (value||100) + '%';
|
|
481
|
+
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
return '';
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* returns a string representation suitable for canvas (or style)
|
|
489
|
+
*
|
|
490
|
+
* @internal
|
|
491
|
+
*/
|
|
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
|
+
*/
|
|
506
|
+
|
|
507
|
+
const parts: string[] = [];
|
|
508
|
+
|
|
509
|
+
//if (properties.font_weight) {
|
|
510
|
+
// parts.push(properties.font_weight.toString());
|
|
511
|
+
//}
|
|
512
|
+
//else
|
|
513
|
+
if (properties.bold) {
|
|
514
|
+
parts.push('bold');
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
if (properties.italic) {
|
|
518
|
+
parts.push('italic');
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
parts.push(((properties.font_size?.value || 0) * scale).toFixed(2) +
|
|
522
|
+
(properties.font_size?.unit || 'pt'));
|
|
523
|
+
|
|
524
|
+
parts.push(properties.font_face || '');
|
|
525
|
+
|
|
526
|
+
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
|
+
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
}
|