@nowline/layout 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 (183) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +103 -0
  3. package/dist/band-scale.d.ts +56 -0
  4. package/dist/band-scale.d.ts.map +1 -0
  5. package/dist/band-scale.js +86 -0
  6. package/dist/band-scale.js.map +1 -0
  7. package/dist/calendar.d.ts +79 -0
  8. package/dist/calendar.d.ts.map +1 -0
  9. package/dist/calendar.js +210 -0
  10. package/dist/calendar.js.map +1 -0
  11. package/dist/capacity.d.ts +72 -0
  12. package/dist/capacity.d.ts.map +1 -0
  13. package/dist/capacity.js +163 -0
  14. package/dist/capacity.js.map +1 -0
  15. package/dist/dsl-utils.d.ts +5 -0
  16. package/dist/dsl-utils.d.ts.map +1 -0
  17. package/dist/dsl-utils.js +28 -0
  18. package/dist/dsl-utils.js.map +1 -0
  19. package/dist/edge-routing.d.ts +89 -0
  20. package/dist/edge-routing.d.ts.map +1 -0
  21. package/dist/edge-routing.js +435 -0
  22. package/dist/edge-routing.js.map +1 -0
  23. package/dist/frame-tab-geometry.d.ts +78 -0
  24. package/dist/frame-tab-geometry.d.ts.map +1 -0
  25. package/dist/frame-tab-geometry.js +115 -0
  26. package/dist/frame-tab-geometry.js.map +1 -0
  27. package/dist/header-card-geometry.d.ts +29 -0
  28. package/dist/header-card-geometry.d.ts.map +1 -0
  29. package/dist/header-card-geometry.js +41 -0
  30. package/dist/header-card-geometry.js.map +1 -0
  31. package/dist/i18n.d.ts +48 -0
  32. package/dist/i18n.d.ts.map +1 -0
  33. package/dist/i18n.js +114 -0
  34. package/dist/i18n.js.map +1 -0
  35. package/dist/include-chrome-geometry.d.ts +86 -0
  36. package/dist/include-chrome-geometry.d.ts.map +1 -0
  37. package/dist/include-chrome-geometry.js +104 -0
  38. package/dist/include-chrome-geometry.js.map +1 -0
  39. package/dist/index.d.ts +11 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +10 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/item-bar-geometry.d.ts +127 -0
  44. package/dist/item-bar-geometry.d.ts.map +1 -0
  45. package/dist/item-bar-geometry.js +173 -0
  46. package/dist/item-bar-geometry.js.map +1 -0
  47. package/dist/lane-utilization.d.ts +90 -0
  48. package/dist/lane-utilization.d.ts.map +1 -0
  49. package/dist/lane-utilization.js +206 -0
  50. package/dist/lane-utilization.js.map +1 -0
  51. package/dist/layout-context.d.ts +143 -0
  52. package/dist/layout-context.d.ts.map +1 -0
  53. package/dist/layout-context.js +8 -0
  54. package/dist/layout-context.js.map +1 -0
  55. package/dist/layout.d.ts +18 -0
  56. package/dist/layout.d.ts.map +1 -0
  57. package/dist/layout.js +1213 -0
  58. package/dist/layout.js.map +1 -0
  59. package/dist/nodes/anchor-node.d.ts +16 -0
  60. package/dist/nodes/anchor-node.d.ts.map +1 -0
  61. package/dist/nodes/anchor-node.js +68 -0
  62. package/dist/nodes/anchor-node.js.map +1 -0
  63. package/dist/nodes/footnote-node.d.ts +10 -0
  64. package/dist/nodes/footnote-node.d.ts.map +1 -0
  65. package/dist/nodes/footnote-node.js +41 -0
  66. package/dist/nodes/footnote-node.js.map +1 -0
  67. package/dist/nodes/group-node.d.ts +29 -0
  68. package/dist/nodes/group-node.d.ts.map +1 -0
  69. package/dist/nodes/group-node.js +187 -0
  70. package/dist/nodes/group-node.js.map +1 -0
  71. package/dist/nodes/include-node.d.ts +16 -0
  72. package/dist/nodes/include-node.d.ts.map +1 -0
  73. package/dist/nodes/include-node.js +117 -0
  74. package/dist/nodes/include-node.js.map +1 -0
  75. package/dist/nodes/item-node.d.ts +51 -0
  76. package/dist/nodes/item-node.d.ts.map +1 -0
  77. package/dist/nodes/item-node.js +108 -0
  78. package/dist/nodes/item-node.js.map +1 -0
  79. package/dist/nodes/marker-geometry.d.ts +22 -0
  80. package/dist/nodes/marker-geometry.d.ts.map +1 -0
  81. package/dist/nodes/marker-geometry.js +38 -0
  82. package/dist/nodes/marker-geometry.js.map +1 -0
  83. package/dist/nodes/milestone-node.d.ts +48 -0
  84. package/dist/nodes/milestone-node.d.ts.map +1 -0
  85. package/dist/nodes/milestone-node.js +210 -0
  86. package/dist/nodes/milestone-node.js.map +1 -0
  87. package/dist/nodes/parallel-node.d.ts +21 -0
  88. package/dist/nodes/parallel-node.d.ts.map +1 -0
  89. package/dist/nodes/parallel-node.js +80 -0
  90. package/dist/nodes/parallel-node.js.map +1 -0
  91. package/dist/nodes/roadmap-node.d.ts +76 -0
  92. package/dist/nodes/roadmap-node.d.ts.map +1 -0
  93. package/dist/nodes/roadmap-node.js +788 -0
  94. package/dist/nodes/roadmap-node.js.map +1 -0
  95. package/dist/nodes/swimlane-node.d.ts +38 -0
  96. package/dist/nodes/swimlane-node.d.ts.map +1 -0
  97. package/dist/nodes/swimlane-node.js +308 -0
  98. package/dist/nodes/swimlane-node.js.map +1 -0
  99. package/dist/renderable.d.ts +44 -0
  100. package/dist/renderable.d.ts.map +1 -0
  101. package/dist/renderable.js +21 -0
  102. package/dist/renderable.js.map +1 -0
  103. package/dist/row-packer.d.ts +125 -0
  104. package/dist/row-packer.d.ts.map +1 -0
  105. package/dist/row-packer.js +169 -0
  106. package/dist/row-packer.js.map +1 -0
  107. package/dist/style-resolution.d.ts +14 -0
  108. package/dist/style-resolution.d.ts.map +1 -0
  109. package/dist/style-resolution.js +191 -0
  110. package/dist/style-resolution.js.map +1 -0
  111. package/dist/themes/dark.d.ts +4 -0
  112. package/dist/themes/dark.d.ts.map +1 -0
  113. package/dist/themes/dark.js +241 -0
  114. package/dist/themes/dark.js.map +1 -0
  115. package/dist/themes/index.d.ts +15 -0
  116. package/dist/themes/index.d.ts.map +1 -0
  117. package/dist/themes/index.js +30 -0
  118. package/dist/themes/index.js.map +1 -0
  119. package/dist/themes/light.d.ts +4 -0
  120. package/dist/themes/light.d.ts.map +1 -0
  121. package/dist/themes/light.js +248 -0
  122. package/dist/themes/light.js.map +1 -0
  123. package/dist/themes/shape.d.ts +194 -0
  124. package/dist/themes/shape.d.ts.map +1 -0
  125. package/dist/themes/shape.js +6 -0
  126. package/dist/themes/shape.js.map +1 -0
  127. package/dist/themes/shared.d.ts +145 -0
  128. package/dist/themes/shared.d.ts.map +1 -0
  129. package/dist/themes/shared.js +310 -0
  130. package/dist/themes/shared.js.map +1 -0
  131. package/dist/time-scale.d.ts +39 -0
  132. package/dist/time-scale.d.ts.map +1 -0
  133. package/dist/time-scale.js +62 -0
  134. package/dist/time-scale.js.map +1 -0
  135. package/dist/types.d.ts +483 -0
  136. package/dist/types.d.ts.map +1 -0
  137. package/dist/types.js +6 -0
  138. package/dist/types.js.map +1 -0
  139. package/dist/view-preset.d.ts +23 -0
  140. package/dist/view-preset.d.ts.map +1 -0
  141. package/dist/view-preset.js +146 -0
  142. package/dist/view-preset.js.map +1 -0
  143. package/dist/working-calendar.d.ts +14 -0
  144. package/dist/working-calendar.d.ts.map +1 -0
  145. package/dist/working-calendar.js +74 -0
  146. package/dist/working-calendar.js.map +1 -0
  147. package/package.json +37 -0
  148. package/src/band-scale.ts +115 -0
  149. package/src/calendar.ts +244 -0
  150. package/src/capacity.ts +191 -0
  151. package/src/dsl-utils.ts +30 -0
  152. package/src/edge-routing.ts +550 -0
  153. package/src/frame-tab-geometry.ts +165 -0
  154. package/src/header-card-geometry.ts +48 -0
  155. package/src/i18n.ts +124 -0
  156. package/src/include-chrome-geometry.ts +156 -0
  157. package/src/index.ts +116 -0
  158. package/src/item-bar-geometry.ts +222 -0
  159. package/src/lane-utilization.ts +259 -0
  160. package/src/layout-context.ts +182 -0
  161. package/src/layout.ts +1446 -0
  162. package/src/nodes/anchor-node.ts +77 -0
  163. package/src/nodes/footnote-node.ts +60 -0
  164. package/src/nodes/group-node.ts +252 -0
  165. package/src/nodes/include-node.ts +168 -0
  166. package/src/nodes/item-node.ts +171 -0
  167. package/src/nodes/marker-geometry.ts +43 -0
  168. package/src/nodes/milestone-node.ts +263 -0
  169. package/src/nodes/parallel-node.ts +101 -0
  170. package/src/nodes/roadmap-node.ts +957 -0
  171. package/src/nodes/swimlane-node.ts +423 -0
  172. package/src/renderable.ts +68 -0
  173. package/src/row-packer.ts +271 -0
  174. package/src/style-resolution.ts +243 -0
  175. package/src/themes/dark.ts +244 -0
  176. package/src/themes/index.ts +36 -0
  177. package/src/themes/light.ts +251 -0
  178. package/src/themes/shape.ts +230 -0
  179. package/src/themes/shared.ts +369 -0
  180. package/src/time-scale.ts +78 -0
  181. package/src/types.ts +607 -0
  182. package/src/view-preset.ts +180 -0
  183. package/src/working-calendar.ts +91 -0
