@rowsncolumns/spreadsheet 10.5.17 → 10.6.4

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 (202) hide show
  1. package/dist/cjs/api/cf-data-bar.d.ts +73 -0
  2. package/dist/cjs/api/cf-data-bar.d.ts.map +1 -0
  3. package/dist/cjs/api/cf-data-bar.js +182 -0
  4. package/dist/cjs/api/cf-icons.d.ts +73 -0
  5. package/dist/cjs/api/cf-icons.d.ts.map +1 -0
  6. package/dist/cjs/api/cf-icons.js +322 -0
  7. package/dist/cjs/api/cf-overlays.d.ts +89 -3
  8. package/dist/cjs/api/cf-overlays.d.ts.map +1 -1
  9. package/dist/cjs/api/cf-overlays.js +256 -80
  10. package/dist/cjs/api/cf-priority.d.ts +34 -0
  11. package/dist/cjs/api/cf-priority.d.ts.map +1 -0
  12. package/dist/cjs/api/cf-priority.js +94 -0
  13. package/dist/cjs/api/heatmap.d.ts +7 -1
  14. package/dist/cjs/api/heatmap.d.ts.map +1 -1
  15. package/dist/cjs/api/heatmap.js +27 -11
  16. package/dist/cjs/api/selections.d.ts +2 -2
  17. package/dist/cjs/api/validation.d.ts +6 -0
  18. package/dist/cjs/api/validation.d.ts.map +1 -1
  19. package/dist/cjs/api/validation.js +10 -1
  20. package/dist/cjs/atoms/goal-seek-dialog.atom.d.ts +8 -3
  21. package/dist/cjs/atoms/goal-seek-dialog.atom.d.ts.map +1 -1
  22. package/dist/cjs/atoms/index.d.ts +4 -0
  23. package/dist/cjs/atoms/index.d.ts.map +1 -1
  24. package/dist/cjs/atoms/index.js +4 -0
  25. package/dist/cjs/components/canvas-grid/index.d.ts.map +1 -1
  26. package/dist/cjs/components/canvas-grid/index.js +194 -51
  27. package/dist/cjs/components/canvas-grid/overflow.d.ts +37 -0
  28. package/dist/cjs/components/canvas-grid/overflow.d.ts.map +1 -0
  29. package/dist/cjs/components/canvas-grid/overflow.js +49 -0
  30. package/dist/cjs/components/canvas-grid/page-breaks.d.ts +15 -0
  31. package/dist/cjs/components/canvas-grid/page-breaks.d.ts.map +1 -0
  32. package/dist/cjs/components/canvas-grid/page-breaks.js +77 -0
  33. package/dist/cjs/components/canvas-grid/typings.d.ts +32 -3
  34. package/dist/cjs/components/canvas-grid/typings.d.ts.map +1 -1
  35. package/dist/cjs/components/cell/alignment.d.ts +58 -1
  36. package/dist/cjs/components/cell/alignment.d.ts.map +1 -1
  37. package/dist/cjs/components/cell/alignment.js +144 -1
  38. package/dist/cjs/components/cell/cell-background.d.ts +2 -0
  39. package/dist/cjs/components/cell/cell-background.d.ts.map +1 -1
  40. package/dist/cjs/components/cell/cell-background.js +5 -6
  41. package/dist/cjs/components/cell/cell-backgrounds.d.ts.map +1 -1
  42. package/dist/cjs/components/cell/cell-backgrounds.js +5 -1
  43. package/dist/cjs/components/cell/cell-text-runs.js +1 -1
  44. package/dist/cjs/components/cell/index.d.ts.map +1 -1
  45. package/dist/cjs/components/cell/index.js +378 -37
  46. package/dist/cjs/components/cell/number-format-layout.d.ts +35 -0
  47. package/dist/cjs/components/cell/number-format-layout.d.ts.map +1 -0
  48. package/dist/cjs/components/cell/number-format-layout.js +106 -0
  49. package/dist/cjs/components/cell/typings.d.ts +22 -0
  50. package/dist/cjs/components/cell/typings.d.ts.map +1 -1
  51. package/dist/cjs/components/cell-editor/index.js +2 -2
  52. package/dist/cjs/components/cell-filter/index.d.ts.map +1 -1
  53. package/dist/cjs/components/cell-filter/index.js +3 -3
  54. package/dist/cjs/components/cell-overlay/index.d.ts +20 -0
  55. package/dist/cjs/components/cell-overlay/index.d.ts.map +1 -1
  56. package/dist/cjs/components/cell-overlay/index.js +155 -28
  57. package/dist/cjs/components/cf-icon-preview/index.d.ts +16 -0
  58. package/dist/cjs/components/cf-icon-preview/index.d.ts.map +1 -0
  59. package/dist/cjs/components/cf-icon-preview/index.js +48 -0
  60. package/dist/cjs/components/context-menu/index.d.ts.map +1 -1
  61. package/dist/cjs/components/context-menu/index.js +11 -3
  62. package/dist/cjs/components/embeds/embed-component.d.ts.map +1 -1
  63. package/dist/cjs/components/embeds/embed-component.js +3 -2
  64. package/dist/cjs/components/goal-seek-dialog/index.d.ts +15 -5
  65. package/dist/cjs/components/goal-seek-dialog/index.d.ts.map +1 -1
  66. package/dist/cjs/components/goal-seek-dialog/index.js +145 -42
  67. package/dist/cjs/components/hidden-markers/index.d.ts.map +1 -1
  68. package/dist/cjs/components/hidden-markers/index.js +8 -7
  69. package/dist/cjs/components/hidden-markers/style.d.ts +7 -0
  70. package/dist/cjs/components/hidden-markers/style.d.ts.map +1 -1
  71. package/dist/cjs/components/hidden-markers/style.js +13 -2
  72. package/dist/cjs/components/protect-sheet-dialog/index.d.ts +67 -0
  73. package/dist/cjs/components/protect-sheet-dialog/index.d.ts.map +1 -0
  74. package/dist/cjs/components/protect-sheet-dialog/index.js +196 -0
  75. package/dist/cjs/components/toolbar/types.d.ts +1 -1
  76. package/dist/cjs/components/toolbar/types.d.ts.map +1 -1
  77. package/dist/cjs/config.d.ts +13 -1
  78. package/dist/cjs/config.d.ts.map +1 -1
  79. package/dist/cjs/config.js +15 -3
  80. package/dist/cjs/helpers.d.ts +10 -5
  81. package/dist/cjs/helpers.d.ts.map +1 -1
  82. package/dist/cjs/helpers.js +43 -31
  83. package/dist/cjs/hooks/use-border-styles.d.ts.map +1 -1
  84. package/dist/cjs/hooks/use-border-styles.js +5 -28
  85. package/dist/cjs/hooks/use-cell-renderer.d.ts +35 -3
  86. package/dist/cjs/hooks/use-cell-renderer.d.ts.map +1 -1
  87. package/dist/cjs/hooks/use-cell-renderer.js +85 -47
  88. package/dist/cjs/hooks/use-conditional-formatting.d.ts +13 -1
  89. package/dist/cjs/hooks/use-conditional-formatting.d.ts.map +1 -1
  90. package/dist/cjs/hooks/use-conditional-formatting.js +281 -230
  91. package/dist/cjs/index.d.ts +7 -0
  92. package/dist/cjs/index.d.ts.map +1 -1
  93. package/dist/cjs/index.js +13 -1
  94. package/dist/cjs/release-date.js +1 -1
  95. package/dist/cjs/themes.d.ts +8 -0
  96. package/dist/cjs/themes.d.ts.map +1 -1
  97. package/dist/cjs/themes.js +21 -3
  98. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  99. package/dist/cjs/types.d.ts +115 -5
  100. package/dist/cjs/types.d.ts.map +1 -1
  101. package/dist/esm/api/cf-data-bar.d.ts +73 -0
  102. package/dist/esm/api/cf-data-bar.d.ts.map +1 -0
  103. package/dist/esm/api/cf-data-bar.js +178 -0
  104. package/dist/esm/api/cf-icons.d.ts +73 -0
  105. package/dist/esm/api/cf-icons.d.ts.map +1 -0
  106. package/dist/esm/api/cf-icons.js +306 -0
  107. package/dist/esm/api/cf-overlays.d.ts +89 -3
  108. package/dist/esm/api/cf-overlays.d.ts.map +1 -1
  109. package/dist/esm/api/cf-overlays.js +223 -67
  110. package/dist/esm/api/cf-priority.d.ts +34 -0
  111. package/dist/esm/api/cf-priority.d.ts.map +1 -0
  112. package/dist/esm/api/cf-priority.js +61 -0
  113. package/dist/esm/api/heatmap.d.ts +7 -1
  114. package/dist/esm/api/heatmap.d.ts.map +1 -1
  115. package/dist/esm/api/heatmap.js +24 -9
  116. package/dist/esm/api/selections.d.ts +2 -2
  117. package/dist/esm/api/validation.d.ts +6 -0
  118. package/dist/esm/api/validation.d.ts.map +1 -1
  119. package/dist/esm/api/validation.js +6 -0
  120. package/dist/esm/atoms/goal-seek-dialog.atom.d.ts +8 -3
  121. package/dist/esm/atoms/goal-seek-dialog.atom.d.ts.map +1 -1
  122. package/dist/esm/atoms/index.d.ts +4 -0
  123. package/dist/esm/atoms/index.d.ts.map +1 -1
  124. package/dist/esm/atoms/index.js +4 -0
  125. package/dist/esm/components/canvas-grid/index.d.ts.map +1 -1
  126. package/dist/esm/components/canvas-grid/index.js +163 -47
  127. package/dist/esm/components/canvas-grid/overflow.d.ts +37 -0
  128. package/dist/esm/components/canvas-grid/overflow.d.ts.map +1 -0
  129. package/dist/esm/components/canvas-grid/overflow.js +39 -0
  130. package/dist/esm/components/canvas-grid/page-breaks.d.ts +15 -0
  131. package/dist/esm/components/canvas-grid/page-breaks.d.ts.map +1 -0
  132. package/dist/esm/components/canvas-grid/page-breaks.js +50 -0
  133. package/dist/esm/components/canvas-grid/typings.d.ts +32 -3
  134. package/dist/esm/components/canvas-grid/typings.d.ts.map +1 -1
  135. package/dist/esm/components/cell/alignment.d.ts +58 -1
  136. package/dist/esm/components/cell/alignment.d.ts.map +1 -1
  137. package/dist/esm/components/cell/alignment.js +110 -1
  138. package/dist/esm/components/cell/cell-background.d.ts +2 -0
  139. package/dist/esm/components/cell/cell-background.d.ts.map +1 -1
  140. package/dist/esm/components/cell/cell-background.js +4 -5
  141. package/dist/esm/components/cell/cell-backgrounds.d.ts.map +1 -1
  142. package/dist/esm/components/cell/cell-backgrounds.js +5 -1
  143. package/dist/esm/components/cell/cell-text-runs.js +2 -2
  144. package/dist/esm/components/cell/index.d.ts.map +1 -1
  145. package/dist/esm/components/cell/index.js +339 -39
  146. package/dist/esm/components/cell/number-format-layout.d.ts +35 -0
  147. package/dist/esm/components/cell/number-format-layout.d.ts.map +1 -0
  148. package/dist/esm/components/cell/number-format-layout.js +99 -0
  149. package/dist/esm/components/cell/typings.d.ts +22 -0
  150. package/dist/esm/components/cell/typings.d.ts.map +1 -1
  151. package/dist/esm/components/cell-editor/index.js +2 -2
  152. package/dist/esm/components/cell-filter/index.d.ts.map +1 -1
  153. package/dist/esm/components/cell-filter/index.js +4 -4
  154. package/dist/esm/components/cell-overlay/index.d.ts +20 -0
  155. package/dist/esm/components/cell-overlay/index.d.ts.map +1 -1
  156. package/dist/esm/components/cell-overlay/index.js +111 -25
  157. package/dist/esm/components/cf-icon-preview/index.d.ts +16 -0
  158. package/dist/esm/components/cf-icon-preview/index.d.ts.map +1 -0
  159. package/dist/esm/components/cf-icon-preview/index.js +41 -0
  160. package/dist/esm/components/context-menu/index.d.ts.map +1 -1
  161. package/dist/esm/components/context-menu/index.js +11 -3
  162. package/dist/esm/components/embeds/embed-component.d.ts.map +1 -1
  163. package/dist/esm/components/embeds/embed-component.js +4 -3
  164. package/dist/esm/components/goal-seek-dialog/index.d.ts +15 -5
  165. package/dist/esm/components/goal-seek-dialog/index.d.ts.map +1 -1
  166. package/dist/esm/components/goal-seek-dialog/index.js +126 -29
  167. package/dist/esm/components/hidden-markers/index.d.ts.map +1 -1
  168. package/dist/esm/components/hidden-markers/index.js +9 -8
  169. package/dist/esm/components/hidden-markers/style.d.ts +7 -0
  170. package/dist/esm/components/hidden-markers/style.d.ts.map +1 -1
  171. package/dist/esm/components/hidden-markers/style.js +8 -1
  172. package/dist/esm/components/protect-sheet-dialog/index.d.ts +67 -0
  173. package/dist/esm/components/protect-sheet-dialog/index.d.ts.map +1 -0
  174. package/dist/esm/components/protect-sheet-dialog/index.js +154 -0
  175. package/dist/esm/components/toolbar/types.d.ts +1 -1
  176. package/dist/esm/components/toolbar/types.d.ts.map +1 -1
  177. package/dist/esm/config.d.ts +13 -1
  178. package/dist/esm/config.d.ts.map +1 -1
  179. package/dist/esm/config.js +13 -1
  180. package/dist/esm/helpers.d.ts +10 -5
  181. package/dist/esm/helpers.d.ts.map +1 -1
  182. package/dist/esm/helpers.js +40 -28
  183. package/dist/esm/hooks/use-border-styles.d.ts.map +1 -1
  184. package/dist/esm/hooks/use-border-styles.js +5 -26
  185. package/dist/esm/hooks/use-cell-renderer.d.ts +35 -3
  186. package/dist/esm/hooks/use-cell-renderer.d.ts.map +1 -1
  187. package/dist/esm/hooks/use-cell-renderer.js +83 -42
  188. package/dist/esm/hooks/use-conditional-formatting.d.ts +13 -1
  189. package/dist/esm/hooks/use-conditional-formatting.d.ts.map +1 -1
  190. package/dist/esm/hooks/use-conditional-formatting.js +215 -120
  191. package/dist/esm/index.d.ts +7 -0
  192. package/dist/esm/index.d.ts.map +1 -1
  193. package/dist/esm/index.js +7 -0
  194. package/dist/esm/release-date.js +1 -1
  195. package/dist/esm/themes.d.ts +8 -0
  196. package/dist/esm/themes.d.ts.map +1 -1
  197. package/dist/esm/themes.js +20 -3
  198. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  199. package/dist/esm/types.d.ts +115 -5
  200. package/dist/esm/types.d.ts.map +1 -1
  201. package/dist/spreadsheet.min.css +1 -1
  202. package/package.json +4 -4
