@ceed/cds 1.2.8-next.1 → 1.2.8-next.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.js CHANGED
@@ -1968,7 +1968,8 @@ import React22, {
1968
1968
  useId,
1969
1969
  forwardRef as forwardRef7,
1970
1970
  useImperativeHandle as useImperativeHandle2,
1971
- createElement
1971
+ createElement,
1972
+ memo
1972
1973
  } from "react";
1973
1974
  import { useVirtualizer as useVirtualizer2 } from "@tanstack/react-virtual";
1974
1975
  import { styled as styled11, LinearProgress, Link, useTheme } from "@mui/joy";
@@ -2957,51 +2958,73 @@ var HeadCell = (props) => {
2957
2958
  () => `${tableId}_header_${headerName ?? field}`.trim(),
2958
2959
  [tableId, headerName, field]
2959
2960
  );
2960
- const resizer = resizable ?? true ? Resizer(ref) : null;
2961
- const style = {
2962
- width,
2963
- minWidth: minWidth ?? "50px",
2964
- maxWidth,
2965
- position: isPinned ? "sticky" : stickyHeader ? void 0 : "relative",
2966
- // 조건식 더 복잡해지면 IIFE로 정리
2967
- left: isPinned ? pinnedStartPosition : void 0,
2968
- right: isPinned ? pinnedEndPosition : void 0,
2969
- zIndex: isPinned ? `calc(${theme.getCssVar("zIndex-table")} + 2)` : void 0,
2970
- cursor: sortable ? "pointer" : "default",
2971
- // TODO: multi-sort때문에 일단 추가한 property, joy-ui에서는 multi-sort시 th에 user-select: none을 적용하고 툴팁을 띄워준다.
2972
- userSelect: "none"
2973
- };
2961
+ const resizer = useMemo8(
2962
+ () => resizable ?? true ? Resizer(ref) : null,
2963
+ [resizable, ref]
2964
+ );
2965
+ const style = useMemo8(
2966
+ () => ({
2967
+ width,
2968
+ minWidth: minWidth ?? "50px",
2969
+ maxWidth,
2970
+ position: isPinned ? "sticky" : stickyHeader ? void 0 : "relative",
2971
+ // 조건식 복잡해지면 IIFE로 정리
2972
+ left: isPinned ? pinnedStartPosition : void 0,
2973
+ right: isPinned ? pinnedEndPosition : void 0,
2974
+ zIndex: isPinned ? `calc(${theme.getCssVar("zIndex-table")} + 2)` : void 0,
2975
+ cursor: sortable ? "pointer" : "default",
2976
+ // TODO: multi-sort때문에 일단 추가한 property, joy-ui에서는 multi-sort시 th에 user-select: none을 적용하고 툴팁을 띄워준다.
2977
+ userSelect: "none"
2978
+ }),
2979
+ [
2980
+ isPinned,
2981
+ maxWidth,
2982
+ minWidth,
2983
+ pinnedEndPosition,
2984
+ pinnedStartPosition,
2985
+ sortable,
2986
+ stickyHeader,
2987
+ theme,
2988
+ width
2989
+ ]
2990
+ );
2974
2991
  const textAlign = getTextAlign(props);
2975
2992
  const initialSort = sortOrder[0];
