@nowline/layout 0.6.0 → 0.8.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.
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/layout-insights.d.ts +26 -0
- package/dist/layout-insights.d.ts.map +1 -0
- package/dist/layout-insights.js +100 -0
- package/dist/layout-insights.js.map +1 -0
- package/package.json +3 -3
- package/src/index.ts +6 -0
- package/src/layout-insights.ts +160 -0
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { INCLUDE_CHROME_BADGE_GAP_PX, INCLUDE_CHROME_BADGE_SIZE_PX, INCLUDE_CHRO
|
|
|
5
5
|
export { ITEM_CAPTION_INSET_X_PX, ITEM_CAPTION_META_BASELINE_OFFSET_PX, ITEM_CAPTION_META_FONT_SIZE_PX, ITEM_CAPTION_SPILL_GAP_PX, ITEM_CAPTION_TITLE_BASELINE_OFFSET_PX, ITEM_CAPTION_TITLE_FONT_SIZE_PX, ITEM_DECORATION_SPILL_GAP_PX, ITEM_FOOTNOTE_INDICATOR_BASELINE_OFFSET_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_INSET_TOP_PX, ITEM_STATUS_DOT_RADIUS_PX, LABEL_CHIP_GAP_ABOVE_PROGRESS_STRIP_PX, LABEL_CHIP_GAP_BETWEEN_PX, LABEL_CHIP_HEIGHT_PX, MIN_BAR_WIDTH_FOR_DOT_PX, MIN_BAR_WIDTH_FOR_FOOTNOTE_PX, MIN_BAR_WIDTH_FOR_LINK_AND_DOT_PX, } from './item-bar-geometry.js';
|
|
6
6
|
export type { LayoutOptions, LayoutResult } from './layout.js';
|
|
7
7
|
export { layoutRoadmap } from './layout.js';
|
|
8
|
+
export { collectLayoutInsights, type LayoutInsight, type LayoutInsightContext, type LayoutInsightSeverity, } from './layout-insights.js';
|
|
8
9
|
export { civilDateInZone, type NormalizedZone, normalizeZone, type ResolveTodayOptions, resolveToday, TimezoneError, } from './resolve-today.js';
|
|
9
10
|
export type { RoadmapSchedule, ScheduledItem, ScheduleOptions } from './schedule.js';
|
|
10
11
|
export { scheduleRoadmap } from './schedule.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,2BAA2B,EAC3B,oBAAoB,EACpB,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,mBAAmB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EACH,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,EACxB,2BAA2B,EAC3B,KAAK,gBAAgB,EACrB,gBAAgB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACH,0BAA0B,EAC1B,4BAA4B,EAC5B,0BAA0B,EAC1B,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,GAChC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACH,2BAA2B,EAC3B,4BAA4B,EAC5B,iCAAiC,EACjC,4BAA4B,EAC5B,iCAAiC,EACjC,iCAAiC,EACjC,oCAAoC,EACpC,gCAAgC,EAChC,+BAA+B,EAC/B,iCAAiC,EACjC,KAAK,qBAAqB,EAC1B,qBAAqB,GACxB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACH,uBAAuB,EACvB,oCAAoC,EACpC,8BAA8B,EAC9B,yBAAyB,EACzB,qCAAqC,EACrC,+BAA+B,EAC/B,4BAA4B,EAC5B,0CAA0C,EAC1C,sCAAsC,EACtC,+BAA+B,EAC/B,uBAAuB,EACvB,2BAA2B,EAC3B,8BAA8B,EAC9B,4BAA4B,EAC5B,yBAAyB,EACzB,sCAAsC,EACtC,yBAAyB,EACzB,oBAAoB,EACpB,wBAAwB,EACxB,6BAA6B,EAC7B,iCAAiC,GACpC,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACH,eAAe,EACf,KAAK,cAAc,EACnB,aAAa,EACb,KAAK,mBAAmB,EACxB,YAAY,EACZ,aAAa,GAChB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACH,SAAS,EACT,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,KAAK,KAAK,EACV,KAAK,SAAS,EACd,MAAM,GACT,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACH,mBAAmB,EACnB,6BAA6B,EAC7B,yBAAyB,EACzB,yBAAyB,EACzB,gBAAgB,EAChB,yBAAyB,EACzB,4BAA4B,EAC5B,iBAAiB,EACjB,gBAAgB,EAChB,8BAA8B,EAC9B,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,EACV,kCAAkC,EAClC,yBAAyB,EACzB,yBAAyB,EACzB,mBAAmB,EACnB,mBAAmB,EACnB,kCAAkC,EAClC,mBAAmB,EACnB,+BAA+B,EAC/B,6BAA6B,EAC7B,yBAAyB,EACzB,yBAAyB,EACzB,wCAAwC,EACxC,kCAAkC,EAClC,wBAAwB,EACxB,yBAAyB,EACzB,kBAAkB,EAClB,iCAAiC,EACjC,2BAA2B,EAC3B,yBAAyB,EACzB,iBAAiB,EACjB,uBAAuB,EACvB,wBAAwB,EACxB,YAAY,EACZ,sCAAsC,EACtC,6BAA6B,EAC7B,0BAA0B,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,2BAA2B,EAC3B,oBAAoB,EACpB,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,mBAAmB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EACH,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,EACxB,2BAA2B,EAC3B,KAAK,gBAAgB,EACrB,gBAAgB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACH,0BAA0B,EAC1B,4BAA4B,EAC5B,0BAA0B,EAC1B,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,GAChC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACH,2BAA2B,EAC3B,4BAA4B,EAC5B,iCAAiC,EACjC,4BAA4B,EAC5B,iCAAiC,EACjC,iCAAiC,EACjC,oCAAoC,EACpC,gCAAgC,EAChC,+BAA+B,EAC/B,iCAAiC,EACjC,KAAK,qBAAqB,EAC1B,qBAAqB,GACxB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACH,uBAAuB,EACvB,oCAAoC,EACpC,8BAA8B,EAC9B,yBAAyB,EACzB,qCAAqC,EACrC,+BAA+B,EAC/B,4BAA4B,EAC5B,0CAA0C,EAC1C,sCAAsC,EACtC,+BAA+B,EAC/B,uBAAuB,EACvB,2BAA2B,EAC3B,8BAA8B,EAC9B,4BAA4B,EAC5B,yBAAyB,EACzB,sCAAsC,EACtC,yBAAyB,EACzB,oBAAoB,EACpB,wBAAwB,EACxB,6BAA6B,EAC7B,iCAAiC,GACpC,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACH,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,GAC7B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACH,eAAe,EACf,KAAK,cAAc,EACnB,aAAa,EACb,KAAK,mBAAmB,EACxB,YAAY,EACZ,aAAa,GAChB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACH,SAAS,EACT,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,KAAK,KAAK,EACV,KAAK,SAAS,EACd,MAAM,GACT,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACH,mBAAmB,EACnB,6BAA6B,EAC7B,yBAAyB,EACzB,yBAAyB,EACzB,gBAAgB,EAChB,yBAAyB,EACzB,4BAA4B,EAC5B,iBAAiB,EACjB,gBAAgB,EAChB,8BAA8B,EAC9B,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,EACV,kCAAkC,EAClC,yBAAyB,EACzB,yBAAyB,EACzB,mBAAmB,EACnB,mBAAmB,EACnB,kCAAkC,EAClC,mBAAmB,EACnB,+BAA+B,EAC/B,6BAA6B,EAC7B,yBAAyB,EACzB,yBAAyB,EACzB,wCAAwC,EACxC,kCAAkC,EAClC,wBAAwB,EACxB,yBAAyB,EACzB,kBAAkB,EAClB,iCAAiC,EACjC,2BAA2B,EAC3B,yBAAyB,EACzB,iBAAiB,EACjB,uBAAuB,EACvB,wBAAwB,EACxB,YAAY,EACZ,sCAAsC,EACtC,6BAA6B,EAC7B,0BAA0B,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ export { HEADER_AUTHOR_FONT_SIZE_PX, HEADER_AUTHOR_LINE_HEIGHT_PX, HEADER_CARD_P
|
|
|
4
4
|
export { INCLUDE_CHROME_BADGE_GAP_PX, INCLUDE_CHROME_BADGE_SIZE_PX, INCLUDE_CHROME_OFFSET_FROM_BOX_PX, INCLUDE_CHROME_SOURCE_GAP_PX, INCLUDE_CHROME_SOURCE_HALO_PAD_PX, INCLUDE_CHROME_SOURCE_PER_CHAR_PX, INCLUDE_CHROME_TAB_LABEL_PER_CHAR_PX, INCLUDE_CHROME_TAB_LEFT_INSET_PX, INCLUDE_CHROME_TAB_MIN_WIDTH_PX, INCLUDE_CHROME_TAB_RIGHT_INSET_PX, includeChromeGeometry, } from './include-chrome-geometry.js';
|
|
5
5
|
export { ITEM_CAPTION_INSET_X_PX, ITEM_CAPTION_META_BASELINE_OFFSET_PX, ITEM_CAPTION_META_FONT_SIZE_PX, ITEM_CAPTION_SPILL_GAP_PX, ITEM_CAPTION_TITLE_BASELINE_OFFSET_PX, ITEM_CAPTION_TITLE_FONT_SIZE_PX, ITEM_DECORATION_SPILL_GAP_PX, ITEM_FOOTNOTE_INDICATOR_BASELINE_OFFSET_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_INSET_TOP_PX, ITEM_STATUS_DOT_RADIUS_PX, LABEL_CHIP_GAP_ABOVE_PROGRESS_STRIP_PX, LABEL_CHIP_GAP_BETWEEN_PX, LABEL_CHIP_HEIGHT_PX, MIN_BAR_WIDTH_FOR_DOT_PX, MIN_BAR_WIDTH_FOR_FOOTNOTE_PX, MIN_BAR_WIDTH_FOR_LINK_AND_DOT_PX, } from './item-bar-geometry.js';
|
|
6
6
|
export { layoutRoadmap } from './layout.js';
|
|
7
|
+
export { collectLayoutInsights, } from './layout-insights.js';
|
|
7
8
|
export { civilDateInZone, normalizeZone, resolveToday, TimezoneError, } from './resolve-today.js';
|
|
8
9
|
export { scheduleRoadmap } from './schedule.js';
|
|
9
10
|
export { darkTheme, grayscaleTheme, lightTheme, normalizeThemeName, themes, } from './themes/index.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,2BAA2B,EAC3B,oBAAoB,EACpB,kBAAkB,EAElB,mBAAmB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EACH,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,EACxB,2BAA2B,EAE3B,gBAAgB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACH,0BAA0B,EAC1B,4BAA4B,EAC5B,0BAA0B,EAC1B,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,GAChC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACH,2BAA2B,EAC3B,4BAA4B,EAC5B,iCAAiC,EACjC,4BAA4B,EAC5B,iCAAiC,EACjC,iCAAiC,EACjC,oCAAoC,EACpC,gCAAgC,EAChC,+BAA+B,EAC/B,iCAAiC,EAEjC,qBAAqB,GACxB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACH,uBAAuB,EACvB,oCAAoC,EACpC,8BAA8B,EAC9B,yBAAyB,EACzB,qCAAqC,EACrC,+BAA+B,EAC/B,4BAA4B,EAC5B,0CAA0C,EAC1C,sCAAsC,EACtC,+BAA+B,EAC/B,uBAAuB,EACvB,2BAA2B,EAC3B,8BAA8B,EAC9B,4BAA4B,EAC5B,yBAAyB,EACzB,sCAAsC,EACtC,yBAAyB,EACzB,oBAAoB,EACpB,wBAAwB,EACxB,6BAA6B,EAC7B,iCAAiC,GACpC,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACH,eAAe,EAEf,aAAa,EAEb,YAAY,EACZ,aAAa,GAChB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACH,SAAS,EACT,cAAc,EACd,UAAU,EACV,kBAAkB,EAGlB,MAAM,GACT,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACH,mBAAmB,EACnB,6BAA6B,EAC7B,yBAAyB,EACzB,yBAAyB,EACzB,gBAAgB,EAChB,yBAAyB,EACzB,4BAA4B,EAC5B,iBAAiB,EACjB,gBAAgB,EAChB,8BAA8B,EAC9B,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,EACV,kCAAkC,EAClC,yBAAyB,EACzB,yBAAyB,EACzB,mBAAmB,EACnB,mBAAmB,EACnB,kCAAkC,EAClC,mBAAmB,EACnB,+BAA+B,EAC/B,6BAA6B,EAC7B,yBAAyB,EACzB,yBAAyB,EACzB,wCAAwC,EACxC,kCAAkC,EAClC,wBAAwB,EACxB,yBAAyB,EACzB,kBAAkB,EAClB,iCAAiC,EACjC,2BAA2B,EAC3B,yBAAyB,EACzB,iBAAiB,EACjB,uBAAuB,EACvB,wBAAwB,EACxB,YAAY,EACZ,sCAAsC,EACtC,6BAA6B,EAC7B,0BAA0B,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,2BAA2B,EAC3B,oBAAoB,EACpB,kBAAkB,EAElB,mBAAmB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EACH,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,EACxB,2BAA2B,EAE3B,gBAAgB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACH,0BAA0B,EAC1B,4BAA4B,EAC5B,0BAA0B,EAC1B,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,GAChC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACH,2BAA2B,EAC3B,4BAA4B,EAC5B,iCAAiC,EACjC,4BAA4B,EAC5B,iCAAiC,EACjC,iCAAiC,EACjC,oCAAoC,EACpC,gCAAgC,EAChC,+BAA+B,EAC/B,iCAAiC,EAEjC,qBAAqB,GACxB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACH,uBAAuB,EACvB,oCAAoC,EACpC,8BAA8B,EAC9B,yBAAyB,EACzB,qCAAqC,EACrC,+BAA+B,EAC/B,4BAA4B,EAC5B,0CAA0C,EAC1C,sCAAsC,EACtC,+BAA+B,EAC/B,uBAAuB,EACvB,2BAA2B,EAC3B,8BAA8B,EAC9B,4BAA4B,EAC5B,yBAAyB,EACzB,sCAAsC,EACtC,yBAAyB,EACzB,oBAAoB,EACpB,wBAAwB,EACxB,6BAA6B,EAC7B,iCAAiC,GACpC,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACH,qBAAqB,GAIxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACH,eAAe,EAEf,aAAa,EAEb,YAAY,EACZ,aAAa,GAChB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACH,SAAS,EACT,cAAc,EACd,UAAU,EACV,kBAAkB,EAGlB,MAAM,GACT,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACH,mBAAmB,EACnB,6BAA6B,EAC7B,yBAAyB,EACzB,yBAAyB,EACzB,gBAAgB,EAChB,yBAAyB,EACzB,4BAA4B,EAC5B,iBAAiB,EACjB,gBAAgB,EAChB,8BAA8B,EAC9B,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,EACV,kCAAkC,EAClC,yBAAyB,EACzB,yBAAyB,EACzB,mBAAmB,EACnB,mBAAmB,EACnB,kCAAkC,EAClC,mBAAmB,EACnB,+BAA+B,EAC/B,6BAA6B,EAC7B,yBAAyB,EACzB,yBAAyB,EACzB,wCAAwC,EACxC,kCAAkC,EAClC,wBAAwB,EACxB,yBAAyB,EACzB,kBAAkB,EAClB,iCAAiC,EACjC,2BAA2B,EAC3B,yBAAyB,EACzB,iBAAiB,EACjB,uBAAuB,EACvB,wBAAwB,EACxB,YAAY,EACZ,sCAAsC,EACtC,6BAA6B,EAC7B,0BAA0B,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type MessageCode } from '@nowline/core';
|
|
2
|
+
import type { PositionedRoadmap } from './types.js';
|
|
3
|
+
export type LayoutInsightSeverity = 'info' | 'warning';
|
|
4
|
+
export interface LayoutInsight {
|
|
5
|
+
message: string;
|
|
6
|
+
severity: LayoutInsightSeverity;
|
|
7
|
+
code: MessageCode;
|
|
8
|
+
entityId?: string;
|
|
9
|
+
/** LSP severity: 2 = warning, 3 = information */
|
|
10
|
+
lspSeverity: 2 | 3;
|
|
11
|
+
data: {
|
|
12
|
+
code: MessageCode;
|
|
13
|
+
args: Record<string, unknown>;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export interface LayoutInsightContext {
|
|
17
|
+
today?: Date;
|
|
18
|
+
locale?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Collect layout-derived insights from a positioned roadmap. These describe
|
|
22
|
+
* observable reflow consequences (caption spill, lane packing, etc.), not
|
|
23
|
+
* parse/validation errors.
|
|
24
|
+
*/
|
|
25
|
+
export declare function collectLayoutInsights(layout: PositionedRoadmap, context?: LayoutInsightContext): LayoutInsight[];
|
|
26
|
+
//# sourceMappingURL=layout-insights.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout-insights.d.ts","sourceRoot":"","sources":["../src/layout-insights.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,WAAW,EAAM,MAAM,eAAe,CAAC;AAErD,OAAO,KAAK,EAER,iBAAiB,EAGpB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,SAAS,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,qBAAqB,CAAC;IAChC,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC;IACnB,IAAI,EAAE;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;CAC9D;AAED,MAAM,WAAW,oBAAoB;IACjC,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAmGD;;;;GAIG;AACH,wBAAgB,qBAAqB,CACjC,MAAM,EAAE,iBAAiB,EACzB,OAAO,GAAE,oBAAyB,GACnC,aAAa,EAAE,CAwBjB"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Layout-time insights — observable reflow consequences from the positioned
|
|
2
|
+
// model. Informational by default; warnings only when author intent is lost
|
|
3
|
+
// (e.g. now-line outside the date window).
|
|
4
|
+
import { tr } from '@nowline/core';
|
|
5
|
+
import { MIN_BAR_WIDTH_FOR_DOT_PX } from './item-bar-geometry.js';
|
|
6
|
+
function formatIsoDate(d) {
|
|
7
|
+
return d.toISOString().slice(0, 10);
|
|
8
|
+
}
|
|
9
|
+
function itemLabel(item) {
|
|
10
|
+
return item.id ?? item.title;
|
|
11
|
+
}
|
|
12
|
+
function walkTrackChildren(children, visit) {
|
|
13
|
+
for (const child of children) {
|
|
14
|
+
if (child.kind === 'item') {
|
|
15
|
+
visit(child);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
walkTrackChildren(child.children, visit);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function collectItemInsights(item, locale, out) {
|
|
23
|
+
const name = itemLabel(item);
|
|
24
|
+
if (item.textSpills) {
|
|
25
|
+
out.push(makeInsight(locale, 'NL.I1000', 'info', { name }, name));
|
|
26
|
+
}
|
|
27
|
+
if (item.chipsOutside) {
|
|
28
|
+
out.push(makeInsight(locale, 'NL.I1001', 'info', { name }, name));
|
|
29
|
+
}
|
|
30
|
+
// The status dot is always present, so a bar narrower than the dot's
|
|
31
|
+
// inset is genuinely too small to host its marker. The other cases are
|
|
32
|
+
// already captured by the layout's actual spill flags — using those
|
|
33
|
+
// avoids flagging "decorations spilled" on items that have no link or
|
|
34
|
+
// footnote and nothing actually spilled.
|
|
35
|
+
const tooNarrow = item.box.width < MIN_BAR_WIDTH_FOR_DOT_PX ||
|
|
36
|
+
item.dotSpills ||
|
|
37
|
+
item.iconSpills ||
|
|
38
|
+
item.footnoteSpills;
|
|
39
|
+
if (tooNarrow) {
|
|
40
|
+
out.push(makeInsight(locale, 'NL.I1002', 'info', { name }, name));
|
|
41
|
+
}
|
|
42
|
+
if (item.hasOverflow) {
|
|
43
|
+
out.push(makeInsight(locale, 'NL.I1003', 'info', { name, anchor: item.overflowAnchorId }, name));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function makeInsight(locale, code, severity, args, entityId) {
|
|
47
|
+
return {
|
|
48
|
+
message: tr(locale, code, args),
|
|
49
|
+
severity,
|
|
50
|
+
code,
|
|
51
|
+
entityId,
|
|
52
|
+
lspSeverity: severity === 'warning' ? 2 : 3,
|
|
53
|
+
data: { code, args },
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function collectSwimlaneInsights(lane, locale, out) {
|
|
57
|
+
const laneName = lane.id ?? lane.title;
|
|
58
|
+
const items = [];
|
|
59
|
+
walkTrackChildren(lane.children, (item) => items.push(item));
|
|
60
|
+
for (const item of items) {
|
|
61
|
+
collectItemInsights(item, locale, out);
|
|
62
|
+
}
|
|
63
|
+
const rowYs = new Set(items.map((i) => i.box.y));
|
|
64
|
+
if (rowYs.size > 1) {
|
|
65
|
+
out.push(makeInsight(locale, 'NL.I1004', 'info', { lane: laneName, rows: rowYs.size }, laneName));
|
|
66
|
+
}
|
|
67
|
+
const hasRed = lane.utilization?.segments.some((s) => s.classification === 'red') ?? false;
|
|
68
|
+
if (hasRed) {
|
|
69
|
+
out.push(makeInsight(locale, 'NL.I1005', 'info', { lane: laneName }, laneName));
|
|
70
|
+
}
|
|
71
|
+
for (const nested of lane.nested) {
|
|
72
|
+
collectSwimlaneInsights(nested, locale, out);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Collect layout-derived insights from a positioned roadmap. These describe
|
|
77
|
+
* observable reflow consequences (caption spill, lane packing, etc.), not
|
|
78
|
+
* parse/validation errors.
|
|
79
|
+
*/
|
|
80
|
+
export function collectLayoutInsights(layout, context = {}) {
|
|
81
|
+
const locale = context.locale ?? 'en-US';
|
|
82
|
+
const out = [];
|
|
83
|
+
for (const lane of layout.swimlanes) {
|
|
84
|
+
collectSwimlaneInsights(lane, locale, out);
|
|
85
|
+
}
|
|
86
|
+
if (context.today) {
|
|
87
|
+
const today = context.today;
|
|
88
|
+
const start = layout.timeline.startDate;
|
|
89
|
+
const end = layout.timeline.endDate;
|
|
90
|
+
if (today < start || today > end) {
|
|
91
|
+
out.push(makeInsight(locale, 'NL.W1000', 'warning', {
|
|
92
|
+
date: formatIsoDate(today),
|
|
93
|
+
start: formatIsoDate(start),
|
|
94
|
+
end: formatIsoDate(end),
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=layout-insights.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout-insights.js","sourceRoot":"","sources":["../src/layout-insights.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nowline/layout",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Nowline layout engine —
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "Nowline layout engine — works out where everything goes on the page before it's drawn.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=22",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"d3-scale": "^4.0.2",
|
|
26
26
|
"d3-time": "^3.1.0",
|
|
27
|
-
"@nowline/core": "0.
|
|
27
|
+
"@nowline/core": "0.8.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/d3-scale": "^4.0.9",
|
package/src/index.ts
CHANGED
|
@@ -65,6 +65,12 @@ export {
|
|
|
65
65
|
} from './item-bar-geometry.js';
|
|
66
66
|
export type { LayoutOptions, LayoutResult } from './layout.js';
|
|
67
67
|
export { layoutRoadmap } from './layout.js';
|
|
68
|
+
export {
|
|
69
|
+
collectLayoutInsights,
|
|
70
|
+
type LayoutInsight,
|
|
71
|
+
type LayoutInsightContext,
|
|
72
|
+
type LayoutInsightSeverity,
|
|
73
|
+
} from './layout-insights.js';
|
|
68
74
|
export {
|
|
69
75
|
civilDateInZone,
|
|
70
76
|
type NormalizedZone,
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// Layout-time insights — observable reflow consequences from the positioned
|
|
2
|
+
// model. Informational by default; warnings only when author intent is lost
|
|
3
|
+
// (e.g. now-line outside the date window).
|
|
4
|
+
|
|
5
|
+
import { type MessageCode, tr } from '@nowline/core';
|
|
6
|
+
import { MIN_BAR_WIDTH_FOR_DOT_PX } from './item-bar-geometry.js';
|
|
7
|
+
import type {
|
|
8
|
+
PositionedItem,
|
|
9
|
+
PositionedRoadmap,
|
|
10
|
+
PositionedSwimlane,
|
|
11
|
+
PositionedTrackChild,
|
|
12
|
+
} from './types.js';
|
|
13
|
+
|
|
14
|
+
export type LayoutInsightSeverity = 'info' | 'warning';
|
|
15
|
+
|
|
16
|
+
export interface LayoutInsight {
|
|
17
|
+
message: string;
|
|
18
|
+
severity: LayoutInsightSeverity;
|
|
19
|
+
code: MessageCode;
|
|
20
|
+
entityId?: string;
|
|
21
|
+
/** LSP severity: 2 = warning, 3 = information */
|
|
22
|
+
lspSeverity: 2 | 3;
|
|
23
|
+
data: { code: MessageCode; args: Record<string, unknown> };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface LayoutInsightContext {
|
|
27
|
+
today?: Date;
|
|
28
|
+
locale?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function formatIsoDate(d: Date): string {
|
|
32
|
+
return d.toISOString().slice(0, 10);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function itemLabel(item: PositionedItem): string {
|
|
36
|
+
return item.id ?? item.title;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function walkTrackChildren(
|
|
40
|
+
children: PositionedTrackChild[],
|
|
41
|
+
visit: (item: PositionedItem) => void,
|
|
42
|
+
): void {
|
|
43
|
+
for (const child of children) {
|
|
44
|
+
if (child.kind === 'item') {
|
|
45
|
+
visit(child);
|
|
46
|
+
} else {
|
|
47
|
+
walkTrackChildren(child.children, visit);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function collectItemInsights(item: PositionedItem, locale: string, out: LayoutInsight[]): void {
|
|
53
|
+
const name = itemLabel(item);
|
|
54
|
+
|
|
55
|
+
if (item.textSpills) {
|
|
56
|
+
out.push(makeInsight(locale, 'NL.I1000', 'info', { name }, name));
|
|
57
|
+
}
|
|
58
|
+
if (item.chipsOutside) {
|
|
59
|
+
out.push(makeInsight(locale, 'NL.I1001', 'info', { name }, name));
|
|
60
|
+
}
|
|
61
|
+
// The status dot is always present, so a bar narrower than the dot's
|
|
62
|
+
// inset is genuinely too small to host its marker. The other cases are
|
|
63
|
+
// already captured by the layout's actual spill flags — using those
|
|
64
|
+
// avoids flagging "decorations spilled" on items that have no link or
|
|
65
|
+
// footnote and nothing actually spilled.
|
|
66
|
+
const tooNarrow =
|
|
67
|
+
item.box.width < MIN_BAR_WIDTH_FOR_DOT_PX ||
|
|
68
|
+
item.dotSpills ||
|
|
69
|
+
item.iconSpills ||
|
|
70
|
+
item.footnoteSpills;
|
|
71
|
+
if (tooNarrow) {
|
|
72
|
+
out.push(makeInsight(locale, 'NL.I1002', 'info', { name }, name));
|
|
73
|
+
}
|
|
74
|
+
if (item.hasOverflow) {
|
|
75
|
+
out.push(
|
|
76
|
+
makeInsight(locale, 'NL.I1003', 'info', { name, anchor: item.overflowAnchorId }, name),
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function makeInsight(
|
|
82
|
+
locale: string,
|
|
83
|
+
code: MessageCode,
|
|
84
|
+
severity: LayoutInsightSeverity,
|
|
85
|
+
args: Record<string, unknown>,
|
|
86
|
+
entityId?: string,
|
|
87
|
+
): LayoutInsight {
|
|
88
|
+
return {
|
|
89
|
+
message: tr(locale, code, args as never),
|
|
90
|
+
severity,
|
|
91
|
+
code,
|
|
92
|
+
entityId,
|
|
93
|
+
lspSeverity: severity === 'warning' ? 2 : 3,
|
|
94
|
+
data: { code, args },
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function collectSwimlaneInsights(
|
|
99
|
+
lane: PositionedSwimlane,
|
|
100
|
+
locale: string,
|
|
101
|
+
out: LayoutInsight[],
|
|
102
|
+
): void {
|
|
103
|
+
const laneName = lane.id ?? lane.title;
|
|
104
|
+
const items: PositionedItem[] = [];
|
|
105
|
+
walkTrackChildren(lane.children, (item) => items.push(item));
|
|
106
|
+
|
|
107
|
+
for (const item of items) {
|
|
108
|
+
collectItemInsights(item, locale, out);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const rowYs = new Set(items.map((i) => i.box.y));
|
|
112
|
+
if (rowYs.size > 1) {
|
|
113
|
+
out.push(
|
|
114
|
+
makeInsight(locale, 'NL.I1004', 'info', { lane: laneName, rows: rowYs.size }, laneName),
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const hasRed = lane.utilization?.segments.some((s) => s.classification === 'red') ?? false;
|
|
119
|
+
if (hasRed) {
|
|
120
|
+
out.push(makeInsight(locale, 'NL.I1005', 'info', { lane: laneName }, laneName));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
for (const nested of lane.nested) {
|
|
124
|
+
collectSwimlaneInsights(nested, locale, out);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Collect layout-derived insights from a positioned roadmap. These describe
|
|
130
|
+
* observable reflow consequences (caption spill, lane packing, etc.), not
|
|
131
|
+
* parse/validation errors.
|
|
132
|
+
*/
|
|
133
|
+
export function collectLayoutInsights(
|
|
134
|
+
layout: PositionedRoadmap,
|
|
135
|
+
context: LayoutInsightContext = {},
|
|
136
|
+
): LayoutInsight[] {
|
|
137
|
+
const locale = context.locale ?? 'en-US';
|
|
138
|
+
const out: LayoutInsight[] = [];
|
|
139
|
+
|
|
140
|
+
for (const lane of layout.swimlanes) {
|
|
141
|
+
collectSwimlaneInsights(lane, locale, out);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (context.today) {
|
|
145
|
+
const today = context.today;
|
|
146
|
+
const start = layout.timeline.startDate;
|
|
147
|
+
const end = layout.timeline.endDate;
|
|
148
|
+
if (today < start || today > end) {
|
|
149
|
+
out.push(
|
|
150
|
+
makeInsight(locale, 'NL.W1000', 'warning', {
|
|
151
|
+
date: formatIsoDate(today),
|
|
152
|
+
start: formatIsoDate(start),
|
|
153
|
+
end: formatIsoDate(end),
|
|
154
|
+
}),
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return out;
|
|
160
|
+
}
|