@elaraai/east-ui-components 0.0.1-beta.1 → 0.0.1-beta.3

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/dist/index.cjs CHANGED
@@ -18240,7 +18240,7 @@ function useChart(props) {
18240
18240
  },
18241
18241
  [env.locale]
18242
18242
  );
18243
- const formatDate = React__namespace.useCallback(
18243
+ const formatDate2 = React__namespace.useCallback(
18244
18244
  (options) => {
18245
18245
  return (value) => new Date(value).toLocaleDateString(env.locale, options);
18246
18246
  },
@@ -18311,7 +18311,7 @@ function useChart(props) {
18311
18311
  spacing,
18312
18312
  // formatters
18313
18313
  formatNumber,
18314
- formatDate,
18314
+ formatDate: formatDate2,
18315
18315
  // state
18316
18316
  highlightedSeries,
18317
18317
  setHighlightedSeries,
@@ -53313,7 +53313,7 @@ class RowStateManager {
53313
53313
  }
53314
53314
  }
53315
53315
  const tableRootEqual = east.equalFor(eastUi.Table.Types.Root);
53316
- function toChakraTableRoot(value) {
53316
+ function toChakraTableRoot$1(value) {
53317
53317
  var _a, _b, _c;
53318
53318
  const style = getSomeorUndefined(value.style);
53319
53319
  return {
@@ -53337,7 +53337,7 @@ const EastChakraTable = React.memo(function EastChakraTable2({
53337
53337
  loadingDelay = 200,
53338
53338
  enableColumnResizing = true
53339
53339
  }) {
53340
- const props = React.useMemo(() => toChakraTableRoot(value), [value]);
53340
+ const props = React.useMemo(() => toChakraTableRoot$1(value), [value]);
53341
53341
  const tableContainerRef = React.useRef(null);
53342
53342
  const [rowStateManager] = React.useState(() => new RowStateManager());
53343
53343
  const [rowStates, setRowStates] = React.useState(/* @__PURE__ */ new Map());
@@ -53756,6 +53756,898 @@ function toChakraTreeViewRoot(value) {
53756
53756
  selectionMode: style ? (_c = getSomeorUndefined(style.selectionMode)) == null ? void 0 : _c.type : void 0
53757
53757
  };
53758
53758
  }
53759
+ const formatDate = (date2) => {
53760
+ return date2.toLocaleDateString("en-US", {
53761
+ month: "short",
53762
+ day: "numeric"
53763
+ });
53764
+ };
53765
+ const generateDateTicks = (startDate, endDate, maxTicks = 8) => {
53766
+ const totalDays = Math.ceil((endDate.getTime() - startDate.getTime()) / (1e3 * 60 * 60 * 24));
53767
+ const tickInterval = Math.max(1, Math.ceil(totalDays / maxTicks));
53768
+ const ticks2 = [];
53769
+ const current2 = new Date(startDate);
53770
+ while (current2 <= endDate) {
53771
+ ticks2.push(new Date(current2));
53772
+ current2.setDate(current2.getDate() + tickInterval);
53773
+ }
53774
+ return ticks2;
53775
+ };
53776
+ const getDatePosition = (date2, startDate, endDate, width) => {
53777
+ const totalTimeDiff = endDate.getTime() - startDate.getTime();
53778
+ const currentTimeDiff = date2.getTime() - startDate.getTime();
53779
+ const ratio = currentTimeDiff / totalTimeDiff;
53780
+ return ratio * width;
53781
+ };
53782
+ const LABEL_HALF_WIDTH = 40;
53783
+ const EventAxis = ({
53784
+ startDate,
53785
+ endDate,
53786
+ width,
53787
+ height
53788
+ }) => {
53789
+ const ticks2 = React.useMemo(() => {
53790
+ const dates = generateDateTicks(startDate, endDate, Math.floor(width / 100));
53791
+ return dates.map((date2, index) => {
53792
+ const x2 = getDatePosition(date2, startDate, endDate, width);
53793
+ if (x2 >= LABEL_HALF_WIDTH && x2 <= width - LABEL_HALF_WIDTH) {
53794
+ return { date: date2, x: x2, index };
53795
+ }
53796
+ return null;
53797
+ }).filter(Boolean);
53798
+ }, [startDate, endDate, width]);
53799
+ return /* @__PURE__ */ jsxRuntime.jsx(
53800
+ react.HStack,
53801
+ {
53802
+ position: "relative",
53803
+ width: "100%",
53804
+ height: `${height}px`,
53805
+ px: "3",
53806
+ alignItems: "center",
53807
+ borderBottomWidth: "1px",
53808
+ borderColor: "border.muted",
53809
+ gap: 0,
53810
+ children: ticks2.map(({ date: date2, x: x2, index }) => /* @__PURE__ */ jsxRuntime.jsx(
53811
+ react.Box,
53812
+ {
53813
+ position: "absolute",
53814
+ left: `${x2}px`,
53815
+ transform: "translateX(-50%)",
53816
+ children: /* @__PURE__ */ jsxRuntime.jsx(
53817
+ react.Text,
53818
+ {
53819
+ fontSize: "sm",
53820
+ fontWeight: "semibold",
53821
+ color: "fg.default",
53822
+ whiteSpace: "nowrap",
53823
+ children: formatDate(date2)
53824
+ }
53825
+ )
53826
+ },
53827
+ `tick-${index}`
53828
+ ))
53829
+ }
53830
+ );
53831
+ };
53832
+ const GanttTask = ({
53833
+ x: x2,
53834
+ y: y2,
53835
+ width,
53836
+ height,
53837
+ value,
53838
+ onClick
53839
+ }) => {
53840
+ const [isHovered, setIsHovered] = React.useState(false);
53841
+ const { colorPalette, label, progress } = React.useMemo(() => {
53842
+ var _a;
53843
+ return {
53844
+ colorPalette: ((_a = getSomeorUndefined(value.colorPalette)) == null ? void 0 : _a.type) ?? "blue",
53845
+ label: getSomeorUndefined(value.label),
53846
+ progress: getSomeorUndefined(value.progress)
53847
+ };
53848
+ }, [value]);
53849
+ const [fillColor, strokeColor] = react.useToken("colors", [
53850
+ `${colorPalette}.500`,
53851
+ `${colorPalette}.600`
53852
+ ]);
53853
+ const fontSize = React.useMemo(() => Math.min(height * 0.7, 14), [height]);
53854
+ const textX = React.useMemo(() => x2 + 8, [x2]);
53855
+ const taskWidth = React.useMemo(() => Math.max(width, 4), [width]);
53856
+ const progressWidth = React.useMemo(() => taskWidth * ((progress ?? 0) / 100), [taskWidth, progress]);
53857
+ const handleMouseEnter = React.useCallback(() => setIsHovered(true), []);
53858
+ const handleMouseLeave = React.useCallback(() => setIsHovered(false), []);
53859
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
53860
+ /* @__PURE__ */ jsxRuntime.jsx(
53861
+ "rect",
53862
+ {
53863
+ x: x2,
53864
+ y: y2,
53865
+ width: taskWidth,
53866
+ height,
53867
+ fill: fillColor,
53868
+ stroke: strokeColor,
53869
+ strokeWidth: isHovered ? 3 : 2,
53870
+ opacity: isHovered ? 1 : 0.9,
53871
+ rx: 4,
53872
+ ry: 4,
53873
+ onClick,
53874
+ onMouseEnter: handleMouseEnter,
53875
+ onMouseLeave: handleMouseLeave,
53876
+ style: { cursor: onClick ? "pointer" : "default" }
53877
+ }
53878
+ ),
53879
+ progress !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(
53880
+ "rect",
53881
+ {
53882
+ x: x2,
53883
+ y: y2,
53884
+ width: progressWidth,
53885
+ height,
53886
+ fill: "rgba(255,255,255,0.3)",
53887
+ rx: 4,
53888
+ ry: 4,
53889
+ style: { pointerEvents: "none" }
53890
+ }
53891
+ ),
53892
+ label && /* @__PURE__ */ jsxRuntime.jsx(
53893
+ "foreignObject",
53894
+ {
53895
+ x: textX,
53896
+ y: y2,
53897
+ width: 180,
53898
+ height,
53899
+ style: { pointerEvents: "auto" },
53900
+ children: /* @__PURE__ */ jsxRuntime.jsx(
53901
+ react.Text,
53902
+ {
53903
+ fontSize: `${fontSize}px`,
53904
+ color: "fg.default",
53905
+ opacity: isHovered ? 1 : 0.9,
53906
+ whiteSpace: "nowrap",
53907
+ cursor: onClick ? "pointer" : "default",
53908
+ userSelect: "none",
53909
+ lineHeight: "1",
53910
+ overflow: "hidden",
53911
+ textOverflow: "ellipsis",
53912
+ display: "flex",
53913
+ alignItems: "center",
53914
+ height: "100%",
53915
+ onMouseEnter: handleMouseEnter,
53916
+ onMouseLeave: handleMouseLeave,
53917
+ onClick,
53918
+ m: 0,
53919
+ p: 0,
53920
+ children: label
53921
+ }
53922
+ )
53923
+ }
53924
+ )
53925
+ ] });
53926
+ };
53927
+ const makeDiamondPoints = (x2, y2, size) => {
53928
+ const centerX = x2;
53929
+ const centerY = y2 + size / 2;
53930
+ return `${centerX},${y2} ${centerX + size / 2},${centerY} ${centerX},${y2 + size} ${centerX - size / 2},${centerY}`;
53931
+ };
53932
+ const GanttMilestone = ({
53933
+ x: x2,
53934
+ y: y2,
53935
+ height,
53936
+ value,
53937
+ onClick
53938
+ }) => {
53939
+ const [isHovered, setIsHovered] = React.useState(false);
53940
+ const { colorPalette, label } = React.useMemo(() => {
53941
+ var _a;
53942
+ return {
53943
+ colorPalette: ((_a = getSomeorUndefined(value.colorPalette)) == null ? void 0 : _a.type) ?? "blue",
53944
+ label: getSomeorUndefined(value.label)
53945
+ };
53946
+ }, [value]);
53947
+ const [fillColor, strokeColor] = react.useToken("colors", [
53948
+ `${colorPalette}.500`,
53949
+ `${colorPalette}.600`
53950
+ ]);
53951
+ const fontSize = React.useMemo(() => Math.min(height * 0.7, 14), [height]);
53952
+ const diamondSize = React.useMemo(() => height, [height]);
53953
+ const textX = React.useMemo(() => x2 + diamondSize / 2 + 4, [x2, diamondSize]);
53954
+ const diamondPoints = React.useMemo(() => makeDiamondPoints(x2, y2, diamondSize), [x2, y2, diamondSize]);
53955
+ const handleMouseEnter = React.useCallback(() => setIsHovered(true), []);
53956
+ const handleMouseLeave = React.useCallback(() => setIsHovered(false), []);
53957
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
53958
+ /* @__PURE__ */ jsxRuntime.jsx(
53959
+ "polygon",
53960
+ {
53961
+ points: diamondPoints,
53962
+ fill: fillColor,
53963
+ stroke: strokeColor,
53964
+ strokeWidth: isHovered ? 3 : 2,
53965
+ opacity: isHovered ? 1 : 0.9,
53966
+ onClick,
53967
+ onMouseEnter: handleMouseEnter,
53968
+ onMouseLeave: handleMouseLeave,
53969
+ style: { cursor: onClick ? "pointer" : "default" }
53970
+ }
53971
+ ),
53972
+ label && /* @__PURE__ */ jsxRuntime.jsx(
53973
+ "foreignObject",
53974
+ {
53975
+ x: textX,
53976
+ y: y2,
53977
+ width: 200,
53978
+ height,
53979
+ style: { pointerEvents: "auto" },
53980
+ children: /* @__PURE__ */ jsxRuntime.jsx(
53981
+ react.Text,
53982
+ {
53983
+ fontSize: `${fontSize}px`,
53984
+ color: "fg.default",
53985
+ opacity: isHovered ? 1 : 0.9,
53986
+ whiteSpace: "nowrap",
53987
+ cursor: onClick ? "pointer" : "default",
53988
+ userSelect: "none",
53989
+ lineHeight: "1",
53990
+ display: "flex",
53991
+ alignItems: "center",
53992
+ height: "100%",
53993
+ onMouseEnter: handleMouseEnter,
53994
+ onMouseLeave: handleMouseLeave,
53995
+ onClick,
53996
+ m: 0,
53997
+ p: 0,
53998
+ children: label
53999
+ }
54000
+ )
54001
+ }
54002
+ )
54003
+ ] });
54004
+ };
54005
+ const getEventPosition = (event, startDate, endDate, width) => {
54006
+ const totalTimespan = endDate.getTime() - startDate.getTime();
54007
+ if (event.type === "Milestone") {
54008
+ const eventDate = event.value.date;
54009
+ const eventTime = eventDate.getTime();
54010
+ if (eventTime >= startDate.getTime() && eventTime <= endDate.getTime()) {
54011
+ const position = (eventTime - startDate.getTime()) / totalTimespan;
54012
+ return {
54013
+ x: position * width,
54014
+ width: 0,
54015
+ isMilestone: true
54016
+ };
54017
+ }
54018
+ return { x: 0, width: 0, isMilestone: true };
54019
+ }
54020
+ const taskValue = event.value;
54021
+ const eventStart = taskValue.start;
54022
+ const eventEnd = taskValue.end;
54023
+ const clampedStart = Math.max(eventStart.getTime(), startDate.getTime());
54024
+ const clampedEnd = Math.min(eventEnd.getTime(), endDate.getTime());
54025
+ const startOffset = (clampedStart - startDate.getTime()) / totalTimespan;
54026
+ const duration = (clampedEnd - clampedStart) / totalTimespan;
54027
+ return {
54028
+ x: startOffset * width,
54029
+ width: Math.max(duration * width, 2),
54030
+ isMilestone: false
54031
+ };
54032
+ };
54033
+ const GanttEventRow = ({
54034
+ events,
54035
+ rowIndex,
54036
+ y: y2,
54037
+ width,
54038
+ height,
54039
+ startDate,
54040
+ endDate,
54041
+ onEventClick
54042
+ }) => {
54043
+ const renderedEvents = React.useMemo(() => {
54044
+ const eventHeight = height - 24;
54045
+ const eventY = y2 + 12;
54046
+ return events.map((event, eventIndex) => {
54047
+ const position = getEventPosition(event, startDate, endDate, width);
54048
+ if (position.x < 0 || position.x > width) return null;
54049
+ if (event.type === "Milestone") {
54050
+ return /* @__PURE__ */ jsxRuntime.jsx(
54051
+ GanttMilestone,
54052
+ {
54053
+ x: position.x,
54054
+ y: eventY,
54055
+ height: eventHeight,
54056
+ value: event.value,
54057
+ onClick: onEventClick ? () => onEventClick(event, rowIndex, eventIndex) : () => {
54058
+ }
54059
+ },
54060
+ `${rowIndex}-${eventIndex}`
54061
+ );
54062
+ }
54063
+ return /* @__PURE__ */ jsxRuntime.jsx(
54064
+ GanttTask,
54065
+ {
54066
+ x: position.x,
54067
+ y: eventY,
54068
+ width: position.width,
54069
+ height: eventHeight,
54070
+ value: event.value,
54071
+ onClick: onEventClick ? () => onEventClick(event, rowIndex, eventIndex) : () => {
54072
+ }
54073
+ },
54074
+ `${rowIndex}-${eventIndex}`
54075
+ );
54076
+ }).filter(Boolean);
54077
+ }, [events, rowIndex, y2, width, height, startDate, endDate, onEventClick]);
54078
+ return /* @__PURE__ */ jsxRuntime.jsx("g", { children: renderedEvents });
54079
+ };
54080
+ const ganttRootEqual = east.equalFor(eastUi.Gantt.Types.Root);
54081
+ function toChakraTableRoot(value) {
54082
+ var _a, _b, _c;
54083
+ const style = getSomeorUndefined(value.style);
54084
+ return {
54085
+ variant: style ? (_a = getSomeorUndefined(style.variant)) == null ? void 0 : _a.type : void 0,
54086
+ size: style ? (_b = getSomeorUndefined(style.size)) == null ? void 0 : _b.type : void 0,
54087
+ striped: style ? getSomeorUndefined(style.striped) : void 0,
54088
+ interactive: style ? getSomeorUndefined(style.interactive) : void 0,
54089
+ stickyHeader: style ? getSomeorUndefined(style.stickyHeader) : void 0,
54090
+ showColumnBorder: style ? getSomeorUndefined(style.showColumnBorder) : void 0,
54091
+ colorPalette: style ? (_c = getSomeorUndefined(style.colorPalette)) == null ? void 0 : _c.type : void 0
54092
+ };
54093
+ }
54094
+ const EastChakraGantt = React.memo(function EastChakraGantt2({
54095
+ value,
54096
+ height = "400px",
54097
+ rowHeight = 48,
54098
+ overscan = 8,
54099
+ onSortChange,
54100
+ enableMultiSort = true,
54101
+ maxSortColumns = 5,
54102
+ loadingDelay = 200,
54103
+ enableColumnResizing = true,
54104
+ onEventClick,
54105
+ tablePanelSize = 40
54106
+ }) {
54107
+ const props = React.useMemo(() => toChakraTableRoot(value), [value]);
54108
+ const headerHeight = 56;
54109
+ const [gridLineColor] = react.useToken("colors", ["gray.300"]);
54110
+ const tableContainerRef = React.useRef(null);
54111
+ const timelineContainerRef = React.useRef(null);
54112
+ const [timelineWidth, setTimelineWidth] = React.useState(400);
54113
+ const [rowStateManager] = React.useState(() => new RowStateManager());
54114
+ const [rowStates, setRowStates] = React.useState(/* @__PURE__ */ new Map());
54115
+ const visibleRowsRef = React.useRef(/* @__PURE__ */ new Set());
54116
+ const dateRange = React.useMemo(() => {
54117
+ let minDate = null;
54118
+ let maxDate = null;
54119
+ value.rows.forEach((row) => {
54120
+ row.events.forEach((event) => {
54121
+ if (event.type === "Milestone") {
54122
+ const date2 = event.value.date;
54123
+ if (minDate === null || date2 < minDate) minDate = date2;
54124
+ if (maxDate === null || date2 > maxDate) maxDate = date2;
54125
+ } else {
54126
+ const start = event.value.start;
54127
+ const end3 = event.value.end;
54128
+ if (minDate === null || start < minDate) minDate = start;
54129
+ if (maxDate === null || end3 > maxDate) maxDate = end3;
54130
+ }
54131
+ });
54132
+ });
54133
+ if (minDate === null) minDate = /* @__PURE__ */ new Date();
54134
+ if (maxDate === null) maxDate = /* @__PURE__ */ new Date();
54135
+ const totalDuration = maxDate.getTime() - minDate.getTime();
54136
+ const bufferDuration = Math.max(totalDuration * 0.1, 24 * 60 * 60 * 1e3);
54137
+ return {
54138
+ start: new Date(minDate.getTime() - bufferDuration),
54139
+ end: new Date(maxDate.getTime() + bufferDuration)
54140
+ };
54141
+ }, [value.rows]);
54142
+ const gridLinePositions = React.useMemo(() => {
54143
+ const dates = generateDateTicks(dateRange.start, dateRange.end, Math.floor(timelineWidth / 100));
54144
+ return dates.map((date2) => getDatePosition(date2, dateRange.start, dateRange.end, timelineWidth)).filter((x2) => x2 >= 0 && x2 <= timelineWidth);
54145
+ }, [dateRange.start, dateRange.end, timelineWidth]);
54146
+ React.useEffect(() => {
54147
+ const container = timelineContainerRef.current;
54148
+ if (!container) return;
54149
+ const updateWidth = () => {
54150
+ const width = container.offsetWidth;
54151
+ setTimelineWidth(Math.max(200, width));
54152
+ };
54153
+ updateWidth();
54154
+ const resizeObserver = new ResizeObserver(updateWidth);
54155
+ resizeObserver.observe(container);
54156
+ return () => resizeObserver.disconnect();
54157
+ }, []);
54158
+ React.useEffect(() => {
54159
+ return rowStateManager.subscribe(() => {
54160
+ setRowStates(new Map(rowStateManager.getStates()));
54161
+ });
54162
+ }, [rowStateManager]);
54163
+ React.useEffect(() => {
54164
+ return () => {
54165
+ rowStateManager.clear();
54166
+ };
54167
+ }, [rowStateManager]);
54168
+ const columnHelper = createColumnHelper();
54169
+ const columns = React.useMemo(() => {
54170
+ return value.columns.map((col) => {
54171
+ const print = east.printFor(col.type);
54172
+ return columnHelper.accessor(
54173
+ (row) => row.cells.get(col.key),
54174
+ {
54175
+ id: col.key,
54176
+ header: getSomeorUndefined(col.header) ?? col.key,
54177
+ enableSorting: true,
54178
+ minSize: 80,
54179
+ size: 150,
54180
+ maxSize: 400,
54181
+ meta: {
54182
+ print,
54183
+ columnKey: col.key
54184
+ }
54185
+ }
54186
+ );
54187
+ });
54188
+ }, [value.columns, columnHelper]);
54189
+ const [sorting, setSorting] = React.useState([]);
54190
+ const handleSortingChange = React.useCallback(
54191
+ (updater) => {
54192
+ setSorting((prev) => {
54193
+ const newSorting = typeof updater === "function" ? updater(prev) : updater;
54194
+ const sorts = newSorting.map((s2) => ({
54195
+ columnKey: s2.id,
54196
+ direction: s2.desc ? "desc" : "asc"
54197
+ }));
54198
+ onSortChange == null ? void 0 : onSortChange(sorts);
54199
+ return newSorting;
54200
+ });
54201
+ },
54202
+ [onSortChange]
54203
+ );
54204
+ const [columnSizing, setColumnSizing] = React.useState({});
54205
+ const table = useReactTable({
54206
+ data: value.rows,
54207
+ columns,
54208
+ state: {
54209
+ sorting,
54210
+ columnSizing
54211
+ },
54212
+ onSortingChange: handleSortingChange,
54213
+ onColumnSizingChange: setColumnSizing,
54214
+ getCoreRowModel: getCoreRowModel(),
54215
+ getSortedRowModel: getSortedRowModel(),
54216
+ enableMultiSort,
54217
+ isMultiSortEvent: () => enableMultiSort,
54218
+ maxMultiSortColCount: maxSortColumns,
54219
+ enableColumnResizing,
54220
+ columnResizeMode: "onChange"
54221
+ });
54222
+ const { rows } = table.getRowModel();
54223
+ const columnSizeVars = React.useMemo(() => {
54224
+ const headers = table.getFlatHeaders();
54225
+ const colSizes = {};
54226
+ headers.forEach((header) => {
54227
+ colSizes[`--header-${header.id}-size`] = `${header.getSize()}px`;
54228
+ colSizes[`--col-${header.column.id}-size`] = `${header.column.getSize()}px`;
54229
+ });
54230
+ return colSizes;
54231
+ }, [table.getState().columnSizingInfo, table.getState().columnSizing]);
54232
+ const virtualizer = useVirtualizer({
54233
+ count: rows.length,
54234
+ getScrollElement: () => tableContainerRef.current,
54235
+ estimateSize: () => rowHeight,
54236
+ overscan
54237
+ });
54238
+ const virtualItems = virtualizer.getVirtualItems();
54239
+ React.useEffect(() => {
54240
+ const currentVisible = /* @__PURE__ */ new Set();
54241
+ virtualItems.forEach((item) => {
54242
+ currentVisible.add(item.index);
54243
+ });
54244
+ const prevVisible = visibleRowsRef.current;
54245
+ const load = [];
54246
+ currentVisible.forEach((key) => {
54247
+ const rowState = rowStateManager.getRowState(key);
54248
+ if (rowState.status === "unloaded") {
54249
+ load.push(key);
54250
+ }
54251
+ });
54252
+ const unload = [];
54253
+ prevVisible.forEach((key) => {
54254
+ if (!currentVisible.has(key)) {
54255
+ unload.push(key);
54256
+ }
54257
+ });
54258
+ if (load.length > 0) {
54259
+ rowStateManager.markRowsLoading(load);
54260
+ load.forEach((key) => rowStateManager.scheduleLoaded(key, loadingDelay));
54261
+ }
54262
+ if (unload.length > 0) {
54263
+ rowStateManager.markRowsUnloaded(unload);
54264
+ }
54265
+ visibleRowsRef.current = currentVisible;
54266
+ }, [virtualItems, rowStateManager, loadingDelay]);
54267
+ const getSortIndex = React.useCallback(
54268
+ (columnId) => {
54269
+ const idx = sorting.findIndex((s2) => s2.id === columnId);
54270
+ return idx >= 0 ? idx + 1 : void 0;
54271
+ },
54272
+ [sorting]
54273
+ );
54274
+ const handleTableScroll = React.useCallback(() => {
54275
+ if (tableContainerRef.current && timelineContainerRef.current) {
54276
+ timelineContainerRef.current.scrollTop = tableContainerRef.current.scrollTop;
54277
+ }
54278
+ }, []);
54279
+ const handleTimelineScroll = React.useCallback(() => {
54280
+ if (tableContainerRef.current && timelineContainerRef.current) {
54281
+ tableContainerRef.current.scrollTop = timelineContainerRef.current.scrollTop;
54282
+ }
54283
+ }, []);
54284
+ const panels = React.useMemo(() => [
54285
+ { id: "table", minSize: 20 },
54286
+ { id: "timeline", minSize: 20 }
54287
+ ], []);
54288
+ return /* @__PURE__ */ jsxRuntime.jsxs(
54289
+ react.Splitter.Root,
54290
+ {
54291
+ defaultSize: [tablePanelSize, 100 - tablePanelSize],
54292
+ panels,
54293
+ width: "100%",
54294
+ height,
54295
+ children: [
54296
+ /* @__PURE__ */ jsxRuntime.jsx(react.Splitter.Panel, { id: "table", children: /* @__PURE__ */ jsxRuntime.jsx(
54297
+ react.Box,
54298
+ {
54299
+ ref: tableContainerRef,
54300
+ height: "100%",
54301
+ overflowY: "auto",
54302
+ position: "relative",
54303
+ onScroll: handleTableScroll,
54304
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
54305
+ react.Table.Root,
54306
+ {
54307
+ ...props,
54308
+ style: {
54309
+ ...columnSizeVars,
54310
+ width: "100%",
54311
+ minWidth: table.getCenterTotalSize(),
54312
+ tableLayout: "fixed"
54313
+ },
54314
+ children: [
54315
+ /* @__PURE__ */ jsxRuntime.jsx(
54316
+ react.Table.Header,
54317
+ {
54318
+ style: { display: "block" },
54319
+ position: "sticky",
54320
+ top: 0,
54321
+ zIndex: 1,
54322
+ bg: "bg.panel",
54323
+ children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsxRuntime.jsx(
54324
+ react.Table.Row,
54325
+ {
54326
+ style: { display: "flex", width: "100%", height: `${headerHeight}px` },
54327
+ children: headerGroup.headers.map((header) => {
54328
+ const sortIndex = getSortIndex(header.id);
54329
+ const isSorted = header.column.getIsSorted();
54330
+ const sortDirection = isSorted || null;
54331
+ const icon3 = !isSorted ? faAnglesDown : sortDirection === "asc" ? faChevronUp : faChevronDown;
54332
+ return /* @__PURE__ */ jsxRuntime.jsxs(
54333
+ react.Table.ColumnHeader,
54334
+ {
54335
+ cursor: header.column.getCanSort() ? "pointer" : "default",
54336
+ _hover: header.column.getCanSort() ? { bg: "bg.muted" } : {},
54337
+ onClick: header.column.getToggleSortingHandler(),
54338
+ transition: "background 0.2s",
54339
+ style: {
54340
+ width: `var(--header-${header.id}-size)`,
54341
+ flex: columnSizing[header.id] ? "none" : 1
54342
+ },
54343
+ position: "relative",
54344
+ children: [
54345
+ /* @__PURE__ */ jsxRuntime.jsxs(
54346
+ react.HStack,
54347
+ {
54348
+ justify: "space-between",
54349
+ width: "100%",
54350
+ pr: enableColumnResizing ? "8px" : "0",
54351
+ children: [
54352
+ /* @__PURE__ */ jsxRuntime.jsx(
54353
+ react.Text,
54354
+ {
54355
+ fontSize: "sm",
54356
+ fontWeight: "semibold",
54357
+ overflow: "hidden",
54358
+ textOverflow: "ellipsis",
54359
+ whiteSpace: "nowrap",
54360
+ flex: "1",
54361
+ children: header.isPlaceholder ? null : flexRender(
54362
+ header.column.columnDef.header,
54363
+ header.getContext()
54364
+ )
54365
+ }
54366
+ ),
54367
+ /* @__PURE__ */ jsxRuntime.jsx(react.HStack, { gap: 1, flexShrink: 0, children: header.column.getCanSort() && /* @__PURE__ */ jsxRuntime.jsxs(
54368
+ react.IconButton,
54369
+ {
54370
+ "aria-label": `Sort by ${header.id}`,
54371
+ size: "xs",
54372
+ variant: "ghost",
54373
+ color: isSorted ? "fg.default" : "fg.muted",
54374
+ onClick: (e3) => {
54375
+ e3.stopPropagation();
54376
+ header.column.toggleSorting(
54377
+ void 0,
54378
+ enableMultiSort
54379
+ );
54380
+ },
54381
+ _hover: {
54382
+ bg: "bg.muted",
54383
+ color: "fg.default"
54384
+ },
54385
+ position: "relative",
54386
+ children: [
54387
+ /* @__PURE__ */ jsxRuntime.jsx(
54388
+ FontAwesomeIcon,
54389
+ {
54390
+ icon: icon3,
54391
+ style: {
54392
+ width: "12px",
54393
+ height: "12px"
54394
+ }
54395
+ }
54396
+ ),
54397
+ isSorted && sortIndex && /* @__PURE__ */ jsxRuntime.jsx(
54398
+ react.Box,
54399
+ {
54400
+ position: "absolute",
54401
+ top: "-2px",
54402
+ right: "-2px",
54403
+ bg: "fg.muted",
54404
+ color: "bg.panel",
54405
+ borderRadius: "full",
54406
+ width: "12px",
54407
+ height: "12px",
54408
+ display: "flex",
54409
+ alignItems: "center",
54410
+ justifyContent: "center",
54411
+ fontSize: "8px",
54412
+ fontWeight: "bold",
54413
+ children: sortIndex
54414
+ }
54415
+ )
54416
+ ]
54417
+ }
54418
+ ) })
54419
+ ]
54420
+ }
54421
+ ),
54422
+ enableColumnResizing && header.column.getCanResize() && /* @__PURE__ */ jsxRuntime.jsx(
54423
+ react.Box,
54424
+ {
54425
+ position: "absolute",
54426
+ right: "0",
54427
+ top: "0",
54428
+ bottom: "0",
54429
+ width: "8px",
54430
+ cursor: "col-resize",
54431
+ bg: "transparent",
54432
+ _hover: {
54433
+ _before: {
54434
+ opacity: 1,
54435
+ bg: "fg.muted"
54436
+ }
54437
+ },
54438
+ transition: "all 0.2s",
54439
+ zIndex: 10,
54440
+ onMouseDown: header.getResizeHandler(),
54441
+ onTouchStart: header.getResizeHandler(),
54442
+ _before: {
54443
+ content: '""',
54444
+ position: "absolute",
54445
+ right: "2px",
54446
+ top: "50%",
54447
+ transform: "translateY(-50%)",
54448
+ width: "2px",
54449
+ height: "16px",
54450
+ bg: "gray.300",
54451
+ borderRadius: "1px",
54452
+ opacity: 0.4,
54453
+ transition: "opacity 0.2s"
54454
+ }
54455
+ }
54456
+ )
54457
+ ]
54458
+ },
54459
+ header.id
54460
+ );
54461
+ })
54462
+ },
54463
+ headerGroup.id
54464
+ ))
54465
+ }
54466
+ ),
54467
+ /* @__PURE__ */ jsxRuntime.jsx(
54468
+ react.Table.Body,
54469
+ {
54470
+ style: {
54471
+ display: "block",
54472
+ position: "relative",
54473
+ height: `${virtualizer.getTotalSize()}px`
54474
+ },
54475
+ children: virtualItems.map((virtualRow) => {
54476
+ const row = rows[virtualRow.index];
54477
+ if (!row) return null;
54478
+ const rowKey = virtualRow.index;
54479
+ const rowState = rowStates.get(rowKey) || { status: "unloaded" };
54480
+ const isRowLoading = !rowStateManager.isRowLoaded(rowKey) || rowState.status === "loading";
54481
+ return /* @__PURE__ */ jsxRuntime.jsx(
54482
+ react.Table.Row,
54483
+ {
54484
+ style: {
54485
+ display: "flex",
54486
+ position: "absolute",
54487
+ top: 0,
54488
+ left: 0,
54489
+ width: "100%",
54490
+ height: `${virtualRow.size}px`,
54491
+ transform: `translateY(${virtualRow.start}px)`
54492
+ },
54493
+ children: row.getVisibleCells().map((cell) => {
54494
+ var _a;
54495
+ const cellValue = cell.getValue();
54496
+ const meta = cell.column.columnDef.meta;
54497
+ const cellStyle = {
54498
+ width: `var(--col-${cell.column.id}-size)`,
54499
+ flex: columnSizing[cell.column.id] ? "none" : 1
54500
+ };
54501
+ if (isRowLoading) {
54502
+ return /* @__PURE__ */ jsxRuntime.jsx(react.Table.Cell, { style: cellStyle, children: /* @__PURE__ */ jsxRuntime.jsx(react.Skeleton, { height: "20px", width: "80%" }) }, cell.id);
54503
+ }
54504
+ if (cellValue == null) {
54505
+ return /* @__PURE__ */ jsxRuntime.jsx(
54506
+ react.Table.Cell,
54507
+ {
54508
+ style: cellStyle
54509
+ },
54510
+ cell.id
54511
+ );
54512
+ }
54513
+ if (cellValue.content != null) {
54514
+ return /* @__PURE__ */ jsxRuntime.jsx(react.Table.Cell, { style: cellStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
54515
+ EastChakraComponent,
54516
+ {
54517
+ value: cellValue.content
54518
+ }
54519
+ ) }, cell.id);
54520
+ }
54521
+ return /* @__PURE__ */ jsxRuntime.jsx(react.Table.Cell, { style: cellStyle, children: /* @__PURE__ */ jsxRuntime.jsx(react.Text, { children: ((_a = meta == null ? void 0 : meta.print) == null ? void 0 : _a.call(meta, cellValue.value.value)) ?? null }) }, cell.id);
54522
+ })
54523
+ },
54524
+ row.id
54525
+ );
54526
+ })
54527
+ }
54528
+ )
54529
+ ]
54530
+ }
54531
+ )
54532
+ }
54533
+ ) }),
54534
+ /* @__PURE__ */ jsxRuntime.jsx(react.Splitter.ResizeTrigger, { id: "table:timeline" }),
54535
+ /* @__PURE__ */ jsxRuntime.jsx(react.Splitter.Panel, { id: "timeline", children: /* @__PURE__ */ jsxRuntime.jsxs(
54536
+ react.Box,
54537
+ {
54538
+ ref: timelineContainerRef,
54539
+ width: "100%",
54540
+ height: "100%",
54541
+ overflowY: "auto",
54542
+ overflowX: "hidden",
54543
+ position: "relative",
54544
+ onScroll: handleTimelineScroll,
54545
+ children: [
54546
+ /* @__PURE__ */ jsxRuntime.jsx(react.Box, { position: "sticky", top: 0, zIndex: 1, bg: "bg.panel", children: /* @__PURE__ */ jsxRuntime.jsx(
54547
+ EventAxis,
54548
+ {
54549
+ startDate: dateRange.start,
54550
+ endDate: dateRange.end,
54551
+ width: timelineWidth,
54552
+ height: headerHeight
54553
+ }
54554
+ ) }),
54555
+ /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { position: "relative", children: [
54556
+ /* @__PURE__ */ jsxRuntime.jsx(
54557
+ react.Table.Root,
54558
+ {
54559
+ ...props,
54560
+ style: {
54561
+ width: "100%",
54562
+ tableLayout: "fixed",
54563
+ position: "relative"
54564
+ },
54565
+ children: /* @__PURE__ */ jsxRuntime.jsx(
54566
+ react.Table.Body,
54567
+ {
54568
+ style: {
54569
+ display: "block",
54570
+ position: "relative",
54571
+ height: `${virtualizer.getTotalSize()}px`
54572
+ },
54573
+ children: virtualItems.map((virtualRow) => {
54574
+ const row = rows[virtualRow.index];
54575
+ if (!row) return null;
54576
+ return /* @__PURE__ */ jsxRuntime.jsx(
54577
+ react.Table.Row,
54578
+ {
54579
+ style: {
54580
+ display: "flex",
54581
+ position: "absolute",
54582
+ top: 0,
54583
+ left: 0,
54584
+ width: "100%",
54585
+ height: `${virtualRow.size}px`,
54586
+ transform: `translateY(${virtualRow.start}px)`
54587
+ },
54588
+ children: /* @__PURE__ */ jsxRuntime.jsx(
54589
+ react.Table.Cell,
54590
+ {
54591
+ style: { width: "100%", padding: 0 },
54592
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "100%", height: virtualRow.size, children: /* @__PURE__ */ jsxRuntime.jsx(
54593
+ GanttEventRow,
54594
+ {
54595
+ events: row.original.events,
54596
+ rowIndex: virtualRow.index,
54597
+ y: 0,
54598
+ width: timelineWidth,
54599
+ height: virtualRow.size,
54600
+ startDate: dateRange.start,
54601
+ endDate: dateRange.end,
54602
+ onEventClick
54603
+ }
54604
+ ) })
54605
+ }
54606
+ )
54607
+ },
54608
+ row.id
54609
+ );
54610
+ })
54611
+ }
54612
+ )
54613
+ }
54614
+ ),
54615
+ /* @__PURE__ */ jsxRuntime.jsx(
54616
+ "svg",
54617
+ {
54618
+ width: timelineWidth,
54619
+ height: virtualizer.getTotalSize(),
54620
+ style: {
54621
+ position: "absolute",
54622
+ top: 0,
54623
+ left: 0,
54624
+ pointerEvents: "none",
54625
+ zIndex: 1
54626
+ },
54627
+ children: gridLinePositions.map((x2, index) => /* @__PURE__ */ jsxRuntime.jsx(
54628
+ "line",
54629
+ {
54630
+ x1: x2,
54631
+ y1: 0,
54632
+ x2,
54633
+ y2: virtualizer.getTotalSize(),
54634
+ stroke: gridLineColor,
54635
+ strokeWidth: 1,
54636
+ strokeDasharray: "4 4",
54637
+ opacity: 0.6
54638
+ },
54639
+ `grid-${index}`
54640
+ ))
54641
+ }
54642
+ )
54643
+ ] })
54644
+ ]
54645
+ }
54646
+ ) })
54647
+ ]
54648
+ }
54649
+ );
54650
+ }, (prev, next) => ganttRootEqual(prev.value, next.value));
53759
54651
  const badgeEqual = east.equalFor(eastUi.Badge.Types.Badge);