2976
- const sortIcon = sortable && /* @__PURE__ */ React22.createElement(
2977
- MotionSortIcon,
2978
- {
2979
- style: {
2980
- width: "16px",
2981
- height: "16px"
2982
- },
2983
- role: "img",
2984
- "aria-labelledby": headId,
2985
- "aria-description": (sort ?? initialSort) === "desc" ? "descending" : "ascending",
2986
- "data-testid": void 0,
2987
- variants: {
2988
- hover: { opacity: 1 },
2989
- initial: { opacity: 0 }
2990
- },
2991
- animate: {
2992
- color: !!sort ? "var(--ceed-palette-text-secondary)" : "var(--ceed-palette-primary-solidDisabledColor)",
2993
- rotate: (sort ?? initialSort) === "desc" ? 180 : 0,
2994
- opacity: !!sort ? 1 : 0
2995
- },
2996
- transition: {
2997
- duration: 0,
2998
- rotate: { duration: 0.2, ease: "easeOut" },
2999
- color: { duration: 0.2, ease: "easeInOut" },
3000
- opacity: { duration: 0.2, ease: "easeInOut" }
2993
+ const sortIcon = useMemo8(
2994
+ () => sortable && /* @__PURE__ */ React22.createElement(
2995
+ MotionSortIcon,
2996
+ {
2997
+ style: {
2998
+ width: "16px",
2999
+ height: "16px"
3000
+ },
3001
+ role: "img",
3002
+ "aria-labelledby": headId,
3003
+ "aria-description": (sort ?? initialSort) === "desc" ? "descending" : "ascending",
3004
+ "data-testid": void 0,
3005
+ variants: {
3006
+ hover: { opacity: 1 },
3007
+ initial: { opacity: 0 }
3008
+ },
3009
+ animate: {
3010
+ color: !!sort ? "var(--ceed-palette-text-secondary)" : "var(--ceed-palette-primary-solidDisabledColor)",
3011
+ rotate: (sort ?? initialSort) === "desc" ? 180 : 0,
3012
+ opacity: !!sort ? 1 : 0
3013
+ },
3014
+ transition: {
3015
+ duration: 0,
3016
+ rotate: { duration: 0.2, ease: "easeOut" },
3017
+ color: { duration: 0.2, ease: "easeInOut" },
3018
+ opacity: { duration: 0.2, ease: "easeInOut" }
3019
+ }
3001
3020
  }
3002
- }
3021
+ ),
3022
+ [headId, initialSort, sort, sortable]
3023
+ );
3024
+ const infoSign = useMemo8(
3025
+ () => description ? /* @__PURE__ */ React22.createElement(InfoSign_default, { message: description, placement: "bottom" }) : null,
3026
+ [description]
3003
3027
  );
3004
- const infoSign = description ? /* @__PURE__ */ React22.createElement(InfoSign_default, { message: description, placement: "bottom" }) : null;
3005
3028
  return /* @__PURE__ */ React22.createElement(
3006
3029
  StyledTh,
3007
3030
  {
@@ -3011,7 +3034,10 @@ var HeadCell = (props) => {
3011
3034
  ref,
3012
3035
  key: field,
3013
3036
  style,
3014
- onClick: (e) => sortable && onSortChange?.({ field, currentSort: sort, multiple: e.shiftKey }),
3037
+ onClick: useCallback9(
3038
+ (e) => sortable && onSortChange?.({ field, currentSort: sort, multiple: e.shiftKey }),
3039
+ [field, onSortChange, sort, sortable]
3040
+ ),
3015
3041
  whileHover: "hover",
3016
3042
  initial: "initial"
3017
3043
  },
@@ -3069,7 +3095,7 @@ var BodyCell = (props) => {
3069
3095
  ...typeof props.componentProps === "function" ? props.componentProps(params) : props.componentProps || {},
3070
3096
  size: "sm"
3071
3097
  }),
3072
- [props, params]
3098
+ [props.componentProps, params]
3073
3099
  );
3074
3100
  const editModeComponentProps = useMemo8(
3075
3101
  () => ({
@@ -3131,11 +3157,20 @@ var BodyCell = (props) => {
3131
3157
  }
3132
3158
  }
3133
3159
  }),
3134
- [params, row, field, value, componentProps, type, props]
3160
+ [
3161
+ params,
3162
+ row,
3163
+ field,
3164
+ value,
3165
+ componentProps,
3166
+ type,
3167
+ props.onCellEditStop,
3168
+ props.onCellEditStart
3169
+ ]
3135
3170
  );
3136
3171
  const EditModeComponent = useMemo8(() => {
3137
3172
  if (renderEditCell) {
3138
- return createElement(renderEditCell, params);
3173
+ return createElement(memo(renderEditCell), params);
3139
3174
  }
3140
3175
  return {
3141
3176
  date: /* @__PURE__ */ React22.createElement(
@@ -3195,7 +3230,7 @@ var BodyCell = (props) => {
3195
3230
  }, [value, editModeComponentProps, type]);
3196
3231
  const ReadModeComponent = useMemo8(() => {
3197
3232
  if (renderCell) {
3198
- return createElement(renderCell, params);
3233
+ return createElement(memo(renderCell), params);
3199
3234
  }
3200
3235
  const innerText = value;
3201
3236
  const typedComponent = {
@@ -3208,14 +3243,14 @@ var BodyCell = (props) => {
3208
3243
  )
3209
3244
  }[type || "text"];
3210
3245
  return typedComponent || innerText;
3211
- }, [value, renderCell, params, type, componentProps, props]);
3246
+ }, [value, renderCell, params, type, componentProps]);
3212
3247
  const CellComponent = useMemo8(
3213
3248
  () => editMode && EditModeComponent ? EditModeComponent : ReadModeComponent,
3214
3249
  [editMode, EditModeComponent, ReadModeComponent]
3215
3250
  );
3216
3251
  const showTooltip = useMemo8(
3217
- () => noWrap && props.type === "longText",
3218
- [noWrap, props.type]
3252
+ () => noWrap && type === "longText",
3253
+ [noWrap, type]
3219
3254
  );
3220
3255
  useEffect5(() => {
3221
3256
  setValue(row[field]);
@@ -3226,55 +3261,59 @@ var BodyCell = (props) => {
3226
3261
  ref: cellRef,
3227
3262
  key: field,
3228
3263
  headers: `${tableId}_header_${props.headerName ?? field}`,
3229
- style: {
3264
+ sx: {
3230
3265
  textAlign: getTextAlign({ type }),
3231
3266
  verticalAlign: editMode ? "top" : "middle",
3232
3267
  position: isPinned ? "sticky" : void 0,
3233
3268
  left: isPinned ? pinnedStartPosition : void 0,
3234
3269
  right: isPinned ? pinnedEndPosition : void 0,
3235
3270
  zIndex: isPinned ? `calc(${theme.getCssVar("zIndex-table")} + 2)` : void 0,
3236
- // @ts-expect-error: react CSSProperties에는 --var를 지원하지 않는다.
3237
3271
  "--TableCell-dataBackground": isPinned ? `var(--TableCell-headBackground)` : void 0
3238
3272
  },
3239
3273
  className: isLastStartPinnedColumn && "is-last-left" || isLastEndPinnedColumn && "is-last-right" || ""
3240
3274
  },
3241
- showTooltip ? /* @__PURE__ */ React22.createElement(
3242
- Tooltip_default,
3243
- {
3244
- title: value,
3245
- placement: "bottom",
3246
- style: { maxWidth: "100%" },
3247
- enterDelay: 1500,
3248
- enterNextDelay: 1500
3249
- },
3250
- /* @__PURE__ */ React22.createElement(
3251
- "div",
3275
+ useMemo8(
3276
+ () => showTooltip ? /* @__PURE__ */ React22.createElement(
3277
+ Tooltip_default,
3252
3278
  {
3253
- style: {
3254
- overflow: "hidden",
3255
- textOverflow: "ellipsis"
3256
- }
3279
+ title: value,
3280
+ placement: "bottom",
3281
+ style: { maxWidth: "100%" },
3282
+ enterDelay: 1500,
3283
+ enterNextDelay: 1500
3257
3284
  },
3258
- CellComponent
3259
- )
3260
- ) : CellComponent
3285
+ /* @__PURE__ */ React22.createElement(
3286
+ "div",
3287
+ {
3288
+ style: {
3289
+ overflow: "hidden",
3290
+ textOverflow: "ellipsis"
3291
+ }
3292
+ },
3293
+ CellComponent
3294
+ )
3295
+ ) : CellComponent,
3296
+ [CellComponent, showTooltip, value]
3297
+ )
3261
3298
  );
3262
3299
  };
3263
- var BodyRow = (props) => {
3264
- const { tableId, columns, rowId, editMode, noWrap, row } = props;
3265
- return /* @__PURE__ */ React22.createElement(React22.Fragment, null, columns.map((column, i) => /* @__PURE__ */ React22.createElement(
3266
- BodyCell,
3267
- {
3268
- ...column,
3269
- tableId,
3270
- key: `${rowId}_${column.field.toString()}_${i}`,
3271
- row,
3272
- rowId,
3273
- editMode,
3274
- noWrap
3275
- }
3276
- )));
3277
- };
3300
+ var BodyRow = memo(
3301
+ (props) => {
3302
+ const { tableId, columns, rowId, editMode, noWrap, row } = props;
3303
+ return /* @__PURE__ */ React22.createElement(React22.Fragment, null, columns.map((column, i) => /* @__PURE__ */ React22.createElement(
3304
+ BodyCell,
3305
+ {
3306
+ ...column,
3307
+ tableId,
3308
+ key: `${rowId}_${column.field.toString()}_${i}`,
3309
+ row,
3310
+ rowId,
3311
+ editMode,
3312
+ noWrap
3313
+ }
3314
+ )));
3315
+ }
3316
+ );
3278
3317
  function useDataTableRenderer({
3279
3318
  rows: _rows,
3280
3319
  columns: columnsProp,
@@ -3286,8 +3325,8 @@ function useDataTableRenderer({
3286
3325
  paginationModel,
3287
3326
  onPaginationModelChange,
3288
3327
  sortModel: controlledSortModel,
3289
- sortOrder: _sortOrder = ["asc", "desc", null],
3290
- selectionModel = [],
3328
+ sortOrder: _sortOrder,
3329
+ selectionModel,
3291
3330
  onSortModelChange,
3292
3331
  onSelectionModelChange,
3293
3332
  editMode,
@@ -3349,7 +3388,8 @@ function useDataTableRenderer({
3349
3388
  [_rows, sortModel, sortComparator]
3350
3389
  );
3351
3390
  const sortOrder = useMemo8(
3352
- () => Array.from(new Set(_sortOrder)),
3391
+ // NOTE: default value를 props destructuring에서 할당하면 렌더링 시점에 초기화가 되어버린다.
3392
+ () => Array.from(new Set(_sortOrder || ["asc", "desc", null])),
3353
3393
  [_sortOrder]
3354
3394
  );
3355
3395
  const [page, setPage] = useState6(paginationModel?.page || 1);
@@ -3359,7 +3399,8 @@ function useDataTableRenderer({
3359
3399
  [_getId, page, pageSize]
3360
3400
  );
3361
3401
  const selectedModelSet = useMemo8(
3362
- () => new Set(selectionModel),
3402
+ // NOTE: default value를 props destructuring에서 할당하면 렌더링 시점에 초기화가 되어버린다.
3403
+ () => new Set(selectionModel || []),
3363
3404
  [selectionModel]
3364
3405
  );
3365
3406
  const dataInPage = useMemo8(
@@ -3372,7 +3413,7 @@ function useDataTableRenderer({
3372
3413
  );
3373
3414
  const rowCount = totalRowsProp || rows.length;
3374
3415
  const isTotalSelected = useMemo8(
3375
- () => _isTotalSelected ?? (rowCount > 0 && selectionModel.length === rowCount),
3416
+ () => _isTotalSelected ?? (rowCount > 0 && (selectionModel?.length || 0) === rowCount),
3376
3417
  [_isTotalSelected, selectionModel, rowCount]
3377
3418
  );
3378
3419
  const columns = useMemo8(() => {
@@ -3496,12 +3537,12 @@ function useDataTableRenderer({
3496
3537
  onCheckboxChange: useCallback9(
3497
3538
  (event, selectedModel) => {
3498
3539
  if (selectedModelSet.has(selectedModel)) {
3499
- const newSelectionModel = selectionModel.filter(
3540
+ const newSelectionModel = (selectionModel || []).filter(
3500
3541
  (model) => model !== selectedModel
3501
3542
  );
3502
3543
  onSelectionModelChange?.(newSelectionModel);
3503
3544
  } else {
3504
- const newSelectionModel = [...selectionModel, selectedModel];
3545
+ const newSelectionModel = [...selectionModel || [], selectedModel];
3505
3546
  onSelectionModelChange?.(newSelectionModel);
3506
3547
  }
3507
3548
  },
@@ -3589,7 +3630,7 @@ function Component(props, apiRef) {
3589
3630
  getScrollElement: () => parentRef.current,
3590
3631
  estimateSize: () => 32,
3591
3632
  measureElement: (element) => element.clientHeight,
3592
- overscan: 20
3633
+ overscan: 10
3593
3634
  });
3594
3635
  const paginationModel = useMemo8(() => ({ page, pageSize }), [page, pageSize]);
3595
3636
  const totalSize = virtualizer.getTotalSize();