@lotics/xlsx 0.1.0

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 (90) hide show
  1. package/package.json +30 -0
  2. package/src/auto_sum.test.ts +71 -0
  3. package/src/auto_sum.ts +83 -0
  4. package/src/canvas_cf.ts +135 -0
  5. package/src/canvas_chart.ts +687 -0
  6. package/src/canvas_fill.ts +156 -0
  7. package/src/canvas_images.ts +99 -0
  8. package/src/canvas_layout.test.ts +159 -0
  9. package/src/canvas_layout.ts +239 -0
  10. package/src/canvas_renderer.ts +1010 -0
  11. package/src/canvas_shape.ts +242 -0
  12. package/src/canvas_sparkline.ts +163 -0
  13. package/src/canvas_text.ts +454 -0
  14. package/src/cell_editor.ts +558 -0
  15. package/src/clipboard.test.ts +145 -0
  16. package/src/clipboard.ts +341 -0
  17. package/src/command_history.ts +102 -0
  18. package/src/csv_parser.test.ts +130 -0
  19. package/src/csv_parser.ts +172 -0
  20. package/src/data_validation.test.ts +95 -0
  21. package/src/data_validation.ts +114 -0
  22. package/src/editing_layer.test.ts +309 -0
  23. package/src/excel_cf_evaluate.test.ts +293 -0
  24. package/src/excel_cf_evaluate.ts +719 -0
  25. package/src/excel_cf_icons.ts +108 -0
  26. package/src/excel_cf_types.ts +67 -0
  27. package/src/excel_numfmt.test.ts +607 -0
  28. package/src/excel_numfmt.ts +1033 -0
  29. package/src/excel_parser.test.ts +1061 -0
  30. package/src/excel_parser.ts +393 -0
  31. package/src/excel_pattern_fills.ts +64 -0
  32. package/src/excel_table_styles.ts +160 -0
  33. package/src/excel_utils.test.ts +108 -0
  34. package/src/excel_utils.ts +162 -0
  35. package/src/fast-formula-parser.d.ts +53 -0
  36. package/src/fill_logic.ts +257 -0
  37. package/src/fill_patterns.test.ts +90 -0
  38. package/src/fill_patterns.ts +71 -0
  39. package/src/flash_fill.test.ts +75 -0
  40. package/src/flash_fill.ts +221 -0
  41. package/src/formula_deps.ts +189 -0
  42. package/src/formula_engine.test.ts +348 -0
  43. package/src/formula_engine.ts +401 -0
  44. package/src/formula_highlight.test.ts +81 -0
  45. package/src/formula_highlight.ts +139 -0
  46. package/src/formula_suggest.ts +100 -0
  47. package/src/hidden_sheets.test.ts +49 -0
  48. package/src/index.ts +149 -0
  49. package/src/keyboard_nav.test.ts +394 -0
  50. package/src/keyboard_nav.ts +891 -0
  51. package/src/move_logic.ts +63 -0
  52. package/src/numfmt_type.test.ts +158 -0
  53. package/src/numfmt_type.ts +231 -0
  54. package/src/ooxml_cell_format.ts +70 -0
  55. package/src/ooxml_chart.test.ts +85 -0
  56. package/src/ooxml_chart.ts +347 -0
  57. package/src/ooxml_chart_types.ts +207 -0
  58. package/src/ooxml_color.ts +339 -0
  59. package/src/ooxml_drawing.test.ts +87 -0
  60. package/src/ooxml_drawing.ts +287 -0
  61. package/src/ooxml_pivot.test.ts +195 -0
  62. package/src/ooxml_pivot.ts +468 -0
  63. package/src/ooxml_pivot_types.ts +165 -0
  64. package/src/ooxml_shape.ts +355 -0
  65. package/src/ooxml_sheet.ts +1271 -0
  66. package/src/ooxml_styles.ts +556 -0
  67. package/src/ooxml_table.test.ts +70 -0
  68. package/src/ooxml_table.ts +131 -0
  69. package/src/ooxml_workbook.test.ts +40 -0
  70. package/src/ooxml_workbook.ts +259 -0
  71. package/src/ooxml_zip.ts +33 -0
  72. package/src/pivot_model.ts +237 -0
  73. package/src/pivot_recompute.test.ts +210 -0
  74. package/src/pivot_recompute.ts +413 -0
  75. package/src/selection_model.ts +364 -0
  76. package/src/spreadsheet_commands.test.ts +772 -0
  77. package/src/spreadsheet_commands.ts +1805 -0
  78. package/src/structured_refs.test.ts +128 -0
  79. package/src/structured_refs.ts +160 -0
  80. package/src/style_helpers.test.ts +33 -0
  81. package/src/style_helpers.ts +30 -0
  82. package/src/template_builder.test.ts +139 -0
  83. package/src/template_builder.ts +36 -0
  84. package/src/types.ts +239 -0
  85. package/src/workbook_model.test.ts +536 -0
  86. package/src/workbook_model.ts +911 -0
  87. package/src/xlsx_round_trip.test.ts +279 -0
  88. package/src/xlsx_writer.test.ts +488 -0
  89. package/src/xlsx_writer.ts +1549 -0
  90. package/src/xml_entities.ts +23 -0
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Inline SVG icons for conditional formatting icon sets.
3
+ * Each icon is a small 16x16 SVG returned as a data URI.
4
+ */
5
+
6
+ const SVG_PREFIX = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16">';
7
+ const SVG_SUFFIX = "</svg>";
8
+
9
+ function svg(body: string): string {
10
+ return `data:image/svg+xml,${encodeURIComponent(SVG_PREFIX + body + SVG_SUFFIX)}`;
11
+ }
12
+
13
+ // Arrow icons
14
+ const arrowUp = (color: string) => svg(`<path d="M8 2l5 8H3z" fill="${color}"/>`);
15
+ const arrowRight = (color: string) => svg(`<path d="M2 4h8l-4 8z" fill="${color}" transform="rotate(-90 8 8)"/>`);
16
+ const arrowDown = (color: string) => svg(`<path d="M8 14l5-8H3z" fill="${color}"/>`);
17
+ const arrowUpRight = (color: string) => svg(`<path d="M4 12L12 4M12 4H6M12 4v6" stroke="${color}" stroke-width="2" fill="none"/>`);
18
+ const arrowDownRight = (color: string) => svg(`<path d="M4 4L12 12M12 12H6M12 12V6" stroke="${color}" stroke-width="2" fill="none"/>`);
19
+
20
+ // Circle/traffic light icons
21
+ const circle = (color: string) => svg(`<circle cx="8" cy="8" r="6" fill="${color}"/>`);
22
+
23
+ // Flag icons
24
+ const flag = (color: string) => svg(`<path d="M3 2v12M3 2h8l-2 3 2 3H3" fill="${color}" stroke="${color}" stroke-width="1"/>`);
25
+
26
+ // Star icons
27
+ const star = (color: string) => svg(
28
+ `<path d="M8 1l2.2 4.5 5 .7-3.6 3.5.9 5L8 12.5 3.5 14.7l.9-5L0.8 6.2l5-.7z" fill="${color}"/>`,
29
+ );
30
+ const starEmpty = svg(
31
+ `<path d="M8 1l2.2 4.5 5 .7-3.6 3.5.9 5L8 12.5 3.5 14.7l.9-5L0.8 6.2l5-.7z" fill="none" stroke="#999" stroke-width="1"/>`,
32
+ );
33
+
34
+ // Diamond icons
35
+ const diamond = (color: string) => svg(`<path d="M8 1L15 8L8 15L1 8z" fill="${color}"/>`);
36
+
37
+ // Triangle icons
38
+ const triangleUp = (color: string) => svg(`<path d="M8 3l5 10H3z" fill="${color}"/>`);
39
+ const triangleDash = (color: string) => svg(`<rect x="2" y="6" width="12" height="4" rx="1" fill="${color}"/>`);
40
+ const triangleDown = (color: string) => svg(`<path d="M8 13l5-10H3z" fill="${color}"/>`);
41
+
42
+ // Quarter icons (pie chart segments)
43
+ const quarter0 = svg(`<circle cx="8" cy="8" r="6" fill="none" stroke="#666" stroke-width="1.5"/>`);
44
+ const quarter1 = svg(`<circle cx="8" cy="8" r="6" fill="none" stroke="#666" stroke-width="1.5"/><path d="M8 2a6 6 0 0 1 6 6H8z" fill="#666"/>`);
45
+ const quarter2 = svg(`<circle cx="8" cy="8" r="6" fill="none" stroke="#666" stroke-width="1.5"/><path d="M8 2a6 6 0 0 1 0 12V2z" fill="#666"/>`);
46
+ const quarter3 = svg(`<circle cx="8" cy="8" r="6" fill="none" stroke="#666" stroke-width="1.5"/><path d="M8 2a6 6 0 0 1 0 12A6 6 0 0 1 2 8h6z" fill="#666"/>`);
47
+ const quarter4 = svg(`<circle cx="8" cy="8" r="6" fill="#666"/>`);
48
+
49
+ // Box icons (rating bars)
50
+ const box = (fill: boolean) => fill
51
+ ? svg(`<rect x="1" y="4" width="14" height="8" rx="1" fill="#666"/>`)
52
+ : svg(`<rect x="1" y="4" width="14" height="8" rx="1" fill="none" stroke="#999" stroke-width="1"/>`);
53
+
54
+ // Sign icons
55
+ const signTriangle = (color: string) => svg(`<path d="M8 2l6.5 12H1.5z" fill="${color}"/>`);
56
+ const signCircle = (color: string) => svg(`<circle cx="8" cy="8" r="7" fill="${color}"/>`);
57
+
58
+ // Symbol icons (check/exclamation/X)
59
+ const symbolCheck = (color: string) => svg(`<circle cx="8" cy="8" r="7" fill="${color}"/><path d="M4.5 8l2 2 5-5" stroke="white" stroke-width="2" fill="none"/>`);
60
+ const symbolExcl = (color: string) => svg(`<circle cx="8" cy="8" r="7" fill="${color}"/><text x="8" y="12" text-anchor="middle" fill="white" font-size="11" font-weight="bold">!</text>`);
61
+ const symbolX = (color: string) => svg(`<circle cx="8" cy="8" r="7" fill="${color}"/><path d="M5 5l6 6M11 5l-6 6" stroke="white" stroke-width="2"/>`);
62
+
63
+ // =============================================================================
64
+ // Icon set definitions
65
+ // =============================================================================
66
+
67
+ type IconSetDef = string[];
68
+
69
+ const ICON_SETS: Record<string, IconSetDef> = {
70
+ // 3-icon sets
71
+ "3Arrows": [arrowDown("#F44336"), arrowRight("#FFC107"), arrowUp("#4CAF50")],
72
+ "3ArrowsGray": [arrowDown("#666"), arrowRight("#999"), arrowUp("#333")],
73
+ "3Flags": [flag("#F44336"), flag("#FFC107"), flag("#4CAF50")],
74
+ "3Signs": [diamond("#F44336"), signTriangle("#FFC107"), signCircle("#4CAF50")],
75
+ "3Stars": [starEmpty, star("#FFC107"), star("#FFC107")],
76
+ "3Symbols": [symbolX("#F44336"), symbolExcl("#FFC107"), symbolCheck("#4CAF50")],
77
+ "3Symbols2": [symbolX("#F44336"), symbolExcl("#FFC107"), symbolCheck("#4CAF50")],
78
+ "3TrafficLights1": [circle("#F44336"), circle("#FFC107"), circle("#4CAF50")],
79
+ "3TrafficLights2": [circle("#F44336"), circle("#FFC107"), circle("#4CAF50")],
80
+ "3Triangles": [triangleDown("#F44336"), triangleDash("#FFC107"), triangleUp("#4CAF50")],
81
+
82
+ // 4-icon sets
83
+ "4Arrows": [arrowDown("#F44336"), arrowDownRight("#FF9800"), arrowUpRight("#FFC107"), arrowUp("#4CAF50")],
84
+ "4ArrowsGray": [arrowDown("#666"), arrowDownRight("#888"), arrowUpRight("#AAA"), arrowUp("#333")],
85
+ "4Rating": [box(false), box(true), box(true), box(true)],
86
+ "4RedToBlack": [circle("#000"), circle("#666"), circle("#FF9800"), circle("#F44336")],
87
+ "4TrafficLights": [circle("#000"), circle("#F44336"), circle("#FFC107"), circle("#4CAF50")],
88
+
89
+ // 5-icon sets
90
+ "5Arrows": [arrowDown("#F44336"), arrowDownRight("#FF9800"), arrowRight("#FFC107"), arrowUpRight("#8BC34A"), arrowUp("#4CAF50")],
91
+ "5ArrowsGray": [arrowDown("#666"), arrowDownRight("#777"), arrowRight("#888"), arrowUpRight("#999"), arrowUp("#333")],
92
+ "5Boxes": [box(false), box(true), box(true), box(true), box(true)],
93
+ "5Quarters": [quarter0, quarter1, quarter2, quarter3, quarter4],
94
+ "5Rating": [box(false), box(true), box(true), box(true), box(true)],
95
+
96
+ // NoIcons - empty set
97
+ NoIcons: [],
98
+ };
99
+
100
+ /**
101
+ * Get the SVG data URI for a specific icon in an icon set.
102
+ * Returns undefined if the icon set or index is invalid.
103
+ */
104
+ export function getCfIcon(iconSet: string, index: number): string | undefined {
105
+ const icons = ICON_SETS[iconSet];
106
+ if (!icons || index < 0 || index >= icons.length) return undefined;
107
+ return icons[index];
108
+ }
@@ -0,0 +1,67 @@
1
+ export interface ParsedConditionalFormat {
2
+ ref: string;
3
+ rules: ParsedCfRule[];
4
+ }
5
+
6
+ export type ParsedCfRule =
7
+ | ParsedColorScaleRule
8
+ | ParsedDataBarRule
9
+ | ParsedIconSetRule
10
+ | ParsedStyleRule;
11
+
12
+ export interface CfThreshold {
13
+ type: "percentile" | "percent" | "num" | "min" | "max" | "formula" | "autoMin" | "autoMax";
14
+ value?: number;
15
+ }
16
+
17
+ export interface ParsedColorScaleRule {
18
+ ruleType: "colorScale";
19
+ priority: number;
20
+ /** Excel's <cfRule stopIfTrue="1">: when this rule matches a cell, lower-
21
+ * priority rules on the same cell are skipped. */
22
+ stopIfTrue?: boolean;
23
+ colors: string[];
24
+ }
25
+
26
+ export interface ParsedDataBarRule {
27
+ ruleType: "dataBar";
28
+ priority: number;
29
+ stopIfTrue?: boolean;
30
+ color: string;
31
+ minLength: number;
32
+ maxLength: number;
33
+ showValue: boolean;
34
+ }
35
+
36
+ export interface ParsedIconSetRule {
37
+ ruleType: "iconSet";
38
+ priority: number;
39
+ stopIfTrue?: boolean;
40
+ iconSet: string;
41
+ thresholds: CfThreshold[];
42
+ showValue: boolean;
43
+ reverse: boolean;
44
+ }
45
+
46
+ export interface ParsedStyleRule {
47
+ ruleType: "style";
48
+ priority: number;
49
+ stopIfTrue?: boolean;
50
+ type: "cellIs" | "containsText" | "top10" | "aboveAverage" | "timePeriod" | "expression";
51
+ operator?: string;
52
+ formulae?: unknown[];
53
+ text?: string;
54
+ rank?: number;
55
+ percent?: boolean;
56
+ bottom?: boolean;
57
+ aboveAverage?: boolean;
58
+ timePeriod?: string;
59
+ style?: ParsedCfStyle;
60
+ }
61
+
62
+ export interface ParsedCfStyle {
63
+ fontBold?: boolean;
64
+ fontItalic?: boolean;
65
+ fontColor?: string;
66
+ backgroundColor?: string;
67
+ }