@@ -1,7 +1,93 @@
1
- import type { CfThreshold, IconSetFamily } from "../types";
1
+ import type { CellFormat, CfThreshold, ConditionalFormatRule, IconSetFamily } from "../types";
2
2
  export declare const ICON_SET_GLYPHS: Record<IconSetFamily, string[]>;
3
+ /** The colour each icon is painted in — what text stand-ins use. */
3
4
  export declare const ICON_SET_COLORS: Record<IconSetFamily, string[]>;
4
- export declare const resolveThreshold: (threshold: CfThreshold, rangeMin: number, rangeMax: number) => number;
5
- export declare const pickIconBucket: (value: number, sortedThresholds: number[]) => number;
5
+ /**
6
+ * Numeric statistics of a rule's covered cells — what cfvo thresholds
7
+ * resolve against. `sorted` (ascending) backs PERCENTILE thresholds; it may
8
+ * be omitted when the caller already knows the rule needs no percentile.
9
+ */
10
+ export type CfRangeStats = {
11
+ count: number;
12
+ min: number;
13
+ max: number;
14
+ sorted?: number[];
15
+ /**
16
+ * Engine-backed stand-ins for `sorted` on windowed hosts: PERCENTILE.INC
17
+ * at `p` (0..100), the k-th largest / smallest value (`k` a percent of the
18
+ * count when `percent`), the mean and the sample standard deviation.
19
+ */
20
+ percentile?: (p: number) => number;
21
+ rankValue?: (k: number, top: boolean, percent?: boolean) => number;
22
+ mean?: number;
23
+ stdDev?: number;
24
+ };
25
+ /** What a rule needs from its full-range statistics (the engine request). */
26
+ export type CfRuleStatsRequest = {
27
+ percentiles: number[];
28
+ ranks: Array<{
29
+ k: number;
30
+ top: boolean;
31
+ percent?: boolean;
32
+ }>;
33
+ };
34
+ /** The engine's reply to a {@link CfRuleStatsRequest} (`conditionalFormatRuleStats`). */
35
+ export type CfRuleStatsResponse = {
36
+ count: number;
37
+ min: number | null;
38
+ max: number | null;
39
+ mean: number | null;
40
+ stdDev: number | null;
41
+ percentiles: Array<number | null>;
42
+ ranks: Array<number | null>;
43
+ };
44
+ /** The percentiles / ranks a rule's thresholds resolve with. */
45
+ export declare const buildCfRuleStatsRequest: (rule: ConditionalFormatRule) => CfRuleStatsRequest;
46
+ /**
47
+ * Turn the engine's reply into {@link CfRangeStats} for the CF hook — what a
48
+ * windowed host returns from `getConditionalFormatRuleStats`.
49
+ */
50
+ export declare const toCfRangeStats: (request: CfRuleStatsRequest, response: CfRuleStatsResponse | null | undefined) => CfRangeStats | undefined;
51
+ export declare const buildCfRangeStats: (values: number[]) => CfRangeStats;
52
+ /** Excel's PERCENTILE.INC over ascending values (`p` in 0..100). */
53
+ export declare const percentileInc: (sorted: number[], p: number) => number;
54
+ /**
55
+ * Resolves a FORMULA threshold's text (e.g. `=$B$1`, `=10`) to a number,
56
+ * or `undefined` when it can't be evaluated.
57
+ */
58
+ export type CfFormulaResolver = (formula: string) => number | undefined;
59
+ /**
60
+ * Resolve a cfvo threshold against the rule's range statistics (OOXML cfvo
61
+ * semantics). `role` picks the AUTOMATIC bound (data bars only): the lower
62
+ * bound is `min(0, lowest)`, the upper `max(0, highest)`. Returns NaN when
63
+ * the threshold can't be resolved.
64
+ */
65
+ export declare const resolveCfThreshold: (threshold: CfThreshold, stats: CfRangeStats, options?: {
66
+ role?: "min" | "max";
67
+ resolveFormula?: CfFormulaResolver;
68
+ }) => number;
69
+ export declare const resolveThreshold: (threshold: CfThreshold, rangeMin: number, rangeMax: number, sorted?: number[]) => number;
70
+ export declare const pickIconBucket: (value: number, thresholds: number[], strict?: boolean[]) => number;
6
71
  export declare const computeDataBarFill: (value: number, min: number, max: number) => number;
