@vmscloud/moz-ui-grid-vue 0.1.41

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 (213) hide show
  1. package/README.md +71 -0
  2. package/dist/MozGrid.vue.d.ts +127 -0
  3. package/dist/bridge/VueRenderer.d.ts +37 -0
  4. package/dist/bridge/fieldBuilder.d.ts +9 -0
  5. package/dist/bridge/lifecycle.d.ts +6 -0
  6. package/dist/bridge/templateRegistry.d.ts +8 -0
  7. package/dist/chunks/index-BDQ0HlwR.js +3404 -0
  8. package/dist/chunks/index-D5KJLBGW.cjs +14 -0
  9. package/dist/chunks/notification.contract-BTOch6ed.js +16 -0
  10. package/dist/chunks/notification.contract-oFkBaE2U.cjs +1 -0
  11. package/dist/compat/MozGridVue.vue.d.ts +645 -0
  12. package/dist/compat/MozPivotVue.vue.d.ts +606 -0
  13. package/dist/compat/index.d.ts +9 -0
  14. package/dist/compat/legacyGridAliases.d.ts +8 -0
  15. package/dist/composables/useGridPreset.d.ts +19 -0
  16. package/dist/contracts/UserLayoutInstance.d.ts +38 -0
  17. package/dist/contracts/notification.contract.d.ts +41 -0
  18. package/dist/contracts/userLayout.contract.d.ts +16 -0
  19. package/dist/index.cjs +26 -0
  20. package/dist/index.d.ts +24 -0
  21. package/dist/index.js +90599 -0
  22. package/dist/legacy/components/common/Dragging.d.ts +17 -0
  23. package/dist/legacy/components/common/Dragging.vue.d.ts +49 -0
  24. package/dist/legacy/components/common/custom-cell/FormulaEngine.d.ts +256 -0
  25. package/dist/legacy/components/common/custom-cell/FormulaInput.vue.d.ts +33 -0
  26. package/dist/legacy/components/common/custom-cell/GridCustomCell.vue.d.ts +23 -0
  27. package/dist/legacy/components/common/custom-cell/useFormulaAutocomplete.d.ts +44 -0
  28. package/dist/legacy/components/common/excel/ClientExcelUploadPopup.vue.d.ts +201 -0
  29. package/dist/legacy/components/common/excel/assets/IconDropZone.vue.d.ts +2 -0
  30. package/dist/legacy/components/common/excel/assets/IconFileUpload.vue.d.ts +2 -0
  31. package/dist/legacy/components/common/filter/GridFilter.vue.d.ts +23 -0
  32. package/dist/legacy/components/common/footer/GridFooter.vue.d.ts +29 -0
  33. package/dist/legacy/components/common/sort/GridSort.vue.d.ts +23 -0
  34. package/dist/legacy/components/common/toolbar/GridSearchInput.vue.d.ts +33 -0
  35. package/dist/legacy/components/grid/MozGridVue.vue.d.ts +2041 -0
  36. package/dist/legacy/components/grid/MozGridVueCore.vue.d.ts +118 -0
  37. package/dist/legacy/components/grid/bulk-editor/GridBulkEditor.vue.d.ts +10 -0
  38. package/dist/legacy/components/grid/column-settings/AlignPicker.vue.d.ts +10 -0
  39. package/dist/legacy/components/grid/column-settings/ColorSwatchPicker.vue.d.ts +11 -0
  40. package/dist/legacy/components/grid/column-settings/ColumnListItem.vue.d.ts +17 -0
  41. package/dist/legacy/components/grid/column-settings/ColumnOptionsPanel.vue.d.ts +32 -0
  42. package/dist/legacy/components/grid/column-settings/FontSizePicker.vue.d.ts +10 -0
  43. package/dist/legacy/components/grid/column-settings/FontStyleToggles.vue.d.ts +15 -0
  44. package/dist/legacy/components/grid/column-settings/MaskPresetPicker.vue.d.ts +14 -0
  45. package/dist/legacy/components/grid/context-menu/GridContextMenu.vue.d.ts +208 -0
  46. package/dist/legacy/components/grid/group-panel/GroupPanel.vue.d.ts +18 -0
  47. package/dist/legacy/components/grid/toolbar/ColumnPicker.vue.d.ts +17 -0
  48. package/dist/legacy/components/grid/toolbar/ColumnSettings.vue.d.ts +30 -0
  49. package/dist/legacy/components/grid/toolbar/GridOptionModal.vue.d.ts +211 -0
  50. package/dist/legacy/components/grid/toolbar/GridToolBox.vue.d.ts +69 -0
  51. package/dist/legacy/components/pivot/MozPivotVue.vue.d.ts +1868 -0
  52. package/dist/legacy/components/pivot/PivotContextMenu.vue.d.ts +634 -0
  53. package/dist/legacy/components/pivot/PivotFieldChip.vue.d.ts +16 -0
  54. package/dist/legacy/components/pivot/PivotFieldDropZone.vue.d.ts +26 -0
  55. package/dist/legacy/components/pivot/PivotFieldPanel.vue.d.ts +28 -0
  56. package/dist/legacy/components/pivot/PivotOptionModal.vue.d.ts +534 -0
  57. package/dist/legacy/components/pivot/PivotToolBox.vue.d.ts +79 -0
  58. package/dist/legacy/components/pivot/chart/EChart.vue.d.ts +13 -0
  59. package/dist/legacy/components/pivot/chart/MozPivotChart.types.d.ts +16 -0
  60. package/dist/legacy/components/pivot/chart/MozPivotChart.vue.d.ts +14 -0
  61. package/dist/legacy/components/pivot/chart/PivotChartDetail.vue.d.ts +13 -0
  62. package/dist/legacy/components/pivot/chart/PivotChartMini.vue.d.ts +18 -0
  63. package/dist/legacy/components/pivot/chart/PivotChartMultiple.vue.d.ts +18 -0
  64. package/dist/legacy/components/pivot/chart/PivotChartToolbar.vue.d.ts +38 -0
  65. package/dist/legacy/components/pivot/chart/chartUtils.d.ts +45 -0
  66. package/dist/legacy/components/pivot/chart/useChartData.d.ts +35 -0
  67. package/dist/legacy/composables/useCellTooltip.d.ts +8 -0
  68. package/dist/legacy/composables/useClientExcelExport.d.ts +24 -0
  69. package/dist/legacy/composables/useClientExcelStore.d.ts +16 -0
  70. package/dist/legacy/composables/useColumnFormatter.d.ts +45 -0
  71. package/dist/legacy/composables/useColumnSettings.d.ts +35 -0
  72. package/dist/legacy/composables/useContextMenu.d.ts +71 -0
  73. package/dist/legacy/composables/useGridBulkEditor.d.ts +36 -0
  74. package/dist/legacy/composables/useGridChanges.d.ts +28 -0
  75. package/dist/legacy/composables/useGridColumns.d.ts +37 -0
  76. package/dist/legacy/composables/useGridCustomCell.d.ts +34 -0
  77. package/dist/legacy/composables/useGridEvents.d.ts +14 -0
  78. package/dist/legacy/composables/useGridFilter.d.ts +38 -0
  79. package/dist/legacy/composables/useGridInstance.d.ts +16 -0
  80. package/dist/legacy/composables/useGridSelect.d.ts +18 -0
  81. package/dist/legacy/composables/useGridSelection.d.ts +18 -0
  82. package/dist/legacy/composables/useGridSort.d.ts +38 -0
  83. package/dist/legacy/composables/useGridUndoRedo.d.ts +28 -0
  84. package/dist/legacy/composables/useGridValidation.d.ts +28 -0
  85. package/dist/legacy/composables/useMaskPresets.d.ts +38 -0
  86. package/dist/legacy/composables/useSearchHighlight.d.ts +12 -0
  87. package/dist/legacy/icons/IconAdd.vue.d.ts +11 -0
  88. package/dist/legacy/icons/IconArrowDownWithTail.vue.d.ts +11 -0
  89. package/dist/legacy/icons/IconArrowLeft.vue.d.ts +11 -0
  90. package/dist/legacy/icons/IconArrowLeftWithTail.vue.d.ts +11 -0
  91. package/dist/legacy/icons/IconArrowRight.vue.d.ts +11 -0
  92. package/dist/legacy/icons/IconArrowUpCenter.vue.d.ts +11 -0
  93. package/dist/legacy/icons/IconArrowUpWithTail.vue.d.ts +11 -0
  94. package/dist/legacy/icons/IconChart.vue.d.ts +11 -0
  95. package/dist/legacy/icons/IconClose.vue.d.ts +13 -0
  96. package/dist/legacy/icons/IconColorPicker.vue.d.ts +11 -0
  97. package/dist/legacy/icons/IconCustomCell.vue.d.ts +11 -0
  98. package/dist/legacy/icons/IconDecide.vue.d.ts +11 -0
  99. package/dist/legacy/icons/IconDownload.vue.d.ts +11 -0
  100. package/dist/legacy/icons/IconDragHandler.vue.d.ts +11 -0
  101. package/dist/legacy/icons/IconFilter.vue.d.ts +11 -0
  102. package/dist/legacy/icons/IconInfoFilled.vue.d.ts +11 -0
  103. package/dist/legacy/icons/IconRedo.vue.d.ts +9 -0
  104. package/dist/legacy/icons/IconReset.vue.d.ts +9 -0
  105. package/dist/legacy/icons/IconResetGridToolbar.vue.d.ts +11 -0
  106. package/dist/legacy/icons/IconSearch.vue.d.ts +11 -0
  107. package/dist/legacy/icons/IconSetting.vue.d.ts +11 -0
  108. package/dist/legacy/icons/IconSettingFilled.vue.d.ts +11 -0
  109. package/dist/legacy/icons/IconSort.vue.d.ts +11 -0
  110. package/dist/legacy/icons/IconToastWarning.vue.d.ts +11 -0
  111. package/dist/legacy/icons/IconUndo.vue.d.ts +9 -0
  112. package/dist/legacy/icons/index.d.ts +25 -0
  113. package/dist/legacy/index.d.ts +69 -0
  114. package/dist/legacy/shared/colorPresets.d.ts +36 -0
  115. package/dist/legacy/store/UploadRefreshRegistry.d.ts +5 -0
  116. package/dist/legacy/store/excelStore.d.ts +89 -0
  117. package/dist/legacy/store/index.d.ts +231 -0
  118. package/dist/legacy/stores/index.d.ts +2 -0
  119. package/dist/legacy/stores/projectInfo/projectInfo.contract.d.ts +130 -0
  120. package/dist/legacy/stories/Autofit.stories.d.ts +9 -0
  121. package/dist/legacy/stories/CRUD.stories.d.ts +9 -0
  122. package/dist/legacy/stories/CellAttributes.stories.d.ts +19 -0
  123. package/dist/legacy/stories/CellMask.stories.d.ts +19 -0
  124. package/dist/legacy/stories/ClientExcel.stories.d.ts +8 -0
  125. package/dist/legacy/stories/Clipboard.stories.d.ts +12 -0
  126. package/dist/legacy/stories/ColumnVisibility.stories.d.ts +12 -0
  127. package/dist/legacy/stories/ColumnWidths.stories.d.ts +11 -0
  128. package/dist/legacy/stories/CustomSortFilter.stories.d.ts +7 -0
  129. package/dist/legacy/stories/DynamicRowHeight.stories.d.ts +13 -0
  130. package/dist/legacy/stories/Editors.stories.d.ts +9 -0
  131. package/dist/legacy/stories/EmptyState.stories.d.ts +10 -0
  132. package/dist/legacy/stories/FormatRow.stories.d.ts +20 -0
  133. package/dist/legacy/stories/Grouping.stories.d.ts +14 -0
  134. package/dist/legacy/stories/HeaderGroup.stories.d.ts +11 -0
  135. package/dist/legacy/stories/LargeData.stories.d.ts +19 -0
  136. package/dist/legacy/stories/MasterDetail.stories.d.ts +17 -0
  137. package/dist/legacy/stories/Merge.stories.d.ts +10 -0
  138. package/dist/legacy/stories/MultiRow.stories.d.ts +12 -0
  139. package/dist/legacy/stories/MultiRowCrud.stories.d.ts +11 -0
  140. package/dist/legacy/stories/MultiRowGroup.stories.d.ts +11 -0
  141. package/dist/legacy/stories/Pinning.stories.d.ts +44 -0
  142. package/dist/legacy/stories/Pivot.stories.d.ts +23 -0
  143. package/dist/legacy/stories/PivotAdvanced.stories.d.ts +20 -0
  144. package/dist/legacy/stories/PivotChart.stories.d.ts +23 -0
  145. package/dist/legacy/stories/PivotNonNumeric.stories.d.ts +27 -0
  146. package/dist/legacy/stories/Preset.stories.d.ts +11 -0
  147. package/dist/legacy/stories/ReactiveAPI.stories.d.ts +8 -0
  148. package/dist/legacy/stories/ReactiveSafety.stories.d.ts +28 -0
  149. package/dist/legacy/stories/Repro.stories.d.ts +36 -0
  150. package/dist/legacy/stories/RowAPI.stories.d.ts +12 -0
  151. package/dist/legacy/stories/SelectionModes.stories.d.ts +35 -0
  152. package/dist/legacy/stories/Streaming.stories.d.ts +12 -0
  153. package/dist/legacy/stories/Tree.stories.d.ts +13 -0
  154. package/dist/legacy/stories/WorkerMode.stories.d.ts +15 -0
  155. package/dist/legacy/stories/_helpers/localDataLoader.d.ts +7 -0
  156. package/dist/legacy/stories/_helpers/sampleData.d.ts +117 -0
  157. package/dist/legacy/types/FileParameter.d.ts +31 -0
  158. package/dist/legacy/types/StreamingParameter.d.ts +18 -0
  159. package/dist/legacy/types/excel.types.d.ts +48 -0
  160. package/dist/legacy/types/index.d.ts +10 -0
  161. package/dist/legacy/types/pivot-props.d.ts +140 -0
  162. package/dist/legacy/types/props.d.ts +176 -0
  163. package/dist/legacy/types/toolbar.d.ts +225 -0
  164. package/dist/legacy/utils/async/debounce.d.ts +4 -0
  165. package/dist/legacy/utils/crypto/crypto.d.ts +7 -0
  166. package/dist/legacy/utils/dialog/dialog.d.ts +19 -0
  167. package/dist/legacy/utils/excel/ExcelGuard.d.ts +73 -0
  168. package/dist/legacy/utils/excel/ExcelImportUtil.d.ts +34 -0
  169. package/dist/legacy/utils/excel/ExcelQueueManager.d.ts +57 -0
  170. package/dist/legacy/utils/excel/ExcelTaskRunner.d.ts +17 -0
  171. package/dist/legacy/utils/excel/ExcelTimeoutManager.d.ts +37 -0
  172. package/dist/legacy/utils/file.d.ts +34 -0
  173. package/dist/legacy/utils/http/rest.d.ts +5 -0
  174. package/dist/legacy/utils/id/generator.d.ts +2 -0
  175. package/dist/legacy/utils/index.d.ts +10 -0
  176. package/dist/store.cjs +1 -0
  177. package/dist/store.js +8 -0
  178. package/dist/stories/ColumnLockVisible.stories.d.ts +42 -0
  179. package/dist/stories/DateBooleanFilter.stories.d.ts +42 -0
  180. package/dist/stories/DisplayedRowApi.stories.d.ts +28 -0
  181. package/dist/stories/FieldId.stories.d.ts +113 -0
  182. package/dist/stories/GroupPanelWithoutToolbox.stories.d.ts +28 -0
  183. package/dist/stories/GroupRowRecycle.stories.d.ts +45 -0
  184. package/dist/stories/GroupTreeExpandNav.stories.d.ts +41 -0
  185. package/dist/stories/LargeData.stories.d.ts +20 -0
  186. package/dist/stories/MozGrid.stories.d.ts +51 -0
  187. package/dist/stories/PivotBarInitiallyOpen.stories.d.ts +69 -0
  188. package/dist/stories/PivotBarWithoutToolbox.stories.d.ts +39 -0
  189. package/dist/stories/SelectionApiPlayground.stories.d.ts +28 -0
  190. package/dist/stories/SingleSelectionModes.stories.d.ts +47 -0
  191. package/dist/stories/WideColumns.stories.d.ts +17 -0
  192. package/dist/style.css +1 -0
  193. package/dist/templates/CellEditor.d.ts +27 -0
  194. package/dist/templates/CellTemplate.d.ts +27 -0
  195. package/dist/templates/DetailTemplate.d.ts +60 -0
  196. package/dist/templates/GroupTemplate.d.ts +17 -0
  197. package/dist/templates/HeaderTemplate.d.ts +25 -0
  198. package/dist/types/injection-keys.d.ts +24 -0
  199. package/dist/types/slots.d.ts +49 -0
  200. package/dist/utils/excel/ExcelGuard.cjs +1 -0
  201. package/dist/utils/excel/ExcelGuard.js +74 -0
  202. package/dist/utils/excel/ExcelImportUtil.cjs +1 -0
  203. package/dist/utils/excel/ExcelImportUtil.js +61 -0
  204. package/dist/utils/excel/ExcelQueueManager.cjs +1 -0
  205. package/dist/utils/excel/ExcelQueueManager.js +10 -0
  206. package/dist/utils/excel/ExcelTaskRunner.cjs +1 -0
  207. package/dist/utils/excel/ExcelTaskRunner.js +12 -0
  208. package/dist/utils/excel/ExcelTimeoutManager.cjs +1 -0
  209. package/dist/utils/excel/ExcelTimeoutManager.js +420 -0
  210. package/docs/manual/examples.md +2385 -0
  211. package/docs/manual/reference.md +4695 -0
  212. package/docs/manual/reference_vue.md +709 -0
  213. package/package.json +129 -0
