@alneas/appkit-react 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (659) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +85 -15
  3. package/consumer-ai/SKILL.md +12 -0
  4. package/consumer-ai/api-index.json +103754 -0
  5. package/consumer-ai/package-context.json +409 -0
  6. package/dist/ai/action/ExecutionHistory.cjs.map +1 -1
  7. package/dist/ai/action/ExecutionHistory.d.cts +32 -2
  8. package/dist/ai/action/ExecutionHistory.d.ts +32 -2
  9. package/dist/ai/action/ExecutionHistory.js.map +1 -1
  10. package/dist/ai/action/ScreenActionContext.cjs.map +1 -1
  11. package/dist/ai/action/ScreenActionContext.d.cts +15 -2
  12. package/dist/ai/action/ScreenActionContext.d.ts +15 -2
  13. package/dist/ai/action/ScreenActionContext.js.map +1 -1
  14. package/dist/ai/action/context.cjs.map +1 -1
  15. package/dist/ai/action/context.d.cts +19 -3
  16. package/dist/ai/action/context.d.ts +19 -3
  17. package/dist/ai/action/context.js.map +1 -1
  18. package/dist/ai/action/types.d.cts +35 -3
  19. package/dist/ai/action/types.d.ts +35 -3
  20. package/dist/ai/action/use-execution-session.cjs.map +1 -1
  21. package/dist/ai/action/use-execution-session.d.cts +17 -1
  22. package/dist/ai/action/use-execution-session.d.ts +17 -1
  23. package/dist/ai/action/use-execution-session.js.map +1 -1
  24. package/dist/ai/action/use-screen-action-registry.cjs.map +1 -1
  25. package/dist/ai/action/use-screen-action-registry.d.cts +77 -8
  26. package/dist/ai/action/use-screen-action-registry.d.ts +77 -8
  27. package/dist/ai/action/use-screen-action-registry.js.map +1 -1
  28. package/dist/ai/action/use-screen-action.cjs.map +1 -1
  29. package/dist/ai/action/use-screen-action.d.cts +23 -6
  30. package/dist/ai/action/use-screen-action.d.ts +23 -6
  31. package/dist/ai/action/use-screen-action.js.map +1 -1
  32. package/dist/ai/action/use-screen-context.cjs.map +1 -1
  33. package/dist/ai/action/use-screen-context.d.cts +42 -5
  34. package/dist/ai/action/use-screen-context.d.ts +42 -5
  35. package/dist/ai/action/use-screen-context.js.map +1 -1
  36. package/dist/ai/ai-chat/transport.cjs.map +1 -1
  37. package/dist/ai/ai-chat/transport.d.cts +35 -8
  38. package/dist/ai/ai-chat/transport.d.ts +35 -8
  39. package/dist/ai/ai-chat/transport.js.map +1 -1
  40. package/dist/ai/generative-ui/GenerativeUIRenderer.cjs.map +1 -1
  41. package/dist/ai/generative-ui/GenerativeUIRenderer.d.cts +21 -3
  42. package/dist/ai/generative-ui/GenerativeUIRenderer.d.ts +21 -3
  43. package/dist/ai/generative-ui/GenerativeUIRenderer.js.map +1 -1
  44. package/dist/ai/generative-ui/error-boundary.cjs.map +1 -1
  45. package/dist/ai/generative-ui/error-boundary.d.cts +98 -2
  46. package/dist/ai/generative-ui/error-boundary.d.ts +98 -2
  47. package/dist/ai/generative-ui/error-boundary.js.map +1 -1
  48. package/dist/ai/generative-ui/registry.cjs.map +1 -1
  49. package/dist/ai/generative-ui/registry.d.cts +96 -7
  50. package/dist/ai/generative-ui/registry.d.ts +96 -7
  51. package/dist/ai/generative-ui/registry.js.map +1 -1
  52. package/dist/ai/proposal/ProposalFieldReview.cjs.map +1 -1
  53. package/dist/ai/proposal/ProposalFieldReview.d.cts +170 -8
  54. package/dist/ai/proposal/ProposalFieldReview.d.ts +170 -8
  55. package/dist/ai/proposal/ProposalFieldReview.js.map +1 -1
  56. package/dist/ai/proposal/types.d.cts +97 -26
  57. package/dist/ai/proposal/types.d.ts +97 -26
  58. package/dist/ai/proposal/use-proposal-batch-review.cjs.map +1 -1
  59. package/dist/ai/proposal/use-proposal-batch-review.d.cts +133 -7
  60. package/dist/ai/proposal/use-proposal-batch-review.d.ts +133 -7
  61. package/dist/ai/proposal/use-proposal-batch-review.js.map +1 -1
  62. package/dist/ai/proposal/use-proposal-review.cjs.map +1 -1
  63. package/dist/ai/proposal/use-proposal-review.d.cts +47 -5
  64. package/dist/ai/proposal/use-proposal-review.d.ts +47 -5
  65. package/dist/ai/proposal/use-proposal-review.js.map +1 -1
  66. package/dist/avatar.svg +1 -0
  67. package/dist/consumer-ai/SKILL.md +6 -0
  68. package/dist/consumer-ai/api-index.json +103754 -0
  69. package/dist/consumer-ai/package-context.json +5 -3
  70. package/dist/mockServiceWorker.js +361 -0
  71. package/dist/styles.css +1 -1
  72. package/dist/tools/components/auth/AuthForms.cjs.map +1 -1
  73. package/dist/tools/components/auth/AuthForms.d.cts +131 -81
  74. package/dist/tools/components/auth/AuthForms.d.ts +131 -81
  75. package/dist/tools/components/auth/AuthForms.js.map +1 -1
  76. package/dist/tools/components/auth/AuthGuard.cjs.map +1 -1
  77. package/dist/tools/components/auth/AuthGuard.d.cts +31 -4
  78. package/dist/tools/components/auth/AuthGuard.d.ts +31 -4
  79. package/dist/tools/components/auth/AuthGuard.js.map +1 -1
  80. package/dist/tools/components/auth/AuthProvider.cjs.map +1 -1
  81. package/dist/tools/components/auth/AuthProvider.d.cts +39 -42
  82. package/dist/tools/components/auth/AuthProvider.d.ts +39 -42
  83. package/dist/tools/components/auth/AuthProvider.js.map +1 -1
  84. package/dist/tools/components/auth/ProtectedRoute.cjs.map +1 -1
  85. package/dist/tools/components/auth/ProtectedRoute.d.cts +75 -60
  86. package/dist/tools/components/auth/ProtectedRoute.d.ts +75 -60
  87. package/dist/tools/components/auth/ProtectedRoute.js.map +1 -1
  88. package/dist/tools/components/auth/SignInButton.cjs.map +1 -1
  89. package/dist/tools/components/auth/SignInButton.d.cts +26 -18
  90. package/dist/tools/components/auth/SignInButton.d.ts +26 -18
  91. package/dist/tools/components/auth/SignInButton.js.map +1 -1
  92. package/dist/tools/components/auth/UserProfileProvider.cjs.map +1 -1
  93. package/dist/tools/components/auth/UserProfileProvider.d.cts +48 -20
  94. package/dist/tools/components/auth/UserProfileProvider.d.ts +48 -20
  95. package/dist/tools/components/auth/UserProfileProvider.js.map +1 -1
  96. package/dist/tools/components/auth/adapters/better-auth-adapter.cjs.map +1 -1
  97. package/dist/tools/components/auth/adapters/better-auth-adapter.d.cts +371 -51
  98. package/dist/tools/components/auth/adapters/better-auth-adapter.d.ts +371 -51
  99. package/dist/tools/components/auth/adapters/better-auth-adapter.js.map +1 -1
  100. package/dist/tools/components/auth/adapters/mock-adapter.cjs.map +1 -1
  101. package/dist/tools/components/auth/adapters/mock-adapter.d.cts +149 -28
  102. package/dist/tools/components/auth/adapters/mock-adapter.d.ts +149 -28
  103. package/dist/tools/components/auth/adapters/mock-adapter.js.map +1 -1
  104. package/dist/tools/components/auth/auth-session.cjs.map +1 -1
  105. package/dist/tools/components/auth/auth-session.d.cts +147 -1
  106. package/dist/tools/components/auth/auth-session.d.ts +147 -1
  107. package/dist/tools/components/auth/auth-session.js.map +1 -1
  108. package/dist/tools/components/auth/session-cache.cjs.map +1 -1
  109. package/dist/tools/components/auth/session-cache.d.cts +88 -24
  110. package/dist/tools/components/auth/session-cache.d.ts +88 -24
  111. package/dist/tools/components/auth/session-cache.js.map +1 -1
  112. package/dist/tools/components/auth/types.cjs.map +1 -1
  113. package/dist/tools/components/auth/types.d.cts +329 -106
  114. package/dist/tools/components/auth/types.d.ts +329 -106
  115. package/dist/tools/components/auth/types.js.map +1 -1
  116. package/dist/tools/components/auth/useAuth.cjs.map +1 -1
  117. package/dist/tools/components/auth/useAuth.d.cts +110 -17
  118. package/dist/tools/components/auth/useAuth.d.ts +110 -17
  119. package/dist/tools/components/auth/useAuth.js.map +1 -1
  120. package/dist/tools/components/auth/useAuthGuard.cjs.map +1 -1
  121. package/dist/tools/components/auth/useAuthGuard.d.cts +49 -38
  122. package/dist/tools/components/auth/useAuthGuard.d.ts +49 -38
  123. package/dist/tools/components/auth/useAuthGuard.js.map +1 -1
  124. package/dist/tools/components/auth/useRoleCheck.cjs.map +1 -1
  125. package/dist/tools/components/auth/useRoleCheck.d.cts +48 -1
  126. package/dist/tools/components/auth/useRoleCheck.d.ts +48 -1
  127. package/dist/tools/components/auth/useRoleCheck.js.map +1 -1
  128. package/dist/tools/components/auth/useUserProfile.cjs.map +1 -1
  129. package/dist/tools/components/auth/useUserProfile.d.cts +66 -1
  130. package/dist/tools/components/auth/useUserProfile.d.ts +66 -1
  131. package/dist/tools/components/auth/useUserProfile.js.map +1 -1
  132. package/dist/tools/components/barcode/BarcodeGenerator.cjs.map +1 -1
  133. package/dist/tools/components/barcode/BarcodeGenerator.d.cts +32 -18
  134. package/dist/tools/components/barcode/BarcodeGenerator.d.ts +32 -18
  135. package/dist/tools/components/barcode/BarcodeGenerator.js.map +1 -1
  136. package/dist/tools/components/barcode/QRCodeGenerator.cjs +1 -1
  137. package/dist/tools/components/barcode/QRCodeGenerator.cjs.map +1 -1
  138. package/dist/tools/components/barcode/QRCodeGenerator.d.cts +20 -13
  139. package/dist/tools/components/barcode/QRCodeGenerator.d.ts +20 -13
  140. package/dist/tools/components/barcode/QRCodeGenerator.js +1 -1
  141. package/dist/tools/components/barcode/QRCodeGenerator.js.map +1 -1
  142. package/dist/tools/components/barcode/QRCodeScanner.cjs.map +1 -1
  143. package/dist/tools/components/barcode/QRCodeScanner.d.cts +32 -1
  144. package/dist/tools/components/barcode/QRCodeScanner.d.ts +32 -1
  145. package/dist/tools/components/barcode/QRCodeScanner.js.map +1 -1
  146. package/dist/tools/components/calendar/ResourceCalendar.cjs.map +1 -1
  147. package/dist/tools/components/calendar/ResourceCalendar.d.cts +17 -42
  148. package/dist/tools/components/calendar/ResourceCalendar.d.ts +17 -42
  149. package/dist/tools/components/calendar/ResourceCalendar.js.map +1 -1
  150. package/dist/tools/components/calendar/views/ResourceView.cjs +1 -1
  151. package/dist/tools/components/calendar/views/ResourceView.cjs.map +1 -1
  152. package/dist/tools/components/calendar/views/ResourceView.js +2 -2
  153. package/dist/tools/components/calendar/views/ResourceView.js.map +1 -1
  154. package/dist/tools/components/chart/ComposedChart.cjs.map +1 -1
  155. package/dist/tools/components/chart/ComposedChart.d.cts +54 -1
  156. package/dist/tools/components/chart/ComposedChart.d.ts +54 -1
  157. package/dist/tools/components/chart/ComposedChart.js.map +1 -1
  158. package/dist/tools/components/chart/SimpleAreaChart.cjs.map +1 -1
  159. package/dist/tools/components/chart/SimpleAreaChart.d.cts +41 -1
  160. package/dist/tools/components/chart/SimpleAreaChart.d.ts +41 -1
  161. package/dist/tools/components/chart/SimpleAreaChart.js.map +1 -1
  162. package/dist/tools/components/chart/SimpleBarChart.cjs.map +1 -1
  163. package/dist/tools/components/chart/SimpleBarChart.d.cts +34 -24
  164. package/dist/tools/components/chart/SimpleBarChart.d.ts +34 -24
  165. package/dist/tools/components/chart/SimpleBarChart.js.map +1 -1
  166. package/dist/tools/components/chart/SimpleLineChart.cjs.map +1 -1
  167. package/dist/tools/components/chart/SimpleLineChart.d.cts +31 -28
  168. package/dist/tools/components/chart/SimpleLineChart.d.ts +31 -28
  169. package/dist/tools/components/chart/SimpleLineChart.js.map +1 -1
  170. package/dist/tools/components/chart/SimplePieChart.cjs.map +1 -1
  171. package/dist/tools/components/chart/SimplePieChart.d.cts +28 -22
  172. package/dist/tools/components/chart/SimplePieChart.d.ts +28 -22
  173. package/dist/tools/components/chart/SimplePieChart.js.map +1 -1
  174. package/dist/tools/components/chart/SimpleRadarChart.cjs.map +1 -1
  175. package/dist/tools/components/chart/SimpleRadarChart.d.cts +38 -1
  176. package/dist/tools/components/chart/SimpleRadarChart.d.ts +38 -1
  177. package/dist/tools/components/chart/SimpleRadarChart.js.map +1 -1
  178. package/dist/tools/components/chart/SimpleScatterChart.cjs.map +1 -1
  179. package/dist/tools/components/chart/SimpleScatterChart.d.cts +44 -1
  180. package/dist/tools/components/chart/SimpleScatterChart.d.ts +44 -1
  181. package/dist/tools/components/chart/SimpleScatterChart.js.map +1 -1
  182. package/dist/tools/components/chart/StackedBarChart.cjs.map +1 -1
  183. package/dist/tools/components/chart/StackedBarChart.d.cts +38 -1
  184. package/dist/tools/components/chart/StackedBarChart.d.ts +38 -1
  185. package/dist/tools/components/chart/StackedBarChart.js.map +1 -1
  186. package/dist/tools/components/data-table/data-table.cjs +1 -1
  187. package/dist/tools/components/data-table/data-table.cjs.map +1 -1
  188. package/dist/tools/components/data-table/data-table.js +286 -263
  189. package/dist/tools/components/data-table/data-table.js.map +1 -1
  190. package/dist/tools/components/data-table/table-utils.cjs.map +1 -1
  191. package/dist/tools/components/data-table/table-utils.d.cts +45 -35
  192. package/dist/tools/components/data-table/table-utils.d.ts +45 -35
  193. package/dist/tools/components/data-table/table-utils.js.map +1 -1
  194. package/dist/tools/components/editable-table/editable-table.cjs +1 -1
  195. package/dist/tools/components/editable-table/editable-table.cjs.map +1 -1
  196. package/dist/tools/components/editable-table/editable-table.js +15 -2
  197. package/dist/tools/components/editable-table/editable-table.js.map +1 -1
  198. package/dist/tools/components/error/ErrorDialog.cjs +1 -1
  199. package/dist/tools/components/error/ErrorDialog.cjs.map +1 -1
  200. package/dist/tools/components/error/ErrorDialog.js +1 -1
  201. package/dist/tools/components/error/ErrorDialog.js.map +1 -1
  202. package/dist/tools/components/error/ErrorInline.cjs +1 -1
  203. package/dist/tools/components/error/ErrorInline.cjs.map +1 -1
  204. package/dist/tools/components/error/ErrorInline.js +1 -1
  205. package/dist/tools/components/error/ErrorInline.js.map +1 -1
  206. package/dist/tools/components/error/ErrorNotification.cjs +1 -1
  207. package/dist/tools/components/error/ErrorNotification.cjs.map +1 -1
  208. package/dist/tools/components/error/ErrorNotification.js +10 -10
  209. package/dist/tools/components/error/ErrorNotification.js.map +1 -1
  210. package/dist/tools/components/file-browser/FilePreview.cjs +1 -1
  211. package/dist/tools/components/file-browser/FilePreview.cjs.map +1 -1
  212. package/dist/tools/components/file-browser/FilePreview.js +28 -26
  213. package/dist/tools/components/file-browser/FilePreview.js.map +1 -1
  214. package/dist/tools/components/filter/filter.cjs.map +1 -1
  215. package/dist/tools/components/filter/filter.d.cts +23 -34
  216. package/dist/tools/components/filter/filter.d.ts +23 -34
  217. package/dist/tools/components/filter/filter.js.map +1 -1
  218. package/dist/tools/components/form/EnhancedDetailPage.cjs.map +1 -1
  219. package/dist/tools/components/form/EnhancedDetailPage.d.cts +47 -42
  220. package/dist/tools/components/form/EnhancedDetailPage.d.ts +47 -42
  221. package/dist/tools/components/form/EnhancedDetailPage.js.map +1 -1
  222. package/dist/tools/components/form/form-grid.cjs.map +1 -1
  223. package/dist/tools/components/form/form-grid.d.cts +44 -22
  224. package/dist/tools/components/form/form-grid.d.ts +44 -22
  225. package/dist/tools/components/form/form-grid.js.map +1 -1
  226. package/dist/tools/components/gantt/GanttChart.cjs +1 -1
  227. package/dist/tools/components/gantt/GanttChart.cjs.map +1 -1
  228. package/dist/tools/components/gantt/GanttChart.d.cts +20 -1
  229. package/dist/tools/components/gantt/GanttChart.d.ts +20 -1
  230. package/dist/tools/components/gantt/GanttChart.js +3 -0
  231. package/dist/tools/components/gantt/GanttChart.js.map +1 -1
  232. package/dist/tools/components/gantt/components/GanttTaskBar.cjs +1 -1
  233. package/dist/tools/components/gantt/components/GanttTaskBar.cjs.map +1 -1
  234. package/dist/tools/components/gantt/components/GanttTaskBar.js +2 -1
  235. package/dist/tools/components/gantt/components/GanttTaskBar.js.map +1 -1
  236. package/dist/tools/components/header/header.cjs +1 -1
  237. package/dist/tools/components/header/header.cjs.map +1 -1
  238. package/dist/tools/components/header/header.d.cts +103 -40
  239. package/dist/tools/components/header/header.d.ts +103 -40
  240. package/dist/tools/components/header/header.js +1 -1
  241. package/dist/tools/components/header/header.js.map +1 -1
  242. package/dist/tools/components/i18n/LanguageSwitcher.cjs.map +1 -1
  243. package/dist/tools/components/i18n/LanguageSwitcher.d.cts +18 -14
  244. package/dist/tools/components/i18n/LanguageSwitcher.d.ts +18 -14
  245. package/dist/tools/components/i18n/LanguageSwitcher.js.map +1 -1
  246. package/dist/tools/components/kanban/KanbanBoard.cjs +1 -1
  247. package/dist/tools/components/kanban/KanbanBoard.cjs.map +1 -1
  248. package/dist/tools/components/kanban/KanbanBoard.d.cts +16 -34
  249. package/dist/tools/components/kanban/KanbanBoard.d.ts +16 -34
  250. package/dist/tools/components/kanban/KanbanBoard.js +3 -0
  251. package/dist/tools/components/kanban/KanbanBoard.js.map +1 -1
  252. package/dist/tools/components/kanban/KanbanColumn.cjs +1 -1
  253. package/dist/tools/components/kanban/KanbanColumn.cjs.map +1 -1
  254. package/dist/tools/components/kanban/KanbanColumn.js +1 -1
  255. package/dist/tools/components/kanban/KanbanColumn.js.map +1 -1
  256. package/dist/tools/components/kanban/kanban-compound.cjs +1 -1
  257. package/dist/tools/components/kanban/kanban-compound.cjs.map +1 -1
  258. package/dist/tools/components/kanban/kanban-compound.js +4 -1
  259. package/dist/tools/components/kanban/kanban-compound.js.map +1 -1
  260. package/dist/tools/components/kanban/kanban-primitives.cjs +1 -1
  261. package/dist/tools/components/kanban/kanban-primitives.cjs.map +1 -1
  262. package/dist/tools/components/kanban/kanban-primitives.js +0 -1
  263. package/dist/tools/components/kanban/kanban-primitives.js.map +1 -1
  264. package/dist/tools/components/priority-queue/PriorityCard.cjs +1 -1
  265. package/dist/tools/components/priority-queue/PriorityCard.cjs.map +1 -1
  266. package/dist/tools/components/priority-queue/PriorityCard.js +3 -1
  267. package/dist/tools/components/priority-queue/PriorityCard.js.map +1 -1
  268. package/dist/tools/components/sidebar/SmartSidebar.cjs.map +1 -1
  269. package/dist/tools/components/sidebar/SmartSidebar.d.cts +41 -43
  270. package/dist/tools/components/sidebar/SmartSidebar.d.ts +41 -43
  271. package/dist/tools/components/sidebar/SmartSidebar.js.map +1 -1
  272. package/dist/tools/components/splash/SplashScreen.cjs.map +1 -1
  273. package/dist/tools/components/splash/SplashScreen.d.cts +43 -68
  274. package/dist/tools/components/splash/SplashScreen.d.ts +43 -68
  275. package/dist/tools/components/splash/SplashScreen.js.map +1 -1
  276. package/dist/tools/components/workflow/WorkflowStatusPanel.cjs +1 -1
  277. package/dist/tools/components/workflow/WorkflowStatusPanel.cjs.map +1 -1
  278. package/dist/tools/components/workflow/WorkflowStatusPanel.js +2 -2
  279. package/dist/tools/components/workflow/WorkflowStatusPanel.js.map +1 -1
  280. package/dist/tools/lib/data-access/data-access-context.cjs.map +1 -1
  281. package/dist/tools/lib/data-access/data-access-context.d.cts +15 -6
  282. package/dist/tools/lib/data-access/data-access-context.d.ts +15 -6
  283. package/dist/tools/lib/data-access/data-access-context.js.map +1 -1
  284. package/dist/tools/lib/data-access/react-query-provider.cjs.map +1 -1
  285. package/dist/tools/lib/data-access/react-query-provider.d.cts +19 -2
  286. package/dist/tools/lib/data-access/react-query-provider.d.ts +19 -2
  287. package/dist/tools/lib/data-access/react-query-provider.js.map +1 -1
  288. package/dist/tools/lib/data-access/react-query.cjs.map +1 -1
  289. package/dist/tools/lib/data-access/react-query.d.cts +365 -90
  290. package/dist/tools/lib/data-access/react-query.d.ts +365 -90
  291. package/dist/tools/lib/data-access/react-query.js.map +1 -1
  292. package/dist/tools/lib/error/AppError.cjs.map +1 -1
  293. package/dist/tools/lib/error/AppError.d.cts +157 -63
  294. package/dist/tools/lib/error/AppError.d.ts +157 -63
  295. package/dist/tools/lib/error/AppError.js.map +1 -1
  296. package/dist/tools/lib/hooks/useAsyncWithTimeout.cjs.map +1 -1
  297. package/dist/tools/lib/hooks/useAsyncWithTimeout.d.cts +79 -26
  298. package/dist/tools/lib/hooks/useAsyncWithTimeout.d.ts +79 -26
  299. package/dist/tools/lib/hooks/useAsyncWithTimeout.js.map +1 -1
  300. package/dist/tools/lib/hooks/useError.cjs.map +1 -1
  301. package/dist/tools/lib/hooks/useError.d.cts +51 -16
  302. package/dist/tools/lib/hooks/useError.d.ts +51 -16
  303. package/dist/tools/lib/hooks/useError.js.map +1 -1
  304. package/dist/tools/lib/schema/ajv.cjs +1 -1
  305. package/dist/tools/lib/schema/ajv.cjs.map +1 -1
  306. package/dist/tools/lib/schema/ajv.d.cts +19 -8
  307. package/dist/tools/lib/schema/ajv.d.ts +19 -8
  308. package/dist/tools/lib/schema/ajv.js +2 -1
  309. package/dist/tools/lib/schema/ajv.js.map +1 -1
  310. package/dist/tools/lib/state/error-store.cjs.map +1 -1
  311. package/dist/tools/lib/state/error-store.d.cts +61 -10
  312. package/dist/tools/lib/state/error-store.d.ts +61 -10
  313. package/dist/tools/lib/state/error-store.js.map +1 -1
  314. package/dist/tools/lib/state/store-factory.cjs.map +1 -1
  315. package/dist/tools/lib/state/store-factory.d.cts +25 -4
  316. package/dist/tools/lib/state/store-factory.d.ts +25 -4
  317. package/dist/tools/lib/state/store-factory.js.map +1 -1
  318. package/dist/tools/lib/state/ui-store.cjs.map +1 -1
  319. package/dist/tools/lib/state/ui-store.d.cts +39 -0
  320. package/dist/tools/lib/state/ui-store.d.ts +39 -0
  321. package/dist/tools/lib/state/ui-store.js.map +1 -1
  322. package/dist/ui/components/theme/theme-context.cjs.map +1 -1
  323. package/dist/ui/components/theme/theme-context.d.cts +171 -1
  324. package/dist/ui/components/theme/theme-context.d.ts +171 -1
  325. package/dist/ui/components/theme/theme-context.js.map +1 -1
  326. package/dist/ui/components/theme/theme-provider.cjs.map +1 -1
  327. package/dist/ui/components/theme/theme-provider.d.cts +31 -19
  328. package/dist/ui/components/theme/theme-provider.d.ts +31 -19
  329. package/dist/ui/components/theme/theme-provider.js.map +1 -1
  330. package/dist/ui/components/theme/theme-script.cjs.map +1 -1
  331. package/dist/ui/components/theme/theme-script.d.cts +16 -1
  332. package/dist/ui/components/theme/theme-script.d.ts +16 -1
  333. package/dist/ui/components/theme/theme-script.js.map +1 -1
  334. package/dist/ui/components/theme/theme-switcher.cjs +1 -1
  335. package/dist/ui/components/theme/theme-switcher.cjs.map +1 -1
  336. package/dist/ui/components/theme/theme-switcher.d.cts +82 -13
  337. package/dist/ui/components/theme/theme-switcher.d.ts +82 -13
  338. package/dist/ui/components/theme/theme-switcher.js +8 -0
  339. package/dist/ui/components/theme/theme-switcher.js.map +1 -1
  340. package/dist/ui/components/ui/accordion.cjs.map +1 -1
  341. package/dist/ui/components/ui/accordion.d.cts +60 -0
  342. package/dist/ui/components/ui/accordion.d.ts +60 -0
  343. package/dist/ui/components/ui/accordion.js.map +1 -1
  344. package/dist/ui/components/ui/adjustable-pane.cjs.map +1 -1
  345. package/dist/ui/components/ui/adjustable-pane.d.cts +44 -26
  346. package/dist/ui/components/ui/adjustable-pane.d.ts +44 -26
  347. package/dist/ui/components/ui/adjustable-pane.js.map +1 -1
  348. package/dist/ui/components/ui/alert-dialog.cjs.map +1 -1
  349. package/dist/ui/components/ui/alert-dialog.d.cts +179 -2
  350. package/dist/ui/components/ui/alert-dialog.d.ts +179 -2
  351. package/dist/ui/components/ui/alert-dialog.js.map +1 -1
  352. package/dist/ui/components/ui/alert.cjs.map +1 -1
  353. package/dist/ui/components/ui/alert.d.cts +52 -4
  354. package/dist/ui/components/ui/alert.d.ts +52 -4
  355. package/dist/ui/components/ui/alert.js.map +1 -1
  356. package/dist/ui/components/ui/aspect-ratio.cjs.map +1 -1
  357. package/dist/ui/components/ui/aspect-ratio.d.cts +16 -1
  358. package/dist/ui/components/ui/aspect-ratio.d.ts +16 -1
  359. package/dist/ui/components/ui/aspect-ratio.js.map +1 -1
  360. package/dist/ui/components/ui/avatar.cjs.map +1 -1
  361. package/dist/ui/components/ui/avatar.d.cts +87 -3
  362. package/dist/ui/components/ui/avatar.d.ts +87 -3
  363. package/dist/ui/components/ui/avatar.js.map +1 -1
  364. package/dist/ui/components/ui/badge-components.cjs.map +1 -1
  365. package/dist/ui/components/ui/badge-components.d.cts +13 -1
  366. package/dist/ui/components/ui/badge-components.d.ts +13 -1
  367. package/dist/ui/components/ui/badge-components.js.map +1 -1
  368. package/dist/ui/components/ui/badge-variants.cjs.map +1 -1
  369. package/dist/ui/components/ui/badge-variants.d.cts +15 -0
  370. package/dist/ui/components/ui/badge-variants.d.ts +15 -0
  371. package/dist/ui/components/ui/badge-variants.js.map +1 -1
  372. package/dist/ui/components/ui/breadcrumb.cjs.map +1 -1
  373. package/dist/ui/components/ui/breadcrumb.d.cts +91 -7
  374. package/dist/ui/components/ui/breadcrumb.d.ts +91 -7
  375. package/dist/ui/components/ui/breadcrumb.js.map +1 -1
  376. package/dist/ui/components/ui/button-components.cjs.map +1 -1
  377. package/dist/ui/components/ui/button-components.d.cts +18 -6
  378. package/dist/ui/components/ui/button-components.d.ts +18 -6
  379. package/dist/ui/components/ui/button-components.js.map +1 -1
  380. package/dist/ui/components/ui/button-group-components.cjs.map +1 -1
  381. package/dist/ui/components/ui/button-group-components.d.cts +39 -3
  382. package/dist/ui/components/ui/button-group-components.d.ts +39 -3
  383. package/dist/ui/components/ui/button-group-components.js.map +1 -1
  384. package/dist/ui/components/ui/button-group-variants.cjs.map +1 -1
  385. package/dist/ui/components/ui/button-group-variants.d.cts +15 -0
  386. package/dist/ui/components/ui/button-group-variants.d.ts +15 -0
  387. package/dist/ui/components/ui/button-group-variants.js.map +1 -1
  388. package/dist/ui/components/ui/button-variants.cjs.map +1 -1
  389. package/dist/ui/components/ui/button-variants.d.cts +13 -2
  390. package/dist/ui/components/ui/button-variants.d.ts +13 -2
  391. package/dist/ui/components/ui/button-variants.js.map +1 -1
  392. package/dist/ui/components/ui/card.cjs.map +1 -1
  393. package/dist/ui/components/ui/card.d.cts +106 -2
  394. package/dist/ui/components/ui/card.d.ts +106 -2
  395. package/dist/ui/components/ui/card.js.map +1 -1
  396. package/dist/ui/components/ui/checkbox-group.cjs.map +1 -1
  397. package/dist/ui/components/ui/checkbox-group.d.cts +13 -1
  398. package/dist/ui/components/ui/checkbox-group.d.ts +13 -1
  399. package/dist/ui/components/ui/checkbox-group.js.map +1 -1
  400. package/dist/ui/components/ui/checkbox.cjs.map +1 -1
  401. package/dist/ui/components/ui/checkbox.d.cts +17 -6
  402. package/dist/ui/components/ui/checkbox.d.ts +17 -6
  403. package/dist/ui/components/ui/checkbox.js.map +1 -1
  404. package/dist/ui/components/ui/collapsible.cjs.map +1 -1
  405. package/dist/ui/components/ui/collapsible.d.cts +39 -3
  406. package/dist/ui/components/ui/collapsible.d.ts +39 -3
  407. package/dist/ui/components/ui/collapsible.js.map +1 -1
  408. package/dist/ui/components/ui/combobox-components.cjs.map +1 -1
  409. package/dist/ui/components/ui/combobox-components.d.cts +209 -14
  410. package/dist/ui/components/ui/combobox-components.d.ts +209 -14
  411. package/dist/ui/components/ui/combobox-components.js.map +1 -1
  412. package/dist/ui/components/ui/combobox-hooks.cjs.map +1 -1
  413. package/dist/ui/components/ui/combobox-hooks.d.cts +13 -1
  414. package/dist/ui/components/ui/combobox-hooks.d.ts +13 -1
  415. package/dist/ui/components/ui/combobox-hooks.js.map +1 -1
  416. package/dist/ui/components/ui/command.cjs.map +1 -1
  417. package/dist/ui/components/ui/command.d.cts +132 -9
  418. package/dist/ui/components/ui/command.d.ts +132 -9
  419. package/dist/ui/components/ui/command.js.map +1 -1
  420. package/dist/ui/components/ui/context-menu.cjs.map +1 -1
  421. package/dist/ui/components/ui/context-menu.d.cts +233 -2
  422. package/dist/ui/components/ui/context-menu.d.ts +233 -2
  423. package/dist/ui/components/ui/context-menu.js.map +1 -1
  424. package/dist/ui/components/ui/dialog.cjs.map +1 -1
  425. package/dist/ui/components/ui/dialog.d.cts +157 -5
  426. package/dist/ui/components/ui/dialog.d.ts +157 -5
  427. package/dist/ui/components/ui/dialog.js.map +1 -1
  428. package/dist/ui/components/ui/drawer.cjs.map +1 -1
  429. package/dist/ui/components/ui/drawer.d.cts +130 -10
  430. package/dist/ui/components/ui/drawer.d.ts +130 -10
  431. package/dist/ui/components/ui/drawer.js.map +1 -1
  432. package/dist/ui/components/ui/dropdown-menu.cjs.map +1 -1
  433. package/dist/ui/components/ui/dropdown-menu.d.cts +225 -6
  434. package/dist/ui/components/ui/dropdown-menu.d.ts +225 -6
  435. package/dist/ui/components/ui/dropdown-menu.js.map +1 -1
  436. package/dist/ui/components/ui/empty.cjs.map +1 -1
  437. package/dist/ui/components/ui/empty.d.cts +78 -6
  438. package/dist/ui/components/ui/empty.d.ts +78 -6
  439. package/dist/ui/components/ui/empty.js.map +1 -1
  440. package/dist/ui/components/ui/field.cjs.map +1 -1
  441. package/dist/ui/components/ui/field.d.cts +180 -6
  442. package/dist/ui/components/ui/field.d.ts +180 -6
  443. package/dist/ui/components/ui/field.js.map +1 -1
  444. package/dist/ui/components/ui/file-icon.cjs.map +1 -1
  445. package/dist/ui/components/ui/file-icon.d.cts +32 -4
  446. package/dist/ui/components/ui/file-icon.d.ts +32 -4
  447. package/dist/ui/components/ui/file-icon.js.map +1 -1
  448. package/dist/ui/components/ui/hover-card.cjs.map +1 -1
  449. package/dist/ui/components/ui/hover-card.d.cts +39 -3
  450. package/dist/ui/components/ui/hover-card.d.ts +39 -3
  451. package/dist/ui/components/ui/hover-card.js.map +1 -1
  452. package/dist/ui/components/ui/input-group.cjs.map +1 -1
  453. package/dist/ui/components/ui/input-group.d.cts +84 -6
  454. package/dist/ui/components/ui/input-group.d.ts +84 -6
  455. package/dist/ui/components/ui/input-group.js.map +1 -1
  456. package/dist/ui/components/ui/input-otp.cjs.map +1 -1
  457. package/dist/ui/components/ui/input-otp.d.cts +58 -4
  458. package/dist/ui/components/ui/input-otp.d.ts +58 -4
  459. package/dist/ui/components/ui/input-otp.js.map +1 -1
  460. package/dist/ui/components/ui/input.cjs.map +1 -1
  461. package/dist/ui/components/ui/input.d.cts +18 -10
  462. package/dist/ui/components/ui/input.d.ts +18 -10
  463. package/dist/ui/components/ui/input.js.map +1 -1
  464. package/dist/ui/components/ui/item.cjs.map +1 -1
  465. package/dist/ui/components/ui/item.d.cts +130 -10
  466. package/dist/ui/components/ui/item.d.ts +130 -10
  467. package/dist/ui/components/ui/item.js.map +1 -1
  468. package/dist/ui/components/ui/kbd.cjs.map +1 -1
  469. package/dist/ui/components/ui/kbd.d.cts +26 -2
  470. package/dist/ui/components/ui/kbd.d.ts +26 -2
  471. package/dist/ui/components/ui/kbd.js.map +1 -1
  472. package/dist/ui/components/ui/label.cjs.map +1 -1
  473. package/dist/ui/components/ui/label.d.cts +15 -0
  474. package/dist/ui/components/ui/label.d.ts +15 -0
  475. package/dist/ui/components/ui/label.js.map +1 -1
  476. package/dist/ui/components/ui/layout.cjs +1 -1
  477. package/dist/ui/components/ui/layout.cjs.map +1 -1
  478. package/dist/ui/components/ui/layout.d.cts +45 -11
  479. package/dist/ui/components/ui/layout.d.ts +45 -11
  480. package/dist/ui/components/ui/layout.js +22 -20
  481. package/dist/ui/components/ui/layout.js.map +1 -1
  482. package/dist/ui/components/ui/menubar.cjs.map +1 -1
  483. package/dist/ui/components/ui/menubar.d.cts +220 -16
  484. package/dist/ui/components/ui/menubar.d.ts +220 -16
  485. package/dist/ui/components/ui/menubar.js.map +1 -1
  486. package/dist/ui/components/ui/meter.cjs.map +1 -1
  487. package/dist/ui/components/ui/meter.d.cts +52 -4
  488. package/dist/ui/components/ui/meter.d.ts +52 -4
  489. package/dist/ui/components/ui/meter.js.map +1 -1
  490. package/dist/ui/components/ui/mobile-form-variants.cjs.map +1 -1
  491. package/dist/ui/components/ui/mobile-form-variants.d.cts +30 -0
  492. package/dist/ui/components/ui/mobile-form-variants.d.ts +30 -0
  493. package/dist/ui/components/ui/mobile-form-variants.js.map +1 -1
  494. package/dist/ui/components/ui/mobile-form.cjs.map +1 -1
  495. package/dist/ui/components/ui/mobile-form.d.cts +186 -9
  496. package/dist/ui/components/ui/mobile-form.d.ts +186 -9
  497. package/dist/ui/components/ui/mobile-form.js.map +1 -1
  498. package/dist/ui/components/ui/navigation-menu-components.cjs.map +1 -1
  499. package/dist/ui/components/ui/navigation-menu-components.d.cts +104 -8
  500. package/dist/ui/components/ui/navigation-menu-components.d.ts +104 -8
  501. package/dist/ui/components/ui/navigation-menu-components.js.map +1 -1
  502. package/dist/ui/components/ui/navigation-menu-variants.cjs.map +1 -1
  503. package/dist/ui/components/ui/navigation-menu-variants.d.cts +15 -0
  504. package/dist/ui/components/ui/navigation-menu-variants.d.ts +15 -0
  505. package/dist/ui/components/ui/navigation-menu-variants.js.map +1 -1
  506. package/dist/ui/components/ui/number-field.cjs.map +1 -1
  507. package/dist/ui/components/ui/number-field.d.cts +78 -6
  508. package/dist/ui/components/ui/number-field.d.ts +78 -6
  509. package/dist/ui/components/ui/number-field.js.map +1 -1
  510. package/dist/ui/components/ui/pagination.cjs.map +1 -1
  511. package/dist/ui/components/ui/pagination.d.cts +99 -7
  512. package/dist/ui/components/ui/pagination.d.ts +99 -7
  513. package/dist/ui/components/ui/pagination.js.map +1 -1
  514. package/dist/ui/components/ui/password-input.cjs.map +1 -1
  515. package/dist/ui/components/ui/password-input.d.cts +10 -7
  516. package/dist/ui/components/ui/password-input.d.ts +10 -7
  517. package/dist/ui/components/ui/password-input.js.map +1 -1
  518. package/dist/ui/components/ui/popover.cjs.map +1 -1
  519. package/dist/ui/components/ui/popover.d.cts +86 -2
  520. package/dist/ui/components/ui/popover.d.ts +86 -2
  521. package/dist/ui/components/ui/popover.js.map +1 -1
  522. package/dist/ui/components/ui/progress.cjs.map +1 -1
  523. package/dist/ui/components/ui/progress.d.cts +72 -2
  524. package/dist/ui/components/ui/progress.d.ts +72 -2
  525. package/dist/ui/components/ui/progress.js.map +1 -1
  526. package/dist/ui/components/ui/radio-card.cjs.map +1 -1
  527. package/dist/ui/components/ui/radio-card.d.cts +32 -4
  528. package/dist/ui/components/ui/radio-card.d.ts +32 -4
  529. package/dist/ui/components/ui/radio-card.js.map +1 -1
  530. package/dist/ui/components/ui/radio-group.cjs.map +1 -1
  531. package/dist/ui/components/ui/radio-group.d.cts +28 -2
  532. package/dist/ui/components/ui/radio-group.d.ts +28 -2
  533. package/dist/ui/components/ui/radio-group.js.map +1 -1
  534. package/dist/ui/components/ui/resizable.cjs.map +1 -1
  535. package/dist/ui/components/ui/resizable.d.cts +42 -3
  536. package/dist/ui/components/ui/resizable.d.ts +42 -3
  537. package/dist/ui/components/ui/resizable.js.map +1 -1
  538. package/dist/ui/components/ui/responsive-list.cjs.map +1 -1
  539. package/dist/ui/components/ui/responsive-list.d.cts +176 -13
  540. package/dist/ui/components/ui/responsive-list.d.ts +176 -13
  541. package/dist/ui/components/ui/responsive-list.js.map +1 -1
  542. package/dist/ui/components/ui/scroll-area.cjs.map +1 -1
  543. package/dist/ui/components/ui/scroll-area.d.cts +28 -1
  544. package/dist/ui/components/ui/scroll-area.d.ts +28 -1
  545. package/dist/ui/components/ui/scroll-area.js.map +1 -1
  546. package/dist/ui/components/ui/searchable-select-input.cjs.map +1 -1
  547. package/dist/ui/components/ui/searchable-select-input.d.cts +199 -49
  548. package/dist/ui/components/ui/searchable-select-input.d.ts +199 -49
  549. package/dist/ui/components/ui/searchable-select-input.js.map +1 -1
  550. package/dist/ui/components/ui/select.cjs.map +1 -1
  551. package/dist/ui/components/ui/select.d.cts +205 -40
  552. package/dist/ui/components/ui/select.d.ts +205 -40
  553. package/dist/ui/components/ui/select.js.map +1 -1
  554. package/dist/ui/components/ui/separator.cjs.map +1 -1
  555. package/dist/ui/components/ui/separator.d.cts +13 -2
  556. package/dist/ui/components/ui/separator.d.ts +13 -2
  557. package/dist/ui/components/ui/separator.js.map +1 -1
  558. package/dist/ui/components/ui/sheet.cjs.map +1 -1
  559. package/dist/ui/components/ui/sheet.d.cts +128 -3
  560. package/dist/ui/components/ui/sheet.d.ts +128 -3
  561. package/dist/ui/components/ui/sheet.js.map +1 -1
  562. package/dist/ui/components/ui/skeleton.cjs.map +1 -1
  563. package/dist/ui/components/ui/skeleton.d.cts +13 -1
  564. package/dist/ui/components/ui/skeleton.d.ts +13 -1
  565. package/dist/ui/components/ui/skeleton.js.map +1 -1
  566. package/dist/ui/components/ui/slider.cjs.map +1 -1
  567. package/dist/ui/components/ui/slider.d.cts +13 -7
  568. package/dist/ui/components/ui/slider.d.ts +13 -7
  569. package/dist/ui/components/ui/slider.js.map +1 -1
  570. package/dist/ui/components/ui/spinner.cjs.map +1 -1
  571. package/dist/ui/components/ui/spinner.d.cts +13 -1
  572. package/dist/ui/components/ui/spinner.d.ts +13 -1
  573. package/dist/ui/components/ui/spinner.js.map +1 -1
  574. package/dist/ui/components/ui/switch.cjs.map +1 -1
  575. package/dist/ui/components/ui/switch.d.cts +26 -0
  576. package/dist/ui/components/ui/switch.d.ts +26 -0
  577. package/dist/ui/components/ui/switch.js.map +1 -1
  578. package/dist/ui/components/ui/table.cjs.map +1 -1
  579. package/dist/ui/components/ui/table.d.cts +118 -2
  580. package/dist/ui/components/ui/table.d.ts +118 -2
  581. package/dist/ui/components/ui/table.js.map +1 -1
  582. package/dist/ui/components/ui/tabs-components.cjs.map +1 -1
  583. package/dist/ui/components/ui/tabs-components.d.cts +52 -5
  584. package/dist/ui/components/ui/tabs-components.d.ts +52 -5
  585. package/dist/ui/components/ui/tabs-components.js.map +1 -1
  586. package/dist/ui/components/ui/tabs-variants.cjs.map +1 -1
  587. package/dist/ui/components/ui/tabs-variants.d.cts +15 -0
  588. package/dist/ui/components/ui/tabs-variants.d.ts +15 -0
  589. package/dist/ui/components/ui/tabs-variants.js.map +1 -1
  590. package/dist/ui/components/ui/textarea.cjs.map +1 -1
  591. package/dist/ui/components/ui/textarea.d.cts +23 -0
  592. package/dist/ui/components/ui/textarea.d.ts +23 -0
  593. package/dist/ui/components/ui/textarea.js.map +1 -1
  594. package/dist/ui/components/ui/toast.cjs.map +1 -1
  595. package/dist/ui/components/ui/toast.d.cts +136 -0
  596. package/dist/ui/components/ui/toast.d.ts +136 -0
  597. package/dist/ui/components/ui/toast.js.map +1 -1
  598. package/dist/ui/components/ui/toaster.cjs.map +1 -1
  599. package/dist/ui/components/ui/toaster.d.cts +12 -3
  600. package/dist/ui/components/ui/toaster.d.ts +12 -3
  601. package/dist/ui/components/ui/toaster.js.map +1 -1
  602. package/dist/ui/components/ui/toggle-components.cjs.map +1 -1
  603. package/dist/ui/components/ui/toggle-components.d.cts +15 -0
  604. package/dist/ui/components/ui/toggle-components.d.ts +15 -0
  605. package/dist/ui/components/ui/toggle-components.js.map +1 -1
  606. package/dist/ui/components/ui/toggle-group.cjs.map +1 -1
  607. package/dist/ui/components/ui/toggle-group.d.cts +33 -0
  608. package/dist/ui/components/ui/toggle-group.d.ts +33 -0
  609. package/dist/ui/components/ui/toggle-group.js.map +1 -1
  610. package/dist/ui/components/ui/toggle-variants.cjs.map +1 -1
  611. package/dist/ui/components/ui/toggle-variants.d.cts +15 -0
  612. package/dist/ui/components/ui/toggle-variants.d.ts +15 -0
  613. package/dist/ui/components/ui/toggle-variants.js.map +1 -1
  614. package/dist/ui/components/ui/toolbar.cjs.map +1 -1
  615. package/dist/ui/components/ui/toolbar.d.cts +94 -7
  616. package/dist/ui/components/ui/toolbar.d.ts +94 -7
  617. package/dist/ui/components/ui/toolbar.js.map +1 -1
  618. package/dist/ui/components/ui/tooltip.cjs.map +1 -1
  619. package/dist/ui/components/ui/tooltip.d.cts +54 -3
  620. package/dist/ui/components/ui/tooltip.d.ts +54 -3
  621. package/dist/ui/components/ui/tooltip.js.map +1 -1
  622. package/dist/ui/lib/hooks/use-gps.cjs.map +1 -1
  623. package/dist/ui/lib/hooks/use-gps.d.cts +29 -4
  624. package/dist/ui/lib/hooks/use-gps.d.ts +29 -4
  625. package/dist/ui/lib/hooks/use-gps.js.map +1 -1
  626. package/dist/ui/lib/hooks/use-is-client.cjs.map +1 -1
  627. package/dist/ui/lib/hooks/use-is-client.d.cts +11 -2
  628. package/dist/ui/lib/hooks/use-is-client.d.ts +11 -2
  629. package/dist/ui/lib/hooks/use-is-client.js.map +1 -1
  630. package/dist/ui/lib/hooks/use-keyboard-shortcut.cjs.map +1 -1
  631. package/dist/ui/lib/hooks/use-keyboard-shortcut.d.cts +48 -18
  632. package/dist/ui/lib/hooks/use-keyboard-shortcut.d.ts +48 -18
  633. package/dist/ui/lib/hooks/use-keyboard-shortcut.js.map +1 -1
  634. package/dist/ui/lib/hooks/use-mobile.cjs.map +1 -1
  635. package/dist/ui/lib/hooks/use-mobile.d.cts +11 -3
  636. package/dist/ui/lib/hooks/use-mobile.d.ts +11 -3
  637. package/dist/ui/lib/hooks/use-mobile.js.map +1 -1
  638. package/dist/ui/lib/hooks/use-toast.cjs.map +1 -1
  639. package/dist/ui/lib/hooks/use-toast.d.cts +184 -15
  640. package/dist/ui/lib/hooks/use-toast.d.ts +184 -15
  641. package/dist/ui/lib/hooks/use-toast.js.map +1 -1
  642. package/dist/ui/lib/ime-utils.cjs.map +1 -1
  643. package/dist/ui/lib/ime-utils.d.cts +40 -13
  644. package/dist/ui/lib/ime-utils.d.ts +40 -13
  645. package/dist/ui/lib/ime-utils.js.map +1 -1
  646. package/dist/ui/lib/utils.cjs.map +1 -1
  647. package/dist/ui/lib/utils.d.cts +9 -6
  648. package/dist/ui/lib/utils.d.ts +9 -6
  649. package/dist/ui/lib/utils.js.map +1 -1
  650. package/docs/ai.md +34 -1
  651. package/docs/exports.md +5 -1
  652. package/docs/index.md +89 -16
  653. package/docs/migration.md +268 -0
  654. package/docs/request-form.md +4 -1
  655. package/docs/tools.md +4 -1
  656. package/docs/ui.md +4 -1
  657. package/llms-full.txt +499 -36
  658. package/llms.txt +4 -0
  659. package/package.json +35 -5