72
+ /**
73
+ * Whether a cell counts as a number for data bars, colour scales, icon sets
74
+ * and the other numeric rules: its computed value is a number (Excel's rule —
75
+ * a typed `1` or a spilled `=SEQUENCE(3)` value qualifies without any number
76
+ * format), or it carries a number format (the legacy store's signal).
77
+ */
78
+ export declare const isConditionalFormatNumberCell: (effectiveValue: Record<string, any> | null | undefined, cellFormat: CellFormat | null | undefined) => boolean;
79
+ /**
80
+ * The comparison bound of an above / below average rule: the mean, moved
81
+ * `stdDev` sample standard deviations (Excel's STDEV) above or below it for
82
+ * the "1/2/3 std dev above / below" options. Mirrors the engine's
83
+ * `average_bound` (rnc-store `derive.rs`).
84
+ */
85
+ export declare const averageBound: (values: number[], above: boolean, stdDev?: number | null) => number;
86
+ /**
87
+ * Whether a CSS colour (`#rrggbb` / `rgb()`) is dark — relative luminance
88
+ * under 0.5. Unparseable colours count as light.
89
+ */
90
+ export declare const isDarkCssColor: (color: string | null | undefined) => boolean;
91
+ /** {@link averageBound} from full-range statistics (sorted values or the engine's mean / std dev). */
92
+ export declare const averageBoundFromStats: (stats: CfRangeStats, above: boolean, stdDev?: number | null) => number | undefined;
7
93
  //# sourceMappingURL=cf-overlays.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cf-overlays.d.ts","sourceRoot":"","sources":["../../../api/cf-overlays.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE3D,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,EAAE,CAqB3D,CAAC;AAIF,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,EAAE,CAkB3D,CAAC;AAKF,eAAO,MAAM,gBAAgB,GAC3B,WAAW,WAAW,EACtB,UAAU,MAAM,EAChB,UAAU,MAAM,KACf,MA6BF,CAAC;AAIF,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,EAAE,kBAAkB,MAAM,EAAE,WAQvE,CAAC;AAKF,eAAO,MAAM,kBAAkB,GAC7B,OAAO,MAAM,EACb,KAAK,MAAM,EACX,KAAK,MAAM,KACV,MAWF,CAAC"}