@@ -0,0 +1,709 @@
1
+ # MozGrid Vue 래퍼 레퍼런스 (Props · Emits · Slots · Instance API)
2
+
3
+ > 패키지: `@vmscloud/moz-ui-grid-vue`
4
+ > 마지막 업데이트: 2026-06-24
5
+
6
+ > 📋 **이 문서는 프레임워크 래퍼 표면만 다룹니다.** 코어 그리드 설정(`PureSheetConfig` 필드), 코어 타입, 이벤트 페이로드 형태는 코어 레퍼런스에 있습니다 → [reference.md](reference.md)
7
+ > 📋 사용 예제 코드는 [examples.md](examples.md) 참조
8
+
9
+ ## 목차
10
+
11
+ - [개요](#개요)
12
+ - [설치](#설치)
13
+ - [타입 재노출](#타입-재노출)
14
+ - [빠른 시작](#빠른-시작)
15
+ - [Props](#props)
16
+ - [v-model:coreConfig (코어 설정)](#v-modelcoreconfig-코어-설정)
17
+ - [WrapperExtras 옵션 (래퍼 전용)](#wrapperextras-옵션-래퍼-전용)
18
+ - [WrapperUIOptions — UI 표시 플래그](#wrapperuioptions--ui-표시-플래그)
19
+ - [contextMenuConfig — IContextMenuConfig](#contextmenuconfig--icontextmenuconfig)
20
+ - [emptyState — EmptyStateConfig](#emptystate--emptystateconfig)
21
+ - [sourceFields — PivotSourceField](#sourcefields--pivotsourcefield)
22
+ - [chartMap — ChartSeriesConfig](#chartmap--chartseriesconfig)
23
+ - [locale](#locale)
24
+ - [Emits](#emits)
25
+ - [Slots](#slots)
26
+ - [default 슬롯 (템플릿 컴포넌트)](#default-슬롯-템플릿-컴포넌트)
27
+ - [Chrome 네임드 슬롯](#chrome-네임드-슬롯)
28
+ - [인스턴스 API (ref / defineExpose)](#인스턴스-api-ref--defineexpose)
29
+ - [GridChrome 표면 전체](#gridchrome-표면-전체)
30
+ - [공개 컨트롤러 및 필드](#공개-컨트롤러-및-필드)
31
+ - [공개 메서드](#공개-메서드)
32
+ - [coreConfig 역류 (update:coreConfig)](#coreconfig-역류-updatecoreconfig)
33
+ - [템플릿 컴포넌트](#템플릿-컴포넌트)
34
+ - [Composables · Contracts (호스트 통합)](#composables--contracts-호스트-통합)
35
+ - [useGridPreset (내부)](#usegridpreset-내부)
36
+ - [Notification Contract](#notification-contract)
37
+ - [User Layout Contract](#user-layout-contract)
38
+ - [compat 래퍼 (MozGridVue / MozPivotVue)](#compat-래퍼-mozgridvue--mozpivotvue)
39
+ - [Legacy 익스포트](#legacy-익스포트)
40
+ - [관련 문서](#관련-문서)
41
+
42
+ ---
43
+
44
+ ## 개요
45
+
46
+ `@vmscloud/moz-ui-grid-vue`는 moz-ui-grid의 **Vue 3 어댑터**입니다. 컴포넌트 `MozGrid`는 바닐라 `GridChrome`(`@vmscloud/moz-ui-grid-wrapper`)을 얇게 감싸는 어댑터로, 그리드 로직을 직접 소유하지 않습니다. Vue는 props/emits/slots/ref를 GridChrome의 표면으로 배선하고, GridChrome 안의 코어 `PureSheet`가 실제 그리드 본체를 담당합니다.
47
+
48
+ ```
49
+ MozGrid.vue (Vue 어댑터)
50
+ └─ GridChrome (바닐라 래퍼: 툴박스 · 푸터 · 패널 · 컨텍스트 메뉴 · 슬롯 호스트)
51
+ └─ PureSheet (코어 그리드 본체 → reference.md)
52
+ ```
53
+
54
+ 따라서 본 문서는 **프레임워크 래퍼 표면**(Vue props/emits/slots/ref + 래퍼 전용 옵션)만 설명합니다. 데이터·필드·피벗·그룹·테마 등 코어 그리드 설정과 이벤트 페이로드 형태는 모두 [reference.md](reference.md)에 있습니다.
55
+
56
+ ### 주요 특징
57
+
58
+ - **2-객체 모델**: 코어 설정은 `v-model:coreConfig`(양방향), 래퍼 전용 옵션은 개별 prop으로 분리
59
+ - **얇은 어댑터**: 코어 변경(피벗 패널·옵션 모달·그룹 조작)은 `update:coreConfig`로 부모에게 역류
60
+ - **슬롯 브리지**: Vue 슬롯 콘텐츠를 코어가 렌더한 DOM에 마운트(렌더리스 템플릿 컴포넌트 + chrome 네임드 슬롯)
61
+ - **인스턴스 API**: `ref`로 GridChrome 표면 전체에 직접 접근(`.grid`는 코어 PureSheet)
62
+ - **호스트 통합 시임**: 알림(notification)·사용자 레이아웃 프리셋(userLayout) 컨트랙트
63
+
64
+ ---
65
+
66
+ ## 설치
67
+
68
+ ```bash
69
+ npm install @vmscloud/moz-ui-grid-vue
70
+ ```
71
+
72
+ ### 레지스트리
73
+
74
+ npmjs에 공개 패키지로 게시됩니다. 레지스트리 매핑이나 토큰 없이 설치되며,
75
+ 예전에 `.npmrc`에 넣어 둔 `@vmscloud:registry=https://npm.pkg.github.com` 매핑은 제거하세요.
76
+
77
+ 단, 필수 peerDependency인 `@vmscloud/moz-ui-components`는 아직 GitHub Packages(private)에만 있습니다.
78
+ 같은 스코프를 두 레지스트리에 동시에 매핑할 수 없으므로, 이 패키지만 tarball URL로 지정해 설치하세요.
79
+
80
+ ```bash
81
+ npm view @vmscloud/moz-ui-components@<version> dist.tarball --@vmscloud:registry=https://npm.pkg.github.com
82
+ pnpm add "@vmscloud/moz-ui-components@<위에서 얻은 tarball URL>"
83
+ ```
84
+
85
+ ```ini
86
+ # .npmrc — 인증은 호스트별로만 남깁니다
87
+ //npm.pkg.github.com/:_authToken=${GITHUB_PACKAGES_TOKEN}
88
+ ```
89
+
90
+ ### peerDependencies
91
+
92
+ | 의존성 | 버전 | 필수 여부 |
93
+ |--------|------|-----------|
94
+ | `vue` | `>=3.4.0` | **필수** |
95
+ | `@vmscloud/moz-ui-components` | `workspace:^` | **필수** |
96
+ | `pinia` | `>=2.1.0` | 선택 (`peerDependenciesMeta`) |
97
+ | `axios` | `>=1.6.0` | 선택 |
98
+ | `file-saver` | `>=2.0.0` | 선택 (Excel 기능 사용 시) |
99
+ | `dayjs` | `>=1.11.0` | 선택 (알림 타임스탬프 등) |
100
+
101
+ > 런타임 의존성(peer 아님): `@vmscloud/moz-ui-grid-core`, `@vmscloud/moz-ui-grid-wrapper`, `crypto-js`, `echarts`, `es-toolkit`. 별도 설치 불필요(패키지 deps).
102
+
103
+ ### 스타일 import
104
+
105
+ 그리드 스타일은 **두 개의 스타일시트**로 나뉩니다. 앱 진입점에서 한 번씩 import하세요.
106
+
107
+ ```typescript
108
+ // 1) 코어 그리드 본체 + 크롬 셸 — **필수**. 코어 그리드 클래스(.ps-*)는 래퍼 스타일시트에만 있다.
109
+ import '@vmscloud/moz-ui-grid-wrapper/style.css';
110
+ // 2) Vue 어댑터 추가 스타일
111
+ import '@vmscloud/moz-ui-grid-vue/style.css';
112
+ ```
113
+
114
+ > ⚠️ `@vmscloud/moz-ui-grid-vue/style.css`만 import하면 그리드 **본체가 스타일 없이** 렌더됩니다 — 코어 그리드 스타일(`.ps-*`)은 `@vmscloud/moz-ui-grid-wrapper`의 `style.css`에만 포함되어 있습니다(래퍼는 vue 패키지의 런타임 의존성이라 별도 설치는 불필요).
115
+
116
+ ### 서브패스 exports
117
+
118
+ | 서브패스 | 내용 |
119
+ |----------|------|
120
+ | `.` | 메인 엔트리 (`MozGrid`, 컨트랙트, 템플릿, compat 등) |
121
+ | `./style.css` | Vue 어댑터 추가 스타일 (코어 그리드 본체 스타일은 `@vmscloud/moz-ui-grid-wrapper/style.css` 필요) |
122
+ | `./store` | Excel 스토어 (`useExcelStore` / `useExcelDownloadStore` / `useExcelUploadStore`) |
123
+ | `./utils/excel/*` | Excel 유틸 5종 (`ExcelGuard` · `ExcelQueueManager` · `ExcelTaskRunner` · `ExcelTimeoutManager` · `ExcelImportUtil`) |
124
+
125
+ > 패키지 버전 0.1.40 · `type: module` · `main` `dist/index.cjs` · `module` `dist/index.js` · `types` `dist/index.d.ts`.
126
+
127
+ ### 타입 재노출
128
+
129
+ Vue 패키지는 소비처가 wrapper/core 를 직접 의존하지 않아도 핸들러를 타입 지정할 수 있도록 아래 타입을 재노출합니다 (ITSM-2026-002154).
130
+
131
+ | 타입 | 원 출처 | 용도 |
132
+ |------|---------|------|
133
+ | `MozGridCoreProps` | `@vmscloud/moz-ui-grid-wrapper` | `v-model:coreConfig` ref 의 타입 |
134
+ | `GridChrome` | `@vmscloud/moz-ui-grid-wrapper` | `@ready` 2번째 인자 · `ref.value` 표면 |
135
+ | `PureSheet` | `@vmscloud/moz-ui-grid-core` | `@ready` 1번째 인자 · `ref.value.grid` |
136
+
137
+ > 재노출하지 않으면 소비처가 `@ready` 핸들러를 `any` 로 받게 되고, 그러면 **크롬 API 변경이 소비처에 전혀 드러나지 않습니다**.
138
+
139
+ ---
140
+
141
+ ## 빠른 시작
142
+
143
+ ```vue
144
+ <script setup lang="ts">
145
+ import { ref } from 'vue';
146
+ import { MozGrid } from '@vmscloud/moz-ui-grid-vue';
147
+ // `@ready` 핸들러 인자 타입은 vue 패키지가 재노출합니다 — 소비처 package.json 에 wrapper/core
148
+ // 의존성이 없어도 타입을 지정할 수 있습니다(ITSM-2026-002154).
149
+ import type { MozGridCoreProps, GridChrome, PureSheet } from '@vmscloud/moz-ui-grid-vue';
150
+ import '@vmscloud/moz-ui-grid-wrapper/style.css'; // 코어 그리드 본체 + 셸 (필수)
151
+ import '@vmscloud/moz-ui-grid-vue/style.css'; // Vue 어댑터 추가 스타일
152
+
153
+ // 코어 그리드 설정(PureSheetConfig 평탄형). 필드별 의미는 reference.md 참조.
154
+ const coreConfig = ref<MozGridCoreProps>({
155
+ mode: 'flat',
156
+ fields: [
157
+ // id = 컬럼 식별자(가리킬 때), field = 원본 데이터 키(읽을 때, 생략 시 id).
158
+ { id: 'name', header: '이름', dataType: 'string', width: 200 },
159
+ { id: 'age', header: '나이', dataType: 'number', width: 100, showFilterIcon: false },
160
+ ],
161
+ data: [
162
+ { id: 1, name: '홍길동', age: 30 },
163
+ { id: 2, name: '김철수', age: 25 },
164
+ ],
165
+ });
166
+
167
+ const gridRef = ref();
168
+
169
+ // `@ready` 는 2개 인자를 줍니다: 코어 PureSheet + wrapper GridChrome.
170
+ function onReady(grid: PureSheet, chrome: GridChrome) {
171
+ console.log('grid ready', grid);
172
+ chrome.setPivotBarVisible(true); // 피벗 옵션 바를 처음부터 켜 두기
173
+ }
174
+ </script>
175
+
176
+ <template>
177
+ <MozGrid
178
+ ref="gridRef"
179
+ v-model:coreConfig="coreConfig"
180
+ height="600px"
181
+ :use-tool-box="true"
182
+ :use-summary-footer="true"
183
+ locale="ko"
184
+ @ready="onReady"
185
+ @cell:change="(p) => console.log('cell changed', p)"
186
+ @header:filterClick="(p) => console.log('필터 아이콘 클릭', p)"
187
+ >
188
+ <!-- 셀 커스터마이징 (렌더리스 템플릿) -->
189
+ <CellTemplate field="name" #default="{ value }">
190
+ <strong>{{ value }}</strong>
191
+ </CellTemplate>
192
+
193
+ <!-- 툴바 우측 커스텀 버튼 (scoped) -->
194
+ <template #tool-items="{ disabled, hasItem }">
195
+ <button :disabled="disabled">내보내기 {{ hasItem ? '(필터 적용됨)' : '' }}</button>
196
+ </template>
197
+ </MozGrid>
198
+ </template>
199
+ ```
200
+
201
+ ---
202
+
203
+ ## Props
204
+
205
+ `MozGrid`의 props는 `withDefaults(defineProps<WrapperExtras & { name?: string }>(), {...})`로 선언됩니다. 즉 props 표면은 **`coreConfig`(별도 v-model)** + **WrapperExtras(래퍼 전용 키)** + **`name`(Vue 전용 프리셋 식별자)** 입니다.
206
+
207
+ ### v-model:coreConfig (코어 설정)
208
+
209
+ `coreConfig`는 모든 코어 그리드 설정(데이터·필드·피벗·그룹·테마·모드 등)을 담는 **단일 양방향 모델**입니다. `defineModel<MozGridCoreProps>('coreConfig', { default: () => ({}) })`로 선언되어 `v-model:coreConfig`로 바인딩하며, `update:coreConfig`가 암시적 emit입니다.
210
+
211
+ | 속성 | 타입 | 기본값 | 설명 |
212
+ |------|------|--------|------|
213
+ | `coreConfig` | `MozGridCoreProps` | `{}` (빈 객체) | 코어 그리드 설정(평탄형 `PureSheetConfig`). **양방향 모델** |
214
+
215
+ `MozGridCoreProps`는 코어의 `PureSheetConfig`(= `FlatModeConfig | PivotModeConfig` 판별 유니온)를 단일 객체로 평탄화한 타입입니다.
216
+
217
+ ```typescript
218
+ type MozGridCoreProps =
219
+ & Partial<Omit<FlatModeConfig, 'mode'>>
220
+ & Partial<Omit<PivotModeConfig, 'mode'>>
221
+ & { mode?: 'flat' | 'pivot' };
222
+ ```
223
+
224
+ - 평탄화 이유: Vue `defineProps<union>`은 외부 prop 타입을 `Record<string, any>`로 떨어뜨리므로, flat+pivot 모든 키를 정밀 타입을 유지한 채 optional로 노출하기 위함입니다(유니온의 엄격성 — `fields` 필수, 모드 배타 키 — 은 완화되지만 어댑터엔 무해).
225
+ - **필드별 의미(`data`/`fields`/`pivot`/`group`/`theme`/`mode` 등)는 코어 레퍼런스 참조** → [reference.md Config](reference.md#config-설정). 본 문서는 "`MozGridCoreProps` === 코어 설정"이라는 사실만 명시합니다.
226
+ - 내부 그리드 변경(피벗 패널, 옵션 모달, 그룹 변경)은 `update:coreConfig`로 부모에 역류합니다. → [coreConfig 역류](#coreconfig-역류-updatecoreconfig)
227
+
228
+ > `coreConfig`의 `fields`는 코어에 전달되기 전에 `cell`/`header`/`editor` 슬롯 템플릿을 `FieldDef` 콜백으로 변환하는 `buildFieldDefs`를 거치며, raw 참조 동일성으로 메모이즈됩니다(큰 배열의 깊은 순회 회피).
229
+
230
+ ### WrapperExtras 옵션 (래퍼 전용)
231
+
232
+ `WrapperExtras`는 `WrapperUIOptions`를 확장(상속 12개 UI 플래그 + 자체 8개 키 = 20개)합니다. 어댑터가 코어 설정을 만들기 전에 이 키들을 분리(strip)합니다. **코어 `PureSheetConfig`와 겹치는 유일한 키는 `locale`**(둘 다 `string`, 무해하며 의도적으로 분리 대상에서 제외 → 코어·래퍼 양쪽에 전달).
233
+
234
+ > **기본값 출처 주의** — Vue `withDefaults`는 **10개 키만** 설정합니다: `height` + 8개 항상-on UI 플래그(`useToolBox` · `useToolBoxSetting` · `useExtendFooter` · `useSummaryFooter` · `useSort` · `useCustomCell` · `useContextMenu` · `useBuiltinTooltip`) + `usePivotBar`. 그 외 키는 prop 레이어에서 `undefined`로 남고, 래퍼의 `DEFAULT_UI_OPTIONS`/`resolveUIOptions`(UI 플래그 SSOT) 또는 다운스트림(차트 등)에서 문서화된 기본값으로 해석됩니다. 아래 표의 기본값은 **최종 적용 기본값**입니다.
235
+ >
236
+ > ⚠️ `usePivotBar` 가 `withDefaults` 에 있는 이유: **Vue 는 미전달 boolean prop 을 `false` 로 강제**하므로 여기서 복원하지 않으면 prop 을 안 준 소비처에서 바가 통째로 사라집니다(= 피벗 정렬·필터 진입점 상실).
237
+
238
+ | 속성 | 타입 | 기본값 | 설명 |
239
+ |------|------|--------|------|
240
+ | `name` | `string` | `undefined` | **Vue 전용**(WrapperExtras 아님). 사용자 레이아웃 프리셋 식별자. `useGridPreset`에 전달되며 `name`이 설정되고 호스트가 user-layout 모듈을 제공할 때만 동작(아니면 no-op). 프리셋 타입은 `mode==='pivot' ? 'mozPivotGrid' : 'mozFlatGrid'` |
241
+ | `height` | `string \| number` | `'100%'` | 호스트 컨테이너 높이(CSS). number=px, string=그대로. **어댑터 로컬 전용**(코어/chrome에 전달 X — `hostStyle` computed에만 사용) |
242
+ | `useToolBox` | `boolean` | `true` | 툴박스 표시 |
243
+ | `useToolBoxSetting` | `boolean` | `true` | 툴박스 설정(기어) 버튼 표시 |
244
+ | `useExtendFooter` | `boolean` | `true` | 확장 푸터 표시 |
245
+ | `useSummaryFooter` | `boolean` | `false` | 푸터 집계(요약) 표시 |
246
+ | `useSort` | `boolean` | `true` | 정렬 기능 활성화 |
247
+ | `useCustomCell` | `boolean` | `true` | 조건부 서식(커스텀 셀) 활성화 |
248
+ | `useContextMenu` | `boolean` | `true` | 컨텍스트 메뉴 활성화 |
249
+ | `useBuiltinTooltip` | `boolean` | `true` | 내장 셀/헤더 툴팁 렌더러 사용. `false`면 wrapper가 툴팁을 그리지 않음 — 코어 `cell:tooltip` 이벤트는 그대로 발행되므로 소비처가 `@ready`의 `grid.on('cell:tooltip', …)`로 직접 렌더 가능(발행은 `tooltipMode`로 제어) |
250
+ | `usePivot` | `boolean` | `false` | 피벗 패널 버튼 표시 (Vue withDefaults 미설정 → `DEFAULT_UI_OPTIONS`에서 `false`) |
251
+ | `usePivotBar` | `boolean` | `true` | **피벗 옵션 바(툴박스 아래 행/열/값 한 줄) 사용 여부** — 피벗 모드 전용 (ITSM-2026-002154). Vue `withDefaults` 가 `true` 로 복원 |
252
+ | `useChart` | `boolean` | `false` | 피벗 차트 버튼 표시(피벗 모드 전용). Vue withDefaults 미설정 |
253
+ | `useMultipleChart` | `boolean` | `true` | 피벗 차트 Multiple(행별 미니 차트) 모드. Vue withDefaults 미설정 → 다운스트림에서 `true` 적용(legacy MozPivotVue 패리티) |
254
+ | `chartIncludeGrandTotal` | `boolean` | `false` | 피벗 차트에 총합(Grand Total) 카테고리 포함 |
255
+ | `chartMap` | `Record<string, ChartSeriesConfig>` | `undefined` | 피벗 차트 시리즈별 type/color 설정 → [chartMap](#chartmap--chartseriesconfig) |
256
+ | `loading` | `boolean` | `false` | 로딩 오버레이 강제 표시(호스트 비동기 상태). `false`여도 내부 비동기 작업(`activity!=='idle'` && 검색 아님) 중에는 스피너 자동 표시. Vue는 `{ immediate: true }` 전용 watch로 `chrome.setUIOptions({ loading })` 배선 |
257
+ | `locale` | `string` | `'ko'` | UI 언어 → [locale](#locale) |
258
+ | `contextMenuConfig` | `IContextMenuConfig` | `undefined` | 컨텍스트 메뉴 설정 → [contextMenuConfig](#contextmenuconfig--icontextmenuconfig) |
259
+ | `emptyState` | `EmptyStateConfig` | `undefined` | 빈 상태 오버레이 설정 → [emptyState](#emptystate--emptystateconfig) |
260
+ | `sourceFields` | `PivotSourceField[]` | `undefined` | 피벗 배치 후보 필드 카탈로그 → [sourceFields](#sourcefields--pivotsourcefield) |
261
+
262
+ > **`usePivotBar` — "지금 보이는가"가 아니라 "이 화면에서 바를 쓰는가" (ITSM-2026-002154)**
263
+ > 표시/숨김은 사용자가 런타임에 바꾸는 **상태**이므로 prop 이 아니라 `GridChrome.setPivotBarVisible()` 이 소유합니다. 초기에 켜 두려면 `@ready` 의 2번째 인자로 오는 chrome 에서 호출하세요:
264
+ > ```vue
265
+ > <MozGrid :usePivotBar="true" @ready="(grid, chrome) => chrome.setPivotBarVisible(true)" />
266
+ > ```
267
+ >
268
+ > 🚨 **`false` 는 바를 숨기는 것이 아니라 피벗의 정렬·필터 진입점을 함께 제거합니다:**
269
+ > - 피벗은 헤더 클릭으로 정렬하지 않습니다. 헤더 클릭이 바를 켜서 정렬 지점(필드 아이템)을 안내하는 구조라, 바가 없으면 **정렬 진입점이 사라집니다**.
270
+ > - 피벗 헤더에는 필터 아이콘이 없습니다. 값 목록 필터의 앵커는 바 아이템의 아이콘뿐이므로(`openPivotValueFilter`), 바가 없으면 **필터 팝오버도 열 수 없습니다**.
271
+ >
272
+ > 그래서 기본값이 `true` 이며, `false` 는 "피벗을 읽기 전용 표로만 쓴다"는 선언에 가깝습니다.
273
+
274
+ > **라이브 토글** — UI 플래그(`useToolBox`/`useToolBoxSetting`/`useExtendFooter`/`useSummaryFooter`/`useSort`/`useCustomCell`/`useContextMenu`/`useBuiltinTooltip`/`usePivot`/`usePivotBar`)는 변경 시 `chrome.setUIOptions`로 런타임 갱신됩니다(`useBuiltinTooltip`은 내장 툴팁 렌더러를 런타임에 생성/파괴). `loading`·`sourceFields`·**`contextMenuConfig`** 는 각자 전용 watch 를 가집니다(`sourceFields`/`contextMenuConfig` 는 래퍼 전용 키라 reconcile 을 거치지 않고 `chrome.setSourceFields`/`chrome.setContextMenuConfig` 로 직접 전파). `useChart`/`useMultipleChart`/`chartIncludeGrandTotal`/`chartMap`은 `GridChromeOptions`로 전달만 됩니다(라이브 watch X). `height`는 순수 어댑터 로컬(`hostStyle`).
275
+ >
276
+ > ⚠️ `contextMenuConfig` 는 이전에 `buildChromeOptions` 가 **생성 시 1회만** 읽어, 소비자가 `customMenu` 를 비동기로 채우면(예: 새 탭 열기 대상의 메뉴 이름 lookup 응답 후) 그대로 유실됐습니다. 이제 변경 시 크롬에 전파됩니다.
277
+
278
+ ### WrapperUIOptions — UI 표시 플래그
279
+
280
+ `WrapperExtras`가 확장하는 12개 UI 플래그 베이스 인터페이스입니다. `DEFAULT_UI_OPTIONS`(`Required<WrapperUIOptions>`)가 기본값 SSOT이고, `resolveUIOptions`가 `options.X ?? DEFAULT_UI_OPTIONS.X`로 병합합니다(프레임워크 무관 기본값).
281
+
282
+ | 플래그 | 기본값 | 플래그 | 기본값 |
283
+ |--------|--------|--------|--------|
284
+ | `useToolBox` | `true` | `useContextMenu` | `true` |
285
+ | `useToolBoxSetting` | `true` | `usePivot` | `false` |
286
+ | `useExtendFooter` | `true` | `usePivotBar` | `true` (피벗 전용) |
287
+ | `useSummaryFooter` | `false` | `useChart` | `false` (피벗 전용) |
288
+ | `useSort` | `true` | `loading` | `false` |
289
+ | `useCustomCell` | `true` | `useBuiltinTooltip` | `true` |
290
+
291
+ > `useMultipleChart`/`chartIncludeGrandTotal`/`chartMap`/`height`/`locale`/`sourceFields`/`contextMenuConfig`/`emptyState`는 `WrapperUIOptions`가 아니라 `WrapperExtras`에만 존재합니다.
292
+
293
+ ### contextMenuConfig — IContextMenuConfig
294
+
295
+ 빌트인 항목 토글 + Excel 콜백 + 커스텀 메뉴(`customMenu`). 전 필드 optional.
296
+
297
+ | 속성 | 타입 | 설명 |
298
+ |------|------|------|
299
+ | `useViewSelectColumn` | `boolean?` | 컬럼 표시 선택 항목 토글 |
300
+ | `useFixedColumn` | `boolean?` | 컬럼 고정 항목 토글 |
301
+ | `useGroupColumn` | `boolean?` | 컬럼 그룹화 항목 토글 |
302
+ | `useContextMenu` | `boolean?` | 컨텍스트 메뉴 마스터 토글(주: `WrapperUIOptions.useContextMenu`와 별개) |
303
+ | `useSort` | `boolean?` | 정렬 항목 토글 |
304
+ | `useFilter` | `boolean?` | 필터 항목 토글 |
305
+ | `useCustomCell` | `boolean?` | 조건부 서식 항목 토글 |
306
+ | `useBulkEditColumn` | `boolean?` | 컬럼 일괄 편집 항목 토글 |
307
+ | `useDataCopy` | `boolean?` | 데이터 복사 항목 토글 |
308
+ | `useDataWithHeaderCopy` | `boolean?` | 헤더 포함 복사 항목 토글 |
309
+ | `useAutoSizeColumns` | `boolean?` | 컬럼 자동 크기 항목 토글 |
310
+ | `useExportCsv` | `boolean?` | CSV 내보내기 항목 토글 |
311
+ | `useRowPinning` | `boolean?` | 행 고정 항목 토글 |
312
+ | `useExportImport` | `boolean?` | 내보내기/가져오기 그룹 토글 |
313
+ | `useExportExcel` | `boolean?` | Excel 내보내기 항목 토글 |
314
+ | `onImportExcel` | `(ctx: IContextMenuExcelEventArgs) => void` | Excel 가져오기 콜백. `IContextMenuExcelEventArgs = { grid: unknown; field?: unknown }` |
315
+ | `onImportExcelAppend` | `(ctx: IContextMenuExcelEventArgs) => void` | Excel 가져오기-추가 콜백 |
316
+ | `onExportOriginalData` | `(format: 'excel' \| 'csv') => void` | 원본(집계 전) 데이터 내보내기 콜백 |
317
+ | `useClientExcelImport` | `boolean?` | 클라이언트 Excel 가져오기 활성화 |
318
+ | `useClientExcelExport` | `boolean?` | 클라이언트 Excel 내보내기 활성화 |
319
+ | `useExportOriginal` | `boolean?` | 원본(집계 전) XLSX 내보내기 — 피벗/그룹/병합 무시, 코어 소스 행 내보내기(`saveExcelToFile({ exportSource: true })`). 피벗 모드에서 raw 데이터 필요 시 |
320
+ | `clientImportOptions` | `Record<string, unknown>?` | 클라이언트 가져오기 옵션 |
321
+ | `clientExportOptions` | `Record<string, unknown>?` | 클라이언트 내보내기 옵션 |
322
+ | `exportFileName` | `string?` | 내보내기 파일명의 base. 실제 저장 다이얼로그 제안명은 `ExcelController`가 `${base}_${YYYYMMDD}.xlsx`(원본 export는 `${base}_source_${YYYYMMDD}.xlsx`, CSV는 `.csv`)로 구성하며, `base` 미지정 시 `'export'`. 이 이름이 `onExportStart(fileName)`으로 어댑터에 전달되어 알림에 그대로 표시된다(어댑터가 재계산하지 않음) |
323
+ | `onClientImportComplete` | `(result: unknown) => void` | 클라이언트 가져오기 완료 콜백 |
324
+ | `onClientExportComplete` | `(result: SaveExcelToFileResult) => void` | 클라이언트 내보내기 완료 — FSA 스트리밍/폴백 다운로드 결과 |
325
+ | `customMenu` | `IContextMenuItem[]?` | 커스텀 메뉴 항목 |
326
+
327
+ `IContextMenuItem = { id: string; label: string; icon?: string; disabled?: boolean; separator?: boolean; children?: IContextMenuItem[]; handler?: () => void; order?: number (기본 50); aggregate?: { header: string; aggLabel: string; value: string }; compact?: boolean }`
328
+
329
+ ### emptyState — EmptyStateConfig
330
+
331
+ 빈 상태 오버레이 설정(legacy `MozGridVue` `emptyState` prop 1:1). 미지정 시 i18n 기본 텍스트/이미지 자동 적용. `empty-state` 슬롯으로 커스텀 영역 주입 가능.
332
+
333
+ | 속성 | 타입 | 설명 |
334
+ |------|------|------|
335
+ | `isCustomState` | `boolean?` | 커스텀 빈 뷰 강제(`custom_empty` 이미지) |
336
+ | `headerMsg` | `string?` | 헤더 텍스트 오버라이드(미지정 시 뷰 타입별 i18n 기본) |
337
+ | `contentMsg` | `string?` | 콘텐츠 텍스트 오버라이드(`unsafeHTML`로 렌더, 미지정 시 i18n 기본) |
338
+ | `useImg` | `boolean?` | 빈 상태 이미지 표시(내부 기본 `true`) |
339
+ | `selectImg` | `EmptyStateImg?` | 명시적 이미지 선택. 행 수가 0일 때 자동 뷰 타입을 오버라이드 |
340
+
341
+ `EmptyStateImg = 'Custom' | 'Result' | 'Data' | 'Search'`
342
+
343
+ ### sourceFields — PivotSourceField
344
+
345
+ 피벗 배치 후보 필드 카탈로그(래퍼 SSOT — 코어는 후보 풀을 노출하지 않음). 피벗 설정엔 `fields`가 없으므로, 필드 패널의 후보 목록(label/type/aggregate)이 이 카탈로그에서 옵니다. 풀 필드를 row/col/value로 드래그하면 선언된 props(`header`/`dataType`/`aggregate`/`formula`/...)가 `PivotConfig`로 옮겨집니다.
346
+
347
+ ```typescript
348
+ type PivotSourceField = PivotRowField & PivotColumnField & PivotValueField;
349
+ ```
350
+
351
+ `PivotRowField`/`PivotColumnField`/`PivotValueField` 3종의 교집합이므로 모든 row/column/value 필드 props(`field`, `header`, `dataType`, `aggregate`, `formula`, `showValueAs`, `headerAttributes`, `cellAttributes`, `width` 등)를 선언할 수 있습니다. **각 필드 상세는 코어 레퍼런스 참조**(3종 모두 코어 `pivot.types.ts`) → [reference.md 피벗 필드 타입](reference.md#피벗-필드-타입).
352
+
353
+ > 런타임 갱신: `chrome.setSourceFields(...)`(어댑터가 `sourceFields` prop watch에서 호출). `PivotSourceField`는 래퍼 index에서 재-export되지 않으며 `sourceFields`/`chartMap` 등의 요소 타입으로만 도달합니다.
354
+
355
+ ### chartMap — ChartSeriesConfig
356
+
357
+ 피벗 차트 시리즈 키 → 시리즈 설정 맵(legacy `MozPivotVue` `chartMap` 1:1). `chartMap = Record<string, ChartSeriesConfig>`.
358
+
359
+ | 속성 | 타입 | 설명 |
360
+ |------|------|------|
361
+ | `type` | `ChartType?` | 시리즈 차트 타입. `ChartType = 'bar' \| 'line' \| 'lineSymbols' \| 'area'` |
362
+ | `color` | `string?` | 시리즈 색상(미지정 시 팔레트 기본) |
363
+
364
+ > `ChartSeriesConfig`/`ChartType`은 래퍼 index에서 재-export되지 않으며 `chartMap`의 값 타입으로만 도달합니다.
365
+
366
+ ### locale
367
+
368
+ | 속성 | 타입 | 기본값 | 설명 |
369
+ |------|------|--------|------|
370
+ | `locale` | `string` (코드: `'ko'` \| `'en'` \| `'ja'` \| `'zh'` 또는 `'en-US'` 같은 접두형) | `'ko'` | UI 언어 |
371
+
372
+ - 허용 코드는 `LocaleCode = 'ko' \| 'en' \| 'ja' \| 'zh'`이며 필드 타입은 `string`이라 접두형(`'en-US'`)도 내부 `normalize()`가 정규화합니다. 미설정 시 `'ko'`.
373
+ - **생성 시 1회만 적용**됩니다(`GridChrome` 생성자에서 모듈 함수 `setLocale(options.locale)` 호출). **런타임 전환 미지원** — 공개 `GridChrome.setLocale` 메서드는 존재하지 않습니다(`WrapperExtras.locale` JSDoc 의 "런타임 변경은 `GridChrome.setLocale` 경유" 표현은 stale). `setUIOptions`도 locale을 처리하지 않습니다.
374
+ - `locale`은 `WrapperExtras`와 코어 `PureSheetConfig` 양쪽에 있는 유일한 키입니다(둘 다 `string`). 의도적으로 `WRAPPER_EXTRA_KEYS`에서 제외되어 코어 설정과 `options.locale` 양쪽에 흐릅니다. Vue에서도 `coreConfig` 변경 감지에 folding되어 locale 변경은 reinit을 유발합니다.
375
+
376
+ > **참고 — `WRAPPER_EXTRA_KEYS`**: 어댑터가 코어 설정을 만들기 전 분리하는 래퍼 전용 키 18개(`height`, `contextMenuConfig`, `emptyState`, `sourceFields`, `useToolBox`, `useToolBoxSetting`, `useExtendFooter`, `useSummaryFooter`, `useSort`, `useCustomCell`, `useContextMenu`, `useBuiltinTooltip`, `usePivot`, `useChart`, `useMultipleChart`, `chartIncludeGrandTotal`, `loading`, `chartMap`). `locale`은 위 사유로 **제외**. (`@vmscloud/moz-ui-grid-wrapper`에서 export)
377
+
378
+ ---
379
+
380
+ ## Emits
381
+
382
+ `MozGrid`는 총 **32개** 이벤트를 emit합니다: `defineEmits`가 선언하는 **31개**(고유 emit 2개 `ready`·`data:loaded` + 코어 인터랙션 이벤트 29개) + `defineModel`이 만드는 암시적 `update:coreConfig` 1개. 인터랙션 이벤트 29개(`row:click` … `contextmenu`)는 `defineEmits`에 선언됨과 동시에 `FORWARD_EVENTS` 배열로 코어에서 일괄 포워딩됩니다(`header:click`/`header:sortClick`/`header:filterClick` 포함 — 별도 배선이 아니라 같은 29개). `ready`/`data:loaded`는 어댑터가 직접 배선(`ready`는 `mountChrome`/`reinitChrome`에서, `data:loaded`는 전용 구독).
383
+
384
+ > **페이로드 형태** — 인터랙션 이벤트 페이로드는 Vue 선언상 `[payload: unknown]`이지만 런타임에는 **코어 이벤트 페이로드**를 그대로 운반합니다. 실제 형태는 [reference.md 이벤트](reference.md#이벤트) 참조.
385
+
386
+ | 이벤트 | 페이로드 | 설명 |
387
+ |--------|----------|------|
388
+ | `ready` | `[grid: PureSheet, chrome: GridChrome]` | 그리드 마운트 + `chrome.ready()` 완료 후. 1번째 인자는 코어 `PureSheet`(`chrome.grid`), **2번째 인자는 wrapper 크롬**(ITSM-2026-002154). **초기 마운트 + 각 reinit마다 발화**하므로 여러 번 받을 수 있음 |
389
+ | `data:loaded` | `[]` (페이로드 없음) | 코어 `data:loaded` 전용 구독으로 포워딩 |
390
+ | `row:click` | `[payload: unknown]` | 코어 이벤트 포워딩 → [reference.md 이벤트](reference.md#이벤트) |
391
+ | `row:dblclick` | `[payload: unknown]` | 코어 이벤트 포워딩 |
392
+ | `row:pinned` | `[payload: unknown]` | 코어 이벤트 포워딩 |
393
+ | `row:unpinned` | `[payload: unknown]` | 코어 이벤트 포워딩 |
394
+ | `row:reordered` | `[payload: unknown]` | 코어 이벤트 포워딩 |
395
+ | `cell:click` | `[payload: unknown]` | 코어 이벤트 포워딩 |
396
+ | `cell:dblclick` | `[payload: unknown]` | 코어 이벤트 포워딩 |
397
+ | `cell:change` | `[payload: unknown]` | 코어 이벤트 포워딩 |
398
+ | `cell:beforeEdit` | `[payload: unknown]` | 코어 이벤트 포워딩 |
399
+ | `cell:editCommitting` | `[payload: unknown]` | 코어 이벤트 포워딩 |
400
+ | `cell:editCommitted` | `[payload: unknown]` | 코어 이벤트 포워딩 |
401
+ | `cell:tooltip` | `[payload: unknown]` | 코어 이벤트 포워딩 |
402
+ | `selection:changed` | `[payload: unknown]` | 코어 이벤트 포워딩 |
403
+ | `column:resize` | `[payload: unknown]` | 코어 이벤트 포워딩 |
404
+ | `column:reorder` | `[payload: unknown]` | 코어 이벤트 포워딩 |
405
+ | `column:pin` | `[payload: unknown]` | 코어 이벤트 포워딩 |
406
+ | `column:visibility` | `[payload: unknown]` | 코어 이벤트 포워딩 |
407
+ | `sort:changed` | `[payload: unknown]` | 코어 이벤트 포워딩 |
408
+ | `header:click` | `[payload: unknown]` | 코어 이벤트 포워딩 — 헤더 **셀 본체** 클릭 |
409
+ | `header:sortClick` | `[payload: unknown]` | 코어 이벤트 포워딩 — 헤더 **정렬 아이콘** 클릭 (ITSM-2026-002185) |
410
+ | `header:filterClick` | `[payload: unknown]` | 코어 이벤트 포워딩 — 헤더 **필터 아이콘** 클릭 (ITSM-2026-002185). 필드에 `showFilterIcon: false` 면 발생하지 않음 |
411
+ | `filter:changed` | `[payload: unknown]` | 코어 이벤트 포워딩 |
412
+ | `scroll` | `[payload: unknown]` | 코어 이벤트 포워딩 |
413
+ | `undo:stateChange` | `[payload: unknown]` | 코어 이벤트 포워딩 |
414
+ | `clipboard:copy` | `[payload: unknown]` | 코어 이벤트 포워딩 |
415
+ | `clipboard:paste` | `[payload: unknown]` | 코어 이벤트 포워딩 |
416
+ | `validation:changed` | `[payload: unknown]` | 코어 이벤트 포워딩 |
417
+ | `columnGroup:toggle` | `[payload: unknown]` | 코어 이벤트 포워딩 (컬럼 그룹 토글, 구 `headerGroup:toggle`) |
418
+ | `rowGroup:toggle` | `[payload: unknown]` | 코어 이벤트 포워딩 (단일 로우 그룹 토글, 헤더 클릭 `source:'user'`/프로그래매틱 `source:'api'`) |
419
+ | `rowGroup:batchToggle` | `[payload: unknown]` | 코어 이벤트 포워딩 (여러 그룹 일괄 토글, `scope`로 `level`/`toLevel`/`all` 구분, 1회 요약 통지) |
420
+ | `contextmenu` | `[payload: unknown]` | 코어 이벤트 포워딩 |
421
+ | `update:coreConfig` | `[value: MozGridCoreProps]` | **암시적**(`defineModel('coreConfig')`). 어댑터가 `coreConfig.value`를 할당할 때마다 발화(내부 변경 역류). → [coreConfig 역류](#coreconfig-역류-updatecoreconfig) |
422
+
423
+ > 인터랙션 27개(`row:click`~`contextmenu`)는 `FORWARD_EVENTS` 배열로 `c.on(ev, (p) => fwd(ev, p))`로 일괄 배선됩니다(legacy `MozGridVue` `BRIDGED_EVENTS` 1:1). `data:loaded`는 `FORWARD_EVENTS`에 없고 전용 `c.on('data:loaded', …)` 구독으로 별도 배선됩니다.
424
+
425
+ ---
426
+
427
+ ## Slots
428
+
429
+ ### default 슬롯 (템플릿 컴포넌트)
430
+
431
+ 기본(default) 슬롯은 **렌더리스 템플릿 채널**입니다. 자식 컴포넌트(`CellTemplate`/`HeaderTemplate`/`CellEditor`/`DetailTemplate`/`GroupTemplate`)가 제공된 template registry/grid에 스스로 등록되며, 화면에는 호스트 div의 형제로 마운트됩니다(chrome 슬롯 아님). → [템플릿 컴포넌트](#템플릿-컴포넌트)
432
+
433
+ ### Chrome 네임드 슬롯
434
+
435
+ 7개 chrome 네임드 슬롯(legacy `MozGridVue` passthrough 지점 1:1). 제공된 슬롯만 `SlotRenderer`로 매핑되어 chrome 컨테이너에 마운트됩니다. **`tool-items`만 scoped 슬롯**입니다.
436
+
437
+ | 슬롯 | scoped | 설명 |
438
+ |------|--------|------|
439
+ | `tool-left` | — | 툴박스 좌측 영역 |
440
+ | `tool-items` | ✅ `{ disabled, hasItem }` | 툴박스 우측 커스텀 아이템. scoped props = `WrapperToolItemsProps` |
441
+ | `option-popup` | — | 설정/옵션 모달 콘텐츠 (legacy `#optionPopup`) |
442
+ | `tool-bottom` | — | 툴박스 하단(그룹 패널 영역) |
443
+ | `notification` | — | 툴박스와 본문 사이 알림 영역 |
444
+ | `footer` | — | 커스텀 푸터 영역 |
445
+ | `empty-state` | — | 커스텀 빈 상태 콘텐츠 (legacy `#customState`) |
446
+
447
+ **`tool-items` scoped props (`WrapperToolItemsProps`)**:
448
+
449
+ | 속성 | 타입 | 설명 |
450
+ |------|------|------|
451
+ | `disabled` | `boolean` | 그리드 비활성(표시 가능 행 0개) |
452
+ | `hasItem` | `boolean` | 적용된 항목(필터 등) 존재(`filter.count > 0`) |
453
+
454
+ `toolItemsProps`는 `{ disabled: true, hasItem: false }`로 시드되며, ready/reinit 후 `chrome.getToolItemsProps()`로 채워지고 `onToolItemsPropsChange` 콜백으로 반응형 갱신됩니다.
455
+
456
+ ```vue
457
+ <template #tool-items="{ disabled, hasItem }">
458
+ <button :disabled="disabled">
459
+ 엑셀 다운로드{{ hasItem ? ' (필터됨)' : '' }}
460
+ </button>
461
+ </template>
462
+ ```
463
+
464
+ ---
465
+
466
+ ## 인스턴스 API (ref / defineExpose)
467
+
468
+ `MozGrid`의 `ref`로 노출되는 값은 **큐레이트된 메서드 목록이 아니라 현재 `GridChrome` 인스턴스 전체를 투명하게 노출하는 Proxy**입니다. `defineExpose`는 `GridChrome & { chrome: GridChrome | null }` 타입으로 선언됩니다. core `PureSheet`는 `ref.value.grid`로 노출되므로, displayed 좌표계 API도 `ref.value?.grid.getDisplayedData()` / `.getDisplayedRowIds()`(배열), `ref.value?.grid.rows.displayedCount()` / `.getByDisplayedIndex(i)` / `.getDisplayedIndexById(id)`(traversal 인덱싱)로 바로 호출합니다. 자세한 계약은 core 레퍼런스(reference.md)를 참조하세요.
469
+
470
+ ```typescript
471
+ const g = gridRef.value; // GridChrome 표면 전체
472
+ g.grid // 코어 PureSheet (→ reference.md)
473
+ g.filter; g.sort; g.pivot; // 서브 컨트롤러
474
+ g.customCell; g.columnFormat;
475
+ g.chart; // 피벗 모드에서만 non-null
476
+ g.setUIOptions({ useToolBox: false });
477
+ g.on('cell:change', handler);
478
+ g.getCoreConfig();
479
+ g.chrome // 원시 GridChrome | null (legacy 호환)
480
+ ```
481
+
482
+ - Proxy는 접근 시마다 살아있는 `chrome`을 읽고, 함수면 `chrome`에 바인딩하여 반환합니다(메서드의 `this` 유지). `chrome`은 mount/reinit마다 재할당되므로 Proxy는 항상 최신 인스턴스를 반영합니다(stale 참조 없음).
483
+ - 특수 키 `chrome`은 원시 `GridChrome | null`(마운트 전/언마운트 후 `null`)을 반환합니다(하위 호환).
484
+ - `mountChrome` 완료 전(또는 `onBeforeUnmount`로 `chrome=null` 이후)에는 `chrome` 외 모든 멤버가 `undefined`입니다.
485
+
486
+ ### GridChrome 표면 전체
487
+
488
+ `ref.value`는 `GridChrome` 표면 전체입니다. 핵심은 `.grid`(코어 PureSheet)와 공개 컨트롤러/필드/메서드입니다.
489
+
490
+ > **`.grid`는 코어 `PureSheet`입니다.** `loadData`, `updateFields`, `select`, `on`, `columns`, `rows`, `filter`, `sort`, `group`, `tree`, `masterDetail`, `dragDrop`, `pivot`, `getConfig`, `applyConfig`, `toggleSort`, `waitForReady`, `destroy` 등 그리드 본체 API는 모두 코어 레퍼런스 참조 → [reference.md PureSheet 최상위 API](reference.md#puresheet-최상위-api).
491
+
492
+ ### 공개 컨트롤러 및 필드
493
+
494
+ | 필드 | 타입 | 설명 |
495
+ |------|------|------|
496
+ | `grid` | `PureSheet` (readonly) | **코어 그리드 본체** → [reference.md](reference.md) |
497
+ | `slots` | `SlotHost` (readonly) | 슬롯 호스트 레지스트리(어댑터가 `SlotRenderer` 등록) |
498
+ | `ui` | `Required<WrapperUIOptions>` (mutable) | 현재 적용된 UI 옵션. 직접 변경 말고 `setUIOptions` 사용 |
499
+ | `filter` | `FilterController` (readonly) | 필터 UI 상태/로직 |
500
+ | `sort` | `SortController` (readonly) | 정렬 UI 상태/로직 |
501
+ | `customCell` | `CustomCellController` (readonly) | 조건부 서식(커스텀 셀) |
502
+ | `bulkEditor` | `BulkEditorController` (readonly) | 일괄 편집 패널 |
503
+ | `columnSettings` | `ColumnSettingsController` (readonly) | 컬럼 표시/순서 설정 |
504
+ | `group` | `GroupController` (readonly) | 그룹 패널 |
505
+ | `excel` | `ExcelController` (readonly) | Excel/CSV 가져오기/내보내기 |
506
+ | `pivot` | `PivotController` (readonly) | 피벗 필드 패널(`sourceFields`/`setSourceFields`/`setConfig`/`subscribe`) |
507
+ | `search` | `SearchController` (readonly) | 검색(키워드 + 하이라이트) |
508
+ | `columnFormat` | `ColumnFormatController` (readonly) | 컬럼 단위 셀/헤더 스타일(조건부 서식 하위 base 레이어) |
509
+ | `contextMenu` | `ContextMenuController` (readonly) | 컨텍스트 메뉴 |
510
+ | `chart` | `ChartController \| null` (readonly) | **피벗 모드에서만 non-null**(flat 모드 `null` → 반드시 null 체크) |
511
+ | `hosts` | `Readonly<Omit<ChromeShell, 'root'>>` (getter) | 내부 DOM 호스트 요소(읽기 전용): `gridPane`, `toolboxHost`, `groupPanelHost`, `notificationHost`, `body`, `gridContainer`, `emptyStateHost`, `loadingHost`, `footerHost`, `splitResizer`, `chartHost` |
512
+
513
+ ### 공개 메서드
514
+
515
+ 생성자를 제외한 공개 메서드는 정확히 다음 17개입니다(`off` 메서드 없음 — `on`/`onConfigChange`가 반환하는 `Unsubscribe`를 호출하거나 `destroy()`에 일임).
516
+
517
+ | 메서드 | 시그니처 | 설명 |
518
+ |--------|----------|------|
519
+ | `ready` | `async ready(): Promise<void>` | 코어 `waitForReady` 대기 → `isDataLoaded=true` → 카운트/푸터/빈 상태 갱신. 생성 후 1회 호출 |
520
+ | `on` | `on(event, handler): Unsubscribe` | 코어 이벤트 구독 + chrome 구독 목록에 추적(destroy 시 자동 정리). `Unsubscribe` 반환 |
521
+ | `reconcileCoreConfig` | `reconcileCoreConfig(next: PureSheetConfig): { reinitRequired: boolean }` | 변경된 코어 설정 키만 타겟 setter로 적용. 런타임 setter 없는 키(rowHeight/headerHeight/keyFields/selection/editable/mode/locale/...) 변경 시 `{ reinitRequired: true }` 반환 → 어댑터가 상태 보존 reinit. disposed 시 early-return |
522
+ | `captureReinitState` | `captureReinitState(): GridChromeReinitState` | 소멸 직전 인스턴스에서 `{ core: getConfig(), customCell, columnFormat }` 스냅샷(래퍼 전용 상태 포함) |
523
+ | `restoreReinitState` | `async restoreReinitState(state): Promise<void>` | 새 인스턴스에서 `applyConfig(core)` 후 `columnFormat`(base) → `customCell`(override) 재적용. 절대 reject 안 함(부분 복원 허용) |
524
+ | `getCoreConfig` | `getCoreConfig(base?: PureSheetConfig): PureSheetConfig` | INPUT 형태의 현재 코어 설정 빌드(`update:coreConfig` 역류용). 라이브 mode/group/pivot 키만 오버레이, `fields`/`data` 참조 보존, sorts/filters 뷰 상태 미포함 |
525
+ | `onConfigChange` | `onConfigChange(cb: () => void): Unsubscribe` | 내부 코어 변경(pivotConfig + groupConfig.columns) 구독 → `update:coreConfig` 역류. UI 옵션/차트/커스텀 셀은 미포함. 반환 unsub도 destroy 추적 |
526
+ | `syncAppliedConfig` | `syncAppliedConfig(next: PureSheetConfig): void` | reconcile 기준선(`appliedConfig`) 강제 동기화 → 직후 prop-back reconcile을 no-op으로(중복 피벗 재계산 회피) |
527
+ | `setSourceFields` | `setSourceFields(sources?: PivotSourceField[]): void` | 피벗 후보 카탈로그 런타임 갱신(래퍼 전용 키라 reconcile 우회, 어댑터가 직접 호출) |
528
+ | `setContextMenuConfig` | `setContextMenuConfig(config?: IContextMenuConfig): void` | **컨텍스트 메뉴 설정 런타임 갱신** (ITSM-2026-002154). `sourceFields` 와 같은 래퍼 전용 키라 reconcile 을 타지 않음 — `buildChromeOptions` 는 생성 시 1회만 읽으므로, 소비자가 `customMenu`/`exportFileName` 을 비동기로 확정하는 경우 이 메서드로 전파해야 유실되지 않음 |
529
+ | `setUIOptions` | `setUIOptions(partial: Partial<WrapperUIOptions>): void` | UI 플래그 런타임 갱신 — `this.ui` 재해석 + 툴박스/푸터/컨텍스트 메뉴/로딩 오버레이 부분 재구성(PureSheet 미변경, 컨트롤러 상태/슬롯 보존). disposed 시 early-return |
530
+ | `getToolItemsProps` | `getToolItemsProps(): WrapperToolItemsProps` | `tool-items` 슬롯 props `{ disabled, hasItem }` |
531
+ | `setPivotBarVisible` | `setPivotBarVisible(visible: boolean): void` | **피벗 옵션 바 표시/숨김** — 사용자가 런타임에 바꾸는 *상태*이므로 prop(`usePivotBar`)이 아니라 이 메서드가 소유. 초기에 켜 두려면 `@ready` 2번째 인자로 호출 |
532
+ | `isPivotBarVisible` | `isPivotBarVisible(): boolean` | 피벗 옵션 바 표시 상태 조회 |
533
+ | `setGroupPanelVisible` | `setGroupPanelVisible(visible: boolean): void` | 그룹 패널 표시/숨김 |
534
+ | `getViewOptions` | `getViewOptions(): WrapperViewOptions` | 뷰 상태 `{ toolbarVisible, footerVisible, groupPanelVisible }` |
535
+ | `destroy` | `destroy(): void` | chrome 인스턴스/구독/슬롯 호스트/코어 그리드/루트 DOM 모두 해제. 멱등(`disposed` 가드) |
536
+
537
+ > `hosts`는 메서드가 아니라 `get hosts()` 게터(`Readonly<Omit<ChromeShell, 'root'>>` 반환)라 위 17개에 포함되지 않습니다.
538
+
539
+ > 어댑터의 양방향 바인딩 4중주: `reconcileCoreConfig`(props → core), `getCoreConfig`(core → `update:coreConfig`), `onConfigChange`(내부 변경 구독), `syncAppliedConfig`(에코 억제). reinit 쌍: `captureReinitState`/`restoreReinitState`(`reconcileCoreConfig`가 `{ reinitRequired: true }` 반환 시 구동).
540
+
541
+ **관련 보조 타입**:
542
+
543
+ - `GridChromeReinitState = { core: ReturnType<PureSheet['getConfig']>; customCell: ReturnType<CustomCellController['getCustomCell']>; columnFormat: ReturnType<ColumnFormatController['getConfig']> }` — 상태 보존 reinit 스냅샷(코어 `getConfig`에 없는 래퍼 전용 조건부 서식·컬럼 서식 상태 포함). `@vmscloud/moz-ui-grid-wrapper`에서 export.
544
+ - `WrapperViewOptions = { toolbarVisible: boolean; footerVisible: boolean; groupPanelVisible: boolean }` — 뷰 설정 상태(옵션 모달에서 토글). `getViewOptions()`로 읽고, `GridChromeOptions.onViewOptionsChange`로 알림.
545
+
546
+ ---
547
+
548
+ ## coreConfig 역류 (update:coreConfig)
549
+
550
+ `coreConfig`는 **컨트롤드 모델**입니다. 그리드 내부 변경(피벗 패널, 옵션 모달, 그룹 변경)이 부모로 역류하여 단방향 prop clobber 버그를 제거합니다.
551
+
552
+ 흐름:
553
+
554
+ 1. 내부 변경 발생 → `chrome.onConfigChange` 콜백 발화
555
+ 2. 어댑터가 `coreConfig.value = chrome.getCoreConfig(coreConfig.value)` 할당 → 암시적 `update:coreConfig` emit
556
+ 3. 이어서 `chrome.syncAppliedConfig(buildCoreConfig())` 호출 → 직후의 prop-back reconcile을 no-op으로(중복 피벗 재계산 회피)
557
+
558
+ 들어오는 prop 변경 흐름:
559
+
560
+ - `coreConfig` 변경 감지 — `data`/`fields`는 ref 동일성으로 추적(큰 배열 깊은 순회 X), 나머지는 deep-compare, `locale`은 fold-in(생성 시 키라 변경 시 reinit).
561
+ - 변경 시 `chrome.reconcileCoreConfig(buildCoreConfig())` 실행. `reinitRequired`(런타임 setter 없는 변경)이면 상태 보존 `reinitChrome()` 발화 → `ready`가 다시 emit됩니다.
562
+
563
+ ```vue
564
+ <script setup lang="ts">
565
+ import { ref, watch } from 'vue';
566
+ import { MozGrid } from '@vmscloud/moz-ui-grid-vue';
567
+ import type { MozGridCoreProps } from '@vmscloud/moz-ui-grid-vue';
568
+
569
+ const coreConfig = ref<MozGridCoreProps>({ mode: 'pivot', /* ... */ });
570
+
571
+ // 사용자가 피벗 패널에서 필드를 옮기면 coreConfig.value 의 피벗 키가 자동 역류됨
572
+ watch(coreConfig, (cfg) => {
573
+ console.log('현재 행 필드', cfg.rowFields);
574
+ }, { deep: true });
575
+ </script>
576
+
577
+ <template>
578
+ <MozGrid v-model:coreConfig="coreConfig" :use-pivot="true" />
579
+ </template>
580
+ ```
581
+
582
+ ---
583
+
584
+ ## 템플릿 컴포넌트
585
+
586
+ 패키지 엔트리에서 export되는 5개 렌더리스 컴포넌트로, **`MozGrid`의 default 슬롯 안에 배치할 때만** 동작합니다(필요한 injection이 없으면 `console.warn` 후 no-op, `() => null` 반환). 두 가지 등록 메커니즘으로 나뉩니다.
587
+
588
+ (A) **Registry 기반** (`CellTemplate`/`HeaderTemplate`/`CellEditor`): `GRID_TEMPLATE_REGISTRY_KEY`를 inject하여 마운트 시 `registry.register({ type, fieldId: props.field, slot })`, 언마운트 시 `unregister`. `field: string` prop 필수.
589
+
590
+ (B) **Grid-API 기반** (`DetailTemplate`/`GroupTemplate`): `GRID_INSTANCE_KEY` + `GRID_RENDERER_KEY`를 inject하여 코어를 직접 구동.
591
+
592
+ | 컴포넌트 | props | default 슬롯 scoped props |
593
+ |----------|-------|---------------------------|
594
+ | `CellTemplate` | `{ field: string (필수) }` | `CellSlotProps = { value: unknown; rowData: Record<string,unknown>; columnId: string; rowId?: string\|number }` |
595
+ | `HeaderTemplate` | `{ field: string (필수) }` | `HeaderSlotProps = { columnId: string; header: string }` |
596
+ | `CellEditor` | `{ field: string (필수) }` | `EditorSlotProps = { value: unknown; rowData: Record<string,unknown>; columnId: string; onCommit: (newValue: unknown) => void; onCancel: () => void }` |
597
+ | `DetailTemplate` | `{ minHeight?: number=100; maxHeight?: number; singleExpand?: boolean=false; keepDetailRows?: boolean=true }` | `DetailSlotProps = { parentData: Record<string,unknown>; dataIndex: number }` |
598
+ | `GroupTemplate` | (없음) | `GroupSlotProps = { groupKey: string; groupValue: unknown; level: number; count: number; isExpanded: boolean }` |
599
+
600
+ - `DetailTemplate`: 마운트 시 `grid.masterDetail.setConfig`로 props 매핑(`keepDetailRows` → 코어 `keepMasterDetailRows`), 디테일 행마다 `detail:${dataIndex}` 키로 슬롯 렌더. 언마운트 시 `renderer.unmountByPrefix('detail:')`.
601
+ - `GroupTemplate`: `_groupTemplate` 이름의 `formatRow` 핸들러를 등록하여 group-header 행에 `group:${ctx.viewIndex}` 키로 슬롯 마운트. 언마운트 시 `unmountByPrefix('group:')` 후 `formatRow.removeHandler('_groupTemplate')`.
602
+
603
+ ```vue
604
+ <MozGrid v-model:coreConfig="coreConfig">
605
+ <CellTemplate field="status" #default="{ value, rowData }">
606
+ <span :class="`badge-${value}`">{{ rowData.statusLabel }}</span>
607
+ </CellTemplate>
608
+
609
+ <HeaderTemplate field="amount" #default="{ header }">
610
+ 💰 {{ header }}
611
+ </HeaderTemplate>
612
+
613
+ <DetailTemplate :min-height="120" #default="{ parentData }">
614
+ <OrderDetail :order="parentData" />
615
+ </DetailTemplate>
616
+
617
+ <GroupTemplate #default="{ groupValue, count, isExpanded }">
618
+ {{ groupValue }} ({{ count }}) {{ isExpanded ? '▼' : '▶' }}
619
+ </GroupTemplate>
620
+ </MozGrid>
621
+ ```
622
+
623
+ ---
624
+
625
+ ## Composables · Contracts (호스트 통합)
626
+
627
+ ### useGridPreset (내부)
628
+
629
+ > `useGridPreset`은 **패키지 export 표면이 아닙니다**(`src/index.ts`/`legacy`에서 재-export 안 됨). `MozGrid`가 내부에서만 소비합니다. 소비처는 `MozGrid` + `name` prop + 호스트의 `'user-layout-module'` 제공으로 그 동작을 암묵적으로 얻습니다.
630
+
631
+ 사용자 레이아웃 프리셋을 저장/복원합니다. `exportDef`(= `grid.getConfig()` + `customCellConfig`(`getCustomCellState() ?? null`) + `columnFormatConfig`(`getColumnFormatState() ?? null`))와 `importDef`(async; `grid.applyConfig()`; preset이 null이면 캡처된 default 스냅샷 적용 + customCell/columnFormat 복원)로 `UserLayoutInstance`를 구성하고, `useUserLayoutModule().register`로 등록합니다. 등록은 `options.gridInstance` watch 안에서 **그리드 인스턴스 존재 + `options.name.value` 비어있지 않음** 조건의 첫 `data:loaded`에서, `layoutInstance.setDefaultToCurrent()` 후 `nextTick`에서 수행됩니다(Wijmo ExtendFlexGrid 패턴 — 동적 컬럼까지 default 스냅샷에 포착). 호스트가 모듈을 제공하지 않으면 register는 no-op.
632
+
633
+ `UseGridPresetOptions`: `name: Ref<string>`(필수), `type: 'mozFlatGrid' | 'mozPivotGrid'`(필수), `gridInstance: Ref<PureSheet | null>`(필수), `getCustomCellState`/`setCustomCellState`/`getColumnFormatState`/`setColumnFormatState`(선택).
634
+
635
+ ### Notification Contract
636
+
637
+ 패키지 엔트리에서 export. 호스트 → 그리드 알림 어댑터로, 호스트가 알림 스토어(SSE 메시지 + 세션 취소)를 제공하면 그리드가 Excel 가져오기/내보내기 진행 메시지를 push합니다.
638
+
639
+ | export | 시그니처 | 설명 |
640
+ |--------|----------|------|
641
+ | `provideGridNotification` | `(store: GridNotificationContract) => void` | Vue `provide(GridNotificationKey, store)` + 모듈 레벨 캐시 등록(비-setup 컨텍스트도 읽기 가능). 각 App.vue setup에서 호출 |
642
+ | `useGridNotificationStore` | `() => GridNotificationContract \| null` | 모듈 캐시 우선, 없으면 `inject(GridNotificationKey, null)`, 그래도 없으면 `null`(완전 선택) |
643
+ | `GridNotificationKey` | `InjectionKey<GridNotificationContract>` | `Symbol.for('MozGridNotification')`(크로스-번들 안정) |
644
+ | `GridNotificationContract` | `{ eventMessages: NotificationItem[]; markSessionCanceled(sessionId): void }` | 그리드가 필요로 하는 스토어 컨트랙트 |
645
+ | `NotificationItem` | (SSE 메시지 형태) | `header_key`/`noti_type`/`noti_sender_id`/`prop_value?{ session_id, file_name, status, progress_per, operation_type, remain_time, error_message, ... }` + `noti_index?` + 인덱스 시그니처 |
646
+ | `SSENotificationType` | `'info' \| 'notice' \| 'engine' \| 'progress' \| 'inbound' \| 'delete' \| 'demandplan'` | 알림 카테고리 |
647
+ | `ExcelNotificationOperationType` | `'upload' \| 'download'` | progress 알림 내 Excel 방향 |
648
+
649
+ > Excel 라이프사이클 훅(`ExcelLifecycleHooks`)은 어댑터가 `GridChromeOptions.excelHooks`로 GridChrome에 전달하며, 위 스토어가 없으면 모든 훅이 조용히 no-op입니다. 훅 종류 7개: `onImportComplete`, `onImportError`, `onExportStart`, `onExportProgress`, `onExportComplete`, `onExportError`, `onExportCancel`. 메시지 포맷팅(타임스탬프·header_key·`NotificationItem` 형태)은 앱별이라 Vue 어댑터가 소유합니다.
650
+ >
651
+ > **파일명 소유권과 알림 타이밍**: 내보내기 파일명은 `ExcelController`가 단독 계산합니다(`${exportFileName}_${YYYYMMDD}.xlsx`). 이 값은 `suggestedName`으로 core에 넘어가고, core는 **저장 파일명이 확정된 시점**(FSA 경로 = 사용자가 저장 다이얼로그에서 저장을 누른 직후의 `handle.name`, 폴백 다운로드 경로 = 다이얼로그가 없으므로 즉시 `suggestedName`)에 `SaveExcelToFileOptions.onFileNameResolved(fileName)`를 호출합니다. `ExcelController`는 이를 `onExportStart(fileName)`으로 어댑터에 전달하므로, 진행률 알림은 **뜨는 순간부터** 실제 저장될 파일명을 표시합니다(사용자가 다이얼로그에서 이름을 바꿔도 다운로드 중 표시가 어긋나지 않음). 저장을 **취소하면 `onExportStart`가 발화하지 않아** 알림이 떴다 사라지는 깜빡임도 없습니다. `onExportComplete(result)`의 `result.fileName`은 동일한 확정명으로, 어댑터가 완료 시 한 번 더 동기화합니다.
652
+
653
+ ```typescript
654
+ // App.vue setup
655
+ import { provideGridNotification } from '@vmscloud/moz-ui-grid-vue';
656
+ provideGridNotification(myNotificationStore); // GridNotificationContract 구현
657
+ ```
658
+
659
+ ### User Layout Contract
660
+
661
+ 패키지 엔트리에서 export.
662
+
663
+ | export | 시그니처 | 설명 |
664
+ |--------|----------|------|
665
+ | `useUserLayoutModule` | `() => UserLayoutModuleContract` | `inject('user-layout-module', { register: ()=>{}, currentPreset: ref(null) })` — 호스트 미제공 시 no-op 기본값 반환(프리셋 기능 조용히 비활성) |
666
+ | `UserLayoutModuleContract` | `{ register(instance: UserLayoutInstance): void; currentPreset: any }` | 그리드가 호스트에 요구하는 컨트랙트 |
667
+ | `UserLayoutInstance` | class | export/import 콜백 + default 스냅샷 보유. moz-shared view-manager 인스턴스의 복사본(직접 수정 금지) |
668
+
669
+ `UserLayoutInstance` 생성자: `{ id: string; type: string; importDef: (value) => void; exportDef: () => any; strict?: boolean; dependencies?: Ref<any>; manualLifeCycle?: boolean }`. 생성 시(`this._default = exportDef()`)와 `setDefaultToCurrent()`에서 default 스냅샷을 캡처하고, `get id`/`get type`/`get/set current`/`get/set default`/`get/set pending` 접근자를 노출합니다(`set pending(false)`가 버퍼된 import를 flush). `manualLifeCycle`이 아니면 Vue `onBeforeUnmount`에서 자동 dispose하므로 반드시 setup 안에서 생성해야 합니다.
670
+
671
+ ---
672
+
673
+ ## compat 래퍼 (MozGridVue / MozPivotVue)
674
+
675
+ > ⛔ **DEPRECATED.** `MozGridVue`/`MozPivotVue`(compat)는 레거시 컴포넌트의 정확한 공개 표면(props/emits/slots/defineExpose)을 보존하는 **얇은 하위 호환 어댑터**입니다. 신규 코드는 `MozGrid`(피벗은 `mode="pivot"`)를 사용하세요. 패키지 엔트리의 명시적 export가 `legacy` 배럴의 동명 export를 **shadow**합니다.
676
+
677
+ 두 compat 파일은 그리드 로직을 소유하지 않고 `<MozGrid>`를 얇게 감쌉니다. props를 `coreConfig` computed(WRAPPER_EXTRA_KEYS + name + locale 분리)와 `wrapperConfig` computed(WRAPPER_EXTRA_KEYS + locale만)로 분리하여 `coreConfig` + `v-bind="wrapperConfig"` + `:name`을 `MozGrid`에 바인딩합니다.
678
+
679
+ | compat 컴포넌트 | props 타입 | emits | slots | defineExpose |
680
+ |-----------------|-----------|-------|-------|--------------|
681
+ | `MozGridVue` (compat) | `MozGridVueProps` (레거시 withDefaults) | 28개 레거시 emit 1:1 포워딩 | `tool-left`, `tool-items`, `notification`, `footer`, `customState`(→`empty-state`), `default` | `{ grid, core, filterModule, sortModule, customCellModule, bulkEditorModule, refresh, loadData, sort, filter }` |
682
+ | `MozPivotVue` (compat) | `PivotGridProps` (피벗 withDefaults) | `ready`/`data:loaded`/`filter:changed`/`pivot:configured`/`pivot:toggled`/`update:rowFields`/`update:columnFields`/`update:valueFields` | `tool-left`, `tool-items`, `footer`, `customState`(→`empty-state`), `default` (notification 슬롯 없음) | `{ grid, core, pivotApi, filterModule, sortModule, customCellModule, showChart, refresh, setConfig, getResult, expandAll, collapseAll, expandToLevel, toggleChart }` |
683
+
684
+ - `MozPivotVue`는 `<MozGrid>`에 `mode='pivot'`을 강제(coreConfig computed 내부). 직접 forward되는 이벤트는 `['ready','data:loaded','filter:changed','pivot:toggled']`이며(`pivot:toggled`는 forward 목록에 있으나 코어 미발화), `update:rowFields`/`columnFields`/`valueFields`와 `pivot:configured`는 별도 `@update:coreConfig` 핸들러(`onCoreConfigUpdate`)에서 재-emit됩니다. coreConfig computed는 `availableFields`/`useFilter`를 삭제하고 `mode='pivot'` 설정, wrapperConfig는 `sourceFields > availableFields(legacy) > fields` 우선순위로 `sourceFields`를 채웁니다.
685
+
686
+ ---
687
+
688
+ ## Legacy 익스포트
689
+
690
+ `export * from './legacy'`로 패키지 소비자에 도달하는 **레거시 표면**입니다. (legacy 폴더는 pre-`MozGrid` 컴포넌트 셋. 신규 작업에는 사용하지 마세요.) 나열만 하며 상세 문서화는 생략합니다. 부작용으로 `legacy/index.ts`가 코어 CSS(`default.css`)를 import합니다.
691
+
692
+ | 분류 | 익스포트 (legacy) |
693
+ |------|-------------------|
694
+ | Vue 컴포넌트 (21) | `MozGridVue`, `MozGridVueCore`, `GridToolBox`, `GridOptionModal`, `ColumnPicker`(@deprecated), `ColumnSettings`, `GridBulkEditor`, `GridSearchInput`, `GridFilter`, `GridSort`, `GridCustomCell`, `GridContextMenu`, `GridFooter`, `MozPivotVue`, `PivotToolBox`, `PivotOptionModal`, `PivotFieldPanel`, `PivotContextMenu`, `PivotGrid`(@deprecated, `MozPivotVue` 별칭), `Dragging`, `ClientExcelUploadPopup` |
695
+ | 값/스토어/유틸 | `draggingEventBus`, `useExcelStore`, `useExcelDownloadStore`, `useExcelUploadStore`, `useClientExcelStore`, `runClientExport`, `exportCsv`, `generateSessionId`, `pickFile`, `downloadBlob`, `VueRenderer`, `UndoStack` |
696
+ | Composables (17) | `useGridInstance`, `useGridSelect`, `useGridEvents`, `useGridSelection`, `useGridChanges`, `useGridFilter`, `useGridSort`, `useGridCustomCell`, `useGridBulkEditor`, `useContextMenu`, `useGridUndoRedo`, `useGridValidation`, `useGridColumns`, `useColumnSettings`, `useColumnFormatter`, `useMaskPresets`, `matchPreset` |
697
+ | 아이콘 (20) | `IconAdd`, `IconArrowDownWithTail`, `IconArrowLeft`, `IconArrowLeftWithTail`, `IconArrowRight`, `IconArrowUpCenter`, `IconArrowUpWithTail`, `IconChart`, `IconClose`, `IconCustomCell`, `IconDownload`, `IconDragHandler`, `IconFilter`, `IconInfoFilled`, `IconReset`, `IconResetGridToolbar`, `IconSearch`, `IconSetting`, `IconSort`, `IconToastWarning` |
698
+ | 레거시 타입(로컬) | `ColumnFormatterOptions`, `UserCellFormat`(@deprecated), `UserHeaderFormat`(@deprecated), `IColumnCellFormat`, `IColumnHeaderFormat`, `IColumnFormatConfig`, `MaskPreset`, `MaskPresetGroup`, `MozGridVueCoreProps`, `MozGridVueProps`, `MozGridVueEmits`, `CellSlotProps`, `HeaderSlotProps`, `EditorSlotProps`, `DetailSlotProps`, `GroupSlotProps`, `TemplateRegistry`, `TemplateEntry`, `ComparisonOperator`, `LogicalOperator`, `IFilterDef`, `ISortDef`, `ICustomCellDef`, `ICustomCellRuleSet`, `ICustomCellConfig`, `IContextMenuItem`, `IContextMenuConfig`, `IContextMenuExcelEventArgs`, `AggregateType`, `IAggregateValues`, `UseGrid*Return` 류, `ClientExcelExportConfig`, `PivotGridProps`, `PivotFieldItem`, `AvailableField`, `PivotFieldPanelConfig`, `PivotGridSettings` |
699
+ | Injection 키 (7/8) | `GRID_INSTANCE_KEY`, `GRID_RENDERER_KEY`, `GRID_TEMPLATE_REGISTRY_KEY`, `GRID_FILTER_MODULE_KEY`, `GRID_SORT_MODULE_KEY`, `GRID_CUSTOM_CELL_MODULE_KEY`, `GRID_BULK_EDITOR_MODULE_KEY` (`GRID_CONTAINER_KEY` 제외) |
700
+ | 코어 타입 재-export | `PureSheetConfig`, `FieldDef`, `SortState`, `FilterState`, `Row`, `ColumnDef`, `GroupConfig`, `TreeConfig`, `MasterDetailConfig`, `PivotConfig`, `PivotRowField`, `PivotColumnField`, `PivotValueField`, `PivotResult`, `IPivotAPI`, `IRowsAPI` 외 다수(편의 패스스루) → 의미는 [reference.md](reference.md) |
701
+
702
+ > Injection 키 8종은 모두 `Symbol('moz-grid-…')`(번들 로컬, `Symbol.for` 아님)로 생성됩니다. `MozGrid`는 그중 4개(`GRID_INSTANCE_KEY`/`GRID_RENDERER_KEY`/`GRID_TEMPLATE_REGISTRY_KEY`/`GRID_CONTAINER_KEY`)를 provide하며, `GRID_CONTAINER_KEY`는 legacy 재-export 목록에서 제외됩니다. 슬롯 prop 타입(`CellSlotProps` 등)은 `types/slots.ts` 정의가 legacy 배럴로 노출됩니다.
703
+
704
+ ---
705
+
706
+ ## 관련 문서
707
+
708
+ - **코어 레퍼런스** → [reference.md](reference.md) — `PureSheetConfig`(`coreConfig`) 필드, 코어 타입, 이벤트 페이로드 형태, `PureSheet` API 전체
709
+ - **사용 예제** → [examples.md](examples.md) — Sub-API별 사용, 이벤트, 선택 모드, Excel I/O 등