@nowline/layout 0.2.5 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/inline-date-pin-geometry.d.ts +46 -0
- package/dist/inline-date-pin-geometry.d.ts.map +1 -0
- package/dist/inline-date-pin-geometry.js +149 -0
- package/dist/inline-date-pin-geometry.js.map +1 -0
- package/dist/item-bar-geometry.d.ts +30 -0
- package/dist/item-bar-geometry.d.ts.map +1 -1
- package/dist/item-bar-geometry.js +41 -0
- package/dist/item-bar-geometry.js.map +1 -1
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +93 -22
- package/dist/layout.js.map +1 -1
- package/dist/nodes/group-node.d.ts.map +1 -1
- package/dist/nodes/group-node.js +8 -0
- package/dist/nodes/group-node.js.map +1 -1
- package/dist/nodes/parallel-node.d.ts.map +1 -1
- package/dist/nodes/parallel-node.js +8 -0
- package/dist/nodes/parallel-node.js.map +1 -1
- package/dist/types.d.ts +33 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +12 -7
- package/src/inline-date-pin-geometry.ts +196 -0
- package/src/item-bar-geometry.ts +49 -0
- package/src/layout.ts +92 -22
- package/src/nodes/group-node.ts +8 -0
- package/src/nodes/parallel-node.ts +9 -0
- package/src/types.ts +34 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { BoundingBox, InlineDatePin } from './types.js';
|
|
2
|
+
export interface ItemInlineDatePinInputs {
|
|
3
|
+
box: BoundingBox;
|
|
4
|
+
/** ISO date string from `after:DATE`, or undefined when no inline `after`. */
|
|
5
|
+
afterDate: string | undefined;
|
|
6
|
+
/** ISO date string from `before:DATE`, or undefined when no inline `before`. */
|
|
7
|
+
beforeDate: string | undefined;
|
|
8
|
+
hasLinkIcon: boolean;
|
|
9
|
+
/** Number of footnote indicators rendered in the bar's top-RIGHT cluster. */
|
|
10
|
+
footnoteCount: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Compute inline-date pin glyph placements for an item bar. Returns an
|
|
14
|
+
* empty array when neither `afterDate` nor `beforeDate` is set.
|
|
15
|
+
*
|
|
16
|
+
* Item bars participate in the narrow-bar spill family — when the bar is
|
|
17
|
+
* narrower than `MIN_BAR_WIDTH_FOR_INLINE_DATE_PX`, the `before:` glyph
|
|
18
|
+
* spills RIGHT of the bar (joining the status-dot / footnote spill
|
|
19
|
+
* column) and the `after:` glyph spills LEFT of the bar's leading edge
|
|
20
|
+
* so the side semantics stay readable.
|
|
21
|
+
*/
|
|
22
|
+
export declare function computeItemInlineDatePins(opts: ItemInlineDatePinInputs): InlineDatePin[];
|
|
23
|
+
export interface ContainerInlineDatePinInputs {
|
|
24
|
+
/** Bounding box that anchors the glyph corners. For styled groups and
|
|
25
|
+
* bracketed parallels this is the visible box; for unstyled groups
|
|
26
|
+
* and bare parallels it is the logical bounding box (leftmost child
|
|
27
|
+
* start, rightmost child end, top of the highest child row). */
|
|
28
|
+
box: BoundingBox;
|
|
29
|
+
afterDate: string | undefined;
|
|
30
|
+
beforeDate: string | undefined;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Compute inline-date pin glyph placements for a container (group or
|
|
34
|
+
* parallel). The glyphs sit flush to the box's top-LEFT (`after`) and
|
|
35
|
+
* top-RIGHT (`before`) corners with the standard inset; containers
|
|
36
|
+
* never spill (they always have room for a 12 px tile in their own
|
|
37
|
+
* top-decoration row).
|
|
38
|
+
*/
|
|
39
|
+
export declare function computeContainerInlineDatePins(opts: ContainerInlineDatePinInputs): InlineDatePin[];
|
|
40
|
+
/**
|
|
41
|
+
* Returns the first ISO date literal in `values`, or undefined when none
|
|
42
|
+
* is present. The validator enforces "at most one inline date per
|
|
43
|
+
* direction" so this lookup is unambiguous.
|
|
44
|
+
*/
|
|
45
|
+
export declare function pickInlineDate(values: readonly string[]): string | undefined;
|
|
46
|
+
//# sourceMappingURL=inline-date-pin-geometry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inline-date-pin-geometry.d.ts","sourceRoot":"","sources":["../src/inline-date-pin-geometry.ts"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAS,MAAM,YAAY,CAAC;AAEpE,MAAM,WAAW,uBAAuB;IACpC,GAAG,EAAE,WAAW,CAAC;IACjB,8EAA8E;IAC9E,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,gFAAgF;IAChF,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,WAAW,EAAE,OAAO,CAAC;IACrB,6EAA6E;IAC7E,aAAa,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,uBAAuB,GAAG,aAAa,EAAE,CAmExF;AAED,MAAM,WAAW,4BAA4B;IACzC;;;qEAGiE;IACjE,GAAG,EAAE,WAAW,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAC1C,IAAI,EAAE,4BAA4B,GACnC,aAAa,EAAE,CAgCjB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAK5E"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// Inline-date pin glyph placement.
|
|
2
|
+
//
|
|
3
|
+
// `after:DATE` paints a calendar glyph in the entity's top-LEFT decoration
|
|
4
|
+
// slot; `before:DATE` paints it in the top-RIGHT slot. The two helpers
|
|
5
|
+
// below produce `Point` coordinates for the glyph's top-left corner, plus
|
|
6
|
+
// a `spilled` flag indicating whether the bar was too narrow to host the
|
|
7
|
+
// glyph inside (item case only — containers always have room).
|
|
8
|
+
//
|
|
9
|
+
// Slot interleaving rules (per specs/rendering.md "Inline-date glyph"):
|
|
10
|
+
//
|
|
11
|
+
// Item top-LEFT: glyph sits at the bar's leftmost slot when no link icon
|
|
12
|
+
// is present, otherwise one decoration step right of the link icon's
|
|
13
|
+
// right edge.
|
|
14
|
+
//
|
|
15
|
+
// Item top-RIGHT: glyph sits at the bar's rightmost slot when no status
|
|
16
|
+
// dot or footnotes are present, one step LEFT of the status dot when no
|
|
17
|
+
// footnotes, and one step LEFT of the LEFTMOST footnote indicator when
|
|
18
|
+
// footnotes are present (so the inline-date glyph inserts at the LEFT
|
|
19
|
+
// end of the existing badge cluster rather than reordering it).
|
|
20
|
+
//
|
|
21
|
+
// Container (group, parallel): glyph sits at the bounding box's top
|
|
22
|
+
// corners with the standard inset. Containers don't carry status dots
|
|
23
|
+
// or footnote indicators in their own decoration row, so no
|
|
24
|
+
// interleaving math is needed.
|
|
25
|
+
import { INLINE_DATE_GLYPH_GAP_PX, INLINE_DATE_GLYPH_INSET_LEFT_PX, INLINE_DATE_GLYPH_INSET_RIGHT_PX, INLINE_DATE_GLYPH_INSET_TOP_PX, INLINE_DATE_GLYPH_TILE_SIZE_PX, ITEM_CAPTION_SPILL_GAP_PX, ITEM_FOOTNOTE_INDICATOR_INSET_RIGHT_PX, ITEM_FOOTNOTE_INDICATOR_STEP_PX, ITEM_LINK_ICON_INSET_PX, ITEM_LINK_ICON_TILE_SIZE_PX, ITEM_STATUS_DOT_INSET_RIGHT_PX, ITEM_STATUS_DOT_RADIUS_PX, MIN_BAR_WIDTH_FOR_INLINE_DATE_PX, } from './item-bar-geometry.js';
|
|
26
|
+
/**
|
|
27
|
+
* Compute inline-date pin glyph placements for an item bar. Returns an
|
|
28
|
+
* empty array when neither `afterDate` nor `beforeDate` is set.
|
|
29
|
+
*
|
|
30
|
+
* Item bars participate in the narrow-bar spill family — when the bar is
|
|
31
|
+
* narrower than `MIN_BAR_WIDTH_FOR_INLINE_DATE_PX`, the `before:` glyph
|
|
32
|
+
* spills RIGHT of the bar (joining the status-dot / footnote spill
|
|
33
|
+
* column) and the `after:` glyph spills LEFT of the bar's leading edge
|
|
34
|
+
* so the side semantics stay readable.
|
|
35
|
+
*/
|
|
36
|
+
export function computeItemInlineDatePins(opts) {
|
|
37
|
+
const { box, afterDate, beforeDate, hasLinkIcon, footnoteCount } = opts;
|
|
38
|
+
if (!afterDate && !beforeDate)
|
|
39
|
+
return [];
|
|
40
|
+
const pins = [];
|
|
41
|
+
const tileSize = INLINE_DATE_GLYPH_TILE_SIZE_PX;
|
|
42
|
+
const topY = box.y + INLINE_DATE_GLYPH_INSET_TOP_PX;
|
|
43
|
+
const spilled = box.width < MIN_BAR_WIDTH_FOR_INLINE_DATE_PX;
|
|
44
|
+
if (afterDate) {
|
|
45
|
+
const insideLeftX = hasLinkIcon
|
|
46
|
+
? box.x +
|
|
47
|
+
ITEM_LINK_ICON_INSET_PX +
|
|
48
|
+
ITEM_LINK_ICON_TILE_SIZE_PX +
|
|
49
|
+
INLINE_DATE_GLYPH_GAP_PX
|
|
50
|
+
: box.x + INLINE_DATE_GLYPH_INSET_LEFT_PX;
|
|
51
|
+
const glyphLeft = spilled
|
|
52
|
+
? {
|
|
53
|
+
x: box.x - ITEM_CAPTION_SPILL_GAP_PX - tileSize,
|
|
54
|
+
y: topY,
|
|
55
|
+
}
|
|
56
|
+
: { x: insideLeftX, y: topY };
|
|
57
|
+
pins.push({
|
|
58
|
+
side: 'after',
|
|
59
|
+
isoDate: afterDate,
|
|
60
|
+
glyphTopLeft: glyphLeft,
|
|
61
|
+
glyphSize: tileSize,
|
|
62
|
+
spilled,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (beforeDate) {
|
|
66
|
+
// Walk LEFT from the rightmost top-decoration slot:
|
|
67
|
+
// - rightmost footnote anchors at (box.right - INSET_RIGHT_PX)
|
|
68
|
+
// - leftmost footnote sits one step further left per extra digit
|
|
69
|
+
// - status dot left edge sits at (box.right - INSET_RIGHT - DOT_RADIUS)
|
|
70
|
+
// - inline-date glyph sits one INLINE_DATE_GLYPH_GAP_PX further left
|
|
71
|
+
const rightEdge = box.x + box.width;
|
|
72
|
+
let anchorRightX;
|
|
73
|
+
if (footnoteCount > 0) {
|
|
74
|
+
const leftmostFootnoteCenter = rightEdge -
|
|
75
|
+
ITEM_FOOTNOTE_INDICATOR_INSET_RIGHT_PX -
|
|
76
|
+
(footnoteCount - 1) * ITEM_FOOTNOTE_INDICATOR_STEP_PX;
|
|
77
|
+
anchorRightX = leftmostFootnoteCenter - INLINE_DATE_GLYPH_GAP_PX;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
const dotLeftEdge = rightEdge - ITEM_STATUS_DOT_INSET_RIGHT_PX - ITEM_STATUS_DOT_RADIUS_PX;
|
|
81
|
+
anchorRightX = dotLeftEdge - INLINE_DATE_GLYPH_GAP_PX;
|
|
82
|
+
}
|
|
83
|
+
const insideRightX = anchorRightX - tileSize;
|
|
84
|
+
const glyphLeft = spilled
|
|
85
|
+
? {
|
|
86
|
+
x: rightEdge + ITEM_CAPTION_SPILL_GAP_PX,
|
|
87
|
+
y: topY,
|
|
88
|
+
}
|
|
89
|
+
: { x: insideRightX, y: topY };
|
|
90
|
+
pins.push({
|
|
91
|
+
side: 'before',
|
|
92
|
+
isoDate: beforeDate,
|
|
93
|
+
glyphTopLeft: glyphLeft,
|
|
94
|
+
glyphSize: tileSize,
|
|
95
|
+
spilled,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return pins;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Compute inline-date pin glyph placements for a container (group or
|
|
102
|
+
* parallel). The glyphs sit flush to the box's top-LEFT (`after`) and
|
|
103
|
+
* top-RIGHT (`before`) corners with the standard inset; containers
|
|
104
|
+
* never spill (they always have room for a 12 px tile in their own
|
|
105
|
+
* top-decoration row).
|
|
106
|
+
*/
|
|
107
|
+
export function computeContainerInlineDatePins(opts) {
|
|
108
|
+
const { box, afterDate, beforeDate } = opts;
|
|
109
|
+
if (!afterDate && !beforeDate)
|
|
110
|
+
return [];
|
|
111
|
+
const pins = [];
|
|
112
|
+
const tileSize = INLINE_DATE_GLYPH_TILE_SIZE_PX;
|
|
113
|
+
const topY = box.y + INLINE_DATE_GLYPH_INSET_TOP_PX;
|
|
114
|
+
if (afterDate) {
|
|
115
|
+
pins.push({
|
|
116
|
+
side: 'after',
|
|
117
|
+
isoDate: afterDate,
|
|
118
|
+
glyphTopLeft: { x: box.x + INLINE_DATE_GLYPH_INSET_LEFT_PX, y: topY },
|
|
119
|
+
glyphSize: tileSize,
|
|
120
|
+
spilled: false,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
if (beforeDate) {
|
|
124
|
+
pins.push({
|
|
125
|
+
side: 'before',
|
|
126
|
+
isoDate: beforeDate,
|
|
127
|
+
glyphTopLeft: {
|
|
128
|
+
x: box.x + box.width - INLINE_DATE_GLYPH_INSET_RIGHT_PX - tileSize,
|
|
129
|
+
y: topY,
|
|
130
|
+
},
|
|
131
|
+
glyphSize: tileSize,
|
|
132
|
+
spilled: false,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return pins;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Returns the first ISO date literal in `values`, or undefined when none
|
|
139
|
+
* is present. The validator enforces "at most one inline date per
|
|
140
|
+
* direction" so this lookup is unambiguous.
|
|
141
|
+
*/
|
|
142
|
+
export function pickInlineDate(values) {
|
|
143
|
+
for (const v of values) {
|
|
144
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(v))
|
|
145
|
+
return v;
|
|
146
|
+
}
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=inline-date-pin-geometry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inline-date-pin-geometry.js","sourceRoot":"","sources":["../src/inline-date-pin-geometry.ts"],"names":[],"mappings":"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"}
|
|
@@ -67,6 +67,36 @@ export declare const MIN_BAR_WIDTH_FOR_LINK_AND_DOT_PX: number;
|
|
|
67
67
|
* for one digit is 8px (font-size 10, bold).
|
|
68
68
|
*/
|
|
69
69
|
export declare const MIN_BAR_WIDTH_FOR_FOOTNOTE_PX: number;
|
|
70
|
+
/** Side length (px) of the inline-date calendar glyph tile. */
|
|
71
|
+
export declare const INLINE_DATE_GLYPH_TILE_SIZE_PX = 12;
|
|
72
|
+
/** Distance (px) from the bar's left edge to the glyph's left edge
|
|
73
|
+
* when the glyph sits at the leftmost top-decoration slot (no link
|
|
74
|
+
* icon present). */
|
|
75
|
+
export declare const INLINE_DATE_GLYPH_INSET_LEFT_PX = 6;
|
|
76
|
+
/** Distance (px) from the bar's right edge to the glyph's right edge
|
|
77
|
+
* when the glyph sits at the rightmost top-decoration slot (no
|
|
78
|
+
* status dot or footnote present). */
|
|
79
|
+
export declare const INLINE_DATE_GLYPH_INSET_RIGHT_PX = 6;
|
|
80
|
+
/** Distance (px) from the bar's top edge to the glyph's top edge. */
|
|
81
|
+
export declare const INLINE_DATE_GLYPH_INSET_TOP_PX = 5;
|
|
82
|
+
/** Horizontal gap (px) between the inline-date glyph and an adjacent
|
|
83
|
+
* decoration (link icon on the left, status dot / footnote indicator
|
|
84
|
+
* on the right). Matches the existing decoration spill gap so the
|
|
85
|
+
* top-decoration row reads as one rhythm. */
|
|
86
|
+
export declare const INLINE_DATE_GLYPH_GAP_PX = 4;
|
|
87
|
+
/**
|
|
88
|
+
* Minimum bar width (px) needed to host the inline-date glyph inside
|
|
89
|
+
* the bar. Below this, the glyph spills:
|
|
90
|
+
* - `before:` glyph spills RIGHT into the column the status dot
|
|
91
|
+
* uses (same family of decorations, same step pitch).
|
|
92
|
+
* - `after:` glyph spills LEFT of the bar's leading edge so the
|
|
93
|
+
* side semantics (after vs before) stay readable in the spill.
|
|
94
|
+
*
|
|
95
|
+
* The threshold reserves room for the glyph itself plus a small
|
|
96
|
+
* clearance from the link-icon column (when present) so the two
|
|
97
|
+
* glyphs don't overlap inside narrow bars.
|
|
98
|
+
*/
|
|
99
|
+
export declare const MIN_BAR_WIDTH_FOR_INLINE_DATE_PX: number;
|
|
70
100
|
/** Height (px) of a label chip rectangle. */
|
|
71
101
|
export declare const LABEL_CHIP_HEIGHT_PX = 13;
|
|
72
102
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"item-bar-geometry.d.ts","sourceRoot":"","sources":["../src/item-bar-geometry.ts"],"names":[],"mappings":"AAkBA,wEAAwE;AACxE,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAE3C,8DAA8D;AAC9D,eAAO,MAAM,qCAAqC,KAAK,CAAC;AAExD,2EAA2E;AAC3E,eAAO,MAAM,oCAAoC,KAAK,CAAC;AAEvD,wCAAwC;AACxC,eAAO,MAAM,+BAA+B,KAAK,CAAC;AAElD,uCAAuC;AACvC,eAAO,MAAM,8BAA8B,KAAK,CAAC;AAIjD,mEAAmE;AACnE,eAAO,MAAM,8BAA8B,KAAK,CAAC;AAEjD,iEAAiE;AACjE,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAE/C,qCAAqC;AACrC,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAI3C;;;GAGG;AACH,eAAO,MAAM,sCAAsC,KAAK,CAAC;AAEzD,oEAAoE;AACpE,eAAO,MAAM,0CAA0C,KAAK,CAAC;AAE7D;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,IAAI,CAAC;AAIjD,qDAAqD;AACrD,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C,0EAA0E;AAC1E,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAIzC;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAE9C;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,QAA6D,CAAC;AAEnG;;;;;;;GAOG;AACH,eAAO,MAAM,iCAAiC,QAKjB,CAAC;AAE9B;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,QAA6C,CAAC;
|
|
1
|
+
{"version":3,"file":"item-bar-geometry.d.ts","sourceRoot":"","sources":["../src/item-bar-geometry.ts"],"names":[],"mappings":"AAkBA,wEAAwE;AACxE,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAE3C,8DAA8D;AAC9D,eAAO,MAAM,qCAAqC,KAAK,CAAC;AAExD,2EAA2E;AAC3E,eAAO,MAAM,oCAAoC,KAAK,CAAC;AAEvD,wCAAwC;AACxC,eAAO,MAAM,+BAA+B,KAAK,CAAC;AAElD,uCAAuC;AACvC,eAAO,MAAM,8BAA8B,KAAK,CAAC;AAIjD,mEAAmE;AACnE,eAAO,MAAM,8BAA8B,KAAK,CAAC;AAEjD,iEAAiE;AACjE,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAE/C,qCAAqC;AACrC,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAI3C;;;GAGG;AACH,eAAO,MAAM,sCAAsC,KAAK,CAAC;AAEzD,oEAAoE;AACpE,eAAO,MAAM,0CAA0C,KAAK,CAAC;AAE7D;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,IAAI,CAAC;AAIjD,qDAAqD;AACrD,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C,0EAA0E;AAC1E,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAIzC;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAE9C;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,QAA6D,CAAC;AAEnG;;;;;;;GAOG;AACH,eAAO,MAAM,iCAAiC,QAKjB,CAAC;AAE9B;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,QAA6C,CAAC;AAUxF,+DAA+D;AAC/D,eAAO,MAAM,8BAA8B,KAAK,CAAC;AAEjD;;qBAEqB;AACrB,eAAO,MAAM,+BAA+B,IAAI,CAAC;AAEjD;;uCAEuC;AACvC,eAAO,MAAM,gCAAgC,IAAI,CAAC;AAElD,qEAAqE;AACrE,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAEhD;;;8CAG8C;AAC9C,eAAO,MAAM,wBAAwB,IAA+B,CAAC;AAErE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gCAAgC,QAKT,CAAC;AAIrC,6CAA6C;AAC7C,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,sCAAsC,IAAI,CAAC;AAExD,8DAA8D;AAC9D,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAE3C;;;GAGG;AACH,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC;;;GAGG;AACH,eAAO,MAAM,sBAAsB,QAA+C,CAAC;AAEnF;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C,MAAM,WAAW,aAAa,CAAC,CAAC;IAC5B,EAAE,EAAE,CAAC,CAAC;IACN,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa,CAAC,CAAC;IAC5B;;qBAEiB;IACjB,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAC3B;;qDAEiD;IACjD,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC5B,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,EACzB,cAAc,EAAE,MAAM,GACvB,aAAa,CAAC,CAAC,CAAC,CAkClB"}
|
|
@@ -91,6 +91,47 @@ export const MIN_BAR_WIDTH_FOR_LINK_AND_DOT_PX = ITEM_LINK_ICON_INSET_PX +
|
|
|
91
91
|
* for one digit is 8px (font-size 10, bold).
|
|
92
92
|
*/
|
|
93
93
|
export const MIN_BAR_WIDTH_FOR_FOOTNOTE_PX = ITEM_FOOTNOTE_INDICATOR_INSET_RIGHT_PX + 1;
|
|
94
|
+
// ---- Inline-date glyph (after:DATE / before:DATE corner badge) ---
|
|
95
|
+
//
|
|
96
|
+
// Renders the renderer's built-in `calendar` SVG at top-LEFT (`after`)
|
|
97
|
+
// or top-RIGHT (`before`) of the entity bar. Sized as a sibling of
|
|
98
|
+
// the status dot and footnote indicators (smaller than the link tile)
|
|
99
|
+
// so the top-decoration row stays visually unified. See
|
|
100
|
+
// specs/rendering.md "Inline-date glyph".
|
|
101
|
+
/** Side length (px) of the inline-date calendar glyph tile. */
|
|
102
|
+
export const INLINE_DATE_GLYPH_TILE_SIZE_PX = 12;
|
|
103
|
+
/** Distance (px) from the bar's left edge to the glyph's left edge
|
|
104
|
+
* when the glyph sits at the leftmost top-decoration slot (no link
|
|
105
|
+
* icon present). */
|
|
106
|
+
export const INLINE_DATE_GLYPH_INSET_LEFT_PX = 6;
|
|
107
|
+
/** Distance (px) from the bar's right edge to the glyph's right edge
|
|
108
|
+
* when the glyph sits at the rightmost top-decoration slot (no
|
|
109
|
+
* status dot or footnote present). */
|
|
110
|
+
export const INLINE_DATE_GLYPH_INSET_RIGHT_PX = 6;
|
|
111
|
+
/** Distance (px) from the bar's top edge to the glyph's top edge. */
|
|
112
|
+
export const INLINE_DATE_GLYPH_INSET_TOP_PX = 5;
|
|
113
|
+
/** Horizontal gap (px) between the inline-date glyph and an adjacent
|
|
114
|
+
* decoration (link icon on the left, status dot / footnote indicator
|
|
115
|
+
* on the right). Matches the existing decoration spill gap so the
|
|
116
|
+
* top-decoration row reads as one rhythm. */
|
|
117
|
+
export const INLINE_DATE_GLYPH_GAP_PX = ITEM_DECORATION_SPILL_GAP_PX;
|
|
118
|
+
/**
|
|
119
|
+
* Minimum bar width (px) needed to host the inline-date glyph inside
|
|
120
|
+
* the bar. Below this, the glyph spills:
|
|
121
|
+
* - `before:` glyph spills RIGHT into the column the status dot
|
|
122
|
+
* uses (same family of decorations, same step pitch).
|
|
123
|
+
* - `after:` glyph spills LEFT of the bar's leading edge so the
|
|
124
|
+
* side semantics (after vs before) stay readable in the spill.
|
|
125
|
+
*
|
|
126
|
+
* The threshold reserves room for the glyph itself plus a small
|
|
127
|
+
* clearance from the link-icon column (when present) so the two
|
|
128
|
+
* glyphs don't overlap inside narrow bars.
|
|
129
|
+
*/
|
|
130
|
+
export const MIN_BAR_WIDTH_FOR_INLINE_DATE_PX = INLINE_DATE_GLYPH_INSET_LEFT_PX +
|
|
131
|
+
INLINE_DATE_GLYPH_TILE_SIZE_PX +
|
|
132
|
+
INLINE_DATE_GLYPH_GAP_PX +
|
|
133
|
+
INLINE_DATE_GLYPH_TILE_SIZE_PX +
|
|
134
|
+
INLINE_DATE_GLYPH_INSET_RIGHT_PX;
|
|
94
135
|
// ---- Label chips (along the bar's bottom) ------------------------
|
|
95
136
|
/** Height (px) of a label chip rectangle. */
|
|
96
137
|
export const LABEL_CHIP_HEIGHT_PX = 13;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"item-bar-geometry.js","sourceRoot":"","sources":["../src/item-bar-geometry.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"item-bar-geometry.js","sourceRoot":"","sources":["../src/item-bar-geometry.ts"],"names":[],"mappings":"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"}
|
package/dist/layout.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAKR,WAAW,EAEX,aAAa,EAEhB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAKR,WAAW,EAEX,aAAa,EAEhB,MAAM,eAAe,CAAC;AA2DvB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAanD,OAAO,KAAK,EAYR,iBAAiB,EAIpB,MAAM,YAAY,CAAC;AAIpB,MAAM,WAAW,aAAa;IAC1B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAAC;AAu2C7C,wBAAgB,aAAa,CACzB,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,aAAa,EACvB,OAAO,GAAE,aAAkB,GAC5B,YAAY,CAcd"}
|
package/dist/layout.js
CHANGED
|
@@ -5,6 +5,7 @@ import { parseDate, propValue, propValues } from './dsl-utils.js';
|
|
|
5
5
|
import { ChannelGrid, collectRoutingObstacles, routeChannelEdges, } from './edge-routing.js';
|
|
6
6
|
import { HEADER_AUTHOR_FONT_SIZE_PX, HEADER_AUTHOR_LINE_HEIGHT_PX, HEADER_CARD_PADDING_BOTTOM, HEADER_CARD_PADDING_TOP, HEADER_CARD_PADDING_X, HEADER_TITLE_FONT_SIZE_PX, HEADER_TITLE_LINE_HEIGHT_PX, HEADER_TITLE_TO_AUTHOR_GAP_PX, } from './header-card-geometry.js';
|
|
7
7
|
import { localeStrings } from './i18n.js';
|
|
8
|
+
import { computeItemInlineDatePins, pickInlineDate } from './inline-date-pin-geometry.js';
|
|
8
9
|
import { ITEM_CAPTION_INSET_X_PX, ITEM_CAPTION_META_BASELINE_OFFSET_PX, ITEM_CAPTION_SPILL_GAP_PX, ITEM_CAPTION_TITLE_FONT_SIZE_PX, ITEM_DECORATION_SPILL_GAP_PX, ITEM_FOOTNOTE_INDICATOR_STEP_PX, ITEM_LINK_ICON_TILE_SIZE_PX, ITEM_STATUS_DOT_RADIUS_PX, LABEL_CHIP_GAP_ABOVE_PROGRESS_STRIP_PX, LABEL_CHIP_GAP_BETWEEN_PX, LABEL_CHIP_HEIGHT_PX, LABEL_CHIP_ROW_STEP_PX, MIN_BAR_WIDTH_FOR_DOT_PX, MIN_BAR_WIDTH_FOR_FOOTNOTE_PX, MIN_BAR_WIDTH_FOR_LINK_AND_DOT_PX, packSpillChips, } from './item-bar-geometry.js';
|
|
9
10
|
import { newCursor } from './layout-context.js';
|
|
10
11
|
import { GroupNode } from './nodes/group-node.js';
|
|
@@ -111,10 +112,14 @@ function sequenceItem(node, cursor, ctx, ownerOverride) {
|
|
|
111
112
|
// "one engineer-week of work left".
|
|
112
113
|
const totalEffortDays = deriveTotalEffortDays(props, ctx.sizes, ctx.cal);
|
|
113
114
|
const afterRaw = propValues(props, 'after');
|
|
114
|
-
const beforeRaw =
|
|
115
|
+
const beforeRaw = propValues(props, 'before');
|
|
115
116
|
const dateRaw = propValue(props, 'date');
|
|
116
117
|
const remainingDays = resolveDuration(propValue(props, 'remaining'), ctx.sizes, ctx.cal);
|
|
117
|
-
// Resolve start x: explicit date > after-chain > cursor position
|
|
118
|
+
// Resolve start x: explicit date > after-chain > cursor position.
|
|
119
|
+
// `after:` accepts both entity ids (looked up in entityRightEdges) and
|
|
120
|
+
// inline ISO date literals (resolved through the time scale). The
|
|
121
|
+
// validator enforces "at most one inline date per direction" so at most
|
|
122
|
+
// one element will hit the date path per item.
|
|
118
123
|
let startX = cursor.x;
|
|
119
124
|
const explicitDate = parseDate(dateRaw);
|
|
120
125
|
if (explicitDate) {
|
|
@@ -125,6 +130,13 @@ function sequenceItem(node, cursor, ctx, ownerOverride) {
|
|
|
125
130
|
else if (afterRaw.length > 0) {
|
|
126
131
|
let maxEnd = cursor.x;
|
|
127
132
|
for (const ref of afterRaw) {
|
|
133
|
+
const inlineDate = parseDate(ref);
|
|
134
|
+
if (inlineDate) {
|
|
135
|
+
const xd = ctx.scale.forwardWithinDomain(inlineDate);
|
|
136
|
+
if (xd !== null)
|
|
137
|
+
maxEnd = Math.max(maxEnd, xd);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
128
140
|
const endX = ctx.entityRightEdges.get(ref);
|
|
129
141
|
if (endX !== undefined)
|
|
130
142
|
maxEnd = Math.max(maxEnd, endX);
|
|
@@ -171,24 +183,39 @@ function sequenceItem(node, cursor, ctx, ownerOverride) {
|
|
|
171
183
|
}
|
|
172
184
|
const chipInsideAvailWidth = Math.max(0, visualWidthPredict - 2 * ITEM_CAPTION_INSET_X_PX);
|
|
173
185
|
const chipsOutside = chipSamples.length > 0 && chipRowWidth > chipInsideAvailWidth;
|
|
174
|
-
// Handle `before:` — item must end by the
|
|
186
|
+
// Handle `before:` — item must end by the earliest cap. Each cap is
|
|
187
|
+
// either an entity id (looked up in entityLeftEdges) or an inline ISO
|
|
188
|
+
// date literal (resolved through the time scale). The validator enforces
|
|
189
|
+
// "at most one inline date per direction" so at most one element per
|
|
190
|
+
// before-list will hit the date path.
|
|
175
191
|
let hasOverflow = false;
|
|
176
192
|
let overflowBox;
|
|
177
193
|
let overflowAnchorId;
|
|
178
|
-
if (beforeRaw) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
194
|
+
if (beforeRaw.length > 0) {
|
|
195
|
+
let earliestCapX;
|
|
196
|
+
let earliestCapRef;
|
|
197
|
+
for (const ref of beforeRaw) {
|
|
198
|
+
const inlineDate = parseDate(ref);
|
|
199
|
+
const capX = inlineDate
|
|
200
|
+
? (ctx.scale.forwardWithinDomain(inlineDate) ?? undefined)
|
|
201
|
+
: ctx.entityLeftEdges.get(ref);
|
|
202
|
+
if (capX === undefined)
|
|
203
|
+
continue;
|
|
204
|
+
if (earliestCapX === undefined || capX < earliestCapX) {
|
|
205
|
+
earliestCapX = capX;
|
|
206
|
+
earliestCapRef = ref;
|
|
190
207
|
}
|
|
191
208
|
}
|
|
209
|
+
if (earliestCapX !== undefined && logicalRight > earliestCapX) {
|
|
210
|
+
hasOverflow = true;
|
|
211
|
+
overflowBox = {
|
|
212
|
+
x: earliestCapX,
|
|
213
|
+
y: cursor.y,
|
|
214
|
+
width: logicalRight - earliestCapX,
|
|
215
|
+
height: ctx.bandScale.bandwidth(),
|
|
216
|
+
};
|
|
217
|
+
overflowAnchorId = earliestCapRef;
|
|
218
|
+
}
|
|
192
219
|
}
|
|
193
220
|
// Progress fraction
|
|
194
221
|
const statusRaw = propValue(props, 'status');
|
|
@@ -564,6 +591,13 @@ function sequenceItem(node, cursor, ctx, ownerOverride) {
|
|
|
564
591
|
// inter-row gap stays constant — the next row's bar starts
|
|
565
592
|
// `step − bandwidth` px below the (now-taller) bar bottom.
|
|
566
593
|
cursor.height = Math.max(cursor.height, ctx.bandScale.step() + chipBarExtra);
|
|
594
|
+
const inlineDatePins = computeItemInlineDatePins({
|
|
595
|
+
box: itemBox,
|
|
596
|
+
afterDate: pickInlineDate(afterRaw),
|
|
597
|
+
beforeDate: pickInlineDate(beforeRaw),
|
|
598
|
+
hasLinkIcon,
|
|
599
|
+
footnoteCount: footnoteIndicators.length,
|
|
600
|
+
});
|
|
567
601
|
const result = {
|
|
568
602
|
kind: 'item',
|
|
569
603
|
id,
|
|
@@ -594,6 +628,7 @@ function sequenceItem(node, cursor, ctx, ownerOverride) {
|
|
|
594
628
|
capacity,
|
|
595
629
|
size: sizeResolved,
|
|
596
630
|
style,
|
|
631
|
+
inlineDatePins: inlineDatePins.length > 0 ? inlineDatePins : undefined,
|
|
597
632
|
};
|
|
598
633
|
return result;
|
|
599
634
|
}
|
|
@@ -738,6 +773,11 @@ function predictItemChipExtraHeight(item, ctx) {
|
|
|
738
773
|
// pin) > `start:` (fixed pin) > `after:` (chain after refs) > sequential
|
|
739
774
|
// default (continue from `seqDefault`, which is the lane's rightmost time
|
|
740
775
|
// cursor across all rows).
|
|
776
|
+
//
|
|
777
|
+
// `after:` accepts both entity ids (looked up in `ctx.entityRightEdges`) and
|
|
778
|
+
// inline ISO date literals (looked up via `ctx.scale.forwardWithinDomain`).
|
|
779
|
+
// The validator already enforces "at most one inline date per direction" so
|
|
780
|
+
// at most one element in the list will hit the date path.
|
|
741
781
|
function resolveChildStart(props, seqDefault, laneLeftX, ctx) {
|
|
742
782
|
const explicitDate = parseDate(propValue(props, 'date')) ?? parseDate(propValue(props, 'start'));
|
|
743
783
|
if (explicitDate) {
|
|
@@ -749,6 +789,13 @@ function resolveChildStart(props, seqDefault, laneLeftX, ctx) {
|
|
|
749
789
|
if (afterRefs.length > 0) {
|
|
750
790
|
let maxEnd = laneLeftX;
|
|
751
791
|
for (const ref of afterRefs) {
|
|
792
|
+
const inlineDate = parseDate(ref);
|
|
793
|
+
if (inlineDate) {
|
|
794
|
+
const xd = ctx.scale.forwardWithinDomain(inlineDate);
|
|
795
|
+
if (xd !== null)
|
|
796
|
+
maxEnd = Math.max(maxEnd, xd);
|
|
797
|
+
continue;
|
|
798
|
+
}
|
|
752
799
|
const endX = ctx.entityRightEdges.get(ref);
|
|
753
800
|
if (endX !== undefined)
|
|
754
801
|
maxEnd = Math.max(maxEnd, endX);
|
|
@@ -912,7 +959,15 @@ function computeContentEndDay(resolved, ctx, startDate, today) {
|
|
|
912
959
|
const anchorEnd = new Map();
|
|
913
960
|
const milestoneEnd = new Map();
|
|
914
961
|
let maxDay = 0;
|
|
915
|
-
|
|
962
|
+
// Resolve a single `after:` element to a day-offset from `startDate`.
|
|
963
|
+
// The element is either an entity id (looked up in itemEnd / anchorEnd /
|
|
964
|
+
// milestoneEnd) or an inline ISO date literal (converted directly via
|
|
965
|
+
// `daysBetween`). The validator already enforces "at most one inline date
|
|
966
|
+
// per direction", so at most one element per list will hit the date path.
|
|
967
|
+
const resolveAfterDay = (ref) => {
|
|
968
|
+
const inlineDate = parseDate(ref);
|
|
969
|
+
if (inlineDate)
|
|
970
|
+
return daysBetween(startDate, inlineDate);
|
|
916
971
|
if (itemEnd.has(ref))
|
|
917
972
|
return itemEnd.get(ref);
|
|
918
973
|
if (anchorEnd.has(ref))
|
|
@@ -955,7 +1010,7 @@ function computeContentEndDay(resolved, ctx, startDate, today) {
|
|
|
955
1010
|
start = daysBetween(startDate, startProp);
|
|
956
1011
|
}
|
|
957
1012
|
else if (afterRefs.length > 0) {
|
|
958
|
-
start = Math.max(prevEnd, ...afterRefs.map(
|
|
1013
|
+
start = Math.max(prevEnd, ...afterRefs.map(resolveAfterDay));
|
|
959
1014
|
}
|
|
960
1015
|
const end = start + dur;
|
|
961
1016
|
if (node.name)
|
|
@@ -964,18 +1019,29 @@ function computeContentEndDay(resolved, ctx, startDate, today) {
|
|
|
964
1019
|
}
|
|
965
1020
|
if (isParallelBlock(node)) {
|
|
966
1021
|
// All children share the parallel's start; the block's effective
|
|
967
|
-
// end is the maximum child end.
|
|
968
|
-
|
|
1022
|
+
// end is the maximum child end. The parallel's own `after:`
|
|
1023
|
+
// (including inline-date pins) widens that shared start.
|
|
1024
|
+
const afterRefs = propValues(node.properties, 'after');
|
|
1025
|
+
const containerStart = afterRefs.length > 0
|
|
1026
|
+
? Math.max(prevEnd, ...afterRefs.map(resolveAfterDay))
|
|
1027
|
+
: prevEnd;
|
|
1028
|
+
let parallelEnd = containerStart;
|
|
969
1029
|
for (const child of node.content) {
|
|
970
1030
|
if (child.$type === 'DescriptionDirective')
|
|
971
1031
|
continue;
|
|
972
|
-
const childEnd = walkNode(child,
|
|
1032
|
+
const childEnd = walkNode(child, containerStart);
|
|
973
1033
|
parallelEnd = Math.max(parallelEnd, childEnd);
|
|
974
1034
|
}
|
|
975
1035
|
return parallelEnd;
|
|
976
1036
|
}
|
|
977
1037
|
if (isGroupBlock(node)) {
|
|
978
|
-
|
|
1038
|
+
// The group's own `after:` (including inline-date pins) widens
|
|
1039
|
+
// the baseline before walking the inner sequential lane.
|
|
1040
|
+
const afterRefs = propValues(node.properties, 'after');
|
|
1041
|
+
const containerStart = afterRefs.length > 0
|
|
1042
|
+
? Math.max(prevEnd, ...afterRefs.map(resolveAfterDay))
|
|
1043
|
+
: prevEnd;
|
|
1044
|
+
return walkLane(node.content, containerStart);
|
|
979
1045
|
}
|
|
980
1046
|
return prevEnd;
|
|
981
1047
|
};
|
|
@@ -994,7 +1060,12 @@ function computeContentEndDay(resolved, ctx, startDate, today) {
|
|
|
994
1060
|
}
|
|
995
1061
|
const after = propValues(ms.properties, 'after');
|
|
996
1062
|
if (after.length > 0) {
|
|
997
|
-
|
|
1063
|
+
// Milestones disallow inline date literals at the validator
|
|
1064
|
+
// level (rule 24a — milestones already have `date:`). The
|
|
1065
|
+
// shared `resolveAfterDay` helper still handles such input
|
|
1066
|
+
// gracefully if it slips past, treating the date as the
|
|
1067
|
+
// milestone's effective day.
|
|
1068
|
+
const day = Math.max(0, ...after.map(resolveAfterDay));
|
|
998
1069
|
if (ms.name)
|
|
999
1070
|
milestoneEnd.set(ms.name, day);
|
|
1000
1071
|
maxDay = Math.max(maxDay, day);
|