1
+ {"version":3,"file":"cf-overlays.d.ts","sourceRoot":"","sources":["../../../api/cf-overlays.ts"],"names":[],"mappings":"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"}
@@ -1,122 +1,231 @@
1
1
  "use strict";
2
2
  // Helpers for IconSetRule and DataBarRule evaluation.
3
3
  //
4
- // Excel ships ~17 named icon-set families. We render them with Unicode glyphs
5
- // so no font / SVG asset is required. Each family is an ordered list of
6
- // glyphs from "worst" → "best"; `reverse` on the rule flips this. The number
7
- // of glyphs encodes the family's bucket count (3, 4, or 5).
4
+ // Icon sets are painted as vector icons (`cf-icons.ts`); the glyphs below
5
+ // are the plain-text stand-ins menus (filter by icon, rule lists) show. Every
6
+ // family lists its icons in OOXML `iconId` order — index 0 is the icon of the
7
+ // LOWEST bucket; `reverse` on the rule flips the order. The number of icons
8
+ // encodes the family's bucket count (3, 4, or 5).
8
9
  //
9
- // Bucket selection: given thresholds[0..n-2] (ascending) and the cell's
10
- // numeric value, the bucket index is the count of thresholds the value
11
- // equals-or-exceeds. (i.e. value < thresholds[0] → 0; >= thresholds[n-2] →
12
- // n-1.) Threshold types follow OOXML cfvo semantics: NUMBER is absolute,
13
- // PERCENT/PERCENTILE are computed relative to the range.
10
+ // Bucket selection (Excel): thresholds are checked from the top bucket down;
11
+ // a value lands in the first bucket whose threshold it meets (`>=`, or `>`
12
+ // when the threshold's `gte` is false), else in bucket 0. Threshold types
13
+ // follow OOXML cfvo semantics: NUMBER is absolute, PERCENT is relative to
14
+ // the range's min..max, PERCENTILE is PERCENTILE.INC over the range values.
14
15
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.computeDataBarFill = exports.pickIconBucket = exports.resolveThreshold = exports.ICON_SET_COLORS = exports.ICON_SET_GLYPHS = void 0;
16
+ exports.averageBoundFromStats = exports.isDarkCssColor = exports.averageBound = exports.isConditionalFormatNumberCell = exports.computeDataBarFill = exports.pickIconBucket = exports.resolveThreshold = exports.resolveCfThreshold = exports.percentileInc = exports.buildCfRangeStats = exports.toCfRangeStats = exports.buildCfRuleStatsRequest = exports.ICON_SET_COLORS = exports.ICON_SET_GLYPHS = void 0;
16
17
  var tslib_1 = require("tslib");
18
+ var utils_1 = require("@rowsncolumns/utils");
19
+ var cf_icons_1 = require("./cf-icons");
17
20
  exports.ICON_SET_GLYPHS = {
18
- // 3-icon families (worst → best)
21
+ // 3-icon families (lowest → highest)
19
22
  "3Arrows": ["▼", "▶", "▲"],
20
23
  "3ArrowsGray": ["▽", "▷", "△"],
21
- "3Flags": ["⚑", "⚐", "⚑"],
24
+ "3Flags": ["⚑", "⚑", "⚑"],
22
25
  "3TrafficLights1": ["●", "●", "●"],
23
- "3TrafficLights2": ["■", "■", "■"],
26
+ "3TrafficLights2": ["●", "●", "●"],
24
27
  "3Signs": ["◆", "▲", "●"],
25
- "3Symbols": ["✖", "❗", "✔"],
28
+ "3Symbols": ["✖", "!", "✔"],
26
29
  "3Symbols2": ["✗", "!", "✓"],
30
+ "3Stars": ["☆", "⯪", "★"],
31
+ "3Triangles": ["▼", "▬", "▲"],
27
32
  // 4-icon families
28
33
  "4Arrows": ["▼", "↘", "↗", "▲"],
29
34
  "4ArrowsGray": ["▽", "↘", "↗", "△"],
30
35
  "4RedToBlack": ["●", "●", "●", "●"],
31
- "4Rating": ["▁", "▃", "▅", "▇"],
32
- "4TrafficLights": ["■", "●", "●", "●"],
36
+ "4Rating": ["▂", "▃", "▅", "▇"],
37
+ "4TrafficLights": ["●", "●", "●", "●"],
33
38
  // 5-icon families
34
39
  "5Arrows": ["▼", "↘", "→", "↗", "▲"],
35
40
  "5ArrowsGray": ["▽", "↘", "→", "↗", "△"],
36
41
  "5Rating": ["▁", "▂", "▄", "▆", "▇"],
37
42
  "5Quarters": ["○", "◔", "◑", "◕", "●"],
43
+ "5Boxes": ["□", "◰", "◧", "◩", "■"],
38
44
  };
