@thewrong/ui 0.1.0

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.
Files changed (125) hide show
  1. package/README.md +65 -0
  2. package/dist/index.cjs.js +40 -0
  3. package/dist/index.es.js +8066 -0
  4. package/dist/src/components/_shared/form-size-tokens.d.ts +16 -0
  5. package/dist/src/components/action-toast/ActionToast.d.ts +56 -0
  6. package/dist/src/components/action-toast/index.d.ts +2 -0
  7. package/dist/src/components/animated-height/AnimatedHeight.d.ts +30 -0
  8. package/dist/src/components/animated-height/index.d.ts +2 -0
  9. package/dist/src/components/badge/Badge.d.ts +2 -0
  10. package/dist/src/components/badge/index.d.ts +2 -0
  11. package/dist/src/components/badge/types.d.ts +56 -0
  12. package/dist/src/components/badge/utils.d.ts +13 -0
  13. package/dist/src/components/button/Button.d.ts +2 -0
  14. package/dist/src/components/button/index.d.ts +2 -0
  15. package/dist/src/components/button/types.d.ts +22 -0
  16. package/dist/src/components/button/utils.d.ts +6 -0
  17. package/dist/src/components/checkbox/Checkbox.d.ts +33 -0
  18. package/dist/src/components/checkbox/index.d.ts +2 -0
  19. package/dist/src/components/checkbox/types.d.ts +33 -0
  20. package/dist/src/components/checkbox/utils.d.ts +33 -0
  21. package/dist/src/components/collapsible/Collapsible.d.ts +36 -0
  22. package/dist/src/components/collapsible/index.d.ts +2 -0
  23. package/dist/src/components/date-input/DateInput.d.ts +27 -0
  24. package/dist/src/components/date-input/index.d.ts +1 -0
  25. package/dist/src/components/date-picker/date-picker.d.ts +34 -0
  26. package/dist/src/components/date-picker/date-range-picker.d.ts +21 -0
  27. package/dist/src/components/date-picker/index.d.ts +5 -0
  28. package/dist/src/components/date-picker/month-picker.d.ts +25 -0
  29. package/dist/src/components/drawer/Drawer.d.ts +18 -0
  30. package/dist/src/components/drawer/index.d.ts +2 -0
  31. package/dist/src/components/info-tooltip/InfoTooltip.d.ts +11 -0
  32. package/dist/src/components/info-tooltip/index.d.ts +2 -0
  33. package/dist/src/components/input/Input.d.ts +10 -0
  34. package/dist/src/components/input/PasswordInput.d.ts +8 -0
  35. package/dist/src/components/input/format.d.ts +38 -0
  36. package/dist/src/components/input/index.d.ts +4 -0
  37. package/dist/src/components/input/types.d.ts +131 -0
  38. package/dist/src/components/input/utils.d.ts +17 -0
  39. package/dist/src/components/loading-spinner/LoadingSpinner.d.ts +16 -0
  40. package/dist/src/components/loading-spinner/index.d.ts +2 -0
  41. package/dist/src/components/modal/Modal.d.ts +51 -0
  42. package/dist/src/components/modal/ModalSubView.d.ts +61 -0
  43. package/dist/src/components/modal/StandardModal.d.ts +59 -0
  44. package/dist/src/components/modal/index.d.ts +6 -0
  45. package/dist/src/components/page-title/PageTitle.d.ts +17 -0
  46. package/dist/src/components/page-title/index.d.ts +1 -0
  47. package/dist/src/components/popover/Popover.d.ts +28 -0
  48. package/dist/src/components/popover/index.d.ts +2 -0
  49. package/dist/src/components/search-box/ExactMatchToggle.d.ts +14 -0
  50. package/dist/src/components/search-box/SearchBox.d.ts +35 -0
  51. package/dist/src/components/search-box/SearchBoxChips.d.ts +12 -0
  52. package/dist/src/components/search-box/SearchBoxDateRange.d.ts +20 -0
  53. package/dist/src/components/search-box/SearchBoxDateSingle.d.ts +17 -0
  54. package/dist/src/components/search-box/SearchBoxField.d.ts +11 -0
  55. package/dist/src/components/search-box/SearchBoxFloatingInput.d.ts +24 -0
  56. package/dist/src/components/search-box/SearchBoxFloatingSelect.d.ts +19 -0
  57. package/dist/src/components/search-box/SearchBoxMonth.d.ts +14 -0
  58. package/dist/src/components/search-box/SearchBoxMultiSelect.d.ts +25 -0
  59. package/dist/src/components/search-box/SearchBoxSheetContext.d.ts +8 -0
  60. package/dist/src/components/search-box/dateRangePresets.d.ts +10 -0
  61. package/dist/src/components/search-box/index.d.ts +5 -0
  62. package/dist/src/components/search-box/parseDateRange.d.ts +15 -0
  63. package/dist/src/components/search-box/parseSearchValues.d.ts +38 -0
  64. package/dist/src/components/search-box/types.d.ts +67 -0
  65. package/dist/src/components/search-box/useSearchBoxState.d.ts +30 -0
  66. package/dist/src/components/select/MultiSelect.d.ts +69 -0
  67. package/dist/src/components/select/Select.d.ts +81 -0
  68. package/dist/src/components/select/index.d.ts +4 -0
  69. package/dist/src/components/select/loading-dots.d.ts +9 -0
  70. package/dist/src/components/select/types.d.ts +141 -0
  71. package/dist/src/components/select/utils.d.ts +16 -0
  72. package/dist/src/components/switch/Switch.d.ts +17 -0
  73. package/dist/src/components/switch/index.d.ts +2 -0
  74. package/dist/src/components/switch/types.d.ts +10 -0
  75. package/dist/src/components/switch/utils.d.ts +14 -0
  76. package/dist/src/components/table/accordion-table.d.ts +31 -0
  77. package/dist/src/components/table/column-group-utils.d.ts +49 -0
  78. package/dist/src/components/table/components/ColumnPresetSelector.d.ts +36 -0
  79. package/dist/src/components/table/components/ColumnSettingsTable.d.ts +25 -0
  80. package/dist/src/components/table/components/KeyboardNavButton.d.ts +12 -0
  81. package/dist/src/components/table/components/PageJumpInput.d.ts +16 -0
  82. package/dist/src/components/table/components/Pagination.d.ts +38 -0
  83. package/dist/src/components/table/components/PaginationFooter.d.ts +28 -0
  84. package/dist/src/components/table/components/SortableHeaderCell.d.ts +27 -0
  85. package/dist/src/components/table/hooks/useColumnPresets.d.ts +48 -0
  86. package/dist/src/components/table/hooks/useColumnResize.d.ts +99 -0
  87. package/dist/src/components/table/hooks/useFillEmptyRows.d.ts +51 -0
  88. package/dist/src/components/table/hooks/useInfiniteScroll.d.ts +58 -0
  89. package/dist/src/components/table/hooks/useTableColumnState.d.ts +30 -0
  90. package/dist/src/components/table/hooks/useTableDragSelection.d.ts +35 -0
  91. package/dist/src/components/table/hooks/useTableSort.d.ts +47 -0
  92. package/dist/src/components/table/hooks/useVirtualTable.d.ts +49 -0
  93. package/dist/src/components/table/index.d.ts +27 -0
  94. package/dist/src/components/table/mini-table.d.ts +44 -0
  95. package/dist/src/components/table/paginated-mini-table.d.ts +28 -0
  96. package/dist/src/components/table/paginated-table.d.ts +8 -0
  97. package/dist/src/components/table/table.d.ts +10 -0
  98. package/dist/src/components/table/types.d.ts +409 -0
  99. package/dist/src/components/table/utils.d.ts +47 -0
  100. package/dist/src/components/table-checkbox/TableCheckbox.d.ts +16 -0
  101. package/dist/src/components/table-checkbox/index.d.ts +1 -0
  102. package/dist/src/components/table-page-layout/TablePageLayout.d.ts +22 -0
  103. package/dist/src/components/table-page-layout/index.d.ts +1 -0
  104. package/dist/src/components/textarea/Textarea.d.ts +10 -0
  105. package/dist/src/components/textarea/index.d.ts +2 -0
  106. package/dist/src/components/textarea/types.d.ts +38 -0
  107. package/dist/src/components/toast/ToastProvider.d.ts +26 -0
  108. package/dist/src/components/toast/index.d.ts +3 -0
  109. package/dist/src/components/toolbar/Toolbar.d.ts +114 -0
  110. package/dist/src/components/toolbar/index.d.ts +2 -0
  111. package/dist/src/components/tooltip/Tooltip.d.ts +18 -0
  112. package/dist/src/components/tooltip/index.d.ts +2 -0
  113. package/dist/src/hooks/index.d.ts +4 -0
  114. package/dist/src/hooks/useBottomSheetDrag.d.ts +41 -0
  115. package/dist/src/hooks/useClickOutside.d.ts +16 -0
  116. package/dist/src/hooks/useMediaQuery.d.ts +15 -0
  117. package/dist/src/hooks/useScrollLock.d.ts +8 -0
  118. package/dist/src/index.d.ts +27 -0
  119. package/dist/src/lib/Portal.d.ts +12 -0
  120. package/dist/src/lib/column-preset-storage.d.ts +54 -0
  121. package/dist/src/lib/index.d.ts +6 -0
  122. package/dist/src/lib/overlay-stack.d.ts +13 -0
  123. package/dist/src/lib/utils.d.ts +11 -0
  124. package/dist/ui.css +3 -0
  125. package/package.json +128 -0
