@neo4j-ndl/react 4.18.0 → 4.18.2

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 (42) hide show
  1. package/lib/cjs/_generated/style-rules/index.js +10 -1
  2. package/lib/cjs/_generated/style-rules/index.js.map +1 -1
  3. package/lib/cjs/_generated/style-rules/literal-schemas.js +16 -1
  4. package/lib/cjs/_generated/style-rules/literal-schemas.js.map +1 -1
  5. package/lib/cjs/_generated/style-rules/numeric-utils.js +163 -0
  6. package/lib/cjs/_generated/style-rules/numeric-utils.js.map +1 -0
  7. package/lib/cjs/data-grid/stories/datagrid-rule-based-styling.story.js +40 -1
  8. package/lib/cjs/data-grid/stories/datagrid-rule-based-styling.story.js.map +1 -1
  9. package/lib/cjs/data-grid/style-rules/evaluate.js +56 -22
  10. package/lib/cjs/data-grid/style-rules/evaluate.js.map +1 -1
  11. package/lib/cjs/data-grid/style-rules/index.js +3 -1
  12. package/lib/cjs/data-grid/style-rules/index.js.map +1 -1
  13. package/lib/cjs/data-grid/style-rules/types.js +10 -6
  14. package/lib/cjs/data-grid/style-rules/types.js.map +1 -1
  15. package/lib/esm/_generated/style-rules/index.js +2 -1
  16. package/lib/esm/_generated/style-rules/index.js.map +1 -1
  17. package/lib/esm/_generated/style-rules/literal-schemas.js +15 -0
  18. package/lib/esm/_generated/style-rules/literal-schemas.js.map +1 -1
  19. package/lib/esm/_generated/style-rules/numeric-utils.js +155 -0
  20. package/lib/esm/_generated/style-rules/numeric-utils.js.map +1 -0
  21. package/lib/esm/data-grid/stories/datagrid-rule-based-styling.story.js +40 -1
  22. package/lib/esm/data-grid/stories/datagrid-rule-based-styling.story.js.map +1 -1
  23. package/lib/esm/data-grid/style-rules/evaluate.js +57 -23
  24. package/lib/esm/data-grid/style-rules/evaluate.js.map +1 -1
  25. package/lib/esm/data-grid/style-rules/index.js +1 -1
  26. package/lib/esm/data-grid/style-rules/index.js.map +1 -1
  27. package/lib/esm/data-grid/style-rules/types.js +10 -6
  28. package/lib/esm/data-grid/style-rules/types.js.map +1 -1
  29. package/lib/types/_generated/style-rules/index.d.ts +4 -2
  30. package/lib/types/_generated/style-rules/index.d.ts.map +1 -1
  31. package/lib/types/_generated/style-rules/literal-schemas.d.ts +13 -0
  32. package/lib/types/_generated/style-rules/literal-schemas.d.ts.map +1 -1
  33. package/lib/types/_generated/style-rules/numeric-utils.d.ts +45 -0
  34. package/lib/types/_generated/style-rules/numeric-utils.d.ts.map +1 -0
  35. package/lib/types/data-grid/stories/datagrid-rule-based-styling.story.d.ts.map +1 -1
  36. package/lib/types/data-grid/style-rules/evaluate.d.ts.map +1 -1
  37. package/lib/types/data-grid/style-rules/index.d.ts +2 -2
  38. package/lib/types/data-grid/style-rules/index.d.ts.map +1 -1
  39. package/lib/types/data-grid/style-rules/types.d.ts +66 -21
  40. package/lib/types/data-grid/style-rules/types.d.ts.map +1 -1
  41. package/package.json +2 -2
  42. package/skills/ndl-react/components/data-grid.md +48 -3
