@elaraai/east-ui 1.0.68 → 1.0.69

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 (306) hide show
  1. package/README.md +2 -2
  2. package/dist/src/charts/chart/index.d.ts +39 -4
  3. package/dist/src/charts/chart/index.d.ts.map +1 -1
  4. package/dist/src/charts/chart/index.js +3 -3
  5. package/dist/src/charts/chart/index.js.map +1 -1
  6. package/dist/src/charts/spec/index.d.ts +61 -3
  7. package/dist/src/charts/spec/index.d.ts.map +1 -1
  8. package/dist/src/charts/spec/types.d.ts +1 -1
  9. package/dist/src/charts/spec/types.js +1 -1
  10. package/dist/src/collections/blend/index.d.ts +1 -1
  11. package/dist/src/collections/blend/index.d.ts.map +1 -1
  12. package/dist/src/collections/blend/index.js +1 -1
  13. package/dist/src/collections/blend/index.js.map +1 -1
  14. package/dist/src/collections/blend/types.js +1 -1
  15. package/dist/src/collections/blend/types.js.map +1 -1
  16. package/dist/src/collections/board/index.d.ts +4 -4
  17. package/dist/src/collections/board/index.d.ts.map +1 -1
  18. package/dist/src/collections/board/index.js +1 -1
  19. package/dist/src/collections/board/index.js.map +1 -1
  20. package/dist/src/collections/board/types.js +1 -1
  21. package/dist/src/collections/board/types.js.map +1 -1
  22. package/dist/src/collections/calendar/index.d.ts +1 -1
  23. package/dist/src/collections/calendar/index.d.ts.map +1 -1
  24. package/dist/src/collections/deck/index.d.ts +58 -0
  25. package/dist/src/collections/deck/index.d.ts.map +1 -1
  26. package/dist/src/collections/index.d.ts +1 -2
  27. package/dist/src/collections/index.d.ts.map +1 -1
  28. package/dist/src/collections/index.js +1 -2
  29. package/dist/src/collections/index.js.map +1 -1
  30. package/dist/src/collections/library/index.d.ts +29 -0
  31. package/dist/src/collections/library/index.d.ts.map +1 -1
  32. package/dist/src/collections/library/types.d.ts +29 -0
  33. package/dist/src/collections/library/types.d.ts.map +1 -1
  34. package/dist/src/collections/matrix/index.d.ts +1 -1
  35. package/dist/src/collections/matrix/index.d.ts.map +1 -1
  36. package/dist/src/collections/plan/assemble.d.ts +3732 -0
  37. package/dist/src/collections/plan/assemble.d.ts.map +1 -0
  38. package/dist/src/collections/plan/assemble.js +187 -0
  39. package/dist/src/collections/plan/assemble.js.map +1 -0
  40. package/dist/src/collections/plan/builders.d.ts +612 -0
  41. package/dist/src/collections/plan/builders.d.ts.map +1 -0
  42. package/dist/src/collections/plan/builders.js +543 -0
  43. package/dist/src/collections/plan/builders.js.map +1 -0
  44. package/dist/src/collections/plan/data-forms.d.ts +332 -0
  45. package/dist/src/collections/plan/data-forms.d.ts.map +1 -0
  46. package/dist/src/collections/plan/data-forms.js +212 -0
  47. package/dist/src/collections/plan/data-forms.js.map +1 -0
  48. package/dist/src/collections/plan/factories.d.ts +338 -0
  49. package/dist/src/collections/plan/factories.d.ts.map +1 -0
  50. package/dist/src/collections/plan/factories.js +414 -0
  51. package/dist/src/collections/plan/factories.js.map +1 -0
  52. package/dist/src/collections/plan/index.d.ts +271 -0
  53. package/dist/src/collections/plan/index.d.ts.map +1 -0
  54. package/dist/src/collections/plan/index.js +162 -0
  55. package/dist/src/collections/plan/index.js.map +1 -0
  56. package/dist/src/collections/plan/ir.d.ts +3496 -0
  57. package/dist/src/collections/plan/ir.d.ts.map +1 -0
  58. package/dist/src/collections/plan/ir.js +83 -0
  59. package/dist/src/collections/plan/ir.js.map +1 -0
  60. package/dist/src/collections/plan/pick.d.ts +115 -0
  61. package/dist/src/collections/plan/pick.d.ts.map +1 -0
  62. package/dist/src/collections/plan/pick.js +193 -0
  63. package/dist/src/collections/plan/pick.js.map +1 -0
  64. package/dist/src/collections/plan/root.d.ts +210 -0
  65. package/dist/src/collections/plan/root.d.ts.map +1 -0
  66. package/dist/src/collections/plan/root.js +146 -0
  67. package/dist/src/collections/plan/root.js.map +1 -0
  68. package/dist/src/collections/plan/series.d.ts +11890 -0
  69. package/dist/src/collections/plan/series.d.ts.map +1 -0
  70. package/dist/src/collections/plan/series.js +412 -0
  71. package/dist/src/collections/plan/series.js.map +1 -0
  72. package/dist/src/collections/plan/types.d.ts +9291 -0
  73. package/dist/src/collections/plan/types.d.ts.map +1 -0
  74. package/dist/src/collections/plan/types.js +940 -0
  75. package/dist/src/collections/plan/types.js.map +1 -0
  76. package/dist/src/collections/roster/index.d.ts +4 -4
  77. package/dist/src/collections/roster/index.d.ts.map +1 -1
  78. package/dist/src/collections/roster/index.js +1 -1
  79. package/dist/src/collections/roster/index.js.map +1 -1
  80. package/dist/src/collections/roster/types.d.ts +1 -1
  81. package/dist/src/collections/roster/types.d.ts.map +1 -1
  82. package/dist/src/collections/roster/types.js +4 -3
  83. package/dist/src/collections/roster/types.js.map +1 -1
  84. package/dist/src/collections/table/index.d.ts +70 -2
  85. package/dist/src/collections/table/index.d.ts.map +1 -1
  86. package/dist/src/collections/table/index.js +55 -11
  87. package/dist/src/collections/table/index.js.map +1 -1
  88. package/dist/src/collections/table/types.d.ts +1 -1
  89. package/dist/src/collections/table/types.d.ts.map +1 -1
  90. package/dist/src/component.d.ts +3898 -1339
  91. package/dist/src/component.d.ts.map +1 -1
  92. package/dist/src/component.js +83 -146
  93. package/dist/src/component.js.map +1 -1
  94. package/dist/src/container/card/types.d.ts +1 -1
  95. package/dist/src/container/card/types.d.ts.map +1 -1
  96. package/dist/src/contracts/approval.d.ts +117 -0
  97. package/dist/src/contracts/approval.d.ts.map +1 -0
  98. package/dist/src/contracts/approval.js +105 -0
  99. package/dist/src/contracts/approval.js.map +1 -0
  100. package/dist/src/contracts/drag.d.ts +3 -3
  101. package/dist/src/contracts/drag.d.ts.map +1 -1
  102. package/dist/src/contracts/drag.js +23 -10
  103. package/dist/src/contracts/drag.js.map +1 -1
  104. package/dist/src/contracts/index.d.ts +4 -1
  105. package/dist/src/contracts/index.d.ts.map +1 -1
  106. package/dist/src/contracts/index.js +4 -1
  107. package/dist/src/contracts/index.js.map +1 -1
  108. package/dist/src/contracts/pick.d.ts +705 -0
  109. package/dist/src/contracts/pick.d.ts.map +1 -0
  110. package/dist/src/contracts/pick.js +360 -0
  111. package/dist/src/contracts/pick.js.map +1 -0
  112. package/dist/src/contracts/review.d.ts +7 -99
  113. package/dist/src/contracts/review.d.ts.map +1 -1
  114. package/dist/src/contracts/review.js +11 -85
  115. package/dist/src/contracts/review.js.map +1 -1
  116. package/dist/src/contracts/slice-affordances.d.ts +13 -4
  117. package/dist/src/contracts/slice-affordances.d.ts.map +1 -1
  118. package/dist/src/contracts/slice-affordances.js +13 -3
  119. package/dist/src/contracts/slice-affordances.js.map +1 -1
  120. package/dist/src/contracts/source.d.ts +432 -0
  121. package/dist/src/contracts/source.d.ts.map +1 -0
  122. package/dist/src/contracts/source.js +505 -0
  123. package/dist/src/contracts/source.js.map +1 -0
  124. package/dist/src/contracts/states.d.ts +130 -0
  125. package/dist/src/contracts/states.d.ts.map +1 -1
  126. package/dist/src/contracts/states.js +122 -0
  127. package/dist/src/contracts/states.js.map +1 -1
  128. package/dist/src/contracts/time.d.ts +76 -0
  129. package/dist/src/contracts/time.d.ts.map +1 -0
  130. package/dist/src/contracts/time.js +78 -0
  131. package/dist/src/contracts/time.js.map +1 -0
  132. package/dist/src/display/trace/types.d.ts +1 -1
  133. package/dist/src/display/trace/types.d.ts.map +1 -1
  134. package/dist/src/index.d.ts +10 -2
  135. package/dist/src/index.d.ts.map +1 -1
  136. package/dist/src/index.js +22 -2
  137. package/dist/src/index.js.map +1 -1
  138. package/dist/src/internal.d.ts +5 -3
  139. package/dist/src/internal.d.ts.map +1 -1
  140. package/dist/src/internal.js +4 -3
  141. package/dist/src/internal.js.map +1 -1
  142. package/dist/src/layout/dock/index.d.ts +1 -1
  143. package/dist/src/layout/dock/index.js +1 -1
  144. package/dist/src/layout/index.d.ts +0 -1
  145. package/dist/src/layout/index.d.ts.map +1 -1
  146. package/dist/src/layout/index.js +0 -1
  147. package/dist/src/layout/index.js.map +1 -1
  148. package/dist/src/overlays/drawer/types.d.ts +1 -1
  149. package/dist/src/overlays/drawer/types.d.ts.map +1 -1
  150. package/dist/src/pick/index.d.ts +443 -0
  151. package/dist/src/pick/index.d.ts.map +1 -0
  152. package/dist/src/pick/index.js +64 -0
  153. package/dist/src/pick/index.js.map +1 -0
  154. package/dist/src/pick/panel/index.d.ts +64 -0
  155. package/dist/src/pick/panel/index.d.ts.map +1 -0
  156. package/dist/src/pick/panel/index.js +61 -0
  157. package/dist/src/pick/panel/index.js.map +1 -0
  158. package/dist/src/platform/slice/index.d.ts +291 -0
  159. package/dist/src/platform/slice/index.d.ts.map +1 -1
  160. package/dist/src/platform/slice/index.js +16 -0
  161. package/dist/src/platform/slice/index.js.map +1 -1
  162. package/dist/src/runtime/collections/deck.d.ts +29 -0
  163. package/dist/src/runtime/collections/deck.d.ts.map +1 -1
  164. package/dist/src/runtime/collections/index.d.ts +1 -2
  165. package/dist/src/runtime/collections/index.d.ts.map +1 -1
  166. package/dist/src/runtime/collections/index.js +1 -2
  167. package/dist/src/runtime/collections/index.js.map +1 -1
  168. package/dist/src/runtime/collections/library.d.ts +1 -1
  169. package/dist/src/runtime/collections/library.js +1 -1
  170. package/dist/src/runtime/collections/plan.d.ts +98 -0
  171. package/dist/src/runtime/collections/plan.d.ts.map +1 -0
  172. package/dist/src/runtime/collections/plan.js +98 -0
  173. package/dist/src/runtime/collections/plan.js.map +1 -0
  174. package/dist/src/runtime/collections/schematic.d.ts +1 -1
  175. package/dist/src/runtime/collections/schematic.js +1 -1
  176. package/dist/src/runtime/collections/table.d.ts +9 -1
  177. package/dist/src/runtime/collections/table.d.ts.map +1 -1
  178. package/dist/src/runtime/collections/table.js +1 -7
  179. package/dist/src/runtime/collections/table.js.map +1 -1
  180. package/dist/src/runtime/layout/dock.d.ts +2 -2
  181. package/dist/src/runtime/layout/dock.js +2 -2
  182. package/dist/src/runtime/layout/index.d.ts +0 -1
  183. package/dist/src/runtime/layout/index.d.ts.map +1 -1
  184. package/dist/src/runtime/layout/index.js +0 -1
  185. package/dist/src/runtime/layout/index.js.map +1 -1
  186. package/dist/src/shared/plot-gutter.d.ts +6 -23
  187. package/dist/src/shared/plot-gutter.d.ts.map +1 -1
  188. package/dist/src/shared/plot-gutter.js +6 -19
  189. package/dist/src/shared/plot-gutter.js.map +1 -1
  190. package/dist/src/shared/reify.d.ts +47 -4
  191. package/dist/src/shared/reify.d.ts.map +1 -1
  192. package/dist/src/shared/reify.js +62 -4
  193. package/dist/src/shared/reify.js.map +1 -1
  194. package/dist/src/slice/breakdown/index.d.ts +27 -0
  195. package/dist/src/slice/breakdown/index.d.ts.map +1 -1
  196. package/dist/src/slice/breakdown/types.d.ts +27 -0
  197. package/dist/src/slice/breakdown/types.d.ts.map +1 -1
  198. package/dist/src/slice/cohort/index.d.ts +54 -0
  199. package/dist/src/slice/cohort/index.d.ts.map +1 -1
  200. package/dist/src/slice/cohort/types.d.ts +27 -0
  201. package/dist/src/slice/cohort/types.d.ts.map +1 -1
  202. package/dist/src/slice/filter/index.d.ts +27 -0
  203. package/dist/src/slice/filter/index.d.ts.map +1 -1
  204. package/dist/src/slice/filter/types.d.ts +27 -0
  205. package/dist/src/slice/filter/types.d.ts.map +1 -1
  206. package/dist/src/slice/index.d.ts +405 -0
  207. package/dist/src/slice/index.d.ts.map +1 -1
  208. package/dist/src/slice/legend/index.d.ts +27 -0
  209. package/dist/src/slice/legend/index.d.ts.map +1 -1
  210. package/dist/src/slice/legend/types.d.ts +27 -0
  211. package/dist/src/slice/legend/types.d.ts.map +1 -1
  212. package/dist/src/slice/range/index.d.ts +60 -18
  213. package/dist/src/slice/range/index.d.ts.map +1 -1
  214. package/dist/src/slice/range/index.js +9 -1
  215. package/dist/src/slice/range/index.js.map +1 -1
  216. package/dist/src/slice/range/types.d.ts +63 -22
  217. package/dist/src/slice/range/types.d.ts.map +1 -1
  218. package/dist/src/slice/range/types.js +12 -5
  219. package/dist/src/slice/range/types.js.map +1 -1
  220. package/dist/src/slice/search/index.d.ts +27 -0
  221. package/dist/src/slice/search/index.d.ts.map +1 -1
  222. package/dist/src/slice/search/types.d.ts +27 -0
  223. package/dist/src/slice/search/types.d.ts.map +1 -1
  224. package/dist/src/slice/summary/index.d.ts +27 -0
  225. package/dist/src/slice/summary/index.d.ts.map +1 -1
  226. package/dist/src/slice/summary/types.d.ts +27 -0
  227. package/dist/src/slice/summary/types.d.ts.map +1 -1
  228. package/dist/src/style/content.d.ts +4 -6
  229. package/dist/src/style/content.d.ts.map +1 -1
  230. package/dist/src/style/content.js +4 -6
  231. package/dist/src/style/content.js.map +1 -1
  232. package/dist/src/style/scheme.js +1 -1
  233. package/dist/src/style/scheme.js.map +1 -1
  234. package/dist/test/collections/index.d.ts +2 -2
  235. package/dist/test/collections/index.d.ts.map +1 -1
  236. package/dist/test/collections/index.js +2 -2
  237. package/dist/test/collections/index.js.map +1 -1
  238. package/dist/test/collections/paged-source.examples.d.ts +9 -0
  239. package/dist/test/collections/paged-source.examples.d.ts.map +1 -0
  240. package/dist/test/collections/paged-source.examples.js +136 -0
  241. package/dist/test/collections/paged-source.examples.js.map +1 -0
  242. package/dist/test/collections/plan.examples.d.ts +125 -0
  243. package/dist/test/collections/plan.examples.d.ts.map +1 -0
  244. package/dist/test/collections/plan.examples.js +2939 -0
  245. package/dist/test/collections/plan.examples.js.map +1 -0
  246. package/dist/test/contracts/pick.examples.d.ts +6 -0
  247. package/dist/test/contracts/pick.examples.d.ts.map +1 -0
  248. package/dist/test/contracts/pick.examples.js +89 -0
  249. package/dist/test/contracts/pick.examples.js.map +1 -0
  250. package/dist/test/layout/dock.examples.d.ts +4 -4
  251. package/dist/test/layout/dock.examples.d.ts.map +1 -1
  252. package/dist/test/layout/dock.examples.js +34 -16
  253. package/dist/test/layout/dock.examples.js.map +1 -1
  254. package/dist/test/slice/slice.examples.d.ts +2 -1
  255. package/dist/test/slice/slice.examples.d.ts.map +1 -1
  256. package/dist/test/slice/slice.examples.js +67 -9
  257. package/dist/test/slice/slice.examples.js.map +1 -1
  258. package/package.json +3 -3
  259. package/dist/src/collections/gantt/index.d.ts +0 -377
  260. package/dist/src/collections/gantt/index.d.ts.map +0 -1
  261. package/dist/src/collections/gantt/index.js +0 -896
  262. package/dist/src/collections/gantt/index.js.map +0 -1
  263. package/dist/src/collections/gantt/types.d.ts +0 -353
  264. package/dist/src/collections/gantt/types.d.ts.map +0 -1
  265. package/dist/src/collections/gantt/types.js +0 -207
  266. package/dist/src/collections/gantt/types.js.map +0 -1
  267. package/dist/src/collections/planner/index.d.ts +0 -624
  268. package/dist/src/collections/planner/index.d.ts.map +0 -1
  269. package/dist/src/collections/planner/index.js +0 -941
  270. package/dist/src/collections/planner/index.js.map +0 -1
  271. package/dist/src/collections/planner/types.d.ts +0 -615
  272. package/dist/src/collections/planner/types.d.ts.map +0 -1
  273. package/dist/src/collections/planner/types.js +0 -423
  274. package/dist/src/collections/planner/types.js.map +0 -1
  275. package/dist/src/layout/aligned-stack/index.d.ts +0 -101
  276. package/dist/src/layout/aligned-stack/index.d.ts.map +0 -1
  277. package/dist/src/layout/aligned-stack/index.js +0 -105
  278. package/dist/src/layout/aligned-stack/index.js.map +0 -1
  279. package/dist/src/layout/aligned-stack/types.d.ts +0 -50
  280. package/dist/src/layout/aligned-stack/types.d.ts.map +0 -1
  281. package/dist/src/layout/aligned-stack/types.js +0 -24
  282. package/dist/src/layout/aligned-stack/types.js.map +0 -1
  283. package/dist/src/runtime/collections/gantt.d.ts +0 -67
  284. package/dist/src/runtime/collections/gantt.d.ts.map +0 -1
  285. package/dist/src/runtime/collections/gantt.js +0 -58
  286. package/dist/src/runtime/collections/gantt.js.map +0 -1
  287. package/dist/src/runtime/collections/planner.d.ts +0 -80
  288. package/dist/src/runtime/collections/planner.d.ts.map +0 -1
  289. package/dist/src/runtime/collections/planner.js +0 -76
  290. package/dist/src/runtime/collections/planner.js.map +0 -1
  291. package/dist/src/runtime/layout/aligned-stack.d.ts +0 -38
  292. package/dist/src/runtime/layout/aligned-stack.d.ts.map +0 -1
  293. package/dist/src/runtime/layout/aligned-stack.js +0 -36
  294. package/dist/src/runtime/layout/aligned-stack.js.map +0 -1
  295. package/dist/test/collections/gantt.examples.d.ts +0 -33
  296. package/dist/test/collections/gantt.examples.d.ts.map +0 -1
  297. package/dist/test/collections/gantt.examples.js +0 -359
  298. package/dist/test/collections/gantt.examples.js.map +0 -1
  299. package/dist/test/collections/planner.examples.d.ts +0 -47
  300. package/dist/test/collections/planner.examples.d.ts.map +0 -1
  301. package/dist/test/collections/planner.examples.js +0 -546
  302. package/dist/test/collections/planner.examples.js.map +0 -1
  303. package/dist/test/layout/aligned-stack.examples.d.ts +0 -25
  304. package/dist/test/layout/aligned-stack.examples.d.ts.map +0 -1
  305. package/dist/test/layout/aligned-stack.examples.js +0 -294
  306. package/dist/test/layout/aligned-stack.examples.js.map +0 -1
