@ceed/cds 1.5.6 → 1.5.7

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
@@ -3037,7 +3037,9 @@ var StyledTh = (0, import_joy33.styled)(import_framer_motion21.motion.th)(({ the
3037
3037
  }));
3038
3038
  var StyledTd = (0, import_joy33.styled)("td")(({ theme }) => ({
3039
3039
  transition: `box-shadow 0.3s`,
3040
- boxShadow: "1px 0 var(--TableCell-borderColor)",
3040
+ "&:not(.is-last-left):not(.is-last-right)": {
3041
+ boxShadow: "1px 0 var(--TableCell-borderColor)"
3042
+ },
3041
3043
  ".ScrollableRight &": {
3042
3044
  "&.is-last-left": {
3043
3045
  boxShadow: `1px 0 var(--TableCell-borderColor), ${theme.shadow.md}`
@@ -3372,6 +3374,7 @@ var BodyCell = (props) => {
3372
3374
  () => noWrap && type === "longText",
3373
3375
  [noWrap, type]
3374
3376
  );
3377
+ const isBoundary = props.isLastStartPinnedColumn || props.isLastEndPinnedColumn;
3375
3378
  (0, import_react25.useEffect)(() => {
3376
3379
  setValue(row[field]);
3377
3380
  }, [row, field]);
@@ -3387,7 +3390,7 @@ var BodyCell = (props) => {
3387
3390
  position: isPinned ? "sticky" : void 0,
3388
3391
  left: isPinned ? pinnedStartPosition : void 0,
3389
3392
  right: isPinned ? pinnedEndPosition : void 0,
3390
- zIndex: isPinned ? `calc(${theme.getCssVar("zIndex-table")} + 2)` : void 0,
3393
+ zIndex: isPinned ? `calc(${theme.getCssVar("zIndex-table")} + ${isBoundary ? 2 : 3})` : void 0,
3391
3394
  "--TableCell-dataBackground": isPinned ? `var(--TableCell-headBackground)` : void 0
3392
3395
  },
3393
3396
  className: isLastStartPinnedColumn && "is-last-left" || isLastEndPinnedColumn && "is-last-right" || ""
@@ -3434,6 +3437,37 @@ var BodyRow = (0, import_react25.memo)(
3434
3437
  )));
3435
3438
  }
3436
3439
  );
3440
+ function useColumnWidths(columnsByField) {
3441
+ const [widths, setWidths] = (0, import_react25.useState)({});
3442
+ const roRef = (0, import_react25.useRef)();
3443
+ (0, import_react25.useLayoutEffect)(() => {
3444
+ if (roRef.current) roRef.current.disconnect();
3445
+ roRef.current = new ResizeObserver((entries) => {
3446
+ let changed = false;
3447
+ setWidths((prev) => {
3448
+ const next = { ...prev };
3449
+ entries.forEach((entry) => {
3450
+ const field = entry.target.dataset.field;
3451
+ const w = Math.round(entry.contentRect.width);
3452
+ if (next[field] !== w) {
3453
+ next[field] = w;
3454
+ changed = true;
3455
+ }
3456
+ });
3457
+ return changed ? next : prev;
3458
+ });
3459
+ });
3460
+ Object.entries(columnsByField).forEach(([field, def]) => {
3461
+ const el = def.headerRef.current;
3462
+ if (el) {
3463
+ el.dataset.field = field;
3464
+ roRef.current.observe(el);
3465
+ }
3466
+ });
3467
+ return () => roRef.current?.disconnect();
3468
+ }, [columnsByField]);
3469
+ return widths;
3470
+ }
3437
3471
  function useDataTableRenderer({
3438
3472
  rows: _rows,
3439
3473
  columns: columnsProp,
@@ -3536,6 +3570,12 @@ function useDataTableRenderer({
3536
3570
  () => _isTotalSelected ?? (rowCount > 0 && (selectionModel?.length || 0) === rowCount),
3537
3571
  [_isTotalSelected, selectionModel, rowCount]
3538
3572
  );
3573
+ const columnWidths = useColumnWidths(columnsByField);
3574
+ const getWidth = (0, import_react25.useCallback)(
3575
+ (f) => (columnWidths[f] ?? columnsByField[f].width ?? // Column prop 으로 지정된 width
3576
+ columnsByField[f].minWidth ?? 0) + columnsProp.length,
3577
+ [columnWidths, columnsByField, columnsProp.length]
3578
+ );
3539
3579
  const columns = (0, import_react25.useMemo)(() => {
3540
3580
  const baseColumns = columnsProp || // fallback
3541
3581
  Object.keys(rows[0] || {}).map((key) => ({
@@ -3557,32 +3597,27 @@ function useDataTableRenderer({
3557
3597
  sortOrder: columnsByField[column.field]?.sortOrder || sortOrder,
3558
3598
  isPinned,
3559
3599
  isLastStartPinnedColumn: isLeftPinned && [...pinnedColumns?.left || []].pop() === column.field,
3560
- isLastEndPinnedColumn: isRightPinned && [...pinnedColumns?.right || []].pop() === column.field,
3600
+ isLastEndPinnedColumn: isRightPinned && (pinnedColumns?.right?.[0] ?? null) === column.field,
3601
+ // pinned 관련 계산부
3561
3602
  pinnedStartPosition: pinnedColumns?.left?.slice(
3562
3603
  0,
3563
- isLeftPinned ? pinnedColumns?.left?.indexOf(column.field) : pinnedColumns.left.length
3564
- ).reduce(
3565
- (acc, curr) => acc + (columnsByField[curr]?.headerRef.current?.clientWidth || 0),
3566
- 0
3567
- ),
3604
+ isLeftPinned ? pinnedColumns.left.indexOf(column.field) : pinnedColumns.left.length
3605
+ ).reduce((acc, curr) => acc + getWidth(curr), 0),
3568
3606
  pinnedEndPosition: pinnedColumns?.right?.slice(
3569
- 0,
3570
- isRightPinned ? pinnedColumns.right.indexOf(column.field) : pinnedColumns.right.length
3571
- ).reduceRight(
3572
- (acc, curr) => acc + (columnsByField[curr]?.headerRef.current?.clientWidth || 0),
3573
- 0
3574
- )
3607
+ isRightPinned ? pinnedColumns.right.indexOf(column.field) + 1 : 0
3608
+ ).reduce((acc, curr) => acc + getWidth(curr), 0)
3575
3609
  };
3576
3610
  });
3577
3611
  }, [
3578
3612
  columnsProp,
3579
3613
  rows,
3614
+ pinnedColumns?.left,
3615
+ pinnedColumns?.right,
3616
+ columnsByField,
3580
3617
  editMode,
3581
3618
  sortModel,
3582
- columnsByField,
3583
3619
  sortOrder,
3584
- pinnedColumns?.left,
3585
- pinnedColumns?.right
3620
+ getWidth
3586
3621
  ]);
3587
3622
  const handlePageChange = (0, import_react25.useCallback)(
3588
3623
  (newPage) => {
package/dist/index.js CHANGED
@@ -2022,7 +2022,8 @@ import React23, {
2022
2022
  forwardRef as forwardRef7,
2023
2023
  useImperativeHandle as useImperativeHandle2,
2024
2024
  createElement,
2025
- memo
2025
+ memo,
2026
+ useLayoutEffect
2026
2027
  } from "react";
2027
2028
  import { useVirtualizer as useVirtualizer2 } from "@tanstack/react-virtual";
2028
2029
  import {
@@ -3005,7 +3006,9 @@ var StyledTh = styled12(motion21.th)(({ theme }) => ({
3005
3006
  }));
3006
3007
  var StyledTd = styled12("td")(({ theme }) => ({
3007
3008
  transition: `box-shadow 0.3s`,
3008
- boxShadow: "1px 0 var(--TableCell-borderColor)",
3009
+ "&:not(.is-last-left):not(.is-last-right)": {
3010
+ boxShadow: "1px 0 var(--TableCell-borderColor)"
3011
+ },
3009
3012
  ".ScrollableRight &": {
3010
3013
  "&.is-last-left": {
3011
3014
  boxShadow: `1px 0 var(--TableCell-borderColor), ${theme.shadow.md}`
@@ -3340,6 +3343,7 @@ var BodyCell = (props) => {
3340
3343
  () => noWrap && type === "longText",
3341
3344
  [noWrap, type]
3342
3345
  );
3346
+ const isBoundary = props.isLastStartPinnedColumn || props.isLastEndPinnedColumn;
3343
3347
  useEffect5(() => {
3344
3348
  setValue(row[field]);
3345
3349
  }, [row, field]);
@@ -3355,7 +3359,7 @@ var BodyCell = (props) => {
3355
3359
  position: isPinned ? "sticky" : void 0,
3356
3360
  left: isPinned ? pinnedStartPosition : void 0,
3357
3361
  right: isPinned ? pinnedEndPosition : void 0,
3358
- zIndex: isPinned ? `calc(${theme.getCssVar("zIndex-table")} + 2)` : void 0,
3362
+ zIndex: isPinned ? `calc(${theme.getCssVar("zIndex-table")} + ${isBoundary ? 2 : 3})` : void 0,
3359
3363
  "--TableCell-dataBackground": isPinned ? `var(--TableCell-headBackground)` : void 0
3360
3364
  },
3361
3365
  className: isLastStartPinnedColumn && "is-last-left" || isLastEndPinnedColumn && "is-last-right" || ""
@@ -3402,6 +3406,37 @@ var BodyRow = memo(
3402
3406
  )));
3403
3407
  }
3404
3408
  );
3409
+ function useColumnWidths(columnsByField) {
3410
+ const [widths, setWidths] = useState6({});
3411
+ const roRef = useRef4();
3412
+ useLayoutEffect(() => {
3413
+ if (roRef.current) roRef.current.disconnect();
3414
+ roRef.current = new ResizeObserver((entries) => {
3415
+ let changed = false;
3416
+ setWidths((prev) => {
3417
+ const next = { ...prev };
3418
+ entries.forEach((entry) => {
3419
+ const field = entry.target.dataset.field;
3420
+ const w = Math.round(entry.contentRect.width);
3421
+ if (next[field] !== w) {
3422
+ next[field] = w;
3423
+ changed = true;
3424
+ }
3425
+ });
3426
+ return changed ? next : prev;
3427
+ });
3428
+ });
3429
+ Object.entries(columnsByField).forEach(([field, def]) => {
3430
+ const el = def.headerRef.current;
3431
+ if (el) {
3432
+ el.dataset.field = field;
3433
+ roRef.current.observe(el);
3434
+ }
3435
+ });
3436
+ return () => roRef.current?.disconnect();
3437
+ }, [columnsByField]);
3438
+ return widths;
3439
+ }
3405
3440
  function useDataTableRenderer({
3406
3441
  rows: _rows,
3407
3442
  columns: columnsProp,
@@ -3504,6 +3539,12 @@ function useDataTableRenderer({
3504
3539
  () => _isTotalSelected ?? (rowCount > 0 && (selectionModel?.length || 0) === rowCount),
3505
3540
  [_isTotalSelected, selectionModel, rowCount]
3506
3541
  );
3542
+ const columnWidths = useColumnWidths(columnsByField);
3543
+ const getWidth = useCallback9(
3544
+ (f) => (columnWidths[f] ?? columnsByField[f].width ?? // Column prop 으로 지정된 width
3545
+ columnsByField[f].minWidth ?? 0) + columnsProp.length,
3546
+ [columnWidths, columnsByField, columnsProp.length]
3547
+ );
3507
3548
  const columns = useMemo8(() => {
3508
3549
  const baseColumns = columnsProp || // fallback
3509
3550
  Object.keys(rows[0] || {}).map((key) => ({
@@ -3525,32 +3566,27 @@ function useDataTableRenderer({
3525
3566
  sortOrder: columnsByField[column.field]?.sortOrder || sortOrder,
3526
3567
  isPinned,
3527
3568
  isLastStartPinnedColumn: isLeftPinned && [...pinnedColumns?.left || []].pop() === column.field,
3528
- isLastEndPinnedColumn: isRightPinned && [...pinnedColumns?.right || []].pop() === column.field,
3569
+ isLastEndPinnedColumn: isRightPinned && (pinnedColumns?.right?.[0] ?? null) === column.field,
3570
+ // pinned 관련 계산부
3529
3571
  pinnedStartPosition: pinnedColumns?.left?.slice(
3530
3572
  0,
3531
- isLeftPinned ? pinnedColumns?.left?.indexOf(column.field) : pinnedColumns.left.length
3532
- ).reduce(
3533
- (acc, curr) => acc + (columnsByField[curr]?.headerRef.current?.clientWidth || 0),
3534
- 0
3535
- ),
3573
+ isLeftPinned ? pinnedColumns.left.indexOf(column.field) : pinnedColumns.left.length
3574
+ ).reduce((acc, curr) => acc + getWidth(curr), 0),
3536
3575
  pinnedEndPosition: pinnedColumns?.right?.slice(
3537
- 0,
3538
- isRightPinned ? pinnedColumns.right.indexOf(column.field) : pinnedColumns.right.length
3539
- ).reduceRight(
3540
- (acc, curr) => acc + (columnsByField[curr]?.headerRef.current?.clientWidth || 0),
3541
- 0
3542
- )
3576
+ isRightPinned ? pinnedColumns.right.indexOf(column.field) + 1 : 0
3577
+ ).reduce((acc, curr) => acc + getWidth(curr), 0)
3543
3578
  };
3544
3579
  });
3545
3580
  }, [
3546
3581
  columnsProp,
3547
3582
  rows,
3583
+ pinnedColumns?.left,
3584
+ pinnedColumns?.right,
3585
+ columnsByField,
3548
3586
  editMode,
3549
3587
  sortModel,
3550
- columnsByField,
3551
3588
  sortOrder,
3552
- pinnedColumns?.left,
3553
- pinnedColumns?.right
3589
+ getWidth
3554
3590
  ]);
3555
3591
  const handlePageChange = useCallback9(
3556
3592
  (newPage) => {