53760
54652
  function toChakraBadge(value) {
53761
54653
  var _a, _b, _c;
@@ -53868,7 +54760,7 @@ function toChakraDateTimeInput(value) {
53868
54760
  var _a, _b;
53869
54761
  const showTime = getSomeorUndefined(value.showTime);
53870
54762
  const dateValue = value.value instanceof Date ? value.value : new Date(value.value);
53871
- const formatDate = (d2) => {
54763
+ const formatDate2 = (d2) => {
53872
54764
  if (showTime) {
53873
54765
  return d2.toISOString().slice(0, 16);
53874
54766
  }
@@ -53876,9 +54768,9 @@ function toChakraDateTimeInput(value) {
53876
54768
  };
53877
54769
  return {
53878
54770
  type: showTime ? "datetime-local" : "date",
53879
- value: formatDate(dateValue),
53880
- min: getSomeorUndefined(value.min) ? formatDate(new Date(getSomeorUndefined(value.min))) : void 0,
53881
- max: getSomeorUndefined(value.max) ? formatDate(new Date(getSomeorUndefined(value.max))) : void 0,
54771
+ value: formatDate2(dateValue),
54772
+ min: getSomeorUndefined(value.min) ? formatDate2(new Date(getSomeorUndefined(value.min))) : void 0,
54773
+ max: getSomeorUndefined(value.max) ? formatDate2(new Date(getSomeorUndefined(value.max))) : void 0,
53882
54774
  variant: (_a = getSomeorUndefined(value.variant)) == null ? void 0 : _a.type,
53883
54775
  size: (_b = getSomeorUndefined(value.size)) == null ? void 0 : _b.type,
53884
54776
  disabled: getSomeorUndefined(value.disabled)
@@ -54473,6 +55365,7 @@ const EastChakraComponent = React.memo(function EastChakraComponent2({ value })
54473
55365
  // Collections
54474
55366
  DataList: (v2) => /* @__PURE__ */ jsxRuntime.jsx(EastChakraDataList, { value: v2 }),
54475
55367
  Table: (v2) => /* @__PURE__ */ jsxRuntime.jsx(EastChakraTable, { value: v2 }),
55368
+ Gantt: (v2) => /* @__PURE__ */ jsxRuntime.jsx(EastChakraGantt, { value: v2 }),
54476
55369
  // Charts
54477
55370
  Sparkline: (v2) => /* @__PURE__ */ jsxRuntime.jsx(EastChakraSparkline, { value: v2 }),
54478
55371
  AreaChart: (v2) => /* @__PURE__ */ jsxRuntime.jsx(EastChakraAreaChart, { value: v2 }),
@@ -54799,7 +55692,7 @@ exports.toChakraSplitter = toChakraSplitter;
54799
55692
  exports.toChakraStack = toChakraStack;
54800
55693
  exports.toChakraStringInput = toChakraStringInput;
54801
55694
  exports.toChakraSwitch = toChakraSwitch;
54802
- exports.toChakraTableRoot = toChakraTableRoot;
55695
+ exports.toChakraTableRoot = toChakraTableRoot$1;
54803
55696
  exports.toChakraTabsContent = toChakraTabsContent;
54804
55697
  exports.toChakraTabsRoot = toChakraTabsRoot;
54805
55698
  exports.toChakraTabsTrigger = toChakraTabsTrigger;