@@ -46,20 +46,16 @@ export type TableHeadBase = {
46
46
  editable?: boolean;
47
47
  };
48
48
  /**
49
- * createColumnsFromHeads のオプション
50
- * Options for createColumnsFromHeads
51
- *
52
- * @typedef {Object} CreateColumnsOptions
53
- * @property {string} [locale] - ロケール / Locale for date formatting
54
- * @property {string} [timezone] - タイムゾーン / Timezone for date formatting
55
- * @property {string} [arraySeparator] - 配列の結合文字 / Separator for joining array values
49
+ * Compatibility options for {@link createColumnsFromHeads}.
50
+ * @remarks Only arraySeparator is currently consumed; locale and timezone do not affect generated cells.
51
+ * @see createColumnsFromHeads
56
52
  */
57
53
  export type CreateColumnsOptions = {
58
- /** ロケール(日付フォーマット用) / Locale for date formatting */
54
+ /** Reserved compatibility option; currently ignored by createColumnsFromHeads. No locale default is applied here. */
59
55
  locale?: string;
60
- /** タイムゾーン(日付フォーマット用) / Timezone for date formatting */
56
+ /** Reserved compatibility option; currently ignored by createColumnsFromHeads. No timezone default is applied here. */
61
57
  timezone?: string;
62
- /** 配列の結合文字 / Separator for joining array values */
58
+ /** Separator for joining array values; defaults to " / ". */
63
59
  arraySeparator?: string;
64
60
  };
