@contrail/documents 2.1.0 → 2.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.
- package/CHANGELOG.md +11 -0
- package/lib/components/item-component.service.d.ts +2 -0
- package/lib/components/item-component.service.js +29 -23
- package/lib/document-element-constants.d.ts +3 -0
- package/lib/document-element-constants.js +4 -1
- package/lib/document-element-factory.d.ts +2 -1
- package/lib/document-element-factory.js +26 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,17 @@ All notable changes to `@contrail/documents` are documented here.
|
|
|
5
5
|
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
6
6
|
Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.2.0] - 2026-09-15
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `ItemComponentService.isAnnotationRowEmpty(annotationElement, annotations)` — whether an item card's annotation row will render nothing, because the row is hidden or the item has no `category === 'property'` annotations. The single predicate behind the reservation, so the layout service and the canvas renderers cannot drift apart on the question. A missing row element is not treated as hidden: renderers supply a default row for item components that have none stored, so only the annotation data decides there.
|
|
13
|
+
- `ItemComponentService.getAnnotationRowHeight(annotationElement, annotations, width)` — the row's reserved height, wrapping onto further rows when the badges do not fit `width`, and `0` when the row is empty. Every creation path must size the row through here so a card laid out by the Item Chooser and one laid out by board generation agree.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- `updateSizeAndPosition` no longer reserves space above the thumbnail for an annotation row that renders nothing. `calculateAnnotationHeight` returned a flat `fontSize + ANNOTATION_PADDING_Y` minimum even when the row was hidden or the item had no annotations, pushing the thumbnail down ~8px on every such card (DESIGN-150). It now returns `0` in those cases and the thumbnail sits at the card origin. Cards whose row does show a badge are unchanged.
|
|
18
|
+
|
|
8
19
|
## [1.19.0] - 2026-09-11
|
|
9
20
|
|
|
10
21
|
### Added
|
|
@@ -15,6 +15,8 @@ export interface ScaledItemCardResult {
|
|
|
15
15
|
export declare class ItemComponentService {
|
|
16
16
|
static isItemComponent(element: DocumentElement): boolean;
|
|
17
17
|
static isThumbnailOnlyComponent(element: DocumentElement): boolean;
|
|
18
|
+
static isAnnotationRowEmpty(annotationElement: DocumentElement, annotations?: any[]): boolean;
|
|
19
|
+
static getAnnotationRowHeight(annotationElement: DocumentElement, annotations?: any[], width?: number): number;
|
|
18
20
|
static updateSizeAndPosition(propertyElements: any[], componentElement: DocumentElement, annotatedElements?: any[]): any;
|
|
19
21
|
private static getYMargin;
|
|
20
22
|
private static calculateAnnotationHeight;
|
|
@@ -17,6 +17,30 @@ class ItemComponentService {
|
|
|
17
17
|
const imageElement = element.elements.find((e) => e.type == 'image');
|
|
18
18
|
return (!annotationElement || annotationElement.isHidden) && imageElement && !imageElement.isHidden;
|
|
19
19
|
}
|
|
20
|
+
static isAnnotationRowEmpty(annotationElement, annotations = []) {
|
|
21
|
+
if (annotationElement === null || annotationElement === void 0 ? void 0 : annotationElement.isHidden) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
return !(annotations === null || annotations === void 0 ? void 0 : annotations.some((annotation) => (annotation === null || annotation === void 0 ? void 0 : annotation.category) === 'property'));
|
|
25
|
+
}
|
|
26
|
+
static getAnnotationRowHeight(annotationElement, annotations = [], width = exports.DEFAULT_THUMBNAIL_WIDTH) {
|
|
27
|
+
var _a, _b;
|
|
28
|
+
if (this.isAnnotationRowEmpty(annotationElement, annotations)) {
|
|
29
|
+
return 0;
|
|
30
|
+
}
|
|
31
|
+
const annotationSize = ((_b = (_a = annotationElement === null || annotationElement === void 0 ? void 0 : annotationElement.style) === null || _a === void 0 ? void 0 : _a.font) === null || _b === void 0 ? void 0 : _b.size) || document_element_constants_1.ANNOTATION_IMG_SIZE;
|
|
32
|
+
const propertyAnnotations = annotations.filter((annotation) => (annotation === null || annotation === void 0 ? void 0 : annotation.category) === 'property');
|
|
33
|
+
let height = annotationSize + document_element_constants_1.ANNOTATION_PADDING_Y;
|
|
34
|
+
let count = 0;
|
|
35
|
+
propertyAnnotations.forEach(() => {
|
|
36
|
+
if ((count + 1) * annotationSize * 1.25 > width) {
|
|
37
|
+
count = 0;
|
|
38
|
+
height = height + annotationSize + document_element_constants_1.ANNOTATION_PADDING_Y;
|
|
39
|
+
}
|
|
40
|
+
count++;
|
|
41
|
+
});
|
|
42
|
+
return height;
|
|
43
|
+
}
|
|
20
44
|
static updateSizeAndPosition(propertyElements, componentElement, annotatedElements = []) {
|
|
21
45
|
var _a, _b, _c, _d;
|
|
22
46
|
const newElements = [];
|
|
@@ -64,9 +88,11 @@ class ItemComponentService {
|
|
|
64
88
|
lastYPosition = element.position.y;
|
|
65
89
|
}
|
|
66
90
|
const annotationHeight = this.calculateAnnotationHeight(element, componentElement, width, annotatedElements);
|
|
67
|
-
lastYPosition = lastYPosition + annotationHeight;
|
|
68
91
|
if (annotationHeight === 0 && index === 0) {
|
|
69
|
-
lastYPosition =
|
|
92
|
+
lastYPosition = 0;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
lastYPosition = lastYPosition + annotationHeight;
|
|
70
96
|
}
|
|
71
97
|
}
|
|
72
98
|
element.size.width = width;
|
|
@@ -112,28 +138,8 @@ class ItemComponentService {
|
|
|
112
138
|
return marginY;
|
|
113
139
|
}
|
|
114
140
|
static calculateAnnotationHeight(element, componentElement, width, annotatedElements = []) {
|
|
115
|
-
var _a, _b;
|
|
116
|
-
const annotationSize = ((_b = (_a = element.style) === null || _a === void 0 ? void 0 : _a.font) === null || _b === void 0 ? void 0 : _b.size) || document_element_constants_1.ANNOTATION_IMG_SIZE;
|
|
117
|
-
let height = annotationSize + document_element_constants_1.ANNOTATION_PADDING_Y;
|
|
118
|
-
let xPos = 0;
|
|
119
141
|
const annotatedElement = annotatedElements.find((elem) => elem.id === componentElement.id);
|
|
120
|
-
|
|
121
|
-
return height;
|
|
122
|
-
}
|
|
123
|
-
const annotations = annotatedElement.annotations.filter((annotation) => annotation.category === 'property');
|
|
124
|
-
if (annotations.length > 0) {
|
|
125
|
-
let count = 0;
|
|
126
|
-
annotations === null || annotations === void 0 ? void 0 : annotations.forEach((annotation) => {
|
|
127
|
-
if ((count + 1) * annotationSize * 1.25 > width) {
|
|
128
|
-
count = 0;
|
|
129
|
-
xPos = -width * 0.5;
|
|
130
|
-
height = height + annotationSize + document_element_constants_1.ANNOTATION_PADDING_Y;
|
|
131
|
-
}
|
|
132
|
-
xPos = xPos + annotationSize * 1.25;
|
|
133
|
-
count++;
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
return height;
|
|
142
|
+
return this.getAnnotationRowHeight(element, annotatedElement === null || annotatedElement === void 0 ? void 0 : annotatedElement.annotations, width);
|
|
137
143
|
}
|
|
138
144
|
static getImageElement(element) {
|
|
139
145
|
var _a;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
export declare const ANNOTATION_IMG_SIZE = 15;
|
|
2
2
|
export declare const ANNOTATION_PADDING_Y = 8;
|
|
3
|
+
export declare const COMPONENT_PADDING_X = 8;
|
|
4
|
+
export declare const COMPONENT_PADDING_T = 18;
|
|
5
|
+
export declare const COMPONENT_PADDING_B = 8;
|
|
3
6
|
export declare const COLOR_PADDING = 5;
|
|
4
7
|
export declare const COLOR_FONT_SIZE = 8;
|
|
5
8
|
export declare const COLOR_WIDTH = 140;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.COLOR_WIDTH = exports.COLOR_FONT_SIZE = exports.COLOR_PADDING = exports.ANNOTATION_PADDING_Y = exports.ANNOTATION_IMG_SIZE = void 0;
|
|
3
|
+
exports.COLOR_WIDTH = exports.COLOR_FONT_SIZE = exports.COLOR_PADDING = exports.COMPONENT_PADDING_B = exports.COMPONENT_PADDING_T = exports.COMPONENT_PADDING_X = exports.ANNOTATION_PADDING_Y = exports.ANNOTATION_IMG_SIZE = void 0;
|
|
4
4
|
exports.ANNOTATION_IMG_SIZE = 15;
|
|
5
5
|
exports.ANNOTATION_PADDING_Y = 8;
|
|
6
|
+
exports.COMPONENT_PADDING_X = 8;
|
|
7
|
+
exports.COMPONENT_PADDING_T = 18;
|
|
8
|
+
exports.COMPONENT_PADDING_B = 8;
|
|
6
9
|
exports.COLOR_PADDING = 5;
|
|
7
10
|
exports.COLOR_FONT_SIZE = 8;
|
|
8
11
|
exports.COLOR_WIDTH = 140;
|
|
@@ -16,7 +16,7 @@ export declare class DocumentElementFactory {
|
|
|
16
16
|
newElements: DocumentElement[];
|
|
17
17
|
};
|
|
18
18
|
static isMask(element: DocumentElement): boolean;
|
|
19
|
-
static getBoundingClientRect(documentElement: DocumentElement, startElement?: DocumentElement, endElement?: DocumentElement): {
|
|
19
|
+
static getBoundingClientRect(documentElement: DocumentElement, startElement?: DocumentElement, endElement?: DocumentElement, annotations?: any[]): {
|
|
20
20
|
x: any;
|
|
21
21
|
y: any;
|
|
22
22
|
width: any;
|
|
@@ -25,5 +25,6 @@ export declare class DocumentElementFactory {
|
|
|
25
25
|
private static getPosition;
|
|
26
26
|
private static getSize;
|
|
27
27
|
private static getComponentSize;
|
|
28
|
+
private static getComponentPaddingTop;
|
|
28
29
|
static getLineDefinition(documentElement: DocumentElement, startElement?: DocumentElement, endElement?: DocumentElement): LineDefinition;
|
|
29
30
|
}
|
|
@@ -8,6 +8,7 @@ const components_1 = require("./components/components");
|
|
|
8
8
|
const document_element_property_binding_handler_1 = require("./document-element-property-binding-handler");
|
|
9
9
|
const document_table_1 = require("@contrail/document-table");
|
|
10
10
|
const document_element_constants_1 = require("./document-element-constants");
|
|
11
|
+
const item_component_service_1 = require("./components/item-component.service");
|
|
11
12
|
const callout_1 = require("./util/callout/callout");
|
|
12
13
|
class DocumentElementFactory {
|
|
13
14
|
static initNewElement(type) {
|
|
@@ -206,9 +207,9 @@ class DocumentElementFactory {
|
|
|
206
207
|
var _a;
|
|
207
208
|
return ['rectangle', 'circle'].indexOf(element === null || element === void 0 ? void 0 : element.type) !== -1 && ((_a = element === null || element === void 0 ? void 0 : element.elementIds) === null || _a === void 0 ? void 0 : _a.length) > 0;
|
|
208
209
|
}
|
|
209
|
-
static getBoundingClientRect(documentElement, startElement, endElement) {
|
|
210
|
+
static getBoundingClientRect(documentElement, startElement, endElement, annotations) {
|
|
210
211
|
const { x, y } = this.getPosition(documentElement, startElement, endElement);
|
|
211
|
-
const { width, height } = this.getSize(documentElement, startElement, endElement);
|
|
212
|
+
const { width, height } = this.getSize(documentElement, startElement, endElement, annotations);
|
|
212
213
|
return {
|
|
213
214
|
x,
|
|
214
215
|
y,
|
|
@@ -235,7 +236,7 @@ class DocumentElementFactory {
|
|
|
235
236
|
(documentElement.type === 'component' && ((_b = documentElement === null || documentElement === void 0 ? void 0 : documentElement.modelBindings) === null || _b === void 0 ? void 0 : _b.item) ? 18 : 0),
|
|
236
237
|
};
|
|
237
238
|
}
|
|
238
|
-
static getSize(documentElement, startElement, endElement) {
|
|
239
|
+
static getSize(documentElement, startElement, endElement, annotations) {
|
|
239
240
|
if (documentElement.type === 'line' || documentElement.type === 'callout') {
|
|
240
241
|
const lineDefinition = this.getLineDefinition(documentElement, startElement, endElement);
|
|
241
242
|
if (!lineDefinition) {
|
|
@@ -246,10 +247,12 @@ class DocumentElementFactory {
|
|
|
246
247
|
height: Math.abs(lineDefinition.y1 - lineDefinition.y2),
|
|
247
248
|
};
|
|
248
249
|
}
|
|
249
|
-
return documentElement.type === 'component'
|
|
250
|
+
return documentElement.type === 'component'
|
|
251
|
+
? this.getComponentSize(documentElement, annotations)
|
|
252
|
+
: documentElement.size;
|
|
250
253
|
}
|
|
251
|
-
static getComponentSize(documentElement) {
|
|
252
|
-
var _a, _b, _c, _d, _e
|
|
254
|
+
static getComponentSize(documentElement, annotations) {
|
|
255
|
+
var _a, _b, _c, _d, _e;
|
|
253
256
|
let width = 0, height = 0, lastY = null;
|
|
254
257
|
for (let i = 0; i < ((_a = documentElement === null || documentElement === void 0 ? void 0 : documentElement.elements) === null || _a === void 0 ? void 0 : _a.length); i++) {
|
|
255
258
|
const element = documentElement.elements[i];
|
|
@@ -263,11 +266,26 @@ class DocumentElementFactory {
|
|
|
263
266
|
lastY = y + renderedHeight;
|
|
264
267
|
}
|
|
265
268
|
}
|
|
269
|
+
if (!((_e = documentElement === null || documentElement === void 0 ? void 0 : documentElement.modelBindings) === null || _e === void 0 ? void 0 : _e.item)) {
|
|
270
|
+
return { width, height };
|
|
271
|
+
}
|
|
266
272
|
return {
|
|
267
|
-
width: width +
|
|
268
|
-
height: height + (
|
|
273
|
+
width: width + document_element_constants_1.COMPONENT_PADDING_X * 2,
|
|
274
|
+
height: height + this.getComponentPaddingTop(documentElement, annotations) + document_element_constants_1.COMPONENT_PADDING_B,
|
|
269
275
|
};
|
|
270
276
|
}
|
|
277
|
+
static getComponentPaddingTop(documentElement, annotations) {
|
|
278
|
+
var _a, _b, _c, _d, _e;
|
|
279
|
+
if (!annotations) {
|
|
280
|
+
return document_element_constants_1.COMPONENT_PADDING_T;
|
|
281
|
+
}
|
|
282
|
+
const annotationElement = (_a = documentElement === null || documentElement === void 0 ? void 0 : documentElement.elements) === null || _a === void 0 ? void 0 : _a.find((element) => element.type === 'annotation');
|
|
283
|
+
if (!item_component_service_1.ItemComponentService.isAnnotationRowEmpty(annotationElement, annotations)) {
|
|
284
|
+
return document_element_constants_1.COMPONENT_PADDING_T;
|
|
285
|
+
}
|
|
286
|
+
const contentOffsetY = (_e = (_d = (_c = (_b = documentElement === null || documentElement === void 0 ? void 0 : documentElement.elements) === null || _b === void 0 ? void 0 : _b.find((element) => element.type === 'image')) === null || _c === void 0 ? void 0 : _c.position) === null || _d === void 0 ? void 0 : _d.y) !== null && _e !== void 0 ? _e : 0;
|
|
287
|
+
return -contentOffsetY;
|
|
288
|
+
}
|
|
271
289
|
static getLineDefinition(documentElement, startElement, endElement) {
|
|
272
290
|
var _a, _b;
|
|
273
291
|
if (documentElement.type === 'line')
|