@@ -1,941 +0,0 @@
1
- /**
2
- * Copyright (c) 2025 Elara AI Pty Ltd
3
- * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
- */
5
- /**
6
- * `Planner` — the discrete `rows × ordered slots` scheduling primitive. Rows are
7
- * typed resources; slots are positions on a typed axis ({@link PlannerSlotType});
8
- * each cell holds zero or more events in one of three audit states
9
- * ({@link PlannerStateType}). The interface follows the `Chart.Spec` style: a
10
- * builder namespace (`Planner.axis.*` / `Planner.at.*` / `Planner.event`) with a
11
- * `.Types.*` mirror, and flat-object factories that normalise `some` / `none` /
12
- * `variant`.
13
- *
14
- * @packageDocumentation
15
- */
16
- import { East, ArrayType, StructType, DictType, OptionType, FunctionType, StringType, FloatType, DateTimeType, BooleanType, NullType, variant, some, none, } from "@elaraai/east";
17
- import { UIComponentType } from "../../component.js";
18
- import { mapRowsBlock } from "../../shared/reify.js";
19
- import { DensityType } from "../../style/interaction.js";
20
- import { PlotGutterType } from "../../shared/plot-gutter.js";
21
- import { reviewType, buildReview } from "../../contracts/review.js";
22
- import { CanDropFnType, DragEventType } from "../../contracts/drag.js";
23
- import { PlannerSlotType, PlannerScaleType, PlannerResolutionType, PlannerBucketType, PlannerRangeType, PlannerAxisType, PlannerFlavourType, PlannerStateType, PlannerMarkerType, PlannerStretchType, PlannerContentAlignType, PlannerContentType, PlannerAnimationType, PlannerAlignType, PlannerColumnType, PlannerCellType, PlannerVariantType, PlannerSelectEventType, PlannerApprovalType, PlannerApproveEventType, } from "./types.js";
24
- import { StatusValueType } from "../../feedback/status/types.js";
25
- import { ColorSchemeType } from "../../style/scheme.js";
26
- // Re-export the UIComp-free types so consumers reach everything via this barrel.
27
- export { PlannerSlotType, PlannerScaleType, PlannerResolutionType, PlannerBucketType, PlannerRangeType, PlannerAxisType, PlannerFlavourType, PlannerStateType, PlannerMarkerType, PlannerStretchType, PlannerContentAlignType, PlannerContentType, PlannerAnimationType, PlannerAlignType, PlannerColumnType, PlannerCellType, PlannerVariantType, PlannerSelectEventType, PlannerApprovalType, PlannerApproveEventType, } from "./types.js";
28
- // ============================================================================
29
- // UIComp-coupled types — event, row, root
30
- // ============================================================================
31
- /**
32
- * A single placed event. `slot` is the (start) coordinate; `endSlot` is set on
33
- * Span events; `bucket` references a declared bucket key (none = unbucketed).
34
- * `popover` is the click-triggered rich body (popover-only — there is no
35
- * tooltip). Conflict markers are declared separately, on the row's `conflicts`.
36
- *
37
- * @property slot - The event's (start) slot coordinate
38
- * @property endSlot - The span end (Span variant; none for Point)
39
- * @property bucket - The declared bucket key the event sits in (none = unbucketed)
40
- * @property label - The event's text
41
- * @property state - The audit state (see {@link PlannerStateType})
42
- * @property key - Optional stable event identity (drag-grammar cell refs)
43
- * @property popover - Optional click-triggered rich body (UIComponent)
44
- * @property stretch - Optional fill axis (horizontal / vertical / both); absent ⇒ content-sized
45
- * @property content - Optional content alignment inside the tile (defaults to top-left)
46
- * @property tone - Optional semantic colour override (tints fill/text/border; none ⇒ the state grammar)
47
- * @property animation - Optional attention animation (pulse / none)
48
- * @property hovercard - Optional open-on-hover rich body (UIComponent); coexists with `popover`
49
- */
50
- export const PlannerEventType = StructType({
51
- key: OptionType(StringType),
52
- slot: PlannerSlotType,
53
- endSlot: OptionType(PlannerSlotType),
54
- bucket: OptionType(StringType),
55
- label: StringType,
56
- state: PlannerStateType,
57
- popover: OptionType(UIComponentType),
58
- stretch: OptionType(PlannerStretchType),
59
- content: OptionType(PlannerContentType),
60
- tone: OptionType(StatusValueType),
61
- color: OptionType(StringType),
62
- colorPalette: OptionType(ColorSchemeType),
63
- animation: OptionType(PlannerAnimationType),
64
- hovercard: OptionType(UIComponentType),
65
- });
66
- /**
67
- * One Planner row — a typed resource. `cells` are the left-column values keyed
68
- * by column key; `events` is the row's slot timeline; `markers` are the row's
69
- * status markers (declared parallel to events, not on them); `group` is the
70
- * optional group-head label. Rows are identified by index.
71
- *
72
- * @property group - Optional group-head label (`groupBy`)
73
- * @property cells - The left-column cell values keyed by column key
74
- * @property events - The row's events ({@link PlannerEventType})
75
- * @property markers - The row's status markers ({@link PlannerMarkerType})
76
- */
77
- export const PlannerRowType = StructType({
78
- group: OptionType(StringType),
79
- cells: DictType(StringType, PlannerCellType),
80
- events: ArrayType(PlannerEventType),
81
- markers: ArrayType(PlannerMarkerType),
82
- // Review chrome (only meaningful when the root carries `review`):
83
- status: OptionType(StatusValueType), // the quiet row dot beside the resource (absent ⇒ clean)
84
- approval: OptionType(PlannerApprovalType), // the row's review decision (absent ⇒ no decision)
85
- });
86
- /**
87
- * The Planner review config — the per-row Approve / Reject calls plus the batch
88
- * foot. Present on the root only when the optional review chrome is enabled.
89
- *
90
- * @remarks
91
- * The shared review contract instantiated at the Planner's row subject —
92
- * `reviewType(PlannerApproveEventType, UIComponentType)` (`contracts/review.ts`).
93
- * Structurally identical to the pre-contract Planner-local definition, so
94
- * existing IR round-trips unchanged.
95
- *
96
- * @property columnLabel - The decision-column header (default `"Decision"`)
97
- * @property summary - Optional foot eyebrow (host-composed, e.g. `Planner.reviewSummary(...)`)
98
- * @property onApprove - Optional per-row Approve callback (receives `{ rowIndex }`)
99
- * @property onReject - Optional per-row Reject callback (receives `{ rowIndex }`)
100
- * @property onApproveAll - Optional batch Approve-all callback
101
- * @property onRejectAll - Optional batch Reject-all callback
102
- * @property onRerun - Optional Rerun callback (absent ⇒ no Rerun button)
103
- * @property rerunLabel - The Rerun button label (default `"Rerun"`)
104
- */
105
- export const PlannerReviewType = reviewType(PlannerApproveEventType, UIComponentType);
106
- /**
107
- * The Planner root IR — shared by Point and Span (the `variant` arm
108
- * discriminates). Content (`rows` / `columns`), the axis, and behaviour
109
- * (`onSelectRow`) sit on the root.
110
- *
111
- * @property variant - Which chassis configuration (point / span)
112
- * @property axis - The axis declaration (scale / buckets / range / format)
113
- * @property columns - The left-side columns
114
- * @property rows - The rows
115
- * @property now - Optional explicit committed/proposed divider; else derived from the data
116
- * @property density - Optional density (row / header rhythm)
117
- * @property slotMinWidth - Optional min-width (CSS) per x-axis slot column; the timeline scrolls when slots can't fit
118
- * @property maxHeight - Optional max-height (CSS) for the plan area; the body scrolls vertically within it with the header pinned. Absent ⇒ content-sized
119
- * @property onSelectRow - Optional row-selection callback
120
- * @property rowHover - Optional opt-in row-highlight outline on hover (absent/false ⇒ no hover affordance)
121
- */
122
- export const PlannerRootType = StructType({
123
- variant: PlannerVariantType,
124
- axis: PlannerAxisType,
125
- columns: ArrayType(PlannerColumnType),
126
- rows: ArrayType(PlannerRowType),
127
- now: OptionType(PlannerSlotType),
128
- density: OptionType(DensityType),
129
- slotMinWidth: OptionType(StringType),
130
- // Optional max-height (CSS) for the plan area — when set, the body scrolls
131
- // vertically within it and the header row stays pinned (sticky-top). Absent
132
- // ⇒ content-sized (grows with the rows, no vertical scroll).
133
- maxHeight: OptionType(StringType),
134
- // Definite height (#320) — pins the plan to exactly this box (`"fill"` fills the parent), header pinned, body scrolls within.
135
- height: OptionType(StringType),
136
- plotGutter: OptionType(PlotGutterType),
137
- onSelectRow: OptionType(FunctionType([PlannerSelectEventType], NullType)),
138
- // Optional review chrome — the per-row Approve/Reject decision column + the
139
- // approve-all/reject-all foot. Absent ⇒ a plain Planner (the decision column
140
- // and foot do not render and the row `status`/`approval` are inert).
141
- review: OptionType(PlannerReviewType),
142
- // Opt-in hover affordance — draws a light brand outline around the whole row
143
- // (over both panes) on hover. Absent/false ⇒ no hover highlight.
144
- rowHover: OptionType(BooleanType),
145
- // Opt-in DnD target role (#269) — the standard trio, matching Roster
146
- // field-for-field. A Planner with no `onDrag` is exactly today's Planner:
147
- // the renderer registers the target iff `onDrag` is present
148
- // (presence-gating; Planner has no edit-mode enum). Drops land as
149
- // `proposed(added)` tiles; committed history never drags. Cell encoding
150
- // (contracts/drag.ts): `row` = the row index key, `slot` = the axis key
151
- // with the bucket composed in (`"wed"` / `"wed:am"`; number axes print
152
- // decimally, time axes the column instant's ISO form).
153
- id: StringType,
154
- sources: ArrayType(StringType),
155
- onDrag: OptionType(FunctionType([DragEventType], NullType)),
156
- canDrop: OptionType(CanDropFnType),
157
- });
158
- // ============================================================================
159
- // Axis builders
160
- // ============================================================================
161
- function axisFields(scale, buckets, range, format, resolution) {
162
- return East.value({
163
- scale: variant(scale, null),
164
- buckets: (buckets ?? []).map(b => East.value({ key: b.key, label: b.label }, PlannerBucketType)),
165
- range: range !== undefined ? some(range) : none,
166
- format: format !== undefined ? some(format) : none,
167
- resolution: resolution !== undefined ? some(resolution) : none,
168
- }, PlannerAxisType);
169
- }
170
- /**
171
- * Builds a datetime axis (calendar slots).
172
- *
173
- * @param options - Buckets, format, resolution, and an optional datetime range
174
- * @returns An East expression of {@link PlannerAxisType}
175
- *
176
- * @remarks
177
- * Pass `options.range` to pin the visible extent to a half-open calendar
178
- * window `[min, max)`; omit it to derive a closed extent from the data.
179
- * `options.resolution` sets the calendar unit of each slot column (`"hour"` /
180
- * `"day"` / `"week"` / `"month"` / `"quarter"` / `"year"`); omitted or
181
- * `"auto"`, a pinned range spanning ≤ 14 days derives day columns and
182
- * anything else month columns. `options.buckets` subdivides each slot column
183
- * into named bands (e.g. AM / PM). `options.format` controls the column-label
184
- * date pattern (Chart tick-format tokens, e.g. `"ddd DD"` → `Mon 30`);
185
- * omitted, a resolution-appropriate default applies.
186
- * Pair every event and `now` coordinate with {@link slotTime}.
187
- */
188
- function axisTime(options) {
189
- const range = options?.range !== undefined
190
- ? East.value(variant("time", { min: options.range.min, max: options.range.max }), PlannerRangeType)
191
- : undefined;
192
- const resolution = options?.resolution !== undefined
193
- ? (typeof options.resolution === "string"
194
- ? East.value(variant(options.resolution, null), PlannerResolutionType)
195
- : options.resolution)
196
- : undefined;
197
- return axisFields("time", options?.buckets, range, options?.format, resolution);
198
- }
199
- /**
200
- * Builds a numeric axis (day-of-X, hour-of-Y).
201
- *
202
- * @param options - Buckets, format, and an optional numeric range
203
- * @returns An East expression of {@link PlannerAxisType}
204
- *
205
- * @remarks
206
- * Pass `options.range` (`{ min, max }`) to fix the slot extent; omit it to
207
- * derive the domain from the event coordinates. `options.buckets` subdivides
208
- * each slot column into named bands (e.g. AM / PM). `options.format` controls
209
- * the tick-label format pattern forwarded to the renderer.
210
- * Pair every event and `now` coordinate with {@link slotNumber}.
211
- */
212
- function axisNumber(options) {
213
- const range = options?.range !== undefined
214
- ? East.value(variant("number", { min: options.range.min, max: options.range.max }), PlannerRangeType)
215
- : undefined;
216
- return axisFields("number", options?.buckets, range, options?.format);
217
- }
218
- /**
219
- * Builds an ordinal axis (phase / stage / week-number).
220
- *
221
- * @param options - Buckets, format, and an optional ordered category range
222
- * @returns An East expression of {@link PlannerAxisType}
223
- *
224
- * @remarks
225
- * Pass `options.range` as a `string[]` to fix the column order and set of
226
- * visible categories; omit it to derive the domain from the event coordinates.
227
- * `options.buckets` subdivides each slot column into named bands.
228
- * `options.format` controls the tick-label format pattern forwarded to the
229
- * renderer. Pair every event and `now` coordinate with {@link slotOrdinal}.
230
- */
231
- function axisOrdinal(options) {
232
- const range = options?.range !== undefined
233
- ? East.value(variant("ordinal", options.range), PlannerRangeType)
234
- : undefined;
235
- return axisFields("ordinal", options?.buckets, range, options?.format);
236
- }
237
- // ============================================================================
238
- // Slot-coordinate shorthands
239
- // ============================================================================
240
- /**
241
- * Builds a datetime slot coordinate.
242
- *
243
- * @param d - A `Date` or East `DateTimeType` expression identifying the slot
244
- * @returns An East expression of {@link PlannerSlotType} with the `time` arm
245
- *
246
- * @remarks
247
- * Use wherever a datetime position is required — the `slot` / `endSlot` fields
248
- * of an event, the `now` divider on the config, and the `now` option on
249
- * {@link axisTime}. Must be paired with a `time`-scale axis ({@link axisTime}).
250
- */
251
- function slotTime(d) {
252
- return East.value(variant("time", d), PlannerSlotType);
253
- }
254
- /**
255
- * Builds a numeric slot coordinate.
256
- *
257
- * @param n - A number or East `FloatType` expression identifying the slot
258
- * @returns An East expression of {@link PlannerSlotType} with the `number` arm
259
- *
260
- * @remarks
261
- * Use wherever a numeric position is required — the `slot` / `endSlot` fields
262
- * of an event, the `now` divider on the config, and the `now` option on
263
- * {@link axisNumber}. Must be paired with a `number`-scale axis ({@link axisNumber}).
264
- */
265
- function slotNumber(n) {
266
- return East.value(variant("number", n), PlannerSlotType);
267
- }
268
- /**
269
- * Builds an ordinal slot coordinate.
270
- *
271
- * @param s - A string or East `StringType` expression naming the category
272
- * @returns An East expression of {@link PlannerSlotType} with the `ordinal` arm
273
- *
274
- * @remarks
275
- * Use wherever a category label is required — the `slot` / `endSlot` fields of
276
- * an event, the `now` divider on the config, and the `now` option on
277
- * {@link axisOrdinal}. The string must match one of the category labels
278
- * declared in `options.range` (or present in the data when range is omitted).
279
- * Must be paired with an `ordinal`-scale axis ({@link axisOrdinal}).
280
- */
281
- function slotOrdinal(s) {
282
- return East.value(variant("ordinal", s), PlannerSlotType);
283
- }
284
- /**
285
- * Resolves the shared event-lifecycle string shorthands (`"committed"` /
286
- * `"rejected"` / `"added"` / `"model"` / `"removed"`) into a
287
- * {@link PlannerStateType} value. Exported for the other lifecycle adopters
288
- * (Gantt) so the authoring shorthand is defined once.
289
- *
290
- * @param state - A `PlannerStateType` value/expression or a string shorthand
291
- * @returns The resolved `PlannerStateType` value
292
- */
293
- export function resolveEventState(state) {
294
- if (typeof state !== "string")
295
- return state;
296
- switch (state) {
297
- case "committed": return East.value(variant("committed", null), PlannerStateType);
298
- case "rejected": return East.value(variant("rejected", null), PlannerStateType);
299
- case "added": return East.value(variant("proposed", variant("added", null)), PlannerStateType);
300
- case "model": return East.value(variant("proposed", variant("model", null)), PlannerStateType);
301
- case "removed": return East.value(variant("proposed", variant("removed", null)), PlannerStateType);
302
- }
303
- }
304
- /** Resolve the `stretch` string shorthand into a {@link PlannerStretchType} value. */
305
- function resolveStretch(s) {
306
- return typeof s === "string" ? East.value(variant(s, null), PlannerStretchType) : s;
307
- }
308
- /** Resolve a content-alignment string shorthand into a {@link PlannerContentAlignType} value. */
309
- function resolveContentAlign(a) {
310
- return typeof a === "string" ? East.value(variant(a, null), PlannerContentAlignType) : a;
311
- }
312
- /** Resolve the `content` two-axis input into a {@link PlannerContentType} value. */
313
- function resolveContent(c) {
314
- return East.value({
315
- horizontal: c.horizontal !== undefined ? some(resolveContentAlign(c.horizontal)) : none,
316
- vertical: c.vertical !== undefined ? some(resolveContentAlign(c.vertical)) : none,
317
- }, PlannerContentType);
318
- }
319
- /** Resolve the `animation` string shorthand into a {@link PlannerAnimationType} value. */
320
- function resolveAnimation(a) {
321
- return typeof a === "string" ? East.value(variant(a, null), PlannerAnimationType) : a;
322
- }
323
- /** Resolve the `tone` status string shorthand into a {@link StatusValueType} value. */
324
- function resolveTone(t) {
325
- return typeof t === "string" ? East.value(variant(t, null), StatusValueType) : t;
326
- }
327
- /** Resolve the `colorPalette` string shorthand into a {@link ColorSchemeType} value. */
328
- function resolveColorPalette(c) {
329
- return typeof c === "string" ? East.value(variant(c, null), ColorSchemeType) : c;
330
- }
331
- /**
332
- * Builds a single Planner event from a flat TS input. Normalises optional fields
333
- * into their `OptionType` envelopes and resolves the `state` string shorthands
334
- * (`"committed"` / `"rejected"` / `"added"` / `"model"` / `"removed"`) as well as
335
- * the `stretch` / `content` / `tone` / `animation` shorthands.
336
- *
337
- * @param input - The event configuration ({@link EventInput})
338
- * @returns An East expression of {@link PlannerEventType}
339
- */
340
- function createEvent(input) {
341
- return East.value({
342
- key: input.key !== undefined ? some(input.key) : none,
343
- slot: input.slot,
344
- endSlot: input.endSlot !== undefined ? some(input.endSlot) : none,
345
- bucket: input.bucket !== undefined ? some(input.bucket) : none,
346
- label: input.label,
347
- state: resolveEventState(input.state),
348
- popover: input.popover !== undefined ? some(input.popover) : none,
349
- stretch: input.stretch !== undefined ? some(resolveStretch(input.stretch)) : none,
350
- content: input.content !== undefined ? some(resolveContent(input.content)) : none,
351
- tone: input.tone !== undefined ? some(resolveTone(input.tone)) : none,
352
- color: input.color !== undefined ? some(input.color) : none,
353
- colorPalette: input.colorPalette !== undefined ? some(resolveColorPalette(input.colorPalette)) : none,
354
- animation: input.animation !== undefined ? some(resolveAnimation(input.animation)) : none,
355
- hovercard: input.hovercard !== undefined ? some(input.hovercard) : none,
356
- }, PlannerEventType);
357
- }
358
- /**
359
- * Builds a single status marker from a flat input — declared parallel to events
360
- * (in a row's `markers`), not on an event. The renderer rings the cell at `slot`,
361
- * paints the paired status icon in the corner, and shows `message` on hover.
362
- *
363
- * @param input - The marker configuration ({@link MarkerInput})
364
- * @returns An East expression of {@link PlannerMarkerType}
365
- */
366
- function createMarker(input) {
367
- return East.value({
368
- slot: input.slot,
369
- status: variant(input.status ?? "danger", null),
370
- message: input.message,
371
- }, PlannerMarkerType);
372
- }
373
- function columnMeta(col) {
374
- return East.value({
375
- key: col.key,
376
- header: col.header ?? col.key,
377
- width: col.width !== undefined ? some(col.width) : none,
378
- frozen: col.frozen !== undefined ? some(col.frozen) : none,
379
- align: col.align !== undefined ? some(variant(col.align, null)) : none,
380
- }, PlannerColumnType);
381
- }
382
- function cellValue(col, row) {
383
- return East.value({
384
- value: col.value(row),
385
- sublabel: col.sublabel !== undefined ? some(col.sublabel(row)) : none,
386
- }, PlannerCellType);
387
- }
388
- function buildRoot(kind, data, config) {
389
- const data_expr = East.value(data);
390
- const columns = config.columns.map(columnMeta);
391
- const rows = mapRowsBlock(data_expr, PlannerRowType, ($, row) => {
392
- const cells = $.let(new Map(), DictType(StringType, PlannerCellType));
393
- for (const col of config.columns) {
394
- $(cells.insert(col.key, cellValue(col, row)));
395
- }
396
- return East.value({
397
- group: config.groupBy !== undefined ? some(config.groupBy(row)) : none,
398
- cells,
399
- events: East.value(config.events(row), ArrayType(PlannerEventType)),
400
- markers: config.markers !== undefined
401
- ? East.value(config.markers(row), ArrayType(PlannerMarkerType))
402
- : East.value([], ArrayType(PlannerMarkerType)),
403
- // Review chrome — pass-through options (the author computes the dot /
404
- // decision in East; clean ⇒ `some(approved)`, flagged ⇒ `some(pending)`).
405
- status: config.status !== undefined
406
- ? East.value(config.status(row), OptionType(StatusValueType))
407
- : none,
408
- approval: config.approval !== undefined
409
- ? East.value(config.approval(row), OptionType(PlannerApprovalType))
410
- : none,
411
- }, PlannerRowType);
412
- });
413
- const density = config.density !== undefined
414
- ? some(typeof config.density === "string" ? East.value(variant(config.density, null), DensityType) : config.density)
415
- : none;
416
- return East.value(variant("Planner", {
417
- variant: variant(kind, null),
418
- axis: config.axis,
419
- columns: East.value(columns, ArrayType(PlannerColumnType)),
420
- rows,
421
- now: config.now !== undefined ? some(config.now) : none,
422
- density,
423
- slotMinWidth: config.slotMinWidth !== undefined ? some(config.slotMinWidth) : none,
424
- maxHeight: config.maxHeight !== undefined ? some(config.maxHeight) : none,
425
- height: config.height !== undefined ? some(config.height) : none,
426
- plotGutter: config.plotGutter !== undefined
427
- ? some(East.value({
428
- left: config.plotGutter.left !== undefined ? some(config.plotGutter.left) : none,
429
- right: config.plotGutter.right !== undefined ? some(config.plotGutter.right) : none,
430
- }, PlotGutterType))
431
- : none,
432
- onSelectRow: config.onSelectRow !== undefined ? some(config.onSelectRow) : none,
433
- review: config.review !== undefined ? some(buildReview(config.review, PlannerReviewType)) : none,
434
- rowHover: config.rowHover !== undefined ? some(config.rowHover) : none,
435
- id: config.id ?? "",
436
- sources: East.value(config.sources ?? [], ArrayType(StringType)),
437
- onDrag: config.onDrag !== undefined ? some(config.onDrag) : none,
438
- canDrop: config.canDrop !== undefined ? some(config.canDrop) : none,
439
- }), UIComponentType);
440
- }
441
- /**
442
- * Creates a Point Planner — slot-bound events (each event sits in one
443
- * slot/bucket). The Roster default.
444
- *
445
- * @typeParam R - The struct type of each data row
446
- * @param data - The rows
447
- * @param config - The Planner configuration ({@link PlannerConfig})
448
- * @returns An East expression of `UIComponentType`
449
- *
450
- * @example
451
- * ```ts
452
- * import { East } from "@elaraai/east";
453
- * import { Planner, UIComponentType } from "@elaraai/east-ui";
454
- *
455
- * const example = East.function([], UIComponentType, _$ =>
456
- * Planner.Point(
457
- * [{ id: "a", name: "Alice", events: [] }],
458
- * {
459
- * axis: Planner.axis.number({ buckets: [{ key: "am", label: "AM" }, { key: "pm", label: "PM" }] }),
460
- * columns: [{ key: "name", frozen: true, value: r => r.name }],
461
- * events: r => r.events,
462
- * },
463
- * ),
464
- * );
465
- * ```
466
- */
467
- function createPoint(data, config) {
468
- return buildRoot("point", data, config);
469
- }
470
- /**
471
- * Creates a Span Planner — multi-slot span events (start → end).
472
- *
473
- * @typeParam R - The struct type of each data row
474
- * @param data - The rows
475
- * @param config - The Planner configuration ({@link PlannerConfig})
476
- * @returns An East expression of `UIComponentType`
477
- */
478
- function createSpan(data, config) {
479
- return buildRoot("span", data, config);
480
- }
481
- /**
482
- * The `Planner` namespace — the discrete `rows × ordered slots` scheduling
483
- * primitive. Assemble a Planner with `Planner.Point` / `Planner.Span`, declare
484
- * the axis with `Planner.axis.*`, place events with `Planner.event` /
485
- * `Planner.at.*`, and reach every East type via `Planner.Types.*`.
486
- */
487
- export const Planner = {
488
- /**
489
- * Creates a Point Planner — slot-bound events (each event sits in one
490
- * slot/bucket). The Roster default.
491
- *
492
- * @typeParam R - The struct type of each data row
493
- * @param data - The rows
494
- * @param config - The Planner configuration ({@link PlannerConfig})
495
- * @returns An East expression of `UIComponentType`
496
- *
497
- * @example
498
- * ```ts
499
- * import { East } from "@elaraai/east";
500
- * import { Planner, UIComponentType } from "@elaraai/east-ui";
501
- *
502
- * const example = East.function([], UIComponentType, _$ =>
503
- * Planner.Point(
504
- * [{ id: "a", name: "Alice", events: [] }],
505
- * {
506
- * axis: Planner.axis.number({ buckets: [{ key: "am", label: "AM" }, { key: "pm", label: "PM" }] }),
507
- * columns: [{ key: "name", frozen: true, value: r => r.name }],
508
- * events: r => r.events,
509
- * },
510
- * ),
511
- * );
512
- * ```
513
- */
514
- Point: createPoint,
515
- /**
516
- * Creates a Span Planner — multi-slot span events (start → end).
517
- *
518
- * @typeParam R - The struct type of each data row
519
- * @param data - The rows
520
- * @param config - The Planner configuration ({@link PlannerConfig})
521
- * @returns An East expression of `UIComponentType`
522
- *
523
- * @example
524
- * ```ts
525
- * import { East } from "@elaraai/east";
526
- * import { Planner, UIComponentType } from "@elaraai/east-ui";
527
- *
528
- * const example = East.function([], UIComponentType, _$ =>
529
- * Planner.Span(
530
- * [{ id: "a", name: "Alice", events: [] }],
531
- * {
532
- * axis: Planner.axis.time(),
533
- * columns: [{ key: "name", frozen: true, value: r => r.name }],
534
- * events: r => r.events,
535
- * },
536
- * ),
537
- * );
538
- * ```
539
- */
540
- Span: createSpan,
541
- /**
542
- * Typed axis builders. Each builder declares the axis scale and returns an
543
- * East expression of {@link PlannerAxisType}.
544
- *
545
- * @remarks
546
- * Choose the builder that matches your slot coordinates — mixing arms within
547
- * one Planner is unsupported. All three accept an optional bucket list and
548
- * format string; the range option is typed per-scale:
549
- * - `time` — datetime axis, `range: { min: Date, max: Date }` (a half-open
550
- * window `[min, max)`), plus an optional column `resolution` (`"hour"` /
551
- * `"day"` / `"week"` / `"month"` / `"quarter"` / `"year"`; omitted, a
552
- * pinned range ≤ 14 days infers day columns, else month).
553
- * - `number` — numeric axis, `range: { min: number, max: number }`.
554
- * - `ordinal` — ordered-category axis, `range: string[]`.
555
- */
556
- axis: { time: axisTime, number: axisNumber, ordinal: axisOrdinal },
557
- /**
558
- * Slot-coordinate shorthands. Each builder wraps a raw coordinate in the
559
- * matching arm of {@link PlannerSlotType}.
560
- *
561
- * @remarks
562
- * Use the same family as the axis — `at.time` with `axis.time`, `at.number`
563
- * with `axis.number`, `at.ordinal` with `axis.ordinal`. These shorthands
564
- * are used for the `slot` / `endSlot` fields of events, the row `now`
565
- * divider on the config, and any explicit `now` forwarded to the axis builder.
566
- */
567
- at: { time: slotTime, number: slotNumber, ordinal: slotOrdinal },
568
- /**
569
- * Builds a single Planner event from a flat TS input. Normalises optional
570
- * fields into their `OptionType` envelopes and resolves the `state` string
571
- * shorthands (`"committed"` / `"rejected"` / `"added"` / `"model"` /
572
- * `"removed"`).
573
- *
574
- * @param input - The event configuration ({@link EventInput})
575
- * @returns An East expression of {@link PlannerEventType}
576
- *
577
- * @example
578
- * ```ts
579
- * import { East } from "@elaraai/east";
580
- * import { Planner, UIComponentType } from "@elaraai/east-ui";
581
- *
582
- * const example = East.function([], UIComponentType, _$ =>
583
- * Planner.Point(
584
- * [{ id: "a", name: "Alice", events: [Planner.event({ slot: Planner.at.number(0), label: "Shift", state: "committed" })] }],
585
- * {
586
- * axis: Planner.axis.number(),
587
- * columns: [{ key: "name", frozen: true, value: r => r.name }],
588
- * events: r => r.events,
589
- * },
590
- * ),
591
- * );
592
- * ```
593
- */
594
- event: createEvent,
595
- /**
596
- * Builds a single status marker from a flat input — declared parallel to
597
- * events (in a row's `markers`), not on an event. The renderer rings the
598
- * cell at `slot`, paints the paired status icon in the corner, and shows
599
- * `message` on hover.
600
- *
601
- * @param input - The marker configuration ({@link MarkerInput})
602
- * @returns An East expression of {@link PlannerMarkerType}
603
- *
604
- * @example
605
- * ```ts
606
- * import { East } from "@elaraai/east";
607
- * import { Planner, UIComponentType } from "@elaraai/east-ui";
608
- *
609
- * const example = East.function([], UIComponentType, _$ =>
610
- * Planner.Point(
611
- * [{ id: "a", name: "Alice", events: [], markers: [Planner.marker({ slot: Planner.at.number(0), status: "danger", message: "Conflict" })] }],
612
- * {
613
- * axis: Planner.axis.number(),
614
- * columns: [{ key: "name", frozen: true, value: r => r.name }],
615
- * events: r => r.events,
616
- * markers: r => r.markers,
617
- * },
618
- * ),
619
- * );
620
- * ```
621
- */
622
- marker: createMarker,
623
- /** The Planner East types. */
624
- Types: {
625
- /**
626
- * The Planner root IR — shared by Point and Span (the `variant` arm
627
- * discriminates).
628
- *
629
- * @remarks
630
- * The top-level shape every Planner compiles to. Content (`rows` /
631
- * `columns`), the axis, and behaviour (`onSelectRow`) sit on the root.
632
- *
633
- * @property variant - Which chassis configuration (point / span)
634
- * @property axis - The axis declaration (scale / buckets / range / format)
635
- * @property columns - The left-side columns
636
- * @property rows - The rows
637
- * @property now - Optional explicit committed/proposed divider; else derived from the data
638
- * @property density - Optional density (row / header rhythm)
639
- * @property slotMinWidth - Optional min-width (CSS) per x-axis slot column; the timeline scrolls when slots can't fit
640
- * @property maxHeight - Optional max-height (CSS) for the plan area; the body scrolls vertically within it with the header pinned. Absent ⇒ content-sized
641
- * @property onSelectRow - Optional row-selection callback
642
- */
643
- Root: PlannerRootType,
644
- /**
645
- * Which chassis configuration this Planner is.
646
- *
647
- * @remarks
648
- * Discriminates Point from Span on the {@link PlannerRootType} root.
649
- *
650
- * @property point - Slot-bound events (each event sits in one slot/bucket)
651
- * @property span - Multi-slot span events (start → end)
652
- */
653
- Variant: PlannerVariantType,
654
- /**
655
- * A typed slot coordinate. The arm chooses the axis scale the renderer
656
- * builds, so the scale kind is derived from the data and never declared
657
- * twice.
658
- *
659
- * @remarks
660
- * The coordinate space of every event and marker; mixing arms within one
661
- * Planner is the forbidden "one axis type per Planner" case.
662
- *
663
- * @property time - A datetime position (calendar slots)
664
- * @property number - A numeric position (day-of-X, hour-of-Y)
665
- * @property ordinal - An ordinal label (phase / stage / week-number)
666
- */
667
- Slot: PlannerSlotType,
668
- /**
669
- * The axis scale kind, declared once on the axis; must match every
670
- * slot's arm.
671
- *
672
- * @remarks
673
- * The scale declaration on {@link PlannerAxisType}, mirroring the arm of
674
- * each {@link PlannerSlotType} coordinate.
675
- *
676
- * @property time - Datetime axis
677
- * @property number - Numeric axis
678
- * @property ordinal - Ordinal axis
679
- */
680
- Scale: PlannerScaleType,
681
- /**
682
- * The time-axis column resolution — the calendar unit of each slot
683
- * column.
684
- *
685
- * @remarks
686
- * The optional `resolution` on {@link PlannerAxisType}; built via
687
- * `Planner.axis.time({ resolution })`. Absent ≡ `auto` (a pinned
688
- * range spanning ≤ 14 days infers day columns, anything else month).
689
- *
690
- * @property auto - Infer from the pinned range span (≤ 14 days ⇒ day, else month)
691
- * @property hour - One column per hour
692
- * @property day - One column per day
693
- * @property week - One column per week
694
- * @property month - One column per calendar month
695
- * @property quarter - One column per calendar quarter
696
- * @property year - One column per calendar year
697
- */
698
- Resolution: PlannerResolutionType,
699
- /**
700
- * One labelled sub-slot bucket inside a column — the explicit name an
701
- * operator reads (AM/PM, the parts of a day, …).
702
- *
703
- * @remarks
704
- * Buckets are an arbitrary labelled array on the axis; an empty array
705
- * means one slot per column.
706
- *
707
- * @property key - The bucket identity an event references
708
- * @property label - The displayed bucket name
709
- */
710
- Bucket: PlannerBucketType,
711
- /**
712
- * An explicit axis domain, typed to the axis's coordinate kind. Supplied
713
- * to fix the extent instead of deriving it from the data.
714
- *
715
- * @remarks
716
- * The optional `range` on {@link PlannerAxisType}; its arm matches the
717
- * axis {@link PlannerScaleType}.
718
- *
719
- * @property time - Datetime bounds for a time axis
720
- * @property number - Numeric bounds for a numeric axis
721
- * @property ordinal - The ordered category labels for an ordinal axis
722
- */
723
- Range: PlannerRangeType,
724
- /**
725
- * The axis declaration — the scale kind, the labelled sub-slot buckets,
726
- * an optional explicit range, and an optional tick-label format.
727
- *
728
- * @remarks
729
- * The `axis` field of {@link PlannerRootType}; built with the
730
- * `Planner.axis.*` builders.
731
- *
732
- * @property scale - The axis coordinate kind (see {@link PlannerScaleType})
733
- * @property buckets - The labelled sub-slot buckets ([] = one slot per column)
734
- * @property range - Optional explicit domain; else derived from the data
735
- * @property format - Optional tick-label format pattern
736
- */
737
- Axis: PlannerAxisType,
738
- /**
739
- * The sub-flavour of a `proposed` event. It rides inside the `proposed`
740
- * arm of {@link PlannerStateType}, so it is only representable while
741
- * proposed — a committed event can never carry a flavour.
742
- *
743
- * @remarks
744
- * Nested under the `proposed` arm of {@link PlannerStateType}; drives the
745
- * proposed event's rendering.
746
- *
747
- * @property added - An operator proposal
748
- * @property model - A model's suggestion (rendered italic)
749
- * @property removed - A proposed deletion of a committed event (struck through)
750
- */
751
- Flavour: PlannerFlavourType,
752
- /**
753
- * The three event states. `committed` is audit-locked and read-only;
754
- * `proposed` is dirty-patch owned (carrying its flavour); `rejected` is a
755
- * proposal that was turned down, kept for diff context.
756
- *
757
- * @remarks
758
- * The `state` of every {@link PlannerEventType}; the `proposed` arm nests
759
- * a {@link PlannerFlavourType}.
760
- *
761
- * @property committed - Audit-locked, immutable
762
- * @property proposed - Drafted; the flavour (see {@link PlannerFlavourType}) is nested
763
- * @property rejected - Reviewed and declined; kept for diff
764
- */
765
- State: PlannerStateType,
766
- /**
767
- * Which axis an event tile stretches to fill its cell on.
768
- *
769
- * @remarks
770
- * The optional `stretch` of a {@link PlannerEventType}; absent ⇒
771
- * content-sized. Deliberately `stretch` (not `fill`) to avoid confusion
772
- * with the background-colour fill.
773
- *
774
- * @property horizontal - Fill the cell width
775
- * @property vertical - Fill the cell height
776
- * @property both - Fill both axes
777
- */
778
- Stretch: PlannerStretchType,
779
- /**
780
- * One content-alignment position along a single axis.
781
- *
782
- * @remarks
783
- * Used for both axes of {@link PlannerContentType}.
784
- *
785
- * @property start - Align to the start (left / top)
786
- * @property center - Centre
787
- * @property end - Align to the end (right / bottom)
788
- */
789
- ContentAlign: PlannerContentAlignType,
790
- /**
791
- * Where an event tile's content sits inside the tile — a two-axis
792
- * alignment.
793
- *
794
- * @remarks
795
- * The optional `content` of a {@link PlannerEventType}; both axes default
796
- * to `start` (top-left).
797
- *
798
- * @property horizontal - Horizontal content alignment (→ `justifyContent`)
799
- * @property vertical - Vertical content alignment (→ `alignItems`)
800
- */
801
- Content: PlannerContentType,
802
- /**
803
- * An event tile's optional attention animation.
804
- *
805
- * @remarks
806
- * The optional `animation` of a {@link PlannerEventType}; `pulse` honours
807
- * `prefers-reduced-motion`.
808
- *
809
- * @property none - No animation (the default)
810
- * @property pulse - A gentle opacity pulse
811
- */
812
- Animation: PlannerAnimationType,
813
- /**
814
- * A status marker placed at a slot — declared parallel to events (in the
815
- * row's `markers`, not on an event). The renderer rings the cell at
816
- * `slot`, paints the paired status icon in its corner, and surfaces
817
- * `message` as a hover tooltip.
818
- *
819
- * @remarks
820
- * Reuses the shared {@link StatusValueType} so a cell can be flagged good
821
- * (`success`) just as readily as bad (`danger` / `warning`); declared on
822
- * a {@link PlannerRowType} row's `markers`.
823
- *
824
- * @property slot - The slot coordinate of the cell the marker rings
825
- * @property status - The semantic status (success / warning / danger / info / neutral) — drives colour + icon
826
- * @property message - The marker text surfaced as a hover tooltip
827
- */
828
- Marker: PlannerMarkerType,
829
- /**
830
- * A single placed event. `slot` is the (start) coordinate; `endSlot` is
831
- * set on Span events; `bucket` references a declared bucket key (none =
832
- * unbucketed).
833
- *
834
- * @remarks
835
- * The element of a {@link PlannerRowType} row's `events`. `popover` is the
836
- * click-triggered rich body (popover-only — there is no tooltip).
837
- *
838
- * @property slot - The event's (start) slot coordinate
839
- * @property endSlot - The span end (Span variant; none for Point)
840
- * @property bucket - The declared bucket key the event sits in (none = unbucketed)
841
- * @property label - The event's text
842
- * @property state - The audit state (see {@link PlannerStateType})
843
- * @property popover - Optional click-triggered rich body (UIComponent)
844
- */
845
- Event: PlannerEventType,
846
- /**
847
- * Horizontal alignment of a left column's content.
848
- *
849
- * @remarks
850
- * The optional `align` of a {@link PlannerColumnType}.
851
- *
852
- * @property start - Align to the start (left)
853
- * @property end - Align to the end (right)
854
- */
855
- Align: PlannerAlignType,
856
- /**
857
- * A left-side column definition — flat and kind-free, the same shape as
858
- * Table / Gantt.
859
- *
860
- * @remarks
861
- * An element of {@link PlannerRootType}'s `columns`. The five spec "column
862
- * kinds" are authoring patterns built from `value` + `sublabel`, not
863
- * distinct IR shapes.
864
- *
865
- * @property key - The column identity (and the row's cell key)
866
- * @property header - The column header text
867
- * @property width - Optional CSS width
868
- * @property frozen - Whether the column is pinned sticky-left
869
- * @property align - Optional horizontal alignment of the cell content
870
- */
871
- Column: PlannerColumnType,
872
- /**
873
- * The per-row cell content — a `value` and an optional muted `sublabel`
874
- * (eyebrow).
875
- *
876
- * @remarks
877
- * The value of a {@link PlannerRowType} row's `cells` dict. A derived
878
- * column is just a `value` computed in East; there is no separate kind.
879
- *
880
- * @property value - The cell text (a field or an East-computed value)
881
- * @property sublabel - The optional muted eyebrow line beneath the value
882
- */
883
- Cell: PlannerCellType,
884
- /**
885
- * One Planner row — a typed resource, identified by index.
886
- *
887
- * @remarks
888
- * An element of {@link PlannerRootType}'s `rows`. `cells` are the
889
- * left-column values keyed by column key; `events` is the row's slot
890
- * timeline; `markers` are the row's status markers (declared parallel to
891
- * events, not on them).
892
- *
893
- * @property group - Optional group-head label (`groupBy`)
894
- * @property cells - The left-column cell values keyed by column key
895
- * @property events - The row's events ({@link PlannerEventType})
896
- * @property markers - The row's status markers ({@link PlannerMarkerType})
897
- */
898
- Row: PlannerRowType,
899
- /**
900
- * The payload of the `onSelectRow` callback (a row was clicked /
901
- * selected).
902
- *
903
- * @remarks
904
- * Passed to {@link PlannerRootType}'s `onSelectRow` when a row is picked.
905
- *
906
- * @property rowIndex - The selected row's index (0-based)
907
- */
908
- SelectEvent: PlannerSelectEventType,
909
- /**
910
- * A row's review decision — `approved` (resting clean line),
911
- * `pending` (awaits an explicit call), or `rejected`.
912
- *
913
- * @property approved - Pre-approved / accepted
914
- * @property pending - Undecided
915
- * @property rejected - Explicitly declined
916
- */
917
- Approval: PlannerApprovalType,
918
- /**
919
- * The payload of the `onApprove` / `onReject` callbacks (a single
920
- * row's Approve or Reject button was clicked).
921
- *
922
- * @property rowIndex - The acted-on row's index (0-based)
923
- */
924
- ApproveEvent: PlannerApproveEventType,
925
- /**
926
- * The review configuration — the per-row decision column plus the
927
- * batch foot (approve-all / reject-all / rerun).
928
- *
929
- * @property columnLabel - The decision column header
930
- * @property summary - Optional foot summary component
931
- * @property onApprove - Per-row approve callback
932
- * @property onReject - Per-row reject callback
933
- * @property onApproveAll - Batch approve callback
934
- * @property onRejectAll - Batch reject callback
935
- * @property onRerun - Re-run callback
936
- * @property rerunLabel - The re-run button label
937
- */
938
- Review: PlannerReviewType,
939
- },
940
- };
941
- //# sourceMappingURL=index.js.map