From 1b21c1e392ec62b641e419ad3fc2366b416204ec Mon Sep 17 00:00:00 2001 From: Boris Jankovic Date: Tue, 16 Sep 2025 22:47:59 +0200 Subject: [PATCH 1/6] refactor: enhance styling capabilities with alignSelf support - Updated the YogaStyles interface to include AlignSelf type. - Added alignSelf mapping in applyStyle.ts for improved style application. - Introduced new Tailwind utility for 'self-auto' alignment. - Updated .gitignore to include *.tgz files. --- .gitignore | 3 ++- src/core/style/applyStyle.ts | 17 +++++++++++++++-- src/core/style/yogaStyles.ts | 3 ++- src/tailwind/ptw.ts | 1 + 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 061b40ae..7f7e92d3 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,5 @@ docs/build *storybook.log *.artifacts -*.temp \ No newline at end of file +*.temp +*.tgz diff --git a/src/core/style/applyStyle.ts b/src/core/style/applyStyle.ts index dd52ab5a..3d88af63 100644 --- a/src/core/style/applyStyle.ts +++ b/src/core/style/applyStyle.ts @@ -12,7 +12,7 @@ import { PositionType, Wrap, } from 'yoga-layout/load'; -import { type AlignContent, type AlignItems, type JustifyContent, type YogaStyles } from './yogaStyles'; +import { type AlignContent, type AlignItems, type AlignSelf, type JustifyContent, type YogaStyles } from './yogaStyles'; const ALIGN_CONTENT_MAP: Record = { 'flex-start': Align.FlexStart, @@ -32,6 +32,14 @@ const ALIGN_ITEMS_MAP: Record = { baseline: Align.Baseline, } as const; +const ALIGN_SELF_MAP: Record = { + auto: Align.Auto, + 'flex-start': Align.FlexStart, + 'flex-end': Align.FlexEnd, + center: Align.Center, + stretch: Align.Stretch, + baseline: Align.Baseline, +} as const; const BOX_SIZING_MAP: Record<'border-box' | 'content-box', BoxSizing> = { 'border-box': BoxSizing.BorderBox, 'content-box': BoxSizing.ContentBox, @@ -85,7 +93,7 @@ const POSITION_MAP: Record<'absolute' | 'relative' | 'static', PositionType> = { const styleSetters: Record void> = { alignContent: (node, value) => node.setAlignContent(alignContent(value)), alignItems: (node, value) => node.setAlignItems(alignItems(value)), - alignSelf: (node, value) => node.setAlignSelf(alignItems(value)), + alignSelf: (node, value) => node.setAlignSelf(alignSelf(value)), aspectRatio: (node, value) => node.setAspectRatio(value), borderBottomWidth: (node, value) => node.setBorder(Edge.Bottom, value), borderEndWidth: (node, value) => node.setBorder(Edge.End, value), @@ -158,6 +166,11 @@ function alignItems(str: keyof typeof ALIGN_ITEMS_MAP): Align { throw new Error(`"${str}" is not a valid value for alignItems`); } +function alignSelf(str: keyof typeof ALIGN_SELF_MAP): Align { + if (str in ALIGN_SELF_MAP) return ALIGN_SELF_MAP[str]; + + throw new Error(`"${str}" is not a valid value for alignSelf`); +} function boxSizing(str: keyof typeof BOX_SIZING_MAP): BoxSizing { if (str in BOX_SIZING_MAP) return BOX_SIZING_MAP[str]; diff --git a/src/core/style/yogaStyles.ts b/src/core/style/yogaStyles.ts index bacd156e..7588c520 100644 --- a/src/core/style/yogaStyles.ts +++ b/src/core/style/yogaStyles.ts @@ -20,7 +20,7 @@ export interface YogaStyles { * Override alignItems for individual flex item * @values 'auto' | 'flex-start' | 'flex-end' | 'center' | 'baseline' | 'stretch' */ - alignSelf?: AlignItems; + alignSelf?: AlignSelf; /** * Fixed ratio between width and height @@ -263,6 +263,7 @@ export interface YogaStyles { export type JustifyContent = 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly'; export type AlignItems = 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline'; +export type AlignSelf = 'auto' | AlignItems; export type AlignContent = | 'flex-start' | 'flex-end' diff --git a/src/tailwind/ptw.ts b/src/tailwind/ptw.ts index db05d113..e63dc350 100644 --- a/src/tailwind/ptw.ts +++ b/src/tailwind/ptw.ts @@ -66,6 +66,7 @@ class TailwindParser { 'content-evenly': { alignContent: 'space-evenly' }, 'content-stretch': { alignContent: 'stretch' }, + 'self-auto': { alignSelf: 'auto' }, 'self-start': { alignSelf: 'flex-start' }, 'self-center': { alignSelf: 'center' }, 'self-end': { alignSelf: 'flex-end' }, From 3600dd664b9eb240f0da8b682c802707791abbbc Mon Sep 17 00:00:00 2001 From: Boris Jankovic Date: Tue, 16 Sep 2025 22:57:38 +0200 Subject: [PATCH 2/6] refactor: optimize child sorting logic in onChildAdded function Replaces direct access to pixiParent.children with a local variable for improved readability and performance. This change simplifies the logic for determining the last child and enhances maintainability of the code. --- src/core/utils/sort-children.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/core/utils/sort-children.ts b/src/core/utils/sort-children.ts index 032514a2..8c1aa670 100644 --- a/src/core/utils/sort-children.ts +++ b/src/core/utils/sort-children.ts @@ -9,13 +9,12 @@ import { type Layout } from '../Layout'; * @param layout - The layout to sort the children for */ export function onChildAdded(layout: Layout, pixiParent: Container) { - let parentLayout = pixiParent.layout; let yogaIndex = -1; + let parentLayout = pixiParent.layout; + const childrenToLoop = pixiParent.children; if (!parentLayout && (pixiParent as OverflowContainer).isOverflowContainer) { parentLayout = pixiParent.parent?.layout; - // update yogaIndex - yogaIndex = pixiParent.children.indexOf(layout.target); pixiParent = pixiParent.parent!; } @@ -27,15 +26,15 @@ export function onChildAdded(layout: Layout, pixiParent: Container) { } // If the child is the last one, we can just append it - if (pixiParent.children.indexOf(layout.target) === pixiParent.children.length - 1 && yogaIndex === -1) { + if (childrenToLoop.indexOf(layout.target) === childrenToLoop.length - 1) { parentLayout.yoga.insertChild(layout.yoga, parentLayout.yoga.getChildCount()); return; } // Find the corresponding Yoga index - for (let i = 0; i < pixiParent.children.length; i++) { - const child = pixiParent.children[i]!; + for (let i = 0; i < childrenToLoop.length; i++) { + const child = childrenToLoop[i]!; if (child.layout && child.visible) { yogaIndex++; From 5402ca8826052ec533f70ee747f79ef5128b5d8f Mon Sep 17 00:00:00 2001 From: Boris Jankovic Date: Tue, 16 Sep 2025 23:23:16 +0200 Subject: [PATCH 3/6] Changes --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a9d690d9..31be59e8 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "@pixi/layout", + "name": "@wonder-design/pixijs-layout", "version": "3.1.0", "description": "A Yoga powered layout library for PixiJS", "keywords": [ @@ -7,17 +7,17 @@ "yoga", "pixi" ], - "homepage": "https://github.com/pixijs/layout#readme", + "homepage": "https://github.com/aquila-lab/pixijs-layout#readme", "bugs": { - "url": "https://github.com/pixijs/layout/issues" + "url": "https://github.com/aquila-lab/pixijs-layout/issues" }, "repository": { "type": "git", - "url": "git+https://github.com/pixijs/layout.git" + "url": "git+https://github.com/aquila-lab/pixijs-layout.git" }, "license": "MIT", "author": { - "name": "PixiJS Team" + "name": "Wonder Design + PixiJS Team" }, "type": "module", "exports": { From ed70e6922ee3b26b5c5b53ec30c598961b3c49c2 Mon Sep 17 00:00:00 2001 From: Boris Jankovic Date: Fri, 19 Sep 2025 21:06:05 +0200 Subject: [PATCH 4/6] feat: add destroyed flag to Layout class for resource management Introduces a 'destroyed' property to the Layout class to track the object's state. Updates the destroy method to prevent multiple calls and ensure proper resource cleanup when the object is destroyed. --- src/core/Layout.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/core/Layout.ts b/src/core/Layout.ts index ebc4665d..b6c8b052 100644 --- a/src/core/Layout.ts +++ b/src/core/Layout.ts @@ -42,6 +42,12 @@ export class Layout { /** The target PixiJS container */ public readonly target: Container; + /** + * Whether this object has been destroyed. If true, the object should no longer be used. + * After an object is destroyed, all of its functionality is disabled and references are removed. + */ + public destroyed = false; + /** * Flag indicating if layout needs recalculation * @ignore @@ -278,6 +284,9 @@ export class Layout { } public destroy(): void { + if (this.destroyed) return; + this.destroyed = true; + this.invalidateRoot(); this.yoga.free(); this.target.off('added', this._onChildAdded, this); From cb6608d1b12c3fa0a50bca02cec87421b9b238f3 Mon Sep 17 00:00:00 2001 From: Boris Jankovic Date: Fri, 19 Sep 2025 21:21:52 +0200 Subject: [PATCH 5/6] Revert to pixijs package.json --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 1c7441ab..1eb088a2 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "@wonder-design/pixijs-layout", + "name": "@pixi/layout", "version": "3.1.0", "description": "A Yoga powered layout library for PixiJS", "keywords": [ @@ -7,17 +7,17 @@ "yoga", "pixi" ], - "homepage": "https://github.com/aquila-lab/pixijs-layout#readme", + "homepage": "https://github.com/pixijs/layout#readme", "bugs": { - "url": "https://github.com/aquila-lab/pixijs-layout/issues" + "url": "https://github.com/pixijs/layout/issues" }, "repository": { "type": "git", - "url": "git+https://github.com/aquila-lab/pixijs-layout.git" + "url": "git+https://github.com/pixijs/layout.git" }, "license": "MIT", "author": { - "name": "Wonder Design + PixiJS Team" + "name": "PixiJS Team" }, "type": "module", "exports": { From 0a93c812e7a33d2d3e46f0e65d24b6c533ee910a Mon Sep 17 00:00:00 2001 From: Boris Jankovic Date: Mon, 2 Feb 2026 18:46:41 +0100 Subject: [PATCH 6/6] fix: ensure proper cleanup on child removal in Layout class Adds a call to onChildRemoved when a child is removed, enhancing the cleanup process and maintaining layout integrity. --- src/core/Layout.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/Layout.ts b/src/core/Layout.ts index 98de44c8..ae0652fd 100644 --- a/src/core/Layout.ts +++ b/src/core/Layout.ts @@ -297,6 +297,7 @@ export class Layout { this.destroyed = true; this.invalidateRoot(); + onChildRemoved(this); this.yoga.free(); this.target.off('added', this._onChildAdded, this); this.target.off('removed', this._onChildRemoved, this);