From e1e25d393ed0ceb4b07acb57074d455d50a64e6a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 27 Aug 2026 16:24:44 +0000 Subject: [PATCH] fix: do not scan custom wrappers for GleamView.Line Recursive Line detection walked every component's children, so a parent GleamView entered Line mode when those Lines actually belonged to a nested GleamView (or were never mounted). Only View and Fragment are transparent for first-render detection; custom wrappers still register after mount. Co-authored-by: David Boutin --- CHANGELOG.md | 3 +- README.md | 2 +- lib/module/index.js | 10 ++++ lib/module/index.js.map | 2 +- lib/typescript/src/index.d.ts.map | 2 +- src/__tests__/GleamView.test.tsx | 77 +++++++++++++++++++++++++++---- src/index.tsx | 10 ++++ 7 files changed, 93 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38c0468..0d65581 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- `GleamView.Line` nested inside intermediate wrappers (e.g. ``) is detected on the first render — stable ref, no NativeGleamView→View flip +- `GleamView.Line` nested inside `View` or Fragment wrappers is detected on the first render — stable ref, no NativeGleamView→View flip ### Fixed @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - CI: always run `pod install` after cache restore (codegen needs fresh `build/generated`) - CI: stop caching `vendor/bundle` (stale gems broke Ruby 3.4 pod install) - Example: add `nkf` and `base64` gems for Ruby 3.4 / CocoaPods compatibility +- `GleamView.Line` detection no longer walks custom component `children` (avoids disabling the parent shimmer when a nested `GleamView` owns those Lines) ## [1.0.6] - 2026-05-15 diff --git a/README.md b/README.md index 233fecf..93588a6 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ When `loading={true}`, each `GleamView.Line` renders its own shimmer bar, sized Lines inherit `loading`, `speed`, `direction`, `baseColor`, `highlightColor`, `intensity`, `transitionDuration`, and `transitionType` from the parent. `delay` and `onTransitionEnd` are per-line. -For best performance, place `GleamView.Line` as direct children of `GleamView` (or inside fragments). Lines nested inside intermediate wrappers (e.g., ``) are detected automatically on the first render. +For best performance, place `GleamView.Line` as direct children of `GleamView` (or inside fragments). Lines nested inside `` or fragments are detected on the first render. Custom wrappers still work; they register after mount. Every `GleamView` provides context to its subtree. A `GleamView.Line` always binds to its nearest `GleamView` ancestor — nested `GleamView` components each control their own Lines independently. diff --git a/lib/module/index.js b/lib/module/index.js index 518debf..691b036 100644 --- a/lib/module/index.js +++ b/lib/module/index.js @@ -33,6 +33,13 @@ export let GleamTransition = /*#__PURE__*/function (GleamTransition) { // Direction 2 (DEV runtime): check inside GleamViewComponent catches // new NativeProps keys that weren't added to this list or destructured. const SHIMMER_KEYS = new Set(['loading', 'speed', 'direction', 'delay', 'transitionDuration', 'transitionType', 'intensity', 'baseColor', 'highlightColor', 'onTransitionEnd']); + +// Only walk host wrappers we can inspect without rendering. Custom components +// may re-parent `children` into a nested GleamView (or not mount them at all); +// those Lines must bind via context + registerLine, same as on main. +function isTransparentLineWrapper(type) { + return type === React.Fragment || type === View; +} function scanLineChildren(children, gleamViewType) { let found = false; React.Children.forEach(children, child => { @@ -45,6 +52,9 @@ function scanLineChildren(children, gleamViewType) { if (child.type === gleamViewType) { return; } + if (!isTransparentLineWrapper(child.type)) { + return; + } const nested = child.props.children; if (nested != null) { found = scanLineChildren(nested, gleamViewType); diff --git a/lib/module/index.js.map b/lib/module/index.js.map index 07a7faa..a6d0d91 100644 --- a/lib/module/index.js.map +++ b/lib/module/index.js.map @@ -1 +1 @@ -{"version":3,"names":["React","useCallback","useEffect","useMemo","useRef","useState","View","NativeGleamView","GleamContext","GleamLine","gleamAccessibilityState","gleamStyles","resolveBaseColor","useReduceMotion","jsx","_jsx","GleamDirection","GleamTransition","SHIMMER_KEYS","Set","scanLineChildren","children","gleamViewType","found","Children","forEach","child","isValidElement","type","nested","props","StaticSkeleton","ref","loading","baseColor","viewProps","accessibilityState","style","restViewProps","backgroundColor","hiddenContent","pointerEvents","GleamViewComponent","speed","direction","delay","transitionDuration","transitionType","intensity","highlightColor","onTransitionEnd","reduceMotion","isLoading","useStaticSkeleton","__DEV__","key","Object","keys","has","console","error","lineCountRef","warnedTransitionRef","warnedDefaultLoadingRef","hasLinesInTree","hasRegisteredLines","setHasRegisteredLines","hasLines","current","undefined","warn","registerLine","queueMicrotask","contextValue","nativeRef","Provider","value","displayName","GleamView","assign","Line"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]} +{"version":3,"names":["React","useCallback","useEffect","useMemo","useRef","useState","View","NativeGleamView","GleamContext","GleamLine","gleamAccessibilityState","gleamStyles","resolveBaseColor","useReduceMotion","jsx","_jsx","GleamDirection","GleamTransition","SHIMMER_KEYS","Set","isTransparentLineWrapper","type","Fragment","scanLineChildren","children","gleamViewType","found","Children","forEach","child","isValidElement","nested","props","StaticSkeleton","ref","loading","baseColor","viewProps","accessibilityState","style","restViewProps","backgroundColor","hiddenContent","pointerEvents","GleamViewComponent","speed","direction","delay","transitionDuration","transitionType","intensity","highlightColor","onTransitionEnd","reduceMotion","isLoading","useStaticSkeleton","__DEV__","key","Object","keys","has","console","error","lineCountRef","warnedTransitionRef","warnedDefaultLoadingRef","hasLinesInTree","hasRegisteredLines","setHasRegisteredLines","hasLines","current","undefined","warn","registerLine","queueMicrotask","contextValue","nativeRef","Provider","value","displayName","GleamView","assign","Line"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]} diff --git a/lib/typescript/src/index.d.ts.map b/lib/typescript/src/index.d.ts.map index cc41d92..f0a3848 100644 --- a/lib/typescript/src/index.d.ts.map +++ b/lib/typescript/src/index.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAMN,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,IAAI,EAAkB,MAAM,cAAc,CAAC;AACpD,OAAwB,EAAE,KAAK,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE/E,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAQxC,YAAY,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IACzC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;CACvB,CAAC;AAEF,oBAAY,cAAc;IACxB,WAAW,QAAQ;IACnB,WAAW,QAAQ;IACnB,WAAW,QAAQ;CACpB;AAED,oBAAY,eAAe;IACzB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,QAAQ,aAAa;CACtB;AA4ED,iBAAS,kBAAkB,CAAC,EAC1B,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;CAAE,2CA6J5C;kBAhKQ,kBAAkB;;;AAoK3B,eAAO,MAAM,SAAS;;CAEpB,CAAC"} \ No newline at end of file +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAMN,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,IAAI,EAAkB,MAAM,cAAc,CAAC;AACpD,OAAwB,EAAE,KAAK,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE/E,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAQxC,YAAY,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IACzC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;CACvB,CAAC;AAEF,oBAAY,cAAc;IACxB,WAAW,QAAQ;IACnB,WAAW,QAAQ;IACnB,WAAW,QAAQ;CACpB;AAED,oBAAY,eAAe;IACzB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,QAAQ,aAAa;CACtB;AAsFD,iBAAS,kBAAkB,CAAC,EAC1B,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;CAAE,2CA6J5C;kBAhKQ,kBAAkB;;;AAoK3B,eAAO,MAAM,SAAS;;CAEpB,CAAC"} \ No newline at end of file diff --git a/src/__tests__/GleamView.test.tsx b/src/__tests__/GleamView.test.tsx index 6d5420d..8c7e5b8 100644 --- a/src/__tests__/GleamView.test.tsx +++ b/src/__tests__/GleamView.test.tsx @@ -782,7 +782,7 @@ describe('GleamView.Line child detection', () => { expect(screen.getByTestId('line').props.loading).toBe(true); }); - it('detects Lines inside a non-fragment wrapper via registration', () => { + it('detects Lines inside a View wrapper on the first render', () => { render( @@ -792,12 +792,75 @@ describe('GleamView.Line child detection', () => { ); - // registerLine fires in useLayoutEffect, switching to plain View const parent = screen.getByTestId('parent'); expect(parent.props.loading).toBeUndefined(); expect(screen.getByTestId('line').props.loading).toBe(true); }); + it('detects Lines inside a custom wrapper via registration', () => { + function Wrapper({ children }: { children: React.ReactNode }) { + return {children}; + } + + render( + + + + Content + + + + ); + // Custom wrappers are not scanned; registerLine still flips to Line mode. + const parent = screen.getByTestId('parent'); + expect(parent.props.loading).toBeUndefined(); + expect(screen.getByTestId('line').props.loading).toBe(true); + }); + + it('does not treat Lines owned by a nested GleamView as parent Lines', () => { + function SkeletonCard({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); + } + + render( + + + + Title + + + + ); + + // Line binds to the inner GleamView. The outer must stay a native shimmer. + expect(screen.getByTestId('outer').props.loading).toBe(true); + expect(screen.getByTestId('inner').props.loading).toBeUndefined(); + expect(screen.getByTestId('line').props.loading).toBe(true); + }); + + it('does not enter Line mode when a custom wrapper keeps Line children unmounted', () => { + function Hidden({ children: _children }: { children: React.ReactNode }) { + return ; + } + + render( + + + + Hidden + + + + ); + + expect(screen.getByTestId('parent').props.loading).toBe(true); + expect(screen.queryByTestId('line')).toBeNull(); + }); + it('renders as native GleamView when conditional Line is false', () => { render( @@ -1030,11 +1093,7 @@ describe('GleamView.Line ref stability', () => { expect(mountCalls).toHaveLength(1); }); - it('ref is stable on first render with Lines inside an intermediate wrapper', () => { - function Wrapper({ children }: { children: React.ReactNode }) { - return {children}; - } - + it('ref is stable on first render with Lines inside a View wrapper', () => { const refCalls: unknown[] = []; const refFn = (node: unknown) => { refCalls.push(node); @@ -1042,11 +1101,11 @@ describe('GleamView.Line ref stability', () => { render( - + Content - + ); diff --git a/src/index.tsx b/src/index.tsx index 811ecaa..d4557e9 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -58,6 +58,13 @@ const SHIMMER_KEYS: ReadonlySet = new Set([ 'onTransitionEnd', ] as const satisfies ReadonlyArray); +// Only walk host wrappers we can inspect without rendering. Custom components +// may re-parent `children` into a nested GleamView (or not mount them at all); +// those Lines must bind via context + registerLine, same as on main. +function isTransparentLineWrapper(type: unknown): boolean { + return type === React.Fragment || type === View; +} + function scanLineChildren( children: React.ReactNode, gleamViewType: unknown @@ -73,6 +80,9 @@ function scanLineChildren( if (child.type === gleamViewType) { return; } + if (!isTransparentLineWrapper(child.type)) { + return; + } const nested = (child.props as { children?: React.ReactNode }).children; if (nested != null) { found = scanLineChildren(nested, gleamViewType);