@@ -0,0 +1,25 @@
1
+ import { TableColumn, TableColumnGroupMeta } from '../types';
2
+ /** ColumnSettingsTable의 max-height. ColumnPresetSelector의 dropdown 위치 계산에 공유돼요. */
3
+ export declare const COLUMN_SETTINGS_DROPDOWN_MAX_HEIGHT = 500;
4
+ interface ColumnSettingsTableProps<T> {
5
+ columns: TableColumn<T>[];
6
+ columnGroups?: TableColumnGroupMeta[];
7
+ columnOrder: string[];
8
+ hiddenColumns: string[];
9
+ /** 컬럼 키 → 픽셀 너비. 프리셋에 저장된 값. */
10
+ columnWidths: Record<string, number>;
11
+ num: string;
12
+ onOrderChange: (newOrder: string[]) => void;
13
+ onHiddenChange: (key: string, hidden: boolean) => void;
14
+ /** 단일 컬럼 너비 갱신. 0이면 기본값 복원. */
15
+ onSetColumnWidth?: (key: string, width: number) => void;
16
+ onSave: () => void;
17
+ onReset: () => void;
18
+ }
19
+ /**
20
+ * 컬럼 설정 드롭다운 내부의 DnD 테이블
21
+ *
22
+ * dnd-kit 기반의 컬럼 순서 변경 + 숨김 토글 UI예요.
23
+ */
24
+ export declare function ColumnSettingsTable<T>({ columns, columnGroups, columnOrder, hiddenColumns, columnWidths, num, onOrderChange, onHiddenChange, onSetColumnWidth, onSave, onReset, }: ColumnSettingsTableProps<T>): import("react").JSX.Element;
25
+ export {};
@@ -0,0 +1,12 @@
1
+ import { KeyboardEvent } from 'react';
2
+ interface KeyboardNavButtonProps {
3
+ onKeyDown: (e: KeyboardEvent<HTMLButtonElement>) => void;
4
+ }
5
+ /**
6
+ * 페이지 키보드 네비게이션 가이드 버튼.
7
+ *
8
+ * 포커스되면 ←/→ 키로 페이지 이동이 가능하다는 라벨이 슬라이드 인.
9
+ * 터치 전용 기기(`pointer: coarse`)에서는 의미가 없으므로 자동 숨김.
10
+ */
11
+ export declare function KeyboardNavButton({ onKeyDown }: KeyboardNavButtonProps): import("react").JSX.Element;
12
+ export {};
@@ -0,0 +1,16 @@
1
+ interface PageJumpInputProps {
2
+ currentPage: number;
3
+ totalPages: number;
4
+ onPageChange: (page: number) => void;
5
+ className?: string;
6
+ "data-testid"?: string;
7
+ }
8
+ /**
9
+ * 페이지 번호 직접 입력 → Enter로 점프.
10
+ *
11
+ * - 입력 동안에는 로컬 state, Enter 시점에만 onPageChange 호출.
12
+ * - 입력 시점에 totalPages를 초과하면 즉시 totalPages로 clamp.
13
+ * - 빈 값 또는 숫자가 아닐 땐 무시.
14
+ */
15
+ export declare function PageJumpInput({ currentPage, totalPages, onPageChange, className, "data-testid": testId, }: PageJumpInputProps): import("react").JSX.Element;
16
+ export {};
@@ -0,0 +1,38 @@
1
+ import { ComponentPropsWithoutRef } from 'react';
2
+ /**
3
+ * 페이지네이션 Props
4
+ */
5
+ export interface PaginationProps extends Omit<ComponentPropsWithoutRef<"div">, "children"> {
6
+ /** 현재 페이지 (1-base) */
7
+ currentPage: number;
8
+ /** 전체 페이지 수 */
9
+ totalPages: number;
10
+ /** 페이지 변경 핸들러 */
11
+ onPageChange: (page: number) => void;
12
+ /** 이전 페이지 존재 여부 (false면 이전/처음 비활성) */
13
+ hasPreviousPage?: boolean;
14
+ /** 다음 페이지 존재 여부 (false면 다음/끝 비활성) */
15
+ hasNextPage?: boolean;
16
+ /** 페이지 번호 버튼 최대 표시 개수 (넓은 화면 기준). 컨테이너 폭에 따라 자동 축소. */
17
+ maxPageButtons?: number;
18
+ /** 테스트 ID */
19
+ "data-testid"?: string;
20
+ }
21
+ /**
22
+ * Pagination 컴포넌트.
23
+ *
24
+ * 컨테이너 폭 + 페이지 자릿수에 반응해 표시할 페이지 버튼 개수를 동적으로 결정.
25
+ * - 기본 후보: 9 → 7 → 5 → 3 → 1.
26
+ * - 가용 폭에서 가장 큰 후보를 선택.
27
+ * - 첫/이전/다음/끝 버튼은 항상 표시(가운데 페이지 윈도우만 축소).
28
+ *
29
+ * @example
30
+ * ```tsx
31
+ * <Pagination
32
+ * currentPage={1}
33
+ * totalPages={10}
34
+ * onPageChange={setPage}
35
+ * />
36
+ * ```
37
+ */
38
+ export declare function Pagination({ currentPage, totalPages, onPageChange, hasPreviousPage, hasNextPage, maxPageButtons, className, "data-testid": testId, ...restProps }: PaginationProps): import("react").JSX.Element | null;
@@ -0,0 +1,28 @@
1
+ export interface PaginationFooterProps {
2
+ currentPage: number;
3
+ totalPages: number;
4
+ onPageChange: (page: number) => void;
5
+ /** 페이지 사이즈 셀렉터 노출 — onPageSizeChange와 pageSize가 함께 있어야 그려짐. */
6
+ pageSize?: number;
7
+ pageSizeOptions?: number[];
8
+ onPageSizeChange?: (size: number) => void;
9
+ /** 백엔드 메타필드 우선, 미지정 시 currentPage 비교로 폴백. */
10
+ hasPreviousPage?: boolean;
11
+ hasNextPage?: boolean;
12
+ /** "총 N건" 표시용. */
13
+ totalElements?: number;
14
+ /** "총 N건" 노출 여부. @default true */
15
+ showTotalCount?: boolean;
16
+ /** 페이지 점프 입력 + 키보드 가이드 노출. @default true */
17
+ enablePageJump?: boolean;
18
+ /** Alt + ←/→ 네비게이션. @default true */
19
+ enableKeyboardPagination?: boolean;
20
+ "data-testid"?: string;
21
+ }
22
+ /**
23
+ * 페이지네이션 footer — "총 N건" + 페이지당 셀렉터 + PageJump + 키보드 가이드 + Pagination.
24
+ *
25
+ * PaginatedTable / PaginatedMiniTable 등이 동일한 footer를 공유하기 위해 분리.
26
+ * 좁은 footer(< 640px)에선 점프/키보드가 좌측 줄(상단), 넓을 땐 우측 그룹 안에 위치.
27
+ */
28
+ export declare function PaginationFooter({ currentPage, totalPages, onPageChange, pageSize, pageSizeOptions, onPageSizeChange, hasPreviousPage, hasNextPage, totalElements, showTotalCount, enablePageJump, enableKeyboardPagination, "data-testid": testId, }: PaginationFooterProps): import("react").JSX.Element;
@@ -0,0 +1,27 @@
1
+ import { CSSProperties, ReactNode } from 'react';
2
+ interface SortableHeaderCellProps {
3
+ id: string;
4
+ /**
5
+ * 드래그 비활성 (시스템 컬럼 등)
6
+ */
7
+ disabled?: boolean;
8
+ /**
9
+ * 컨테이너 태그 — 가상화는 div, 일반 테이블은 th
10
+ * @default "div"
11
+ */
12
+ as?: "div" | "th";
13
+ /** `as="th"`일 때만 의미. 컬럼 그룹 헤더에서 사용. */
14
+ colSpan?: number;
15
+ /** `as="th"`일 때만 의미. 그룹과 평면 컬럼이 섞일 때 평면 컬럼은 rowSpan=2. */
16
+ rowSpan?: number;
17
+ className?: string;
18
+ style?: CSSProperties;
19
+ children: ReactNode;
20
+ }
21
+ /**
22
+ * 헤더 셀을 드래그 가능한 sortable item으로 감싸요.
23
+ * 5px 임계는 부모 DndContext의 PointerSensor에서 처리해서, 헤더 클릭(정렬)이나
24
+ * 리사이즈 핸들 mousedown은 방해하지 않아요.
25
+ */
26
+ export declare function SortableHeaderCell({ id, disabled, as, colSpan, rowSpan, className, style, children, }: SortableHeaderCellProps): import("react").JSX.Element;
27
+ export {};
@@ -0,0 +1,48 @@
1
+ import { PresetNumber } from '../../../../lib/column-preset-storage';
2
+ import { TableColumn, TableColumnGroupMeta } from '../types';
3
+ export interface UseColumnPresetsOptions<T> {
4
+ /** localStorage 페이지 키. 미지정 시 메모리만 사용. */
5
+ pageKey?: string;
6
+ columns: TableColumn<T>[];
7
+ /**
8
+ * 컬럼 그룹 메타. 정의 시 columnOrder/hiddenColumns가 다루는 단위가 슬롯(그룹키 또는 컬럼키)이 된다.
9
+ * 옵션 2 정책 — 그룹은 묶음 고정.
10
+ */
11
+ columnGroups?: TableColumnGroupMeta[];
12
+ /** 기존 단일 키로 저장된 width 데이터를 프리셋 시스템으로 1회 마이그레이션. */
13
+ legacyStorageKey?: string;
14
+ }
15
+ export interface UseColumnPresetsReturn {
16
+ activePreset: PresetNumber;
17
+ /** 편집 중 상태(메모리). 헤더 DnD/리사이즈/드롭다운 편집은 여기에만 반영. */
18
+ columnOrder: string[];
19
+ hiddenColumns: string[];
20
+ columnWidths: Record<string, number>;
21
+ /** 저장본과 편집본이 다를 때 true. */
22
+ isDirty: boolean;
23
+ hasPreset: (num: PresetNumber) => boolean;
24
+ /** 다른 프리셋 활성화. 편집 중 변경분은 버려짐. */
25
+ applyPreset: (num: PresetNumber) => void;
26
+ /** 현재 편집 중 상태를 저장본으로 commit. 빈 order 등으로 실패하면 false. */
27
+ saveActivePreset: () => boolean;
28
+ /** 지정 프리셋에 현재 편집 중 상태를 저장하고 그 프리셋을 활성화. 실패 시 false. */
29
+ saveAsPreset: (num: PresetNumber) => boolean;
30
+ /** 활성 프리셋을 기본값(빈 저장본)으로 되돌리고 편집본도 초기화. */
31
+ resetActivePreset: () => void;
32
+ /** 편집 중 상태 변경 (자동 persist 없음). */
33
+ setColumnOrder: (next: string[]) => void;
34
+ setHiddenColumns: (next: string[]) => void;
35
+ setColumnWidths: (next: Record<string, number>) => void;
36
+ /** 단일 키 너비 갱신. 0 이하면 키 제거(기본값 복원). */
37
+ setColumnWidth: (key: string, width: number) => void;
38
+ }
39
+ /**
40
+ * 컬럼 프리셋 관리 훅 (B-2 모델)
41
+ *
42
+ * - 활성 프리셋의 (순서/숨김/너비) 셋을 편집 중 상태로 메모리 보유
43
+ * - 헤더 DnD, 리사이즈, 드롭다운 편집은 모두 편집 중 상태에만 반영 (자동 persist 없음)
44
+ * - 명시 저장(`saveActivePreset` / `saveAsPreset`) 시에만 localStorage에 commit
45
+ * - 새로고침 시 마지막 저장본으로 복귀
46
+ * - 다른 프리셋으로 전환 시 편집 중 변경분은 그대로 버려짐
47
+ */
48
+ export declare function useColumnPresets<T>({ pageKey, columns, columnGroups, legacyStorageKey, }: UseColumnPresetsOptions<T>): UseColumnPresetsReturn;
@@ -0,0 +1,99 @@
1
+ import { ReactNode } from 'react';
2
+ /**
3
+ * 컬럼 너비 상태 타입
4
+ */
5
+ export interface ColumnWidths {
6
+ [key: string]: number;
7
+ }
8
+ /**
9
+ * 컬럼 리사이즈 훅 옵션
10
+ */
11
+ export interface UseColumnResizeOptions<T> {
12
+ /**
13
+ * 컬럼 정의 배열
14
+ */
15
+ columns: Array<{
16
+ key: string;
17
+ header?: string | ReactNode;
18
+ }>;
19
+ /**
20
+ * 테이블 데이터
21
+ */
22
+ data: T[];
23
+ /**
24
+ * 셀 내용 추출 함수
25
+ */
26
+ getCellContent: (row: T, key: string) => ReactNode;
27
+ /**
28
+ * 기본 컬럼 너비
29
+ * @default 150
30
+ */
31
+ defaultWidth?: number;
32
+ /**
33
+ * 최소 컬럼 너비
34
+ * @default 50
35
+ */
36
+ minWidth?: number;
37
+ /**
38
+ * 최대 컬럼 너비
39
+ */
40
+ maxWidth?: number;
41
+ /**
42
+ * 테이블 요소 ref (실제 DOM 측정용)
43
+ */
44
+ tableRef?: React.RefObject<HTMLTableElement | null>;
45
+ /**
46
+ * 컬럼 너비 저장 키 (localStorage 키, 저장 기능 활성화).
47
+ * `controlledWidths`가 주어지면 무시된다.
48
+ */
49
+ storageKey?: string;
50
+ /**
51
+ * 외부(예: 프리셋 훅)에서 너비를 controlled로 주입. 주어지면 내부 state 대신 사용.
52
+ */
53
+ controlledWidths?: ColumnWidths;
54
+ /**
55
+ * controlled 모드일 때 너비가 변할 때마다 호출. 외부 store에 반영 책임을 넘긴다.
56
+ */
57
+ onColumnWidthsChange?: (widths: ColumnWidths) => void;
58
+ }
59
+ /**
60
+ * 컬럼 리사이즈 훅 반환값
61
+ */
62
+ export interface UseColumnResizeReturn {
63
+ /**
64
+ * 컬럼 너비 상태
65
+ */
66
+ columnWidths: ColumnWidths;
67
+ /**
68
+ * 마우스 다운 핸들러 (드래그 시작)
69
+ */
70
+ handleMouseDown: (key: string, e: React.MouseEvent) => void;
71
+ /**
72
+ * 더블 클릭 핸들러 (자동 너비 조절)
73
+ */
74
+ handleDoubleClick: (key: string, e: React.MouseEvent) => void;
75
+ /**
76
+ * 컬럼 너비 가져오기
77
+ */
78
+ getColumnWidth: (key: string, defaultWidth?: number | string) => string;
79
+ /**
80
+ * 측정용 ref
81
+ */
82
+ measureRef: React.RefObject<HTMLDivElement | null>;
83
+ }
84
+ /**
85
+ * 컬럼 리사이즈 훅
86
+ *
87
+ * @example
88
+ * ```tsx
89
+ * const { columnWidths, handleMouseDown, handleDoubleClick, getColumnWidth, measureRef } = useColumnResize({
90
+ * columns,
91
+ * data,
92
+ * getCellContent: (row, key) => {
93
+ * const column = columns.find((col) => col.key === key);
94
+ * return column?.accessor ? column.accessor(row) : (row as any)[key];
95
+ * },
96
+ * });
97
+ * ```
98
+ */
99
+ export declare function useColumnResize<T = any>({ columns, defaultWidth, minWidth, maxWidth, tableRef, storageKey, controlledWidths, onColumnWidthsChange, }: UseColumnResizeOptions<T>): UseColumnResizeReturn;
@@ -0,0 +1,51 @@
1
+ import { RefObject } from 'react';
2
+ export type FillEmptyRowsRemainingMode = "sum-real-rows" | "tbody-height";
3
+ export interface UseFillEmptyRowsOptions {
4
+ /** 활성 여부. false면 빈 행 0으로 고정. */
5
+ enabled: boolean;
6
+ /** 스크롤 컨테이너 ref — 가용 높이의 기준. */
7
+ containerRef: RefObject<HTMLElement | null>;
8
+ /** thead ref — 헤더 높이만큼 가용 영역에서 제외. */
9
+ theadRef: RefObject<HTMLElement | null>;
10
+ /** tbody ref — 평균 행 높이 측정 + 잔여 공간 계산. */
11
+ tbodyRef: RefObject<HTMLElement | null>;
12
+ /**
13
+ * 평균 행 높이 측정에서 제외할 행을 가리키는 CSS selector.
14
+ * 예: `"tr:not([data-empty-row])"`, `"tr:not([data-empty-row]):not([data-expanded-row])"`
15
+ */
16
+ excludeRowsSelector: string;
17
+ /**
18
+ * 잔여 공간 계산 방식.
19
+ * - `sum-real-rows`: 측정 대상 행들의 높이 합을 뺀다 (펼침 없는 단순 테이블).
20
+ * - `tbody-height`: tbody 전체 높이를 뺀다 (펼침 행이 있어 tbody가 동적으로 커지는 경우).
21
+ */
22
+ remainingMode: FillEmptyRowsRemainingMode;
23
+ /**
24
+ * tbody 자체도 ResizeObserver로 감시할지. 펼침 토글 등 tbody 높이가 변하는 경우 true.
25
+ * @default false
26
+ */
27
+ observeTbody?: boolean;
28
+ /**
29
+ * effect deps에 함께 묶을 추가 값들. data/visibleColumns 등 측정에 영향 주는 외부 값.
30
+ *
31
+ * **중요**: 호출처에서 안정 참조로 넘겨야 한다. 매 렌더마다 새 배열/객체가 들어오면
32
+ * effect가 매 렌더 재구독되어 ResizeObserver가 반복 생성/해제된다.
33
+ * - 배열/객체: `useMemo`로 메모이즈
34
+ * - 원시값(length, key 등): 그대로 전달 OK
35
+ * - 펼침 토글 등 DOM 변화는 `observeTbody` ResizeObserver가 잡으므로 deps에 두지 말 것.
36
+ */
37
+ deps?: ReadonlyArray<unknown>;
38
+ }
39
+ export interface UseFillEmptyRowsReturn {
40
+ /** 빈 행으로 채워야 할 개수. */
41
+ emptyRowCount: number;
42
+ /** 측정된 평균 행 높이(px). 빈 행의 height에 그대로 적용 가능. */
43
+ measuredRowHeight: number | null;
44
+ }
45
+ /**
46
+ * 컨테이너 잔여 공간만큼 빈 행을 채우기 위한 개수/높이를 계산한다.
47
+ *
48
+ * `Table`(단순)과 `AccordionTable`(펼침 포함) 모두에서 동일한 측정 흐름을 공유하되,
49
+ * 측정 대상 행 셀렉터와 잔여 공간 계산 방식만 옵션으로 다르게 받는다.
50
+ */
51
+ export declare function useFillEmptyRows({ enabled, containerRef, theadRef, tbodyRef, excludeRowsSelector, remainingMode, observeTbody, deps, }: UseFillEmptyRowsOptions): UseFillEmptyRowsReturn;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * 무한스크롤 훅 옵션
3
+ */
4
+ export interface UseInfiniteScrollOptions {
5
+ /**
6
+ * 다음 페이지 로드 함수
7
+ */
8
+ fetchNextPage: () => void;
9
+ /**
10
+ * 다음 페이지 존재 여부
11
+ */
12
+ hasNextPage: boolean;
13
+ /**
14
+ * 다음 페이지 로딩 중 여부
15
+ */
16
+ isFetchingNextPage: boolean;
17
+ /**
18
+ * 스크롤 컨테이너 ref (없으면 window 사용)
19
+ */
20
+ scrollElement?: HTMLElement | null;
21
+ /**
22
+ * 스크롤 임계값 (하단에서 얼마나 떨어진 위치에서 로드할지, %)
23
+ * @default 80
24
+ */
25
+ threshold?: number;
26
+ /**
27
+ * 활성화 여부
28
+ * @default true
29
+ */
30
+ enabled?: boolean;
31
+ }
32
+ /**
33
+ * 무한스크롤 훅
34
+ *
35
+ * 스크롤이 하단에 도달하면 자동으로 다음 페이지를 로드해요.
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * const {
40
+ * data,
41
+ * fetchNextPage,
42
+ * hasNextPage,
43
+ * isFetchingNextPage,
44
+ * } = useApiInfiniteQuery({ ... });
45
+ *
46
+ * const containerRef = useRef<HTMLDivElement>(null);
47
+ *
48
+ * useInfiniteScroll({
49
+ * fetchNextPage,
50
+ * hasNextPage,
51
+ * isFetchingNextPage,
52
+ * scrollElement: containerRef.current,
53
+ * });
54
+ * ```
55
+ */
56
+ export declare function useInfiniteScroll({ fetchNextPage, hasNextPage, isFetchingNextPage, scrollElement, threshold, enabled, }: UseInfiniteScrollOptions): {
57
+ sentinelRef: import('react').RefObject<HTMLDivElement | null>;
58
+ };
@@ -0,0 +1,30 @@
1
+ import { ReactElement } from 'react';
2
+ import { TableColumn, TableColumnGroupMeta, TableColumnState } from '../types';
3
+ interface Options<T> {
4
+ /** localStorage 페이지 키. 없으면 프리셋 비활성(컬럼 상태는 메모리만). */
5
+ pageKey?: string;
6
+ columns: TableColumn<T>[];
7
+ /** 컬럼 그룹 메타 — 정의 시 슬롯 단위(그룹키 or 컬럼키)로 순서/숨김 관리. */
8
+ columnGroups?: TableColumnGroupMeta[];
9
+ /** 컬럼 프리셋 셀렉터 UI 노출 여부. 기본 true. */
10
+ showSelector?: boolean;
11
+ /** ColumnPresetSelector에 적용할 className. */
12
+ selectorClassName?: string;
13
+ }
14
+ interface Result {
15
+ /** Table에 넘길 controlled column-state 객체. */
16
+ columnState: TableColumnState;
17
+ /**
18
+ * 렌더할 프리셋 셀렉터 element. `showSelector=false`이거나 `pageKey` 미지정 시 null.
19
+ * 페이지에서 원하는 위치에 그대로 꽂으면 된다.
20
+ */
21
+ selector: ReactElement | null;
22
+ }
23
+ /**
24
+ * Table의 controlled column-state + 프리셋 셀렉터 UI를 한 번에 묶어주는 헬퍼.
25
+ *
26
+ * 페이지/widget이 `useColumnPresets`를 직접 부르고 두 군데(셀렉터/Table)에 같은 객체를
27
+ * 분배하는 보일러플레이트를 줄인다. 더 세밀한 제어가 필요하면 `useColumnPresets`를 직접 사용한다.
28
+ */
29
+ export declare function useTableColumnState<T>({ pageKey, columns, columnGroups, showSelector, selectorClassName, }: Options<T>): Result;
30
+ export {};
@@ -0,0 +1,35 @@
1
+ interface Options<T> {
2
+ /** 현재 표에 그려진 row들 (순서대로). */
3
+ rows: T[];
4
+ /** row의 안정 식별자. */
5
+ getRowId: (row: T) => string | number;
6
+ /** 어떤 row가 현재 선택되었는지 알려준다 — 드래그 시작 시 모드(check/uncheck)를 결정한다. */
7
+ isSelected: (row: T) => boolean;
8
+ /** 단일 row의 선택 상태를 next로 강제 설정. */
9
+ setSelected: (row: T, next: boolean) => void;
10
+ /** 훅을 활성화할지 여부. false면 window 리스너를 등록하지 않는다. */
11
+ enabled?: boolean;
12
+ /** 자동 스크롤 컨테이너 ref (window 리스너 + 좌표 비교). */
13
+ scrollContainerRef?: React.RefObject<HTMLElement | null>;
14
+ /** 자동 스크롤 트리거 영역(컨테이너 상/하단 px). 기본 60. */
15
+ edgeSize?: number;
16
+ /** 자동 스크롤 최대 속도(px/frame). 기본 14. */
17
+ maxSpeed?: number;
18
+ }
19
+ /**
20
+ * 표의 다중 행을 드래그로 선택/해제한다 — 비스킷링크의 드래그 체크 패턴을 일반화.
21
+ *
22
+ * 동작:
23
+ * - mouseDown(row 인덱스 i): 드래그 시작. row의 현재 선택 상태를 뒤집은 값을 모드로 잡고, 그 row를 그 모드로 적용
24
+ * - mouseEnter(row 인덱스 j): 드래그 중이면 [lastIndex, j] 범위의 모든 row를 모드와 다른 항목만 토글
25
+ * - mouseUp/mouseLeave(window): 드래그 종료
26
+ * - 드래그 중 컨테이너 상/하 edgeSize 안에 마우스가 들어오면 매 프레임 자동 스크롤
27
+ *
28
+ * 드래그 도중 데이터가 refetch 등으로 흔들려도 마지막 식별자(lastIdRef)를 기준으로 인덱스를 다시 찾아
29
+ * 어긋남 위험을 줄인다.
30
+ */
31
+ export declare function useTableDragSelection<T>({ rows, getRowId, isSelected, setSelected, enabled, scrollContainerRef, edgeSize, maxSpeed, }: Options<T>): {
32
+ onRowMouseDown: (index: number) => void;
33
+ onRowMouseEnter: (index: number) => void;
34
+ };
35
+ export {};
@@ -0,0 +1,47 @@
1
+ import { ColumnSort } from '../types';
2
+ /**
3
+ * 테이블 정렬 훅 옵션
4
+ */
5
+ export interface UseTableSortOptions {
6
+ /**
7
+ * 초기 정렬 상태
8
+ */
9
+ initialSort?: ColumnSort;
10
+ /**
11
+ * 서버 사이드 정렬 사용 여부
12
+ * @default false
13
+ */
14
+ serverSide?: boolean;
15
+ /**
16
+ * 서버 사이드 정렬 콜백
17
+ */
18
+ onSort?: (sort: ColumnSort) => void;
19
+ }
20
+ /**
21
+ * 테이블 정렬 훅 반환값
22
+ */
23
+ export interface UseTableSortReturn {
24
+ /**
25
+ * 현재 정렬 상태
26
+ */
27
+ sort: ColumnSort | null;
28
+ /**
29
+ * 정렬 핸들러
30
+ */
31
+ handleSort: (key: string) => void;
32
+ /**
33
+ * 정렬된 데이터 (클라이언트 사이드 정렬 시)
34
+ */
35
+ sortedData: <T>(data: T[], getValue: (row: T, key: string) => any) => T[];
36
+ }
37
+ /**
38
+ * 테이블 정렬 훅
39
+ *
40
+ * @example
41
+ * ```tsx
42
+ * const { sort, handleSort, sortedData } = useTableSort({
43
+ * initialSort: { key: 'date', direction: 'desc' },
44
+ * });
45
+ * ```
46
+ */
47
+ export declare function useTableSort({ initialSort, serverSide, onSort, }?: UseTableSortOptions): UseTableSortReturn;
@@ -0,0 +1,49 @@
1
+ import { Virtualizer } from '@tanstack/react-virtual';
2
+ /**
3
+ * 가상화 테이블 훅 옵션
4
+ */
5
+ export interface UseVirtualTableOptions {
6
+ /**
7
+ * 데이터 개수
8
+ */
9
+ count: number;
10
+ /**
11
+ * 예상 행 높이 (px)
12
+ * @default 50
13
+ */
14
+ estimateSize?: number;
15
+ /**
16
+ * 화면 밖 렌더링 범위 (overscan)
17
+ * @default 5
18
+ */
19
+ overscan?: number;
20
+ /**
21
+ * 스크롤 컨테이너 ref
22
+ */
23
+ scrollElement?: HTMLElement | null;
24
+ }
25
+ /**
26
+ * 가상화 테이블 훅 반환값
27
+ */
28
+ export interface UseVirtualTableReturn {
29
+ /**
30
+ * 가상화 인스턴스
31
+ */
32
+ virtualizer: Virtualizer<HTMLElement, Element>;
33
+ /**
34
+ * 스크롤 컨테이너 ref
35
+ */
36
+ parentRef: React.RefObject<HTMLDivElement | null>;
37
+ }
38
+ /**
39
+ * 가상화 테이블 훅
40
+ *
41
+ * @example
42
+ * ```tsx
43
+ * const { virtualizer, parentRef } = useVirtualTable({
44
+ * count: data.length,
45
+ * estimateSize: 60,
46
+ * });
47
+ * ```
48
+ */
49
+ export declare function useVirtualTable({ count, estimateSize, overscan, scrollElement, }: UseVirtualTableOptions): UseVirtualTableReturn;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Table 컴포넌트 모듈 export
3
+ */
4
+ export { Table } from './table';
5
+ export { PaginatedTable } from './paginated-table';
6
+ export { MiniTable } from './mini-table';
7
+ export type { MiniTableProps } from './mini-table';
8
+ export { PaginatedMiniTable } from './paginated-mini-table';
9
+ export type { PaginatedMiniTableProps } from './paginated-mini-table';
10
+ export { AccordionTable } from './accordion-table';
11
+ export type { AccordionTableProps, AccordionExpandable, ExpandedRowId, } from './accordion-table';
12
+ export type { TableProps, PaginatedTableProps, TableColumn, TableColumnGroupMeta, TableColumnState, TableVariant, TableSize, SortDirection, ColumnSort, } from './types';
13
+ export { useVirtualTable } from './hooks/useVirtualTable';
14
+ export type { UseVirtualTableOptions, UseVirtualTableReturn, } from './hooks/useVirtualTable';
15
+ export { useTableSort } from './hooks/useTableSort';
16
+ export type { UseTableSortOptions, UseTableSortReturn, } from './hooks/useTableSort';
17
+ export { useInfiniteScroll } from './hooks/useInfiniteScroll';
18
+ export type { UseInfiniteScrollOptions } from './hooks/useInfiniteScroll';
19
+ export { Pagination } from './components/Pagination';
20
+ export type { PaginationProps } from './components/Pagination';
21
+ export { ColumnPresetSelector } from './components/ColumnPresetSelector';
22
+ export { ColumnSettingsTable } from './components/ColumnSettingsTable';
23
+ export { useColumnPresets } from './hooks/useColumnPresets';
24
+ export type { UseColumnPresetsOptions, UseColumnPresetsReturn, } from './hooks/useColumnPresets';
25
+ export { useTableColumnState } from './hooks/useTableColumnState';
26
+ export { ColumnPresetStorage } from '../../../lib/column-preset-storage';
27
+ export type { PresetNumber, ColumnPresetData, PagePresets, AllPresets, } from '../../../lib/column-preset-storage';
@@ -0,0 +1,44 @@
1
+ import { TableColumn, TableSize, TableVariant } from './types';
2
+ import { ComponentPropsWithoutRef, ReactNode } from 'react';
3
+ export interface MiniTableProps<T> extends Omit<ComponentPropsWithoutRef<"div">, "children"> {
4
+ data: T[];
5
+ /** 컬럼 정의 — `TableColumn`과 동일 타입이지만 sortable/sticky 등 일부 옵션은 무시한다. */
6
+ columns: TableColumn<T>[];
7
+ loading?: boolean;
8
+ isFetching?: boolean;
9
+ emptyMessage?: string;
10
+ rowHeight?: number;
11
+ height?: number | string;
12
+ variant?: TableVariant;
13
+ size?: TableSize;
14
+ /** 행 부족 시 빈 행으로 채워 컨테이너 높이 유지. @default true */
15
+ fillEmptyRows?: boolean;
16
+ /** 행 클릭 핸들러 — 상세 드릴다운 등. */
17
+ onRowClick?: (row: T, index: number) => void;
18
+ /** footer 영역 (페이지네이션 등). */
19
+ footerSlot?: ReactNode;
20
+ /**
21
+ * 행의 React key 추출. 데이터가 변경되는 페이지네이션 컨텍스트에서 stale 상태 재사용을 막는다.
22
+ * 미지정 시 index를 사용(데이터가 정적인 경우만 안전).
23
+ */
24
+ getRowKey?: (row: T, index: number) => string | number;
25
+ "data-testid"?: string;
26
+ }
27
+ /**
28
+ * MiniTable — 통계 카드/요약 카드용 단순 표.
29
+ *
30
+ * Table과의 차이:
31
+ * - 헤더 DnD / 리사이즈 / grip / 컬럼 프리셋 / 정렬 없음
32
+ * - 행 선택 / 체크박스 / 드래그 멀티선택 없음
33
+ * - sticky 헤더 / 가상화 없음
34
+ * - 우측 더미 컬럼 없음 — 컬럼 너비 합이 부족하면 마지막 컬럼이 잔여폭 흡수
35
+ * - 본문 컨테이너는 `overflow-x: auto; overflow-y: hidden` 고정 — 통계 카드에서 행 수가
36
+ * 정확히 표시되고, 가로 스크롤바가 컨테이너 높이를 깎아 의도치 않은 세로 스크롤이 생기는 걸 방지
37
+ *
38
+ * **사용 시 주의**: `table-layout: auto`라 컬럼 width는 콘텐츠 우선. 짧은 라벨 + 고정 데이터
39
+ * 패턴(투자 변동 이력 등)에 적합. 컬럼별 콘텐츠 길이 편차가 큰 페이지에 재사용할 때는
40
+ * 미리 한 번 다양한 데이터 모양으로 시각 검증.
41
+ */
42
+ export declare const MiniTable: <T>(props: MiniTableProps<T> & {
43
+ ref?: React.ForwardedRef<HTMLDivElement>;
44
+ }) => React.ReactElement;