@neo4j-ndl/react 4.18.6 → 4.18.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/_generated/style-rules/index.js +7 -1
- package/lib/cjs/_generated/style-rules/index.js.map +1 -1
- package/lib/cjs/_generated/style-rules/literal-schemas.js +32 -1
- package/lib/cjs/_generated/style-rules/literal-schemas.js.map +1 -1
- package/lib/cjs/_generated/style-rules/range-utils.js +46 -0
- package/lib/cjs/_generated/style-rules/range-utils.js.map +1 -0
- package/lib/cjs/ai/user-bubble/UserBubble.js +39 -2
- package/lib/cjs/ai/user-bubble/UserBubble.js.map +1 -1
- package/lib/cjs/ai/user-bubble/stories/user-bubble.story.js +1 -5
- package/lib/cjs/ai/user-bubble/stories/user-bubble.story.js.map +1 -1
- package/lib/cjs/data-grid/stories/datagrid-rule-based-styling-datetime.story.js +26 -8
- package/lib/cjs/data-grid/stories/datagrid-rule-based-styling-datetime.story.js.map +1 -1
- package/lib/cjs/data-grid/style-rules/evaluate.js +60 -55
- package/lib/cjs/data-grid/style-rules/evaluate.js.map +1 -1
- package/lib/cjs/data-grid/style-rules/index.js +2 -1
- package/lib/cjs/data-grid/style-rules/index.js.map +1 -1
- package/lib/cjs/data-grid/style-rules/types.js +20 -14
- package/lib/cjs/data-grid/style-rules/types.js.map +1 -1
- package/lib/esm/_generated/style-rules/index.js +2 -1
- package/lib/esm/_generated/style-rules/index.js.map +1 -1
- package/lib/esm/_generated/style-rules/literal-schemas.js +28 -0
- package/lib/esm/_generated/style-rules/literal-schemas.js.map +1 -1
- package/lib/esm/_generated/style-rules/range-utils.js +43 -0
- package/lib/esm/_generated/style-rules/range-utils.js.map +1 -0
- package/lib/esm/ai/user-bubble/UserBubble.js +41 -4
- package/lib/esm/ai/user-bubble/UserBubble.js.map +1 -1
- package/lib/esm/ai/user-bubble/stories/user-bubble.story.js +1 -5
- package/lib/esm/ai/user-bubble/stories/user-bubble.story.js.map +1 -1
- package/lib/esm/data-grid/stories/datagrid-rule-based-styling-datetime.story.js +26 -8
- package/lib/esm/data-grid/stories/datagrid-rule-based-styling-datetime.story.js.map +1 -1
- package/lib/esm/data-grid/style-rules/evaluate.js +61 -56
- package/lib/esm/data-grid/style-rules/evaluate.js.map +1 -1
- package/lib/esm/data-grid/style-rules/index.js +1 -1
- package/lib/esm/data-grid/style-rules/index.js.map +1 -1
- package/lib/esm/data-grid/style-rules/types.js +20 -14
- package/lib/esm/data-grid/style-rules/types.js.map +1 -1
- package/lib/types/_generated/style-rules/index.d.ts +3 -2
- package/lib/types/_generated/style-rules/index.d.ts.map +1 -1
- package/lib/types/_generated/style-rules/literal-schemas.d.ts +20 -0
- package/lib/types/_generated/style-rules/literal-schemas.d.ts.map +1 -1
- package/lib/types/_generated/style-rules/range-utils.d.ts +26 -0
- package/lib/types/_generated/style-rules/range-utils.d.ts.map +1 -0
- package/lib/types/ai/user-bubble/UserBubble.d.ts +7 -1
- package/lib/types/ai/user-bubble/UserBubble.d.ts.map +1 -1
- package/lib/types/ai/user-bubble/stories/user-bubble.story.d.ts.map +1 -1
- package/lib/types/data-grid/stories/datagrid-rule-based-styling-datetime.story.d.ts.map +1 -1
- package/lib/types/data-grid/style-rules/evaluate.d.ts.map +1 -1
- package/lib/types/data-grid/style-rules/index.d.ts +2 -2
- package/lib/types/data-grid/style-rules/index.d.ts.map +1 -1
- package/lib/types/data-grid/style-rules/types.d.ts +141 -28
- package/lib/types/data-grid/style-rules/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/skills/ndl-react/components/ai/user-bubble.md +1 -0
- package/skills/ndl-react/components/data-grid.md +27 -9
|
@@ -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.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;
|
|
8
|
+
exports.resolveRangeLiteral = exports.resolveNumericLiteral = exports.numericValuesEqual = exports.isBigintLiteral = exports.getNumericWeight = exports.compareNumericValues = exports.clampNumericValue = exports.TimeLiteralSchema = exports.RangeLiteralSchema = exports.NumericLiteralSchema = exports.LocalDatetimeLiteralSchema = exports.isTimeLiteral = exports.isLocalDatetimeLiteral = exports.isDatetimeLiteral = 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"
|
|
@@ -36,8 +36,12 @@ Object.defineProperty(exports, "parseTimeString", { enumerable: true, get: funct
|
|
|
36
36
|
var literal_schemas_1 = require("./literal-schemas");
|
|
37
37
|
Object.defineProperty(exports, "BigintLiteralSchema", { enumerable: true, get: function () { return literal_schemas_1.BigintLiteralSchema; } });
|
|
38
38
|
Object.defineProperty(exports, "DatetimeLiteralSchema", { enumerable: true, get: function () { return literal_schemas_1.DatetimeLiteralSchema; } });
|
|
39
|
+
Object.defineProperty(exports, "isDatetimeLiteral", { enumerable: true, get: function () { return literal_schemas_1.isDatetimeLiteral; } });
|
|
40
|
+
Object.defineProperty(exports, "isLocalDatetimeLiteral", { enumerable: true, get: function () { return literal_schemas_1.isLocalDatetimeLiteral; } });
|
|
41
|
+
Object.defineProperty(exports, "isTimeLiteral", { enumerable: true, get: function () { return literal_schemas_1.isTimeLiteral; } });
|
|
39
42
|
Object.defineProperty(exports, "LocalDatetimeLiteralSchema", { enumerable: true, get: function () { return literal_schemas_1.LocalDatetimeLiteralSchema; } });
|
|
40
43
|
Object.defineProperty(exports, "NumericLiteralSchema", { enumerable: true, get: function () { return literal_schemas_1.NumericLiteralSchema; } });
|
|
44
|
+
Object.defineProperty(exports, "RangeLiteralSchema", { enumerable: true, get: function () { return literal_schemas_1.RangeLiteralSchema; } });
|
|
41
45
|
Object.defineProperty(exports, "TimeLiteralSchema", { enumerable: true, get: function () { return literal_schemas_1.TimeLiteralSchema; } });
|
|
42
46
|
var numeric_utils_1 = require("./numeric-utils");
|
|
43
47
|
Object.defineProperty(exports, "clampNumericValue", { enumerable: true, get: function () { return numeric_utils_1.clampNumericValue; } });
|
|
@@ -46,4 +50,6 @@ Object.defineProperty(exports, "getNumericWeight", { enumerable: true, get: func
|
|
|
46
50
|
Object.defineProperty(exports, "isBigintLiteral", { enumerable: true, get: function () { return numeric_utils_1.isBigintLiteral; } });
|
|
47
51
|
Object.defineProperty(exports, "numericValuesEqual", { enumerable: true, get: function () { return numeric_utils_1.numericValuesEqual; } });
|
|
48
52
|
Object.defineProperty(exports, "resolveNumericLiteral", { enumerable: true, get: function () { return numeric_utils_1.resolveNumericLiteral; } });
|
|
53
|
+
var range_utils_1 = require("./range-utils");
|
|
54
|
+
Object.defineProperty(exports, "resolveRangeLiteral", { enumerable: true, get: function () { return range_utils_1.resolveRangeLiteral; } });
|
|
49
55
|
//# 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,
|
|
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,qDAU2B;AATzB,sHAAA,mBAAmB,OAAA;AACnB,wHAAA,qBAAqB,OAAA;AACrB,oHAAA,iBAAiB,OAAA;AACjB,yHAAA,sBAAsB,OAAA;AACtB,gHAAA,aAAa,OAAA;AACb,6HAAA,0BAA0B,OAAA;AAC1B,uHAAA,oBAAoB,OAAA;AACpB,qHAAA,kBAAkB,OAAA;AAClB,oHAAA,iBAAiB,OAAA;AAUnB,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;AAGvB,6CAAoD;AAA3C,kHAAA,mBAAmB,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 isDatetimeLiteral,\n isLocalDatetimeLiteral,\n isTimeLiteral,\n LocalDatetimeLiteralSchema,\n NumericLiteralSchema,\n RangeLiteralSchema,\n TimeLiteralSchema,\n} from './literal-schemas';\nexport type {\n BigintLiteral,\n DatetimeLiteral,\n LocalDatetimeLiteral,\n NumericLiteral,\n RangeLiteral,\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';\nexport { resolveRangeLiteral } from './range-utils';\n"]}
|
|
@@ -5,7 +5,10 @@
|
|
|
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.NumericLiteralSchema = exports.BigintLiteralSchema = void 0;
|
|
8
|
+
exports.RangeLiteralSchema = exports.TimeLiteralSchema = exports.LocalDatetimeLiteralSchema = exports.DatetimeLiteralSchema = exports.NumericLiteralSchema = exports.BigintLiteralSchema = void 0;
|
|
9
|
+
exports.isDatetimeLiteral = isDatetimeLiteral;
|
|
10
|
+
exports.isLocalDatetimeLiteral = isLocalDatetimeLiteral;
|
|
11
|
+
exports.isTimeLiteral = isTimeLiteral;
|
|
9
12
|
/**
|
|
10
13
|
*
|
|
11
14
|
* Copyright (c) "Neo4j"
|
|
@@ -94,4 +97,32 @@ exports.TimeLiteralSchema = zod_1.z.object({
|
|
|
94
97
|
message: 'time must be a valid ISO 8601 time string (e.g. "14:30:00" or "14:30:00+02:00")',
|
|
95
98
|
}),
|
|
96
99
|
});
|
|
100
|
+
function isObjectWithStringKey(value, key) {
|
|
101
|
+
return (typeof value === 'object' &&
|
|
102
|
+
value !== null &&
|
|
103
|
+
key in value &&
|
|
104
|
+
typeof value[key] === 'string');
|
|
105
|
+
}
|
|
106
|
+
/** Returns whether a value is a `{ datetime: string }` wrapper. Does not validate the string. */
|
|
107
|
+
function isDatetimeLiteral(value) {
|
|
108
|
+
return isObjectWithStringKey(value, 'datetime');
|
|
109
|
+
}
|
|
110
|
+
/** Returns whether a value is a `{ localdatetime: string }` wrapper. Does not validate the string. */
|
|
111
|
+
function isLocalDatetimeLiteral(value) {
|
|
112
|
+
return isObjectWithStringKey(value, 'localdatetime');
|
|
113
|
+
}
|
|
114
|
+
/** Returns whether a value is a `{ time: string }` wrapper. Does not validate the string. */
|
|
115
|
+
function isTimeLiteral(value) {
|
|
116
|
+
return isObjectWithStringKey(value, 'time');
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* A continuous, orderable literal that can be used as a range boundary.
|
|
120
|
+
* Temporal literals resolve to numbers before range interpolation.
|
|
121
|
+
*/
|
|
122
|
+
exports.RangeLiteralSchema = zod_1.z.union([
|
|
123
|
+
exports.NumericLiteralSchema,
|
|
124
|
+
exports.DatetimeLiteralSchema,
|
|
125
|
+
exports.LocalDatetimeLiteralSchema,
|
|
126
|
+
exports.TimeLiteralSchema,
|
|
127
|
+
]);
|
|
97
128
|
//# sourceMappingURL=literal-schemas.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"literal-schemas.js","sourceRoot":"","sources":["../../../../src/_generated/style-rules/literal-schemas.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;
|
|
1
|
+
{"version":3,"file":"literal-schemas.js","sourceRoot":"","sources":["../../../../src/_generated/style-rules/literal-schemas.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AA2HH,8CAEC;AAGD,wDAIC;AAGD,sCAEC;AAvID;;;;;;;;;;;;;;;;;;;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;AAGH,SAAS,qBAAqB,CAC5B,KAAc,EACd,GAAM;IAEN,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,GAAG,IAAI,KAAK;QACZ,OAAQ,KAAiC,CAAC,GAAG,CAAC,KAAK,QAAQ,CAC5D,CAAC;AACJ,CAAC;AAED,iGAAiG;AACjG,SAAgB,iBAAiB,CAAC,KAAc;IAC9C,OAAO,qBAAqB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;AAClD,CAAC;AAED,sGAAsG;AACtG,SAAgB,sBAAsB,CACpC,KAAc;IAEd,OAAO,qBAAqB,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;AACvD,CAAC;AAED,6FAA6F;AAC7F,SAAgB,aAAa,CAAC,KAAc;IAC1C,OAAO,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACU,QAAA,kBAAkB,GAAG,OAAC,CAAC,KAAK,CAAC;IACxC,4BAAoB;IACpB,6BAAqB;IACrB,kCAA0B;IAC1B,yBAAiB;CAClB,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\nfunction isObjectWithStringKey<K extends string>(\n value: unknown,\n key: K,\n): value is Record<K, string> {\n return (\n typeof value === 'object' &&\n value !== null &&\n key in value &&\n typeof (value as Record<string, unknown>)[key] === 'string'\n );\n}\n\n/** Returns whether a value is a `{ datetime: string }` wrapper. Does not validate the string. */\nexport function isDatetimeLiteral(value: unknown): value is DatetimeLiteral {\n return isObjectWithStringKey(value, 'datetime');\n}\n\n/** Returns whether a value is a `{ localdatetime: string }` wrapper. Does not validate the string. */\nexport function isLocalDatetimeLiteral(\n value: unknown,\n): value is LocalDatetimeLiteral {\n return isObjectWithStringKey(value, 'localdatetime');\n}\n\n/** Returns whether a value is a `{ time: string }` wrapper. Does not validate the string. */\nexport function isTimeLiteral(value: unknown): value is TimeLiteral {\n return isObjectWithStringKey(value, 'time');\n}\n\n/**\n * A continuous, orderable literal that can be used as a range boundary.\n * Temporal literals resolve to numbers before range interpolation.\n */\nexport const RangeLiteralSchema = z.union([\n NumericLiteralSchema,\n DatetimeLiteralSchema,\n LocalDatetimeLiteralSchema,\n TimeLiteralSchema,\n]);\nexport type RangeLiteral = z.infer<typeof RangeLiteralSchema>;\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* AUTO-GENERATED FILE — DO NOT EDIT.
|
|
4
|
+
* Source of truth: packages/style-rules/src/
|
|
5
|
+
* Regenerate with `pnpm generate:shared` (runs automatically at build/dev/install).
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.resolveRangeLiteral = resolveRangeLiteral;
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* Copyright (c) "Neo4j"
|
|
12
|
+
* Neo4j Sweden AB [http://neo4j.com]
|
|
13
|
+
*
|
|
14
|
+
* This file is part of Neo4j.
|
|
15
|
+
*
|
|
16
|
+
* Neo4j is free software: you can redistribute it and/or modify
|
|
17
|
+
* it under the terms of the GNU General Public License as published by
|
|
18
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
19
|
+
* (at your option) any later version.
|
|
20
|
+
*
|
|
21
|
+
* This program is distributed in the hope that it will be useful,
|
|
22
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
23
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
24
|
+
* GNU General Public License for more details.
|
|
25
|
+
*
|
|
26
|
+
* You should have received a copy of the GNU General Public License
|
|
27
|
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
28
|
+
*/
|
|
29
|
+
const date_utils_1 = require("./date-utils");
|
|
30
|
+
const numeric_utils_1 = require("./numeric-utils");
|
|
31
|
+
/** Resolves a range literal to the numeric representation used for interpolation. */
|
|
32
|
+
function resolveRangeLiteral(value) {
|
|
33
|
+
if (typeof value === 'object' && value !== null) {
|
|
34
|
+
if ('datetime' in value) {
|
|
35
|
+
return (0, date_utils_1.parseDateString)(value.datetime);
|
|
36
|
+
}
|
|
37
|
+
if ('localdatetime' in value) {
|
|
38
|
+
return (0, date_utils_1.parseLocalDateString)(value.localdatetime);
|
|
39
|
+
}
|
|
40
|
+
if ('time' in value) {
|
|
41
|
+
return (0, date_utils_1.parseTimeString)(value.time);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return (0, numeric_utils_1.resolveNumericLiteral)(value);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=range-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"range-utils.js","sourceRoot":"","sources":["../../../../src/_generated/style-rules/range-utils.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAgCH,kDAaC;AA3CD;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,6CAIsB;AAEtB,mDAA2E;AAE3E,qFAAqF;AACrF,SAAgB,mBAAmB,CAAC,KAAmB;IACrD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;YACxB,OAAO,IAAA,4BAAe,EAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACzC,CAAC;QACD,IAAI,eAAe,IAAI,KAAK,EAAE,CAAC;YAC7B,OAAO,IAAA,iCAAoB,EAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;YACpB,OAAO,IAAA,4BAAe,EAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IACD,OAAO,IAAA,qCAAqB,EAAC,KAAK,CAAC,CAAC;AACtC,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 {\n parseDateString,\n parseLocalDateString,\n parseTimeString,\n} from './date-utils';\nimport type { RangeLiteral } from './literal-schemas';\nimport { type NumericValue, resolveNumericLiteral } from './numeric-utils';\n\n/** Resolves a range literal to the numeric representation used for interpolation. */\nexport function resolveRangeLiteral(value: RangeLiteral): NumericValue | null {\n if (typeof value === 'object' && value !== null) {\n if ('datetime' in value) {\n return parseDateString(value.datetime);\n }\n if ('localdatetime' in value) {\n return parseLocalDateString(value.localdatetime);\n }\n if ('time' in value) {\n return parseTimeString(value.time);\n }\n }\n return resolveNumericLiteral(value);\n}\n"]}
|
|
@@ -38,6 +38,9 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
38
38
|
*/
|
|
39
39
|
const react_1 = require("@neo4j-ndl/react");
|
|
40
40
|
const classnames_1 = __importDefault(require("classnames"));
|
|
41
|
+
const react_2 = require("react");
|
|
42
|
+
const ChevronDownIconOutline_1 = require("../../icons/generated/heroIcons/ChevronDownIconOutline");
|
|
43
|
+
const ChevronUpIconOutline_1 = require("../../icons/generated/heroIcons/ChevronUpIconOutline");
|
|
41
44
|
/**
|
|
42
45
|
* The component is used to display the user's message in a chat.
|
|
43
46
|
* It has an avatar to represent the user and a trailing element to display potential additional actions.
|
|
@@ -45,9 +48,43 @@ const classnames_1 = __importDefault(require("classnames"));
|
|
|
45
48
|
* @alpha - Changes to this component may be breaking.
|
|
46
49
|
*/
|
|
47
50
|
const UserBubbleComponent = (_a) => {
|
|
48
|
-
var { avatarProps, trailingElement, children, className, style, htmlAttributes, ref } = _a, restProps = __rest(_a, ["avatarProps", "trailingElement", "children", "className", "style", "htmlAttributes", "ref"]);
|
|
51
|
+
var { avatarProps, trailingElement, children, maxLines = 4, className, style, htmlAttributes, ref } = _a, restProps = __rest(_a, ["avatarProps", "trailingElement", "children", "maxLines", "className", "style", "htmlAttributes", "ref"]);
|
|
49
52
|
const classes = (0, classnames_1.default)('ndl-ai-user-bubble', className);
|
|
50
|
-
|
|
53
|
+
const contentRef = (0, react_2.useRef)(null);
|
|
54
|
+
const [isExpanded, setIsExpanded] = (0, react_2.useState)(false);
|
|
55
|
+
const [hasOverflow, setHasOverflow] = (0, react_2.useState)(false);
|
|
56
|
+
const isCollapseEnabled = maxLines !== null;
|
|
57
|
+
(0, react_2.useLayoutEffect)(() => {
|
|
58
|
+
const element = contentRef.current;
|
|
59
|
+
if (element === null || maxLines === null) {
|
|
60
|
+
setHasOverflow(false);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const checkOverflow = () => {
|
|
64
|
+
const lineHeight = Number.parseFloat(window.getComputedStyle(element).lineHeight);
|
|
65
|
+
if (!Number.isFinite(lineHeight)) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
setHasOverflow(element.scrollHeight > lineHeight * maxLines + 1);
|
|
69
|
+
};
|
|
70
|
+
checkOverflow();
|
|
71
|
+
const resizeObserver = new ResizeObserver(checkOverflow);
|
|
72
|
+
resizeObserver.observe(element);
|
|
73
|
+
return () => {
|
|
74
|
+
resizeObserver.disconnect();
|
|
75
|
+
};
|
|
76
|
+
}, [children, isExpanded, maxLines]);
|
|
77
|
+
const expandButton = hasOverflow ? ((0, jsx_runtime_1.jsxs)("div", { className: "ndl-ai-user-bubble-expand-wrap", children: [(0, jsx_runtime_1.jsx)(react_1.CleanIconButton, { className: "ndl-ai-user-bubble-expand", size: "small", onClick: () => setIsExpanded((expanded) => !expanded), description: isExpanded ? 'Show less' : 'Show more', htmlAttributes: {
|
|
78
|
+
'aria-expanded': isExpanded,
|
|
79
|
+
type: 'button',
|
|
80
|
+
}, children: isExpanded ? (0, jsx_runtime_1.jsx)(ChevronUpIconOutline_1.ChevronUpIconOutline, {}) : (0, jsx_runtime_1.jsx)(ChevronDownIconOutline_1.ChevronDownIconOutline, {}) }), (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: "ndl-ai-user-bubble-expand-blur", "aria-hidden": "true" }), (0, jsx_runtime_1.jsx)("div", { className: "ndl-ai-user-bubble-expand-fill", "aria-hidden": "true" })] })] })) : null;
|
|
81
|
+
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ ref: ref, className: classes, style: style }, restProps, htmlAttributes, { children: [avatarProps && ((0, jsx_runtime_1.jsx)(react_1.Avatar, Object.assign({ type: "image" }, avatarProps, { size: "small", shape: "circle", className: (0, classnames_1.default)('ndl-ai-user-bubble-avatar', avatarProps === null || avatarProps === void 0 ? void 0 : avatarProps.className) }))), (0, jsx_runtime_1.jsxs)("div", { className: "ndl-ai-user-bubble-main", children: [(0, jsx_runtime_1.jsxs)(react_1.Typography, { as: "div", variant: "body-medium", ref: contentRef, className: (0, classnames_1.default)('ndl-ai-user-bubble-content', {
|
|
82
|
+
'ndl-ai-user-bubble-content-clamped': isCollapseEnabled && !isExpanded,
|
|
83
|
+
}), style: isCollapseEnabled
|
|
84
|
+
? {
|
|
85
|
+
'--ndl-ai-user-bubble-collapsed-lines': maxLines,
|
|
86
|
+
}
|
|
87
|
+
: undefined, children: [children, hasOverflow && isExpanded && ((0, jsx_runtime_1.jsx)("span", { className: "ndl-ai-user-bubble-expand-spacer", "aria-hidden": "true" }))] }), hasOverflow && ((0, jsx_runtime_1.jsx)("div", { className: "ndl-ai-user-bubble-toggle", children: expandButton }))] }), (0, jsx_runtime_1.jsx)("div", { className: "ndl-ai-user-bubble-trailing", children: trailingElement })] })));
|
|
51
88
|
};
|
|
52
89
|
exports.UserBubble = UserBubbleComponent;
|
|
53
90
|
//# sourceMappingURL=UserBubble.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserBubble.js","sourceRoot":"","sources":["../../../../src/ai/user-bubble/UserBubble.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,
|
|
1
|
+
{"version":3,"file":"UserBubble.js","sourceRoot":"","sources":["../../../../src/ai/user-bubble/UserBubble.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 { Avatar, CleanIconButton, Typography } from '@neo4j-ndl/react';\nimport classNames from 'classnames';\nimport { useLayoutEffect, useRef, useState } from 'react';\n\nimport type { CommonProps } from '../../_common/types';\nimport { ChevronDownIconOutline } from '../../icons/generated/heroIcons/ChevronDownIconOutline';\nimport { ChevronUpIconOutline } from '../../icons/generated/heroIcons/ChevronUpIconOutline';\n\ntype UserBubbleProps = {\n /** The content of the user bubble */\n children?: React.ReactNode;\n /** The props for the avatar */\n avatarProps?: React.ComponentProps<typeof Avatar>;\n /** The element to display after the content. Could be a CleanIconButton to edit the user bubble. */\n trailingElement?: React.ReactNode;\n /**\n * Maximum number of lines visible before the message is collapsed.\n * Set to `null` to always show the full message.\n * @default 4\n */\n maxLines?: number | null;\n};\n\n/**\n * The component is used to display the user's message in a chat.\n * It has an avatar to represent the user and a trailing element to display potential additional actions.\n *\n * @alpha - Changes to this component may be breaking.\n */\nconst UserBubbleComponent = ({\n avatarProps,\n trailingElement,\n children,\n maxLines = 4,\n className,\n style,\n htmlAttributes,\n ref,\n ...restProps\n}: CommonProps<'div', UserBubbleProps>) => {\n const classes = classNames('ndl-ai-user-bubble', className);\n const contentRef = useRef<HTMLDivElement>(null);\n const [isExpanded, setIsExpanded] = useState(false);\n const [hasOverflow, setHasOverflow] = useState(false);\n const isCollapseEnabled = maxLines !== null;\n\n useLayoutEffect(() => {\n const element = contentRef.current;\n if (element === null || maxLines === null) {\n setHasOverflow(false);\n return;\n }\n\n const checkOverflow = () => {\n const lineHeight = Number.parseFloat(\n window.getComputedStyle(element).lineHeight,\n );\n if (!Number.isFinite(lineHeight)) {\n return;\n }\n\n setHasOverflow(element.scrollHeight > lineHeight * maxLines + 1);\n };\n\n checkOverflow();\n\n const resizeObserver = new ResizeObserver(checkOverflow);\n resizeObserver.observe(element);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [children, isExpanded, maxLines]);\n\n const expandButton = hasOverflow ? (\n <div className=\"ndl-ai-user-bubble-expand-wrap\">\n <CleanIconButton\n className=\"ndl-ai-user-bubble-expand\"\n size=\"small\"\n onClick={() => setIsExpanded((expanded) => !expanded)}\n description={isExpanded ? 'Show less' : 'Show more'}\n htmlAttributes={{\n 'aria-expanded': isExpanded,\n type: 'button',\n }}\n >\n {isExpanded ? <ChevronUpIconOutline /> : <ChevronDownIconOutline />}\n </CleanIconButton>\n <>\n <div className=\"ndl-ai-user-bubble-expand-blur\" aria-hidden=\"true\" />\n <div className=\"ndl-ai-user-bubble-expand-fill\" aria-hidden=\"true\" />\n </>\n </div>\n ) : null;\n\n return (\n <div\n ref={ref}\n className={classes}\n style={style}\n {...restProps}\n {...htmlAttributes}\n >\n {avatarProps && (\n <Avatar\n type=\"image\"\n {...avatarProps}\n size=\"small\"\n shape=\"circle\"\n className={classNames(\n 'ndl-ai-user-bubble-avatar',\n avatarProps?.className,\n )}\n />\n )}\n <div className=\"ndl-ai-user-bubble-main\">\n <Typography\n as=\"div\"\n variant=\"body-medium\"\n ref={contentRef}\n className={classNames('ndl-ai-user-bubble-content', {\n 'ndl-ai-user-bubble-content-clamped':\n isCollapseEnabled && !isExpanded,\n })}\n style={\n isCollapseEnabled\n ? ({\n '--ndl-ai-user-bubble-collapsed-lines': maxLines,\n } as React.CSSProperties)\n : undefined\n }\n >\n {children}\n {hasOverflow && isExpanded && (\n <span\n className=\"ndl-ai-user-bubble-expand-spacer\"\n aria-hidden=\"true\"\n />\n )}\n </Typography>\n {hasOverflow && (\n <div className=\"ndl-ai-user-bubble-toggle\">{expandButton}</div>\n )}\n </div>\n <div className=\"ndl-ai-user-bubble-trailing\">{trailingElement}</div>\n </div>\n );\n};\n\nexport { UserBubbleComponent as UserBubble };\n"]}
|
|
@@ -24,11 +24,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
24
24
|
require("@neo4j-ndl/base/lib/neo4j-ds-styles.css");
|
|
25
25
|
const ai_1 = require("@neo4j-ndl/react/ai");
|
|
26
26
|
const Component = () => {
|
|
27
|
-
return (
|
|
28
|
-
name: 'KM',
|
|
29
|
-
source: 'https://media.istockphoto.com/id/1334716681/photo/a-smiling-man.jpg?s=612x612&w=0&k=20&c=U6rkSDpQMzkcJEqx2hAa63fNLIhqnZb31Xuc_QSi648=',
|
|
30
|
-
type: 'image',
|
|
31
|
-
}, children: "Can you analyse my data and tell me about...?" }));
|
|
27
|
+
return (0, jsx_runtime_1.jsx)(ai_1.UserBubble, { children: "Can you analyse my data and tell me about...?" });
|
|
32
28
|
};
|
|
33
29
|
exports.default = Component;
|
|
34
30
|
//# sourceMappingURL=user-bubble.story.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-bubble.story.js","sourceRoot":"","sources":["../../../../../src/ai/user-bubble/stories/user-bubble.story.tsx"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,mDAAiD;AAEjD,4CAAiD;AAEjD,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,OAAO,
|
|
1
|
+
{"version":3,"file":"user-bubble.story.js","sourceRoot":"","sources":["../../../../../src/ai/user-bubble/stories/user-bubble.story.tsx"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,mDAAiD;AAEjD,4CAAiD;AAEjD,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,OAAO,uBAAC,eAAU,gEAA2D,CAAC;AAChF,CAAC,CAAC;AAEF,kBAAe,SAAS,CAAC","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 { UserBubble } from '@neo4j-ndl/react/ai';\n\nconst Component = () => {\n return <UserBubble>Can you analyse my data and tell me about...?</UserBubble>;\n};\n\nexport default Component;\n"]}
|
|
@@ -74,16 +74,13 @@ const data = [
|
|
|
74
74
|
// 13:15 Paris CEST (+02:00) = 11:15 UTC
|
|
75
75
|
scheduledDate: new Date('2026-07-08T13:15:00+02:00'),
|
|
76
76
|
scheduledTimeMs: 11 * 3600000 + 15 * 60000,
|
|
77
|
-
status: '
|
|
77
|
+
status: 'confirmed',
|
|
78
78
|
},
|
|
79
|
-
// ── Far future (after 2026-07-15T00:00 Stockholm / CEST = 2026-07-14T22:00Z)
|
|
80
79
|
{
|
|
81
80
|
event: 'Architecture summit',
|
|
82
81
|
localTimeDisplay: '08:00 CEST (+02:00)',
|
|
83
|
-
// 08:00 Amsterdam CEST (+02:00) = 06:00 UTC
|
|
84
|
-
|
|
85
|
-
// same UTC day as July 14 22:00Z, so it crosses the far-future boundary.
|
|
86
|
-
scheduledDate: new Date('2026-07-15T08:00:00+02:00'),
|
|
82
|
+
// 08:00 Amsterdam CEST (+02:00) = 06:00 UTC
|
|
83
|
+
scheduledDate: new Date('2026-07-11T08:00:00+02:00'),
|
|
87
84
|
scheduledTimeMs: 6 * 3600000,
|
|
88
85
|
status: 'confirmed',
|
|
89
86
|
},
|
|
@@ -91,17 +88,18 @@ const data = [
|
|
|
91
88
|
event: 'Annual conference',
|
|
92
89
|
localTimeDisplay: '09:00 PDT (-07:00)',
|
|
93
90
|
// 09:00 San Francisco PDT (-07:00) = 16:00 UTC — after Stockholm closes
|
|
94
|
-
scheduledDate: new Date('2026-
|
|
91
|
+
scheduledDate: new Date('2026-07-13T09:00:00-07:00'),
|
|
95
92
|
scheduledTimeMs: 16 * 3600000,
|
|
96
93
|
status: 'confirmed',
|
|
97
94
|
},
|
|
95
|
+
// ── Far future (after 2026-07-15T00:00 Stockholm / CEST = 2026-07-14T22:00Z)
|
|
98
96
|
{
|
|
99
97
|
event: 'Year-end planning',
|
|
100
98
|
localTimeDisplay: '09:00 JST (+09:00)',
|
|
101
99
|
// 09:00 Tokyo JST (+09:00) = 00:00 UTC — midnight, well before Stockholm opens
|
|
102
100
|
scheduledDate: new Date('2026-11-20T09:00:00+09:00'),
|
|
103
101
|
scheduledTimeMs: 0,
|
|
104
|
-
status: '
|
|
102
|
+
status: 'cancelled',
|
|
105
103
|
},
|
|
106
104
|
];
|
|
107
105
|
/**
|
|
@@ -122,6 +120,26 @@ const data = [
|
|
|
122
120
|
* { time: '17:00:00+02:00' } resolves to 15:00 UTC (54 000 000 ms)
|
|
123
121
|
*/
|
|
124
122
|
const styleRules = [
|
|
123
|
+
// Near-future date cells use temporal literals directly as gradient
|
|
124
|
+
// boundaries. Several rows are spread across this interval so the progression
|
|
125
|
+
// from amber to blue is easy to see.
|
|
126
|
+
{
|
|
127
|
+
apply: {
|
|
128
|
+
colorRange: {
|
|
129
|
+
maxColor: '#dbeafe',
|
|
130
|
+
maxValue: {
|
|
131
|
+
datetime: '2026-07-15T00:00:00[Europe/Stockholm]',
|
|
132
|
+
},
|
|
133
|
+
minColor: '#fef3c7',
|
|
134
|
+
minValue: {
|
|
135
|
+
datetime: '2026-06-26T00:00:00[Europe/Stockholm]',
|
|
136
|
+
},
|
|
137
|
+
onColumn: 'scheduledDate',
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
column: 'scheduledDate',
|
|
141
|
+
priority: 0,
|
|
142
|
+
},
|
|
125
143
|
// Past events — entire row in muted red
|
|
126
144
|
{
|
|
127
145
|
apply: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"datagrid-rule-based-styling-datetime.story.js","sourceRoot":"","sources":["../../../../src/data-grid/stories/datagrid-rule-based-styling-datetime.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';\n\ntype EventRow = {\n event: string;\n /**\n * JS Date coerced from the event's local ISO string. Natively converted to\n * Unix ms by the engine and compared against { datetime: \"...\" } literals.\n */\n scheduledDate: Date;\n /**\n * UTC milliseconds since midnight. Compared against { time: \"...\" } literals\n * that are defined in Stockholm / CEST (+02:00) time — the engine normalises\n * both sides to UTC before comparing.\n */\n scheduledTimeMs: number;\n /** Human-readable local time shown in the cell, e.g. \"09:00 CEST (+02:00)\". */\n localTimeDisplay: string;\n status: 'confirmed' | 'delayed' | 'cancelled';\n};\n\nconst data: EventRow[] = [\n // ── Past events (before start of 2026-06-25 in Stockholm / CEST) ──────────\n {\n event: 'Quarterly review',\n localTimeDisplay: '09:00 CEST (+02:00)',\n // 09:00 Stockholm CEST = 07:00 UTC\n scheduledDate: new Date('2026-06-10T09:00:00+02:00'),\n scheduledTimeMs: 7 * 3_600_000,\n status: 'confirmed',\n },\n {\n event: 'Security audit',\n localTimeDisplay: '07:30 BST (+01:00)',\n // 07:30 London BST (+01:00) = 06:30 UTC — before Stockholm opens\n scheduledDate: new Date('2026-06-18T07:30:00+01:00'),\n scheduledTimeMs: 6 * 3_600_000 + 30 * 60_000,\n status: 'delayed',\n },\n // ── Today (2026-06-25 in Stockholm / CEST) ─────────────────────────────────\n {\n event: 'Customer demo',\n localTimeDisplay: '09:00 EDT (-04:00)',\n // 09:00 New York EDT (-04:00) = 13:00 UTC\n scheduledDate: new Date('2026-06-25T09:00:00-04:00'),\n scheduledTimeMs: 13 * 3_600_000,\n status: 'confirmed',\n },\n {\n event: 'Platform migration',\n localTimeDisplay: '22:00 CEST (+02:00)',\n // 22:00 Stockholm CEST (+02:00) = 20:00 UTC — after Stockholm closes\n scheduledDate: new Date('2026-06-25T22:00:00+02:00'),\n scheduledTimeMs: 20 * 3_600_000,\n status: 'confirmed',\n },\n // ── Near future (up to and including 2026-07-14 in Stockholm) ─────────────\n {\n event: 'Board presentation',\n localTimeDisplay: '10:00 SGT (+08:00)',\n // 10:00 Singapore SGT (+08:00) = 02:00 UTC — before Stockholm opens\n scheduledDate: new Date('2026-07-02T10:00:00+08:00'),\n scheduledTimeMs: 2 * 3_600_000,\n status: 'confirmed',\n },\n {\n event: 'Partner onboarding',\n localTimeDisplay: '13:15 CEST (+02:00)',\n // 13:15 Paris CEST (+02:00) = 11:15 UTC\n scheduledDate: new Date('2026-07-08T13:15:00+02:00'),\n scheduledTimeMs: 11 * 3_600_000 + 15 * 60_000,\n status: 'cancelled',\n },\n // ── Far future (after 2026-07-15T00:00 Stockholm / CEST = 2026-07-14T22:00Z)\n {\n event: 'Architecture summit',\n localTimeDisplay: '08:00 CEST (+02:00)',\n // 08:00 Amsterdam CEST (+02:00) = 06:00 UTC.\n // Although the calendar date is \"July 15\", 08:00 CEST is still within the\n // same UTC day as July 14 22:00Z, so it crosses the far-future boundary.\n scheduledDate: new Date('2026-07-15T08:00:00+02:00'),\n scheduledTimeMs: 6 * 3_600_000,\n status: 'confirmed',\n },\n {\n event: 'Annual conference',\n localTimeDisplay: '09:00 PDT (-07:00)',\n // 09:00 San Francisco PDT (-07:00) = 16:00 UTC — after Stockholm closes\n scheduledDate: new Date('2026-08-03T09:00:00-07:00'),\n scheduledTimeMs: 16 * 3_600_000,\n status: 'confirmed',\n },\n {\n event: 'Year-end planning',\n localTimeDisplay: '09:00 JST (+09:00)',\n // 09:00 Tokyo JST (+09:00) = 00:00 UTC — midnight, well before Stockholm opens\n scheduledDate: new Date('2026-11-20T09:00:00+09:00'),\n scheduledTimeMs: 0,\n status: 'confirmed',\n },\n];\n\n/**\n * All date and time boundaries are anchored to Stockholm in June–July 2026.\n * Date literals use RFC 9557 IANA bracket notation — the UTC offset is inferred\n * from the named zone (CEST = +02:00 in this period); writing `+02:00` explicitly\n * is optional. Time literals use UTC-offset notation.\n *\n * \"Today\" from a Stockholm perspective:\n * 2026-06-25T00:00:00[Europe/Stockholm] = 2026-06-24T22:00:00Z\n * 2026-06-26T00:00:00[Europe/Stockholm] = 2026-06-25T22:00:00Z\n *\n * \"Far future\" threshold:\n * 2026-07-15T00:00:00[Europe/Stockholm] = 2026-07-14T22:00:00Z\n *\n * Business hours (Stockholm):\n * { time: '09:00:00+02:00' } resolves to 07:00 UTC (25 200 000 ms)\n * { time: '17:00:00+02:00' } resolves to 15:00 UTC (54 000 000 ms)\n */\nconst styleRules: DataGridStyleRule[] = [\n // Past events — entire row in muted red\n {\n apply: {\n color: { value: '#fee2e2' },\n textColor: { value: '#7f1d1d' },\n },\n column: null,\n priority: 1,\n where: {\n lessThan: [\n { column: 'scheduledDate' },\n { datetime: '2026-06-25T00:00:00[Europe/Stockholm]' },\n ],\n },\n },\n // Today (in Stockholm timezone) — entire row in amber\n {\n apply: {\n color: { value: '#fef9c3' },\n textColor: { value: '#713f12' },\n },\n column: null,\n priority: 1,\n where: {\n and: [\n {\n greaterThanOrEqual: [\n { column: 'scheduledDate' },\n { datetime: '2026-06-25T00:00:00[Europe/Stockholm]' },\n ],\n },\n {\n lessThan: [\n { column: 'scheduledDate' },\n { datetime: '2026-06-26T00:00:00[Europe/Stockholm]' },\n ],\n },\n ],\n },\n },\n // Far future (after 2026-07-15 midnight Stockholm time) — entire row in green\n {\n apply: {\n color: { value: '#dcfce7' },\n textColor: { value: '#14532d' },\n },\n column: null,\n priority: 1,\n where: {\n greaterThanOrEqual: [\n { column: 'scheduledDate' },\n { datetime: '2026-07-15T00:00:00[Europe/Stockholm]' },\n ],\n },\n },\n // Outside Stockholm business hours (before 09:00 CEST or from 17:00 CEST) —\n // time cell in orange. The { time: \"...\" } literals carry an offset so the\n // engine normalises them to UTC before comparing against scheduledTimeMs.\n {\n apply: {\n color: { value: '#ffedd5' },\n textColor: { value: '#7c2d12' },\n },\n column: 'scheduledTimeMs',\n priority: 2,\n where: {\n or: [\n {\n lessThan: [{ column: 'scheduledTimeMs' }, { time: '09:00:00+02:00' }],\n },\n {\n greaterThanOrEqual: [\n { column: 'scheduledTimeMs' },\n { time: '17:00:00+02:00' },\n ],\n },\n ],\n },\n },\n // Cancelled events — all cells grayed out at highest priority\n {\n apply: {\n color: { value: '#f3f4f6' },\n textColor: { value: '#9ca3af' },\n },\n column: null,\n priority: 5,\n where: { equal: [{ column: 'status' }, 'cancelled'] },\n },\n];\n\nconst Component = () => {\n const columnHelper = createColumnHelper<EventRow>();\n\n const columns = [\n columnHelper.accessor('event', {\n cell: (info) => info.getValue(),\n header: () => 'Event',\n minSize: 180,\n size: 220,\n }),\n columnHelper.accessor('scheduledDate', {\n cell: (info) =>\n info.getValue().toLocaleDateString('en-GB', {\n day: 'numeric',\n month: 'short',\n timeZone: 'Europe/Stockholm',\n year: 'numeric',\n }),\n header: () => 'Date (Stockholm)',\n minSize: 150,\n size: 170,\n }),\n columnHelper.accessor('localTimeDisplay', {\n cell: (info) => info.getValue(),\n header: () => 'Local time',\n minSize: 160,\n size: 180,\n }),\n columnHelper.accessor('scheduledTimeMs', {\n cell: (info) => {\n const ms = info.getValue();\n const h = Math.floor(ms / 3_600_000)\n .toString()\n .padStart(2, '0');\n const m = Math.floor((ms % 3_600_000) / 60_000)\n .toString()\n .padStart(2, '0');\n return `${h}:${m} UTC`;\n },\n header: () => 'Time (UTC)',\n minSize: 110,\n size: 130,\n }),\n columnHelper.accessor('status', {\n cell: (info) => info.getValue(),\n header: () => 'Status',\n minSize: 100,\n size: 120,\n }),\n ];\n\n const table = useReactTable({\n columnResizeMode: 'onChange',\n columns,\n 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: { pageSize: 10 },\n },\n });\n\n return (\n <div className=\"n-w-full n-bg-light-neutral-text-weakest\">\n <DataGrid\n isResizable={false}\n isKeyboardNavigable={false}\n tableInstance={table}\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-datetime.story.js","sourceRoot":"","sources":["../../../../src/data-grid/stories/datagrid-rule-based-styling-datetime.story.tsx"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,mDAAiD;AAEjD,4CAA4C;AAC5C,uDAM+B;AAsB/B,MAAM,IAAI,GAAe;IACvB,6EAA6E;IAC7E;QACE,KAAK,EAAE,kBAAkB;QACzB,gBAAgB,EAAE,qBAAqB;QACvC,mCAAmC;QACnC,aAAa,EAAE,IAAI,IAAI,CAAC,2BAA2B,CAAC;QACpD,eAAe,EAAE,CAAC,GAAG,OAAS;QAC9B,MAAM,EAAE,WAAW;KACpB;IACD;QACE,KAAK,EAAE,gBAAgB;QACvB,gBAAgB,EAAE,oBAAoB;QACtC,iEAAiE;QACjE,aAAa,EAAE,IAAI,IAAI,CAAC,2BAA2B,CAAC;QACpD,eAAe,EAAE,CAAC,GAAG,OAAS,GAAG,EAAE,GAAG,KAAM;QAC5C,MAAM,EAAE,SAAS;KAClB;IACD,8EAA8E;IAC9E;QACE,KAAK,EAAE,eAAe;QACtB,gBAAgB,EAAE,oBAAoB;QACtC,0CAA0C;QAC1C,aAAa,EAAE,IAAI,IAAI,CAAC,2BAA2B,CAAC;QACpD,eAAe,EAAE,EAAE,GAAG,OAAS;QAC/B,MAAM,EAAE,WAAW;KACpB;IACD;QACE,KAAK,EAAE,oBAAoB;QAC3B,gBAAgB,EAAE,qBAAqB;QACvC,qEAAqE;QACrE,aAAa,EAAE,IAAI,IAAI,CAAC,2BAA2B,CAAC;QACpD,eAAe,EAAE,EAAE,GAAG,OAAS;QAC/B,MAAM,EAAE,WAAW;KACpB;IACD,6EAA6E;IAC7E;QACE,KAAK,EAAE,oBAAoB;QAC3B,gBAAgB,EAAE,oBAAoB;QACtC,oEAAoE;QACpE,aAAa,EAAE,IAAI,IAAI,CAAC,2BAA2B,CAAC;QACpD,eAAe,EAAE,CAAC,GAAG,OAAS;QAC9B,MAAM,EAAE,WAAW;KACpB;IACD;QACE,KAAK,EAAE,oBAAoB;QAC3B,gBAAgB,EAAE,qBAAqB;QACvC,wCAAwC;QACxC,aAAa,EAAE,IAAI,IAAI,CAAC,2BAA2B,CAAC;QACpD,eAAe,EAAE,EAAE,GAAG,OAAS,GAAG,EAAE,GAAG,KAAM;QAC7C,MAAM,EAAE,WAAW;KACpB;IACD;QACE,KAAK,EAAE,qBAAqB;QAC5B,gBAAgB,EAAE,qBAAqB;QACvC,4CAA4C;QAC5C,aAAa,EAAE,IAAI,IAAI,CAAC,2BAA2B,CAAC;QACpD,eAAe,EAAE,CAAC,GAAG,OAAS;QAC9B,MAAM,EAAE,WAAW;KACpB;IACD;QACE,KAAK,EAAE,mBAAmB;QAC1B,gBAAgB,EAAE,oBAAoB;QACtC,wEAAwE;QACxE,aAAa,EAAE,IAAI,IAAI,CAAC,2BAA2B,CAAC;QACpD,eAAe,EAAE,EAAE,GAAG,OAAS;QAC/B,MAAM,EAAE,WAAW;KACpB;IACD,8EAA8E;IAC9E;QACE,KAAK,EAAE,mBAAmB;QAC1B,gBAAgB,EAAE,oBAAoB;QACtC,+EAA+E;QAC/E,aAAa,EAAE,IAAI,IAAI,CAAC,2BAA2B,CAAC;QACpD,eAAe,EAAE,CAAC;QAClB,MAAM,EAAE,WAAW;KACpB;CACF,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,GAAwB;IACtC,oEAAoE;IACpE,8EAA8E;IAC9E,qCAAqC;IACrC;QACE,KAAK,EAAE;YACL,UAAU,EAAE;gBACV,QAAQ,EAAE,SAAS;gBACnB,QAAQ,EAAE;oBACR,QAAQ,EAAE,uCAAuC;iBAClD;gBACD,QAAQ,EAAE,SAAS;gBACnB,QAAQ,EAAE;oBACR,QAAQ,EAAE,uCAAuC;iBAClD;gBACD,QAAQ,EAAE,eAAe;aAC1B;SACF;QACD,MAAM,EAAE,eAAe;QACvB,QAAQ,EAAE,CAAC;KACZ;IACD,wCAAwC;IACxC;QACE,KAAK,EAAE;YACL,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;YAC3B,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;SAChC;QACD,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,CAAC;QACX,KAAK,EAAE;YACL,QAAQ,EAAE;gBACR,EAAE,MAAM,EAAE,eAAe,EAAE;gBAC3B,EAAE,QAAQ,EAAE,uCAAuC,EAAE;aACtD;SACF;KACF;IACD,sDAAsD;IACtD;QACE,KAAK,EAAE;YACL,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;YAC3B,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;SAChC;QACD,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,CAAC;QACX,KAAK,EAAE;YACL,GAAG,EAAE;gBACH;oBACE,kBAAkB,EAAE;wBAClB,EAAE,MAAM,EAAE,eAAe,EAAE;wBAC3B,EAAE,QAAQ,EAAE,uCAAuC,EAAE;qBACtD;iBACF;gBACD;oBACE,QAAQ,EAAE;wBACR,EAAE,MAAM,EAAE,eAAe,EAAE;wBAC3B,EAAE,QAAQ,EAAE,uCAAuC,EAAE;qBACtD;iBACF;aACF;SACF;KACF;IACD,8EAA8E;IAC9E;QACE,KAAK,EAAE;YACL,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;YAC3B,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;SAChC;QACD,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,CAAC;QACX,KAAK,EAAE;YACL,kBAAkB,EAAE;gBAClB,EAAE,MAAM,EAAE,eAAe,EAAE;gBAC3B,EAAE,QAAQ,EAAE,uCAAuC,EAAE;aACtD;SACF;KACF;IACD,4EAA4E;IAC5E,2EAA2E;IAC3E,0EAA0E;IAC1E;QACE,KAAK,EAAE;YACL,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;YAC3B,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;SAChC;QACD,MAAM,EAAE,iBAAiB;QACzB,QAAQ,EAAE,CAAC;QACX,KAAK,EAAE;YACL,EAAE,EAAE;gBACF;oBACE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;iBACtE;gBACD;oBACE,kBAAkB,EAAE;wBAClB,EAAE,MAAM,EAAE,iBAAiB,EAAE;wBAC7B,EAAE,IAAI,EAAE,gBAAgB,EAAE;qBAC3B;iBACF;aACF;SACF;KACF;IACD,8DAA8D;IAC9D;QACE,KAAK,EAAE;YACL,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;YAC3B,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;SAChC;QACD,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,CAAC;QACX,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,WAAW,CAAC,EAAE;KACtD;CACF,CAAC;AAEF,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,MAAM,YAAY,GAAG,IAAA,gCAAkB,GAAY,CAAC;IAEpD,MAAM,OAAO,GAAG;QACd,YAAY,CAAC,QAAQ,CAAC,OAAO,EAAE;YAC7B,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE;YAC/B,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO;YACrB,OAAO,EAAE,GAAG;YACZ,IAAI,EAAE,GAAG;SACV,CAAC;QACF,YAAY,CAAC,QAAQ,CAAC,eAAe,EAAE;YACrC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CACb,IAAI,CAAC,QAAQ,EAAE,CAAC,kBAAkB,CAAC,OAAO,EAAE;gBAC1C,GAAG,EAAE,SAAS;gBACd,KAAK,EAAE,OAAO;gBACd,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,SAAS;aAChB,CAAC;YACJ,MAAM,EAAE,GAAG,EAAE,CAAC,kBAAkB;YAChC,OAAO,EAAE,GAAG;YACZ,IAAI,EAAE,GAAG;SACV,CAAC;QACF,YAAY,CAAC,QAAQ,CAAC,kBAAkB,EAAE;YACxC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE;YAC/B,MAAM,EAAE,GAAG,EAAE,CAAC,YAAY;YAC1B,OAAO,EAAE,GAAG;YACZ,IAAI,EAAE,GAAG;SACV,CAAC;QACF,YAAY,CAAC,QAAQ,CAAC,iBAAiB,EAAE;YACvC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;gBACb,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,OAAS,CAAC;qBACjC,QAAQ,EAAE;qBACV,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;gBACpB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,OAAS,CAAC,GAAG,KAAM,CAAC;qBAC5C,QAAQ,EAAE;qBACV,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;gBACpB,OAAO,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;YACzB,CAAC;YACD,MAAM,EAAE,GAAG,EAAE,CAAC,YAAY;YAC1B,OAAO,EAAE,GAAG;YACZ,IAAI,EAAE,GAAG;SACV,CAAC;QACF,YAAY,CAAC,QAAQ,CAAC,QAAQ,EAAE;YAC9B,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE;YAC/B,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ;YACtB,OAAO,EAAE,GAAG;YACZ,IAAI,EAAE,GAAG;SACV,CAAC;KACH,CAAC;IAEF,MAAM,KAAK,GAAG,IAAA,2BAAa,EAAC;QAC1B,gBAAgB,EAAE,UAAU;QAC5B,OAAO;QACP,IAAI;QACJ,aAAa,EAAE;YACb,OAAO,EAAE,GAAG;YACZ,OAAO,EAAE,EAAE;SACZ;QACD,aAAa,EAAE,IAAI;QACnB,eAAe,EAAE,IAAA,6BAAe,GAAE;QAClC,qBAAqB,EAAE,IAAA,mCAAqB,GAAE;QAC9C,iBAAiB,EAAE,IAAA,+BAAiB,GAAE;QACtC,YAAY,EAAE;YACZ,UAAU,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;SAC7B;KACF,CAAC,CAAC;IAEH,OAAO,CACL,gCAAK,SAAS,EAAC,0CAA0C,YACvD,uBAAC,gBAAQ,IACP,WAAW,EAAE,KAAK,EAClB,mBAAmB,EAAE,KAAK,EAC1B,aAAa,EAAE,KAAK,EACpB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE;gBACP,WAAW,EAAE,WAAW;gBACxB,eAAe,EAAE,IAAI;gBACrB,gBAAgB,EAAE,KAAK;aACxB,GACD,GACE,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,SAAS,CAAC","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';\n\ntype EventRow = {\n event: string;\n /**\n * JS Date coerced from the event's local ISO string. Natively converted to\n * Unix ms by the engine and compared against { datetime: \"...\" } literals.\n */\n scheduledDate: Date;\n /**\n * UTC milliseconds since midnight. Compared against { time: \"...\" } literals\n * that are defined in Stockholm / CEST (+02:00) time — the engine normalises\n * both sides to UTC before comparing.\n */\n scheduledTimeMs: number;\n /** Human-readable local time shown in the cell, e.g. \"09:00 CEST (+02:00)\". */\n localTimeDisplay: string;\n status: 'confirmed' | 'delayed' | 'cancelled';\n};\n\nconst data: EventRow[] = [\n // ── Past events (before start of 2026-06-25 in Stockholm / CEST) ──────────\n {\n event: 'Quarterly review',\n localTimeDisplay: '09:00 CEST (+02:00)',\n // 09:00 Stockholm CEST = 07:00 UTC\n scheduledDate: new Date('2026-06-10T09:00:00+02:00'),\n scheduledTimeMs: 7 * 3_600_000,\n status: 'confirmed',\n },\n {\n event: 'Security audit',\n localTimeDisplay: '07:30 BST (+01:00)',\n // 07:30 London BST (+01:00) = 06:30 UTC — before Stockholm opens\n scheduledDate: new Date('2026-06-18T07:30:00+01:00'),\n scheduledTimeMs: 6 * 3_600_000 + 30 * 60_000,\n status: 'delayed',\n },\n // ── Today (2026-06-25 in Stockholm / CEST) ─────────────────────────────────\n {\n event: 'Customer demo',\n localTimeDisplay: '09:00 EDT (-04:00)',\n // 09:00 New York EDT (-04:00) = 13:00 UTC\n scheduledDate: new Date('2026-06-25T09:00:00-04:00'),\n scheduledTimeMs: 13 * 3_600_000,\n status: 'confirmed',\n },\n {\n event: 'Platform migration',\n localTimeDisplay: '22:00 CEST (+02:00)',\n // 22:00 Stockholm CEST (+02:00) = 20:00 UTC — after Stockholm closes\n scheduledDate: new Date('2026-06-25T22:00:00+02:00'),\n scheduledTimeMs: 20 * 3_600_000,\n status: 'confirmed',\n },\n // ── Near future (up to and including 2026-07-14 in Stockholm) ─────────────\n {\n event: 'Board presentation',\n localTimeDisplay: '10:00 SGT (+08:00)',\n // 10:00 Singapore SGT (+08:00) = 02:00 UTC — before Stockholm opens\n scheduledDate: new Date('2026-07-02T10:00:00+08:00'),\n scheduledTimeMs: 2 * 3_600_000,\n status: 'confirmed',\n },\n {\n event: 'Partner onboarding',\n localTimeDisplay: '13:15 CEST (+02:00)',\n // 13:15 Paris CEST (+02:00) = 11:15 UTC\n scheduledDate: new Date('2026-07-08T13:15:00+02:00'),\n scheduledTimeMs: 11 * 3_600_000 + 15 * 60_000,\n status: 'confirmed',\n },\n {\n event: 'Architecture summit',\n localTimeDisplay: '08:00 CEST (+02:00)',\n // 08:00 Amsterdam CEST (+02:00) = 06:00 UTC\n scheduledDate: new Date('2026-07-11T08:00:00+02:00'),\n scheduledTimeMs: 6 * 3_600_000,\n status: 'confirmed',\n },\n {\n event: 'Annual conference',\n localTimeDisplay: '09:00 PDT (-07:00)',\n // 09:00 San Francisco PDT (-07:00) = 16:00 UTC — after Stockholm closes\n scheduledDate: new Date('2026-07-13T09:00:00-07:00'),\n scheduledTimeMs: 16 * 3_600_000,\n status: 'confirmed',\n },\n // ── Far future (after 2026-07-15T00:00 Stockholm / CEST = 2026-07-14T22:00Z)\n {\n event: 'Year-end planning',\n localTimeDisplay: '09:00 JST (+09:00)',\n // 09:00 Tokyo JST (+09:00) = 00:00 UTC — midnight, well before Stockholm opens\n scheduledDate: new Date('2026-11-20T09:00:00+09:00'),\n scheduledTimeMs: 0,\n status: 'cancelled',\n },\n];\n\n/**\n * All date and time boundaries are anchored to Stockholm in June–July 2026.\n * Date literals use RFC 9557 IANA bracket notation — the UTC offset is inferred\n * from the named zone (CEST = +02:00 in this period); writing `+02:00` explicitly\n * is optional. Time literals use UTC-offset notation.\n *\n * \"Today\" from a Stockholm perspective:\n * 2026-06-25T00:00:00[Europe/Stockholm] = 2026-06-24T22:00:00Z\n * 2026-06-26T00:00:00[Europe/Stockholm] = 2026-06-25T22:00:00Z\n *\n * \"Far future\" threshold:\n * 2026-07-15T00:00:00[Europe/Stockholm] = 2026-07-14T22:00:00Z\n *\n * Business hours (Stockholm):\n * { time: '09:00:00+02:00' } resolves to 07:00 UTC (25 200 000 ms)\n * { time: '17:00:00+02:00' } resolves to 15:00 UTC (54 000 000 ms)\n */\nconst styleRules: DataGridStyleRule[] = [\n // Near-future date cells use temporal literals directly as gradient\n // boundaries. Several rows are spread across this interval so the progression\n // from amber to blue is easy to see.\n {\n apply: {\n colorRange: {\n maxColor: '#dbeafe',\n maxValue: {\n datetime: '2026-07-15T00:00:00[Europe/Stockholm]',\n },\n minColor: '#fef3c7',\n minValue: {\n datetime: '2026-06-26T00:00:00[Europe/Stockholm]',\n },\n onColumn: 'scheduledDate',\n },\n },\n column: 'scheduledDate',\n priority: 0,\n },\n // Past events — entire row in muted red\n {\n apply: {\n color: { value: '#fee2e2' },\n textColor: { value: '#7f1d1d' },\n },\n column: null,\n priority: 1,\n where: {\n lessThan: [\n { column: 'scheduledDate' },\n { datetime: '2026-06-25T00:00:00[Europe/Stockholm]' },\n ],\n },\n },\n // Today (in Stockholm timezone) — entire row in amber\n {\n apply: {\n color: { value: '#fef9c3' },\n textColor: { value: '#713f12' },\n },\n column: null,\n priority: 1,\n where: {\n and: [\n {\n greaterThanOrEqual: [\n { column: 'scheduledDate' },\n { datetime: '2026-06-25T00:00:00[Europe/Stockholm]' },\n ],\n },\n {\n lessThan: [\n { column: 'scheduledDate' },\n { datetime: '2026-06-26T00:00:00[Europe/Stockholm]' },\n ],\n },\n ],\n },\n },\n // Far future (after 2026-07-15 midnight Stockholm time) — entire row in green\n {\n apply: {\n color: { value: '#dcfce7' },\n textColor: { value: '#14532d' },\n },\n column: null,\n priority: 1,\n where: {\n greaterThanOrEqual: [\n { column: 'scheduledDate' },\n { datetime: '2026-07-15T00:00:00[Europe/Stockholm]' },\n ],\n },\n },\n // Outside Stockholm business hours (before 09:00 CEST or from 17:00 CEST) —\n // time cell in orange. The { time: \"...\" } literals carry an offset so the\n // engine normalises them to UTC before comparing against scheduledTimeMs.\n {\n apply: {\n color: { value: '#ffedd5' },\n textColor: { value: '#7c2d12' },\n },\n column: 'scheduledTimeMs',\n priority: 2,\n where: {\n or: [\n {\n lessThan: [{ column: 'scheduledTimeMs' }, { time: '09:00:00+02:00' }],\n },\n {\n greaterThanOrEqual: [\n { column: 'scheduledTimeMs' },\n { time: '17:00:00+02:00' },\n ],\n },\n ],\n },\n },\n // Cancelled events — all cells grayed out at highest priority\n {\n apply: {\n color: { value: '#f3f4f6' },\n textColor: { value: '#9ca3af' },\n },\n column: null,\n priority: 5,\n where: { equal: [{ column: 'status' }, 'cancelled'] },\n },\n];\n\nconst Component = () => {\n const columnHelper = createColumnHelper<EventRow>();\n\n const columns = [\n columnHelper.accessor('event', {\n cell: (info) => info.getValue(),\n header: () => 'Event',\n minSize: 180,\n size: 220,\n }),\n columnHelper.accessor('scheduledDate', {\n cell: (info) =>\n info.getValue().toLocaleDateString('en-GB', {\n day: 'numeric',\n month: 'short',\n timeZone: 'Europe/Stockholm',\n year: 'numeric',\n }),\n header: () => 'Date (Stockholm)',\n minSize: 150,\n size: 170,\n }),\n columnHelper.accessor('localTimeDisplay', {\n cell: (info) => info.getValue(),\n header: () => 'Local time',\n minSize: 160,\n size: 180,\n }),\n columnHelper.accessor('scheduledTimeMs', {\n cell: (info) => {\n const ms = info.getValue();\n const h = Math.floor(ms / 3_600_000)\n .toString()\n .padStart(2, '0');\n const m = Math.floor((ms % 3_600_000) / 60_000)\n .toString()\n .padStart(2, '0');\n return `${h}:${m} UTC`;\n },\n header: () => 'Time (UTC)',\n minSize: 110,\n size: 130,\n }),\n columnHelper.accessor('status', {\n cell: (info) => info.getValue(),\n header: () => 'Status',\n minSize: 100,\n size: 120,\n }),\n ];\n\n const table = useReactTable({\n columnResizeMode: 'onChange',\n columns,\n 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: { pageSize: 10 },\n },\n });\n\n return (\n <div className=\"n-w-full n-bg-light-neutral-text-weakest\">\n <DataGrid\n isResizable={false}\n isKeyboardNavigable={false}\n tableInstance={table}\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,8 +31,11 @@ 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 resolvedMinValue = (0, style_rules_1.
|
|
35
|
-
const resolvedMaxValue = (0, style_rules_1.
|
|
34
|
+
const resolvedMinValue = (0, style_rules_1.resolveRangeLiteral)(minValue);
|
|
35
|
+
const resolvedMaxValue = (0, style_rules_1.resolveRangeLiteral)(maxValue);
|
|
36
|
+
if (resolvedMinValue === null || resolvedMaxValue === null) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
36
39
|
const boundsOrder = (0, style_rules_1.compareNumericValues)(resolvedMinValue, resolvedMaxValue);
|
|
37
40
|
if (boundsOrder === null) {
|
|
38
41
|
return null;
|
|
@@ -40,7 +43,10 @@ function getInterpolatedColor(colorRange, rowData, converters) {
|
|
|
40
43
|
const actualMinValue = boundsOrder <= 0 ? resolvedMinValue : resolvedMaxValue;
|
|
41
44
|
const actualMaxValue = boundsOrder <= 0 ? resolvedMaxValue : resolvedMinValue;
|
|
42
45
|
let midRgb = undefined;
|
|
43
|
-
const resolvedMidValue = midValue === undefined ? undefined : (0, style_rules_1.
|
|
46
|
+
const resolvedMidValue = midValue === undefined ? undefined : (0, style_rules_1.resolveRangeLiteral)(midValue);
|
|
47
|
+
if (resolvedMidValue === null) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
44
50
|
if (midValue !== undefined && midColor !== undefined) {
|
|
45
51
|
const minToMid = (0, style_rules_1.compareNumericValues)(actualMinValue, resolvedMidValue);
|
|
46
52
|
const midToMax = (0, style_rules_1.compareNumericValues)(resolvedMidValue, actualMaxValue);
|
|
@@ -51,31 +57,13 @@ function getInterpolatedColor(colorRange, rowData, converters) {
|
|
|
51
57
|
midRgb = (0, react_color_1.color)(midColor).rgb;
|
|
52
58
|
}
|
|
53
59
|
const rawValue = rowData[onColumn];
|
|
60
|
+
const resolved = resolveCellValue(rawValue, converters === null || converters === void 0 ? void 0 : converters[onColumn]);
|
|
54
61
|
let numericValue = null;
|
|
55
|
-
if (typeof
|
|
56
|
-
numericValue =
|
|
57
|
-
typeof rawValue === 'bigint' || Number.isFinite(rawValue)
|
|
58
|
-
? rawValue
|
|
59
|
-
: null;
|
|
62
|
+
if (typeof resolved === 'bigint') {
|
|
63
|
+
numericValue = resolved;
|
|
60
64
|
}
|
|
61
|
-
else if (
|
|
62
|
-
|
|
63
|
-
numericValue = Number.isFinite(ts) ? ts : null;
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
const converter = converters === null || converters === void 0 ? void 0 : converters[onColumn];
|
|
67
|
-
if (converter !== undefined) {
|
|
68
|
-
const converted = converter(rawValue);
|
|
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);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
65
|
+
else if (typeof resolved === 'number' && Number.isFinite(resolved)) {
|
|
66
|
+
numericValue = resolved;
|
|
79
67
|
}
|
|
80
68
|
if (numericValue === null) {
|
|
81
69
|
return null;
|
|
@@ -111,44 +99,61 @@ function getInterpolatedColor(colorRange, rowData, converters) {
|
|
|
111
99
|
}
|
|
112
100
|
return (0, react_color_1.rgbToHex)(rgb);
|
|
113
101
|
}
|
|
114
|
-
|
|
115
|
-
|
|
102
|
+
const UNRESOLVED = Symbol('unresolved');
|
|
103
|
+
function resolveNativeValue(value) {
|
|
104
|
+
if (value === null) {
|
|
116
105
|
return null;
|
|
117
106
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (cellVal === undefined) {
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
if (typeof cellVal === 'string' ||
|
|
127
|
-
typeof cellVal === 'number' ||
|
|
128
|
-
typeof cellVal === 'boolean' ||
|
|
129
|
-
typeof cellVal === 'bigint') {
|
|
130
|
-
return cellVal;
|
|
131
|
-
}
|
|
132
|
-
if (cellVal instanceof Date) {
|
|
133
|
-
const ts = cellVal.getTime();
|
|
134
|
-
return isNaN(ts) ? null : ts;
|
|
135
|
-
}
|
|
136
|
-
const converter = converters === null || converters === void 0 ? void 0 : converters[value.column];
|
|
137
|
-
if (converter !== undefined) {
|
|
138
|
-
return resolveLiteral(converter(cellVal));
|
|
139
|
-
}
|
|
140
|
-
return null;
|
|
107
|
+
if (typeof value === 'string' ||
|
|
108
|
+
typeof value === 'boolean' ||
|
|
109
|
+
typeof value === 'bigint' ||
|
|
110
|
+
typeof value === 'number') {
|
|
111
|
+
return value;
|
|
141
112
|
}
|
|
142
|
-
if (
|
|
113
|
+
if (value instanceof Date) {
|
|
114
|
+
const ts = value.getTime();
|
|
115
|
+
return isNaN(ts) ? null : ts;
|
|
116
|
+
}
|
|
117
|
+
if ((0, style_rules_1.isDatetimeLiteral)(value)) {
|
|
143
118
|
return (0, style_rules_1.parseDateString)(value.datetime);
|
|
144
119
|
}
|
|
145
|
-
if (
|
|
120
|
+
if ((0, style_rules_1.isLocalDatetimeLiteral)(value)) {
|
|
146
121
|
return (0, style_rules_1.parseLocalDateString)(value.localdatetime);
|
|
147
122
|
}
|
|
148
|
-
if (
|
|
123
|
+
if ((0, style_rules_1.isTimeLiteral)(value)) {
|
|
149
124
|
return (0, style_rules_1.parseTimeString)(value.time);
|
|
150
125
|
}
|
|
151
|
-
|
|
126
|
+
if ((0, style_rules_1.isBigintLiteral)(value)) {
|
|
127
|
+
return (0, style_rules_1.resolveNumericLiteral)(value);
|
|
128
|
+
}
|
|
129
|
+
return UNRESOLVED;
|
|
130
|
+
}
|
|
131
|
+
function resolveCellValue(cellVal, converter) {
|
|
132
|
+
if (cellVal === undefined) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
const native = resolveNativeValue(cellVal);
|
|
136
|
+
if (native !== UNRESOLVED) {
|
|
137
|
+
return native;
|
|
138
|
+
}
|
|
139
|
+
if (converter !== undefined) {
|
|
140
|
+
const converted = converter(cellVal);
|
|
141
|
+
if (converted === undefined) {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
const fromConverted = resolveNativeValue(converted);
|
|
145
|
+
if (fromConverted !== UNRESOLVED) {
|
|
146
|
+
return fromConverted;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
function resolveValue(value, rowData, converters) {
|
|
152
|
+
if (typeof value === 'object' && value !== null && 'column' in value) {
|
|
153
|
+
return resolveCellValue(rowData[value.column], converters === null || converters === void 0 ? void 0 : converters[value.column]);
|
|
154
|
+
}
|
|
155
|
+
const resolved = resolveNativeValue(value);
|
|
156
|
+
return resolved === UNRESOLVED ? null : resolved;
|
|
152
157
|
}
|
|
153
158
|
function safeCompare(left, right, rowData, compareFn, converters) {
|
|
154
159
|
const leftVal = resolveValue(left, rowData, converters);
|