kokotable 0.95.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.
- package/LICENSE +21 -0
- package/README.md +320 -0
- package/contract/table-request.schema.json +424 -0
- package/dist/core/src/adapters/sources.d.ts +59 -0
- package/dist/core/src/adapters/sources.js +235 -0
- package/dist/core/src/client/aggregate.d.ts +94 -0
- package/dist/core/src/client/aggregate.js +222 -0
- package/dist/core/src/client/groupRows.d.ts +40 -0
- package/dist/core/src/client/groupRows.js +145 -0
- package/dist/core/src/client/runClientQuery.d.ts +67 -0
- package/dist/core/src/client/runClientQuery.js +157 -0
- package/dist/core/src/columns/ColumnBuilder.d.ts +121 -0
- package/dist/core/src/columns/ColumnBuilder.js +273 -0
- package/dist/core/src/columns/cascade.d.ts +24 -0
- package/dist/core/src/columns/cascade.js +93 -0
- package/dist/core/src/columns/deriveOperators.d.ts +38 -0
- package/dist/core/src/columns/deriveOperators.js +94 -0
- package/dist/core/src/columns/expandSorting.d.ts +19 -0
- package/dist/core/src/columns/expandSorting.js +52 -0
- package/dist/core/src/columns/helper.d.ts +196 -0
- package/dist/core/src/columns/helper.js +250 -0
- package/dist/core/src/columns/labels.d.ts +12 -0
- package/dist/core/src/columns/labels.js +21 -0
- package/dist/core/src/contract.d.ts +12 -0
- package/dist/core/src/contract.js +12 -0
- package/dist/core/src/contracts/aiColumnMeta.d.ts +102 -0
- package/dist/core/src/contracts/aiColumnMeta.js +197 -0
- package/dist/core/src/contracts/describeColumns.d.ts +48 -0
- package/dist/core/src/contracts/describeColumns.js +40 -0
- package/dist/core/src/contracts/exportData.d.ts +150 -0
- package/dist/core/src/contracts/exportData.js +228 -0
- package/dist/core/src/contracts/index.d.ts +6 -0
- package/dist/core/src/contracts/index.js +12 -0
- package/dist/core/src/contracts/legacyUrl.d.ts +47 -0
- package/dist/core/src/contracts/legacyUrl.js +156 -0
- package/dist/core/src/contracts/preset.d.ts +104 -0
- package/dist/core/src/contracts/preset.js +141 -0
- package/dist/core/src/contracts/presetStore.d.ts +81 -0
- package/dist/core/src/contracts/presetStore.js +146 -0
- package/dist/core/src/contracts/usePresets.d.ts +51 -0
- package/dist/core/src/contracts/usePresets.js +170 -0
- package/dist/core/src/defaults.d.ts +7 -0
- package/dist/core/src/defaults.js +9 -0
- package/dist/core/src/filters/codec.d.ts +20 -0
- package/dist/core/src/filters/codec.js +61 -0
- package/dist/core/src/filters/date.d.ts +30 -0
- package/dist/core/src/filters/date.js +179 -0
- package/dist/core/src/filters/describe.d.ts +45 -0
- package/dist/core/src/filters/describe.js +189 -0
- package/dist/core/src/filters/kind.d.ts +52 -0
- package/dist/core/src/filters/kind.js +110 -0
- package/dist/core/src/filters/kinds/_list.d.ts +13 -0
- package/dist/core/src/filters/kinds/_list.js +42 -0
- package/dist/core/src/filters/kinds/boolean.d.ts +3 -0
- package/dist/core/src/filters/kinds/boolean.js +21 -0
- package/dist/core/src/filters/kinds/cascade.d.ts +6 -0
- package/dist/core/src/filters/kinds/cascade.js +16 -0
- package/dist/core/src/filters/kinds/commonCode.d.ts +3 -0
- package/dist/core/src/filters/kinds/commonCode.js +13 -0
- package/dist/core/src/filters/kinds/date.d.ts +9 -0
- package/dist/core/src/filters/kinds/date.js +32 -0
- package/dist/core/src/filters/kinds/enum.d.ts +4 -0
- package/dist/core/src/filters/kinds/enum.js +13 -0
- package/dist/core/src/filters/kinds/index.d.ts +49 -0
- package/dist/core/src/filters/kinds/index.js +39 -0
- package/dist/core/src/filters/kinds/linear.d.ts +5 -0
- package/dist/core/src/filters/kinds/linear.js +16 -0
- package/dist/core/src/filters/kinds/number.d.ts +5 -0
- package/dist/core/src/filters/kinds/number.js +19 -0
- package/dist/core/src/filters/kinds/period.d.ts +4 -0
- package/dist/core/src/filters/kinds/period.js +17 -0
- package/dist/core/src/filters/kinds/relation.d.ts +5 -0
- package/dist/core/src/filters/kinds/relation.js +17 -0
- package/dist/core/src/filters/kinds/schedule.d.ts +5 -0
- package/dist/core/src/filters/kinds/schedule.js +16 -0
- package/dist/core/src/filters/kinds/text.d.ts +4 -0
- package/dist/core/src/filters/kinds/text.js +18 -0
- package/dist/core/src/filters/linear.d.ts +33 -0
- package/dist/core/src/filters/linear.js +65 -0
- package/dist/core/src/filters/list.d.ts +32 -0
- package/dist/core/src/filters/list.js +87 -0
- package/dist/core/src/filters/number.d.ts +17 -0
- package/dist/core/src/filters/number.js +82 -0
- package/dist/core/src/filters/registry.d.ts +23 -0
- package/dist/core/src/filters/registry.js +121 -0
- package/dist/core/src/filters/relation.d.ts +26 -0
- package/dist/core/src/filters/relation.js +75 -0
- package/dist/core/src/filters/schedule.d.ts +21 -0
- package/dist/core/src/filters/schedule.js +60 -0
- package/dist/core/src/filters/text.d.ts +44 -0
- package/dist/core/src/filters/text.js +127 -0
- package/dist/core/src/hooks/index.d.ts +6 -0
- package/dist/core/src/hooks/index.js +6 -0
- package/dist/core/src/hooks/useDataTable.d.ts +13 -0
- package/dist/core/src/hooks/useDataTable.js +109 -0
- package/dist/core/src/hooks/useGrouping.d.ts +33 -0
- package/dist/core/src/hooks/useGrouping.js +57 -0
- package/dist/core/src/hooks/useSearchHistory.d.ts +20 -0
- package/dist/core/src/hooks/useSearchHistory.js +52 -0
- package/dist/core/src/hooks/useTableData.d.ts +25 -0
- package/dist/core/src/hooks/useTableData.js +49 -0
- package/dist/core/src/hooks/useTableFromDefinition.d.ts +47 -0
- package/dist/core/src/hooks/useTableFromDefinition.js +174 -0
- package/dist/core/src/hooks/useTableSearch.d.ts +10 -0
- package/dist/core/src/hooks/useTableSearch.js +434 -0
- package/dist/core/src/hooks/useUrlSync.d.ts +64 -0
- package/dist/core/src/hooks/useUrlSync.js +145 -0
- package/dist/core/src/index.d.ts +38 -0
- package/dist/core/src/index.js +43 -0
- package/dist/core/src/pivot/runClientPivot.d.ts +101 -0
- package/dist/core/src/pivot/runClientPivot.js +230 -0
- package/dist/core/src/pivot/transforms.d.ts +19 -0
- package/dist/core/src/pivot/transforms.js +105 -0
- package/dist/core/src/registry.d.ts +46 -0
- package/dist/core/src/registry.js +67 -0
- package/dist/core/src/types/column.d.ts +213 -0
- package/dist/core/src/types/column.js +1 -0
- package/dist/core/src/types/data.d.ts +63 -0
- package/dist/core/src/types/data.js +1 -0
- package/dist/core/src/types/definition.d.ts +239 -0
- package/dist/core/src/types/definition.js +59 -0
- package/dist/core/src/types/filter.d.ts +94 -0
- package/dist/core/src/types/filter.js +1 -0
- package/dist/core/src/types/filterKind.d.ts +204 -0
- package/dist/core/src/types/filterKind.js +1 -0
- package/dist/core/src/types/grouping.d.ts +80 -0
- package/dist/core/src/types/grouping.js +4 -0
- package/dist/core/src/types/index.d.ts +8 -0
- package/dist/core/src/types/index.js +8 -0
- package/dist/core/src/types/operators.d.ts +64 -0
- package/dist/core/src/types/operators.js +108 -0
- package/dist/core/src/types/request.d.ts +114 -0
- package/dist/core/src/types/request.js +1 -0
- package/dist/core/src/types/search.d.ts +112 -0
- package/dist/core/src/types/search.js +1 -0
- package/dist/core/src/types/sources.d.ts +84 -0
- package/dist/core/src/types/sources.js +1 -0
- package/dist/core/src/types/table.d.ts +40 -0
- package/dist/core/src/types/table.js +1 -0
- package/dist/core/src/utils/compare.d.ts +13 -0
- package/dist/core/src/utils/compare.js +53 -0
- package/dist/core/src/utils/dateText.d.ts +12 -0
- package/dist/core/src/utils/dateText.js +30 -0
- package/dist/core/src/utils/getValue.d.ts +9 -0
- package/dist/core/src/utils/getValue.js +32 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/mui/src/TableLayout.d.ts +75 -0
- package/dist/mui/src/TableLayout.js +162 -0
- package/dist/mui/src/TableScreen.d.ts +70 -0
- package/dist/mui/src/TableScreen.js +174 -0
- package/dist/mui/src/addons/FilterModal.d.ts +45 -0
- package/dist/mui/src/addons/FilterModal.js +39 -0
- package/dist/mui/src/addons/FilterStatusModal.d.ts +40 -0
- package/dist/mui/src/addons/FilterStatusModal.js +68 -0
- package/dist/mui/src/addons/PresetBar.d.ts +56 -0
- package/dist/mui/src/addons/PresetBar.js +145 -0
- package/dist/mui/src/addons/ShareDropdown.d.ts +35 -0
- package/dist/mui/src/addons/ShareDropdown.js +41 -0
- package/dist/mui/src/addons/searchStore.d.ts +44 -0
- package/dist/mui/src/addons/searchStore.js +112 -0
- package/dist/mui/src/addons/searchSummary.d.ts +106 -0
- package/dist/mui/src/addons/searchSummary.js +109 -0
- package/dist/mui/src/columns/displayColumns.d.ts +100 -0
- package/dist/mui/src/columns/displayColumns.js +174 -0
- package/dist/mui/src/content/CardContent.d.ts +24 -0
- package/dist/mui/src/content/CardContent.js +25 -0
- package/dist/mui/src/content/ColumnMenu.d.ts +43 -0
- package/dist/mui/src/content/ColumnMenu.js +40 -0
- package/dist/mui/src/content/ColumnVisibilityMenu.d.ts +14 -0
- package/dist/mui/src/content/ColumnVisibilityMenu.js +37 -0
- package/dist/mui/src/content/EditCell.d.ts +19 -0
- package/dist/mui/src/content/EditCell.js +61 -0
- package/dist/mui/src/content/HeaderCell.d.ts +59 -0
- package/dist/mui/src/content/HeaderCell.js +88 -0
- package/dist/mui/src/content/SelectionActionBar.d.ts +17 -0
- package/dist/mui/src/content/SelectionActionBar.js +19 -0
- package/dist/mui/src/content/SortControl.d.ts +17 -0
- package/dist/mui/src/content/SortControl.js +45 -0
- package/dist/mui/src/content/TableContent.d.ts +191 -0
- package/dist/mui/src/content/TableContent.js +525 -0
- package/dist/mui/src/content/TableErrorFallback.d.ts +24 -0
- package/dist/mui/src/content/TableErrorFallback.js +29 -0
- package/dist/mui/src/content/cellError.d.ts +13 -0
- package/dist/mui/src/content/cellError.js +20 -0
- package/dist/mui/src/content/cellRenderers.d.ts +71 -0
- package/dist/mui/src/content/cellRenderers.js +127 -0
- package/dist/mui/src/content/cellValue.d.ts +27 -0
- package/dist/mui/src/content/cellValue.js +82 -0
- package/dist/mui/src/content/columnOrder.d.ts +7 -0
- package/dist/mui/src/content/columnOrder.js +48 -0
- package/dist/mui/src/content/density.d.ts +13 -0
- package/dist/mui/src/content/density.js +12 -0
- package/dist/mui/src/content/menuItems.d.ts +118 -0
- package/dist/mui/src/content/menuItems.js +128 -0
- package/dist/mui/src/content/pinning.d.ts +17 -0
- package/dist/mui/src/content/pinning.js +65 -0
- package/dist/mui/src/exporters/index.d.ts +1 -0
- package/dist/mui/src/exporters/index.js +1 -0
- package/dist/mui/src/exporters/useExportFormatters.d.ts +13 -0
- package/dist/mui/src/exporters/useExportFormatters.js +17 -0
- package/dist/mui/src/filter/FilterArea.d.ts +40 -0
- package/dist/mui/src/filter/FilterArea.js +37 -0
- package/dist/mui/src/filter/FilterInput.d.ts +14 -0
- package/dist/mui/src/filter/FilterInput.js +18 -0
- package/dist/mui/src/filter/inputs/DateFilterInput.d.ts +14 -0
- package/dist/mui/src/filter/inputs/DateFilterInput.js +112 -0
- package/dist/mui/src/filter/inputs/LinearFilterInput.d.ts +10 -0
- package/dist/mui/src/filter/inputs/LinearFilterInput.js +35 -0
- package/dist/mui/src/filter/inputs/NumberFilterInput.d.ts +12 -0
- package/dist/mui/src/filter/inputs/NumberFilterInput.js +111 -0
- package/dist/mui/src/filter/inputs/OperatorMenu.d.ts +14 -0
- package/dist/mui/src/filter/inputs/OperatorMenu.js +25 -0
- package/dist/mui/src/filter/inputs/RelationFilterInput.d.ts +11 -0
- package/dist/mui/src/filter/inputs/RelationFilterInput.js +67 -0
- package/dist/mui/src/filter/inputs/ScheduleFilterInput.d.ts +8 -0
- package/dist/mui/src/filter/inputs/ScheduleFilterInput.js +17 -0
- package/dist/mui/src/filter/inputs/SelectFilterInput.d.ts +16 -0
- package/dist/mui/src/filter/inputs/SelectFilterInput.js +57 -0
- package/dist/mui/src/filter/inputs/TextFilterInput.d.ts +13 -0
- package/dist/mui/src/filter/inputs/TextFilterInput.js +55 -0
- package/dist/mui/src/filter/kinds.d.ts +58 -0
- package/dist/mui/src/filter/kinds.js +103 -0
- package/dist/mui/src/grouping/AggregateChip.d.ts +55 -0
- package/dist/mui/src/grouping/AggregateChip.js +128 -0
- package/dist/mui/src/grouping/AggregationChips.d.ts +49 -0
- package/dist/mui/src/grouping/AggregationChips.js +80 -0
- package/dist/mui/src/grouping/AggregationSettingsButton.d.ts +14 -0
- package/dist/mui/src/grouping/AggregationSettingsButton.js +19 -0
- package/dist/mui/src/grouping/GroupingBar.d.ts +59 -0
- package/dist/mui/src/grouping/GroupingBar.js +267 -0
- package/dist/mui/src/grouping/StepExpandButton.d.ts +12 -0
- package/dist/mui/src/grouping/StepExpandButton.js +18 -0
- package/dist/mui/src/grouping/groupRow.d.ts +68 -0
- package/dist/mui/src/grouping/groupRow.js +129 -0
- package/dist/mui/src/headers/defaultHeader.d.ts +28 -0
- package/dist/mui/src/headers/defaultHeader.js +90 -0
- package/dist/mui/src/headers/defineHeader.d.ts +21 -0
- package/dist/mui/src/headers/defineHeader.js +68 -0
- package/dist/mui/src/headers/index.d.ts +5 -0
- package/dist/mui/src/headers/index.js +3 -0
- package/dist/mui/src/headers/meta.d.ts +18 -0
- package/dist/mui/src/headers/meta.js +11 -0
- package/dist/mui/src/headers/types.d.ts +84 -0
- package/dist/mui/src/headers/types.js +1 -0
- package/dist/mui/src/index.d.ts +110 -0
- package/dist/mui/src/index.js +79 -0
- package/dist/mui/src/layout/ResizeHandle.d.ts +30 -0
- package/dist/mui/src/layout/ResizeHandle.js +66 -0
- package/dist/mui/src/menus/columnMenu.d.ts +45 -0
- package/dist/mui/src/menus/columnMenu.js +144 -0
- package/dist/mui/src/menus/copy.d.ts +5 -0
- package/dist/mui/src/menus/copy.js +25 -0
- package/dist/mui/src/menus/index.d.ts +6 -0
- package/dist/mui/src/menus/index.js +4 -0
- package/dist/mui/src/menus/resolve.d.ts +15 -0
- package/dist/mui/src/menus/resolve.js +60 -0
- package/dist/mui/src/menus/rowMenu.d.ts +46 -0
- package/dist/mui/src/menus/rowMenu.js +76 -0
- package/dist/mui/src/pagination/PaginationArea.d.ts +16 -0
- package/dist/mui/src/pagination/PaginationArea.js +23 -0
- package/dist/mui/src/pivot/PivotTable.d.ts +18 -0
- package/dist/mui/src/pivot/PivotTable.js +100 -0
- package/dist/mui/src/provider/KokoTableProvider.d.ts +184 -0
- package/dist/mui/src/provider/KokoTableProvider.js +118 -0
- package/dist/mui/src/provider/labels.d.ts +85 -0
- package/dist/mui/src/provider/labels.js +104 -0
- package/dist/mui/src/registry.d.ts +30 -0
- package/dist/mui/src/registry.js +5 -0
- package/dist/mui/src/toolbar/GlobalFilterField.d.ts +36 -0
- package/dist/mui/src/toolbar/GlobalFilterField.js +78 -0
- package/dist/mui/src/virtual/VirtualTableContent.d.ts +41 -0
- package/dist/mui/src/virtual/VirtualTableContent.js +58 -0
- package/dist/mui/src/virtual/VirtualTableScreen.d.ts +13 -0
- package/dist/mui/src/virtual/VirtualTableScreen.js +23 -0
- package/dist/mui/src/virtual.d.ts +4 -0
- package/dist/mui/src/virtual.js +4 -0
- package/dist/mui/src/virtualColumns/VirtualColumnCard.d.ts +26 -0
- package/dist/mui/src/virtualColumns/VirtualColumnCard.js +29 -0
- package/dist/mui/src/virtualColumns/VirtualColumnDialog.d.ts +27 -0
- package/dist/mui/src/virtualColumns/VirtualColumnDialog.js +154 -0
- package/dist/mui/src/virtualColumns/VirtualColumnSection.d.ts +31 -0
- package/dist/mui/src/virtualColumns/VirtualColumnSection.js +55 -0
- package/dist/mui/src/virtualColumns/expression.d.ts +68 -0
- package/dist/mui/src/virtualColumns/expression.js +489 -0
- package/dist/mui/src/virtualColumns/useVirtualColumns.d.ts +67 -0
- package/dist/mui/src/virtualColumns/useVirtualColumns.js +111 -0
- package/dist/mui/src/virtualColumns/virtualColumnDefs.d.ts +29 -0
- package/dist/mui/src/virtualColumns/virtualColumnDefs.js +51 -0
- package/dist/mui-virtual.d.ts +1 -0
- package/dist/mui-virtual.js +2 -0
- package/dist/mui.d.ts +1 -0
- package/dist/mui.js +2 -0
- package/dist/query/src/index.d.ts +6 -0
- package/dist/query/src/index.js +7 -0
- package/dist/query/src/serverPivot.d.ts +42 -0
- package/dist/query/src/serverPivot.js +153 -0
- package/dist/query/src/useServerGrouping.d.ts +52 -0
- package/dist/query/src/useServerGrouping.js +186 -0
- package/dist/query/src/useServerTable.d.ts +20 -0
- package/dist/query/src/useServerTable.js +106 -0
- package/dist/query/src/useServerTableData.d.ts +48 -0
- package/dist/query/src/useServerTableData.js +64 -0
- package/dist/query/src/wire.d.ts +16 -0
- package/dist/query/src/wire.js +32 -0
- package/dist/query.d.ts +1 -0
- package/dist/query.js +2 -0
- package/package.json +125 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// ── 필터 구역 ──
|
|
2
|
+
export { FilterArea, resolveFilterGridSize } from "./filter/FilterArea";
|
|
3
|
+
export { FilterInput } from "./filter/FilterInput";
|
|
4
|
+
export { OperatorMenu, operatorLabel, OPERATOR_LABELS } from "./filter/inputs/OperatorMenu";
|
|
5
|
+
export { TextFilterInput } from "./filter/inputs/TextFilterInput";
|
|
6
|
+
export { NumberFilterInput } from "./filter/inputs/NumberFilterInput";
|
|
7
|
+
export { DateFilterInput, periodRange } from "./filter/inputs/DateFilterInput";
|
|
8
|
+
export { SelectFilterInput, MultiSelectFilterInput, BooleanFilterInput, } from "./filter/inputs/SelectFilterInput";
|
|
9
|
+
export { RelationFilterInput } from "./filter/inputs/RelationFilterInput";
|
|
10
|
+
export { LinearFilterInput } from "./filter/inputs/LinearFilterInput";
|
|
11
|
+
export { ScheduleFilterInput } from "./filter/inputs/ScheduleFilterInput";
|
|
12
|
+
// ── 필터 kind ──
|
|
13
|
+
export { withEditor, builtinFilterEditors, defaultEditorForVariant, registerBuiltinEditors, resolveFilterEditor, resolveFilterChip, } from "./filter/kinds";
|
|
14
|
+
// ── 콘텐츠 구역 ──
|
|
15
|
+
export { TableContent } from "./content/TableContent";
|
|
16
|
+
export { HeaderCell } from "./content/HeaderCell";
|
|
17
|
+
export { ColumnMenu, moveColumn, canMoveColumn } from "./content/ColumnMenu";
|
|
18
|
+
export { ColumnVisibilityMenu } from "./content/ColumnVisibilityMenu";
|
|
19
|
+
export { SelectionActionBar } from "./content/SelectionActionBar";
|
|
20
|
+
export { TableErrorFallback, errorStatus, isBadRequestError } from "./content/TableErrorFallback";
|
|
21
|
+
export { EditCell } from "./content/EditCell";
|
|
22
|
+
export { renderCellValue } from "./content/cellValue";
|
|
23
|
+
export { getCellError, cellErrorSx } from "./content/cellError";
|
|
24
|
+
export { pinnedSx } from "./content/pinning";
|
|
25
|
+
export { resolveDensity } from "./content/density";
|
|
26
|
+
// ── 표시 전용 컬럼 (행 선택·확장·액션·번호) ──
|
|
27
|
+
export { selectionColumn, expandColumn, rowActionsColumn, rowNumberColumn, withDisplayColumns, canExpandRow, isDisplayColumnId, DISPLAY_COLUMN_PREFIX, LEGACY_DISPLAY_COLUMN_PREFIX, LEGACY_DISPLAY_COLUMN_IDS, ROW_SELECT_COLUMN_ID, ROW_EXPAND_COLUMN_ID, ROW_ACTIONS_COLUMN_ID, ROW_NUMBER_COLUMN_ID, } from "./columns/displayColumns";
|
|
28
|
+
// ── 툴바 ──
|
|
29
|
+
export { GlobalFilterField } from "./toolbar/GlobalFilterField";
|
|
30
|
+
export { SortControl } from "./content/SortControl";
|
|
31
|
+
export { CardContent } from "./content/CardContent";
|
|
32
|
+
// ── 그룹핑 ──
|
|
33
|
+
export { GroupingBar } from "./grouping/GroupingBar";
|
|
34
|
+
export { StepExpandButton } from "./grouping/StepExpandButton";
|
|
35
|
+
export { GROUP_DRAG_COLUMN_TYPE, GROUP_DRAG_INDEX_TYPE, GROUP_BATCH_SIZE_OPTIONS, GROUP_REJECTED_MESSAGE, } from "./grouping/GroupingBar";
|
|
36
|
+
export { AggregationChips, aggregatableColumns, toggleAggregation } from "./grouping/AggregationChips";
|
|
37
|
+
export { AggregateChip, getAggIcon, formatAggValue, AGG_CHIP_COLORS } from "./grouping/AggregateChip";
|
|
38
|
+
export { GROUP_DEPTH_INDENT, GROUP_ROW_BG_SHADES, groupRowBgColor, resolveGroupValue, renderAggregateCellContent, isCategoricalColumn, } from "./grouping/groupRow";
|
|
39
|
+
// ── 페이지네이션 구역 ──
|
|
40
|
+
export { PaginationArea } from "./pagination/PaginationArea";
|
|
41
|
+
// ── 피벗 ──
|
|
42
|
+
export { PivotTable } from "./pivot/PivotTable";
|
|
43
|
+
// ── 레이아웃 ──
|
|
44
|
+
export { TopFilterLayout, SideFilterLayout, SearchBar } from "./TableLayout";
|
|
45
|
+
export { ResizeHandle, useResizeWidth, clampWidth } from "./layout/ResizeHandle";
|
|
46
|
+
// ── 가상 컬럼 ──
|
|
47
|
+
export { useVirtualColumns, virtualColumnSlots } from "./virtualColumns/useVirtualColumns";
|
|
48
|
+
export { virtualColumnDefs, virtualColumnFields } from "./virtualColumns/virtualColumnDefs";
|
|
49
|
+
export { validateExpression, evaluateExpression, evaluateTemplate, evaluateVirtualColumn, applyVirtualColumns, tokenizeExpression, normalizeExpression, referencedFields, describeExpression, TEMPLATE_FIELD_PATTERN, } from "./virtualColumns/expression";
|
|
50
|
+
export { VirtualColumnSection } from "./virtualColumns/VirtualColumnSection";
|
|
51
|
+
export { VirtualColumnDialog } from "./virtualColumns/VirtualColumnDialog";
|
|
52
|
+
export { VirtualColumnCard, VIRTUAL_NUMBER_OPERATORS } from "./virtualColumns/VirtualColumnCard";
|
|
53
|
+
// ── groupedColumnMode ──
|
|
54
|
+
export { arrangeGroupedColumns } from "./content/TableContent";
|
|
55
|
+
// ── 애드온 ──
|
|
56
|
+
export { summarizeSearch, formatConditionValue, countActiveConditions, isActiveCondition, EMPTY_VALUE_TEXT, VALUELESS_TEXT, } from "./addons/searchSummary";
|
|
57
|
+
export { FilterStatusContent, FilterStatusModal, FilterStatusButton, useFilterStatusSummary, } from "./addons/FilterStatusModal";
|
|
58
|
+
export { ShareDropdown } from "./addons/ShareDropdown";
|
|
59
|
+
export { createSearchStore, useSearchStore, useSearchStoreBridge } from "./addons/searchStore";
|
|
60
|
+
export { FilterModal, FilterModalButton } from "./addons/FilterModal";
|
|
61
|
+
// ── 커스터마이즈 ──
|
|
62
|
+
export { KokoTableProvider, useKokoTableConfig, resolveTableProps, mergeKokoTableConfig, DEFAULT_KOKO_TABLE_CONFIG, DEFAULT_TABLE_DEFAULTS, toRegistry, applyPatch, } from "./provider/KokoTableProvider";
|
|
63
|
+
export { DEFAULT_LABELS, DEFAULT_UI_LABELS, mergeLabels } from "./provider/labels";
|
|
64
|
+
export { MenuItemList, ContextMenu, defaultColumnMenuItems, defaultRowMenuItems, defaultGroupRowMenuItems, visibleMenuItems, createHeaderContext, createColumnMenuCtx, createRowMenuCtx, } from "./content/menuItems";
|
|
65
|
+
// ── 레지스트리 (확장점 공통) ──
|
|
66
|
+
export { createRegistry, isRegistry } from "./registry";
|
|
67
|
+
// ── 헤더·메뉴 ──
|
|
68
|
+
export { defineHeader, resolveHeaderDef, applyHeaderRules, headerMetaOf, defaultHeader, compactHeader, headerRegistry, defaultHeaderSlots, renderDefaultHeader, materializeHeader, SortArrow, headerRuleMetaOf, resolveCellAlign, } from "./headers";
|
|
69
|
+
export { columnMenuRegistry, defaultColumnMenuDefs, columnHeaderText, COLUMN_MENU_GROUP, rowMenuRegistry, defaultRowMenuDefs, rowCopyText, ROW_MENU_GROUP, resolveMenuDefs, menuSpecsFrom, copyToClipboard, } from "./menus";
|
|
70
|
+
// ── 검색 debounce·프리셋 ──
|
|
71
|
+
export { PresetBar } from "./addons/PresetBar";
|
|
72
|
+
// ── 테이블 정의 ──
|
|
73
|
+
export { TableScreen, TableScreenBase, displayColumnOptionsOf } from "./TableScreen";
|
|
74
|
+
// ── 셀·집계·export 레지스트리 (설계 문서 4절 — 정의·기본 세트·Provider 읽기 훅) ──
|
|
75
|
+
export { cellRenderers, defineCellRenderer, resolveCellRenderer, toCellRendererDefs, useCellRenderers, layerRegistry, registriesOf, isEmptyCellValue, BUILTIN_CELL_RENDERERS, } from "./content/cellRenderers";
|
|
76
|
+
export { useAggregations, aggChipColor } from "./grouping/AggregateChip";
|
|
77
|
+
export { useExportFormatters } from "./exporters";
|
|
78
|
+
// ── 집계 상세 설정 ──
|
|
79
|
+
export { AggregationSettingsButton } from "./grouping/AggregationSettingsButton";
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type MouseEvent as ReactMouseEvent } from "react";
|
|
2
|
+
export interface UseResizeWidthOptions {
|
|
3
|
+
width: number;
|
|
4
|
+
min?: number;
|
|
5
|
+
max?: number;
|
|
6
|
+
/** true 면 마우스가 왼쪽으로 갈 때 넓어진다 (패널이 오른쪽에 있을 때) */
|
|
7
|
+
reversed?: boolean;
|
|
8
|
+
/** 드래그 중 매 이동마다 · 끝날 때 호출 */
|
|
9
|
+
onChange?: (width: number) => void;
|
|
10
|
+
onDragEnd?: (width: number) => void;
|
|
11
|
+
}
|
|
12
|
+
export interface ResizeHandleBinding {
|
|
13
|
+
isDragging: boolean;
|
|
14
|
+
onMouseDown: (event: ReactMouseEvent<HTMLElement>) => void;
|
|
15
|
+
}
|
|
16
|
+
export declare function clampWidth(width: number, min: number, max: number): number;
|
|
17
|
+
/**
|
|
18
|
+
* 마우스 드래그로 폭을 바꾸는 훅 — 기존 ERP `useResize`(px 모드) 대응.
|
|
19
|
+
* 폭 상태는 호출부가 가진다(`width` + `onChange`) — 제어/비제어를 호출부가 고른다.
|
|
20
|
+
*/
|
|
21
|
+
export declare function useResizeWidth({ width, min, max, reversed, onChange, onDragEnd, }: UseResizeWidthOptions): ResizeHandleBinding;
|
|
22
|
+
export interface ResizeHandleProps extends ResizeHandleBinding {
|
|
23
|
+
/** 기준 요소의 어느 변에 붙일지 — 부모에 `position: relative` 가 필요하다 */
|
|
24
|
+
position: "left" | "right";
|
|
25
|
+
label?: string;
|
|
26
|
+
/** 드래그 감지 폭 (px) */
|
|
27
|
+
hitSize?: number;
|
|
28
|
+
}
|
|
29
|
+
/** 세로 드래그 핸들 — hover/드래그 중에만 선이 보인다 */
|
|
30
|
+
export declare function ResizeHandle({ isDragging, onMouseDown, position, label, hitSize }: ResizeHandleProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
|
+
import { Box } from "@mui/material";
|
|
4
|
+
export function clampWidth(width, min, max) {
|
|
5
|
+
return Math.min(max, Math.max(min, Math.round(width)));
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* 마우스 드래그로 폭을 바꾸는 훅 — 기존 ERP `useResize`(px 모드) 대응.
|
|
9
|
+
* 폭 상태는 호출부가 가진다(`width` + `onChange`) — 제어/비제어를 호출부가 고른다.
|
|
10
|
+
*/
|
|
11
|
+
export function useResizeWidth({ width, min = 200, max = 800, reversed = false, onChange, onDragEnd, }) {
|
|
12
|
+
const [isDragging, setDragging] = useState(false);
|
|
13
|
+
const start = useRef({ x: 0, width });
|
|
14
|
+
const latest = useRef(width);
|
|
15
|
+
latest.current = width;
|
|
16
|
+
const onChangeRef = useRef(onChange);
|
|
17
|
+
onChangeRef.current = onChange;
|
|
18
|
+
const onDragEndRef = useRef(onDragEnd);
|
|
19
|
+
onDragEndRef.current = onDragEnd;
|
|
20
|
+
const onMouseDown = useCallback((event) => {
|
|
21
|
+
event.preventDefault();
|
|
22
|
+
start.current = { x: event.clientX, width: latest.current };
|
|
23
|
+
setDragging(true);
|
|
24
|
+
}, []);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!isDragging)
|
|
27
|
+
return;
|
|
28
|
+
const move = (event) => {
|
|
29
|
+
const delta = event.clientX - start.current.x;
|
|
30
|
+
const next = clampWidth(start.current.width + (reversed ? -delta : delta), min, max);
|
|
31
|
+
if (next !== latest.current) {
|
|
32
|
+
latest.current = next;
|
|
33
|
+
onChangeRef.current?.(next);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const up = () => {
|
|
37
|
+
setDragging(false);
|
|
38
|
+
onDragEndRef.current?.(latest.current);
|
|
39
|
+
};
|
|
40
|
+
document.addEventListener("mousemove", move);
|
|
41
|
+
document.addEventListener("mouseup", up);
|
|
42
|
+
const { userSelect, cursor } = document.body.style;
|
|
43
|
+
document.body.style.userSelect = "none";
|
|
44
|
+
document.body.style.cursor = "col-resize";
|
|
45
|
+
return () => {
|
|
46
|
+
document.removeEventListener("mousemove", move);
|
|
47
|
+
document.removeEventListener("mouseup", up);
|
|
48
|
+
document.body.style.userSelect = userSelect;
|
|
49
|
+
document.body.style.cursor = cursor;
|
|
50
|
+
};
|
|
51
|
+
}, [isDragging, min, max, reversed]);
|
|
52
|
+
return { isDragging, onMouseDown };
|
|
53
|
+
}
|
|
54
|
+
/** 세로 드래그 핸들 — hover/드래그 중에만 선이 보인다 */
|
|
55
|
+
export function ResizeHandle({ isDragging, onMouseDown, position, label = "패널 폭 조절", hitSize = 12 }) {
|
|
56
|
+
return (_jsx(Box, { role: "separator", "aria-orientation": "vertical", "aria-label": label, onMouseDown: onMouseDown, sx: {
|
|
57
|
+
position: "absolute", top: 0, bottom: 0, width: hitSize, zIndex: 2, cursor: "col-resize",
|
|
58
|
+
[position]: -hitSize / 2,
|
|
59
|
+
display: "flex", alignItems: "stretch", justifyContent: "center",
|
|
60
|
+
touchAction: "none",
|
|
61
|
+
"&:hover > span, &:active > span": { opacity: 1 },
|
|
62
|
+
}, children: _jsx(Box, { component: "span", sx: {
|
|
63
|
+
width: 3, borderRadius: 1, bgcolor: "primary.main",
|
|
64
|
+
opacity: isDragging ? 1 : 0, transition: "opacity 0.15s",
|
|
65
|
+
} }) }));
|
|
66
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { RowData } from "@tanstack/react-table";
|
|
2
|
+
import { type MenuItemDef, type MenuPatch, type Registry } from "../registry";
|
|
3
|
+
import { type AggregationSpec } from "../../../core/src/index";
|
|
4
|
+
import type { HeaderCapabilities, HeaderContext } from "../headers/types";
|
|
5
|
+
/**
|
|
6
|
+
* 컬럼 메뉴 항목이 받는 컨텍스트 (설계 3절).
|
|
7
|
+
* `HeaderContext` + 그룹핑 상태 + 필터 열기(소비자가 `onOpenFilter` 를 줄 때만) + 클립보드.
|
|
8
|
+
* `can` 은 헤더 `rules` 와 TanStack 옵션을 합친 결과 — 기본 항목의 `when` 이 본다.
|
|
9
|
+
*/
|
|
10
|
+
export interface ColumnMenuCtx<T extends RowData = any> extends HeaderContext<T> {
|
|
11
|
+
/** 판별자 — 행 메뉴 항목을 컬럼 레지스트리에 넣으면 컴파일 오류가 나게 */
|
|
12
|
+
readonly kind: "column";
|
|
13
|
+
can: HeaderCapabilities;
|
|
14
|
+
grouping: string[];
|
|
15
|
+
/** 있을 때만 `group.add` / `group.remove` 가 보인다 */
|
|
16
|
+
setGrouping?: (grouping: string[]) => void;
|
|
17
|
+
/** 있을 때만 `filter.open` 이 보인다 — `TableContent`/Provider `onOpenFilter` */
|
|
18
|
+
openFilter?: () => void;
|
|
19
|
+
/** 현재 집계 명세 — `setAggregation` 과 함께 있을 때만 "집계" 항목이 보인다(그룹핑 중, 집계 가능 컬럼) */
|
|
20
|
+
aggregation?: AggregationSpec;
|
|
21
|
+
setAggregation?: (next: AggregationSpec) => void;
|
|
22
|
+
copy: (text: string) => void;
|
|
23
|
+
}
|
|
24
|
+
export type ColumnMenuItemDef<T extends RowData = any> = MenuItemDef<ColumnMenuCtx<T>>;
|
|
25
|
+
export type ColumnMenuPatch<T extends RowData = any> = MenuPatch<ColumnMenuCtx<T>>;
|
|
26
|
+
export declare const COLUMN_MENU_GROUP: {
|
|
27
|
+
readonly sort: "sort";
|
|
28
|
+
readonly pin: "pin";
|
|
29
|
+
readonly move: "move";
|
|
30
|
+
readonly visibility: "visibility";
|
|
31
|
+
readonly group: "group";
|
|
32
|
+
readonly filter: "filter";
|
|
33
|
+
readonly size: "size";
|
|
34
|
+
readonly copy: "copy";
|
|
35
|
+
};
|
|
36
|
+
/** 헤더 문자열 — 헤더가 문자열이면 그것, 아니면 id */
|
|
37
|
+
export declare function columnHeaderText<T extends RowData>(ctx: Pick<ColumnMenuCtx<T>, "column">): string;
|
|
38
|
+
/**
|
|
39
|
+
* 기본 컬럼 메뉴 — 정렬 / 고정 / 이동 / 숨기기 / 그룹 기준 / 필터 열기 / 너비 초기화 / 헤더 복사.
|
|
40
|
+
* 각 항목의 `when` 이 규칙(`ctx.can`)·상태를 본다. 라벨은 `ctx.labels.ui` 에서 온다.
|
|
41
|
+
* Provider `menus.column` 으로 add · remove · replace · order 한다.
|
|
42
|
+
*/
|
|
43
|
+
export declare const defaultColumnMenuDefs: Array<ColumnMenuItemDef<any>>;
|
|
44
|
+
/** 내장 컬럼 메뉴 레지스트리 — Provider 가 `with(patch)` 로 파생한다. 전역을 바꾸려면 `register` */
|
|
45
|
+
export declare const columnMenuRegistry: Registry<ColumnMenuItemDef<any>>;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import PushPinIcon from "@mui/icons-material/PushPin";
|
|
3
|
+
import PushPinOutlinedIcon from "@mui/icons-material/PushPinOutlined";
|
|
4
|
+
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
|
5
|
+
import ArrowForwardIcon from "@mui/icons-material/ArrowForward";
|
|
6
|
+
import ArrowUpwardIcon from "@mui/icons-material/ArrowUpward";
|
|
7
|
+
import ArrowDownwardIcon from "@mui/icons-material/ArrowDownward";
|
|
8
|
+
import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
|
|
9
|
+
import ClearIcon from "@mui/icons-material/Clear";
|
|
10
|
+
import AccountTreeIcon from "@mui/icons-material/AccountTree";
|
|
11
|
+
import FilterAltIcon from "@mui/icons-material/FilterAlt";
|
|
12
|
+
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
|
|
13
|
+
import SettingsBackupRestoreIcon from "@mui/icons-material/SettingsBackupRestore";
|
|
14
|
+
import { createRegistry } from "../registry";
|
|
15
|
+
import { canMoveColumn, moveColumn } from "../content/columnOrder";
|
|
16
|
+
import FunctionsIcon from "@mui/icons-material/Functions";
|
|
17
|
+
import { aggregations } from "../../../core/src/index";
|
|
18
|
+
import { aggregatableColumns, toggleAggregation } from "../grouping/AggregationChips";
|
|
19
|
+
export const COLUMN_MENU_GROUP = {
|
|
20
|
+
sort: "sort", pin: "pin", move: "move", visibility: "visibility", group: "group", filter: "filter", size: "size", copy: "copy",
|
|
21
|
+
};
|
|
22
|
+
/** 헤더 문자열 — 헤더가 문자열이면 그것, 아니면 id */
|
|
23
|
+
export function columnHeaderText(ctx) {
|
|
24
|
+
const header = ctx.column.columnDef.header;
|
|
25
|
+
return typeof header === "string" ? header : ctx.column.id;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 기본 컬럼 메뉴 — 정렬 / 고정 / 이동 / 숨기기 / 그룹 기준 / 필터 열기 / 너비 초기화 / 헤더 복사.
|
|
29
|
+
* 각 항목의 `when` 이 규칙(`ctx.can`)·상태를 본다. 라벨은 `ctx.labels.ui` 에서 온다.
|
|
30
|
+
* Provider `menus.column` 으로 add · remove · replace · order 한다.
|
|
31
|
+
*/
|
|
32
|
+
export const defaultColumnMenuDefs = [
|
|
33
|
+
{
|
|
34
|
+
id: "sort.asc", group: COLUMN_MENU_GROUP.sort, order: 10,
|
|
35
|
+
label: (ctx) => ctx.labels.ui.sortAsc, icon: _jsx(ArrowUpwardIcon, { fontSize: "small" }),
|
|
36
|
+
when: (ctx) => !!ctx.sort && ctx.can.canSort,
|
|
37
|
+
disabled: (ctx) => !!ctx.sortState && !ctx.sortState.desc,
|
|
38
|
+
run: (ctx) => ctx.sort?.toggleSort(ctx.column.id, { desc: false }),
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: "sort.desc", group: COLUMN_MENU_GROUP.sort, order: 11,
|
|
42
|
+
label: (ctx) => ctx.labels.ui.sortDesc, icon: _jsx(ArrowDownwardIcon, { fontSize: "small" }),
|
|
43
|
+
when: (ctx) => !!ctx.sort && ctx.can.canSort,
|
|
44
|
+
disabled: (ctx) => !!ctx.sortState && ctx.sortState.desc,
|
|
45
|
+
run: (ctx) => ctx.sort?.toggleSort(ctx.column.id, { desc: true }),
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
id: "sort.clear", group: COLUMN_MENU_GROUP.sort, order: 12,
|
|
49
|
+
label: (ctx) => ctx.labels.ui.clearSort, icon: _jsx(ClearIcon, { fontSize: "small" }),
|
|
50
|
+
when: (ctx) => !!ctx.sort && ctx.can.canSort,
|
|
51
|
+
disabled: (ctx) => !ctx.sortState,
|
|
52
|
+
run: (ctx) => ctx.sort?.clearSort(ctx.column.id),
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: "pin.left", group: COLUMN_MENU_GROUP.pin, order: 20,
|
|
56
|
+
label: (ctx) => ctx.labels.ui.pinLeft, icon: _jsx(PushPinOutlinedIcon, { fontSize: "small" }),
|
|
57
|
+
when: (ctx) => ctx.can.canPin,
|
|
58
|
+
disabled: (ctx) => ctx.column.getIsPinned() === "left",
|
|
59
|
+
run: (ctx) => ctx.column.pin("left"),
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: "pin.right", group: COLUMN_MENU_GROUP.pin, order: 21,
|
|
63
|
+
label: (ctx) => ctx.labels.ui.pinRight,
|
|
64
|
+
icon: _jsx(PushPinOutlinedIcon, { fontSize: "small", sx: { transform: "scaleX(-1)" } }),
|
|
65
|
+
when: (ctx) => ctx.can.canPin,
|
|
66
|
+
disabled: (ctx) => ctx.column.getIsPinned() === "right",
|
|
67
|
+
run: (ctx) => ctx.column.pin("right"),
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: "pin.clear", group: COLUMN_MENU_GROUP.pin, order: 22,
|
|
71
|
+
label: (ctx) => ctx.labels.ui.unpin, icon: _jsx(PushPinIcon, { fontSize: "small" }),
|
|
72
|
+
when: (ctx) => ctx.can.canPin,
|
|
73
|
+
disabled: (ctx) => !ctx.column.getIsPinned(),
|
|
74
|
+
run: (ctx) => ctx.column.pin(false),
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: "move.left", group: COLUMN_MENU_GROUP.move, order: 30,
|
|
78
|
+
label: (ctx) => ctx.labels.ui.moveLeft, icon: _jsx(ArrowBackIcon, { fontSize: "small" }),
|
|
79
|
+
disabled: (ctx) => !canMoveColumn(ctx.table, ctx.column.id, "left"),
|
|
80
|
+
run: (ctx) => moveColumn(ctx.table, ctx.column.id, "left"),
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
id: "move.right", group: COLUMN_MENU_GROUP.move, order: 31,
|
|
84
|
+
label: (ctx) => ctx.labels.ui.moveRight, icon: _jsx(ArrowForwardIcon, { fontSize: "small" }),
|
|
85
|
+
disabled: (ctx) => !canMoveColumn(ctx.table, ctx.column.id, "right"),
|
|
86
|
+
run: (ctx) => moveColumn(ctx.table, ctx.column.id, "right"),
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "hide", group: COLUMN_MENU_GROUP.visibility, order: 40,
|
|
90
|
+
label: (ctx) => ctx.labels.ui.hide, icon: _jsx(VisibilityOffIcon, { fontSize: "small" }),
|
|
91
|
+
when: (ctx) => ctx.can.canHide,
|
|
92
|
+
run: (ctx) => ctx.column.toggleVisibility(false),
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: "group.add", group: COLUMN_MENU_GROUP.group, order: 50,
|
|
96
|
+
label: (ctx) => ctx.labels.ui.groupBy, icon: _jsx(AccountTreeIcon, { fontSize: "small" }),
|
|
97
|
+
when: (ctx) => !!ctx.setGrouping && ctx.can.canGroup && !ctx.grouping.includes(ctx.column.id),
|
|
98
|
+
run: (ctx) => ctx.setGrouping?.([...ctx.grouping, ctx.column.id]),
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
// 집계 함수 토글 — 그룹핑 중이고 이 컬럼이 집계 후보일 때만. 함수마다 항목 하나(체크 표시).
|
|
102
|
+
id: "aggregate", group: COLUMN_MENU_GROUP.group, order: 55,
|
|
103
|
+
label: (ctx) => ctx.labels.ui.aggregation, icon: _jsx(FunctionsIcon, { fontSize: "small" }),
|
|
104
|
+
when: (ctx) => !!ctx.setAggregation && ctx.grouping.length > 0 && !ctx.grouping.includes(ctx.column.id)
|
|
105
|
+
&& aggregatableColumns(ctx.table.options.columns, { columnIds: [ctx.column.id] }).length > 0,
|
|
106
|
+
run: () => { },
|
|
107
|
+
items: (ctx) => {
|
|
108
|
+
const [candidate] = aggregatableColumns(ctx.table.options.columns, { columnIds: [ctx.column.id] });
|
|
109
|
+
const current = ctx.aggregation?.[ctx.column.id] ?? [];
|
|
110
|
+
return (candidate?.keys ?? []).map((fn) => ({
|
|
111
|
+
id: `aggregate.${fn}`,
|
|
112
|
+
// 부모 항목은 items 로 대체되므로 라벨에 "집계 · " 를 붙여 맥락을 남긴다
|
|
113
|
+
label: `${ctx.labels.ui.aggregation} · ${aggregations.get(fn)?.label ?? fn}${current.includes(fn) ? " ✓" : ""}`,
|
|
114
|
+
run: () => ctx.setAggregation?.(toggleAggregation(ctx.aggregation ?? {}, ctx.column.id, fn)),
|
|
115
|
+
}));
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
id: "group.remove", group: COLUMN_MENU_GROUP.group, order: 51,
|
|
120
|
+
label: (ctx) => ctx.labels.ui.ungroup, icon: _jsx(AccountTreeIcon, { fontSize: "small" }),
|
|
121
|
+
when: (ctx) => !!ctx.setGrouping && ctx.grouping.includes(ctx.column.id),
|
|
122
|
+
run: (ctx) => ctx.setGrouping?.(ctx.grouping.filter((id) => id !== ctx.column.id)),
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
id: "filter.open", group: COLUMN_MENU_GROUP.filter, order: 60,
|
|
126
|
+
label: (ctx) => ctx.labels.ui.openFilter, icon: _jsx(FilterAltIcon, { fontSize: "small" }),
|
|
127
|
+
when: (ctx) => !!ctx.openFilter && ctx.can.canFilter,
|
|
128
|
+
run: (ctx) => ctx.openFilter?.(),
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
id: "resize.reset", group: COLUMN_MENU_GROUP.size, order: 70,
|
|
132
|
+
label: (ctx) => ctx.labels.ui.resetColumnSize, icon: _jsx(SettingsBackupRestoreIcon, { fontSize: "small" }),
|
|
133
|
+
when: (ctx) => ctx.can.canResize,
|
|
134
|
+
disabled: (ctx) => ctx.column.getSize() === (ctx.column.columnDef.size ?? ctx.table._getDefaultColumnDef().size),
|
|
135
|
+
run: (ctx) => ctx.column.resetSize(),
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
id: "copy.header", group: COLUMN_MENU_GROUP.copy, order: 80,
|
|
139
|
+
label: (ctx) => ctx.labels.ui.copyHeader, icon: _jsx(ContentCopyIcon, { fontSize: "small" }),
|
|
140
|
+
run: (ctx) => ctx.copy(columnHeaderText(ctx)),
|
|
141
|
+
},
|
|
142
|
+
];
|
|
143
|
+
/** 내장 컬럼 메뉴 레지스트리 — Provider 가 `with(patch)` 로 파생한다. 전역을 바꾸려면 `register` */
|
|
144
|
+
export const columnMenuRegistry = createRegistry(defaultColumnMenuDefs);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 클립보드 복사 — 메뉴 항목의 `ctx.copy(text)`.
|
|
3
|
+
* `navigator.clipboard` 가 없으면(비보안 컨텍스트·구형 브라우저) 조용히 실패한다.
|
|
4
|
+
*/
|
|
5
|
+
export function copyToClipboard(text) {
|
|
6
|
+
const clipboard = typeof navigator !== "undefined" ? navigator.clipboard : undefined;
|
|
7
|
+
if (clipboard?.writeText) {
|
|
8
|
+
void clipboard.writeText(text).catch(() => { });
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (typeof document === "undefined" || typeof document.execCommand !== "function")
|
|
12
|
+
return;
|
|
13
|
+
const area = document.createElement("textarea");
|
|
14
|
+
area.value = text;
|
|
15
|
+
area.setAttribute("readonly", "");
|
|
16
|
+
area.style.position = "fixed";
|
|
17
|
+
area.style.opacity = "0";
|
|
18
|
+
document.body.appendChild(area);
|
|
19
|
+
area.select();
|
|
20
|
+
try {
|
|
21
|
+
document.execCommand("copy");
|
|
22
|
+
}
|
|
23
|
+
catch { /* 무시 */ }
|
|
24
|
+
document.body.removeChild(area);
|
|
25
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { columnMenuRegistry, defaultColumnMenuDefs, columnHeaderText, COLUMN_MENU_GROUP } from "./columnMenu";
|
|
2
|
+
export type { ColumnMenuCtx, ColumnMenuItemDef, ColumnMenuPatch } from "./columnMenu";
|
|
3
|
+
export { rowMenuRegistry, defaultRowMenuDefs, rowCopyText, ROW_MENU_GROUP } from "./rowMenu";
|
|
4
|
+
export type { RowMenuCtx, RowMenuItemDef, RowMenuPatch, GroupRowCtx } from "./rowMenu";
|
|
5
|
+
export { resolveMenuDefs, menuSpecsFrom } from "./resolve";
|
|
6
|
+
export { copyToClipboard } from "./copy";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { columnMenuRegistry, defaultColumnMenuDefs, columnHeaderText, COLUMN_MENU_GROUP } from "./columnMenu";
|
|
2
|
+
export { rowMenuRegistry, defaultRowMenuDefs, rowCopyText, ROW_MENU_GROUP } from "./rowMenu";
|
|
3
|
+
export { resolveMenuDefs, menuSpecsFrom } from "./resolve";
|
|
4
|
+
export { copyToClipboard } from "./copy";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { MenuItemDef } from "../registry";
|
|
2
|
+
import type { MenuItemSpec } from "../content/menuItems";
|
|
3
|
+
/**
|
|
4
|
+
* 레지스트리 항목 → 실제로 보일 항목.
|
|
5
|
+
* 1. `when` 이 거짓인 항목 제거
|
|
6
|
+
* 2. 숫자 `order` 로 정렬 — `order` 가 없는 항목은 레지스트리 위치를 지킨다
|
|
7
|
+
* (바로 앞의 `order` 있는 항목 뒤에 붙는다. 그래서 `with({ order: [...] })` 로 정한 자리도 살아 있다)
|
|
8
|
+
* 3. `items` 가 있으면 그 자리에 펼침 (펼쳐진 항목에도 `when` 적용)
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveMenuDefs<Ctx>(defs: ReadonlyArray<MenuItemDef<Ctx>>, ctx: Ctx): Array<MenuItemDef<Ctx>>;
|
|
11
|
+
/**
|
|
12
|
+
* 보일 항목 → `MenuItemList` 가 그리는 `MenuItemSpec` 배열.
|
|
13
|
+
* `group` 이 바뀌는 자리와 `divider: true` 항목 앞에 구분선을 넣는다 (앞·뒤·연속 구분선은 그릴 때 합쳐진다).
|
|
14
|
+
*/
|
|
15
|
+
export declare function menuSpecsFrom<Ctx>(defs: ReadonlyArray<MenuItemDef<Ctx>>, ctx: Ctx): Array<MenuItemSpec<Ctx>>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
function resolveFn(value, ctx) {
|
|
2
|
+
return typeof value === "function" ? value(ctx) : value;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* 레지스트리 항목 → 실제로 보일 항목.
|
|
6
|
+
* 1. `when` 이 거짓인 항목 제거
|
|
7
|
+
* 2. 숫자 `order` 로 정렬 — `order` 가 없는 항목은 레지스트리 위치를 지킨다
|
|
8
|
+
* (바로 앞의 `order` 있는 항목 뒤에 붙는다. 그래서 `with({ order: [...] })` 로 정한 자리도 살아 있다)
|
|
9
|
+
* 3. `items` 가 있으면 그 자리에 펼침 (펼쳐진 항목에도 `when` 적용)
|
|
10
|
+
*/
|
|
11
|
+
export function resolveMenuDefs(defs, ctx) {
|
|
12
|
+
let anchor = Number.NEGATIVE_INFINITY;
|
|
13
|
+
const keyed = defs.map((def, index) => {
|
|
14
|
+
if (def.order !== undefined)
|
|
15
|
+
anchor = def.order;
|
|
16
|
+
return { def, key: def.order ?? anchor, index };
|
|
17
|
+
});
|
|
18
|
+
const visible = keyed
|
|
19
|
+
.filter(({ def }) => !def.when || def.when(ctx))
|
|
20
|
+
.sort((a, b) => a.key - b.key || a.index - b.index)
|
|
21
|
+
.map(({ def }) => def);
|
|
22
|
+
const out = [];
|
|
23
|
+
for (const def of visible) {
|
|
24
|
+
if (def.items) {
|
|
25
|
+
for (const child of def.items(ctx)) {
|
|
26
|
+
if (child.when && !child.when(ctx))
|
|
27
|
+
continue;
|
|
28
|
+
out.push({ group: def.group, ...child });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
out.push(def);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 보일 항목 → `MenuItemList` 가 그리는 `MenuItemSpec` 배열.
|
|
39
|
+
* `group` 이 바뀌는 자리와 `divider: true` 항목 앞에 구분선을 넣는다 (앞·뒤·연속 구분선은 그릴 때 합쳐진다).
|
|
40
|
+
*/
|
|
41
|
+
export function menuSpecsFrom(defs, ctx) {
|
|
42
|
+
const specs = [];
|
|
43
|
+
let lastGroup;
|
|
44
|
+
let first = true;
|
|
45
|
+
for (const def of resolveMenuDefs(defs, ctx)) {
|
|
46
|
+
const groupChanged = !first && def.group !== lastGroup;
|
|
47
|
+
if (def.divider || groupChanged)
|
|
48
|
+
specs.push({ key: `divider-${def.id}`, divider: true });
|
|
49
|
+
specs.push({
|
|
50
|
+
key: def.id,
|
|
51
|
+
label: resolveFn(def.label, ctx),
|
|
52
|
+
icon: resolveFn(def.icon, ctx),
|
|
53
|
+
disabled: def.disabled ? def.disabled(ctx) : false,
|
|
54
|
+
onClick: (c) => def.run(c),
|
|
55
|
+
});
|
|
56
|
+
lastGroup = def.group;
|
|
57
|
+
first = false;
|
|
58
|
+
}
|
|
59
|
+
return specs;
|
|
60
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Row, RowData, Table } from "@tanstack/react-table";
|
|
2
|
+
import type { GroupTreeNode } from "../../../core/src/index";
|
|
3
|
+
import { type MenuItemDef, type MenuPatch, type Registry } from "../registry";
|
|
4
|
+
import type { KokoTableLabels } from "../provider/labels";
|
|
5
|
+
/** 그룹 행 우클릭 시 `ctx.group` — ERP `GroupRowContextMenu` 가 받던 것 */
|
|
6
|
+
export interface GroupRowCtx<T extends RowData = any> {
|
|
7
|
+
node: GroupTreeNode<T>;
|
|
8
|
+
depth: number;
|
|
9
|
+
expanded: boolean;
|
|
10
|
+
toggle: () => void;
|
|
11
|
+
/** 이 그룹 아래 남은 그룹 기준 컬럼 id (다음 단계부터) */
|
|
12
|
+
subLevels: string[];
|
|
13
|
+
/** `TableContent onExpandGroupToDepth` 가 있을 때만 */
|
|
14
|
+
expandToDepth?: (depth: number) => void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 행 메뉴 항목이 받는 컨텍스트 (설계 3절).
|
|
18
|
+
* 설계와 다른 점: `row` 는 선택 — 그룹 행에는 TanStack `Row` 가 없다(`group` 만 있다). `labels` 를 더했다.
|
|
19
|
+
*/
|
|
20
|
+
export interface RowMenuCtx<T extends RowData = any> {
|
|
21
|
+
/** 판별자 — 컬럼 메뉴 항목을 행 레지스트리에 넣으면 컴파일 오류가 나게 */
|
|
22
|
+
readonly kind: "row";
|
|
23
|
+
/** 말단 행. 그룹 행이면 없다 */
|
|
24
|
+
row?: Row<T>;
|
|
25
|
+
table: Table<T>;
|
|
26
|
+
/** 그룹 행일 때 */
|
|
27
|
+
group?: GroupRowCtx<T>;
|
|
28
|
+
copy: (text: string) => void;
|
|
29
|
+
labels: KokoTableLabels;
|
|
30
|
+
}
|
|
31
|
+
export type RowMenuItemDef<T extends RowData = any> = MenuItemDef<RowMenuCtx<T>>;
|
|
32
|
+
export type RowMenuPatch<T extends RowData = any> = MenuPatch<RowMenuCtx<T>>;
|
|
33
|
+
export declare const ROW_MENU_GROUP: {
|
|
34
|
+
readonly copy: "copy";
|
|
35
|
+
readonly expand: "expand";
|
|
36
|
+
readonly depth: "depth";
|
|
37
|
+
};
|
|
38
|
+
/** 행 복사 텍스트 — 보이는 셀 값을 탭으로 잇는다 (스프레드시트에 붙여 넣기 좋게) */
|
|
39
|
+
export declare function rowCopyText<T extends RowData>(row: Row<T>): string;
|
|
40
|
+
/**
|
|
41
|
+
* 기본 행 메뉴 — 말단 행: 행 복사 / 그룹 행: 이 그룹 펼치기·접기, N단계까지 펼치기(단계마다), 하위 펼치기.
|
|
42
|
+
* Provider `menus.row` 로 add · remove · replace · order 한다.
|
|
43
|
+
*/
|
|
44
|
+
export declare const defaultRowMenuDefs: Array<RowMenuItemDef<any>>;
|
|
45
|
+
/** 내장 행 메뉴 레지스트리 — Provider 가 `with(patch)` 로 파생한다 */
|
|
46
|
+
export declare const rowMenuRegistry: Registry<RowMenuItemDef<any>>;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
|
|
3
|
+
import AccountTreeIcon from "@mui/icons-material/AccountTree";
|
|
4
|
+
import UnfoldLessIcon from "@mui/icons-material/UnfoldLess";
|
|
5
|
+
import UnfoldMoreIcon from "@mui/icons-material/UnfoldMore";
|
|
6
|
+
import { createRegistry } from "../registry";
|
|
7
|
+
export const ROW_MENU_GROUP = { copy: "copy", expand: "expand", depth: "depth" };
|
|
8
|
+
/** 그룹 컬럼의 표시 이름 — 헤더가 문자열이면 그것, 아니면 id */
|
|
9
|
+
function columnNameOf(table, columnId) {
|
|
10
|
+
const header = table.getColumn(columnId)?.columnDef.header;
|
|
11
|
+
return typeof header === "string" ? header : columnId;
|
|
12
|
+
}
|
|
13
|
+
/** 행 복사 텍스트 — 보이는 셀 값을 탭으로 잇는다 (스프레드시트에 붙여 넣기 좋게) */
|
|
14
|
+
export function rowCopyText(row) {
|
|
15
|
+
return row.getVisibleCells()
|
|
16
|
+
.filter((cell) => !cell.column.id.startsWith("koko-row-"))
|
|
17
|
+
.map((cell) => {
|
|
18
|
+
const value = cell.getValue();
|
|
19
|
+
return value === null || value === undefined ? "" : typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
20
|
+
})
|
|
21
|
+
.join("\t");
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 기본 행 메뉴 — 말단 행: 행 복사 / 그룹 행: 이 그룹 펼치기·접기, N단계까지 펼치기(단계마다), 하위 펼치기.
|
|
25
|
+
* Provider `menus.row` 로 add · remove · replace · order 한다.
|
|
26
|
+
*/
|
|
27
|
+
export const defaultRowMenuDefs = [
|
|
28
|
+
{
|
|
29
|
+
id: "copy.row", group: ROW_MENU_GROUP.copy, order: 10,
|
|
30
|
+
label: (ctx) => ctx.labels.ui.copyRow, icon: _jsx(ContentCopyIcon, { fontSize: "small" }),
|
|
31
|
+
when: (ctx) => !!ctx.row,
|
|
32
|
+
run: (ctx) => { if (ctx.row)
|
|
33
|
+
ctx.copy(rowCopyText(ctx.row)); },
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "expand", group: ROW_MENU_GROUP.expand, order: 20,
|
|
37
|
+
label: (ctx) => ctx.labels.ui.expandGroup, icon: _jsx(UnfoldMoreIcon, { fontSize: "small" }),
|
|
38
|
+
when: (ctx) => !!ctx.group && !ctx.group.expanded,
|
|
39
|
+
run: (ctx) => ctx.group?.toggle(),
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: "collapse", group: ROW_MENU_GROUP.expand, order: 21,
|
|
43
|
+
label: (ctx) => ctx.labels.ui.collapseGroup, icon: _jsx(UnfoldLessIcon, { fontSize: "small" }),
|
|
44
|
+
when: (ctx) => !!ctx.group && ctx.group.expanded,
|
|
45
|
+
run: (ctx) => ctx.group?.toggle(),
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
id: "expandToDepth", group: ROW_MENU_GROUP.depth, order: 30,
|
|
49
|
+
label: (ctx) => ctx.labels.ui.expandChildren,
|
|
50
|
+
when: (ctx) => !!ctx.group?.expandToDepth && ctx.group.subLevels.length > 0,
|
|
51
|
+
run: () => { },
|
|
52
|
+
// 단계마다 하나 + "하위 펼치기"
|
|
53
|
+
items: (ctx) => {
|
|
54
|
+
const group = ctx.group;
|
|
55
|
+
const expandToDepth = group.expandToDepth;
|
|
56
|
+
const perLevel = group.subLevels.map((columnId, index) => {
|
|
57
|
+
const target = group.depth + 1 + index;
|
|
58
|
+
return {
|
|
59
|
+
id: `expandToDepth.${target}`,
|
|
60
|
+
label: ctx.labels.ui.expandToDepth(index + 1, columnNameOf(ctx.table, columnId)),
|
|
61
|
+
icon: _jsx(AccountTreeIcon, { fontSize: "small" }),
|
|
62
|
+
run: () => expandToDepth(target),
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
return [
|
|
66
|
+
...perLevel,
|
|
67
|
+
{
|
|
68
|
+
id: "expandToDepth.all", label: ctx.labels.ui.expandChildren, icon: _jsx(UnfoldMoreIcon, { fontSize: "small" }),
|
|
69
|
+
run: () => expandToDepth(group.depth + group.subLevels.length + 1),
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
/** 내장 행 메뉴 레지스트리 — Provider 가 `with(patch)` 로 파생한다 */
|
|
76
|
+
export const rowMenuRegistry = createRegistry(defaultRowMenuDefs);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { RowData } from "@tanstack/react-table";
|
|
2
|
+
import type { AnyPaginationSource } from "../../../core/src/index";
|
|
3
|
+
export interface PaginationAreaProps<T extends RowData> {
|
|
4
|
+
source: AnyPaginationSource<T>;
|
|
5
|
+
/** 미지정 시 `KokoTableProvider defaults.pageSizeOptions` (기본 15/30/50/100) */
|
|
6
|
+
pageSizeOptions?: number[];
|
|
7
|
+
/** 총 건수 표시 */
|
|
8
|
+
showTotal?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 페이지네이션 구역.
|
|
12
|
+
*
|
|
13
|
+
* `PaginationSource` 만 요구하므로 테이블 인스턴스가 없어도 붙는다 —
|
|
14
|
+
* 카드 화면에서는 `paginationSource(search, data)` 를 넘긴다.
|
|
15
|
+
*/
|
|
16
|
+
export declare function PaginationArea<T extends RowData>({ source, pageSizeOptions: pageSizeOptionsProp, showTotal, }: PaginationAreaProps<T>): import("react").JSX.Element;
|