@capillarytech/blaze-ui 5.2.2 → 5.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.npmrc +2 -0
- package/CapCollapsibleNavbar/index.js +55 -3
- package/CapCollapsibleNavbar/index.js.map +1 -1
- package/CapCondition/index.js +55 -3
- package/CapCondition/index.js.map +1 -1
- package/CapDatePicker/index.js +55 -3
- package/CapDatePicker/index.js.map +1 -1
- package/CapDateTimePicker/README.md +136 -0
- package/CapDateTimePicker/index.d.ts +13 -0
- package/CapDateTimePicker/index.d.ts.map +1 -0
- package/CapDateTimePicker/index.js +166 -106
- package/CapDateTimePicker/index.js.map +1 -1
- package/CapDateTimePicker/messages.d.ts +17 -0
- package/CapDateTimePicker/messages.d.ts.map +1 -0
- package/CapDateTimePicker/types.d.ts +93 -0
- package/CapDateTimePicker/types.d.ts.map +1 -0
- package/CapDateTimeRangePicker/index.js +55 -3
- package/CapDateTimeRangePicker/index.js.map +1 -1
- package/CapEventCalendar/index.js +55 -3
- package/CapEventCalendar/index.js.map +1 -1
- package/CapLanguageProvider/index.js +55 -3
- package/CapLanguageProvider/index.js.map +1 -1
- package/CapLevelGraphRenderer/CapLevelGraphRenderer-test-cases.md +50 -0
- package/CapLevelGraphRenderer/MIGRATION_ANALYSIS.md +138 -0
- package/CapLevelGraphRenderer/README.md +123 -0
- package/CapLevelGraphRenderer/STORYBOOK_ANALYSIS.md +96 -0
- package/CapLevelGraphRenderer/Tooltip.d.ts +31 -0
- package/CapLevelGraphRenderer/Tooltip.d.ts.map +1 -0
- package/CapLevelGraphRenderer/Tooltip_MIGRATION_ANALYSIS.md +120 -0
- package/CapLevelGraphRenderer/index.d.ts +16 -0
- package/CapLevelGraphRenderer/index.d.ts.map +1 -0
- package/CapLevelGraphRenderer/index.js +159 -135
- package/CapLevelGraphRenderer/index.js.map +1 -1
- package/CapLevelGraphRenderer/tests/TEST_COVERAGE.md +119 -0
- package/CapLevelGraphRenderer/types.d.ts +139 -0
- package/CapLevelGraphRenderer/types.d.ts.map +1 -0
- package/CapNotificationDropdown/index.js +55 -3
- package/CapNotificationDropdown/index.js.map +1 -1
- package/CapTimePicker/index.js +55 -3
- package/CapTimePicker/index.js.map +1 -1
- package/index.d.ts +4 -0
- package/index.d.ts.map +1 -1
- package/index.js +1053 -4
- package/index.js.map +1 -1
- package/package.json +4 -2
- package/utils/dayjs.d.ts +21 -0
- package/utils/dayjs.d.ts.map +1 -1
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Test Coverage: CapLevelGraphRenderer
|
|
2
|
+
|
|
3
|
+
## Test Files Created
|
|
4
|
+
|
|
5
|
+
1. **CapLevelGraphRenderer.test.tsx** - Main test file with comprehensive coverage
|
|
6
|
+
2. **CapLevelGraphRenderer.mockData.ts** - Mock data and test fixtures
|
|
7
|
+
|
|
8
|
+
## Test Coverage Summary
|
|
9
|
+
|
|
10
|
+
### ✅ Default Rendering (4 tests)
|
|
11
|
+
- Renders graph container and pagination controls
|
|
12
|
+
- Renders with nodes and connections
|
|
13
|
+
- Renders empty state without errors
|
|
14
|
+
- Renders single node without connections
|
|
15
|
+
|
|
16
|
+
### ✅ Graph Initialization (4 tests)
|
|
17
|
+
- Initializes graph with correct container
|
|
18
|
+
- Registers tooltip tool when showToolTip is true
|
|
19
|
+
- Does not register tooltip tool when showToolTip is false
|
|
20
|
+
- Handles missing container gracefully
|
|
21
|
+
|
|
22
|
+
### ✅ Node Rendering (3 tests)
|
|
23
|
+
- Renders multiple nodes
|
|
24
|
+
- Renders nodes with custom components and props
|
|
25
|
+
- Handles nodes with toolTip property
|
|
26
|
+
|
|
27
|
+
### ✅ Connections (4 tests)
|
|
28
|
+
- Renders forward connections between adjacent nodes
|
|
29
|
+
- Renders reverse connections
|
|
30
|
+
- Handles complex connection scenarios
|
|
31
|
+
- Handles invalid connections gracefully
|
|
32
|
+
|
|
33
|
+
### ✅ Pagination (5 tests)
|
|
34
|
+
- Disables previous button at start position
|
|
35
|
+
- Enables next button when content exceeds viewport
|
|
36
|
+
- Disables both buttons when all content fits
|
|
37
|
+
- Scrolls left when previous button is clicked
|
|
38
|
+
- Scrolls right when next button is clicked
|
|
39
|
+
|
|
40
|
+
### ✅ Props Variations (9 tests)
|
|
41
|
+
- Applies className and scrollClassName props
|
|
42
|
+
- Applies graphStyles prop
|
|
43
|
+
- Applies containerStyles prop
|
|
44
|
+
- Applies graphWidth and graphHeight props
|
|
45
|
+
- Applies layout props (offsetHeight, defaultStartX, defaultStartY, etc.)
|
|
46
|
+
- Applies lineStrokeColor prop
|
|
47
|
+
- Applies forwardConnProps
|
|
48
|
+
- Applies reverseConnProps
|
|
49
|
+
|
|
50
|
+
### ✅ Tooltip Functionality (3 tests)
|
|
51
|
+
- Registers edge events when showToolTip is true
|
|
52
|
+
- Does not register edge events when showToolTip is false
|
|
53
|
+
- Registers node events for input focus
|
|
54
|
+
|
|
55
|
+
### ✅ Scroller Props (1 test)
|
|
56
|
+
- Applies scrollerProps to graph
|
|
57
|
+
|
|
58
|
+
### ✅ Edge Cases (3 tests)
|
|
59
|
+
- Handles empty nodes array
|
|
60
|
+
- Handles empty connections array
|
|
61
|
+
- Updates scroll position when nodes change
|
|
62
|
+
|
|
63
|
+
## Total Test Count
|
|
64
|
+
|
|
65
|
+
**36 test cases** covering all major functionality areas.
|
|
66
|
+
|
|
67
|
+
## Test Patterns Used
|
|
68
|
+
|
|
69
|
+
- ✅ `it.each` for repetitive prop variations
|
|
70
|
+
- ✅ Reusable helper functions (`renderWithProps`)
|
|
71
|
+
- ✅ Mock data in separate file (`CapLevelGraphRenderer.mockData.ts`)
|
|
72
|
+
- ✅ Focus on functional behavior (not styling)
|
|
73
|
+
- ✅ User interaction testing with `@testing-library/user-event`
|
|
74
|
+
- ✅ Edge case coverage
|
|
75
|
+
- ✅ Proper mocking of @antv/x6 Graph library
|
|
76
|
+
|
|
77
|
+
## Mocking Strategy
|
|
78
|
+
|
|
79
|
+
- **@antv/x6 Graph**: Mocked constructor and instance methods (addNode, addEdge, on, setScrollbarPosition)
|
|
80
|
+
- **Graph.registerEdgeTool**: Mocked static method
|
|
81
|
+
- **TooltipTool**: Mocked module
|
|
82
|
+
- **DOM Containers**: Created and cleaned up in beforeEach/afterEach
|
|
83
|
+
|
|
84
|
+
## Notes
|
|
85
|
+
|
|
86
|
+
- Tests focus on functional behavior and user interactions
|
|
87
|
+
- No Cap UI components are mocked (CapButton, CapIcon render normally)
|
|
88
|
+
- Tests verify graph initialization, node rendering, connection drawing, and pagination
|
|
89
|
+
- Edge cases like empty states and invalid data are covered
|
|
90
|
+
- Tooltip functionality is tested through event registration verification
|
|
91
|
+
|
|
92
|
+
## Use Cases Coverage
|
|
93
|
+
|
|
94
|
+
Based on `CapLevelGraphRenderer-test-cases.md`:
|
|
95
|
+
|
|
96
|
+
| Use Case ID | Status | Test Coverage |
|
|
97
|
+
|-------------|--------|---------------|
|
|
98
|
+
| UC-001 | ✅ | Basic rendering test |
|
|
99
|
+
| UC-002 | ✅ | Empty state test |
|
|
100
|
+
| UC-003 | ✅ | Single node test |
|
|
101
|
+
| UC-004 | ✅ | Forward connections test |
|
|
102
|
+
| UC-005 | ✅ | Reverse connections test |
|
|
103
|
+
| UC-006 | ✅ | Styling props test |
|
|
104
|
+
| UC-007 | ✅ | Layout props test |
|
|
105
|
+
| UC-008 | ✅ | Connection styling test |
|
|
106
|
+
| UC-009 | ✅ | Tooltip registration test |
|
|
107
|
+
| UC-010 | ✅ | Tooltip registration test |
|
|
108
|
+
| UC-011 | ✅ | Tooltip disabled test |
|
|
109
|
+
| UC-012 | ✅ | Pagination previous test |
|
|
110
|
+
| UC-013 | ✅ | Pagination next test |
|
|
111
|
+
| UC-014 | ✅ | Pagination states test |
|
|
112
|
+
| UC-015 | ✅ | Scroller props test |
|
|
113
|
+
| UC-016 | ✅ | Node component rendering test |
|
|
114
|
+
| UC-017 | ✅ | Complex connections test |
|
|
115
|
+
| UC-018 | ✅ | Missing container test |
|
|
116
|
+
| UC-019 | ✅ | Invalid connections test |
|
|
117
|
+
| UC-020 | ✅ | Graph API integration test |
|
|
118
|
+
|
|
119
|
+
**Coverage**: 20/20 use cases covered ✅
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { Graph } from '@antv/x6';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Node data structure for graph rendering
|
|
5
|
+
*/
|
|
6
|
+
export interface GraphNode {
|
|
7
|
+
/** Unique identifier for the node */
|
|
8
|
+
id: string;
|
|
9
|
+
/** React component to render inside the node */
|
|
10
|
+
component: React.ComponentType<Record<string, unknown>>;
|
|
11
|
+
/** Height of the node in pixels */
|
|
12
|
+
height: number;
|
|
13
|
+
/** Props to pass to the component */
|
|
14
|
+
props?: Record<string, unknown>;
|
|
15
|
+
/** Tooltip text for the node */
|
|
16
|
+
toolTip?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Connection data structure for graph edges
|
|
20
|
+
*/
|
|
21
|
+
export interface GraphConnection {
|
|
22
|
+
/** Source node ID */
|
|
23
|
+
sourceId: string;
|
|
24
|
+
/** Target node ID */
|
|
25
|
+
targetId: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Node position tracking object
|
|
29
|
+
*/
|
|
30
|
+
export interface NodePosition {
|
|
31
|
+
/** X coordinate */
|
|
32
|
+
x: number;
|
|
33
|
+
/** Y coordinate */
|
|
34
|
+
y: number;
|
|
35
|
+
/** End X coordinate */
|
|
36
|
+
x1: number;
|
|
37
|
+
/** End Y coordinate */
|
|
38
|
+
y1: number;
|
|
39
|
+
/** Node height */
|
|
40
|
+
height: number;
|
|
41
|
+
/** Node width */
|
|
42
|
+
width: number;
|
|
43
|
+
/** Tooltip text */
|
|
44
|
+
toolTip: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Edge tracking object
|
|
48
|
+
*/
|
|
49
|
+
export interface EdgeObj {
|
|
50
|
+
forward?: boolean;
|
|
51
|
+
reverse?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Connection object for internal tracking
|
|
55
|
+
*/
|
|
56
|
+
export interface ConnectionObj {
|
|
57
|
+
in: string[];
|
|
58
|
+
out: string[];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Props for CapLevelGraphRenderer component
|
|
62
|
+
*/
|
|
63
|
+
export interface CapLevelGraphRendererProps {
|
|
64
|
+
/** Array of nodes to render in the graph */
|
|
65
|
+
nodes?: GraphNode[];
|
|
66
|
+
/** Unique identifier for the graph container DOM element (required) */
|
|
67
|
+
graphId: string;
|
|
68
|
+
/** Additional CSS class name */
|
|
69
|
+
className?: string;
|
|
70
|
+
/** Width of the graph container (number in pixels or string like '500px') */
|
|
71
|
+
graphWidth?: number | string;
|
|
72
|
+
/** Height of the graph container (number in pixels or string like '500px') */
|
|
73
|
+
graphHeight?: number | string;
|
|
74
|
+
/** Whether to show tooltips on edges */
|
|
75
|
+
showToolTip?: boolean;
|
|
76
|
+
/** Array of connections between nodes */
|
|
77
|
+
connections?: GraphConnection[];
|
|
78
|
+
/** Inline styles for the graph container */
|
|
79
|
+
graphStyles?: React.CSSProperties;
|
|
80
|
+
/** Offset height for connection lines from node top */
|
|
81
|
+
offsetHeight?: number;
|
|
82
|
+
/** Default starting X coordinate */
|
|
83
|
+
defaultStartX?: number;
|
|
84
|
+
/** Default starting Y coordinate */
|
|
85
|
+
defaultStartY?: number;
|
|
86
|
+
/** Props to pass to the x6 scroller */
|
|
87
|
+
scrollerProps?: Record<string, unknown>;
|
|
88
|
+
/** CSS class name for the scroller */
|
|
89
|
+
scrollClassName?: string;
|
|
90
|
+
/** Inline styles for the container wrapper */
|
|
91
|
+
containerStyles?: React.CSSProperties;
|
|
92
|
+
/** Color for connection lines */
|
|
93
|
+
lineStrokeColor?: string;
|
|
94
|
+
/** Default width for each node element */
|
|
95
|
+
defaultEleWidth?: number;
|
|
96
|
+
/** Default distance between node elements */
|
|
97
|
+
defaultEleDistance?: number;
|
|
98
|
+
/** Offset distance for reverse connection lines */
|
|
99
|
+
offsetLineDistance?: number;
|
|
100
|
+
/** Props to apply to forward connections */
|
|
101
|
+
forwardConnProps?: Record<string, unknown>;
|
|
102
|
+
/** Props to apply to reverse connections */
|
|
103
|
+
reverseConnProps?: Record<string, unknown>;
|
|
104
|
+
/** Whether to allow tooltips on forward arrows */
|
|
105
|
+
allowForwardArrowTooltip?: boolean;
|
|
106
|
+
/** Whether to allow tooltips on reverse arrows */
|
|
107
|
+
allowReverseArrowTooltip?: boolean;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Reference type for the graph instance
|
|
111
|
+
*/
|
|
112
|
+
export type GraphRef = React.MutableRefObject<Graph | null>;
|
|
113
|
+
/**
|
|
114
|
+
* Options for TooltipTool
|
|
115
|
+
*/
|
|
116
|
+
export interface TooltipToolOptions {
|
|
117
|
+
/** Tooltip text content */
|
|
118
|
+
tooltip?: string;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Type for x6 Graph instance methods used by TooltipTool
|
|
122
|
+
*/
|
|
123
|
+
export interface GraphInstance {
|
|
124
|
+
/** Convert client coordinates to graph coordinates */
|
|
125
|
+
clientToGraph: (x: number, y: number) => {
|
|
126
|
+
x: number;
|
|
127
|
+
y: number;
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Type for x6 CellView instance methods used by TooltipTool
|
|
132
|
+
*/
|
|
133
|
+
export interface CellViewInstance {
|
|
134
|
+
/** Register event handler */
|
|
135
|
+
on: (event: string, handler: () => void, context: unknown) => void;
|
|
136
|
+
/** Unregister event handler */
|
|
137
|
+
off: (event: string, handler: () => void) => void;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../components/CapLevelGraphRenderer/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -4226,7 +4226,7 @@ var _default = exports["default"] = SvgFile;
|
|
|
4226
4226
|
|
|
4227
4227
|
|
|
4228
4228
|
exports.__esModule = true;
|
|
4229
|
-
exports.TIME_UNITS = exports.FORMAT_TOKENS = void 0;
|
|
4229
|
+
exports.TIME_UNITS = exports.FORMAT_TOKENS = exports.DEFAULT_TIMEZONE = void 0;
|
|
4230
4230
|
exports.dayjsToMoment = dayjsToMoment;
|
|
4231
4231
|
exports["default"] = void 0;
|
|
4232
4232
|
exports.hasMomentTimezoneSupport = hasMomentTimezoneSupport;
|
|
@@ -4234,6 +4234,7 @@ exports.isDayjsObject = isDayjsObject;
|
|
|
4234
4234
|
exports.isMomentObject = isMomentObject;
|
|
4235
4235
|
exports.momentToDayjs = momentToDayjs;
|
|
4236
4236
|
exports.normalizeDateValue = normalizeDateValue;
|
|
4237
|
+
exports.toDayjsInTimezone = toDayjsInTimezone;
|
|
4237
4238
|
var _dayjs = _interopRequireDefault(__webpack_require__(87695));
|
|
4238
4239
|
var _advancedFormat = _interopRequireDefault(__webpack_require__(96833));
|
|
4239
4240
|
var _customParseFormat = _interopRequireDefault(__webpack_require__(2825));
|
|
@@ -4345,7 +4346,23 @@ if (!tzIsCallable) {
|
|
|
4345
4346
|
if (_dayjs.default.isDayjs(date)) {
|
|
4346
4347
|
return date.tz(tzName);
|
|
4347
4348
|
}
|
|
4348
|
-
|
|
4349
|
+
// For strings/Dates: interpret the date/time values as being IN the target timezone
|
|
4350
|
+
// (matching moment.tz(string, tz) semantics). dayjs(date).tz(tz) is wrong because
|
|
4351
|
+
// dayjs(date) anchors to the system local timezone, so .tz() converts FROM local TO tz.
|
|
4352
|
+
// Instead: parse as UTC to get raw date/time values, compute the target timezone's offset,
|
|
4353
|
+
// then adjust the UTC timestamp so .tz() produces the intended local time.
|
|
4354
|
+
try {
|
|
4355
|
+
// Validate timezone is a real IANA timezone before applying the offset correction
|
|
4356
|
+
Intl.DateTimeFormat(undefined, {
|
|
4357
|
+
timeZone: tzName
|
|
4358
|
+
});
|
|
4359
|
+
} catch (_unused) {
|
|
4360
|
+
// Invalid timezone — fall back to local time
|
|
4361
|
+
return (0, _dayjs.default)(date);
|
|
4362
|
+
}
|
|
4363
|
+
const asUtc = _dayjs.default.utc(date);
|
|
4364
|
+
const tzOffset = asUtc.tz(tzName).utcOffset(); // target tz offset in minutes
|
|
4365
|
+
return _dayjs.default.utc(asUtc.valueOf() - tzOffset * 60000).tz(tzName);
|
|
4349
4366
|
} catch (error) {
|
|
4350
4367
|
// If timezone is invalid, log error and fall back to local time
|
|
4351
4368
|
logDevError("dayjs.tz: Invalid timezone \"" + tzName + "\"", error);
|
|
@@ -4422,6 +4439,8 @@ const FORMAT_TOKENS = exports.FORMAT_TOKENS = {
|
|
|
4422
4439
|
MONTH_FULL: 'MMMM',
|
|
4423
4440
|
YEAR: 'YYYY',
|
|
4424
4441
|
YEAR_SHORT: 'YY',
|
|
4442
|
+
// Cap UI datetime picker format (DD-MM-YYYY | HH:mm)
|
|
4443
|
+
DATE_TIME: 'DD-MM-YYYY | HH:mm',
|
|
4425
4444
|
// Localized formats
|
|
4426
4445
|
DATE_LOCALIZED_SHORT: 'l',
|
|
4427
4446
|
DATETIME_LOCALIZED_SHORT: 'll',
|
|
@@ -4432,6 +4451,7 @@ const FORMAT_TOKENS = exports.FORMAT_TOKENS = {
|
|
|
4432
4451
|
DATETIME_LOCALIZED_LONG_TIME: 'LLL',
|
|
4433
4452
|
DATETIME_LOCALIZED_LONG_TIME_WEEKDAY: 'LLLL'
|
|
4434
4453
|
};
|
|
4454
|
+
const DEFAULT_TIMEZONE = exports.DEFAULT_TIMEZONE = 'Asia/Kolkata';
|
|
4435
4455
|
function logDevError(message, error) {
|
|
4436
4456
|
if (false) // removed by dead control flow
|
|
4437
4457
|
{}
|
|
@@ -4512,7 +4532,10 @@ function momentToDayjs(value) {
|
|
|
4512
4532
|
const tz = value.tz();
|
|
4513
4533
|
if (tz) {
|
|
4514
4534
|
// Has a named timezone - preserve it
|
|
4515
|
-
|
|
4535
|
+
// dayjs.utc(date) is required here: dayjs(date) anchors to the system local timezone,
|
|
4536
|
+
// causing .tz() to only re-label without converting hours. dayjs.utc(date) creates a
|
|
4537
|
+
// UTC-mode dayjs, which .tz() correctly converts to the target timezone for display.
|
|
4538
|
+
dayjsObj = _dayjs.default.utc(date).tz(tz);
|
|
4516
4539
|
|
|
4517
4540
|
// WORKAROUND: dayjs-timezone-iana-plugin doesn't persist timezone name in standard way
|
|
4518
4541
|
// Store it manually in $x for round-trip conversion fidelity
|
|
@@ -4565,6 +4588,35 @@ function momentToDayjs(value) {
|
|
|
4565
4588
|
return null;
|
|
4566
4589
|
}
|
|
4567
4590
|
|
|
4591
|
+
/**
|
|
4592
|
+
* Converts any supported date value (Moment, Day.js, string, Date) to a Day.js object
|
|
4593
|
+
* in the specified timezone. This is the recommended single entry point for timezone-safe
|
|
4594
|
+
* date conversion — it handles moment-to-dayjs conversion and timezone application in one step,
|
|
4595
|
+
* avoiding the double-offset bug in dayjs-timezone-iana-plugin.
|
|
4596
|
+
*
|
|
4597
|
+
* @param value - Moment, Day.js, string, Date, or null/undefined
|
|
4598
|
+
* @param timezone - Target IANA timezone (e.g., 'Asia/Kolkata', 'America/New_York')
|
|
4599
|
+
* @returns Day.js object in the target timezone, or null if invalid
|
|
4600
|
+
*
|
|
4601
|
+
* @example
|
|
4602
|
+
* toDayjsInTimezone(moment.tz('2025-04-21 00:00', 'Asia/Kolkata'), 'Asia/Kolkata');
|
|
4603
|
+
* // Returns dayjs representing 2025-04-21 00:00 IST
|
|
4604
|
+
*
|
|
4605
|
+
* @example
|
|
4606
|
+
* toDayjsInTimezone(moment.tz('2025-04-21 00:00', 'UTC'), 'Asia/Kolkata');
|
|
4607
|
+
* // Returns dayjs representing 2025-04-21 05:30 IST
|
|
4608
|
+
*/
|
|
4609
|
+
function toDayjsInTimezone(value, timezone) {
|
|
4610
|
+
const dayjsValue = momentToDayjs(value);
|
|
4611
|
+
if (!dayjsValue) return null;
|
|
4612
|
+
|
|
4613
|
+
// Convert via UTC to avoid the double-offset bug in dayjs-timezone-iana-plugin:
|
|
4614
|
+
// calling .tz() on a dayjs that already has a non-zero utcOffset corrupts the value.
|
|
4615
|
+
// Going through .toDate() → dayjs.utc() gives us a clean UTC-mode dayjs that .tz()
|
|
4616
|
+
// correctly converts to the target timezone.
|
|
4617
|
+
return _dayjs.default.utc(dayjsValue.toDate()).tz(timezone);
|
|
4618
|
+
}
|
|
4619
|
+
|
|
4568
4620
|
/**
|
|
4569
4621
|
* Converts a Day.js object to Moment.js, preserving timezone and locale information.
|
|
4570
4622
|
*
|