65
61
  /**
@@ -71,9 +67,12 @@ export type CreateColumnsOptions = {
71
67
  * @returns {unknown} 指定パスの値、存在しない場合はundefined / The value at the path
72
68
  *
73
69
  * @example
74
- * const obj = { user: { profile: { name: "John" } } };
75
- * getNestedValue(obj, "user.profile.name"); // "John"
76
- * getNestedValue(obj, "user.email"); // undefined
70
+ * ```ts
71
+ * import { getNestedValue } from '@alneas/appkit-react/tools/data-table';
72
+ * const obj = { user: { profile: { name: 'John' } } };
73
+ * getNestedValue(obj, 'user.profile.name'); // 'John'
74
+ * getNestedValue(obj, 'user.email'); // undefined
75
+ * ```
77
76
  */
78
77
  export declare const getNestedValue: (obj: KV, path: string) => unknown;
79
78
  /**
@@ -82,8 +81,12 @@ export declare const getNestedValue: (obj: KV, path: string) => unknown;
82
81
  * Each generator returns a function that takes a row and returns a formatted string.
83
82
  *
84
83
  * @example
84
+ * ```ts
85
+ * import { cellGenerators } from '@alneas/appkit-react/tools/data-table';
86
+ * const rowData = { createdAt: new Date(2026, 0, 15) };
85
87
  * const dateCell = cellGenerators.Date('createdAt');
86
- * const formatted = dateCell(rowData); // "2024/01/15"
88
+ * const formatted = dateCell(rowData);
89
+ * ```
87
90
  */
