PenpotUtils.analyzeDescendants: Try more explicit args (root, shape) for evaluator #26

This can perhaps prevent usage errors
This commit is contained in:
Dominik Jain 2026-01-15 17:30:36 +01:00
parent e993c74636
commit 07300fea2d
2 changed files with 7 additions and 7 deletions

View File

@ -137,7 +137,7 @@ initial_instructions: |
Returns true if child is fully within parent's visual bounds
* setParentXY(shape: Shape, parentX: number, parentY: number): void
Sets shape position relative to its parent (since parentX/parentY are read-only)
* analyzeDescendants<T>(root: Shape, evaluator: (descendant: Shape) => T | null | undefined, maxDepth?: number): Array<{ shape: Shape, result: T }>
* analyzeDescendants<T>(root: Shape, evaluator: (root: Shape, descendant: Shape) => T | null | undefined, maxDepth?: number): Array<{ shape: Shape, result: T }>
General-purpose utility for analyzing/validating descendants
Calls evaluator on each descendant; collects non-null/undefined results
Powerful pattern: evaluator can return corrector functions or diagnostic data
@ -163,7 +163,7 @@ initial_instructions: |
* Find shapes in current selection/board:
const shapes = penpotUtils.findShapes(predicate, penpot.selection[0] || penpot.root);
* Validate/analyze descendants (returns corrector functions):
const fixes = penpotUtils.analyzeDescendants(board, (shape) => {
const fixes = penpotUtils.analyzeDescendants(board, (root, shape) => {
const xMod = shape.parentX % 4;
if (xMod !== 0) {
return () => penpotUtils.setParentXY(shape, Math.round(shape.parentX / 4) * 4, shape.parentY);
@ -171,8 +171,8 @@ initial_instructions: |
});
fixes.forEach(f => f.result()); // Apply all fixes
* Find containment violations:
const violations = penpotUtils.analyzeDescendants(board, (shape) => {
return !penpotUtils.isContainedIn(shape, board) ? 'outside-bounds' : null;
const violations = penpotUtils.analyzeDescendants(board, (root, shape) => {
return !penpotUtils.isContainedIn(shape, root) ? 'outside-bounds' : null;
});
# Asset Libraries

View File

@ -204,19 +204,19 @@ export class PenpotUtils {
* This is a general-purpose utility for validation, analysis, or collecting corrector functions.
*
* @param root - The root shape whose descendants to analyze
* @param evaluator - Function called for each descendant; return null/undefined to skip
* @param evaluator - Function called for each descendant with (root, descendant); return null/undefined to skip
* @param maxDepth - Optional maximum depth to traverse (undefined for unlimited)
* @returns Array of objects containing the shape and the evaluator's result
*/
public static analyzeDescendants<T>(
root: Shape,
evaluator: (descendant: Shape) => T | null | undefined,
evaluator: (root: Shape, descendant: Shape) => T | null | undefined,
maxDepth: number | undefined = undefined
): Array<{ shape: Shape; result: NonNullable<T> }> {
const results: Array<{ shape: Shape; result: NonNullable<T> }> = [];
const traverse = (shape: Shape, currentDepth: number): void => {
const result = evaluator(shape);
const result = evaluator(root, shape);
if (result !== null && result !== undefined) {
results.push({ shape, result: result as NonNullable<T> });
}