@@ -5,7 +5,7 @@
5
5
  * Regenerate with `pnpm generate:shared` (runs automatically at build/dev/install).
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.TimeLiteralSchema = exports.LocalDatetimeLiteralSchema = exports.DatetimeLiteralSchema = exports.parseTimeString = exports.parseLocalDateString = exports.parseDateString = exports.lerpColor = exports.getWeight = void 0;
8
+ exports.resolveNumericLiteral = exports.numericValuesEqual = exports.isBigintLiteral = exports.getNumericWeight = exports.compareNumericValues = exports.clampNumericValue = exports.TimeLiteralSchema = exports.NumericLiteralSchema = exports.LocalDatetimeLiteralSchema = exports.DatetimeLiteralSchema = exports.BigintLiteralSchema = exports.parseTimeString = exports.parseLocalDateString = exports.parseDateString = exports.lerpColor = exports.getWeight = void 0;
9
9
  /**
10
10
  *
11
11
  * Copyright (c) "Neo4j"
@@ -34,7 +34,16 @@ Object.defineProperty(exports, "parseDateString", { enumerable: true, get: funct
34
34
  Object.defineProperty(exports, "parseLocalDateString", { enumerable: true, get: function () { return date_utils_1.parseLocalDateString; } });
35
35
  Object.defineProperty(exports, "parseTimeString", { enumerable: true, get: function () { return date_utils_1.parseTimeString; } });
36
36
  var literal_schemas_1 = require("./literal-schemas");
37
+ Object.defineProperty(exports, "BigintLiteralSchema", { enumerable: true, get: function () { return literal_schemas_1.BigintLiteralSchema; } });
37
38
  Object.defineProperty(exports, "DatetimeLiteralSchema", { enumerable: true, get: function () { return literal_schemas_1.DatetimeLiteralSchema; } });
38
39
  Object.defineProperty(exports, "LocalDatetimeLiteralSchema", { enumerable: true, get: function () { return literal_schemas_1.LocalDatetimeLiteralSchema; } });
40
+ Object.defineProperty(exports, "NumericLiteralSchema", { enumerable: true, get: function () { return literal_schemas_1.NumericLiteralSchema; } });
39
41
  Object.defineProperty(exports, "TimeLiteralSchema", { enumerable: true, get: function () { return literal_schemas_1.TimeLiteralSchema; } });
42
+ var numeric_utils_1 = require("./numeric-utils");
43
+ Object.defineProperty(exports, "clampNumericValue", { enumerable: true, get: function () { return numeric_utils_1.clampNumericValue; } });
44
+ Object.defineProperty(exports, "compareNumericValues", { enumerable: true, get: function () { return numeric_utils_1.compareNumericValues; } });
45
+ Object.defineProperty(exports, "getNumericWeight", { enumerable: true, get: function () { return numeric_utils_1.getNumericWeight; } });
46
+ Object.defineProperty(exports, "isBigintLiteral", { enumerable: true, get: function () { return numeric_utils_1.isBigintLiteral; } });
47
+ Object.defineProperty(exports, "numericValuesEqual", { enumerable: true, get: function () { return numeric_utils_1.numericValuesEqual; } });
48
+ Object.defineProperty(exports, "resolveNumericLiteral", { enumerable: true, get: function () { return numeric_utils_1.resolveNumericLiteral; } });
40
49
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/_generated/style-rules/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,6CAAqD;AAA5C,wGAAA,SAAS,OAAA;AAAE,wGAAA,SAAS,OAAA;AAC7B,2CAIsB;AAHpB,6GAAA,eAAe,OAAA;AACf,kHAAA,oBAAoB,OAAA;AACpB,6GAAA,eAAe,OAAA;AAEjB,qDAI2B;AAHzB,wHAAA,qBAAqB,OAAA;AACrB,6HAAA,0BAA0B,OAAA;AAC1B,oHAAA,iBAAiB,OAAA","sourcesContent":["/*\n * AUTO-GENERATED FILE — DO NOT EDIT.\n * Source of truth: packages/style-rules/src/\n * Regenerate with `pnpm generate:shared` (runs automatically at build/dev/install).\n */\n\n/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nexport { getWeight, lerpColor } from './color-utils';\nexport {\n parseDateString,\n parseLocalDateString,\n parseTimeString,\n} from './date-utils';\nexport {\n DatetimeLiteralSchema,\n LocalDatetimeLiteralSchema,\n TimeLiteralSchema,\n} from './literal-schemas';\nexport type {\n DatetimeLiteral,\n LocalDatetimeLiteral,\n TimeLiteral,\n} from './literal-schemas';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/_generated/style-rules/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,6CAAqD;AAA5C,wGAAA,SAAS,OAAA;AAAE,wGAAA,SAAS,OAAA;AAC7B,2CAIsB;AAHpB,6GAAA,eAAe,OAAA;AACf,kHAAA,oBAAoB,OAAA;AACpB,6GAAA,eAAe,OAAA;AAEjB,qDAM2B;AALzB,sHAAA,mBAAmB,OAAA;AACnB,wHAAA,qBAAqB,OAAA;AACrB,6HAAA,0BAA0B,OAAA;AAC1B,uHAAA,oBAAoB,OAAA;AACpB,oHAAA,iBAAiB,OAAA;AASnB,iDAOyB;AANvB,kHAAA,iBAAiB,OAAA;AACjB,qHAAA,oBAAoB,OAAA;AACpB,iHAAA,gBAAgB,OAAA;AAChB,gHAAA,eAAe,OAAA;AACf,mHAAA,kBAAkB,OAAA;AAClB,sHAAA,qBAAqB,OAAA","sourcesContent":["/*\n * AUTO-GENERATED FILE — DO NOT EDIT.\n * Source of truth: packages/style-rules/src/\n * Regenerate with `pnpm generate:shared` (runs automatically at build/dev/install).\n */\n\n/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nexport { getWeight, lerpColor } from './color-utils';\nexport {\n parseDateString,\n parseLocalDateString,\n parseTimeString,\n} from './date-utils';\nexport {\n BigintLiteralSchema,\n DatetimeLiteralSchema,\n LocalDatetimeLiteralSchema,\n NumericLiteralSchema,\n TimeLiteralSchema,\n} from './literal-schemas';\nexport type {\n BigintLiteral,\n DatetimeLiteral,\n LocalDatetimeLiteral,\n NumericLiteral,\n TimeLiteral,\n} from './literal-schemas';\nexport {\n clampNumericValue,\n compareNumericValues,\n getNumericWeight,\n isBigintLiteral,\n numericValuesEqual,\n resolveNumericLiteral,\n} from './numeric-utils';\nexport type { NumericValue } from './numeric-utils';\n"]}
@@ -5,7 +5,7 @@
5
5
  * Regenerate with `pnpm generate:shared` (runs automatically at build/dev/install).
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.TimeLiteralSchema = exports.LocalDatetimeLiteralSchema = exports.DatetimeLiteralSchema = void 0;
8
+ exports.TimeLiteralSchema = exports.LocalDatetimeLiteralSchema = exports.DatetimeLiteralSchema = exports.NumericLiteralSchema = exports.BigintLiteralSchema = void 0;
9
9
  /**
10
10
  *
11
11
  * Copyright (c) "Neo4j"
@@ -28,6 +28,21 @@ exports.TimeLiteralSchema = exports.LocalDatetimeLiteralSchema = exports.Datetim
28
28
  */
29
29
  const zod_1 = require("zod");
30
30
  const date_utils_1 = require("./date-utils");