88
91
  export declare const cellGenerators: {
89
92
  /**
@@ -127,7 +130,11 @@ export declare const cellGenerators: {
127
130
  * @returns {(row: KV) => string} セルレンダラー関数 / Cell renderer function
128
131
  *
129
132
  * @example
130
- * const statusCell = cellGenerators.Option('status', { 0: '未処理', 1: '完了' });
133
+ * ```ts
134
+ * import { cellGenerators } from '@alneas/appkit-react/tools/data-table';
135
+ * const statusCell = cellGenerators.Option('status', { 0: 'Pending', 1: 'Complete' });
136
+ * const label = statusCell({ status: 1 }); // 'Complete'
137
+ * ```
131
138
  */
132
139
  Option: (field: string, options?: Record<string | number, string>) => (row: KV) => string;
133
140
  /**
@@ -178,25 +185,25 @@ export declare const timeSort: SortingFn<KV>;
178
185
  */
179
186
  export declare const trimmedSort: SortingFn<KV>;
180
187
  /**
181
- * 宣言的なヘッダー定義からTanStack Tableのカラム定義を生成する
182
- * Creates TanStack Table column definitions from a declarative TableHeadBase array.
183
- *
184
- * デフォルト動作:
185
- * - 論理的な`type`を`cellGenerators`にマッピング
186
- * - Optionセル用の`options`マッピングを使用
187
- * - TimeString型には`timeSort`を適用
188
- * - その他の型には`trimmedSort`を適用
189
- *
190
- * @param {TableHeadBase[]} heads - ヘッダー定義の配列 / Array of header definitions
191
- * @param {CreateColumnsOptions} [options] - オプション設定 / Optional configuration
192
- * @returns {ColumnDef<KV>[]} TanStack Tableのカラム定義配列 / Array of column definitions
193
- *
188
+ * Creates table column definitions from declarative headers and built-in cell generators.
189
+ * @param heads - Header definitions in display order; field selects a row path and id can
190
+ * override the source path. Cell type defaults to String and sorting is enabled unless explicitly false.
191
+ * @param options - Array formatting options; see {@link CreateColumnsOptions}. arraySeparator
192
+ * defaults to " / "; locale and timezone are accepted but ignored by this function.
193
+ * @returns A newly allocated column-definition array; each definition closes over its header configuration.
194
+ * @remarks Date/Time cells receive only the field name and use their cell-generator defaults;
195
+ * passing locale/timezone here does not change them. Custom head.cell receives the original row.
196
+ * The generated JSX uses Appkit UI components; import Appkit CSS in the rendering host.
194
197
  * @example
198
+ * ```tsx
199
+ * import { createColumnsFromHeads } from '@alneas/appkit-react/tools/data-table';
200
+ * import '@alneas/appkit-react/styles';
195
201
  * const columns = createColumnsFromHeads([
196
- * { field: 'name', text: '氏名' },
197
- * { field: 'birthday', text: '生年月日', type: 'Date' },
198
- * { field: 'status', text: '状態', type: 'Option', options: { 0: '未処理', 1: '完了' } },
199
- * ]);
202
+ * { field: 'name', text: 'Name' },
203
+ * { field: 'birthday', text: 'Birthday', type: 'Date' },
204
+ * { field: 'status', text: 'Status', type: 'Option', options: { 0: 'Pending', 1: 'Done' } },
205
+ * ], { arraySeparator: ', ' });
206
+ * ```
200
207
  */
201
208
  export declare const createColumnsFromHeads: (heads: TableHeadBase[], options?: CreateColumnsOptions) => ColumnDef<KV>[];
202
209
  /**
@@ -208,9 +215,12 @@ export declare const createColumnsFromHeads: (heads: TableHeadBase[], options?:
208
215
  * @returns {string} 結合された文字列、空の場合は空文字列 / Joined string or empty string
209
216
  *
210
217
  * @example
211
- * joinValues(['a', 'b', 'c']); // "a / b / c"
212
- * joinValues(['a', 'b'], ', '); // "a, b"
213
- * joinValues(); // ""
218
+ * ```ts
219
+ * import { joinValues } from '@alneas/appkit-react/tools/data-table';
220
+ * joinValues(['a', 'b', 'c']); // 'a / b / c'
221
+ * joinValues(['a', 'b'], ', '); // 'a, b'
222
+ * joinValues(); // ''
223
+ * ```
214
224
  */
215
225
  export declare const joinValues: (value?: string[], separator?: string) => string;
216
226
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"table-utils.js","names":["formatDate","formatTime","getAge","getNestedValue","path","current","key","obj","cellGenerators","value","row","field","date_utils_exports","age","options","separator","timeRegex","compareTimeStrings","aMatch","a","bMatch","b","aH","aM","bH","bM","timeSort","rawA","rowA","columnId","rawB","rowB","aEmpty","bEmpty","timeComparison","trimmedSort","createColumnsFromHeads","heads","dbField","head","cellType","columnDef","val","numericCell","x","id","y","xn","yn","dateCell","timeCell","timeStringCell","ageCell","optionCell","arrayCell","arraySeparator","stringCell","joinValues","filterDataByMongoQuery","query","data","matchRow","subQuery","q","rowVal","isDateField","schema","op","opVal","regexVal","rowStr","caseInsensitive","normalizedRow","normalizedQuery","r","compareRow","compareQuery"],"sources":["../../../../src/tools/components/data-table/table-utils.ts"],"sourcesContent":["/**\n * @fileoverview Table utility functions for DataTable component\n *\n * Provides:\n * - `getNestedValue` - Access nested object properties via dot notation\n * - `cellGenerators` - Pre-built cell formatters for common types\n * - `createColumnsFromHeads` - Create column definitions declaratively\n * - `timeSort`, `trimmedSort` - Custom sorting functions\n *\n * @module data-table/table-utils\n */\n\nimport { ColumnDef, Row, SortingFn } from './table-engine';\nimport { formatDate, formatTime, getAge } from \"../../lib/date-utils\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * 汎用キーバリューオブジェクト型\n * Generic key-value object type for table row data\n * @typedef {Record<string, unknown>} KV\n */\n\nexport type KV = Record<string, unknown>;\n\n/**\n * セルタイプの種類\n * Available cell generator types\n * @typedef {'Date' | 'Time' | 'TimeString' | 'Age' | 'Option' | 'String' | 'Array'} CellType\n */\nexport type CellType =\n | 'Date'\n | 'Time'\n | 'TimeString'\n | 'Age'\n | 'Option'\n | 'String'\n | 'Array'\n | 'Boolean'\n | 'Number';\n\n/**\n * テーブルヘッダーの基本定義\n * Base type for table column header definitions\n *\n * @typedef {Object} TableHeadBase\n * @property {string} field - カラムの一意識別子 / Unique column identifier\n * @property {string} text - ヘッダーの表示テキスト / Display text for the column header\n * @property {string} [id] - ソート/クエリ用のDBフィールド名 / Database field name for sorting\n * @property {CellType} [type] - セルタイプ / Logical cell type, defaults to \"String\"\n * @property {Record<string | number, string>} [options] - Optionタイプ用のマッピング / Options mapping\n * @property {Function} [accessorFn] - カスタムアクセサー関数 / Custom accessor function\n * @property {Function} [cell] - カスタムセルレンダラー / Custom cell renderer\n * @property {boolean} [enableSorting] - ソートを有効にするか / Enable sorting for this column\n */\nexport type TableHeadBase = {\n /** カラムの一意識別子 / Unique column identifier */\n field: string;\n /** ヘッダーの表示テキスト / Display text for the column header */\n text: string;\n /** ソート/クエリ用のDBフィールド名(省略時はfieldと同じ) / Optional database field name for sorting/querying */\n id?: string;\n /** セルタイプ(省略時は\"String\") / Logical cell type, defaults to \"String\" */\n type?: CellType;\n /** Optionタイプ用のオプションマッピング / Options mapping for Option-type cells */\n options?: Record<string | number, string>;\n /** カスタムアクセサー関数 / Optional accessor function */\n accessorFn?: (row: KV) => unknown;\n /** カスタムセルレンダラー / Optional custom cell renderer */\n cell?: (row: KV) => React.ReactNode;\n /** ソートを無効にするか / Disable sorting for this column */\n enableSorting?: boolean;\n /** インライン編集を有効にする / Enable inline editing for this column */\n editable?: boolean;\n};\n\n/**\n * createColumnsFromHeads のオプション\n * Options for createColumnsFromHeads\n *\n * @typedef {Object} CreateColumnsOptions\n * @property {string} [locale] - ロケール / Locale for date formatting\n * @property {string} [timezone] - タイムゾーン / Timezone for date formatting\n * @property {string} [arraySeparator] - 配列の結合文字 / Separator for joining array values\n */\nexport type CreateColumnsOptions = {\n /** ロケール(日付フォーマット用) / Locale for date formatting */\n locale?: string;\n /** タイムゾーン(日付フォーマット用) / Timezone for date formatting */\n timezone?: string;\n /** 配列の結合文字 / Separator for joining array values */\n arraySeparator?: string;\n};\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\n/**\n * ドット記法でネストされた値を取得する\n * Retrieves a nested value from an object using a dot-notation path.\n *\n * @param {KV} obj - 走査するオブジェクト / The object to traverse\n * @param {string} path - ドット記法のパス / Dot-notation path (e.g., \"user.profile.name\")\n * @returns {unknown} 指定パスの値、存在しない場合はundefined / The value at the path\n *\n * @example\n * const obj = { user: { profile: { name: \"John\" } } };\n * getNestedValue(obj, \"user.profile.name\"); // \"John\"\n * getNestedValue(obj, \"user.email\"); // undefined\n */\nexport const getNestedValue = (obj: KV, path: string): unknown => {\n return path.split('.').reduce<unknown>((current, key) => {\n if (\n current &&\n typeof current === 'object' &&\n key !== '__proto__' &&\n key !== 'constructor' &&\n key !== 'prototype' &&\n Object.prototype.hasOwnProperty.call(current, key)\n ) {\n return (current as Record<string, unknown>)[key];\n }\n return undefined;\n }, obj);\n};\n\n// =============================================================================\n// Cell Generators\n// =============================================================================\n\n/**\n * セルジェネレーター関数群\n * Cell generators for rendering different data types in table cells.\n * Each generator returns a function that takes a row and returns a formatted string.\n *\n * @example\n * const dateCell = cellGenerators.Date('createdAt');\n * const formatted = dateCell(rowData); // \"2024/01/15\"\n */\nexport const cellGenerators = {\n /**\n * 日付値をローカライズされた日付文字列にフォーマットする\n * Formats a date value as localized date string.\n *\n * @param {string} field - データフィールド名 / Field name to access\n * @returns {(row: KV) => string} セルレンダラー関数 / Cell renderer function\n */\n Date:\n (field: string) =>\n (row: KV): string => {\n const value = getNestedValue(row, field);\n if (!value) return '';\n return formatDate(new Date(value as string | number | Date));\n },\n\n /**\n * タイムスタンプをローカライズされた時刻文字列にフォーマットする\n * Formats a timestamp as localized time string (HH:mm).\n *\n * @param {string} field - データフィールド名 / Field name to access\n * @returns {(row: KV) => string} セルレンダラー関数 / Cell renderer function\n */\n Time:\n (field: string) =>\n (row: KV): string => {\n const value = getNestedValue(row, field);\n if (!value) return '';\n return formatTime(new Date(value as string | number | Date));\n },\n\n /**\n * 時刻文字列(HH:mm)をそのまま表示する\n * Renders a time string (HH:mm) directly without conversion.\n *\n * @param {string} field - データフィールド名 / Field name to access\n * @returns {(row: KV) => string} セルレンダラー関数 / Cell renderer function\n */\n TimeString:\n (field: string) =>\n (row: KV): string => {\n const value = getNestedValue(row, field);\n return (value as string) || '';\n },\n\n /**\n * 生年月日から年齢を計算して表示する\n * Calculates and formats age from a birth date value.\n *\n * @param {string} field - 生年月日フィールド名 / Field name containing birth date\n * @returns {(row: KV) => string} セルレンダラー関数 / Cell renderer function\n */\n Age:\n (field: string) =>\n (row: KV): string => {\n const value = getNestedValue(row, field);\n if (!value) return '';\n const age = getAge(new Date(value as string | number | Date));\n return age !== null ? String(age) : '';\n },\n\n /**\n * オプションマッピングを使って値をラベルに変換する\n * Maps a value to its label using the provided options mapping.\n *\n * @param {string} field - データフィールド名 / Field name to access\n * @param {Record<string | number, string>} [options] - 値→ラベルのマッピング / Value to label mapping\n * @returns {(row: KV) => string} セルレンダラー関数 / Cell renderer function\n *\n * @example\n * const statusCell = cellGenerators.Option('status', { 0: '未処理', 1: '完了' });\n */\n Option:\n (field: string, options?: Record<string | number, string>) =>\n (row: KV): string => {\n const value = getNestedValue(row, field);\n if (value === undefined || value === null) return '';\n if (options && (typeof value === 'string' || typeof value === 'number') && value in options) {\n return options[value];\n }\n return String(value);\n },\n\n /**\n * 文字列値を表示する(ネストフィールド対応)\n * Formats a string value, supporting nested field access.\n *\n * @param {string} field - データフィールド名 / Field name to access\n * @returns {(row: KV) => string} セルレンダラー関数 / Cell renderer function\n */\n /** Finite numeric values retain their numeric accessor for sorting. */\n Number: (field: string) => (row: KV): string => {\n const value = getNestedValue(row, field);\n return typeof value === 'number' && Number.isFinite(value) ? String(value) : '';\n },\n String:\n (field: string) =>\n (row: KV): string => {\n const value = getNestedValue(row, field);\n return value?.toString() || '';\n },\n\n /**\n * 配列値をセパレータで結合する\n * Formats an array value by joining elements with a separator.\n *\n * @param {string} field - データフィールド名 / Field name to access\n * @param {string} [separator=' / '] - 結合文字 / Separator string\n * @returns {(row: KV) => string} セルレンダラー関数 / Cell renderer function\n */\n Array:\n (field: string, separator = ' / ') =>\n (row: KV): string => {\n const value = getNestedValue(row, field);\n return Array.isArray(value) && value.length ? value.join(separator) : '';\n },\n};\n\n// =============================================================================\n// Custom Sorting Functions\n// =============================================================================\n\n/** 時刻文字列のパターン (H:mm or HH:mm) */\nconst timeRegex = /^(\\d{1,2}):(\\d{2})$/;\n\n/**\n * 2つの時刻文字列を数値比較する\n * @param {string} a - 時刻文字列A\n * @param {string} b - 時刻文字列B\n * @returns {number | null} 比較結果 (負=a<b, 正=a>b, 0=等しい, null=比較不可)\n */\nconst compareTimeStrings = (a: string, b: string): number | null => {\n const aMatch = a.match(timeRegex);\n const bMatch = b.match(timeRegex);\n\n if (aMatch && bMatch) {\n const aH = parseInt(aMatch[1], 10);\n const aM = parseInt(aMatch[2], 10);\n const bH = parseInt(bMatch[1], 10);\n const bM = parseInt(bMatch[2], 10);\n\n if (aH !== bH) return aH - bH;\n return aM - bM;\n }\n return null;\n};\n\n/**\n * 時刻文字列用のカスタムソート関数\n * H:mm/HH:mm形式の時刻を正しく数値順にソートする。\n * 空の値は先頭に配置される。\n *\n * Custom sorting function for time strings (H:mm/HH:mm format).\n * Correctly sorts times numerically. Empty values are sorted first.\n *\n * @param {Row<KV>} rowA - 行A / Row A to compare\n * @param {Row<KV>} rowB - 行B / Row B to compare\n * @param {string} columnId - カラムID / Column ID to sort by\n * @returns {number} ソート順序 / Sort order (-1, 0, or 1)\n */\nexport const timeSort: SortingFn<KV> = (rowA: Row<KV>, rowB: Row<KV>, columnId: string): number => {\n const rawA = rowA.getValue(columnId);\n const rawB = rowB.getValue(columnId);\n\n let a = rawA === null || rawA === undefined ? '' : rawA;\n let b = rawB === null || rawB === undefined ? '' : rawB;\n\n if (typeof a === 'string') a = a.trim();\n if (typeof b === 'string') b = b.trim();\n\n const aEmpty = a === '';\n const bEmpty = b === '';\n\n if (aEmpty && bEmpty) return 0;\n if (aEmpty) return -1;\n if (bEmpty) return 1;\n\n if (typeof a === 'string' && typeof b === 'string') {\n const timeComparison = compareTimeStrings(a, b);\n if (timeComparison !== null) return timeComparison;\n }\n\n if ((a as string) < (b as string)) return -1;\n if ((a as string) > (b as string)) return 1;\n return 0;\n};\n\n/**\n * トリム済み文字列用のカスタムソート関数\n * 空の値を一貫して処理する(空の値は先頭に配置)。\n *\n * Custom sorting function for trimmed strings.\n * Handles empty values consistently (empty values sorted first).\n *\n * @param {Row<KV>} rowA - 行A / Row A to compare\n * @param {Row<KV>} rowB - 行B / Row B to compare\n * @param {string} columnId - カラムID / Column ID to sort by\n * @returns {number} ソート順序 / Sort order (-1, 0, or 1)\n */\nexport const trimmedSort: SortingFn<KV> = (\n rowA: Row<KV>,\n rowB: Row<KV>,\n columnId: string,\n): number => {\n const rawA = rowA.getValue(columnId);\n const rawB = rowB.getValue(columnId);\n\n let a = rawA === null || rawA === undefined ? '' : rawA;\n let b = rawB === null || rawB === undefined ? '' : rawB;\n\n if (typeof a === 'string') a = a.trim();\n if (typeof b === 'string') b = b.trim();\n\n const aEmpty = a === '';\n const bEmpty = b === '';\n\n if (aEmpty && bEmpty) return 0;\n if (aEmpty) return -1;\n if (bEmpty) return 1;\n\n if (typeof a === 'number' && typeof b === 'number') {\n return a - b;\n }\n\n if ((a as string) < (b as string)) return -1;\n if ((a as string) > (b as string)) return 1;\n return 0;\n};\n\n// =============================================================================\n// Column Creation Helper\n// =============================================================================\n\n/**\n * 宣言的なヘッダー定義からTanStack Tableのカラム定義を生成する\n * Creates TanStack Table column definitions from a declarative TableHeadBase array.\n *\n * デフォルト動作:\n * - 論理的な`type`を`cellGenerators`にマッピング\n * - Optionセル用の`options`マッピングを使用\n * - TimeString型には`timeSort`を適用\n * - その他の型には`trimmedSort`を適用\n *\n * @param {TableHeadBase[]} heads - ヘッダー定義の配列 / Array of header definitions\n * @param {CreateColumnsOptions} [options] - オプション設定 / Optional configuration\n * @returns {ColumnDef<KV>[]} TanStack Tableのカラム定義配列 / Array of column definitions\n *\n * @example\n * const columns = createColumnsFromHeads([\n * { field: 'name', text: '氏名' },\n * { field: 'birthday', text: '生年月日', type: 'Date' },\n * { field: 'status', text: '状態', type: 'Option', options: { 0: '未処理', 1: '完了' } },\n * ]);\n */\nexport const createColumnsFromHeads = (\n heads: TableHeadBase[],\n options?: CreateColumnsOptions,\n): ColumnDef<KV>[] => {\n const { arraySeparator = ' / ' } = options || {};\n\n return heads.map((head) => {\n const dbField = head.id || head.field;\n const cellType = head.type || 'String';\n\n const columnDef: ColumnDef<KV> = {\n id: head.field,\n header: head.text,\n enableSorting: head.enableSorting !== false,\n accessorFn: (row: KV) => {\n const val = getNestedValue(row, dbField);\n if (val === null || val === undefined || val === '') return '';\n if (typeof val === 'string' && val.trim() === '') return '';\n return val;\n },\n sortFn: trimmedSort,\n };\n\n if (head.accessorFn) {\n columnDef.accessorFn = head.accessorFn;\n }\n\n if (head.cell) {\n columnDef.cell = ({ row }: { row: { original: KV } }) => head.cell!(row.original);\n } else if (cellType === 'Number') {\n const numericCell = cellGenerators.Number(dbField);\n columnDef.cell = ({ row }: { row: { original: KV } }) => numericCell(row.original);\n columnDef.sortFn = (a, b, id) => {\n const x = a.getValue(id), y = b.getValue(id);\n const xn = typeof x === 'number' && Number.isFinite(x);\n const yn = typeof y === 'number' && Number.isFinite(y);\n return xn && yn ? x - y : xn ? 1 : yn ? -1 : 0;\n };\n } else if (cellType === 'Date') {\n const dateCell = cellGenerators.Date(dbField);\n columnDef.cell = ({ row }: { row: { original: KV } }) => dateCell(row.original);\n } else if (cellType === 'Time') {\n const timeCell = cellGenerators.Time(dbField);\n columnDef.cell = ({ row }: { row: { original: KV } }) => timeCell(row.original);\n } else if (cellType === 'TimeString') {\n const timeStringCell = cellGenerators.TimeString(dbField);\n columnDef.cell = ({ row }: { row: { original: KV } }) => timeStringCell(row.original);\n columnDef.sortFn = timeSort;\n } else if (cellType === 'Age') {\n const ageCell = cellGenerators.Age(dbField);\n columnDef.cell = ({ row }: { row: { original: KV } }) => ageCell(row.original);\n } else if (cellType === 'Option') {\n const optionCell = cellGenerators.Option(dbField, head.options);\n columnDef.cell = ({ row }: { row: { original: KV } }) => optionCell(row.original);\n } else if (cellType === 'Boolean') {\n // Default boolean display (editable version handled in DataTableView)\n columnDef.cell = ({ row }: { row: { original: KV } }) => {\n const val = getNestedValue(row.original, dbField);\n return val ? '✓' : '-';\n };\n } else if (cellType === 'Array') {\n const arrayCell = cellGenerators.Array(dbField, arraySeparator);\n columnDef.cell = ({ row }: { row: { original: KV } }) => arrayCell(row.original);\n } else {\n const stringCell = cellGenerators.String(dbField);\n columnDef.cell = ({ row }: { row: { original: KV } }) => stringCell(row.original);\n }\n\n // Store metadata for editable columns (used by DataTableView)\n if (head.editable) {\n columnDef.meta = {\n editable: true,\n field: dbField,\n type: cellType,\n options: head.options,\n };\n }\n\n return columnDef;\n });\n};\n\n/**\n * 配列を指定のセパレータで結合する\n * Joins an array of strings with the specified separator.\n *\n * @param {string[]} [value] - 結合する文字列配列 / Array of strings to join\n * @param {string} [separator=' / '] - セパレータ / Separator string\n * @returns {string} 結合された文字列、空の場合は空文字列 / Joined string or empty string\n *\n * @example\n * joinValues(['a', 'b', 'c']); // \"a / b / c\"\n * joinValues(['a', 'b'], ', '); // \"a, b\"\n * joinValues(); // \"\"\n */\nexport const joinValues = (value?: string[], separator = ' / '): string =>\n value && value.length ? value.join(separator) : '';\n\n/**\n * MongoDBスタイルのクエリを用いてローカルデータ配列をフィルタリングします(クライアントサイドフィルタリング用)。\n *\n * サポートする演算子:\n * - 完全一致 (値が等しい場合。日付の場合は日付のミリ秒値で比較)\n * - $regex (部分一致、前方一致、後方一致。$options: 'i' による大文字小文字無視をサポート)\n * - $gte, $lte, $gt, $lt (数値、日付の比較)\n * - $in (複数選択のいずれかに一致)\n * - $and (複数条件の論理積)\n * - $or (複数条件の論理和)\n *\n * @param data フィルタリング対象のデータ配列\n * @param query MongoDBスタイルのフィルターオブジェクト\n * @param schema コレクションスキーマ(オプショナル。型推論のために使用)\n * @returns フィルタリング後のデータ配列\n */\nexport function filterDataByMongoQuery<T extends Record<string, any>>(\n data: T[],\n query: Record<string, any>,\n schema?: any,\n): T[] {\n if (!query || Object.keys(query).length === 0) {\n return data;\n }\n\n const matchRow = (row: T, subQuery: Record<string, any>): boolean => {\n for (const [key, val] of Object.entries(subQuery)) {\n if (key === '$and') {\n if (!Array.isArray(val)) continue;\n if (!val.every((q) => matchRow(row, q))) {\n return false;\n }\n continue;\n }\n if (key === '$or') {\n if (!Array.isArray(val)) continue;\n if (!val.some((q) => matchRow(row, q))) {\n return false;\n }\n continue;\n }\n\n const rowVal = getNestedValue(row, key);\n const schemaField = schema?.[key];\n const isDateField = schemaField?.type === 'date' || rowVal instanceof Date;\n\n if (val && typeof val === 'object' && !(val instanceof Date)) {\n // MongoDB-style operators\n for (const [op, opVal] of Object.entries(val)) {\n if (op === '$regex') {\n const regexVal = String(opVal);\n // Limit pattern length to prevent pathological regular expressions (ReDoS)\n if (regexVal.length > 256) return false;\n\n const rowStr = rowVal !== undefined && rowVal !== null ? String(rowVal) : '';\n const options = (val as any).$options || '';\n const caseInsensitive = options.includes('i');\n\n try {\n const regex = new RegExp(regexVal, caseInsensitive ? 'i' : '');\n if (!regex.test(rowStr)) return false;\n } catch (_e) {\n const normalizedRow = caseInsensitive ? rowStr.toLowerCase() : rowStr;\n const normalizedQuery = caseInsensitive ? regexVal.toLowerCase() : regexVal;\n if (!normalizedRow.includes(normalizedQuery)) return false;\n }\n } else if (op === '$options') {\n continue;\n } else if (op === '$in') {\n if (!Array.isArray(opVal)) return false;\n const rowArr = Array.isArray(rowVal) ? rowVal : [rowVal];\n const hasMatch = rowArr.some((r) =>\n opVal.some((q) => {\n if (isDateField && r && q) {\n return new Date(r as any).getTime() === new Date(q as any).getTime();\n }\n return String(r) === String(q);\n }),\n );\n if (!hasMatch) return false;\n } else if (op === '$gte' || op === '$gt' || op === '$lte' || op === '$lt') {\n if (rowVal === undefined || rowVal === null || rowVal === '') return false;\n\n const compareRow = isDateField ? new Date(rowVal as any).getTime() : Number(rowVal);\n const compareQuery = isDateField ? new Date(opVal as any).getTime() : Number(opVal);\n\n if (isNaN(compareRow) || isNaN(compareQuery)) return false;\n\n if (op === '$gte' && !(compareRow >= compareQuery)) return false;\n if (op === '$gt' && !(compareRow > compareQuery)) return false;\n if (op === '$lte' && !(compareRow <= compareQuery)) return false;\n if (op === '$lt' && !(compareRow < compareQuery)) return false;\n }\n }\n } else {\n // Exact match\n if (rowVal === undefined || rowVal === null || rowVal === '') {\n if (val !== undefined && val !== null && val !== '') return false;\n } else if (isDateField && rowVal && val) {\n if (new Date(rowVal as any).getTime() !== new Date(val as any).getTime()) return false;\n } else {\n if (String(rowVal) !== String(val)) return false;\n }\n }\n }\n return true;\n };\n\n return data.filter((row) => matchRow(row, query));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"table-utils.js","names":["formatDate","formatTime","getAge","getNestedValue","path","current","key","obj","cellGenerators","value","row","field","date_utils_exports","age","options","separator","timeRegex","compareTimeStrings","aMatch","a","bMatch","b","aH","aM","bH","bM","timeSort","rawA","rowA","columnId","rawB","rowB","aEmpty","bEmpty","timeComparison","trimmedSort","createColumnsFromHeads","heads","dbField","head","cellType","columnDef","val","numericCell","x","id","y","xn","yn","dateCell","timeCell","timeStringCell","ageCell","optionCell","arrayCell","arraySeparator","stringCell","joinValues","filterDataByMongoQuery","query","data","matchRow","subQuery","q","rowVal","isDateField","schema","op","opVal","regexVal","rowStr","caseInsensitive","normalizedRow","normalizedQuery","r","compareRow","compareQuery"],"sources":["../../../../src/tools/components/data-table/table-utils.ts"],"sourcesContent":["/**\n * @fileoverview Table utility functions for DataTable component\n *\n * Provides:\n * - `getNestedValue` - Access nested object properties via dot notation\n * - `cellGenerators` - Pre-built cell formatters for common types\n * - `createColumnsFromHeads` - Create column definitions declaratively\n * - `timeSort`, `trimmedSort` - Custom sorting functions\n *\n * @module data-table/table-utils\n */\n\nimport { ColumnDef, Row, SortingFn } from './table-engine';\nimport { formatDate, formatTime, getAge } from \"../../lib/date-utils\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * 汎用キーバリューオブジェクト型\n * Generic key-value object type for table row data\n * @typedef {Record<string, unknown>} KV\n */\n\nexport type KV = Record<string, unknown>;\n\n/**\n * セルタイプの種類\n * Available cell generator types\n * @typedef {'Date' | 'Time' | 'TimeString' | 'Age' | 'Option' | 'String' | 'Array'} CellType\n */\nexport type CellType =\n | 'Date'\n | 'Time'\n | 'TimeString'\n | 'Age'\n | 'Option'\n | 'String'\n | 'Array'\n | 'Boolean'\n | 'Number';\n\n/**\n * テーブルヘッダーの基本定義\n * Base type for table column header definitions\n *\n * @typedef {Object} TableHeadBase\n * @property {string} field - カラムの一意識別子 / Unique column identifier\n * @property {string} text - ヘッダーの表示テキスト / Display text for the column header\n * @property {string} [id] - ソート/クエリ用のDBフィールド名 / Database field name for sorting\n * @property {CellType} [type] - セルタイプ / Logical cell type, defaults to \"String\"\n * @property {Record<string | number, string>} [options] - Optionタイプ用のマッピング / Options mapping\n * @property {Function} [accessorFn] - カスタムアクセサー関数 / Custom accessor function\n * @property {Function} [cell] - カスタムセルレンダラー / Custom cell renderer\n * @property {boolean} [enableSorting] - ソートを有効にするか / Enable sorting for this column\n */\nexport type TableHeadBase = {\n /** カラムの一意識別子 / Unique column identifier */\n field: string;\n /** ヘッダーの表示テキスト / Display text for the column header */\n text: string;\n /** ソート/クエリ用のDBフィールド名(省略時はfieldと同じ) / Optional database field name for sorting/querying */\n id?: string;\n /** セルタイプ(省略時は\"String\") / Logical cell type, defaults to \"String\" */\n type?: CellType;\n /** Optionタイプ用のオプションマッピング / Options mapping for Option-type cells */\n options?: Record<string | number, string>;\n /** カスタムアクセサー関数 / Optional accessor function */\n accessorFn?: (row: KV) => unknown;\n /** カスタムセルレンダラー / Optional custom cell renderer */\n cell?: (row: KV) => React.ReactNode;\n /** ソートを無効にするか / Disable sorting for this column */\n enableSorting?: boolean;\n /** インライン編集を有効にする / Enable inline editing for this column */\n editable?: boolean;\n};\n\n/**\n * Compatibility options for {@link createColumnsFromHeads}.\n * @remarks Only arraySeparator is currently consumed; locale and timezone do not affect generated cells.\n * @see createColumnsFromHeads\n */\nexport type CreateColumnsOptions = {\n /** Reserved compatibility option; currently ignored by createColumnsFromHeads. No locale default is applied here. */\n locale?: string;\n /** Reserved compatibility option; currently ignored by createColumnsFromHeads. No timezone default is applied here. */\n timezone?: string;\n /** Separator for joining array values; defaults to \" / \". */\n arraySeparator?: string;\n};\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\n/**\n * ドット記法でネストされた値を取得する\n * Retrieves a nested value from an object using a dot-notation path.\n *\n * @param {KV} obj - 走査するオブジェクト / The object to traverse\n * @param {string} path - ドット記法のパス / Dot-notation path (e.g., \"user.profile.name\")\n * @returns {unknown} 指定パスの値、存在しない場合はundefined / The value at the path\n *\n * @example\n * ```ts\n * import { getNestedValue } from '@alneas/appkit-react/tools/data-table';\n * const obj = { user: { profile: { name: 'John' } } };\n * getNestedValue(obj, 'user.profile.name'); // 'John'\n * getNestedValue(obj, 'user.email'); // undefined\n * ```\n */\nexport const getNestedValue = (obj: KV, path: string): unknown => {\n return path.split('.').reduce<unknown>((current, key) => {\n if (\n current &&\n typeof current === 'object' &&\n key !== '__proto__' &&\n key !== 'constructor' &&\n key !== 'prototype' &&\n Object.prototype.hasOwnProperty.call(current, key)\n ) {\n return (current as Record<string, unknown>)[key];\n }\n return undefined;\n }, obj);\n};\n\n// =============================================================================\n// Cell Generators\n// =============================================================================\n\n/**\n * セルジェネレーター関数群\n * Cell generators for rendering different data types in table cells.\n * Each generator returns a function that takes a row and returns a formatted string.\n *\n * @example\n * ```ts\n * import { cellGenerators } from '@alneas/appkit-react/tools/data-table';\n * const rowData = { createdAt: new Date(2026, 0, 15) };\n * const dateCell = cellGenerators.Date('createdAt');\n * const formatted = dateCell(rowData);\n * ```\n */\nexport const cellGenerators = {\n /**\n * 日付値をローカライズされた日付文字列にフォーマットする\n * Formats a date value as localized date string.\n *\n * @param {string} field - データフィールド名 / Field name to access\n * @returns {(row: KV) => string} セルレンダラー関数 / Cell renderer function\n */\n Date:\n (field: string) =>\n (row: KV): string => {\n const value = getNestedValue(row, field);\n if (!value) return '';\n return formatDate(new Date(value as string | number | Date));\n },\n\n /**\n * タイムスタンプをローカライズされた時刻文字列にフォーマットする\n * Formats a timestamp as localized time string (HH:mm).\n *\n * @param {string} field - データフィールド名 / Field name to access\n * @returns {(row: KV) => string} セルレンダラー関数 / Cell renderer function\n */\n Time:\n (field: string) =>\n (row: KV): string => {\n const value = getNestedValue(row, field);\n if (!value) return '';\n return formatTime(new Date(value as string | number | Date));\n },\n\n /**\n * 時刻文字列(HH:mm)をそのまま表示する\n * Renders a time string (HH:mm) directly without conversion.\n *\n * @param {string} field - データフィールド名 / Field name to access\n * @returns {(row: KV) => string} セルレンダラー関数 / Cell renderer function\n */\n TimeString:\n (field: string) =>\n (row: KV): string => {\n const value = getNestedValue(row, field);\n return (value as string) || '';\n },\n\n /**\n * 生年月日から年齢を計算して表示する\n * Calculates and formats age from a birth date value.\n *\n * @param {string} field - 生年月日フィールド名 / Field name containing birth date\n * @returns {(row: KV) => string} セルレンダラー関数 / Cell renderer function\n */\n Age:\n (field: string) =>\n (row: KV): string => {\n const value = getNestedValue(row, field);\n if (!value) return '';\n const age = getAge(new Date(value as string | number | Date));\n return age !== null ? String(age) : '';\n },\n\n /**\n * オプションマッピングを使って値をラベルに変換する\n * Maps a value to its label using the provided options mapping.\n *\n * @param {string} field - データフィールド名 / Field name to access\n * @param {Record<string | number, string>} [options] - 値→ラベルのマッピング / Value to label mapping\n * @returns {(row: KV) => string} セルレンダラー関数 / Cell renderer function\n *\n * @example\n * ```ts\n * import { cellGenerators } from '@alneas/appkit-react/tools/data-table';\n * const statusCell = cellGenerators.Option('status', { 0: 'Pending', 1: 'Complete' });\n * const label = statusCell({ status: 1 }); // 'Complete'\n * ```\n */\n Option:\n (field: string, options?: Record<string | number, string>) =>\n (row: KV): string => {\n const value = getNestedValue(row, field);\n if (value === undefined || value === null) return '';\n if (options && (typeof value === 'string' || typeof value === 'number') && value in options) {\n return options[value];\n }\n return String(value);\n },\n\n /**\n * 文字列値を表示する(ネストフィールド対応)\n * Formats a string value, supporting nested field access.\n *\n * @param {string} field - データフィールド名 / Field name to access\n * @returns {(row: KV) => string} セルレンダラー関数 / Cell renderer function\n */\n /** Finite numeric values retain their numeric accessor for sorting. */\n Number: (field: string) => (row: KV): string => {\n const value = getNestedValue(row, field);\n return typeof value === 'number' && Number.isFinite(value) ? String(value) : '';\n },\n String:\n (field: string) =>\n (row: KV): string => {\n const value = getNestedValue(row, field);\n return value?.toString() || '';\n },\n\n /**\n * 配列値をセパレータで結合する\n * Formats an array value by joining elements with a separator.\n *\n * @param {string} field - データフィールド名 / Field name to access\n * @param {string} [separator=' / '] - 結合文字 / Separator string\n * @returns {(row: KV) => string} セルレンダラー関数 / Cell renderer function\n */\n Array:\n (field: string, separator = ' / ') =>\n (row: KV): string => {\n const value = getNestedValue(row, field);\n return Array.isArray(value) && value.length ? value.join(separator) : '';\n },\n};\n\n// =============================================================================\n// Custom Sorting Functions\n// =============================================================================\n\n/** 時刻文字列のパターン (H:mm or HH:mm) */\nconst timeRegex = /^(\\d{1,2}):(\\d{2})$/;\n\n/**\n * 2つの時刻文字列を数値比較する\n * @param {string} a - 時刻文字列A\n * @param {string} b - 時刻文字列B\n * @returns {number | null} 比較結果 (負=a<b, 正=a>b, 0=等しい, null=比較不可)\n */\nconst compareTimeStrings = (a: string, b: string): number | null => {\n const aMatch = a.match(timeRegex);\n const bMatch = b.match(timeRegex);\n\n if (aMatch && bMatch) {\n const aH = parseInt(aMatch[1], 10);\n const aM = parseInt(aMatch[2], 10);\n const bH = parseInt(bMatch[1], 10);\n const bM = parseInt(bMatch[2], 10);\n\n if (aH !== bH) return aH - bH;\n return aM - bM;\n }\n return null;\n};\n\n/**\n * 時刻文字列用のカスタムソート関数\n * H:mm/HH:mm形式の時刻を正しく数値順にソートする。\n * 空の値は先頭に配置される。\n *\n * Custom sorting function for time strings (H:mm/HH:mm format).\n * Correctly sorts times numerically. Empty values are sorted first.\n *\n * @param {Row<KV>} rowA - 行A / Row A to compare\n * @param {Row<KV>} rowB - 行B / Row B to compare\n * @param {string} columnId - カラムID / Column ID to sort by\n * @returns {number} ソート順序 / Sort order (-1, 0, or 1)\n */\nexport const timeSort: SortingFn<KV> = (rowA: Row<KV>, rowB: Row<KV>, columnId: string): number => {\n const rawA = rowA.getValue(columnId);\n const rawB = rowB.getValue(columnId);\n\n let a = rawA === null || rawA === undefined ? '' : rawA;\n let b = rawB === null || rawB === undefined ? '' : rawB;\n\n if (typeof a === 'string') a = a.trim();\n if (typeof b === 'string') b = b.trim();\n\n const aEmpty = a === '';\n const bEmpty = b === '';\n\n if (aEmpty && bEmpty) return 0;\n if (aEmpty) return -1;\n if (bEmpty) return 1;\n\n if (typeof a === 'string' && typeof b === 'string') {\n const timeComparison = compareTimeStrings(a, b);\n if (timeComparison !== null) return timeComparison;\n }\n\n if ((a as string) < (b as string)) return -1;\n if ((a as string) > (b as string)) return 1;\n return 0;\n};\n\n/**\n * トリム済み文字列用のカスタムソート関数\n * 空の値を一貫して処理する(空の値は先頭に配置)。\n *\n * Custom sorting function for trimmed strings.\n * Handles empty values consistently (empty values sorted first).\n *\n * @param {Row<KV>} rowA - 行A / Row A to compare\n * @param {Row<KV>} rowB - 行B / Row B to compare\n * @param {string} columnId - カラムID / Column ID to sort by\n * @returns {number} ソート順序 / Sort order (-1, 0, or 1)\n */\nexport const trimmedSort: SortingFn<KV> = (\n rowA: Row<KV>,\n rowB: Row<KV>,\n columnId: string,\n): number => {\n const rawA = rowA.getValue(columnId);\n const rawB = rowB.getValue(columnId);\n\n let a = rawA === null || rawA === undefined ? '' : rawA;\n let b = rawB === null || rawB === undefined ? '' : rawB;\n\n if (typeof a === 'string') a = a.trim();\n if (typeof b === 'string') b = b.trim();\n\n const aEmpty = a === '';\n const bEmpty = b === '';\n\n if (aEmpty && bEmpty) return 0;\n if (aEmpty) return -1;\n if (bEmpty) return 1;\n\n if (typeof a === 'number' && typeof b === 'number') {\n return a - b;\n }\n\n if ((a as string) < (b as string)) return -1;\n if ((a as string) > (b as string)) return 1;\n return 0;\n};\n\n// =============================================================================\n// Column Creation Helper\n// =============================================================================\n\n/**\n * Creates table column definitions from declarative headers and built-in cell generators.\n * @param heads - Header definitions in display order; field selects a row path and id can\n * override the source path. Cell type defaults to String and sorting is enabled unless explicitly false.\n * @param options - Array formatting options; see {@link CreateColumnsOptions}. arraySeparator\n * defaults to \" / \"; locale and timezone are accepted but ignored by this function.\n * @returns A newly allocated column-definition array; each definition closes over its header configuration.\n * @remarks Date/Time cells receive only the field name and use their cell-generator defaults;\n * passing locale/timezone here does not change them. Custom head.cell receives the original row.\n * The generated JSX uses Appkit UI components; import Appkit CSS in the rendering host.\n * @example\n * ```tsx\n * import { createColumnsFromHeads } from '@alneas/appkit-react/tools/data-table';\n * import '@alneas/appkit-react/styles';\n * const columns = createColumnsFromHeads([\n * { field: 'name', text: 'Name' },\n * { field: 'birthday', text: 'Birthday', type: 'Date' },\n * { field: 'status', text: 'Status', type: 'Option', options: { 0: 'Pending', 1: 'Done' } },\n * ], { arraySeparator: ', ' });\n * ```\n */\nexport const createColumnsFromHeads = (\n heads: TableHeadBase[],\n options?: CreateColumnsOptions,\n): ColumnDef<KV>[] => {\n const { arraySeparator = ' / ' } = options || {};\n\n return heads.map((head) => {\n const dbField = head.id || head.field;\n const cellType = head.type || 'String';\n\n const columnDef: ColumnDef<KV> = {\n id: head.field,\n header: head.text,\n enableSorting: head.enableSorting !== false,\n accessorFn: (row: KV) => {\n const val = getNestedValue(row, dbField);\n if (val === null || val === undefined || val === '') return '';\n if (typeof val === 'string' && val.trim() === '') return '';\n return val;\n },\n sortFn: trimmedSort,\n };\n\n if (head.accessorFn) {\n columnDef.accessorFn = head.accessorFn;\n }\n\n if (head.cell) {\n columnDef.cell = ({ row }: { row: { original: KV } }) => head.cell!(row.original);\n } else if (cellType === 'Number') {\n const numericCell = cellGenerators.Number(dbField);\n columnDef.cell = ({ row }: { row: { original: KV } }) => numericCell(row.original);\n columnDef.sortFn = (a, b, id) => {\n const x = a.getValue(id), y = b.getValue(id);\n const xn = typeof x === 'number' && Number.isFinite(x);\n const yn = typeof y === 'number' && Number.isFinite(y);\n return xn && yn ? x - y : xn ? 1 : yn ? -1 : 0;\n };\n } else if (cellType === 'Date') {\n const dateCell = cellGenerators.Date(dbField);\n columnDef.cell = ({ row }: { row: { original: KV } }) => dateCell(row.original);\n } else if (cellType === 'Time') {\n const timeCell = cellGenerators.Time(dbField);\n columnDef.cell = ({ row }: { row: { original: KV } }) => timeCell(row.original);\n } else if (cellType === 'TimeString') {\n const timeStringCell = cellGenerators.TimeString(dbField);\n columnDef.cell = ({ row }: { row: { original: KV } }) => timeStringCell(row.original);\n columnDef.sortFn = timeSort;\n } else if (cellType === 'Age') {\n const ageCell = cellGenerators.Age(dbField);\n columnDef.cell = ({ row }: { row: { original: KV } }) => ageCell(row.original);\n } else if (cellType === 'Option') {\n const optionCell = cellGenerators.Option(dbField, head.options);\n columnDef.cell = ({ row }: { row: { original: KV } }) => optionCell(row.original);\n } else if (cellType === 'Boolean') {\n // Default boolean display (editable version handled in DataTableView)\n columnDef.cell = ({ row }: { row: { original: KV } }) => {\n const val = getNestedValue(row.original, dbField);\n return val ? '✓' : '-';\n };\n } else if (cellType === 'Array') {\n const arrayCell = cellGenerators.Array(dbField, arraySeparator);\n columnDef.cell = ({ row }: { row: { original: KV } }) => arrayCell(row.original);\n } else {\n const stringCell = cellGenerators.String(dbField);\n columnDef.cell = ({ row }: { row: { original: KV } }) => stringCell(row.original);\n }\n\n // Store metadata for editable columns (used by DataTableView)\n if (head.editable) {\n columnDef.meta = {\n editable: true,\n field: dbField,\n type: cellType,\n options: head.options,\n };\n }\n\n return columnDef;\n });\n};\n\n/**\n * 配列を指定のセパレータで結合する\n * Joins an array of strings with the specified separator.\n *\n * @param {string[]} [value] - 結合する文字列配列 / Array of strings to join\n * @param {string} [separator=' / '] - セパレータ / Separator string\n * @returns {string} 結合された文字列、空の場合は空文字列 / Joined string or empty string\n *\n * @example\n * ```ts\n * import { joinValues } from '@alneas/appkit-react/tools/data-table';\n * joinValues(['a', 'b', 'c']); // 'a / b / c'\n * joinValues(['a', 'b'], ', '); // 'a, b'\n * joinValues(); // ''\n * ```\n */\nexport const joinValues = (value?: string[], separator = ' / '): string =>\n value && value.length ? value.join(separator) : '';\n\n/**\n * MongoDBスタイルのクエリを用いてローカルデータ配列をフィルタリングします(クライアントサイドフィルタリング用)。\n *\n * サポートする演算子:\n * - 完全一致 (値が等しい場合。日付の場合は日付のミリ秒値で比較)\n * - $regex (部分一致、前方一致、後方一致。$options: 'i' による大文字小文字無視をサポート)\n * - $gte, $lte, $gt, $lt (数値、日付の比較)\n * - $in (複数選択のいずれかに一致)\n * - $and (複数条件の論理積)\n * - $or (複数条件の論理和)\n *\n * @param data フィルタリング対象のデータ配列\n * @param query MongoDBスタイルのフィルターオブジェクト\n * @param schema コレクションスキーマ(オプショナル。型推論のために使用)\n * @returns フィルタリング後のデータ配列\n */\nexport function filterDataByMongoQuery<T extends Record<string, any>>(\n data: T[],\n query: Record<string, any>,\n schema?: any,\n): T[] {\n if (!query || Object.keys(query).length === 0) {\n return data;\n }\n\n const matchRow = (row: T, subQuery: Record<string, any>): boolean => {\n for (const [key, val] of Object.entries(subQuery)) {\n if (key === '$and') {\n if (!Array.isArray(val)) continue;\n if (!val.every((q) => matchRow(row, q))) {\n return false;\n }\n continue;\n }\n if (key === '$or') {\n if (!Array.isArray(val)) continue;\n if (!val.some((q) => matchRow(row, q))) {\n return false;\n }\n continue;\n }\n\n const rowVal = getNestedValue(row, key);\n const schemaField = schema?.[key];\n const isDateField = schemaField?.type === 'date' || rowVal instanceof Date;\n\n if (val && typeof val === 'object' && !(val instanceof Date)) {\n // MongoDB-style operators\n for (const [op, opVal] of Object.entries(val)) {\n if (op === '$regex') {\n const regexVal = String(opVal);\n // Limit pattern length to prevent pathological regular expressions (ReDoS)\n if (regexVal.length > 256) return false;\n\n const rowStr = rowVal !== undefined && rowVal !== null ? String(rowVal) : '';\n const options = (val as any).$options || '';\n const caseInsensitive = options.includes('i');\n\n try {\n const regex = new RegExp(regexVal, caseInsensitive ? 'i' : '');\n if (!regex.test(rowStr)) return false;\n } catch (_e) {\n const normalizedRow = caseInsensitive ? rowStr.toLowerCase() : rowStr;\n const normalizedQuery = caseInsensitive ? regexVal.toLowerCase() : regexVal;\n if (!normalizedRow.includes(normalizedQuery)) return false;\n }\n } else if (op === '$options') {\n continue;\n } else if (op === '$in') {\n if (!Array.isArray(opVal)) return false;\n const rowArr = Array.isArray(rowVal) ? rowVal : [rowVal];\n const hasMatch = rowArr.some((r) =>\n opVal.some((q) => {\n if (isDateField && r && q) {\n return new Date(r as any).getTime() === new Date(q as any).getTime();\n }\n return String(r) === String(q);\n }),\n );\n if (!hasMatch) return false;\n } else if (op === '$gte' || op === '$gt' || op === '$lte' || op === '$lt') {\n if (rowVal === undefined || rowVal === null || rowVal === '') return false;\n\n const compareRow = isDateField ? new Date(rowVal as any).getTime() : Number(rowVal);\n const compareQuery = isDateField ? new Date(opVal as any).getTime() : Number(opVal);\n\n if (isNaN(compareRow) || isNaN(compareQuery)) return false;\n\n if (op === '$gte' && !(compareRow >= compareQuery)) return false;\n if (op === '$gt' && !(compareRow > compareQuery)) return false;\n if (op === '$lte' && !(compareRow <= compareQuery)) return false;\n if (op === '$lt' && !(compareRow < compareQuery)) return false;\n }\n }\n } else {\n // Exact match\n if (rowVal === undefined || rowVal === null || rowVal === '') {\n if (val !== undefined && val !== null && val !== '') return false;\n } else if (isDateField && rowVal && val) {\n if (new Date(rowVal as any).getTime() !== new Date(val as any).getTime()) return false;\n } else {\n if (String(rowVal) !== String(val)) return false;\n }\n }\n }\n return true;\n };\n\n return data.filter((row) => matchRow(row, query));\n}\n"],"mappings":";;;AAgHA,IAAaG,KAAkB,GAAS,MAC/BC,EAAK,MAAM,GAAG,CAAC,CAAC,QAAiB,GAAS,MAAQ;CACvD,IACEC,KACA,OAAOA,KAAY,YACnBC,MAAQ,eACRA,MAAQ,iBACRA,MAAQ,eACR,OAAO,UAAU,eAAe,KAAKD,GAASC,CAAG,GAEjD,OAAQD,EAAoCC;AAGhD,GAAGC,CAAG,GAoBKC,IAAiB;CAQ5B,OACG,OACA,MAAoB;EACnB,IAAMC,IAAQN,EAAeO,GAAKC,CAAK;EAEvC,OADKF,KACL,GAAOT,EAAAA,WAAAA,CAAW,IAAI,KAAKS,CAA+B,CAAC,IADxC;CAErB;CASF,OACG,OACA,MAAoB;EACnB,IAAMA,IAAQN,EAAeO,GAAKC,CAAK;EAEvC,OADKF,KACL,GAAOR,EAAAA,WAAAA,CAAW,IAAI,KAAKQ,CAA+B,CAAC,IADxC;CAErB;CASF,aACG,OACA,MACeN,EAAeO,GAAKC,CAC1B,KAAoB;CAUhC,MACG,OACA,MAAoB;EACnB,IAAMF,IAAQN,EAAeO,GAAKC,CAAK;EACvC,IAAI,CAACF,GAAO,OAAO;EACnB,IAAMI,KAAA,GAAMX,EAAAA,OAAAA,CAAO,IAAI,KAAKO,CAA+B,CAAC;EAC5D,OAAOI,MAAQ,OAAqB,KAAd,OAAOA,CAAG;CAClC;CAiBF,SACG,GAAe,OACf,MAAoB;EACnB,IAAMJ,IAAQN,EAAeO,GAAKC,CAAK;EAKvC,OAJIF,KAAiC,OAAa,KAC9CK,MAAY,OAAOL,KAAU,YAAY,OAAOA,KAAU,aAAaA,KAASK,IAC3EA,EAAQL,KAEV,OAAOA,CAAK;CACrB;CAUF,SAAS,OAAmB,MAAoB;EAC9C,IAAMA,IAAQN,EAAeO,GAAKC,CAAK;EACvC,OAAO,OAAOF,KAAU,YAAY,OAAO,SAASA,CAAK,IAAI,OAAOA,CAAK,IAAI;CAC/E;CACA,SACG,OACA,MACeN,EAAeO,GAAKC,CAC3B,CAAA,EAAO,SAAS,KAAK;CAWhC,QACG,GAAe,IAAY,WAC3B,MAAoB;EACnB,IAAMF,IAAQN,EAAeO,GAAKC,CAAK;EACvC,OAAO,MAAM,QAAQF,CAAK,KAAKA,EAAM,SAASA,EAAM,KAAKM,CAAS,IAAI;CACxE;AACJ,GAOMC,IAAY,uBAQZC,KAAsB,GAAW,MAA6B;CAClE,IAAMC,IAASC,EAAE,MAAMH,CAAS,GAC1BI,IAASC,EAAE,MAAML,CAAS;CAEhC,IAAIE,KAAUE,GAAQ;EACpB,IAAME,IAAK,SAASJ,EAAO,IAAI,EAAE,GAC3BK,IAAK,SAASL,EAAO,IAAI,EAAE,GAC3BM,IAAK,SAASJ,EAAO,IAAI,EAAE,GAC3BK,IAAK,SAASL,EAAO,IAAI,EAAE;EAGjC,OADIE,MAAOE,IACJD,IAAKE,IADUH,IAAKE;CAE7B;CACA,OAAO;AACT,GAeaE,KAA2B,GAAe,GAAe,MAA6B;CACjG,IAAMC,IAAOC,EAAK,SAASC,CAAQ,GAC7BC,IAAOC,EAAK,SAASF,CAAQ,GAE/BV,IAAIQ,KAAsC,IAC1CN,IAAIS,KAAsC;CAG9C,AADI,OAAOX,KAAM,aAAU,IAAIA,EAAE,KAAK,IAClC,OAAOE,KAAM,aAAU,IAAIA,EAAE,KAAK;CAEtC,IAAMW,IAASb,MAAM,IACfc,IAASZ,MAAM;CAErB,IAAIW,KAAUC,GAAQ,OAAO;CAC7B,IAAID,GAAQ,OAAO;CACnB,IAAIC,GAAQ,OAAO;CAEnB,IAAI,OAAOd,KAAM,YAAY,OAAOE,KAAM,UAAU;EAClD,IAAMa,IAAiBjB,EAAmBE,GAAGE,CAAC;EAC9C,IAAIa,MAAmB,MAAM,OAAOA;CACtC;CAIA,OAFKf,IAAgBE,IAAqB,KAC1C,EAAKF,IAAgBE;AAEvB,GAcac,KACX,GACA,GACA,MACW;CACX,IAAMR,IAAOC,EAAK,SAASC,CAAQ,GAC7BC,IAAOC,EAAK,SAASF,CAAQ,GAE/B,IAAIF,KAAsC,IAC1CN,IAAIS,KAAsC;CAG9C,AADI,OAAO,KAAM,aAAU,IAAI,EAAE,KAAK,IAClC,OAAOT,KAAM,aAAU,IAAIA,EAAE,KAAK;CAEtC,IAAMW,IAAS,MAAM,IACfC,IAASZ,MAAM;CAYrB,OAVIW,KAAUC,IAAe,IACzBD,IAAe,KACfC,IAAe,IAEf,OAAO,KAAM,YAAY,OAAOZ,KAAM,WACjC,IAAIA,IAGR,IAAgBA,IAAqB,KAC1C,EAAK,IAAgBA;AAEvB,GA2Bae,KACX,GACA,MACoB;CACpB,IAAM,EAAE,oBAAiB,UAAUtB,KAAW,CAAC;CAE/C,OAAOuB,EAAM,KAAK,MAAS;EACzB,IAAMC,IAAUC,EAAK,MAAMA,EAAK,OAC1BC,IAAWD,EAAK,QAAQ,UAExBE,IAA2B;GAC/B,IAAIF,EAAK;GACT,QAAQA,EAAK;GACb,eAAeA,EAAK,kBAAkB;GACtC,aAAa,MAAY;IACvB,IAAMG,IAAMvC,EAAeO,GAAK4B,CAAO;IAGvC,OAFII,KAAQ,QAA6BA,MAAQ,MAC7C,OAAOA,KAAQ,YAAYA,EAAI,KAAK,MAAM,KAAW,KAClDA;GACT;GACA,QAAQP;EACV;EAMA,IAJII,EAAK,eACP,EAAU,aAAaA,EAAK,aAG1BA,EAAK,MACP,EAAU,QAAQ,EAAE,aAAqCA,EAAK,KAAM7B,EAAI,QAAQ;OAC3E,IAAI8B,MAAa,UAAU;GAChC,IAAMG,IAAcnC,EAAe,OAAO8B,CAAO;GAEjD,AADA,EAAU,QAAQ,EAAE,aAAqCK,EAAYjC,EAAI,QAAQ,GACjF,EAAU,UAAU,GAAG,GAAG,MAAO;IAC/B,IAAMkC,IAAIzB,EAAE,SAAS0B,CAAE,GAAGC,IAAIzB,EAAE,SAASwB,CAAE,GACrCE,IAAK,OAAOH,KAAM,YAAY,OAAO,SAASA,CAAC,GAC/CI,IAAK,OAAOF,KAAM,YAAY,OAAO,SAASA,CAAC;IACrD,OAAOC,KAAMC,IAAKJ,IAAIE,IAAIC,IAAK,IAAIC,IAAK,KAAK;GAC/C;EACF,OAAO,IAAIR,MAAa,QAAQ;GAC9B,IAAMS,IAAWzC,EAAe,KAAK8B,CAAO;GAC5C,EAAU,QAAQ,EAAE,aAAqCW,EAASvC,EAAI,QAAQ;EAChF,OAAO,IAAI8B,MAAa,QAAQ;GAC9B,IAAMU,IAAW1C,EAAe,KAAK8B,CAAO;GAC5C,EAAU,QAAQ,EAAE,aAAqCY,EAASxC,EAAI,QAAQ;EAChF,OAAO,IAAI8B,MAAa,cAAc;GACpC,IAAMW,IAAiB3C,EAAe,WAAW8B,CAAO;GAExD,AADA,EAAU,QAAQ,EAAE,aAAqCa,EAAezC,EAAI,QAAQ,GACpF,EAAU,SAASgB;EACrB,OAAO,IAAIc,MAAa,OAAO;GAC7B,IAAMY,IAAU5C,EAAe,IAAI8B,CAAO;GAC1C,EAAU,QAAQ,EAAE,aAAqCc,EAAQ1C,EAAI,QAAQ;EAC/E,OAAO,IAAI8B,MAAa,UAAU;GAChC,IAAMa,IAAa7C,EAAe,OAAO8B,GAASC,EAAK,OAAO;GAC9D,EAAU,QAAQ,EAAE,aAAqCc,EAAW3C,EAAI,QAAQ;EAClF,OAAO,IAAI8B,MAAa,WAEtB,EAAU,QAAQ,EAAE,aACNrC,EAAeO,EAAI,UAAU4B,CAClC,IAAM,MAAM;OAEhB,IAAIE,MAAa,SAAS;GAC/B,IAAMc,IAAY9C,EAAe,MAAM8B,GAASiB,CAAc;GAC9D,EAAU,QAAQ,EAAE,aAAqCD,EAAU5C,EAAI,QAAQ;EACjF,OAAO;GACL,IAAM8C,IAAahD,EAAe,OAAO8B,CAAO;GAChD,EAAU,QAAQ,EAAE,aAAqCkB,EAAW9C,EAAI,QAAQ;EAClF;EAYA,OATI6B,EAAK,aACP,EAAU,OAAO;GACf,UAAU;GACV,OAAOD;GACP,MAAME;GACN,SAASD,EAAK;EAChB,IAGKE;CACT,CAAC;AACH,GAkBagB,KAAc,GAAkB,IAAY,UACvDhD,KAASA,EAAM,SAASA,EAAM,KAAKM,CAAS,IAAI;AAkBlD,SAAgB2C,EACd,GACA,GACA,GACK;CACL,IAAI,CAACC,KAAS,OAAO,KAAKA,CAAK,CAAC,CAAC,WAAW,GAC1C,OAAOC;CAGT,IAAMC,KAAY,GAAQ,MAA2C;EACnE,KAAK,IAAM,CAACvD,GAAKoC,MAAQ,OAAO,QAAQoB,CAAQ,GAAG;GACjD,IAAIxD,MAAQ,QAAQ;IAClB,IAAI,CAAC,MAAM,QAAQoC,CAAG,GAAG;IACzB,IAAI,CAACA,EAAI,OAAO,MAAMmB,EAASnD,GAAKqD,CAAC,CAAC,GACpC,OAAO;IAET;GACF;GACA,IAAIzD,MAAQ,OAAO;IACjB,IAAI,CAAC,MAAM,QAAQoC,CAAG,GAAG;IACzB,IAAI,CAACA,EAAI,MAAM,MAAMmB,EAASnD,GAAKqD,CAAC,CAAC,GACnC,OAAO;IAET;GACF;GAEA,IAAMC,IAAS7D,EAAeO,GAAKJ,CAAG,GAEhC2D,IADcC,IAAS5D,EAAA,EACI,SAAS,UAAU0D,aAAkB;GAEtE,IAAItB,KAAO,OAAOA,KAAQ,YAAY,EAAEA,aAAe,OAEhD;SAAA,IAAM,CAACyB,GAAIC,MAAU,OAAO,QAAQ1B,CAAG,GAC1C,IAAIyB,MAAO,UAAU;KACnB,IAAME,IAAW,OAAOD,CAAK;KAE7B,IAAIC,EAAS,SAAS,KAAK,OAAO;KAElC,IAAMC,IAASN,KAAmC,OAAwB,KAAjB,OAAOA,CAAM,GAEhEO,KADW7B,EAAY,YAAY,GAAA,CACT,SAAS,GAAG;KAE5C,IAAI;MAEF,IAAI,CAAC,IADa,OAAO2B,GAAUE,IAAkB,MAAM,EACtD,CAAA,CAAM,KAAKD,CAAM,GAAG,OAAO;KAClC,QAAa;MACX,IAAME,IAAgBD,IAAkBD,EAAO,YAAY,IAAIA,GACzDG,IAAkBF,IAAkBF,EAAS,YAAY,IAAIA;MACnE,IAAI,CAACG,EAAc,SAASC,CAAe,GAAG,OAAO;KACvD;IACF,OAAO,IAAIN,MAAO,YAChB;SACK,IAAIA,MAAO,OAWhB;SAVI,CAAC,MAAM,QAAQC,CAAK,KAUpB,EATW,MAAM,QAAQJ,CAAM,IAAIA,IAAS,CAACA,CAAM,EAAA,CAC/B,MAAM,MAC5BI,EAAM,MAAM,MACNH,KAAeS,KAAKX,IACf,IAAI,KAAKW,CAAQ,CAAC,CAAC,QAAQ,MAAM,IAAI,KAAKX,CAAQ,CAAC,CAAC,QAAQ,IAE9D,OAAOW,CAAC,MAAM,OAAOX,CAAC,CAC9B,CAEE,GAAU,OAAO;IAAA,OACjB,IAAII,MAAO,UAAUA,MAAO,SAASA,MAAO,UAAUA,MAAO,OAAO;KACzE,IAAIH,KAAmC,QAAQA,MAAW,IAAI,OAAO;KAErE,IAAMW,IAAaV,IAAc,IAAI,KAAKD,CAAa,CAAC,CAAC,QAAQ,IAAI,OAAOA,CAAM,GAC5EY,IAAeX,IAAc,IAAI,KAAKG,CAAY,CAAC,CAAC,QAAQ,IAAI,OAAOA,CAAK;KAOlF,IALI,MAAMO,CAAU,KAAK,MAAMC,CAAY,KAEvCT,MAAO,UAAU,EAAEQ,KAAcC,MACjCT,MAAO,SAAS,EAAEQ,IAAaC,MAC/BT,MAAO,UAAU,EAAEQ,KAAcC,MACjCT,MAAO,SAAS,EAAEQ,IAAaC,IAAe,OAAO;IAC3D;UAIF,IAAIZ,KAAmC,QAAQA,MAAW,IACpD;QAAAtB,KAA6B,QAAQA,MAAQ,IAAI,OAAO;GAAA,OACvD,IAAIuB,KAAeD,KAAUtB,GAC9B;QAAA,IAAI,KAAKsB,CAAa,CAAC,CAAC,QAAQ,MAAM,IAAI,KAAKtB,CAAU,CAAC,CAAC,QAAQ,GAAG,OAAO;GAAA,OAEjF,IAAI,OAAOsB,CAAM,MAAM,OAAOtB,CAAG,GAAG,OAAO;EAGjD;EACA,OAAO;CACT;CAEA,OAAOkB,EAAK,QAAQ,MAAQC,EAASnD,GAAKiD,CAAK,CAAC;AAClD"}
@@ -1,2 +1,2 @@
1
- "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../ui/components/ui/button-components.cjs"),n=require("../../../ui/components/ui/table.cjs");let r=require("react/jsx-runtime"),i=require("react");i=e.__toESM(i,1);let a=require("lucide-react");function o({columns:e,data:o,emptyMessage:s=`データがありません`,onRemove:c,onAddRow:l,getRowKey:u=(e,t)=>`row-${t}`,renderRowActions:d,renderExtraRow:f,className:p=``,isWrapped:m=!1,zoomLevel:h=0,onRowBlur:g}){let _=(0,i.useRef)(null),v=(0,i.useRef)(l);(0,i.useEffect)(()=>{v.current=l});let y=(0,i.useRef)(new Set);(0,i.useEffect)(()=>{let e=y.current;return()=>{e.forEach(e=>clearTimeout(e)),e.clear()}},[]);let b=e=>e instanceof HTMLElement&&!!e.closest(`[data-searchable-select-portal="true"]`);(0,i.useEffect)(()=>{let e=_.current;if(!e)return;let t=t=>{let n=document.activeElement;if(!n||!e.contains(n)||t.isComposing||n.tagName!==`INPUT`&&n.tagName!==`TEXTAREA`&&n.tagName!==`SELECT`&&n.getAttribute(`role`)!==`combobox`)return;let r=n.closest(`td`);if(!r)return;let i=r.closest(`tr`);if(!i)return;let a=i.closest(`tbody`);if(!a)return;let o=Array.from(a.querySelectorAll(`tr:not([class*="extra"])`)),s=o.indexOf(i),c=Array.from(i.querySelectorAll(`td`)),l=c.indexOf(r),u=null;switch(t.key){case`ArrowRight`:t.preventDefault(),l<c.length-1&&(u=c[l+1]);break;case`ArrowLeft`:t.preventDefault(),l>0&&(u=c[l-1]);break;case`ArrowDown`:if(t.preventDefault(),s<o.length-1){let e=o[s+1],t=Array.from(e.querySelectorAll(`td`));t[l]&&(u=t[l])}break;case`ArrowUp`:if(t.preventDefault(),s>0){let e=o[s-1],t=Array.from(e.querySelectorAll(`td`));t[l]&&(u=t[l])}break;case`Enter`:if(n.tagName!==`TEXTAREA`&&!t.shiftKey){t.preventDefault();let e=s===o.length-1,n=l>=c.length-1,r=(e,t)=>{let n=setTimeout(()=>{y.current.delete(n),e()},t);y.current.add(n)};r(()=>{if(l<c.length-1)u=c[l+1];else if(s<o.length-1){let e=o[s+1],t=Array.from(e.querySelectorAll(`td`));t[0]&&(u=t[0])}else e&&n&&v.current&&(v.current(),r(()=>{let e=Array.from(a.querySelectorAll(`tr:not([class*="extra"])`)),t=e[e.length-1];if(t){let e=t.querySelector(`input, textarea, select, [role="combobox"]`);e&&(e.focus(),e instanceof HTMLInputElement&&e.type!==`number`&&e.select())}},100));if(u){let e=u.querySelector(`input, textarea, select, [role="combobox"]`);e&&(e.focus(),e instanceof HTMLInputElement&&e.type!==`number`&&e.select())}},50)}return;case`Tab`:return}if(u){let e=u.querySelector(`input, textarea, select, [role="combobox"]`);e&&(e.focus(),e instanceof HTMLInputElement&&e.type!==`number`&&e.select())}};return e.addEventListener(`keydown`,t),()=>e.removeEventListener(`keydown`,t)},[e,o]);let x=m?`[&_td]:whitespace-normal [&_td_*]:whitespace-normal [&_th]:whitespace-normal`:`[&_td]:whitespace-nowrap [&_th]:whitespace-nowrap`,S=[``,`[&_td]:text-[0.85rem] [&_th]:text-[0.85rem] [&_td_*]:text-[0.85rem] [&_button]:h-7 [&_input]:h-7 [&_select]:h-7`,`[&_td]:text-[0.75rem] [&_th]:text-[0.75rem] [&_td_*]:text-[0.75rem] [&_button]:h-6 [&_input]:h-6 [&_select]:h-6`,`[&_td]:text-[0.65rem] [&_th]:text-[0.65rem] [&_td_*]:text-[0.65rem] [&_button]:h-5 [&_input]:h-5 [&_select]:h-5`,`[&_td]:text-[0.55rem] [&_th]:text-[0.55rem] [&_td_*]:text-[0.55rem] [&_button]:h-4 [&_input]:h-4 [&_select]:h-4`],C=S[Math.min(h,S.length-1)]||``;return(0,r.jsx)(`div`,{className:`${p} ${x} ${C} overflow-x-auto`,children:(0,r.jsxs)(n.Table,{ref:_,children:[(0,r.jsx)(n.TableHeader,{children:(0,r.jsxs)(n.TableRow,{children:[e.map(e=>(0,r.jsx)(n.TableHead,{className:`px-2 py-1 h-auto border border-border align-middle ${e.headerClassName||``}`,style:{textAlign:e.align||`center`,verticalAlign:`middle`,minWidth:e.width},children:e.label},e.key)),d&&(0,r.jsx)(n.TableHead,{className:`px-2 py-1 h-auto`}),c&&(0,r.jsx)(n.TableHead,{className:`px-2 py-1 h-auto`})]})}),(0,r.jsx)(n.TableBody,{children:o.length===0?(0,r.jsx)(n.TableRow,{children:(0,r.jsx)(n.TableCell,{colSpan:e.length+ +!!d+ +!!c,className:`h-24 text-center`,children:s})}):o.map((o,s)=>{let l=u(o,s);return(0,r.jsxs)(i.default.Fragment,{children:[(0,r.jsxs)(n.TableRow,{className:`hover:bg-muted/50`,onBlur:e=>{if(!g)return;let t=e.currentTarget,n=e.relatedTarget;t.contains(n)||b(n)||window.setTimeout(()=>{if(!t.isConnected)return;let e=document.activeElement;t.contains(e)||b(e)||g(s)},0)},children:[e.map(e=>{let t=e.render?e.render(o,s):o[e.key],i=e.isEditable===void 0?!!e.render:e.isEditable;return(0,r.jsx)(n.TableCell,{className:`text-sm border border-border ${i||e.cellClassName?`p-0`:`px-2 py-1`} ${e.align===`center`?`text-center`:e.align===`right`?`text-right`:``} ${e.cellClassName||``}`,children:(0,r.jsx)(`div`,{className:i?`w-full h-full`:``,children:t})},e.key)}),d&&(0,r.jsx)(n.TableCell,{className:`px-1 py-1 text-center`,children:d(o,s)}),c&&(0,r.jsx)(n.TableCell,{className:`px-1 py-1 text-center`,children:(0,r.jsx)(t.Button,{type:`button`,variant:`destructive`,size:`sm`,className:`h-6 w-6 p-0`,onClick:()=>c(s),children:(0,r.jsx)(a.Trash2,{className:`h-3 w-3`})})})]}),f&&(0,r.jsx)(n.TableRow,{className:`bg-muted/50 hover:bg-muted/50`,children:(0,r.jsx)(n.TableCell,{colSpan:e.length+ +!!d+ +!!c,className:`px-4 py-2`,children:f(o,s)})},`${l}-extra`)]},l)})})]})})}exports.EditableTable=o;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../ui/components/ui/button-components.cjs"),n=require("../../../ui/components/ui/table.cjs");let r=require("react/jsx-runtime"),i=require("react");i=e.__toESM(i,1);let a=require("lucide-react");function o({columns:e,data:o,emptyMessage:s=`データがありません`,onRemove:c,onAddRow:l,getRowKey:u=(e,t)=>`row-${t}`,renderRowActions:d,renderExtraRow:f,className:p=``,isWrapped:m=!1,zoomLevel:h=0,onRowBlur:g}){let _=(0,i.useRef)(null),v=(0,i.useRef)(l);(0,i.useEffect)(()=>{v.current=l});let y=(0,i.useRef)(new Set);(0,i.useEffect)(()=>{let e=y.current;return()=>{e.forEach(e=>clearTimeout(e)),e.clear()}},[]);let b=e=>e instanceof HTMLElement&&!!e.closest(`[data-searchable-select-portal="true"]`);(0,i.useEffect)(()=>{let e=_.current;if(!e)return;let t=t=>{let n=document.activeElement;if(!n||!e.contains(n)||t.isComposing||n.tagName!==`INPUT`&&n.tagName!==`TEXTAREA`&&n.tagName!==`SELECT`&&n.getAttribute(`role`)!==`combobox`)return;let r=n.closest(`td`);if(!r)return;let i=r.closest(`tr`);if(!i)return;let a=i.closest(`tbody`);if(!a)return;let o=Array.from(a.querySelectorAll(`tr:not([class*="extra"])`)),s=o.indexOf(i),c=Array.from(i.querySelectorAll(`td`)),l=c.indexOf(r),u=null;switch(t.key){case`ArrowRight`:t.preventDefault(),l<c.length-1&&(u=c[l+1]);break;case`ArrowLeft`:t.preventDefault(),l>0&&(u=c[l-1]);break;case`ArrowDown`:if(t.preventDefault(),s<o.length-1){let e=o[s+1],t=Array.from(e.querySelectorAll(`td`));t[l]&&(u=t[l])}break;case`ArrowUp`:if(t.preventDefault(),s>0){let e=o[s-1],t=Array.from(e.querySelectorAll(`td`));t[l]&&(u=t[l])}break;case`Enter`:if(n.tagName!==`TEXTAREA`&&!t.shiftKey){t.preventDefault();let e=s===o.length-1,n=l>=c.length-1,r=(e,t)=>{let n=setTimeout(()=>{y.current.delete(n),e()},t);y.current.add(n)};r(()=>{if(l<c.length-1)u=c[l+1];else if(s<o.length-1){let e=o[s+1],t=Array.from(e.querySelectorAll(`td`));t[0]&&(u=t[0])}else e&&n&&v.current&&(v.current(),r(()=>{let e=Array.from(a.querySelectorAll(`tr:not([class*="extra"])`)),t=e[e.length-1];if(t){let e=t.querySelector(`input, textarea, select, [role="combobox"]`);e&&(e.focus(),e instanceof HTMLInputElement&&e.type!==`number`&&e.select())}},100));if(u){let e=u.querySelector(`input, textarea, select, [role="combobox"]`);e&&(e.focus(),e instanceof HTMLInputElement&&e.type!==`number`&&e.select())}},50)}return;case`Tab`:return}if(u){let e=u.querySelector(`input, textarea, select, [role="combobox"]`);e&&(e.focus(),e instanceof HTMLInputElement&&e.type!==`number`&&e.select())}};return e.addEventListener(`keydown`,t),()=>e.removeEventListener(`keydown`,t)},[e,o]);let x=m?`[&_td]:whitespace-normal [&_td_*]:whitespace-normal [&_th]:whitespace-normal`:`[&_td]:whitespace-nowrap [&_th]:whitespace-nowrap`,S=[``,`[&_td]:text-[0.85rem] [&_th]:text-[0.85rem] [&_td_*]:text-[0.85rem] [&_button]:h-7 [&_input]:h-7 [&_select]:h-7`,`[&_td]:text-[0.75rem] [&_th]:text-[0.75rem] [&_td_*]:text-[0.75rem] [&_button]:h-6 [&_input]:h-6 [&_select]:h-6`,`[&_td]:text-[0.65rem] [&_th]:text-[0.65rem] [&_td_*]:text-[0.65rem] [&_button]:h-5 [&_input]:h-5 [&_select]:h-5`,`[&_td]:text-[0.55rem] [&_th]:text-[0.55rem] [&_td_*]:text-[0.55rem] [&_button]:h-4 [&_input]:h-4 [&_select]:h-4`],C=S[Math.min(h,S.length-1)]||``;return(0,r.jsx)(`div`,{className:`${p} ${x} ${C} overflow-x-auto`,children:(0,r.jsxs)(n.Table,{ref:_,children:[(0,r.jsx)(n.TableHeader,{children:(0,r.jsxs)(n.TableRow,{children:[e.map(e=>(0,r.jsx)(n.TableHead,{className:`px-2 py-1 h-auto border border-border align-middle ${e.headerClassName||``}`,style:{textAlign:e.align||`center`,verticalAlign:`middle`,minWidth:e.width},children:e.label},e.key)),d&&(0,r.jsx)(n.TableHead,{className:`px-2 py-1 h-auto`,children:(0,r.jsx)(`span`,{className:`sr-only`,children:`Actions`})}),c&&(0,r.jsx)(n.TableHead,{className:`px-2 py-1 h-auto`,children:(0,r.jsx)(`span`,{className:`sr-only`,children:`Actions`})})]})}),(0,r.jsx)(n.TableBody,{children:o.length===0?(0,r.jsx)(n.TableRow,{children:(0,r.jsx)(n.TableCell,{colSpan:e.length+ +!!d+ +!!c,className:`h-24 text-center`,children:s})}):o.map((o,s)=>{let l=u(o,s);return(0,r.jsxs)(i.default.Fragment,{children:[(0,r.jsxs)(n.TableRow,{className:`hover:bg-muted/50`,onBlur:e=>{if(!g)return;let t=e.currentTarget,n=e.relatedTarget;t.contains(n)||b(n)||window.setTimeout(()=>{if(!t.isConnected)return;let e=document.activeElement;t.contains(e)||b(e)||g(s)},0)},children:[e.map(e=>{let t=e.render?e.render(o,s):o[e.key],i=e.isEditable===void 0?!!e.render:e.isEditable;return(0,r.jsx)(n.TableCell,{className:`text-sm border border-border ${i||e.cellClassName?`p-0`:`px-2 py-1`} ${e.align===`center`?`text-center`:e.align===`right`?`text-right`:``} ${e.cellClassName||``}`,children:(0,r.jsx)(`div`,{className:i?`w-full h-full`:``,children:t})},e.key)}),d&&(0,r.jsx)(n.TableCell,{className:`px-1 py-1 text-center`,children:d(o,s)}),c&&(0,r.jsx)(n.TableCell,{className:`px-1 py-1 text-center`,children:(0,r.jsx)(t.Button,{type:`button`,variant:`destructive`,size:`sm`,className:`h-6 w-6 p-0`,"aria-label":`Remove row ${s+1}`,onClick:()=>c(s),children:(0,r.jsx)(a.Trash2,{className:`h-3 w-3`})})})]}),f&&(0,r.jsx)(n.TableRow,{className:`bg-muted/50 hover:bg-muted/50`,children:(0,r.jsx)(n.TableCell,{colSpan:e.length+ +!!d+ +!!c,className:`px-4 py-2`,children:f(o,s)})},`${l}-extra`)]},l)})})]})})}exports.EditableTable=o;
2
2
  //# sourceMappingURL=editable-table.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"editable-table.cjs","names":["useRef","input","Table","TableHeader","TableRow","TableHead","TableBody","TableCell","React","Button","Trash2","require_runtime","require_ui_components_ui_button_components","require_ui_components_ui_table","react_jsx_runtime","react","lucide_react","EditableTable","index","tableRef","onAddRowRef","onAddRow","timersRef","timers","id","isWithinSearchableSelectPortal","node","table","handleKeyDown","activeElement","e","cell","row","tbody","allRows","currentRowIndex","allCells","currentCellIndex","targetCell","nextRow","nextRowCells","prevRow","prevRowCells","isLastRow","isLastCell","scheduleTimeout","timerId","cb","ms","newRows","newLastRow","firstInput","nextInput","columns","data","wrapClass","isWrapped","zoomClasses","zoomClass","zoomLevel","className","col","renderRowActions","onRemove","emptyMessage","rowKey","getRowKey","item","onRowBlur","currentTarget","nextTarget","active","cellContent","isEditable","renderExtraRow"],"sources":["../../../../src/tools/components/editable-table/editable-table.tsx"],"sourcesContent":["import React, { useRef, useEffect } from 'react';\nimport { Button } from '../ui/button';\nimport { Trash2 } from 'lucide-react';\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../ui/table';\n\nexport interface EditableTableColumn<T> {\n key: string;\n label: string;\n align?: 'left' | 'center' | 'right';\n /** Render function for custom cell content, like inputs */\n render?: (item: T, index: number) => React.ReactNode;\n width?: string;\n cellClassName?: string;\n headerClassName?: string;\n /** Whether the cell contains an input and should remove padding */\n isEditable?: boolean;\n}\n\nexport interface EditableTableProps<T> {\n columns: EditableTableColumn<T>[];\n data: T[];\n emptyMessage?: string;\n onRemove?: (index: number) => void;\n onAddRow?: () => void;\n getRowKey?: (item: T, index: number) => string;\n renderRowActions?: (item: T, index: number) => React.ReactNode;\n renderExtraRow?: (item: T, index: number) => React.ReactNode;\n className?: string;\n isWrapped?: boolean;\n zoomLevel?: number; // 0: 100%, 1: 90%, 2: 80%, 3: 70%, 4: 60%\n onRowBlur?: (index: number) => void;\n}\n\n/**\n * キーボードナビゲーションに対応した、インライン編集可能なテーブルコンポーネント。\n */\nexport function EditableTable<T extends Record<string, any>>({\n columns,\n data,\n emptyMessage = 'データがありません',\n onRemove,\n onAddRow,\n getRowKey = (_, index) => `row-${index}`,\n renderRowActions,\n renderExtraRow,\n className = '',\n isWrapped = false,\n zoomLevel = 0,\n onRowBlur,\n}: EditableTableProps<T>) {\n const tableRef = useRef<HTMLTableElement>(null);\n const onAddRowRef = useRef(onAddRow);\n useEffect(() => {\n onAddRowRef.current = onAddRow;\n });\n const timersRef = useRef<Set<ReturnType<typeof setTimeout>>>(new Set());\n\n useEffect(() => {\n const timers = timersRef.current;\n return () => {\n timers.forEach((id) => clearTimeout(id));\n timers.clear();\n };\n }, []);\n\n const isWithinSearchableSelectPortal = (node: EventTarget | Node | null) => {\n if (!(node instanceof HTMLElement)) return false;\n return Boolean(node.closest('[data-searchable-select-portal=\"true\"]'));\n };\n\n // Handle keyboard navigation\n useEffect(() => {\n const table = tableRef.current;\n if (!table) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n const activeElement = document.activeElement;\n if (!activeElement || !table.contains(activeElement)) return;\n\n // Don't trigger if user is composing text (IME)\n if (e.isComposing) return;\n\n // Check if we're in an input/textarea/select\n const isInput =\n activeElement.tagName === 'INPUT' ||\n activeElement.tagName === 'TEXTAREA' ||\n activeElement.tagName === 'SELECT' ||\n activeElement.getAttribute('role') === 'combobox';\n\n if (!isInput) return;\n\n const input = activeElement as HTMLElement;\n const cell = input.closest('td');\n if (!cell) return;\n\n const row = cell.closest('tr');\n if (!row) return;\n\n const tbody = row.closest('tbody');\n if (!tbody) return;\n\n const allRows = Array.from(tbody.querySelectorAll('tr:not([class*=\"extra\"])'));\n const currentRowIndex = allRows.indexOf(row);\n const allCells = Array.from(row.querySelectorAll('td'));\n const currentCellIndex = allCells.indexOf(cell);\n\n let targetCell: HTMLElement | null = null;\n\n switch (e.key) {\n case 'ArrowRight':\n e.preventDefault();\n if (currentCellIndex < allCells.length - 1) {\n targetCell = allCells[currentCellIndex + 1];\n }\n break;\n case 'ArrowLeft':\n e.preventDefault();\n if (currentCellIndex > 0) {\n targetCell = allCells[currentCellIndex - 1];\n }\n break;\n case 'ArrowDown':\n e.preventDefault();\n if (currentRowIndex < allRows.length - 1) {\n const nextRow = allRows[currentRowIndex + 1];\n const nextRowCells = Array.from(nextRow.querySelectorAll('td'));\n if (nextRowCells[currentCellIndex]) {\n targetCell = nextRowCells[currentCellIndex];\n }\n }\n break;\n case 'ArrowUp':\n e.preventDefault();\n if (currentRowIndex > 0) {\n const prevRow = allRows[currentRowIndex - 1];\n const prevRowCells = Array.from(prevRow.querySelectorAll('td'));\n if (prevRowCells[currentCellIndex]) {\n targetCell = prevRowCells[currentCellIndex];\n }\n }\n break;\n case 'Enter':\n if (activeElement.tagName !== 'TEXTAREA' && !e.shiftKey) {\n e.preventDefault();\n const isLastRow = currentRowIndex === allRows.length - 1;\n const isLastCell = currentCellIndex >= allCells.length - 1;\n const scheduleTimeout = (cb: () => void, ms: number) => {\n const timerId = setTimeout(() => {\n timersRef.current.delete(timerId);\n cb();\n }, ms);\n timersRef.current.add(timerId);\n };\n\n scheduleTimeout(() => {\n if (currentCellIndex < allCells.length - 1) {\n targetCell = allCells[currentCellIndex + 1];\n } else if (currentRowIndex < allRows.length - 1) {\n const nextRow = allRows[currentRowIndex + 1];\n const nextRowCells = Array.from(nextRow.querySelectorAll('td'));\n if (nextRowCells[0]) {\n targetCell = nextRowCells[0];\n }\n } else if (isLastRow && isLastCell && onAddRowRef.current) {\n onAddRowRef.current();\n scheduleTimeout(() => {\n const newRows = Array.from(tbody.querySelectorAll('tr:not([class*=\"extra\"])'));\n const newLastRow = newRows[newRows.length - 1];\n if (newLastRow) {\n const firstInput = newLastRow.querySelector(\n 'input, textarea, select, [role=\"combobox\"]',\n ) as HTMLElement;\n if (firstInput) {\n firstInput.focus();\n if (firstInput instanceof HTMLInputElement && firstInput.type !== 'number') {\n firstInput.select();\n }\n }\n }\n }, 100);\n }\n if (targetCell) {\n const nextInput = targetCell.querySelector(\n 'input, textarea, select, [role=\"combobox\"]',\n ) as HTMLElement;\n if (nextInput) {\n nextInput.focus();\n if (nextInput instanceof HTMLInputElement && nextInput.type !== 'number') {\n nextInput.select();\n }\n }\n }\n }, 50);\n }\n return;\n case 'Tab':\n return;\n }\n\n if (targetCell) {\n const nextInput = targetCell.querySelector(\n 'input, textarea, select, [role=\"combobox\"]',\n ) as HTMLElement;\n if (nextInput) {\n nextInput.focus();\n if (nextInput instanceof HTMLInputElement && nextInput.type !== 'number') {\n nextInput.select();\n }\n }\n }\n };\n\n table.addEventListener('keydown', handleKeyDown);\n return () => table.removeEventListener('keydown', handleKeyDown);\n }, [columns, data]);\n\n const wrapClass = isWrapped\n ? '[&_td]:whitespace-normal [&_td_*]:whitespace-normal [&_th]:whitespace-normal'\n : '[&_td]:whitespace-nowrap [&_th]:whitespace-nowrap';\n\n const zoomClasses = [\n '', // 0: 100%\n '[&_td]:text-[0.85rem] [&_th]:text-[0.85rem] [&_td_*]:text-[0.85rem] [&_button]:h-7 [&_input]:h-7 [&_select]:h-7', // 1: 85%\n '[&_td]:text-[0.75rem] [&_th]:text-[0.75rem] [&_td_*]:text-[0.75rem] [&_button]:h-6 [&_input]:h-6 [&_select]:h-6', // 2: 75%\n '[&_td]:text-[0.65rem] [&_th]:text-[0.65rem] [&_td_*]:text-[0.65rem] [&_button]:h-5 [&_input]:h-5 [&_select]:h-5', // 3: 65%\n '[&_td]:text-[0.55rem] [&_th]:text-[0.55rem] [&_td_*]:text-[0.55rem] [&_button]:h-4 [&_input]:h-4 [&_select]:h-4', // 4: 55%\n ];\n const zoomClass = zoomClasses[Math.min(zoomLevel, zoomClasses.length - 1)] || '';\n\n return (\n <div className={`${className} ${wrapClass} ${zoomClass} overflow-x-auto`}>\n <Table ref={tableRef}>\n <TableHeader>\n <TableRow>\n {columns.map((col) => (\n <TableHead\n key={col.key}\n className={`px-2 py-1 h-auto border border-border align-middle ${col.headerClassName || ''}`}\n style={{\n textAlign: col.align || 'center',\n verticalAlign: 'middle',\n minWidth: col.width,\n }}\n >\n {col.label}\n </TableHead>\n ))}\n {renderRowActions && <TableHead className='px-2 py-1 h-auto'></TableHead>}\n {onRemove && <TableHead className='px-2 py-1 h-auto'></TableHead>}\n </TableRow>\n </TableHeader>\n <TableBody>\n {data.length === 0 ? (\n <TableRow>\n <TableCell\n colSpan={columns.length + (renderRowActions ? 1 : 0) + (onRemove ? 1 : 0)}\n className='h-24 text-center'\n >\n {emptyMessage}\n </TableCell>\n </TableRow>\n ) : (\n data.map((item, index) => {\n const rowKey = getRowKey(item, index);\n return (\n <React.Fragment key={rowKey}>\n <TableRow\n className='hover:bg-muted/50'\n onBlur={(e: React.FocusEvent<HTMLTableRowElement>) => {\n if (!onRowBlur) return;\n\n const currentTarget = e.currentTarget;\n const nextTarget = e.relatedTarget;\n\n if (currentTarget.contains(nextTarget as Node | null)) return;\n if (isWithinSearchableSelectPortal(nextTarget)) return;\n\n window.setTimeout(() => {\n if (!currentTarget.isConnected) return;\n\n const active = document.activeElement;\n if (currentTarget.contains(active)) return;\n if (isWithinSearchableSelectPortal(active)) return;\n\n onRowBlur(index);\n }, 0);\n }}\n >\n {columns.map((col) => {\n const cellContent = (col.render ? col.render(item, index) : item[col.key]) as React.ReactNode;\n const isEditable =\n col.isEditable !== undefined ? col.isEditable : !!col.render;\n\n return (\n <TableCell\n key={col.key}\n className={`text-sm border border-border ${isEditable || col.cellClassName ? 'p-0' : 'px-2 py-1'} ${col.align === 'center' ? 'text-center' : col.align === 'right' ? 'text-right' : ''} ${col.cellClassName || ''}`}\n >\n <div className={isEditable ? 'w-full h-full' : ''}>{cellContent}</div>\n </TableCell>\n );\n })}\n {renderRowActions && (\n <TableCell className='px-1 py-1 text-center'>\n {renderRowActions(item, index)}\n </TableCell>\n )}\n {onRemove && (\n <TableCell className='px-1 py-1 text-center'>\n <Button\n type='button'\n variant='destructive'\n size='sm'\n className='h-6 w-6 p-0'\n onClick={() => onRemove(index)}\n >\n <Trash2 className='h-3 w-3' />\n </Button>\n </TableCell>\n )}\n </TableRow>\n {renderExtraRow && (\n <TableRow key={`${rowKey}-extra`} className='bg-muted/50 hover:bg-muted/50'>\n <TableCell\n colSpan={columns.length + (renderRowActions ? 1 : 0) + (onRemove ? 1 : 0)}\n className='px-4 py-2'\n >\n {renderExtraRow(item, index)}\n </TableCell>\n </TableRow>\n )}\n </React.Fragment>\n );\n })\n )}\n </TableBody>\n </Table>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"editable-table.cjs","names":["useRef","input","Table","TableHeader","TableRow","TableHead","TableBody","TableCell","React","Button","Trash2","require_runtime","require_ui_components_ui_button_components","require_ui_components_ui_table","react_jsx_runtime","react","lucide_react","EditableTable","index","tableRef","onAddRowRef","onAddRow","timersRef","timers","id","isWithinSearchableSelectPortal","node","table","handleKeyDown","activeElement","e","cell","row","tbody","allRows","currentRowIndex","allCells","currentCellIndex","targetCell","nextRow","nextRowCells","prevRow","prevRowCells","isLastRow","isLastCell","scheduleTimeout","timerId","cb","ms","newRows","newLastRow","firstInput","nextInput","columns","data","wrapClass","isWrapped","zoomClasses","zoomClass","zoomLevel","className","col","renderRowActions","onRemove","emptyMessage","rowKey","getRowKey","item","onRowBlur","currentTarget","nextTarget","active","cellContent","isEditable","renderExtraRow"],"sources":["../../../../src/tools/components/editable-table/editable-table.tsx"],"sourcesContent":["import React, { useRef, useEffect } from 'react';\nimport { Button } from '../ui/button';\nimport { Trash2 } from 'lucide-react';\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../ui/table';\n\nexport interface EditableTableColumn<T> {\n key: string;\n label: string;\n align?: 'left' | 'center' | 'right';\n /** Render function for custom cell content, like inputs */\n render?: (item: T, index: number) => React.ReactNode;\n width?: string;\n cellClassName?: string;\n headerClassName?: string;\n /** Whether the cell contains an input and should remove padding */\n isEditable?: boolean;\n}\n\nexport interface EditableTableProps<T> {\n columns: EditableTableColumn<T>[];\n data: T[];\n emptyMessage?: string;\n onRemove?: (index: number) => void;\n onAddRow?: () => void;\n getRowKey?: (item: T, index: number) => string;\n renderRowActions?: (item: T, index: number) => React.ReactNode;\n renderExtraRow?: (item: T, index: number) => React.ReactNode;\n className?: string;\n isWrapped?: boolean;\n zoomLevel?: number; // 0: 100%, 1: 90%, 2: 80%, 3: 70%, 4: 60%\n onRowBlur?: (index: number) => void;\n}\n\n/**\n * キーボードナビゲーションに対応した、インライン編集可能なテーブルコンポーネント。\n */\nexport function EditableTable<T extends Record<string, any>>({\n columns,\n data,\n emptyMessage = 'データがありません',\n onRemove,\n onAddRow,\n getRowKey = (_, index) => `row-${index}`,\n renderRowActions,\n renderExtraRow,\n className = '',\n isWrapped = false,\n zoomLevel = 0,\n onRowBlur,\n}: EditableTableProps<T>) {\n const tableRef = useRef<HTMLTableElement>(null);\n const onAddRowRef = useRef(onAddRow);\n useEffect(() => {\n onAddRowRef.current = onAddRow;\n });\n const timersRef = useRef<Set<ReturnType<typeof setTimeout>>>(new Set());\n\n useEffect(() => {\n const timers = timersRef.current;\n return () => {\n timers.forEach((id) => clearTimeout(id));\n timers.clear();\n };\n }, []);\n\n const isWithinSearchableSelectPortal = (node: EventTarget | Node | null) => {\n if (!(node instanceof HTMLElement)) return false;\n return Boolean(node.closest('[data-searchable-select-portal=\"true\"]'));\n };\n\n // Handle keyboard navigation\n useEffect(() => {\n const table = tableRef.current;\n if (!table) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n const activeElement = document.activeElement;\n if (!activeElement || !table.contains(activeElement)) return;\n\n // Don't trigger if user is composing text (IME)\n if (e.isComposing) return;\n\n // Check if we're in an input/textarea/select\n const isInput =\n activeElement.tagName === 'INPUT' ||\n activeElement.tagName === 'TEXTAREA' ||\n activeElement.tagName === 'SELECT' ||\n activeElement.getAttribute('role') === 'combobox';\n\n if (!isInput) return;\n\n const input = activeElement as HTMLElement;\n const cell = input.closest('td');\n if (!cell) return;\n\n const row = cell.closest('tr');\n if (!row) return;\n\n const tbody = row.closest('tbody');\n if (!tbody) return;\n\n const allRows = Array.from(tbody.querySelectorAll('tr:not([class*=\"extra\"])'));\n const currentRowIndex = allRows.indexOf(row);\n const allCells = Array.from(row.querySelectorAll('td'));\n const currentCellIndex = allCells.indexOf(cell);\n\n let targetCell: HTMLElement | null = null;\n\n switch (e.key) {\n case 'ArrowRight':\n e.preventDefault();\n if (currentCellIndex < allCells.length - 1) {\n targetCell = allCells[currentCellIndex + 1];\n }\n break;\n case 'ArrowLeft':\n e.preventDefault();\n if (currentCellIndex > 0) {\n targetCell = allCells[currentCellIndex - 1];\n }\n break;\n case 'ArrowDown':\n e.preventDefault();\n if (currentRowIndex < allRows.length - 1) {\n const nextRow = allRows[currentRowIndex + 1];\n const nextRowCells = Array.from(nextRow.querySelectorAll('td'));\n if (nextRowCells[currentCellIndex]) {\n targetCell = nextRowCells[currentCellIndex];\n }\n }\n break;\n case 'ArrowUp':\n e.preventDefault();\n if (currentRowIndex > 0) {\n const prevRow = allRows[currentRowIndex - 1];\n const prevRowCells = Array.from(prevRow.querySelectorAll('td'));\n if (prevRowCells[currentCellIndex]) {\n targetCell = prevRowCells[currentCellIndex];\n }\n }\n break;\n case 'Enter':\n if (activeElement.tagName !== 'TEXTAREA' && !e.shiftKey) {\n e.preventDefault();\n const isLastRow = currentRowIndex === allRows.length - 1;\n const isLastCell = currentCellIndex >= allCells.length - 1;\n const scheduleTimeout = (cb: () => void, ms: number) => {\n const timerId = setTimeout(() => {\n timersRef.current.delete(timerId);\n cb();\n }, ms);\n timersRef.current.add(timerId);\n };\n\n scheduleTimeout(() => {\n if (currentCellIndex < allCells.length - 1) {\n targetCell = allCells[currentCellIndex + 1];\n } else if (currentRowIndex < allRows.length - 1) {\n const nextRow = allRows[currentRowIndex + 1];\n const nextRowCells = Array.from(nextRow.querySelectorAll('td'));\n if (nextRowCells[0]) {\n targetCell = nextRowCells[0];\n }\n } else if (isLastRow && isLastCell && onAddRowRef.current) {\n onAddRowRef.current();\n scheduleTimeout(() => {\n const newRows = Array.from(tbody.querySelectorAll('tr:not([class*=\"extra\"])'));\n const newLastRow = newRows[newRows.length - 1];\n if (newLastRow) {\n const firstInput = newLastRow.querySelector(\n 'input, textarea, select, [role=\"combobox\"]',\n ) as HTMLElement;\n if (firstInput) {\n firstInput.focus();\n if (firstInput instanceof HTMLInputElement && firstInput.type !== 'number') {\n firstInput.select();\n }\n }\n }\n }, 100);\n }\n if (targetCell) {\n const nextInput = targetCell.querySelector(\n 'input, textarea, select, [role=\"combobox\"]',\n ) as HTMLElement;\n if (nextInput) {\n nextInput.focus();\n if (nextInput instanceof HTMLInputElement && nextInput.type !== 'number') {\n nextInput.select();\n }\n }\n }\n }, 50);\n }\n return;\n case 'Tab':\n return;\n }\n\n if (targetCell) {\n const nextInput = targetCell.querySelector(\n 'input, textarea, select, [role=\"combobox\"]',\n ) as HTMLElement;\n if (nextInput) {\n nextInput.focus();\n if (nextInput instanceof HTMLInputElement && nextInput.type !== 'number') {\n nextInput.select();\n }\n }\n }\n };\n\n table.addEventListener('keydown', handleKeyDown);\n return () => table.removeEventListener('keydown', handleKeyDown);\n }, [columns, data]);\n\n const wrapClass = isWrapped\n ? '[&_td]:whitespace-normal [&_td_*]:whitespace-normal [&_th]:whitespace-normal'\n : '[&_td]:whitespace-nowrap [&_th]:whitespace-nowrap';\n\n const zoomClasses = [\n '', // 0: 100%\n '[&_td]:text-[0.85rem] [&_th]:text-[0.85rem] [&_td_*]:text-[0.85rem] [&_button]:h-7 [&_input]:h-7 [&_select]:h-7', // 1: 85%\n '[&_td]:text-[0.75rem] [&_th]:text-[0.75rem] [&_td_*]:text-[0.75rem] [&_button]:h-6 [&_input]:h-6 [&_select]:h-6', // 2: 75%\n '[&_td]:text-[0.65rem] [&_th]:text-[0.65rem] [&_td_*]:text-[0.65rem] [&_button]:h-5 [&_input]:h-5 [&_select]:h-5', // 3: 65%\n '[&_td]:text-[0.55rem] [&_th]:text-[0.55rem] [&_td_*]:text-[0.55rem] [&_button]:h-4 [&_input]:h-4 [&_select]:h-4', // 4: 55%\n ];\n const zoomClass = zoomClasses[Math.min(zoomLevel, zoomClasses.length - 1)] || '';\n\n return (\n <div className={`${className} ${wrapClass} ${zoomClass} overflow-x-auto`}>\n <Table ref={tableRef}>\n <TableHeader>\n <TableRow>\n {columns.map((col) => (\n <TableHead\n key={col.key}\n className={`px-2 py-1 h-auto border border-border align-middle ${col.headerClassName || ''}`}\n style={{\n textAlign: col.align || 'center',\n verticalAlign: 'middle',\n minWidth: col.width,\n }}\n >\n {col.label}\n </TableHead>\n ))}\n {renderRowActions && <TableHead className='px-2 py-1 h-auto'><span className='sr-only'>Actions</span></TableHead>}\n {onRemove && <TableHead className='px-2 py-1 h-auto'><span className='sr-only'>Actions</span></TableHead>}\n </TableRow>\n </TableHeader>\n <TableBody>\n {data.length === 0 ? (\n <TableRow>\n <TableCell\n colSpan={columns.length + (renderRowActions ? 1 : 0) + (onRemove ? 1 : 0)}\n className='h-24 text-center'\n >\n {emptyMessage}\n </TableCell>\n </TableRow>\n ) : (\n data.map((item, index) => {\n const rowKey = getRowKey(item, index);\n return (\n <React.Fragment key={rowKey}>\n <TableRow\n className='hover:bg-muted/50'\n onBlur={(e: React.FocusEvent<HTMLTableRowElement>) => {\n if (!onRowBlur) return;\n\n const currentTarget = e.currentTarget;\n const nextTarget = e.relatedTarget;\n\n if (currentTarget.contains(nextTarget as Node | null)) return;\n if (isWithinSearchableSelectPortal(nextTarget)) return;\n\n window.setTimeout(() => {\n if (!currentTarget.isConnected) return;\n\n const active = document.activeElement;\n if (currentTarget.contains(active)) return;\n if (isWithinSearchableSelectPortal(active)) return;\n\n onRowBlur(index);\n }, 0);\n }}\n >\n {columns.map((col) => {\n const cellContent = (col.render ? col.render(item, index) : item[col.key]) as React.ReactNode;\n const isEditable =\n col.isEditable !== undefined ? col.isEditable : !!col.render;\n\n return (\n <TableCell\n key={col.key}\n className={`text-sm border border-border ${isEditable || col.cellClassName ? 'p-0' : 'px-2 py-1'} ${col.align === 'center' ? 'text-center' : col.align === 'right' ? 'text-right' : ''} ${col.cellClassName || ''}`}\n >\n <div className={isEditable ? 'w-full h-full' : ''}>{cellContent}</div>\n </TableCell>\n );\n })}\n {renderRowActions && (\n <TableCell className='px-1 py-1 text-center'>\n {renderRowActions(item, index)}\n </TableCell>\n )}\n {onRemove && (\n <TableCell className='px-1 py-1 text-center'>\n <Button\n type='button'\n variant='destructive'\n size='sm'\n className='h-6 w-6 p-0'\n aria-label={`Remove row ${index + 1}`}\n onClick={() => onRemove(index)}\n >\n <Trash2 className='h-3 w-3' />\n </Button>\n </TableCell>\n )}\n </TableRow>\n {renderExtraRow && (\n <TableRow key={`${rowKey}-extra`} className='bg-muted/50 hover:bg-muted/50'>\n <TableCell\n colSpan={columns.length + (renderRowActions ? 1 : 0) + (onRemove ? 1 : 0)}\n className='px-4 py-2'\n >\n {renderExtraRow(item, index)}\n </TableCell>\n </TableRow>\n )}\n </React.Fragment>\n );\n })\n )}\n </TableBody>\n </Table>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -108,8 +108,20 @@ function p({ columns: p, data: m, emptyMessage: h = "データがありません
