@mondrianai/runyourai-design-system 0.0.20 → 0.0.21

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.d.mts CHANGED
@@ -596,7 +596,7 @@ interface ModalProps {
596
596
  title: string;
597
597
  /** 제목 아래 부제목 (선택) */
598
598
  description?: string;
599
- /** 우상단 X 닫기 버튼 표시 여부 */
599
+ /** 우상단 X 닫기 버튼 표시 여부 (기본: true) */
600
600
  showCloseButton?: boolean;
601
601
  /** 모달 본문 */
602
602
  children?: React$1.ReactNode;
@@ -1065,6 +1065,15 @@ interface TableProps<T> {
1065
1065
  defaultSorting?: TableSortingItem[];
1066
1066
  /** 데이터 로딩 중 상태. true이면 tbody 대신 스피너를 표시 */
1067
1067
  loading?: boolean;
1068
+ /**
1069
+ * data가 비어 있을 때 tbody 영역에 표시할 내용.
1070
+ * - 미전달: 기본값 <Empty description="No Data" /> 표시
1071
+ * - { description }: 기본 Empty 스타일을 유지한 채 description만 교체
1072
+ * - ReactNode: 전달한 내용을 그대로 렌더(완전 커스텀)
1073
+ */
1074
+ empty?: React$1.ReactNode | {
1075
+ description: React$1.ReactNode;
1076
+ };
1068
1077
  /** true이면 각 행 앞에 체크박스가 추가되어 row multi-select 활성화 */
1069
1078
  enableRowSelection?: boolean;
1070
1079
  /** 외부에서 selection 상태를 제어할 때 사용 (controlled) */
@@ -1079,6 +1088,12 @@ interface TableProps<T> {
1079
1088
  rowActions?: (row: T) => React$1.ReactNode;
1080
1089
  /** 행 클릭 핸들러. enableRowSelection=true(편집 모드)일 때는 동작하지 않음. */
1081
1090
  onRowClick?: (row: T) => void;
1091
+ /**
1092
+ * 특정 행을 disabled 처리할지 판단하는 콜백. true를 반환한 행은
1093
+ * 모든 셀 텍스트가 text-muted-foreground로 통일되고, 클릭(onRowClick)·선택(체크박스)이
1094
+ * 비활성화된다. hover 효과는 그대로 유지된다.
1095
+ */
1096
+ isRowDisabled?: (row: T) => boolean;
1082
1097
  /**
1083
1098
  * 정렬 상태 변경 콜백. 서버사이드 정렬 연동에 사용.
1084
1099
  * 빈 배열(정렬 해제)은 전달되지 않으므로 항상 최소 1개 항목 보장.
@@ -1094,7 +1109,7 @@ interface TableProps<T> {
1094
1109
  declare function SortIcon({ direction }: {
1095
1110
  direction: SortDirection;
1096
1111
  }): react_jsx_runtime.JSX.Element;
1097
- declare function Table<T>({ columns, data, rowKey, pagination, defaultSorting, loading, enableRowSelection, rowSelection: rowSelectionProp, onRowSelectionChange, rowActions, onRowClick, onSortingChange, className, maxHeight, }: TableProps<T>): react_jsx_runtime.JSX.Element;
1112
+ declare function Table<T>({ columns, data, rowKey, pagination, defaultSorting, loading, empty, enableRowSelection, rowSelection: rowSelectionProp, onRowSelectionChange, rowActions, onRowClick, isRowDisabled, onSortingChange, className, maxHeight, }: TableProps<T>): react_jsx_runtime.JSX.Element;
1098
1113
 
1099
1114
  declare const TooltipProvider: React$1.FC<Tooltip$1.TooltipProviderProps>;
1100
1115
  interface TooltipProps extends Pick<React$1.ComponentPropsWithoutRef<typeof Tooltip$1.Root>, 'open' | 'defaultOpen' | 'onOpenChange' | 'delayDuration'>, Omit<React$1.ComponentPropsWithoutRef<typeof Tooltip$1.Content>, 'children' | 'content'> {
package/dist/index.d.ts CHANGED
@@ -596,7 +596,7 @@ interface ModalProps {
596
596
  title: string;
597
597
  /** 제목 아래 부제목 (선택) */
598
598
  description?: string;
599
- /** 우상단 X 닫기 버튼 표시 여부 */
599
+ /** 우상단 X 닫기 버튼 표시 여부 (기본: true) */
600
600
  showCloseButton?: boolean;
601
601
  /** 모달 본문 */
602
602
  children?: React$1.ReactNode;
@@ -1065,6 +1065,15 @@ interface TableProps<T> {
1065
1065
  defaultSorting?: TableSortingItem[];
1066
1066
  /** 데이터 로딩 중 상태. true이면 tbody 대신 스피너를 표시 */
1067
1067
  loading?: boolean;
1068
+ /**
1069
+ * data가 비어 있을 때 tbody 영역에 표시할 내용.
1070
+ * - 미전달: 기본값 <Empty description="No Data" /> 표시
1071
+ * - { description }: 기본 Empty 스타일을 유지한 채 description만 교체
1072
+ * - ReactNode: 전달한 내용을 그대로 렌더(완전 커스텀)
1073
+ */
1074
+ empty?: React$1.ReactNode | {
1075
+ description: React$1.ReactNode;
1076
+ };
1068
1077
  /** true이면 각 행 앞에 체크박스가 추가되어 row multi-select 활성화 */
1069
1078
  enableRowSelection?: boolean;
1070
1079
  /** 외부에서 selection 상태를 제어할 때 사용 (controlled) */
@@ -1079,6 +1088,12 @@ interface TableProps<T> {
1079
1088
  rowActions?: (row: T) => React$1.ReactNode;
1080
1089
  /** 행 클릭 핸들러. enableRowSelection=true(편집 모드)일 때는 동작하지 않음. */
1081
1090
  onRowClick?: (row: T) => void;
1091
+ /**
1092
+ * 특정 행을 disabled 처리할지 판단하는 콜백. true를 반환한 행은
1093
+ * 모든 셀 텍스트가 text-muted-foreground로 통일되고, 클릭(onRowClick)·선택(체크박스)이
1094
+ * 비활성화된다. hover 효과는 그대로 유지된다.
1095
+ */
1096
+ isRowDisabled?: (row: T) => boolean;
1082
1097
  /**
1083
1098
  * 정렬 상태 변경 콜백. 서버사이드 정렬 연동에 사용.
1084
1099
  * 빈 배열(정렬 해제)은 전달되지 않으므로 항상 최소 1개 항목 보장.
@@ -1094,7 +1109,7 @@ interface TableProps<T> {
1094
1109
  declare function SortIcon({ direction }: {
1095
1110
  direction: SortDirection;
1096
1111
  }): react_jsx_runtime.JSX.Element;
1097
- declare function Table<T>({ columns, data, rowKey, pagination, defaultSorting, loading, enableRowSelection, rowSelection: rowSelectionProp, onRowSelectionChange, rowActions, onRowClick, onSortingChange, className, maxHeight, }: TableProps<T>): react_jsx_runtime.JSX.Element;
1112
+ declare function Table<T>({ columns, data, rowKey, pagination, defaultSorting, loading, empty, enableRowSelection, rowSelection: rowSelectionProp, onRowSelectionChange, rowActions, onRowClick, isRowDisabled, onSortingChange, className, maxHeight, }: TableProps<T>): react_jsx_runtime.JSX.Element;
1098
1113
 
1099
1114
  declare const TooltipProvider: React$1.FC<Tooltip$1.TooltipProviderProps>;
1100
1115
  interface TooltipProps extends Pick<React$1.ComponentPropsWithoutRef<typeof Tooltip$1.Root>, 'open' | 'defaultOpen' | 'onOpenChange' | 'delayDuration'>, Omit<React$1.ComponentPropsWithoutRef<typeof Tooltip$1.Content>, 'children' | 'content'> {
package/dist/index.js CHANGED
@@ -4321,7 +4321,7 @@ function Modal({
4321
4321
  variant = "confirm",
4322
4322
  title,
4323
4323
  description,
4324
- showCloseButton = false,
4324
+ showCloseButton = true,
4325
4325
  children,
4326
4326
  cancelLabel = "\uCDE8\uC18C",
4327
4327
  confirmLabel = "\uD655\uC778",
@@ -6269,6 +6269,9 @@ function SortIcon({ direction }) {
6269
6269
  }
6270
6270
  );
6271
6271
  }
6272
+ function isEmptyConfig(value) {
6273
+ return typeof value === "object" && value !== null && !React27.isValidElement(value) && "description" in value;
6274
+ }
6272
6275
  function Table({
6273
6276
  columns,
6274
6277
  data,
@@ -6276,11 +6279,13 @@ function Table({
6276
6279
  pagination,
6277
6280
  defaultSorting,
6278
6281
  loading = false,
6282
+ empty,
6279
6283
  enableRowSelection,
6280
6284
  rowSelection: rowSelectionProp,
6281
6285
  onRowSelectionChange,
6282
6286
  rowActions,
6283
6287
  onRowClick,
6288
+ isRowDisabled,
6284
6289
  onSortingChange,
6285
6290
  className,
6286
6291
  maxHeight
@@ -6347,6 +6352,7 @@ function Table({
6347
6352
  Checkbox,
6348
6353
  {
6349
6354
  checked: row.getIsSelected(),
6355
+ disabled: !row.getCanSelect(),
6350
6356
  onCheckedChange: (checked) => row.toggleSelected(!!checked),
6351
6357
  "aria-label": "\uD589 \uC120\uD0DD",
6352
6358
  onClick: (e) => e.stopPropagation()
@@ -6392,7 +6398,7 @@ function Table({
6392
6398
  getRowId: (row) => getRowKey(row),
6393
6399
  onSortingChange: handleSortingChange
6394
6400
  }, hasPagination && { onPaginationChange: handlePaginationChange }), isSelectionActive && {
6395
- enableRowSelection: true,
6401
+ enableRowSelection: isRowDisabled ? (row) => !isRowDisabled(row.original) : true,
6396
6402
  onRowSelectionChange: handleRowSelectionChange
6397
6403
  }), {
6398
6404
  getCoreRowModel: (0, import_react_table.getCoreRowModel)(),
@@ -6501,81 +6507,87 @@ function Table({
6501
6507
  name: "loader-2",
6502
6508
  className: "mx-auto size-6 animate-spin text-muted-foreground"
6503
6509
  }
6504
- ) }) }) : table.getRowModel().rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
6505
- "tr",
6506
- {
6507
- onClick: !isSelectionActive && onRowClick ? () => onRowClick(row.original) : void 0,
6508
- className: cn(
6509
- "group border-b border-border transition-colors hover:bg-accent/50 last:border-b-0",
6510
- !isSelectionActive && onRowClick && "cursor-pointer",
6511
- isSelectionActive && row.getIsSelected() && "bg-accent/30"
6512
- ),
6513
- children: row.getVisibleCells().map((cell) => {
6514
- var _a2;
6515
- if (cell.column.id === "__select__") {
6516
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("td", { className: "w-10 p-0 relative", children: isSelectionActive && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "absolute inset-0 flex items-center justify-center", children: (0, import_react_table.flexRender)(
6510
+ ) }) }) : table.getRowModel().rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("td", { colSpan: colCount, children: empty === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Empty, { description: "No Data" }) : isEmptyConfig(empty) ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Empty, { description: empty.description }) : empty }) }) : table.getRowModel().rows.map((row) => {
6511
+ var _a2;
6512
+ const rowDisabled = (_a2 = isRowDisabled == null ? void 0 : isRowDisabled(row.original)) != null ? _a2 : false;
6513
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
6514
+ "tr",
6515
+ {
6516
+ "aria-disabled": rowDisabled || void 0,
6517
+ onClick: !isSelectionActive && onRowClick && !rowDisabled ? () => onRowClick(row.original) : void 0,
6518
+ className: cn(
6519
+ "group border-b border-border transition-colors hover:bg-accent/50 last:border-b-0",
6520
+ !isSelectionActive && onRowClick && !rowDisabled && "cursor-pointer",
6521
+ isSelectionActive && row.getIsSelected() && "bg-accent/30",
6522
+ rowDisabled && "cursor-not-allowed [&_td]:text-muted-foreground"
6523
+ ),
6524
+ children: row.getVisibleCells().map((cell) => {
6525
+ var _a3;
6526
+ if (cell.column.id === "__select__") {
6527
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("td", { className: "w-10 p-0 relative", children: isSelectionActive && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "absolute inset-0 flex items-center justify-center", children: (0, import_react_table.flexRender)(
6528
+ cell.column.columnDef.cell,
6529
+ cell.getContext()
6530
+ ) }) }, cell.id);
6531
+ }
6532
+ if (cell.column.id === "__row_actions__") {
6533
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
6534
+ "td",
6535
+ {
6536
+ className: "w-12 px-2 py-4 align-middle text-right",
6537
+ children: (0, import_react_table.flexRender)(
6538
+ cell.column.columnDef.cell,
6539
+ cell.getContext()
6540
+ )
6541
+ },
6542
+ cell.id
6543
+ );
6544
+ }
6545
+ const {
6546
+ align,
6547
+ cellCls,
6548
+ ellipsis,
6549
+ ellipsisTooltip,
6550
+ cellFn
6551
+ } = (_a3 = colMap[cell.column.id]) != null ? _a3 : {
6552
+ align: "left",
6553
+ cellCls: "",
6554
+ ellipsis: false,
6555
+ ellipsisTooltip: void 0,
6556
+ cellFn: () => null
6557
+ };
6558
+ const rendered = (0, import_react_table.flexRender)(
6517
6559
  cell.column.columnDef.cell,
6518
6560
  cell.getContext()
6519
- ) }) }, cell.id);
6520
- }
6521
- if (cell.column.id === "__row_actions__") {
6561
+ );
6562
+ const rawContent = ellipsis ? cellFn(row.original) : null;
6563
+ const cellContent = ellipsis ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
6564
+ EllipsisCell,
6565
+ {
6566
+ rendered: rawContent,
6567
+ tooltip: ellipsisTooltip ? ellipsisTooltip(row.original) : rawContent
6568
+ }
6569
+ ) : rendered;
6522
6570
  return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
6523
6571
  "td",
6524
6572
  {
6525
- className: "w-12 px-2 py-4 align-middle text-right",
6526
- children: (0, import_react_table.flexRender)(
6527
- cell.column.columnDef.cell,
6528
- cell.getContext()
6529
- )
6573
+ className: cn(
6574
+ "px-2 py-4 text-sm leading-none text-foreground align-middle",
6575
+ align === "center" && "text-center",
6576
+ align === "right" && "text-right",
6577
+ // ellipsis 컬럼은 max-w-0으로 table 레이아웃상 너비를 고정하고
6578
+ // overflow-hidden으로 td 밖으로 나가는 콘텐츠를 클리핑
6579
+ ellipsis && "max-w-0 overflow-hidden",
6580
+ cellCls
6581
+ ),
6582
+ children: cellContent
6530
6583
  },
6531
6584
  cell.id
6532
6585
  );
6533
- }
6534
- const {
6535
- align,
6536
- cellCls,
6537
- ellipsis,
6538
- ellipsisTooltip,
6539
- cellFn
6540
- } = (_a2 = colMap[cell.column.id]) != null ? _a2 : {
6541
- align: "left",
6542
- cellCls: "",
6543
- ellipsis: false,
6544
- ellipsisTooltip: void 0,
6545
- cellFn: () => null
6546
- };
6547
- const rendered = (0, import_react_table.flexRender)(
6548
- cell.column.columnDef.cell,
6549
- cell.getContext()
6550
- );
6551
- const rawContent = ellipsis ? cellFn(row.original) : null;
6552
- const cellContent = ellipsis ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
6553
- EllipsisCell,
6554
- {
6555
- rendered: rawContent,
6556
- tooltip: ellipsisTooltip ? ellipsisTooltip(row.original) : rawContent
6557
- }
6558
- ) : rendered;
6559
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
6560
- "td",
6561
- {
6562
- className: cn(
6563
- "px-2 py-4 text-sm leading-none text-foreground align-middle",
6564
- align === "center" && "text-center",
6565
- align === "right" && "text-right",
6566
- // ellipsis 컬럼은 max-w-0으로 table 레이아웃상 너비를 고정하고
6567
- // overflow-hidden으로 td 밖으로 나가는 콘텐츠를 클리핑
6568
- ellipsis && "max-w-0 overflow-hidden",
6569
- cellCls
6570
- ),
6571
- children: cellContent
6572
- },
6573
- cell.id
6574
- );
6575
- })
6576
- },
6577
- getRowKey(row.original)
6578
- )) })
6586
+ })
6587
+ },
6588
+ getRowKey(row.original)
6589
+ );
6590
+ }) })
6579
6591
  ] })
6580
6592
  }
6581
6593
  ),