31
+ /**
32
+ * A JSON-safe bigint literal. Native bigint values cannot be serialized as
33
+ * JSON, so persisted style rules can use a signed decimal string instead.
34
+ */
35
+ exports.BigintLiteralSchema = zod_1.z.object({
36
+ bigint: zod_1.z.string().regex(/^[+-]?\d+$/, {
37
+ message: 'bigint must be a signed decimal integer string',
38
+ }),
39
+ });
40
+ /** A numeric style-rule literal, including native and JSON-safe bigints. */
41
+ exports.NumericLiteralSchema = zod_1.z.union([
42
+ zod_1.z.number(),
43
+ zod_1.z.bigint(),
44
+ exports.BigintLiteralSchema,
45
+ ]);
31
46
  /**
32
47
  * An ISO 8601 or RFC 9557 datetime literal that resolves to a Unix millisecond
33
48
  * timestamp at evaluation time. Supported formats:
@@ -1 +1 @@
1
- {"version":3,"file":"literal-schemas.js","sourceRoot":"","sources":["../../../../src/_generated/style-rules/literal-schemas.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,6BAAwB;AAExB,6CAIsB;AAEtB;;;;;;;;;GASG;AACU,QAAA,qBAAqB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC5C,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,4BAAe,EAAC,CAAC,CAAC,KAAK,IAAI,EAAE;QAC9D,OAAO,EACL,sEAAsE;KACzE,CAAC;CACH,CAAC,CAAC;AAGH;;;;;;;;;;;;GAYG;AACU,QAAA,0BAA0B,GAAG,OAAC,CAAC,MAAM,CAAC;IACjD,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,iCAAoB,EAAC,CAAC,CAAC,KAAK,IAAI,EAAE;QACxE,OAAO,EACL,kGAAkG;KACrG,CAAC;CACH,CAAC,CAAC;AAGH;;;;;;;;;;;;GAYG;AACU,QAAA,iBAAiB,GAAG,OAAC,CAAC,MAAM,CAAC;IACxC,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,4BAAe,EAAC,CAAC,CAAC,KAAK,IAAI,EAAE;QAC1D,OAAO,EACL,iFAAiF;KACpF,CAAC;CACH,CAAC,CAAC","sourcesContent":["/*\n * AUTO-GENERATED FILE — DO NOT EDIT.\n * Source of truth: packages/style-rules/src/\n * Regenerate with `pnpm generate:shared` (runs automatically at build/dev/install).\n */\n\n/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { z } from 'zod';\n\nimport {\n parseDateString,\n parseLocalDateString,\n parseTimeString,\n} from './date-utils';\n\n/**\n * An ISO 8601 or RFC 9557 datetime literal that resolves to a Unix millisecond\n * timestamp at evaluation time. Supported formats:\n * - RFC 9557 with IANA timezone: `\"2024-06-15T14:00:00[Europe/Stockholm]\"` (offset\n * inferred from the named zone, DST-aware) or `\"2024-06-15T14:00:00+02:00[Europe/Stockholm]\"`\n * (offset explicit)\n * - UTC or offset datetime: `\"2024-01-01T00:00:00Z\"`, `\"2024-01-01T00:00:00+02:00\"`\n * - Plain datetime (treated as UTC): `\"2024-01-01T14:30:00\"`, `\"2024-01-01T14:30:00.500\"`\n * - Date-only (treated as UTC midnight): `\"2024-01-01\"`\n */\nexport const DatetimeLiteralSchema = z.object({\n datetime: z.string().refine((s) => parseDateString(s) !== null, {\n message:\n 'datetime must be a valid ISO 8601 / RFC 9557 date or datetime string',\n }),\n});\nexport type DatetimeLiteral = z.infer<typeof DatetimeLiteralSchema>;\n\n/**\n * A plain (unzoned) ISO 8601 date or datetime literal that resolves to a Unix\n * millisecond timestamp at evaluation time, interpreting the wall-clock time\n * in the browser's local timezone.\n *\n * Only plain date/datetime strings without timezone qualifiers are accepted:\n * - Plain datetime: `\"2024-01-01T14:30:00\"`, `\"2024-01-01T14:30:00.500\"`\n * - Date-only (treated as local midnight): `\"2024-01-01\"`\n *\n * Strings with `Z`, a UTC offset (`+02:00`), or an IANA bracket\n * (`[Europe/Stockholm]`) are **rejected** — use `{ datetime }` for\n * timezone-aware instants. This matches the semantics of Neo4j `LocalDateTime`.\n */\nexport const LocalDatetimeLiteralSchema = z.object({\n localdatetime: z.string().refine((s) => parseLocalDateString(s) !== null, {\n message:\n 'localdatetime must be a valid ISO 8601 plain date or datetime string (no Z, offset, or timezone)',\n }),\n});\nexport type LocalDatetimeLiteral = z.infer<typeof LocalDatetimeLiteralSchema>;\n\n/**\n * An ISO 8601 time literal that resolves to milliseconds since UTC midnight\n * at evaluation time. Supported formats:\n * - Local time (treated as UTC): `\"14:30:00\"`, `\"14:30:00.500\"`\n * - UTC time: `\"14:30:00Z\"` — identical to local form\n * - Offset time (UTC-normalised): `\"14:30:00+02:00\"` → 45,000,000 ms (12:30 UTC)\n *\n * IANA timezone brackets (e.g. `[Europe/Stockholm]`) are **not** accepted — a\n * time-of-day value has no calendar date so DST cannot be resolved. Use\n * `{ datetime }` literals for timezone-aware instants.\n *\n * Full datetime strings (containing `T`) are rejected.\n */\nexport const TimeLiteralSchema = z.object({\n time: z.string().refine((s) => parseTimeString(s) !== null, {\n message:\n 'time must be a valid ISO 8601 time string (e.g. \"14:30:00\" or \"14:30:00+02:00\")',\n }),\n});\nexport type TimeLiteral = z.infer<typeof TimeLiteralSchema>;\n"]}
1
+ {"version":3,"file":"literal-schemas.js","sourceRoot":"","sources":["../../../../src/_generated/style-rules/literal-schemas.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,6BAAwB;AAExB,6CAIsB;AAEtB;;;GAGG;AACU,QAAA,mBAAmB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC1C,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE;QACrC,OAAO,EAAE,gDAAgD;KAC1D,CAAC;CACH,CAAC,CAAC;AAGH,4EAA4E;AAC/D,QAAA,oBAAoB,GAAG,OAAC,CAAC,KAAK,CAAC;IAC1C,OAAC,CAAC,MAAM,EAAE;IACV,OAAC,CAAC,MAAM,EAAE;IACV,2BAAmB;CACpB,CAAC,CAAC;AAGH;;;;;;;;;GASG;AACU,QAAA,qBAAqB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC5C,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,4BAAe,EAAC,CAAC,CAAC,KAAK,IAAI,EAAE;QAC9D,OAAO,EACL,sEAAsE;KACzE,CAAC;CACH,CAAC,CAAC;AAGH;;;;;;;;;;;;GAYG;AACU,QAAA,0BAA0B,GAAG,OAAC,CAAC,MAAM,CAAC;IACjD,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,iCAAoB,EAAC,CAAC,CAAC,KAAK,IAAI,EAAE;QACxE,OAAO,EACL,kGAAkG;KACrG,CAAC;CACH,CAAC,CAAC;AAGH;;;;;;;;;;;;GAYG;AACU,QAAA,iBAAiB,GAAG,OAAC,CAAC,MAAM,CAAC;IACxC,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,4BAAe,EAAC,CAAC,CAAC,KAAK,IAAI,EAAE;QAC1D,OAAO,EACL,iFAAiF;KACpF,CAAC;CACH,CAAC,CAAC","sourcesContent":["/*\n * AUTO-GENERATED FILE — DO NOT EDIT.\n * Source of truth: packages/style-rules/src/\n * Regenerate with `pnpm generate:shared` (runs automatically at build/dev/install).\n */\n\n/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { z } from 'zod';\n\nimport {\n parseDateString,\n parseLocalDateString,\n parseTimeString,\n} from './date-utils';\n\n/**\n * A JSON-safe bigint literal. Native bigint values cannot be serialized as\n * JSON, so persisted style rules can use a signed decimal string instead.\n */\nexport const BigintLiteralSchema = z.object({\n bigint: z.string().regex(/^[+-]?\\d+$/, {\n message: 'bigint must be a signed decimal integer string',\n }),\n});\nexport type BigintLiteral = z.infer<typeof BigintLiteralSchema>;\n\n/** A numeric style-rule literal, including native and JSON-safe bigints. */\nexport const NumericLiteralSchema = z.union([\n z.number(),\n z.bigint(),\n BigintLiteralSchema,\n]);\nexport type NumericLiteral = z.infer<typeof NumericLiteralSchema>;\n\n/**\n * An ISO 8601 or RFC 9557 datetime literal that resolves to a Unix millisecond\n * timestamp at evaluation time. Supported formats:\n * - RFC 9557 with IANA timezone: `\"2024-06-15T14:00:00[Europe/Stockholm]\"` (offset\n * inferred from the named zone, DST-aware) or `\"2024-06-15T14:00:00+02:00[Europe/Stockholm]\"`\n * (offset explicit)\n * - UTC or offset datetime: `\"2024-01-01T00:00:00Z\"`, `\"2024-01-01T00:00:00+02:00\"`\n * - Plain datetime (treated as UTC): `\"2024-01-01T14:30:00\"`, `\"2024-01-01T14:30:00.500\"`\n * - Date-only (treated as UTC midnight): `\"2024-01-01\"`\n */\nexport const DatetimeLiteralSchema = z.object({\n datetime: z.string().refine((s) => parseDateString(s) !== null, {\n message:\n 'datetime must be a valid ISO 8601 / RFC 9557 date or datetime string',\n }),\n});\nexport type DatetimeLiteral = z.infer<typeof DatetimeLiteralSchema>;\n\n/**\n * A plain (unzoned) ISO 8601 date or datetime literal that resolves to a Unix\n * millisecond timestamp at evaluation time, interpreting the wall-clock time\n * in the browser's local timezone.\n *\n * Only plain date/datetime strings without timezone qualifiers are accepted:\n * - Plain datetime: `\"2024-01-01T14:30:00\"`, `\"2024-01-01T14:30:00.500\"`\n * - Date-only (treated as local midnight): `\"2024-01-01\"`\n *\n * Strings with `Z`, a UTC offset (`+02:00`), or an IANA bracket\n * (`[Europe/Stockholm]`) are **rejected** — use `{ datetime }` for\n * timezone-aware instants. This matches the semantics of Neo4j `LocalDateTime`.\n */\nexport const LocalDatetimeLiteralSchema = z.object({\n localdatetime: z.string().refine((s) => parseLocalDateString(s) !== null, {\n message:\n 'localdatetime must be a valid ISO 8601 plain date or datetime string (no Z, offset, or timezone)',\n }),\n});\nexport type LocalDatetimeLiteral = z.infer<typeof LocalDatetimeLiteralSchema>;\n\n/**\n * An ISO 8601 time literal that resolves to milliseconds since UTC midnight\n * at evaluation time. Supported formats:\n * - Local time (treated as UTC): `\"14:30:00\"`, `\"14:30:00.500\"`\n * - UTC time: `\"14:30:00Z\"` — identical to local form\n * - Offset time (UTC-normalised): `\"14:30:00+02:00\"` → 45,000,000 ms (12:30 UTC)\n *\n * IANA timezone brackets (e.g. `[Europe/Stockholm]`) are **not** accepted — a\n * time-of-day value has no calendar date so DST cannot be resolved. Use\n * `{ datetime }` literals for timezone-aware instants.\n *\n * Full datetime strings (containing `T`) are rejected.\n */\nexport const TimeLiteralSchema = z.object({\n time: z.string().refine((s) => parseTimeString(s) !== null, {\n message:\n 'time must be a valid ISO 8601 time string (e.g. \"14:30:00\" or \"14:30:00+02:00\")',\n }),\n});\nexport type TimeLiteral = z.infer<typeof TimeLiteralSchema>;\n"]}
@@ -0,0 +1,163 @@
1
+ /**
2
+ *
3
+ * Copyright (c) "Neo4j"
4
+ * Neo4j Sweden AB [http://neo4j.com]
5
+ *
6
+ * This file is part of Neo4j.
7
+ *
8
+ * Neo4j is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ */
21
+
22
+ "use strict";
23
+ /*
24
+ * AUTO-GENERATED FILE — DO NOT EDIT.
25
+ * Source of truth: packages/style-rules/src/
26
+ * Regenerate with `pnpm generate:shared` (runs automatically at build/dev/install).
27
+ */
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.resolveNumericLiteral = resolveNumericLiteral;
30
+ exports.isBigintLiteral = isBigintLiteral;
31
+ exports.compareNumericValues = compareNumericValues;
32
+ exports.numericValuesEqual = numericValuesEqual;
33
+ exports.clampNumericValue = clampNumericValue;
34
+ exports.getNumericWeight = getNumericWeight;
35
+ const BIGINT_ZERO = BigInt(0);
36
+ const BIGINT_ONE = BigInt(1);
37
+ const BIGINT_TWO = BigInt(2);
38
+ const BIGINT_RATIO_SCALE = BigInt('1000000000000000000');
39
+ function bigintPowerOfTen(exponent) {
40
+ return BigInt(`1${'0'.repeat(exponent)}`);
41
+ }
42
+ /** Resolves a native or JSON-safe numeric literal without reducing bigints. */
43
+ function resolveNumericLiteral(value) {
44
+ return typeof value === 'object' ? BigInt(value.bigint) : value;
45
+ }
46
+ /** Returns whether a value is the JSON-safe bigint literal shape. */
47
+ function isBigintLiteral(value) {
48
+ return (typeof value === 'object' &&
49
+ value !== null &&
50
+ 'bigint' in value &&
51
+ typeof value.bigint === 'string' &&
52
+ /^[+-]?\d+$/.test(value.bigint));
53
+ }
54
+ /**
55
+ * Compares numeric values without coercing bigint operands to number.
56
+ * Returns null for NaN, otherwise -1, 0, or 1.
57
+ */
58
+ function compareNumericValues(left, right) {
59
+ if ((typeof left === 'number' && Number.isNaN(left)) ||
60
+ (typeof right === 'number' && Number.isNaN(right))) {
61
+ return null;
62
+ }
63
+ if (left < right) {
64
+ return -1;
65
+ }
66
+ if (left > right) {
67
+ return 1;
68
+ }
69
+ return 0;
70
+ }
71
+ /** Numeric equality that treats equivalent number and bigint values as equal. */
72
+ function numericValuesEqual(left, right) {
73
+ return compareNumericValues(left, right) === 0;
74
+ }
75
+ /**
76
+ * Clamps a numeric value between two endpoints. Inverted endpoints are
77
+ * supported, and the original number/bigint representation is retained.
78
+ */
79
+ function clampNumericValue(value, firstBound, secondBound) {
80
+ const boundsOrder = compareNumericValues(firstBound, secondBound);
81
+ if (boundsOrder === null) {
82
+ return null;
83
+ }
84
+ const min = boundsOrder <= 0 ? firstBound : secondBound;
85
+ const max = boundsOrder <= 0 ? secondBound : firstBound;
86
+ const minOrder = compareNumericValues(value, min);
87
+ const maxOrder = compareNumericValues(value, max);
88
+ if (minOrder === null || maxOrder === null) {
89
+ return null;
90
+ }
91
+ if (minOrder < 0) {
92
+ return min;
93
+ }
94
+ if (maxOrder > 0) {
95
+ return max;
96
+ }
97
+ return value;
98
+ }
99
+ function numberToRational(value) {
100
+ if (!Number.isFinite(value)) {
101
+ return null;
102
+ }
103
+ const match = /^([+-]?)(\d+)(?:\.(\d+))?(?:e([+-]?\d+))?$/i.exec(value.toString());
104
+ if (!match) {
105
+ return null;
106
+ }
107
+ const [, sign, integer, fraction = '', exponentText = '0'] = match;
108
+ const exponent = Number(exponentText) - fraction.length;
109
+ const digits = BigInt(`${sign}${integer}${fraction}`);
110
+ if (exponent >= 0) {
111
+ return {
112
+ denominator: BIGINT_ONE,
113
+ numerator: digits * bigintPowerOfTen(exponent),
114
+ };
115
+ }
116
+ return {
117
+ denominator: bigintPowerOfTen(-exponent),
118
+ numerator: digits,
119
+ };
120
+ }
121
+ function toRational(value) {
122
+ return typeof value === 'bigint'
123
+ ? { denominator: BIGINT_ONE, numerator: value }
124
+ : numberToRational(value);
125
+ }
126
+ function divideBigints(numerator, denominator) {
127
+ if (denominator === BIGINT_ZERO) {
128
+ return null;
129
+ }
130
+ const isNegative = numerator < BIGINT_ZERO !== denominator < BIGINT_ZERO;
131
+ const absoluteNumerator = numerator < BIGINT_ZERO ? -numerator : numerator;
132
+ const absoluteDenominator = denominator < BIGINT_ZERO ? -denominator : denominator;
133
+ const integer = absoluteNumerator / absoluteDenominator;
134
+ const remainder = absoluteNumerator % absoluteDenominator;
135
+ const fraction = (remainder * BIGINT_RATIO_SCALE + absoluteDenominator / BIGINT_TWO) /
136
+ absoluteDenominator;
137
+ const result = Number(integer) + Number(fraction) / Number(BIGINT_RATIO_SCALE);
138
+ return isNegative ? -result : result;
139
+ }
140
+ /**
141
+ * Computes `(value - startValue) / (endValue - startValue)` while retaining
142
+ * bigint precision. Only the final dimensionless interpolation weight is
143
+ * converted to number.
144
+ */
145
+ function getNumericWeight(startValue, endValue, value) {
146
+ if (typeof startValue === 'number' &&
147
+ typeof endValue === 'number' &&
148
+ typeof value === 'number') {
149
+ const weight = (value - startValue) / (endValue - startValue);
150
+ return Number.isNaN(weight) ? null : weight;
151
+ }
152
+ const start = toRational(startValue);
153
+ const end = toRational(endValue);
154
+ const current = toRational(value);
155
+ if (start === null || end === null || current === null) {
156
+ return null;
157
+ }
158
+ const valueDelta = current.numerator * start.denominator -
159
+ start.numerator * current.denominator;
160
+ const rangeDelta = end.numerator * start.denominator - start.numerator * end.denominator;
161
+ return divideBigints(valueDelta * end.denominator, current.denominator * rangeDelta);
162
+ }
163
+ //# sourceMappingURL=numeric-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"numeric-utils.js","sourceRoot":"","sources":["../../../../src/_generated/style-rules/numeric-utils.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * AUTO-GENERATED FILE — DO NOT EDIT.\n * Source of truth: packages/style-rules/src/\n * Regenerate with `pnpm generate:shared` (runs automatically at build/dev/install).\n */\n\n/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport type { BigintLiteral, NumericLiteral } from './literal-schemas';\n\nexport type NumericValue = number | bigint;\n\ntype Rational = {\n denominator: bigint;\n numerator: bigint;\n};\n\nconst BIGINT_ZERO = BigInt(0);\nconst BIGINT_ONE = BigInt(1);\nconst BIGINT_TWO = BigInt(2);\nconst BIGINT_RATIO_SCALE = BigInt('1000000000000000000');\n\nfunction bigintPowerOfTen(exponent: number): bigint {\n return BigInt(`1${'0'.repeat(exponent)}`);\n}\n\n/** Resolves a native or JSON-safe numeric literal without reducing bigints. */\nexport function resolveNumericLiteral(value: NumericLiteral): NumericValue {\n return typeof value === 'object' ? BigInt(value.bigint) : value;\n}\n\n/** Returns whether a value is the JSON-safe bigint literal shape. */\nexport function isBigintLiteral(value: unknown): value is BigintLiteral {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'bigint' in value &&\n typeof value.bigint === 'string' &&\n /^[+-]?\\d+$/.test(value.bigint)\n );\n}\n\n/**\n * Compares numeric values without coercing bigint operands to number.\n * Returns null for NaN, otherwise -1, 0, or 1.\n */\nexport function compareNumericValues(\n left: NumericValue,\n right: NumericValue,\n): -1 | 0 | 1 | null {\n if (\n (typeof left === 'number' && Number.isNaN(left)) ||\n (typeof right === 'number' && Number.isNaN(right))\n ) {\n return null;\n }\n if (left < right) {\n return -1;\n }\n if (left > right) {\n return 1;\n }\n return 0;\n}\n\n/** Numeric equality that treats equivalent number and bigint values as equal. */\nexport function numericValuesEqual(\n left: NumericValue,\n right: NumericValue,\n): boolean {\n return compareNumericValues(left, right) === 0;\n}\n\n/**\n * Clamps a numeric value between two endpoints. Inverted endpoints are\n * supported, and the original number/bigint representation is retained.\n */\nexport function clampNumericValue(\n value: NumericValue,\n firstBound: NumericValue,\n secondBound: NumericValue,\n): NumericValue | null {\n const boundsOrder = compareNumericValues(firstBound, secondBound);\n if (boundsOrder === null) {\n return null;\n }\n const min = boundsOrder <= 0 ? firstBound : secondBound;\n const max = boundsOrder <= 0 ? secondBound : firstBound;\n const minOrder = compareNumericValues(value, min);\n const maxOrder = compareNumericValues(value, max);\n if (minOrder === null || maxOrder === null) {\n return null;\n }\n if (minOrder < 0) {\n return min;\n }\n if (maxOrder > 0) {\n return max;\n }\n return value;\n}\n\nfunction numberToRational(value: number): Rational | null {\n if (!Number.isFinite(value)) {\n return null;\n }\n\n const match = /^([+-]?)(\\d+)(?:\\.(\\d+))?(?:e([+-]?\\d+))?$/i.exec(\n value.toString(),\n );\n if (!match) {\n return null;\n }\n\n const [, sign, integer, fraction = '', exponentText = '0'] = match;\n const exponent = Number(exponentText) - fraction.length;\n const digits = BigInt(`${sign}${integer}${fraction}`);\n if (exponent >= 0) {\n return {\n denominator: BIGINT_ONE,\n numerator: digits * bigintPowerOfTen(exponent),\n };\n }\n return {\n denominator: bigintPowerOfTen(-exponent),\n numerator: digits,\n };\n}\n\nfunction toRational(value: NumericValue): Rational | null {\n return typeof value === 'bigint'\n ? { denominator: BIGINT_ONE, numerator: value }\n : numberToRational(value);\n}\n\nfunction divideBigints(numerator: bigint, denominator: bigint): number | null {\n if (denominator === BIGINT_ZERO) {\n return null;\n }\n\n const isNegative = numerator < BIGINT_ZERO !== denominator < BIGINT_ZERO;\n const absoluteNumerator = numerator < BIGINT_ZERO ? -numerator : numerator;\n const absoluteDenominator =\n denominator < BIGINT_ZERO ? -denominator : denominator;\n const integer = absoluteNumerator / absoluteDenominator;\n const remainder = absoluteNumerator % absoluteDenominator;\n const fraction =\n (remainder * BIGINT_RATIO_SCALE + absoluteDenominator / BIGINT_TWO) /\n absoluteDenominator;\n const result =\n Number(integer) + Number(fraction) / Number(BIGINT_RATIO_SCALE);\n\n return isNegative ? -result : result;\n}\n\n/**\n * Computes `(value - startValue) / (endValue - startValue)` while retaining\n * bigint precision. Only the final dimensionless interpolation weight is\n * converted to number.\n */\nexport function getNumericWeight(\n startValue: NumericValue,\n endValue: NumericValue,\n value: NumericValue,\n): number | null {\n if (\n typeof startValue === 'number' &&\n typeof endValue === 'number' &&\n typeof value === 'number'\n ) {\n const weight = (value - startValue) / (endValue - startValue);\n return Number.isNaN(weight) ? null : weight;\n }\n\n const start = toRational(startValue);\n const end = toRational(endValue);\n const current = toRational(value);\n if (start === null || end === null || current === null) {\n return null;\n }\n\n const valueDelta =\n current.numerator * start.denominator -\n start.numerator * current.denominator;\n const rangeDelta =\n end.numerator * start.denominator - start.numerator * end.denominator;\n\n return divideBigints(\n valueDelta * end.denominator,\n current.denominator * rangeDelta,\n );\n}\n"]}
@@ -25,6 +25,8 @@ require("@neo4j-ndl/base/lib/neo4j-ds-styles.css");
25
25
  const react_1 = require("@neo4j-ndl/react");
26
26
  const react_table_1 = require("@tanstack/react-table");
27
27
  const staticData_1 = require("./staticData");
28
+ const BIGINT_ID_START = BigInt('9007199254740993');
29
+ const tableData = staticData_1.TABLE_DEMO_DATA.map((row, index) => (Object.assign(Object.assign({}, row), { preciseId: BIGINT_ID_START + BigInt(index) })));
28
30
  const styleRules = [
29
31
  // Row coloring: all cells styled when name contains "Alicia"
30
32
  {
@@ -83,6 +85,37 @@ const styleRules = [
83
85
  ],
84
86
  },
85
87
  },
88
+ // Bigint range: adjacent values above Number.MAX_SAFE_INTEGER retain their
89
+ // precision. Wrapped literals are JSON-safe; BigInt(...) is programmatic.
90
+ {
91
+ apply: {
92
+ colorRange: {
93
+ maxColor: '#7c3aed',
94
+ maxValue: BIGINT_ID_START + BigInt(tableData.length - 1),
95
+ minColor: '#ede9fe',
96
+ minValue: { bigint: BIGINT_ID_START.toString() },
97
+ onColumn: 'preciseId',
98
+ },
99
+ textColor: { value: '#111827' },
100
+ },
101
+ column: 'preciseId',
102
+ priority: 1,
103
+ },
104
+ // Exact bigint comparison using the JSON-safe literal form.
105
+ {
106
+ apply: {
107
+ color: { value: '#4c1d95' },
108
+ textColor: { value: '#ffffff' },
109
+ },
110
+ column: 'preciseId',
111
+ priority: 2,
112
+ where: {
113
+ equal: [
114
+ { column: 'preciseId' },
115
+ { bigint: (BIGINT_ID_START + BigInt(2)).toString() },
116
+ ],
117
+ },
118
+ },
86
119
  ];
