@mindlogic-ai/logician-ui 4.0.0-alpha.18 → 4.0.0-alpha.19

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.
@@ -1 +1 @@
1
- {"version":3,"file":"TableContext.d.ts","sourceRoot":"","sources":["../../../src/components/Table/TableContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAEZ,SAAS,EAMV,MAAM,OAAO,CAAC;AAEf,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB;AAOD,UAAU,iBAAkB,SAAQ,gBAAgB;IAClD,eAAe,EAAE,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,KAAK,IAAI,CAAC;IACvD,oBAAoB,EAAE,CACpB,SAAS,EAAE,MAAM,GAAG,OAAO,EAC3B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,KACV,IAAI,CAAC;IACV,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACxE,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;CAC7E;AAID,eAAO,MAAM,eAAe,yBAM3B,CAAC;AAEF,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA4ItD,CAAC"}
1
+ {"version":3,"file":"TableContext.d.ts","sourceRoot":"","sources":["../../../src/components/Table/TableContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAEZ,SAAS,EAMV,MAAM,OAAO,CAAC;AAEf,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB;AASD,UAAU,iBAAkB,SAAQ,gBAAgB;IAClD,eAAe,EAAE,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,KAAK,IAAI,CAAC;IACvD,oBAAoB,EAAE,CACpB,SAAS,EAAE,MAAM,GAAG,OAAO,EAC3B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,KACV,IAAI,CAAC;IACV,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACxE,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;CAC7E;AAID,eAAO,MAAM,eAAe,yBAM3B,CAAC;AAEF,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAgJtD,CAAC"}
@@ -19,9 +19,15 @@ const TableProvider = ({ children }) => {
19
19
  isScrollEnd: false,
20
20
  isScrolling: false,
21
21
  });
22
- const stickyColumnsRef = React.useRef({
23
- leftColumnWidths: new Map(),
24
- rightColumnWidths: new Map(),
22
+ // Column widths live in state (not a ref) so that a width change — a font
23
+ // swap, a window/sidebar resize, or the columns re-flowing when the table
24
+ // goes from fitting to overflowing — triggers a re-render and the sticky
25
+ // offsets are recomputed. Storing them in a ref (the previous approach) meant
26
+ // the offsets were computed once at mount and then went stale, detaching the
27
+ // sticky columns from their real positions.
28
+ const [stickyColumns, setStickyColumns] = React.useState({
29
+ left: {},
30
+ right: {},
25
31
  });
26
32
  // 스크롤 상태 업데이트
27
33
  const updateScrollState = React.useCallback(() => {
@@ -52,41 +58,41 @@ const TableProvider = ({ children }) => {
52
58
  updateScrollState();
53
59
  }
54
60
  }, [updateScrollState]);
55
- // Register a sticky column with its width
61
+ // Register a sticky column with its (measured) width. Rounds to whole pixels
62
+ // and bails when unchanged so the ResizeObserver-driven callers can't
63
+ // ping-pong on sub-pixel differences and spin the render loop.
56
64
  const registerStickyColumn = React.useCallback((direction, index, width) => {
57
- if (direction === 'left') {
58
- stickyColumnsRef.current.leftColumnWidths.set(index, width);
59
- }
60
- else {
61
- stickyColumnsRef.current.rightColumnWidths.set(index, width);
62
- }
65
+ const rounded = Math.round(width);
66
+ setStickyColumns((prev) => {
67
+ const side = prev[direction];
68
+ if (side[index] === rounded)
69
+ return prev;
70
+ return { ...prev, [direction]: { ...side, [index]: rounded } };
71
+ });
63
72
  }, []);
64
73
  // Get the offset for a sticky column based on its index and direction
65
74
  const getStickyOffset = React.useCallback((direction, index) => {
66
75
  if (index === 0)
67
76
  return 0;
68
- const widthsMap = direction === 'left'
69
- ? stickyColumnsRef.current.leftColumnWidths
70
- : stickyColumnsRef.current.rightColumnWidths;
77
+ const widths = stickyColumns[direction];
71
78
  let offset = 0;
72
79
  for (let i = 0; i < index; i++) {
73
- offset += widthsMap.get(i) || 0;
80
+ offset += widths[i] || 0;
74
81
  }
75
82
  return offset;
76
- }, []);
83
+ }, [stickyColumns]);
77
84
  // Check if a column is the last sticky column on its side
78
85
  const isLastStickyColumn = React.useCallback((direction, index) => {
79
- const widthsMap = direction === 'left'
80
- ? stickyColumnsRef.current.leftColumnWidths
81
- : stickyColumnsRef.current.rightColumnWidths;
82
- // Find the highest index in the map
86
+ const widths = stickyColumns[direction];
87
+ // Find the highest registered index on this side
83
88
  let maxIndex = -1;
84
- for (const idx of widthsMap.keys()) {
89
+ for (const key of Object.keys(widths)) {
90
+ const idx = Number(key);
85
91
  if (idx > maxIndex)
86
92
  maxIndex = idx;
87
93
  }
88
94
  return index === maxIndex;
89
- }, []);
95
+ }, [stickyColumns]);
90
96
  // 단일 useEffect에서 모든 이벤트 리스너 관리