@@ -0,0 +1,169 @@
1
+ // RowPacker — the topmost-fit row-pack engine shared by `SwimlaneNode`
2
+ // and `GroupNode`. Tracks rows of variable height (each row's height is
3
+ // the max of its placed children's heights, with a per-packer minimum)
4
+ // and bumps a child to a new row when it would collide with a sibling's
5
+ // `rightEdge`, caption `spillX`, or a slack-arrow corridor.
6
+ //
7
+ // Two-phase API per child:
8
+ // 1) `placeItem(...)` / `placeBlock(...)` decides which row the child
9
+ // lands on. The caller then sequences the child at the returned
10
+ // `(rowIndex, y)`, producing a fully positioned subtree.
11
+ // 2) `commitItem(...)` / `commitBlock(...)` records the placed child
12
+ // back into the packer so the row's `rightEdge` / `spillX` advance
13
+ // and the row's height grows to accommodate the new child.
14
+ //
15
+ // When a row's height grows after later rows already exist, the packer
16
+ // shifts every subsequent row (and every positioned child placed in it)
17
+ // downward by the delta. Items keep their row-anchored top edge; the
18
+ // row simply gets taller. This keeps the contract "all children in a
19
+ // row share that row's top y" intact while letting individual children
20
+ // grow vertically (e.g. wrapped label-chiclet stacks in m3).
21
+ export class RowPacker {
22
+ rows;
23
+ opts;
24
+ constructor(opts) {
25
+ this.opts = opts;
26
+ this.rows = [
27
+ {
28
+ y: opts.originY,
29
+ height: opts.minRowHeight,
30
+ rightEdge: opts.laneLeftX,
31
+ spillX: opts.laneLeftX,
32
+ placedChildren: [],
33
+ },
34
+ ];
35
+ }
36
+ /**
37
+ * Find the topmost row where the item's natural extent fits without
38
+ * colliding with sibling content or a slack corridor; appending a
39
+ * fresh row at the bottom when none of the existing rows fit.
40
+ */
41
+ placeItem(input) {
42
+ for (let i = 0; i < this.rows.length; i += 1) {
43
+ const r = this.rows[i];
44
+ if (input.desiredStart < r.rightEdge)
45
+ continue;
46
+ if (input.desiredStart < r.spillX)
47
+ continue;
48
+ if (this.rowIntersectsCorridor(r, input))
49
+ continue;
50
+ return { rowIndex: i, y: r.y };
51
+ }
52
+ const fresh = this.appendRow(Math.max(this.opts.minRowHeight, input.predictedHeight));
53
+ return { rowIndex: this.rows.length - 1, y: fresh.y };
54
+ }
55
+ /**
56
+ * Blocks (parallel / group) always claim a fresh row at the bottom
57
+ * of the stack so their inner sub-tracks have contiguous rows to
58
+ * expand into. If the bottom row is empty, we reuse it; otherwise
59
+ * we append.
60
+ */
61
+ placeBlock() {
62
+ const last = this.rows[this.rows.length - 1];
63
+ if (last.rightEdge > this.opts.laneLeftX) {
64
+ const fresh = this.appendRow(this.opts.minRowHeight);
65
+ return { rowIndex: this.rows.length - 1, y: fresh.y };
66
+ }
67
+ return { rowIndex: this.rows.length - 1, y: last.y };
68
+ }
69
+ /**
70
+ * Record a placed item back into its row. Grows the row's height to
71
+ * fit the item, advances `rightEdge`, sets the caption spill, and
72
+ * shifts later rows down if this row got taller.
73
+ */
74
+ commitItem(input) {
75
+ const row = this.rows[input.rowIndex];
76
+ const target = Math.max(input.placed.box.height, input.rowHeight ?? 0);
77
+ this.growRowHeight(input.rowIndex, target);
78
+ row.rightEdge = input.logicalEnd;
79
+ row.spillX = input.spillReservation ?? this.opts.laneLeftX;
80
+ row.placedChildren.push(input.placed);
81
+ }
82
+ /**
83
+ * Record a placed block. Sets the row's height to the block's full
84
+ * height (blocks own their row, no other child shares it).
85
+ */
86
+ commitBlock(input) {
87
+ const row = this.rows[input.rowIndex];
88
+ this.growRowHeight(input.rowIndex, input.blockHeight);
89
+ row.rightEdge = input.blockEnd;
90
+ row.spillX = this.opts.laneLeftX;
91
+ row.placedChildren.push(input.placed);
92
+ }
93
+ /** Total vertical extent reached (last row's bottom - originY). */
94
+ usedHeight() {
95
+ const last = this.rows[this.rows.length - 1];
96
+ return last.y + last.height - this.opts.originY;
97
+ }
98
+ /** Rightmost extent reached — bar logical end OR caption spill,
99
+ * whichever is wider, across every row. Empty rows contribute
100
+ * `laneLeftX`. */
101
+ usedRightX() {
102
+ let x = this.opts.laneLeftX;
103
+ for (const r of this.rows) {
104
+ if (r.rightEdge > x)
105
+ x = r.rightEdge;
106
+ if (r.spillX > x)
107
+ x = r.spillX;
108
+ }
109
+ return x;
110
+ }
111
+ rowIntersectsCorridor(r, p) {
112
+ return this.opts.slackCorridors.some((c) => c.y >= r.y &&
113
+ c.y < r.y + r.height &&
114
+ p.desiredStart < c.xEnd &&
115
+ p.desiredEnd > c.xStart &&
116
+ c.slackPredId !== p.childId);
117
+ }
118
+ appendRow(height) {
119
+ const last = this.rows[this.rows.length - 1];
120
+ const r = {
121
+ y: last.y + last.height,
122
+ height,
123
+ rightEdge: this.opts.laneLeftX,
124
+ spillX: this.opts.laneLeftX,
125
+ placedChildren: [],
126
+ };
127
+ this.rows.push(r);
128
+ return r;
129
+ }
130
+ growRowHeight(rowIndex, newHeight) {
131
+ const row = this.rows[rowIndex];
132
+ const delta = newHeight - row.height;
133
+ if (delta <= 0)
134
+ return;
135
+ row.height = newHeight;
136
+ for (let i = rowIndex + 1; i < this.rows.length; i += 1) {
137
+ const r = this.rows[i];
138
+ r.y += delta;
139
+ for (const child of r.placedChildren) {
140
+ shiftPositionedY(child, delta);
141
+ }
142
+ }
143
+ }
144
+ }
145
+ /**
146
+ * Walk a positioned subtree and shift every absolute y by `dy`. Used
147
+ * when an earlier row in the packer grows, retroactively pushing every
148
+ * later row (and its placed subtrees) down to keep them clear.
149
+ *
150
+ * Items: shift the bar box plus label chips and any overflow box.
151
+ * Groups / parallels: shift the container box and recurse into
152
+ * children. The caller's `box.y` already moved with the parent.
153
+ */
154
+ function shiftPositionedY(p, dy) {
155
+ p.box.y += dy;
156
+ if (p.kind === 'item') {
157
+ for (const chip of p.labelChips) {
158
+ chip.box.y += dy;
159
+ }
160
+ if (p.overflowBox) {
161
+ p.overflowBox.y += dy;
162
+ }
163
+ return;
164
+ }
165
+ for (const child of p.children) {
166
+ shiftPositionedY(child, dy);
167
+ }
168
+ }
169
+ //# sourceMappingURL=row-packer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row-packer.js","sourceRoot":"","sources":["../src/row-packer.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,wEAAwE;AACxE,uEAAuE;AACvE,wEAAwE;AACxE,4DAA4D;AAC5D,EAAE;AACF,2BAA2B;AAC3B,wEAAwE;AACxE,qEAAqE;AACrE,8DAA8D;AAC9D,uEAAuE;AACvE,wEAAwE;AACxE,gEAAgE;AAChE,EAAE;AACF,uEAAuE;AACvE,wEAAwE;AACxE,qEAAqE;AACrE,qEAAqE;AACrE,uEAAuE;AACvE,6DAA6D;AAgG7D,MAAM,OAAO,SAAS;IACF,IAAI,CAAc;IACjB,IAAI,CAAmB;IAExC,YAAY,IAAsB;QAC9B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG;YACR;gBACI,CAAC,EAAE,IAAI,CAAC,OAAO;gBACf,MAAM,EAAE,IAAI,CAAC,YAAY;gBACzB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,MAAM,EAAE,IAAI,CAAC,SAAS;gBACtB,cAAc,EAAE,EAAE;aACrB;SACJ,CAAC;IACN,CAAC;IAED;;;;OAIG;IACH,SAAS,CAAC,KAAyB;QAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,SAAS;gBAAE,SAAS;YAC/C,IAAI,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,MAAM;gBAAE,SAAS;YAC5C,IAAI,IAAI,CAAC,qBAAqB,CAAC,CAAC,EAAE,KAAK,CAAC;gBAAE,SAAS;YACnD,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;QACtF,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;IAC1D,CAAC;IAED;;;;;OAKG;IACH,UAAU;QACN,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC7C,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACrD,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;QAC1D,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;IACzD,CAAC;IAED;;;;OAIG;IACH,UAAU,CAAC,KAAsB;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC;QACvE,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC3C,GAAG,CAAC,SAAS,GAAG,KAAK,CAAC,UAAU,CAAC;QACjC,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,gBAAgB,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;QAC3D,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED;;;OAGG;IACH,WAAW,CAAC,KAAuB;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACtC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;QACtD,GAAG,CAAC,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC;QAC/B,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;QACjC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,mEAAmE;IACnE,UAAU;QACN,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;IACpD,CAAC;IAED;;uBAEmB;IACnB,UAAU;QACN,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;QAC5B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,CAAC,SAAS,GAAG,CAAC;gBAAE,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC;YACrC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;gBAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QACnC,CAAC;QACD,OAAO,CAAC,CAAC;IACb,CAAC;IAEO,qBAAqB,CAAC,CAAY,EAAE,CAAqB;QAC7D,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAChC,CAAC,CAAC,EAAE,EAAE,CACF,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACV,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM;YACpB,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,IAAI;YACvB,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,MAAM;YACvB,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,OAAO,CAClC,CAAC;IACN,CAAC;IAEO,SAAS,CAAC,MAAc;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,GAAc;YACjB,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM;YACvB,MAAM;YACN,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS;YAC9B,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS;YAC3B,cAAc,EAAE,EAAE;SACrB,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,OAAO,CAAC,CAAC;IACb,CAAC;IAEO,aAAa,CAAC,QAAgB,EAAE,SAAiB;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChC,MAAM,KAAK,GAAG,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC;QACrC,IAAI,KAAK,IAAI,CAAC;YAAE,OAAO;QACvB,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC;QACvB,KAAK,IAAI,CAAC,GAAG,QAAQ,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACtD,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACvB,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;YACb,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,cAAc,EAAE,CAAC;gBACnC,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YACnC,CAAC;QACL,CAAC;IACL,CAAC;CACJ;AAED;;;;;;;;GAQG;AACH,SAAS,gBAAgB,CAAC,CAAuB,EAAE,EAAU;IACzD,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACd,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;YAC9B,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACrB,CAAC;QACD,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YAChB,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1B,CAAC;QACD,OAAO;IACX,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC7B,gBAAgB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAChC,CAAC;AACL,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { DefaultDeclaration, EntityProperty, LabelDeclaration, StyleDeclaration } from '@nowline/core';
2
+ import type { Theme } from './themes/shape.js';
3
+ import type { ResolvedStyle } from './types.js';
4
+ type EntityTypeKey = 'roadmap' | 'swimlane' | 'item' | 'parallel' | 'group' | 'anchor' | 'milestone' | 'footnote' | 'label';
5
+ export interface StyleContext {
6
+ theme: Theme;
7
+ styles: Map<string, StyleDeclaration>;
8
+ defaults: Map<string, DefaultDeclaration>;
9
+ labels: Map<string, LabelDeclaration>;
10
+ }
11
+ export declare function resolveStyle(entityType: EntityTypeKey, props: EntityProperty[], ctx: StyleContext): ResolvedStyle;
12
+ export declare function resolveLabelChipStyle(label: LabelDeclaration, ctx: StyleContext): ResolvedStyle;
13
+ export {};
14
+ //# sourceMappingURL=style-resolution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style-resolution.d.ts","sourceRoot":"","sources":["../src/style-resolution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAEnB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAe,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,YAAY,CAAC;AAE5D,KAAK,aAAa,GACZ,SAAS,GACT,UAAU,GACV,MAAM,GACN,UAAU,GACV,OAAO,GACP,QAAQ,GACR,WAAW,GACX,UAAU,GACV,OAAO,CAAC;AAEd,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,KAAK,CAAC;IAGb,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAEtC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAE1C,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CACzC;AAiLD,wBAAgB,YAAY,CACxB,UAAU,EAAE,aAAa,EACzB,KAAK,EAAE,cAAc,EAAE,EACvB,GAAG,EAAE,YAAY,GAClB,aAAa,CAwBf;AAID,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,YAAY,GAAG,aAAa,CAE/F"}
@@ -0,0 +1,191 @@
1
+ import { resolveColor } from './themes/index.js';
2
+ function propKey(prop) {
3
+ return prop.key.endsWith(':') ? prop.key.slice(0, -1) : prop.key;
4
+ }
5
+ function entityStyleToResolved(e, theme) {
6
+ return {
7
+ bg: resolveColor(e.bg, theme),
8
+ fg: resolveColor(e.fg, theme),
9
+ text: resolveColor(e.text, theme),
10
+ border: e.border,
11
+ icon: e.icon,
12
+ shadow: e.shadow,
13
+ font: e.font,
14
+ weight: e.weight,
15
+ italic: e.italic,
16
+ textSize: e.textSize,
17
+ padding: e.padding,
18
+ spacing: e.spacing,
19
+ headerHeight: e.headerHeight,
20
+ cornerRadius: e.cornerRadius,
21
+ bracket: e.bracket,
22
+ // DSL does not expose header-position on non-roadmap entities; system
23
+ // default `beside` applies. Roadmap entity's resolve step lifts this
24
+ // from the 5-level chain.
25
+ headerPosition: 'beside',
26
+ capacityIcon: e.capacityIcon,
27
+ // Roadmap-only readability knobs. Defaults preserve the existing
28
+ // single-top-strip layout and keep the major-ticks-only grid.
29
+ timelinePosition: 'top',
30
+ minorGrid: false,
31
+ };
32
+ }
33
+ // Apply a single style property (from `style` blocks, `default` blocks, or
34
+ // label styles) onto an accumulating ResolvedStyle.
35
+ function applyProp(target, key, value, theme) {
36
+ switch (key) {
37
+ case 'bg':
38
+ target.bg = resolveColor(value, theme);
39
+ break;
40
+ case 'fg':
41
+ target.fg = resolveColor(value, theme);
42
+ break;
43
+ case 'text':
44
+ target.text = resolveColor(value, theme);
45
+ break;
46
+ case 'border':
47
+ if (value === 'solid' || value === 'dashed' || value === 'dotted')
48
+ target.border = value;
49
+ break;
50
+ case 'icon':
51
+ target.icon = value;
52
+ break;
53
+ case 'shadow':
54
+ if (value === 'none' || value === 'subtle' || value === 'soft' || value === 'hard') {
55
+ target.shadow = value;
56
+ }
57
+ break;
58
+ case 'font':
59
+ if (value === 'sans' || value === 'serif' || value === 'mono')
60
+ target.font = value;
61
+ break;
62
+ case 'weight':
63
+ if (value === 'thin' || value === 'light' || value === 'normal' || value === 'bold') {
64
+ target.weight = value;
65
+ }
66
+ break;
67
+ case 'italic':
68
+ target.italic = value === 'true';
69
+ break;
70
+ case 'text-size':
71
+ target.textSize = coerceSize(value, 'xl');
72
+ break;
73
+ case 'padding':
74
+ target.padding = coerceSize(value, 'xl');
75
+ break;
76
+ case 'spacing':
77
+ target.spacing = coerceSize(value, 'xl');
78
+ break;
79
+ case 'header-height':
80
+ target.headerHeight = coerceSize(value, 'xl');
81
+ break;
82
+ case 'corner-radius':
83
+ target.cornerRadius = coerceSize(value, 'full');
84
+ break;
85
+ case 'bracket':
86
+ if (value === 'none' || value === 'solid' || value === 'dashed')
87
+ target.bracket = value;
88
+ break;
89
+ case 'header-position':
90
+ if (value === 'beside' || value === 'above')
91
+ target.headerPosition = value;
92
+ break;
93
+ case 'capacity-icon':
94
+ // Validator (rule 17e + checkSymbolReferences) has already verified
95
+ // the value is a built-in name, a declared symbol id, or an inline
96
+ // Unicode literal. Pass it through verbatim — interpretation
97
+ // happens in the renderer where we have access to ResolvedConfig.symbols.
98
+ target.capacityIcon = value;
99
+ break;
100
+ case 'timeline-position':
101
+ if (value === 'top' || value === 'bottom' || value === 'both') {
102
+ target.timelinePosition = value;
103
+ }
104
+ break;
105
+ case 'minor-grid':
106
+ target.minorGrid = value === 'true';
107
+ break;
108
+ default:
109
+ break;
110
+ }
111
+ }
112
+ function coerceSize(value, max) {
113
+ const order = ['none', 'xs', 'sm', 'md', 'lg', 'xl', 'full'];
114
+ const cap = order.indexOf(max);
115
+ const idx = order.indexOf(value);
116
+ if (idx < 0)
117
+ return 'md';
118
+ if (idx > cap)
119
+ return order[cap];
120
+ return order[idx];
121
+ }
122
+ function applyStyleDecl(target, decl, theme) {
123
+ if (!decl)
124
+ return;
125
+ for (const p of decl.properties) {
126
+ applyProp(target, propKey(p), p.value, theme);
127
+ }
128
+ }
129
+ function applyProperties(target, props, theme) {
130
+ for (const p of props) {
131
+ const key = propKey(p);
132
+ if (p.value !== undefined) {
133
+ applyProp(target, key, p.value, theme);
134
+ }
135
+ }
136
+ }
137
+ function applyLabelStyleRefs(target, props, ctx) {
138
+ const labelsProp = props.find((p) => propKey(p) === 'labels');
139
+ if (!labelsProp)
140
+ return;
141
+ const names = labelsProp.value ? [labelsProp.value] : labelsProp.values;
142
+ for (const name of names) {
143
+ const label = ctx.labels.get(name);
144
+ if (!label)
145
+ continue;
146
+ // Label's `style:` ref gets applied.
147
+ const styleRef = label.properties.find((p) => propKey(p) === 'style');
148
+ if (styleRef?.value) {
149
+ applyStyleDecl(target, ctx.styles.get(styleRef.value), ctx.theme);
150
+ }
151
+ }
152
+ }
153
+ function applyEntityStyleRef(target, props, ctx) {
154
+ const styleProp = props.find((p) => propKey(p) === 'style');
155
+ if (!styleProp?.value)
156
+ return;
157
+ applyStyleDecl(target, ctx.styles.get(styleProp.value), ctx.theme);
158
+ }
159
+ // Five-level precedence chain from specs/rendering.md § Style Precedence:
160
+ // 1. system default (theme's EntityStyle for this type)
161
+ // 2. config `default <entity>` properties
162
+ // 3. label `style:` refs (per applied label)
163
+ // 4. entity's own `style:` ref
164
+ // 5. inline style properties on the entity (banned by validator for roadmap
165
+ // entities; still supported for declared styles / defaults)
166
+ export function resolveStyle(entityType, props, ctx) {
167
+ const baseEntity = ctx.theme.entities[entityType];
168
+ const out = entityStyleToResolved(baseEntity, ctx.theme);
169
+ // Level 2: config defaults
170
+ const defaultDecl = ctx.defaults.get(entityType);
171
+ if (defaultDecl) {
172
+ for (const p of defaultDecl.properties) {
173
+ if (p.value !== undefined) {
174
+ applyProp(out, propKey(p), p.value, ctx.theme);
175
+ }
176
+ }
177
+ }
178
+ // Level 3: label styles (labels on this entity, each label's `style:` ref)
179
+ applyLabelStyleRefs(out, props, ctx);
180
+ // Level 4: entity's own `style:` ref
181
+ applyEntityStyleRef(out, props, ctx);
182
+ // Level 5: inline props on the entity
183
+ applyProperties(out, props, ctx.theme);
184
+ return out;
185
+ }
186
+ // Resolve a label's *display* style (bg/fg/text + bracket etc.) as used on
187
+ // label chips rendered on items. The chip uses the label entity type.
188
+ export function resolveLabelChipStyle(label, ctx) {
189
+ return resolveStyle('label', label.properties, ctx);
190
+ }
191
+ //# sourceMappingURL=style-resolution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style-resolution.js","sourceRoot":"","sources":["../src/style-resolution.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { NamedColors, Theme } from './shape.js';
2
+ export declare const darkNamed: NamedColors;
3
+ export declare const darkTheme: Theme;
4
+ //# sourceMappingURL=dark.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dark.d.ts","sourceRoot":"","sources":["../../src/themes/dark.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,WAAW,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGlE,eAAO,MAAM,SAAS,EAAE,WAUvB,CAAC;AAqBF,eAAO,MAAM,SAAS,EAAE,KAiNvB,CAAC"}
@@ -0,0 +1,241 @@
1
+ // Named-color mapping for dark theme. Tailwind's slate-on-near-black tints.
2
+ export const darkNamed = {
3
+ red: '#f87171',
4
+ blue: '#60a5fa',
5
+ yellow: '#facc15',
6
+ green: '#34d399',
7
+ orange: '#fb923c',
8
+ purple: '#a78bfa',
9
+ gray: '#94a3b8',
10
+ navy: '#818cf8',
11
+ white: '#e2e8f0',
12
+ };
13
+ const baseEntity = {
14
+ bg: 'none',
15
+ fg: '#e2e8f0',
16
+ text: '#e2e8f0',
17
+ border: 'solid',
18
+ icon: 'none',
19
+ shadow: 'none',
20
+ font: 'sans',
21
+ weight: 'normal',
22
+ italic: false,
23
+ textSize: 'md',
24
+ padding: 'sm',
25
+ spacing: 'sm',
26
+ headerHeight: 'sm',
27
+ cornerRadius: 'sm',
28
+ bracket: 'none',
29
+ capacityIcon: 'multiplier',
30
+ };
31
+ export const darkTheme = {
32
+ name: 'dark',
33
+ surface: {
34
+ page: '#0b1220',
35
+ chart: '#111827',
36
+ headerBox: '#1e293b',
37
+ },
38
+ entities: {
39
+ roadmap: {
40
+ ...baseEntity,
41
+ headerHeight: 'md',
42
+ padding: 'md',
43
+ },
44
+ swimlane: {
45
+ ...baseEntity,
46
+ fg: '#e2e8f0',
47
+ text: '#e2e8f0',
48
+ padding: 'sm',
49
+ spacing: 'none',
50
+ textSize: 'sm',
51
+ },
52
+ item: {
53
+ ...baseEntity,
54
+ // Status-aware tint applied during layout when bg stays #0f172a.
55
+ bg: '#0f172a',
56
+ fg: '#94a3b8',
57
+ text: '#e2e8f0',
58
+ shadow: 'subtle',
59
+ cornerRadius: 'sm',
60
+ },
61
+ parallel: {
62
+ ...baseEntity,
63
+ bracket: 'none',
64
+ padding: 'xs',
65
+ },
66
+ group: {
67
+ ...baseEntity,
68
+ bracket: 'solid',
69
+ padding: 'xs',
70
+ fg: '#94a3b8',
71
+ },
72
+ anchor: {
73
+ ...baseEntity,
74
+ bg: '#0b1220',
75
+ fg: '#cbd5e1',
76
+ text: '#cbd5e1',
77
+ cornerRadius: 'sm',
78
+ },
79
+ milestone: {
80
+ ...baseEntity,
81
+ bg: '#e2e8f0',
82
+ fg: '#e2e8f0',
83
+ text: '#0b1220',
84
+ border: 'solid',
85
+ },
86
+ footnote: {
87
+ ...baseEntity,
88
+ bg: 'none',
89
+ fg: '#94a3b8',
90
+ text: '#e2e8f0',
91
+ textSize: 'sm',
92
+ },
93
+ label: {
94
+ ...baseEntity,
95
+ bg: '#1e293b',
96
+ fg: '#94a3b8',
97
+ text: '#e2e8f0',
98
+ textSize: 'xs',
99
+ padding: 'xs',
100
+ cornerRadius: 'full',
101
+ },
102
+ },
103
+ swimlane: {
104
+ bandEven: '#111827',
105
+ bandOdd: '#0f172a',
106
+ separator: '#1f2937',
107
+ frameTabText: '#e2e8f0',
108
+ frameTabMuted: '#94a3b8',
109
+ border: '#334155',
110
+ tabFill: '#1e293b',
111
+ tabStroke: '#475569',
112
+ tabText: '#e2e8f0',
113
+ ownerText: '#94a3b8',
114
+ footnoteIndicator: '#f87171',
115
+ rowTintEven: '#0f172a',
116
+ rowTintOdd: '#1e293b',
117
+ utilizationOk: '#34d399',
118
+ utilizationWarn: '#fbbf24',
119
+ utilizationOver: '#f87171',
120
+ },
121
+ timeline: {
122
+ gridLine: '#475569',
123
+ minorGridLine: '#334155',
124
+ tickMark: '#334155',
125
+ labelText: '#cbd5e1',
126
+ panelFill: '#0f172a',
127
+ border: '#334155',
128
+ },
129
+ header: {
130
+ cardBorder: '#475569',
131
+ author: '#94a3b8',
132
+ },
133
+ item: {
134
+ overflowX: '#f87171',
135
+ linkIconFg: '#94a3b8',
136
+ overflowTailFill: '#7f1d1d',
137
+ overflowTailStroke: '#f87171',
138
+ overflowCaption: '#fecaca',
139
+ },
140
+ parallel: {
141
+ bracketStroke: '#cbd5e1',
142
+ },
143
+ anchorDiamond: {
144
+ fill: '#0f172a',
145
+ stroke: '#cbd5e1',
146
+ label: '#cbd5e1',
147
+ cutLine: '#94a3b8',
148
+ },
149
+ milestoneDiamond: {
150
+ fill: '#e2e8f0',
151
+ label: '#e2e8f0',
152
+ cutLineNormal: '#a5b4fc',
153
+ cutLineOverrun: '#ef4444',
154
+ slack: '#cbd5e1',
155
+ },
156
+ footnotePanel: {
157
+ fill: '#0f172a',
158
+ border: '#334155',
159
+ header: '#e2e8f0',
160
+ title: '#e2e8f0',
161
+ description: '#94a3b8',
162
+ number: '#f87171',
163
+ },
164
+ nowline: {
165
+ stroke: '#f87171',
166
+ labelText: '#0b1220',
167
+ labelBg: '#f87171',
168
+ },
169
+ milestone: {
170
+ dashedInk: '#a5b4fc',
171
+ overrun: '#ef4444',
172
+ },
173
+ anchor: {
174
+ predecessorLine: '#94a3b8',
175
+ },
176
+ dependency: {
177
+ edgeStroke: '#cbd5e1',
178
+ overflowStroke: '#ef5350',
179
+ },
180
+ footnote: {
181
+ indicatorText: '#f87171',
182
+ descriptionMuted: '#94a3b8',
183
+ },
184
+ includeRegion: {
185
+ border: '#475569',
186
+ label: '#cbd5e1',
187
+ badge: '#94a3b8',
188
+ fill: '#0b1220',
189
+ tabFill: '#111827',
190
+ tabStroke: '#475569',
191
+ tabText: '#e2e8f0',
192
+ badgeFill: '#1e293b',
193
+ badgeStroke: '#475569',
194
+ badgeText: '#94a3b8',
195
+ },
196
+ arrowhead: {
197
+ neutral: '#94a3b8',
198
+ light: '#64748b',
199
+ dark: '#e2e8f0',
200
+ },
201
+ status: {
202
+ done: '#34d399',
203
+ inProgress: '#60a5fa',
204
+ atRisk: '#facc15',
205
+ blocked: '#ef4444',
206
+ planned: '#94a3b8',
207
+ neutral: '#94a3b8',
208
+ },
209
+ // Status-dot palettes — see `light.ts` for the contract. Same
210
+ // two palettes both themes; dark-theme bars come in BOTH dark
211
+ // (status-tint) and bright (label-driven) flavors, so a single
212
+ // palette can never satisfy both. The renderer picks per-bar
213
+ // based on the bar bg's relative luminance.
214
+ statusDot: {
215
+ onLight: {
216
+ done: '#065f46',
217
+ inProgress: '#1e3a8a',
218
+ atRisk: '#92400e',
219
+ blocked: '#991b1b',
220
+ planned: '#334155',
221
+ neutral: '#334155',
222
+ },
223
+ onDark: {
224
+ done: '#d1fae5',
225
+ inProgress: '#dbeafe',
226
+ atRisk: '#fef3c7',
227
+ blocked: '#fee2e2',
228
+ planned: '#e2e8f0',
229
+ neutral: '#e2e8f0',
230
+ },
231
+ },
232
+ attribution: {
233
+ mark: '#cbd5e1',
234
+ link: '#f87171',
235
+ },
236
+ diagnostic: {
237
+ overlayBg: '#7f1d1d',
238
+ errorText: '#fecaca',
239
+ },
240
+ };
241
+ //# sourceMappingURL=dark.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dark.js","sourceRoot":"","sources":["../../src/themes/dark.ts"],"names":[],"mappings":"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"}