87
120
  const Component = () => {
88
121
  const columnHelper = (0, react_table_1.createColumnHelper)();
@@ -98,6 +131,12 @@ const Component = () => {
98
131
  header: () => 'Age',
99
132
  minSize: 80,
100
133
  }),
134
+ columnHelper.accessor('preciseId', {
135
+ cell: (info) => info.getValue().toString(),
136
+ header: () => 'Bigint ID',
137
+ minSize: 180,
138
+ size: 180,
139
+ }),
101
140
  columnHelper.accessor('cypherCommand', {
102
141
  cell: (info) => info.getValue(),
103
142
  header: () => 'Cypher Command',
@@ -108,7 +147,7 @@ const Component = () => {
108
147
  const table = (0, react_table_1.useReactTable)({
109
148
  columnResizeMode: 'onChange',
110
149
  columns,
111
- data: staticData_1.TABLE_DEMO_DATA,
150
+ data: tableData,
112
151
  defaultColumn: {
113
152
  maxSize: 800,
114
153
  minSize: 80,
@@ -1 +1 @@
1
- {"version":3,"file":"datagrid-rule-based-styling.story.js","sourceRoot":"","sources":["../../../../src/data-grid/stories/datagrid-rule-based-styling.story.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport '@neo4j-ndl/base/lib/neo4j-ds-styles.css';\n\nimport { DataGrid } from '@neo4j-ndl/react';\nimport {\n createColumnHelper,\n getCoreRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n useReactTable,\n} from '@tanstack/react-table';\n\nimport { type DataGridStyleRule } from '../style-rules/types';\nimport { TABLE_DEMO_DATA, type TestDataFormat } from './staticData';\n\nconst styleRules: DataGridStyleRule[] = [\n // Row coloring: all cells styled when name contains \"Alicia\"\n {\n apply: {\n color: { value: '#000000' },\n textColor: { value: '#ffffff' },\n },\n column: null,\n priority: 3,\n where: { contains: [{ column: 'name' }, 'Alicia'] },\n },\n // Cell coloring: cells in the \"age\" column with value 51 get green\n {\n apply: { color: { value: '#00bb00' } },\n column: 'age',\n priority: 3,\n where: { equal: [{ column: 'age' }, 51] },\n },\n // Dual color ranges on the \"age\" column: independent gradients for background\n // (driven by age, full 0-100 range) and text color (driven by age too, but\n // with a narrower 20-80 band so the text contrast is calibrated separately).\n {\n apply: {\n colorRange: {\n maxColor: '#f00000',\n maxValue: 100,\n midColor: '#a00000',\n midValue: 50,\n minColor: '#800000',\n minValue: 0,\n onColumn: 'age',\n },\n textColorRange: {\n maxColor: '#aaaaaa',\n maxValue: 80,\n minColor: '#ffffff',\n minValue: 20,\n onColumn: 'age',\n },\n },\n column: 'age',\n priority: 2, // Lower priority so explicit green rule overrides\n },\n // Multi-column rule: all cells styled when age > 50 AND name contains \"o\"\n {\n apply: {\n color: { value: '#fef3c7' },\n textColor: { value: '#000000' },\n },\n column: null,\n priority: 0, // Lower priority so other rules take precedence\n where: {\n and: [\n { greaterThan: [{ column: 'age' }, 50] },\n { contains: [{ column: 'name' }, 'o'] },\n ],\n },\n },\n];\n\nconst Component = () => {\n const columnHelper = createColumnHelper<TestDataFormat>();\n\n const columns = [\n columnHelper.accessor('name', {\n cell: (info) => info.getValue(),\n header: () => 'Name',\n minSize: 180,\n size: 220,\n }),\n columnHelper.accessor('age', {\n cell: (info) => info.renderValue(),\n header: () => 'Age',\n minSize: 80,\n }),\n columnHelper.accessor('cypherCommand', {\n cell: (info) => info.getValue(),\n header: () => 'Cypher Command',\n minSize: 400,\n size: 400,\n }),\n ];\n\n const table = useReactTable({\n columnResizeMode: 'onChange',\n columns,\n data: TABLE_DEMO_DATA,\n defaultColumn: {\n maxSize: 800,\n minSize: 80,\n },\n enableSorting: true,\n getCoreRowModel: getCoreRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n getSortedRowModel: getSortedRowModel(),\n initialState: {\n pagination: {\n pageSize: 10,\n },\n },\n });\n\n return (\n <div className=\"n-w-full n-bg-light-neutral-text-weakest\">\n <DataGrid\n isResizable={false}\n tableInstance={table}\n isKeyboardNavigable={false}\n styleRules={styleRules}\n styling={{\n borderStyle: 'all-sides',\n hasHoverEffects: true,\n hasZebraStriping: false,\n }}\n />\n </div>\n );\n};\n\nexport default Component;\n"]}
1
+ {"version":3,"file":"datagrid-rule-based-styling.story.js","sourceRoot":"","sources":["../../../../src/data-grid/stories/datagrid-rule-based-styling.story.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport '@neo4j-ndl/base/lib/neo4j-ds-styles.css';\n\nimport { DataGrid } from '@neo4j-ndl/react';\nimport {\n createColumnHelper,\n getCoreRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n useReactTable,\n} from '@tanstack/react-table';\n\nimport { type DataGridStyleRule } from '../style-rules/types';\nimport { TABLE_DEMO_DATA, type TestDataFormat } from './staticData';\n\ntype BigintTestDataFormat = TestDataFormat & { preciseId: bigint };\n\nconst BIGINT_ID_START = BigInt('9007199254740993');\nconst tableData: BigintTestDataFormat[] = TABLE_DEMO_DATA.map((row, index) => ({\n ...row,\n preciseId: BIGINT_ID_START + BigInt(index),\n}));\n\nconst styleRules: DataGridStyleRule[] = [\n // Row coloring: all cells styled when name contains \"Alicia\"\n {\n apply: {\n color: { value: '#000000' },\n textColor: { value: '#ffffff' },\n },\n column: null,\n priority: 3,\n where: { contains: [{ column: 'name' }, 'Alicia'] },\n },\n // Cell coloring: cells in the \"age\" column with value 51 get green\n {\n apply: { color: { value: '#00bb00' } },\n column: 'age',\n priority: 3,\n where: { equal: [{ column: 'age' }, 51] },\n },\n // Dual color ranges on the \"age\" column: independent gradients for background\n // (driven by age, full 0-100 range) and text color (driven by age too, but\n // with a narrower 20-80 band so the text contrast is calibrated separately).\n {\n apply: {\n colorRange: {\n maxColor: '#f00000',\n maxValue: 100,\n midColor: '#a00000',\n midValue: 50,\n minColor: '#800000',\n minValue: 0,\n onColumn: 'age',\n },\n textColorRange: {\n maxColor: '#aaaaaa',\n maxValue: 80,\n minColor: '#ffffff',\n minValue: 20,\n onColumn: 'age',\n },\n },\n column: 'age',\n priority: 2, // Lower priority so explicit green rule overrides\n },\n // Multi-column rule: all cells styled when age > 50 AND name contains \"o\"\n {\n apply: {\n color: { value: '#fef3c7' },\n textColor: { value: '#000000' },\n },\n column: null,\n priority: 0, // Lower priority so other rules take precedence\n where: {\n and: [\n { greaterThan: [{ column: 'age' }, 50] },\n { contains: [{ column: 'name' }, 'o'] },\n ],\n },\n },\n // Bigint range: adjacent values above Number.MAX_SAFE_INTEGER retain their\n // precision. Wrapped literals are JSON-safe; BigInt(...) is programmatic.\n {\n apply: {\n colorRange: {\n maxColor: '#7c3aed',\n maxValue: BIGINT_ID_START + BigInt(tableData.length - 1),\n minColor: '#ede9fe',\n minValue: { bigint: BIGINT_ID_START.toString() },\n onColumn: 'preciseId',\n },\n textColor: { value: '#111827' },\n },\n column: 'preciseId',\n priority: 1,\n },\n // Exact bigint comparison using the JSON-safe literal form.\n {\n apply: {\n color: { value: '#4c1d95' },\n textColor: { value: '#ffffff' },\n },\n column: 'preciseId',\n priority: 2,\n where: {\n equal: [\n { column: 'preciseId' },\n { bigint: (BIGINT_ID_START + BigInt(2)).toString() },\n ],\n },\n },\n];\n\nconst Component = () => {\n const columnHelper = createColumnHelper<BigintTestDataFormat>();\n\n const columns = [\n columnHelper.accessor('name', {\n cell: (info) => info.getValue(),\n header: () => 'Name',\n minSize: 180,\n size: 220,\n }),\n columnHelper.accessor('age', {\n cell: (info) => info.renderValue(),\n header: () => 'Age',\n minSize: 80,\n }),\n columnHelper.accessor('preciseId', {\n cell: (info) => info.getValue().toString(),\n header: () => 'Bigint ID',\n minSize: 180,\n size: 180,\n }),\n columnHelper.accessor('cypherCommand', {\n cell: (info) => info.getValue(),\n header: () => 'Cypher Command',\n minSize: 400,\n size: 400,\n }),\n ];\n\n const table = useReactTable({\n columnResizeMode: 'onChange',\n columns,\n data: tableData,\n defaultColumn: {\n maxSize: 800,\n minSize: 80,\n },\n enableSorting: true,\n getCoreRowModel: getCoreRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n getSortedRowModel: getSortedRowModel(),\n initialState: {\n pagination: {\n pageSize: 10,\n },\n },\n });\n\n return (\n <div className=\"n-w-full n-bg-light-neutral-text-weakest\">\n <DataGrid\n isResizable={false}\n tableInstance={table}\n isKeyboardNavigable={false}\n styleRules={styleRules}\n styling={{\n borderStyle: 'all-sides',\n hasHoverEffects: true,\n hasZebraStriping: false,\n }}\n />\n </div>\n );\n};\n\nexport default Component;\n"]}
@@ -31,11 +31,20 @@ function getInterpolatedColor(colorRange, rowData, converters) {
31
31
  }
32
32
  const minRgb = (0, react_color_1.color)(minColor).rgb;
33
33
  const maxRgb = (0, react_color_1.color)(maxColor).rgb;
34
- const actualMinValue = Math.min(minValue, maxValue);
35
- const actualMaxValue = Math.max(minValue, maxValue);
34
+ const resolvedMinValue = (0, style_rules_1.resolveNumericLiteral)(minValue);
35
+ const resolvedMaxValue = (0, style_rules_1.resolveNumericLiteral)(maxValue);
36
+ const boundsOrder = (0, style_rules_1.compareNumericValues)(resolvedMinValue, resolvedMaxValue);
37
+ if (boundsOrder === null) {
38
+ return null;
39
+ }
40
+ const actualMinValue = boundsOrder <= 0 ? resolvedMinValue : resolvedMaxValue;
41
+ const actualMaxValue = boundsOrder <= 0 ? resolvedMaxValue : resolvedMinValue;
36
42
  let midRgb = undefined;
43
+ const resolvedMidValue = midValue === undefined ? undefined : (0, style_rules_1.resolveNumericLiteral)(midValue);
37
44
  if (midValue !== undefined && midColor !== undefined) {
38
- const isMidInRange = actualMinValue <= midValue && midValue <= actualMaxValue;
45
+ const minToMid = (0, style_rules_1.compareNumericValues)(actualMinValue, resolvedMidValue);
46
+ const midToMax = (0, style_rules_1.compareNumericValues)(resolvedMidValue, actualMaxValue);
47
+ const isMidInRange = minToMid !== null && midToMax !== null && minToMid <= 0 && midToMax <= 0;
39
48
  if (!isMidInRange || !(0, react_color_1.validHex)(midColor)) {
40
49
  return null;
41
50
  }
@@ -43,12 +52,11 @@ function getInterpolatedColor(colorRange, rowData, converters) {
43
52
  }
44
53
  const rawValue = rowData[onColumn];
45
54
  let numericValue = null;
46
- if (typeof rawValue === 'number') {
47
- numericValue = Number.isFinite(rawValue) ? rawValue : null;
48
- }
49
- else if (typeof rawValue === 'bigint') {
50
- const n = Number(rawValue);
51
- numericValue = Number.isFinite(n) ? n : null;
55
+ if (typeof rawValue === 'number' || typeof rawValue === 'bigint') {
56
+ numericValue =
57
+ typeof rawValue === 'bigint' || Number.isFinite(rawValue)
58
+ ? rawValue
59
+ : null;
52
60
  }
53
61
  else if (rawValue instanceof Date) {
54
62
  const ts = rawValue.getTime();
@@ -58,33 +66,57 @@ function getInterpolatedColor(colorRange, rowData, converters) {
58
66
  const converter = converters === null || converters === void 0 ? void 0 : converters[onColumn];
59
67
  if (converter !== undefined) {
60
68
  const converted = converter(rawValue);
61
- if (typeof converted === 'number') {
62
- numericValue = Number.isFinite(converted) ? converted : null;
69
+ if (typeof converted === 'number' || typeof converted === 'bigint') {
70
+ numericValue =
71
+ typeof converted === 'bigint' || Number.isFinite(converted)
72
+ ? converted
73
+ : null;
74
+ }
75
+ else if ((0, style_rules_1.isBigintLiteral)(converted)) {
76
+ numericValue = (0, style_rules_1.resolveNumericLiteral)(converted);
63
77
  }
64
78
  }
65
79
  }
66
80
  if (numericValue === null) {
67
81
  return null;
68
82
  }
69
- const clampedValue = Math.max(actualMinValue, Math.min(actualMaxValue, numericValue));
83
+ const clampedValue = (0, style_rules_1.clampNumericValue)(numericValue, actualMinValue, actualMaxValue);
84
+ if (clampedValue === null) {
85
+ return null;
86
+ }
70
87
  let rgb;
71
- if (midRgb !== undefined && midValue !== undefined) {
72
- const t = (0, style_rules_1.getWeight)(minValue, midValue, clampedValue);
88
+ if (midRgb !== undefined && resolvedMidValue !== undefined) {
89
+ const t = (0, style_rules_1.getNumericWeight)(resolvedMinValue, resolvedMidValue, clampedValue);
90
+ if (t === null) {
91
+ return null;
92
+ }
73
93
  const isBetweenMinAndMid = t <= 1;
74
94
  if (isBetweenMinAndMid) {
75
95
  rgb = (0, style_rules_1.lerpColor)(minRgb, midRgb, t);
76
96
  }
77
97
  else {
78
- const t2 = (0, style_rules_1.getWeight)(midValue, maxValue, clampedValue);
98
+ const t2 = (0, style_rules_1.getNumericWeight)(resolvedMidValue, resolvedMaxValue, clampedValue);
99
+ if (t2 === null) {
100
+ return null;
101
+ }
79
102
  rgb = (0, style_rules_1.lerpColor)(midRgb, maxRgb, t2);
80
103
  }
81
104
  }
82
105
  else {
83
- const t = (0, style_rules_1.getWeight)(minValue, maxValue, clampedValue);
106
+ const t = (0, style_rules_1.getNumericWeight)(resolvedMinValue, resolvedMaxValue, clampedValue);
107
+ if (t === null) {
108
+ return null;
109
+ }
84
110
  rgb = (0, style_rules_1.lerpColor)(minRgb, maxRgb, t);
85
111
  }
86
112
  return (0, react_color_1.rgbToHex)(rgb);
87
113
  }
114
+ function resolveLiteral(value) {
115
+ if (value === undefined) {
116
+ return null;
117
+ }
118
+ return (0, style_rules_1.isBigintLiteral)(value) ? (0, style_rules_1.resolveNumericLiteral)(value) : value;
119
+ }
88
120
  function resolveValue(value, rowData, converters) {
89
121
  if (typeof value === 'object' && value !== null && 'column' in value) {
90
122
  const cellVal = rowData[value.column];
@@ -93,19 +125,17 @@ function resolveValue(value, rowData, converters) {
93
125
  }
94
126
  if (typeof cellVal === 'string' ||
95
127
  typeof cellVal === 'number' ||
96
- typeof cellVal === 'boolean') {
128
+ typeof cellVal === 'boolean' ||
129
+ typeof cellVal === 'bigint') {
97
130
  return cellVal;
98
131
  }
99
- if (typeof cellVal === 'bigint') {
100
- return Number(cellVal);
101
- }
102
132
  if (cellVal instanceof Date) {
103
133
  const ts = cellVal.getTime();
104
134
  return isNaN(ts) ? null : ts;
105
135
  }
106
136
  const converter = converters === null || converters === void 0 ? void 0 : converters[value.column];
107
137
  if (converter !== undefined) {
108
- return converter(cellVal);
138
+ return resolveLiteral(converter(cellVal));
109
139
  }
110
140
  return null;
111
141
  }
@@ -118,7 +148,7 @@ function resolveValue(value, rowData, converters) {
118
148
  if (typeof value === 'object' && value !== null && 'time' in value) {
119
149
  return (0, style_rules_1.parseTimeString)(value.time);
120
150
  }
121
- return value;
151
+ return resolveLiteral(value);
122
152
  }
123
153
  function safeCompare(left, right, rowData, compareFn, converters) {
124
154
  const leftVal = resolveValue(left, rowData, converters);
@@ -150,6 +180,10 @@ function evaluateWhere(rowData, where, converters) {
150
180
  if (leftVal === null || rightVal === null) {
151
181
  return null;
152
182
  }
183
+ if ((typeof leftVal === 'number' || typeof leftVal === 'bigint') &&
184
+ (typeof rightVal === 'number' || typeof rightVal === 'bigint')) {
185
+ return (0, style_rules_1.numericValuesEqual)(leftVal, rightVal);
186
+ }
153
187
  return leftVal === rightVal;
154
188
  }
155
189
  if ('not' in where) {