91
97
  React.useEffect(() => {
92
98
  const container = containerRef.current;
@@ -1 +1 @@
1
- {"version":3,"file":"TableContext.js","sources":["../../../src/components/Table/TableContext.tsx"],"sourcesContent":[null],"names":["createContext","useContext","useRef","useState","useCallback","useEffect","_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"TableContext.js","sources":["../../../src/components/Table/TableContext.tsx"],"sourcesContent":[null],"names":["createContext","useContext","useRef","useState","useCallback","useEffect","_jsx"],"mappings":"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"}
@@ -17,9 +17,15 @@ const TableProvider = ({ children }) => {
17
17
  isScrollEnd: false,
18
18
  isScrolling: false,
19
19
  });
20
- const stickyColumnsRef = useRef({
21
- leftColumnWidths: new Map(),
22
- rightColumnWidths: new Map(),
20
+ // Column widths live in state (not a ref) so that a width change — a font
21
+ // swap, a window/sidebar resize, or the columns re-flowing when the table
22
+ // goes from fitting to overflowing — triggers a re-render and the sticky
23
+ // offsets are recomputed. Storing them in a ref (the previous approach) meant
24
+ // the offsets were computed once at mount and then went stale, detaching the
25
+ // sticky columns from their real positions.
26
+ const [stickyColumns, setStickyColumns] = useState({
27
+ left: {},
28
+ right: {},
23
29
  });
24
30
  // 스크롤 상태 업데이트
25
31
  const updateScrollState = useCallback(() => {
@@ -50,41 +56,41 @@ const TableProvider = ({ children }) => {
50
56
  updateScrollState();
51
57
  }
52
58
  }, [updateScrollState]);
53
- // Register a sticky column with its width
59
+ // Register a sticky column with its (measured) width. Rounds to whole pixels
60
+ // and bails when unchanged so the ResizeObserver-driven callers can't
61
+ // ping-pong on sub-pixel differences and spin the render loop.
54
62
  const registerStickyColumn = useCallback((direction, index, width) => {
55
- if (direction === 'left') {
56
- stickyColumnsRef.current.leftColumnWidths.set(index, width);
57
- }
58
- else {
59
- stickyColumnsRef.current.rightColumnWidths.set(index, width);
60
- }
63
+ const rounded = Math.round(width);
64
+ setStickyColumns((prev) => {
65
+ const side = prev[direction];
66
+ if (side[index] === rounded)
67
+ return prev;
68
+ return { ...prev, [direction]: { ...side, [index]: rounded } };
69
+ });
61
70
  }, []);
62
71
  // Get the offset for a sticky column based on its index and direction
63
72
  const getStickyOffset = useCallback((direction, index) => {
64
73
  if (index === 0)
65
74
  return 0;
66
- const widthsMap = direction === 'left'
67
- ? stickyColumnsRef.current.leftColumnWidths
68
- : stickyColumnsRef.current.rightColumnWidths;
75
+ const widths = stickyColumns[direction];
69
76
  let offset = 0;
70
77
  for (let i = 0; i < index; i++) {
71
- offset += widthsMap.get(i) || 0;
78
+ offset += widths[i] || 0;
72
79
  }
73
80
  return offset;
74
- }, []);
81
+ }, [stickyColumns]);
75
82
  // Check if a column is the last sticky column on its side
76
83
  const isLastStickyColumn = useCallback((direction, index) => {
77
- const widthsMap = direction === 'left'
78
- ? stickyColumnsRef.current.leftColumnWidths
79
- : stickyColumnsRef.current.rightColumnWidths;
80
- // Find the highest index in the map
84
+ const widths = stickyColumns[direction];
85
+ // Find the highest registered index on this side
81
86
  let maxIndex = -1;
82
- for (const idx of widthsMap.keys()) {
87
+ for (const key of Object.keys(widths)) {
88
+ const idx = Number(key);
83
89
  if (idx > maxIndex)
84
90
  maxIndex = idx;
85
91
  }
86
92
  return index === maxIndex;
87
- }, []);
93
+ }, [stickyColumns]);
88
94
  // 단일 useEffect에서 모든 이벤트 리스너 관리
89
95
  useEffect(() => {
90
96
  const container = containerRef.current;
@@ -1 +1 @@
1
- {"version":3,"file":"TableContext.mjs","sources":["../../../src/components/Table/TableContext.tsx"],"sourcesContent":[null],"names":["_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"TableContext.mjs","sources":["../../../src/components/Table/TableContext.tsx"],"sourcesContent":[null],"names":["_jsx"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Td.d.ts","sourceRoot":"","sources":["../../../src/components/Table/Td.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,eAAO,MAAM,EAAE;yIAaZ,cAAc,GAAG;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE;;CAqHrC,CAAC"}
1
+ {"version":3,"file":"Td.d.ts","sourceRoot":"","sources":["../../../src/components/Table/Td.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAI/C,eAAO,MAAM,EAAE;yIAaZ,cAAc,GAAG;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE;;CAsHrC,CAAC"}
@@ -6,6 +6,7 @@ var React = require('react');
6
6
  var react = require('@chakra-ui/react');
7
7
  var Table_styles = require('./Table.styles.js');
8
8
  var TableContext = require('./TableContext.js');
9
+ var useRegisterStickyWidth = require('./useRegisterStickyWidth.js');
9
10
 
10
11
  const Td = ({ wrap, isSticky = false, stickyDirection = 'left', stickyIndex = 0, _first, style, className, children, onClick, onMouseEnter, onMouseLeave, ...rest }) => {
11
12
  const cellRef = React.useRef(null);
@@ -53,13 +54,14 @@ const Td = ({ wrap, isSticky = false, stickyDirection = 'left', stickyIndex = 0,
53
54
  }, ...htmlProps, children: children }));
54
55
  }
55
56
  const { registerStickyColumn, getStickyOffset, isLastStickyColumn, ...scrollState } = tableContext;
56
- // Update width when element is mounted and dimensions change
57
- React.useEffect(() => {
58
- if (isSticky && cellRef.current) {
59
- const width = cellRef.current.getBoundingClientRect().width;
60
- registerStickyColumn(stickyDirection, stickyIndex, width);
61
- }
62
- }, [isSticky, registerStickyColumn, stickyDirection, stickyIndex]);
57
+ // Keep this column's width registered so the cumulative sticky offsets stay
58
+ // correct across layout changes (font swap, resize, fit -> overflow).
59
+ useRegisterStickyWidth.useRegisterStickyWidth(cellRef, {
60
+ isSticky,
61
+ direction: stickyDirection,
62
+ index: stickyIndex,
63
+ register: registerStickyColumn,
64
+ });
63
65
  // Get the sticky offset based on the column's position
64
66
  const stickyOffset = isSticky
65
67
  ? getStickyOffset(stickyDirection, stickyIndex)
@@ -1 +1 @@
1
- {"version":3,"file":"Td.js","sources":["../../../src/components/Table/Td.tsx"],"sourcesContent":[null],"names":["useRef","useTableContext","useToken","_jsx","useEffect","getStickyStyles","Table"],"mappings":"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"}
1
+ {"version":3,"file":"Td.js","sources":["../../../src/components/Table/Td.tsx"],"sourcesContent":[null],"names":["useRef","useTableContext","useToken","_jsx","useRegisterStickyWidth","getStickyStyles","Table"],"mappings":"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"}
@@ -1,9 +1,10 @@
1
1
  "use client";
2
2
  import { jsx } from 'react/jsx-runtime';
3
- import { useRef, useEffect } from 'react';
3
+ import { useRef } from 'react';
4
4
  import { useToken, Table } from '@chakra-ui/react';
5
5
  import { getStickyStyles } from './Table.styles.mjs';
6
6
  import { useTableContext } from './TableContext.mjs';
7
+ import { useRegisterStickyWidth } from './useRegisterStickyWidth.mjs';
7
8
 
8
9
  const Td = ({ wrap, isSticky = false, stickyDirection = 'left', stickyIndex = 0, _first, style, className, children, onClick, onMouseEnter, onMouseLeave, ...rest }) => {
9
10
  const cellRef = useRef(null);
@@ -51,13 +52,14 @@ const Td = ({ wrap, isSticky = false, stickyDirection = 'left', stickyIndex = 0,
51
52
  }, ...htmlProps, children: children }));
52
53
  }
53
54
  const { registerStickyColumn, getStickyOffset, isLastStickyColumn, ...scrollState } = tableContext;
54
- // Update width when element is mounted and dimensions change
55
- useEffect(() => {
56
- if (isSticky && cellRef.current) {
57
- const width = cellRef.current.getBoundingClientRect().width;
58
- registerStickyColumn(stickyDirection, stickyIndex, width);
59
- }
60
- }, [isSticky, registerStickyColumn, stickyDirection, stickyIndex]);
55
+ // Keep this column's width registered so the cumulative sticky offsets stay
56
+ // correct across layout changes (font swap, resize, fit -> overflow).
57
+ useRegisterStickyWidth(cellRef, {
58
+ isSticky,
59
+ direction: stickyDirection,
60
+ index: stickyIndex,
61
+ register: registerStickyColumn,
62
+ });
61
63
  // Get the sticky offset based on the column's position
62
64
  const stickyOffset = isSticky
63
65
  ? getStickyOffset(stickyDirection, stickyIndex)
@@ -1 +1 @@
1
- {"version":3,"file":"Td.mjs","sources":["../../../src/components/Table/Td.tsx"],"sourcesContent":[null],"names":["_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"Td.mjs","sources":["../../../src/components/Table/Td.tsx"],"sourcesContent":[null],"names":["_jsx"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Th.d.ts","sourceRoot":"","sources":["../../../src/components/Table/Th.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAY,MAAM,kBAAkB,CAAC;AAGnD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,eAAO,MAAM,EAAE,2IAiJd,CAAC"}
1
+ {"version":3,"file":"Th.d.ts","sourceRoot":"","sources":["../../../src/components/Table/Th.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAY,MAAM,kBAAkB,CAAC;AAGnD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAI/C,eAAO,MAAM,EAAE,2IAkJd,CAAC"}
@@ -6,6 +6,7 @@ var React = require('react');
6
6
  var react = require('@chakra-ui/react');
7
7
  var Table_styles = require('./Table.styles.js');
8
8
  var TableContext = require('./TableContext.js');
9
+ var useRegisterStickyWidth = require('./useRegisterStickyWidth.js');
9
10
 
10
11
  const Th = React.forwardRef(({ isSticky = false, stickyDirection = 'left', stickyIndex = 0, style, className, children, onClick, onMouseEnter, onMouseLeave, ...rest }, forwardedRef) => {
11
12
  const tableContext = TableContext.useTableContext();
@@ -49,13 +50,14 @@ const Th = React.forwardRef(({ isSticky = false, stickyDirection = 'left', stick
49
50
  }, ...htmlProps, children: children }));
50
51
  }
51
52
  const { registerStickyColumn, getStickyOffset, isLastStickyColumn, ...scrollState } = tableContext;
52
- // Update width when element is mounted and dimensions change
53
- React.useEffect(() => {
54
- if (isSticky && measureNodeRef.current) {
55
- const width = measureNodeRef.current.getBoundingClientRect().width;
56
- registerStickyColumn(stickyDirection, stickyIndex, width);
57
- }
58
- }, [isSticky, registerStickyColumn, stickyDirection, stickyIndex]);
53
+ // Keep this column's width registered so the cumulative sticky offsets stay
54
+ // correct across layout changes (font swap, resize, fit -> overflow).
55
+ useRegisterStickyWidth.useRegisterStickyWidth(measureNodeRef, {
56
+ isSticky,
57
+ direction: stickyDirection,
58
+ index: stickyIndex,
59
+ register: registerStickyColumn,
60
+ });
59
61
  // Combine refs (forwarded ref and internal ref)
60
62
  const setRefs = React.useCallback((node) => {
61
63
  // Set internal ref
@@ -1 +1 @@
1
- {"version":3,"file":"Th.js","sources":["../../../src/components/Table/Th.tsx"],"sourcesContent":[null],"names":["forwardRef","useTableContext","useRef","useToken","useCallback","_jsx","useEffect","getStickyStyles","Table"],"mappings":"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"}
1
+ {"version":3,"file":"Th.js","sources":["../../../src/components/Table/Th.tsx"],"sourcesContent":[null],"names":["forwardRef","useTableContext","useRef","useToken","useCallback","_jsx","useRegisterStickyWidth","getStickyStyles","Table"],"mappings":"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"}
@@ -1,9 +1,10 @@
1
1
  "use client";
2
2
  import { jsx } from 'react/jsx-runtime';
3
- import { forwardRef, useRef, useCallback, useEffect } from 'react';
3
+ import { forwardRef, useRef, useCallback } from 'react';
4
4
  import { useToken, Table } from '@chakra-ui/react';
5
5
  import { getStickyStyles } from './Table.styles.mjs';
6
6
  import { useTableContext } from './TableContext.mjs';
7
+ import { useRegisterStickyWidth } from './useRegisterStickyWidth.mjs';
7
8
 
8
9
  const Th = forwardRef(({ isSticky = false, stickyDirection = 'left', stickyIndex = 0, style, className, children, onClick, onMouseEnter, onMouseLeave, ...rest }, forwardedRef) => {
9
10
  const tableContext = useTableContext();
@@ -47,13 +48,14 @@ const Th = forwardRef(({ isSticky = false, stickyDirection = 'left', stickyIndex
47
48
  }, ...htmlProps, children: children }));
48
49
  }
49
50
  const { registerStickyColumn, getStickyOffset, isLastStickyColumn, ...scrollState } = tableContext;
50
- // Update width when element is mounted and dimensions change
51
- useEffect(() => {
52
- if (isSticky && measureNodeRef.current) {
53
- const width = measureNodeRef.current.getBoundingClientRect().width;
54
- registerStickyColumn(stickyDirection, stickyIndex, width);
55
- }
56
- }, [isSticky, registerStickyColumn, stickyDirection, stickyIndex]);
51
+ // Keep this column's width registered so the cumulative sticky offsets stay
52
+ // correct across layout changes (font swap, resize, fit -> overflow).
53
+ useRegisterStickyWidth(measureNodeRef, {
54
+ isSticky,
55
+ direction: stickyDirection,
56
+ index: stickyIndex,
57
+ register: registerStickyColumn,
58
+ });
57
59
  // Combine refs (forwarded ref and internal ref)
58
60
  const setRefs = useCallback((node) => {
59
61
  // Set internal ref
@@ -1 +1 @@
1
- {"version":3,"file":"Th.mjs","sources":["../../../src/components/Table/Th.tsx"],"sourcesContent":[null],"names":["_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"Th.mjs","sources":["../../../src/components/Table/Th.tsx"],"sourcesContent":[null],"names":["_jsx"],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { RefObject } from 'react';
2
+ import { StickyDirection } from './Table.styles';
3
+ interface UseRegisterStickyWidthOptions {
4
+ isSticky: boolean;
5
+ direction: StickyDirection;
6
+ index: number;
7
+ register: (direction: StickyDirection, index: number, width: number) => void;
8
+ }
9
+ /**
10
+ * Keep a sticky cell's measured width registered with the table context.
11
+ *
12
+ * Unlike a mount-only measurement, this observes the cell with a
13
+ * `ResizeObserver`, so the width stays correct through later layout changes —
14
+ * a web-font swap that reflows the text, a window/sidebar resize, or the
15
+ * columns shrinking when the table goes from fitting its container to
16
+ * overflowing it. Without this, the cumulative sticky offsets are computed once
17
+ * from stale widths and the pinned columns visibly detach (an empty gap opens
18
+ * between them and neighbouring columns collapse).
19
+ *
20
+ * `getBoundingClientRect().width` is read inside the callback so the value is
21
+ * always the border-box width the offset maths expects.
22
+ */
23
+ export declare function useRegisterStickyWidth(ref: RefObject<HTMLTableCellElement | null>, { isSticky, direction, index, register }: UseRegisterStickyWidthOptions): void;
24
+ export {};
25
+ //# sourceMappingURL=useRegisterStickyWidth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRegisterStickyWidth.d.ts","sourceRoot":"","sources":["../../../src/components/Table/useRegisterStickyWidth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAa,MAAM,OAAO,CAAC;AAE7C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,UAAU,6BAA6B;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,eAAe,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,SAAS,CAAC,oBAAoB,GAAG,IAAI,CAAC,EAC3C,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,6BAA6B,QAiBxE"}
@@ -0,0 +1,37 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var React = require('react');
5
+
6
+ /**
7
+ * Keep a sticky cell's measured width registered with the table context.
8
+ *
9
+ * Unlike a mount-only measurement, this observes the cell with a
10
+ * `ResizeObserver`, so the width stays correct through later layout changes —
11
+ * a web-font swap that reflows the text, a window/sidebar resize, or the
12
+ * columns shrinking when the table goes from fitting its container to
13
+ * overflowing it. Without this, the cumulative sticky offsets are computed once
14
+ * from stale widths and the pinned columns visibly detach (an empty gap opens
15
+ * between them and neighbouring columns collapse).
16
+ *
17
+ * `getBoundingClientRect().width` is read inside the callback so the value is
18
+ * always the border-box width the offset maths expects.
19
+ */
20
+ function useRegisterStickyWidth(ref, { isSticky, direction, index, register }) {
21
+ React.useEffect(() => {
22
+ const node = ref.current;
23
+ if (!isSticky || !node)
24
+ return;
25
+ register(direction, index, node.getBoundingClientRect().width);
26
+ if (typeof ResizeObserver === 'undefined')
27
+ return;
28
+ const observer = new ResizeObserver(() => {
29
+ register(direction, index, node.getBoundingClientRect().width);
30
+ });
31
+ observer.observe(node);
32
+ return () => observer.disconnect();
33
+ }, [ref, isSticky, direction, index, register]);
34
+ }
35
+
36
+ exports.useRegisterStickyWidth = useRegisterStickyWidth;
37
+ //# sourceMappingURL=useRegisterStickyWidth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRegisterStickyWidth.js","sources":["../../../src/components/Table/useRegisterStickyWidth.ts"],"sourcesContent":[null],"names":["useEffect"],"mappings":";;;;;AAWA;;;;;;;;;;;;;AAaG;AACG,SAAU,sBAAsB,CACpC,GAA2C,EAC3C,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAiC,EAAA;IAEvEA,eAAS,CAAC,MAAK;AACb,QAAA,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO;AACxB,QAAA,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI;YAAE;AAExB,QAAA,QAAQ,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC;QAE9D,IAAI,OAAO,cAAc,KAAK,WAAW;YAAE;AAE3C,QAAA,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,MAAK;AACvC,YAAA,QAAQ,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC;AAChE,QAAA,CAAC,CAAC;AACF,QAAA,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;AAEtB,QAAA,OAAO,MAAM,QAAQ,CAAC,UAAU,EAAE;AACpC,IAAA,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;AACjD;;;;"}
@@ -0,0 +1,35 @@
1
+ "use client";
2
+ import { useEffect } from 'react';
3
+
4
+ /**
5
+ * Keep a sticky cell's measured width registered with the table context.
6
+ *
7
+ * Unlike a mount-only measurement, this observes the cell with a
8
+ * `ResizeObserver`, so the width stays correct through later layout changes —
9
+ * a web-font swap that reflows the text, a window/sidebar resize, or the
10
+ * columns shrinking when the table goes from fitting its container to
11
+ * overflowing it. Without this, the cumulative sticky offsets are computed once
12
+ * from stale widths and the pinned columns visibly detach (an empty gap opens
13
+ * between them and neighbouring columns collapse).
14
+ *
15
+ * `getBoundingClientRect().width` is read inside the callback so the value is
16
+ * always the border-box width the offset maths expects.
17
+ */
18
+ function useRegisterStickyWidth(ref, { isSticky, direction, index, register }) {
19
+ useEffect(() => {
20
+ const node = ref.current;
21
+ if (!isSticky || !node)
22
+ return;
23
+ register(direction, index, node.getBoundingClientRect().width);
24
+ if (typeof ResizeObserver === 'undefined')
25
+ return;
26
+ const observer = new ResizeObserver(() => {
27
+ register(direction, index, node.getBoundingClientRect().width);
28
+ });
29
+ observer.observe(node);
30
+ return () => observer.disconnect();
31
+ }, [ref, isSticky, direction, index, register]);
32
+ }
33
+
34
+ export { useRegisterStickyWidth };
35
+ //# sourceMappingURL=useRegisterStickyWidth.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRegisterStickyWidth.mjs","sources":["../../../src/components/Table/useRegisterStickyWidth.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAWA;;;;;;;;;;;;;AAaG;AACG,SAAU,sBAAsB,CACpC,GAA2C,EAC3C,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAiC,EAAA;IAEvE,SAAS,CAAC,MAAK;AACb,QAAA,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO;AACxB,QAAA,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI;YAAE;AAExB,QAAA,QAAQ,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC;QAE9D,IAAI,OAAO,cAAc,KAAK,WAAW;YAAE;AAE3C,QAAA,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,MAAK;AACvC,YAAA,QAAQ,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC;AAChE,QAAA,CAAC,CAAC;AACF,QAAA,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;AAEtB,QAAA,OAAO,MAAM,QAAQ,CAAC,UAAU,EAAE;AACpC,IAAA,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;AACjD;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindlogic-ai/logician-ui",
3
- "version": "4.0.0-alpha.18",
3
+ "version": "4.0.0-alpha.19",
4
4
  "description": "A comprehensive React design system built on Chakra UI",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -12,6 +12,7 @@ import {
12
12
  Thead,
13
13
  Tr,
14
14
  } from '.';
15
+ import { Button } from '../Button';
15
16
  import { IoChevronDownOutline } from '../Icon';
16
17
  import { IconButton } from '../IconButton';
17
18
 
@@ -430,3 +431,255 @@ export const WithTwoLeftStickyColumns: Story = {
430
431
  args: { width: '180%' },
431
432
  argTypes: {},
432
433
  };
434
+
435
+ // Three consecutive left-pinned columns + one right-pinned column — the shape of
436
+ // the admin 챗봇 공개 관리 / 전체 멤버 tables (checkbox · name · status pinned
437
+ // left, an action column pinned right, many trailing columns scrolling between).
438
+ const adminColumns: { key: string; label: string }[] = [
439
+ { key: 'check', label: '' },
440
+ { key: 'name', label: '이름' },
441
+ { key: 'status', label: '상태' },
442
+ { key: 'email', label: '이메일' },
443
+ { key: 'phone', label: '전화번호' },
444
+ { key: 'address', label: '주소' },
445
+ { key: 'company', label: '회사' },
446
+ { key: 'department', label: '부서' },
447
+ { key: 'action', label: '' },
448
+ ];
449
+
450
+ const LEFT_STICKY = new Set([0, 1, 2]);
451
+ const RIGHT_STICKY = adminColumns.length - 1;
452
+
453
+ const adminRow = (
454
+ i: number,
455
+ name: string,
456
+ status: string
457
+ ): Record<string, string> => ({
458
+ check: `${i + 1}`,
459
+ name,
460
+ status,
461
+ email: `user${i + 1}@example.com`,
462
+ phone: '010-1234-5678',
463
+ address: '서울특별시 강남구 테헤란로 123',
464
+ company: '테크 주식회사',
465
+ department: '프론트엔드 팀',
466
+ action: '⋯',
467
+ });
468
+
469
+ /**
470
+ * Multiple left-pinned columns kept flush during horizontal scroll — the admin
471
+ * table layout that surfaced the offset bug. Scroll sideways: the three left
472
+ * columns and the right action column stay pinned and opaque, with the middle
473
+ * columns scrolling underneath.
474
+ */
475
+ export const WithMultipleLeftStickyColumns: Story = {
476
+ render: (args) => {
477
+ const rows = [
478
+ adminRow(0, '김철수', '승인됨'),
479
+ adminRow(1, '이영희', '검토중'),
480
+ adminRow(2, '박지훈', '거절됨'),
481
+ ];
482
+ return (
483
+ <TableContainer>
484
+ <Table {...args}>
485
+ <Thead>
486
+ <Tr>
487
+ {adminColumns.map((column, index) => (
488
+ <Th
489
+ key={column.key}
490
+ isSticky={LEFT_STICKY.has(index) || index === RIGHT_STICKY}
491
+ stickyDirection={index === RIGHT_STICKY ? 'right' : 'left'}
492
+ stickyIndex={index === RIGHT_STICKY ? 0 : index}
493
+ >
494
+ {column.label}
495
+ </Th>
496
+ ))}
497
+ </Tr>
498
+ </Thead>
499
+ <Tbody>
500
+ {rows.map((item, i) => (
501
+ <Tr key={i}>
502
+ {adminColumns.map((column, index) => (
503
+ <Td
504
+ key={column.key}
505
+ isSticky={LEFT_STICKY.has(index) || index === RIGHT_STICKY}
506
+ stickyDirection={index === RIGHT_STICKY ? 'right' : 'left'}
507
+ stickyIndex={index === RIGHT_STICKY ? 0 : index}
508
+ >
509
+ {item[column.key]}
510
+ </Td>
511
+ ))}
512
+ </Tr>
513
+ ))}
514
+ </Tbody>
515
+ </Table>
516
+ </TableContainer>
517
+ );
518
+ },
519
+ args: { width: '220%' },
520
+ argTypes: {},
521
+ };
522
+
523
+ /**
524
+ * Regression coverage for the admin 챗봇 공개 관리 / 전체 멤버 breakage.
525
+ *
526
+ * The pinned columns' cumulative offsets used to be measured once at mount and
527
+ * then frozen, so when a column's width changed afterwards — a web-font swap, a
528
+ * resize, pagination swapping in wider content, or the columns reflowing as the
529
+ * table went from fitting to overflowing — the following pinned columns stayed
530
+ * at the stale offsets and visibly detached (an empty gap opened between them).
531
+ *
532
+ * Toggle the button: the second pinned column ("이름") grows/shrinks its
533
+ * content, so the third pinned column ("상태") must re-pin to the new edge. It
534
+ * has to stay flush — no empty gap, no overlap. Before the ResizeObserver fix a
535
+ * gap appeared here after toggling.
536
+ */
537
+ export const StickyOffsetsTrackWidthChanges: Story = {
538
+ render: (args) => {
539
+ const [long, setLong] = useState(false);
540
+ const longName = '아주 아주 긴 이름 콘텐츠로 컬럼 폭을 넓힙니다';
541
+ const rows = [
542
+ adminRow(0, long ? `김철수 — ${longName}` : '김철수', '승인됨'),
543
+ adminRow(1, long ? `이영희 — ${longName}` : '이영희', '검토중'),
544
+ adminRow(2, long ? `박지훈 — ${longName}` : '박지훈', '거절됨'),
545
+ ];
546
+ return (
547
+ <Flex direction="column" gap={3} align="start">
548
+ <Button onClick={() => setLong((v) => !v)}>
549
+ {long ? '이름 컬럼 짧게' : '이름 컬럼 길게 (폭 변경)'}
550
+ </Button>
551
+ <TableContainer>
552
+ <Table {...args}>
553
+ <Thead>
554
+ <Tr>
555
+ {adminColumns.map((column, index) => (
556
+ <Th
557
+ key={column.key}
558
+ isSticky={LEFT_STICKY.has(index) || index === RIGHT_STICKY}
559
+ stickyDirection={index === RIGHT_STICKY ? 'right' : 'left'}
560
+ stickyIndex={index === RIGHT_STICKY ? 0 : index}
561
+ >
562
+ {column.label}
563
+ </Th>
564
+ ))}
565
+ </Tr>
566
+ </Thead>
567
+ <Tbody>
568
+ {rows.map((item, i) => (
569
+ <Tr key={i}>
570
+ {adminColumns.map((column, index) => (
571
+ <Td
572
+ key={column.key}
573
+ isSticky={LEFT_STICKY.has(index) || index === RIGHT_STICKY}
574
+ stickyDirection={index === RIGHT_STICKY ? 'right' : 'left'}
575
+ stickyIndex={index === RIGHT_STICKY ? 0 : index}
576
+ >
577
+ {item[column.key]}
578
+ </Td>
579
+ ))}
580
+ </Tr>
581
+ ))}
582
+ </Tbody>
583
+ </Table>
584
+ </TableContainer>
585
+ </Flex>
586
+ );
587
+ },
588
+ args: { width: '220%' },
589
+ argTypes: {},
590
+ };
591
+
592
+ // Pages whose pinned "이름" column has a different natural width each page — the
593
+ // real admin case, where paging swaps in rows of different content lengths.
594
+ const PAGES: { name: string; status: string }[][] = [
595
+ [
596
+ { name: '김철수', status: '승인됨' },
597
+ { name: '이영희', status: '검토중' },
598
+ { name: '박지훈', status: '거절됨' },
599
+ ],
600
+ [
601
+ { name: '남궁민수 — 아주 아주 길어서 컬럼을 넓히는 이름', status: '승인됨' },
602
+ { name: '황보지훈 — 아주 아주 길어서 컬럼을 넓히는 이름', status: '승인됨' },
603
+ { name: '독고영희 — 아주 아주 길어서 컬럼을 넓히는 이름', status: '검토중' },
604
+ ],
605
+ [
606
+ { name: '최민', status: '거절됨' },
607
+ { name: '한수', status: '승인됨' },
608
+ { name: '오지', status: '검토중' },
609
+ ],
610
+ ];
611
+
612
+ /**
613
+ * Regression coverage for the exact admin-page symptom: **pagination didn't
614
+ * re-pin the sticky columns.**
615
+ *
616
+ * Paging swaps only the `<tbody>` rows while the `<thead>` (and its Th cells)
617
+ * stay mounted. Each page here has a different-width pinned "이름" column. The
618
+ * old engine measured the pinned widths once and only recalculated on a
619
+ * scroll/resize event — which paging doesn't fire — so pages 2/3 rendered
620
+ * pinned to page 1's widths and the following columns overlapped. Step through
621
+ * the pages: the "상태" column must stay flush against "이름" on every page.
622
+ */
623
+ export const StickyOffsetsSurvivePagination: Story = {
624
+ render: (args) => {
625
+ const [page, setPage] = useState(0);
626
+ const rows = PAGES[page].map((r, i) => adminRow(i, r.name, r.status));
627
+ return (
628
+ <Flex direction="column" gap={3} align="start">
629
+ <Flex gap={2} align="center">
630
+ <Button
631
+ variant="outline"
632
+ disabled={page === 0}
633
+ onClick={() => setPage((p) => Math.max(0, p - 1))}
634
+ >
635
+ 이전
636
+ </Button>
637
+ <span>{page + 1} / {PAGES.length} 페이지</span>
638
+ <Button
639
+ variant="outline"
640
+ disabled={page === PAGES.length - 1}
641
+ onClick={() => setPage((p) => Math.min(PAGES.length - 1, p + 1))}
642
+ >
643
+ 다음
644
+ </Button>
645
+ </Flex>
646
+ <TableContainer>
647
+ <Table {...args}>
648
+ <Thead>
649
+ <Tr>
650
+ {adminColumns.map((column, index) => (
651
+ <Th
652
+ key={column.key}
653
+ isSticky={LEFT_STICKY.has(index) || index === RIGHT_STICKY}
654
+ stickyDirection={index === RIGHT_STICKY ? 'right' : 'left'}
655
+ stickyIndex={index === RIGHT_STICKY ? 0 : index}
656
+ >
657
+ {column.label}
658
+ </Th>
659
+ ))}
660
+ </Tr>
661
+ </Thead>
662
+ <Tbody>
663
+ {rows.map((item, i) => (
664
+ <Tr key={i}>
665
+ {adminColumns.map((column, index) => (
666
+ <Td
667
+ key={column.key}
668
+ isSticky={LEFT_STICKY.has(index) || index === RIGHT_STICKY}
669
+ stickyDirection={index === RIGHT_STICKY ? 'right' : 'left'}
670
+ stickyIndex={index === RIGHT_STICKY ? 0 : index}
671
+ >
672
+ {item[column.key]}
673
+ </Td>
674
+ ))}
675
+ </Tr>
676
+ ))}
677
+ </Tbody>
678
+ </Table>
679
+ </TableContainer>
680
+ </Flex>
681
+ );
682
+ },
683
+ args: { width: '220%' },
684
+ argTypes: {},
685
+ };
@@ -14,9 +14,11 @@ export interface TableScrollState {
14
14
  isScrolling: boolean;
15
15
  }
16
16
 
17
+ type ColumnWidths = Record<number, number>; // Maps index to width
18
+
17
19
  interface StickyColumnInfo {
18
- leftColumnWidths: Map<number, number>; // Maps index to width
19
- rightColumnWidths: Map<number, number>; // Maps index to width
20
+ left: ColumnWidths;
21
+ right: ColumnWidths;
20
22
  }
21
23
 
22
24
  interface TableContextValue extends TableScrollState {
@@ -52,9 +54,15 @@ export const TableProvider: React.FC<TableProviderProps> = ({ children }) => {
52
54
  isScrolling: false,
53
55
  });
54
56
 
55
- const stickyColumnsRef = useRef<StickyColumnInfo>({
56
- leftColumnWidths: new Map(),
57
- rightColumnWidths: new Map(),
57
+ // Column widths live in state (not a ref) so that a width change — a font
58
+ // swap, a window/sidebar resize, or the columns re-flowing when the table
59
+ // goes from fitting to overflowing — triggers a re-render and the sticky
60
+ // offsets are recomputed. Storing them in a ref (the previous approach) meant
61
+ // the offsets were computed once at mount and then went stale, detaching the
62
+ // sticky columns from their real positions.
63
+ const [stickyColumns, setStickyColumns] = useState<StickyColumnInfo>({
64
+ left: {},
65
+ right: {},
58
66
  });
59
67
 
60
68
  // 스크롤 상태 업데이트
@@ -95,14 +103,17 @@ export const TableProvider: React.FC<TableProviderProps> = ({ children }) => {
95
103
  [updateScrollState]
96
104
  );
97
105
 
98
- // Register a sticky column with its width
106
+ // Register a sticky column with its (measured) width. Rounds to whole pixels
107
+ // and bails when unchanged so the ResizeObserver-driven callers can't
108
+ // ping-pong on sub-pixel differences and spin the render loop.
99
109
  const registerStickyColumn = useCallback(
100
110
  (direction: 'left' | 'right', index: number, width: number) => {
101
- if (direction === 'left') {
102
- stickyColumnsRef.current.leftColumnWidths.set(index, width);
103
- } else {
104
- stickyColumnsRef.current.rightColumnWidths.set(index, width);
105
- }
111
+ const rounded = Math.round(width);
112
+ setStickyColumns((prev) => {
113
+ const side = prev[direction];
114
+ if (side[index] === rounded) return prev;
115
+ return { ...prev, [direction]: { ...side, [index]: rounded } };
116
+ });
106
117
  },
107
118
  []
108
119
  );
@@ -112,38 +123,33 @@ export const TableProvider: React.FC<TableProviderProps> = ({ children }) => {
112
123
  (direction: 'left' | 'right', index: number) => {
113
124
  if (index === 0) return 0;
114
125
 
115
- const widthsMap =
116
- direction === 'left'
117
- ? stickyColumnsRef.current.leftColumnWidths
118
- : stickyColumnsRef.current.rightColumnWidths;
126
+ const widths = stickyColumns[direction];
119
127
 
120
128
  let offset = 0;
121
129
  for (let i = 0; i < index; i++) {
122
- offset += widthsMap.get(i) || 0;
130
+ offset += widths[i] || 0;
123
131
  }
124
132
 
125
133
  return offset;
126
134
  },
127
- []
135
+ [stickyColumns]
128
136
  );
129
137
 
130
138
  // Check if a column is the last sticky column on its side
131
139
  const isLastStickyColumn = useCallback(
132
140
  (direction: 'left' | 'right', index: number) => {
133
- const widthsMap =
134
- direction === 'left'
135
- ? stickyColumnsRef.current.leftColumnWidths
136
- : stickyColumnsRef.current.rightColumnWidths;
141
+ const widths = stickyColumns[direction];
137
142
 
138
- // Find the highest index in the map
143
+ // Find the highest registered index on this side
139
144
  let maxIndex = -1;
140
- for (const idx of widthsMap.keys()) {
145
+ for (const key of Object.keys(widths)) {
146
+ const idx = Number(key);
141
147
  if (idx > maxIndex) maxIndex = idx;
142
148
  }
143
149
 
144
150
  return index === maxIndex;
145
151
  },
146
- []
152
+ [stickyColumns]
147
153
  );
148
154
 
149
155
  // 단일 useEffect에서 모든 이벤트 리스너 관리
@@ -1,9 +1,10 @@
1
- import { useEffect, useRef } from 'react';
1
+ import { useRef } from 'react';
2
2
  import { Table, useToken } from '@chakra-ui/react';
3
3
 
4
4
  import { getStickyStyles } from './Table.styles';
5
5
  import { TableCellProps } from './Table.types';
6
6
  import { useTableContext } from './TableContext';
7
+ import { useRegisterStickyWidth } from './useRegisterStickyWidth';
7
8
 
8
9
  export const Td = ({
9
10
  wrap,
@@ -82,13 +83,14 @@ export const Td = ({
82
83
  ...scrollState
83
84
  } = tableContext;
84
85
 
85
- // Update width when element is mounted and dimensions change
86
- useEffect(() => {
87
- if (isSticky && cellRef.current) {
88
- const width = cellRef.current.getBoundingClientRect().width;
89
- registerStickyColumn(stickyDirection, stickyIndex, width);
90
- }
91
- }, [isSticky, registerStickyColumn, stickyDirection, stickyIndex]);
86
+ // Keep this column's width registered so the cumulative sticky offsets stay
87
+ // correct across layout changes (font swap, resize, fit -> overflow).
88
+ useRegisterStickyWidth(cellRef, {
89
+ isSticky,
90
+ direction: stickyDirection,
91
+ index: stickyIndex,
92
+ register: registerStickyColumn,
93
+ });
92
94
 
93
95
  // Get the sticky offset based on the column's position
94
96
  const stickyOffset = isSticky
@@ -1,9 +1,10 @@
1
- import { forwardRef, useCallback, useEffect, useRef } from 'react';
1
+ import { forwardRef, useCallback, useRef } from 'react';
2
2
  import { Table, useToken } from '@chakra-ui/react';
3
3
 
4
4
  import { getStickyStyles } from './Table.styles';
5
5
  import { TableCellProps } from './Table.types';
6
6
  import { useTableContext } from './TableContext';
7
+ import { useRegisterStickyWidth } from './useRegisterStickyWidth';
7
8
 
8
9
  export const Th = forwardRef<
9
10
  HTMLTableCellElement,
@@ -86,13 +87,14 @@ export const Th = forwardRef<
86
87
  ...scrollState
87
88
  } = tableContext;
88
89
 
89
- // Update width when element is mounted and dimensions change
90
- useEffect(() => {
91
- if (isSticky && measureNodeRef.current) {
92
- const width = measureNodeRef.current.getBoundingClientRect().width;
93
- registerStickyColumn(stickyDirection, stickyIndex, width);
94
- }
95
- }, [isSticky, registerStickyColumn, stickyDirection, stickyIndex]);
90
+ // Keep this column's width registered so the cumulative sticky offsets stay
91
+ // correct across layout changes (font swap, resize, fit -> overflow).
92
+ useRegisterStickyWidth(measureNodeRef, {
93
+ isSticky,
94
+ direction: stickyDirection,
95
+ index: stickyIndex,
96
+ register: registerStickyColumn,
97
+ });
96
98
 
97
99
  // Combine refs (forwarded ref and internal ref)
98
100
  const setRefs = useCallback(
@@ -0,0 +1,45 @@
1
+ import { RefObject, useEffect } from 'react';
2
+
3
+ import { StickyDirection } from './Table.styles';
4
+
5
+ interface UseRegisterStickyWidthOptions {
6
+ isSticky: boolean;
7
+ direction: StickyDirection;
8
+ index: number;
9
+ register: (direction: StickyDirection, index: number, width: number) => void;
10
+ }
11
+
12
+ /**
13
+ * Keep a sticky cell's measured width registered with the table context.
14
+ *
15
+ * Unlike a mount-only measurement, this observes the cell with a
16
+ * `ResizeObserver`, so the width stays correct through later layout changes —
17
+ * a web-font swap that reflows the text, a window/sidebar resize, or the
18
+ * columns shrinking when the table goes from fitting its container to
19
+ * overflowing it. Without this, the cumulative sticky offsets are computed once
20
+ * from stale widths and the pinned columns visibly detach (an empty gap opens
21
+ * between them and neighbouring columns collapse).
22
+ *
23
+ * `getBoundingClientRect().width` is read inside the callback so the value is
24
+ * always the border-box width the offset maths expects.
25
+ */
26
+ export function useRegisterStickyWidth(
27
+ ref: RefObject<HTMLTableCellElement | null>,
28
+ { isSticky, direction, index, register }: UseRegisterStickyWidthOptions
29
+ ) {
30
+ useEffect(() => {
31
+ const node = ref.current;
32
+ if (!isSticky || !node) return;
33
+
34
+ register(direction, index, node.getBoundingClientRect().width);
35
+
36
+ if (typeof ResizeObserver === 'undefined') return;
37
+
38
+ const observer = new ResizeObserver(() => {
39
+ register(direction, index, node.getBoundingClientRect().width);
40
+ });
41
+ observer.observe(node);
42
+
43
+ return () => observer.disconnect();
44
+ }, [ref, isSticky, direction, index, register]);
45
+ }