@rowsncolumns/utils 9.2.35

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 (154) hide show
  1. package/LICENSE.md +100 -0
  2. package/dist/cjs/array.d.ts +3 -0
  3. package/dist/cjs/array.d.ts.map +1 -0
  4. package/dist/cjs/array.js +19 -0
  5. package/dist/cjs/cell-data-helpers.d.ts +19 -0
  6. package/dist/cjs/cell-data-helpers.d.ts.map +1 -0
  7. package/dist/cjs/cell-data-helpers.js +64 -0
  8. package/dist/cjs/color.d.ts +20 -0
  9. package/dist/cjs/color.d.ts.map +1 -0
  10. package/dist/cjs/color.js +168 -0
  11. package/dist/cjs/colors.d.ts +2 -0
  12. package/dist/cjs/colors.d.ts.map +1 -0
  13. package/dist/cjs/colors.js +78 -0
  14. package/dist/cjs/conditional-format.d.ts +49 -0
  15. package/dist/cjs/conditional-format.d.ts.map +1 -0
  16. package/dist/cjs/conditional-format.js +227 -0
  17. package/dist/cjs/content-hash.d.ts +16 -0
  18. package/dist/cjs/content-hash.d.ts.map +1 -0
  19. package/dist/cjs/content-hash.js +72 -0
  20. package/dist/cjs/data-validation.d.ts +54 -0
  21. package/dist/cjs/data-validation.d.ts.map +1 -0
  22. package/dist/cjs/data-validation.js +249 -0
  23. package/dist/cjs/date.d.ts +15 -0
  24. package/dist/cjs/date.d.ts.map +1 -0
  25. package/dist/cjs/date.js +56 -0
  26. package/dist/cjs/dom.d.ts +10 -0
  27. package/dist/cjs/dom.d.ts.map +1 -0
  28. package/dist/cjs/dom.js +97 -0
  29. package/dist/cjs/formatter.d.ts +22 -0
  30. package/dist/cjs/formatter.d.ts.map +1 -0
  31. package/dist/cjs/formatter.js +264 -0
  32. package/dist/cjs/formula-refs.d.ts +7 -0
  33. package/dist/cjs/formula-refs.d.ts.map +1 -0
  34. package/dist/cjs/formula-refs.js +54 -0
  35. package/dist/cjs/formula.d.ts +80 -0
  36. package/dist/cjs/formula.d.ts.map +1 -0
  37. package/dist/cjs/formula.js +401 -0
  38. package/dist/cjs/index.d.ts +24 -0
  39. package/dist/cjs/index.d.ts.map +1 -0
  40. package/dist/cjs/index.js +26 -0
  41. package/dist/cjs/locale.d.ts +34 -0
  42. package/dist/cjs/locale.d.ts.map +1 -0
  43. package/dist/cjs/locale.js +260 -0
  44. package/dist/cjs/log.d.ts +4 -0
  45. package/dist/cjs/log.d.ts.map +1 -0
  46. package/dist/cjs/log.js +28 -0
  47. package/dist/cjs/memoize.d.ts +18 -0
  48. package/dist/cjs/memoize.d.ts.map +1 -0
  49. package/dist/cjs/memoize.js +128 -0
  50. package/dist/cjs/numbers.d.ts +19 -0
  51. package/dist/cjs/numbers.d.ts.map +1 -0
  52. package/dist/cjs/numbers.js +47 -0
  53. package/dist/cjs/selection.d.ts +88 -0
  54. package/dist/cjs/selection.d.ts.map +1 -0
  55. package/dist/cjs/selection.js +368 -0
  56. package/dist/cjs/shared-string-canonical.d.ts +18 -0
  57. package/dist/cjs/shared-string-canonical.d.ts.map +1 -0
  58. package/dist/cjs/shared-string-canonical.js +74 -0
  59. package/dist/cjs/sort.d.ts +15 -0
  60. package/dist/cjs/sort.d.ts.map +1 -0
  61. package/dist/cjs/sort.js +44 -0
  62. package/dist/cjs/string.d.ts +74 -0
  63. package/dist/cjs/string.d.ts.map +1 -0
  64. package/dist/cjs/string.js +237 -0
  65. package/dist/cjs/table-styles.d.ts +56 -0
  66. package/dist/cjs/table-styles.d.ts.map +1 -0
  67. package/dist/cjs/table-styles.js +362 -0
  68. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
  69. package/dist/cjs/typeguards.d.ts +4 -0
  70. package/dist/cjs/typeguards.d.ts.map +1 -0
  71. package/dist/cjs/typeguards.js +15 -0
  72. package/dist/cjs/uuid.d.ts +8 -0
  73. package/dist/cjs/uuid.d.ts.map +1 -0
  74. package/dist/cjs/uuid.js +30 -0
  75. package/dist/cjs/vitest.config.d.ts +3 -0
  76. package/dist/cjs/vitest.config.d.ts.map +1 -0
  77. package/dist/cjs/vitest.config.js +9 -0
  78. package/dist/esm/array.d.ts +3 -0
  79. package/dist/esm/array.d.ts.map +1 -0
  80. package/dist/esm/array.js +14 -0
  81. package/dist/esm/cell-data-helpers.d.ts +19 -0
  82. package/dist/esm/cell-data-helpers.d.ts.map +1 -0
  83. package/dist/esm/cell-data-helpers.js +39 -0
  84. package/dist/esm/color.d.ts +20 -0
  85. package/dist/esm/color.d.ts.map +1 -0
  86. package/dist/esm/color.js +152 -0
  87. package/dist/esm/colors.d.ts +2 -0
  88. package/dist/esm/colors.d.ts.map +1 -0
  89. package/dist/esm/colors.js +75 -0
  90. package/dist/esm/conditional-format.d.ts +49 -0
  91. package/dist/esm/conditional-format.d.ts.map +1 -0
  92. package/dist/esm/conditional-format.js +219 -0
  93. package/dist/esm/content-hash.d.ts +16 -0
  94. package/dist/esm/content-hash.d.ts.map +1 -0
  95. package/dist/esm/content-hash.js +68 -0
  96. package/dist/esm/data-validation.d.ts +54 -0
  97. package/dist/esm/data-validation.d.ts.map +1 -0
  98. package/dist/esm/data-validation.js +237 -0
  99. package/dist/esm/date.d.ts +15 -0
  100. package/dist/esm/date.d.ts.map +1 -0
  101. package/dist/esm/date.js +46 -0
  102. package/dist/esm/dom.d.ts +10 -0
  103. package/dist/esm/dom.d.ts.map +1 -0
  104. package/dist/esm/dom.js +90 -0
  105. package/dist/esm/formatter.d.ts +22 -0
  106. package/dist/esm/formatter.d.ts.map +1 -0
  107. package/dist/esm/formatter.js +253 -0
  108. package/dist/esm/formula-refs.d.ts +7 -0
  109. package/dist/esm/formula-refs.d.ts.map +1 -0
  110. package/dist/esm/formula-refs.js +49 -0
  111. package/dist/esm/formula.d.ts +80 -0
  112. package/dist/esm/formula.d.ts.map +1 -0
  113. package/dist/esm/formula.js +298 -0
  114. package/dist/esm/index.d.ts +24 -0
  115. package/dist/esm/index.d.ts.map +1 -0
  116. package/dist/esm/index.js +23 -0
  117. package/dist/esm/locale.d.ts +34 -0
  118. package/dist/esm/locale.d.ts.map +1 -0
  119. package/dist/esm/locale.js +223 -0
  120. package/dist/esm/log.d.ts +4 -0
  121. package/dist/esm/log.d.ts.map +1 -0
  122. package/dist/esm/log.js +3 -0
  123. package/dist/esm/memoize.d.ts +18 -0
  124. package/dist/esm/memoize.d.ts.map +1 -0
  125. package/dist/esm/memoize.js +95 -0
  126. package/dist/esm/numbers.d.ts +19 -0
  127. package/dist/esm/numbers.d.ts.map +1 -0
  128. package/dist/esm/numbers.js +40 -0
  129. package/dist/esm/selection.d.ts +88 -0
  130. package/dist/esm/selection.d.ts.map +1 -0
  131. package/dist/esm/selection.js +311 -0
  132. package/dist/esm/shared-string-canonical.d.ts +18 -0
  133. package/dist/esm/shared-string-canonical.d.ts.map +1 -0
  134. package/dist/esm/shared-string-canonical.js +68 -0
  135. package/dist/esm/sort.d.ts +15 -0
  136. package/dist/esm/sort.d.ts.map +1 -0
  137. package/dist/esm/sort.js +39 -0
  138. package/dist/esm/string.d.ts +74 -0
  139. package/dist/esm/string.d.ts.map +1 -0
  140. package/dist/esm/string.js +213 -0
  141. package/dist/esm/table-styles.d.ts +56 -0
  142. package/dist/esm/table-styles.d.ts.map +1 -0
  143. package/dist/esm/table-styles.js +367 -0
  144. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
  145. package/dist/esm/typeguards.d.ts +4 -0
  146. package/dist/esm/typeguards.d.ts.map +1 -0
  147. package/dist/esm/typeguards.js +7 -0
  148. package/dist/esm/uuid.d.ts +8 -0
  149. package/dist/esm/uuid.d.ts.map +1 -0
  150. package/dist/esm/uuid.js +25 -0
  151. package/dist/esm/vitest.config.d.ts +3 -0
  152. package/dist/esm/vitest.config.d.ts.map +1 -0
  153. package/dist/esm/vitest.config.js +7 -0
  154. package/package.json +49 -0
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isNilOrBlank = exports.isNil = exports.isDefined = void 0;
4
+ // Typeguards
5
+ var isDefined = function (val) {
6
+ return val !== undefined && val !== null;
7
+ };
8
+ exports.isDefined = isDefined;
9
+ // Typeguards isNil
10
+ var isNil = function (value) { return !(0, exports.isDefined)(value); };
11
+ exports.isNil = isNil;
12
+ var isNilOrBlank = function (value) {
13
+ return (0, exports.isNil)(value) || String(value).trim() === "";
14
+ };
15
+ exports.isNilOrBlank = isNilOrBlank;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Generate a random uuid
3
+ * Conform to Google Sheet 9 Digit ID
4
+ * @returns
5
+ */
6
+ export declare const uuid: () => number;
7
+ export declare const uuidString: () => string;
8
+ //# sourceMappingURL=uuid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uuid.d.ts","sourceRoot":"","sources":["../../uuid.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,IAAI,cAA0D,CAAC;AAE5E,eAAO,MAAM,UAAU,cAqBtB,CAAC"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.uuidString = exports.uuid = void 0;
4
+ /**
5
+ * Generate a random uuid
6
+ * Conform to Google Sheet 9 Digit ID
7
+ * @returns
8
+ */
9
+ var uuid = function () { return Math.floor(Math.random() * 900000000) + 100000000; };
10
+ exports.uuid = uuid;
11
+ var uuidString = function () {
12
+ // Check for crypto in various environments (Node.js, browser, etc.)
13
+ var cryptoObj = typeof crypto !== "undefined"
14
+ ? crypto
15
+ : typeof window !== "undefined" && window.crypto
16
+ ? window.crypto
17
+ : typeof global !== "undefined" && global.crypto
18
+ ? global.crypto
19
+ : null;
20
+ if (cryptoObj && typeof cryptoObj.randomUUID === "function") {
21
+ return cryptoObj.randomUUID();
22
+ }
23
+ var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
24
+ var result = "";
25
+ for (var i = 0; i < 9; i++) {
26
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
27
+ }
28
+ return result;
29
+ };
30
+ exports.uuidString = uuidString;
@@ -0,0 +1,3 @@
1
+ declare const _default: import("vite").UserConfig;
2
+ export default _default;
3
+ //# sourceMappingURL=vitest.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitest.config.d.ts","sourceRoot":"","sources":["../../vitest.config.ts"],"names":[],"mappings":";AAEA,wBAKG"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var config_1 = require("vitest/config");
4
+ exports.default = (0, config_1.defineConfig)({
5
+ test: {
6
+ globals: true,
7
+ environment: "node",
8
+ },
9
+ });
@@ -0,0 +1,3 @@
1
+ export declare function findLastIndex<T>(array: Array<T>, predicate: (value: T, index: number, obj: T[]) => boolean): number;
2
+ export declare const createArrayRange: (start: number, end: number) => number[];
3
+ //# sourceMappingURL=array.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../../array.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,CAAC,EAC7B,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EACf,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,OAAO,GACxD,MAAM,CAMR;AAED,eAAO,MAAM,gBAAgB,GAAI,OAAO,MAAM,EAAE,KAAK,MAAM,KAAG,MAAM,EAKnE,CAAC"}
@@ -0,0 +1,14 @@
1
+ export function findLastIndex(array, predicate) {
2
+ let l = array.length;
3
+ while (l--) {
4
+ if (predicate(array[l], l, array))
5
+ return l;
6
+ }
7
+ return -1;
8
+ }
9
+ export const createArrayRange = (start, end) => {
10
+ if (end < start) {
11
+ return [];
12
+ }
13
+ return Array.from({ length: end - start + 1 }, (_, index) => start + index);
14
+ };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Utility functions for CellData property access with fallback logic
3
+ * Prioritizes short keys (ue, ev) over long keys (userEnteredValue, effectiveValue)
4
+ *
5
+ * Note: These functions use generic types to avoid circular dependencies
6
+ */
7
+ import type { CellData, CellFormat, StyleReference } from "@rowsncolumns/common-types";
8
+ export declare const getCellUserEnteredValue: <T extends CellData>(cell?: T | null) => T["ue"];
9
+ export declare const getCellEffectiveValue: <T extends CellData>(cell?: T | null) => T["ev"];
10
+ export declare const getCellUserEnteredFormat: <T extends CellData>(cell?: T | null) => T["uf"];
11
+ export declare const getCellEffectiveFormat: <T extends CellData>(cell?: T | null) => CellFormat | StyleReference | null | undefined;
12
+ export declare const getCellFormattedValue: <T extends CellData>(cell?: T | null) => string | undefined | null;
13
+ export declare const getStyleId: (styleRef: Record<string, any>) => string;
14
+ export declare const getExtendedValueNumber: (extValue?: Record<string, any> | null) => number | undefined;
15
+ export declare const getExtendedValueString: (extValue?: Record<string, any> | null) => string | undefined;
16
+ export declare const getExtendedValueBool: (extValue?: Record<string, any> | null) => boolean | undefined;
17
+ export declare const getExtendedValueFormula: (extValue?: Record<string, any> | null) => string | undefined;
18
+ export declare const getExtendedValueError: (extValue?: Record<string, any> | null) => any | undefined;
19
+ //# sourceMappingURL=cell-data-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cell-data-helpers.d.ts","sourceRoot":"","sources":["../../cell-data-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,cAAc,EACf,MAAM,4BAA4B,CAAC;AAEpC,eAAO,MAAM,uBAAuB,GAAI,CAAC,SAAS,QAAQ,EACxD,OAAO,CAAC,GAAG,IAAI,KACd,CAAC,CAAC,IAAI,CAER,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,QAAQ,EACtD,OAAO,CAAC,GAAG,IAAI,KACd,CAAC,CAAC,IAAI,CAER,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,CAAC,SAAS,QAAQ,EACzD,OAAO,CAAC,GAAG,IAAI,KACd,CAAC,CAAC,IAAI,CAER,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,CAAC,SAAS,QAAQ,EACvD,OAAO,CAAC,GAAG,IAAI,KACd,UAAU,GAAG,cAAc,GAAG,IAAI,GAAG,SAEvC,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,QAAQ,EACtD,OAAO,CAAC,GAAG,IAAI,KACd,MAAM,GAAG,SAAS,GAAG,IAEvB,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,UAAU,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAG,MAE1D,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KACpC,MAAM,GAAG,SAEX,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KACpC,MAAM,GAAG,SAEX,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KACpC,OAAO,GAAG,SAEZ,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KACpC,MAAM,GAAG,SAEX,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KACpC,GAAG,GAAG,SAER,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Utility functions for CellData property access with fallback logic
3
+ * Prioritizes short keys (ue, ev) over long keys (userEnteredValue, effectiveValue)
4
+ *
5
+ * Note: These functions use generic types to avoid circular dependencies
6
+ */
7
+ export const getCellUserEnteredValue = (cell) => {
8
+ return cell?.ue ?? cell?.userEnteredValue;
9
+ };
10
+ export const getCellEffectiveValue = (cell) => {
11
+ return cell?.ev ?? cell?.effectiveValue;
12
+ };
13
+ export const getCellUserEnteredFormat = (cell) => {
14
+ return cell?.uf ?? cell?.userEnteredFormat;
15
+ };
16
+ export const getCellEffectiveFormat = (cell) => {
17
+ return cell?.ef ?? cell?.effectiveFormat;
18
+ };
19
+ export const getCellFormattedValue = (cell) => {
20
+ return cell?.fv ?? cell?.formattedValue;
21
+ };
22
+ export const getStyleId = (styleRef) => {
23
+ return styleRef.sid ?? styleRef.styleId;
24
+ };
25
+ export const getExtendedValueNumber = (extValue) => {
26
+ return extValue?.nv ?? extValue?.numberValue;
27
+ };
28
+ export const getExtendedValueString = (extValue) => {
29
+ return extValue?.sv ?? extValue?.stringValue;
30
+ };
31
+ export const getExtendedValueBool = (extValue) => {
32
+ return extValue?.bv ?? extValue?.boolValue;
33
+ };
34
+ export const getExtendedValueFormula = (extValue) => {
35
+ return extValue?.fv ?? extValue?.formulaValue;
36
+ };
37
+ export const getExtendedValueError = (extValue) => {
38
+ return extValue?.ev ?? extValue?.errorValue;
39
+ };
@@ -0,0 +1,20 @@
1
+ export declare const getSelectionColorAtIndex: (key: number) => string;
2
+ export type RGBA = {
3
+ r: number;
4
+ g: number;
5
+ b: number;
6
+ a?: number;
7
+ };
8
+ export declare function normalizeColor(color: string): RGBA | null;
9
+ export declare const rgbaToArgbHex: ({ r, g, b, a }: RGBA) => string;
10
+ export declare const isSameColor: (colorA: string | undefined, colorB: string | undefined) => boolean | undefined;
11
+ export declare const colorStringToHex: (color: string | undefined) => string | undefined;
12
+ export declare const lightenColor: (unit: number | undefined, color: string) => string | undefined;
13
+ export declare const hexToRgb: (hex: string) => {
14
+ r: number;
15
+ g: number;
16
+ b: number;
17
+ };
18
+ export declare const rgbToHex: (r: number, g: number, b: number) => string;
19
+ export declare const getContrastColor: (backgroundColor: string, lightColor: string, darkColor: string) => string | undefined;
20
+ //# sourceMappingURL=color.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color.d.ts","sourceRoot":"","sources":["../../color.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,wBAAwB,GAAI,KAAK,MAAM,WAoCnD,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAYnE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAkBzD;AAED,eAAO,MAAM,aAAa,GAAI,gBAAoB,IAAI,WAUrD,CAAC;AAEF,eAAO,MAAM,WAAW,GACtB,QAAQ,MAAM,GAAG,SAAS,EAC1B,QAAQ,MAAM,GAAG,SAAS,wBAiB3B,CAAC;AAQF,eAAO,MAAM,gBAAgB,GAAI,OAAO,MAAM,GAAG,SAAS,uBAczD,CAAC;AAGF,eAAO,MAAM,YAAY,GAAI,wBAAU,EAAE,OAAO,MAAM,uBAGrD,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,KAAK,MAAM;;;;CAOnC,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,MAAM,WAGvD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,iBAAiB,MAAM,EACvB,YAAY,MAAM,EAClB,WAAW,MAAM,uBAUlB,CAAC"}
@@ -0,0 +1,152 @@
1
+ import { isNil } from "./typeguards";
2
+ // Shared by editor decorator + spreadsheet
3
+ export const getSelectionColorAtIndex = (key) => {
4
+ let hash = 0;
5
+ const colors = [
6
+ "#11a9cc",
7
+ "#a61d4c",
8
+ "#4285f4",
9
+ "#f4b400",
10
+ "#65b045",
11
+ "#e51c23",
12
+ "#e91e63",
13
+ "#9c27b0",
14
+ "#673ab7",
15
+ "#3f51b5",
16
+ "#5677fc",
17
+ "#03a9f4",
18
+ "#00bcd4",
19
+ "#009688",
20
+ "#259b24",
21
+ "#8bc34a",
22
+ "#afb42b",
23
+ "#ff9800",
24
+ "#ff5722",
25
+ "#795548",
26
+ "#607d8b",
27
+ "#880e4f",
28
+ "#827717",
29
+ "#f7981d", // orange
30
+ "#7e3794",
31
+ ];
32
+ const str = key.toString();
33
+ for (let i = 0; i < str.length; i++) {
34
+ hash = str.charCodeAt(i) + ((hash << 5) - hash);
35
+ hash = hash & hash;
36
+ }
37
+ hash = ((hash % colors.length) + colors.length) % colors.length;
38
+ return colors[hash];
39
+ };
40
+ function parseRGBA(rgbString) {
41
+ const regex = /^rgba?\((\d+),\s*(\d+),\s*(\d+),?\s*([01]?(\.\d+)?)?\)$/;
42
+ const match = rgbString.match(regex);
43
+ if (match) {
44
+ const [, r, g, b, a] = match.map(Number);
45
+ return { r, g, b, a: a === undefined || isNaN(a) ? 1 : a };
46
+ }
47
+ return undefined;
48
+ }
49
+ export function normalizeColor(color) {
50
+ if (color.startsWith("#")) {
51
+ // Hex to RGB conversion
52
+ const hex = color.slice(1);
53
+ const bigint = parseInt(hex, 16);
54
+ const r = (bigint >> 16) & 255;
55
+ const g = (bigint >> 8) & 255;
56
+ const b = bigint & 255;
57
+ return { r, g, b };
58
+ }
59
+ else if (color.startsWith("rgb")) {
60
+ // RGB string parsing
61
+ const parsedColor = parseRGBA(color);
62
+ if (parsedColor) {
63
+ return parsedColor;
64
+ }
65
+ }
66
+ return null; // Unsupported color format
67
+ }
68
+ export const rgbaToArgbHex = ({ r, g, b, a = 1 }) => {
69
+ const alpha = Math.round(a * 255);
70
+ const hex = [alpha, r, g, b]
71
+ .map((value) => {
72
+ const hex = value.toString(16);
73
+ return hex.length === 1 ? "0" + hex : hex;
74
+ })
75
+ .join("");
76
+ return hex;
77
+ };
78
+ export const isSameColor = (colorA, colorB) => {
79
+ if (colorA === colorB) {
80
+ return true;
81
+ }
82
+ const normalizedColorA = isNil(colorA) ? undefined : normalizeColor(colorA);
83
+ const normalizedColorB = isNil(colorB) ? undefined : normalizeColor(colorB);
84
+ if (normalizedColorA && normalizedColorB) {
85
+ return (normalizedColorA.r === normalizedColorB.r &&
86
+ normalizedColorA.g === normalizedColorB.g &&
87
+ normalizedColorA.b === normalizedColorB.b);
88
+ }
89
+ return undefined;
90
+ };
91
+ // Returns a `#RRGGBB` hex string, or undefined if the input isn't a recognized
92
+ // color form (rgb()/rgba() function or already-hex). The previous fallback
93
+ // `return color` let CSS fragments like `font-family:"…"` flow through as
94
+ // "colors", which then ended up in cell formatting and broke xlsx export.
95
+ const HEX_COLOR_RE = /^#?[0-9A-Fa-f]{3}([0-9A-Fa-f])?([0-9A-Fa-f]{2})?([0-9A-Fa-f]{2})?$/;
96
+ export const colorStringToHex = (color) => {
97
+ if (isNil(color)) {
98
+ return undefined;
99
+ }
100
+ const trimmed = color.trim();
101
+ if (!trimmed)
102
+ return undefined;
103
+ if (trimmed.startsWith("rgb")) {
104
+ const rgb = parseRGBA(trimmed);
105
+ return rgb ? rgbToHex(rgb.r, rgb.g, rgb.b) : undefined;
106
+ }
107
+ if (HEX_COLOR_RE.test(trimmed)) {
108
+ return trimmed.startsWith("#") ? trimmed : `#${trimmed}`;
109
+ }
110
+ return undefined;
111
+ };
112
+ // Lighten a color
113
+ export const lightenColor = (unit = 0.2, color) => {
114
+ const rgbColor = normalizeColor(color);
115
+ return rgbColor ? shade(unit, rgbColor) : undefined;
116
+ };
117
+ export const hexToRgb = (hex) => {
118
+ const bigint = parseInt(hex.slice(1), 16);
119
+ const r = (bigint >> 16) & 255;
120
+ const g = (bigint >> 8) & 255;
121
+ const b = bigint & 255;
122
+ return { r, g, b };
123
+ };
124
+ export const rgbToHex = (r, g, b) => {
125
+ const hex = ((r << 16) | (g << 8) | b).toString(16);
126
+ return "#" + ("000000" + hex).slice(-6);
127
+ };
128
+ export const getContrastColor = (backgroundColor, lightColor, darkColor) => {
129
+ const rgbColor = normalizeColor(backgroundColor);
130
+ if (rgbColor) {
131
+ const { r, g, b } = rgbColor;
132
+ const yiq = (r * 299 + g * 587 + b * 114) / 1000;
133
+ return yiq >= 128 ? lightColor : darkColor;
134
+ }
135
+ return undefined;
136
+ };
137
+ const shade = (light, { r, g, b, a }) => {
138
+ if (a === 0) {
139
+ return undefined;
140
+ }
141
+ if (light < 0) {
142
+ r = (1 + light) * r;
143
+ g = (1 + light) * g;
144
+ b = (1 + light) * b;
145
+ }
146
+ else {
147
+ r = (1 - light) * r + light * 255;
148
+ g = (1 - light) * g + light * 255;
149
+ b = (1 - light) * b + light * 255;
150
+ }
151
+ return rgbToHex(r, g, b);
152
+ };
@@ -0,0 +1,2 @@
1
+ export declare const IndexedColors: readonly string[];
2
+ //# sourceMappingURL=colors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../colors.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,aAAa,mBAyExB,CAAC"}
@@ -0,0 +1,75 @@
1
+ // Excel indexed colors mapping used for legacy color references
2
+ export const IndexedColors = Object.freeze([
3
+ // 0-7
4
+ "#000000",
5
+ "#FFFFFF",
6
+ "#FF0000",
7
+ "#00FF00",
8
+ "#0000FF",
9
+ "#FFFF00",
10
+ "#FF00FF",
11
+ "#00FFFF",
12
+ // 8-15
13
+ "#000000",
14
+ "#FFFFFF",
15
+ "#FF0000",
16
+ "#00FF00",
17
+ "#0000FF",
18
+ "#FFFF00",
19
+ "#FF00FF",
20
+ "#00FFFF",
21
+ // 16-23
22
+ "#800000",
23
+ "#008000",
24
+ "#000080",
25
+ "#808000",
26
+ "#800080",
27
+ "#008080",
28
+ "#C0C0C0",
29
+ "#808080",
30
+ // 24-31
31
+ "#9999FF",
32
+ "#993366",
33
+ "#FFFFCC",
34
+ "#CCFFFF",
35
+ "#660066",
36
+ "#FF8080",
37
+ "#0066CC",
38
+ "#CCCCFF",
39
+ // 32-39
40
+ "#000080",
41
+ "#FF00FF",
42
+ "#FFFF00",
43
+ "#00FFFF",
44
+ "#800080",
45
+ "#800000",
46
+ "#008080",
47
+ "#0000FF",
48
+ // 40-47
49
+ "#00CCFF",
50
+ "#CCFFFF",
51
+ "#CCFFCC",
52
+ "#FFFF99",
53
+ "#99CCFF",
54
+ "#FF99CC",
55
+ "#CC99FF",
56
+ "#FFCC99",
57
+ // 48-55
58
+ "#3366FF",
59
+ "#33CCCC",
60
+ "#99CC00",
61
+ "#FFCC00",
62
+ "#FF9900",
63
+ "#FF6600",
64
+ "#666699",
65
+ "#969696",
66
+ // 56-63
67
+ "#003366",
68
+ "#339966",
69
+ "#003300",
70
+ "#333300",
71
+ "#993300",
72
+ "#993366",
73
+ "#333399",
74
+ "#333333",
75
+ ]);
@@ -0,0 +1,49 @@
1
+ import type { BooleanCondition } from "@rowsncolumns/common-types";
2
+ /**
3
+ * Minimal structural shape of a conditional-format rule needed by the
4
+ * predicate/builder below. The full `ConditionalFormatRule` type lives in the
5
+ * `@rowsncolumns/spreadsheet` package and is structurally compatible with
6
+ * this shape.
7
+ */
8
+ export type ConditionalFormatRuleLike = {
9
+ booleanRule?: {
10
+ condition?: BooleanCondition | null;
11
+ } | null;
12
+ };
13
+ /**
14
+ * Whether a CF rule is evaluated via the calculator (formula path) instead of
15
+ * the synchronous `checkBooleanRule` path used in
16
+ * `apps/spreadsheet/hooks/use-conditional-formatting.ts`.
17
+ *
18
+ * Returns `true` for every condition type that `buildConditionalFormatExpression`
19
+ * can express as a single-cell formula: CUSTOM_FORMULA, all NUMBER_/DATE_/TEXT_
20
+ * comparisons, BETWEEN/NOT_BETWEEN, CONTAINS/NOT_CONTAINS, STARTS_WITH/ENDS_WITH,
21
+ * ONE_OF_LIST/ONE_OF_RANGE, BLANK/NOT_BLANK, BOOLEAN, TEXT_IS_EMAIL/TEXT_IS_URL.
22
+ * The calculator stores the per-cell boolean on
23
+ * `cellData.conditionalFormattingResultById[ruleId]`.
24
+ *
25
+ * Returns `false` — leaving the rule on the sync path — for rules that aren't
26
+ * expressible as a single-cell formula:
27
+ * - Aggregate-over-range: gradient/heatmap, TOP/BOTTOM N, DUPLICATE/UNIQUE,
28
+ * NUMBER_ABOVE_AVERAGE / NUMBER_BELOW_AVERAGE — the result depends on
29
+ * other cells in the range, not just the current cell.
30
+ * - Loop-state: NUMBER_GREATER_THAN_PREVIOUS and the other `*_PREVIOUS`
31
+ * variants — compare against the prior row's value held in iteration state.
32
+ * - Calendar-relative dates: DATE_TODAY / DATE_THIS_WEEK / DATE_THIS_MONTH
33
+ * and the surrounding family, plus DATE_IS_VALID. Could be expressed via
34
+ * TODAY()-based formulas if we ever want to migrate them.
35
+ * - Cell error state: ERROR / NOT_ERROR — read directly from the extended
36
+ * value in `getValidationValue`.
37
+ *
38
+ * The consumers (rule create/update/delete enqueueing in spreadsheet-state,
39
+ * `getConditionalFormatFormula` building the expression, `getValidationValue`
40
+ * choosing where to read the per-cell value, and the `isFormulaRule` branch
41
+ * in `use-conditional-formatting.ts`) MUST stay in lockstep with this
42
+ * predicate — if it returns `true`, the calculator owns the result and the
43
+ * sync `checkBooleanRule` path must not run for that rule. Delegating to
44
+ * `buildConditionalFormatExpression` keeps the predicate and the builder from
45
+ * drifting.
46
+ */
47
+ export declare const isConditionalFormatFormulaRule: (rule: ConditionalFormatRuleLike | undefined) => boolean;
48
+ export declare const buildConditionalFormatExpression: (rule: ConditionalFormatRuleLike | undefined, baseCellRef: string, locale?: string) => string | undefined;
49
+ //# sourceMappingURL=conditional-format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conditional-format.d.ts","sourceRoot":"","sources":["../../conditional-format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAEjB,MAAM,4BAA4B,CAAC;AAKpC;;;;;GAKG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,WAAW,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;CAC9D,CAAC;AA+DF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,8BAA8B,GACzC,MAAM,yBAAyB,GAAG,SAAS,YAK5C,CAAC;AAEF,eAAO,MAAM,gCAAgC,GAC3C,MAAM,yBAAyB,GAAG,SAAS,EAC3C,aAAa,MAAM,EACnB,SAAS,MAAM,uBA8HhB,CAAC"}