39
- // Per-family default colors for traffic lights / signs / arrows. When the
40
- // imported rule doesn't carry explicit per-icon colors we use these.
41
- exports.ICON_SET_COLORS = {
42
- "3Arrows": ["#dc2626", "#f59e0b", "#16a34a"],
43
- "3ArrowsGray": ["#6b7280", "#6b7280", "#6b7280"],
44
- "3Flags": ["#dc2626", "#f59e0b", "#16a34a"],
45
- "3TrafficLights1": ["#dc2626", "#f59e0b", "#16a34a"],
46
- "3TrafficLights2": ["#dc2626", "#f59e0b", "#16a34a"],
47
- "3Signs": ["#dc2626", "#f59e0b", "#16a34a"],
48
- "3Symbols": ["#dc2626", "#f59e0b", "#16a34a"],
49
- "3Symbols2": ["#dc2626", "#f59e0b", "#16a34a"],
50
- "4Arrows": ["#dc2626", "#f59e0b", "#84cc16", "#16a34a"],
51
- "4ArrowsGray": ["#6b7280", "#6b7280", "#6b7280", "#6b7280"],
52
- "4RedToBlack": ["#dc2626", "#f97316", "#525252", "#000000"],
53
- "4Rating": ["#6b7280", "#6b7280", "#6b7280", "#6b7280"],
54
- "4TrafficLights": ["#dc2626", "#f59e0b", "#84cc16", "#16a34a"],
55
- "5Arrows": ["#dc2626", "#f59e0b", "#eab308", "#84cc16", "#16a34a"],
56
- "5ArrowsGray": ["#6b7280", "#6b7280", "#6b7280", "#6b7280", "#6b7280"],
57
- "5Rating": ["#6b7280", "#6b7280", "#6b7280", "#6b7280", "#6b7280"],
58
- "5Quarters": ["#6b7280", "#6b7280", "#6b7280", "#6b7280", "#6b7280"],
45
+ var shapeColor = function (shape) {
46
+ switch (shape.kind) {
47
+ case "star":
48
+ return "#F5B800";
49
+ case "rating":
50
+ case "boxes":
51
+ return "#2F6EBA";
52
+ case "quarters":
53
+ return "#262626";
54
+ default:
55
+ return shape.color;
56
+ }
59
57
  };
60
- // Resolve a cfvo threshold value against a range's min/max numeric values.
61
- // Returns NaN when the threshold can't be resolved (e.g. PERCENT against
62
- // an empty range), which downstream callers should skip.
63
- var resolveThreshold = function (threshold, rangeMin, rangeMax) {
64
- var raw = threshold.value;
65
- var num = typeof raw === "number" ? raw : Number(raw);
58
+ /** The colour each icon is painted in — what text stand-ins use. */
59
+ exports.ICON_SET_COLORS = Object.fromEntries(Object.entries(cf_icons_1.CF_ICON_SETS).map(function (_a) {
60
+ var _b = tslib_1.__read(_a, 2), family = _b[0], shapes = _b[1];
61
+ return [
62
+ family,
63
+ shapes.map(shapeColor),
64
+ ];
65
+ }));
66
+ /** The percentiles / ranks a rule's thresholds resolve with. */
67
+ var buildCfRuleStatsRequest = function (rule) {
68
+ var _a, _b, _c, _d, _e, _f;
69
+ var percentiles = new Set();
70
+ var addPoint = function (point) {
71
+ if ((point === null || point === void 0 ? void 0 : point.type) !== "PERCENTILE")
72
+ return;
73
+ var p = Number(point.value);
74
+ if (!Number.isFinite(p))
75
+ return;
76
+ percentiles.add(p);
77
+ // Colour scales read a 0..1 percentile as a fraction.
78
+ if (p <= 1)
79
+ percentiles.add(p * 100);
80
+ };
81
+ addPoint((_a = rule.dataBarRule) === null || _a === void 0 ? void 0 : _a.minpoint);
82
+ addPoint((_b = rule.dataBarRule) === null || _b === void 0 ? void 0 : _b.maxpoint);
83
+ (_c = rule.iconSetRule) === null || _c === void 0 ? void 0 : _c.thresholds.forEach(addPoint);
84
+ addPoint((_d = rule.gradientRule) === null || _d === void 0 ? void 0 : _d.minpoint);
85
+ addPoint((_e = rule.gradientRule) === null || _e === void 0 ? void 0 : _e.midpoint);
86
+ addPoint((_f = rule.gradientRule) === null || _f === void 0 ? void 0 : _f.maxpoint);
87
+ var ranks = [];
88
+ if (rule.topBottomRule) {
89
+ ranks.push({
90
+ k: rule.topBottomRule.rank,
91
+ top: rule.topBottomRule.type === "TOP",
92
+ percent: !!rule.topBottomRule.isPercent,
93
+ });
94
+ }
95
+ return { percentiles: tslib_1.__spreadArray([], tslib_1.__read(percentiles), false), ranks: ranks };
96
+ };
97
+ exports.buildCfRuleStatsRequest = buildCfRuleStatsRequest;
98
+ /**
99
+ * Turn the engine's reply into {@link CfRangeStats} for the CF hook — what a
100
+ * windowed host returns from `getConditionalFormatRuleStats`.
101
+ */
102
+ var toCfRangeStats = function (request, response) {
103
+ var _a, _b, _c, _d;
104
+ if (!response)
105
+ return undefined;
106
+ var at = function (list, i) {
107
+ return i >= 0 && list[i] != null ? list[i] : NaN;
108
+ };
109
+ return {
110
+ count: response.count,
111
+ min: (_a = response.min) !== null && _a !== void 0 ? _a : NaN,
112
+ max: (_b = response.max) !== null && _b !== void 0 ? _b : NaN,
113
+ mean: (_c = response.mean) !== null && _c !== void 0 ? _c : undefined,
114
+ stdDev: (_d = response.stdDev) !== null && _d !== void 0 ? _d : undefined,
115
+ percentile: function (p) {
116
+ return at(response.percentiles, request.percentiles.indexOf(p));
117
+ },
118
+ rankValue: function (k, top, percent) {
119
+ return at(response.ranks, request.ranks.findIndex(function (r) { return r.k === k && r.top === top && !!r.percent === !!percent; }));
120
+ },
121
+ };
122
+ };
123
+ exports.toCfRangeStats = toCfRangeStats;
124
+ var buildCfRangeStats = function (values) {
125
+ var sorted = values.slice().sort(function (a, b) { return a - b; });
126
+ return {
127
+ count: sorted.length,
128
+ min: sorted.length ? sorted[0] : NaN,
129
+ max: sorted.length ? sorted[sorted.length - 1] : NaN,
130
+ sorted: sorted,
131
+ };
132
+ };
133
+ exports.buildCfRangeStats = buildCfRangeStats;
134
+ /** Excel's PERCENTILE.INC over ascending values (`p` in 0..100). */
135
+ var percentileInc = function (sorted, p) {
136
+ if (!sorted.length || !Number.isFinite(p))
137
+ return NaN;
138
+ var k = (Math.max(0, Math.min(100, p)) / 100) * (sorted.length - 1);
139
+ var lower = Math.floor(k);
140
+ var upper = Math.ceil(k);
141
+ if (lower === upper)
142
+ return sorted[lower];
143
+ return sorted[lower] + (sorted[upper] - sorted[lower]) * (k - lower);
144
+ };
145
+ exports.percentileInc = percentileInc;
146
+ var numericValue = function (raw) {
147
+ return typeof raw === "number" ? raw : raw == null || raw === "" ? NaN : Number(raw);
148
+ };
149
+ /**
150
+ * Resolve a cfvo threshold against the rule's range statistics (OOXML cfvo
151
+ * semantics). `role` picks the AUTOMATIC bound (data bars only): the lower
152
+ * bound is `min(0, lowest)`, the upper `max(0, highest)`. Returns NaN when
153
+ * the threshold can't be resolved.
154
+ */
155
+ var resolveCfThreshold = function (threshold, stats, options) {
156
+ var _a, _b;
157
+ if (options === void 0) { options = {}; }
158
+ var num = numericValue(threshold.value);
66
159
  switch (threshold.type) {
67
160
  case "MIN":
68
- return rangeMin;
161
+ return stats.min;
69
162
  case "MAX":
70
- return rangeMax;
163
+ return stats.max;
164
+ case "AUTOMATIC":
165
+ return options.role === "max"
166
+ ? Math.max(0, stats.max)
167
+ : Math.min(0, stats.min);
71
168
  case "NUMBER":
72
169
  return Number.isFinite(num) ? num : NaN;
73
- case "PERCENT": {
170
+ case "PERCENT":
74
171
  if (!Number.isFinite(num))
75
172
  return NaN;
76
- var span = rangeMax - rangeMin;
77
- return rangeMin + (span * num) / 100;
78
- }
173
+ return stats.min + ((stats.max - stats.min) * num) / 100;
79
174
  case "PERCENTILE":
80
- // Approximate percentile by linear interpolation of min/max — the
81
- // engine doesn't have access to the sorted value list here. For tight
82
- // OOXML conformance the caller can pass a true percentile separately.
83
175
  if (!Number.isFinite(num))
84
176
  return NaN;
85
- return rangeMin + (rangeMax - rangeMin) * (num / 100);
86
- case "FORMULA":
87
- // FORMULA thresholds aren't evaluated client-side here; the importer
88
- // will have substituted a computed number into `value`. If still a
89
- // string, skip.
90
- return Number.isFinite(num) ? num : NaN;
177
+ return stats.sorted
178
+ ? (0, exports.percentileInc)(stats.sorted, num)
179
+ : stats.percentile
180
+ ? stats.percentile(num)
181
+ : stats.min + (stats.max - stats.min) * (num / 100);
182
+ case "FORMULA": {
183
+ if (Number.isFinite(num))
184
+ return num;
185
+ var text = String((_a = threshold.value) !== null && _a !== void 0 ? _a : "").trim();
186
+ if (!text)
187
+ return NaN;
188
+ var literal = Number(text.replace(/^=/, ""));
189
+ if (text.replace(/^=/, "") !== "" && Number.isFinite(literal)) {
190
+ return literal;
191
+ }
192
+ var resolved = (_b = options.resolveFormula) === null || _b === void 0 ? void 0 : _b.call(options, text);
193
+ return typeof resolved === "number" && Number.isFinite(resolved)
194
+ ? resolved
195
+ : NaN;
196
+ }
91
197
  default:
92
198
  return NaN;
93
199
  }
94
200
  };
201
+ exports.resolveCfThreshold = resolveCfThreshold;
202
+ // Resolve a cfvo threshold value against a range's min/max numeric values.
203
+ // Returns NaN when the threshold can't be resolved (e.g. PERCENT against
204
+ // an empty range), which downstream callers should skip. Pass `sorted`
205
+ // values for an exact PERCENTILE.
206
+ var resolveThreshold = function (threshold, rangeMin, rangeMax, sorted) {
207
+ var _a;
208
+ return (0, exports.resolveCfThreshold)(threshold, {
209
+ count: (_a = sorted === null || sorted === void 0 ? void 0 : sorted.length) !== null && _a !== void 0 ? _a : 0,
210
+ min: rangeMin,
211
+ max: rangeMax,
212
+ sorted: sorted,
213
+ });
214
+ };
95
215
  exports.resolveThreshold = resolveThreshold;
96
- // Pick the icon bucket index for a value given ordered thresholds.
97
- // thresholds: length = (iconCount - 1), ascending.
98
- var pickIconBucket = function (value, sortedThresholds) {
99
- var e_1, _a;
100
- var bucket = 0;
101
- try {
102
- for (var sortedThresholds_1 = tslib_1.__values(sortedThresholds), sortedThresholds_1_1 = sortedThresholds_1.next(); !sortedThresholds_1_1.done; sortedThresholds_1_1 = sortedThresholds_1.next()) {
103
- var t = sortedThresholds_1_1.value;
104
- if (!Number.isFinite(t))
105
- break;
106
- if (value >= t)
107
- bucket++;
108
- else
109
- break;
110
- }
216
+ // Pick the icon bucket index for a value. `thresholds[i]` is the lower bound
217
+ // of bucket `i + 1` (length = iconCount - 1); `strict[i]` makes it a `>`
218
+ // comparison. Checked from the top bucket down, like Excel; non-finite
219
+ // thresholds never match.
220
+ var pickIconBucket = function (value, thresholds, strict) {
221
+ for (var i = thresholds.length - 1; i >= 0; i--) {
222
+ var t = thresholds[i];
223
+ if (!Number.isFinite(t))
224
+ continue;
225
+ if ((strict === null || strict === void 0 ? void 0 : strict[i]) ? value > t : value >= t)
226
+ return i + 1;
111
227
  }
112
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
113
- finally {
114
- try {
115
- if (sortedThresholds_1_1 && !sortedThresholds_1_1.done && (_a = sortedThresholds_1.return)) _a.call(sortedThresholds_1);
116
- }
117
- finally { if (e_1) throw e_1.error; }
118
- }
119
- return bucket;
228
+ return 0;
120
229
  };
121
230
  exports.pickIconBucket = pickIconBucket;
122
231
  // Compute a 0..1 fill fraction for a data-bar cell value.
@@ -134,3 +243,70 @@ var computeDataBarFill = function (value, min, max) {
134
243
  return (clamped - min) / (max - min);
135
244
  };
136
245
  exports.computeDataBarFill = computeDataBarFill;
246
+ /**
247
+ * Whether a cell counts as a number for data bars, colour scales, icon sets
248
+ * and the other numeric rules: its computed value is a number (Excel's rule —
249
+ * a typed `1` or a spilled `=SEQUENCE(3)` value qualifies without any number
250
+ * format), or it carries a number format (the legacy store's signal).
251
+ */
252
+ var isConditionalFormatNumberCell = function (effectiveValue, cellFormat) {
253
+ var _a;
254
+ return (0, utils_1.getExtendedValueNumber)(effectiveValue) != null ||
255
+ !!((_a = cellFormat === null || cellFormat === void 0 ? void 0 : cellFormat.numberFormat) === null || _a === void 0 ? void 0 : _a.type);
256
+ };
257
+ exports.isConditionalFormatNumberCell = isConditionalFormatNumberCell;
258
+ /**
259
+ * The comparison bound of an above / below average rule: the mean, moved
260
+ * `stdDev` sample standard deviations (Excel's STDEV) above or below it for
261
+ * the "1/2/3 std dev above / below" options. Mirrors the engine's
262
+ * `average_bound` (rnc-store `derive.rs`).
263
+ */
264
+ var averageBound = function (values, above, stdDev) {
265
+ var mean = values.reduce(function (sum, v) { return sum + v; }, 0) / values.length;
266
+ if (!stdDev || stdDev <= 0 || values.length < 2)
267
+ return mean;
268
+ var variance = values.reduce(function (sum, v) { return sum + Math.pow((v - mean), 2); }, 0) / (values.length - 1);
269
+ var offset = stdDev * Math.sqrt(variance);
270
+ return above ? mean + offset : mean - offset;
271
+ };
272
+ exports.averageBound = averageBound;
273
+ /**
274
+ * Whether a CSS colour (`#rrggbb` / `rgb()`) is dark — relative luminance
275
+ * under 0.5. Unparseable colours count as light.
276
+ */
277
+ var isDarkCssColor = function (color) {
278
+ if (!color)
279
+ return false;
280
+ var hex = /^#?([0-9a-f]{6})/i.exec(color.trim());
281
+ var rgb = /^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i.exec(color.trim());
282
+ var channels;
283
+ if (hex) {
284
+ var n = parseInt(hex[1], 16);
285
+ channels = [(n >> 16) & 255, (n >> 8) & 255, n & 255];
286
+ }
287
+ else if (rgb) {
288
+ channels = [Number(rgb[1]), Number(rgb[2]), Number(rgb[3])];
289
+ }
290
+ if (!channels)
291
+ return false;
292
+ var _a = tslib_1.__read(channels.map(function (c) {
293
+ var v = c / 255;
294
+ return v <= 0.03928 ? v / 12.92 : Math.pow(((v + 0.055) / 1.055), 2.4);
295
+ }), 3), r = _a[0], g = _a[1], b = _a[2];
296
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b < 0.5;
297
+ };
298
+ exports.isDarkCssColor = isDarkCssColor;
299
+ /** {@link averageBound} from full-range statistics (sorted values or the engine's mean / std dev). */
300
+ var averageBoundFromStats = function (stats, above, stdDev) {
301
+ var _a;
302
+ if (stats.sorted) {
303
+ return stats.sorted.length
304
+ ? (0, exports.averageBound)(stats.sorted, above, stdDev)
305
+ : undefined;
306
+ }
307
+ if (stats.mean == null || !stats.count)
308
+ return undefined;
309
+ var offset = stdDev && stdDev > 0 ? stdDev * ((_a = stats.stdDev) !== null && _a !== void 0 ? _a : 0) : 0;
310
+ return above ? stats.mean + offset : stats.mean - offset;
311
+ };
312
+ exports.averageBoundFromStats = averageBoundFromStats;
@@ -0,0 +1,34 @@
1
+ import type { ConditionalFormatRule } from "../types";
2
+ /**
3
+ * Conditional-format precedence, as Excel defines it ("Manage conditional formatting rule
4
+ * precedence", support.microsoft.com): the rule listed FIRST has the highest precedence and wins a
5
+ * conflicting format; new rules go to the top of the list.
6
+ *
7
+ * `priority` carries that order (lower = higher precedence, as in xlsx `<cfRule priority>`). A rule
8
+ * without one ranks below every rule that has one; ties keep the stored order. The grid paints, the
9
+ * Rules Manager lists and the exporters number rules with this one ordering.
10
+ */
11
+ export declare const sortConditionalFormatRules: <T extends Pick<ConditionalFormatRule, "priority">>(rules: ReadonlyArray<T>) => T[];
12
+ /**
13
+ * The `priority` that puts a new rule above every existing one (Excel adds new rules at the top of
14
+ * the list). Priorities may go to zero or below; exporters renumber from 1.
15
+ */
16
+ export declare const getTopConditionalFormatPriority: (rules: ReadonlyArray<Pick<ConditionalFormatRule, "priority">>) => number;
17
+ /** A new rule with its `priority` set to the top of `rules`, unless it already carries one. */
18
+ export declare const withTopConditionalFormatPriority: <T extends Pick<ConditionalFormatRule, "priority">>(rule: T, rules: ReadonlyArray<Pick<ConditionalFormatRule, "priority">>) => T;
19
+ /**
20
+ * Move one rule up (`-1`) or down (`+1`) among `scope` (the rules the Rules Manager is showing —
21
+ * "Show formatting rules for" may hide some), returning the `priority` updates that realise the new
22
+ * order: every rule of the workbook renumbered 1..N in its new precedence order, keeping only the
23
+ * rules whose priority changes. Empty when the move is a no-op (first rule up, last rule down).
24
+ */
25
+ export declare const planConditionalFormatMove: <T extends Pick<ConditionalFormatRule, "id" | "priority">>(rules: ReadonlyArray<T>, ruleId: T["id"], direction: -1 | 1, scope?: ReadonlyArray<Pick<T, "id">>) => Array<{
26
+ rule: T;
27
+ priority: number;
28
+ }>;
29
+ /** `priority` updates that make `ordered` the precedence order (1..N), changed rules only. */
30
+ export declare const planConditionalFormatOrder: <T extends Pick<ConditionalFormatRule, "priority">>(ordered: ReadonlyArray<T>) => Array<{
31
+ rule: T;
32
+ priority: number;
33
+ }>;
34
+ //# sourceMappingURL=cf-priority.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cf-priority.d.ts","sourceRoot":"","sources":["../../../api/cf-priority.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAEtD;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,GACrC,CAAC,SAAS,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,EAEjD,OAAO,aAAa,CAAC,CAAC,CAAC,KACtB,CAAC,EAWwB,CAAC;AAE7B;;;GAGG;AACH,eAAO,MAAM,+BAA+B,GAC1C,OAAO,aAAa,CAAC,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,CAAC,KAC5D,MAQF,CAAC;AAEF,+FAA+F;AAC/F,eAAO,MAAM,gCAAgC,GAC3C,CAAC,SAAS,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,EAEjD,MAAM,CAAC,EACP,OAAO,aAAa,CAAC,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,CAAC,KAC5D,CAGgE,CAAC;AAEpE;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GACpC,CAAC,SAAS,IAAI,CAAC,qBAAqB,EAAE,IAAI,GAAG,UAAU,CAAC,EAExD,OAAO,aAAa,CAAC,CAAC,CAAC,EACvB,QAAQ,CAAC,CAAC,IAAI,CAAC,EACf,WAAW,CAAC,CAAC,GAAG,CAAC,EACjB,QAAO,aAAa,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAS,KAC1C,KAAK,CAAC;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAerC,CAAC;AAEF,8FAA8F;AAC9F,eAAO,MAAM,0BAA0B,GACrC,CAAC,SAAS,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,EAEjD,SAAS,aAAa,CAAC,CAAC,CAAC,KACxB,KAAK,CAAC;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAGnC,CAAC"}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.planConditionalFormatOrder = exports.planConditionalFormatMove = exports.withTopConditionalFormatPriority = exports.getTopConditionalFormatPriority = exports.sortConditionalFormatRules = void 0;
4
+ var tslib_1 = require("tslib");
5
+ /**
6
+ * Conditional-format precedence, as Excel defines it ("Manage conditional formatting rule
7
+ * precedence", support.microsoft.com): the rule listed FIRST has the highest precedence and wins a
8
+ * conflicting format; new rules go to the top of the list.
9
+ *
10
+ * `priority` carries that order (lower = higher precedence, as in xlsx `<cfRule priority>`). A rule
11
+ * without one ranks below every rule that has one; ties keep the stored order. The grid paints, the
12
+ * Rules Manager lists and the exporters number rules with this one ordering.
13
+ */
14
+ var sortConditionalFormatRules = function (rules) {
15
+ return rules
16
+ .map(function (rule, index) { return ({ rule: rule, index: index }); })
17
+ .sort(function (left, right) {
18
+ var _a, _b;
19
+ var leftPriority = (_a = left.rule.priority) !== null && _a !== void 0 ? _a : Number.POSITIVE_INFINITY;
20
+ var rightPriority = (_b = right.rule.priority) !== null && _b !== void 0 ? _b : Number.POSITIVE_INFINITY;
21
+ if (leftPriority === rightPriority) {
22
+ return left.index - right.index;
23
+ }
24
+ return leftPriority - rightPriority;
25
+ })
26
+ .map(function (_a) {
27
+ var rule = _a.rule;
28
+ return rule;
29
+ });
30
+ };
31
+ exports.sortConditionalFormatRules = sortConditionalFormatRules;
32
+ /**
33
+ * The `priority` that puts a new rule above every existing one (Excel adds new rules at the top of
34
+ * the list). Priorities may go to zero or below; exporters renumber from 1.
35
+ */
36
+ var getTopConditionalFormatPriority = function (rules) {
37
+ var e_1, _a;
38
+ var top = 1;
39
+ try {
40
+ for (var rules_1 = tslib_1.__values(rules), rules_1_1 = rules_1.next(); !rules_1_1.done; rules_1_1 = rules_1.next()) {
41
+ var rule = rules_1_1.value;
42
+ if (typeof rule.priority === "number" && Number.isFinite(rule.priority)) {
43
+ top = Math.min(top, rule.priority);
44
+ }
45
+ }
46
+ }
47
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
48
+ finally {
49
+ try {
50
+ if (rules_1_1 && !rules_1_1.done && (_a = rules_1.return)) _a.call(rules_1);
51
+ }
52
+ finally { if (e_1) throw e_1.error; }
53
+ }
54
+ return top - 1;
55
+ };
56
+ exports.getTopConditionalFormatPriority = getTopConditionalFormatPriority;
57
+ /** A new rule with its `priority` set to the top of `rules`, unless it already carries one. */
58
+ var withTopConditionalFormatPriority = function (rule, rules) {
59
+ return typeof rule.priority === "number"
60
+ ? rule
61
+ : tslib_1.__assign(tslib_1.__assign({}, rule), { priority: (0, exports.getTopConditionalFormatPriority)(rules) });
62
+ };
63
+ exports.withTopConditionalFormatPriority = withTopConditionalFormatPriority;
64
+ /**
65
+ * Move one rule up (`-1`) or down (`+1`) among `scope` (the rules the Rules Manager is showing —
66
+ * "Show formatting rules for" may hide some), returning the `priority` updates that realise the new
67
+ * order: every rule of the workbook renumbered 1..N in its new precedence order, keeping only the
68
+ * rules whose priority changes. Empty when the move is a no-op (first rule up, last rule down).
69
+ */
70
+ var planConditionalFormatMove = function (rules, ruleId, direction, scope) {
71
+ if (scope === void 0) { scope = rules; }
72
+ var ordered = (0, exports.sortConditionalFormatRules)(rules);
73
+ var scopeIds = new Set(scope.map(function (rule) { return rule.id; }));
74
+ var visible = ordered.filter(function (rule) { return scopeIds.has(rule.id); });
75
+ var at = visible.findIndex(function (rule) { return rule.id === ruleId; });
76
+ var neighbour = visible[at + direction];
77
+ if (at === -1 || !neighbour) {
78
+ return [];
79
+ }
80
+ var from = ordered.indexOf(visible[at]);
81
+ var to = ordered.indexOf(neighbour);
82
+ var next = tslib_1.__spreadArray([], tslib_1.__read(ordered), false);
83
+ next[from] = neighbour;
84
+ next[to] = visible[at];
85
+ return (0, exports.planConditionalFormatOrder)(next);
86
+ };
87
+ exports.planConditionalFormatMove = planConditionalFormatMove;
88
+ /** `priority` updates that make `ordered` the precedence order (1..N), changed rules only. */
89
+ var planConditionalFormatOrder = function (ordered) {
90
+ return ordered.flatMap(function (rule, index) {
91
+ return rule.priority === index + 1 ? [] : [{ rule: rule, priority: index + 1 }];
92
+ });
93
+ };
94
+ exports.planConditionalFormatOrder = planConditionalFormatOrder;
@@ -1,4 +1,10 @@
1
1
  import type { SpreadsheetTheme } from "../components/canvas-grid/typings";
2
2
  import type { GradientRule } from "../types";
3
- export declare const getGradientColors: (values: (number | undefined)[][][], gradientRule: GradientRule, theme: SpreadsheetTheme) => (string | undefined)[][][];
3
+ import type { CfRangeStats } from "./cf-overlays";
4
+ /**
5
+ * `population` — the rule's full-range statistics when `values` is only the
6
+ * visible slice of a windowed rule; min / mid / max resolve over it instead
7
+ * of the slice.
8
+ */
9
+ export declare const getGradientColors: (values: (number | undefined)[][][], gradientRule: GradientRule, theme: SpreadsheetTheme, population?: CfRangeStats) => (string | undefined)[][][];
4
10
  //# sourceMappingURL=heatmap.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"heatmap.d.ts","sourceRoot":"","sources":["../../../api/heatmap.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAE1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,EAAE,EAAE,EAClC,cAAc,YAAY,EAC1B,OAAO,gBAAgB,+BAgExB,CAAC"}
1
+ {"version":3,"file":"heatmap.d.ts","sourceRoot":"","sources":["../../../api/heatmap.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAE1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,EAAE,EAAE,EAClC,cAAc,YAAY,EAC1B,OAAO,gBAAgB,EACvB,aAAa,YAAY,+BAoE1B,CAAC"}