108
108
  },
109
109
  children: e.label
110
110
  }, e.key)),
111
- y && /* @__PURE__ */ s(i, { className: "px-2 py-1 h-auto" }),
112
- g && /* @__PURE__ */ s(i, { className: "px-2 py-1 h-auto" })
111
+ y && /* @__PURE__ */ s(i, {
112
+ className: "px-2 py-1 h-auto",
113
+ children: /* @__PURE__ */ s("span", {
114
+ className: "sr-only",
115
+ children: "Actions"
116
+ })
117
+ }),
118
+ g && /* @__PURE__ */ s(i, {
119
+ className: "px-2 py-1 h-auto",
120
+ children: /* @__PURE__ */ s("span", {
121
+ className: "sr-only",
122
+ children: "Actions"
123
+ })
124
+ })
113
125
  ] }) }), /* @__PURE__ */ s(n, { children: m.length === 0 ? /* @__PURE__ */ s(o, { children: /* @__PURE__ */ s(r, {
114
126
  colSpan: p.length + +!!y + +!!g,
115
127
  className: "h-24 text-center",
@@ -149,6 +161,7 @@ function p({ columns: p, data: m, emptyMessage: h = "データがありません
149
161
  variant: "destructive",
150
162
  size: "sm",
151
163
  className: "h-6 w-6 p-0",
164
+ "aria-label": `Remove row ${n + 1}`,
152
165
  onClick: () => g(n),
153
166
  children: /* @__PURE__ */ s(f, { className: "h-3 w-3" })
154
167
  })
@@ -1 +1 @@
1
- {"version":3,"file":"editable-table.js","names":["input","React","EditableTable","index","tableRef","useRef","onAddRowRef","onAddRow","timersRef","timers","id","isWithinSearchableSelectPortal","node","table","handleKeyDown","activeElement","e","cell","row","tbody","allRows","currentRowIndex","allCells","currentCellIndex","targetCell","nextRow","nextRowCells","prevRow","prevRowCells","isLastRow","isLastCell","scheduleTimeout","timerId","cb","ms","newRows","newLastRow","firstInput","nextInput","columns","data","wrapClass","isWrapped","zoomClasses","zoomClass","zoomLevel","className","Table","TableHeader","TableRow","TableHead","col","renderRowActions","onRemove","TableBody","TableCell","emptyMessage","rowKey","getRowKey","item","onRowBlur","currentTarget","nextTarget","active","cellContent","isEditable","Button","Trash2","renderExtraRow"],"sources":["../../../../src/tools/components/editable-table/editable-table.tsx"],"sourcesContent":["import React, { useRef, useEffect } from 'react';\nimport { Button } from '../ui/button';\nimport { Trash2 } from 'lucide-react';\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../ui/table';\n\nexport interface EditableTableColumn<T> {\n key: string;\n label: string;\n align?: 'left' | 'center' | 'right';\n /** Render function for custom cell content, like inputs */\n render?: (item: T, index: number) => React.ReactNode;\n width?: string;\n cellClassName?: string;\n headerClassName?: string;\n /** Whether the cell contains an input and should remove padding */\n isEditable?: boolean;\n}\n\nexport interface EditableTableProps<T> {\n columns: EditableTableColumn<T>[];\n data: T[];\n emptyMessage?: string;\n onRemove?: (index: number) => void;\n onAddRow?: () => void;\n getRowKey?: (item: T, index: number) => string;\n renderRowActions?: (item: T, index: number) => React.ReactNode;\n renderExtraRow?: (item: T, index: number) => React.ReactNode;\n className?: string;\n isWrapped?: boolean;\n zoomLevel?: number; // 0: 100%, 1: 90%, 2: 80%, 3: 70%, 4: 60%\n onRowBlur?: (index: number) => void;\n}\n\n/**\n * キーボードナビゲーションに対応した、インライン編集可能なテーブルコンポーネント。\n */\nexport function EditableTable<T extends Record<string, any>>({\n columns,\n data,\n emptyMessage = 'データがありません',\n onRemove,\n onAddRow,\n getRowKey = (_, index) => `row-${index}`,\n renderRowActions,\n renderExtraRow,\n className = '',\n isWrapped = false,\n zoomLevel = 0,\n onRowBlur,\n}: EditableTableProps<T>) {\n const tableRef = useRef<HTMLTableElement>(null);\n const onAddRowRef = useRef(onAddRow);\n useEffect(() => {\n onAddRowRef.current = onAddRow;\n });\n const timersRef = useRef<Set<ReturnType<typeof setTimeout>>>(new Set());\n\n useEffect(() => {\n const timers = timersRef.current;\n return () => {\n timers.forEach((id) => clearTimeout(id));\n timers.clear();\n };\n }, []);\n\n const isWithinSearchableSelectPortal = (node: EventTarget | Node | null) => {\n if (!(node instanceof HTMLElement)) return false;\n return Boolean(node.closest('[data-searchable-select-portal=\"true\"]'));\n };\n\n // Handle keyboard navigation\n useEffect(() => {\n const table = tableRef.current;\n if (!table) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n const activeElement = document.activeElement;\n if (!activeElement || !table.contains(activeElement)) return;\n\n // Don't trigger if user is composing text (IME)\n if (e.isComposing) return;\n\n // Check if we're in an input/textarea/select\n const isInput =\n activeElement.tagName === 'INPUT' ||\n activeElement.tagName === 'TEXTAREA' ||\n activeElement.tagName === 'SELECT' ||\n activeElement.getAttribute('role') === 'combobox';\n\n if (!isInput) return;\n\n const input = activeElement as HTMLElement;\n const cell = input.closest('td');\n if (!cell) return;\n\n const row = cell.closest('tr');\n if (!row) return;\n\n const tbody = row.closest('tbody');\n if (!tbody) return;\n\n const allRows = Array.from(tbody.querySelectorAll('tr:not([class*=\"extra\"])'));\n const currentRowIndex = allRows.indexOf(row);\n const allCells = Array.from(row.querySelectorAll('td'));\n const currentCellIndex = allCells.indexOf(cell);\n\n let targetCell: HTMLElement | null = null;\n\n switch (e.key) {\n case 'ArrowRight':\n e.preventDefault();\n if (currentCellIndex < allCells.length - 1) {\n targetCell = allCells[currentCellIndex + 1];\n }\n break;\n case 'ArrowLeft':\n e.preventDefault();\n if (currentCellIndex > 0) {\n targetCell = allCells[currentCellIndex - 1];\n }\n break;\n case 'ArrowDown':\n e.preventDefault();\n if (currentRowIndex < allRows.length - 1) {\n const nextRow = allRows[currentRowIndex + 1];\n const nextRowCells = Array.from(nextRow.querySelectorAll('td'));\n if (nextRowCells[currentCellIndex]) {\n targetCell = nextRowCells[currentCellIndex];\n }\n }\n break;\n case 'ArrowUp':\n e.preventDefault();\n if (currentRowIndex > 0) {\n const prevRow = allRows[currentRowIndex - 1];\n const prevRowCells = Array.from(prevRow.querySelectorAll('td'));\n if (prevRowCells[currentCellIndex]) {\n targetCell = prevRowCells[currentCellIndex];\n }\n }\n break;\n case 'Enter':\n if (activeElement.tagName !== 'TEXTAREA' && !e.shiftKey) {\n e.preventDefault();\n const isLastRow = currentRowIndex === allRows.length - 1;\n const isLastCell = currentCellIndex >= allCells.length - 1;\n const scheduleTimeout = (cb: () => void, ms: number) => {\n const timerId = setTimeout(() => {\n timersRef.current.delete(timerId);\n cb();\n }, ms);\n timersRef.current.add(timerId);\n };\n\n scheduleTimeout(() => {\n if (currentCellIndex < allCells.length - 1) {\n targetCell = allCells[currentCellIndex + 1];\n } else if (currentRowIndex < allRows.length - 1) {\n const nextRow = allRows[currentRowIndex + 1];\n const nextRowCells = Array.from(nextRow.querySelectorAll('td'));\n if (nextRowCells[0]) {\n targetCell = nextRowCells[0];\n }\n } else if (isLastRow && isLastCell && onAddRowRef.current) {\n onAddRowRef.current();\n scheduleTimeout(() => {\n const newRows = Array.from(tbody.querySelectorAll('tr:not([class*=\"extra\"])'));\n const newLastRow = newRows[newRows.length - 1];\n if (newLastRow) {\n const firstInput = newLastRow.querySelector(\n 'input, textarea, select, [role=\"combobox\"]',\n ) as HTMLElement;\n if (firstInput) {\n firstInput.focus();\n if (firstInput instanceof HTMLInputElement && firstInput.type !== 'number') {\n firstInput.select();\n }\n }\n }\n }, 100);\n }\n if (targetCell) {\n const nextInput = targetCell.querySelector(\n 'input, textarea, select, [role=\"combobox\"]',\n ) as HTMLElement;\n if (nextInput) {\n nextInput.focus();\n if (nextInput instanceof HTMLInputElement && nextInput.type !== 'number') {\n nextInput.select();\n }\n }\n }\n }, 50);\n }\n return;\n case 'Tab':\n return;\n }\n\n if (targetCell) {\n const nextInput = targetCell.querySelector(\n 'input, textarea, select, [role=\"combobox\"]',\n ) as HTMLElement;\n if (nextInput) {\n nextInput.focus();\n if (nextInput instanceof HTMLInputElement && nextInput.type !== 'number') {\n nextInput.select();\n }\n }\n }\n };\n\n table.addEventListener('keydown', handleKeyDown);\n return () => table.removeEventListener('keydown', handleKeyDown);\n }, [columns, data]);\n\n const wrapClass = isWrapped\n ? '[&_td]:whitespace-normal [&_td_*]:whitespace-normal [&_th]:whitespace-normal'\n : '[&_td]:whitespace-nowrap [&_th]:whitespace-nowrap';\n\n const zoomClasses = [\n '', // 0: 100%\n '[&_td]:text-[0.85rem] [&_th]:text-[0.85rem] [&_td_*]:text-[0.85rem] [&_button]:h-7 [&_input]:h-7 [&_select]:h-7', // 1: 85%\n '[&_td]:text-[0.75rem] [&_th]:text-[0.75rem] [&_td_*]:text-[0.75rem] [&_button]:h-6 [&_input]:h-6 [&_select]:h-6', // 2: 75%\n '[&_td]:text-[0.65rem] [&_th]:text-[0.65rem] [&_td_*]:text-[0.65rem] [&_button]:h-5 [&_input]:h-5 [&_select]:h-5', // 3: 65%\n '[&_td]:text-[0.55rem] [&_th]:text-[0.55rem] [&_td_*]:text-[0.55rem] [&_button]:h-4 [&_input]:h-4 [&_select]:h-4', // 4: 55%\n ];\n const zoomClass = zoomClasses[Math.min(zoomLevel, zoomClasses.length - 1)] || '';\n\n return (\n <div className={`${className} ${wrapClass} ${zoomClass} overflow-x-auto`}>\n <Table ref={tableRef}>\n <TableHeader>\n <TableRow>\n {columns.map((col) => (\n <TableHead\n key={col.key}\n className={`px-2 py-1 h-auto border border-border align-middle ${col.headerClassName || ''}`}\n style={{\n textAlign: col.align || 'center',\n verticalAlign: 'middle',\n minWidth: col.width,\n }}\n >\n {col.label}\n </TableHead>\n ))}\n {renderRowActions && <TableHead className='px-2 py-1 h-auto'></TableHead>}\n {onRemove && <TableHead className='px-2 py-1 h-auto'></TableHead>}\n </TableRow>\n </TableHeader>\n <TableBody>\n {data.length === 0 ? (\n <TableRow>\n <TableCell\n colSpan={columns.length + (renderRowActions ? 1 : 0) + (onRemove ? 1 : 0)}\n className='h-24 text-center'\n >\n {emptyMessage}\n </TableCell>\n </TableRow>\n ) : (\n data.map((item, index) => {\n const rowKey = getRowKey(item, index);\n return (\n <React.Fragment key={rowKey}>\n <TableRow\n className='hover:bg-muted/50'\n onBlur={(e: React.FocusEvent<HTMLTableRowElement>) => {\n if (!onRowBlur) return;\n\n const currentTarget = e.currentTarget;\n const nextTarget = e.relatedTarget;\n\n if (currentTarget.contains(nextTarget as Node | null)) return;\n if (isWithinSearchableSelectPortal(nextTarget)) return;\n\n window.setTimeout(() => {\n if (!currentTarget.isConnected) return;\n\n const active = document.activeElement;\n if (currentTarget.contains(active)) return;\n if (isWithinSearchableSelectPortal(active)) return;\n\n onRowBlur(index);\n }, 0);\n }}\n >\n {columns.map((col) => {\n const cellContent = (col.render ? col.render(item, index) : item[col.key]) as React.ReactNode;\n const isEditable =\n col.isEditable !== undefined ? col.isEditable : !!col.render;\n\n return (\n <TableCell\n key={col.key}\n className={`text-sm border border-border ${isEditable || col.cellClassName ? 'p-0' : 'px-2 py-1'} ${col.align === 'center' ? 'text-center' : col.align === 'right' ? 'text-right' : ''} ${col.cellClassName || ''}`}\n >\n <div className={isEditable ? 'w-full h-full' : ''}>{cellContent}</div>\n </TableCell>\n );\n })}\n {renderRowActions && (\n <TableCell className='px-1 py-1 text-center'>\n {renderRowActions(item, index)}\n </TableCell>\n )}\n {onRemove && (\n <TableCell className='px-1 py-1 text-center'>\n <Button\n type='button'\n variant='destructive'\n size='sm'\n className='h-6 w-6 p-0'\n onClick={() => onRemove(index)}\n >\n <Trash2 className='h-3 w-3' />\n </Button>\n </TableCell>\n )}\n </TableRow>\n {renderExtraRow && (\n <TableRow key={`${rowKey}-extra`} className='bg-muted/50 hover:bg-muted/50'>\n <TableCell\n colSpan={columns.length + (renderRowActions ? 1 : 0) + (onRemove ? 1 : 0)}\n className='px-4 py-2'\n >\n {renderExtraRow(item, index)}\n </TableCell>\n </TableRow>\n )}\n </React.Fragment>\n );\n })\n )}\n </TableBody>\n </Table>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"editable-table.js","names":["input","React","EditableTable","index","tableRef","useRef","onAddRowRef","onAddRow","timersRef","timers","id","isWithinSearchableSelectPortal","node","table","handleKeyDown","activeElement","e","cell","row","tbody","allRows","currentRowIndex","allCells","currentCellIndex","targetCell","nextRow","nextRowCells","prevRow","prevRowCells","isLastRow","isLastCell","scheduleTimeout","timerId","cb","ms","newRows","newLastRow","firstInput","nextInput","columns","data","wrapClass","isWrapped","zoomClasses","zoomClass","zoomLevel","className","Table","TableHeader","TableRow","TableHead","col","renderRowActions","onRemove","TableBody","TableCell","emptyMessage","rowKey","getRowKey","item","onRowBlur","currentTarget","nextTarget","active","cellContent","isEditable","Button","Trash2","renderExtraRow"],"sources":["../../../../src/tools/components/editable-table/editable-table.tsx"],"sourcesContent":["import React, { useRef, useEffect } from 'react';\nimport { Button } from '../ui/button';\nimport { Trash2 } from 'lucide-react';\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../ui/table';\n\nexport interface EditableTableColumn<T> {\n key: string;\n label: string;\n align?: 'left' | 'center' | 'right';\n /** Render function for custom cell content, like inputs */\n render?: (item: T, index: number) => React.ReactNode;\n width?: string;\n cellClassName?: string;\n headerClassName?: string;\n /** Whether the cell contains an input and should remove padding */\n isEditable?: boolean;\n}\n\nexport interface EditableTableProps<T> {\n columns: EditableTableColumn<T>[];\n data: T[];\n emptyMessage?: string;\n onRemove?: (index: number) => void;\n onAddRow?: () => void;\n getRowKey?: (item: T, index: number) => string;\n renderRowActions?: (item: T, index: number) => React.ReactNode;\n renderExtraRow?: (item: T, index: number) => React.ReactNode;\n className?: string;\n isWrapped?: boolean;\n zoomLevel?: number; // 0: 100%, 1: 90%, 2: 80%, 3: 70%, 4: 60%\n onRowBlur?: (index: number) => void;\n}\n\n/**\n * キーボードナビゲーションに対応した、インライン編集可能なテーブルコンポーネント。\n */\nexport function EditableTable<T extends Record<string, any>>({\n columns,\n data,\n emptyMessage = 'データがありません',\n onRemove,\n onAddRow,\n getRowKey = (_, index) => `row-${index}`,\n renderRowActions,\n renderExtraRow,\n className = '',\n isWrapped = false,\n zoomLevel = 0,\n onRowBlur,\n}: EditableTableProps<T>) {\n const tableRef = useRef<HTMLTableElement>(null);\n const onAddRowRef = useRef(onAddRow);\n useEffect(() => {\n onAddRowRef.current = onAddRow;\n });\n const timersRef = useRef<Set<ReturnType<typeof setTimeout>>>(new Set());\n\n useEffect(() => {\n const timers = timersRef.current;\n return () => {\n timers.forEach((id) => clearTimeout(id));\n timers.clear();\n };\n }, []);\n\n const isWithinSearchableSelectPortal = (node: EventTarget | Node | null) => {\n if (!(node instanceof HTMLElement)) return false;\n return Boolean(node.closest('[data-searchable-select-portal=\"true\"]'));\n };\n\n // Handle keyboard navigation\n useEffect(() => {\n const table = tableRef.current;\n if (!table) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n const activeElement = document.activeElement;\n if (!activeElement || !table.contains(activeElement)) return;\n\n // Don't trigger if user is composing text (IME)\n if (e.isComposing) return;\n\n // Check if we're in an input/textarea/select\n const isInput =\n activeElement.tagName === 'INPUT' ||\n activeElement.tagName === 'TEXTAREA' ||\n activeElement.tagName === 'SELECT' ||\n activeElement.getAttribute('role') === 'combobox';\n\n if (!isInput) return;\n\n const input = activeElement as HTMLElement;\n const cell = input.closest('td');\n if (!cell) return;\n\n const row = cell.closest('tr');\n if (!row) return;\n\n const tbody = row.closest('tbody');\n if (!tbody) return;\n\n const allRows = Array.from(tbody.querySelectorAll('tr:not([class*=\"extra\"])'));\n const currentRowIndex = allRows.indexOf(row);\n const allCells = Array.from(row.querySelectorAll('td'));\n const currentCellIndex = allCells.indexOf(cell);\n\n let targetCell: HTMLElement | null = null;\n\n switch (e.key) {\n case 'ArrowRight':\n e.preventDefault();\n if (currentCellIndex < allCells.length - 1) {\n targetCell = allCells[currentCellIndex + 1];\n }\n break;\n case 'ArrowLeft':\n e.preventDefault();\n if (currentCellIndex > 0) {\n targetCell = allCells[currentCellIndex - 1];\n }\n break;\n case 'ArrowDown':\n e.preventDefault();\n if (currentRowIndex < allRows.length - 1) {\n const nextRow = allRows[currentRowIndex + 1];\n const nextRowCells = Array.from(nextRow.querySelectorAll('td'));\n if (nextRowCells[currentCellIndex]) {\n targetCell = nextRowCells[currentCellIndex];\n }\n }\n break;\n case 'ArrowUp':\n e.preventDefault();\n if (currentRowIndex > 0) {\n const prevRow = allRows[currentRowIndex - 1];\n const prevRowCells = Array.from(prevRow.querySelectorAll('td'));\n if (prevRowCells[currentCellIndex]) {\n targetCell = prevRowCells[currentCellIndex];\n }\n }\n break;\n case 'Enter':\n if (activeElement.tagName !== 'TEXTAREA' && !e.shiftKey) {\n e.preventDefault();\n const isLastRow = currentRowIndex === allRows.length - 1;\n const isLastCell = currentCellIndex >= allCells.length - 1;\n const scheduleTimeout = (cb: () => void, ms: number) => {\n const timerId = setTimeout(() => {\n timersRef.current.delete(timerId);\n cb();\n }, ms);\n timersRef.current.add(timerId);\n };\n\n scheduleTimeout(() => {\n if (currentCellIndex < allCells.length - 1) {\n targetCell = allCells[currentCellIndex + 1];\n } else if (currentRowIndex < allRows.length - 1) {\n const nextRow = allRows[currentRowIndex + 1];\n const nextRowCells = Array.from(nextRow.querySelectorAll('td'));\n if (nextRowCells[0]) {\n targetCell = nextRowCells[0];\n }\n } else if (isLastRow && isLastCell && onAddRowRef.current) {\n onAddRowRef.current();\n scheduleTimeout(() => {\n const newRows = Array.from(tbody.querySelectorAll('tr:not([class*=\"extra\"])'));\n const newLastRow = newRows[newRows.length - 1];\n if (newLastRow) {\n const firstInput = newLastRow.querySelector(\n 'input, textarea, select, [role=\"combobox\"]',\n ) as HTMLElement;\n if (firstInput) {\n firstInput.focus();\n if (firstInput instanceof HTMLInputElement && firstInput.type !== 'number') {\n firstInput.select();\n }\n }\n }\n }, 100);\n }\n if (targetCell) {\n const nextInput = targetCell.querySelector(\n 'input, textarea, select, [role=\"combobox\"]',\n ) as HTMLElement;\n if (nextInput) {\n nextInput.focus();\n if (nextInput instanceof HTMLInputElement && nextInput.type !== 'number') {\n nextInput.select();\n }\n }\n }\n }, 50);\n }\n return;\n case 'Tab':\n return;\n }\n\n if (targetCell) {\n const nextInput = targetCell.querySelector(\n 'input, textarea, select, [role=\"combobox\"]',\n ) as HTMLElement;\n if (nextInput) {\n nextInput.focus();\n if (nextInput instanceof HTMLInputElement && nextInput.type !== 'number') {\n nextInput.select();\n }\n }\n }\n };\n\n table.addEventListener('keydown', handleKeyDown);\n return () => table.removeEventListener('keydown', handleKeyDown);\n }, [columns, data]);\n\n const wrapClass = isWrapped\n ? '[&_td]:whitespace-normal [&_td_*]:whitespace-normal [&_th]:whitespace-normal'\n : '[&_td]:whitespace-nowrap [&_th]:whitespace-nowrap';\n\n const zoomClasses = [\n '', // 0: 100%\n '[&_td]:text-[0.85rem] [&_th]:text-[0.85rem] [&_td_*]:text-[0.85rem] [&_button]:h-7 [&_input]:h-7 [&_select]:h-7', // 1: 85%\n '[&_td]:text-[0.75rem] [&_th]:text-[0.75rem] [&_td_*]:text-[0.75rem] [&_button]:h-6 [&_input]:h-6 [&_select]:h-6', // 2: 75%\n '[&_td]:text-[0.65rem] [&_th]:text-[0.65rem] [&_td_*]:text-[0.65rem] [&_button]:h-5 [&_input]:h-5 [&_select]:h-5', // 3: 65%\n '[&_td]:text-[0.55rem] [&_th]:text-[0.55rem] [&_td_*]:text-[0.55rem] [&_button]:h-4 [&_input]:h-4 [&_select]:h-4', // 4: 55%\n ];\n const zoomClass = zoomClasses[Math.min(zoomLevel, zoomClasses.length - 1)] || '';\n\n return (\n <div className={`${className} ${wrapClass} ${zoomClass} overflow-x-auto`}>\n <Table ref={tableRef}>\n <TableHeader>\n <TableRow>\n {columns.map((col) => (\n <TableHead\n key={col.key}\n className={`px-2 py-1 h-auto border border-border align-middle ${col.headerClassName || ''}`}\n style={{\n textAlign: col.align || 'center',\n verticalAlign: 'middle',\n minWidth: col.width,\n }}\n >\n {col.label}\n </TableHead>\n ))}\n {renderRowActions && <TableHead className='px-2 py-1 h-auto'><span className='sr-only'>Actions</span></TableHead>}\n {onRemove && <TableHead className='px-2 py-1 h-auto'><span className='sr-only'>Actions</span></TableHead>}\n </TableRow>\n </TableHeader>\n <TableBody>\n {data.length === 0 ? (\n <TableRow>\n <TableCell\n colSpan={columns.length + (renderRowActions ? 1 : 0) + (onRemove ? 1 : 0)}\n className='h-24 text-center'\n >\n {emptyMessage}\n </TableCell>\n </TableRow>\n ) : (\n data.map((item, index) => {\n const rowKey = getRowKey(item, index);\n return (\n <React.Fragment key={rowKey}>\n <TableRow\n className='hover:bg-muted/50'\n onBlur={(e: React.FocusEvent<HTMLTableRowElement>) => {\n if (!onRowBlur) return;\n\n const currentTarget = e.currentTarget;\n const nextTarget = e.relatedTarget;\n\n if (currentTarget.contains(nextTarget as Node | null)) return;\n if (isWithinSearchableSelectPortal(nextTarget)) return;\n\n window.setTimeout(() => {\n if (!currentTarget.isConnected) return;\n\n const active = document.activeElement;\n if (currentTarget.contains(active)) return;\n if (isWithinSearchableSelectPortal(active)) return;\n\n onRowBlur(index);\n }, 0);\n }}\n >\n {columns.map((col) => {\n const cellContent = (col.render ? col.render(item, index) : item[col.key]) as React.ReactNode;\n const isEditable =\n col.isEditable !== undefined ? col.isEditable : !!col.render;\n\n return (\n <TableCell\n key={col.key}\n className={`text-sm border border-border ${isEditable || col.cellClassName ? 'p-0' : 'px-2 py-1'} ${col.align === 'center' ? 'text-center' : col.align === 'right' ? 'text-right' : ''} ${col.cellClassName || ''}`}\n >\n <div className={isEditable ? 'w-full h-full' : ''}>{cellContent}</div>\n </TableCell>\n );\n })}\n {renderRowActions && (\n <TableCell className='px-1 py-1 text-center'>\n {renderRowActions(item, index)}\n </TableCell>\n )}\n {onRemove && (\n <TableCell className='px-1 py-1 text-center'>\n <Button\n type='button'\n variant='destructive'\n size='sm'\n className='h-6 w-6 p-0'\n aria-label={`Remove row ${index + 1}`}\n onClick={() => onRemove(index)}\n >\n <Trash2 className='h-3 w-3' />\n </Button>\n </TableCell>\n )}\n </TableRow>\n {renderExtraRow && (\n <TableRow key={`${rowKey}-extra`} className='bg-muted/50 hover:bg-muted/50'>\n <TableCell\n colSpan={columns.length + (renderRowActions ? 1 : 0) + (onRemove ? 1 : 0)}\n className='px-4 py-2'\n >\n {renderExtraRow(item, index)}\n </TableCell>\n </TableRow>\n )}\n </React.Fragment>\n );\n })\n )}\n </TableBody>\n </Table>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../ui/lib/utils.cjs"),n=require("../../../ui/components/ui/button-components.cjs"),r=require("../../../ui/components/ui/dialog.cjs"),i=require("../../paraglide/messages/common_actions_ok.cjs"),a=require("../../paraglide/messages/errors_code.cjs"),o=require("../../paraglide/messages/errors_dialogtitle1.cjs"),s=require("../../lib/error/AppError.cjs"),c=require("../../lib/state/error-store.cjs");let l=require("react/jsx-runtime"),u=require("react");u=e.__toESM(u,1);let d=require("lucide-react");var f={info:{icon:d.Info,iconBgClass:`bg-blue-500`,iconClass:`text-white`,titleClass:`text-blue-600 dark:text-blue-400`},warning:{icon:d.AlertTriangle,iconBgClass:`bg-amber-500`,iconClass:`text-white`,titleClass:`text-amber-600 dark:text-amber-400`},error:{icon:d.X,iconBgClass:`bg-red-500`,iconClass:`text-white`,titleClass:`text-red-600 dark:text-red-400`},critical:{icon:d.AlertCircle,iconBgClass:`bg-red-600`,iconClass:`text-white`,titleClass:`text-red-600 dark:text-red-400`}};function p({testId:e,error:u,open:d,onClose:p,primaryActionLabel:m,onPrimaryAction:h,secondaryActionLabel:g,onSecondaryAction:_}){let{removeError:v,getErrorsByMode:y}=c.useErrorStore(),b=y(`dialog`),x=b.length>0?b[0]:null,S=u??x?.error??null,C=d??x!==null,w=()=>{x&&v(x.id),p?.()},T=()=>{h?.(),w()},E=()=>{_?.(),w()};if(!S)return null;let D=S instanceof s.AppError?S.severity:`error`,O=f[D],k=O.icon;return(0,l.jsx)(r.Dialog,{open:C,onOpenChange:e=>!e&&w(),children:(0,l.jsxs)(r.DialogContent,{testId:e,"data-severity":D,className:`sm:max-w-md`,children:[(0,l.jsx)(r.DialogHeader,{children:(0,l.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,l.jsx)(`div`,{className:t.cn(`rounded-full p-1.5`,O.iconBgClass),children:(0,l.jsx)(k,{className:t.cn(`h-4 w-4`,O.iconClass),"aria-hidden":`true`})}),(0,l.jsx)(r.DialogTitle,{className:O.titleClass,children:o.errors_dialogTitle({defaultValue:`エラー`})})]})}),(0,l.jsx)(r.DialogDescription,{className:`text-foreground`,children:S.message}),S instanceof s.AppError&&S.code&&S.code!==`error/unknown`&&(0,l.jsxs)(`p`,{className:`text-xs text-muted-foreground mt-2`,children:[a.errors_code({defaultValue:`コード`}),`: `,S.code]}),(0,l.jsxs)(r.DialogFooter,{className:`gap-2 sm:gap-0`,children:[g&&(0,l.jsx)(n.Button,{testId:e?`${e}-secondary`:void 0,variant:`outline`,onClick:E,children:g}),(0,l.jsx)(n.Button,{testId:e?`${e}-primary`:void 0,onClick:T,children:m??i.common_actions_ok({defaultValue:`OK`})})]})]})})}exports.ErrorDialog=p;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../ui/lib/utils.cjs"),n=require("../../../ui/components/ui/button-components.cjs"),r=require("../../../ui/components/ui/dialog.cjs"),i=require("../../paraglide/messages/common_actions_ok.cjs"),a=require("../../paraglide/messages/errors_code.cjs"),o=require("../../paraglide/messages/errors_dialogtitle1.cjs"),s=require("../../lib/error/AppError.cjs"),c=require("../../lib/state/error-store.cjs");let l=require("react/jsx-runtime"),u=require("react");u=e.__toESM(u,1);let d=require("lucide-react");var f={info:{icon:d.Info,iconBgClass:`bg-blue-500`,iconClass:`text-white`,titleClass:`text-blue-600 dark:text-blue-400`},warning:{icon:d.AlertTriangle,iconBgClass:`bg-amber-500`,iconClass:`text-white`,titleClass:`text-amber-800 dark:text-amber-400`},error:{icon:d.X,iconBgClass:`bg-red-500`,iconClass:`text-white`,titleClass:`text-red-600 dark:text-red-400`},critical:{icon:d.AlertCircle,iconBgClass:`bg-red-600`,iconClass:`text-white`,titleClass:`text-red-600 dark:text-red-400`}};function p({testId:e,error:u,open:d,onClose:p,primaryActionLabel:m,onPrimaryAction:h,secondaryActionLabel:g,onSecondaryAction:_}){let{removeError:v,getErrorsByMode:y}=c.useErrorStore(),b=y(`dialog`),x=b.length>0?b[0]:null,S=u??x?.error??null,C=d??x!==null,w=()=>{x&&v(x.id),p?.()},T=()=>{h?.(),w()},E=()=>{_?.(),w()};if(!S)return null;let D=S instanceof s.AppError?S.severity:`error`,O=f[D],k=O.icon;return(0,l.jsx)(r.Dialog,{open:C,onOpenChange:e=>!e&&w(),children:(0,l.jsxs)(r.DialogContent,{testId:e,"data-severity":D,className:`sm:max-w-md`,children:[(0,l.jsx)(r.DialogHeader,{children:(0,l.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,l.jsx)(`div`,{className:t.cn(`rounded-full p-1.5`,O.iconBgClass),children:(0,l.jsx)(k,{className:t.cn(`h-4 w-4`,O.iconClass),"aria-hidden":`true`})}),(0,l.jsx)(r.DialogTitle,{className:O.titleClass,children:o.errors_dialogTitle({defaultValue:`エラー`})})]})}),(0,l.jsx)(r.DialogDescription,{className:`text-foreground`,children:S.message}),S instanceof s.AppError&&S.code&&S.code!==`error/unknown`&&(0,l.jsxs)(`p`,{className:`text-xs text-muted-foreground mt-2`,children:[a.errors_code({defaultValue:`コード`}),`: `,S.code]}),(0,l.jsxs)(r.DialogFooter,{className:`gap-2 sm:gap-0`,children:[g&&(0,l.jsx)(n.Button,{testId:e?`${e}-secondary`:void 0,variant:`outline`,onClick:E,children:g}),(0,l.jsx)(n.Button,{testId:e?`${e}-primary`:void 0,onClick:T,children:m??i.common_actions_ok({defaultValue:`OK`})})]})]})})}exports.ErrorDialog=p;
2
2
  //# sourceMappingURL=ErrorDialog.cjs.map